[lld] e00ac48 - [ELF] Use tombstone values for discarded symbols in relocatable output
Igor Kudrin via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 12 21:32:39 PST 2022
Author: Igor Kudrin
Date: 2022-01-13T11:38:26+07:00
New Revision: e00ac48df3a6d5e3fa23fdb898c5179a75fd855f
URL: https://github.com/llvm/llvm-project/commit/e00ac48df3a6d5e3fa23fdb898c5179a75fd855f
DIFF: https://github.com/llvm/llvm-project/commit/e00ac48df3a6d5e3fa23fdb898c5179a75fd855f.diff
LOG: [ELF] Use tombstone values for discarded symbols in relocatable output
This extends D81784. Sections can be discarded when linking a
relocatable output. Before the patch, LLD did not update the content
of debug sections and only replaced the corresponding relocations with
R_*_NONE, which could break the debug information.
Differential Revision: https://reviews.llvm.org/D116946
Added:
lld/test/ELF/debug-dead-reloc-relocatable.s
Modified:
lld/ELF/InputSection.cpp
Removed:
################################################################################
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index ae7ddb50793b2..f767f9e94c2b7 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -890,38 +890,6 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
if (expr == R_NONE)
continue;
- if (expr == R_SIZE) {
- target.relocateNoSym(bufLoc, type,
- SignExtend64<bits>(sym.getSize() + addend));
- continue;
- }
-
- // R_ABS/R_DTPREL and some other relocations can be used from non-SHF_ALLOC
- // sections.
- if (expr != R_ABS && expr != R_DTPREL && expr != R_GOTPLTREL &&
- expr != R_RISCV_ADD) {
- std::string msg = getLocation<ELFT>(offset) +
- ": has non-ABS relocation " + toString(type) +
- " against symbol '" + toString(sym) + "'";
- if (expr != R_PC && expr != R_ARM_PCA) {
- error(msg);
- return;
- }
-
- // If the control reaches here, we found a PC-relative relocation in a
- // non-ALLOC section. Since non-ALLOC section is not loaded into memory
- // at runtime, the notion of PC-relative doesn't make sense here. So,
- // this is a usage error. However, GNU linkers historically accept such
- // relocations without any errors and relocate them as if they were at
- // address 0. For bug-compatibilty, we accept them with warnings. We
- // know Steel Bank Common Lisp as of 2018 have this bug.
- warn(msg);
- target.relocateNoSym(
- bufLoc, type,
- SignExtend64<bits>(sym.getVA(addend - offset - outSecOff)));
- continue;
- }
-
if (tombstone ||
(isDebug && (type == target.symbolicRel || expr == R_DTPREL))) {
// Resolve relocations in .debug_* referencing (discarded symbols or ICF
@@ -961,7 +929,44 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
continue;
}
}
- target.relocateNoSym(bufLoc, type, SignExtend64<bits>(sym.getVA(addend)));
+
+ // For a relocatable link, only tombstone values are applied.
+ if (config->relocatable)
+ continue;
+
+ if (expr == R_SIZE) {
+ target.relocateNoSym(bufLoc, type,
+ SignExtend64<bits>(sym.getSize() + addend));
+ continue;
+ }
+
+ // R_ABS/R_DTPREL and some other relocations can be used from non-SHF_ALLOC
+ // sections.
+ if (expr == R_ABS || expr == R_DTPREL || expr == R_GOTPLTREL ||
+ expr == R_RISCV_ADD) {
+ target.relocateNoSym(bufLoc, type, SignExtend64<bits>(sym.getVA(addend)));
+ continue;
+ }
+
+ std::string msg = getLocation<ELFT>(offset) + ": has non-ABS relocation " +
+ toString(type) + " against symbol '" + toString(sym) +
+ "'";
+ if (expr != R_PC && expr != R_ARM_PCA) {
+ error(msg);
+ return;
+ }
+
+ // If the control reaches here, we found a PC-relative relocation in a
+ // non-ALLOC section. Since non-ALLOC section is not loaded into memory
+ // at runtime, the notion of PC-relative doesn't make sense here. So,
+ // this is a usage error. However, GNU linkers historically accept such
+ // relocations without any errors and relocate them as if they were at
+ // address 0. For bug-compatibilty, we accept them with warnings. We
+ // know Steel Bank Common Lisp as of 2018 have this bug.
+ warn(msg);
+ target.relocateNoSym(
+ bufLoc, type,
+ SignExtend64<bits>(sym.getVA(addend - offset - outSecOff)));
}
}
@@ -993,15 +998,15 @@ void InputSectionBase::relocate(uint8_t *buf, uint8_t *bufEnd) {
}
auto *sec = cast<InputSection>(this);
- if (config->relocatable) {
+ if (config->relocatable)
relocateNonAllocForRelocatable(sec, buf);
- } else {
- const RelsOrRelas<ELFT> rels = sec->template relsOrRelas<ELFT>();
- if (rels.areRelocsRel())
- sec->relocateNonAlloc<ELFT>(buf, rels.rels);
- else
- sec->relocateNonAlloc<ELFT>(buf, rels.relas);
- }
+ // For a relocatable link, also call relocateNonAlloc() to rewrite applicable
+ // locations with tombstone values.
+ const RelsOrRelas<ELFT> rels = sec->template relsOrRelas<ELFT>();
+ if (rels.areRelocsRel())
+ sec->relocateNonAlloc<ELFT>(buf, rels.rels);
+ else
+ sec->relocateNonAlloc<ELFT>(buf, rels.relas);
}
void InputSectionBase::relocateAlloc(uint8_t *buf, uint8_t *bufEnd) {
diff --git a/lld/test/ELF/debug-dead-reloc-relocatable.s b/lld/test/ELF/debug-dead-reloc-relocatable.s
new file mode 100644
index 0000000000000..e8886f096a8f3
--- /dev/null
+++ b/lld/test/ELF/debug-dead-reloc-relocatable.s
@@ -0,0 +1,36 @@
+# REQUIRES: x86
+## Test we resolve symbolic relocations in .debug_* sections to a tombstone
+## value if the referenced symbol is discarded when linking a relocatable object.
+
+# RUN: llvm-mc -filetype=obj -triple=x86_64 %s -o %t1.o
+# RUN: ld.lld -r %t1.o %t1.o -o %t2.o
+# RUN: llvm-readelf -r -x .debug_ranges %t2.o | FileCheck %s
+
+## Relocations for a discarded section are changed to R_*_NONE.
+# CHECK: Relocation section '.rela.debug_ranges' at offset [[#%#x,]] contains 4 entries:
+# CHECK-NEXT: Offset Info Type Symbol's Value Symbol's Name + Addend
+# CHECK-NEXT: 0000000000000000 [[#%x,]] R_X86_64_64 0000000000000000 .text.foo + 0
+# CHECK-NEXT: 0000000000000008 [[#%x,]] R_X86_64_64 0000000000000000 .text.foo + 1
+# CHECK-NEXT: 0000000000000020 [[#%x,]] R_X86_64_NONE
+# CHECK-NEXT: 0000000000000028 [[#%x,]] R_X86_64_NONE
+
+## References to a discarded section are changed to tombstone values.
+# CHECK: Hex dump of section '.debug_ranges':
+# CHECK-NEXT: 0x00000000 00000000 00000000 00000000 00000000
+# CHECK-NEXT: 0x00000010 00000000 00000000 00000000 00000000
+# CHECK-NEXT: 0x00000020 01000000 00000000 01000000 00000000
+# CHECK-NEXT: 0x00000030 00000000 00000000 00000000 00000000
+
+.weak foo
+
+ .section .text.foo,"axG", at progbits,foo,comdat
+.Lfoo:
+foo:
+ ret
+.Lfoo_end:
+
+ .section .debug_ranges,"", at progbits
+ .quad .Lfoo
+ .quad .Lfoo_end
+ .quad 0
+ .quad 0
More information about the llvm-commits
mailing list