blob: 1391056ad645091d1ed86ec6435daa4589296922 [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
10#include "Driver.h"
11#include "Config.h"
12#include "Writer.h"
13#include "llvm/ADT/STLExtras.h"
14
15using namespace llvm;
16
17using namespace lld;
18using namespace lld::elf2;
19
20namespace lld {
21namespace elf2 {
22Configuration *Config;
23LinkerDriver *Driver;
24
25void link(ArrayRef<const char *> Args) {
26 auto C = make_unique<Configuration>();
27 Config = C.get();
28 auto D = make_unique<LinkerDriver>();
29 Driver = D.get();
30 Driver->link(Args.slice(1));
31}
32
33void error(Twine Msg) {
34 errs() << Msg << "\n";
35 exit(1);
36}
37
38void error(std::error_code EC, Twine Prefix) {
39 if (!EC)
40 return;
41 error(Prefix + ": " + EC.message());
42}
43
44void error(std::error_code EC) {
45 if (!EC)
46 return;
47 error(EC.message());
48}
49}
50}
51
52// Opens a file. Path has to be resolved already.
53// Newly created memory buffers are owned by this driver.
54MemoryBufferRef LinkerDriver::openFile(StringRef Path) {
55 ErrorOr<std::unique_ptr<MemoryBuffer>> MBOrErr = MemoryBuffer::getFile(Path);
56 error(MBOrErr, Twine("cannot open ") + Path);
57 std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
58 MemoryBufferRef MBRef = MB->getMemBufferRef();
59 OwningMBs.push_back(std::move(MB)); // take ownership
60 return MBRef;
61}
62
63static std::unique_ptr<InputFile> createFile(MemoryBufferRef MB) {
64 return std::unique_ptr<InputFile>(new ObjectFile<object::ELF64LE>(MB));
65}
66
67void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
68 // Parse command line options.
69 opt::InputArgList Args = Parser.parse(ArgsArr);
70
71 // Handle -o
72 if (auto *Arg = Args.getLastArg(OPT_output))
73 Config->OutputFile = Arg->getValue();
74 if (Config->OutputFile.empty())
75 error("-o must be specified.");
76
77 // Create a list of input files.
78 std::vector<MemoryBufferRef> Inputs;
79
80 for (auto *Arg : Args.filtered(OPT_INPUT)) {
81 StringRef Path = Arg->getValue();
82 Inputs.push_back(openFile(Path));
83 }
84
85 if (Inputs.empty())
86 error("no input files.");
87
88 // Create a symbol table.
89 SymbolTable<object::ELF64LE> Symtab;
90
91 // Parse all input files and put all symbols to the symbol table.
92 // The symbol table will take care of name resolution.
93 for (MemoryBufferRef MB : Inputs) {
94 std::unique_ptr<InputFile> File = createFile(MB);
95 Symtab.addFile(std::move(File));
96 }
97
98 // Make sure we have resolved all symbols.
99 Symtab.reportRemainingUndefines();
100
101 // Write the result.
102 Writer<object::ELF64LE> Out(&Symtab);
103 Out.write(Config->OutputFile);
104}