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 Configuration *lld::elf2::Config; 27 LinkerDriver *lld::elf2::Driver; 28 29 void lld::elf2::link(ArrayRef<const char *> Args) { 30 Configuration C; 31 LinkerDriver D; 32 Config = &C; 33 Driver = &D; 34 Driver->link(Args.slice(1)); 35 } 36 37 // Makes a path by concatenating Dir and File. 38 // If Dir starts with '=' the result will be preceded by Sysroot, 39 // which can be set with --sysroot command line switch. 40 static std::string buildSysrootedPath(StringRef Dir, StringRef File) { 41 SmallString<128> Path; 42 if (Dir.startswith("=")) 43 sys::path::append(Path, Config->Sysroot, Dir.substr(1), File); 44 else 45 sys::path::append(Path, Dir, File); 46 return Path.str().str(); 47 } 48 49 // Searches a given library from input search paths, which are filled 50 // from -L command line switches. Returns a path to an existent library file. 51 static std::string searchLibrary(StringRef Path) { 52 std::vector<std::string> Names; 53 if (Path[0] == ':') { 54 Names.push_back(Path.drop_front().str()); 55 } else { 56 if (!Config->Static) 57 Names.push_back((Twine("lib") + Path + ".so").str()); 58 Names.push_back((Twine("lib") + Path + ".a").str()); 59 } 60 for (StringRef Dir : Config->InputSearchPaths) { 61 for (const std::string &Name : Names) { 62 std::string FullPath = buildSysrootedPath(Dir, Name); 63 if (sys::fs::exists(FullPath)) 64 return FullPath; 65 } 66 } 67 error(Twine("Unable to find library -l") + Path); 68 } 69 70 // Opens and parses a file. Path has to be resolved already. 71 // Newly created memory buffers are owned by this driver. 72 void LinkerDriver::addFile(StringRef Path) { 73 using namespace llvm::sys::fs; 74 auto MBOrErr = MemoryBuffer::getFile(Path); 75 error(MBOrErr, Twine("cannot open ") + Path); 76 std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 77 MemoryBufferRef MBRef = MB->getMemBufferRef(); 78 OwningMBs.push_back(std::move(MB)); // take MB ownership 79 80 switch (identify_magic(MBRef.getBuffer())) { 81 case file_magic::unknown: 82 readLinkerScript(MBRef); 83 return; 84 case file_magic::archive: 85 Symtab.addFile(make_unique<ArchiveFile>(MBRef)); 86 return; 87 case file_magic::elf_shared_object: 88 Symtab.addFile(createELFFile<SharedFile>(MBRef)); 89 return; 90 default: 91 Symtab.addFile(createELFFile<ObjectFile>(MBRef)); 92 } 93 } 94 95 void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { 96 // Parse command line options. 97 opt::InputArgList Args = Parser.parse(ArgsArr); 98 99 if (auto *Arg = Args.getLastArg(OPT_output)) 100 Config->OutputFile = Arg->getValue(); 101 102 if (auto *Arg = Args.getLastArg(OPT_dynamic_linker)) 103 Config->DynamicLinker = Arg->getValue(); 104 105 if (auto *Arg = Args.getLastArg(OPT_sysroot)) 106 Config->Sysroot = Arg->getValue(); 107 108 std::vector<StringRef> RPaths; 109 for (auto *Arg : Args.filtered(OPT_rpath)) 110 RPaths.push_back(Arg->getValue()); 111 if (!RPaths.empty()) 112 Config->RPath = llvm::join(RPaths.begin(), RPaths.end(), ":"); 113 114 for (auto *Arg : Args.filtered(OPT_L)) 115 Config->InputSearchPaths.push_back(Arg->getValue()); 116 117 if (auto *Arg = Args.getLastArg(OPT_entry)) 118 Config->Entry = Arg->getValue(); 119 120 if (auto *Arg = Args.getLastArg(OPT_fini)) 121 Config->Fini = Arg->getValue(); 122 123 if (auto *Arg = Args.getLastArg(OPT_init)) 124 Config->Init = Arg->getValue(); 125 126 if (auto *Arg = Args.getLastArg(OPT_soname)) 127 Config->SoName = Arg->getValue(); 128 129 Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition); 130 Config->DiscardAll = Args.hasArg(OPT_discard_all); 131 Config->DiscardLocals = Args.hasArg(OPT_discard_locals); 132 Config->DiscardNone = Args.hasArg(OPT_discard_none); 133 Config->ExportDynamic = Args.hasArg(OPT_export_dynamic); 134 Config->NoInhibitExec = Args.hasArg(OPT_noinhibit_exec); 135 Config->NoUndefined = Args.hasArg(OPT_no_undefined); 136 Config->Shared = Args.hasArg(OPT_shared); 137 138 for (auto *Arg : Args) { 139 switch (Arg->getOption().getID()) { 140 case OPT_l: 141 addFile(searchLibrary(Arg->getValue())); 142 break; 143 case OPT_INPUT: 144 addFile(Arg->getValue()); 145 break; 146 case OPT_Bstatic: 147 Config->Static = true; 148 break; 149 case OPT_Bdynamic: 150 Config->Static = false; 151 break; 152 case OPT_whole_archive: 153 Config->WholeArchive = true; 154 break; 155 case OPT_no_whole_archive: 156 Config->WholeArchive = false; 157 break; 158 default: 159 break; 160 } 161 } 162 163 if (Symtab.getObjectFiles().empty()) 164 error("no input files."); 165 166 for (auto *Arg : Args.filtered(OPT_undefined)) 167 Symtab.addUndefinedSym(Arg->getValue()); 168 169 // Write the result. 170 const ELFFileBase *FirstObj = Symtab.getFirstELF(); 171 switch (FirstObj->getELFKind()) { 172 case ELF32LEKind: 173 writeResult<object::ELF32LE>(&Symtab); 174 return; 175 case ELF32BEKind: 176 writeResult<object::ELF32BE>(&Symtab); 177 return; 178 case ELF64LEKind: 179 writeResult<object::ELF64LE>(&Symtab); 180 return; 181 case ELF64BEKind: 182 writeResult<object::ELF64BE>(&Symtab); 183 return; 184 } 185 } 186