blob: 49d10fc2ab741634fcb7f385c4fc912e49fa9cb8 [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 Espindola2e9eac12015-09-11 21:18:56 +000017#include "llvm/ADT/StringExtras.h"
Rafael Espindolaf98d6d82015-09-03 20:03:54 +000018#include "llvm/Support/FileSystem.h"
Rafael Espindolaabb7b282015-09-28 12:52:21 +000019#include "llvm/Support/Path.h"
Michael J. Spencer84487f12015-07-24 21:03:07 +000020
21using namespace llvm;
22
23using namespace lld;
24using namespace lld::elf2;
25
Rui Ueyama983ed2b2015-10-01 15:23:09 +000026Configuration *lld::elf2::Config;
27LinkerDriver *lld::elf2::Driver;
Rui Ueyamaf5c4aca2015-09-30 17:06:09 +000028
Rui Ueyama983ed2b2015-10-01 15:23:09 +000029void lld::elf2::link(ArrayRef<const char *> Args) {
Rui Ueyama570752c2015-08-18 09:13:25 +000030 Configuration C;
Rui Ueyama983ed2b2015-10-01 15:23:09 +000031 LinkerDriver D;
Rui Ueyama570752c2015-08-18 09:13:25 +000032 Config = &C;
Rui Ueyama983ed2b2015-10-01 15:23:09 +000033 Driver = &D;
34 Driver->link(Args.slice(1));
Michael J. Spencer84487f12015-07-24 21:03:07 +000035}
36
Igor Kudrin1309fc02015-09-28 15:01:59 +000037// Makes a path by concatenating Dir and File.
Igor Kudrinf03d2b42015-09-30 10:39:37 +000038// If Dir starts with '=' the result will be preceded by Sysroot,
Igor Kudrin1309fc02015-09-28 15:01:59 +000039// which can be set with --sysroot command line switch.
40static std::string buildSysrootedPath(StringRef Dir, StringRef File) {
41 SmallString<128> Path;
Igor Kudrinf03d2b42015-09-30 10:39:37 +000042 if (Dir.startswith("="))
43 sys::path::append(Path, Config->Sysroot, Dir.substr(1), File);
44 else
45 sys::path::append(Path, Dir, File);
Igor Kudrin1309fc02015-09-28 15:01:59 +000046 return Path.str().str();
47}
48
Rafael Espindolaabb7b282015-09-28 12:52:21 +000049// 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.
51static 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 Names.push_back((Twine("lib") + Path + ".so").str());
57 Names.push_back((Twine("lib") + Path + ".a").str());
58 }
Rafael Espindolaabb7b282015-09-28 12:52:21 +000059 for (StringRef Dir : Config->InputSearchPaths) {
60 for (const std::string &Name : Names) {
Igor Kudrin1309fc02015-09-28 15:01:59 +000061 std::string FullPath = buildSysrootedPath(Dir, Name);
62 if (sys::fs::exists(FullPath))
63 return FullPath;
Rafael Espindolaabb7b282015-09-28 12:52:21 +000064 }
65 }
66 error(Twine("Unable to find library -l") + Path);
67}
68
Rui Ueyama983ed2b2015-10-01 15:23:09 +000069// Opens and parses a file. Path has to be resolved already.
70// Newly created memory buffers are owned by this driver.
71void LinkerDriver::addFile(StringRef Path) {
Rui Ueyamaf5c4aca2015-09-30 17:06:09 +000072 using namespace llvm::sys::fs;
Rui Ueyama983ed2b2015-10-01 15:23:09 +000073 auto MBOrErr = MemoryBuffer::getFile(Path);
74 error(MBOrErr, Twine("cannot open ") + Path);
75 std::unique_ptr<MemoryBuffer> &MB = *MBOrErr;
76 MemoryBufferRef MBRef = MB->getMemBufferRef();
77 OwningMBs.push_back(std::move(MB)); // take MB ownership
78
79 switch (identify_magic(MBRef.getBuffer())) {
80 case file_magic::unknown:
81 readLinkerScript(MBRef);
82 return;
83 case file_magic::archive:
84 Symtab.addFile(make_unique<ArchiveFile>(MBRef));
85 return;
86 case file_magic::elf_shared_object:
87 Symtab.addFile(createELFFile<SharedFile>(MBRef));
88 return;
89 default:
90 Symtab.addFile(createELFFile<ObjectFile>(MBRef));
91 }
Rui Ueyamaf5c4aca2015-09-30 17:06:09 +000092}
93
Michael J. Spencer84487f12015-07-24 21:03:07 +000094void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
95 // Parse command line options.
96 opt::InputArgList Args = Parser.parse(ArgsArr);
97
Michael J. Spencer84487f12015-07-24 21:03:07 +000098 if (auto *Arg = Args.getLastArg(OPT_output))
99 Config->OutputFile = Arg->getValue();
Michael J. Spencer84487f12015-07-24 21:03:07 +0000100
Rafael Espindola70107762015-09-11 18:49:42 +0000101 if (auto *Arg = Args.getLastArg(OPT_dynamic_linker))
102 Config->DynamicLinker = Arg->getValue();
103
Igor Kudrin1309fc02015-09-28 15:01:59 +0000104 if (auto *Arg = Args.getLastArg(OPT_sysroot))
105 Config->Sysroot = Arg->getValue();
106
Rafael Espindola2e9eac12015-09-11 21:18:56 +0000107 std::vector<StringRef> RPaths;
108 for (auto *Arg : Args.filtered(OPT_rpath))
109 RPaths.push_back(Arg->getValue());
110 if (!RPaths.empty())
111 Config->RPath = llvm::join(RPaths.begin(), RPaths.end(), ":");
112
Rafael Espindolaabb7b282015-09-28 12:52:21 +0000113 for (auto *Arg : Args.filtered(OPT_L))
114 Config->InputSearchPaths.push_back(Arg->getValue());
115
Rui Ueyama9d4c6d72015-09-29 16:40:13 +0000116 if (auto *Arg = Args.getLastArg(OPT_entry))
117 Config->Entry = Arg->getValue();
118
Rui Ueyamad7c417c2015-09-29 22:33:18 +0000119 Config->AllowMultipleDefinition = Args.hasArg(OPT_allow_multiple_definition);
120 Config->DiscardAll = Args.hasArg(OPT_discard_all);
121 Config->DiscardLocals = Args.hasArg(OPT_discard_locals);
122 Config->DiscardNone = Args.hasArg(OPT_discard_none);
123 Config->ExportDynamic = Args.hasArg(OPT_export_dynamic);
124 Config->NoInhibitExec = Args.hasArg(OPT_noinhibit_exec);
125 Config->Shared = Args.hasArg(OPT_shared);
126
Rui Ueyamaf5c4aca2015-09-30 17:06:09 +0000127 for (auto *Arg : Args.filtered(OPT_l, OPT_INPUT)) {
Rui Ueyama983ed2b2015-10-01 15:23:09 +0000128 StringRef Path = Arg->getValue();
129 if (Arg->getOption().getID() == OPT_l) {
130 addFile(searchLibrary(Path));
131 } else {
132 addFile(Path);
Rui Ueyamaf5c4aca2015-09-30 17:06:09 +0000133 }
Michael J. Spencer84487f12015-07-24 21:03:07 +0000134 }
135
Rui Ueyamaf5c4aca2015-09-30 17:06:09 +0000136 if (Symtab.getObjectFiles().empty())
137 error("no input files.");
138
Michael J. Spencer84487f12015-07-24 21:03:07 +0000139 // Write the result.
Rafael Espindolaf98d6d82015-09-03 20:03:54 +0000140 const ELFFileBase *FirstObj = Symtab.getFirstELF();
141 switch (FirstObj->getELFKind()) {
Rafael Espindola905ad342015-09-02 20:43:43 +0000142 case ELF32LEKind:
Rui Ueyamacb8474ed2015-08-05 23:51:50 +0000143 writeResult<object::ELF32LE>(&Symtab);
Rafael Espindola4b7c2fc2015-08-05 15:08:40 +0000144 return;
Rafael Espindola905ad342015-09-02 20:43:43 +0000145 case ELF32BEKind:
Rui Ueyamacb8474ed2015-08-05 23:51:50 +0000146 writeResult<object::ELF32BE>(&Symtab);
Rafael Espindola4b7c2fc2015-08-05 15:08:40 +0000147 return;
Rafael Espindola905ad342015-09-02 20:43:43 +0000148 case ELF64LEKind:
Rui Ueyamacb8474ed2015-08-05 23:51:50 +0000149 writeResult<object::ELF64LE>(&Symtab);
Rafael Espindola4b7c2fc2015-08-05 15:08:40 +0000150 return;
Rafael Espindola905ad342015-09-02 20:43:43 +0000151 case ELF64BEKind:
Rui Ueyamacb8474ed2015-08-05 23:51:50 +0000152 writeResult<object::ELF64BE>(&Symtab);
Rafael Espindola4b7c2fc2015-08-05 15:08:40 +0000153 return;
154 }
Michael J. Spencer84487f12015-07-24 21:03:07 +0000155}