Index: lld/trunk/COFF/Driver.cpp =================================================================== --- lld/trunk/COFF/Driver.cpp +++ lld/trunk/COFF/Driver.cpp @@ -575,27 +575,12 @@ MBs.erase(It, MBs.end()); } - // Read all input files given via the command line. Note that step() - // doesn't read files that are specified by directive sections. + // Read all input files given via the command line. for (MemoryBufferRef MB : MBs) Symtab.addFile(createFile(MB)); - Symtab.step(); - // Determine machine type and check if all object files are - // for the same CPU type. Note that this needs to be done before - // any call to mangle(). - for (InputFile *File : Symtab.getFiles()) { - MachineTypes MT = File->getMachineType(); - if (MT == IMAGE_FILE_MACHINE_UNKNOWN) - continue; - if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) { - Config->Machine = MT; - continue; - } - if (Config->Machine != MT) - fatal(toString(File) + ": machine type " + machineToStr(MT) + - " conflicts with " + machineToStr(Config->Machine)); - } + // We should have inferred a machine type by now from the input files, but if + // not we assume x64. if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) { errs() << "warning: /machine is not specified. x64 is assumed.\n"; Config->Machine = AMD64; @@ -686,50 +671,37 @@ Symtab.addAbsolute(mangle("__guard_fids_count"), 0); Symtab.addAbsolute(mangle("__guard_flags"), 0x100); - // Read as much files as we can from directives sections. - Symtab.run(); - - // Resolve auxiliary symbols until we get a convergence. - // (Trying to resolve a symbol may trigger a Lazy symbol to load a new file. - // A new file may contain a directive section to add new command line options. - // That's why we have to repeat until converge.) - for (;;) { - // Windows specific -- if entry point is not found, - // search for its mangled names. - if (Config->Entry) - Symtab.mangleMaybe(Config->Entry); - - // Windows specific -- Make sure we resolve all dllexported symbols. - for (Export &E : Config->Exports) { - if (!E.ForwardTo.empty()) - continue; - E.Sym = addUndefined(E.Name); - if (!E.Directives) - Symtab.mangleMaybe(E.Sym); - } - - // Add weak aliases. Weak aliases is a mechanism to give remaining - // undefined symbols final chance to be resolved successfully. - for (auto Pair : Config->AlternateNames) { - StringRef From = Pair.first; - StringRef To = Pair.second; - Symbol *Sym = Symtab.find(From); - if (!Sym) - continue; - if (auto *U = dyn_cast(Sym->body())) - if (!U->WeakAlias) - U->WeakAlias = Symtab.addUndefined(To); - } - - // Windows specific -- if __load_config_used can be resolved, resolve it. - if (Symtab.findUnderscore("_load_config_used")) - addUndefined(mangle("_load_config_used")); + // Windows specific -- if entry point is not found, + // search for its mangled names. + if (Config->Entry) + Symtab.mangleMaybe(Config->Entry); + + // Windows specific -- Make sure we resolve all dllexported symbols. + for (Export &E : Config->Exports) { + if (!E.ForwardTo.empty()) + continue; + E.Sym = addUndefined(E.Name); + if (!E.Directives) + Symtab.mangleMaybe(E.Sym); + } - if (Symtab.queueEmpty()) - break; - Symtab.run(); + // Add weak aliases. Weak aliases is a mechanism to give remaining + // undefined symbols final chance to be resolved successfully. + for (auto Pair : Config->AlternateNames) { + StringRef From = Pair.first; + StringRef To = Pair.second; + Symbol *Sym = Symtab.find(From); + if (!Sym) + continue; + if (auto *U = dyn_cast(Sym->body())) + if (!U->WeakAlias) + U->WeakAlias = Symtab.addUndefined(To); } + // Windows specific -- if __load_config_used can be resolved, resolve it. + if (Symtab.findUnderscore("_load_config_used")) + addUndefined(mangle("_load_config_used")); + // Do LTO by compiling bitcode input files to a set of native COFF files then // link those files. Symtab.addCombinedLTOObjects(); Index: lld/trunk/COFF/SymbolTable.h =================================================================== --- lld/trunk/COFF/SymbolTable.h +++ lld/trunk/COFF/SymbolTable.h @@ -21,9 +21,6 @@ #include #endif -#include -#include - namespace llvm { struct LTOCodeGenerator; } @@ -56,10 +53,6 @@ class SymbolTable { public: void addFile(InputFile *File); - std::vector &getFiles() { return Files; } - void step(); - void run(); - bool queueEmpty(); // Try to resolve any undefined symbols and update the symbol table // accordingly, then print an error message for any remaining undefined @@ -129,10 +122,6 @@ llvm::DenseMap Symtab; - std::vector Files; - std::list ArchiveQueue; - std::vector ObjectQueue; - std::vector BitcodeFiles; std::vector> Objs; }; Index: lld/trunk/COFF/SymbolTable.cpp =================================================================== --- lld/trunk/COFF/SymbolTable.cpp +++ lld/trunk/COFF/SymbolTable.cpp @@ -27,76 +27,33 @@ SymbolTable *Symtab; void SymbolTable::addFile(InputFile *File) { - Files.push_back(File); - if (auto *F = dyn_cast(File)) { - ArchiveQueue.push_back(F); - return; + if (Config->Verbose) + outs() << "Reading " << toString(File) << "\n"; + File->parse(); + + MachineTypes MT = File->getMachineType(); + if (Config->Machine == IMAGE_FILE_MACHINE_UNKNOWN) { + Config->Machine = MT; + } else if (MT != IMAGE_FILE_MACHINE_UNKNOWN && Config->Machine != MT) { + fatal(toString(File) + ": machine type " + machineToStr(MT) + + " conflicts with " + machineToStr(Config->Machine)); } - ObjectQueue.push_back(File); + if (auto *F = dyn_cast(File)) { ObjectFiles.push_back(F); } else if (auto *F = dyn_cast(File)) { BitcodeFiles.push_back(F); - } else { - ImportFiles.push_back(cast(File)); + } else if (auto *F = dyn_cast(File)) { + ImportFiles.push_back(F); } -} - -void SymbolTable::step() { - if (queueEmpty()) - return; - readObjects(); - readArchive(); -} - -void SymbolTable::run() { - while (!queueEmpty()) - step(); -} -void SymbolTable::readArchive() { - if (ArchiveQueue.empty()) + StringRef S = File->getDirectives(); + if (S.empty()) return; - // Add lazy symbols to the symbol table. Lazy symbols that conflict - // with existing undefined symbols are accumulated in LazySyms. - ArchiveFile *File = ArchiveQueue.front(); - ArchiveQueue.pop_front(); if (Config->Verbose) - outs() << "Reading " << toString(File) << "\n"; - File->parse(); -} - -void SymbolTable::readObjects() { - if (ObjectQueue.empty()) - return; - - // Add defined and undefined symbols to the symbol table. - std::vector Directives; - for (size_t I = 0; I < ObjectQueue.size(); ++I) { - InputFile *File = ObjectQueue[I]; - if (Config->Verbose) - outs() << "Reading " << toString(File) << "\n"; - File->parse(); - // Adding symbols may add more files to ObjectQueue - // (but not to ArchiveQueue). - StringRef S = File->getDirectives(); - if (!S.empty()) { - Directives.push_back(S); - if (Config->Verbose) - outs() << "Directives: " << toString(File) << ": " << S << "\n"; - } - } - ObjectQueue.clear(); - - // Parse directive sections. This may add files to - // ArchiveQueue and ObjectQueue. - for (StringRef S : Directives) - Driver->parseDirectives(S); -} - -bool SymbolTable::queueEmpty() { - return ArchiveQueue.empty() && ObjectQueue.empty(); + outs() << "Directives: " << toString(File) << ": " << S << "\n"; + Driver->parseDirectives(S); } void SymbolTable::reportRemainingUndefines() { @@ -419,7 +376,6 @@ size_t NumBitcodeFiles = BitcodeFiles.size(); for (ObjectFile *Obj : Objs) Obj->parse(); - run(); if (BitcodeFiles.size() != NumBitcodeFiles) fatal("LTO: late loaded symbol created new bitcode reference"); } @@ -465,7 +421,6 @@ std::vector ObjFiles; for (SmallString<0> &Obj : Objs) { auto *ObjFile = new ObjectFile(MemoryBufferRef(Obj, "")); - Files.emplace_back(ObjFile); ObjectFiles.push_back(ObjFile); ObjFiles.push_back(ObjFile); } Index: lld/trunk/test/COFF/order.test =================================================================== --- lld/trunk/test/COFF/order.test +++ lld/trunk/test/COFF/order.test @@ -9,7 +9,7 @@ # RUN: FileCheck %s < %t.log CHECK: order.test.tmp1.obj -CHECK: order.test.tmp3.obj CHECK: order.test.tmp2.lib CHECK: order.test.tmp2.lib(order.test.tmp2.obj) for foo +CHECK: order.test.tmp3.obj CHECK: order.test.tmp3.lib