blob: a9c1c9d5593e0956e79c1d58e12b474c8fbd81e8 [file] [log] [blame]
Rui Ueyama3500f662015-05-28 20:30:06 +00001//===- DriverUtils.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// This file contains utility functions for the driver. Because there
11// are so many small functions, we created this separate file to make
12// Driver.cpp less cluttered.
13//
14//===----------------------------------------------------------------------===//
15
Rui Ueyama8854d8a2015-06-04 19:21:24 +000016#include "Config.h"
Rui Ueyama3500f662015-05-28 20:30:06 +000017#include "Driver.h"
Rui Ueyama8fd9fb92015-06-01 02:58:15 +000018#include "Error.h"
Rui Ueyama9381eb12016-12-18 14:06:06 +000019#include "Memory.h"
Rui Ueyama8765fba2015-07-15 22:21:08 +000020#include "Symbols.h"
Rui Ueyama3500f662015-05-28 20:30:06 +000021#include "llvm/ADT/Optional.h"
Rui Ueyama3500f662015-05-28 20:30:06 +000022#include "llvm/ADT/StringSwitch.h"
23#include "llvm/Object/COFF.h"
24#include "llvm/Option/Arg.h"
25#include "llvm/Option/ArgList.h"
26#include "llvm/Option/Option.h"
27#include "llvm/Support/CommandLine.h"
Rui Ueyama151d8622015-06-17 20:40:43 +000028#include "llvm/Support/FileUtilities.h"
Rui Ueyama3500f662015-05-28 20:30:06 +000029#include "llvm/Support/Process.h"
Rui Ueyama2bf6a122015-06-14 21:50:50 +000030#include "llvm/Support/Program.h"
Rui Ueyama3500f662015-05-28 20:30:06 +000031#include "llvm/Support/raw_ostream.h"
32#include <memory>
33
34using namespace llvm::COFF;
35using namespace llvm;
Rui Ueyamab51f67a2015-06-07 23:00:29 +000036using llvm::cl::ExpandResponseFiles;
37using llvm::cl::TokenizeWindowsCommandLine;
Rui Ueyama3500f662015-05-28 20:30:06 +000038using llvm::sys::Process;
Rui Ueyama3500f662015-05-28 20:30:06 +000039
40namespace lld {
41namespace coff {
Rui Ueyamaa9c88382015-06-17 21:01:56 +000042namespace {
43
44class Executor {
45public:
46 explicit Executor(StringRef S) : Saver(Alloc), Prog(Saver.save(S)) {}
Rui Ueyamae6e206d2017-02-21 23:22:56 +000047 void add(StringRef S) { Args.push_back(Saver.save(S)); }
48 void add(std::string &S) { Args.push_back(Saver.save(S)); }
49 void add(Twine S) { Args.push_back(Saver.save(S)); }
50 void add(const char *S) { Args.push_back(Saver.save(S)); }
Rui Ueyamaa9c88382015-06-17 21:01:56 +000051
Rafael Espindolab835ae82015-08-06 14:58:50 +000052 void run() {
Rui Ueyama8fe17672016-12-08 20:50:47 +000053 ErrorOr<std::string> ExeOrErr = sys::findProgramByName(Prog);
Rui Ueyama0d09a862016-07-15 00:40:46 +000054 if (auto EC = ExeOrErr.getError())
55 fatal(EC, "unable to find " + Prog + " in PATH: ");
Rui Ueyamae6e206d2017-02-21 23:22:56 +000056 StringRef Exe = Saver.save(*ExeOrErr);
Rui Ueyamaa9c88382015-06-17 21:01:56 +000057 Args.insert(Args.begin(), Exe);
Rui Ueyamae6e206d2017-02-21 23:22:56 +000058
59 std::vector<const char *> Vec;
60 for (StringRef S : Args)
61 Vec.push_back(S.data());
62 Vec.push_back(nullptr);
63
64 if (sys::ExecuteAndWait(Args[0], Vec.data()) != 0)
65 fatal("ExecuteAndWait failed: " +
66 llvm::join(Args.begin(), Args.end(), " "));
Rui Ueyamaa9c88382015-06-17 21:01:56 +000067 }
68
69private:
Rui Ueyama8fe17672016-12-08 20:50:47 +000070 BumpPtrAllocator Alloc;
71 StringSaver Saver;
Rui Ueyamaa9c88382015-06-17 21:01:56 +000072 StringRef Prog;
Rui Ueyamae6e206d2017-02-21 23:22:56 +000073 std::vector<StringRef> Args;
Rui Ueyamaa9c88382015-06-17 21:01:56 +000074};
75
76} // anonymous namespace
Rui Ueyama3500f662015-05-28 20:30:06 +000077
Rui Ueyama3d3e6fb2015-05-29 16:06:00 +000078// Returns /machine's value.
Rafael Espindolab835ae82015-08-06 14:58:50 +000079MachineTypes getMachineType(StringRef S) {
Rui Ueyamae16a75d52015-07-08 18:14:51 +000080 MachineTypes MT = StringSwitch<MachineTypes>(S.lower())
Rui Ueyamac79ecdd2016-09-30 22:01:25 +000081 .Cases("x64", "amd64", AMD64)
82 .Cases("x86", "i386", I386)
Rui Ueyama5e706b32015-07-25 21:54:50 +000083 .Case("arm", ARMNT)
Rui Ueyamae16a75d52015-07-08 18:14:51 +000084 .Default(IMAGE_FILE_MACHINE_UNKNOWN);
85 if (MT != IMAGE_FILE_MACHINE_UNKNOWN)
Rui Ueyama3d3e6fb2015-05-29 16:06:00 +000086 return MT;
Rui Ueyama1a3fd132016-07-14 23:43:36 +000087 fatal("unknown /machine argument: " + S);
Rui Ueyama3d3e6fb2015-05-29 16:06:00 +000088}
89
Rui Ueyama5e706b32015-07-25 21:54:50 +000090StringRef machineToStr(MachineTypes MT) {
Rui Ueyama84936e02015-07-07 23:39:18 +000091 switch (MT) {
Rui Ueyama5e706b32015-07-25 21:54:50 +000092 case ARMNT:
Rui Ueyama84936e02015-07-07 23:39:18 +000093 return "arm";
Rui Ueyama5e706b32015-07-25 21:54:50 +000094 case AMD64:
Rui Ueyama84936e02015-07-07 23:39:18 +000095 return "x64";
Rui Ueyama5e706b32015-07-25 21:54:50 +000096 case I386:
Rui Ueyama84936e02015-07-07 23:39:18 +000097 return "x86";
98 default:
99 llvm_unreachable("unknown machine type");
100 }
101}
102
Rui Ueyama804a8b62015-05-29 16:18:15 +0000103// Parses a string in the form of "<integer>[,<integer>]".
Rafael Espindolab835ae82015-08-06 14:58:50 +0000104void parseNumbers(StringRef Arg, uint64_t *Addr, uint64_t *Size) {
Rui Ueyama804a8b62015-05-29 16:18:15 +0000105 StringRef S1, S2;
106 std::tie(S1, S2) = Arg.split(',');
Rafael Espindolab835ae82015-08-06 14:58:50 +0000107 if (S1.getAsInteger(0, *Addr))
Rui Ueyama1a3fd132016-07-14 23:43:36 +0000108 fatal("invalid number: " + S1);
Rafael Espindolab835ae82015-08-06 14:58:50 +0000109 if (Size && !S2.empty() && S2.getAsInteger(0, *Size))
Rui Ueyama1a3fd132016-07-14 23:43:36 +0000110 fatal("invalid number: " + S2);
Rui Ueyama804a8b62015-05-29 16:18:15 +0000111}
112
Rui Ueyamab9dcdb52015-05-29 16:28:29 +0000113// Parses a string in the form of "<integer>[.<integer>]".
114// If second number is not present, Minor is set to 0.
Rafael Espindolab835ae82015-08-06 14:58:50 +0000115void parseVersion(StringRef Arg, uint32_t *Major, uint32_t *Minor) {
Rui Ueyamab9dcdb52015-05-29 16:28:29 +0000116 StringRef S1, S2;
117 std::tie(S1, S2) = Arg.split('.');
Rafael Espindolab835ae82015-08-06 14:58:50 +0000118 if (S1.getAsInteger(0, *Major))
Rui Ueyama1a3fd132016-07-14 23:43:36 +0000119 fatal("invalid number: " + S1);
Rui Ueyamab9dcdb52015-05-29 16:28:29 +0000120 *Minor = 0;
Rafael Espindolab835ae82015-08-06 14:58:50 +0000121 if (!S2.empty() && S2.getAsInteger(0, *Minor))
Rui Ueyama1a3fd132016-07-14 23:43:36 +0000122 fatal("invalid number: " + S2);
Rui Ueyamab9dcdb52015-05-29 16:28:29 +0000123}
124
Rui Ueyama15cc47e2015-05-29 16:34:31 +0000125// Parses a string in the form of "<subsystem>[,<integer>[.<integer>]]".
Rafael Espindolab835ae82015-08-06 14:58:50 +0000126void parseSubsystem(StringRef Arg, WindowsSubsystem *Sys, uint32_t *Major,
127 uint32_t *Minor) {
Rui Ueyama15cc47e2015-05-29 16:34:31 +0000128 StringRef SysStr, Ver;
129 std::tie(SysStr, Ver) = Arg.split(',');
130 *Sys = StringSwitch<WindowsSubsystem>(SysStr.lower())
131 .Case("boot_application", IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION)
132 .Case("console", IMAGE_SUBSYSTEM_WINDOWS_CUI)
133 .Case("efi_application", IMAGE_SUBSYSTEM_EFI_APPLICATION)
134 .Case("efi_boot_service_driver", IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER)
135 .Case("efi_rom", IMAGE_SUBSYSTEM_EFI_ROM)
136 .Case("efi_runtime_driver", IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)
137 .Case("native", IMAGE_SUBSYSTEM_NATIVE)
138 .Case("posix", IMAGE_SUBSYSTEM_POSIX_CUI)
139 .Case("windows", IMAGE_SUBSYSTEM_WINDOWS_GUI)
140 .Default(IMAGE_SUBSYSTEM_UNKNOWN);
Rafael Espindolab835ae82015-08-06 14:58:50 +0000141 if (*Sys == IMAGE_SUBSYSTEM_UNKNOWN)
Rui Ueyama1a3fd132016-07-14 23:43:36 +0000142 fatal("unknown subsystem: " + SysStr);
Rui Ueyama15cc47e2015-05-29 16:34:31 +0000143 if (!Ver.empty())
Rafael Espindolab835ae82015-08-06 14:58:50 +0000144 parseVersion(Ver, Major, Minor);
Rui Ueyama15cc47e2015-05-29 16:34:31 +0000145}
146
Rui Ueyama2edb35a2015-06-18 19:09:30 +0000147// Parse a string of the form of "<from>=<to>".
148// Results are directly written to Config.
Rafael Espindolab835ae82015-08-06 14:58:50 +0000149void parseAlternateName(StringRef S) {
Rui Ueyama2edb35a2015-06-18 19:09:30 +0000150 StringRef From, To;
151 std::tie(From, To) = S.split('=');
Rafael Espindolab835ae82015-08-06 14:58:50 +0000152 if (From.empty() || To.empty())
Rui Ueyama1a3fd132016-07-14 23:43:36 +0000153 fatal("/alternatename: invalid argument: " + S);
Rui Ueyamae8d56b52015-06-18 23:04:26 +0000154 auto It = Config->AlternateNames.find(From);
Rafael Espindolab835ae82015-08-06 14:58:50 +0000155 if (It != Config->AlternateNames.end() && It->second != To)
Rui Ueyama1a3fd132016-07-14 23:43:36 +0000156 fatal("/alternatename: conflicts: " + S);
Rui Ueyamae8d56b52015-06-18 23:04:26 +0000157 Config->AlternateNames.insert(It, std::make_pair(From, To));
Rui Ueyama2edb35a2015-06-18 19:09:30 +0000158}
159
Rui Ueyama6600eb12015-07-04 23:37:32 +0000160// Parse a string of the form of "<from>=<to>".
161// Results are directly written to Config.
Rafael Espindolab835ae82015-08-06 14:58:50 +0000162void parseMerge(StringRef S) {
Rui Ueyama6600eb12015-07-04 23:37:32 +0000163 StringRef From, To;
164 std::tie(From, To) = S.split('=');
Rafael Espindolab835ae82015-08-06 14:58:50 +0000165 if (From.empty() || To.empty())
Rui Ueyama1a3fd132016-07-14 23:43:36 +0000166 fatal("/merge: invalid argument: " + S);
Rui Ueyama6600eb12015-07-04 23:37:32 +0000167 auto Pair = Config->Merge.insert(std::make_pair(From, To));
168 bool Inserted = Pair.second;
Rui Ueyama2b82d5f2015-07-04 23:54:52 +0000169 if (!Inserted) {
170 StringRef Existing = Pair.first->second;
171 if (Existing != To)
Rui Ueyamae6e206d2017-02-21 23:22:56 +0000172 warn(S + ": already merged into " + Existing);
Rui Ueyama2b82d5f2015-07-04 23:54:52 +0000173 }
Rui Ueyama6600eb12015-07-04 23:37:32 +0000174}
175
Rui Ueyama440138c2016-06-20 03:39:39 +0000176static uint32_t parseSectionAttributes(StringRef S) {
177 uint32_t Ret = 0;
178 for (char C : S.lower()) {
179 switch (C) {
180 case 'd':
181 Ret |= IMAGE_SCN_MEM_DISCARDABLE;
182 break;
183 case 'e':
184 Ret |= IMAGE_SCN_MEM_EXECUTE;
185 break;
186 case 'k':
187 Ret |= IMAGE_SCN_MEM_NOT_CACHED;
188 break;
189 case 'p':
190 Ret |= IMAGE_SCN_MEM_NOT_PAGED;
191 break;
192 case 'r':
193 Ret |= IMAGE_SCN_MEM_READ;
194 break;
195 case 's':
196 Ret |= IMAGE_SCN_MEM_SHARED;
197 break;
198 case 'w':
199 Ret |= IMAGE_SCN_MEM_WRITE;
200 break;
201 default:
Rui Ueyama1a3fd132016-07-14 23:43:36 +0000202 fatal("/section: invalid argument: " + S);
Rui Ueyama440138c2016-06-20 03:39:39 +0000203 }
204 }
205 return Ret;
206}
207
208// Parses /section option argument.
209void parseSection(StringRef S) {
210 StringRef Name, Attrs;
211 std::tie(Name, Attrs) = S.split(',');
212 if (Name.empty() || Attrs.empty())
Rui Ueyama1a3fd132016-07-14 23:43:36 +0000213 fatal("/section: invalid argument: " + S);
Rui Ueyama440138c2016-06-20 03:39:39 +0000214 Config->Section[Name] = parseSectionAttributes(Attrs);
215}
216
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000217// Parses a string in the form of "EMBED[,=<integer>]|NO".
218// Results are directly written to Config.
Rafael Espindolab835ae82015-08-06 14:58:50 +0000219void parseManifest(StringRef Arg) {
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000220 if (Arg.equals_lower("no")) {
221 Config->Manifest = Configuration::No;
Rafael Espindolab835ae82015-08-06 14:58:50 +0000222 return;
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000223 }
224 if (!Arg.startswith_lower("embed"))
Rui Ueyamabb579542016-07-15 01:12:24 +0000225 fatal("invalid option " + Arg);
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000226 Config->Manifest = Configuration::Embed;
227 Arg = Arg.substr(strlen("embed"));
228 if (Arg.empty())
Rafael Espindolab835ae82015-08-06 14:58:50 +0000229 return;
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000230 if (!Arg.startswith_lower(",id="))
Rui Ueyamabb579542016-07-15 01:12:24 +0000231 fatal("invalid option " + Arg);
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000232 Arg = Arg.substr(strlen(",id="));
233 if (Arg.getAsInteger(0, Config->ManifestID))
Rui Ueyamabb579542016-07-15 01:12:24 +0000234 fatal("invalid option " + Arg);
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000235}
236
237// Parses a string in the form of "level=<string>|uiAccess=<string>|NO".
238// Results are directly written to Config.
Rafael Espindolab835ae82015-08-06 14:58:50 +0000239void parseManifestUAC(StringRef Arg) {
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000240 if (Arg.equals_lower("no")) {
241 Config->ManifestUAC = false;
Rafael Espindolab835ae82015-08-06 14:58:50 +0000242 return;
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000243 }
244 for (;;) {
245 Arg = Arg.ltrim();
246 if (Arg.empty())
Rafael Espindolab835ae82015-08-06 14:58:50 +0000247 return;
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000248 if (Arg.startswith_lower("level=")) {
249 Arg = Arg.substr(strlen("level="));
250 std::tie(Config->ManifestLevel, Arg) = Arg.split(" ");
251 continue;
252 }
253 if (Arg.startswith_lower("uiaccess=")) {
254 Arg = Arg.substr(strlen("uiaccess="));
255 std::tie(Config->ManifestUIAccess, Arg) = Arg.split(" ");
256 continue;
257 }
Rui Ueyamabb579542016-07-15 01:12:24 +0000258 fatal("invalid option " + Arg);
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000259 }
260}
261
262// Quote each line with "". Existing double-quote is converted
263// to two double-quotes.
264static void quoteAndPrint(raw_ostream &Out, StringRef S) {
265 while (!S.empty()) {
266 StringRef Line;
267 std::tie(Line, S) = S.split("\n");
268 if (Line.empty())
269 continue;
270 Out << '\"';
271 for (int I = 0, E = Line.size(); I != E; ++I) {
272 if (Line[I] == '\"') {
273 Out << "\"\"";
274 } else {
275 Out << Line[I];
276 }
277 }
278 Out << "\"\n";
279 }
280}
281
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000282// An RAII temporary file class that automatically removes a temporary file.
283namespace {
284class TemporaryFile {
285public:
Rui Ueyama1e0b1582017-02-06 20:47:55 +0000286 TemporaryFile(StringRef Prefix, StringRef Extn, StringRef Contents = "") {
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000287 SmallString<128> S;
288 if (auto EC = sys::fs::createTemporaryFile("lld-" + Prefix, Extn, S))
289 fatal(EC, "cannot create a temporary file");
290 Path = S.str();
Rui Ueyama1e0b1582017-02-06 20:47:55 +0000291
292 if (!Contents.empty()) {
293 std::error_code EC;
294 raw_fd_ostream OS(Path, EC, sys::fs::F_None);
295 if (EC)
296 fatal(EC, "failed to open " + Path);
297 OS << Contents;
298 }
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000299 }
300
301 TemporaryFile(TemporaryFile &&Obj) {
302 std::swap(Path, Obj.Path);
303 }
304
305 ~TemporaryFile() {
306 if (Path.empty())
307 return;
308 if (sys::fs::remove(Path))
309 fatal("failed to remove " + Path);
310 }
311
312 // Returns a memory buffer of this temporary file.
313 // Note that this function does not leave the file open,
314 // so it is safe to remove the file immediately after this function
315 // is called (you cannot remove an opened file on Windows.)
316 std::unique_ptr<MemoryBuffer> getMemoryBuffer() {
317 // IsVolatileSize=true forces MemoryBuffer to not use mmap().
318 return check(MemoryBuffer::getFile(Path, /*FileSize=*/-1,
319 /*RequiresNullTerminator=*/false,
320 /*IsVolatileSize=*/true),
321 "could not open " + Path);
322 }
323
324 std::string Path;
325};
326}
327
Rui Ueyamaafb19012016-04-19 01:21:58 +0000328// Create the default manifest file as a temporary file.
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000329TemporaryFile createDefaultXml() {
Rui Ueyamaafb19012016-04-19 01:21:58 +0000330 // Create a temporary file.
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000331 TemporaryFile File("defaultxml", "manifest");
Rui Ueyamaafb19012016-04-19 01:21:58 +0000332
333 // Open the temporary file for writing.
Rui Ueyama0d09a862016-07-15 00:40:46 +0000334 std::error_code EC;
Rui Ueyama8fe17672016-12-08 20:50:47 +0000335 raw_fd_ostream OS(File.Path, EC, sys::fs::F_Text);
Rui Ueyama0d09a862016-07-15 00:40:46 +0000336 if (EC)
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000337 fatal(EC, "failed to open " + File.Path);
Rui Ueyamaafb19012016-04-19 01:21:58 +0000338
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000339 // Emit the XML. Note that we do *not* verify that the XML attributes are
340 // syntactically correct. This is intentional for link.exe compatibility.
341 OS << "<?xml version=\"1.0\" standalone=\"yes\"?>\n"
342 << "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\"\n"
343 << " manifestVersion=\"1.0\">\n";
344 if (Config->ManifestUAC) {
345 OS << " <trustInfo>\n"
346 << " <security>\n"
347 << " <requestedPrivileges>\n"
348 << " <requestedExecutionLevel level=" << Config->ManifestLevel
349 << " uiAccess=" << Config->ManifestUIAccess << "/>\n"
350 << " </requestedPrivileges>\n"
351 << " </security>\n"
352 << " </trustInfo>\n";
353 if (!Config->ManifestDependency.empty()) {
354 OS << " <dependency>\n"
355 << " <dependentAssembly>\n"
356 << " <assemblyIdentity " << Config->ManifestDependency << " />\n"
357 << " </dependentAssembly>\n"
358 << " </dependency>\n";
359 }
360 }
361 OS << "</assembly>\n";
Rui Ueyamaafb19012016-04-19 01:21:58 +0000362 OS.close();
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000363 return File;
Rui Ueyamaafb19012016-04-19 01:21:58 +0000364}
365
366static std::string readFile(StringRef Path) {
Rui Ueyama659a4f22016-07-15 01:06:38 +0000367 std::unique_ptr<MemoryBuffer> MB =
Rui Ueyamabb579542016-07-15 01:12:24 +0000368 check(MemoryBuffer::getFile(Path), "could not open " + Path);
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000369 return MB->getBuffer();
Rui Ueyamaafb19012016-04-19 01:21:58 +0000370}
371
372static std::string createManifestXml() {
373 // Create the default manifest file.
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000374 TemporaryFile File1 = createDefaultXml();
Rui Ueyamaafb19012016-04-19 01:21:58 +0000375 if (Config->ManifestInput.empty())
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000376 return readFile(File1.Path);
Rui Ueyamaafb19012016-04-19 01:21:58 +0000377
378 // If manifest files are supplied by the user using /MANIFESTINPUT
379 // option, we need to merge them with the default manifest.
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000380 TemporaryFile File2("user", "manifest");
Rui Ueyamaafb19012016-04-19 01:21:58 +0000381
382 Executor E("mt.exe");
383 E.add("/manifest");
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000384 E.add(File1.Path);
Rui Ueyamaafb19012016-04-19 01:21:58 +0000385 for (StringRef Filename : Config->ManifestInput) {
386 E.add("/manifest");
387 E.add(Filename);
388 }
389 E.add("/nologo");
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000390 E.add("/out:" + StringRef(File2.Path));
Rui Ueyamaafb19012016-04-19 01:21:58 +0000391 E.run();
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000392 return readFile(File2.Path);
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000393}
394
395// Create a resource file containing a manifest XML.
Rafael Espindolab835ae82015-08-06 14:58:50 +0000396std::unique_ptr<MemoryBuffer> createManifestRes() {
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000397 // Create a temporary file for the resource script file.
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000398 TemporaryFile RCFile("manifest", "rc");
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000399
400 // Open the temporary file for writing.
Rui Ueyama0d09a862016-07-15 00:40:46 +0000401 std::error_code EC;
Rui Ueyama8fe17672016-12-08 20:50:47 +0000402 raw_fd_ostream Out(RCFile.Path, EC, sys::fs::F_Text);
Rui Ueyama0d09a862016-07-15 00:40:46 +0000403 if (EC)
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000404 fatal(EC, "failed to open " + RCFile.Path);
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000405
406 // Write resource script to the RC file.
407 Out << "#define LANG_ENGLISH 9\n"
408 << "#define SUBLANG_DEFAULT 1\n"
409 << "#define APP_MANIFEST " << Config->ManifestID << "\n"
410 << "#define RT_MANIFEST 24\n"
411 << "LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT\n"
412 << "APP_MANIFEST RT_MANIFEST {\n";
413 quoteAndPrint(Out, createManifestXml());
414 Out << "}\n";
415 Out.close();
416
417 // Create output resource file.
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000418 TemporaryFile ResFile("output-resource", "res");
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000419
420 Executor E("rc.exe");
421 E.add("/fo");
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000422 E.add(ResFile.Path);
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000423 E.add("/nologo");
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000424 E.add(RCFile.Path);
Rafael Espindolab835ae82015-08-06 14:58:50 +0000425 E.run();
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000426 return ResFile.getMemoryBuffer();
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000427}
428
Rafael Espindolab835ae82015-08-06 14:58:50 +0000429void createSideBySideManifest() {
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000430 std::string Path = Config->ManifestFile;
431 if (Path == "")
Rui Ueyama1a3fd132016-07-14 23:43:36 +0000432 Path = Config->OutputFile + ".manifest";
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000433 std::error_code EC;
Rui Ueyama8fe17672016-12-08 20:50:47 +0000434 raw_fd_ostream Out(Path, EC, sys::fs::F_Text);
Rui Ueyama0d09a862016-07-15 00:40:46 +0000435 if (EC)
436 fatal(EC, "failed to create manifest");
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000437 Out << createManifestXml();
Rui Ueyama24c5fd02015-06-18 00:12:42 +0000438}
439
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000440// Parse a string in the form of
Rui Ueyama84425d72016-01-09 01:22:00 +0000441// "<name>[=<internalname>][,@ordinal[,NONAME]][,DATA][,PRIVATE]"
442// or "<name>=<dllname>.<name>".
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000443// Used for parsing /export arguments.
Rafael Espindolab835ae82015-08-06 14:58:50 +0000444Export parseExport(StringRef Arg) {
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000445 Export E;
446 StringRef Rest;
447 std::tie(E.Name, Rest) = Arg.split(",");
448 if (E.Name.empty())
449 goto err;
Rui Ueyama84425d72016-01-09 01:22:00 +0000450
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000451 if (E.Name.find('=') != StringRef::npos) {
Rui Ueyama84425d72016-01-09 01:22:00 +0000452 StringRef X, Y;
453 std::tie(X, Y) = E.Name.split("=");
454
455 // If "<name>=<dllname>.<name>".
456 if (Y.find(".") != StringRef::npos) {
457 E.Name = X;
458 E.ForwardTo = Y;
459 return E;
460 }
461
462 E.ExtName = X;
463 E.Name = Y;
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000464 if (E.Name.empty())
465 goto err;
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000466 }
467
Rui Ueyama84425d72016-01-09 01:22:00 +0000468 // If "<name>=<internalname>[,@ordinal[,NONAME]][,DATA][,PRIVATE]"
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000469 while (!Rest.empty()) {
470 StringRef Tok;
471 std::tie(Tok, Rest) = Rest.split(",");
472 if (Tok.equals_lower("noname")) {
473 if (E.Ordinal == 0)
474 goto err;
475 E.Noname = true;
476 continue;
477 }
478 if (Tok.equals_lower("data")) {
479 E.Data = true;
480 continue;
481 }
482 if (Tok.equals_lower("private")) {
483 E.Private = true;
484 continue;
485 }
486 if (Tok.startswith("@")) {
487 int32_t Ord;
488 if (Tok.substr(1).getAsInteger(0, Ord))
489 goto err;
490 if (Ord <= 0 || 65535 < Ord)
491 goto err;
492 E.Ordinal = Ord;
493 continue;
494 }
495 goto err;
496 }
497 return E;
498
499err:
Rui Ueyama1a3fd132016-07-14 23:43:36 +0000500 fatal("invalid /export: " + Arg);
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000501}
502
Rui Ueyamaf10a3202015-08-31 08:43:21 +0000503static StringRef undecorate(StringRef Sym) {
504 if (Config->Machine != I386)
505 return Sym;
506 return Sym.startswith("_") ? Sym.substr(1) : Sym;
507}
508
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000509// Performs error checking on all /export arguments.
510// It also sets ordinals.
Rafael Espindolab835ae82015-08-06 14:58:50 +0000511void fixupExports() {
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000512 // Symbol ordinals must be unique.
513 std::set<uint16_t> Ords;
514 for (Export &E : Config->Exports) {
515 if (E.Ordinal == 0)
516 continue;
Rafael Espindolab835ae82015-08-06 14:58:50 +0000517 if (!Ords.insert(E.Ordinal).second)
Rui Ueyama60604792016-07-14 23:37:14 +0000518 fatal("duplicate export ordinal: " + E.Name);
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000519 }
520
Rui Ueyama8765fba2015-07-15 22:21:08 +0000521 for (Export &E : Config->Exports) {
Peter Collingbourne79a5e6b2016-12-09 21:55:24 +0000522 SymbolBody *Sym = E.Sym;
Rui Ueyama84425d72016-01-09 01:22:00 +0000523 if (!E.ForwardTo.empty()) {
524 E.SymbolName = E.Name;
Peter Collingbourne6baa5d22016-12-09 23:34:49 +0000525 } else {
526 if (auto *U = dyn_cast<Undefined>(Sym))
527 if (U->WeakAlias)
528 Sym = U->WeakAlias;
529 E.SymbolName = Sym->getName();
530 }
Rui Ueyama8765fba2015-07-15 22:21:08 +0000531 }
532
Rui Ueyama84425d72016-01-09 01:22:00 +0000533 for (Export &E : Config->Exports) {
534 if (!E.ForwardTo.empty()) {
535 E.ExportName = undecorate(E.Name);
536 } else {
537 E.ExportName = undecorate(E.ExtName.empty() ? E.Name : E.ExtName);
538 }
539 }
Rui Ueyamaf10a3202015-08-31 08:43:21 +0000540
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000541 // Uniquefy by name.
Rui Ueyama4b8cdd22015-07-03 23:23:29 +0000542 std::map<StringRef, Export *> Map;
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000543 std::vector<Export> V;
544 for (Export &E : Config->Exports) {
Rui Ueyamaf10a3202015-08-31 08:43:21 +0000545 auto Pair = Map.insert(std::make_pair(E.ExportName, &E));
Rui Ueyama3126c6c2015-07-04 02:00:22 +0000546 bool Inserted = Pair.second;
547 if (Inserted) {
Rui Ueyama4b8cdd22015-07-03 23:23:29 +0000548 V.push_back(E);
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000549 continue;
550 }
Rui Ueyama3126c6c2015-07-04 02:00:22 +0000551 Export *Existing = Pair.first->second;
Rui Ueyama966acb22015-07-29 22:38:27 +0000552 if (E == *Existing || E.Name != Existing->Name)
Rui Ueyama4b8cdd22015-07-03 23:23:29 +0000553 continue;
Rui Ueyamae6e206d2017-02-21 23:22:56 +0000554 warn("duplicate /export option: " + E.Name);
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000555 }
556 Config->Exports = std::move(V);
557
558 // Sort by name.
Rui Ueyama9420dee2015-07-28 22:34:24 +0000559 std::sort(Config->Exports.begin(), Config->Exports.end(),
560 [](const Export &A, const Export &B) {
Rui Ueyamaf10a3202015-08-31 08:43:21 +0000561 return A.ExportName < B.ExportName;
Rui Ueyama9420dee2015-07-28 22:34:24 +0000562 });
Rui Ueyama8765fba2015-07-15 22:21:08 +0000563}
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000564
Rui Ueyama8765fba2015-07-15 22:21:08 +0000565void assignExportOrdinals() {
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000566 // Assign unique ordinals if default (= 0).
567 uint16_t Max = 0;
568 for (Export &E : Config->Exports)
569 Max = std::max(Max, E.Ordinal);
570 for (Export &E : Config->Exports)
571 if (E.Ordinal == 0)
572 E.Ordinal = ++Max;
Rui Ueyama97dff9e2015-06-17 00:16:33 +0000573}
574
Rui Ueyama8854d8a2015-06-04 19:21:24 +0000575// Parses a string in the form of "key=value" and check
576// if value matches previous values for the same key.
Rafael Espindolab835ae82015-08-06 14:58:50 +0000577void checkFailIfMismatch(StringRef Arg) {
Rui Ueyama75b098b2015-06-18 21:23:34 +0000578 StringRef K, V;
579 std::tie(K, V) = Arg.split('=');
Rafael Espindolab835ae82015-08-06 14:58:50 +0000580 if (K.empty() || V.empty())
Rui Ueyama1a3fd132016-07-14 23:43:36 +0000581 fatal("/failifmismatch: invalid argument: " + Arg);
Rui Ueyama75b098b2015-06-18 21:23:34 +0000582 StringRef Existing = Config->MustMatch[K];
Rafael Espindolab835ae82015-08-06 14:58:50 +0000583 if (!Existing.empty() && V != Existing)
Rui Ueyama1a3fd132016-07-14 23:43:36 +0000584 fatal("/failifmismatch: mismatch detected: " + Existing + " and " + V +
585 " for key " + K);
Rui Ueyama75b098b2015-06-18 21:23:34 +0000586 Config->MustMatch[K] = V;
Rui Ueyama8854d8a2015-06-04 19:21:24 +0000587}
588
Rui Ueyama2bf6a122015-06-14 21:50:50 +0000589// Convert Windows resource files (.res files) to a .obj file
590// using cvtres.exe.
Rafael Espindolab835ae82015-08-06 14:58:50 +0000591std::unique_ptr<MemoryBuffer>
Rui Ueyama2bf6a122015-06-14 21:50:50 +0000592convertResToCOFF(const std::vector<MemoryBufferRef> &MBs) {
Rui Ueyama2bf6a122015-06-14 21:50:50 +0000593 // Create an output file path.
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000594 TemporaryFile File("resource-file", "obj");
Rui Ueyama2bf6a122015-06-14 21:50:50 +0000595
596 // Execute cvtres.exe.
Rui Ueyamaa9c88382015-06-17 21:01:56 +0000597 Executor E("cvtres.exe");
Rui Ueyama5e706b32015-07-25 21:54:50 +0000598 E.add("/machine:" + machineToStr(Config->Machine));
Rui Ueyamaa9c88382015-06-17 21:01:56 +0000599 E.add("/readonly");
600 E.add("/nologo");
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000601 E.add("/out:" + Twine(File.Path));
Rui Ueyamac3dcf992016-11-15 21:25:20 +0000602
603 // We must create new files because the memory buffers we have may have no
604 // underlying file still existing on the disk.
605 // It happens if it was created from a TemporaryFile, which usually delete
606 // the file just after creating the MemoryBuffer.
607 std::vector<TemporaryFile> ResFiles;
608 ResFiles.reserve(MBs.size());
609 for (MemoryBufferRef MB : MBs) {
610 // We store the temporary file in a vector to avoid deletion
611 // before running cvtres
612 ResFiles.emplace_back("resource-file", "res");
613 TemporaryFile& ResFile = ResFiles.back();
614 // Write the content of the resource in a temporary file
615 std::error_code EC;
Rui Ueyama8fe17672016-12-08 20:50:47 +0000616 raw_fd_ostream OS(ResFile.Path, EC, sys::fs::F_None);
Rui Ueyamac3dcf992016-11-15 21:25:20 +0000617 if (EC)
618 fatal(EC, "failed to open " + ResFile.Path);
619 OS << MB.getBuffer();
620 OS.close();
621
622 E.add(ResFile.Path);
623 }
624
Rafael Espindolab835ae82015-08-06 14:58:50 +0000625 E.run();
Rui Ueyamafa12b8b2016-09-02 17:34:17 +0000626 return File.getMemoryBuffer();
Rui Ueyama2bf6a122015-06-14 21:50:50 +0000627}
628
Rui Ueyama1e0b1582017-02-06 20:47:55 +0000629// Run MSVC link.exe for given in-memory object files.
630// Command line options are copied from those given to LLD.
631// This is for the /msvclto option.
Rui Ueyama85d54b02017-02-23 00:26:42 +0000632void runMSVCLinker(std::string Rsp, ArrayRef<StringRef> Objects) {
Rui Ueyama1e0b1582017-02-06 20:47:55 +0000633 // Write the in-memory object files to disk.
634 std::vector<TemporaryFile> Temps;
Rui Ueyama85d54b02017-02-23 00:26:42 +0000635 for (StringRef S : Objects) {
Rui Ueyama1e0b1582017-02-06 20:47:55 +0000636 Temps.emplace_back("lto", "obj", S);
Rui Ueyama85d54b02017-02-23 00:26:42 +0000637 Rsp += quote(Temps.back().Path) + " ";
Rui Ueyama1e0b1582017-02-06 20:47:55 +0000638 }
639
Rui Ueyamae6e206d2017-02-21 23:22:56 +0000640 log("link.exe " + Rsp);
Rui Ueyama1e0b1582017-02-06 20:47:55 +0000641
642 // Run MSVC link.exe.
643 Temps.emplace_back("lto", "rsp", Rsp);
644 Executor E("link.exe");
645 E.add(Twine("@" + Temps.back().Path));
646 E.run();
647}
648
Rui Ueyama3500f662015-05-28 20:30:06 +0000649// Create OptTable
650
651// Create prefix string literals used in Options.td
652#define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
653#include "Options.inc"
654#undef PREFIX
655
656// Create table mapping all options defined in Options.td
657static const llvm::opt::OptTable::Info infoTable[] = {
658#define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X6, X7, X8, X9, X10) \
659 { \
660 X1, X2, X9, X10, OPT_##ID, llvm::opt::Option::KIND##Class, X8, X7, \
661 OPT_##GROUP, OPT_##ALIAS, X6 \
662 },
663#include "Options.inc"
664#undef OPTION
665};
666
667class COFFOptTable : public llvm::opt::OptTable {
668public:
Craig Topperf88d22972015-10-21 16:31:56 +0000669 COFFOptTable() : OptTable(infoTable, true) {}
Rui Ueyama3500f662015-05-28 20:30:06 +0000670};
671
Rui Ueyama115d7c12015-06-07 02:55:19 +0000672// Parses a given list of options.
Rui Ueyama8fe17672016-12-08 20:50:47 +0000673opt::InputArgList ArgParser::parse(ArrayRef<const char *> ArgsArr) {
Rui Ueyama115d7c12015-06-07 02:55:19 +0000674 // First, replace respnose files (@<file>-style options).
Rafael Espindolab835ae82015-08-06 14:58:50 +0000675 std::vector<const char *> Argv = replaceResponseFiles(ArgsArr);
Rui Ueyama115d7c12015-06-07 02:55:19 +0000676
677 // Make InputArgList from string vectors.
Rui Ueyama3500f662015-05-28 20:30:06 +0000678 COFFOptTable Table;
679 unsigned MissingIndex;
680 unsigned MissingCount;
Rui Ueyama8fe17672016-12-08 20:50:47 +0000681 opt::InputArgList Args = Table.ParseArgs(Argv, MissingIndex, MissingCount);
Rui Ueyama2caf4072015-08-26 07:12:08 +0000682
683 // Print the real command line if response files are expanded.
684 if (Args.hasArg(OPT_verbose) && ArgsArr.size() != Argv.size()) {
Rui Ueyamae6e206d2017-02-21 23:22:56 +0000685 std::string Msg = "Command line:";
Rui Ueyama2caf4072015-08-26 07:12:08 +0000686 for (const char *S : Argv)
Rui Ueyamae6e206d2017-02-21 23:22:56 +0000687 Msg += " " + std::string(S);
688 message(Msg);
Rui Ueyama2caf4072015-08-26 07:12:08 +0000689 }
690
Rafael Espindolab835ae82015-08-06 14:58:50 +0000691 if (MissingCount)
Rui Ueyamac910bc72016-11-29 04:17:31 +0000692 fatal(Twine(Args.getArgString(MissingIndex)) + ": missing argument");
David Blaikie6521ed92015-06-22 22:06:52 +0000693 for (auto *Arg : Args.filtered(OPT_UNKNOWN))
Rui Ueyamae6e206d2017-02-21 23:22:56 +0000694 warn("ignoring unknown argument: " + Arg->getSpelling());
Rafael Espindolab835ae82015-08-06 14:58:50 +0000695 return Args;
Rui Ueyama3500f662015-05-28 20:30:06 +0000696}
697
Rui Ueyamae5e407b2016-11-29 04:17:30 +0000698// link.exe has an interesting feature. If LINK environment exists,
699// its contents are handled as a command line string. So you can pass
700// extra arguments using the environment variable.
Rui Ueyama8fe17672016-12-08 20:50:47 +0000701opt::InputArgList ArgParser::parseLINK(ArrayRef<const char *> Args) {
Rui Ueyamae5e407b2016-11-29 04:17:30 +0000702 // Concatenate LINK env and command line arguments, and then parse them.
Rui Ueyama06cf3df2015-06-28 02:35:31 +0000703 Optional<std::string> Env = Process::GetEnv("LINK");
704 if (!Env)
705 return parse(Args);
706 std::vector<const char *> V = tokenize(*Env);
Rui Ueyama9d72f092015-06-28 03:05:38 +0000707 V.insert(V.end(), Args.begin(), Args.end());
Rui Ueyama06cf3df2015-06-28 02:35:31 +0000708 return parse(V);
709}
710
Rui Ueyama115d7c12015-06-07 02:55:19 +0000711std::vector<const char *> ArgParser::tokenize(StringRef S) {
712 SmallVector<const char *, 16> Tokens;
Rui Ueyama8fe17672016-12-08 20:50:47 +0000713 cl::TokenizeWindowsCommandLine(S, Saver, Tokens);
Rui Ueyamaaace5772015-06-07 23:02:50 +0000714 return std::vector<const char *>(Tokens.begin(), Tokens.end());
Rui Ueyama115d7c12015-06-07 02:55:19 +0000715}
716
Rui Ueyamab51f67a2015-06-07 23:00:29 +0000717// Creates a new command line by replacing options starting with '@'
Rui Ueyama115d7c12015-06-07 02:55:19 +0000718// character. '@<filename>' is replaced by the file's contents.
Rafael Espindolab835ae82015-08-06 14:58:50 +0000719std::vector<const char *>
Rui Ueyama115d7c12015-06-07 02:55:19 +0000720ArgParser::replaceResponseFiles(std::vector<const char *> Argv) {
Peter Collingbourne74ecc892015-06-19 22:40:05 +0000721 SmallVector<const char *, 256> Tokens(Argv.data(), Argv.data() + Argv.size());
Rui Ueyamab51f67a2015-06-07 23:00:29 +0000722 ExpandResponseFiles(Saver, TokenizeWindowsCommandLine, Tokens);
723 return std::vector<const char *>(Tokens.begin(), Tokens.end());
Rui Ueyama115d7c12015-06-07 02:55:19 +0000724}
725
Rui Ueyama5c726432015-05-29 16:11:52 +0000726void printHelp(const char *Argv0) {
727 COFFOptTable Table;
Rui Ueyama8fe17672016-12-08 20:50:47 +0000728 Table.PrintHelp(outs(), Argv0, "LLVM Linker", false);
Rui Ueyama5c726432015-05-29 16:11:52 +0000729}
730
Rui Ueyama3500f662015-05-28 20:30:06 +0000731} // namespace coff
732} // namespace lld