[U-Boot] [PATCH v2 1/2] riscv: tools: Fix prelink-riscv to work on big endian hosts
Rick Chen
rickchen36 at gmail.com
Wed Aug 7 08:44:41 UTC 2019
> > 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 at mc.pp.se>
> > Cc: Rick Chen <rick at andestech.com>
Reviewed-by: Rick Chen <rick at 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
>
More information about the U-Boot
mailing list