[PATCH] D48929: [ELF] Update addends in non-allocatable sections for REL targets when creating a relocatable output.
Igor Kudrin via Phabricator via llvm-commits
llvm-commits at lists.llvm.org
Wed Jul 4 03:30:19 PDT 2018
ikudrin created this revision.
ikudrin added a reviewer: ruiu.
ikudrin added a project: lld.
Herald added subscribers: MaskRay, JDevlieghere, arichardson, aprantl, emaste.
Herald added a reviewer: espindola.
This fixes PR37735.
As addends were not updated in that case, the debug information in the relocatable output became corrupted.
Repository:
rLLD LLVM Linker
https://reviews.llvm.org/D48929
Files:
ELF/InputSection.cpp
ELF/InputSection.h
test/ELF/pr37735.s
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
Index: ELF/InputSection.h
===================================================================
--- ELF/InputSection.h
+++ ELF/InputSection.h
@@ -179,6 +179,7 @@
// the mmap'ed output buffer.
template <class ELFT> void relocate(uint8_t *Buf, uint8_t *BufEnd);
void relocateAlloc(uint8_t *Buf, uint8_t *BufEnd);
+ void relocateNonAllocForRelocatable(uint8_t *Buf, uint8_t *BufEnd);
// The native ELF reloc data type is not very convenient to handle.
// So we convert ELF reloc records to our own records in Relocations.cpp.
Index: ELF/InputSection.cpp
===================================================================
--- ELF/InputSection.cpp
+++ ELF/InputSection.cpp
@@ -734,6 +734,11 @@
return;
}
+ if (Config->Relocatable) {
+ relocateNonAllocForRelocatable(Buf, BufEnd);
+ return;
+ }
+
auto *Sec = cast<InputSection>(this);
if (Sec->AreRelocsRela)
Sec->relocateNonAlloc<ELFT>(Buf, Sec->template relas<ELFT>());
@@ -804,6 +809,30 @@
}
}
+// 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 method does the same for non-allocatable
+// sections, such as sections with debug information.
+void InputSectionBase::relocateNonAllocForRelocatable(uint8_t *Buf,
+ uint8_t *BufEnd) {
+ const unsigned Bits = Config->Wordsize * 8;
+
+ for (const Relocation &Rel : Relocations) {
+ // InputSection::copyRelocations() adds only R_ABS relocations.
+ // We don't expect to see here anything else.
+ assert(Rel.Expr == R_ABS);
+
+ auto *Sec = cast<InputSection>(this);
+ uint64_t Offset = Rel.Offset + Sec->OutSecOff;
+ uint8_t *BufLoc = Buf + Offset;
+ RelType Type = Rel.Type;
+ uint64_t TargetVA = SignExtend64(Rel.Sym->getVA(Rel.Addend), Bits);
+
+ Target->relocateOne(BufLoc, Type, TargetVA);
+ }
+}
+
template <class ELFT> void InputSection::writeTo(uint8_t *Buf) {
if (Type == SHT_NOBITS)
return;
-------------- next part --------------
A non-text attachment was scrubbed...
Name: D48929.154085.patch
Type: text/x-patch
Size: 2577 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/llvm-commits/attachments/20180704/602687a7/attachment.bin>
More information about the llvm-commits
mailing list