@@ -80,11 +80,11 @@ template <class ELFT, bool TrackWhyLive> class MarkLive {
80
80
// identifiers, so we just store a SmallVector instead of a multimap.
81
81
DenseMap<StringRef, SmallVector<InputSectionBase *, 0 >> cNamedSections;
82
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;
83
+ // The most proximate reason that something is live. A nullopt means
84
+ // "intrinsically live". If something doesn't have a recorded reason, it is
85
+ // either dead or an unreferenced symbol in a live section. (These cases are
86
+ // trivially detectable and need not be stored.)
87
+ DenseMap<LiveReason, std::optional< LiveReason> > whyLive;
88
88
};
89
89
} // namespace
90
90
@@ -157,7 +157,7 @@ void MarkLive<ELFT, TrackWhyLive>::resolveReloc(InputSectionBase &sec,
157
157
if (!ss->isWeak ()) {
158
158
cast<SharedFile>(ss->file )->isNeeded = true ;
159
159
if (TrackWhyLive)
160
- whyLive.try_emplace (&sym, * reason);
160
+ whyLive.try_emplace (&sym, reason);
161
161
}
162
162
}
163
163
@@ -236,15 +236,15 @@ void MarkLive<ELFT, TrackWhyLive>::enqueue(InputSectionBase *sec,
236
236
return ;
237
237
sec->partition = sec->partition ? 1 : partition;
238
238
239
- if (TrackWhyLive && reason ) {
239
+ if (TrackWhyLive) {
240
240
if (sym) {
241
241
// If a specific symbol is referenced, that makes it alive. It may in turn
242
242
// make its section alive.
243
- whyLive.try_emplace (sym, * reason);
243
+ whyLive.try_emplace (sym, reason);
244
244
whyLive.try_emplace (sec, sym);
245
245
} else {
246
246
// Otherwise, the reference generically makes the section live.
247
- whyLive.try_emplace (sec, * reason);
247
+ whyLive.try_emplace (sec, reason);
248
248
}
249
249
}
250
250
@@ -264,37 +264,45 @@ void MarkLive<ELFT, TrackWhyLive>::printWhyLive(Symbol *s) const {
264
264
}
265
265
266
266
auto msg = Msg (ctx);
267
- msg << " live symbol: " << toStr (ctx, *s);
268
267
269
- LiveReason cur = s;
268
+ const auto printSymbol = [&](Symbol *s) {
269
+ if (s->isLocal ())
270
+ msg << s->file << " :(" << toStr (ctx, *s) << ' )' ;
271
+ else
272
+ msg << toStr (ctx, *s);
273
+ };
274
+
275
+ msg << " live symbol: " ;
276
+ printSymbol (s);
277
+
278
+ std::optional<LiveReason> cur = s;
270
279
while (true ) {
271
- auto it = whyLive.find (cur);
280
+ auto it = whyLive.find (* cur);
272
281
// If there is a specific reason this object is live...
273
282
if (it != whyLive.end ()) {
274
283
cur = it->second ;
275
284
} else {
276
285
// This object is live, but it has no tracked reason. It is either
277
286
// intrinsically live or an unreferenced symbol in a live section. Return
278
287
// in the first case.
279
- if (!std::holds_alternative<Symbol *>(cur))
288
+ if (!std::holds_alternative<Symbol *>(* cur))
280
289
return ;
281
- auto *d = dyn_cast<Defined>(std::get<Symbol *>(cur));
290
+ auto *d = dyn_cast<Defined>(std::get<Symbol *>(* cur));
282
291
if (!d)
283
292
return ;
284
293
auto *reason = dyn_cast_or_null<InputSectionBase>(d->section );
285
294
if (!reason)
286
295
return ;
287
296
cur = LiveReason{reason};
288
297
}
298
+ if (!cur)
299
+ break ;
289
300
290
301
msg << " \n >>> kept live by " ;
291
- if (std::holds_alternative<Symbol *>(cur)) {
292
- auto *s = std::get<Symbol *>(cur);
293
- msg << toStr (ctx, *s);
294
- } else {
295
- auto *s = std::get<InputSectionBase *>(cur);
296
- msg << toStr (ctx, s);
297
- }
302
+ if (std::holds_alternative<Symbol *>(*cur))
303
+ printSymbol (std::get<Symbol *>(*cur));
304
+ else
305
+ msg << toStr (ctx, std::get<InputSectionBase *>(*cur));
298
306
}
299
307
}
300
308
@@ -403,12 +411,19 @@ void MarkLive<ELFT, TrackWhyLive>::run() {
403
411
mark ();
404
412
405
413
if (TrackWhyLive) {
406
- for (Symbol *sym : ctx. symtab -> getSymbols () ) {
414
+ const auto handleSym = [&] (Symbol *sym) {
407
415
if (llvm::any_of (ctx.arg .whyLive , [sym](const llvm::GlobPattern &pat) {
408
416
return pat.match (sym->getName ());
409
417
}))
410
418
printWhyLive (sym);
411
- }
419
+ };
420
+
421
+ for (Symbol *sym : ctx.symtab ->getSymbols ())
422
+ handleSym (sym);
423
+ for (ELFFileBase *file : ctx.objectFiles )
424
+ for (Symbol *sym : file->getSymbols ())
425
+ if (sym->isLocal ())
426
+ handleSym (sym);
412
427
}
413
428
}
414
429
0 commit comments