1 //===- DriverUtils.cpp ----------------------------------------------------===// 2 // 3 // The LLVM Linker 4 // 5 // This file is distributed under the University of Illinois Open Source 6 // License. See LICENSE.TXT for details. 7 // 8 //===----------------------------------------------------------------------===// 9 // 10 // This file contains utility functions for the driver. Because there 11 // are so many small functions, we created this separate file to make 12 // Driver.cpp less cluttered. 13 // 14 //===----------------------------------------------------------------------===// 15 16 #include "Config.h" 17 #include "Driver.h" 18 #include "Error.h" 19 #include "Symbols.h" 20 #include "llvm/ADT/Optional.h" 21 #include "llvm/ADT/StringSwitch.h" 22 #include "llvm/Object/Archive.h" 23 #include "llvm/Object/ArchiveWriter.h" 24 #include "llvm/Object/COFF.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/Path.h" 31 #include "llvm/Support/Process.h" 32 #include "llvm/Support/Program.h" 33 #include "llvm/Support/raw_ostream.h" 34 #include <memory> 35 36 using namespace llvm::COFF; 37 using namespace llvm; 38 using llvm::cl::ExpandResponseFiles; 39 using llvm::cl::TokenizeWindowsCommandLine; 40 using llvm::sys::Process; 41 42 namespace lld { 43 namespace coff { 44 namespace { 45 46 class Executor { 47 public: 48 explicit Executor(StringRef S) : Saver(Alloc), Prog(Saver.save(S)) {} 49 void add(StringRef S) { Args.push_back(Saver.save(S)); } 50 void add(std::string &S) { Args.push_back(Saver.save(S)); } 51 void add(Twine S) { Args.push_back(Saver.save(S)); } 52 void add(const char *S) { Args.push_back(Saver.save(S)); } 53 54 void run() { 55 ErrorOr<std::string> ExeOrErr = llvm::sys::findProgramByName(Prog); 56 error(ExeOrErr, Twine("unable to find ") + Prog + " in PATH: "); 57 const char *Exe = Saver.save(*ExeOrErr); 58 Args.insert(Args.begin(), Exe); 59 Args.push_back(nullptr); 60 if (llvm::sys::ExecuteAndWait(Args[0], Args.data()) != 0) { 61 for (const char *S : Args) 62 if (S) 63 llvm::errs() << S << " "; 64 error("failed"); 65 } 66 } 67 68 private: 69 llvm::BumpPtrAllocator Alloc; 70 llvm::StringSaver Saver; 71 StringRef Prog; 72 std::vector<const char *> Args; 73 }; 74 75 } // anonymous namespace 76 77 // Returns /machine's value. 78 MachineTypes getMachineType(StringRef S) { 79 MachineTypes MT = StringSwitch<MachineTypes>(S.lower()) 80 .Case("x64", AMD64) 81 .Case("amd64", AMD64) 82 .Case("x86", I386) 83 .Case("i386", I386) 84 .Case("arm", ARMNT) 85 .Default(IMAGE_FILE_MACHINE_UNKNOWN); 86 if (MT != IMAGE_FILE_MACHINE_UNKNOWN) 87 return MT; 88 error(Twine("unknown /machine argument: ") + S); 89 } 90 91 StringRef machineToStr(MachineTypes MT) { 92 switch (MT) { 93 case ARMNT: 94 return "arm"; 95 case AMD64: 96 return "x64"; 97 case I386: 98 return "x86"; 99 default: 100 llvm_unreachable("unknown machine type"); 101 } 102 } 103 104 // Parses a string in the form of "<integer>[,<integer>]". 105 void parseNumbers(StringRef Arg, uint64_t *Addr, uint64_t *Size) { 106 StringRef S1, S2; 107 std::tie(S1, S2) = Arg.split(','); 108 if (S1.getAsInteger(0, *Addr)) 109 error(Twine("invalid number: ") + S1); 110 if (Size && !S2.empty() && S2.getAsInteger(0, *Size)) 111 error(Twine("invalid number: ") + S2); 112 } 113 114 // Parses a string in the form of "<integer>[.<integer>]". 115 // If second number is not present, Minor is set to 0. 116 void parseVersion(StringRef Arg, uint32_t *Major, uint32_t *Minor) { 117 StringRef S1, S2; 118 std::tie(S1, S2) = Arg.split('.'); 119 if (S1.getAsInteger(0, *Major)) 120 error(Twine("invalid number: ") + S1); 121 *Minor = 0; 122 if (!S2.empty() && S2.getAsInteger(0, *Minor)) 123 error(Twine("invalid number: ") + S2); 124 } 125 126 // Parses a string in the form of "<subsystem>[,<integer>[.<integer>]]". 127 void parseSubsystem(StringRef Arg, WindowsSubsystem *Sys, uint32_t *Major, 128 uint32_t *Minor) { 129 StringRef SysStr, Ver; 130 std::tie(SysStr, Ver) = Arg.split(','); 131 *Sys = StringSwitch<WindowsSubsystem>(SysStr.lower()) 132 .Case("boot_application", IMAGE_SUBSYSTEM_WINDOWS_BOOT_APPLICATION) 133 .Case("console", IMAGE_SUBSYSTEM_WINDOWS_CUI) 134 .Case("efi_application", IMAGE_SUBSYSTEM_EFI_APPLICATION) 135 .Case("efi_boot_service_driver", IMAGE_SUBSYSTEM_EFI_BOOT_SERVICE_DRIVER) 136 .Case("efi_rom", IMAGE_SUBSYSTEM_EFI_ROM) 137 .Case("efi_runtime_driver", IMAGE_SUBSYSTEM_EFI_RUNTIME_DRIVER) 138 .Case("native", IMAGE_SUBSYSTEM_NATIVE) 139 .Case("posix", IMAGE_SUBSYSTEM_POSIX_CUI) 140 .Case("windows", IMAGE_SUBSYSTEM_WINDOWS_GUI) 141 .Default(IMAGE_SUBSYSTEM_UNKNOWN); 142 if (*Sys == IMAGE_SUBSYSTEM_UNKNOWN) 143 error(Twine("unknown subsystem: ") + SysStr); 144 if (!Ver.empty()) 145 parseVersion(Ver, Major, Minor); 146 } 147 148 // Parse a string of the form of "<from>=<to>". 149 // Results are directly written to Config. 150 void parseAlternateName(StringRef S) { 151 StringRef From, To; 152 std::tie(From, To) = S.split('='); 153 if (From.empty() || To.empty()) 154 error(Twine("/alternatename: invalid argument: ") + S); 155 auto It = Config->AlternateNames.find(From); 156 if (It != Config->AlternateNames.end() && It->second != To) 157 error(Twine("/alternatename: conflicts: ") + S); 158 Config->AlternateNames.insert(It, std::make_pair(From, To)); 159 } 160 161 // Parse a string of the form of "<from>=<to>". 162 // Results are directly written to Config. 163 void parseMerge(StringRef S) { 164 StringRef From, To; 165 std::tie(From, To) = S.split('='); 166 if (From.empty() || To.empty()) 167 error(Twine("/merge: invalid argument: ") + S); 168 auto Pair = Config->Merge.insert(std::make_pair(From, To)); 169 bool Inserted = Pair.second; 170 if (!Inserted) { 171 StringRef Existing = Pair.first->second; 172 if (Existing != To) 173 llvm::errs() << "warning: " << S << ": already merged into " 174 << Existing << "\n"; 175 } 176 } 177 178 static uint32_t parseSectionAttributes(StringRef S) { 179 uint32_t Ret = 0; 180 for (char C : S.lower()) { 181 switch (C) { 182 case 'd': 183 Ret |= IMAGE_SCN_MEM_DISCARDABLE; 184 break; 185 case 'e': 186 Ret |= IMAGE_SCN_MEM_EXECUTE; 187 break; 188 case 'k': 189 Ret |= IMAGE_SCN_MEM_NOT_CACHED; 190 break; 191 case 'p': 192 Ret |= IMAGE_SCN_MEM_NOT_PAGED; 193 break; 194 case 'r': 195 Ret |= IMAGE_SCN_MEM_READ; 196 break; 197 case 's': 198 Ret |= IMAGE_SCN_MEM_SHARED; 199 break; 200 case 'w': 201 Ret |= IMAGE_SCN_MEM_WRITE; 202 break; 203 default: 204 error(Twine("/section: invalid argument: ") + S); 205 } 206 } 207 return Ret; 208 } 209 210 // Parses /section option argument. 211 void parseSection(StringRef S) { 212 StringRef Name, Attrs; 213 std::tie(Name, Attrs) = S.split(','); 214 if (Name.empty() || Attrs.empty()) 215 error(Twine("/section: invalid argument: ") + S); 216 Config->Section[Name] = parseSectionAttributes(Attrs); 217 } 218 219 // Parses a string in the form of "EMBED[,=<integer>]|NO". 220 // Results are directly written to Config. 221 void parseManifest(StringRef Arg) { 222 if (Arg.equals_lower("no")) { 223 Config->Manifest = Configuration::No; 224 return; 225 } 226 if (!Arg.startswith_lower("embed")) 227 error(Twine("Invalid option ") + Arg); 228 Config->Manifest = Configuration::Embed; 229 Arg = Arg.substr(strlen("embed")); 230 if (Arg.empty()) 231 return; 232 if (!Arg.startswith_lower(",id=")) 233 error(Twine("Invalid option ") + Arg); 234 Arg = Arg.substr(strlen(",id=")); 235 if (Arg.getAsInteger(0, Config->ManifestID)) 236 error(Twine("Invalid option ") + Arg); 237 } 238 239 // Parses a string in the form of "level=<string>|uiAccess=<string>|NO". 240 // Results are directly written to Config. 241 void parseManifestUAC(StringRef Arg) { 242 if (Arg.equals_lower("no")) { 243 Config->ManifestUAC = false; 244 return; 245 } 246 for (;;) { 247 Arg = Arg.ltrim(); 248 if (Arg.empty()) 249 return; 250 if (Arg.startswith_lower("level=")) { 251 Arg = Arg.substr(strlen("level=")); 252 std::tie(Config->ManifestLevel, Arg) = Arg.split(" "); 253 continue; 254 } 255 if (Arg.startswith_lower("uiaccess=")) { 256 Arg = Arg.substr(strlen("uiaccess=")); 257 std::tie(Config->ManifestUIAccess, Arg) = Arg.split(" "); 258 continue; 259 } 260 error(Twine("Invalid option ") + Arg); 261 } 262 } 263 264 // Quote each line with "". Existing double-quote is converted 265 // to two double-quotes. 266 static void quoteAndPrint(raw_ostream &Out, StringRef S) { 267 while (!S.empty()) { 268 StringRef Line; 269 std::tie(Line, S) = S.split("\n"); 270 if (Line.empty()) 271 continue; 272 Out << '\"'; 273 for (int I = 0, E = Line.size(); I != E; ++I) { 274 if (Line[I] == '\"') { 275 Out << "\"\""; 276 } else { 277 Out << Line[I]; 278 } 279 } 280 Out << "\"\n"; 281 } 282 } 283 284 // Create the default manifest file as a temporary file. 285 static std::string createDefaultXml() { 286 // Create a temporary file. 287 SmallString<128> Path; 288 std::error_code EC = sys::fs::createTemporaryFile("tmp", "manifest", Path); 289 error(EC, "cannot create a temporary file"); 290 291 // Open the temporary file for writing. 292 llvm::raw_fd_ostream OS(Path, EC, sys::fs::F_Text); 293 error(EC, Twine("failed to open ") + Path); 294 295 // Emit the XML. Note that we do *not* verify that the XML attributes are 296 // syntactically correct. This is intentional for link.exe compatibility. 297 OS << "<?xml version=\"1.0\" standalone=\"yes\"?>\n" 298 << "<assembly xmlns=\"urn:schemas-microsoft-com:asm.v1\"\n" 299 << " manifestVersion=\"1.0\">\n"; 300 if (Config->ManifestUAC) { 301 OS << " <trustInfo>\n" 302 << " <security>\n" 303 << " <requestedPrivileges>\n" 304 << " <requestedExecutionLevel level=" << Config->ManifestLevel 305 << " uiAccess=" << Config->ManifestUIAccess << "/>\n" 306 << " </requestedPrivileges>\n" 307 << " </security>\n" 308 << " </trustInfo>\n"; 309 if (!Config->ManifestDependency.empty()) { 310 OS << " <dependency>\n" 311 << " <dependentAssembly>\n" 312 << " <assemblyIdentity " << Config->ManifestDependency << " />\n" 313 << " </dependentAssembly>\n" 314 << " </dependency>\n"; 315 } 316 } 317 OS << "</assembly>\n"; 318 OS.close(); 319 return StringRef(Path); 320 } 321 322 static std::string readFile(StringRef Path) { 323 ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr = MemoryBuffer::getFile(Path); 324 error(BufOrErr, "Could not open " + Path); 325 std::unique_ptr<MemoryBuffer> Buf(std::move(*BufOrErr)); 326 return Buf->getBuffer(); 327 } 328 329 static std::string createManifestXml() { 330 // Create the default manifest file. 331 std::string Path1 = createDefaultXml(); 332 if (Config->ManifestInput.empty()) 333 return readFile(Path1); 334 335 // If manifest files are supplied by the user using /MANIFESTINPUT 336 // option, we need to merge them with the default manifest. 337 SmallString<128> Path2; 338 std::error_code EC = sys::fs::createTemporaryFile("tmp", "manifest", Path2); 339 error(EC, "cannot create a temporary file"); 340 FileRemover Remover1(Path1); 341 FileRemover Remover2(Path2); 342 343 Executor E("mt.exe"); 344 E.add("/manifest"); 345 E.add(Path1); 346 for (StringRef Filename : Config->ManifestInput) { 347 E.add("/manifest"); 348 E.add(Filename); 349 } 350 E.add("/nologo"); 351 E.add("/out:" + StringRef(Path2)); 352 E.run(); 353 return readFile(Path2); 354 } 355 356 // Create a resource file containing a manifest XML. 357 std::unique_ptr<MemoryBuffer> createManifestRes() { 358 // Create a temporary file for the resource script file. 359 SmallString<128> RCPath; 360 std::error_code EC = sys::fs::createTemporaryFile("tmp", "rc", RCPath); 361 error(EC, "cannot create a temporary file"); 362 FileRemover RCRemover(RCPath); 363 364 // Open the temporary file for writing. 365 llvm::raw_fd_ostream Out(RCPath, EC, sys::fs::F_Text); 366 error(EC, Twine("failed to open ") + RCPath); 367 368 // Write resource script to the RC file. 369 Out << "#define LANG_ENGLISH 9\n" 370 << "#define SUBLANG_DEFAULT 1\n" 371 << "#define APP_MANIFEST " << Config->ManifestID << "\n" 372 << "#define RT_MANIFEST 24\n" 373 << "LANGUAGE LANG_ENGLISH, SUBLANG_DEFAULT\n" 374 << "APP_MANIFEST RT_MANIFEST {\n"; 375 quoteAndPrint(Out, createManifestXml()); 376 Out << "}\n"; 377 Out.close(); 378 379 // Create output resource file. 380 SmallString<128> ResPath; 381 EC = sys::fs::createTemporaryFile("tmp", "res", ResPath); 382 error(EC, "cannot create a temporary file"); 383 384 Executor E("rc.exe"); 385 E.add("/fo"); 386 E.add(ResPath.str()); 387 E.add("/nologo"); 388 E.add(RCPath.str()); 389 E.run(); 390 ErrorOr<std::unique_ptr<MemoryBuffer>> Ret = MemoryBuffer::getFile(ResPath); 391 error(Ret, Twine("Could not open ") + ResPath); 392 return std::move(*Ret); 393 } 394 395 void createSideBySideManifest() { 396 std::string Path = Config->ManifestFile; 397 if (Path == "") 398 Path = (Twine(Config->OutputFile) + ".manifest").str(); 399 std::error_code EC; 400 llvm::raw_fd_ostream Out(Path, EC, llvm::sys::fs::F_Text); 401 error(EC, "failed to create manifest"); 402 Out << createManifestXml(); 403 } 404 405 // Parse a string in the form of 406 // "<name>[=<internalname>][,@ordinal[,NONAME]][,DATA][,PRIVATE]" 407 // or "<name>=<dllname>.<name>". 408 // Used for parsing /export arguments. 409 Export parseExport(StringRef Arg) { 410 Export E; 411 StringRef Rest; 412 std::tie(E.Name, Rest) = Arg.split(","); 413 if (E.Name.empty()) 414 goto err; 415 416 if (E.Name.find('=') != StringRef::npos) { 417 StringRef X, Y; 418 std::tie(X, Y) = E.Name.split("="); 419 420 // If "<name>=<dllname>.<name>". 421 if (Y.find(".") != StringRef::npos) { 422 E.Name = X; 423 E.ForwardTo = Y; 424 return E; 425 } 426 427 E.ExtName = X; 428 E.Name = Y; 429 if (E.Name.empty()) 430 goto err; 431 } 432 433 // If "<name>=<internalname>[,@ordinal[,NONAME]][,DATA][,PRIVATE]" 434 while (!Rest.empty()) { 435 StringRef Tok; 436 std::tie(Tok, Rest) = Rest.split(","); 437 if (Tok.equals_lower("noname")) { 438 if (E.Ordinal == 0) 439 goto err; 440 E.Noname = true; 441 continue; 442 } 443 if (Tok.equals_lower("data")) { 444 E.Data = true; 445 continue; 446 } 447 if (Tok.equals_lower("private")) { 448 E.Private = true; 449 continue; 450 } 451 if (Tok.startswith("@")) { 452 int32_t Ord; 453 if (Tok.substr(1).getAsInteger(0, Ord)) 454 goto err; 455 if (Ord <= 0 || 65535 < Ord) 456 goto err; 457 E.Ordinal = Ord; 458 continue; 459 } 460 goto err; 461 } 462 return E; 463 464 err: 465 error(Twine("invalid /export: ") + Arg); 466 } 467 468 static StringRef undecorate(StringRef Sym) { 469 if (Config->Machine != I386) 470 return Sym; 471 return Sym.startswith("_") ? Sym.substr(1) : Sym; 472 } 473 474 // Performs error checking on all /export arguments. 475 // It also sets ordinals. 476 void fixupExports() { 477 // Symbol ordinals must be unique. 478 std::set<uint16_t> Ords; 479 for (Export &E : Config->Exports) { 480 if (E.Ordinal == 0) 481 continue; 482 if (!Ords.insert(E.Ordinal).second) 483 error("duplicate export ordinal: " + E.Name); 484 } 485 486 for (Export &E : Config->Exports) { 487 if (!E.ForwardTo.empty()) { 488 E.SymbolName = E.Name; 489 } else if (Undefined *U = cast_or_null<Undefined>(E.Sym->WeakAlias)) { 490 E.SymbolName = U->getName(); 491 } else { 492 E.SymbolName = E.Sym->getName(); 493 } 494 } 495 496 for (Export &E : Config->Exports) { 497 if (!E.ForwardTo.empty()) { 498 E.ExportName = undecorate(E.Name); 499 } else { 500 E.ExportName = undecorate(E.ExtName.empty() ? E.Name : E.ExtName); 501 } 502 } 503 504 // Uniquefy by name. 505 std::map<StringRef, Export *> Map; 506 std::vector<Export> V; 507 for (Export &E : Config->Exports) { 508 auto Pair = Map.insert(std::make_pair(E.ExportName, &E)); 509 bool Inserted = Pair.second; 510 if (Inserted) { 511 V.push_back(E); 512 continue; 513 } 514 Export *Existing = Pair.first->second; 515 if (E == *Existing || E.Name != Existing->Name) 516 continue; 517 llvm::errs() << "warning: duplicate /export option: " << E.Name << "\n"; 518 } 519 Config->Exports = std::move(V); 520 521 // Sort by name. 522 std::sort(Config->Exports.begin(), Config->Exports.end(), 523 [](const Export &A, const Export &B) { 524 return A.ExportName < B.ExportName; 525 }); 526 } 527 528 void assignExportOrdinals() { 529 // Assign unique ordinals if default (= 0). 530 uint16_t Max = 0; 531 for (Export &E : Config->Exports) 532 Max = std::max(Max, E.Ordinal); 533 for (Export &E : Config->Exports) 534 if (E.Ordinal == 0) 535 E.Ordinal = ++Max; 536 } 537 538 // Parses a string in the form of "key=value" and check 539 // if value matches previous values for the same key. 540 void checkFailIfMismatch(StringRef Arg) { 541 StringRef K, V; 542 std::tie(K, V) = Arg.split('='); 543 if (K.empty() || V.empty()) 544 error(Twine("/failifmismatch: invalid argument: ") + Arg); 545 StringRef Existing = Config->MustMatch[K]; 546 if (!Existing.empty() && V != Existing) 547 error(Twine("/failifmismatch: mismatch detected: ") + Existing + " and " + 548 V + " for key " + K); 549 Config->MustMatch[K] = V; 550 } 551 552 // Convert Windows resource files (.res files) to a .obj file 553 // using cvtres.exe. 554 std::unique_ptr<MemoryBuffer> 555 convertResToCOFF(const std::vector<MemoryBufferRef> &MBs) { 556 // Create an output file path. 557 SmallString<128> Path; 558 if (llvm::sys::fs::createTemporaryFile("resource", "obj", Path)) 559 error("Could not create temporary file"); 560 561 // Execute cvtres.exe. 562 Executor E("cvtres.exe"); 563 E.add("/machine:" + machineToStr(Config->Machine)); 564 E.add("/readonly"); 565 E.add("/nologo"); 566 E.add("/out:" + Path); 567 for (MemoryBufferRef MB : MBs) 568 E.add(MB.getBufferIdentifier()); 569 E.run(); 570 ErrorOr<std::unique_ptr<MemoryBuffer>> Ret = MemoryBuffer::getFile(Path); 571 error(Ret, Twine("Could not open ") + Path); 572 return std::move(*Ret); 573 } 574 575 static std::string writeToTempFile(StringRef Contents) { 576 SmallString<128> Path; 577 int FD; 578 if (llvm::sys::fs::createTemporaryFile("tmp", "def", FD, Path)) { 579 llvm::errs() << "failed to create a temporary file\n"; 580 return ""; 581 } 582 llvm::raw_fd_ostream OS(FD, /*shouldClose*/ true); 583 OS << Contents; 584 return Path.str(); 585 } 586 587 void touchFile(StringRef Path) { 588 int FD; 589 std::error_code EC = sys::fs::openFileForWrite(Path, FD, sys::fs::F_Append); 590 error(EC, "failed to create a file"); 591 sys::Process::SafelyCloseFileDescriptor(FD); 592 } 593 594 static std::string getImplibPath() { 595 if (!Config->Implib.empty()) 596 return Config->Implib; 597 SmallString<128> Out = StringRef(Config->OutputFile); 598 sys::path::replace_extension(Out, ".lib"); 599 return Out.str(); 600 } 601 602 static std::unique_ptr<MemoryBuffer> createEmptyImportLibrary() { 603 std::string S = (Twine("LIBRARY \"") + 604 llvm::sys::path::filename(Config->OutputFile) + "\"\n") 605 .str(); 606 std::string Path1 = writeToTempFile(S); 607 std::string Path2 = getImplibPath(); 608 llvm::FileRemover Remover1(Path1); 609 llvm::FileRemover Remover2(Path2); 610 611 Executor E("lib.exe"); 612 E.add("/nologo"); 613 E.add("/machine:" + machineToStr(Config->Machine)); 614 E.add(Twine("/def:") + Path1); 615 E.add(Twine("/out:") + Path2); 616 E.run(); 617 618 ErrorOr<std::unique_ptr<MemoryBuffer>> BufOrErr = 619 MemoryBuffer::getFile(Path2, -1, false); 620 error(BufOrErr, Twine("Failed to open ") + Path2); 621 return MemoryBuffer::getMemBufferCopy((*BufOrErr)->getBuffer()); 622 } 623 624 static std::vector<NewArchiveIterator> 625 readMembers(const object::Archive &Archive) { 626 std::vector<NewArchiveIterator> V; 627 for (const auto &ChildOrErr : Archive.children()) { 628 error(ChildOrErr, "Archive::Child::getName failed"); 629 const object::Archive::Child C(*ChildOrErr); 630 ErrorOr<StringRef> NameOrErr = C.getName(); 631 error(NameOrErr, "Archive::Child::getName failed"); 632 V.emplace_back(C, *NameOrErr); 633 } 634 return V; 635 } 636 637 // This class creates short import files which is described in 638 // PE/COFF spec 7. Import Library Format. 639 class ShortImportCreator { 640 public: 641 ShortImportCreator(object::Archive *A, StringRef S) : Parent(A), DLLName(S) {} 642 643 NewArchiveIterator create(StringRef Sym, uint16_t Ordinal, 644 ImportNameType NameType, bool isData) { 645 size_t ImpSize = DLLName.size() + Sym.size() + 2; // +2 for NULs 646 size_t Size = sizeof(object::ArchiveMemberHeader) + 647 sizeof(coff_import_header) + ImpSize; 648 char *Buf = Alloc.Allocate<char>(Size); 649 memset(Buf, 0, Size); 650 char *P = Buf; 651 652 // Write archive member header 653 auto *Hdr = reinterpret_cast<object::ArchiveMemberHeader *>(P); 654 P += sizeof(*Hdr); 655 sprintf(Hdr->Name, "%-12s", "dummy"); 656 sprintf(Hdr->LastModified, "%-12d", 0); 657 sprintf(Hdr->UID, "%-6d", 0); 658 sprintf(Hdr->GID, "%-6d", 0); 659 sprintf(Hdr->AccessMode, "%-8d", 0644); 660 sprintf(Hdr->Size, "%-10d", int(sizeof(coff_import_header) + ImpSize)); 661 662 // Write short import library. 663 auto *Imp = reinterpret_cast<coff_import_header *>(P); 664 P += sizeof(*Imp); 665 Imp->Sig2 = 0xFFFF; 666 Imp->Machine = Config->Machine; 667 Imp->SizeOfData = ImpSize; 668 if (Ordinal > 0) 669 Imp->OrdinalHint = Ordinal; 670 Imp->TypeInfo = (isData ? IMPORT_DATA : IMPORT_CODE); 671 Imp->TypeInfo |= NameType << 2; 672 673 // Write symbol name and DLL name. 674 memcpy(P, Sym.data(), Sym.size()); 675 P += Sym.size() + 1; 676 memcpy(P, DLLName.data(), DLLName.size()); 677 678 std::error_code EC; 679 object::Archive::Child C(Parent, Buf, &EC); 680 assert(!EC && "We created an invalid buffer"); 681 return NewArchiveIterator(C, DLLName); 682 } 683 684 private: 685 BumpPtrAllocator Alloc; 686 object::Archive *Parent; 687 StringRef DLLName; 688 }; 689 690 static ImportNameType getNameType(StringRef Sym, StringRef ExtName) { 691 if (Sym != ExtName) 692 return IMPORT_NAME_UNDECORATE; 693 if (Config->Machine == I386 && Sym.startswith("_")) 694 return IMPORT_NAME_NOPREFIX; 695 return IMPORT_NAME; 696 } 697 698 static std::string replace(StringRef S, StringRef From, StringRef To) { 699 size_t Pos = S.find(From); 700 assert(Pos != StringRef::npos); 701 return (Twine(S.substr(0, Pos)) + To + S.substr(Pos + From.size())).str(); 702 } 703 704 // Creates an import library for a DLL. In this function, we first 705 // create an empty import library using lib.exe and then adds short 706 // import files to that file. 707 void writeImportLibrary() { 708 std::unique_ptr<MemoryBuffer> Buf = createEmptyImportLibrary(); 709 std::error_code EC; 710 object::Archive Archive(Buf->getMemBufferRef(), EC); 711 error(EC, "Error reading an empty import file"); 712 std::vector<NewArchiveIterator> Members = readMembers(Archive); 713 714 std::string DLLName = llvm::sys::path::filename(Config->OutputFile); 715 ShortImportCreator ShortImport(&Archive, DLLName); 716 for (Export &E : Config->Exports) { 717 if (E.Private) 718 continue; 719 if (E.ExtName.empty()) { 720 Members.push_back(ShortImport.create( 721 E.SymbolName, E.Ordinal, getNameType(E.SymbolName, E.Name), E.Data)); 722 } else { 723 Members.push_back(ShortImport.create( 724 replace(E.SymbolName, E.Name, E.ExtName), E.Ordinal, 725 getNameType(E.SymbolName, E.Name), E.Data)); 726 } 727 } 728 729 std::string Path = getImplibPath(); 730 std::pair<StringRef, std::error_code> Result = 731 writeArchive(Path, Members, /*WriteSymtab*/ true, object::Archive::K_GNU, 732 /*Deterministic*/ true, /*Thin*/ false); 733 error(Result.second, Twine("Failed to write ") + Path); 734 } 735 736 // Create OptTable 737 738 // Create prefix string literals used in Options.td 739 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE; 740 #include "Options.inc" 741 #undef PREFIX 742 743 // Create table mapping all options defined in Options.td 744 static const llvm::opt::OptTable::Info infoTable[] = { 745 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X6, X7, X8, X9, X10) \ 746 { \ 747 X1, X2, X9, X10, OPT_##ID, llvm::opt::Option::KIND##Class, X8, X7, \ 748 OPT_##GROUP, OPT_##ALIAS, X6 \ 749 }, 750 #include "Options.inc" 751 #undef OPTION 752 }; 753 754 class COFFOptTable : public llvm::opt::OptTable { 755 public: 756 COFFOptTable() : OptTable(infoTable, true) {} 757 }; 758 759 // Parses a given list of options. 760 llvm::opt::InputArgList ArgParser::parse(ArrayRef<const char *> ArgsArr) { 761 // First, replace respnose files (@<file>-style options). 762 std::vector<const char *> Argv = replaceResponseFiles(ArgsArr); 763 764 // Make InputArgList from string vectors. 765 COFFOptTable Table; 766 unsigned MissingIndex; 767 unsigned MissingCount; 768 llvm::opt::InputArgList Args = 769 Table.ParseArgs(Argv, MissingIndex, MissingCount); 770 771 // Print the real command line if response files are expanded. 772 if (Args.hasArg(OPT_verbose) && ArgsArr.size() != Argv.size()) { 773 llvm::outs() << "Command line:"; 774 for (const char *S : Argv) 775 llvm::outs() << " " << S; 776 llvm::outs() << "\n"; 777 } 778 779 if (MissingCount) 780 error(Twine("missing arg value for \"") + Args.getArgString(MissingIndex) + 781 "\", expected " + Twine(MissingCount) + 782 (MissingCount == 1 ? " argument." : " arguments.")); 783 for (auto *Arg : Args.filtered(OPT_UNKNOWN)) 784 llvm::errs() << "ignoring unknown argument: " << Arg->getSpelling() << "\n"; 785 return Args; 786 } 787 788 llvm::opt::InputArgList ArgParser::parseLINK(ArrayRef<const char *> Args) { 789 // Concatenate LINK env and given arguments and parse them. 790 Optional<std::string> Env = Process::GetEnv("LINK"); 791 if (!Env) 792 return parse(Args); 793 std::vector<const char *> V = tokenize(*Env); 794 V.insert(V.end(), Args.begin(), Args.end()); 795 return parse(V); 796 } 797 798 std::vector<const char *> ArgParser::tokenize(StringRef S) { 799 SmallVector<const char *, 16> Tokens; 800 StringSaver Saver(AllocAux); 801 llvm::cl::TokenizeWindowsCommandLine(S, Saver, Tokens); 802 return std::vector<const char *>(Tokens.begin(), Tokens.end()); 803 } 804 805 // Creates a new command line by replacing options starting with '@' 806 // character. '@<filename>' is replaced by the file's contents. 807 std::vector<const char *> 808 ArgParser::replaceResponseFiles(std::vector<const char *> Argv) { 809 SmallVector<const char *, 256> Tokens(Argv.data(), Argv.data() + Argv.size()); 810 StringSaver Saver(AllocAux); 811 ExpandResponseFiles(Saver, TokenizeWindowsCommandLine, Tokens); 812 return std::vector<const char *>(Tokens.begin(), Tokens.end()); 813 } 814 815 void printHelp(const char *Argv0) { 816 COFFOptTable Table; 817 Table.PrintHelp(llvm::outs(), Argv0, "LLVM Linker", false); 818 } 819 820 } // namespace coff 821 } // namespace lld 822