[PATCH] D150220: [lld]: Fix RISC-V relaxation bug

Kishore Ganesh via Phabricator via llvm-commits llvm-commits at lists.llvm.org
Tue May 9 12:38:36 PDT 2023


kishore-rivos created this revision.
Herald added subscribers: luke, VincentWu, vkmr, frasercrmck, luismarques, apazos, sameer.abuasal, s.egerton, Jim, jocewei, PkmX, the_o, brucehoult, MartinMosbeck, rogfer01, edward-jones, zzheng, jrtc27, shiva0217, kito-cheng, niosHD, sabuasal, simoncook, johnrusso, rbar, asb, arichardson, emaste.
Herald added a reviewer: MaskRay.
Herald added a project: All.
kishore-rivos requested review of this revision.
Herald added subscribers: llvm-commits, pcwang-thead.
Herald added a project: LLVM.

When multiple symbol names alias to the same symbol (which is the case
when we use --wrap), the RISC-V relaxation steps are executed multiple
times for the same symbol, causing erroneous addresses being assigned to
symbols. This commit fixes this by only operating on unique symbols
(addressed by the symbol pointers).

Signed-off-by: Kishore Ganesh <kishoreganesh at rivosinc.com>


Repository:
  rG LLVM Github Monorepo

https://reviews.llvm.org/D150220

Files:
  lld/ELF/Arch/RISCV.cpp
  lld/test/ELF/Inputs/riscv-wrap.s
  lld/test/ELF/riscv-wrap.s


Index: lld/test/ELF/riscv-wrap.s
===================================================================
--- /dev/null
+++ lld/test/ELF/riscv-wrap.s
@@ -0,0 +1,13 @@
+# REQUIRES: riscv 
+## Test RISCV's handling of --wrap when R_RISCV_ALIGN is present 
+# RUN: rm -rf %t && mkdir %t && cd %t 
+# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=+relax %s -o %t1 
+# RUN: llvm-mc -filetype=obj -triple=riscv64-unknown-elf -mattr=+relax %p/Inputs/riscv-wrap.s  -o %t2 
+# RUN: ld.lld -Ttext=0x100000 -o %t3 %t1 %t2 --wrap foo
+# RUN: llvm-objdump -d --print-imm-hex %t3 | FileCheck %s 
+# CHECK: 0000000000100040 <__wrap_foo>:
+## CHECK-NEXT:   100040: 93 80 10 00   addi    ra, ra, 1  
+.global _start
+_start:
+    call foo
+    ret
Index: lld/test/ELF/Inputs/riscv-wrap.s
===================================================================
--- /dev/null
+++ lld/test/ELF/Inputs/riscv-wrap.s
@@ -0,0 +1,11 @@
+.global foo 
+.weak __wrap_foo 
+.protected __wrap_foo
+.global __real_foo
+nop
+foo:
+    addi x1,x1,1
+.align 5
+__wrap_foo:
+    addi x1,x1,1
+    call __real_foo
\ No newline at end of file
Index: lld/ELF/Arch/RISCV.cpp
===================================================================
--- lld/ELF/Arch/RISCV.cpp
+++ lld/ELF/Arch/RISCV.cpp
@@ -503,6 +503,7 @@
   // This records symbol start and end offsets which will be adjusted according
   // to the nearest relocDeltas element.
   SmallVector<SymbolAnchor, 0> anchors;
+  llvm::DenseMap<Symbol *, int> symMap;
   // For relocations[i], the actual offset is r_offset - (i ? relocDeltas[i-1] :
   // 0).
   std::unique_ptr<uint32_t[]> relocDeltas;
@@ -535,9 +536,14 @@
         continue;
       if (auto *sec = dyn_cast_or_null<InputSection>(d->section))
         if (sec->flags & SHF_EXECINSTR && sec->relaxAux) {
-          // If sec is discarded, relaxAux will be nullptr.
-          sec->relaxAux->anchors.push_back({d->value, d, false});
-          sec->relaxAux->anchors.push_back({d->value + d->size, d, true});
+          bool found =
+              sec->relaxAux->symMap.find(sym) != sec->relaxAux->symMap.end();
+          if (!found) {
+            // If sec is discarded, relaxAux will be nullptr.
+            sec->relaxAux->anchors.push_back({d->value, d, false});
+            sec->relaxAux->anchors.push_back({d->value + d->size, d, true});
+            sec->relaxAux->symMap.insert({sym, 1});
+          }
         }
     }
   // Sort anchors by offset so that we can find the closest relocation


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D150220.520793.patch
Type: text/x-patch
Size: 2491 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20230509/cfc263ca/attachment.bin>


More information about the llvm-commits mailing list