[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