@@ -41,66 +41,72 @@ using namespace llvm::support::endian;
41
41
using namespace lld ;
42
42
using namespace lld ::elf;
43
43
44
+ namespace {
45
+ template <class ELFT > class MarkLive {
46
+ public:
47
+ void run ();
48
+
49
+ private:
50
+ void enqueue (InputSectionBase *Sec, uint64_t Offset);
51
+ void markSymbol (Symbol *Sym);
52
+
53
+ template <class RelTy >
54
+ void resolveReloc (InputSectionBase &Sec, RelTy &Rel, bool IsLSDA);
55
+
56
+ template <class RelTy >
57
+ void scanEhFrameSection (EhInputSection &EH, ArrayRef<RelTy> Rels);
58
+
59
+ // A list of sections to visit.
60
+ SmallVector<InputSection *, 256 > Queue;
61
+
62
+ // There are normally few input sections whose names are valid C
63
+ // identifiers, so we just store a std::vector instead of a multimap.
64
+ DenseMap<StringRef, std::vector<InputSectionBase *>> CNamedSections;
65
+ };
66
+ } // namespace
67
+
44
68
template <class ELFT >
45
- static typename ELFT:: uint getAddend (InputSectionBase &Sec,
46
- const typename ELFT::Rel &Rel) {
69
+ static uint64_t getAddend (InputSectionBase &Sec,
70
+ const typename ELFT::Rel &Rel) {
47
71
return Target->getImplicitAddend (Sec.data ().begin () + Rel.r_offset ,
48
72
Rel.getType (Config->IsMips64EL ));
49
73
}
50
74
51
75
template <class ELFT >
52
- static typename ELFT:: uint getAddend (InputSectionBase &Sec,
53
- const typename ELFT::Rela &Rel) {
76
+ static uint64_t getAddend (InputSectionBase &Sec,
77
+ const typename ELFT::Rela &Rel) {
54
78
return Rel.r_addend ;
55
79
}
56
80
57
- // There are normally few input sections whose names are valid C
58
- // identifiers, so we just store a std::vector instead of a multimap.
59
- static DenseMap<StringRef, std::vector<InputSectionBase *>> CNamedSections;
60
-
61
- template <class ELFT , class RelT >
62
- static void
63
- resolveReloc (InputSectionBase &Sec, RelT &Rel,
64
- llvm::function_ref<void (InputSectionBase *, uint64_t )> Fn) {
65
- Symbol &B = Sec.getFile <ELFT>()->getRelocTargetSym (Rel);
81
+ template <class ELFT >
82
+ template <class RelTy >
83
+ void MarkLive<ELFT>::resolveReloc(InputSectionBase &Sec, RelTy &Rel,
84
+ bool IsLSDA) {
85
+ Symbol &Sym = Sec.getFile <ELFT>()->getRelocTargetSym (Rel);
66
86
67
87
// If a symbol is referenced in a live section, it is used.
68
- B.Used = true ;
69
- if (auto *SS = dyn_cast<SharedSymbol>(&B))
70
- if (!SS->isWeak ())
71
- SS->getFile <ELFT>().IsNeeded = true ;
88
+ Sym.Used = true ;
72
89
73
- if (auto *D = dyn_cast<Defined>(&B )) {
90
+ if (auto *D = dyn_cast<Defined>(&Sym )) {
74
91
auto *RelSec = dyn_cast_or_null<InputSectionBase>(D->Section );
75
92
if (!RelSec)
76
93
return ;
94
+
77
95
uint64_t Offset = D->Value ;
78
96
if (D->isSection ())
79
97
Offset += getAddend<ELFT>(Sec, Rel);
80
- Fn (RelSec, Offset);
98
+
99
+ if (!IsLSDA || !(RelSec->Flags & SHF_EXECINSTR))
100
+ enqueue (RelSec, Offset);
81
101
return ;
82
102
}
83
103
84
- if (!B.isDefined ())
85
- for (InputSectionBase *Sec : CNamedSections.lookup (B.getName ()))
86
- Fn (Sec, 0 );
87
- }
88
-
89
- // Calls Fn for each section that Sec refers to via relocations.
90
- template <class ELFT >
91
- static void
92
- forEachSuccessor (InputSection &Sec,
93
- llvm::function_ref<void (InputSectionBase *, uint64_t )> Fn) {
94
- if (Sec.AreRelocsRela ) {
95
- for (const typename ELFT::Rela &Rel : Sec.template relas <ELFT>())
96
- resolveReloc<ELFT>(Sec, Rel, Fn);
97
- } else {
98
- for (const typename ELFT::Rel &Rel : Sec.template rels <ELFT>())
99
- resolveReloc<ELFT>(Sec, Rel, Fn);
100
- }
104
+ if (auto *SS = dyn_cast<SharedSymbol>(&Sym))
105
+ if (!SS->isWeak ())
106
+ SS->getFile <ELFT>().IsNeeded = true ;
101
107
102
- for (InputSectionBase *IS : Sec. DependentSections )
103
- Fn (IS , 0 );
108
+ for (InputSectionBase *Sec : CNamedSections. lookup (Sym. getName ()) )
109
+ enqueue (Sec , 0 );
104
110
}
105
111
106
112
// The .eh_frame section is an unfortunate special case.
@@ -117,54 +123,33 @@ forEachSuccessor(InputSection &Sec,
117
123
// A possible improvement would be to fully process .eh_frame in the middle of
118
124
// the gc pass. With that we would be able to also gc some sections holding
119
125
// LSDAs and personality functions if we found that they were unused.
120
- template <class ELFT , class RelTy >
121
- static void
122
- scanEhFrameSection (EhInputSection &EH, ArrayRef<RelTy> Rels,
123
- llvm::function_ref<void (InputSectionBase *, uint64_t )> Fn) {
124
- const endianness E = ELFT::TargetEndianness;
125
-
126
- for (unsigned I = 0 , N = EH.Pieces .size (); I < N; ++I) {
126
+ template <class ELFT >
127
+ template <class RelTy >
128
+ void MarkLive<ELFT>::scanEhFrameSection(EhInputSection &EH,
129
+ ArrayRef<RelTy> Rels) {
130
+ for (size_t I = 0 , End = EH.Pieces .size (); I < End; ++I) {
127
131
EhSectionPiece &Piece = EH.Pieces [I];
128
- unsigned FirstRelI = Piece.FirstRelocation ;
132
+ size_t FirstRelI = Piece.FirstRelocation ;
129
133
if (FirstRelI == (unsigned )-1 )
130
134
continue ;
131
- if (read32<E>(Piece.data ().data () + 4 ) == 0 ) {
135
+
136
+ if (read32<ELFT::TargetEndianness>(Piece.data ().data () + 4 ) == 0 ) {
132
137
// This is a CIE, we only need to worry about the first relocation. It is
133
138
// known to point to the personality function.
134
- resolveReloc<ELFT> (EH, Rels[FirstRelI], Fn );
139
+ resolveReloc (EH, Rels[FirstRelI], false );
135
140
continue ;
136
141
}
142
+
137
143
// This is a FDE. The relocations point to the described function or to
138
144
// a LSDA. We only need to keep the LSDA alive, so ignore anything that
139
145
// points to executable sections.
140
- typename ELFT::uint PieceEnd = Piece.InputOff + Piece.Size ;
141
- for (unsigned I2 = FirstRelI, N2 = Rels.size (); I2 < N2; ++I2) {
142
- const RelTy &Rel = Rels[I2];
143
- if (Rel.r_offset >= PieceEnd)
144
- break ;
145
- resolveReloc<ELFT>(EH, Rels[I2],
146
- [&](InputSectionBase *Sec, uint64_t Offset) {
147
- if (Sec && Sec != &InputSection::Discarded &&
148
- !(Sec->Flags & SHF_EXECINSTR))
149
- Fn (Sec, 0 );
150
- });
151
- }
146
+ uint64_t PieceEnd = Piece.InputOff + Piece.Size ;
147
+ for (size_t J = FirstRelI, End2 = Rels.size (); J < End2; ++J)
148
+ if (Rels[J].r_offset < PieceEnd)
149
+ resolveReloc (EH, Rels[J], true );
152
150
}
153
151
}
154
152
155
- template <class ELFT >
156
- static void
157
- scanEhFrameSection (EhInputSection &EH,
158
- llvm::function_ref<void (InputSectionBase *, uint64_t )> Fn) {
159
- if (!EH.NumRelocations )
160
- return ;
161
-
162
- if (EH.AreRelocsRela )
163
- scanEhFrameSection<ELFT>(EH, EH.template relas <ELFT>(), Fn);
164
- else
165
- scanEhFrameSection<ELFT>(EH, EH.template rels <ELFT>(), Fn);
166
- }
167
-
168
153
// Some sections are used directly by the loader, so they should never be
169
154
// garbage-collected. This function returns true if a given section is such
170
155
// section.
@@ -183,57 +168,54 @@ static bool isReserved(InputSectionBase *Sec) {
183
168
}
184
169
}
185
170
186
- // This is the main function of the garbage collector.
187
- // Starting from GC-root sections, this function visits all reachable
188
- // sections to set their "Live" bits.
189
- template <class ELFT > static void doGcSections () {
190
- SmallVector<InputSection *, 256 > Q;
191
- CNamedSections.clear ();
192
-
193
- auto Enqueue = [&](InputSectionBase *Sec, uint64_t Offset) {
194
- // Skip over discarded sections. This in theory shouldn't happen, because
195
- // the ELF spec doesn't allow a relocation to point to a deduplicated
196
- // COMDAT section directly. Unfortunately this happens in practice (e.g.
197
- // .eh_frame) so we need to add a check.
198
- if (Sec == &InputSection::Discarded)
199
- return ;
200
-
171
+ template <class ELFT >
172
+ void MarkLive<ELFT>::enqueue(InputSectionBase *Sec, uint64_t Offset) {
173
+ // Skip over discarded sections. This in theory shouldn't happen, because
174
+ // the ELF spec doesn't allow a relocation to point to a deduplicated
175
+ // COMDAT section directly. Unfortunately this happens in practice (e.g.
176
+ // .eh_frame) so we need to add a check.
177
+ if (Sec == &InputSection::Discarded)
178
+ return ;
201
179
202
- // Usually, a whole section is marked as live or dead, but in mergeable
203
- // (splittable) sections, each piece of data has independent liveness bit.
204
- // So we explicitly tell it which offset is in use.
205
- if (auto *MS = dyn_cast<MergeInputSection>(Sec))
206
- MS->getSectionPiece (Offset)->Live = true ;
180
+ // Usually, a whole section is marked as live or dead, but in mergeable
181
+ // (splittable) sections, each piece of data has independent liveness bit.
182
+ // So we explicitly tell it which offset is in use.
183
+ if (auto *MS = dyn_cast<MergeInputSection>(Sec))
184
+ MS->getSectionPiece (Offset)->Live = true ;
207
185
208
- if (Sec->Live )
209
- return ;
210
- Sec->Live = true ;
186
+ if (Sec->Live )
187
+ return ;
188
+ Sec->Live = true ;
211
189
212
- // Add input section to the queue.
213
- if (InputSection *S = dyn_cast<InputSection>(Sec))
214
- Q .push_back (S);
215
- };
190
+ // Add input section to the queue.
191
+ if (InputSection *S = dyn_cast<InputSection>(Sec))
192
+ Queue .push_back (S);
193
+ }
216
194
217
- auto MarkSymbol = [&] (Symbol *Sym) {
218
- if (auto *D = dyn_cast_or_null<Defined>(Sym))
219
- if (auto *IS = dyn_cast_or_null<InputSectionBase>(D->Section ))
220
- Enqueue (IS, D->Value );
221
- };
195
+ template < class ELFT > void MarkLive<ELFT>::markSymbol (Symbol *Sym) {
196
+ if (auto *D = dyn_cast_or_null<Defined>(Sym))
197
+ if (auto *IS = dyn_cast_or_null<InputSectionBase>(D->Section ))
198
+ enqueue (IS, D->Value );
199
+ }
222
200
201
+ // This is the main function of the garbage collector.
202
+ // Starting from GC-root sections, this function visits all reachable
203
+ // sections to set their "Live" bits.
204
+ template <class ELFT > void MarkLive<ELFT>::run() {
223
205
// Add GC root symbols.
224
- MarkSymbol (Symtab->find (Config->Entry ));
225
- MarkSymbol (Symtab->find (Config->Init ));
226
- MarkSymbol (Symtab->find (Config->Fini ));
206
+ markSymbol (Symtab->find (Config->Entry ));
207
+ markSymbol (Symtab->find (Config->Init ));
208
+ markSymbol (Symtab->find (Config->Fini ));
227
209
for (StringRef S : Config->Undefined )
228
- MarkSymbol (Symtab->find (S));
210
+ markSymbol (Symtab->find (S));
229
211
for (StringRef S : Script->ReferencedSymbols )
230
- MarkSymbol (Symtab->find (S));
212
+ markSymbol (Symtab->find (S));
231
213
232
214
// Preserve externally-visible symbols if the symbols defined by this
233
215
// file can interrupt other ELF file's symbols at runtime.
234
216
for (Symbol *S : Symtab->getSymbols ())
235
217
if (S->includeInDynsym ())
236
- MarkSymbol (S);
218
+ markSymbol (S);
237
219
238
220
// Preserve special sections and those which are specified in linker
239
221
// script KEEP command.
@@ -244,31 +226,49 @@ template <class ELFT> static void doGcSections() {
244
226
// referenced by .eh_frame sections, so we scan them for that here.
245
227
if (auto *EH = dyn_cast<EhInputSection>(Sec)) {
246
228
EH->Live = true ;
247
- scanEhFrameSection<ELFT>(*EH, Enqueue );
229
+ if (!EH->NumRelocations )
230
+ continue ;
231
+
232
+ if (EH->AreRelocsRela )
233
+ scanEhFrameSection (*EH, EH->template relas <ELFT>());
234
+ else
235
+ scanEhFrameSection (*EH, EH->template rels <ELFT>());
248
236
}
249
237
250
238
if (Sec->Flags & SHF_LINK_ORDER)
251
239
continue ;
252
240
253
241
if (isReserved (Sec) || Script->shouldKeep (Sec)) {
254
- Enqueue (Sec, 0 );
242
+ enqueue (Sec, 0 );
255
243
} else if (isValidCIdentifier (Sec->Name )) {
256
244
CNamedSections[Saver.save (" __start_" + Sec->Name )].push_back (Sec);
257
245
CNamedSections[Saver.save (" __stop_" + Sec->Name )].push_back (Sec);
258
246
}
259
247
}
260
248
261
249
// Mark all reachable sections.
262
- while (!Q.empty ())
263
- forEachSuccessor<ELFT>(*Q.pop_back_val (), Enqueue );
250
+ while (!Queue.empty ()) {
251
+ InputSectionBase &Sec = *Queue.pop_back_val ();
252
+
253
+ if (Sec.AreRelocsRela ) {
254
+ for (const typename ELFT::Rela &Rel : Sec.template relas <ELFT>())
255
+ resolveReloc (Sec, Rel, false );
256
+ } else {
257
+ for (const typename ELFT::Rel &Rel : Sec.template rels <ELFT>())
258
+ resolveReloc (Sec, Rel, false );
259
+ }
260
+
261
+ for (InputSectionBase *IS : Sec.DependentSections )
262
+ enqueue (IS, 0 );
263
+ }
264
264
}
265
265
266
266
// Before calling this function, Live bits are off for all
267
267
// input sections. This function make some or all of them on
268
268
// so that they are emitted to the output file.
269
269
template <class ELFT > void elf::markLive () {
270
+ // If -gc-sections is not given, no sections are removed.
270
271
if (!Config->GcSections ) {
271
- // If -gc-sections is missing, no sections are removed.
272
272
for (InputSectionBase *Sec : InputSections)
273
273
Sec->Live = true ;
274
274
@@ -280,6 +280,8 @@ template <class ELFT> void elf::markLive() {
280
280
return ;
281
281
}
282
282
283
+ // Otheriwse, do mark-sweep GC.
284
+ //
283
285
// The -gc-sections option works only for SHF_ALLOC sections
284
286
// (sections that are memory-mapped at runtime). So we can
285
287
// unconditionally make non-SHF_ALLOC sections alive except
@@ -303,12 +305,13 @@ template <class ELFT> void elf::markLive() {
303
305
bool IsAlloc = (Sec->Flags & SHF_ALLOC);
304
306
bool IsLinkOrder = (Sec->Flags & SHF_LINK_ORDER);
305
307
bool IsRel = (Sec->Type == SHT_REL || Sec->Type == SHT_RELA);
308
+
306
309
if (!IsAlloc && !IsLinkOrder && !IsRel)
307
310
Sec->Live = true ;
308
311
}
309
312
310
313
// Follow the graph to mark all live sections.
311
- doGcSections <ELFT>();
314
+ MarkLive <ELFT>(). run ();
312
315
313
316
// Report garbage-collected sections.
314
317
if (Config->PrintGcSections )
0 commit comments