blob: 9d5c50f121fc87809207f699e85ac483acbb19e1 [file] [log] [blame]
Michael J. Spencer84487f12015-07-24 21:03:07 +00001//===- 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
Rui Ueyamaafff74e22015-08-05 23:24:46 +000010#include "Driver.h"
Rafael Espindola192e1fa2015-08-06 15:08:23 +000011#include "Config.h"
12#include "Error.h"
Rui Ueyamaafff74e22015-08-05 23:24:46 +000013#include "InputFiles.h"
14#include "SymbolTable.h"
Michael J. Spencer84487f12015-07-24 21:03:07 +000015#include "Writer.h"
16#include "llvm/ADT/STLExtras.h"
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000017#include "llvm/Support/FileSystem.h"
Michael J. Spencer84487f12015-07-24 21:03:07 +000018
19using namespace llvm;
20
21using namespace lld;
22using namespace lld::elf2;
23
24namespace lld {
25namespace elf2 {
26Configuration *Config;
Michael J. Spencer84487f12015-07-24 21:03:07 +000027
28void link(ArrayRef<const char *> Args) {
Rui Ueyama570752c2015-08-18 09:13:25 +000029 Configuration C;
30 Config = &C;
Rui Ueyama880632c2015-08-11 21:45:55 +000031 LinkerDriver().link(Args.slice(1));
Michael J. Spencer84487f12015-07-24 21:03:07 +000032}
33
Michael J. Spencer84487f12015-07-24 21:03:07 +000034}
35}
36
37// Opens a file. Path has to be resolved already.
38// Newly created memory buffers are owned by this driver.
39MemoryBufferRef LinkerDriver::openFile(StringRef Path) {
40 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getFile(Path);
41 error(MBOrErr, Twine("cannot open ") + Path);
42 std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
43 MemoryBufferRef MBRef = MB->getMemBufferRef();
44 OwningMBs.push_back(std::move(MB)); // take ownership
45 return MBRef;
46}
47
48static std::unique_ptr<InputFile> createFile(MemoryBufferRef MB) {
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000049 using namespace llvm::sys::fs;
50 file_magic Magic = identify_magic(MB.getBuffer());
51
Michael J. Spencer1b348a62015-09-04 22:28:10 +000052 if (Magic == file_magic::archive)
53 return make_unique<ArchiveFile>(MB);
Rafael Espindolaaefd5c12015-08-04 15:45:54 +000054
Michael J. Spencer1b348a62015-09-04 22:28:10 +000055 if (Magic == file_magic::elf_shared_object)
56 return createELFFile<SharedFile>(MB);
57
58 return createELFFile<ObjectFile>(MB);
Michael J. Spencer84487f12015-07-24 21:03:07 +000059}
60
61void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
62 // Parse command line options.
63 opt::InputArgList Args = Parser.parse(ArgsArr);
64
65 // Handle -o
66 if (auto *Arg = Args.getLastArg(OPT_output))
67 Config->OutputFile = Arg->getValue();
68 if (Config->OutputFile.empty())
69 error("-o must be specified.");
70
71 // Create a list of input files.
72 std::vector<MemoryBufferRef> Inputs;
73
74 for (auto *Arg : Args.filtered(OPT_INPUT)) {
75 StringRef Path = Arg->getValue();
76 Inputs.push_back(openFile(Path));
77 }
78
79 if (Inputs.empty())
80 error("no input files.");
81
82 // Create a symbol table.
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000083 SymbolTable Symtab;
Michael J. Spencer84487f12015-07-24 21:03:07 +000084
85 // Parse all input files and put all symbols to the symbol table.
86 // The symbol table will take care of name resolution.
87 for (MemoryBufferRef MB : Inputs) {
88 std::unique_ptr<InputFile> File = createFile(MB);
89 Symtab.addFile(std::move(File));
90 }
91
Michael J. Spencer84487f12015-07-24 21:03:07 +000092 // Write the result.
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000093 const ELFFileBase *FirstObj = Symtab.getFirstELF();
94 switch (FirstObj->getELFKind()) {
Rafael Espindola905ad342015-09-02 20:43:43 +000095 case ELF32LEKind:
Rui Ueyamacb8474ed2015-08-05 23:51:50 +000096 writeResult<object::ELF32LE>(&Symtab);
Rafael Espindola4b7c2fc2015-08-05 15:08:40 +000097 return;
Rafael Espindola905ad342015-09-02 20:43:43 +000098 case ELF32BEKind:
Rui Ueyamacb8474ed2015-08-05 23:51:50 +000099 writeResult<object::ELF32BE>(&Symtab);
Rafael Espindola4b7c2fc2015-08-05 15:08:40 +0000100 return;
Rafael Espindola905ad342015-09-02 20:43:43 +0000101 case ELF64LEKind:
Rui Ueyamacb8474ed2015-08-05 23:51:50 +0000102 writeResult<object::ELF64LE>(&Symtab);
Rafael Espindola4b7c2fc2015-08-05 15:08:40 +0000103 return;
Rafael Espindola905ad342015-09-02 20:43:43 +0000104 case ELF64BEKind:
Rui Ueyamacb8474ed2015-08-05 23:51:50 +0000105 writeResult<object::ELF64BE>(&Symtab);
Rafael Espindola4b7c2fc2015-08-05 15:08:40 +0000106 return;
107 }
Michael J. Spencer84487f12015-07-24 21:03:07 +0000108}