Index: ELF/InputSection.cpp =================================================================== --- ELF/InputSection.cpp +++ ELF/InputSection.cpp @@ -727,6 +727,23 @@ } } +// This is used when '-r' is given. +// For REL targets, InputSection::copyRelocations() may store artificial +// relocations aimed to update addends. They are handled in relocateAlloc() +// for allocatable sections, and this function does the same for +// non-allocatable sections, such as sections with debug information. +static void relocateNonAllocForRelocatable(InputSection *Sec, uint8_t *Buf) { + const unsigned Bits = Config->Is64 ? 64 : 32; + + for (const Relocation &Rel : Sec->Relocations) { + // InputSection::copyRelocations() adds only R_ABS relocations. + assert(Rel.Expr == R_ABS); + uint8_t *BufLoc = Buf + Rel.Offset + Sec->OutSecOff; + uint64_t TargetVA = SignExtend64(Rel.Sym->getVA(Rel.Addend), Bits); + Target->relocateOne(BufLoc, Rel.Type, TargetVA); + } +} + template void InputSectionBase::relocate(uint8_t *Buf, uint8_t *BufEnd) { if (Flags & SHF_ALLOC) { @@ -735,7 +752,9 @@ } auto *Sec = cast(this); - if (Sec->AreRelocsRela) + if (Config->Relocatable) + relocateNonAllocForRelocatable(Sec, Buf); + else if (Sec->AreRelocsRela) Sec->relocateNonAlloc(Buf, Sec->template relas()); else Sec->relocateNonAlloc(Buf, Sec->template rels()); Index: test/ELF/pr37735.s =================================================================== --- /dev/null +++ test/ELF/pr37735.s @@ -0,0 +1,12 @@ +# REQUIRES: x86 +# RUN: llvm-mc -filetype=obj -triple=i386-pc-linux-gnu %s -o %t.o +# RUN: ld.lld -r %t.o %t.o -o %t1.o +# RUN: llvm-objdump -s -section=.bar %t1.o | FileCheck %s + +.section .foo + .byte 0 + +# CHECK: Contents of section .bar: +# CHECK-NEXT: 0000 00000000 01000000 +.section .bar + .dc.a .foo