-
Notifications
You must be signed in to change notification settings - Fork 13.5k
[LLD] Tombstone LocalTU entry in .debug_names #70701
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Changes from all commits
d2665cc
792155d
854a281
b716d70
19fa33e
a69878b
8e5c0b7
be18f4f
e25f409
03afbda
036dbef
1dfdf18
File filter
Filter by extension
Conversations
Jump to
Diff view
Diff view
There are no files selected for viewing
Original file line number | Diff line number | Diff line change |
---|---|---|
|
@@ -20,8 +20,7 @@ | |
#include "llvm/Support/Compression.h" | ||
#include "llvm/Support/Endian.h" | ||
#include "llvm/Support/xxhash.h" | ||
#include <algorithm> | ||
#include <mutex> | ||
#include <optional> | ||
#include <vector> | ||
|
||
using namespace llvm; | ||
|
@@ -886,16 +885,25 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) { | |
const unsigned bits = sizeof(typename ELFT::uint) * 8; | ||
const TargetInfo &target = *elf::target; | ||
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 = std::nullopt; | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. An optional defaults to std::nullopt. Just default initialize it. |
||
std::optional<uint64_t> tombstoneValueToUse = std::nullopt; | ||
for (const auto &patAndValue : llvm::reverse(config->deadRelocInNonAlloc)) | ||
if (patAndValue.first.match(this->name)) { | ||
tombstone = patAndValue.second; | ||
break; | ||
} | ||
|
||
const uint64_t debugTombstone = StringSwitch<uint64_t>(name) | ||
.Case(".debug_ranges", 1) | ||
.Case(".debug_loc", 1) | ||
.Case(".debug_names", llvm::maxUIntN(32)) | ||
.Default(0); | ||
// If -z dead-reloc-in-nonalloc= is specified, respect it. | ||
if (!tombstone && isDebug) | ||
tombstoneValueToUse = debugTombstone; | ||
else if (tombstone) | ||
tombstoneValueToUse = SignExtend64<bits>(*tombstone); | ||
for (const RelTy &rel : rels) { | ||
RelType type = rel.getType(config->isMips64EL); | ||
|
||
|
@@ -917,8 +925,9 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) { | |
if (expr == R_NONE) | ||
continue; | ||
|
||
if (tombstone || | ||
(isDebug && (type == target.symbolicRel || expr == R_DTPREL))) { | ||
auto *ds = dyn_cast<Defined>(&sym); | ||
if (tombstoneValueToUse && | ||
(!sym.getOutputSection() || (ds && ds->folded && !isDebugLine))) { | ||
// 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 | ||
|
@@ -947,14 +956,13 @@ void InputSection::relocateNonAlloc(uint8_t *buf, ArrayRef<RelTy> rels) { | |
// | ||
// TODO To reduce disruption, we use 0 instead of -1 as the tombstone | ||
// value. Enable -1 in a future release. | ||
auto *ds = dyn_cast<Defined>(&sym); | ||
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); | ||
target.relocateNoSym(bufLoc, type, value); | ||
continue; | ||
} | ||
|
||
// Extending 32bit MAX value to 64bit MAX value.. | ||
// One usage example is in .debug_names LocatTU tombstoning. | ||
if (!tombstone && type == target.symbolicRel) | ||
tombstoneValueToUse = SignExtend64<32>(*tombstoneValueToUse); | ||
target.relocateNoSym(bufLoc, type, *tombstoneValueToUse); | ||
continue; | ||
} | ||
|
||
// For a relocatable link, content relocated by RELA remains unchanged and | ||
|
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,97 @@ | ||
# REQUIRES: x86 | ||
|
||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux --defsym DWARF32=1 %s -o %t.o | ||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux --defsym DWARF32=1 %s -o %t1.o | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. You can do
|
||
# RUN: ld.lld %t.o %t1.o -o %t1 | ||
# RUN: llvm-objdump -s %t1 | FileCheck %s --check-prefix=CHECK32 | ||
|
||
# Test checks that LLD tombstones TU section that was de-duplicated using COMDAT to the maxium value. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. For newer tests we use |
||
|
||
# CHECK32:Contents of section .debug_names: | ||
# CHECK32-NEXT: 0000 37000000 05000000 00000000 01000000 7............... | ||
# CHECK32-NEXT: 0010 00000000 00000000 00000000 03000000 ................ | ||
# CHECK32-NEXT: 0020 08000000 4c4c564d 30373030 00000000 ....LLVM0700.... | ||
# CHECK32-NEXT: 0030 00000000 00000000 00000037 00000005 ...........7.... | ||
# CHECK32-NEXT: 0040 00000000 00000001 00000000 00000000 ................ | ||
# CHECK32-NEXT: 0050 00000000 00000003 00000008 0000004c ...............L | ||
# CHECK32-NEXT: 0060 4c564d30 37303000 000000ff ffffff00 LVM0700......... | ||
|
||
|
||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux --defsym DWARF64=1 %s -o %t.o | ||
# RUN: llvm-mc -filetype=obj -triple=x86_64-unknown-linux --defsym DWARF64=1 %s -o %t1.o | ||
# RUN: ld.lld %t.o %t1.o -o %t1 | ||
# RUN: llvm-objdump -s %t1 | FileCheck %s --check-prefix=CHECK64 | ||
|
||
# Test checks that LLD tombstones TU section that was de-duplicated using COMDAT to the maxium value. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. ditto |
||
|
||
# CHECK64: Contents of section .debug_names: | ||
# CHECK64-NEXT: 0000 ffffffff 3f000000 00000000 05000000 ....?........... | ||
# CHECK64-NEXT: 0010 00000000 01000000 00000000 00000000 ................ | ||
# CHECK64-NEXT: 0020 00000000 03000000 08000000 4c4c564d ............LLVM | ||
# CHECK64-NEXT: 0030 30373030 00000000 00000000 00000000 0700............ | ||
# CHECK64-NEXT: 0040 00000000 00000000 000000ff ffffff3f ...............? | ||
# CHECK64-NEXT: 0050 00000000 00000005 00000000 00000001 ................ | ||
# CHECK64-NEXT: 0060 00000000 00000000 00000000 00000003 ................ | ||
# CHECK64-NEXT: 0070 00000008 0000004c 4c564d30 37303000 .......LLVM0700. | ||
# CHECK64-NEXT: 0080 00000000 000000ff ffffffff ffffff00 ................ | ||
|
||
# Test generated with clang++ -g2 -gdwarf-5 -gpubnames -fdebug-types-section -S and then manually reduced. | ||
.ifdef DWARF32 | ||
.section .debug_info,"G",@progbits,1175092228111723119,comdat | ||
.Ltu_begin0: | ||
.section .debug_names,"",@progbits | ||
.long .Lnames_end0-.Lnames_start0 # Header: unit length | ||
.Lnames_start0: | ||
.short 5 # Header: version | ||
.short 0 # Header: padding | ||
.long 0 # Header: compilation unit count | ||
.long 1 # Header: local type unit count | ||
.long 0 # Header: foreign type unit count | ||
.long 0 # Header: bucket count | ||
.long 0 # Header: name count | ||
.long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size | ||
.long 8 # Header: augmentation string size | ||
.ascii "LLVM0700" # Header: augmentation string | ||
.long 0 # Compilation unit 0 | ||
.long .Ltu_begin0 # Type unit 0 | ||
.long 0 # Bucket 0 | ||
|
||
.Lnames_abbrev_start0: | ||
.byte 0 # End of abbrev | ||
.byte 0 # End of abbrev | ||
.byte 0 # End of abbrev list | ||
.Lnames_abbrev_end0: | ||
.Lnames_entries0: | ||
.Lnames_end0: | ||
.endif | ||
|
||
# Test generated with clang++ -g2 -gdwarf-5 -gdwarf64 -gpubnames -fdebug-types-section -S and then manually reduced. | ||
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. This needs a C++ source example. |
||
.ifdef DWARF64 | ||
.section .debug_info,"G",@progbits,1175092228111723119,comdat | ||
.Ltu_begin0: | ||
.section .debug_names,"",@progbits | ||
.long 4294967295 # DWARF64 Mark | ||
.quad .Lnames_end0-.Lnames_start0 # Header: unit length | ||
.Lnames_start0: | ||
.short 5 # Header: version | ||
.short 0 # Header: padding | ||
.long 0 # Header: compilation unit count | ||
.long 1 # Header: local type unit count | ||
.long 0 # Header: foreign type unit count | ||
.long 0 # Header: bucket count | ||
.long 0 # Header: name count | ||
.long .Lnames_abbrev_end0-.Lnames_abbrev_start0 # Header: abbreviation table size | ||
.long 8 # Header: augmentation string size | ||
.ascii "LLVM0700" # Header: augmentation string | ||
.quad 0 # Compilation unit 0 | ||
.quad .Ltu_begin0 # Type unit 0 | ||
.long 0 # Bucket 0 | ||
|
||
.Lnames_abbrev_start0: | ||
.byte 0 # End of abbrev | ||
.byte 0 # End of abbrev | ||
.byte 0 # End of abbrev list | ||
.Lnames_abbrev_end0: | ||
.Lnames_entries0: | ||
.Lnames_end0: | ||
.endif |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
We should keep the headers. mutex is used by std::mutex in this file.