blob: f80d74f0c67cb45ecf05798ce6ec32129cb0721e [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"
17
18using namespace llvm;
19
20using namespace lld;
21using namespace lld::elf2;
22
23namespace lld {
24namespace elf2 {
25Configuration *Config;
Michael J. Spencer84487f12015-07-24 21:03:07 +000026
27void link(ArrayRef<const char *> Args) {
28 auto C = make_unique<Configuration>();
29 Config = C.get();
Rui Ueyama880632c2015-08-11 21:45:55 +000030 LinkerDriver().link(Args.slice(1));
Michael J. Spencer84487f12015-07-24 21:03:07 +000031}
32
Michael J. Spencer84487f12015-07-24 21:03:07 +000033}
34}
35
36// Opens a file. Path has to be resolved already.
37// Newly created memory buffers are owned by this driver.
38MemoryBufferRef 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
47static std::unique_ptr<InputFile> createFile(MemoryBufferRef MB) {
Rafael Espindolaaefd5c12015-08-04 15:45:54 +000048 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");
Michael J. Spencer84487f12015-07-24 21:03:07 +000064}
65
66void 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.
Rafael Espindola2ffdd4d2015-08-04 14:29:01 +000088 SymbolTable Symtab;
Michael J. Spencer84487f12015-07-24 21:03:07 +000089
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.
Rafael Espindola4b7c2fc2015-08-05 15:08:40 +0000101 ObjectFileBase &FirstObj = *Symtab.ObjectFiles[0];
102 switch (FirstObj.kind()) {
Rui Ueyamaafff74e22015-08-05 23:24:46 +0000103 case InputFile::Object32LEKind:
Rui Ueyamacb8474ed2015-08-05 23:51:50 +0000104 writeResult<object::ELF32LE>(&Symtab);
Rafael Espindola4b7c2fc2015-08-05 15:08:40 +0000105 return;
Rui Ueyamaafff74e22015-08-05 23:24:46 +0000106 case InputFile::Object32BEKind:
Rui Ueyamacb8474ed2015-08-05 23:51:50 +0000107 writeResult<object::ELF32BE>(&Symtab);
Rafael Espindola4b7c2fc2015-08-05 15:08:40 +0000108 return;
Rui Ueyamaafff74e22015-08-05 23:24:46 +0000109 case InputFile::Object64LEKind:
Rui Ueyamacb8474ed2015-08-05 23:51:50 +0000110 writeResult<object::ELF64LE>(&Symtab);
Rafael Espindola4b7c2fc2015-08-05 15:08:40 +0000111 return;
Rui Ueyamaafff74e22015-08-05 23:24:46 +0000112 case InputFile::Object64BEKind:
Rui Ueyamacb8474ed2015-08-05 23:51:50 +0000113 writeResult<object::ELF64BE>(&Symtab);
Rafael Espindola4b7c2fc2015-08-05 15:08:40 +0000114 return;
115 }
Michael J. Spencer84487f12015-07-24 21:03:07 +0000116}