diff --git a/lld/ELF/Arch/RISCV.cpp b/lld/ELF/Arch/RISCV.cpp --- a/lld/ELF/Arch/RISCV.cpp +++ b/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 anchors; + llvm::DenseMap symMap; // For relocations[i], the actual offset is r_offset - (i ? relocDeltas[i-1] : // 0). std::unique_ptr relocDeltas; @@ -535,9 +536,14 @@ continue; if (auto *sec = dyn_cast_or_null(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 diff --git a/lld/test/ELF/Inputs/riscv-wrap.s b/lld/test/ELF/Inputs/riscv-wrap.s new file mode 100644 --- /dev/null +++ b/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 diff --git a/lld/test/ELF/riscv-wrap.s b/lld/test/ELF/riscv-wrap.s new file mode 100644 --- /dev/null +++ b/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