X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FLinker%2FLinkArchives.cpp;h=2c4ed7fdc17a78e0cf70500cc65571842fe2e9f6;hb=680018ff8965610b3f1c976b0be1dfd45116b218;hp=69549251b9f17432031b3b22dd4db825041eb06a;hpb=50c301b9bbf80c00d26e49129a2a5d02132b9b2b;p=oota-llvm.git diff --git a/lib/Linker/LinkArchives.cpp b/lib/Linker/LinkArchives.cpp index 69549251b9f..2c4ed7fdc17 100644 --- a/lib/Linker/LinkArchives.cpp +++ b/lib/Linker/LinkArchives.cpp @@ -1,43 +1,26 @@ //===- lib/Linker/LinkArchives.cpp - Link LLVM objects and libraries ------===// -// +// // The LLVM Compiler Infrastructure // -// This file was developed by the LLVM research group and is distributed under -// the University of Illinois Open Source License. See LICENSE.TXT for details. -// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// //===----------------------------------------------------------------------===// // -// This file contains routines to handle linking together LLVM bytecode files, +// This file contains routines to handle linking together LLVM bitcode files, // and to handle annoying things like static libraries. // //===----------------------------------------------------------------------===// #include "llvm/Linker.h" #include "llvm/Module.h" -#include "llvm/ModuleProvider.h" #include "llvm/ADT/SetOperations.h" -#include "llvm/Bytecode/Reader.h" -#include "llvm/Bytecode/Archive.h" +#include "llvm/Bitcode/Archive.h" #include "llvm/Config/config.h" #include #include -#include - using namespace llvm; -/// GetAllDefinedSymbols - Modifies its parameter DefinedSymbols to contain the -/// name of each externally-visible symbol defined in M. -/// -static void -GetAllDefinedSymbols(Module *M, std::set &DefinedSymbols) { - for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) - if (I->hasName() && !I->isExternal() && !I->hasInternalLinkage()) - DefinedSymbols.insert(I->getName()); - for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) - if (I->hasName() && !I->isExternal() && !I->hasInternalLinkage()) - DefinedSymbols.insert(I->getName()); -} - /// GetAllUndefinedSymbols - calculates the set of undefined symbols that still /// exist in an LLVM module. This is a bit tricky because there may be two /// symbols with the same name but different LLVM types that will be resolved to @@ -54,22 +37,42 @@ static void GetAllUndefinedSymbols(Module *M, std::set &UndefinedSymbols) { std::set DefinedSymbols; UndefinedSymbols.clear(); - + + // If the program doesn't define a main, try pulling one in from a .a file. + // This is needed for programs where the main function is defined in an + // archive, such f2c'd programs. + Function *Main = M->getFunction("main"); + if (Main == 0 || Main->isDeclaration()) + UndefinedSymbols.insert("main"); + for (Module::iterator I = M->begin(), E = M->end(); I != E; ++I) if (I->hasName()) { - if (I->isExternal()) + if (I->isDeclaration()) UndefinedSymbols.insert(I->getName()); - else if (!I->hasInternalLinkage()) + else if (!I->hasLocalLinkage()) { + assert(!I->hasDLLImportLinkage() + && "Found dllimported non-external symbol!"); DefinedSymbols.insert(I->getName()); + } } - for (Module::giterator I = M->gbegin(), E = M->gend(); I != E; ++I) + + for (Module::global_iterator I = M->global_begin(), E = M->global_end(); + I != E; ++I) if (I->hasName()) { - if (I->isExternal()) + if (I->isDeclaration()) UndefinedSymbols.insert(I->getName()); - else if (!I->hasInternalLinkage()) + else if (!I->hasLocalLinkage()) { + assert(!I->hasDLLImportLinkage() + && "Found dllimported non-external symbol!"); DefinedSymbols.insert(I->getName()); + } } - + + for (Module::alias_iterator I = M->alias_begin(), E = M->alias_end(); + I != E; ++I) + if (I->hasName()) + DefinedSymbols.insert(I->getName()); + // Prune out any defined symbols from the undefined symbols set... for (std::set::iterator I = UndefinedSymbols.begin(); I != UndefinedSymbols.end(); ) @@ -88,51 +91,62 @@ GetAllUndefinedSymbols(Module *M, std::set &UndefinedSymbols) { /// Return Value: /// TRUE - An error occurred. /// FALSE - No errors. -bool -Linker::LinkInArchive(const sys::Path &Filename) { - +bool +Linker::LinkInArchive(const sys::Path &Filename, bool &is_native) { // Make sure this is an archive file we're dealing with if (!Filename.isArchive()) - return error("File '" + Filename.toString() + "' is not an archive."); + return error("File '" + Filename.str() + "' is not an archive."); // Open the archive file - verbose("Linking archive file '" + Filename.toString() + "'"); + verbose("Linking archive file '" + Filename.str() + "'"); - // Find all of the symbols currently undefined in the bytecode program. + // Find all of the symbols currently undefined in the bitcode program. // If all the symbols are defined, the program is complete, and there is // no reason to link in any archive files. std::set UndefinedSymbols; GetAllUndefinedSymbols(Composite, UndefinedSymbols); - + if (UndefinedSymbols.empty()) { - verbose("No symbols undefined, skipping library '" + - Filename.toString() + "'"); + verbose("No symbols undefined, skipping library '" + Filename.str() + "'"); return false; // No need to link anything in! } std::string ErrMsg; std::auto_ptr AutoArch ( - Archive::OpenAndLoadSymbols(Filename,&ErrMsg)); + Archive::OpenAndLoadSymbols(Filename, Context, &ErrMsg)); Archive* arch = AutoArch.get(); if (!arch) - return error("Cannot read archive '" + Filename.toString() + + return error("Cannot read archive '" + Filename.str() + "': " + ErrMsg); + if (!arch->isBitcodeArchive()) { + is_native = true; + return false; + } + is_native = false; // Save a set of symbols that are not defined by the archive. Since we're // entering a loop, there's no point searching for these multiple times. This // variable is used to "set_subtract" from the set of undefined symbols. std::set NotDefinedByArchive; - // While we are linking in object files, loop. - while (true) { + // Save the current set of undefined symbols, because we may have to make + // multiple passes over the archive: + std::set CurrentlyUndefinedSymbols; - // Find the modules we need to link into the target module - std::set Modules; - arch->findModulesDefiningSymbols(UndefinedSymbols, Modules); + do { + CurrentlyUndefinedSymbols = UndefinedSymbols; - // If we didn't find any more modules to link this time, we are done + // Find the modules we need to link into the target module. Note that arch + // keeps ownership of these modules and may return the same Module* from a + // subsequent call. + std::set Modules; + if (!arch->findModulesDefiningSymbols(UndefinedSymbols, Modules, &ErrMsg)) + return error("Cannot find symbols in '" + Filename.str() + + "': " + ErrMsg); + + // If we didn't find any more modules to link this time, we are done // searching this archive. if (Modules.empty()) break; @@ -143,39 +157,42 @@ Linker::LinkInArchive(const sys::Path &Filename) { NotDefinedByArchive.insert(UndefinedSymbols.begin(), UndefinedSymbols.end()); - // Loop over all the ModuleProviders that we got back from the archive - for (std::set::iterator I=Modules.begin(), E=Modules.end(); + // Loop over all the Modules that we got back from the archive + for (std::set::iterator I=Modules.begin(), E=Modules.end(); I != E; ++I) { // Get the module we must link in. - std::auto_ptr AutoModule( (*I)->releaseModule() ); - Module* aModule = AutoModule.get(); - - verbose(" Linking in module: " + aModule->getModuleIdentifier()); - - // Link it in - if (this->LinkInModule(aModule)) - return error("Cannot link in module '" + - aModule->getModuleIdentifier() + "': " + Error); + std::string moduleErrorMsg; + Module* aModule = *I; + if (aModule != NULL) { + if (aModule->MaterializeAll(&moduleErrorMsg)) + return error("Could not load a module: " + moduleErrorMsg); + + verbose(" Linking in module: " + aModule->getModuleIdentifier()); + + // Link it in + if (LinkInModule(aModule, &moduleErrorMsg)) + return error("Cannot link in module '" + + aModule->getModuleIdentifier() + "': " + moduleErrorMsg); + } } - + // Get the undefined symbols from the aggregate module. This recomputes the // symbols we still need after the new modules have been linked in. GetAllUndefinedSymbols(Composite, UndefinedSymbols); // At this point we have two sets of undefined symbols: UndefinedSymbols - // which holds the undefined symbols from all the modules, and + // which holds the undefined symbols from all the modules, and // NotDefinedByArchive which holds symbols we know the archive doesn't // define. There's no point searching for symbols that we won't find in the // archive so we subtract these sets. - set_subtract,std::set >( - UndefinedSymbols,NotDefinedByArchive); - + set_subtract(UndefinedSymbols, NotDefinedByArchive); + // If there's no symbols left, no point in continuing to search the // archive. if (UndefinedSymbols.empty()) break; - } - + } while (CurrentlyUndefinedSymbols != UndefinedSymbols); + return false; }