@@ -68,10 +68,9 @@ template <class ELFT, bool TrackWhyLive> class MarkLive {
6868 void mark ();
6969
7070 template <class RelTy >
71- void resolveReloc (InputSectionBase &sec, RelTy &rel, bool fromFDE);
71+ void resolveReloc (InputSectionBase &sec, const RelTy &rel, bool fromFDE);
7272
73- template <class RelTy >
74- void scanEhFrameSection (EhInputSection &eh, ArrayRef<RelTy> rels);
73+ void scanEhFrameSection (EhInputSection &eh);
7574
7675 Ctx &ctx;
7776 // The index of the partition that we are currently processing.
@@ -115,23 +114,38 @@ static uint64_t getAddend(Ctx &, InputSectionBase &sec,
115114template <class ELFT , bool TrackWhyLive>
116115template <class RelTy >
117116void MarkLive<ELFT, TrackWhyLive>::resolveReloc(InputSectionBase &sec,
118- RelTy &rel, bool fromFDE) {
117+ const RelTy &rel,
118+ bool fromFDE) {
119119 // If a symbol is referenced in a live section, it is used.
120- Symbol &sym = sec.file ->getRelocTargetSym (rel);
121- sym.used = true ;
120+ Symbol *sym;
121+ if constexpr (std::is_same_v<RelTy, Relocation>) {
122+ assert (isa<EhInputSection>(sec));
123+ sym = rel.sym ;
124+ } else {
125+ sym = &sec.file ->getRelocTargetSym (rel);
126+ }
127+ sym->used = true ;
122128
123129 LiveReason reason;
124- if (TrackWhyLive)
125- reason = {SecOffset (&sec, rel.r_offset ), " referenced by" };
130+ if (TrackWhyLive) {
131+ if constexpr (std::is_same_v<RelTy, Relocation>)
132+ reason = {SecOffset (&sec, rel.offset ), " referenced by" };
133+ else
134+ reason = {SecOffset (&sec, rel.r_offset ), " referenced by" };
135+ }
126136
127- if (auto *d = dyn_cast<Defined>(& sym)) {
137+ if (auto *d = dyn_cast<Defined>(sym)) {
128138 auto *relSec = dyn_cast_or_null<InputSectionBase>(d->section );
129139 if (!relSec)
130140 return ;
131141
132142 uint64_t offset = d->value ;
133- if (d->isSection ())
134- offset += getAddend<ELFT>(ctx, sec, rel);
143+ if (d->isSection ()) {
144+ if constexpr (std::is_same_v<RelTy, Relocation>)
145+ offset += rel.addend ;
146+ else
147+ offset += getAddend<ELFT>(ctx, sec, rel);
148+ }
135149
136150 // fromFDE being true means this is referenced by a FDE in a .eh_frame
137151 // piece. The relocation points to the described function or to a LSDA. We
@@ -141,8 +155,9 @@ void MarkLive<ELFT, TrackWhyLive>::resolveReloc(InputSectionBase &sec,
141155 // associated text section is live, the LSDA will be retained due to section
142156 // group/SHF_LINK_ORDER rules (b) if the associated text section should be
143157 // discarded, marking the LSDA will unnecessarily retain the text section.
144- if (!(fromFDE && ((relSec->flags & (SHF_EXECINSTR | SHF_LINK_ORDER)) ||
145- relSec->nextInSectionGroup ))) {
158+ if (!(fromFDE && std::is_same_v<RelTy, Relocation> &&
159+ ((relSec->flags & (SHF_EXECINSTR | SHF_LINK_ORDER)) ||
160+ relSec->nextInSectionGroup ))) {
146161 Symbol *canonicalSym = d;
147162 if (TrackWhyLive && d->isSection ()) {
148163 // This is expensive, so ideally this would be deferred until it's known
@@ -159,15 +174,15 @@ void MarkLive<ELFT, TrackWhyLive>::resolveReloc(InputSectionBase &sec,
159174 return ;
160175 }
161176
162- if (auto *ss = dyn_cast<SharedSymbol>(& sym)) {
177+ if (auto *ss = dyn_cast<SharedSymbol>(sym)) {
163178 if (!ss->isWeak ()) {
164179 cast<SharedFile>(ss->file )->isNeeded = true ;
165180 if (TrackWhyLive)
166- whyLive.try_emplace (& sym, reason);
181+ whyLive.try_emplace (sym, reason);
167182 }
168183 }
169184
170- for (InputSectionBase *sec : cNamedSections.lookup (sym. getName ()))
185+ for (InputSectionBase *sec : cNamedSections.lookup (sym-> getName ()))
171186 enqueue (sec, /* offset=*/ 0 , /* sym=*/ nullptr , reason);
172187}
173188
@@ -186,9 +201,8 @@ void MarkLive<ELFT, TrackWhyLive>::resolveReloc(InputSectionBase &sec,
186201// the gc pass. With that we would be able to also gc some sections holding
187202// LSDAs and personality functions if we found that they were unused.
188203template <class ELFT , bool TrackWhyLive>
189- template <class RelTy >
190- void MarkLive<ELFT, TrackWhyLive>::scanEhFrameSection(EhInputSection &eh,
191- ArrayRef<RelTy> rels) {
204+ void MarkLive<ELFT, TrackWhyLive>::scanEhFrameSection(EhInputSection &eh) {
205+ ArrayRef<Relocation> rels = eh.rels ;
192206 for (const EhSectionPiece &cie : eh.cies )
193207 if (cie.firstRelocation != unsigned (-1 ))
194208 resolveReloc (eh, rels[cie.firstRelocation ], false );
@@ -198,7 +212,7 @@ void MarkLive<ELFT, TrackWhyLive>::scanEhFrameSection(EhInputSection &eh,
198212 continue ;
199213 uint64_t pieceEnd = fde.inputOff + fde.size ;
200214 for (size_t j = firstRelI, end2 = rels.size ();
201- j < end2 && rels[j].r_offset < pieceEnd; ++j)
215+ j < end2 && rels[j].offset < pieceEnd; ++j)
202216 resolveReloc (eh, rels[j], true );
203217 }
204218}
@@ -360,14 +374,8 @@ void MarkLive<ELFT, TrackWhyLive>::run() {
360374 // that point to .eh_frames. Otherwise, the garbage collector would drop
361375 // all of them. We also want to preserve personality routines and LSDA
362376 // referenced by .eh_frame sections, so we scan them for that here.
363- for (EhInputSection *eh : ctx.ehInputSections ) {
364- const RelsOrRelas<ELFT> rels =
365- eh->template relsOrRelas <ELFT>(/* supportsCrel=*/ false );
366- if (rels.areRelocsRel ())
367- scanEhFrameSection (*eh, rels.rels );
368- else if (rels.relas .size ())
369- scanEhFrameSection (*eh, rels.relas );
370- }
377+ for (EhInputSection *eh : ctx.ehInputSections )
378+ scanEhFrameSection (*eh);
371379 for (InputSectionBase *sec : ctx.inputSections ) {
372380 if (sec->flags & SHF_GNU_RETAIN) {
373381 enqueue (sec, /* offset=*/ 0 , /* sym=*/ nullptr , {std::nullopt , " retained" });
0 commit comments