[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:
parent
5260146a8a
commit
6b6d1abb10
|
@ -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()
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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
|
||||
|
|
Loading…
Reference in New Issue