Hi Marcus > From: Marcus Comstedt [mailto:mar...@mc.pp.se] > Sent: Monday, July 15, 2019 8:36 PM > To: u-boot@lists.denx.de > Cc: Marcus Comstedt; Rick Jian-Zhi Chen(陳建志) > Subject: [PATCH] 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. > > Note that it is still assumed that the RISC-V ELF is little endian. > In order to support big endian RISC-V targets as well, the calls to le*_to_cpu > need to be replaced with macros target*_to_cpu defined by prelink-riscv.c, and > prelink-riscv.inc included four times (32le, 64le, 32be, 32be) instead of two. > > Signed-off-by: Marcus Comstedt <mar...@mc.pp.se> > Cc: Rick Chen <r...@andestech.com> > --- > tools/prelink-riscv.c | 5 +---- > tools/prelink-riscv.inc | 41 +++++++++++++++++++++-------------------- > 2 files changed, 22 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..e451159c03 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; > } > } >
Nitpick: #undef lenn_to_cpu at the end of prelink-riscv.inc. Other than that, Reviewed-by: Rick Chen <r...@andestech.com> > -- > 2.21.0 > _______________________________________________ U-Boot mailing list U-Boot@lists.denx.de https://lists.denx.de/listinfo/u-boot