aboutsummaryrefslogtreecommitdiff
path: root/lld/MachO/Writer.cpp
diff options
context:
space:
mode:
Diffstat (limited to 'lld/MachO/Writer.cpp')
-rw-r--r--lld/MachO/Writer.cpp51
1 files changed, 43 insertions, 8 deletions
diff --git a/lld/MachO/Writer.cpp b/lld/MachO/Writer.cpp
index d9c9cf570054..093a380d175e 100644
--- a/lld/MachO/Writer.cpp
+++ b/lld/MachO/Writer.cpp
@@ -227,7 +227,7 @@ public:
void writeTo(uint8_t *buf) const override {
using SegmentCommand = typename LP::segment_command;
- using Section = typename LP::section;
+ using SectionHeader = typename LP::section;
auto *c = reinterpret_cast<SegmentCommand *>(buf);
buf += sizeof(SegmentCommand);
@@ -248,8 +248,8 @@ public:
if (osec->isHidden())
continue;
- auto *sectHdr = reinterpret_cast<Section *>(buf);
- buf += sizeof(Section);
+ auto *sectHdr = reinterpret_cast<SectionHeader *>(buf);
+ buf += sizeof(SectionHeader);
memcpy(sectHdr->sectname, osec->name.data(), osec->name.size());
memcpy(sectHdr->segname, name.data(), name.size());
@@ -343,6 +343,7 @@ public:
}
static uint32_t getInstanceCount() { return instanceCount; }
+ static void resetInstanceCount() { instanceCount = 0; }
private:
LoadCommandType type;
@@ -671,10 +672,15 @@ void Writer::scanRelocations() {
void Writer::scanSymbols() {
TimeTraceScope timeScope("Scan symbols");
- for (const Symbol *sym : symtab->getSymbols()) {
- if (const auto *defined = dyn_cast<Defined>(sym)) {
- if (defined->overridesWeakDef && defined->isLive())
+ for (Symbol *sym : symtab->getSymbols()) {
+ if (auto *defined = dyn_cast<Defined>(sym)) {
+ if (!defined->isLive())
+ continue;
+ defined->canonicalize();
+ if (defined->overridesWeakDef)
in.weakBinding->addNonWeakDefinition(defined);
+ if (!defined->isAbsolute() && isCodeSection(defined->isec))
+ in.unwindInfo->addSymbol(defined);
} else if (const auto *dysym = dyn_cast<DylibSymbol>(sym)) {
// This branch intentionally doesn't check isLive().
if (dysym->isDynamicLookup())
@@ -683,6 +689,20 @@ void Writer::scanSymbols() {
std::max(dysym->getFile()->refState, dysym->getRefState());
}
}
+
+ for (const InputFile *file : inputFiles) {
+ if (auto *objFile = dyn_cast<ObjFile>(file))
+ for (Symbol *sym : objFile->symbols) {
+ if (auto *defined = dyn_cast_or_null<Defined>(sym)) {
+ if (!defined->isLive())
+ continue;
+ defined->canonicalize();
+ if (!defined->isExternal() && !defined->isAbsolute() &&
+ isCodeSection(defined->isec))
+ in.unwindInfo->addSymbol(defined);
+ }
+ }
+ }
}
// TODO: ld64 enforces the old load commands in a few other cases.
@@ -954,7 +974,12 @@ template <class LP> void Writer::createOutputSections() {
for (SyntheticSection *ssec : syntheticSections) {
auto it = concatOutputSections.find({ssec->segname, ssec->name});
- if (ssec->isNeeded()) {
+ // We add all LinkEdit sections here because we don't know if they are
+ // needed until their finalizeContents() methods get called later. While
+ // this means that we add some redundant sections to __LINKEDIT, there is
+ // is no redundancy in the output, as we do not emit section headers for
+ // any LinkEdit sections.
+ if (ssec->isNeeded() || ssec->segname == segment_names::linkEdit) {
if (it == concatOutputSections.end()) {
getOrCreateOutputSegment(ssec->segname)->addOutputSection(ssec);
} else {
@@ -1101,11 +1126,19 @@ template <class LP> void Writer::run() {
treatSpecialUndefineds();
if (config->entry && !isa<Undefined>(config->entry))
prepareBranchTarget(config->entry);
+ // Canonicalization of all pointers to InputSections should be handled by
+ // these two methods.
+ scanSymbols();
scanRelocations();
+
+ // Do not proceed if there was an undefined symbol.
+ if (errorCount())
+ return;
+
if (in.stubHelper->isNeeded())
in.stubHelper->setup();
- scanSymbols();
createOutputSections<LP>();
+
// After this point, we create no new segments; HOWEVER, we might
// yet create branch-range extension thunks for architectures whose
// hardware call instructions have limited range, e.g., ARM(64).
@@ -1121,6 +1154,8 @@ template <class LP> void Writer::run() {
template <class LP> void macho::writeResult() { Writer().run<LP>(); }
+void macho::resetWriter() { LCDylib::resetInstanceCount(); }
+
void macho::createSyntheticSections() {
in.header = make<MachHeaderSection>();
if (config->dedupLiterals) {