All of lore.kernel.org
 help / color / mirror / Atom feed
* [U-Boot] [PATCH v2 1/2] riscv: tools: Fix prelink-riscv to work on big endian hosts
@ 2019-08-02 17:45 Marcus Comstedt
  2019-08-02 17:45 ` [U-Boot] [PATCH v2 2/2] riscv: tools: Add big endian target support to prelink-riscv Marcus Comstedt
       [not found] ` <752D002CFF5D0F4FA35C0100F1D73F3FA40FA9DF@ATCPCS16.andestech.com>
  0 siblings, 2 replies; 6+ messages in thread
From: Marcus Comstedt @ 2019-08-02 17:45 UTC (permalink / raw)
  To: u-boot

All ELF fields whose values are inspected by the code are converted to
CPU byteorder first.  Values which are copied verbatim (relocation
fixups) are not swapped to CPU byteorder and back as it is not needed.

Signed-off-by: Marcus Comstedt <marcus@mc.pp.se>
Cc: Rick Chen <rick@andestech.com>
---
Changes for v2:
   - Now #undef:s lenn_to_cpu

 tools/prelink-riscv.c   |  5 +----
 tools/prelink-riscv.inc | 42 +++++++++++++++++++++--------------------
 2 files changed, 23 insertions(+), 24 deletions(-)

diff --git a/tools/prelink-riscv.c b/tools/prelink-riscv.c
index 52eb78e9d0..a900a1497a 100644
--- a/tools/prelink-riscv.c
+++ b/tools/prelink-riscv.c
@@ -8,10 +8,6 @@
  * without fixup. Both RV32 and RV64 are supported.
  */
 
-#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__
-#error "Only little-endian host is supported"
-#endif
-
 #include <errno.h>
 #include <stdbool.h>
 #include <stdint.h>
@@ -25,6 +21,7 @@
 #include <sys/stat.h>
 #include <sys/types.h>
 #include <unistd.h>
+#include <compiler.h>
 
 #ifndef EM_RISCV
 #define EM_RISCV 243
diff --git a/tools/prelink-riscv.inc b/tools/prelink-riscv.inc
index d49258707d..86ce1aa93f 100644
--- a/tools/prelink-riscv.inc
+++ b/tools/prelink-riscv.inc
@@ -23,14 +23,15 @@
 #define Elf_Addr        CONCAT3(Elf, PRELINK_INC_BITS, _Addr)
 #define ELF_R_TYPE      CONCAT3(ELF, PRELINK_INC_BITS, _R_TYPE)
 #define ELF_R_SYM       CONCAT3(ELF, PRELINK_INC_BITS, _R_SYM)
+#define lenn_to_cpu     CONCAT3(le, PRELINK_INC_BITS, _to_cpu)
 
 static void* get_offset_nn (void* data, Elf_Phdr* phdrs, size_t phnum, Elf_Addr addr)
 {
 	Elf_Phdr *p;
 
 	for (p = phdrs; p < phdrs + phnum; ++p)
-		if (p->p_vaddr <= addr && p->p_vaddr + p->p_memsz > addr)
-			return data + p->p_offset + (addr - p->p_vaddr);
+		if (lenn_to_cpu(p->p_vaddr) <= addr && lenn_to_cpu(p->p_vaddr) + lenn_to_cpu(p->p_memsz) > addr)
+			return data + lenn_to_cpu(p->p_offset) + (addr - lenn_to_cpu(p->p_vaddr));
 
 	return NULL;
 }
@@ -42,15 +43,15 @@ static void prelink_nn(void *data)
 	Elf_Dyn *dyn;
 	Elf_Rela *r;
 
-	if (ehdr->e_machine != EM_RISCV)
+	if (le16_to_cpu(ehdr->e_machine) != EM_RISCV)
 		die("Machine type is not RISC-V");
 
-	Elf_Phdr *phdrs = data + ehdr->e_phoff;
+	Elf_Phdr *phdrs = data + lenn_to_cpu(ehdr->e_phoff);
 
 	Elf_Dyn *dyns = NULL;
-	for (p = phdrs; p < phdrs + ehdr->e_phnum; ++p) {
-		if (p->p_type == PT_DYNAMIC) {
-			dyns = data + p->p_offset;
+	for (p = phdrs; p < phdrs + le16_to_cpu(ehdr->e_phnum); ++p) {
+		if (le32_to_cpu(p->p_type) == PT_DYNAMIC) {
+			dyns = data + lenn_to_cpu(p->p_offset);
 			break;
 		}
 	}
@@ -62,14 +63,14 @@ static void prelink_nn(void *data)
 	size_t rela_count = 0;
 	Elf_Sym *dynsym = NULL;
 	for (dyn = dyns;; ++dyn) {
-		if (dyn->d_tag == DT_NULL)
+		if (lenn_to_cpu(dyn->d_tag) == DT_NULL)
 			break;
-		else if (dyn->d_tag == DT_RELA)
-			rela_dyn = get_offset_nn(data, phdrs, ehdr->e_phnum, + dyn->d_un.d_ptr);
-		else if (dyn->d_tag == DT_RELASZ)
-			rela_count = dyn->d_un.d_val / sizeof(Elf_Rela);
-		else if (dyn->d_tag == DT_SYMTAB)
-			dynsym = get_offset_nn(data, phdrs, ehdr->e_phnum, + dyn->d_un.d_ptr);
+		else if (lenn_to_cpu(dyn->d_tag) == DT_RELA)
+			rela_dyn = get_offset_nn(data, phdrs, le16_to_cpu(ehdr->e_phnum), + lenn_to_cpu(dyn->d_un.d_ptr));
+		else if (lenn_to_cpu(dyn->d_tag) == DT_RELASZ)
+		  rela_count = lenn_to_cpu(dyn->d_un.d_val) / sizeof(Elf_Rela);
+		else if (lenn_to_cpu(dyn->d_tag) == DT_SYMTAB)
+			dynsym = get_offset_nn(data, phdrs, le16_to_cpu(ehdr->e_phnum), + lenn_to_cpu(dyn->d_un.d_ptr));
 
 	}
 
@@ -80,17 +81,17 @@ static void prelink_nn(void *data)
 		die("No .dynsym found");
 
 	for (r = rela_dyn; r < rela_dyn + rela_count; ++r) {
-		void* buf = get_offset_nn(data, phdrs, ehdr->e_phnum, r->r_offset);
+		void* buf = get_offset_nn(data, phdrs, le16_to_cpu(ehdr->e_phnum), lenn_to_cpu(r->r_offset));
 
 		if (buf == NULL)
 			continue;
 
-		if (ELF_R_TYPE(r->r_info) == R_RISCV_RELATIVE)
+		if (ELF_R_TYPE(lenn_to_cpu(r->r_info)) == R_RISCV_RELATIVE)
 			*((uintnn_t*) buf) = r->r_addend;
-		else if (ELF_R_TYPE(r->r_info) == R_RISCV_32)
-			*((uint32_t*) buf) = dynsym[ELF_R_SYM(r->r_info)].st_value;
-		else if (ELF_R_TYPE(r->r_info) == R_RISCV_64)
-			*((uint64_t*) buf) = dynsym[ELF_R_SYM(r->r_info)].st_value;
+		else if (ELF_R_TYPE(lenn_to_cpu(r->r_info)) == R_RISCV_32)
+			*((uint32_t*) buf) = dynsym[ELF_R_SYM(lenn_to_cpu(r->r_info))].st_value;
+		else if (ELF_R_TYPE(lenn_to_cpu(r->r_info)) == R_RISCV_64)
+			*((uint64_t*) buf) = dynsym[ELF_R_SYM(lenn_to_cpu(r->r_info))].st_value;
 	}
 }
 
@@ -105,6 +106,7 @@ static void prelink_nn(void *data)
 #undef Elf_Addr
 #undef ELF_R_TYPE
 #undef ELF_R_SYM
+#undef lenn_to_cpu
 
 #undef CONCAT_IMPL
 #undef CONCAT
-- 
2.21.0

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH v2 2/2] riscv: tools: Add big endian target support to prelink-riscv
  2019-08-02 17:45 [U-Boot] [PATCH v2 1/2] riscv: tools: Fix prelink-riscv to work on big endian hosts Marcus Comstedt
@ 2019-08-02 17:45 ` Marcus Comstedt
       [not found]   ` <752D002CFF5D0F4FA35C0100F1D73F3FA40FA9E8@ATCPCS16.andestech.com>
       [not found] ` <752D002CFF5D0F4FA35C0100F1D73F3FA40FA9DF@ATCPCS16.andestech.com>
  1 sibling, 1 reply; 6+ messages in thread
From: Marcus Comstedt @ 2019-08-02 17:45 UTC (permalink / raw)
  To: u-boot

Signed-off-by: Marcus Comstedt <marcus@mc.pp.se>
Cc: Rick Chen <rick@andestech.com>
---
Changes for v2:
   - Added

 tools/prelink-riscv.c   | 34 ++++++++++++++++++----
 tools/prelink-riscv.inc | 62 ++++++++++++++++++++++-------------------
 2 files changed, 63 insertions(+), 33 deletions(-)

diff --git a/tools/prelink-riscv.c b/tools/prelink-riscv.c
index a900a1497a..b0467949eb 100644
--- a/tools/prelink-riscv.c
+++ b/tools/prelink-riscv.c
@@ -47,12 +47,28 @@ const char *argv0;
 		exit(EXIT_FAILURE); \
 	} while (0)
 
+#define PRELINK_BYTEORDER le
 #define PRELINK_INC_BITS 32
 #include "prelink-riscv.inc"
+#undef PRELINK_BYTEORDER
 #undef PRELINK_INC_BITS
 
+#define PRELINK_BYTEORDER le
 #define PRELINK_INC_BITS 64
 #include "prelink-riscv.inc"
+#undef PRELINK_BYTEORDER
+#undef PRELINK_INC_BITS
+
+#define PRELINK_BYTEORDER be
+#define PRELINK_INC_BITS 32
+#include "prelink-riscv.inc"
+#undef PRELINK_BYTEORDER
+#undef PRELINK_INC_BITS
+
+#define PRELINK_BYTEORDER be
+#define PRELINK_INC_BITS 64
+#include "prelink-riscv.inc"
+#undef PRELINK_BYTEORDER
 #undef PRELINK_INC_BITS
 
 int main(int argc, const char *const *argv)
@@ -88,11 +104,19 @@ int main(int argc, const char *const *argv)
 		die("Invalid ELF file %s", argv[1]);
 
 	bool is64 = e_ident[EI_CLASS] == ELFCLASS64;
-
-	if (is64)
-		prelink64(data);
-	else
-		prelink32(data);
+	bool isbe = e_ident[EI_DATA] == ELFDATA2MSB;
+
+	if (is64) {
+		if (isbe)
+			prelink_be64(data);
+		else
+			prelink_le64(data);
+	} else {
+		if (isbe)
+			prelink_be32(data);
+		else
+			prelink_le32(data);
+	}
 
 	return 0;
 }
diff --git a/tools/prelink-riscv.inc b/tools/prelink-riscv.inc
index 86ce1aa93f..8b40ec430a 100644
--- a/tools/prelink-riscv.inc
+++ b/tools/prelink-riscv.inc
@@ -12,9 +12,9 @@
 #define CONCAT(x, y) CONCAT_IMPL(x, y)
 #define CONCAT3(x, y, z) CONCAT(CONCAT(x, y), z)
 
-#define prelink_nn      CONCAT(prelink, PRELINK_INC_BITS)
+#define prelink_bonn    CONCAT3(prelink_, PRELINK_BYTEORDER, PRELINK_INC_BITS)
 #define uintnn_t        CONCAT3(uint, PRELINK_INC_BITS, _t)
-#define get_offset_nn   CONCAT(get_offset_, PRELINK_INC_BITS)
+#define get_offset_bonn CONCAT3(get_offset_, PRELINK_BYTEORDER, PRELINK_INC_BITS)
 #define Elf_Ehdr        CONCAT3(Elf, PRELINK_INC_BITS, _Ehdr)
 #define Elf_Phdr        CONCAT3(Elf, PRELINK_INC_BITS, _Phdr)
 #define Elf_Rela        CONCAT3(Elf, PRELINK_INC_BITS, _Rela)
@@ -23,35 +23,38 @@
 #define Elf_Addr        CONCAT3(Elf, PRELINK_INC_BITS, _Addr)
 #define ELF_R_TYPE      CONCAT3(ELF, PRELINK_INC_BITS, _R_TYPE)
 #define ELF_R_SYM       CONCAT3(ELF, PRELINK_INC_BITS, _R_SYM)
-#define lenn_to_cpu     CONCAT3(le, PRELINK_INC_BITS, _to_cpu)
+#define target16_to_cpu CONCAT(PRELINK_BYTEORDER, 16_to_cpu)
+#define target32_to_cpu CONCAT(PRELINK_BYTEORDER, 32_to_cpu)
+#define target64_to_cpu CONCAT(PRELINK_BYTEORDER, 64_to_cpu)
+#define targetnn_to_cpu CONCAT3(PRELINK_BYTEORDER, PRELINK_INC_BITS, _to_cpu)
 
-static void* get_offset_nn (void* data, Elf_Phdr* phdrs, size_t phnum, Elf_Addr addr)
+static void* get_offset_bonn (void* data, Elf_Phdr* phdrs, size_t phnum, Elf_Addr addr)
 {
 	Elf_Phdr *p;
 
 	for (p = phdrs; p < phdrs + phnum; ++p)
-		if (lenn_to_cpu(p->p_vaddr) <= addr && lenn_to_cpu(p->p_vaddr) + lenn_to_cpu(p->p_memsz) > addr)
-			return data + lenn_to_cpu(p->p_offset) + (addr - lenn_to_cpu(p->p_vaddr));
+		if (targetnn_to_cpu(p->p_vaddr) <= addr && targetnn_to_cpu(p->p_vaddr) + targetnn_to_cpu(p->p_memsz) > addr)
+			return data + targetnn_to_cpu(p->p_offset) + (addr - targetnn_to_cpu(p->p_vaddr));
 
 	return NULL;
 }
 
-static void prelink_nn(void *data)
+static void prelink_bonn(void *data)
 {
 	Elf_Ehdr *ehdr = data;
 	Elf_Phdr *p;
 	Elf_Dyn *dyn;
 	Elf_Rela *r;
 
-	if (le16_to_cpu(ehdr->e_machine) != EM_RISCV)
+	if (target16_to_cpu(ehdr->e_machine) != EM_RISCV)
 		die("Machine type is not RISC-V");
 
-	Elf_Phdr *phdrs = data + lenn_to_cpu(ehdr->e_phoff);
+	Elf_Phdr *phdrs = data + targetnn_to_cpu(ehdr->e_phoff);
 
 	Elf_Dyn *dyns = NULL;
-	for (p = phdrs; p < phdrs + le16_to_cpu(ehdr->e_phnum); ++p) {
-		if (le32_to_cpu(p->p_type) == PT_DYNAMIC) {
-			dyns = data + lenn_to_cpu(p->p_offset);
+	for (p = phdrs; p < phdrs + target16_to_cpu(ehdr->e_phnum); ++p) {
+		if (target32_to_cpu(p->p_type) == PT_DYNAMIC) {
+			dyns = data + targetnn_to_cpu(p->p_offset);
 			break;
 		}
 	}
@@ -63,14 +66,14 @@ static void prelink_nn(void *data)
 	size_t rela_count = 0;
 	Elf_Sym *dynsym = NULL;
 	for (dyn = dyns;; ++dyn) {
-		if (lenn_to_cpu(dyn->d_tag) == DT_NULL)
+		if (targetnn_to_cpu(dyn->d_tag) == DT_NULL)
 			break;
-		else if (lenn_to_cpu(dyn->d_tag) == DT_RELA)
-			rela_dyn = get_offset_nn(data, phdrs, le16_to_cpu(ehdr->e_phnum), + lenn_to_cpu(dyn->d_un.d_ptr));
-		else if (lenn_to_cpu(dyn->d_tag) == DT_RELASZ)
-		  rela_count = lenn_to_cpu(dyn->d_un.d_val) / sizeof(Elf_Rela);
-		else if (lenn_to_cpu(dyn->d_tag) == DT_SYMTAB)
-			dynsym = get_offset_nn(data, phdrs, le16_to_cpu(ehdr->e_phnum), + lenn_to_cpu(dyn->d_un.d_ptr));
+		else if (targetnn_to_cpu(dyn->d_tag) == DT_RELA)
+			rela_dyn = get_offset_bonn(data, phdrs, target16_to_cpu(ehdr->e_phnum), + targetnn_to_cpu(dyn->d_un.d_ptr));
+		else if (targetnn_to_cpu(dyn->d_tag) == DT_RELASZ)
+		  rela_count = targetnn_to_cpu(dyn->d_un.d_val) / sizeof(Elf_Rela);
+		else if (targetnn_to_cpu(dyn->d_tag) == DT_SYMTAB)
+			dynsym = get_offset_bonn(data, phdrs, target16_to_cpu(ehdr->e_phnum), + targetnn_to_cpu(dyn->d_un.d_ptr));
 
 	}
 
@@ -81,23 +84,23 @@ static void prelink_nn(void *data)
 		die("No .dynsym found");
 
 	for (r = rela_dyn; r < rela_dyn + rela_count; ++r) {
-		void* buf = get_offset_nn(data, phdrs, le16_to_cpu(ehdr->e_phnum), lenn_to_cpu(r->r_offset));
+		void* buf = get_offset_bonn(data, phdrs, target16_to_cpu(ehdr->e_phnum), targetnn_to_cpu(r->r_offset));
 
 		if (buf == NULL)
 			continue;
 
-		if (ELF_R_TYPE(lenn_to_cpu(r->r_info)) == R_RISCV_RELATIVE)
+		if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_RELATIVE)
 			*((uintnn_t*) buf) = r->r_addend;
-		else if (ELF_R_TYPE(lenn_to_cpu(r->r_info)) == R_RISCV_32)
-			*((uint32_t*) buf) = dynsym[ELF_R_SYM(lenn_to_cpu(r->r_info))].st_value;
-		else if (ELF_R_TYPE(lenn_to_cpu(r->r_info)) == R_RISCV_64)
-			*((uint64_t*) buf) = dynsym[ELF_R_SYM(lenn_to_cpu(r->r_info))].st_value;
+		else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_32)
+			*((uint32_t*) buf) = dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value;
+		else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_64)
+			*((uint64_t*) buf) = dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value;
 	}
 }
 
-#undef prelink_nn
+#undef prelink_bonn
 #undef uintnn_t
-#undef get_offset_nn
+#undef get_offset_bonn
 #undef Elf_Ehdr
 #undef Elf_Phdr
 #undef Elf_Rela
@@ -106,7 +109,10 @@ static void prelink_nn(void *data)
 #undef Elf_Addr
 #undef ELF_R_TYPE
 #undef ELF_R_SYM
-#undef lenn_to_cpu
+#undef target16_to_cpu
+#undef target32_to_cpu
+#undef target64_to_cpu
+#undef targetnn_to_cpu
 
 #undef CONCAT_IMPL
 #undef CONCAT
-- 
2.21.0

^ permalink raw reply related	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH v2 1/2] riscv: tools: Fix prelink-riscv to work on big endian hosts
       [not found] ` <752D002CFF5D0F4FA35C0100F1D73F3FA40FA9DF@ATCPCS16.andestech.com>
@ 2019-08-07  8:44   ` Rick Chen
  0 siblings, 0 replies; 6+ messages in thread
From: Rick Chen @ 2019-08-07  8:44 UTC (permalink / raw)
  To: u-boot

> > From: Marcus Comstedt [mailto:marcus at mc.pp.se]
> > Sent: Saturday, August 03, 2019 1:45 AM
> > To: u-boot at lists.denx.de
> > Cc: Marcus Comstedt; Rick Jian-Zhi Chen(陳建志)
> > Subject: [PATCH v2 1/2] riscv: tools: Fix prelink-riscv to work on big endian
> > hosts
> >
> > All ELF fields whose values are inspected by the code are converted to CPU
> > byteorder first.  Values which are copied verbatim (relocation
> > fixups) are not swapped to CPU byteorder and back as it is not needed.
> >
> > Signed-off-by: Marcus Comstedt <marcus@mc.pp.se>
> > Cc: Rick Chen <rick@andestech.com>

Reviewed-by: Rick Chen <rick@andestech.com>

> > ---
> > Changes for v2:
> >    - Now #undef:s lenn_to_cpu
> >
> >  tools/prelink-riscv.c   |  5 +----
> >  tools/prelink-riscv.inc | 42 +++++++++++++++++++++--------------------
> >  2 files changed, 23 insertions(+), 24 deletions(-)
> >
> > diff --git a/tools/prelink-riscv.c b/tools/prelink-riscv.c index
> > 52eb78e9d0..a900a1497a 100644
> > --- a/tools/prelink-riscv.c
> > +++ b/tools/prelink-riscv.c
> > @@ -8,10 +8,6 @@
> >   * without fixup. Both RV32 and RV64 are supported.
> >   */
> >
> > -#if __BYTE_ORDER__ != __ORDER_LITTLE_ENDIAN__ -#error "Only
> > little-endian host is supported"
> > -#endif
> > -
> >  #include <errno.h>
> >  #include <stdbool.h>
> >  #include <stdint.h>
> > @@ -25,6 +21,7 @@
> >  #include <sys/stat.h>
> >  #include <sys/types.h>
> >  #include <unistd.h>
> > +#include <compiler.h>
> >
> >  #ifndef EM_RISCV
> >  #define EM_RISCV 243
> > diff --git a/tools/prelink-riscv.inc b/tools/prelink-riscv.inc index
> > d49258707d..86ce1aa93f 100644
> > --- a/tools/prelink-riscv.inc
> > +++ b/tools/prelink-riscv.inc
> > @@ -23,14 +23,15 @@
> >  #define Elf_Addr        CONCAT3(Elf, PRELINK_INC_BITS, _Addr)
> >  #define ELF_R_TYPE      CONCAT3(ELF, PRELINK_INC_BITS, _R_TYPE)
> >  #define ELF_R_SYM       CONCAT3(ELF, PRELINK_INC_BITS, _R_SYM)
> > +#define lenn_to_cpu     CONCAT3(le, PRELINK_INC_BITS, _to_cpu)
> >
> >  static void* get_offset_nn (void* data, Elf_Phdr* phdrs, size_t phnum,
> > Elf_Addr addr)  {
> >       Elf_Phdr *p;
> >
> >       for (p = phdrs; p < phdrs + phnum; ++p)
> > -             if (p->p_vaddr <= addr && p->p_vaddr + p->p_memsz > addr)
> > -                     return data + p->p_offset + (addr - p->p_vaddr);
> > +             if (lenn_to_cpu(p->p_vaddr) <= addr && lenn_to_cpu(p->p_vaddr) +
> > lenn_to_cpu(p->p_memsz) > addr)
> > +                     return data + lenn_to_cpu(p->p_offset) + (addr -
> > +lenn_to_cpu(p->p_vaddr));
> >
> >       return NULL;
> >  }
> > @@ -42,15 +43,15 @@ static void prelink_nn(void *data)
> >       Elf_Dyn *dyn;
> >       Elf_Rela *r;
> >
> > -     if (ehdr->e_machine != EM_RISCV)
> > +     if (le16_to_cpu(ehdr->e_machine) != EM_RISCV)
> >               die("Machine type is not RISC-V");
> >
> > -     Elf_Phdr *phdrs = data + ehdr->e_phoff;
> > +     Elf_Phdr *phdrs = data + lenn_to_cpu(ehdr->e_phoff);
> >
> >       Elf_Dyn *dyns = NULL;
> > -     for (p = phdrs; p < phdrs + ehdr->e_phnum; ++p) {
> > -             if (p->p_type == PT_DYNAMIC) {
> > -                     dyns = data + p->p_offset;
> > +     for (p = phdrs; p < phdrs + le16_to_cpu(ehdr->e_phnum); ++p) {
> > +             if (le32_to_cpu(p->p_type) == PT_DYNAMIC) {
> > +                     dyns = data + lenn_to_cpu(p->p_offset);
> >                       break;
> >               }
> >       }
> > @@ -62,14 +63,14 @@ static void prelink_nn(void *data)
> >       size_t rela_count = 0;
> >       Elf_Sym *dynsym = NULL;
> >       for (dyn = dyns;; ++dyn) {
> > -             if (dyn->d_tag == DT_NULL)
> > +             if (lenn_to_cpu(dyn->d_tag) == DT_NULL)
> >                       break;
> > -             else if (dyn->d_tag == DT_RELA)
> > -                     rela_dyn = get_offset_nn(data, phdrs, ehdr->e_phnum, +
> > dyn->d_un.d_ptr);
> > -             else if (dyn->d_tag == DT_RELASZ)
> > -                     rela_count = dyn->d_un.d_val / sizeof(Elf_Rela);
> > -             else if (dyn->d_tag == DT_SYMTAB)
> > -                     dynsym = get_offset_nn(data, phdrs, ehdr->e_phnum, +
> > dyn->d_un.d_ptr);
> > +             else if (lenn_to_cpu(dyn->d_tag) == DT_RELA)
> > +                     rela_dyn = get_offset_nn(data, phdrs,
> > le16_to_cpu(ehdr->e_phnum), + lenn_to_cpu(dyn->d_un.d_ptr));
> > +             else if (lenn_to_cpu(dyn->d_tag) == DT_RELASZ)
> > +               rela_count = lenn_to_cpu(dyn->d_un.d_val) / sizeof(Elf_Rela);
> > +             else if (lenn_to_cpu(dyn->d_tag) == DT_SYMTAB)
> > +                     dynsym = get_offset_nn(data, phdrs,
> > le16_to_cpu(ehdr->e_phnum), +
> > +lenn_to_cpu(dyn->d_un.d_ptr));
> >
> >       }
> >
> > @@ -80,17 +81,17 @@ static void prelink_nn(void *data)
> >               die("No .dynsym found");
> >
> >       for (r = rela_dyn; r < rela_dyn + rela_count; ++r) {
> > -             void* buf = get_offset_nn(data, phdrs, ehdr->e_phnum, r->r_offset);
> > +             void* buf = get_offset_nn(data, phdrs,
> > le16_to_cpu(ehdr->e_phnum),
> > +lenn_to_cpu(r->r_offset));
> >
> >               if (buf == NULL)
> >                       continue;
> >
> > -             if (ELF_R_TYPE(r->r_info) == R_RISCV_RELATIVE)
> > +             if (ELF_R_TYPE(lenn_to_cpu(r->r_info)) == R_RISCV_RELATIVE)
> >                       *((uintnn_t*) buf) = r->r_addend;
> > -             else if (ELF_R_TYPE(r->r_info) == R_RISCV_32)
> > -                     *((uint32_t*) buf) = dynsym[ELF_R_SYM(r->r_info)].st_value;
> > -             else if (ELF_R_TYPE(r->r_info) == R_RISCV_64)
> > -                     *((uint64_t*) buf) = dynsym[ELF_R_SYM(r->r_info)].st_value;
> > +             else if (ELF_R_TYPE(lenn_to_cpu(r->r_info)) == R_RISCV_32)
> > +                     *((uint32_t*) buf) =
> > dynsym[ELF_R_SYM(lenn_to_cpu(r->r_info))].st_value;
> > +             else if (ELF_R_TYPE(lenn_to_cpu(r->r_info)) == R_RISCV_64)
> > +                     *((uint64_t*) buf) =
> > +dynsym[ELF_R_SYM(lenn_to_cpu(r->r_info))].st_value;
> >       }
> >  }
> >
> > @@ -105,6 +106,7 @@ static void prelink_nn(void *data)  #undef Elf_Addr
> > #undef ELF_R_TYPE  #undef ELF_R_SYM
> > +#undef lenn_to_cpu
> >
> >  #undef CONCAT_IMPL
> >  #undef CONCAT
> > --
> > 2.21.0
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH v2 2/2] riscv: tools: Add big endian target support to prelink-riscv
       [not found]   ` <752D002CFF5D0F4FA35C0100F1D73F3FA40FA9E8@ATCPCS16.andestech.com>
@ 2019-08-07  8:49     ` Rick Chen
  2019-08-07 20:36       ` Marcus Comstedt
  0 siblings, 1 reply; 6+ messages in thread
From: Rick Chen @ 2019-08-07  8:49 UTC (permalink / raw)
  To: u-boot

Hi Marcus

> > From: Marcus Comstedt [mailto:marcus at mc.pp.se]
> > Sent: Saturday, August 03, 2019 1:45 AM
> > To: u-boot at lists.denx.de
> > Cc: Marcus Comstedt; Rick Jian-Zhi Chen(陳建志)
> > Subject: [PATCH v2 2/2] riscv: tools: Add big endian target support to
> > prelink-riscv
> >
> > Signed-off-by: Marcus Comstedt <marcus@mc.pp.se>
> > Cc: Rick Chen <rick@andestech.com>
> > ---
> > Changes for v2:
> >    - Added
> >
> >  tools/prelink-riscv.c   | 34 ++++++++++++++++++----
> >  tools/prelink-riscv.inc | 62 ++++++++++++++++++++++-------------------
> >  2 files changed, 63 insertions(+), 33 deletions(-)
> >

Thanks for your efforts about the support for big endian ELFs.
But I don't have big endian toolchain to verify.
I verify 32le and 64le, both are ok.

Reviewed-by: Rick Chen <rick@andestech.com>

> > diff --git a/tools/prelink-riscv.c b/tools/prelink-riscv.c index
> > a900a1497a..b0467949eb 100644
> > --- a/tools/prelink-riscv.c
> > +++ b/tools/prelink-riscv.c
> > @@ -47,12 +47,28 @@ const char *argv0;
> >               exit(EXIT_FAILURE); \
> >       } while (0)
> >
> > +#define PRELINK_BYTEORDER le
> >  #define PRELINK_INC_BITS 32
> >  #include "prelink-riscv.inc"
> > +#undef PRELINK_BYTEORDER
> >  #undef PRELINK_INC_BITS
> >
> > +#define PRELINK_BYTEORDER le
> >  #define PRELINK_INC_BITS 64
> >  #include "prelink-riscv.inc"
> > +#undef PRELINK_BYTEORDER
> > +#undef PRELINK_INC_BITS
> > +
> > +#define PRELINK_BYTEORDER be
> > +#define PRELINK_INC_BITS 32
> > +#include "prelink-riscv.inc"
> > +#undef PRELINK_BYTEORDER
> > +#undef PRELINK_INC_BITS
> > +
> > +#define PRELINK_BYTEORDER be
> > +#define PRELINK_INC_BITS 64
> > +#include "prelink-riscv.inc"
> > +#undef PRELINK_BYTEORDER
> >  #undef PRELINK_INC_BITS
> >
> >  int main(int argc, const char *const *argv) @@ -88,11 +104,19 @@ int
> > main(int argc, const char *const *argv)
> >               die("Invalid ELF file %s", argv[1]);
> >
> >       bool is64 = e_ident[EI_CLASS] == ELFCLASS64;
> > -
> > -     if (is64)
> > -             prelink64(data);
> > -     else
> > -             prelink32(data);
> > +     bool isbe = e_ident[EI_DATA] == ELFDATA2MSB;
> > +
> > +     if (is64) {
> > +             if (isbe)
> > +                     prelink_be64(data);
> > +             else
> > +                     prelink_le64(data);
> > +     } else {
> > +             if (isbe)
> > +                     prelink_be32(data);
> > +             else
> > +                     prelink_le32(data);
> > +     }
> >
> >       return 0;
> >  }
> > diff --git a/tools/prelink-riscv.inc b/tools/prelink-riscv.inc index
> > 86ce1aa93f..8b40ec430a 100644
> > --- a/tools/prelink-riscv.inc
> > +++ b/tools/prelink-riscv.inc
> > @@ -12,9 +12,9 @@
> >  #define CONCAT(x, y) CONCAT_IMPL(x, y)
> >  #define CONCAT3(x, y, z) CONCAT(CONCAT(x, y), z)
> >
> > -#define prelink_nn      CONCAT(prelink, PRELINK_INC_BITS)
> > +#define prelink_bonn    CONCAT3(prelink_, PRELINK_BYTEORDER,
> > PRELINK_INC_BITS)
> >  #define uintnn_t        CONCAT3(uint, PRELINK_INC_BITS, _t)
> > -#define get_offset_nn   CONCAT(get_offset_, PRELINK_INC_BITS)
> > +#define get_offset_bonn CONCAT3(get_offset_, PRELINK_BYTEORDER,
> > +PRELINK_INC_BITS)
> >  #define Elf_Ehdr        CONCAT3(Elf, PRELINK_INC_BITS, _Ehdr)
> >  #define Elf_Phdr        CONCAT3(Elf, PRELINK_INC_BITS, _Phdr)
> >  #define Elf_Rela        CONCAT3(Elf, PRELINK_INC_BITS, _Rela)
> > @@ -23,35 +23,38 @@
> >  #define Elf_Addr        CONCAT3(Elf, PRELINK_INC_BITS, _Addr)
> >  #define ELF_R_TYPE      CONCAT3(ELF, PRELINK_INC_BITS, _R_TYPE)
> >  #define ELF_R_SYM       CONCAT3(ELF, PRELINK_INC_BITS, _R_SYM)
> > -#define lenn_to_cpu     CONCAT3(le, PRELINK_INC_BITS, _to_cpu)
> > +#define target16_to_cpu CONCAT(PRELINK_BYTEORDER, 16_to_cpu) #define
> > +target32_to_cpu CONCAT(PRELINK_BYTEORDER, 32_to_cpu) #define
> > +target64_to_cpu CONCAT(PRELINK_BYTEORDER, 64_to_cpu) #define
> > +targetnn_to_cpu CONCAT3(PRELINK_BYTEORDER, PRELINK_INC_BITS,
> > _to_cpu)
> >
> > -static void* get_offset_nn (void* data, Elf_Phdr* phdrs, size_t phnum,
> > Elf_Addr addr)
> > +static void* get_offset_bonn (void* data, Elf_Phdr* phdrs, size_t
> > +phnum, Elf_Addr addr)
> >  {
> >       Elf_Phdr *p;
> >
> >       for (p = phdrs; p < phdrs + phnum; ++p)
> > -             if (lenn_to_cpu(p->p_vaddr) <= addr && lenn_to_cpu(p->p_vaddr) +
> > lenn_to_cpu(p->p_memsz) > addr)
> > -                     return data + lenn_to_cpu(p->p_offset) + (addr -
> > lenn_to_cpu(p->p_vaddr));
> > +             if (targetnn_to_cpu(p->p_vaddr) <= addr &&
> > targetnn_to_cpu(p->p_vaddr) + targetnn_to_cpu(p->p_memsz) > addr)
> > +                     return data + targetnn_to_cpu(p->p_offset) + (addr -
> > +targetnn_to_cpu(p->p_vaddr));
> >
> >       return NULL;
> >  }
> >
> > -static void prelink_nn(void *data)
> > +static void prelink_bonn(void *data)
> >  {
> >       Elf_Ehdr *ehdr = data;
> >       Elf_Phdr *p;
> >       Elf_Dyn *dyn;
> >       Elf_Rela *r;
> >
> > -     if (le16_to_cpu(ehdr->e_machine) != EM_RISCV)
> > +     if (target16_to_cpu(ehdr->e_machine) != EM_RISCV)
> >               die("Machine type is not RISC-V");
> >
> > -     Elf_Phdr *phdrs = data + lenn_to_cpu(ehdr->e_phoff);
> > +     Elf_Phdr *phdrs = data + targetnn_to_cpu(ehdr->e_phoff);
> >
> >       Elf_Dyn *dyns = NULL;
> > -     for (p = phdrs; p < phdrs + le16_to_cpu(ehdr->e_phnum); ++p) {
> > -             if (le32_to_cpu(p->p_type) == PT_DYNAMIC) {
> > -                     dyns = data + lenn_to_cpu(p->p_offset);
> > +     for (p = phdrs; p < phdrs + target16_to_cpu(ehdr->e_phnum); ++p) {
> > +             if (target32_to_cpu(p->p_type) == PT_DYNAMIC) {
> > +                     dyns = data + targetnn_to_cpu(p->p_offset);
> >                       break;
> >               }
> >       }
> > @@ -63,14 +66,14 @@ static void prelink_nn(void *data)
> >       size_t rela_count = 0;
> >       Elf_Sym *dynsym = NULL;
> >       for (dyn = dyns;; ++dyn) {
> > -             if (lenn_to_cpu(dyn->d_tag) == DT_NULL)
> > +             if (targetnn_to_cpu(dyn->d_tag) == DT_NULL)
> >                       break;
> > -             else if (lenn_to_cpu(dyn->d_tag) == DT_RELA)
> > -                     rela_dyn = get_offset_nn(data, phdrs,
> > le16_to_cpu(ehdr->e_phnum), + lenn_to_cpu(dyn->d_un.d_ptr));
> > -             else if (lenn_to_cpu(dyn->d_tag) == DT_RELASZ)
> > -               rela_count = lenn_to_cpu(dyn->d_un.d_val) / sizeof(Elf_Rela);
> > -             else if (lenn_to_cpu(dyn->d_tag) == DT_SYMTAB)
> > -                     dynsym = get_offset_nn(data, phdrs,
> > le16_to_cpu(ehdr->e_phnum), + lenn_to_cpu(dyn->d_un.d_ptr));
> > +             else if (targetnn_to_cpu(dyn->d_tag) == DT_RELA)
> > +                     rela_dyn = get_offset_bonn(data, phdrs,
> > target16_to_cpu(ehdr->e_phnum), + targetnn_to_cpu(dyn->d_un.d_ptr));
> > +             else if (targetnn_to_cpu(dyn->d_tag) == DT_RELASZ)
> > +               rela_count = targetnn_to_cpu(dyn->d_un.d_val) /
> > sizeof(Elf_Rela);
> > +             else if (targetnn_to_cpu(dyn->d_tag) == DT_SYMTAB)
> > +                     dynsym = get_offset_bonn(data, phdrs,
> > +target16_to_cpu(ehdr->e_phnum), + targetnn_to_cpu(dyn->d_un.d_ptr));
> >
> >       }
> >
> > @@ -81,23 +84,23 @@ static void prelink_nn(void *data)
> >               die("No .dynsym found");
> >
> >       for (r = rela_dyn; r < rela_dyn + rela_count; ++r) {
> > -             void* buf = get_offset_nn(data, phdrs,
> > le16_to_cpu(ehdr->e_phnum), lenn_to_cpu(r->r_offset));
> > +             void* buf = get_offset_bonn(data, phdrs,
> > +target16_to_cpu(ehdr->e_phnum), targetnn_to_cpu(r->r_offset));
> >
> >               if (buf == NULL)
> >                       continue;
> >
> > -             if (ELF_R_TYPE(lenn_to_cpu(r->r_info)) == R_RISCV_RELATIVE)
> > +             if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_RELATIVE)
> >                       *((uintnn_t*) buf) = r->r_addend;
> > -             else if (ELF_R_TYPE(lenn_to_cpu(r->r_info)) == R_RISCV_32)
> > -                     *((uint32_t*) buf) =
> > dynsym[ELF_R_SYM(lenn_to_cpu(r->r_info))].st_value;
> > -             else if (ELF_R_TYPE(lenn_to_cpu(r->r_info)) == R_RISCV_64)
> > -                     *((uint64_t*) buf) =
> > dynsym[ELF_R_SYM(lenn_to_cpu(r->r_info))].st_value;
> > +             else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_32)
> > +                     *((uint32_t*) buf) =
> > dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value;
> > +             else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_64)
> > +                     *((uint64_t*) buf) =
> > +dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value;
> >       }
> >  }
> >
> > -#undef prelink_nn
> > +#undef prelink_bonn
> >  #undef uintnn_t
> > -#undef get_offset_nn
> > +#undef get_offset_bonn
> >  #undef Elf_Ehdr
> >  #undef Elf_Phdr
> >  #undef Elf_Rela
> > @@ -106,7 +109,10 @@ static void prelink_nn(void *data)  #undef Elf_Addr
> > #undef ELF_R_TYPE  #undef ELF_R_SYM -#undef lenn_to_cpu
> > +#undef target16_to_cpu
> > +#undef target32_to_cpu
> > +#undef target64_to_cpu
> > +#undef targetnn_to_cpu
> >
> >  #undef CONCAT_IMPL
> >  #undef CONCAT
> > --
> > 2.21.0
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH v2 2/2] riscv: tools: Add big endian target support to prelink-riscv
  2019-08-07  8:49     ` Rick Chen
@ 2019-08-07 20:36       ` Marcus Comstedt
       [not found]         ` <752D002CFF5D0F4FA35C0100F1D73F3FA40FAF35@ATCPCS16.andestech.com>
  0 siblings, 1 reply; 6+ messages in thread
From: Marcus Comstedt @ 2019-08-07 20:36 UTC (permalink / raw)
  To: u-boot


Hi Rick,

Rick Chen <rickchen36@gmail.com> writes:

> Thanks for your efforts about the support for big endian ELFs.
> But I don't have big endian toolchain to verify.

I don't think anyone has a big endian toolchain for riscv at this
juncture.  :-)  (No specification for big/bi endian has been nailed
down yet, AFAIK, although there has been discussion about how to
implement it.)

I expect the patch to work for symmetry reasons - the places that need
byteswapping when the host is little endian and the target is big
endian are exactly the same as the places that need byteswapping when
the host is big endian and the target is little endian (a case which I
have tested), so it's just a matter of keeping track of the endianness
of the host (something which U-Boot does internally already) versus
the endianness of the target (which is handled by this patch).

Merging this right now is probably about as useful as merging 128-bit
ELF support, but I don't think it really adds any maintainence burden,
so it might be simpler than keeping it around in patchwork.  It's your
call.  :-)


  // Marcus

^ permalink raw reply	[flat|nested] 6+ messages in thread

* [U-Boot] [PATCH v2 2/2] riscv: tools: Add big endian target support to prelink-riscv
       [not found]         ` <752D002CFF5D0F4FA35C0100F1D73F3FA40FAF35@ATCPCS16.andestech.com>
@ 2019-08-08  2:34           ` Rick Chen
  0 siblings, 0 replies; 6+ messages in thread
From: Rick Chen @ 2019-08-08  2:34 UTC (permalink / raw)
  To: u-boot

Hi Marcus

> > From: Marcus Comstedt [mailto:marcus at mc.pp.se]
> > Sent: Thursday, August 08, 2019 4:36 AM
> > To: Rick Chen
> > Cc: U-Boot Mailing List; Rick Jian-Zhi Chen(陳建志); K.C. Kuen-Chern Lin(林坤
> > 成)
> > Subject: Re: [PATCH v2 2/2] riscv: tools: Add big endian target support to
> > prelink-riscv
> >
> >
> > Hi Rick,
> >
> > Rick Chen <rickchen36@gmail.com> writes:
> >
> > > Thanks for your efforts about the support for big endian ELFs.
> > > But I don't have big endian toolchain to verify.
> >
> > I don't think anyone has a big endian toolchain for riscv at this juncture.  :-)
> > (No specification for big/bi endian has been nailed down yet, AFAIK, although
> > there has been discussion about how to implement it.)
> >
> > I expect the patch to work for symmetry reasons - the places that need
> > byteswapping when the host is little endian and the target is big endian are
> > exactly the same as the places that need byteswapping when the host is big
> > endian and the target is little endian (a case which I have tested), so it's just a
> > matter of keeping track of the endianness of the host (something which
> > U-Boot does internally already) versus the endianness of the target (which is
> > handled by this patch).
> >
> > Merging this right now is probably about as useful as merging 128-bit ELF
> > support, but I don't think it really adds any maintainence burden, so it might
> > be simpler than keeping it around in patchwork.  It's your call.  :-)
> >

Thanks for your explanation. :)

I have applied to u-boot-riscv/master, thanks!

Regards,
Rick

> >
> >   // Marcus
> >
>

^ permalink raw reply	[flat|nested] 6+ messages in thread

end of thread, other threads:[~2019-08-08  2:34 UTC | newest]

Thread overview: 6+ messages (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2019-08-02 17:45 [U-Boot] [PATCH v2 1/2] riscv: tools: Fix prelink-riscv to work on big endian hosts Marcus Comstedt
2019-08-02 17:45 ` [U-Boot] [PATCH v2 2/2] riscv: tools: Add big endian target support to prelink-riscv Marcus Comstedt
     [not found]   ` <752D002CFF5D0F4FA35C0100F1D73F3FA40FA9E8@ATCPCS16.andestech.com>
2019-08-07  8:49     ` Rick Chen
2019-08-07 20:36       ` Marcus Comstedt
     [not found]         ` <752D002CFF5D0F4FA35C0100F1D73F3FA40FAF35@ATCPCS16.andestech.com>
2019-08-08  2:34           ` Rick Chen
     [not found] ` <752D002CFF5D0F4FA35C0100F1D73F3FA40FA9DF@ATCPCS16.andestech.com>
2019-08-07  8:44   ` [U-Boot] [PATCH v2 1/2] riscv: tools: Fix prelink-riscv to work on big endian hosts Rick Chen

This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.