[WebAssembly] Fix asan issue from https://reviews.llvm.org/D121349
[llvm-project.git] / lld / COFF / DriverUtils.cpp
blobac0f1f972c7985d681ed5663bedd0a6594868c07
1 //===- DriverUtils.cpp ----------------------------------------------------===//
2 //
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6 //
7 //===----------------------------------------------------------------------===//
8 //
9 // This file contains utility functions for the driver. Because there
10 // are so many small functions, we created this separate file to make
11 // Driver.cpp less cluttered.
13 //===----------------------------------------------------------------------===//
15 #include "Config.h"
16 #include "Driver.h"
17 #include "Symbols.h"
18 #include "lld/Common/ErrorHandler.h"
19 #include "lld/Common/Memory.h"
20 #include "llvm/ADT/Optional.h"
21 #include "llvm/ADT/StringSwitch.h"
22 #include "llvm/BinaryFormat/COFF.h"
23 #include "llvm/Object/COFF.h"
24 #include "llvm/Object/WindowsResource.h"
25 #include "llvm/Option/Arg.h"
26 #include "llvm/Option/ArgList.h"
27 #include "llvm/Option/Option.h"
28 #include "llvm/Support/CommandLine.h"
29 #include "llvm/Support/FileUtilities.h"
30 #include "llvm/Support/MathExtras.h"
31 #include "llvm/Support/Process.h"
32 #include "llvm/Support/Program.h"
33 #include "llvm/Support/raw_ostream.h"
34 #include "llvm/WindowsManifest/WindowsManifestMerger.h"
35 #include <limits>
36 #include <memory>
38 using namespace llvm::COFF;
39 using namespace llvm;
40 using llvm::sys::Process;
42 namespace lld {
43 namespace coff {
44 namespace {
46 const uint16_t SUBLANG_ENGLISH_US = 0x0409;
47 const uint16_t RT_MANIFEST = 24;
49 class Executor {
50 public:
51 explicit Executor(StringRef s) : prog(saver().save(s)) {}
52 void add(StringRef s) { args.push_back(saver().save(s)); }
53 void add(std::string &s) { args.push_back(saver().save(s)); }
54 void add(Twine s) { args.push_back(saver().save(s)); }
55 void add(const char *s) { args.push_back(saver().save(s)); }
57 void run() {
58 ErrorOr<std::string> exeOrErr = sys::findProgramByName(prog);
59 if (auto ec = exeOrErr.getError())
60 fatal("unable to find " + prog + " in PATH: " + ec.message());
61 StringRef exe = saver().save(*exeOrErr);
62 args.insert(args.begin(), exe);
64 if (sys::ExecuteAndWait(args[0], args) != 0)
65 fatal("ExecuteAndWait failed: " +
66 llvm::join(args.begin(), args.end(), " "));
69 private:
70 StringRef prog;
71 std::vector<StringRef> args;
74 } // anonymous namespace
76 // Parses a string in the form of "<integer>[,<integer>]".
77 void parseNumbers(StringRef arg, uint64_t *addr, uint64_t *size) {
78 StringRef s1, s2;
79 std::tie(s1, s2) = arg.split(',');
80 if (s1.getAsInteger(0, *addr))
81 fatal("invalid number: " + s1);
82 if (size && !s2.empty() && s2.getAsInteger(0, *size))
83 fatal("invalid number: " + s2);
86 // Parses a string in the form of "<integer>[.<integer>]".
87 // If second number is not present, Minor is set to 0.
88 void parseVersion(StringRef arg, uint32_t *major, uint32_t *minor) {
89 StringRef s1, s2;
90 std::tie(s1, s2) = arg.split('.');
91 if (s1.getAsInteger(10, *major))
92 fatal("invalid number: " + s1);
93 *minor = 0;
94 if (!s2.empty() && s2.getAsInteger(10, *minor))
95 fatal("invalid number: " + s2);
98 void parseGuard(StringRef fullArg) {
99 SmallVector<StringRef, 1> splitArgs;
100 fullArg.split(splitArgs, ",");
101 for (StringRef arg : splitArgs) {
102 if (arg.equals_insensitive("no"))
103 config->guardCF = GuardCFLevel::Off;
104 else if (arg.equals_insensitive("nolongjmp"))
105 config->guardCF &= ~GuardCFLevel::LongJmp;
106 else if (arg.equals_insensitive("noehcont"))
107 config->guardCF &= ~GuardCFLevel::EHCont;
108 else if (arg.equals_insensitive("cf"))
109 config->guardCF = GuardCFLevel::CF;
110 else if (arg.equals_insensitive("longjmp"))
111 config->guardCF |= GuardCFLevel::CF | GuardCFLevel::LongJmp;
112 else if (arg.equals_insensitive("ehcont"))
113 config->guardCF |= GuardCFLevel::CF | GuardCFLevel::EHCont;
114 else
115 fatal("invalid argument to /guard: " + arg);
119 // Parses a string in the form of "<subsystem>[,<integer>[.<integer>]]".
120 void parseSubsystem(StringRef arg, WindowsSubsystem *sys, uint32_t *major,
121 uint32_t *minor, bool *gotVersion) {
122 StringRef sysStr, ver;
123 std::tie(sysStr, ver) = arg.split(',');
124 std::string sysStrLower = sysStr.lower();
125 *sys = StringSwitch<WindowsSubsystem>(sysStrLower)
126 .Case("boot_application", IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION)
127 .Case("console", IMAGE_SUBSYSTEM_WINDOWS_CUI)
128 .Case("default", IMAGE_SUBSYSTEM_UNKNOWN)
129 .Case("efi_application", IMAGE_SUBSYSTEM_EFI_APPLICATION)
130 .Case("efi_boot_service_driver", IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER)
131 .Case("efi_rom", IMAGE_SUBSYSTEM_EFI_ROM)
132 .Case("efi_runtime_driver", IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER)
133 .Case("native", IMAGE_SUBSYSTEM_NATIVE)
134 .Case("posix", IMAGE_SUBSYSTEM_POSIX_CUI)
135 .Case("windows", IMAGE_SUBSYSTEM_WINDOWS_GUI)
136 .Default(IMAGE_SUBSYSTEM_UNKNOWN);
137 if (*sys == IMAGE_SUBSYSTEM_UNKNOWN && sysStrLower != "default")
138 fatal("unknown subsystem: " + sysStr);
139 if (!ver.empty())
140 parseVersion(ver, major, minor);
141 if (gotVersion)
142 *gotVersion = !ver.empty();
145 // Parse a string of the form of "<from>=<to>".
146 // Results are directly written to Config.
147 void parseAlternateName(StringRef s) {
148 StringRef from, to;
149 std::tie(from, to) = s.split('=');
150 if (from.empty() || to.empty())
151 fatal("/alternatename: invalid argument: " + s);
152 auto it = config->alternateNames.find(from);
153 if (it != config->alternateNames.end() && it->second != to)
154 fatal("/alternatename: conflicts: " + s);
155 config->alternateNames.insert(it, std::make_pair(from, to));
158 // Parse a string of the form of "<from>=<to>".
159 // Results are directly written to Config.
160 void parseMerge(StringRef s) {
161 StringRef from, to;
162 std::tie(from, to) = s.split('=');
163 if (from.empty() || to.empty())
164 fatal("/merge: invalid argument: " + s);
165 if (from == ".rsrc" || to == ".rsrc")
166 fatal("/merge: cannot merge '.rsrc' with any section");
167 if (from == ".reloc" || to == ".reloc")
168 fatal("/merge: cannot merge '.reloc' with any section");
169 auto pair = config->merge.insert(std::make_pair(from, to));
170 bool inserted = pair.second;
171 if (!inserted) {
172 StringRef existing = pair.first->second;
173 if (existing != to)
174 warn(s + ": already merged into " + existing);
178 void parsePDBPageSize(StringRef s) {
179 int v;
180 if (s.getAsInteger(0, v)) {
181 error("/pdbpagesize: invalid argument: " + s);
182 return;
184 if (v != 4096 && v != 8192 && v != 16384 && v != 32768) {
185 error("/pdbpagesize: invalid argument: " + s);
186 return;
189 config->pdbPageSize = v;
192 static uint32_t parseSectionAttributes(StringRef s) {
193 uint32_t ret = 0;
194 for (char c : s.lower()) {
195 switch (c) {
196 case 'd':
197 ret |= IMAGE_SCN_MEM_DISCARDABLE;
198 break;
199 case 'e':
200 ret |= IMAGE_SCN_MEM_EXECUTE;
201 break;
202 case 'k':
203 ret |= IMAGE_SCN_MEM_NOT_CACHED;
204 break;
205 case 'p':
206 ret |= IMAGE_SCN_MEM_NOT_PAGED;
207 break;
208 case 'r':
209 ret |= IMAGE_SCN_MEM_READ;
210 break;
211 case 's':
212 ret |= IMAGE_SCN_MEM_SHARED;
213 break;
214 case 'w':
215 ret |= IMAGE_SCN_MEM_WRITE;
216 break;
217 default:
218 fatal("/section: invalid argument: " + s);
221 return ret;
224 // Parses /section option argument.
225 void parseSection(StringRef s) {
226 StringRef name, attrs;
227 std::tie(name, attrs) = s.split(',');
228 if (name.empty() || attrs.empty())
229 fatal("/section: invalid argument: " + s);
230 config->section[name] = parseSectionAttributes(attrs);
233 // Parses /aligncomm option argument.
234 void parseAligncomm(StringRef s) {
235 StringRef name, align;
236 std::tie(name, align) = s.split(',');
237 if (name.empty() || align.empty()) {
238 error("/aligncomm: invalid argument: " + s);
239 return;
241 int v;
242 if (align.getAsInteger(0, v)) {
243 error("/aligncomm: invalid argument: " + s);
244 return;
246 config->alignComm[std::string(name)] =
247 std::max(config->alignComm[std::string(name)], 1 << v);
250 // Parses /functionpadmin option argument.
251 void parseFunctionPadMin(llvm::opt::Arg *a, llvm::COFF::MachineTypes machine) {
252 StringRef arg = a->getNumValues() ? a->getValue() : "";
253 if (!arg.empty()) {
254 // Optional padding in bytes is given.
255 if (arg.getAsInteger(0, config->functionPadMin))
256 error("/functionpadmin: invalid argument: " + arg);
257 return;
259 // No optional argument given.
260 // Set default padding based on machine, similar to link.exe.
261 // There is no default padding for ARM platforms.
262 if (machine == I386) {
263 config->functionPadMin = 5;
264 } else if (machine == AMD64) {
265 config->functionPadMin = 6;
266 } else {
267 error("/functionpadmin: invalid argument for this machine: " + arg);
271 // Parses a string in the form of "EMBED[,=<integer>]|NO".
272 // Results are directly written to Config.
273 void parseManifest(StringRef arg) {
274 if (arg.equals_insensitive("no")) {
275 config->manifest = Configuration::No;
276 return;
278 if (!arg.startswith_insensitive("embed"))
279 fatal("invalid option " + arg);
280 config->manifest = Configuration::Embed;
281 arg = arg.substr(strlen("embed"));
282 if (arg.empty())
283 return;
284 if (!arg.startswith_insensitive(",id="))
285 fatal("invalid option " + arg);
286 arg = arg.substr(strlen(",id="));
287 if (arg.getAsInteger(0, config->manifestID))
288 fatal("invalid option " + arg);
291 // Parses a string in the form of "level=<string>|uiAccess=<string>|NO".
292 // Results are directly written to Config.
293 void parseManifestUAC(StringRef arg) {
294 if (arg.equals_insensitive("no")) {
295 config->manifestUAC = false;
296 return;
298 for (;;) {
299 arg = arg.ltrim();
300 if (arg.empty())
301 return;
302 if (arg.startswith_insensitive("level=")) {
303 arg = arg.substr(strlen("level="));
304 std::tie(config->manifestLevel, arg) = arg.split(" ");
305 continue;
307 if (arg.startswith_insensitive("uiaccess=")) {
308 arg = arg.substr(strlen("uiaccess="));
309 std::tie(config->manifestUIAccess, arg) = arg.split(" ");
310 continue;
312 fatal("invalid option " + arg);
316 // Parses a string in the form of "cd|net[,(cd|net)]*"
317 // Results are directly written to Config.
318 void parseSwaprun(StringRef arg) {
319 do {
320 StringRef swaprun, newArg;
321 std::tie(swaprun, newArg) = arg.split(',');
322 if (swaprun.equals_insensitive("cd"))
323 config->swaprunCD = true;
324 else if (swaprun.equals_insensitive("net"))
325 config->swaprunNet = true;
326 else if (swaprun.empty())
327 error("/swaprun: missing argument");
328 else
329 error("/swaprun: invalid argument: " + swaprun);
330 // To catch trailing commas, e.g. `/spawrun:cd,`
331 if (newArg.empty() && arg.endswith(","))
332 error("/swaprun: missing argument");
333 arg = newArg;
334 } while (!arg.empty());
337 // An RAII temporary file class that automatically removes a temporary file.
338 namespace {
339 class TemporaryFile {
340 public:
341 TemporaryFile(StringRef prefix, StringRef extn, StringRef contents = "") {
342 SmallString<128> s;
343 if (auto ec = sys::fs::createTemporaryFile("lld-" + prefix, extn, s))
344 fatal("cannot create a temporary file: " + ec.message());
345 path = std::string(s.str());
347 if (!contents.empty()) {
348 std::error_code ec;
349 raw_fd_ostream os(path, ec, sys::fs::OF_None);
350 if (ec)
351 fatal("failed to open " + path + ": " + ec.message());
352 os << contents;
356 TemporaryFile(TemporaryFile &&obj) {
357 std::swap(path, obj.path);
360 ~TemporaryFile() {
361 if (path.empty())
362 return;
363 if (sys::fs::remove(path))
364 fatal("failed to remove " + path);
367 // Returns a memory buffer of this temporary file.
368 // Note that this function does not leave the file open,
369 // so it is safe to remove the file immediately after this function
370 // is called (you cannot remove an opened file on Windows.)
371 std::unique_ptr<MemoryBuffer> getMemoryBuffer() {
372 // IsVolatile=true forces MemoryBuffer to not use mmap().
373 return CHECK(MemoryBuffer::getFile(path, /*IsText=*/false,
374 /*RequiresNullTerminator=*/false,
375 /*IsVolatile=*/true),
376 "could not open " + path);
379 std::string path;
383 static std::string createDefaultXml() {
384 std::string ret;
385 raw_string_ostream os(ret);
387 // Emit the XML. Note that we do *not* verify that the XML attributes are
388 // syntactically correct. This is intentional for link.exe compatibility.
389 os << "<?xml version=\"1.0\" standalone=\"yes\"?>\n"
390 << "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\"\n"
391 << " manifestVersion=\"1.0\">\n";
392 if (config->manifestUAC) {
393 os << " <trustInfo>\n"
394 << " <security>\n"
395 << " <requestedPrivileges>\n"
396 << " <requestedExecutionLevel level=" << config->manifestLevel
397 << " uiAccess=" << config->manifestUIAccess << "/>\n"
398 << " </requestedPrivileges>\n"
399 << " </security>\n"
400 << " </trustInfo>\n";
402 for (auto manifestDependency : config->manifestDependencies) {
403 os << " <dependency>\n"
404 << " <dependentAssembly>\n"
405 << " <assemblyIdentity " << manifestDependency << " />\n"
406 << " </dependentAssembly>\n"
407 << " </dependency>\n";
409 os << "</assembly>\n";
410 return os.str();
413 static std::string createManifestXmlWithInternalMt(StringRef defaultXml) {
414 std::unique_ptr<MemoryBuffer> defaultXmlCopy =
415 MemoryBuffer::getMemBufferCopy(defaultXml);
417 windows_manifest::WindowsManifestMerger merger;
418 if (auto e = merger.merge(*defaultXmlCopy.get()))
419 fatal("internal manifest tool failed on default xml: " +
420 toString(std::move(e)));
422 for (StringRef filename : config->manifestInput) {
423 std::unique_ptr<MemoryBuffer> manifest =
424 check(MemoryBuffer::getFile(filename));
425 // Call takeBuffer to include in /reproduce: output if applicable.
426 if (auto e = merger.merge(driver->takeBuffer(std::move(manifest))))
427 fatal("internal manifest tool failed on file " + filename + ": " +
428 toString(std::move(e)));
431 return std::string(merger.getMergedManifest().get()->getBuffer());
434 static std::string createManifestXmlWithExternalMt(StringRef defaultXml) {
435 // Create the default manifest file as a temporary file.
436 TemporaryFile Default("defaultxml", "manifest");
437 std::error_code ec;
438 raw_fd_ostream os(Default.path, ec, sys::fs::OF_TextWithCRLF);
439 if (ec)
440 fatal("failed to open " + Default.path + ": " + ec.message());
441 os << defaultXml;
442 os.close();
444 // Merge user-supplied manifests if they are given. Since libxml2 is not
445 // enabled, we must shell out to Microsoft's mt.exe tool.
446 TemporaryFile user("user", "manifest");
448 Executor e("mt.exe");
449 e.add("/manifest");
450 e.add(Default.path);
451 for (StringRef filename : config->manifestInput) {
452 e.add("/manifest");
453 e.add(filename);
455 // Manually add the file to the /reproduce: tar if needed.
456 if (driver->tar)
457 if (auto mbOrErr = MemoryBuffer::getFile(filename))
458 driver->takeBuffer(std::move(*mbOrErr));
460 e.add("/nologo");
461 e.add("/out:" + StringRef(user.path));
462 e.run();
464 return std::string(
465 CHECK(MemoryBuffer::getFile(user.path), "could not open " + user.path)
466 .get()
467 ->getBuffer());
470 static std::string createManifestXml() {
471 std::string defaultXml = createDefaultXml();
472 if (config->manifestInput.empty())
473 return defaultXml;
475 if (windows_manifest::isAvailable())
476 return createManifestXmlWithInternalMt(defaultXml);
478 return createManifestXmlWithExternalMt(defaultXml);
481 static std::unique_ptr<WritableMemoryBuffer>
482 createMemoryBufferForManifestRes(size_t manifestSize) {
483 size_t resSize = alignTo(
484 object::WIN_RES_MAGIC_SIZE + object::WIN_RES_NULL_ENTRY_SIZE +
485 sizeof(object::WinResHeaderPrefix) + sizeof(object::WinResIDs) +
486 sizeof(object::WinResHeaderSuffix) + manifestSize,
487 object::WIN_RES_DATA_ALIGNMENT);
488 return WritableMemoryBuffer::getNewMemBuffer(resSize, config->outputFile +
489 ".manifest.res");
492 static void writeResFileHeader(char *&buf) {
493 memcpy(buf, COFF::WinResMagic, sizeof(COFF::WinResMagic));
494 buf += sizeof(COFF::WinResMagic);
495 memset(buf, 0, object::WIN_RES_NULL_ENTRY_SIZE);
496 buf += object::WIN_RES_NULL_ENTRY_SIZE;
499 static void writeResEntryHeader(char *&buf, size_t manifestSize) {
500 // Write the prefix.
501 auto *prefix = reinterpret_cast<object::WinResHeaderPrefix *>(buf);
502 prefix->DataSize = manifestSize;
503 prefix->HeaderSize = sizeof(object::WinResHeaderPrefix) +
504 sizeof(object::WinResIDs) +
505 sizeof(object::WinResHeaderSuffix);
506 buf += sizeof(object::WinResHeaderPrefix);
508 // Write the Type/Name IDs.
509 auto *iDs = reinterpret_cast<object::WinResIDs *>(buf);
510 iDs->setType(RT_MANIFEST);
511 iDs->setName(config->manifestID);
512 buf += sizeof(object::WinResIDs);
514 // Write the suffix.
515 auto *suffix = reinterpret_cast<object::WinResHeaderSuffix *>(buf);
516 suffix->DataVersion = 0;
517 suffix->MemoryFlags = object::WIN_RES_PURE_MOVEABLE;
518 suffix->Language = SUBLANG_ENGLISH_US;
519 suffix->Version = 0;
520 suffix->Characteristics = 0;
521 buf += sizeof(object::WinResHeaderSuffix);
524 // Create a resource file containing a manifest XML.
525 std::unique_ptr<MemoryBuffer> createManifestRes() {
526 std::string manifest = createManifestXml();
528 std::unique_ptr<WritableMemoryBuffer> res =
529 createMemoryBufferForManifestRes(manifest.size());
531 char *buf = res->getBufferStart();
532 writeResFileHeader(buf);
533 writeResEntryHeader(buf, manifest.size());
535 // Copy the manifest data into the .res file.
536 std::copy(manifest.begin(), manifest.end(), buf);
537 return std::move(res);
540 void createSideBySideManifest() {
541 std::string path = std::string(config->manifestFile);
542 if (path == "")
543 path = config->outputFile + ".manifest";
544 std::error_code ec;
545 raw_fd_ostream out(path, ec, sys::fs::OF_TextWithCRLF);
546 if (ec)
547 fatal("failed to create manifest: " + ec.message());
548 out << createManifestXml();
551 // Parse a string in the form of
552 // "<name>[=<internalname>][,@ordinal[,NONAME]][,DATA][,PRIVATE]"
553 // or "<name>=<dllname>.<name>".
554 // Used for parsing /export arguments.
555 Export parseExport(StringRef arg) {
556 Export e;
557 StringRef rest;
558 std::tie(e.name, rest) = arg.split(",");
559 if (e.name.empty())
560 goto err;
562 if (e.name.contains('=')) {
563 StringRef x, y;
564 std::tie(x, y) = e.name.split("=");
566 // If "<name>=<dllname>.<name>".
567 if (y.contains(".")) {
568 e.name = x;
569 e.forwardTo = y;
570 return e;
573 e.extName = x;
574 e.name = y;
575 if (e.name.empty())
576 goto err;
579 // If "<name>=<internalname>[,@ordinal[,NONAME]][,DATA][,PRIVATE]"
580 while (!rest.empty()) {
581 StringRef tok;
582 std::tie(tok, rest) = rest.split(",");
583 if (tok.equals_insensitive("noname")) {
584 if (e.ordinal == 0)
585 goto err;
586 e.noname = true;
587 continue;
589 if (tok.equals_insensitive("data")) {
590 e.data = true;
591 continue;
593 if (tok.equals_insensitive("constant")) {
594 e.constant = true;
595 continue;
597 if (tok.equals_insensitive("private")) {
598 e.isPrivate = true;
599 continue;
601 if (tok.startswith("@")) {
602 int32_t ord;
603 if (tok.substr(1).getAsInteger(0, ord))
604 goto err;
605 if (ord <= 0 || 65535 < ord)
606 goto err;
607 e.ordinal = ord;
608 continue;
610 goto err;
612 return e;
614 err:
615 fatal("invalid /export: " + arg);
618 static StringRef undecorate(StringRef sym) {
619 if (config->machine != I386)
620 return sym;
621 // In MSVC mode, a fully decorated stdcall function is exported
622 // as-is with the leading underscore (with type IMPORT_NAME).
623 // In MinGW mode, a decorated stdcall function gets the underscore
624 // removed, just like normal cdecl functions.
625 if (sym.startswith("_") && sym.contains('@') && !config->mingw)
626 return sym;
627 return sym.startswith("_") ? sym.substr(1) : sym;
630 // Convert stdcall/fastcall style symbols into unsuffixed symbols,
631 // with or without a leading underscore. (MinGW specific.)
632 static StringRef killAt(StringRef sym, bool prefix) {
633 if (sym.empty())
634 return sym;
635 // Strip any trailing stdcall suffix
636 sym = sym.substr(0, sym.find('@', 1));
637 if (!sym.startswith("@")) {
638 if (prefix && !sym.startswith("_"))
639 return saver().save("_" + sym);
640 return sym;
642 // For fastcall, remove the leading @ and replace it with an
643 // underscore, if prefixes are used.
644 sym = sym.substr(1);
645 if (prefix)
646 sym = saver().save("_" + sym);
647 return sym;
650 // Performs error checking on all /export arguments.
651 // It also sets ordinals.
652 void fixupExports() {
653 // Symbol ordinals must be unique.
654 std::set<uint16_t> ords;
655 for (Export &e : config->exports) {
656 if (e.ordinal == 0)
657 continue;
658 if (!ords.insert(e.ordinal).second)
659 fatal("duplicate export ordinal: " + e.name);
662 for (Export &e : config->exports) {
663 if (!e.forwardTo.empty()) {
664 e.exportName = undecorate(e.name);
665 } else {
666 e.exportName = undecorate(e.extName.empty() ? e.name : e.extName);
670 if (config->killAt && config->machine == I386) {
671 for (Export &e : config->exports) {
672 e.name = killAt(e.name, true);
673 e.exportName = killAt(e.exportName, false);
674 e.extName = killAt(e.extName, true);
675 e.symbolName = killAt(e.symbolName, true);
679 // Uniquefy by name.
680 DenseMap<StringRef, Export *> map(config->exports.size());
681 std::vector<Export> v;
682 for (Export &e : config->exports) {
683 auto pair = map.insert(std::make_pair(e.exportName, &e));
684 bool inserted = pair.second;
685 if (inserted) {
686 v.push_back(e);
687 continue;
689 Export *existing = pair.first->second;
690 if (e == *existing || e.name != existing->name)
691 continue;
692 warn("duplicate /export option: " + e.name);
694 config->exports = std::move(v);
696 // Sort by name.
697 std::sort(config->exports.begin(), config->exports.end(),
698 [](const Export &a, const Export &b) {
699 return a.exportName < b.exportName;
703 void assignExportOrdinals() {
704 // Assign unique ordinals if default (= 0).
705 uint32_t max = 0;
706 for (Export &e : config->exports)
707 max = std::max(max, (uint32_t)e.ordinal);
708 for (Export &e : config->exports)
709 if (e.ordinal == 0)
710 e.ordinal = ++max;
711 if (max > std::numeric_limits<uint16_t>::max())
712 fatal("too many exported symbols (max " +
713 Twine(std::numeric_limits<uint16_t>::max()) + ")");
716 // Parses a string in the form of "key=value" and check
717 // if value matches previous values for the same key.
718 void checkFailIfMismatch(StringRef arg, InputFile *source) {
719 StringRef k, v;
720 std::tie(k, v) = arg.split('=');
721 if (k.empty() || v.empty())
722 fatal("/failifmismatch: invalid argument: " + arg);
723 std::pair<StringRef, InputFile *> existing = config->mustMatch[k];
724 if (!existing.first.empty() && v != existing.first) {
725 std::string sourceStr = source ? toString(source) : "cmd-line";
726 std::string existingStr =
727 existing.second ? toString(existing.second) : "cmd-line";
728 fatal("/failifmismatch: mismatch detected for '" + k + "':\n>>> " +
729 existingStr + " has value " + existing.first + "\n>>> " + sourceStr +
730 " has value " + v);
732 config->mustMatch[k] = {v, source};
735 // Convert Windows resource files (.res files) to a .obj file.
736 // Does what cvtres.exe does, but in-process and cross-platform.
737 MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs,
738 ArrayRef<ObjFile *> objs) {
739 object::WindowsResourceParser parser(/* MinGW */ config->mingw);
741 std::vector<std::string> duplicates;
742 for (MemoryBufferRef mb : mbs) {
743 std::unique_ptr<object::Binary> bin = check(object::createBinary(mb));
744 object::WindowsResource *rf = dyn_cast<object::WindowsResource>(bin.get());
745 if (!rf)
746 fatal("cannot compile non-resource file as resource");
748 if (auto ec = parser.parse(rf, duplicates))
749 fatal(toString(std::move(ec)));
752 // Note: This processes all .res files before all objs. Ideally they'd be
753 // handled in the same order they were linked (to keep the right one, if
754 // there are duplicates that are tolerated due to forceMultipleRes).
755 for (ObjFile *f : objs) {
756 object::ResourceSectionRef rsf;
757 if (auto ec = rsf.load(f->getCOFFObj()))
758 fatal(toString(f) + ": " + toString(std::move(ec)));
760 if (auto ec = parser.parse(rsf, f->getName(), duplicates))
761 fatal(toString(std::move(ec)));
764 if (config->mingw)
765 parser.cleanUpManifests(duplicates);
767 for (const auto &dupeDiag : duplicates)
768 if (config->forceMultipleRes)
769 warn(dupeDiag);
770 else
771 error(dupeDiag);
773 Expected<std::unique_ptr<MemoryBuffer>> e =
774 llvm::object::writeWindowsResourceCOFF(config->machine, parser,
775 config->timestamp);
776 if (!e)
777 fatal("failed to write .res to COFF: " + toString(e.takeError()));
779 MemoryBufferRef mbref = **e;
780 make<std::unique_ptr<MemoryBuffer>>(std::move(*e)); // take ownership
781 return mbref;
784 // Create OptTable
786 // Create prefix string literals used in Options.td
787 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
788 #include "Options.inc"
789 #undef PREFIX
791 // Create table mapping all options defined in Options.td
792 static const llvm::opt::OptTable::Info infoTable[] = {
793 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \
794 {X1, X2, X10, X11, OPT_##ID, llvm::opt::Option::KIND##Class, \
795 X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12},
796 #include "Options.inc"
797 #undef OPTION
800 COFFOptTable::COFFOptTable() : OptTable(infoTable, true) {}
802 COFFOptTable optTable;
804 // Set color diagnostics according to --color-diagnostics={auto,always,never}
805 // or --no-color-diagnostics flags.
806 static void handleColorDiagnostics(opt::InputArgList &args) {
807 auto *arg = args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq,
808 OPT_no_color_diagnostics);
809 if (!arg)
810 return;
811 if (arg->getOption().getID() == OPT_color_diagnostics) {
812 lld::errs().enable_colors(true);
813 } else if (arg->getOption().getID() == OPT_no_color_diagnostics) {
814 lld::errs().enable_colors(false);
815 } else {
816 StringRef s = arg->getValue();
817 if (s == "always")
818 lld::errs().enable_colors(true);
819 else if (s == "never")
820 lld::errs().enable_colors(false);
821 else if (s != "auto")
822 error("unknown option: --color-diagnostics=" + s);
826 static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &args) {
827 if (auto *arg = args.getLastArg(OPT_rsp_quoting)) {
828 StringRef s = arg->getValue();
829 if (s != "windows" && s != "posix")
830 error("invalid response file quoting: " + s);
831 if (s == "windows")
832 return cl::TokenizeWindowsCommandLine;
833 return cl::TokenizeGNUCommandLine;
835 // The COFF linker always defaults to Windows quoting.
836 return cl::TokenizeWindowsCommandLine;
839 // Parses a given list of options.
840 opt::InputArgList ArgParser::parse(ArrayRef<const char *> argv) {
841 // Make InputArgList from string vectors.
842 unsigned missingIndex;
843 unsigned missingCount;
845 // We need to get the quoting style for response files before parsing all
846 // options so we parse here before and ignore all the options but
847 // --rsp-quoting and /lldignoreenv.
848 // (This means --rsp-quoting can't be added through %LINK%.)
849 opt::InputArgList args = optTable.ParseArgs(argv, missingIndex, missingCount);
851 // Expand response files (arguments in the form of @<filename>) and insert
852 // flags from %LINK% and %_LINK_%, and then parse the argument again.
853 SmallVector<const char *, 256> expandedArgv(argv.data(),
854 argv.data() + argv.size());
855 if (!args.hasArg(OPT_lldignoreenv))
856 addLINK(expandedArgv);
857 cl::ExpandResponseFiles(saver(), getQuotingStyle(args), expandedArgv);
858 args = optTable.ParseArgs(makeArrayRef(expandedArgv).drop_front(),
859 missingIndex, missingCount);
861 // Print the real command line if response files are expanded.
862 if (args.hasArg(OPT_verbose) && argv.size() != expandedArgv.size()) {
863 std::string msg = "Command line:";
864 for (const char *s : expandedArgv)
865 msg += " " + std::string(s);
866 message(msg);
869 // Save the command line after response file expansion so we can write it to
870 // the PDB if necessary.
871 config->argv = {expandedArgv.begin(), expandedArgv.end()};
873 // Handle /WX early since it converts missing argument warnings to errors.
874 errorHandler().fatalWarnings = args.hasFlag(OPT_WX, OPT_WX_no, false);
876 if (missingCount)
877 fatal(Twine(args.getArgString(missingIndex)) + ": missing argument");
879 handleColorDiagnostics(args);
881 for (opt::Arg *arg : args.filtered(OPT_UNKNOWN)) {
882 std::string nearest;
883 if (optTable.findNearest(arg->getAsString(args), nearest) > 1)
884 warn("ignoring unknown argument '" + arg->getAsString(args) + "'");
885 else
886 warn("ignoring unknown argument '" + arg->getAsString(args) +
887 "', did you mean '" + nearest + "'");
890 if (args.hasArg(OPT_lib))
891 warn("ignoring /lib since it's not the first argument");
893 return args;
896 // Tokenizes and parses a given string as command line in .drective section.
897 ParsedDirectives ArgParser::parseDirectives(StringRef s) {
898 ParsedDirectives result;
899 SmallVector<const char *, 16> rest;
901 // Handle /EXPORT and /INCLUDE in a fast path. These directives can appear for
902 // potentially every symbol in the object, so they must be handled quickly.
903 SmallVector<StringRef, 16> tokens;
904 cl::TokenizeWindowsCommandLineNoCopy(s, saver(), tokens);
905 for (StringRef tok : tokens) {
906 if (tok.startswith_insensitive("/export:") ||
907 tok.startswith_insensitive("-export:"))
908 result.exports.push_back(tok.substr(strlen("/export:")));
909 else if (tok.startswith_insensitive("/include:") ||
910 tok.startswith_insensitive("-include:"))
911 result.includes.push_back(tok.substr(strlen("/include:")));
912 else {
913 // Copy substrings that are not valid C strings. The tokenizer may have
914 // already copied quoted arguments for us, so those do not need to be
915 // copied again.
916 bool HasNul = tok.end() != s.end() && tok.data()[tok.size()] == '\0';
917 rest.push_back(HasNul ? tok.data() : saver().save(tok).data());
921 // Make InputArgList from unparsed string vectors.
922 unsigned missingIndex;
923 unsigned missingCount;
925 result.args = optTable.ParseArgs(rest, missingIndex, missingCount);
927 if (missingCount)
928 fatal(Twine(result.args.getArgString(missingIndex)) + ": missing argument");
929 for (auto *arg : result.args.filtered(OPT_UNKNOWN))
930 warn("ignoring unknown argument: " + arg->getAsString(result.args));
931 return result;
934 // link.exe has an interesting feature. If LINK or _LINK_ environment
935 // variables exist, their contents are handled as command line strings.
936 // So you can pass extra arguments using them.
937 void ArgParser::addLINK(SmallVector<const char *, 256> &argv) {
938 // Concatenate LINK env and command line arguments, and then parse them.
939 if (Optional<std::string> s = Process::GetEnv("LINK")) {
940 std::vector<const char *> v = tokenize(*s);
941 argv.insert(std::next(argv.begin()), v.begin(), v.end());
943 if (Optional<std::string> s = Process::GetEnv("_LINK_")) {
944 std::vector<const char *> v = tokenize(*s);
945 argv.insert(std::next(argv.begin()), v.begin(), v.end());
949 std::vector<const char *> ArgParser::tokenize(StringRef s) {
950 SmallVector<const char *, 16> tokens;
951 cl::TokenizeWindowsCommandLine(s, saver(), tokens);
952 return std::vector<const char *>(tokens.begin(), tokens.end());
955 void printHelp(const char *argv0) {
956 optTable.printHelp(lld::outs(),
957 (std::string(argv0) + " [options] file...").c_str(),
958 "LLVM Linker", false);
961 } // namespace coff
962 } // namespace lld