diff options
Diffstat (limited to 'lld/MachO/Writer.cpp')
| -rw-r--r-- | lld/MachO/Writer.cpp | 51 |
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) { |
