[lld-macho] Move adding bindings for stub targets out of Writer (NFC)

We now re-use the existing needsBinding() helper to determine if a
branch has to go through a stub. The logic for determining which type of
binding is needed is moved inside StubsSection::addEntry().

This is an NFC refactor that simplifies my diff that adds support for
chained fixups.

Differential Revision: https://reviews.llvm.org/D132476
This commit is contained in:
Daniel Bertalan 2022-08-14 15:42:21 +02:00
parent 5260146a8a
commit 6b6d1abb10
No known key found for this signature in database
3 changed files with 37 additions and 40 deletions

View File

@ -659,11 +659,38 @@ void StubsSection::writeTo(uint8_t *buf) const {
void StubsSection::finalize() { isFinal = true; }
bool StubsSection::addEntry(Symbol *sym) {
static void addBindingsForStub(Symbol *sym) {
if (auto *dysym = dyn_cast<DylibSymbol>(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<Defined>(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()

View File

@ -279,9 +279,9 @@ public:
void finalize() override;
void writeTo(uint8_t *buf) const override;
const llvm::SetVector<Symbol *> &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

View File

@ -575,37 +575,6 @@ void Writer::treatSpecialUndefineds() {
}
}
// Add stubs and bindings where necessary (e.g. if the symbol is a
// DylibSymbol.)
static void prepareBranchTarget(Symbol *sym) {
if (auto *dysym = dyn_cast<DylibSymbol>(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<Defined>(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<DylibSymbol>(sym))
@ -621,7 +590,8 @@ static void prepareSymbolRelocation(Symbol *sym, const InputSection *isec,
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 @@ void Writer::writeOutputFile() {
template <class LP> void Writer::run() {
treatSpecialUndefineds();
if (config->entry && !isa<Undefined>(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