@@ -150,14 +150,15 @@ class UnwindInfoSectionImpl final : public UnwindInfoSection {
150150public:
151151 UnwindInfoSectionImpl () : cuOffsets(target->wordSize) {}
152152 uint64_t getSize () const override { return unwindInfoSize; }
153- void prepareRelocations () override ;
153+ void prepare () override ;
154154 void finalize () override ;
155155 void writeTo (uint8_t *buf) const override ;
156156
157157private:
158158 void prepareRelocations (ConcatInputSection *);
159159 void relocateCompactUnwind (std::vector<CompactUnwindEntry> &);
160160 void encodePersonalities ();
161+ Symbol *canonicalizePersonality (Symbol *);
161162
162163 uint64_t unwindInfoSize = 0 ;
163164 std::vector<decltype (symbols)::value_type> symbolsVec;
@@ -210,14 +211,24 @@ void UnwindInfoSection::addSymbol(const Defined *d) {
210211 }
211212}
212213
213- void UnwindInfoSectionImpl::prepareRelocations () {
214+ void UnwindInfoSectionImpl::prepare () {
214215 // This iteration needs to be deterministic, since prepareRelocations may add
215216 // entries to the GOT. Hence the use of a MapVector for
216217 // UnwindInfoSection::symbols.
217218 for (const Defined *d : make_second_range (symbols))
218- if (d->unwindEntry &&
219- d->unwindEntry ->getName () == section_names::compactUnwind)
220- prepareRelocations (d->unwindEntry );
219+ if (d->unwindEntry ) {
220+ if (d->unwindEntry ->getName () == section_names::compactUnwind) {
221+ prepareRelocations (d->unwindEntry );
222+ } else {
223+ // We don't have to add entries to the GOT here because FDEs have
224+ // explicit GOT relocations, so Writer::scanRelocations() will add those
225+ // GOT entries. However, we still need to canonicalize the personality
226+ // pointers (like prepareRelocations() does for CU entries) in order
227+ // to avoid overflowing the 3-personality limit.
228+ FDE &fde = cast<ObjFile>(d->getFile ())->fdes [d->unwindEntry ];
229+ fde.personality = canonicalizePersonality (fde.personality );
230+ }
231+ }
221232}
222233
223234// Compact unwind relocations have different semantics, so we handle them in a
@@ -271,6 +282,7 @@ void UnwindInfoSectionImpl::prepareRelocations(ConcatInputSection *isec) {
271282 continue ;
272283 }
273284
285+ // Similar to canonicalizePersonality(), but we also register a GOT entry.
274286 if (auto *defined = dyn_cast<Defined>(s)) {
275287 // Check if we have created a synthetic symbol at the same address.
276288 Symbol *&personality =
@@ -283,6 +295,7 @@ void UnwindInfoSectionImpl::prepareRelocations(ConcatInputSection *isec) {
283295 }
284296 continue ;
285297 }
298+
286299 assert (isa<DylibSymbol>(s));
287300 in.got ->addEntry (s);
288301 continue ;
@@ -312,6 +325,18 @@ void UnwindInfoSectionImpl::prepareRelocations(ConcatInputSection *isec) {
312325 }
313326}
314327
328+ Symbol *UnwindInfoSectionImpl::canonicalizePersonality (Symbol *personality) {
329+ if (auto *defined = dyn_cast_or_null<Defined>(personality)) {
330+ // Check if we have created a synthetic symbol at the same address.
331+ Symbol *&synth = personalityTable[{defined ->isec , defined ->value }];
332+ if (synth == nullptr )
333+ synth = defined ;
334+ else if (synth != defined )
335+ return synth;
336+ }
337+ return personality;
338+ }
339+
315340// We need to apply the relocations to the pre-link compact unwind section
316341// before converting it to post-link form. There should only be absolute
317342// relocations here: since we are not emitting the pre-link CU section, there
0 commit comments