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. 12 // 13 //===----------------------------------------------------------------------===// 14 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> 37 38 using namespace llvm::COFF; 39 using namespace llvm; 40 using llvm::sys::Process; 41 42 namespace lld { 43 namespace coff { 44 namespace { 45 46 const uint16_t SUBLANG_ENGLISH_US = 0x0409; 47 const uint16_t RT_MANIFEST = 24; 48 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)); } 56 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); 63 64 if (sys::ExecuteAndWait(args[0], args) != 0) 65 fatal("ExecuteAndWait failed: " + 66 llvm::join(args.begin(), args.end(), " ")); 67 } 68 69 private: 70 StringRef prog; 71 std::vector<StringRef> args; 72 }; 73 74 } // anonymous namespace 75 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); 84 } 85 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(0, *major)) 92 fatal("invalid number: " + s1); 93 *minor = 0; 94 if (!s2.empty() && s2.getAsInteger(0, *minor)) 95 fatal("invalid number: " + s2); 96 } 97 98 void parseGuard(StringRef fullArg) { 99 SmallVector<StringRef, 1> splitArgs; 100 fullArg.split(splitArgs, ","); 101 for (StringRef arg : splitArgs) { 102 if (arg.equals_lower("no")) 103 config->guardCF = GuardCFLevel::Off; 104 else if (arg.equals_lower("nolongjmp")) 105 config->guardCF = GuardCFLevel::NoLongJmp; 106 else if (arg.equals_lower("cf") || arg.equals_lower("longjmp")) 107 config->guardCF = GuardCFLevel::Full; 108 else 109 fatal("invalid argument to /guard: " + arg); 110 } 111 } 112 113 // Parses a string in the form of "<subsystem>[,<integer>[.<integer>]]". 114 void parseSubsystem(StringRef arg, WindowsSubsystem *sys, uint32_t *major, 115 uint32_t *minor) { 116 StringRef sysStr, ver; 117 std::tie(sysStr, ver) = arg.split(','); 118 std::string sysStrLower = sysStr.lower(); 119 *sys = StringSwitch<WindowsSubsystem>(sysStrLower) 120 .Case("boot_application", IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION) 121 .Case("console", IMAGE_SUBSYSTEM_WINDOWS_CUI) 122 .Case("default", IMAGE_SUBSYSTEM_UNKNOWN) 123 .Case("efi_application", IMAGE_SUBSYSTEM_EFI_APPLICATION) 124 .Case("efi_boot_service_driver", IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) 125 .Case("efi_rom", IMAGE_SUBSYSTEM_EFI_ROM) 126 .Case("efi_runtime_driver", IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) 127 .Case("native", IMAGE_SUBSYSTEM_NATIVE) 128 .Case("posix", IMAGE_SUBSYSTEM_POSIX_CUI) 129 .Case("windows", IMAGE_SUBSYSTEM_WINDOWS_GUI) 130 .Default(IMAGE_SUBSYSTEM_UNKNOWN); 131 if (*sys == IMAGE_SUBSYSTEM_UNKNOWN && sysStrLower != "default") 132 fatal("unknown subsystem: " + sysStr); 133 if (!ver.empty()) 134 parseVersion(ver, major, minor); 135 } 136 137 // Parse a string of the form of "<from>=<to>". 138 // Results are directly written to Config. 139 void parseAlternateName(StringRef s) { 140 StringRef from, to; 141 std::tie(from, to) = s.split('='); 142 if (from.empty() || to.empty()) 143 fatal("/alternatename: invalid argument: " + s); 144 auto it = config->alternateNames.find(from); 145 if (it != config->alternateNames.end() && it->second != to) 146 fatal("/alternatename: conflicts: " + s); 147 config->alternateNames.insert(it, std::make_pair(from, to)); 148 } 149 150 // Parse a string of the form of "<from>=<to>". 151 // Results are directly written to Config. 152 void parseMerge(StringRef s) { 153 StringRef from, to; 154 std::tie(from, to) = s.split('='); 155 if (from.empty() || to.empty()) 156 fatal("/merge: invalid argument: " + s); 157 if (from == ".rsrc" || to == ".rsrc") 158 fatal("/merge: cannot merge '.rsrc' with any section"); 159 if (from == ".reloc" || to == ".reloc") 160 fatal("/merge: cannot merge '.reloc' with any section"); 161 auto pair = config->merge.insert(std::make_pair(from, to)); 162 bool inserted = pair.second; 163 if (!inserted) { 164 StringRef existing = pair.first->second; 165 if (existing != to) 166 warn(s + ": already merged into " + existing); 167 } 168 } 169 170 static uint32_t parseSectionAttributes(StringRef s) { 171 uint32_t ret = 0; 172 for (char c : s.lower()) { 173 switch (c) { 174 case 'd': 175 ret |= IMAGE_SCN_MEM_DISCARDABLE; 176 break; 177 case 'e': 178 ret |= IMAGE_SCN_MEM_EXECUTE; 179 break; 180 case 'k': 181 ret |= IMAGE_SCN_MEM_NOT_CACHED; 182 break; 183 case 'p': 184 ret |= IMAGE_SCN_MEM_NOT_PAGED; 185 break; 186 case 'r': 187 ret |= IMAGE_SCN_MEM_READ; 188 break; 189 case 's': 190 ret |= IMAGE_SCN_MEM_SHARED; 191 break; 192 case 'w': 193 ret |= IMAGE_SCN_MEM_WRITE; 194 break; 195 default: 196 fatal("/section: invalid argument: " + s); 197 } 198 } 199 return ret; 200 } 201 202 // Parses /section option argument. 203 void parseSection(StringRef s) { 204 StringRef name, attrs; 205 std::tie(name, attrs) = s.split(','); 206 if (name.empty() || attrs.empty()) 207 fatal("/section: invalid argument: " + s); 208 config->section[name] = parseSectionAttributes(attrs); 209 } 210 211 // Parses /aligncomm option argument. 212 void parseAligncomm(StringRef s) { 213 StringRef name, align; 214 std::tie(name, align) = s.split(','); 215 if (name.empty() || align.empty()) { 216 error("/aligncomm: invalid argument: " + s); 217 return; 218 } 219 int v; 220 if (align.getAsInteger(0, v)) { 221 error("/aligncomm: invalid argument: " + s); 222 return; 223 } 224 config->alignComm[std::string(name)] = 225 std::max(config->alignComm[std::string(name)], 1 << v); 226 } 227 228 // Parses /functionpadmin option argument. 229 void parseFunctionPadMin(llvm::opt::Arg *a, llvm::COFF::MachineTypes machine) { 230 StringRef arg = a->getNumValues() ? a->getValue() : ""; 231 if (!arg.empty()) { 232 // Optional padding in bytes is given. 233 if (arg.getAsInteger(0, config->functionPadMin)) 234 error("/functionpadmin: invalid argument: " + arg); 235 return; 236 } 237 // No optional argument given. 238 // Set default padding based on machine, similar to link.exe. 239 // There is no default padding for ARM platforms. 240 if (machine == I386) { 241 config->functionPadMin = 5; 242 } else if (machine == AMD64) { 243 config->functionPadMin = 6; 244 } else { 245 error("/functionpadmin: invalid argument for this machine: " + arg); 246 } 247 } 248 249 // Parses a string in the form of "EMBED[,=<integer>]|NO". 250 // Results are directly written to Config. 251 void parseManifest(StringRef arg) { 252 if (arg.equals_lower("no")) { 253 config->manifest = Configuration::No; 254 return; 255 } 256 if (!arg.startswith_lower("embed")) 257 fatal("invalid option " + arg); 258 config->manifest = Configuration::Embed; 259 arg = arg.substr(strlen("embed")); 260 if (arg.empty()) 261 return; 262 if (!arg.startswith_lower(",id=")) 263 fatal("invalid option " + arg); 264 arg = arg.substr(strlen(",id=")); 265 if (arg.getAsInteger(0, config->manifestID)) 266 fatal("invalid option " + arg); 267 } 268 269 // Parses a string in the form of "level=<string>|uiAccess=<string>|NO". 270 // Results are directly written to Config. 271 void parseManifestUAC(StringRef arg) { 272 if (arg.equals_lower("no")) { 273 config->manifestUAC = false; 274 return; 275 } 276 for (;;) { 277 arg = arg.ltrim(); 278 if (arg.empty()) 279 return; 280 if (arg.startswith_lower("level=")) { 281 arg = arg.substr(strlen("level=")); 282 std::tie(config->manifestLevel, arg) = arg.split(" "); 283 continue; 284 } 285 if (arg.startswith_lower("uiaccess=")) { 286 arg = arg.substr(strlen("uiaccess=")); 287 std::tie(config->manifestUIAccess, arg) = arg.split(" "); 288 continue; 289 } 290 fatal("invalid option " + arg); 291 } 292 } 293 294 // Parses a string in the form of "cd|net[,(cd|net)]*" 295 // Results are directly written to Config. 296 void parseSwaprun(StringRef arg) { 297 do { 298 StringRef swaprun, newArg; 299 std::tie(swaprun, newArg) = arg.split(','); 300 if (swaprun.equals_lower("cd")) 301 config->swaprunCD = true; 302 else if (swaprun.equals_lower("net")) 303 config->swaprunNet = true; 304 else if (swaprun.empty()) 305 error("/swaprun: missing argument"); 306 else 307 error("/swaprun: invalid argument: " + swaprun); 308 // To catch trailing commas, e.g. `/spawrun:cd,` 309 if (newArg.empty() && arg.endswith(",")) 310 error("/swaprun: missing argument"); 311 arg = newArg; 312 } while (!arg.empty()); 313 } 314 315 // An RAII temporary file class that automatically removes a temporary file. 316 namespace { 317 class TemporaryFile { 318 public: 319 TemporaryFile(StringRef prefix, StringRef extn, StringRef contents = "") { 320 SmallString<128> s; 321 if (auto ec = sys::fs::createTemporaryFile("lld-" + prefix, extn, s)) 322 fatal("cannot create a temporary file: " + ec.message()); 323 path = std::string(s.str()); 324 325 if (!contents.empty()) { 326 std::error_code ec; 327 raw_fd_ostream os(path, ec, sys::fs::OF_None); 328 if (ec) 329 fatal("failed to open " + path + ": " + ec.message()); 330 os << contents; 331 } 332 } 333 334 TemporaryFile(TemporaryFile &&obj) { 335 std::swap(path, obj.path); 336 } 337 338 ~TemporaryFile() { 339 if (path.empty()) 340 return; 341 if (sys::fs::remove(path)) 342 fatal("failed to remove " + path); 343 } 344 345 // Returns a memory buffer of this temporary file. 346 // Note that this function does not leave the file open, 347 // so it is safe to remove the file immediately after this function 348 // is called (you cannot remove an opened file on Windows.) 349 std::unique_ptr<MemoryBuffer> getMemoryBuffer() { 350 // IsVolatile=true forces MemoryBuffer to not use mmap(). 351 return CHECK(MemoryBuffer::getFile(path, /*FileSize=*/-1, 352 /*RequiresNullTerminator=*/false, 353 /*IsVolatile=*/true), 354 "could not open " + path); 355 } 356 357 std::string path; 358 }; 359 } 360 361 static std::string createDefaultXml() { 362 std::string ret; 363 raw_string_ostream os(ret); 364 365 // Emit the XML. Note that we do *not* verify that the XML attributes are 366 // syntactically correct. This is intentional for link.exe compatibility. 367 os << "<?xml version=\"1.0\" standalone=\"yes\"?>\n" 368 << "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\"\n" 369 << " manifestVersion=\"1.0\">\n"; 370 if (config->manifestUAC) { 371 os << " <trustInfo>\n" 372 << " <security>\n" 373 << " <requestedPrivileges>\n" 374 << " <requestedExecutionLevel level=" << config->manifestLevel 375 << " uiAccess=" << config->manifestUIAccess << "/>\n" 376 << " </requestedPrivileges>\n" 377 << " </security>\n" 378 << " </trustInfo>\n"; 379 } 380 if (!config->manifestDependency.empty()) { 381 os << " <dependency>\n" 382 << " <dependentAssembly>\n" 383 << " <assemblyIdentity " << config->manifestDependency << " />\n" 384 << " </dependentAssembly>\n" 385 << " </dependency>\n"; 386 } 387 os << "</assembly>\n"; 388 return os.str(); 389 } 390 391 static std::string createManifestXmlWithInternalMt(StringRef defaultXml) { 392 std::unique_ptr<MemoryBuffer> defaultXmlCopy = 393 MemoryBuffer::getMemBufferCopy(defaultXml); 394 395 windows_manifest::WindowsManifestMerger merger; 396 if (auto e = merger.merge(*defaultXmlCopy.get())) 397 fatal("internal manifest tool failed on default xml: " + 398 toString(std::move(e))); 399 400 for (StringRef filename : config->manifestInput) { 401 std::unique_ptr<MemoryBuffer> manifest = 402 check(MemoryBuffer::getFile(filename)); 403 if (auto e = merger.merge(*manifest.get())) 404 fatal("internal manifest tool failed on file " + filename + ": " + 405 toString(std::move(e))); 406 } 407 408 return std::string(merger.getMergedManifest().get()->getBuffer()); 409 } 410 411 static std::string createManifestXmlWithExternalMt(StringRef defaultXml) { 412 // Create the default manifest file as a temporary file. 413 TemporaryFile Default("defaultxml", "manifest"); 414 std::error_code ec; 415 raw_fd_ostream os(Default.path, ec, sys::fs::OF_Text); 416 if (ec) 417 fatal("failed to open " + Default.path + ": " + ec.message()); 418 os << defaultXml; 419 os.close(); 420 421 // Merge user-supplied manifests if they are given. Since libxml2 is not 422 // enabled, we must shell out to Microsoft's mt.exe tool. 423 TemporaryFile user("user", "manifest"); 424 425 Executor e("mt.exe"); 426 e.add("/manifest"); 427 e.add(Default.path); 428 for (StringRef filename : config->manifestInput) { 429 e.add("/manifest"); 430 e.add(filename); 431 } 432 e.add("/nologo"); 433 e.add("/out:" + StringRef(user.path)); 434 e.run(); 435 436 return std::string( 437 CHECK(MemoryBuffer::getFile(user.path), "could not open " + user.path) 438 .get() 439 ->getBuffer()); 440 } 441 442 static std::string createManifestXml() { 443 std::string defaultXml = createDefaultXml(); 444 if (config->manifestInput.empty()) 445 return defaultXml; 446 447 if (windows_manifest::isAvailable()) 448 return createManifestXmlWithInternalMt(defaultXml); 449 450 return createManifestXmlWithExternalMt(defaultXml); 451 } 452 453 static std::unique_ptr<WritableMemoryBuffer> 454 createMemoryBufferForManifestRes(size_t manifestSize) { 455 size_t resSize = alignTo( 456 object::WIN_RES_MAGIC_SIZE + object::WIN_RES_NULL_ENTRY_SIZE + 457 sizeof(object::WinResHeaderPrefix) + sizeof(object::WinResIDs) + 458 sizeof(object::WinResHeaderSuffix) + manifestSize, 459 object::WIN_RES_DATA_ALIGNMENT); 460 return WritableMemoryBuffer::getNewMemBuffer(resSize, config->outputFile + 461 ".manifest.res"); 462 } 463 464 static void writeResFileHeader(char *&buf) { 465 memcpy(buf, COFF::WinResMagic, sizeof(COFF::WinResMagic)); 466 buf += sizeof(COFF::WinResMagic); 467 memset(buf, 0, object::WIN_RES_NULL_ENTRY_SIZE); 468 buf += object::WIN_RES_NULL_ENTRY_SIZE; 469 } 470 471 static void writeResEntryHeader(char *&buf, size_t manifestSize) { 472 // Write the prefix. 473 auto *prefix = reinterpret_cast<object::WinResHeaderPrefix *>(buf); 474 prefix->DataSize = manifestSize; 475 prefix->HeaderSize = sizeof(object::WinResHeaderPrefix) + 476 sizeof(object::WinResIDs) + 477 sizeof(object::WinResHeaderSuffix); 478 buf += sizeof(object::WinResHeaderPrefix); 479 480 // Write the Type/Name IDs. 481 auto *iDs = reinterpret_cast<object::WinResIDs *>(buf); 482 iDs->setType(RT_MANIFEST); 483 iDs->setName(config->manifestID); 484 buf += sizeof(object::WinResIDs); 485 486 // Write the suffix. 487 auto *suffix = reinterpret_cast<object::WinResHeaderSuffix *>(buf); 488 suffix->DataVersion = 0; 489 suffix->MemoryFlags = object::WIN_RES_PURE_MOVEABLE; 490 suffix->Language = SUBLANG_ENGLISH_US; 491 suffix->Version = 0; 492 suffix->Characteristics = 0; 493 buf += sizeof(object::WinResHeaderSuffix); 494 } 495 496 // Create a resource file containing a manifest XML. 497 std::unique_ptr<MemoryBuffer> createManifestRes() { 498 std::string manifest = createManifestXml(); 499 500 std::unique_ptr<WritableMemoryBuffer> res = 501 createMemoryBufferForManifestRes(manifest.size()); 502 503 char *buf = res->getBufferStart(); 504 writeResFileHeader(buf); 505 writeResEntryHeader(buf, manifest.size()); 506 507 // Copy the manifest data into the .res file. 508 std::copy(manifest.begin(), manifest.end(), buf); 509 return std::move(res); 510 } 511 512 void createSideBySideManifest() { 513 std::string path = std::string(config->manifestFile); 514 if (path == "") 515 path = config->outputFile + ".manifest"; 516 std::error_code ec; 517 raw_fd_ostream out(path, ec, sys::fs::OF_Text); 518 if (ec) 519 fatal("failed to create manifest: " + ec.message()); 520 out << createManifestXml(); 521 } 522 523 // Parse a string in the form of 524 // "<name>[=<internalname>][,@ordinal[,NONAME]][,DATA][,PRIVATE]" 525 // or "<name>=<dllname>.<name>". 526 // Used for parsing /export arguments. 527 Export parseExport(StringRef arg) { 528 Export e; 529 StringRef rest; 530 std::tie(e.name, rest) = arg.split(","); 531 if (e.name.empty()) 532 goto err; 533 534 if (e.name.contains('=')) { 535 StringRef x, y; 536 std::tie(x, y) = e.name.split("="); 537 538 // If "<name>=<dllname>.<name>". 539 if (y.contains(".")) { 540 e.name = x; 541 e.forwardTo = y; 542 return e; 543 } 544 545 e.extName = x; 546 e.name = y; 547 if (e.name.empty()) 548 goto err; 549 } 550 551 // If "<name>=<internalname>[,@ordinal[,NONAME]][,DATA][,PRIVATE]" 552 while (!rest.empty()) { 553 StringRef tok; 554 std::tie(tok, rest) = rest.split(","); 555 if (tok.equals_lower("noname")) { 556 if (e.ordinal == 0) 557 goto err; 558 e.noname = true; 559 continue; 560 } 561 if (tok.equals_lower("data")) { 562 e.data = true; 563 continue; 564 } 565 if (tok.equals_lower("constant")) { 566 e.constant = true; 567 continue; 568 } 569 if (tok.equals_lower("private")) { 570 e.isPrivate = true; 571 continue; 572 } 573 if (tok.startswith("@")) { 574 int32_t ord; 575 if (tok.substr(1).getAsInteger(0, ord)) 576 goto err; 577 if (ord <= 0 || 65535 < ord) 578 goto err; 579 e.ordinal = ord; 580 continue; 581 } 582 goto err; 583 } 584 return e; 585 586 err: 587 fatal("invalid /export: " + arg); 588 } 589 590 static StringRef undecorate(StringRef sym) { 591 if (config->machine != I386) 592 return sym; 593 // In MSVC mode, a fully decorated stdcall function is exported 594 // as-is with the leading underscore (with type IMPORT_NAME). 595 // In MinGW mode, a decorated stdcall function gets the underscore 596 // removed, just like normal cdecl functions. 597 if (sym.startswith("_") && sym.contains('@') && !config->mingw) 598 return sym; 599 return sym.startswith("_") ? sym.substr(1) : sym; 600 } 601 602 // Convert stdcall/fastcall style symbols into unsuffixed symbols, 603 // with or without a leading underscore. (MinGW specific.) 604 static StringRef killAt(StringRef sym, bool prefix) { 605 if (sym.empty()) 606 return sym; 607 // Strip any trailing stdcall suffix 608 sym = sym.substr(0, sym.find('@', 1)); 609 if (!sym.startswith("@")) { 610 if (prefix && !sym.startswith("_")) 611 return saver.save("_" + sym); 612 return sym; 613 } 614 // For fastcall, remove the leading @ and replace it with an 615 // underscore, if prefixes are used. 616 sym = sym.substr(1); 617 if (prefix) 618 sym = saver.save("_" + sym); 619 return sym; 620 } 621 622 // Performs error checking on all /export arguments. 623 // It also sets ordinals. 624 void fixupExports() { 625 // Symbol ordinals must be unique. 626 std::set<uint16_t> ords; 627 for (Export &e : config->exports) { 628 if (e.ordinal == 0) 629 continue; 630 if (!ords.insert(e.ordinal).second) 631 fatal("duplicate export ordinal: " + e.name); 632 } 633 634 for (Export &e : config->exports) { 635 if (!e.forwardTo.empty()) { 636 e.exportName = undecorate(e.name); 637 } else { 638 e.exportName = undecorate(e.extName.empty() ? e.name : e.extName); 639 } 640 } 641 642 if (config->killAt && config->machine == I386) { 643 for (Export &e : config->exports) { 644 e.name = killAt(e.name, true); 645 e.exportName = killAt(e.exportName, false); 646 e.extName = killAt(e.extName, true); 647 e.symbolName = killAt(e.symbolName, true); 648 } 649 } 650 651 // Uniquefy by name. 652 DenseMap<StringRef, Export *> map(config->exports.size()); 653 std::vector<Export> v; 654 for (Export &e : config->exports) { 655 auto pair = map.insert(std::make_pair(e.exportName, &e)); 656 bool inserted = pair.second; 657 if (inserted) { 658 v.push_back(e); 659 continue; 660 } 661 Export *existing = pair.first->second; 662 if (e == *existing || e.name != existing->name) 663 continue; 664 warn("duplicate /export option: " + e.name); 665 } 666 config->exports = std::move(v); 667 668 // Sort by name. 669 std::sort(config->exports.begin(), config->exports.end(), 670 [](const Export &a, const Export &b) { 671 return a.exportName < b.exportName; 672 }); 673 } 674 675 void assignExportOrdinals() { 676 // Assign unique ordinals if default (= 0). 677 uint32_t max = 0; 678 for (Export &e : config->exports) 679 max = std::max(max, (uint32_t)e.ordinal); 680 for (Export &e : config->exports) 681 if (e.ordinal == 0) 682 e.ordinal = ++max; 683 if (max > std::numeric_limits<uint16_t>::max()) 684 fatal("too many exported symbols (max " + 685 Twine(std::numeric_limits<uint16_t>::max()) + ")"); 686 } 687 688 // Parses a string in the form of "key=value" and check 689 // if value matches previous values for the same key. 690 void checkFailIfMismatch(StringRef arg, InputFile *source) { 691 StringRef k, v; 692 std::tie(k, v) = arg.split('='); 693 if (k.empty() || v.empty()) 694 fatal("/failifmismatch: invalid argument: " + arg); 695 std::pair<StringRef, InputFile *> existing = config->mustMatch[k]; 696 if (!existing.first.empty() && v != existing.first) { 697 std::string sourceStr = source ? toString(source) : "cmd-line"; 698 std::string existingStr = 699 existing.second ? toString(existing.second) : "cmd-line"; 700 fatal("/failifmismatch: mismatch detected for '" + k + "':\n>>> " + 701 existingStr + " has value " + existing.first + "\n>>> " + sourceStr + 702 " has value " + v); 703 } 704 config->mustMatch[k] = {v, source}; 705 } 706 707 // Convert Windows resource files (.res files) to a .obj file. 708 // Does what cvtres.exe does, but in-process and cross-platform. 709 MemoryBufferRef convertResToCOFF(ArrayRef<MemoryBufferRef> mbs, 710 ArrayRef<ObjFile *> objs) { 711 object::WindowsResourceParser parser(/* MinGW */ config->mingw); 712 713 std::vector<std::string> duplicates; 714 for (MemoryBufferRef mb : mbs) { 715 std::unique_ptr<object::Binary> bin = check(object::createBinary(mb)); 716 object::WindowsResource *rf = dyn_cast<object::WindowsResource>(bin.get()); 717 if (!rf) 718 fatal("cannot compile non-resource file as resource"); 719 720 if (auto ec = parser.parse(rf, duplicates)) 721 fatal(toString(std::move(ec))); 722 } 723 724 // Note: This processes all .res files before all objs. Ideally they'd be 725 // handled in the same order they were linked (to keep the right one, if 726 // there are duplicates that are tolerated due to forceMultipleRes). 727 for (ObjFile *f : objs) { 728 object::ResourceSectionRef rsf; 729 if (auto ec = rsf.load(f->getCOFFObj())) 730 fatal(toString(f) + ": " + toString(std::move(ec))); 731 732 if (auto ec = parser.parse(rsf, f->getName(), duplicates)) 733 fatal(toString(std::move(ec))); 734 } 735 736 if (config->mingw) 737 parser.cleanUpManifests(duplicates); 738 739 for (const auto &dupeDiag : duplicates) 740 if (config->forceMultipleRes) 741 warn(dupeDiag); 742 else 743 error(dupeDiag); 744 745 Expected<std::unique_ptr<MemoryBuffer>> e = 746 llvm::object::writeWindowsResourceCOFF(config->machine, parser, 747 config->timestamp); 748 if (!e) 749 fatal("failed to write .res to COFF: " + toString(e.takeError())); 750 751 MemoryBufferRef mbref = **e; 752 make<std::unique_ptr<MemoryBuffer>>(std::move(*e)); // take ownership 753 return mbref; 754 } 755 756 // Create OptTable 757 758 // Create prefix string literals used in Options.td 759 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; 760 #include "Options.inc" 761 #undef PREFIX 762 763 // Create table mapping all options defined in Options.td 764 static const llvm::opt::OptTable::Info infoTable[] = { 765 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12) \ 766 {X1, X2, X10, X11, OPT_##ID, llvm::opt::Option::KIND##Class, \ 767 X9, X8, OPT_##GROUP, OPT_##ALIAS, X7, X12}, 768 #include "Options.inc" 769 #undef OPTION 770 }; 771 772 COFFOptTable::COFFOptTable() : OptTable(infoTable, true) {} 773 774 COFFOptTable optTable; 775 776 // Set color diagnostics according to --color-diagnostics={auto,always,never} 777 // or --no-color-diagnostics flags. 778 static void handleColorDiagnostics(opt::InputArgList &args) { 779 auto *arg = args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq, 780 OPT_no_color_diagnostics); 781 if (!arg) 782 return; 783 if (arg->getOption().getID() == OPT_color_diagnostics) { 784 lld::errs().enable_colors(true); 785 } else if (arg->getOption().getID() == OPT_no_color_diagnostics) { 786 lld::errs().enable_colors(false); 787 } else { 788 StringRef s = arg->getValue(); 789 if (s == "always") 790 lld::errs().enable_colors(true); 791 else if (s == "never") 792 lld::errs().enable_colors(false); 793 else if (s != "auto") 794 error("unknown option: --color-diagnostics=" + s); 795 } 796 } 797 798 static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &args) { 799 if (auto *arg = args.getLastArg(OPT_rsp_quoting)) { 800 StringRef s = arg->getValue(); 801 if (s != "windows" && s != "posix") 802 error("invalid response file quoting: " + s); 803 if (s == "windows") 804 return cl::TokenizeWindowsCommandLine; 805 return cl::TokenizeGNUCommandLine; 806 } 807 // The COFF linker always defaults to Windows quoting. 808 return cl::TokenizeWindowsCommandLine; 809 } 810 811 // Parses a given list of options. 812 opt::InputArgList ArgParser::parse(ArrayRef<const char *> argv) { 813 // Make InputArgList from string vectors. 814 unsigned missingIndex; 815 unsigned missingCount; 816 817 // We need to get the quoting style for response files before parsing all 818 // options so we parse here before and ignore all the options but 819 // --rsp-quoting and /lldignoreenv. 820 // (This means --rsp-quoting can't be added through %LINK%.) 821 opt::InputArgList args = optTable.ParseArgs(argv, missingIndex, missingCount); 822 823 // Expand response files (arguments in the form of @<filename>) and insert 824 // flags from %LINK% and %_LINK_%, and then parse the argument again. 825 SmallVector<const char *, 256> expandedArgv(argv.data(), 826 argv.data() + argv.size()); 827 if (!args.hasArg(OPT_lldignoreenv)) 828 addLINK(expandedArgv); 829 cl::ExpandResponseFiles(saver, getQuotingStyle(args), expandedArgv); 830 args = optTable.ParseArgs(makeArrayRef(expandedArgv).drop_front(), 831 missingIndex, missingCount); 832 833 // Print the real command line if response files are expanded. 834 if (args.hasArg(OPT_verbose) && argv.size() != expandedArgv.size()) { 835 std::string msg = "Command line:"; 836 for (const char *s : expandedArgv) 837 msg += " " + std::string(s); 838 message(msg); 839 } 840 841 // Save the command line after response file expansion so we can write it to 842 // the PDB if necessary. 843 config->argv = {expandedArgv.begin(), expandedArgv.end()}; 844 845 // Handle /WX early since it converts missing argument warnings to errors. 846 errorHandler().fatalWarnings = args.hasFlag(OPT_WX, OPT_WX_no, false); 847 848 if (missingCount) 849 fatal(Twine(args.getArgString(missingIndex)) + ": missing argument"); 850 851 handleColorDiagnostics(args); 852 853 for (auto *arg : args.filtered(OPT_UNKNOWN)) { 854 std::string nearest; 855 if (optTable.findNearest(arg->getAsString(args), nearest) > 1) 856 warn("ignoring unknown argument '" + arg->getAsString(args) + "'"); 857 else 858 warn("ignoring unknown argument '" + arg->getAsString(args) + 859 "', did you mean '" + nearest + "'"); 860 } 861 862 if (args.hasArg(OPT_lib)) 863 warn("ignoring /lib since it's not the first argument"); 864 865 return args; 866 } 867 868 // Tokenizes and parses a given string as command line in .drective section. 869 ParsedDirectives ArgParser::parseDirectives(StringRef s) { 870 ParsedDirectives result; 871 SmallVector<const char *, 16> rest; 872 873 // Handle /EXPORT and /INCLUDE in a fast path. These directives can appear for 874 // potentially every symbol in the object, so they must be handled quickly. 875 SmallVector<StringRef, 16> tokens; 876 cl::TokenizeWindowsCommandLineNoCopy(s, saver, tokens); 877 for (StringRef tok : tokens) { 878 if (tok.startswith_lower("/export:") || tok.startswith_lower("-export:")) 879 result.exports.push_back(tok.substr(strlen("/export:"))); 880 else if (tok.startswith_lower("/include:") || 881 tok.startswith_lower("-include:")) 882 result.includes.push_back(tok.substr(strlen("/include:"))); 883 else { 884 // Save non-null-terminated strings to make proper C strings. 885 bool HasNul = tok.data()[tok.size()] == '\0'; 886 rest.push_back(HasNul ? tok.data() : saver.save(tok).data()); 887 } 888 } 889 890 // Make InputArgList from unparsed string vectors. 891 unsigned missingIndex; 892 unsigned missingCount; 893 894 result.args = optTable.ParseArgs(rest, missingIndex, missingCount); 895 896 if (missingCount) 897 fatal(Twine(result.args.getArgString(missingIndex)) + ": missing argument"); 898 for (auto *arg : result.args.filtered(OPT_UNKNOWN)) 899 warn("ignoring unknown argument: " + arg->getAsString(result.args)); 900 return result; 901 } 902 903 // link.exe has an interesting feature. If LINK or _LINK_ environment 904 // variables exist, their contents are handled as command line strings. 905 // So you can pass extra arguments using them. 906 void ArgParser::addLINK(SmallVector<const char *, 256> &argv) { 907 // Concatenate LINK env and command line arguments, and then parse them. 908 if (Optional<std::string> s = Process::GetEnv("LINK")) { 909 std::vector<const char *> v = tokenize(*s); 910 argv.insert(std::next(argv.begin()), v.begin(), v.end()); 911 } 912 if (Optional<std::string> s = Process::GetEnv("_LINK_")) { 913 std::vector<const char *> v = tokenize(*s); 914 argv.insert(std::next(argv.begin()), v.begin(), v.end()); 915 } 916 } 917 918 std::vector<const char *> ArgParser::tokenize(StringRef s) { 919 SmallVector<const char *, 16> tokens; 920 cl::TokenizeWindowsCommandLine(s, saver, tokens); 921 return std::vector<const char *>(tokens.begin(), tokens.end()); 922 } 923 924 void printHelp(const char *argv0) { 925 optTable.PrintHelp(lld::outs(), 926 (std::string(argv0) + " [options] file...").c_str(), 927 "LLVM Linker", false); 928 } 929 930 } // namespace coff 931 } // namespace lld 932