diff --git a/include/llvm/Linker.h b/include/llvm/Linker.h index f7b03c2ee5c..21f32afb3c0 100644 --- a/include/llvm/Linker.h +++ b/include/llvm/Linker.h @@ -158,7 +158,8 @@ class Linker { /// @see getLastError /// @throws nothing bool LinkInItems ( - const ItemList& Items // Set of libraries/files to link in + const ItemList& Items, ///< Set of libraries/files to link in + ItemList& NativeItems ///< Output list of native files/libs ); /// This function links the bytecode \p Files into the composite module. @@ -210,7 +211,8 @@ class Linker { /// @returns true if an error occurs, false otherwise /// @brief Link one library into the module bool LinkInLibrary ( - const std::string& Library ///< The library to link in + const std::string& Library, ///< The library to link in + bool& is_file ///< Indicates if lib is really a bc file ); /// This function links one bytecode archive, \p Filename, into the module. diff --git a/lib/Linker/LinkItems.cpp b/lib/Linker/LinkItems.cpp index a67733437ee..aaa87dcb377 100644 --- a/lib/Linker/LinkItems.cpp +++ b/lib/Linker/LinkItems.cpp @@ -17,17 +17,28 @@ using namespace llvm; -// LinkItems - preserve link order for an arbitrary set of linkage items. +// LinkItems - This function is the main entry point into linking. It takes a +// list of LinkItem which indicates the order the files should be linked and +// how each file should be treated (plain file or with library search). The +// function only links bytecode and produces a result list of items that are +// native objects. bool -Linker::LinkInItems(const ItemList& Items) { +Linker::LinkInItems(const ItemList& Items, ItemList& NativeItems) { + // Clear the NativeItems just in case + NativeItems.clear(); + // For each linkage item ... for (ItemList::const_iterator I = Items.begin(), E = Items.end(); I != E; ++I) { if (I->second) { // Link in the library suggested. - if (LinkInLibrary(I->first)) + bool is_file = true; + if (LinkInLibrary(I->first,is_file)) return true; + if (!is_file) + NativeItems.push_back(*I); } else { + // Link in the file suggested if (LinkInFile(sys::Path(I->first))) return true; } @@ -38,9 +49,10 @@ Linker::LinkInItems(const ItemList& Items) { // that module should also be aggregated with duplicates eliminated. This is // now the time to process the dependent libraries to resolve any remaining // symbols. + bool is_bytecode; for (Module::lib_iterator I = Composite->lib_begin(), E = Composite->lib_end(); I != E; ++I) - if(LinkInLibrary(*I)) + if(LinkInLibrary(*I, is_bytecode)) return true; return false; @@ -49,25 +61,30 @@ Linker::LinkInItems(const ItemList& Items) { /// LinkInLibrary - links one library into the HeadModule. /// -bool Linker::LinkInLibrary(const std::string& Lib) { +bool Linker::LinkInLibrary(const std::string& Lib, bool& is_file) { + is_file = false; // Determine where this library lives. sys::Path Pathname = FindLib(Lib); if (Pathname.isEmpty()) return warning("Cannot find library '" + Lib + "'"); // If its an archive, try to link it in - if (Pathname.isArchive()) { - if (LinkInArchive(Pathname)) - return error("Cannot link archive '" + Pathname.toString() + "'"); - } else if (Pathname.isBytecodeFile()) { - // LLVM ".so" file. - if (LinkInFile(Pathname)) - return error("Cannot link file '" + Pathname.toString() + "'"); - - } else if (Pathname.isDynamicLibrary()) { - return warning("Library '" + Lib + "' is a native dynamic library."); - } else { - return warning("Supposed library '" + Lib + "' isn't a library."); + std::string Magic; + Pathname.getMagicNumber(Magic, 64); + switch (sys::IdentifyFileType(Magic.c_str(), 64)) { + case sys::BytecodeFileType: + case sys::CompressedBytecodeFileType: + // LLVM ".so" file. + if (LinkInFile(Pathname)) + return error("Cannot link file '" + Pathname.toString() + "'"); + is_file = true; + break; + case sys::ArchiveFileType: + if (LinkInArchive(Pathname)) + return error("Cannot link archive '" + Pathname.toString() + "'"); + break; + default: + return warning("Supposed library '" + Lib + "' isn't a library."); } return false; } @@ -85,8 +102,9 @@ bool Linker::LinkInLibrary(const std::string& Lib) { bool Linker::LinkInLibraries(const std::vector &Libraries) { // Process the set of libraries we've been provided. + bool is_bytecode; for (unsigned i = 0; i < Libraries.size(); ++i) - if (LinkInLibrary(Libraries[i])) + if (LinkInLibrary(Libraries[i], is_bytecode)) return true; // At this point we have processed all the libraries provided to us. Since @@ -97,7 +115,7 @@ bool Linker::LinkInLibraries(const std::vector &Libraries) { const Module::LibraryListType& DepLibs = Composite->getLibraries(); for (Module::LibraryListType::const_iterator I = DepLibs.begin(), E = DepLibs.end(); I != E; ++I) - if (LinkInLibrary(*I)) + if (LinkInLibrary(*I, is_bytecode)) return true; return false; diff --git a/tools/gccld/gccld.cpp b/tools/gccld/gccld.cpp index ae451000884..22a26ef91a7 100644 --- a/tools/gccld/gccld.cpp +++ b/tools/gccld/gccld.cpp @@ -243,11 +243,23 @@ int main(int argc, char **argv, char **envp ) { } else { // Build a list of the items from our command line Linker::ItemList Items; + Linker::ItemList NativeItems; BuildLinkItems(Items, InputFilenames, Libraries); // Link all the items together - if (TheLinker.LinkInItems(Items)) + if (TheLinker.LinkInItems(Items,NativeItems)) return 1; // Error already printed + + // Revise the Libraries based on the remaining (native) libraries that + // were not linked in to the bytecode. This ensures that we don't attempt + // to pass a bytecode library to the native linker + Libraries.clear(); // we've consumed the libraries except for native + if ((Native || NativeCBE) && !NativeItems.empty()) { + for (Linker::ItemList::const_iterator I = NativeItems.begin(), + E = NativeItems.end(); I != E; ++I) { + Libraries.push_back(I->first); + } + } } // We're done with the Linker, so tell it to release its module diff --git a/tools/llvm-ld/llvm-ld.cpp b/tools/llvm-ld/llvm-ld.cpp index 0c633d2462d..f6c9c747421 100644 --- a/tools/llvm-ld/llvm-ld.cpp +++ b/tools/llvm-ld/llvm-ld.cpp @@ -434,10 +434,11 @@ int main(int argc, char **argv, char **envp) { } else { // Build a list of the items from our command line Linker::ItemList Items; + Linker::ItemList NativeItems; BuildLinkItems(Items, InputFilenames, Libraries); // Link all the items together - if (TheLinker.LinkInItems(Items) ) + if (TheLinker.LinkInItems(Items,NativeItems) ) return 1; }