29
29
#include " Target.h"
30
30
#include " lld/Common/CommonLinkerContext.h"
31
31
#include " lld/Common/Strings.h"
32
+ #include " llvm/ADT/DenseMapInfoVariant.h"
32
33
#include " llvm/ADT/STLExtras.h"
33
34
#include " llvm/Object/ELF.h"
34
35
#include " llvm/Support/TimeProfiler.h"
36
+ #include < variant>
35
37
#include < vector>
36
38
37
39
using namespace llvm ;
@@ -42,6 +44,10 @@ using namespace lld;
42
44
using namespace lld ::elf;
43
45
44
46
namespace {
47
+
48
+ // Something that can be the most proximate reason that something else is alive.
49
+ typedef std::variant<InputSectionBase *, Symbol *> LiveReason;
50
+
45
51
template <class ELFT > class MarkLive {
46
52
public:
47
53
MarkLive (Ctx &ctx, unsigned partition) : ctx(ctx), partition(partition) {}
@@ -50,7 +56,10 @@ template <class ELFT> class MarkLive {
50
56
void moveToMain ();
51
57
52
58
private:
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 ;
54
63
void markSymbol (Symbol *sym);
55
64
void mark ();
56
65
@@ -70,6 +79,12 @@ template <class ELFT> class MarkLive {
70
79
// There are normally few input sections whose names are valid C
71
80
// identifiers, so we just store a SmallVector instead of a multimap.
72
81
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;
73
88
};
74
89
} // namespace
75
90
@@ -101,6 +116,12 @@ void MarkLive<ELFT>::resolveReloc(InputSectionBase &sec, RelTy &rel,
101
116
Symbol &sym = sec.file ->getRelocTargetSym (rel);
102
117
sym.used = true ;
103
118
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
+
104
125
if (auto *d = dyn_cast<Defined>(&sym)) {
105
126
auto *relSec = dyn_cast_or_null<InputSectionBase>(d->section );
106
127
if (!relSec)
@@ -119,17 +140,29 @@ void MarkLive<ELFT>::resolveReloc(InputSectionBase &sec, RelTy &rel,
119
140
// group/SHF_LINK_ORDER rules (b) if the associated text section should be
120
141
// discarded, marking the LSDA will unnecessarily retain the text section.
121
142
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
+ }
124
153
return ;
125
154
}
126
155
127
- if (auto *ss = dyn_cast<SharedSymbol>(&sym))
128
- if (!ss->isWeak ())
156
+ if (auto *ss = dyn_cast<SharedSymbol>(&sym)) {
157
+ if (!ss->isWeak ()) {
129
158
cast<SharedFile>(ss->file )->isNeeded = true ;
159
+ if (!ctx.arg .whyLive .empty ())
160
+ whyLive.try_emplace (&sym, reason);
161
+ }
162
+ }
130
163
131
164
for (InputSectionBase *sec : cNamedSections.lookup (sym.getName ()))
132
- enqueue (sec, 0 );
165
+ enqueue (sec, 0 , nullptr , reason );
133
166
}
134
167
135
168
// The .eh_frame section is an unfortunate special case.
@@ -187,7 +220,8 @@ static bool isReserved(InputSectionBase *sec) {
187
220
}
188
221
189
222
template <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) {
191
225
// Usually, a whole section is marked as live or dead, but in mergeable
192
226
// (splittable) sections, each piece of data has independent liveness bit.
193
227
// So we explicitly tell it which offset is in use.
@@ -201,15 +235,71 @@ void MarkLive<ELFT>::enqueue(InputSectionBase *sec, uint64_t offset) {
201
235
return ;
202
236
sec->partition = sec->partition ? 1 : partition;
203
237
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
+
204
250
// Add input section to the queue.
205
251
if (InputSection *s = dyn_cast<InputSection>(sec))
206
252
queue.push_back (s);
207
253
}
208
254
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
+
209
299
template <class ELFT > void MarkLive<ELFT>::markSymbol(Symbol *sym) {
210
300
if (auto *d = dyn_cast_or_null<Defined>(sym))
211
301
if (auto *isec = dyn_cast_or_null<InputSectionBase>(d->section ))
212
- enqueue (isec, d->value );
302
+ enqueue (isec, d->value , sym );
213
303
}
214
304
215
305
// This is the main function of the garbage collector.
@@ -256,7 +346,7 @@ template <class ELFT> void MarkLive<ELFT>::run() {
256
346
}
257
347
for (InputSectionBase *sec : ctx.inputSections ) {
258
348
if (sec->flags & SHF_GNU_RETAIN) {
259
- enqueue (sec, 0 );
349
+ enqueue (sec, 0 , nullptr , std::nullopt );
260
350
continue ;
261
351
}
262
352
if (sec->flags & SHF_LINK_ORDER)
@@ -295,7 +385,7 @@ template <class ELFT> void MarkLive<ELFT>::run() {
295
385
// Preserve special sections and those which are specified in linker
296
386
// script KEEP command.
297
387
if (isReserved (sec) || ctx.script ->shouldKeep (sec)) {
298
- enqueue (sec, 0 );
388
+ enqueue (sec);
299
389
} else if ((!ctx.arg .zStartStopGC || sec->name .starts_with (" __libc_" )) &&
300
390
isValidCIdentifier (sec->name )) {
301
391
// As a workaround for glibc libc.a before 2.34
@@ -323,11 +413,20 @@ template <class ELFT> void MarkLive<ELFT>::mark() {
323
413
resolveReloc (sec, rel, false );
324
414
325
415
for (InputSectionBase *isec : sec.dependentSections )
326
- enqueue (isec, 0 );
416
+ enqueue (isec, 0 , nullptr , &sec );
327
417
328
418
// Mark the next group member.
329
419
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
+ }
331
430
}
332
431
}
333
432
@@ -353,7 +452,7 @@ template <class ELFT> void MarkLive<ELFT>::moveToMain() {
353
452
continue ;
354
453
if (ctx.symtab ->find ((" __start_" + sec->name ).str ()) ||
355
454
ctx.symtab ->find ((" __stop_" + sec->name ).str ()))
356
- enqueue (sec, 0 );
455
+ enqueue (sec);
357
456
}
358
457
359
458
mark ();
0 commit comments