1//===- lib/Linker/Linker.cpp - Basic Linker functionality ----------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file contains basic Linker functionality that all usages will need. 11// 12//===----------------------------------------------------------------------===// 13 14#include "llvm/Linker.h" 15#include "llvm/Module.h" 16#include "llvm/Bitcode/ReaderWriter.h" 17#include "llvm/Support/Path.h" 18#include "llvm/Support/MemoryBuffer.h" 19#include "llvm/Support/raw_ostream.h" 20#include "llvm/Support/system_error.h" 21using namespace llvm; 22 23Linker::Linker(StringRef progname, StringRef modname, 24 LLVMContext& C, unsigned flags): 25 Context(C), 26 Composite(new Module(modname, C)), 27 LibPaths(), 28 Flags(flags), 29 Error(), 30 ProgramName(progname) { } 31 32Linker::Linker(StringRef progname, Module* aModule, unsigned flags) : 33 Context(aModule->getContext()), 34 Composite(aModule), 35 LibPaths(), 36 Flags(flags), 37 Error(), 38 ProgramName(progname) { } 39 40Linker::~Linker() { 41 delete Composite; 42} 43 44bool 45Linker::error(StringRef message) { 46 Error = message; 47 if (!(Flags&QuietErrors)) 48 errs() << ProgramName << ": error: " << message << "\n"; 49 return true; 50} 51 52bool 53Linker::warning(StringRef message) { 54 Error = message; 55 if (!(Flags&QuietWarnings)) 56 errs() << ProgramName << ": warning: " << message << "\n"; 57 return false; 58} 59 60void 61Linker::verbose(StringRef message) { 62 if (Flags&Verbose) 63 errs() << " " << message << "\n"; 64} 65 66void 67Linker::addPath(const sys::Path& path) { 68 LibPaths.push_back(path); 69} 70 71void 72Linker::addPaths(const std::vector<std::string>& paths) { 73 for (unsigned i = 0, e = paths.size(); i != e; ++i) 74 LibPaths.push_back(sys::Path(paths[i])); 75} 76 77void 78Linker::addSystemPaths() { 79 sys::Path::GetBitcodeLibraryPaths(LibPaths); 80 LibPaths.insert(LibPaths.begin(),sys::Path("./")); 81} 82 83Module* 84Linker::releaseModule() { 85 Module* result = Composite; 86 LibPaths.clear(); 87 Error.clear(); 88 Composite = 0; 89 Flags = 0; 90 return result; 91} 92 93// LoadObject - Read in and parse the bitcode file named by FN and return the 94// module it contains (wrapped in an auto_ptr), or auto_ptr<Module>() and set 95// Error if an error occurs. 96std::auto_ptr<Module> 97Linker::LoadObject(const sys::Path &FN) { 98 std::string ParseErrorMessage; 99 Module *Result = 0; 100 101 OwningPtr<MemoryBuffer> Buffer; 102 if (error_code ec = MemoryBuffer::getFileOrSTDIN(FN.c_str(), Buffer)) 103 ParseErrorMessage = "Error reading file '" + FN.str() + "'" + ": " 104 + ec.message(); 105 else 106 Result = ParseBitcodeFile(Buffer.get(), Context, &ParseErrorMessage); 107 108 if (Result) 109 return std::auto_ptr<Module>(Result); 110 Error = "Bitcode file '" + FN.str() + "' could not be loaded"; 111 if (ParseErrorMessage.size()) 112 Error += ": " + ParseErrorMessage; 113 return std::auto_ptr<Module>(); 114} 115 116// IsLibrary - Determine if "Name" is a library in "Directory". Return 117// a non-empty sys::Path if its found, an empty one otherwise. 118static inline sys::Path IsLibrary(StringRef Name, 119 const sys::Path &Directory) { 120 121 sys::Path FullPath(Directory); 122 123 // Try the libX.a form 124 FullPath.appendComponent(("lib" + Name).str()); 125 FullPath.appendSuffix("a"); 126 if (FullPath.isArchive()) 127 return FullPath; 128 129 // Try the libX.bca form 130 FullPath.eraseSuffix(); 131 FullPath.appendSuffix("bca"); 132 if (FullPath.isArchive()) 133 return FullPath; 134 135 // Try the libX.so (or .dylib) form 136 FullPath.eraseSuffix(); 137 FullPath.appendSuffix(sys::Path::GetDLLSuffix()); 138 if (FullPath.isDynamicLibrary()) // Native shared library? 139 return FullPath; 140 if (FullPath.isBitcodeFile()) // .so file containing bitcode? 141 return FullPath; 142 143 // Try libX form, to make it possible to add dependency on the 144 // specific version of .so, like liblzma.so.1.0.0 145 FullPath.eraseSuffix(); 146 if (FullPath.isDynamicLibrary()) // Native shared library? 147 return FullPath; 148 if (FullPath.isBitcodeFile()) // .so file containing bitcode? 149 return FullPath; 150 151 // Not found .. fall through 152 153 // Indicate that the library was not found in the directory. 154 FullPath.clear(); 155 return FullPath; 156} 157 158/// FindLib - Try to convert Filename into the name of a file that we can open, 159/// if it does not already name a file we can open, by first trying to open 160/// Filename, then libFilename.[suffix] for each of a set of several common 161/// library suffixes, in each of the directories in LibPaths. Returns an empty 162/// Path if no matching file can be found. 163/// 164sys::Path 165Linker::FindLib(StringRef Filename) { 166 // Determine if the pathname can be found as it stands. 167 sys::Path FilePath(Filename); 168 if (FilePath.canRead() && 169 (FilePath.isArchive() || FilePath.isDynamicLibrary())) 170 return FilePath; 171 172 // Iterate over the directories in Paths to see if we can find the library 173 // there. 174 for (unsigned Index = 0; Index != LibPaths.size(); ++Index) { 175 sys::Path Directory(LibPaths[Index]); 176 sys::Path FullPath = IsLibrary(Filename, Directory); 177 if (!FullPath.isEmpty()) 178 return FullPath; 179 } 180 return sys::Path(); 181} 182