Thanks to visit codestin.com
Credit goes to github.com

Skip to content

Commit 1869b15

Browse files
authored
[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
1 parent b57dcff commit 1869b15

2 files changed

Lines changed: 52 additions & 1 deletion

File tree

lld/ELF/MarkLive.cpp

Lines changed: 8 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -202,6 +202,9 @@ void MarkLive<ELFT, TrackWhyLive>::resolveReloc(InputSectionBase &sec,
202202
// LSDAs and personality functions if we found that they were unused.
203203
template <class ELFT, bool TrackWhyLive>
204204
void MarkLive<ELFT, TrackWhyLive>::scanEhFrameSection(EhInputSection &eh) {
205+
if (TrackWhyLive)
206+
whyLive.try_emplace(&eh,
207+
LiveReason{std::nullopt, "exception handling frame"});
205208
ArrayRef<Relocation> rels = eh.rels;
206209
for (const EhSectionPiece &cie : eh.cies)
207210
if (cie.firstRelocation != unsigned(-1))
@@ -443,9 +446,13 @@ void MarkLive<ELFT, TrackWhyLive>::run() {
443446

444447
for (Symbol *sym : ctx.symtab->getSymbols())
445448
handleSym(sym);
449+
// Handle local symbols, skipping the symbol at index 0 and section
450+
// symbols, which usually have empty names and technically not live. Note:
451+
// a live section may lack an associated section symbol, making them
452+
// unreliable liveness indicators.
446453
for (ELFFileBase *file : ctx.objectFiles)
447454
for (Symbol *sym : file->getSymbols())
448-
if (sym->isLocal())
455+
if (sym->isLocal() && sym->isDefined() && !sym->isSection())
449456
handleSym(sym);
450457
}
451458
}

lld/test/ELF/why-live.test

Lines changed: 44 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,7 @@
44
# RUN: llvm-mc -n -filetype=obj -triple=x86_64 -o shared.o shared.s
55
# RUN: ld.lld -shared shared.o -o a.so
66
# RUN: llvm-mc -n -filetype=obj -triple=x86_64 -o a.o a.s
7+
# RUN: llvm-mc -n -filetype=obj -triple=x86_64 -o b.o b.s
78

89
#--- shared.s
910
.globl test_shared
@@ -159,3 +160,46 @@ test_local:
159160
# MULTIPLE-DAG: live symbol: a.o:(test_section_offset)
160161
# MULTIPLE-DAG: live symbol: a.o:(test_section_offset_within_symbol)
161162
# MULTIPLE-NOT: live symbol
163+
164+
#--- b.s
165+
## --why-live='*' skips symbol at index 0 and section symbols.
166+
# RUN: ld.lld b.o --threads=1 --gc-sections --why-live="*" | FileCheck %s --check-prefix=STAR --match-full-lines
167+
# STAR-NOT: {{.}}
168+
# STAR: live symbol: b.o:(_start) (entry point)
169+
# STAR-NEXT: live symbol: b.o:(b.s) (no section)
170+
# STAR-NEXT: live symbol: b.o:(str1)
171+
# STAR-NEXT: >>> referenced by: b.o:(.alloc)
172+
# STAR-NEXT: >>> referenced by: b.o:(.text)
173+
# STAR-NEXT: >>> contained live symbol: b.o:(_start) (entry point)
174+
# STAR-NEXT: live symbol: b.o:(note1)
175+
# STAR-NEXT: >>> in live section: b.o:(.note.1) (reserved)
176+
# STAR-NEXT: live symbol: b.o:(__FRAME_END__)
177+
# STAR-NEXT: >>> in live section: b.o:(.eh_frame) (exception handling frame)
178+
# STAR-NOT: {{.}}
179+
180+
## STT_FILE symbol
181+
.file "b.s"
182+
183+
.text
184+
.globl _start
185+
_start:
186+
call .alloc
187+
188+
.section .alloc,"a"
189+
lea str1(%rip), %rax
190+
191+
.section .nonalloc
192+
.long .nonalloc
193+
194+
.section .note.1,"a",@note
195+
note1:
196+
197+
## GCC crtendS.o has such a local symbol relative to an explicit .eh_frame
198+
## section.
199+
.section .eh_frame,"a"
200+
__FRAME_END__:
201+
.long 0
202+
203+
.section .rodata.str1.1,"aMS",@progbits,1
204+
str1:
205+
.asciz "str1"

0 commit comments

Comments
 (0)