This is an automated email from the ASF dual-hosted git repository. xiaoxiang pushed a commit to branch master in repository https://gitbox.apache.org/repos/asf/incubator-nuttx.git
The following commit(s) were added to refs/heads/master by this push: new 9288ed8 RISC-V: Add/fix implementation for arch_elf.c 9288ed8 is described below commit 9288ed85e73db088143d0622165a1ca572e2ed91 Author: Ville Juven <ville.ju...@unikie.com> AuthorDate: Wed Feb 23 13:01:57 2022 +0200 RISC-V: Add/fix implementation for arch_elf.c The jump instruction relocation had an assert that tests for jumps with an offset of 0. This makes it so that a while(1); statement causes an assert because the jump instruction points to the same address, which is perfectly legal. Addend was not handled correctly in several reloc types. Add ADD32/64 + SUB32/64 relocations, for some reason the compiler I use likes to add them. --- libs/libc/machine/risc-v/common/arch_elf.c | 39 +++++++++++++++++++++--------- 1 file changed, 27 insertions(+), 12 deletions(-) diff --git a/libs/libc/machine/risc-v/common/arch_elf.c b/libs/libc/machine/risc-v/common/arch_elf.c index 275b51f..67c89e4 100644 --- a/libs/libc/machine/risc-v/common/arch_elf.c +++ b/libs/libc/machine/risc-v/common/arch_elf.c @@ -343,7 +343,7 @@ int up_relocateadd(FAR const Elf_Rela *rel, FAR const Elf_Sym *sym, addr, _get_val((uint16_t *)addr), sym, sym->st_value); - offset = (long)sym->st_value - (long)addr; + offset = (long)sym->st_value + (long)rel->r_addend - (long)addr; long imm_hi; long imm_lo; @@ -386,7 +386,7 @@ int up_relocateadd(FAR const Elf_Rela *rel, FAR const Elf_Sym *sym, /* P.23 Conditinal Branches : B type (imm=12bit) */ - offset = (long)sym->st_value - (long)addr; + offset = (long)sym->st_value + (long)rel->r_addend - (long)addr; uint32_t val = _get_val((uint16_t *)addr) & 0xfe000f80; /* NOTE: we assume that a compiler adds an immediate value */ @@ -409,7 +409,7 @@ int up_relocateadd(FAR const Elf_Rela *rel, FAR const Elf_Sym *sym, /* P.19 LUI */ - offset = (long)sym->st_value; + offset = (long)sym->st_value + (long)rel->r_addend; uint32_t insn = _get_val((uint16_t *)addr); ASSERT(OPCODE_LUI == (insn & RVI_OPCODE_MASK)); @@ -433,7 +433,7 @@ int up_relocateadd(FAR const Elf_Rela *rel, FAR const Elf_Sym *sym, /* ADDI, FLW, LD, ... : I-type */ - offset = (long)sym->st_value; + offset = (long)sym->st_value + (long)rel->r_addend; uint32_t insn = _get_val((uint16_t *)addr); long imm_hi; @@ -458,7 +458,7 @@ int up_relocateadd(FAR const Elf_Rela *rel, FAR const Elf_Sym *sym, * may not generates these two instructions continuously. */ - offset = (long)sym->st_value; + offset = (long)sym->st_value + (long)rel->r_addend; long imm_hi; long imm_lo; @@ -484,15 +484,11 @@ int up_relocateadd(FAR const Elf_Rela *rel, FAR const Elf_Sym *sym, /* P.111 Table 16.6 : Instruction listings for RVC */ - offset = ((long)sym->st_value - (long)addr); + offset = (long)sym->st_value + (long)rel->r_addend - (long)addr; ASSERT(-2048 <= offset && offset <= 2047); uint16_t val = (*(uint16_t *)addr) & 0x1ffc; - /* NOTE: we assume that a compiler adds an immediate value */ - - ASSERT(offset && val); - binfo("offset for C.J=%ld (0x%lx) (val=0x%04x) already set!\n", offset, offset, val); } @@ -508,7 +504,7 @@ int up_relocateadd(FAR const Elf_Rela *rel, FAR const Elf_Sym *sym, /* P.111 Table 16.6 : Instruction listings for RVC */ - offset = ((long)sym->st_value - (long)addr); + offset = (long)sym->st_value + (long)rel->r_addend - (long)addr; ASSERT(-256 <= offset && offset <= 255); uint16_t val = (*(uint16_t *)addr) & 0x1c7c; @@ -521,7 +517,26 @@ int up_relocateadd(FAR const Elf_Rela *rel, FAR const Elf_Sym *sym, offset, offset, val); } break; - + case R_RISCV_ADD32: + { + *(uint32_t *)addr += (uint32_t)(sym->st_value + rel->r_addend); + } + break; + case R_RISCV_ADD64: + { + *(uint64_t *)addr += (uint64_t)(sym->st_value + rel->r_addend); + } + break; + case R_RISCV_SUB32: + { + *(uint32_t *)addr -= (uint32_t)(sym->st_value + rel->r_addend); + } + break; + case R_RISCV_SUB64: + { + *(uint64_t *)addr -= (uint64_t)(sym->st_value + rel->r_addend); + } + break; default: berr("ERROR: Unsupported relocation: %ld\n", ARCH_ELF_RELTYPE(rel->r_info));