[ELF] --why-live: Skip symbol at index 0 and section symbols, handle .eh_frame symbols (#177099)
Symbols of empty names can be matched by `--why-live='*'`, which are
generally not useful.
* The first entry in a symbol table (STB_LOCAL and undefined)
* `STT_SECTION` symbols (emitted by LLVM integrated assembler when
needed by relocations). These input section symbols will be demoted by
`demoteAndCopyLocalSymbols`, so technically not really live.
In addition, such symbols of non-allocable sections currently lead to
crashes: `whyLive` does not record the section, causing the second
iteration of the `while (true)` loop in printWhyLive to call
`std::get<Symbol *>(cur)` when `cur` is an `InputSectionBase *`.
In addition, handle GCC crtendS.o `__FRAME_END__`, which is defined
relative to a `.eh_frame` section created with
`__attribute__((used, section(".eh_frame")))`.
Fix #176890
This commit is contained in:
@@ -202,6 +202,9 @@ void MarkLive<ELFT, TrackWhyLive>::resolveReloc(InputSectionBase &sec,
|
||||
// LSDAs and personality functions if we found that they were unused.
|
||||
template <class ELFT, bool TrackWhyLive>
|
||||
void MarkLive<ELFT, TrackWhyLive>::scanEhFrameSection(EhInputSection &eh) {
|
||||
if (TrackWhyLive)
|
||||
whyLive.try_emplace(&eh,
|
||||
LiveReason{std::nullopt, "exception handling frame"});
|
||||
ArrayRef<Relocation> rels = eh.rels;
|
||||
for (const EhSectionPiece &cie : eh.cies)
|
||||
if (cie.firstRelocation != unsigned(-1))
|
||||
@@ -443,9 +446,13 @@ void MarkLive<ELFT, TrackWhyLive>::run() {
|
||||
|
||||
for (Symbol *sym : ctx.symtab->getSymbols())
|
||||
handleSym(sym);
|
||||
// Handle local symbols, skipping the symbol at index 0 and section
|
||||
// symbols, which usually have empty names and technically not live. Note:
|
||||
// a live section may lack an associated section symbol, making them
|
||||
// unreliable liveness indicators.
|
||||
for (ELFFileBase *file : ctx.objectFiles)
|
||||
for (Symbol *sym : file->getSymbols())
|
||||
if (sym->isLocal())
|
||||
if (sym->isLocal() && sym->isDefined() && !sym->isSection())
|
||||
handleSym(sym);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
# RUN: llvm-mc -n -filetype=obj -triple=x86_64 -o shared.o shared.s
|
||||
# RUN: ld.lld -shared shared.o -o a.so
|
||||
# RUN: llvm-mc -n -filetype=obj -triple=x86_64 -o a.o a.s
|
||||
# RUN: llvm-mc -n -filetype=obj -triple=x86_64 -o b.o b.s
|
||||
|
||||
#--- shared.s
|
||||
.globl test_shared
|
||||
@@ -159,3 +160,46 @@ test_local:
|
||||
# MULTIPLE-DAG: live symbol: a.o:(test_section_offset)
|
||||
# MULTIPLE-DAG: live symbol: a.o:(test_section_offset_within_symbol)
|
||||
# MULTIPLE-NOT: live symbol
|
||||
|
||||
#--- b.s
|
||||
## --why-live='*' skips symbol at index 0 and section symbols.
|
||||
# RUN: ld.lld b.o --threads=1 --gc-sections --why-live="*" | FileCheck %s --check-prefix=STAR --match-full-lines
|
||||
# STAR-NOT: {{.}}
|
||||
# STAR: live symbol: b.o:(_start) (entry point)
|
||||
# STAR-NEXT: live symbol: b.o:(b.s) (no section)
|
||||
# STAR-NEXT: live symbol: b.o:(str1)
|
||||
# STAR-NEXT: >>> referenced by: b.o:(.alloc)
|
||||
# STAR-NEXT: >>> referenced by: b.o:(.text)
|
||||
# STAR-NEXT: >>> contained live symbol: b.o:(_start) (entry point)
|
||||
# STAR-NEXT: live symbol: b.o:(note1)
|
||||
# STAR-NEXT: >>> in live section: b.o:(.note.1) (reserved)
|
||||
# STAR-NEXT: live symbol: b.o:(__FRAME_END__)
|
||||
# STAR-NEXT: >>> in live section: b.o:(.eh_frame) (exception handling frame)
|
||||
# STAR-NOT: {{.}}
|
||||
|
||||
## STT_FILE symbol
|
||||
.file "b.s"
|
||||
|
||||
.text
|
||||
.globl _start
|
||||
_start:
|
||||
call .alloc
|
||||
|
||||
.section .alloc,"a"
|
||||
lea str1(%rip), %rax
|
||||
|
||||
.section .nonalloc
|
||||
.long .nonalloc
|
||||
|
||||
.section .note.1,"a",@note
|
||||
note1:
|
||||
|
||||
## GCC crtendS.o has such a local symbol relative to an explicit .eh_frame
|
||||
## section.
|
||||
.section .eh_frame,"a"
|
||||
__FRAME_END__:
|
||||
.long 0
|
||||
|
||||
.section .rodata.str1.1,"aMS",@progbits,1
|
||||
str1:
|
||||
.asciz "str1"
|
||||
|
||||
Reference in New Issue
Block a user