diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h --- a/lld/MachO/SyntheticSections.h +++ b/lld/MachO/SyntheticSections.h @@ -279,9 +279,9 @@ void finalize() override; void writeTo(uint8_t *buf) const override; const llvm::SetVector &getEntries() const { return entries; } - // Returns whether the symbol was added. Note that every stubs entry will - // have a corresponding entry in the LazyPointerSection. - bool addEntry(Symbol *); + // Creates a stub for the symbol and the corresponding entry in the + // LazyPointerSection. + void addEntry(Symbol *); uint64_t getVA(uint32_t stubsIndex) const { assert(isFinal || target->usesThunks()); // ConcatOutputSection::finalize() can seek the address of a diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp --- a/lld/MachO/SyntheticSections.cpp +++ b/lld/MachO/SyntheticSections.cpp @@ -659,11 +659,38 @@ void StubsSection::finalize() { isFinal = true; } -bool StubsSection::addEntry(Symbol *sym) { +static void addBindingsForStub(Symbol *sym) { + if (auto *dysym = dyn_cast(sym)) { + if (sym->isWeakDef()) { + in.binding->addEntry(dysym, in.lazyPointers->isec, + sym->stubsIndex * target->wordSize); + in.weakBinding->addEntry(sym, in.lazyPointers->isec, + sym->stubsIndex * target->wordSize); + } else { + in.lazyBinding->addEntry(dysym); + } + } else if (auto *defined = dyn_cast(sym)) { + if (defined->isExternalWeakDef()) { + in.rebase->addEntry(in.lazyPointers->isec, + sym->stubsIndex * target->wordSize); + in.weakBinding->addEntry(sym, in.lazyPointers->isec, + sym->stubsIndex * target->wordSize); + } else if (defined->interposable) { + in.lazyBinding->addEntry(sym); + } else { + llvm_unreachable("invalid stub target"); + } + } else { + llvm_unreachable("invalid stub target symbol type"); + } +} + +void StubsSection::addEntry(Symbol *sym) { bool inserted = entries.insert(sym); - if (inserted) + if (inserted) { sym->stubsIndex = entries.size() - 1; - return inserted; + addBindingsForStub(sym); + } } StubHelperSection::StubHelperSection() diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp --- a/lld/MachO/Writer.cpp +++ b/lld/MachO/Writer.cpp @@ -575,37 +575,6 @@ } } -// Add stubs and bindings where necessary (e.g. if the symbol is a -// DylibSymbol.) -static void prepareBranchTarget(Symbol *sym) { - if (auto *dysym = dyn_cast(sym)) { - if (in.stubs->addEntry(dysym)) { - if (sym->isWeakDef()) { - in.binding->addEntry(dysym, in.lazyPointers->isec, - sym->stubsIndex * target->wordSize); - in.weakBinding->addEntry(sym, in.lazyPointers->isec, - sym->stubsIndex * target->wordSize); - } else { - in.lazyBinding->addEntry(dysym); - } - } - } else if (auto *defined = dyn_cast(sym)) { - if (defined->isExternalWeakDef()) { - if (in.stubs->addEntry(sym)) { - in.rebase->addEntry(in.lazyPointers->isec, - sym->stubsIndex * target->wordSize); - in.weakBinding->addEntry(sym, in.lazyPointers->isec, - sym->stubsIndex * target->wordSize); - } - } else if (defined->interposable) { - if (in.stubs->addEntry(sym)) - in.lazyBinding->addEntry(sym); - } - } else { - llvm_unreachable("invalid branch target symbol type"); - } -} - // Can a symbol's address can only be resolved at runtime? static bool needsBinding(const Symbol *sym) { if (isa(sym)) @@ -621,7 +590,8 @@ const RelocAttrs &relocAttrs = target->getRelocAttrs(r.type); if (relocAttrs.hasAttr(RelocAttrBits::BRANCH)) { - prepareBranchTarget(sym); + if (needsBinding(sym)) + in.stubs->addEntry(sym); } else if (relocAttrs.hasAttr(RelocAttrBits::GOT)) { if (relocAttrs.hasAttr(RelocAttrBits::POINTER) || needsBinding(sym)) in.got->addEntry(sym); @@ -1161,8 +1131,8 @@ template void Writer::run() { treatSpecialUndefineds(); - if (config->entry && !isa(config->entry)) - prepareBranchTarget(config->entry); + if (config->entry && needsBinding(config->entry)) + in.stubs->addEntry(config->entry); // Canonicalization of all pointers to InputSections should be handled by // these two scan* methods. I.e. from this point onward, for all live