[lld] [ELF] Change .debug_names tombstone value to UINT32_MAX/UINT64_MAX (PR #74686)
via llvm-commits
llvm-commits at lists.llvm.org
Wed Dec 6 17:02:15 PST 2023
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-lld
Author: Fangrui Song (MaskRay)
<details>
<summary>Changes</summary>
`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.
---
Full diff: https://github.com/llvm/llvm-project/pull/74686.diff
3 Files Affected:
- (modified) lld/ELF/InputSection.cpp (+17-7)
- (modified) lld/test/ELF/debug-dead-reloc-32.s (+11)
- (modified) lld/test/ELF/debug-dead-reloc.s (+22-2)
``````````diff
diff --git a/lld/ELF/InputSection.cpp b/lld/ELF/InputSection.cpp
index 145d55d9a0a4b..5a62b14f4c973 100644
--- a/lld/ELF/InputSection.cpp
+++ b/lld/ELF/InputSection.cpp
@@ -898,10 +898,16 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
const TargetInfo &target = *elf::target;
const auto emachine = config->emachine;
const bool isDebug = isDebugSection(*this);
- const bool isDebugLocOrRanges =
- isDebug && (name == ".debug_loc" || name == ".debug_ranges");
const bool isDebugLine = isDebug && name == ".debug_line";
- std::optional<uint64_t> tombstone;
+ std::optional<uint64_t> tombstone, debugTombstone;
+ if (isDebug) {
+ if (name == ".debug_loc" || name == ".debug_ranges")
+ debugTombstone = 1;
+ else if (name == ".debug_names")
+ debugTombstone = UINT64_MAX; // DWARF Issue 231013.1
+ else
+ debugTombstone = 0;
+ }
for (const auto &patAndValue : llvm::reverse(config->deadRelocInNonAlloc))
if (patAndValue.first.match(this->name)) {
tombstone = patAndValue.second;
@@ -954,8 +960,7 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
return;
}
- if (tombstone ||
- (isDebug && (type == target.symbolicRel || expr == R_DTPREL))) {
+ if (tombstone || (isDebug && (expr == R_ABS || expr == R_DTPREL))) {
// Resolve relocations in .debug_* referencing (discarded symbols or ICF
// folded section symbols) to a tombstone value. Resolving to addend is
// unsatisfactory because the result address range may collide with a
@@ -986,8 +991,13 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) {
// value. Enable -1 in a future release.
if (!sym.getOutputSection() || (ds && ds->folded && !isDebugLine)) {
// If -z dead-reloc-in-nonalloc= is specified, respect it.
- const uint64_t value = tombstone ? SignExtend64<bits>(*tombstone)
- : (isDebugLocOrRanges ? 1 : 0);
+ uint64_t value;
+ if (tombstone)
+ value = SignExtend64<bits>(*tombstone);
+ else if (type == target.symbolicRel)
+ value = *debugTombstone;
+ else // .debug_names uses 32-bit local TU offsets for DWARF32
+ value = static_cast<uint32_t>(*debugTombstone);
target.relocateNoSym(bufLoc, type, value);
continue;
}
diff --git a/lld/test/ELF/debug-dead-reloc-32.s b/lld/test/ELF/debug-dead-reloc-32.s
index b2708a744f288..7bf30b98e6890 100644
--- a/lld/test/ELF/debug-dead-reloc-32.s
+++ b/lld/test/ELF/debug-dead-reloc-32.s
@@ -13,6 +13,8 @@
# CHECK-NEXT: 0000 01000000
# CHECK-NEXT: Contents of section .debug_addr:
# CHECK-NEXT: 0000 00000000
+# CHECK-NEXT: Contents of section .debug_names:
+# CHECK-NEXT: 0000 ffffffff
.section .text.1,"axe"
.byte 0
@@ -27,3 +29,12 @@
## Resolved to UINT32_C(0), with the addend ignored.
.section .debug_addr
.long .text.1+8
+
+.section .debug_info,"eG", at progbits,5657452045627120676,comdat
+.Ltu_begin0:
+
+.section .debug_names
+## .debug_names may reference a local type unit defined in a COMDAT .debug_info
+## section (-g -gpubnames -fdebug-types-section). If the referenced section is
+## non-prevailing, resolve to UINT32_MAX.
+.long .Ltu_begin0
diff --git a/lld/test/ELF/debug-dead-reloc.s b/lld/test/ELF/debug-dead-reloc.s
index fcf53205079ed..627513c2672c4 100644
--- a/lld/test/ELF/debug-dead-reloc.s
+++ b/lld/test/ELF/debug-dead-reloc.s
@@ -16,9 +16,12 @@
# CHECK: Contents of section .debug_addr:
# CHECK-NEXT: 0000 {{.*}}000 00000000 {{.*}}000 00000000
# CHECK-NEXT: 0010 00000000 00000000 {{.*}}000 00000000
+# CHECK: Contents of section .debug_names:
+# CHECK-NEXT: 0000 00000000 00000000 00000000 ffffffff .
+# CHECK-NEXT: 0010 ffffffff ffffffff .
# CHECK: Contents of section .debug_foo:
-# CHECK-NEXT: 0000 00000000 00000000 08000000 00000000
-# CHECK-NEXT: 0010 00000000 00000000 08000000 00000000
+# CHECK-NEXT: 0000 00000000 00000000 00000000 00000000
+# CHECK-NEXT: 0010 00000000 00000000 00000000 00000000
# REL: Relocations [
# REL-NEXT: .rela.text {
@@ -38,6 +41,12 @@
# REL-NEXT: 0x10 R_X86_64_NONE - 0x18
# REL-NEXT: 0x18 R_X86_64_64 group 0x20
# REL-NEXT: }
+# REL-NEXT: .rela.debug_names {
+# REL-NEXT: 0x0 R_X86_64_32 .debug_info 0x0
+# REL-NEXT: 0x4 R_X86_64_64 .debug_info 0x0
+# REL-NEXT: 0xC R_X86_64_NONE - 0x0
+# REL-NEXT: 0x10 R_X86_64_NONE - 0x0
+# REL-NEXT: }
# REL-NEXT: .rela.debug_foo {
# REL-NEXT: 0x0 R_X86_64_NONE - 0x8
# REL-NEXT: 0x8 R_X86_64_NONE - 0x8
@@ -77,6 +86,17 @@ group:
## resolved to the prevailing copy.
.quad group+32
+.section .debug_info,"G", at progbits,5657452045627120676,comdat
+.Ltu_begin0:
+
+.section .debug_names
+## .debug_names may reference a local type unit defined in a COMDAT .debug_info
+## section (-g -gpubnames -fdebug-types-section). If the referenced section is
+## non-prevailing, resolve to UINT32_MAX.
+.long .Ltu_begin0
+## ... or UINT64_MAX for DWARF64.
+.quad .Ltu_begin0
+
.section .debug_foo
.quad .text.1+8
``````````
</details>
https://github.com/llvm/llvm-project/pull/74686
More information about the llvm-commits
mailing list