diff --git a/lld/COFF/SymbolTable.cpp b/lld/COFF/SymbolTable.cpp index 8d6754e6e352..a81d6bdbe58b 100644 --- a/lld/COFF/SymbolTable.cpp +++ b/lld/COFF/SymbolTable.cpp @@ -235,40 +235,17 @@ std::error_code SymbolTable::addCombinedLTOObject() { if (BitcodeFiles.empty()) return std::error_code(); - llvm::LTOCodeGenerator CG; - - // All symbols referenced by non-bitcode objects must be preserved. - for (std::unique_ptr &File : ObjectFiles) - for (SymbolBody *Body : File->getSymbols()) - if (auto *S = dyn_cast(Body->getReplacement())) - CG.addMustPreserveSymbol(S->getName()); - - // Likewise for other symbols that must be preserved. - for (StringRef Name : Config->GCRoots) - if (isa(Symtab[Name]->Body)) - CG.addMustPreserveSymbol(Name); - - CG.setModule(BitcodeFiles[0]->releaseModule()); - for (unsigned I = 1, E = BitcodeFiles.size(); I != E; ++I) - CG.addModule(BitcodeFiles[I]->getModule()); - - std::string ErrMsg; - LTOObjectFile = CG.compile(false, false, false, ErrMsg); - if (!LTOObjectFile) { - llvm::errs() << ErrMsg << '\n'; - return make_error_code(LLDError::BrokenFile); - } - // Create an object file and add it to the symbol table by replacing any // DefinedBitcode symbols with the definitions in the object file. - auto Obj = new ObjectFile(LTOObjectFile->getMemBufferRef()); - ObjectFiles.emplace_back(Obj); - if (auto EC = Obj->parse()) + LTOCodeGenerator CG; + auto FileOrErr = createLTOObject(&CG); + if (auto EC = FileOrErr.getError()) return EC; + ObjectFile *Obj = FileOrErr.get(); + for (SymbolBody *Body : Obj->getSymbols()) { if (!Body->isExternal()) continue; - // Find an existing Symbol. We should not see any new undefined symbols at // this point. StringRef Name = Body->getName(); @@ -311,9 +288,39 @@ std::error_code SymbolTable::addCombinedLTOObject() { // New runtime library symbol references may have created undefined references. if (reportRemainingUndefines()) return make_error_code(LLDError::BrokenFile); - return std::error_code(); } +// Combine and compile bitcode files and then return the result +// as a regular COFF object file. +ErrorOr SymbolTable::createLTOObject(LTOCodeGenerator *CG) { + // All symbols referenced by non-bitcode objects must be preserved. + for (std::unique_ptr &File : ObjectFiles) + for (SymbolBody *Body : File->getSymbols()) + if (auto *S = dyn_cast(Body->getReplacement())) + CG->addMustPreserveSymbol(S->getName()); + + // Likewise for other symbols that must be preserved. + for (StringRef Name : Config->GCRoots) + if (isa(Symtab[Name]->Body)) + CG->addMustPreserveSymbol(Name); + + CG->setModule(BitcodeFiles[0]->releaseModule()); + for (unsigned I = 1, E = BitcodeFiles.size(); I != E; ++I) + CG->addModule(BitcodeFiles[I]->getModule()); + + std::string ErrMsg; + LTOMB = CG->compile(false, false, false, ErrMsg); // take MB ownership + if (!LTOMB) { + llvm::errs() << ErrMsg << '\n'; + return make_error_code(LLDError::BrokenFile); + } + auto Obj = new ObjectFile(LTOMB->getMemBufferRef()); + ObjectFiles.emplace_back(Obj); + if (auto EC = Obj->parse()) + return EC; + return Obj; +} + } // namespace coff } // namespace lld diff --git a/lld/COFF/SymbolTable.h b/lld/COFF/SymbolTable.h index 922ae220dd68..3ce4a9953efb 100644 --- a/lld/COFF/SymbolTable.h +++ b/lld/COFF/SymbolTable.h @@ -15,6 +15,10 @@ #include "llvm/Support/Allocator.h" #include +namespace llvm { +struct LTOCodeGenerator; +} + namespace lld { namespace coff { @@ -86,11 +90,12 @@ private: std::error_code resolve(SymbolBody *Body); std::error_code addMemberFile(Lazy *Body); + ErrorOr createLTOObject(llvm::LTOCodeGenerator *CG); std::unordered_map Symtab; std::vector> ArchiveFiles; std::vector> BitcodeFiles; - std::unique_ptr LTOObjectFile; + std::unique_ptr LTOMB; llvm::BumpPtrAllocator Alloc; };