X-Git-Url: https://git.librecmc.org/?a=blobdiff_plain;f=tools%2Fprelink-riscv.inc;h=f2b5467f5b3c19be285153d3ad7cdb210a24a94c;hb=c3aa81e35cc53fcd825e89510cd648288e0b6b92;hp=c07d930f7ed24da4f16409565fdca03b06a4492f;hpb=3dde8f20377c3a051dda64497bdf0cdb23e03a2d;p=oweals%2Fu-boot.git diff --git a/tools/prelink-riscv.inc b/tools/prelink-riscv.inc index c07d930f7e..f2b5467f5b 100644 --- a/tools/prelink-riscv.inc +++ b/tools/prelink-riscv.inc @@ -1,9 +1,8 @@ +// SPDX-License-Identifier: GPL-2.0+ /* * Copyright (C) 2017 Andes Technology * Chih-Mao Chen * - * SPDX-License-Identifier: GPL-2.0+ - * * Statically process runtime relocations on RISC-V ELF images * so that it can be directly executed when loaded at LMA * without fixup. Both RV32 and RV64 are supported. @@ -13,9 +12,9 @@ #define CONCAT(x, y) CONCAT_IMPL(x, y) #define CONCAT3(x, y, z) CONCAT(CONCAT(x, y), z) -#define prelink_nn CONCAT(prelink, PRELINK_INC_BITS) +#define prelink_bonn CONCAT3(prelink_, PRELINK_BYTEORDER, PRELINK_INC_BITS) #define uintnn_t CONCAT3(uint, PRELINK_INC_BITS, _t) -#define get_offset_nn CONCAT(get_offset_, PRELINK_INC_BITS) +#define get_offset_bonn CONCAT3(get_offset_, PRELINK_BYTEORDER, PRELINK_INC_BITS) #define Elf_Ehdr CONCAT3(Elf, PRELINK_INC_BITS, _Ehdr) #define Elf_Phdr CONCAT3(Elf, PRELINK_INC_BITS, _Phdr) #define Elf_Rela CONCAT3(Elf, PRELINK_INC_BITS, _Rela) @@ -24,34 +23,40 @@ #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) - -static void* get_offset_nn (void* data, Elf_Phdr* phdrs, size_t phnum, Elf_Addr addr) +#define target16_to_cpu CONCAT(PRELINK_BYTEORDER, 16_to_cpu) +#define target32_to_cpu CONCAT(PRELINK_BYTEORDER, 32_to_cpu) +#define target64_to_cpu CONCAT(PRELINK_BYTEORDER, 64_to_cpu) +#define targetnn_to_cpu CONCAT3(PRELINK_BYTEORDER, PRELINK_INC_BITS, _to_cpu) +#define cpu_to_target32 CONCAT3(cpu_to_, PRELINK_BYTEORDER, 32) +#define cpu_to_target64 CONCAT3(cpu_to_, PRELINK_BYTEORDER, 64) + +static void* get_offset_bonn (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 (targetnn_to_cpu(p->p_vaddr) <= addr && targetnn_to_cpu(p->p_vaddr) + targetnn_to_cpu(p->p_memsz) > addr) + return data + targetnn_to_cpu(p->p_offset) + (addr - targetnn_to_cpu(p->p_vaddr)); return NULL; } -static void prelink_nn(void *data) +static void prelink_bonn(void *data) { Elf_Ehdr *ehdr = data; Elf_Phdr *p; Elf_Dyn *dyn; Elf_Rela *r; - if (ehdr->e_machine != EM_RISCV) + if (target16_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 + targetnn_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 + target16_to_cpu(ehdr->e_phnum); ++p) { + if (target32_to_cpu(p->p_type) == PT_DYNAMIC) { + dyns = data + targetnn_to_cpu(p->p_offset); break; } } @@ -63,14 +68,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 (targetnn_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 (targetnn_to_cpu(dyn->d_tag) == DT_RELA) + rela_dyn = get_offset_bonn(data, phdrs, target16_to_cpu(ehdr->e_phnum), + targetnn_to_cpu(dyn->d_un.d_ptr)); + else if (targetnn_to_cpu(dyn->d_tag) == DT_RELASZ) + rela_count = targetnn_to_cpu(dyn->d_un.d_val) / sizeof(Elf_Rela); + else if (targetnn_to_cpu(dyn->d_tag) == DT_SYMTAB) + dynsym = get_offset_bonn(data, phdrs, target16_to_cpu(ehdr->e_phnum), + targetnn_to_cpu(dyn->d_un.d_ptr)); } @@ -81,23 +86,23 @@ 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_bonn(data, phdrs, target16_to_cpu(ehdr->e_phnum), targetnn_to_cpu(r->r_offset)); if (buf == NULL) continue; - if (ELF_R_TYPE(r->r_info) == R_RISCV_RELATIVE) + if (ELF_R_TYPE(targetnn_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(targetnn_to_cpu(r->r_info)) == R_RISCV_32) + *((uint32_t*) buf) = cpu_to_target32(targetnn_to_cpu(dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value) + targetnn_to_cpu(r->r_addend)); + else if (ELF_R_TYPE(targetnn_to_cpu(r->r_info)) == R_RISCV_64) + *((uint64_t*) buf) = cpu_to_target64(targetnn_to_cpu(dynsym[ELF_R_SYM(targetnn_to_cpu(r->r_info))].st_value) + targetnn_to_cpu(r->r_addend)); } } -#undef prelink_nn +#undef prelink_bonn #undef uintnn_t -#undef get_offset_nn +#undef get_offset_bonn #undef Elf_Ehdr #undef Elf_Phdr #undef Elf_Rela @@ -106,6 +111,12 @@ static void prelink_nn(void *data) #undef Elf_Addr #undef ELF_R_TYPE #undef ELF_R_SYM +#undef target16_to_cpu +#undef target32_to_cpu +#undef target64_to_cpu +#undef targetnn_to_cpu +#undef cpu_to_target32 +#undef cpu_to_target64 #undef CONCAT_IMPL #undef CONCAT