[lld] 74b888b - [lld-macho][NFC] Minor refactor of Writer::run()
Greg McGary via llvm-commits
llvm-commits at lists.llvm.org
Wed Mar 17 15:16:16 PDT 2021
Author: Greg McGary
Date: 2021-03-17T15:13:43-07:00
New Revision: 74b888baaddc7ca0fe692650db1f2214be66f28a
URL: https://github.com/llvm/llvm-project/commit/74b888baaddc7ca0fe692650db1f2214be66f28a
DIFF: https://github.com/llvm/llvm-project/commit/74b888baaddc7ca0fe692650db1f2214be66f28a.diff
LOG: [lld-macho][NFC] Minor refactor of Writer::run()
Move some functions closer to their uses. Move detailed address-assignment logic out of the otherwise abstract `Writer::run()`. This prepares the ground for a diff to implement branch range extension thunks.
* `SyntheticSections.cpp`
** move `needsBinding()` and `prepareBranchTarget()` into `Writer.cpp`
** move `addNonLazyBindingEntries()` adjacent to its use.
* `Writer.cpp`
** move address-assignment logic from `Writer::run()` into new function `Writer::assignAddresses()`
** move `needsBinding()` and `prepareBranchTarget()` from `SyntheticSections.cpp`
* `Target.h`
** remove orphaned decls of `prepareSymbolRelocation()` and `validateRelocationInfo()` which were moved to other files in earlier diffs.
Differential Revision: https://reviews.llvm.org/D98795
Added:
Modified:
lld/MachO/SyntheticSections.cpp
lld/MachO/SyntheticSections.h
lld/MachO/Target.h
lld/MachO/Writer.cpp
lld/MachO/Writer.h
Removed:
################################################################################
diff --git a/lld/MachO/SyntheticSections.cpp b/lld/MachO/SyntheticSections.cpp
index 2080ccfed318..1834a48f0e56 100644
--- a/lld/MachO/SyntheticSections.cpp
+++ b/lld/MachO/SyntheticSections.cpp
@@ -207,6 +207,24 @@ NonLazyPointerSectionBase::NonLazyPointerSectionBase(const char *segname,
flags = S_NON_LAZY_SYMBOL_POINTERS;
}
+void macho::addNonLazyBindingEntries(const Symbol *sym,
+ const InputSection *isec, uint64_t offset,
+ int64_t addend) {
+ if (const auto *dysym = dyn_cast<DylibSymbol>(sym)) {
+ in.binding->addEntry(dysym, isec, offset, addend);
+ if (dysym->isWeakDef())
+ in.weakBinding->addEntry(sym, isec, offset, addend);
+ } else if (const auto *defined = dyn_cast<Defined>(sym)) {
+ in.rebase->addEntry(isec, offset);
+ if (defined->isExternalWeakDef())
+ in.weakBinding->addEntry(sym, isec, offset, addend);
+ } else {
+ // Undefined symbols are filtered out in scanRelocations(); we should never
+ // get here
+ llvm_unreachable("cannot bind to an undefined symbol");
+ }
+}
+
void NonLazyPointerSectionBase::addEntry(Symbol *sym) {
if (entries.insert(sym)) {
assert(!sym->isInGot());
@@ -370,32 +388,6 @@ void WeakBindingSection::writeTo(uint8_t *buf) const {
memcpy(buf, contents.data(), contents.size());
}
-bool macho::needsBinding(const Symbol *sym) {
- if (isa<DylibSymbol>(sym))
- return true;
- if (const auto *defined = dyn_cast<Defined>(sym))
- return defined->isExternalWeakDef();
- return false;
-}
-
-void macho::addNonLazyBindingEntries(const Symbol *sym,
- const InputSection *isec, uint64_t offset,
- int64_t addend) {
- if (auto *dysym = dyn_cast<DylibSymbol>(sym)) {
- in.binding->addEntry(dysym, isec, offset, addend);
- if (dysym->isWeakDef())
- in.weakBinding->addEntry(sym, isec, offset, addend);
- } else if (auto *defined = dyn_cast<Defined>(sym)) {
- in.rebase->addEntry(isec, offset);
- if (defined->isExternalWeakDef())
- in.weakBinding->addEntry(sym, isec, offset, addend);
- } else {
- // Undefined symbols are filtered out in scanRelocations(); we should never
- // get here
- llvm_unreachable("cannot bind to an undefined symbol");
- }
-}
-
StubsSection::StubsSection()
: SyntheticSection(segment_names::text, "__stubs") {
flags = S_SYMBOL_STUBS | S_ATTR_SOME_INSTRUCTIONS | S_ATTR_PURE_INSTRUCTIONS;
@@ -549,29 +541,6 @@ uint32_t LazyBindingSection::encode(const DylibSymbol &sym) {
return opstreamOffset;
}
-void macho::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 * WordSize);
- in.weakBinding->addEntry(sym, in.lazyPointers->isec,
- sym->stubsIndex * 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 * WordSize);
- in.weakBinding->addEntry(sym, in.lazyPointers->isec,
- sym->stubsIndex * WordSize);
- }
- }
- }
-}
-
ExportSection::ExportSection()
: LinkEditSection(segment_names::linkEdit, section_names::export_) {}
diff --git a/lld/MachO/SyntheticSections.h b/lld/MachO/SyntheticSections.h
index 8a100fdbfb8c..74a6d3c9475c 100644
--- a/lld/MachO/SyntheticSections.h
+++ b/lld/MachO/SyntheticSections.h
@@ -243,13 +243,6 @@ class WeakBindingSection : public LinkEditSection {
SmallVector<char, 128> contents;
};
-// Whether a given symbol's address can only be resolved at runtime.
-bool needsBinding(const Symbol *);
-
-// Add bindings for symbols that need weak or non-lazy bindings.
-void addNonLazyBindingEntries(const Symbol *, const InputSection *,
- uint64_t offset, int64_t addend = 0);
-
// The following sections implement lazy symbol binding -- very similar to the
// PLT mechanism in ELF.
//
@@ -349,10 +342,6 @@ class LazyBindingSection : public LinkEditSection {
llvm::raw_svector_ostream os{contents};
};
-// Adds stubs and bindings where necessary (e.g. if the symbol is a
-// DylibSymbol.)
-void prepareBranchTarget(Symbol *);
-
// Stores a trie that describes the set of exported symbols.
class ExportSection : public LinkEditSection {
public:
diff --git a/lld/MachO/Target.h b/lld/MachO/Target.h
index 52a2c5b44376..2e4329bc0030 100644
--- a/lld/MachO/Target.h
+++ b/lld/MachO/Target.h
@@ -67,11 +67,6 @@ class TargetInfo {
return getRelocAttrs(type).hasAttr(bit);
}
- bool validateRelocationInfo(llvm::MemoryBufferRef,
- const llvm::MachO::section_64 &sec,
- llvm::MachO::relocation_info);
- void prepareSymbolRelocation(Symbol *, const InputSection *, const Reloc &);
-
uint32_t cpuType;
uint32_t cpuSubtype;
diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index 1776fa01538d..62f4eef19498 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -47,6 +47,8 @@ class Writer {
void scanSymbols();
void createOutputSections();
void createLoadCommands();
+ void finalizeAddressses();
+ void finalizeLinkEditSegment();
void assignAddresses(OutputSegment *);
void openFile();
@@ -66,6 +68,7 @@ class Writer {
CodeSignatureSection *codeSignatureSection = nullptr;
UnwindInfoSection *unwindInfoSection = nullptr;
LCUuid *uuidCommand = nullptr;
+ OutputSegment *linkEditSegment = nullptr;
};
// LC_DYLD_INFO_ONLY stores the offsets of symbol import/export information.
@@ -442,6 +445,40 @@ class LCCodeSignature : public LoadCommand {
} // namespace
+// Adds 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 * WordSize);
+ in.weakBinding->addEntry(sym, in.lazyPointers->isec,
+ sym->stubsIndex * 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 * WordSize);
+ in.weakBinding->addEntry(sym, in.lazyPointers->isec,
+ sym->stubsIndex * WordSize);
+ }
+ }
+ }
+}
+
+// Can a symbol's address can only be resolved at runtime?
+static bool needsBinding(const Symbol *sym) {
+ if (isa<DylibSymbol>(sym))
+ return true;
+ if (const auto *defined = dyn_cast<Defined>(sym))
+ return defined->isExternalWeakDef();
+ return false;
+}
+
static void prepareSymbolRelocation(lld::macho::Symbol *sym,
const InputSection *isec, const Reloc &r) {
const RelocAttrs &relocAttrs = target->getRelocAttrs(r.type);
@@ -791,6 +828,39 @@ void Writer::createOutputSections() {
ssec->name);
}
}
+
+ // dyld requires __LINKEDIT segment to always exist (even if empty).
+ linkEditSegment = getOrCreateOutputSegment(segment_names::linkEdit);
+}
+
+void Writer::finalizeAddressses() {
+ // Ensure that segments (and the sections they contain) are allocated
+ // addresses in ascending order, which dyld requires.
+ //
+ // Note that at this point, __LINKEDIT sections are empty, but we need to
+ // determine addresses of other segments/sections before generating its
+ // contents.
+ for (OutputSegment *seg : outputSegments)
+ if (seg != linkEditSegment)
+ assignAddresses(seg);
+
+ // FIXME(gkm): create branch-extension thunks here, then adjust addresses
+}
+
+void Writer::finalizeLinkEditSegment() {
+ // Fill __LINKEDIT contents.
+ in.rebase->finalizeContents();
+ in.binding->finalizeContents();
+ in.weakBinding->finalizeContents();
+ in.lazyBinding->finalizeContents();
+ in.exports->finalizeContents();
+ in.functionStarts->finalizeContents();
+ symtabSection->finalizeContents();
+ indirectSymtabSection->finalizeContents();
+
+ // Now that __LINKEDIT is filled out, do a proper calculation of its
+ // addresses and offsets.
+ assignAddresses(linkEditSegment);
}
void Writer::assignAddresses(OutputSegment *seg) {
@@ -845,51 +915,20 @@ void Writer::writeCodeSignature() {
}
void Writer::run() {
- // dyld requires __LINKEDIT segment to always exist (even if empty).
- OutputSegment *linkEditSegment =
- getOrCreateOutputSegment(segment_names::linkEdit);
-
prepareBranchTarget(config->entry);
scanRelocations();
if (in.stubHelper->isNeeded())
in.stubHelper->setup();
scanSymbols();
-
- // Sort and assign sections to their respective segments. No more sections nor
- // segments may be created after these methods run.
createOutputSections();
+ // No more sections nor segments are created beyond this point.
sortSegmentsAndSections();
-
createLoadCommands();
-
- // Ensure that segments (and the sections they contain) are allocated
- // addresses in ascending order, which dyld requires.
- //
- // Note that at this point, __LINKEDIT sections are empty, but we need to
- // determine addresses of other segments/sections before generating its
- // contents.
- for (OutputSegment *seg : outputSegments)
- if (seg != linkEditSegment)
- assignAddresses(seg);
-
- // Fill __LINKEDIT contents.
- in.rebase->finalizeContents();
- in.binding->finalizeContents();
- in.weakBinding->finalizeContents();
- in.lazyBinding->finalizeContents();
- in.exports->finalizeContents();
- in.functionStarts->finalizeContents();
- symtabSection->finalizeContents();
- indirectSymtabSection->finalizeContents();
-
- // Now that __LINKEDIT is filled out, do a proper calculation of its
- // addresses and offsets.
- assignAddresses(linkEditSegment);
-
+ finalizeAddressses();
+ finalizeLinkEditSegment();
openFile();
if (errorCount())
return;
-
writeSections();
writeUuid();
writeCodeSignature();
diff --git a/lld/MachO/Writer.h b/lld/MachO/Writer.h
index 88baa8a1e4bb..a13b5ceebf5a 100644
--- a/lld/MachO/Writer.h
+++ b/lld/MachO/Writer.h
@@ -15,6 +15,8 @@ namespace lld {
namespace macho {
class OutputSection;
+class InputSection;
+class Symbol;
class LoadCommand {
public:
@@ -27,6 +29,10 @@ void writeResult();
void createSyntheticSections();
+// Add bindings for symbols that need weak or non-lazy bindings.
+void addNonLazyBindingEntries(const Symbol *, const InputSection *,
+ uint64_t offset, int64_t addend = 0);
+
extern OutputSection *firstTLVDataSection;
} // namespace macho
More information about the llvm-commits
mailing list