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 18 using namespace llvm; 19 20 using namespace lld; 21 using namespace lld::elf2; 22 23 namespace lld { 24 namespace elf2 { 25 Configuration *Config; 26 27 void link(ArrayRef<const char *> Args) { 28 auto C = make_unique<Configuration>(); 29 Config = C.get(); 30 LinkerDriver().link(Args.slice(1)); 31 } 32 33 } 34 } 35 36 // Opens a file. Path has to be resolved already. 37 // Newly created memory buffers are owned by this driver. 38 MemoryBufferRef LinkerDriver::openFile(StringRef Path) { 39 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getFile(Path); 40 error(MBOrErr, Twine("cannot open ") + Path); 41 std::unique_ptr<MemoryBuffer> &MB = *MBOrErr; 42 MemoryBufferRef MBRef = MB->getMemBufferRef(); 43 OwningMBs.push_back(std::move(MB)); // take ownership 44 return MBRef; 45 } 46 47 static std::unique_ptr<InputFile> createFile(MemoryBufferRef MB) { 48 std::pair<unsigned char, unsigned char> Type = 49 object::getElfArchType(MB.getBuffer()); 50 if (Type.second != ELF::ELFDATA2LSB && Type.second != ELF::ELFDATA2MSB) 51 error("Invalid data encoding"); 52 53 if (Type.first == ELF::ELFCLASS32) { 54 if (Type.second == ELF::ELFDATA2LSB) 55 return make_unique<ObjectFile<object::ELF32LE>>(MB); 56 return make_unique<ObjectFile<object::ELF32BE>>(MB); 57 } 58 if (Type.first == ELF::ELFCLASS64) { 59 if (Type.second == ELF::ELFDATA2LSB) 60 return make_unique<ObjectFile<object::ELF64LE>>(MB); 61 return make_unique<ObjectFile<object::ELF64BE>>(MB); 62 } 63 error("Invalid file class"); 64 } 65 66 void LinkerDriver::link(ArrayRef<const char *> ArgsArr) { 67 // Parse command line options. 68 opt::InputArgList Args = Parser.parse(ArgsArr); 69 70 // Handle -o 71 if (auto *Arg = Args.getLastArg(OPT_output)) 72 Config->OutputFile = Arg->getValue(); 73 if (Config->OutputFile.empty()) 74 error("-o must be specified."); 75 76 // Create a list of input files. 77 std::vector<MemoryBufferRef> Inputs; 78 79 for (auto *Arg : Args.filtered(OPT_INPUT)) { 80 StringRef Path = Arg->getValue(); 81 Inputs.push_back(openFile(Path)); 82 } 83 84 if (Inputs.empty()) 85 error("no input files."); 86 87 // Create a symbol table. 88 SymbolTable Symtab; 89 90 // Parse all input files and put all symbols to the symbol table. 91 // The symbol table will take care of name resolution. 92 for (MemoryBufferRef MB : Inputs) { 93 std::unique_ptr<InputFile> File = createFile(MB); 94 Symtab.addFile(std::move(File)); 95 } 96 97 // Make sure we have resolved all symbols. 98 Symtab.reportRemainingUndefines(); 99 100 // Write the result. 101 ObjectFileBase &FirstObj = *Symtab.ObjectFiles[0]; 102 switch (FirstObj.kind()) { 103 case InputFile::Object32LEKind: 104 writeResult<object::ELF32LE>(&Symtab); 105 return; 106 case InputFile::Object32BEKind: 107 writeResult<object::ELF32BE>(&Symtab); 108 return; 109 case InputFile::Object64LEKind: 110 writeResult<object::ELF64LE>(&Symtab); 111 return; 112 case InputFile::Object64BEKind: 113 writeResult<object::ELF64BE>(&Symtab); 114 return; 115 } 116 } 117