Skip to content

Commit 0991d3c

Browse files
MaskRaytstellar
authored andcommitted
[ELF] Don't resolve relocations referencing SHN_ABS to tombstone in non-SHF_ALLOC sections (#79238)
A SHN_ABS symbol has never been considered for InputSection::relocateNonAlloc. Before #74686, the code did made it work in the absence of `-z dead-reloc-in-nonalloc=`. There is now a report about such SHN_ABS uses (#74686 (comment)) and I think it makes sense for non-SHF_ALLOC to support SHN_ABS, like SHF_ALLOC sections do. ``` // clang -g __attribute__((weak)) int symbol; int *foo() { return &symbol; } 0x00000023: DW_TAG_variable [2] (0x0000000c) ... DW_AT_location [DW_FORM_exprloc] (DW_OP_addrx 0x0) ``` .debug_addr references `symbol`, which can be redefined by a symbol assignment or --defsym to become a SHN_ABS symbol. The problem is that `!sym.getOutputSection()` cannot discern SHN_ABS from a symbol whose section has been discarded. Since commit 1981b1b, a symbol relative to a discarded section is changed to `Undefined`, so the `SHN_ABS` check become trivial. We currently apply tombstone for a relocation referencing `SharedSymbol`. This patch does not change the behavior. (cherry picked from commit 8abf8d1)
1 parent 453ff4b commit 0991d3c

File tree

2 files changed

+7
-8
lines changed

2 files changed

+7
-8
lines changed

lld/ELF/InputSection.cpp

Lines changed: 6 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -961,20 +961,19 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
961961
// vector. The computed value is st_value plus a non-negative offset.
962962
// Negative values are invalid, so -1 can be used as the tombstone value.
963963
//
964-
// If the referenced symbol is discarded (made Undefined), or the
965-
// section defining the referenced symbol is garbage collected,
966-
// sym.getOutputSection() is nullptr. `ds->folded` catches the ICF folded
967-
// case. However, resolving a relocation in .debug_line to -1 would stop
968-
// debugger users from setting breakpoints on the folded-in function, so
969-
// exclude .debug_line.
964+
// If the referenced symbol is relative to a discarded section (due to
965+
// --gc-sections, COMDAT, etc), it has been converted to a Undefined.
966+
// `ds->folded` catches the ICF folded case. However, resolving a
967+
// relocation in .debug_line to -1 would stop debugger users from setting
968+
// breakpoints on the folded-in function, so exclude .debug_line.
970969
//
971970
// For pre-DWARF-v5 .debug_loc and .debug_ranges, -1 is a reserved value
972971
// (base address selection entry), use 1 (which is used by GNU ld for
973972
// .debug_ranges).
974973
//
975974
// TODO To reduce disruption, we use 0 instead of -1 as the tombstone
976975
// value. Enable -1 in a future release.
977-
if (!sym.getOutputSection() || (ds && ds->folded && !isDebugLine)) {
976+
if (!ds || (ds->folded && !isDebugLine)) {
978977
// If -z dead-reloc-in-nonalloc= is specified, respect it.
979978
uint64_t value = SignExtend64<bits>(*tombstone);
980979
// For a 32-bit local TU reference in .debug_names, X86_64::relocate

lld/test/ELF/dead-reloc-in-nonalloc.s

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
# AA: Contents of section .debug_info:
1818
# AA-NEXT: 0000 [[ADDR]] 00000000 aaaaaaaa 00000000
1919
# AA: Contents of section .not_debug:
20-
# AA-NEXT: 0000 bbbbbbbb bbbbbbbb 00000000 .
20+
# AA-NEXT: 0000 bbbbbbbb 2a000000 00000000 .
2121

2222
## Specifying zero can get a behavior similar to GNU ld.
2323
# RUN: ld.lld --icf=all -z dead-reloc-in-nonalloc=.debug_info=0 %t.o %tabs.o -o %tzero

0 commit comments

Comments
 (0)