DriverUtils.cpp 29 KB

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