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/STLExtras.h" 22 #include "llvm/ADT/StringSwitch.h" 23 #include "llvm/BinaryFormat/COFF.h" 24 #include "llvm/Object/COFF.h" 25 #include "llvm/Object/WindowsResource.h" 26 #include "llvm/Option/Arg.h" 27 #include "llvm/Option/ArgList.h" 28 #include "llvm/Option/Option.h" 29 #include "llvm/Support/CommandLine.h" 30 #include "llvm/Support/FileUtilities.h" 31 #include "llvm/Support/MathExtras.h" 32 #include "llvm/Support/Process.h" 33 #include "llvm/Support/Program.h" 34 #include "llvm/Support/raw_ostream.h" 35 #include "llvm/WindowsManifest/WindowsManifestMerger.h" 36 #include <limits> 37 #include <memory> 38 39 using namespace llvm::COFF; 40 using namespace llvm; 41 using llvm::sys::Process; 42 43 namespace lld { 44 namespace coff { 45 namespace { 46 47 const uint16_t SUBLANG_ENGLISH_US = 0x0409; 48 const uint16_t RT_MANIFEST = 24; 49 50 class Executor { 51 public: 52 explicit Executor(StringRef s) : prog(saver().save(s)) {} 53 void add(StringRef s) { args.push_back(saver().save(s)); } 54 void add(std::string &s) { args.push_back(saver().save(s)); } 55 void add(Twine s) { args.push_back(saver().save(s)); } 56 void add(const char *s) { args.push_back(saver().save(s)); } 57 58 void run() { 59 ErrorOr<std::string> exeOrErr = sys::findProgramByName(prog); 60 if (auto ec = exeOrErr.getError()) 61 fatal("unable to find " + prog + " in PATH: " + ec.message()); 62 StringRef exe = saver().save(*exeOrErr); 63 args.insert(args.begin(), exe); 64 65 if (sys::ExecuteAndWait(args[0], args) != 0) 66 fatal("ExecuteAndWait failed: " + 67 llvm::join(args.begin(), args.end(), " ")); 68 } 69 70 private: 71 StringRef prog; 72 std::vector<StringRef> args; 73 }; 74 75 } // anonymous namespace 76 77 // Parses a string in the form of "<integer>[,<integer>]". 78 void parseNumbers(StringRef arg, uint64_t *addr, uint64_t *size) { 79 StringRef s1, s2; 80 std::tie(s1, s2) = arg.split(','); 81 if (s1.getAsInteger(0, *addr)) 82 fatal("invalid number: " + s1); 83 if (size && !s2.empty() && s2.getAsInteger(0, *size)) 84 fatal("invalid number: " + s2); 85 } 86 87 // Parses a string in the form of "<integer>[.<integer>]". 88 // If second number is not present, Minor is set to 0. 89 void parseVersion(StringRef arg, uint32_t *major, uint32_t *minor) { 90 StringRef s1, s2; 91 std::tie(s1, s2) = arg.split('.'); 92 if (s1.getAsInteger(10, *major)) 93 fatal("invalid number: " + s1); 94 *minor = 0; 95 if (!s2.empty() && s2.getAsInteger(10, *minor)) 96 fatal("invalid number: " + s2); 97 } 98 99 void parseGuard(StringRef fullArg) { 100 SmallVector<StringRef, 1> splitArgs; 101 fullArg.split(splitArgs, ","); 102 for (StringRef arg : splitArgs) { 103 if (arg.equals_insensitive("no")) 104 config->guardCF = GuardCFLevel::Off; 105 else if (arg.equals_insensitive("nolongjmp")) 106 config->guardCF &= ~GuardCFLevel::LongJmp; 107 else if (arg.equals_insensitive("noehcont")) 108 config->guardCF &= ~GuardCFLevel::EHCont; 109 else if (arg.equals_insensitive("cf")) 110 config->guardCF = GuardCFLevel::CF; 111 else if (arg.equals_insensitive("longjmp")) 112 config->guardCF |= GuardCFLevel::CF | GuardCFLevel::LongJmp; 113 else if (arg.equals_insensitive("ehcont")) 114 config->guardCF |= GuardCFLevel::CF | GuardCFLevel::EHCont; 115 else 116 fatal("invalid argument to /guard: " + arg); 117 } 118 } 119 120 // Parses a string in the form of "<subsystem>[,<integer>[.<integer>]]". 121 void parseSubsystem(StringRef arg, WindowsSubsystem *sys, uint32_t *major, 122 uint32_t *minor, bool *gotVersion) { 123 StringRef sysStr, ver; 124 std::tie(sysStr, ver) = arg.split(','); 125 std::string sysStrLower = sysStr.lower(); 126 *sys = StringSwitch<WindowsSubsystem>(sysStrLower) 127 .Case("boot_application", IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION) 128 .Case("console", IMAGE_SUBSYSTEM_WINDOWS_CUI) 129 .Case("default", IMAGE_SUBSYSTEM_UNKNOWN) 130 .Case("efi_application", IMAGE_SUBSYSTEM_EFI_APPLICATION) 131 .Case("efi_boot_service_driver", IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) 132 .Case("efi_rom", IMAGE_SUBSYSTEM_EFI_ROM) 133 .Case("efi_runtime_driver", IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) 134 .Case("native", IMAGE_SUBSYSTEM_NATIVE) 135 .Case("posix", IMAGE_SUBSYSTEM_POSIX_CUI) 136 .Case("windows", IMAGE_SUBSYSTEM_WINDOWS_GUI) 137 .Default(IMAGE_SUBSYSTEM_UNKNOWN); 138 if (*sys == IMAGE_SUBSYSTEM_UNKNOWN && sysStrLower != "default") 139 fatal("unknown subsystem: " + sysStr); 140 if (!ver.empty()) 141 parseVersion(ver, major, minor); 142 if (gotVersion) 143 *gotVersion = !ver.empty(); 144 } 145 146 // Parse a string of the form of "<from>=<to>". 147 // Results are directly written to Config. 148 void parseAlternateName(StringRef s) { 149 StringRef from, to; 150 std::tie(from, to) = s.split('='); 151 if (from.empty() || to.empty()) 152 fatal("/alternatename: invalid argument: " + s); 153 auto it = config->alternateNames.find(from); 154 if (it != config->alternateNames.end() && it->second != to) 155 fatal("/alternatename: conflicts: " + s); 156 config->alternateNames.insert(it, std::make_pair(from, to)); 157 } 158 159 // Parse a string of the form of "<from>=<to>". 160 // Results are directly written to Config. 161 void parseMerge(StringRef s) { 162 StringRef from, to; 163 std::tie(from, to) = s.split('='); 164 if (from.empty() || to.empty()) 165 fatal("/merge: invalid argument: " + s); 166 if (from == ".rsrc" || to == ".rsrc") 167 fatal("/merge: cannot merge '.rsrc' with any section"); 168 if (from == ".reloc" || to == ".reloc") 169 fatal("/merge: cannot merge '.reloc' with any section"); 170 auto pair = config->merge.insert(std::make_pair(from, to)); 171 bool inserted = pair.second; 172 if (!inserted) { 173 StringRef existing = pair.first->second; 174 if (existing != to) 175 warn(s + ": already merged into " + existing); 176 } 177 } 178 179 void parsePDBPageSize(StringRef s) { 180 int v; 181 if (s.getAsInteger(0, v)) { 182 error("/pdbpagesize: invalid argument: " + s); 183 return; 184 } 185 if (v != 4096 && v != 8192 && v != 16384 && v != 32768) { 186 error("/pdbpagesize: invalid argument: " + s); 187 return; 188 } 189 190 config->pdbPageSize = v; 191 } 192 193 static uint32_t parseSectionAttributes(StringRef s) { 194 uint32_t ret = 0; 195 for (char c : s.lower()) { 196 switch (c) { 197 case 'd': 198 ret |= IMAGE_SCN_MEM_DISCARDABLE; 199 break; 200 case 'e': 201 ret |= IMAGE_SCN_MEM_EXECUTE; 202 break; 203 case 'k': 204 ret |= IMAGE_SCN_MEM_NOT_CACHED; 205 break; 206 case 'p': 207 ret |= IMAGE_SCN_MEM_NOT_PAGED; 208 break; 209 case 'r': 210 ret |= IMAGE_SCN_MEM_READ; 211 break; 212 case 's': 213 ret |= IMAGE_SCN_MEM_SHARED; 214 break; 215 case 'w': 216 ret |= IMAGE_SCN_MEM_WRITE; 217 break; 218 default: 219 fatal("/section: invalid argument: " + s); 220 } 221 } 222 return ret; 223 } 224 225 // Parses /section option argument. 226 void parseSection(StringRef s) { 227 StringRef name, attrs; 228 std::tie(name, attrs) = s.split(','); 229 if (name.empty() || attrs.empty()) 230 fatal("/section: invalid argument: " + s); 231 config->section[name] = parseSectionAttributes(attrs); 232 } 233 234 // Parses /aligncomm option argument. 235 void parseAligncomm(StringRef s) { 236 StringRef name, align; 237 std::tie(name, align) = s.split(','); 238 if (name.empty() || align.empty()) { 239 error("/aligncomm: invalid argument: " + s); 240 return; 241 } 242 int v; 243 if (align.getAsInteger(0, v)) { 244 error("/aligncomm: invalid argument: " + s); 245 return; 246 } 247 config->alignComm[std::string(name)] = 248 std::max(config->alignComm[std::string(name)], 1 << v); 249 } 250 251 // Parses /functionpadmin option argument. 252 void parseFunctionPadMin(llvm::opt::Arg *a, llvm::COFF::MachineTypes machine) { 253 StringRef arg = a->getNumValues() ? a->getValue() : ""; 254 if (!arg.empty()) { 255 // Optional padding in bytes is given. 256 if (arg.getAsInteger(0, config->functionPadMin)) 257 error("/functionpadmin: invalid argument: " + arg); 258 return; 259 } 260 // No optional argument given. 261 // Set default padding based on machine, similar to link.exe. 262 // There is no default padding for ARM platforms. 263 if (machine == I386) { 264 config->functionPadMin = 5; 265 } else if (machine == AMD64) { 266 config->functionPadMin = 6; 267 } else { 268 error("/functionpadmin: invalid argument for this machine: " + arg); 269 } 270 } 271 272 // Parses a string in the form of "EMBED[,=<integer>]|NO". 273 // Results are directly written to Config. 274 void parseManifest(StringRef arg) { 275 if (arg.equals_insensitive("no")) { 276 config->manifest = Configuration::No; 277 return; 278 } 279 if (!arg.startswith_insensitive("embed")) 280 fatal("invalid option " + arg); 281 config->manifest = Configuration::Embed; 282 arg = arg.substr(strlen("embed")); 283 if (arg.empty()) 284 return; 285 if (!arg.startswith_insensitive(",id=")) 286 fatal("invalid option " + arg); 287 arg = arg.substr(strlen(",id=")); 288 if (arg.getAsInteger(0, config->manifestID)) 289 fatal("invalid option " + arg); 290 } 291 292 // Parses a string in the form of "level=<string>|uiAccess=<string>|NO". 293 // Results are directly written to Config. 294 void parseManifestUAC(StringRef arg) { 295 if (arg.equals_insensitive("no")) { 296 config->manifestUAC = false; 297 return; 298 } 299 for (;;) { 300 arg = arg.ltrim(); 301 if (arg.empty()) 302 return; 303 if (arg.startswith_insensitive("level=")) { 304 arg = arg.substr(strlen("level=")); 305 std::tie(config->manifestLevel, arg) = arg.split(" "); 306 continue; 307 } 308 if (arg.startswith_insensitive("uiaccess=")) { 309 arg = arg.substr(strlen("uiaccess=")); 310 std::tie(config->manifestUIAccess, arg) = arg.split(" "); 311 continue; 312 } 313 fatal("invalid option " + arg); 314 } 315 } 316 317 // Parses a string in the form of "cd|net[,(cd|net)]*" 318 // Results are directly written to Config. 319 void parseSwaprun(StringRef arg) { 320 do { 321 StringRef swaprun, newArg; 322 std::tie(swaprun, newArg) = arg.split(','); 323 if (swaprun.equals_insensitive("cd")) 324 config->swaprunCD = true; 325 else if (swaprun.equals_insensitive("net")) 326 config->swaprunNet = true; 327 else if (swaprun.empty()) 328 error("/swaprun: missing argument"); 329 else 330 error("/swaprun: invalid argument: " + swaprun); 331 // To catch trailing commas, e.g. `/spawrun:cd,` 332 if (newArg.empty() && arg.endswith(",")) 333 error("/swaprun: missing argument"); 334 arg = newArg; 335 } while (!arg.empty()); 336 } 337 338 // An RAII temporary file class that automatically removes a temporary file. 339 namespace { 340 class TemporaryFile { 341 public: 342 TemporaryFile(StringRef prefix, StringRef extn, StringRef contents = "") { 343 SmallString<128> s; 344 if (auto ec = sys::fs::createTemporaryFile("lld-" + prefix, extn, s)) 345 fatal("cannot create a temporary file: " + ec.message()); 346 path = std::string(s.str()); 347 348 if (!contents.empty()) { 349 std::error_code ec; 350 raw_fd_ostream os(path, ec, sys::fs::OF_None); 351 if (ec) 352 fatal("failed to open " + path + ": " + ec.message()); 353 os << contents; 354 } 355 } 356 357 TemporaryFile(TemporaryFile &&obj) { 358 std::swap(path, obj.path); 359 } 360 361 ~TemporaryFile() { 362 if (path.empty()) 363 return; 364 if (sys::fs::remove(path)) 365 fatal("failed to remove " + path); 366 } 367 368 // Returns a memory buffer of this temporary file. 369 // Note that this function does not leave the file open, 370 // so it is safe to remove the file immediately after this function 371 // is called (you cannot remove an opened file on Windows.) 372 std::unique_ptr<MemoryBuffer> getMemoryBuffer() { 373 // IsVolatile=true forces MemoryBuffer to not use mmap(). 374 return CHECK(MemoryBuffer::getFile(path, /*IsText=*/false, 375 /*RequiresNullTerminator=*/false, 376 /*IsVolatile=*/true), 377 "could not open " + path); 378 } 379 380 std::string path; 381 }; 382 } 383 384 static std::string createDefaultXml() { 385 std::string ret; 386 raw_string_ostream os(ret); 387 388 // Emit the XML. Note that we do *not* verify that the XML attributes are 389 // syntactically correct. This is intentional for link.exe compatibility. 390 os << "<?xml version=\"1.0\" standalone=\"yes\"?>\n" 391 << "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\"\n" 392 << " manifestVersion=\"1.0\">\n"; 393 if (config->manifestUAC) { 394 os << " <trustInfo>\n" 395 << " <security>\n" 396 << " <requestedPrivileges>\n" 397 << " <requestedExecutionLevel level=" << config->manifestLevel 398 << " uiAccess=" << config->manifestUIAccess << "/>\n" 399 << " </requestedPrivileges>\n" 400 << " </security>\n" 401 << " </trustInfo>\n"; 402 } 403 for (auto manifestDependency : config->manifestDependencies) { 404 os << " <dependency>\n" 405 << " <dependentAssembly>\n" 406 << " <assemblyIdentity " << manifestDependency << " />\n" 407 << " </dependentAssembly>\n" 408 << " </dependency>\n"; 409 } 410 os << "</assembly>\n"; 411 return os.str(); 412 } 413 414 static std::string createManifestXmlWithInternalMt(StringRef defaultXml) { 415 std::unique_ptr<MemoryBuffer> defaultXmlCopy = 416 MemoryBuffer::getMemBufferCopy(defaultXml); 417 418 windows_manifest::WindowsManifestMerger merger; 419 if (auto e = merger.merge(*defaultXmlCopy.get())) 420 fatal("internal manifest tool failed on default xml: " + 421 toString(std::move(e))); 422 423 for (StringRef filename : config->manifestInput) { 424 std::unique_ptr<MemoryBuffer> manifest = 425 check(MemoryBuffer::getFile(filename)); 426 // Call takeBuffer to include in /reproduce: output if applicable. 427 if (auto e = merger.merge(driver->takeBuffer(std::move(manifest)))) 428 fatal("internal manifest tool failed on file " + filename + ": " + 429 toString(std::move(e))); 430 } 431 432 return std::string(merger.getMergedManifest().get()->getBuffer()); 433 } 434 435 static std::string createManifestXmlWithExternalMt(StringRef defaultXml) { 436 // Create the default manifest file as a temporary file. 437 TemporaryFile Default("defaultxml", "manifest"); 438 std::error_code ec; 439 raw_fd_ostream os(Default.path, ec, sys::fs::OF_TextWithCRLF); 440 if (ec) 441 fatal("failed to open " + Default.path + ": " + ec.message()); 442 os << defaultXml; 443 os.close(); 444 445 // Merge user-supplied manifests if they are given. Since libxml2 is not 446 // enabled, we must shell out to Microsoft's mt.exe tool. 447 TemporaryFile user("user", "manifest"); 448 449 Executor e("mt.exe"); 450 e.add("/manifest"); 451 e.add(Default.path); 452 for (StringRef filename : config->manifestInput) { 453 e.add("/manifest"); 454 e.add(filename); 455 456 // Manually add the file to the /reproduce: tar if needed. 457 if (driver->tar) 458 if (auto mbOrErr = MemoryBuffer::getFile(filename)) 459 driver->takeBuffer(std::move(*mbOrErr)); 460 } 461 e.add("/nologo"); 462 e.add("/out:" + StringRef(user.path)); 463 e.run(); 464 465 return std::string( 466 CHECK(MemoryBuffer::getFile(user.path), "could not open " + user.path) 467 .get() 468 ->getBuffer()); 469 } 470 471 static std::string createManifestXml() { 472 std::string defaultXml = createDefaultXml(); 473 if (config->manifestInput.empty()) 474 return defaultXml; 475 476 if (windows_manifest::isAvailable()) 477 return createManifestXmlWithInternalMt(defaultXml); 478 479 return createManifestXmlWithExternalMt(defaultXml); 480 } 481 482 static std::unique_ptr<WritableMemoryBuffer> 483 createMemoryBufferForManifestRes(size_t manifestSize) { 484 size_t resSize = alignTo( 485 object::WIN_RES_MAGIC_SIZE + object::WIN_RES_NULL_ENTRY_SIZE + 486 sizeof(object::WinResHeaderPrefix) + sizeof(object::WinResIDs) + 487 sizeof(object::WinResHeaderSuffix) + manifestSize, 488 object::WIN_RES_DATA_ALIGNMENT); 489 return WritableMemoryBuffer::getNewMemBuffer(resSize, config->outputFile + 490 ".manifest.res"); 491 } 492 493 static void writeResFileHeader(char *&buf) { 494 memcpy(buf, COFF::WinResMagic, sizeof(COFF::WinResMagic)); 495 buf += sizeof(COFF::WinResMagic); 496 memset(buf, 0, object::WIN_RES_NULL_ENTRY_SIZE); 497 buf += object::WIN_RES_NULL_ENTRY_SIZE; 498 } 499 500 static void writeResEntryHeader(char *&buf, size_t manifestSize) { 501 // Write the prefix. 502 auto *prefix = reinterpret_cast<object::WinResHeaderPrefix *>(buf); 503 prefix->DataSize = manifestSize; 504 prefix->HeaderSize = sizeof(object::WinResHeaderPrefix) + 505 sizeof(object::WinResIDs) + 506 sizeof(object::WinResHeaderSuffix); 507 buf += sizeof(object::WinResHeaderPrefix); 508 509 // Write the Type/Name IDs. 510 auto *iDs = reinterpret_cast<object::WinResIDs *>(buf); 511 iDs->setType(RT_MANIFEST); 512 iDs->setName(config->manifestID); 513 buf += sizeof(object::WinResIDs); 514 515 // Write the suffix. 516 auto *suffix = reinterpret_cast<object::WinResHeaderSuffix *>(buf); 517 suffix->DataVersion = 0; 518 suffix->MemoryFlags = object::WIN_RES_PURE_MOVEABLE; 519 suffix->Language = SUBLANG_ENGLISH_US; 520 suffix->Version = 0; 521 suffix->Characteristics = 0; 522 buf += sizeof(object::WinResHeaderSuffix); 523 } 524 525 // Create a resource file containing a manifest XML. 526 std::unique_ptr<MemoryBuffer> createManifestRes() { 527 std::string manifest = createManifestXml(); 528 529 std::unique_ptr<WritableMemoryBuffer> res = 530 createMemoryBufferForManifestRes(manifest.size()); 531 532 char *buf = res->getBufferStart(); 533 writeResFileHeader(buf); 534 writeResEntryHeader(buf, manifest.size()); 535 536 // Copy the manifest data into the .res file. 537 std::copy(manifest.begin(), manifest.end(), buf); 538 return std::move(res); 539 } 540 541 void createSideBySideManifest() { 542 std::string path = std::string(config->manifestFile); 543 if (path == "") 544 path = config->outputFile + ".manifest"; 545 std::error_code ec; 546 raw_fd_ostream out(path, ec, sys::fs::OF_TextWithCRLF); 547 if (ec) 548 fatal("failed to create manifest: " + ec.message()); 549 out << createManifestXml(); 550 } 551 552 // Parse a string in the form of 553 // "<name>[=<internalname>][,@ordinal[,NONAME]][,DATA][,PRIVATE]" 554 // or "<name>=<dllname>.<name>". 555 // Used for parsing /export arguments. 556 Export parseExport(StringRef arg) { 557 Export e; 558 StringRef rest; 559 std::tie(e.name, rest) = arg.split(","); 560 if (e.name.empty()) 561 goto err; 562 563 if (e.name.contains('=')) { 564 StringRef x, y; 565 std::tie(x, y) = e.name.split("="); 566 567 // If "<name>=<dllname>.<name>". 568 if (y.contains(".")) { 569 e.name = x; 570 e.forwardTo = y; 571 return e; 572 } 573 574 e.extName = x; 575 e.name = y; 576 if (e.name.empty()) 577 goto err; 578 } 579 580 // If "<name>=<internalname>[,@ordinal[,NONAME]][,DATA][,PRIVATE]" 581 while (!rest.empty()) { 582 StringRef tok; 583 std::tie(tok, rest) = rest.split(","); 584 if (tok.equals_insensitive("noname")) { 585 if (e.ordinal == 0) 586 goto err; 587 e.noname = true; 588 continue; 589 } 590 if (tok.equals_insensitive("data")) { 591 e.data = true; 592 continue; 593 } 594 if (tok.equals_insensitive("constant")) { 595 e.constant = true; 596 continue; 597 } 598 if (tok.equals_insensitive("private")) { 599 e.isPrivate = true; 600 continue; 601 } 602 if (tok.startswith("@")) { 603 int32_t ord; 604 if (tok.substr(1).getAsInteger(0, ord)) 605 goto err; 606 if (ord <= 0 || 65535 < ord) 607 goto err; 608 e.ordinal = ord; 609 continue; 610 } 611 goto err; 612 } 613 return e; 614 615 err: 616 fatal("invalid /export: " + arg); 617 } 618 619 static StringRef undecorate(StringRef sym) { 620 if (config->machine != I386) 621 return sym; 622 // In MSVC mode, a fully decorated stdcall function is exported 623 // as-is with the leading underscore (with type IMPORT_NAME). 624 // In MinGW mode, a decorated stdcall function gets the underscore 625 // removed, just like normal cdecl functions. 626 if (sym.startswith("_") && sym.contains('@') && !config->mingw) 627 return sym; 628 return sym.startswith("_") ? sym.substr(1) : sym; 629 } 630 631 // Convert stdcall/fastcall style symbols into unsuffixed symbols, 632 // with or without a leading underscore. (MinGW specific.) 633 static StringRef killAt(StringRef sym, bool prefix) { 634 if (sym.empty()) 635 return sym; 636 // Strip any trailing stdcall suffix 637 sym = sym.substr(0, sym.find('@', 1)); 638 if (!sym.startswith("@")) { 639 if (prefix && !sym.startswith("_")) 640 return saver().save("_" + sym); 641 return sym; 642 } 643 // For fastcall, remove the leading @ and replace it with an 644 // underscore, if prefixes are used. 645 sym = sym.substr(1); 646 if (prefix) 647 sym = saver().save("_" + sym); 648 return sym; 649 } 650 651 // Performs error checking on all /export arguments. 652 // It also sets ordinals. 653 void fixupExports() { 654 // Symbol ordinals must be unique. 655 std::set<uint16_t> ords; 656 for (Export &e : config->exports) { 657 if (e.ordinal == 0) 658 continue; 659 if (!ords.insert(e.ordinal).second) 660 fatal("duplicate export ordinal: " + e.name); 661 } 662 663 for (Export &e : config->exports) { 664 if (!e.forwardTo.empty()) { 665 e.exportName = undecorate(e.name); 666 } else { 667 e.exportName = undecorate(e.extName.empty() ? e.name : e.extName); 668 } 669 } 670 671 if (config->killAt && config->machine == I386) { 672 for (Export &e : config->exports) { 673 e.name = killAt(e.name, true); 674 e.exportName = killAt(e.exportName, false); 675 e.extName = killAt(e.extName, true); 676 e.symbolName = killAt(e.symbolName, true); 677 } 678 } 679 680 // Uniquefy by name. 681 DenseMap<StringRef, Export *> map(config->exports.size()); 682 std::vector<Export> v; 683 for (Export &e : config->exports) { 684 auto pair = map.insert(std::make_pair(e.exportName, &e)); 685 bool inserted = pair.second; 686 if (inserted) { 687 v.push_back(e); 688 continue; 689 } 690 Export *existing = pair.first->second; 691 if (e == *existing || e.name != existing->name) 692 continue; 693 warn("duplicate /export option: " + e.name); 694 } 695 config->exports = std::move(v); 696 697 // Sort by name. 698 llvm::sort(config->exports, [](const Export &a, const Export &b) { 699 return a.exportName < b.exportName; 700 }); 701 } 702 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 (got " + Twine(max) + ", max " + 713 Twine(std::numeric_limits<uint16_t>::max()) + ")"); 714 } 715 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); 731 } 732 config->mustMatch[k] = {v, source}; 733 } 734 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); 740 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"); 747 748 if (auto ec = parser.parse(rf, duplicates)) 749 fatal(toString(std::move(ec))); 750 } 751 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))); 759 760 if (auto ec = parser.parse(rsf, f->getName(), duplicates)) 761 fatal(toString(std::move(ec))); 762 } 763 764 if (config->mingw) 765 parser.cleanUpManifests(duplicates); 766 767 for (const auto &dupeDiag : duplicates) 768 if (config->forceMultipleRes) 769 warn(dupeDiag); 770 else 771 error(dupeDiag); 772 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())); 778 779 MemoryBufferRef mbref = **e; 780 make<std::unique_ptr<MemoryBuffer>>(std::move(*e)); // take ownership 781 return mbref; 782 } 783 784 // Create OptTable 785 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 790 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 798 }; 799 800 COFFOptTable::COFFOptTable() : OptTable(infoTable, true) {} 801 802 COFFOptTable optTable; 803 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); 823 } 824 } 825 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; 834 } 835 // The COFF linker always defaults to Windows quoting. 836 return cl::TokenizeWindowsCommandLine; 837 } 838 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; 844 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); 850 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); 860 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); 867 } 868 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()}; 872 873 // Handle /WX early since it converts missing argument warnings to errors. 874 errorHandler().fatalWarnings = args.hasFlag(OPT_WX, OPT_WX_no, false); 875 876 if (missingCount) 877 fatal(Twine(args.getArgString(missingIndex)) + ": missing argument"); 878 879 handleColorDiagnostics(args); 880 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 + "'"); 888 } 889 890 if (args.hasArg(OPT_lib)) 891 warn("ignoring /lib since it's not the first argument"); 892 893 return args; 894 } 895 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; 900 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 if (tok.startswith_insensitive("/exclude-symbols:") || 913 tok.startswith_insensitive("-exclude-symbols:")) 914 result.excludes.push_back(tok.substr(strlen("/exclude-symbols:"))); 915 else { 916 // Copy substrings that are not valid C strings. The tokenizer may have 917 // already copied quoted arguments for us, so those do not need to be 918 // copied again. 919 bool HasNul = tok.end() != s.end() && tok.data()[tok.size()] == '\0'; 920 rest.push_back(HasNul ? tok.data() : saver().save(tok).data()); 921 } 922 } 923 924 // Make InputArgList from unparsed string vectors. 925 unsigned missingIndex; 926 unsigned missingCount; 927 928 result.args = optTable.ParseArgs(rest, missingIndex, missingCount); 929 930 if (missingCount) 931 fatal(Twine(result.args.getArgString(missingIndex)) + ": missing argument"); 932 for (auto *arg : result.args.filtered(OPT_UNKNOWN)) 933 warn("ignoring unknown argument: " + arg->getAsString(result.args)); 934 return result; 935 } 936 937 // link.exe has an interesting feature. If LINK or _LINK_ environment 938 // variables exist, their contents are handled as command line strings. 939 // So you can pass extra arguments using them. 940 void ArgParser::addLINK(SmallVector<const char *, 256> &argv) { 941 // Concatenate LINK env and command line arguments, and then parse them. 942 if (Optional<std::string> s = Process::GetEnv("LINK")) { 943 std::vector<const char *> v = tokenize(*s); 944 argv.insert(std::next(argv.begin()), v.begin(), v.end()); 945 } 946 if (Optional<std::string> s = Process::GetEnv("_LINK_")) { 947 std::vector<const char *> v = tokenize(*s); 948 argv.insert(std::next(argv.begin()), v.begin(), v.end()); 949 } 950 } 951 952 std::vector<const char *> ArgParser::tokenize(StringRef s) { 953 SmallVector<const char *, 16> tokens; 954 cl::TokenizeWindowsCommandLine(s, saver(), tokens); 955 return std::vector<const char *>(tokens.begin(), tokens.end()); 956 } 957 958 void printHelp(const char *argv0) { 959 optTable.printHelp(lld::outs(), 960 (std::string(argv0) + " [options] file...").c_str(), 961 "LLVM Linker", false); 962 } 963 964 } // namespace coff 965 } // namespace lld 966