Skip to content

Commit 26ddf4e

Browse files
MaskRayayermolo
andauthored
[ELF] Change .debug_names tombstone value to UINT32_MAX/UINT64_MAX (#74686)
`clang -g -gpubnames -fdebug-types-section` now emits .debug_names section with references to local type unit entries defined in COMDAT .debug_info sections. ``` .section .debug_info,"G",@progbits,5657452045627120676,comdat .Ltu_begin0: ... .section .debug_names,"",@progbits ... // DWARF32 .long .Ltu_begin0 # Type unit 0 // DWARF64 // .long .Ltu_begin0 # Type unit 0 ``` When `.Ltu_begin0` is relative to a non-prevailing .debug_info section, the relocation resolves to 0, which is a valid offset within the .debug_info section. ``` cat > a.cc <<e struct A { int x; }; inline A foo() { return {1}; } int main() { foo(); } e cat > b.cc <<e struct A { int x; }; inline A foo() { return {1}; } void use() { foo(); } e clang++ -g -gpubnames -fdebug-types-section -fuse-ld=lld a.cc b.cc -o old ``` ``` % llvm-dwarfdump old ... Local Type Unit offsets [ LocalTU[0]: 0x00000000 ] ... Local Type Unit offsets [ LocalTU[0]: 0x00000000 // indistinguishable from a valid offset within .debug_info ] ``` https://dwarfstd.org/issues/231013.1.html proposes that we use a tombstone value instead to inform consumers. This patch implements the idea. The second LocalTU entry will now use 0xffffffff. https://reviews.llvm.org/D84825 has a TODO that we should switch the tombstone value for most `.debug_*` sections to UINT64_MAX. We have postponed the change for more than three years for consumers to migrate. At some point we shall make the change, so that .debug_names is no long different from other debug section that is not .debug_loc/.debug_ranges. Co-authored-by: Alexander Yermolovich <[email protected]>
1 parent 847a6f8 commit 26ddf4e

File tree

3 files changed

+49
-8
lines changed

3 files changed

+49
-8
lines changed

lld/ELF/InputSection.cpp

+16-6
Original file line numberDiff line numberDiff line change
@@ -898,10 +898,16 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
898898
const TargetInfo &target = *elf::target;
899899
const auto emachine = config->emachine;
900900
const bool isDebug = isDebugSection(*this);
901-
const bool isDebugLocOrRanges =
902-
isDebug && (name == ".debug_loc" || name == ".debug_ranges");
903901
const bool isDebugLine = isDebug && name == ".debug_line";
904902
std::optional<uint64_t> tombstone;
903+
if (isDebug) {
904+
if (name == ".debug_loc" || name == ".debug_ranges")
905+
tombstone = 1;
906+
else if (name == ".debug_names")
907+
tombstone = UINT64_MAX; // tombstone value
908+
else
909+
tombstone = 0;
910+
}
905911
for (const auto &patAndValue : llvm::reverse(config->deadRelocInNonAlloc))
906912
if (patAndValue.first.match(this->name)) {
907913
tombstone = patAndValue.second;
@@ -946,8 +952,7 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
946952
return;
947953
}
948954

949-
if (tombstone ||
950-
(isDebug && (type == target.symbolicRel || expr == R_DTPREL))) {
955+
if (tombstone && (expr == R_ABS || expr == R_DTPREL)) {
951956
// Resolve relocations in .debug_* referencing (discarded symbols or ICF
952957
// folded section symbols) to a tombstone value. Resolving to addend is
953958
// unsatisfactory because the result address range may collide with a
@@ -978,8 +983,13 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
978983
// value. Enable -1 in a future release.
979984
if (!sym.getOutputSection() || (ds && ds->folded && !isDebugLine)) {
980985
// If -z dead-reloc-in-nonalloc= is specified, respect it.
981-
const uint64_t value = tombstone ? SignExtend64<bits>(*tombstone)
982-
: (isDebugLocOrRanges ? 1 : 0);
986+
uint64_t value = SignExtend64<bits>(*tombstone);
987+
// For a 32-bit local TU reference in .debug_names, X86_64::relocate
988+
// requires that the unsigned value for R_X86_64_32 is truncated to
989+
// 32-bit. Other 64-bit targets's don't discern signed/unsigned 32-bit
990+
// absolute relocations and do not need this change.
991+
if (emachine == EM_X86_64 && type == R_X86_64_32)
992+
value = static_cast<uint32_t>(value);
983993
target.relocateNoSym(bufLoc, type, value);
984994
continue;
985995
}

lld/test/ELF/debug-dead-reloc-32.s

+11
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
# CHECK-NEXT: 0000 01000000
1414
# CHECK-NEXT: Contents of section .debug_addr:
1515
# CHECK-NEXT: 0000 00000000
16+
# CHECK-NEXT: Contents of section .debug_names:
17+
# CHECK-NEXT: 0000 ffffffff
1618

1719
## -z dead-reloc-in-nonalloc= can override the tombstone value.
1820
# RUN: ld.lld -z dead-reloc-in-nonalloc=.debug_loc=42 -z dead-reloc-in-nonalloc=.debug_addr=0xfffffffffffffffe %t.o -o %t1
@@ -38,3 +40,12 @@
3840
## Resolved to UINT32_C(0), with the addend ignored.
3941
.section .debug_addr
4042
.long .text.1+8
43+
44+
.section .debug_info,"eG",@progbits,5657452045627120676,comdat
45+
.Ltu_begin0:
46+
47+
.section .debug_names
48+
## .debug_names may reference a local type unit defined in a COMDAT .debug_info
49+
## section (-g -gpubnames -fdebug-types-section). If the referenced section is
50+
## non-prevailing, resolve to UINT32_MAX.
51+
.long .Ltu_begin0

lld/test/ELF/debug-dead-reloc.s

+22-2
Original file line numberDiff line numberDiff line change
@@ -21,9 +21,12 @@
2121
# CHECK: Contents of section .debug_addr:
2222
# CHECK-NEXT: 0000 {{.*}}00 00000000 {{.*}}00 00000000
2323
# CHECK-NEXT: 0010 00000000 00000000 {{.*}}00 00000000
24+
# CHECK: Contents of section .debug_names:
25+
# CHECK-NEXT: 0000 00000000 00000000 00000000 ffffffff .
26+
# CHECK-NEXT: 0010 ffffffff ffffffff .
2427
# CHECK: Contents of section .debug_foo:
25-
# CHECK-NEXT: 0000 00000000 00000000 08000000 00000000
26-
# CHECK-NEXT: 0010 00000000 00000000 08000000 00000000
28+
# CHECK-NEXT: 0000 00000000 00000000 00000000 00000000
29+
# CHECK-NEXT: 0010 00000000 00000000 00000000 00000000
2730

2831
# REL: Relocations [
2932
# REL-NEXT: .rela.text {
@@ -43,6 +46,12 @@
4346
# REL-NEXT: 0x10 R_X86_64_NONE - 0x18
4447
# REL-NEXT: 0x18 R_X86_64_64 group 0x20
4548
# REL-NEXT: }
49+
# REL-NEXT: .rela.debug_names {
50+
# REL-NEXT: 0x0 R_X86_64_32 .debug_info 0x0
51+
# REL-NEXT: 0x4 R_X86_64_64 .debug_info 0x0
52+
# REL-NEXT: 0xC R_X86_64_NONE - 0x0
53+
# REL-NEXT: 0x10 R_X86_64_NONE - 0x0
54+
# REL-NEXT: }
4655
# REL-NEXT: .rela.debug_foo {
4756
# REL-NEXT: 0x0 R_X86_64_NONE - 0x8
4857
# REL-NEXT: 0x8 R_X86_64_NONE - 0x8
@@ -82,6 +91,17 @@ group:
8291
## resolved to the prevailing copy.
8392
.quad group+32
8493

94+
.section .debug_info,"G",@progbits,5657452045627120676,comdat
95+
.Ltu_begin0:
96+
97+
.section .debug_names
98+
## .debug_names may reference a local type unit defined in a COMDAT .debug_info
99+
## section (-g -gpubnames -fdebug-types-section). If the referenced section is
100+
## non-prevailing, resolve to UINT32_MAX.
101+
.long .Ltu_begin0
102+
## ... or UINT64_MAX for DWARF64.
103+
.quad .Ltu_begin0
104+
85105
.section .debug_foo
86106
.quad .text.1+8
87107

0 commit comments

Comments
 (0)