You are viewing a plain text version of this content. The canonical link for it is here.
Posted to commits@nuttx.apache.org by xi...@apache.org on 2022/03/23 09:57:02 UTC
[incubator-nuttx] branch master updated: RISC-V: Add/fix implementation for arch_elf.c
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 <vi...@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));