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));