diff --git a/lld/MachO/Driver.cpp b/lld/MachO/Driver.cpp --- a/lld/MachO/Driver.cpp +++ b/lld/MachO/Driver.cpp @@ -1015,6 +1015,8 @@ break; } } + + parallelForEach(objFiles, [](ObjFile *objFile) { objFile->parseLate(); }); } static void gatherInputSections() { diff --git a/lld/MachO/InputFiles.h b/lld/MachO/InputFiles.h --- a/lld/MachO/InputFiles.h +++ b/lld/MachO/InputFiles.h @@ -106,9 +106,11 @@ const uint32_t modTime; std::vector debugSections; ArrayRef dataInCodeEntries; + void parseLate(); private: template void parse(); + template void parseLateImpl(); template void parseSections(ArrayRef
); template void parseSymbols(ArrayRef sectionHeaders, @@ -212,6 +214,7 @@ }; extern llvm::SetVector inputFiles; +extern std::vector objFiles; extern llvm::DenseMap cachedReads; llvm::Optional readFile(StringRef path); diff --git a/lld/MachO/InputFiles.cpp b/lld/MachO/InputFiles.cpp --- a/lld/MachO/InputFiles.cpp +++ b/lld/MachO/InputFiles.cpp @@ -93,6 +93,7 @@ } SetVector macho::inputFiles; +std::vector macho::objFiles; std::unique_ptr macho::tar; int InputFile::idCount = 0; @@ -783,6 +784,7 @@ ObjFile::ObjFile(MemoryBufferRef mb, uint32_t modTime, StringRef archiveName) : InputFile(ObjKind, mb), modTime(modTime) { + objFiles.push_back(this); this->archiveName = std::string(archiveName); if (target->wordSize == 8) parse(); @@ -790,6 +792,13 @@ parse(); } +void ObjFile::parseLate() { + if (target->wordSize == 8) + parseLateImpl(); + else + parseLateImpl(); +} + template void ObjFile::parse() { using Header = typename LP::mach_header; using SegmentCommand = typename LP::segment_command; @@ -837,13 +846,27 @@ parseSymbols(sectionHeaders, nList, strtab, subsectionsViaSymbols); } + parseDebugInfo(); +} + +template void ObjFile::parseLateImpl() { + using Header = typename LP::mach_header; + using Section = typename LP::section; + using SegmentCommand = typename LP::segment_command; + auto *hdr = reinterpret_cast(mb.getBufferStart()); + ArrayRef
sectionHeaders; + if (const load_command *cmd = findCommand(hdr, LP::segmentLCType)) { + auto *c = reinterpret_cast(cmd); + sectionHeaders = + ArrayRef
{reinterpret_cast(c + 1), c->nsects}; + } + // The relocations may refer to the symbols, so we parse them after we have // parsed all the symbols. for (size_t i = 0, n = subsections.size(); i < n; ++i) if (!subsections[i].empty()) parseRelocations(sectionHeaders, sectionHeaders[i], subsections[i]); - parseDebugInfo(); if (config->emitDataInCodeInfo) parseDataInCode(); registerCompactUnwind();