blob: 750e86bd12272203e3209f793bd2559966ad452a [file] [log] [blame]
Rui Ueyama411c63602015-05-28 19:09:30 +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 "Config.h"
11#include "Driver.h"
12#include "InputFiles.h"
13#include "Memory.h"
14#include "SymbolTable.h"
15#include "Writer.h"
16#include "lld/Core/Error.h"
17#include "llvm/ADT/Optional.h"
18#include "llvm/ADT/STLExtras.h"
Rui Ueyama3ee0fe42015-05-31 03:55:46 +000019#include "llvm/ADT/StringSwitch.h"
Rui Ueyama411c63602015-05-28 19:09:30 +000020#include "llvm/Option/Arg.h"
21#include "llvm/Option/ArgList.h"
22#include "llvm/Option/Option.h"
23#include "llvm/Support/CommandLine.h"
24#include "llvm/Support/Debug.h"
Rui Ueyama411c63602015-05-28 19:09:30 +000025#include "llvm/Support/Path.h"
Rui Ueyama54b71da2015-05-31 19:17:12 +000026#include "llvm/Support/Process.h"
Rui Ueyama411c63602015-05-28 19:09:30 +000027#include "llvm/Support/raw_ostream.h"
28#include <memory>
29
30using namespace llvm;
Rui Ueyama3ee0fe42015-05-31 03:55:46 +000031using llvm::COFF::IMAGE_SUBSYSTEM_UNKNOWN;
32using llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_CUI;
33using llvm::COFF::IMAGE_SUBSYSTEM_WINDOWS_GUI;
Rui Ueyama54b71da2015-05-31 19:17:12 +000034using llvm::sys::Process;
Rui Ueyama411c63602015-05-28 19:09:30 +000035
Rui Ueyama3500f662015-05-28 20:30:06 +000036namespace lld {
37namespace coff {
Rui Ueyama411c63602015-05-28 19:09:30 +000038
Rui Ueyama3500f662015-05-28 20:30:06 +000039Configuration *Config;
Rui Ueyamaa9cbbf82015-05-31 19:17:09 +000040LinkerDriver *Driver;
41
42bool link(int Argc, const char *Argv[]) {
43 auto C = make_unique<Configuration>();
44 Config = C.get();
45 auto D = make_unique<LinkerDriver>();
46 Driver = D.get();
47 return Driver->link(Argc, Argv);
48}
Rui Ueyama411c63602015-05-28 19:09:30 +000049
50static std::string getOutputPath(llvm::opt::InputArgList *Args) {
51 if (auto *Arg = Args->getLastArg(OPT_out))
52 return Arg->getValue();
53 for (auto *Arg : Args->filtered(OPT_INPUT)) {
54 if (!StringRef(Arg->getValue()).endswith_lower(".obj"))
55 continue;
56 SmallString<128> Val = StringRef(Arg->getValue());
57 llvm::sys::path::replace_extension(Val, ".exe");
58 return Val.str();
59 }
60 llvm_unreachable("internal error");
61}
62
Rui Ueyamad7c2f582015-05-31 21:04:56 +000063// Opens a file. Path has to be resolved already.
64// Newly created memory buffers are owned by this driver.
65ErrorOr<std::unique_ptr<InputFile>> LinkerDriver::createFile(StringRef Path) {
66 auto MBOrErr = MemoryBuffer::getFile(Path);
67 if (auto EC = MBOrErr.getError())
68 return EC;
69 std::unique_ptr<MemoryBuffer> MB = std::move(MBOrErr.get());
70 MemoryBufferRef MBRef = MB->getMemBufferRef();
71 OwningMBs.push_back(std::move(MB)); // take ownership
Rui Ueyama411c63602015-05-28 19:09:30 +000072 if (StringRef(Path).endswith_lower(".lib"))
Rui Ueyamad7c2f582015-05-31 21:04:56 +000073 return std::unique_ptr<InputFile>(new ArchiveFile(MBRef));
74 return std::unique_ptr<InputFile>(new ObjectFile(MBRef));
Rui Ueyama411c63602015-05-28 19:09:30 +000075}
76
Rui Ueyama3500f662015-05-28 20:30:06 +000077namespace {
78class BumpPtrStringSaver : public llvm::cl::StringSaver {
79public:
80 BumpPtrStringSaver(lld::coff::StringAllocator *A) : Alloc(A) {}
81 const char *SaveString(const char *S) override {
82 return Alloc->save(S).data();
83 }
84 lld::coff::StringAllocator *Alloc;
85};
86}
87
Rui Ueyama411c63602015-05-28 19:09:30 +000088// Parses .drectve section contents and returns a list of files
89// specified by /defaultlib.
Rui Ueyamaa9cbbf82015-05-31 19:17:09 +000090std::error_code
91LinkerDriver::parseDirectives(StringRef S,
92 std::vector<std::unique_ptr<InputFile>> *Res) {
Rui Ueyama411c63602015-05-28 19:09:30 +000093 SmallVector<const char *, 16> Tokens;
94 Tokens.push_back("link"); // argv[0] value. Will be ignored.
Rui Ueyamaa9cbbf82015-05-31 19:17:09 +000095 BumpPtrStringSaver Saver(&Alloc);
Rui Ueyama411c63602015-05-28 19:09:30 +000096 llvm::cl::TokenizeWindowsCommandLine(S, Saver, Tokens);
97 Tokens.push_back(nullptr);
98 int Argc = Tokens.size() - 1;
99 const char **Argv = &Tokens[0];
100
101 auto ArgsOrErr = parseArgs(Argc, Argv);
102 if (auto EC = ArgsOrErr.getError())
103 return EC;
104 std::unique_ptr<llvm::opt::InputArgList> Args = std::move(ArgsOrErr.get());
105
Rui Ueyamad7c2f582015-05-31 21:04:56 +0000106 for (auto *Arg : Args->filtered(OPT_defaultlib)) {
107 if (Optional<StringRef> Path = findLib(Arg->getValue())) {
108 auto FileOrErr = createFile(*Path);
109 if (auto EC = FileOrErr.getError())
110 return EC;
111 std::unique_ptr<InputFile> File = std::move(FileOrErr.get());
112 Res->push_back(std::move(File));
113 }
114 }
Rui Ueyama411c63602015-05-28 19:09:30 +0000115 return std::error_code();
116}
117
Rui Ueyama54b71da2015-05-31 19:17:12 +0000118// Find file from search paths. You can omit ".obj", this function takes
119// care of that. Note that the returned path is not guaranteed to exist.
Rui Ueyamad21b00b2015-05-31 19:17:14 +0000120StringRef LinkerDriver::doFindFile(StringRef Filename) {
Rui Ueyama54b71da2015-05-31 19:17:12 +0000121 bool hasPathSep = (Filename.find_first_of("/\\") != StringRef::npos);
122 if (hasPathSep)
123 return Filename;
124 bool hasExt = (Filename.find('.') != StringRef::npos);
125 for (StringRef Dir : SearchPaths) {
126 SmallString<128> Path = Dir;
127 llvm::sys::path::append(Path, Filename);
128 if (llvm::sys::fs::exists(Path.str()))
129 return Alloc.save(Path.str());
130 if (!hasExt) {
131 Path.append(".obj");
132 if (llvm::sys::fs::exists(Path.str()))
133 return Alloc.save(Path.str());
134 }
135 }
136 return Filename;
137}
138
Rui Ueyamad21b00b2015-05-31 19:17:14 +0000139// Resolves a file path. This never returns the same path
140// (in that case, it returns None).
141Optional<StringRef> LinkerDriver::findFile(StringRef Filename) {
142 StringRef Path = doFindFile(Filename);
143 bool Seen = !VisitedFiles.insert(Path.lower()).second;
144 if (Seen)
145 return None;
146 return Path;
Rui Ueyama54b71da2015-05-31 19:17:12 +0000147}
148
Rui Ueyamad21b00b2015-05-31 19:17:14 +0000149// Find library file from search path.
150StringRef LinkerDriver::doFindLib(StringRef Filename) {
151 // Add ".lib" to Filename if that has no file extension.
Rui Ueyama54b71da2015-05-31 19:17:12 +0000152 bool hasExt = (Filename.find('.') != StringRef::npos);
Rui Ueyamad21b00b2015-05-31 19:17:14 +0000153 if (!hasExt)
154 Filename = Alloc.save(Filename + ".lib");
155 return doFindFile(Filename);
156}
157
158// Resolves a library path. /nodefaultlib options are taken into
159// consideration. This never returns the same path (in that case,
160// it returns None).
161Optional<StringRef> LinkerDriver::findLib(StringRef Filename) {
162 if (Config->NoDefaultLibAll)
163 return None;
164 StringRef Path = doFindLib(Filename);
165 if (Config->NoDefaultLibs.count(Path))
166 return None;
167 bool Seen = !VisitedFiles.insert(Path.lower()).second;
168 if (Seen)
169 return None;
170 return Path;
Rui Ueyama54b71da2015-05-31 19:17:12 +0000171}
172
173// Parses LIB environment which contains a list of search paths.
174std::vector<StringRef> LinkerDriver::getSearchPaths() {
175 std::vector<StringRef> Ret;
176 Ret.push_back(".");
177 Optional<std::string> EnvOpt = Process::GetEnv("LIB");
178 if (!EnvOpt.hasValue())
179 return Ret;
180 StringRef Env = Alloc.save(*EnvOpt);
181 while (!Env.empty()) {
182 StringRef Path;
183 std::tie(Path, Env) = Env.split(';');
184 Ret.push_back(Path);
185 }
186 return Ret;
187}
188
Rui Ueyamaa9cbbf82015-05-31 19:17:09 +0000189bool LinkerDriver::link(int Argc, const char *Argv[]) {
Rui Ueyama411c63602015-05-28 19:09:30 +0000190 // Parse command line options.
Rui Ueyama411c63602015-05-28 19:09:30 +0000191 auto ArgsOrErr = parseArgs(Argc, Argv);
192 if (auto EC = ArgsOrErr.getError()) {
193 llvm::errs() << EC.message() << "\n";
194 return false;
195 }
196 std::unique_ptr<llvm::opt::InputArgList> Args = std::move(ArgsOrErr.get());
197
Rui Ueyama5c726432015-05-29 16:11:52 +0000198 // Handle /help
199 if (Args->hasArg(OPT_help)) {
200 printHelp(Argv[0]);
201 return true;
202 }
203
Rui Ueyama411c63602015-05-28 19:09:30 +0000204 if (Args->filtered_begin(OPT_INPUT) == Args->filtered_end()) {
205 llvm::errs() << "no input files.\n";
206 return false;
207 }
Rui Ueyama3d3e6fb2015-05-29 16:06:00 +0000208
209 // Handle /verbose
Rui Ueyama411c63602015-05-28 19:09:30 +0000210 if (Args->hasArg(OPT_verbose))
211 Config->Verbose = true;
Rui Ueyama3d3e6fb2015-05-29 16:06:00 +0000212
213 // Handle /entry
Rui Ueyama411c63602015-05-28 19:09:30 +0000214 if (auto *Arg = Args->getLastArg(OPT_entry))
215 Config->EntryName = Arg->getValue();
216
Rui Ueyama3d3e6fb2015-05-29 16:06:00 +0000217 // Handle /machine
218 auto MTOrErr = getMachineType(Args.get());
219 if (auto EC = MTOrErr.getError()) {
220 llvm::errs() << EC.message() << "\n";
221 return false;
222 }
223 Config->MachineType = MTOrErr.get();
224
Rui Ueyama06137472015-05-31 20:10:11 +0000225 // Handle /libpath
Rui Ueyamaf4784cc2015-05-31 20:20:37 +0000226 for (auto *Arg : Args->filtered(OPT_libpath)) {
227 // Inserting at front of a vector is okay because it's short.
228 // +1 because the first entry is always "." (current directory).
229 SearchPaths.insert(SearchPaths.begin() + 1, Arg->getValue());
230 }
Rui Ueyama06137472015-05-31 20:10:11 +0000231
Rui Ueyamad21b00b2015-05-31 19:17:14 +0000232 // Handle /nodefaultlib:<filename>
233 for (auto *Arg : Args->filtered(OPT_nodefaultlib))
234 Config->NoDefaultLibs.insert(doFindLib(Arg->getValue()));
235
236 // Handle /nodefaultlib
237 if (Args->hasArg(OPT_nodefaultlib_all))
238 Config->NoDefaultLibAll = true;
239
Rui Ueyama804a8b62015-05-29 16:18:15 +0000240 // Handle /base
241 if (auto *Arg = Args->getLastArg(OPT_base)) {
242 if (auto EC = parseNumbers(Arg->getValue(), &Config->ImageBase)) {
Rui Ueyamab41b7e52015-05-29 16:21:11 +0000243 llvm::errs() << "/base: " << EC.message() << "\n";
244 return false;
245 }
246 }
247
248 // Handle /stack
249 if (auto *Arg = Args->getLastArg(OPT_stack)) {
250 if (auto EC = parseNumbers(Arg->getValue(), &Config->StackReserve,
251 &Config->StackCommit)) {
252 llvm::errs() << "/stack: " << EC.message() << "\n";
Rui Ueyama804a8b62015-05-29 16:18:15 +0000253 return false;
254 }
255 }
256
Rui Ueyamac377e9a2015-05-29 16:23:40 +0000257 // Handle /heap
258 if (auto *Arg = Args->getLastArg(OPT_heap)) {
259 if (auto EC = parseNumbers(Arg->getValue(), &Config->HeapReserve,
260 &Config->HeapCommit)) {
261 llvm::errs() << "/heap: " << EC.message() << "\n";
262 return false;
263 }
264 }
265
Rui Ueyamab9dcdb52015-05-29 16:28:29 +0000266 // Handle /version
267 if (auto *Arg = Args->getLastArg(OPT_version)) {
268 if (auto EC = parseVersion(Arg->getValue(), &Config->MajorImageVersion,
269 &Config->MinorImageVersion)) {
270 llvm::errs() << "/version: " << EC.message() << "\n";
271 return false;
272 }
273 }
274
Rui Ueyama15cc47e2015-05-29 16:34:31 +0000275 // Handle /subsystem
276 if (auto *Arg = Args->getLastArg(OPT_subsystem)) {
277 if (auto EC = parseSubsystem(Arg->getValue(), &Config->Subsystem,
278 &Config->MajorOSVersion,
279 &Config->MinorOSVersion)) {
280 llvm::errs() << "/subsystem: " << EC.message() << "\n";
281 return false;
282 }
283 }
284
Rui Ueyamad21b00b2015-05-31 19:17:14 +0000285 // Create a list of input files. Files can be given as arguments
286 // for /defaultlib option.
287 std::vector<StringRef> Inputs;
288 for (auto *Arg : Args->filtered(OPT_INPUT))
289 if (Optional<StringRef> Path = findFile(Arg->getValue()))
290 Inputs.push_back(*Path);
291 for (auto *Arg : Args->filtered(OPT_defaultlib))
292 if (Optional<StringRef> Path = findLib(Arg->getValue()))
293 Inputs.push_back(*Path);
294
Rui Ueyamae042fa9a2015-05-31 19:55:40 +0000295 // Create a symbol table.
296 SymbolTable Symtab;
297
298 // Add undefined symbols given via the command line.
299 // (/include is equivalent to Unix linker's -u option.)
300 for (auto *Arg : Args->filtered(OPT_incl))
301 Symtab.addUndefined(Arg->getValue());
302
Rui Ueyama411c63602015-05-28 19:09:30 +0000303 // Parse all input files and put all symbols to the symbol table.
304 // The symbol table will take care of name resolution.
Rui Ueyamad21b00b2015-05-31 19:17:14 +0000305 for (StringRef Path : Inputs) {
Rui Ueyamad7c2f582015-05-31 21:04:56 +0000306 auto FileOrErr = createFile(Path);
307 if (auto EC = FileOrErr.getError()) {
308 llvm::errs() << Path << ": " << EC.message() << "\n";
309 return false;
310 }
311 std::unique_ptr<InputFile> File = std::move(FileOrErr.get());
312 if (auto EC = Symtab.addFile(std::move(File))) {
Rui Ueyama411c63602015-05-28 19:09:30 +0000313 llvm::errs() << Path << ": " << EC.message() << "\n";
314 return false;
315 }
316 }
Rui Ueyama5cff6852015-05-31 03:34:08 +0000317
318 // Windows specific -- If entry point name is not given, we need to
319 // infer that from user-defined entry name. The symbol table takes
320 // care of details.
321 if (Config->EntryName.empty()) {
322 auto EntryOrErr = Symtab.findDefaultEntry();
323 if (auto EC = EntryOrErr.getError()) {
324 llvm::errs() << EC.message() << "\n";
325 return false;
326 }
327 Config->EntryName = EntryOrErr.get();
328 }
329
330 // Make sure we have resolved all symbols.
Rui Ueyama411c63602015-05-28 19:09:30 +0000331 if (Symtab.reportRemainingUndefines())
332 return false;
333
Rui Ueyama3ee0fe42015-05-31 03:55:46 +0000334 // Windows specific -- if no /subsystem is given, we need to infer
335 // that from entry point name.
336 if (Config->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN) {
337 Config->Subsystem =
338 StringSwitch<WindowsSubsystem>(Config->EntryName)
339 .Case("mainCRTStartup", IMAGE_SUBSYSTEM_WINDOWS_CUI)
340 .Case("wmainCRTStartup", IMAGE_SUBSYSTEM_WINDOWS_CUI)
341 .Case("WinMainCRTStartup", IMAGE_SUBSYSTEM_WINDOWS_GUI)
342 .Case("wWinMainCRTStartup", IMAGE_SUBSYSTEM_WINDOWS_GUI)
343 .Default(IMAGE_SUBSYSTEM_UNKNOWN);
344 if (Config->Subsystem == IMAGE_SUBSYSTEM_UNKNOWN) {
345 llvm::errs() << "subsystem must be defined\n";
346 return false;
347 }
348 }
349
Rui Ueyama411c63602015-05-28 19:09:30 +0000350 // Write the result.
351 Writer Out(&Symtab);
352 if (auto EC = Out.write(getOutputPath(Args.get()))) {
353 llvm::errs() << EC.message() << "\n";
354 return false;
355 }
356 return true;
357}
358
Rui Ueyama411c63602015-05-28 19:09:30 +0000359} // namespace coff
360} // namespace lld