https://github.com/c-rhodes updated 
https://github.com/llvm/llvm-project/pull/177306

>From c8122e4004d2b7a9a286f4c07b3928aadb915423 Mon Sep 17 00:00:00 2001
From: Fangrui Song <[email protected]>
Date: Wed, 21 Jan 2026 18:58:35 -0800
Subject: [PATCH] [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

(cherry picked from commit 1869b15a0569e4e0fa0b97ee462db4e826519d4f)
---
 lld/ELF/MarkLive.cpp       |  9 +++++++-
 lld/test/ELF/why-live.test | 44 ++++++++++++++++++++++++++++++++++++++
 2 files changed, 52 insertions(+), 1 deletion(-)

diff --git a/lld/ELF/MarkLive.cpp b/lld/ELF/MarkLive.cpp
index a7b0f08c8d954..c43022a6b9d3f 100644
--- a/lld/ELF/MarkLive.cpp
+++ b/lld/ELF/MarkLive.cpp
@@ -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);
   }
 }
diff --git a/lld/test/ELF/why-live.test b/lld/test/ELF/why-live.test
index d8f8cc7b6db64..a281f9942985e 100644
--- a/lld/test/ELF/why-live.test
+++ b/lld/test/ELF/why-live.test
@@ -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"

_______________________________________________
llvm-branch-commits mailing list
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/llvm-branch-commits

Reply via email to