1 //===- Driver.cpp ---------------------------------------------------------===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 10 #include "Driver.h" 11 #include "Config.h" 12 #include "Error.h" 13 #include "InputFiles.h" 14 #include "SymbolTable.h" 15 #include "Writer.h" 16 #include "llvm/ADT/STLExtras.h" 17 #include "llvm/ADT/StringExtras.h" 18 #include "llvm/Support/FileSystem.h" 19 #include "llvm/Support/Path.h" 20 21 using namespace llvm; 22 23 using namespace lld; 24 using namespace lld::elf2; 25 26 namespace lld { 27 namespace elf2 { 28 29 Configuration *Config; 30 std::vector<std::unique_ptr<MemoryBuffer>> *MemoryBufferPool; 31 32 void link(ArrayRef<const char *> Args) { 33 Configuration C; 34 Config = &C; 35 std::vector<std::unique_ptr<MemoryBuffer>> V; 36 MemoryBufferPool = &V; 37 LinkerDriver().link(Args.slice(1)); 38 } 39 40 // Opens a file. Path has to be resolved already. 41 // Newly created memory buffers are owned by this driver. 42 MemoryBufferRef openFile(StringRef Path) { 43 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getFile(Path); 44 error(MBOrErr, Twine("cannot open ") + Path); 45 std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 46 MemoryBufferRef MBRef = MB->getMemBufferRef(); 47 MemoryBufferPool->push_back(std::move(MB)); // transfer ownership 48 return MBRef; 49 } 50 } 51 } 52 53 // Makes a path by concatenating Dir and File. 54 // If Dir starts with '=' the result will be preceded by Sysroot, 55 // which can be set with --sysroot command line switch. 56 static std::string buildSysrootedPath(StringRef Dir, StringRef File) { 57 SmallString<128> Path; 58 if (Dir.startswith("=")) 59 sys::path::append(Path, Config->Sysroot, Dir.substr(1), File); 60 else 61 sys::path::append(Path, Dir, File); 62 return Path.str().str(); 63 } 64 65 // Searches a given library from input search paths, which are filled 66 // from -L command line switches. Returns a path to an existent library file. 67 static std::string searchLibrary(StringRef Path) { 68 std::vector<std::string> Names; 69 if (Path[0] == ':') { 70 Names.push_back(Path.drop_front().str()); 71 } else { 72 Names.push_back((Twine("lib") + Path + ".so").str()); 73 Names.push_back((Twine("lib") + Path + ".a").str()); 74 } 75 for (StringRef Dir : Config->InputSearchPaths) { 76 for (const std::string &Name : Names) { 77 std::string FullPath = buildSysrootedPath(Dir, Name); 78 if (sys::fs::exists(FullPath)) 79 return FullPath; 80 } 81 } 82 error(Twine("Unable to find library -l") + Path); 83 } 84 85 // Returns true if MB looks like a linker script. 86 static bool isLinkerScript(MemoryBufferRef MB) { 87 using namespace llvm::sys::fs; 88 return identify_magic(MB.getBuffer()) == file_magic::unknown; 89 } 90 91 void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { 92 // Parse command line options. 93 opt::InputArgList Args = Parser.parse(ArgsArr); 94 95 if (auto *Arg = Args.getLastArg(OPT_output)) 96 Config->OutputFile = Arg->getValue(); 97 98 if (auto *Arg = Args.getLastArg(OPT_dynamic_linker)) 99 Config->DynamicLinker = Arg->getValue(); 100 101 if (auto *Arg = Args.getLastArg(OPT_sysroot)) 102 Config->Sysroot = Arg->getValue(); 103 104 std::vector<StringRef> RPaths; 105 for (auto *Arg : Args.filtered(OPT_rpath)) 106 RPaths.push_back(Arg->getValue()); 107 if (!RPaths.empty()) 108 Config->RPath = llvm::join(RPaths.begin(), RPaths.end(), ":"); 109 110 for (auto *Arg : Args.filtered(OPT_L)) 111 Config->InputSearchPaths.push_back(Arg->getValue()); 112 113 if (auto *Arg = Args.getLastArg(OPT_entry)) 114 Config->Entry = Arg->getValue(); 115 116 Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition); 117 Config->DiscardAll = Args.hasArg(OPT_discard_all); 118 Config->DiscardLocals = Args.hasArg(OPT_discard_locals); 119 Config->DiscardNone = Args.hasArg(OPT_discard_none); 120 Config->ExportDynamic = Args.hasArg(OPT_export_dynamic); 121 Config->NoInhibitExec = Args.hasArg(OPT_noinhibit_exec); 122 Config->Shared = Args.hasArg(OPT_shared); 123 124 // Create a symbol table. 125 SymbolTable Symtab; 126 127 for (auto *Arg : Args.filtered(OPT_l, OPT_INPUT)) { 128 std::string Path = Arg->getValue(); 129 if (Arg->getOption().getID() == OPT_l) 130 Path = searchLibrary(Path); 131 MemoryBufferRef MB = openFile(Path); 132 if (isLinkerScript(MB)) { 133 // readLinkerScript may add files to the symbol table. 134 readLinkerScript(&Symtab, MB); 135 continue; 136 } 137 Symtab.addFile(createFile(MB)); 138 } 139 140 if (Symtab.getObjectFiles().empty()) 141 error("no input files."); 142 143 // Write the result. 144 const ELFFileBase *FirstObj = Symtab.getFirstELF(); 145 switch (FirstObj->getELFKind()) { 146 case ELF32LEKind: 147 writeResult<object::ELF32LE>(&Symtab); 148 return; 149 case ELF32BEKind: 150 writeResult<object::ELF32BE>(&Symtab); 151 return; 152 case ELF64LEKind: 153 writeResult<object::ELF64LE>(&Symtab); 154 return; 155 case ELF64BEKind: 156 writeResult<object::ELF64BE>(&Symtab); 157 return; 158 } 159 } 160