[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