2929#include " Target.h"
3030#include " lld/Common/CommonLinkerContext.h"
3131#include " lld/Common/Strings.h"
32+ #include " llvm/ADT/DenseMapInfoVariant.h"
3233#include " llvm/ADT/STLExtras.h"
3334#include " llvm/Object/ELF.h"
3435#include " llvm/Support/TimeProfiler.h"
36+ #include < variant>
3537#include < vector>
3638
3739using namespace llvm ;
@@ -42,6 +44,10 @@ using namespace lld;
4244using namespace lld ::elf;
4345
4446namespace {
47+
48+ // Something that can be the most proximate reason that something else is alive.
49+ typedef std::variant<InputSectionBase *, Symbol *> LiveReason;
50+
4551template <class ELFT > class MarkLive {
4652public:
4753 MarkLive (Ctx &ctx, unsigned partition) : ctx(ctx), partition(partition) {}
@@ -50,7 +56,10 @@ template <class ELFT> class MarkLive {
5056 void moveToMain ();
5157
5258private:
53- void enqueue (InputSectionBase *sec, uint64_t offset);
59+ void enqueue (InputSectionBase *sec, uint64_t offset = 0 ,
60+ Symbol *sym = nullptr ,
61+ std::optional<LiveReason> reason = std::nullopt );
62+ void printWhyLive (Symbol *s) const ;
5463 void markSymbol (Symbol *sym);
5564 void mark ();
5665
@@ -70,6 +79,12 @@ template <class ELFT> class MarkLive {
7079 // There are normally few input sections whose names are valid C
7180 // identifiers, so we just store a SmallVector instead of a multimap.
7281 DenseMap<StringRef, SmallVector<InputSectionBase *, 0 >> cNamedSections;
82+
83+ // The most proximate reason that something is live. If something doesn't have
84+ // a recorded reason, it is either dead, intrinsically live, or an
85+ // unreferenced symbol in a live section. (These cases are trivially
86+ // detectable and need not be stored.)
87+ DenseMap<LiveReason, LiveReason> whyLive;
7388};
7489} // namespace
7590
@@ -101,6 +116,12 @@ void MarkLive<ELFT>::resolveReloc(InputSectionBase &sec, RelTy &rel,
101116 Symbol &sym = sec.file ->getRelocTargetSym (rel);
102117 sym.used = true ;
103118
119+ LiveReason reason;
120+ if (!ctx.arg .whyLive .empty ()) {
121+ Defined *reasonSym = sec.getEnclosingSymbol (rel.r_offset );
122+ reason = reasonSym ? LiveReason (reasonSym) : LiveReason (&sec);
123+ }
124+
104125 if (auto *d = dyn_cast<Defined>(&sym)) {
105126 auto *relSec = dyn_cast_or_null<InputSectionBase>(d->section );
106127 if (!relSec)
@@ -119,17 +140,29 @@ void MarkLive<ELFT>::resolveReloc(InputSectionBase &sec, RelTy &rel,
119140 // group/SHF_LINK_ORDER rules (b) if the associated text section should be
120141 // discarded, marking the LSDA will unnecessarily retain the text section.
121142 if (!(fromFDE && ((relSec->flags & (SHF_EXECINSTR | SHF_LINK_ORDER)) ||
122- relSec->nextInSectionGroup )))
123- enqueue (relSec, offset);
143+ relSec->nextInSectionGroup ))) {
144+ Symbol *canonicalSym = d;
145+ if (!ctx.arg .whyLive .empty () && d->isSection ()) {
146+ if (Symbol *s = relSec->getEnclosingSymbol (offset))
147+ canonicalSym = s;
148+ else
149+ canonicalSym = nullptr ;
150+ }
151+ enqueue (relSec, offset, canonicalSym, reason);
152+ }
124153 return ;
125154 }
126155
127- if (auto *ss = dyn_cast<SharedSymbol>(&sym))
128- if (!ss->isWeak ())
156+ if (auto *ss = dyn_cast<SharedSymbol>(&sym)) {
157+ if (!ss->isWeak ()) {
129158 cast<SharedFile>(ss->file )->isNeeded = true ;
159+ if (!ctx.arg .whyLive .empty ())
160+ whyLive.try_emplace (&sym, reason);
161+ }
162+ }
130163
131164 for (InputSectionBase *sec : cNamedSections.lookup (sym.getName ()))
132- enqueue (sec, 0 );
165+ enqueue (sec, 0 , nullptr , reason );
133166}
134167
135168// The .eh_frame section is an unfortunate special case.
@@ -187,7 +220,8 @@ static bool isReserved(InputSectionBase *sec) {
187220}
188221
189222template <class ELFT >
190- void MarkLive<ELFT>::enqueue(InputSectionBase *sec, uint64_t offset) {
223+ void MarkLive<ELFT>::enqueue(InputSectionBase *sec, uint64_t offset,
224+ Symbol *sym, std::optional<LiveReason> reason) {
191225 // Usually, a whole section is marked as live or dead, but in mergeable
192226 // (splittable) sections, each piece of data has independent liveness bit.
193227 // So we explicitly tell it which offset is in use.
@@ -201,15 +235,71 @@ void MarkLive<ELFT>::enqueue(InputSectionBase *sec, uint64_t offset) {
201235 return ;
202236 sec->partition = sec->partition ? 1 : partition;
203237
238+ if (!ctx.arg .whyLive .empty () && reason) {
239+ if (sym) {
240+ // If a specific symbol is referenced, that makes it alive. It may in turn
241+ // make its section alive.
242+ whyLive.try_emplace (sym, *reason);
243+ whyLive.try_emplace (sec, sym);
244+ } else {
245+ // Otherwise, the reference generically makes the section live.
246+ whyLive.try_emplace (sec, *reason);
247+ }
248+ }
249+
204250 // Add input section to the queue.
205251 if (InputSection *s = dyn_cast<InputSection>(sec))
206252 queue.push_back (s);
207253}
208254
255+ // Print the stack of reasons that the given symbol is live.
256+ template <class ELFT > void MarkLive<ELFT>::printWhyLive(Symbol *s) const {
257+ // Skip dead symbols. A symbol is dead if it belongs to a dead section.
258+ if (auto *d = dyn_cast<Defined>(s)) {
259+ auto *reason = dyn_cast_or_null<InputSectionBase>(d->section );
260+ if (reason && !reason->isLive ())
261+ return ;
262+ }
263+
264+ auto msg = Msg (ctx);
265+ msg << " live symbol: " << toStr (ctx, *s);
266+
267+ LiveReason cur = s;
268+ while (true ) {
269+ auto it = whyLive.find (cur);
270+ // If there is a specific reason this object is live...
271+ if (it != whyLive.end ()) {
272+ cur = it->second ;
273+ } else {
274+ // This object is live, but it has no tracked reason. It is either
275+ // intrinsically live or an unreferenced symbol in a live section. Return
276+ // in the first case.
277+ if (!std::holds_alternative<Symbol *>(cur))
278+ return ;
279+ auto *d = dyn_cast<Defined>(std::get<Symbol *>(cur));
280+ if (!d)
281+ return ;
282+ auto *reason = dyn_cast_or_null<InputSectionBase>(d->section );
283+ if (!reason)
284+ return ;
285+ cur = LiveReason{reason};
286+ }
287+
288+ msg << " \n >>> kept live by " ;
289+ if (std::holds_alternative<Symbol *>(cur)) {
290+ auto *s = std::get<Symbol *>(cur);
291+ msg << toStr (ctx, *s);
292+ } else {
293+ auto *s = std::get<InputSectionBase *>(cur);
294+ msg << toStr (ctx, s);
295+ }
296+ }
297+ }
298+
209299template <class ELFT > void MarkLive<ELFT>::markSymbol(Symbol *sym) {
210300 if (auto *d = dyn_cast_or_null<Defined>(sym))
211301 if (auto *isec = dyn_cast_or_null<InputSectionBase>(d->section ))
212- enqueue (isec, d->value );
302+ enqueue (isec, d->value , sym );
213303}
214304
215305// This is the main function of the garbage collector.
@@ -256,7 +346,7 @@ template <class ELFT> void MarkLive<ELFT>::run() {
256346 }
257347 for (InputSectionBase *sec : ctx.inputSections ) {
258348 if (sec->flags & SHF_GNU_RETAIN) {
259- enqueue (sec, 0 );
349+ enqueue (sec, 0 , nullptr , std:: nullopt );
260350 continue ;
261351 }
262352 if (sec->flags & SHF_LINK_ORDER)
@@ -295,7 +385,7 @@ template <class ELFT> void MarkLive<ELFT>::run() {
295385 // Preserve special sections and those which are specified in linker
296386 // script KEEP command.
297387 if (isReserved (sec) || ctx.script ->shouldKeep (sec)) {
298- enqueue (sec, 0 );
388+ enqueue (sec);
299389 } else if ((!ctx.arg .zStartStopGC || sec->name .starts_with (" __libc_" )) &&
300390 isValidCIdentifier (sec->name )) {
301391 // As a workaround for glibc libc.a before 2.34
@@ -323,11 +413,20 @@ template <class ELFT> void MarkLive<ELFT>::mark() {
323413 resolveReloc (sec, rel, false );
324414
325415 for (InputSectionBase *isec : sec.dependentSections )
326- enqueue (isec, 0 );
416+ enqueue (isec, 0 , nullptr , &sec );
327417
328418 // Mark the next group member.
329419 if (sec.nextInSectionGroup )
330- enqueue (sec.nextInSectionGroup , 0 );
420+ enqueue (sec.nextInSectionGroup , 0 , nullptr , &sec);
421+ }
422+
423+ if (!ctx.arg .whyLive .empty ()) {
424+ for (Symbol *sym : ctx.symtab ->getSymbols ()) {
425+ if (llvm::any_of (ctx.arg .whyLive , [sym](const llvm::GlobPattern &pat) {
426+ return pat.match (sym->getName ());
427+ }))
428+ printWhyLive (sym);
429+ }
331430 }
332431}
333432
@@ -353,7 +452,7 @@ template <class ELFT> void MarkLive<ELFT>::moveToMain() {
353452 continue ;
354453 if (ctx.symtab ->find ((" __start_" + sec->name ).str ()) ||
355454 ctx.symtab ->find ((" __stop_" + sec->name ).str ()))
356- enqueue (sec, 0 );
455+ enqueue (sec);
357456 }
358457
359458 mark ();
0 commit comments