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