[U-Boot] [PATCH] riscv: tools: Fix prelink-riscv to work on big endian hosts

Rick Chen rickchen36 at gmail.com
Thu Jul 18 06:13:19 UTC 2019


Hi Marcus

> From: Marcus Comstedt [mailto:marcus at mc.pp.se]
> Sent: Monday, July 15, 2019 8:36 PM
> To: u-boot at 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 <marcus at mc.pp.se>
> Cc: Rick Chen <rick at 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 <rick at andestech.com>


> --
> 2.21.0
>


More information about the U-Boot mailing list