1//===- Driver.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#include "Driver.h"
10#include "COFFLinkerContext.h"
11#include "Config.h"
12#include "DebugTypes.h"
13#include "ICF.h"
14#include "InputFiles.h"
15#include "MarkLive.h"
16#include "MinGW.h"
17#include "SymbolTable.h"
18#include "Symbols.h"
19#include "Writer.h"
20#include "lld/Common/Args.h"
21#include "lld/Common/CommonLinkerContext.h"
22#include "lld/Common/Filesystem.h"
23#include "lld/Common/Timer.h"
24#include "lld/Common/Version.h"
25#include "llvm/ADT/IntrusiveRefCntPtr.h"
26#include "llvm/ADT/SmallSet.h"
27#include "llvm/ADT/StringSwitch.h"
28#include "llvm/BinaryFormat/Magic.h"
29#include "llvm/Config/llvm-config.h"
30#include "llvm/LTO/LTO.h"
31#include "llvm/Object/COFFImportFile.h"
32#include "llvm/Object/IRObjectFile.h"
33#include "llvm/Option/Arg.h"
34#include "llvm/Option/ArgList.h"
35#include "llvm/Option/Option.h"
36#include "llvm/Remarks/HotnessThresholdParser.h"
37#include "llvm/Support/BinaryStreamReader.h"
38#include "llvm/Support/CommandLine.h"
39#include "llvm/Support/Debug.h"
40#include "llvm/Support/LEB128.h"
41#include "llvm/Support/MathExtras.h"
42#include "llvm/Support/Parallel.h"
43#include "llvm/Support/Path.h"
44#include "llvm/Support/Process.h"
45#include "llvm/Support/TarWriter.h"
46#include "llvm/Support/TargetSelect.h"
47#include "llvm/Support/TimeProfiler.h"
48#include "llvm/Support/VirtualFileSystem.h"
49#include "llvm/Support/raw_ostream.h"
50#include "llvm/TargetParser/Triple.h"
51#include "llvm/ToolDrivers/llvm-lib/LibDriver.h"
52#include <algorithm>
53#include <future>
54#include <memory>
55#include <optional>
56#include <tuple>
57
58using namespace lld;
59using namespace lld::coff;
60using namespace llvm;
61using namespace llvm::object;
62using namespace llvm::COFF;
63using namespace llvm::sys;
64
65COFFSyncStream::COFFSyncStream(COFFLinkerContext &ctx, DiagLevel level)
66 : SyncStream(ctx.e, level), ctx(ctx) {}
67
68COFFSyncStream coff::Log(COFFLinkerContext &ctx) {
69 return {ctx, DiagLevel::Log};
70}
71COFFSyncStream coff::Msg(COFFLinkerContext &ctx) {
72 return {ctx, DiagLevel::Msg};
73}
74COFFSyncStream coff::Warn(COFFLinkerContext &ctx) {
75 return {ctx, DiagLevel::Warn};
76}
77COFFSyncStream coff::Err(COFFLinkerContext &ctx) {
78 return {ctx, DiagLevel::Err};
79}
80COFFSyncStream coff::Fatal(COFFLinkerContext &ctx) {
81 return {ctx, DiagLevel::Fatal};
82}
83uint64_t coff::errCount(COFFLinkerContext &ctx) { return ctx.e.errorCount; }
84
85namespace lld::coff {
86
87bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
88 llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput) {
89 // This driver-specific context will be freed later by unsafeLldMain().
90 auto *ctx = new COFFLinkerContext;
91
92 ctx->e.initialize(stdoutOS, stderrOS, exitEarly, disableOutput);
93 ctx->e.logName = args::getFilenameWithoutExe(path: args[0]);
94 ctx->e.errorLimitExceededMsg = "too many errors emitted, stopping now"
95 " (use /errorlimit:0 to see all errors)";
96
97 ctx->driver.linkerMain(args);
98
99 return errCount(ctx&: *ctx) == 0;
100}
101
102// Parse options of the form "old;new".
103static std::pair<StringRef, StringRef>
104getOldNewOptions(COFFLinkerContext &ctx, opt::InputArgList &args, unsigned id) {
105 auto *arg = args.getLastArg(Ids: id);
106 if (!arg)
107 return {"", ""};
108
109 StringRef s = arg->getValue();
110 std::pair<StringRef, StringRef> ret = s.split(Separator: ';');
111 if (ret.second.empty())
112 Err(ctx) << arg->getSpelling() << " expects 'old;new' format, but got "
113 << s;
114 return ret;
115}
116
117// Parse options of the form "old;new[;extra]".
118static std::tuple<StringRef, StringRef, StringRef>
119getOldNewOptionsExtra(COFFLinkerContext &ctx, opt::InputArgList &args,
120 unsigned id) {
121 auto [oldDir, second] = getOldNewOptions(ctx, args, id);
122 auto [newDir, extraDir] = second.split(Separator: ';');
123 return {oldDir, newDir, extraDir};
124}
125
126// Drop directory components and replace extension with
127// ".exe", ".dll" or ".sys".
128static std::string getOutputPath(StringRef path, bool isDll, bool isDriver) {
129 StringRef ext = ".exe";
130 if (isDll)
131 ext = ".dll";
132 else if (isDriver)
133 ext = ".sys";
134
135 return (sys::path::stem(path) + ext).str();
136}
137
138// Returns true if S matches /crtend.?\.o$/.
139static bool isCrtend(StringRef s) {
140 if (!s.consume_back(Suffix: ".o"))
141 return false;
142 if (s.ends_with(Suffix: "crtend"))
143 return true;
144 return !s.empty() && s.drop_back().ends_with(Suffix: "crtend");
145}
146
147// ErrorOr is not default constructible, so it cannot be used as the type
148// parameter of a future.
149// FIXME: We could open the file in createFutureForFile and avoid needing to
150// return an error here, but for the moment that would cost us a file descriptor
151// (a limited resource on Windows) for the duration that the future is pending.
152using MBErrPair = std::pair<std::unique_ptr<MemoryBuffer>, std::error_code>;
153
154// Create a std::future that opens and maps a file using the best strategy for
155// the host platform.
156static std::future<MBErrPair> createFutureForFile(std::string path,
157 bool prefetchInputs) {
158#if _WIN64
159 // On Windows, file I/O is relatively slow so it is best to do this
160 // asynchronously. But 32-bit has issues with potentially launching tons
161 // of threads
162 auto strategy = std::launch::async;
163#else
164 auto strategy = std::launch::deferred;
165#endif
166 return std::async(policy: strategy, fn: [=]() {
167 auto mbOrErr = MemoryBuffer::getFile(Filename: path, /*IsText=*/false,
168 /*RequiresNullTerminator=*/false);
169 if (!mbOrErr)
170 return MBErrPair{nullptr, mbOrErr.getError()};
171 // Prefetch memory pages in the background as we will need them soon enough.
172 if (prefetchInputs)
173 (*mbOrErr)->willNeedIfMmap();
174 return MBErrPair{std::move(*mbOrErr), std::error_code()};
175 });
176}
177
178llvm::Triple::ArchType LinkerDriver::getArch() {
179 return getMachineArchType(machine: ctx.config.machine);
180}
181
182std::vector<Chunk *> LinkerDriver::getChunks() const {
183 std::vector<Chunk *> res;
184 for (ObjFile *file : ctx.objFileInstances) {
185 ArrayRef<Chunk *> v = file->getChunks();
186 res.insert(position: res.end(), first: v.begin(), last: v.end());
187 }
188 return res;
189}
190
191static bool compatibleMachineType(COFFLinkerContext &ctx, MachineTypes mt) {
192 if (mt == IMAGE_FILE_MACHINE_UNKNOWN)
193 return true;
194 switch (ctx.config.machine) {
195 case ARM64:
196 return mt == ARM64 || mt == ARM64X;
197 case ARM64EC:
198 case ARM64X:
199 return isAnyArm64(Machine: mt) || mt == AMD64;
200 case IMAGE_FILE_MACHINE_UNKNOWN:
201 return true;
202 default:
203 return ctx.config.machine == mt;
204 }
205}
206
207void LinkerDriver::addFile(InputFile *file) {
208 Log(ctx) << "Reading " << toString(file);
209 if (file->lazy) {
210 if (auto *f = dyn_cast<BitcodeFile>(Val: file))
211 f->parseLazy();
212 else
213 cast<ObjFile>(Val: file)->parseLazy();
214 } else {
215 ctx.consumedInputsSize += file->mb.getBufferSize();
216 file->parse();
217 if (auto *f = dyn_cast<ObjFile>(Val: file)) {
218 ctx.objFileInstances.push_back(x: f);
219 } else if (auto *f = dyn_cast<BitcodeFile>(Val: file)) {
220 if (ltoCompilationDone) {
221 Err(ctx) << "LTO object file " << toString(file)
222 << " linked in after "
223 "doing LTO compilation.";
224 }
225 f->symtab.bitcodeFileInstances.push_back(x: f);
226 } else if (auto *f = dyn_cast<ImportFile>(Val: file)) {
227 ctx.importFileInstances.push_back(x: f);
228 }
229 }
230
231 MachineTypes mt = file->getMachineType();
232 // The ARM64EC target must be explicitly specified and cannot be inferred.
233 if (mt == ARM64EC &&
234 (ctx.config.machine == IMAGE_FILE_MACHINE_UNKNOWN ||
235 (ctx.config.machineInferred &&
236 (ctx.config.machine == ARM64 || ctx.config.machine == AMD64)))) {
237 Err(ctx) << toString(file)
238 << ": machine type arm64ec is ambiguous and cannot be "
239 "inferred, use /machine:arm64ec or /machine:arm64x";
240 return;
241 }
242 if (!compatibleMachineType(ctx, mt)) {
243 Err(ctx) << toString(file) << ": machine type " << machineToStr(MT: mt)
244 << " conflicts with " << machineToStr(MT: ctx.config.machine);
245 return;
246 }
247 if (ctx.config.machine == IMAGE_FILE_MACHINE_UNKNOWN &&
248 mt != IMAGE_FILE_MACHINE_UNKNOWN) {
249 ctx.config.machineInferred = true;
250 setMachine(mt);
251 }
252
253 parseDirectives(file);
254}
255
256MemoryBufferRef LinkerDriver::takeBuffer(std::unique_ptr<MemoryBuffer> mb) {
257 MemoryBufferRef mbref = *mb;
258 make<std::unique_ptr<MemoryBuffer>>(args: std::move(mb)); // take ownership
259
260 if (ctx.driver.tar)
261 ctx.driver.tar->append(Path: relativeToRoot(path: mbref.getBufferIdentifier()),
262 Data: mbref.getBuffer());
263 return mbref;
264}
265
266InputFile *LinkerDriver::addObjectFile(COFFLinkerContext &ctx,
267 MemoryBufferRef mb,
268 StringRef archiveName,
269 uint64_t offsetInArchive, bool lazy) {
270 std::unique_ptr<COFFObjectFile> coffObj = ObjFile::createCOFFObject(ctx, mb);
271 InputFile *obj = nullptr;
272
273 // On ARM64EC, check for a hybrid object section and use it for the EC object.
274 if (ctx.symtab.isEC()) {
275 if (std::optional<MemoryBufferRef> hybridSec =
276 coffObj->findHybridObjectSection()) {
277 InputFile *hybridObj =
278 addObjectFile(ctx, mb: *hybridSec, archiveName, offsetInArchive, lazy);
279 // For the ARM64X target, continue processing the native file.
280 if (ctx.config.machine != ARM64X)
281 return hybridObj;
282 }
283 }
284
285 if (ctx.config.fatLTOObjects) {
286 Expected<MemoryBufferRef> fatLTOData =
287 IRObjectFile::findBitcodeInObject(Obj: *coffObj);
288
289 if (!errorToBool(Err: fatLTOData.takeError())) {
290 obj = BitcodeFile::create(ctx, mb: *fatLTOData, archiveName, offsetInArchive,
291 lazy);
292 }
293 }
294
295 if (!obj)
296 obj = ObjFile::create(ctx, coffObj: coffObj.release(), lazy);
297 obj->parentName = archiveName;
298 addFile(file: obj);
299 return obj;
300}
301
302void LinkerDriver::addBuffer(std::unique_ptr<MemoryBuffer> mb,
303 bool wholeArchive, bool lazy) {
304 StringRef filename = mb->getBufferIdentifier();
305
306 MemoryBufferRef mbref = takeBuffer(mb: std::move(mb));
307
308 // File type is detected by contents, not by file extension.
309 switch (identify_magic(magic: mbref.getBuffer())) {
310 case file_magic::windows_resource:
311 resources.push_back(x: mbref);
312 break;
313 case file_magic::archive: {
314 std::unique_ptr<Archive> file =
315 CHECK(Archive::create(mbref), filename + ": failed to parse archive");
316
317 // On ARM64EC/ARM64X, the archive may contain both, potentially conflicting,
318 // native and EC symbols in the symbol table. Regular archives handle this
319 // using the extended archive format, which stores the EC symbol table in a
320 // separate section, but it is not available for thin archives.
321 // Work around this limitation by lazily parsing all thin archive members
322 // instead of relying on the archive symbol table.
323 if (wholeArchive || (ctx.symtab.isEC() && file->isThin())) {
324 Archive *archive = file.get();
325 make<std::unique_ptr<Archive>>(args: std::move(file)); // take ownership
326
327 int memberIndex = 0;
328 for (MemoryBufferRef m : getArchiveMembers(ctx, file: archive)) {
329 if (!archive->isThin())
330 addArchiveBuffer(mbref: m, symName: "<whole-archive>", parentName: filename, offsetInArchive: memberIndex++,
331 lazy: !wholeArchive);
332 else
333 addThinArchiveBuffer(mbref: m, symName: "<whole-archive>", lazy: !wholeArchive);
334 }
335
336 return;
337 }
338 addFile(file: make<ArchiveFile>(args&: ctx, args&: mbref, args&: file));
339 break;
340 }
341 case file_magic::bitcode:
342 addFile(file: BitcodeFile::create(ctx, mb: mbref, archiveName: "", offsetInArchive: 0, lazy));
343 break;
344 case file_magic::coff_object: {
345 addObjectFile(ctx, mb: mbref, archiveName: "", offsetInArchive: 0, lazy);
346 break;
347 }
348 case file_magic::coff_import_library:
349 addFile(file: ObjFile::create(ctx, mb: mbref, lazy));
350 break;
351 case file_magic::pdb:
352 addFile(file: make<PDBInputFile>(args&: ctx, args&: mbref));
353 break;
354 case file_magic::coff_cl_gl_object:
355 Err(ctx) << filename
356 << ": is not a native COFF file. Recompile without /GL";
357 break;
358 case file_magic::pecoff_executable:
359 if (ctx.config.mingw) {
360 std::unique_ptr<COFFObjectFile> obj =
361 ObjFile::createCOFFObject(ctx, mb: mbref);
362 if (ctx.symtab.isEC()) {
363 // When importing an ARM64X image, add both the native and EC views.
364 if (std::unique_ptr<MemoryBuffer> hybridView =
365 obj->getHybridObjectView()) {
366 std::unique_ptr<COFFObjectFile> hybridObj =
367 ObjFile::createCOFFObject(ctx, mb: takeBuffer(mb: std::move(hybridView)));
368 addFile(file: make<DLLFile>(args&: ctx.symtab, args&: hybridObj));
369 addFile(file: make<DLLFile>(args&: *ctx.hybridSymtab, args&: obj));
370 break;
371 }
372 }
373 auto machine = static_cast<MachineTypes>(obj->getMachine());
374 addFile(file: make<DLLFile>(args&: ctx.getSymtab(machine), args&: obj));
375 break;
376 }
377 if (filename.ends_with_insensitive(Suffix: ".dll")) {
378 Err(ctx) << filename
379 << ": bad file type. Did you specify a DLL instead of an "
380 "import library?";
381 break;
382 }
383 [[fallthrough]];
384 default:
385 Err(ctx) << mbref.getBufferIdentifier() << ": unknown file type";
386 break;
387 }
388}
389
390void LinkerDriver::handleReproFile(StringRef path, InputOpt inputOpt) {
391 if (!reproFile)
392 return;
393
394 *reproFile << '"';
395 if (inputOpt == InputOpt::DefaultLib)
396 *reproFile << "/defaultlib:";
397 else if (inputOpt == InputOpt::WholeArchive)
398 *reproFile << "/wholearchive:";
399
400 SmallString<128> absPath = path;
401 std::error_code ec = sys::fs::make_absolute(path&: absPath);
402 if (ec)
403 Err(ctx) << "cannot find absolute path for reproFile for " << absPath
404 << ": " << ec.message();
405 sys::path::remove_dots(path&: absPath, remove_dot_dot: true);
406 *reproFile << absPath << "\"\n";
407}
408
409void LinkerDriver::enqueuePath(StringRef path, bool lazy, InputOpt inputOpt) {
410 auto future = std::make_shared<std::future<MBErrPair>>(
411 args: createFutureForFile(path: std::string(path), prefetchInputs: ctx.config.prefetchInputs));
412 std::string pathStr = std::string(path);
413 enqueueTask(task: [=]() {
414 llvm::TimeTraceScope timeScope("File: ", path);
415 auto [mb, ec] = future->get();
416 if (ec) {
417 // Retry reading the file (synchronously) now that we may have added
418 // winsysroot search paths from SymbolTable::addFile().
419 // Retrying synchronously is important for keeping the order of inputs
420 // consistent.
421 // This makes it so that if the user passes something in the winsysroot
422 // before something we can find with an architecture, we won't find the
423 // winsysroot file.
424 if (std::optional<StringRef> retryPath = findFileIfNew(filename: pathStr)) {
425 auto retryMb = MemoryBuffer::getFile(Filename: *retryPath, /*IsText=*/false,
426 /*RequiresNullTerminator=*/false);
427 ec = retryMb.getError();
428 if (!ec) {
429 mb = std::move(*retryMb);
430 // Prefetch memory pages in the background as we will need them soon
431 // enough.
432 if (ctx.config.prefetchInputs)
433 mb->willNeedIfMmap();
434 }
435 } else {
436 // We've already handled this file.
437 return;
438 }
439 }
440 if (ec) {
441 std::string msg = "could not open '" + pathStr + "': " + ec.message();
442 // Check if the filename is a typo for an option flag. OptTable thinks
443 // that all args that are not known options and that start with / are
444 // filenames, but e.g. `/nodefaultlibs` is more likely a typo for
445 // the option `/nodefaultlib` than a reference to a file in the root
446 // directory.
447 std::string nearest;
448 if (ctx.optTable.findNearest(Option: pathStr, NearestString&: nearest) > 1)
449 Err(ctx) << msg;
450 else
451 Err(ctx) << msg << "; did you mean '" << nearest << "'";
452 } else {
453 handleReproFile(path: pathStr, inputOpt);
454 ctx.driver.addBuffer(mb: std::move(mb), wholeArchive: inputOpt == InputOpt::WholeArchive,
455 lazy);
456 }
457 });
458}
459
460void LinkerDriver::addArchiveBuffer(MemoryBufferRef mb, StringRef symName,
461 StringRef parentName,
462 uint64_t offsetInArchive, bool lazy) {
463 file_magic magic = identify_magic(magic: mb.getBuffer());
464 if (magic == file_magic::coff_import_library) {
465 InputFile *imp = make<ImportFile>(args&: ctx, args&: mb);
466 imp->parentName = parentName;
467 addFile(file: imp);
468 return;
469 }
470
471 InputFile *obj;
472 if (magic == file_magic::coff_object) {
473 obj = addObjectFile(ctx, mb, archiveName: parentName, offsetInArchive, lazy);
474 } else if (magic == file_magic::bitcode) {
475 obj = BitcodeFile::create(ctx, mb, archiveName: parentName, offsetInArchive, lazy);
476 obj->parentName = parentName;
477 addFile(file: obj);
478 } else if (magic == file_magic::coff_cl_gl_object) {
479 Err(ctx) << mb.getBufferIdentifier()
480 << ": is not a native COFF file. Recompile without /GL?";
481 return;
482 } else {
483 Err(ctx) << "unknown file type: " << mb.getBufferIdentifier();
484 return;
485 }
486
487 Log(ctx) << "Loaded " << obj << " for " << symName;
488}
489
490void LinkerDriver::addThinArchiveBuffer(MemoryBufferRef mb, StringRef symName,
491 bool lazy) {
492 // Pass an empty string as the archive name and an offset of 0 so that
493 // the original filename is used as the buffer identifier. This is
494 // useful for DTLTO, where having the member identifier be the actual
495 // path on disk enables distribution of bitcode files during ThinLTO.
496 addArchiveBuffer(mb, symName, /*parentName=*/"", /*OffsetInArchive=*/offsetInArchive: 0, lazy);
497}
498
499void LinkerDriver::enqueueArchiveMember(const Archive::Child &c,
500 const Archive::Symbol &sym,
501 StringRef parentName) {
502
503 auto reportBufferError = [=](Error &&e) {
504 StringRef childName = CHECK(
505 c.getName(), "could not get child name for archive " + parentName +
506 " while loading symbol " + toCOFFString(ctx, sym));
507 Fatal(ctx) << "could not get the buffer for the member defining symbol "
508 << &sym << ": " << parentName << "(" << childName
509 << "): " << std::move(e);
510 };
511
512 if (!c.getParent()->isThin()) {
513 uint64_t offsetInArchive = c.getChildOffset();
514 Expected<MemoryBufferRef> mbOrErr = c.getMemoryBufferRef();
515 if (!mbOrErr)
516 reportBufferError(mbOrErr.takeError());
517 MemoryBufferRef mb = mbOrErr.get();
518 enqueueTask(task: [=]() {
519 llvm::TimeTraceScope timeScope("Archive: ", mb.getBufferIdentifier());
520 ctx.driver.addArchiveBuffer(mb, symName: toCOFFString(ctx, b: sym), parentName,
521 offsetInArchive, lazy: false);
522 });
523 return;
524 }
525
526 std::string childName =
527 CHECK(c.getFullName(),
528 "could not get the filename for the member defining symbol " +
529 toCOFFString(ctx, sym));
530 auto future = std::make_shared<std::future<MBErrPair>>(
531 args: createFutureForFile(path: childName, prefetchInputs: ctx.config.prefetchInputs));
532 enqueueTask(task: [=]() {
533 auto mbOrErr = future->get();
534 if (mbOrErr.second)
535 reportBufferError(errorCodeToError(EC: mbOrErr.second));
536 llvm::TimeTraceScope timeScope("Archive: ",
537 mbOrErr.first->getBufferIdentifier());
538 ctx.driver.addThinArchiveBuffer(mb: takeBuffer(mb: std::move(mbOrErr.first)),
539 symName: toCOFFString(ctx, b: sym), lazy: false);
540 });
541}
542
543bool LinkerDriver::isDecorated(StringRef sym) {
544 return sym.starts_with(Prefix: "@") || sym.contains(Other: "@@") || sym.starts_with(Prefix: "?") ||
545 (!ctx.config.mingw && sym.contains(C: '@'));
546}
547
548// Parses .drectve section contents and returns a list of files
549// specified by /defaultlib.
550void LinkerDriver::parseDirectives(InputFile *file) {
551 StringRef s = file->getDirectives();
552 if (s.empty())
553 return;
554
555 Log(ctx) << "Directives: " << file << ": " << s;
556
557 ArgParser parser(ctx);
558 // .drectve is always tokenized using Windows shell rules.
559 // /EXPORT: option can appear too many times, processing in fastpath.
560 ParsedDirectives directives = parser.parseDirectives(s);
561
562 for (StringRef e : directives.exports) {
563 // If a common header file contains dllexported function
564 // declarations, many object files may end up with having the
565 // same /EXPORT options. In order to save cost of parsing them,
566 // we dedup them first.
567 if (!file->symtab.directivesExports.insert(V: e).second)
568 continue;
569
570 Export exp = parseExport(arg: e);
571 if (ctx.config.machine == I386 && ctx.config.mingw) {
572 if (!isDecorated(sym: exp.name))
573 exp.name = saver().save(S: "_" + exp.name);
574 if (!exp.extName.empty() && !isDecorated(sym: exp.extName))
575 exp.extName = saver().save(S: "_" + exp.extName);
576 }
577 exp.source = ExportSource::Directives;
578 file->symtab.exports.push_back(x: exp);
579 }
580
581 // Handle /include: in bulk.
582 for (StringRef inc : directives.includes)
583 file->symtab.addGCRoot(sym: inc);
584
585 // Handle /exclude-symbols: in bulk.
586 for (StringRef e : directives.excludes) {
587 SmallVector<StringRef, 2> vec;
588 e.split(A&: vec, Separator: ',');
589 for (StringRef sym : vec)
590 excludedSymbols.insert(V: file->symtab.mangle(sym));
591 }
592
593 // https://docs.microsoft.com/en-us/cpp/preprocessor/comment-c-cpp?view=msvc-160
594 for (auto *arg : directives.args) {
595 switch (arg->getOption().getID()) {
596 case OPT_aligncomm:
597 file->symtab.parseAligncomm(arg->getValue());
598 break;
599 case OPT_alternatename:
600 file->symtab.parseAlternateName(arg->getValue());
601 break;
602 case OPT_arm64xsameaddress:
603 if (file->symtab.isEC())
604 parseSameAddress(arg->getValue());
605 else
606 Warn(ctx) << arg->getSpelling()
607 << " is not allowed in non-ARM64EC files (" << toString(file)
608 << ")";
609 break;
610 case OPT_defaultlib:
611 if (std::optional<StringRef> path = findLibIfNew(filename: arg->getValue()))
612 enqueuePath(path: *path, lazy: false, inputOpt: InputOpt::DefaultLib);
613 break;
614 case OPT_entry:
615 if (!arg->getValue()[0])
616 Fatal(ctx) << "missing entry point symbol name";
617 ctx.forEachActiveSymtab(f: [&](SymbolTable &symtab) {
618 symtab.entry = symtab.addGCRoot(sym: symtab.mangle(sym: arg->getValue()), aliasEC: true);
619 });
620 break;
621 case OPT_failifmismatch:
622 checkFailIfMismatch(arg: arg->getValue(), source: file);
623 break;
624 case OPT_incl:
625 file->symtab.addGCRoot(sym: arg->getValue());
626 break;
627 case OPT_manifestdependency:
628 ctx.config.manifestDependencies.insert(X: arg->getValue());
629 break;
630 case OPT_merge:
631 parseMerge(arg->getValue());
632 break;
633 case OPT_nodefaultlib:
634 ctx.config.noDefaultLibs.insert(key: findLib(filename: arg->getValue()).lower());
635 break;
636 case OPT_release:
637 ctx.config.writeCheckSum = true;
638 break;
639 case OPT_section:
640 parseSection(arg->getValue());
641 break;
642 case OPT_stack:
643 parseNumbers(arg: arg->getValue(), addr: &ctx.config.stackReserve,
644 size: &ctx.config.stackCommit);
645 break;
646 case OPT_subsystem: {
647 bool gotVersion = false;
648 parseSubsystem(arg: arg->getValue(), sys: &ctx.config.subsystem,
649 major: &ctx.config.majorSubsystemVersion,
650 minor: &ctx.config.minorSubsystemVersion, gotVersion: &gotVersion);
651 if (gotVersion) {
652 ctx.config.majorOSVersion = ctx.config.majorSubsystemVersion;
653 ctx.config.minorOSVersion = ctx.config.minorSubsystemVersion;
654 }
655 break;
656 }
657 // Only add flags here that link.exe accepts in
658 // `#pragma comment(linker, "/flag")`-generated sections.
659 case OPT_editandcontinue:
660 case OPT_guardsym:
661 case OPT_throwingnew:
662 case OPT_inferasanlibs:
663 case OPT_inferasanlibs_no:
664 break;
665 default:
666 Err(ctx) << arg->getSpelling() << " is not allowed in .drectve ("
667 << toString(file) << ")";
668 }
669 }
670}
671
672// Find file from search paths. You can omit ".obj", this function takes
673// care of that. Note that the returned path is not guaranteed to exist.
674StringRef LinkerDriver::findFile(StringRef filename) {
675 auto getFilename = [this](StringRef filename) -> StringRef {
676 if (ctx.config.vfs)
677 if (auto statOrErr = ctx.config.vfs->status(Path: filename))
678 return saver().save(S: statOrErr->getName());
679 return filename;
680 };
681
682 if (sys::path::is_absolute(path: filename))
683 return getFilename(filename);
684 bool hasExt = filename.contains(C: '.');
685 for (StringRef dir : searchPaths) {
686 SmallString<128> path = dir;
687 sys::path::append(path, a: filename);
688 path = SmallString<128>{getFilename(path.str())};
689 if (sys::fs::exists(Path: path.str()))
690 return saver().save(S: path.str());
691 if (!hasExt) {
692 path.append(RHS: ".obj");
693 path = SmallString<128>{getFilename(path.str())};
694 if (sys::fs::exists(Path: path.str()))
695 return saver().save(S: path.str());
696 }
697 }
698 return filename;
699}
700
701static std::optional<sys::fs::UniqueID> getUniqueID(StringRef path) {
702 sys::fs::UniqueID ret;
703 if (sys::fs::getUniqueID(Path: path, Result&: ret))
704 return std::nullopt;
705 return ret;
706}
707
708// Resolves a file path. This never returns the same path
709// (in that case, it returns std::nullopt).
710std::optional<StringRef> LinkerDriver::findFileIfNew(StringRef filename) {
711 StringRef path = findFile(filename);
712
713 if (std::optional<sys::fs::UniqueID> id = getUniqueID(path)) {
714 bool seen = !visitedFiles.insert(x: *id).second;
715 if (seen)
716 return std::nullopt;
717 }
718
719 if (path.ends_with_insensitive(Suffix: ".lib"))
720 visitedLibs.insert(x: std::string(sys::path::filename(path).lower()));
721 return path;
722}
723
724// MinGW specific. If an embedded directive specified to link to
725// foo.lib, but it isn't found, try libfoo.a instead.
726StringRef LinkerDriver::findLibMinGW(StringRef filename) {
727 if (filename.contains(C: '/') || filename.contains(C: '\\'))
728 return filename;
729
730 SmallString<128> s = filename;
731 sys::path::replace_extension(path&: s, extension: ".a");
732 StringRef libName = saver().save(S: "lib" + s.str());
733 return findFile(filename: libName);
734}
735
736// Find library file from search path.
737StringRef LinkerDriver::findLib(StringRef filename) {
738 // Add ".lib" to Filename if that has no file extension.
739 bool hasExt = filename.contains(C: '.');
740 if (!hasExt)
741 filename = saver().save(S: filename + ".lib");
742 StringRef ret = findFile(filename);
743 // For MinGW, if the find above didn't turn up anything, try
744 // looking for a MinGW formatted library name.
745 if (ctx.config.mingw && ret == filename)
746 return findLibMinGW(filename);
747 return ret;
748}
749
750// Resolves a library path. /nodefaultlib options are taken into
751// consideration. This never returns the same path (in that case,
752// it returns std::nullopt).
753std::optional<StringRef> LinkerDriver::findLibIfNew(StringRef filename) {
754 if (ctx.config.noDefaultLibAll)
755 return std::nullopt;
756 if (!visitedLibs.insert(x: filename.lower()).second)
757 return std::nullopt;
758
759 StringRef path = findLib(filename);
760 if (ctx.config.noDefaultLibs.contains(key: path.lower()))
761 return std::nullopt;
762
763 if (std::optional<sys::fs::UniqueID> id = getUniqueID(path))
764 if (!visitedFiles.insert(x: *id).second)
765 return std::nullopt;
766 return path;
767}
768
769void LinkerDriver::setMachine(MachineTypes machine) {
770 assert(ctx.config.machine == IMAGE_FILE_MACHINE_UNKNOWN);
771 assert(machine != IMAGE_FILE_MACHINE_UNKNOWN);
772
773 ctx.config.machine = machine;
774
775 if (!isArm64EC(Machine: machine)) {
776 ctx.symtab.machine = machine;
777 } else {
778 // Set up a hybrid symbol table on ARM64EC/ARM64X. This is primarily useful
779 // on ARM64X, where both the native and EC symbol tables are meaningful.
780 // However, since ARM64EC can include native object files, we also need to
781 // support a hybrid symbol table there.
782 ctx.symtab.machine = ARM64EC;
783 ctx.hybridSymtab.emplace(args&: ctx, args: ARM64);
784 }
785
786 addWinSysRootLibSearchPaths();
787}
788
789void LinkerDriver::detectWinSysRoot(const opt::InputArgList &Args) {
790 IntrusiveRefCntPtr<vfs::FileSystem> VFS = vfs::getRealFileSystem();
791
792 // Check the command line first, that's the user explicitly telling us what to
793 // use. Check the environment next, in case we're being invoked from a VS
794 // command prompt. Failing that, just try to find the newest Visual Studio
795 // version we can and use its default VC toolchain.
796 std::optional<StringRef> VCToolsDir, VCToolsVersion, WinSysRoot;
797 if (auto *A = Args.getLastArg(Ids: OPT_vctoolsdir))
798 VCToolsDir = A->getValue();
799 if (auto *A = Args.getLastArg(Ids: OPT_vctoolsversion))
800 VCToolsVersion = A->getValue();
801 if (auto *A = Args.getLastArg(Ids: OPT_winsysroot))
802 WinSysRoot = A->getValue();
803 if (!findVCToolChainViaCommandLine(VFS&: *VFS, VCToolsDir, VCToolsVersion,
804 WinSysRoot, Path&: vcToolChainPath, VSLayout&: vsLayout) &&
805 (Args.hasArg(Ids: OPT_lldignoreenv) ||
806 !findVCToolChainViaEnvironment(VFS&: *VFS, Path&: vcToolChainPath, VSLayout&: vsLayout)) &&
807 !findVCToolChainViaSetupConfig(VFS&: *VFS, VCToolsVersion: {}, Path&: vcToolChainPath, VSLayout&: vsLayout) &&
808 !findVCToolChainViaRegistry(Path&: vcToolChainPath, VSLayout&: vsLayout))
809 return;
810
811 // If the VC environment hasn't been configured (perhaps because the user did
812 // not run vcvarsall), try to build a consistent link environment. If the
813 // environment variable is set however, assume the user knows what they're
814 // doing. If the user passes /vctoolsdir or /winsdkdir, trust that over env
815 // vars.
816 if (const auto *A = Args.getLastArg(Ids: OPT_diasdkdir, Ids: OPT_winsysroot)) {
817 diaPath = A->getValue();
818 if (A->getOption().getID() == OPT_winsysroot)
819 path::append(path&: diaPath, a: "DIA SDK");
820 }
821 useWinSysRootLibPath = !Process::GetEnv(name: "LIB") ||
822 Args.hasArg(Ids: OPT_lldignoreenv, Ids: OPT_vctoolsdir,
823 Ids: OPT_vctoolsversion, Ids: OPT_winsysroot);
824 if (!Process::GetEnv(name: "LIB") ||
825 Args.hasArg(Ids: OPT_lldignoreenv, Ids: OPT_winsdkdir, Ids: OPT_winsdkversion,
826 Ids: OPT_winsysroot)) {
827 std::optional<StringRef> WinSdkDir, WinSdkVersion;
828 if (auto *A = Args.getLastArg(Ids: OPT_winsdkdir))
829 WinSdkDir = A->getValue();
830 if (auto *A = Args.getLastArg(Ids: OPT_winsdkversion))
831 WinSdkVersion = A->getValue();
832
833 if (useUniversalCRT(VSLayout: vsLayout, VCToolChainPath: vcToolChainPath, TargetArch: getArch(), VFS&: *VFS)) {
834 std::string UniversalCRTSdkPath;
835 std::string UCRTVersion;
836 if (getUniversalCRTSdkDir(VFS&: *VFS, WinSdkDir, WinSdkVersion, WinSysRoot,
837 Path&: UniversalCRTSdkPath, UCRTVersion)) {
838 universalCRTLibPath = UniversalCRTSdkPath;
839 path::append(path&: universalCRTLibPath, a: "Lib", b: UCRTVersion, c: "ucrt");
840 }
841 }
842
843 std::string sdkPath;
844 std::string windowsSDKIncludeVersion;
845 std::string windowsSDKLibVersion;
846 if (getWindowsSDKDir(VFS&: *VFS, WinSdkDir, WinSdkVersion, WinSysRoot, Path&: sdkPath,
847 Major&: sdkMajor, WindowsSDKIncludeVersion&: windowsSDKIncludeVersion,
848 WindowsSDKLibVersion&: windowsSDKLibVersion)) {
849 windowsSdkLibPath = sdkPath;
850 path::append(path&: windowsSdkLibPath, a: "Lib");
851 if (sdkMajor >= 8)
852 path::append(path&: windowsSdkLibPath, a: windowsSDKLibVersion, b: "um");
853 }
854 }
855}
856
857void LinkerDriver::addClangLibSearchPaths(const std::string &argv0) {
858 std::string lldBinary = sys::fs::getMainExecutable(argv0: argv0.c_str(), MainExecAddr: nullptr);
859 SmallString<128> binDir(lldBinary);
860 sys::path::remove_filename(path&: binDir); // remove lld-link.exe
861 StringRef rootDir = sys::path::parent_path(path: binDir); // remove 'bin'
862
863 SmallString<128> libDir(rootDir);
864 sys::path::append(path&: libDir, a: "lib");
865
866 // Add the resource dir library path
867 SmallString<128> runtimeLibDir(rootDir);
868 sys::path::append(path&: runtimeLibDir, a: "lib", b: "clang",
869 c: std::to_string(LLVM_VERSION_MAJOR), d: "lib");
870 // Resource dir + osname, which is hardcoded to windows since we are in the
871 // COFF driver.
872 SmallString<128> runtimeLibDirWithOS(runtimeLibDir);
873 sys::path::append(path&: runtimeLibDirWithOS, a: "windows");
874
875 searchPaths.push_back(x: saver().save(S: runtimeLibDirWithOS.str()));
876 searchPaths.push_back(x: saver().save(S: runtimeLibDir.str()));
877 searchPaths.push_back(x: saver().save(S: libDir.str()));
878}
879
880void LinkerDriver::addWinSysRootLibSearchPaths() {
881 if (!diaPath.empty()) {
882 // The DIA SDK always uses the legacy vc arch, even in new MSVC versions.
883 path::append(path&: diaPath, a: "lib", b: archToLegacyVCArch(Arch: getArch()));
884 searchPaths.push_back(x: saver().save(S: diaPath.str()));
885 }
886 if (useWinSysRootLibPath) {
887 searchPaths.push_back(x: saver().save(S: getSubDirectoryPath(
888 Type: SubDirectoryType::Lib, VSLayout: vsLayout, VCToolChainPath: vcToolChainPath, TargetArch: getArch())));
889 searchPaths.push_back(x: saver().save(
890 S: getSubDirectoryPath(Type: SubDirectoryType::Lib, VSLayout: vsLayout, VCToolChainPath: vcToolChainPath,
891 TargetArch: getArch(), SubdirParent: "atlmfc")));
892 }
893 if (!universalCRTLibPath.empty()) {
894 StringRef ArchName = archToWindowsSDKArch(Arch: getArch());
895 if (!ArchName.empty()) {
896 path::append(path&: universalCRTLibPath, a: ArchName);
897 searchPaths.push_back(x: saver().save(S: universalCRTLibPath.str()));
898 }
899 }
900 if (!windowsSdkLibPath.empty()) {
901 std::string path;
902 if (appendArchToWindowsSDKLibPath(SDKMajor: sdkMajor, LibPath: windowsSdkLibPath, Arch: getArch(),
903 path))
904 searchPaths.push_back(x: saver().save(S: path));
905 }
906
907 // Libraries specified by `/nodefaultlib:` may not be found in incomplete
908 // search paths before lld infers a machine type from input files.
909 llvm::StringSet<> noDefaultLibs;
910 for (auto &iter : ctx.config.noDefaultLibs)
911 noDefaultLibs.insert(key: findLib(filename: iter.first()).lower());
912 ctx.config.noDefaultLibs = std::move(noDefaultLibs);
913}
914
915// Parses LIB environment which contains a list of search paths.
916void LinkerDriver::addLibSearchPaths() {
917 std::optional<std::string> envOpt = Process::GetEnv(name: "LIB");
918 if (!envOpt)
919 return;
920 StringRef env = saver().save(S: *envOpt);
921 while (!env.empty()) {
922 StringRef path;
923 std::tie(args&: path, args&: env) = env.split(Separator: ';');
924 searchPaths.push_back(x: path);
925 }
926}
927
928uint64_t LinkerDriver::getDefaultImageBase() {
929 if (ctx.config.is64())
930 return ctx.config.dll ? 0x180000000 : 0x140000000;
931 return ctx.config.dll ? 0x10000000 : 0x400000;
932}
933
934static std::string rewritePath(StringRef s) {
935 if (fs::exists(Path: s))
936 return relativeToRoot(path: s);
937 return std::string(s);
938}
939
940// Reconstructs command line arguments so that so that you can re-run
941// the same command with the same inputs. This is for --reproduce.
942static std::string createResponseFile(const opt::InputArgList &args,
943 ArrayRef<StringRef> searchPaths) {
944 SmallString<0> data;
945 raw_svector_ostream os(data);
946
947 for (auto *arg : args) {
948 switch (arg->getOption().getID()) {
949 case OPT_linkrepro:
950 case OPT_reproduce:
951 case OPT_libpath:
952 case OPT_winsysroot:
953 break;
954 case OPT_INPUT:
955 os << quote(s: rewritePath(s: arg->getValue())) << "\n";
956 break;
957 case OPT_wholearchive_file:
958 os << arg->getSpelling() << quote(s: rewritePath(s: arg->getValue())) << "\n";
959 break;
960 case OPT_call_graph_ordering_file:
961 case OPT_deffile:
962 case OPT_manifestinput:
963 case OPT_natvis:
964 os << arg->getSpelling() << quote(s: rewritePath(s: arg->getValue())) << '\n';
965 break;
966 case OPT_order: {
967 StringRef orderFile = arg->getValue();
968 orderFile.consume_front(Prefix: "@");
969 os << arg->getSpelling() << '@' << quote(s: rewritePath(s: orderFile)) << '\n';
970 break;
971 }
972 case OPT_pdbstream: {
973 const std::pair<StringRef, StringRef> nameFile =
974 StringRef(arg->getValue()).split(Separator: "=");
975 os << arg->getSpelling() << nameFile.first << '='
976 << quote(s: rewritePath(s: nameFile.second)) << '\n';
977 break;
978 }
979 case OPT_implib:
980 case OPT_manifestfile:
981 case OPT_pdb:
982 case OPT_pdbstripped:
983 case OPT_out:
984 os << arg->getSpelling() << sys::path::filename(path: arg->getValue()) << "\n";
985 break;
986 default:
987 os << toString(arg: *arg) << "\n";
988 }
989 }
990
991 for (StringRef path : searchPaths) {
992 std::string relPath = relativeToRoot(path);
993 os << "/libpath:" << quote(s: relPath) << "\n";
994 }
995
996 return std::string(data);
997}
998
999static unsigned parseDebugTypes(COFFLinkerContext &ctx,
1000 const opt::InputArgList &args) {
1001 unsigned debugTypes = static_cast<unsigned>(DebugType::None);
1002
1003 if (auto *a = args.getLastArg(Ids: OPT_debugtype)) {
1004 SmallVector<StringRef, 3> types;
1005 StringRef(a->getValue())
1006 .split(A&: types, Separator: ',', /*MaxSplit=*/-1, /*KeepEmpty=*/false);
1007
1008 for (StringRef type : types) {
1009 unsigned v = StringSwitch<unsigned>(type.lower())
1010 .Case(S: "cv", Value: static_cast<unsigned>(DebugType::CV))
1011 .Case(S: "pdata", Value: static_cast<unsigned>(DebugType::PData))
1012 .Case(S: "fixup", Value: static_cast<unsigned>(DebugType::Fixup))
1013 .Default(Value: 0);
1014 if (v == 0) {
1015 Warn(ctx) << "/debugtype: unknown option '" << type << "'";
1016 continue;
1017 }
1018 debugTypes |= v;
1019 }
1020 return debugTypes;
1021 }
1022
1023 // Default debug types
1024 debugTypes = static_cast<unsigned>(DebugType::CV);
1025 if (args.hasArg(Ids: OPT_driver))
1026 debugTypes |= static_cast<unsigned>(DebugType::PData);
1027 if (args.hasArg(Ids: OPT_profile))
1028 debugTypes |= static_cast<unsigned>(DebugType::Fixup);
1029
1030 return debugTypes;
1031}
1032
1033std::string LinkerDriver::getMapFile(const opt::InputArgList &args,
1034 opt::OptSpecifier os,
1035 opt::OptSpecifier osFile) {
1036 auto *arg = args.getLastArg(Ids: os, Ids: osFile);
1037 if (!arg)
1038 return "";
1039 if (arg->getOption().getID() == osFile.getID())
1040 return arg->getValue();
1041
1042 assert(arg->getOption().getID() == os.getID());
1043 StringRef outFile = ctx.config.outputFile;
1044 return (outFile.substr(Start: 0, N: outFile.rfind(C: '.')) + ".map").str();
1045}
1046
1047std::string LinkerDriver::getImplibPath() {
1048 if (!ctx.config.implib.empty())
1049 return std::string(ctx.config.implib);
1050 SmallString<128> out = StringRef(ctx.config.outputFile);
1051 sys::path::replace_extension(path&: out, extension: ".lib");
1052 return std::string(out);
1053}
1054
1055// The import name is calculated as follows:
1056//
1057// | LIBRARY w/ ext | LIBRARY w/o ext | no LIBRARY
1058// -----+----------------+---------------------+------------------
1059// LINK | {value} | {value}.{.dll/.exe} | {output name}
1060// LIB | {value} | {value}.dll | {output name}.dll
1061//
1062std::string LinkerDriver::getImportName(bool asLib) {
1063 SmallString<128> out;
1064
1065 if (ctx.config.importName.empty()) {
1066 out.assign(RHS: sys::path::filename(path: ctx.config.outputFile));
1067 if (asLib)
1068 sys::path::replace_extension(path&: out, extension: ".dll");
1069 } else {
1070 out.assign(RHS: ctx.config.importName);
1071 if (!sys::path::has_extension(path: out))
1072 sys::path::replace_extension(path&: out,
1073 extension: (ctx.config.dll || asLib) ? ".dll" : ".exe");
1074 }
1075
1076 return std::string(out);
1077}
1078
1079void LinkerDriver::createImportLibrary(bool asLib) {
1080 llvm::TimeTraceScope timeScope("Create import library");
1081 std::vector<COFFShortExport> exports, nativeExports;
1082
1083 auto getExports = [](SymbolTable &symtab,
1084 std::vector<COFFShortExport> &exports) {
1085 for (Export &e1 : symtab.exports) {
1086 COFFShortExport e2;
1087 e2.Name = std::string(e1.name);
1088 e2.SymbolName = std::string(e1.symbolName);
1089 e2.ExtName = std::string(e1.extName);
1090 e2.ExportAs = std::string(e1.exportAs);
1091 e2.ImportName = std::string(e1.importName);
1092 e2.Ordinal = e1.ordinal;
1093 e2.Noname = e1.noname;
1094 e2.Data = e1.data;
1095 e2.Private = e1.isPrivate;
1096 e2.Constant = e1.constant;
1097 exports.push_back(x: e2);
1098 }
1099 };
1100
1101 getExports(ctx.symtab, exports);
1102 if (ctx.config.machine == ARM64X)
1103 getExports(*ctx.hybridSymtab, nativeExports);
1104
1105 std::string libName = getImportName(asLib);
1106 std::string path = getImplibPath();
1107
1108 if (!ctx.config.incremental) {
1109 checkError(e: writeImportLibrary(ImportName: libName, Path: path, Exports: exports, Machine: ctx.config.machine,
1110 MinGW: ctx.config.mingw, NativeExports: nativeExports));
1111 return;
1112 }
1113
1114 // If the import library already exists, replace it only if the contents
1115 // have changed.
1116 ErrorOr<std::unique_ptr<MemoryBuffer>> oldBuf = MemoryBuffer::getFile(
1117 Filename: path, /*IsText=*/false, /*RequiresNullTerminator=*/false);
1118 if (!oldBuf) {
1119 checkError(e: writeImportLibrary(ImportName: libName, Path: path, Exports: exports, Machine: ctx.config.machine,
1120 MinGW: ctx.config.mingw, NativeExports: nativeExports));
1121 return;
1122 }
1123
1124 SmallString<128> tmpName;
1125 if (std::error_code ec =
1126 sys::fs::createUniqueFile(Model: path + ".tmp-%%%%%%%%.lib", ResultPath&: tmpName))
1127 Fatal(ctx) << "cannot create temporary file for import library " << path
1128 << ": " << ec.message();
1129
1130 if (Error e =
1131 writeImportLibrary(ImportName: libName, Path: tmpName, Exports: exports, Machine: ctx.config.machine,
1132 MinGW: ctx.config.mingw, NativeExports: nativeExports)) {
1133 checkError(e: std::move(e));
1134 return;
1135 }
1136
1137 std::unique_ptr<MemoryBuffer> newBuf = check(e: MemoryBuffer::getFile(
1138 Filename: tmpName, /*IsText=*/false, /*RequiresNullTerminator=*/false));
1139 if ((*oldBuf)->getBuffer() != newBuf->getBuffer()) {
1140 oldBuf->reset();
1141 checkError(e: errorCodeToError(EC: sys::fs::rename(from: tmpName, to: path)));
1142 } else {
1143 sys::fs::remove(path: tmpName);
1144 }
1145}
1146
1147void LinkerDriver::enqueueTask(std::function<void()> task) {
1148 taskQueue.push_back(x: std::move(task));
1149}
1150
1151bool LinkerDriver::run() {
1152 llvm::TimeTraceScope timeScope("Read input files");
1153 ScopedTimer t(ctx.inputFileTimer);
1154
1155 bool didWork = !taskQueue.empty();
1156 while (!taskQueue.empty()) {
1157 taskQueue.front()();
1158 taskQueue.pop_front();
1159 }
1160 return didWork;
1161}
1162
1163// Parse an /order file. If an option is given, the linker places
1164// COMDAT sections in the same order as their names appear in the
1165// given file.
1166void LinkerDriver::parseOrderFile(StringRef arg) {
1167 // For some reason, the MSVC linker requires a filename to be
1168 // preceded by "@".
1169 if (!arg.starts_with(Prefix: "@")) {
1170 Err(ctx) << "malformed /order option: '@' missing";
1171 return;
1172 }
1173
1174 // Get a list of all comdat sections for error checking.
1175 DenseSet<StringRef> set;
1176 for (Chunk *c : ctx.driver.getChunks())
1177 if (auto *sec = dyn_cast<SectionChunk>(Val: c))
1178 if (sec->sym)
1179 set.insert(V: sec->sym->getName());
1180
1181 // Open a file.
1182 StringRef path = arg.substr(Start: 1);
1183 std::unique_ptr<MemoryBuffer> mb =
1184 CHECK(MemoryBuffer::getFile(path, /*IsText=*/false,
1185 /*RequiresNullTerminator=*/false,
1186 /*IsVolatile=*/true),
1187 "could not open " + path);
1188
1189 // Parse a file. An order file contains one symbol per line.
1190 // All symbols that were not present in a given order file are
1191 // considered to have the lowest priority 0 and are placed at
1192 // end of an output section.
1193 for (StringRef arg : args::getLines(mb: mb->getMemBufferRef())) {
1194 std::string s(arg);
1195 if (ctx.config.machine == I386 && !isDecorated(sym: s))
1196 s = "_" + s;
1197
1198 if (!set.contains(V: s)) {
1199 if (ctx.config.warnMissingOrderSymbol)
1200 Warn(ctx) << "/order:" << arg << ": missing symbol: " << s
1201 << " [LNK4037]";
1202 } else
1203 ctx.config.order[s] = INT_MIN + ctx.config.order.size();
1204 }
1205
1206 // Include in /reproduce: output if applicable.
1207 ctx.driver.takeBuffer(mb: std::move(mb));
1208}
1209
1210void LinkerDriver::parseCallGraphFile(StringRef path) {
1211 std::unique_ptr<MemoryBuffer> mb =
1212 CHECK(MemoryBuffer::getFile(path, /*IsText=*/false,
1213 /*RequiresNullTerminator=*/false,
1214 /*IsVolatile=*/true),
1215 "could not open " + path);
1216
1217 // Build a map from symbol name to section.
1218 DenseMap<StringRef, Symbol *> map;
1219 for (ObjFile *file : ctx.objFileInstances)
1220 for (Symbol *sym : file->getSymbols())
1221 if (sym)
1222 map[sym->getName()] = sym;
1223
1224 auto findSection = [&](StringRef name) -> SectionChunk * {
1225 Symbol *sym = map.lookup(Val: name);
1226 if (!sym) {
1227 if (ctx.config.warnMissingOrderSymbol)
1228 Warn(ctx) << path << ": no such symbol: " << name;
1229 return nullptr;
1230 }
1231
1232 if (DefinedCOFF *dr = dyn_cast_or_null<DefinedCOFF>(Val: sym))
1233 return dyn_cast_or_null<SectionChunk>(Val: dr->getChunk());
1234 return nullptr;
1235 };
1236
1237 for (StringRef line : args::getLines(mb: *mb)) {
1238 SmallVector<StringRef, 3> fields;
1239 line.split(A&: fields, Separator: ' ');
1240 uint64_t count;
1241
1242 if (fields.size() != 3 || !to_integer(S: fields[2], Num&: count)) {
1243 Err(ctx) << path << ": parse error";
1244 return;
1245 }
1246
1247 if (SectionChunk *from = findSection(fields[0]))
1248 if (SectionChunk *to = findSection(fields[1]))
1249 ctx.config.callGraphProfile[{from, to}] += count;
1250 }
1251
1252 // Include in /reproduce: output if applicable.
1253 ctx.driver.takeBuffer(mb: std::move(mb));
1254}
1255
1256static void readCallGraphsFromObjectFiles(COFFLinkerContext &ctx) {
1257 for (ObjFile *obj : ctx.objFileInstances) {
1258 if (obj->callgraphSec) {
1259 ArrayRef<uint8_t> contents;
1260 cantFail(
1261 Err: obj->getCOFFObj()->getSectionContents(Sec: obj->callgraphSec, Res&: contents));
1262 BinaryStreamReader reader(contents, llvm::endianness::little);
1263 while (!reader.empty()) {
1264 uint32_t fromIndex, toIndex;
1265 uint64_t count;
1266 if (Error err = reader.readInteger(Dest&: fromIndex))
1267 Fatal(ctx) << toString(file: obj) << ": Expected 32-bit integer";
1268 if (Error err = reader.readInteger(Dest&: toIndex))
1269 Fatal(ctx) << toString(file: obj) << ": Expected 32-bit integer";
1270 if (Error err = reader.readInteger(Dest&: count))
1271 Fatal(ctx) << toString(file: obj) << ": Expected 64-bit integer";
1272 auto *fromSym = dyn_cast_or_null<Defined>(Val: obj->getSymbol(symbolIndex: fromIndex));
1273 auto *toSym = dyn_cast_or_null<Defined>(Val: obj->getSymbol(symbolIndex: toIndex));
1274 if (!fromSym || !toSym)
1275 continue;
1276 auto *from = dyn_cast_or_null<SectionChunk>(Val: fromSym->getChunk());
1277 auto *to = dyn_cast_or_null<SectionChunk>(Val: toSym->getChunk());
1278 if (from && to)
1279 ctx.config.callGraphProfile[{from, to}] += count;
1280 }
1281 }
1282 }
1283}
1284
1285static void markAddrsig(Symbol *s) {
1286 if (auto *d = dyn_cast_or_null<Defined>(Val: s))
1287 if (SectionChunk *c = dyn_cast_or_null<SectionChunk>(Val: d->getChunk()))
1288 c->keepUnique = true;
1289}
1290
1291static void findKeepUniqueSections(COFFLinkerContext &ctx) {
1292 llvm::TimeTraceScope timeScope("Find keep unique sections");
1293
1294 // Exported symbols could be address-significant in other executables or DSOs,
1295 // so we conservatively mark them as address-significant.
1296 ctx.forEachSymtab(f: [](SymbolTable &symtab) {
1297 for (Export &r : symtab.exports)
1298 markAddrsig(s: r.sym);
1299 });
1300
1301 // Visit the address-significance table in each object file and mark each
1302 // referenced symbol as address-significant.
1303 for (ObjFile *obj : ctx.objFileInstances) {
1304 ArrayRef<Symbol *> syms = obj->getSymbols();
1305 if (obj->addrsigSec) {
1306 ArrayRef<uint8_t> contents;
1307 cantFail(
1308 Err: obj->getCOFFObj()->getSectionContents(Sec: obj->addrsigSec, Res&: contents));
1309 const uint8_t *cur = contents.begin();
1310 while (cur != contents.end()) {
1311 unsigned size;
1312 const char *err = nullptr;
1313 uint64_t symIndex = decodeULEB128(p: cur, n: &size, end: contents.end(), error: &err);
1314 if (err)
1315 Fatal(ctx) << toString(file: obj)
1316 << ": could not decode addrsig section: " << err;
1317 if (symIndex >= syms.size())
1318 Fatal(ctx) << toString(file: obj)
1319 << ": invalid symbol index in addrsig section";
1320 markAddrsig(s: syms[symIndex]);
1321 cur += size;
1322 }
1323 } else {
1324 // If an object file does not have an address-significance table,
1325 // conservatively mark all of its symbols as address-significant.
1326 for (Symbol *s : syms)
1327 markAddrsig(s);
1328 }
1329 }
1330}
1331
1332// link.exe replaces each %foo% in altPath with the contents of environment
1333// variable foo, and adds the two magic env vars _PDB (expands to the basename
1334// of pdb's output path) and _EXT (expands to the extension of the output
1335// binary).
1336// lld only supports %_PDB% and %_EXT% and warns on references to all other env
1337// vars.
1338void LinkerDriver::parsePDBAltPath() {
1339 SmallString<128> buf;
1340 StringRef pdbBasename =
1341 sys::path::filename(path: ctx.config.pdbPath, style: sys::path::Style::windows);
1342 StringRef binaryExtension =
1343 sys::path::extension(path: ctx.config.outputFile, style: sys::path::Style::windows);
1344 if (!binaryExtension.empty())
1345 binaryExtension = binaryExtension.substr(Start: 1); // %_EXT% does not include '.'.
1346
1347 // Invariant:
1348 // +--------- cursor ('a...' might be the empty string).
1349 // | +----- firstMark
1350 // | | +- secondMark
1351 // v v v
1352 // a...%...%...
1353 size_t cursor = 0;
1354 while (cursor < ctx.config.pdbAltPath.size()) {
1355 size_t firstMark, secondMark;
1356 if ((firstMark = ctx.config.pdbAltPath.find(C: '%', From: cursor)) ==
1357 StringRef::npos ||
1358 (secondMark = ctx.config.pdbAltPath.find(C: '%', From: firstMark + 1)) ==
1359 StringRef::npos) {
1360 // Didn't find another full fragment, treat rest of string as literal.
1361 buf.append(RHS: ctx.config.pdbAltPath.substr(Start: cursor));
1362 break;
1363 }
1364
1365 // Found a full fragment. Append text in front of first %, and interpret
1366 // text between first and second % as variable name.
1367 buf.append(RHS: ctx.config.pdbAltPath.substr(Start: cursor, N: firstMark - cursor));
1368 StringRef var =
1369 ctx.config.pdbAltPath.substr(Start: firstMark, N: secondMark - firstMark + 1);
1370 if (var.equals_insensitive(RHS: "%_pdb%"))
1371 buf.append(RHS: pdbBasename);
1372 else if (var.equals_insensitive(RHS: "%_ext%"))
1373 buf.append(RHS: binaryExtension);
1374 else {
1375 Warn(ctx) << "only %_PDB% and %_EXT% supported in /pdbaltpath:, keeping "
1376 << var << " as literal";
1377 buf.append(RHS: var);
1378 }
1379
1380 cursor = secondMark + 1;
1381 }
1382
1383 ctx.config.pdbAltPath = std::move(buf);
1384}
1385
1386/// Convert resource files and potentially merge input resource object
1387/// trees into one resource tree.
1388/// Call after ObjFile::Instances is complete.
1389void LinkerDriver::convertResources() {
1390 llvm::TimeTraceScope timeScope("Convert resources");
1391 std::vector<ObjFile *> resourceObjFiles;
1392
1393 for (ObjFile *f : ctx.objFileInstances) {
1394 if (f->isResourceObjFile())
1395 resourceObjFiles.push_back(x: f);
1396 }
1397
1398 if (!ctx.config.mingw &&
1399 (resourceObjFiles.size() > 1 ||
1400 (resourceObjFiles.size() == 1 && !resources.empty()))) {
1401 Err(ctx) << (!resources.empty()
1402 ? "internal .obj file created from .res files"
1403 : toString(file: resourceObjFiles[1]))
1404 << ": more than one resource obj file not allowed, already got "
1405 << resourceObjFiles.front();
1406 return;
1407 }
1408
1409 if (resources.empty() && resourceObjFiles.size() <= 1) {
1410 // No resources to convert, and max one resource object file in
1411 // the input. Keep that preconverted resource section as is.
1412 for (ObjFile *f : resourceObjFiles)
1413 f->includeResourceChunks();
1414 return;
1415 }
1416 ObjFile *f =
1417 ObjFile::create(ctx, mb: convertResToCOFF(mbs: resources, objs: resourceObjFiles));
1418 addFile(file: f);
1419 f->includeResourceChunks();
1420}
1421
1422void LinkerDriver::maybeCreateECExportThunk(StringRef name, Symbol *&sym) {
1423 if (!sym)
1424 return;
1425 Defined *def = sym->getDefined();
1426 if (!def)
1427 return;
1428
1429 if (def->getChunk()->getArm64ECRangeType() != chpe_range_type::Arm64EC)
1430 return;
1431 StringRef expName;
1432 if (auto mangledName = getArm64ECMangledFunctionName(Name: name))
1433 expName = saver().save(S: "EXP+" + *mangledName);
1434 else
1435 expName = saver().save(S: "EXP+" + name);
1436 sym = ctx.symtab.addGCRoot(sym: expName);
1437 if (auto undef = dyn_cast<Undefined>(Val: sym)) {
1438 if (!undef->getWeakAlias()) {
1439 auto thunk = make<ECExportThunkChunk>(args&: def);
1440 replaceSymbol<DefinedSynthetic>(s: undef, arg: undef->getName(), arg&: thunk);
1441 }
1442 }
1443}
1444
1445void LinkerDriver::createECExportThunks() {
1446 // Check if EXP+ symbols have corresponding $hp_target symbols and use them
1447 // to create export thunks when available.
1448 for (Symbol *s : ctx.symtab.expSymbols) {
1449 if (!s->isUsedInRegularObj)
1450 continue;
1451 assert(s->getName().starts_with("EXP+"));
1452 std::string targetName =
1453 (s->getName().substr(Start: strlen(s: "EXP+")) + "$hp_target").str();
1454 Symbol *sym = ctx.symtab.find(name: targetName);
1455 if (!sym)
1456 continue;
1457 Defined *targetSym = sym->getDefined();
1458 if (!targetSym)
1459 continue;
1460
1461 auto *undef = dyn_cast<Undefined>(Val: s);
1462 if (undef && !undef->getWeakAlias()) {
1463 auto thunk = make<ECExportThunkChunk>(args&: targetSym);
1464 replaceSymbol<DefinedSynthetic>(s: undef, arg: undef->getName(), arg&: thunk);
1465 }
1466 if (!targetSym->isGCRoot) {
1467 targetSym->isGCRoot = true;
1468 ctx.config.gcroot.push_back(x: targetSym);
1469 }
1470 }
1471
1472 if (ctx.symtab.entry)
1473 maybeCreateECExportThunk(name: ctx.symtab.entry->getName(), sym&: ctx.symtab.entry);
1474 for (Export &e : ctx.symtab.exports) {
1475 if (!e.data)
1476 maybeCreateECExportThunk(name: e.extName.empty() ? e.name : e.extName, sym&: e.sym);
1477 }
1478}
1479
1480void LinkerDriver::pullArm64ECIcallHelper() {
1481 if (!ctx.config.arm64ECIcallHelper)
1482 ctx.config.arm64ECIcallHelper =
1483 ctx.symtab.addGCRoot(sym: "__icall_helper_arm64ec");
1484}
1485
1486// In MinGW, if no symbols are chosen to be exported, then all symbols are
1487// automatically exported by default. This behavior can be forced by the
1488// -export-all-symbols option, so that it happens even when exports are
1489// explicitly specified. The automatic behavior can be disabled using the
1490// -exclude-all-symbols option, so that lld-link behaves like link.exe rather
1491// than MinGW in the case that nothing is explicitly exported.
1492void LinkerDriver::maybeExportMinGWSymbols(const opt::InputArgList &args) {
1493 if (!args.hasArg(Ids: OPT_export_all_symbols)) {
1494 if (!ctx.config.dll)
1495 return;
1496
1497 if (ctx.symtab.hadExplicitExports ||
1498 (ctx.config.machine == ARM64X && ctx.hybridSymtab->hadExplicitExports))
1499 return;
1500 if (args.hasArg(Ids: OPT_exclude_all_symbols))
1501 return;
1502 }
1503
1504 ctx.forEachActiveSymtab(f: [&](SymbolTable &symtab) {
1505 AutoExporter exporter(symtab, excludedSymbols);
1506
1507 for (auto *arg : args.filtered(Ids: OPT_wholearchive_file))
1508 if (std::optional<StringRef> path = findFile(filename: arg->getValue()))
1509 exporter.addWholeArchive(path: *path);
1510
1511 for (auto *arg : args.filtered(Ids: OPT_exclude_symbols)) {
1512 SmallVector<StringRef, 2> vec;
1513 StringRef(arg->getValue()).split(A&: vec, Separator: ',');
1514 for (StringRef sym : vec)
1515 exporter.addExcludedSymbol(symbol: symtab.mangle(sym));
1516 }
1517
1518 symtab.forEachSymbol(callback: [&](Symbol *s) {
1519 auto *def = dyn_cast<Defined>(Val: s);
1520 if (!exporter.shouldExport(sym: def))
1521 return;
1522
1523 if (!def->isGCRoot) {
1524 def->isGCRoot = true;
1525 ctx.config.gcroot.push_back(x: def);
1526 }
1527
1528 Export e;
1529 e.name = def->getName();
1530 e.sym = def;
1531 e.source = ExportSource::ExportAll;
1532 if (Chunk *c = def->getChunk())
1533 if (!(c->getOutputCharacteristics() & IMAGE_SCN_MEM_EXECUTE))
1534 e.data = true;
1535 s->isUsedInRegularObj = true;
1536 symtab.exports.push_back(x: e);
1537 });
1538 });
1539}
1540
1541// lld has a feature to create a tar file containing all input files as well as
1542// all command line options, so that other people can run lld again with exactly
1543// the same inputs. This feature is accessible via /linkrepro and /reproduce.
1544//
1545// /linkrepro and /reproduce are very similar, but /linkrepro takes a directory
1546// name while /reproduce takes a full path. We have /linkrepro for compatibility
1547// with Microsoft link.exe.
1548std::optional<std::string> getReproduceFile(const opt::InputArgList &args) {
1549 if (auto *arg = args.getLastArg(Ids: OPT_reproduce))
1550 return std::string(arg->getValue());
1551
1552 if (auto *arg = args.getLastArg(Ids: OPT_linkrepro)) {
1553 SmallString<64> path = StringRef(arg->getValue());
1554 sys::path::append(path, a: "repro.tar");
1555 return std::string(path);
1556 }
1557
1558 // This is intentionally not guarded by OPT_lldignoreenv since writing
1559 // a repro tar file doesn't affect the main output.
1560 if (auto *path = getenv(name: "LLD_REPRODUCE"))
1561 return std::string(path);
1562
1563 return std::nullopt;
1564}
1565
1566static std::unique_ptr<llvm::vfs::FileSystem>
1567getVFS(COFFLinkerContext &ctx, const opt::InputArgList &args) {
1568 using namespace llvm::vfs;
1569
1570 const opt::Arg *arg = args.getLastArg(Ids: OPT_vfsoverlay);
1571 if (!arg)
1572 return nullptr;
1573
1574 auto bufOrErr = llvm::MemoryBuffer::getFile(Filename: arg->getValue());
1575 if (!bufOrErr) {
1576 checkError(e: errorCodeToError(EC: bufOrErr.getError()));
1577 return nullptr;
1578 }
1579
1580 if (auto ret = vfs::getVFSFromYAML(Buffer: std::move(*bufOrErr),
1581 /*DiagHandler*/ nullptr, YAMLFilePath: arg->getValue()))
1582 return ret;
1583
1584 Err(ctx) << "Invalid vfs overlay";
1585 return nullptr;
1586}
1587
1588static StringRef DllDefaultEntryPoint(MachineTypes machine, bool mingw) {
1589 if (mingw) {
1590 return (machine == I386) ? "_DllMainCRTStartup@12" : "DllMainCRTStartup";
1591 } else {
1592 return (machine == I386) ? "__DllMainCRTStartup@12" : "_DllMainCRTStartup";
1593 }
1594}
1595
1596constexpr const char *lldsaveTempsValues[] = {
1597 "resolution", "preopt", "promote", "internalize", "import",
1598 "opt", "precodegen", "prelink", "combinedindex"};
1599
1600void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
1601 ScopedTimer rootTimer(ctx.rootTimer);
1602 Configuration *config = &ctx.config;
1603
1604 // Needed for LTO.
1605 InitializeAllTargetInfos();
1606 InitializeAllTargets();
1607 InitializeAllTargetMCs();
1608 InitializeAllAsmParsers();
1609 InitializeAllAsmPrinters();
1610
1611 // If the first command line argument is "/lib", link.exe acts like lib.exe.
1612 // We call our own implementation of lib.exe that understands bitcode files.
1613 if (argsArr.size() > 1 &&
1614 (StringRef(argsArr[1]).equals_insensitive(RHS: "/lib") ||
1615 StringRef(argsArr[1]).equals_insensitive(RHS: "-lib"))) {
1616 if (llvm::libDriverMain(ARgs: argsArr.slice(N: 1)) != 0)
1617 Fatal(ctx) << "lib failed";
1618 return;
1619 }
1620
1621 // Parse command line options.
1622 ArgParser parser(ctx);
1623 opt::InputArgList args = parser.parse(args: argsArr);
1624
1625 // Initialize time trace profiler.
1626 config->timeTraceEnabled = args.hasArg(Ids: OPT_time_trace_eq);
1627 config->timeTraceGranularity =
1628 args::getInteger(args, key: OPT_time_trace_granularity_eq, Default: 500);
1629
1630 if (config->timeTraceEnabled)
1631 timeTraceProfilerInitialize(TimeTraceGranularity: config->timeTraceGranularity, ProcName: argsArr[0]);
1632
1633 llvm::TimeTraceScope timeScope("COFF link");
1634
1635 // Parse and evaluate -mllvm options.
1636 std::vector<const char *> v;
1637 v.push_back(x: "lld-link (LLVM option parsing)");
1638 for (const auto *arg : args.filtered(Ids: OPT_mllvm)) {
1639 v.push_back(x: arg->getValue());
1640 config->mllvmOpts.emplace_back(Args: arg->getValue());
1641 }
1642 {
1643 llvm::TimeTraceScope timeScope2("Parse cl::opt");
1644 cl::ResetAllOptionOccurrences();
1645 cl::ParseCommandLineOptions(argc: v.size(), argv: v.data());
1646 }
1647
1648 // Handle /errorlimit early, because error() depends on it.
1649 if (auto *arg = args.getLastArg(Ids: OPT_errorlimit)) {
1650 int n = 20;
1651 StringRef s = arg->getValue();
1652 if (s.getAsInteger(Radix: 10, Result&: n))
1653 Err(ctx) << arg->getSpelling() << " number expected, but got " << s;
1654 ctx.e.errorLimit = n;
1655 }
1656
1657 config->vfs = getVFS(ctx, args);
1658
1659 // Handle /help
1660 if (args.hasArg(Ids: OPT_help)) {
1661 printHelp(argv0: argsArr[0]);
1662 return;
1663 }
1664
1665 // /threads: takes a positive integer and provides the default value for
1666 // /opt:lldltojobs=.
1667 if (auto *arg = args.getLastArg(Ids: OPT_threads)) {
1668 StringRef v(arg->getValue());
1669 unsigned threads = 0;
1670 if (!llvm::to_integer(S: v, Num&: threads, Base: 0) || threads == 0)
1671 Err(ctx) << arg->getSpelling()
1672 << ": expected a positive integer, but got '" << arg->getValue()
1673 << "'";
1674 parallel::strategy = hardware_concurrency(ThreadCount: threads);
1675 config->thinLTOJobs = v.str();
1676 }
1677
1678 if (args.hasArg(Ids: OPT_show_timing))
1679 config->showTiming = true;
1680
1681 config->showSummary = args.hasArg(Ids: OPT_summary);
1682 config->printSearchPaths = args.hasArg(Ids: OPT_print_search_paths);
1683
1684 // Handle --version, which is an lld extension. This option is a bit odd
1685 // because it doesn't start with "/", but we deliberately chose "--" to
1686 // avoid conflict with /version and for compatibility with clang-cl.
1687 if (args.hasArg(Ids: OPT_dash_dash_version)) {
1688 Msg(ctx) << getLLDVersion();
1689 return;
1690 }
1691
1692 // Handle /lldmingw early, since it can potentially affect how other
1693 // options are handled.
1694 config->mingw = args.hasArg(Ids: OPT_lldmingw);
1695 if (config->mingw)
1696 ctx.e.errorLimitExceededMsg = "too many errors emitted, stopping now"
1697 " (use --error-limit=0 to see all errors)";
1698
1699 // Handle /linkrepro and /reproduce.
1700 {
1701 llvm::TimeTraceScope timeScope2("Reproducer");
1702 if (std::optional<std::string> path = getReproduceFile(args)) {
1703 Expected<std::unique_ptr<TarWriter>> errOrWriter =
1704 TarWriter::create(OutputPath: *path, BaseDir: sys::path::stem(path: *path));
1705
1706 if (errOrWriter) {
1707 tar = std::move(*errOrWriter);
1708 } else {
1709 Err(ctx) << "/linkrepro: failed to open " << *path << ": "
1710 << toString(E: errOrWriter.takeError());
1711 }
1712 }
1713 }
1714 // Handle /linkreprofullpathrsp
1715 if (auto *arg = args.getLastArg(Ids: OPT_linkreprofullpathrsp)) {
1716 std::error_code ec;
1717 reproFile = std::make_unique<raw_fd_ostream>(args: arg->getValue(), args&: ec);
1718 if (ec) {
1719 Err(ctx) << "cannot open " << arg->getValue() << ": " << ec.message();
1720 reproFile.reset();
1721 }
1722 }
1723
1724 if (!args.hasArg(Ids: OPT_INPUT, Ids: OPT_wholearchive_file)) {
1725 if (args.hasArg(Ids: OPT_deffile))
1726 config->noEntry = true;
1727 else
1728 Fatal(ctx) << "no input files";
1729 }
1730
1731 // Construct search path list.
1732 {
1733 llvm::TimeTraceScope timeScope2("Search paths");
1734 searchPaths.emplace_back(args: "");
1735 for (auto *arg : args.filtered(Ids: OPT_libpath))
1736 searchPaths.push_back(x: arg->getValue());
1737 if (!config->mingw) {
1738 // Prefer the Clang provided builtins over the ones bundled with MSVC.
1739 // In MinGW mode, the compiler driver passes the necessary libpath
1740 // options explicitly.
1741 addClangLibSearchPaths(argv0: argsArr[0]);
1742 // Don't automatically deduce the lib path from the environment or MSVC
1743 // installations when operating in mingw mode. (This also makes LLD ignore
1744 // winsysroot and vctoolsdir arguments.)
1745 detectWinSysRoot(Args: args);
1746 if (!args.hasArg(Ids: OPT_lldignoreenv, Ids: OPT_winsysroot, Ids: OPT_vctoolsdir,
1747 Ids: OPT_vctoolsversion, Ids: OPT_winsdkdir, Ids: OPT_winsdkversion))
1748 addLibSearchPaths();
1749 } else {
1750 if (args.hasArg(Ids: OPT_vctoolsdir, Ids: OPT_winsysroot))
1751 Warn(ctx) << "ignoring /vctoolsdir or /winsysroot flags in MinGW mode";
1752 }
1753 }
1754
1755 // Handle /ignore
1756 for (auto *arg : args.filtered(Ids: OPT_ignore)) {
1757 SmallVector<StringRef, 8> vec;
1758 StringRef(arg->getValue()).split(A&: vec, Separator: ',');
1759 for (StringRef s : vec) {
1760 if (s == "4037")
1761 config->warnMissingOrderSymbol = false;
1762 else if (s == "4099")
1763 config->warnDebugInfoUnusable = false;
1764 else if (s == "4217")
1765 config->warnLocallyDefinedImported = false;
1766 else if (s == "longsections")
1767 config->warnLongSectionNames = false;
1768 else if (s == "importeddllmain")
1769 config->warnImportedDllMain = false;
1770 // Other warning numbers are ignored.
1771 }
1772 }
1773
1774 // Handle /out
1775 if (auto *arg = args.getLastArg(Ids: OPT_out))
1776 config->outputFile = arg->getValue();
1777
1778 // Handle /verbose
1779 if (args.hasArg(Ids: OPT_verbose))
1780 config->verbose = true;
1781 ctx.e.verbose = config->verbose;
1782
1783 // Handle /force or /force:unresolved
1784 if (args.hasArg(Ids: OPT_force, Ids: OPT_force_unresolved))
1785 config->forceUnresolved = true;
1786
1787 // Handle /force or /force:multiple
1788 if (args.hasArg(Ids: OPT_force, Ids: OPT_force_multiple))
1789 config->forceMultiple = true;
1790
1791 // Handle /force or /force:multipleres
1792 if (args.hasArg(Ids: OPT_force, Ids: OPT_force_multipleres))
1793 config->forceMultipleRes = true;
1794
1795 // Don't warn about long section names, such as .debug_info, for mingw (or
1796 // when -debug:dwarf is requested, handled below).
1797 if (config->mingw)
1798 config->warnLongSectionNames = false;
1799
1800 bool doGC = true;
1801
1802 // Handle /debug
1803 bool shouldCreatePDB = false;
1804 for (auto *arg : args.filtered(Ids: OPT_debug, Ids: OPT_debug_opt)) {
1805 std::string str;
1806 if (arg->getOption().getID() == OPT_debug)
1807 str = "full";
1808 else
1809 str = StringRef(arg->getValue()).lower();
1810 SmallVector<StringRef, 1> vec;
1811 StringRef(str).split(A&: vec, Separator: ',');
1812 for (StringRef s : vec) {
1813 if (s == "fastlink") {
1814 Warn(ctx) << "/debug:fastlink unsupported; using /debug:full";
1815 s = "full";
1816 }
1817 if (s == "none") {
1818 config->debug = false;
1819 config->incremental = false;
1820 config->includeDwarfChunks = false;
1821 config->debugGHashes = false;
1822 config->writeSymtab = false;
1823 shouldCreatePDB = false;
1824 doGC = true;
1825 } else if (s == "full" || s == "ghash" || s == "noghash") {
1826 config->debug = true;
1827 config->incremental = true;
1828 config->includeDwarfChunks = true;
1829 if (s == "full" || s == "ghash")
1830 config->debugGHashes = true;
1831 shouldCreatePDB = true;
1832 doGC = false;
1833 } else if (s == "dwarf") {
1834 config->debug = true;
1835 config->incremental = true;
1836 config->includeDwarfChunks = true;
1837 config->writeSymtab = true;
1838 config->warnLongSectionNames = false;
1839 doGC = false;
1840 } else if (s == "nodwarf") {
1841 config->includeDwarfChunks = false;
1842 } else if (s == "symtab") {
1843 config->writeSymtab = true;
1844 doGC = false;
1845 } else if (s == "nosymtab") {
1846 config->writeSymtab = false;
1847 } else {
1848 Err(ctx) << "/debug: unknown option: " << s;
1849 }
1850 }
1851 }
1852
1853 // Handle /demangle
1854 config->demangle = args.hasFlag(Pos: OPT_demangle, Neg: OPT_demangle_no, Default: true);
1855
1856 // Handle /debugtype
1857 config->debugTypes = parseDebugTypes(ctx, args);
1858
1859 // Handle /driver[:uponly|:wdm].
1860 config->driverUponly = args.hasArg(Ids: OPT_driver_uponly) ||
1861 args.hasArg(Ids: OPT_driver_uponly_wdm) ||
1862 args.hasArg(Ids: OPT_driver_wdm_uponly);
1863 config->driverWdm = args.hasArg(Ids: OPT_driver_wdm) ||
1864 args.hasArg(Ids: OPT_driver_uponly_wdm) ||
1865 args.hasArg(Ids: OPT_driver_wdm_uponly);
1866 config->driver =
1867 config->driverUponly || config->driverWdm || args.hasArg(Ids: OPT_driver);
1868
1869 // Handle /pdb
1870 if (shouldCreatePDB) {
1871 if (auto *arg = args.getLastArg(Ids: OPT_pdb))
1872 config->pdbPath = arg->getValue();
1873 if (auto *arg = args.getLastArg(Ids: OPT_pdbaltpath))
1874 config->pdbAltPath = arg->getValue();
1875 if (auto *arg = args.getLastArg(Ids: OPT_pdbpagesize))
1876 parsePDBPageSize(arg->getValue());
1877 if (args.hasArg(Ids: OPT_natvis))
1878 config->natvisFiles = args.getAllArgValues(Id: OPT_natvis);
1879 if (args.hasArg(Ids: OPT_pdbstream)) {
1880 for (const StringRef value : args.getAllArgValues(Id: OPT_pdbstream)) {
1881 const std::pair<StringRef, StringRef> nameFile = value.split(Separator: "=");
1882 const StringRef name = nameFile.first;
1883 const std::string file = nameFile.second.str();
1884 config->namedStreams[name] = file;
1885 }
1886 }
1887
1888 if (auto *arg = args.getLastArg(Ids: OPT_pdb_source_path))
1889 config->pdbSourcePath = arg->getValue();
1890 }
1891
1892 // Handle /pdbstripped
1893 if (args.hasArg(Ids: OPT_pdbstripped))
1894 Warn(ctx) << "ignoring /pdbstripped flag, it is not yet supported";
1895
1896 // Handle /noentry
1897 if (args.hasArg(Ids: OPT_noentry)) {
1898 if (args.hasArg(Ids: OPT_dll))
1899 config->noEntry = true;
1900 else
1901 Err(ctx) << "/noentry must be specified with /dll";
1902 }
1903
1904 // Handle /dll
1905 if (args.hasArg(Ids: OPT_dll)) {
1906 config->dll = true;
1907 config->manifestID = 2;
1908 }
1909
1910 // Handle /dynamicbase and /fixed. We can't use hasFlag for /dynamicbase
1911 // because we need to explicitly check whether that option or its inverse was
1912 // present in the argument list in order to handle /fixed.
1913 auto *dynamicBaseArg = args.getLastArg(Ids: OPT_dynamicbase, Ids: OPT_dynamicbase_no);
1914 if (dynamicBaseArg &&
1915 dynamicBaseArg->getOption().getID() == OPT_dynamicbase_no)
1916 config->dynamicBase = false;
1917
1918 // MSDN claims "/FIXED:NO is the default setting for a DLL, and /FIXED is the
1919 // default setting for any other project type.", but link.exe defaults to
1920 // /FIXED:NO for exe outputs as well. Match behavior, not docs.
1921 bool fixed = args.hasFlag(Pos: OPT_fixed, Neg: OPT_fixed_no, Default: false);
1922 if (fixed) {
1923 if (dynamicBaseArg &&
1924 dynamicBaseArg->getOption().getID() == OPT_dynamicbase) {
1925 Err(ctx) << "/fixed must not be specified with /dynamicbase";
1926 } else {
1927 config->relocatable = false;
1928 config->dynamicBase = false;
1929 }
1930 }
1931
1932 // Handle /appcontainer
1933 config->appContainer =
1934 args.hasFlag(Pos: OPT_appcontainer, Neg: OPT_appcontainer_no, Default: false);
1935
1936 // Handle /machine
1937 {
1938 llvm::TimeTraceScope timeScope2("Machine arg");
1939 if (auto *arg = args.getLastArg(Ids: OPT_machine)) {
1940 MachineTypes machine = getMachineType(S: arg->getValue());
1941 if (machine == IMAGE_FILE_MACHINE_UNKNOWN)
1942 Fatal(ctx) << "unknown /machine argument: " << arg->getValue();
1943 setMachine(machine);
1944 }
1945 }
1946
1947 // Handle /nodefaultlib:<filename>
1948 {
1949 llvm::TimeTraceScope timeScope2("Nodefaultlib");
1950 for (auto *arg : args.filtered(Ids: OPT_nodefaultlib))
1951 config->noDefaultLibs.insert(key: findLib(filename: arg->getValue()).lower());
1952 }
1953
1954 // Handle /nodefaultlib
1955 if (args.hasArg(Ids: OPT_nodefaultlib_all))
1956 config->noDefaultLibAll = true;
1957
1958 // Handle /base
1959 if (auto *arg = args.getLastArg(Ids: OPT_base))
1960 parseNumbers(arg: arg->getValue(), addr: &config->imageBase);
1961
1962 // Handle /filealign
1963 if (auto *arg = args.getLastArg(Ids: OPT_filealign)) {
1964 parseNumbers(arg: arg->getValue(), addr: &config->fileAlign);
1965 if (!isPowerOf2_64(Value: config->fileAlign))
1966 Err(ctx) << "/filealign: not a power of two: " << config->fileAlign;
1967 }
1968
1969 // Handle /stack
1970 if (auto *arg = args.getLastArg(Ids: OPT_stack))
1971 parseNumbers(arg: arg->getValue(), addr: &config->stackReserve, size: &config->stackCommit);
1972
1973 // Handle /guard:cf
1974 if (auto *arg = args.getLastArg(Ids: OPT_guard))
1975 parseGuard(arg: arg->getValue());
1976
1977 // Handle /heap
1978 if (auto *arg = args.getLastArg(Ids: OPT_heap))
1979 parseNumbers(arg: arg->getValue(), addr: &config->heapReserve, size: &config->heapCommit);
1980
1981 // Handle /version
1982 if (auto *arg = args.getLastArg(Ids: OPT_version))
1983 parseVersion(arg: arg->getValue(), major: &config->majorImageVersion,
1984 minor: &config->minorImageVersion);
1985
1986 // Handle /subsystem
1987 if (auto *arg = args.getLastArg(Ids: OPT_subsystem))
1988 parseSubsystem(arg: arg->getValue(), sys: &config->subsystem,
1989 major: &config->majorSubsystemVersion,
1990 minor: &config->minorSubsystemVersion);
1991
1992 // Handle /osversion
1993 if (auto *arg = args.getLastArg(Ids: OPT_osversion)) {
1994 parseVersion(arg: arg->getValue(), major: &config->majorOSVersion,
1995 minor: &config->minorOSVersion);
1996 } else {
1997 config->majorOSVersion = config->majorSubsystemVersion;
1998 config->minorOSVersion = config->minorSubsystemVersion;
1999 }
2000
2001 // Handle /timestamp
2002 if (llvm::opt::Arg *arg = args.getLastArg(Ids: OPT_timestamp, Ids: OPT_repro)) {
2003 if (arg->getOption().getID() == OPT_repro) {
2004 config->timestamp = 0;
2005 config->repro = true;
2006 } else {
2007 config->repro = false;
2008 StringRef value(arg->getValue());
2009 if (value.getAsInteger(Radix: 0, Result&: config->timestamp))
2010 Fatal(ctx) << "invalid timestamp: " << value
2011 << ". Expected 32-bit integer";
2012 }
2013 } else {
2014 config->repro = false;
2015 if (std::optional<std::string> epoch =
2016 Process::GetEnv(name: "SOURCE_DATE_EPOCH")) {
2017 StringRef value(*epoch);
2018 if (value.getAsInteger(Radix: 0, Result&: config->timestamp))
2019 Fatal(ctx) << "invalid SOURCE_DATE_EPOCH timestamp: " << value
2020 << ". Expected 32-bit integer";
2021 } else {
2022 config->timestamp = time(timer: nullptr);
2023 }
2024 }
2025
2026 // Handle /alternatename
2027 for (auto *arg : args.filtered(Ids: OPT_alternatename))
2028 ctx.symtab.parseAlternateName(arg->getValue());
2029
2030 // Handle /include
2031 for (auto *arg : args.filtered(Ids: OPT_incl))
2032 ctx.symtab.addGCRoot(sym: arg->getValue());
2033
2034 // Handle /implib
2035 if (auto *arg = args.getLastArg(Ids: OPT_implib))
2036 config->implib = arg->getValue();
2037
2038 config->noimplib = args.hasArg(Ids: OPT_noimplib);
2039
2040 if (args.hasArg(Ids: OPT_profile))
2041 doGC = true;
2042 // Handle /opt.
2043 std::optional<ICFLevel> icfLevel;
2044 if (args.hasArg(Ids: OPT_profile))
2045 icfLevel = ICFLevel::None;
2046 unsigned tailMerge = 1;
2047 bool ltoDebugPM = false;
2048 for (auto *arg : args.filtered(Ids: OPT_opt)) {
2049 std::string str = StringRef(arg->getValue()).lower();
2050 SmallVector<StringRef, 1> vec;
2051 StringRef(str).split(A&: vec, Separator: ',');
2052 for (StringRef s : vec) {
2053 if (s == "ref") {
2054 doGC = true;
2055 } else if (s == "noref") {
2056 doGC = false;
2057 } else if (s == "icf" || s.starts_with(Prefix: "icf=")) {
2058 icfLevel = ICFLevel::All;
2059 } else if (s == "safeicf") {
2060 icfLevel = ICFLevel::Safe;
2061 } else if (s == "noicf") {
2062 icfLevel = ICFLevel::None;
2063 } else if (s == "lldtailmerge") {
2064 tailMerge = 2;
2065 } else if (s == "nolldtailmerge") {
2066 tailMerge = 0;
2067 } else if (s == "ltodebugpassmanager") {
2068 ltoDebugPM = true;
2069 } else if (s == "noltodebugpassmanager") {
2070 ltoDebugPM = false;
2071 } else if (s.consume_front(Prefix: "lldlto=")) {
2072 if (s.getAsInteger(Radix: 10, Result&: config->ltoo) || config->ltoo > 3)
2073 Err(ctx) << "/opt:lldlto: invalid optimization level: " << s;
2074 } else if (s.consume_front(Prefix: "lldltocgo=")) {
2075 config->ltoCgo.emplace();
2076 if (s.getAsInteger(Radix: 10, Result&: *config->ltoCgo) || *config->ltoCgo > 3)
2077 Err(ctx) << "/opt:lldltocgo: invalid codegen optimization level: "
2078 << s;
2079 } else if (s.consume_front(Prefix: "lldltojobs=")) {
2080 if (!get_threadpool_strategy(Num: s))
2081 Err(ctx) << "/opt:lldltojobs: invalid job count: " << s;
2082 config->thinLTOJobs = s.str();
2083 } else if (s.consume_front(Prefix: "lldltopartitions=")) {
2084 if (s.getAsInteger(Radix: 10, Result&: config->ltoPartitions) ||
2085 config->ltoPartitions == 0)
2086 Err(ctx) << "/opt:lldltopartitions: invalid partition count: " << s;
2087 } else if (s != "lbr" && s != "nolbr")
2088 Err(ctx) << "/opt: unknown option: " << s;
2089 }
2090 }
2091
2092 if (!icfLevel)
2093 icfLevel = doGC ? ICFLevel::All : ICFLevel::None;
2094 config->doGC = doGC;
2095 config->doICF = *icfLevel;
2096 config->tailMerge =
2097 (tailMerge == 1 && config->doICF != ICFLevel::None) || tailMerge == 2;
2098 config->ltoDebugPassManager = ltoDebugPM;
2099
2100 // Handle /lldsavetemps
2101 if (args.hasArg(Ids: OPT_lldsavetemps)) {
2102 config->saveTempsArgs.insert_range(R: lldsaveTempsValues);
2103 } else {
2104 for (auto *arg : args.filtered(Ids: OPT_lldsavetemps_colon)) {
2105 StringRef s = arg->getValue();
2106 if (llvm::is_contained(Range: lldsaveTempsValues, Element: s))
2107 config->saveTempsArgs.insert(V: s);
2108 else
2109 Err(ctx) << "unknown /lldsavetemps value: " << s;
2110 }
2111 }
2112
2113 // Handle /lldemit
2114 if (auto *arg = args.getLastArg(Ids: OPT_lldemit)) {
2115 StringRef s = arg->getValue();
2116 if (s == "obj")
2117 config->emit = EmitKind::Obj;
2118 else if (s == "llvm")
2119 config->emit = EmitKind::LLVM;
2120 else if (s == "asm")
2121 config->emit = EmitKind::ASM;
2122 else
2123 Err(ctx) << "/lldemit: unknown option: " << s;
2124 }
2125
2126 // Handle /kill-at
2127 if (args.hasArg(Ids: OPT_kill_at))
2128 config->killAt = true;
2129
2130 // Handle /lldltocache
2131 if (auto *arg = args.getLastArg(Ids: OPT_lldltocache))
2132 config->ltoCache = arg->getValue();
2133
2134 // Handle /lldsavecachepolicy
2135 if (auto *arg = args.getLastArg(Ids: OPT_lldltocachepolicy))
2136 config->ltoCachePolicy = CHECK(
2137 parseCachePruningPolicy(arg->getValue()),
2138 Twine("/lldltocachepolicy: invalid cache policy: ") + arg->getValue());
2139
2140 // Handle /failifmismatch
2141 for (auto *arg : args.filtered(Ids: OPT_failifmismatch))
2142 checkFailIfMismatch(arg: arg->getValue(), source: nullptr);
2143
2144 // Handle /merge
2145 for (auto *arg : args.filtered(Ids: OPT_merge))
2146 parseMerge(arg->getValue());
2147
2148 // Handle /discard-section
2149 for (auto *arg : args.filtered(Ids: OPT_discard_section))
2150 config->discardSection.insert(key: arg->getValue());
2151
2152 // Add default section merging rules after user rules. User rules take
2153 // precedence, but we will emit a warning if there is a conflict.
2154 parseMerge(".idata=.rdata");
2155 parseMerge(".didat=.rdata");
2156 parseMerge(".edata=.rdata");
2157 parseMerge(".xdata=.rdata");
2158 parseMerge(".00cfg=.rdata");
2159 parseMerge(".bss=.data");
2160
2161 if (isArm64EC(Machine: config->machine))
2162 parseMerge(".wowthk=.text");
2163
2164 if (config->mingw) {
2165 parseMerge(".ctors=.rdata");
2166 parseMerge(".dtors=.rdata");
2167 parseMerge(".CRT=.rdata");
2168 parseMerge(".data_cygwin_nocopy=.data");
2169 }
2170
2171 // Handle /section
2172 for (auto *arg : args.filtered(Ids: OPT_section))
2173 parseSection(arg->getValue());
2174 // Handle /sectionlayout
2175 if (auto *arg = args.getLastArg(Ids: OPT_sectionlayout))
2176 parseSectionLayout(arg->getValue());
2177
2178 // Handle /align
2179 if (auto *arg = args.getLastArg(Ids: OPT_align)) {
2180 parseNumbers(arg: arg->getValue(), addr: &config->align);
2181 if (!isPowerOf2_64(Value: config->align))
2182 Err(ctx) << "/align: not a power of two: " << StringRef(arg->getValue());
2183 if (!args.hasArg(Ids: OPT_driver))
2184 Warn(ctx) << "/align specified without /driver; image may not run";
2185 }
2186
2187 // Handle /aligncomm
2188 for (auto *arg : args.filtered(Ids: OPT_aligncomm))
2189 ctx.symtab.parseAligncomm(arg->getValue());
2190
2191 // Handle /manifestdependency.
2192 for (auto *arg : args.filtered(Ids: OPT_manifestdependency))
2193 config->manifestDependencies.insert(X: arg->getValue());
2194
2195 // Handle /manifest and /manifest:
2196 if (auto *arg = args.getLastArg(Ids: OPT_manifest, Ids: OPT_manifest_colon)) {
2197 if (arg->getOption().getID() == OPT_manifest)
2198 config->manifest = Configuration::SideBySide;
2199 else
2200 parseManifest(arg: arg->getValue());
2201 }
2202
2203 // Handle /manifestuac
2204 if (auto *arg = args.getLastArg(Ids: OPT_manifestuac))
2205 parseManifestUAC(arg: arg->getValue());
2206
2207 // Handle /manifestfile
2208 if (auto *arg = args.getLastArg(Ids: OPT_manifestfile))
2209 config->manifestFile = arg->getValue();
2210
2211 // Handle /manifestinput
2212 for (auto *arg : args.filtered(Ids: OPT_manifestinput))
2213 config->manifestInput.push_back(x: arg->getValue());
2214
2215 if (!config->manifestInput.empty() &&
2216 config->manifest != Configuration::Embed) {
2217 Fatal(ctx) << "/manifestinput: requires /manifest:embed";
2218 }
2219
2220 // Handle /thinlto-distributor:<path>
2221 config->dtltoDistributor = args.getLastArgValue(Id: OPT_thinlto_distributor);
2222
2223 // Handle /thinlto-distributor-arg:<arg>
2224 config->dtltoDistributorArgs =
2225 args::getStrings(args, id: OPT_thinlto_distributor_arg);
2226
2227 // Handle /thinlto-remote-compiler:<path>
2228 config->dtltoCompiler = args.getLastArgValue(Id: OPT_thinlto_remote_compiler);
2229 if (!config->dtltoDistributor.empty() && config->dtltoCompiler.empty())
2230 Err(ctx) << "A value must be specified for /thinlto-remote-compiler if "
2231 "/thinlto-distributor is specified.";
2232
2233 // Handle /thinlto-remote-compiler-prepend-arg:<arg>
2234 config->dtltoCompilerPrependArgs =
2235 args::getStrings(args, id: OPT_thinlto_remote_compiler_prepend_arg);
2236
2237 // Handle /thinlto-remote-compiler-arg:<arg>
2238 config->dtltoCompilerArgs =
2239 args::getStrings(args, id: OPT_thinlto_remote_compiler_arg);
2240
2241 // Handle /fat-lto-objects
2242 config->fatLTOObjects =
2243 args.hasFlag(Pos: OPT_fat_lto_objects, Neg: OPT_fat_lto_objects_no, Default: false);
2244
2245 // Handle /dwodir
2246 config->dwoDir = args.getLastArgValue(Id: OPT_dwodir);
2247
2248 config->thinLTOEmitImportsFiles = args.hasArg(Ids: OPT_thinlto_emit_imports_files);
2249 config->thinLTOIndexOnly = args.hasArg(Ids: OPT_thinlto_index_only) ||
2250 args.hasArg(Ids: OPT_thinlto_index_only_arg);
2251 config->thinLTOIndexOnlyArg =
2252 args.getLastArgValue(Id: OPT_thinlto_index_only_arg);
2253 std::tie(args&: config->thinLTOPrefixReplaceOld, args&: config->thinLTOPrefixReplaceNew,
2254 args&: config->thinLTOPrefixReplaceNativeObject) =
2255 getOldNewOptionsExtra(ctx, args, id: OPT_thinlto_prefix_replace);
2256 config->thinLTOObjectSuffixReplace =
2257 getOldNewOptions(ctx, args, id: OPT_thinlto_object_suffix_replace);
2258 config->ltoObjPath = args.getLastArgValue(Id: OPT_lto_obj_path);
2259 config->ltoCSProfileGenerate = args.hasArg(Ids: OPT_lto_cs_profile_generate);
2260 config->ltoCSProfileFile = args.getLastArgValue(Id: OPT_lto_cs_profile_file);
2261 config->ltoSampleProfileName = args.getLastArgValue(Id: OPT_lto_sample_profile);
2262 // Handle miscellaneous boolean flags.
2263 config->ltoPGOWarnMismatch = args.hasFlag(Pos: OPT_lto_pgo_warn_mismatch,
2264 Neg: OPT_lto_pgo_warn_mismatch_no, Default: true);
2265 config->allowBind = args.hasFlag(Pos: OPT_allowbind, Neg: OPT_allowbind_no, Default: true);
2266 config->allowIsolation =
2267 args.hasFlag(Pos: OPT_allowisolation, Neg: OPT_allowisolation_no, Default: true);
2268 config->incremental =
2269 args.hasFlag(Pos: OPT_incremental, Neg: OPT_incremental_no,
2270 Default: !config->doGC && config->doICF == ICFLevel::None &&
2271 !args.hasArg(Ids: OPT_order) && !args.hasArg(Ids: OPT_profile));
2272 config->integrityCheck =
2273 args.hasFlag(Pos: OPT_integritycheck, Neg: OPT_integritycheck_no, Default: false);
2274 config->cetCompat = args.hasFlag(Pos: OPT_cetcompat, Neg: OPT_cetcompat_no, Default: false);
2275 config->cetCompatStrict =
2276 args.hasFlag(Pos: OPT_cetcompatstrict, Neg: OPT_cetcompatstrict_no, Default: false);
2277 config->cetCompatIpValidationRelaxed = args.hasFlag(
2278 Pos: OPT_cetipvalidationrelaxed, Neg: OPT_cetipvalidationrelaxed_no, Default: false);
2279 config->cetCompatDynamicApisInProcOnly = args.hasFlag(
2280 Pos: OPT_cetdynamicapisinproc, Neg: OPT_cetdynamicapisinproc_no, Default: false);
2281 config->hotpatchCompat =
2282 args.hasFlag(Pos: OPT_hotpatchcompatible, Neg: OPT_hotpatchcompatible_no, Default: false);
2283 config->nxCompat = args.hasFlag(Pos: OPT_nxcompat, Neg: OPT_nxcompat_no, Default: true);
2284 for (auto *arg : args.filtered(Ids: OPT_swaprun))
2285 parseSwaprun(arg: arg->getValue());
2286 config->terminalServerAware =
2287 !config->dll && args.hasFlag(Pos: OPT_tsaware, Neg: OPT_tsaware_no, Default: true);
2288 config->autoImport =
2289 args.hasFlag(Pos: OPT_auto_import, Neg: OPT_auto_import_no, Default: config->mingw);
2290 config->pseudoRelocs = args.hasFlag(
2291 Pos: OPT_runtime_pseudo_reloc, Neg: OPT_runtime_pseudo_reloc_no, Default: config->mingw);
2292 config->callGraphProfileSort = args.hasFlag(
2293 Pos: OPT_call_graph_profile_sort, Neg: OPT_call_graph_profile_sort_no, Default: true);
2294 config->stdcallFixup =
2295 args.hasFlag(Pos: OPT_stdcall_fixup, Neg: OPT_stdcall_fixup_no, Default: config->mingw);
2296 config->warnStdcallFixup = !args.hasArg(Ids: OPT_stdcall_fixup);
2297 config->allowDuplicateWeak =
2298 args.hasFlag(Pos: OPT_lld_allow_duplicate_weak,
2299 Neg: OPT_lld_allow_duplicate_weak_no, Default: config->mingw);
2300
2301 if (args.hasFlag(Pos: OPT_inferasanlibs, Neg: OPT_inferasanlibs_no, Default: false))
2302 Warn(ctx) << "ignoring '/inferasanlibs', this flag is not supported";
2303
2304 if (config->incremental && args.hasArg(Ids: OPT_profile)) {
2305 Warn(ctx) << "ignoring '/incremental' due to '/profile' specification";
2306 config->incremental = false;
2307 }
2308
2309 if (config->incremental && args.hasArg(Ids: OPT_order)) {
2310 Warn(ctx) << "ignoring '/incremental' due to '/order' specification";
2311 config->incremental = false;
2312 }
2313
2314 if (config->incremental && config->doGC) {
2315 Warn(ctx) << "ignoring '/incremental' because REF is enabled; use "
2316 "'/opt:noref' to "
2317 "disable";
2318 config->incremental = false;
2319 }
2320
2321 if (config->incremental && config->doICF != ICFLevel::None) {
2322 Warn(ctx) << "ignoring '/incremental' because ICF is enabled; use "
2323 "'/opt:noicf' to "
2324 "disable";
2325 config->incremental = false;
2326 }
2327
2328 if (args.hasFlag(Pos: OPT_prefetch_inputs, Neg: OPT_prefetch_inputs_no, Default: false))
2329 config->prefetchInputs = true;
2330
2331 config->optRemarksFilename = args.getLastArgValue(Id: OPT_opt_remarks_filename);
2332 config->optRemarksPasses = args.getLastArgValue(Id: OPT_opt_remarks_passes);
2333 config->optRemarksFormat = args.getLastArgValue(Id: OPT_opt_remarks_format);
2334 config->optRemarksWithHotness = args.hasArg(Ids: OPT_opt_remarks_with_hotness);
2335 if (auto *arg = args.getLastArg(Ids: OPT_opt_remarks_hotness_threshold)) {
2336 auto resultOrErr = remarks::parseHotnessThresholdOption(Arg: arg->getValue());
2337 if (!resultOrErr)
2338 Err(ctx) << arg->getSpelling() << ": invalid argument '"
2339 << arg->getValue() << "', only integer or 'auto' is supported";
2340 else
2341 config->optRemarksHotnessThreshold = *resultOrErr;
2342 }
2343
2344 if (errCount(ctx))
2345 return;
2346
2347 SmallSet<sys::fs::UniqueID, 0> wholeArchives;
2348 for (auto *arg : args.filtered(Ids: OPT_wholearchive_file))
2349 if (std::optional<StringRef> path = findFile(filename: arg->getValue()))
2350 if (std::optional<sys::fs::UniqueID> id = getUniqueID(path: *path))
2351 wholeArchives.insert(V: *id);
2352
2353 // A predicate returning true if a given path is an argument for
2354 // /wholearchive:, or /wholearchive is enabled globally.
2355 // This function is a bit tricky because "foo.obj /wholearchive:././foo.obj"
2356 // needs to be handled as "/wholearchive:foo.obj foo.obj".
2357 auto isWholeArchive = [&](StringRef path) -> bool {
2358 if (args.hasArg(Ids: OPT_wholearchive_flag))
2359 return true;
2360 if (std::optional<sys::fs::UniqueID> id = getUniqueID(path))
2361 return wholeArchives.contains(V: *id);
2362 return false;
2363 };
2364
2365 // Create a list of input files. These can be given as OPT_INPUT options
2366 // and OPT_wholearchive_file options, and we also need to track OPT_start_lib
2367 // and OPT_end_lib.
2368 {
2369 llvm::TimeTraceScope timeScope2("Parse & queue inputs");
2370 bool inLib = false;
2371 for (auto *arg : args) {
2372 switch (arg->getOption().getID()) {
2373 case OPT_end_lib:
2374 if (!inLib)
2375 Err(ctx) << "stray " << arg->getSpelling();
2376 inLib = false;
2377 break;
2378 case OPT_start_lib:
2379 if (inLib)
2380 Err(ctx) << "nested " << arg->getSpelling();
2381 inLib = true;
2382 break;
2383 case OPT_wholearchive_file:
2384 if (std::optional<StringRef> path = findFileIfNew(filename: arg->getValue()))
2385 enqueuePath(path: *path, lazy: inLib, inputOpt: InputOpt::WholeArchive);
2386 break;
2387 case OPT_INPUT:
2388 if (std::optional<StringRef> path = findFileIfNew(filename: arg->getValue()))
2389 enqueuePath(path: *path, lazy: inLib,
2390 inputOpt: isWholeArchive(*path) ? InputOpt::WholeArchive
2391 : InputOpt::None);
2392 break;
2393 default:
2394 // Ignore other options.
2395 break;
2396 }
2397 }
2398 }
2399
2400 // Read all input files given via the command line.
2401 run();
2402 if (errorCount())
2403 return;
2404
2405 // We should have inferred a machine type by now from the input files, but if
2406 // not we assume x64.
2407 if (config->machine == IMAGE_FILE_MACHINE_UNKNOWN) {
2408 Warn(ctx) << "/machine is not specified. x64 is assumed";
2409 setMachine(AMD64);
2410 }
2411 config->wordsize = config->is64() ? 8 : 4;
2412
2413 if (config->printSearchPaths) {
2414 SmallString<256> buffer;
2415 raw_svector_ostream stream(buffer);
2416 stream << "Library search paths:\n";
2417
2418 for (StringRef path : searchPaths) {
2419 if (path == "")
2420 path = "(cwd)";
2421 stream << " " << path << "\n";
2422 }
2423
2424 Msg(ctx) << buffer;
2425 }
2426
2427 // Process files specified as /defaultlib. These must be processed after
2428 // addWinSysRootLibSearchPaths(), which is why they are in a separate loop.
2429 for (auto *arg : args.filtered(Ids: OPT_defaultlib))
2430 if (std::optional<StringRef> path = findLibIfNew(filename: arg->getValue()))
2431 enqueuePath(path: *path, lazy: false, inputOpt: InputOpt::DefaultLib);
2432 run();
2433 if (errorCount())
2434 return;
2435
2436 // Handle /RELEASE
2437 if (args.hasArg(Ids: OPT_release))
2438 config->writeCheckSum = true;
2439
2440 // Handle /safeseh, x86 only, on by default, except for mingw.
2441 if (config->machine == I386) {
2442 config->safeSEH = args.hasFlag(Pos: OPT_safeseh, Neg: OPT_safeseh_no, Default: !config->mingw);
2443 config->noSEH = args.hasArg(Ids: OPT_noseh);
2444 }
2445
2446 // Handle /stub
2447 if (auto *arg = args.getLastArg(Ids: OPT_stub))
2448 parseDosStub(path: arg->getValue());
2449
2450 // Handle /functionpadmin
2451 for (auto *arg : args.filtered(Ids: OPT_functionpadmin, Ids: OPT_functionpadmin_opt))
2452 parseFunctionPadMin(a: arg);
2453
2454 // MS link.exe compatibility, at least 6 bytes of function padding is
2455 // required if hotpatchable
2456 if (config->hotpatchCompat && config->functionPadMin < 6)
2457 Err(ctx)
2458 << "/hotpatchcompatible: requires at least 6 bytes of /functionpadmin";
2459
2460 // Handle /dependentloadflag
2461 for (auto *arg :
2462 args.filtered(Ids: OPT_dependentloadflag, Ids: OPT_dependentloadflag_opt))
2463 parseDependentLoadFlags(a: arg);
2464
2465 for (auto *arg : args.filtered(Ids: OPT_arm64xsameaddress)) {
2466 if (ctx.hybridSymtab)
2467 parseSameAddress(arg->getValue());
2468 else
2469 Warn(ctx) << arg->getSpelling() << " is allowed only on EC targets";
2470 }
2471
2472 if (tar) {
2473 llvm::TimeTraceScope timeScope("Reproducer: response file");
2474 tar->append(
2475 Path: "response.txt",
2476 Data: createResponseFile(args, searchPaths: ArrayRef<StringRef>(searchPaths).slice(N: 1)));
2477 }
2478
2479 // Handle /largeaddressaware
2480 config->largeAddressAware = args.hasFlag(
2481 Pos: OPT_largeaddressaware, Neg: OPT_largeaddressaware_no, Default: config->is64());
2482
2483 // Handle /highentropyva
2484 config->highEntropyVA =
2485 config->is64() &&
2486 args.hasFlag(Pos: OPT_highentropyva, Neg: OPT_highentropyva_no, Default: true);
2487
2488 // Handle /nodbgdirmerge
2489 config->mergeDebugDirectory = !args.hasArg(Ids: OPT_nodbgdirmerge);
2490
2491 if (!config->dynamicBase &&
2492 (config->machine == ARMNT || isAnyArm64(Machine: config->machine)))
2493 Err(ctx) << "/dynamicbase:no is not compatible with "
2494 << machineToStr(MT: config->machine);
2495
2496 // Handle /export
2497 {
2498 llvm::TimeTraceScope timeScope("Parse /export");
2499 for (auto *arg : args.filtered(Ids: OPT_export)) {
2500 Export e = parseExport(arg: arg->getValue());
2501 if (config->machine == I386) {
2502 if (!isDecorated(sym: e.name))
2503 e.name = saver().save(S: "_" + e.name);
2504 if (!e.extName.empty() && !isDecorated(sym: e.extName))
2505 e.extName = saver().save(S: "_" + e.extName);
2506 }
2507 ctx.symtab.exports.push_back(x: e);
2508 }
2509 }
2510
2511 // Handle /def
2512 if (auto *arg = args.getLastArg(Ids: OPT_deffile)) {
2513 // parseModuleDefs mutates Config object.
2514 ctx.symtab.parseModuleDefs(path: arg->getValue());
2515 if (ctx.config.machine == ARM64X) {
2516 // MSVC ignores the /defArm64Native argument on non-ARM64X targets.
2517 // It is also ignored if the /def option is not specified.
2518 if (auto *arg = args.getLastArg(Ids: OPT_defarm64native))
2519 ctx.hybridSymtab->parseModuleDefs(path: arg->getValue());
2520 }
2521 }
2522
2523 // Handle generation of import library from a def file.
2524 if (!args.hasArg(Ids: OPT_INPUT, Ids: OPT_wholearchive_file)) {
2525 ctx.forEachSymtab(f: [](SymbolTable &symtab) { symtab.fixupExports(); });
2526 if (!config->noimplib)
2527 createImportLibrary(/*asLib=*/true);
2528 return;
2529 }
2530
2531 // Windows specific -- if no /subsystem is given, we need to infer
2532 // that from entry point name. Must happen before /entry handling,
2533 // and after the early return when just writing an import library.
2534 if (config->subsystem == IMAGE_SUBSYSTEM_UNKNOWN) {
2535 llvm::TimeTraceScope timeScope("Infer subsystem");
2536 config->subsystem = ctx.symtab.inferSubsystem();
2537 if (config->subsystem == IMAGE_SUBSYSTEM_UNKNOWN)
2538 Fatal(ctx) << "subsystem must be defined";
2539 }
2540
2541 // Handle /entry and /dll
2542 ctx.forEachActiveSymtab(f: [&](SymbolTable &symtab) {
2543 llvm::TimeTraceScope timeScope("Entry point");
2544 if (auto *arg = args.getLastArg(Ids: OPT_entry)) {
2545 if (!arg->getValue()[0])
2546 Fatal(ctx) << "missing entry point symbol name";
2547 symtab.entry = symtab.addGCRoot(sym: symtab.mangle(sym: arg->getValue()), aliasEC: true);
2548 } else if (!symtab.entry && !config->noEntry) {
2549 if (args.hasArg(Ids: OPT_dll)) {
2550 StringRef s = DllDefaultEntryPoint(machine: config->machine, mingw: config->mingw);
2551 symtab.entry = symtab.addGCRoot(sym: s, aliasEC: true);
2552 } else if (config->driverWdm) {
2553 // /driver:wdm implies /entry:_NtProcessStartup
2554 symtab.entry =
2555 symtab.addGCRoot(sym: symtab.mangle(sym: "_NtProcessStartup"), aliasEC: true);
2556 } else {
2557 // Windows specific -- If entry point name is not given, we need to
2558 // infer that from user-defined entry name.
2559 StringRef s = symtab.findDefaultEntry();
2560 if (s.empty())
2561 Fatal(ctx) << "entry point must be defined";
2562 symtab.entry = symtab.addGCRoot(sym: s, aliasEC: true);
2563 Log(ctx) << "Entry name inferred: " << s;
2564 }
2565 }
2566 });
2567
2568 // Handle /delayload
2569 {
2570 llvm::TimeTraceScope timeScope("Delay load");
2571 for (auto *arg : args.filtered(Ids: OPT_delayload)) {
2572 config->delayLoads.insert(key: StringRef(arg->getValue()).lower());
2573 ctx.forEachActiveSymtab(f: [&](SymbolTable &symtab) {
2574 if (symtab.machine == I386) {
2575 symtab.delayLoadHelper = symtab.addGCRoot(sym: "___delayLoadHelper2@8");
2576 } else {
2577 symtab.delayLoadHelper = symtab.addGCRoot(sym: "__delayLoadHelper2", aliasEC: true);
2578 }
2579 });
2580 }
2581 }
2582
2583 // Set default image name if neither /out or /def set it.
2584 if (config->outputFile.empty()) {
2585 config->outputFile = getOutputPath(
2586 path: (*args.filtered(Ids: OPT_INPUT, Ids: OPT_wholearchive_file).begin())->getValue(),
2587 isDll: config->dll, isDriver: config->driver);
2588 }
2589
2590 // Fail early if an output file is not writable.
2591 if (auto e = tryCreateFile(path: config->outputFile)) {
2592 Err(ctx) << "cannot open output file " << config->outputFile << ": "
2593 << e.message();
2594 return;
2595 }
2596
2597 config->lldmapFile = getMapFile(args, os: OPT_lldmap, osFile: OPT_lldmap_file);
2598 config->mapFile = getMapFile(args, os: OPT_map, osFile: OPT_map_file);
2599
2600 if (config->mapFile != "" && args.hasArg(Ids: OPT_map_info)) {
2601 for (auto *arg : args.filtered(Ids: OPT_map_info)) {
2602 std::string s = StringRef(arg->getValue()).lower();
2603 if (s == "exports")
2604 config->mapInfo = true;
2605 else
2606 Err(ctx) << "unknown option: /mapinfo:" << s;
2607 }
2608 }
2609
2610 if (config->lldmapFile != "" && config->lldmapFile == config->mapFile) {
2611 Warn(ctx) << "/lldmap and /map have the same output file '"
2612 << config->mapFile << "'.\n>>> ignoring /lldmap";
2613 config->lldmapFile.clear();
2614 }
2615
2616 // If should create PDB, use the hash of PDB content for build id. Otherwise,
2617 // generate using the hash of executable content.
2618 if (args.hasFlag(Pos: OPT_build_id, Neg: OPT_build_id_no, Default: false))
2619 config->buildIDHash = BuildIDHash::Binary;
2620
2621 if (shouldCreatePDB) {
2622 // Put the PDB next to the image if no /pdb flag was passed.
2623 if (config->pdbPath.empty()) {
2624 config->pdbPath = config->outputFile;
2625 sys::path::replace_extension(path&: config->pdbPath, extension: ".pdb");
2626 }
2627
2628 // The embedded PDB path should be the absolute path to the PDB if no
2629 // /pdbaltpath flag was passed.
2630 if (config->pdbAltPath.empty()) {
2631 config->pdbAltPath = config->pdbPath;
2632
2633 // It's important to make the path absolute and remove dots. This path
2634 // will eventually be written into the PE header, and certain Microsoft
2635 // tools won't work correctly if these assumptions are not held.
2636 sys::fs::make_absolute(path&: config->pdbAltPath);
2637 sys::path::remove_dots(path&: config->pdbAltPath);
2638 } else {
2639 // Don't do this earlier, so that ctx.OutputFile is ready.
2640 parsePDBAltPath();
2641 }
2642 config->buildIDHash = BuildIDHash::PDB;
2643 }
2644
2645 // Set default image base if /base is not given.
2646 if (config->imageBase == uint64_t(-1))
2647 config->imageBase = getDefaultImageBase();
2648
2649 ctx.forEachSymtab(f: [&](SymbolTable &symtab) {
2650 symtab.addSynthetic(n: symtab.mangle(sym: "__ImageBase"), c: nullptr);
2651 if (symtab.machine == I386) {
2652 symtab.addAbsolute(n: "___safe_se_handler_table", va: 0);
2653 symtab.addAbsolute(n: "___safe_se_handler_count", va: 0);
2654 }
2655
2656 symtab.addAbsolute(n: symtab.mangle(sym: "__guard_fids_count"), va: 0);
2657 symtab.addAbsolute(n: symtab.mangle(sym: "__guard_fids_table"), va: 0);
2658 symtab.addAbsolute(n: symtab.mangle(sym: "__guard_flags"), va: 0);
2659 symtab.addAbsolute(n: symtab.mangle(sym: "__guard_iat_count"), va: 0);
2660 symtab.addAbsolute(n: symtab.mangle(sym: "__guard_iat_table"), va: 0);
2661 symtab.addAbsolute(n: symtab.mangle(sym: "__guard_longjmp_count"), va: 0);
2662 symtab.addAbsolute(n: symtab.mangle(sym: "__guard_longjmp_table"), va: 0);
2663 // Needed for MSVC 2017 15.5 CRT.
2664 symtab.addAbsolute(n: symtab.mangle(sym: "__enclave_config"), va: 0);
2665 // Needed for MSVC 2019 16.8 CRT.
2666 symtab.addAbsolute(n: symtab.mangle(sym: "__guard_eh_cont_count"), va: 0);
2667 symtab.addAbsolute(n: symtab.mangle(sym: "__guard_eh_cont_table"), va: 0);
2668
2669 if (symtab.isEC()) {
2670 symtab.addAbsolute(n: "__arm64x_extra_rfe_table", va: 0);
2671 symtab.addAbsolute(n: "__arm64x_extra_rfe_table_size", va: 0);
2672 symtab.addAbsolute(n: "__arm64x_redirection_metadata", va: 0);
2673 symtab.addAbsolute(n: "__arm64x_redirection_metadata_count", va: 0);
2674 symtab.addAbsolute(n: "__hybrid_auxiliary_delayload_iat_copy", va: 0);
2675 symtab.addAbsolute(n: "__hybrid_auxiliary_delayload_iat", va: 0);
2676 symtab.addAbsolute(n: "__hybrid_auxiliary_iat", va: 0);
2677 symtab.addAbsolute(n: "__hybrid_auxiliary_iat_copy", va: 0);
2678 symtab.addAbsolute(n: "__hybrid_code_map", va: 0);
2679 symtab.addAbsolute(n: "__hybrid_code_map_count", va: 0);
2680 symtab.addAbsolute(n: "__hybrid_image_info_bitfield", va: 0);
2681 symtab.addAbsolute(n: "__x64_code_ranges_to_entry_points", va: 0);
2682 symtab.addAbsolute(n: "__x64_code_ranges_to_entry_points_count", va: 0);
2683 symtab.addSynthetic(n: "__guard_check_icall_a64n_fptr", c: nullptr);
2684 symtab.addSynthetic(n: "__arm64x_native_entrypoint", c: nullptr);
2685 }
2686
2687 if (config->pseudoRelocs) {
2688 symtab.addAbsolute(n: symtab.mangle(sym: "__RUNTIME_PSEUDO_RELOC_LIST__"), va: 0);
2689 symtab.addAbsolute(n: symtab.mangle(sym: "__RUNTIME_PSEUDO_RELOC_LIST_END__"), va: 0);
2690 }
2691 if (config->mingw) {
2692 symtab.addAbsolute(n: symtab.mangle(sym: "__CTOR_LIST__"), va: 0);
2693 symtab.addAbsolute(n: symtab.mangle(sym: "__DTOR_LIST__"), va: 0);
2694 symtab.addAbsolute(n: "__data_start__", va: 0);
2695 symtab.addAbsolute(n: "__data_end__", va: 0);
2696 symtab.addAbsolute(n: "__bss_start__", va: 0);
2697 symtab.addAbsolute(n: "__bss_end__", va: 0);
2698 }
2699 if (config->debug || config->buildIDHash != BuildIDHash::None)
2700 if (symtab.findUnderscore(name: "__buildid"))
2701 symtab.addUndefined(name: symtab.mangle(sym: "__buildid"));
2702 });
2703
2704 // This code may add new undefined symbols to the link, which may enqueue more
2705 // symbol resolution tasks, so we need to continue executing tasks until we
2706 // converge.
2707 {
2708 llvm::TimeTraceScope timeScope("Add unresolved symbols");
2709 do {
2710 ctx.forEachSymtab(f: [&](SymbolTable &symtab) {
2711 // Windows specific -- if entry point is not found,
2712 // search for its mangled names.
2713 if (symtab.entry)
2714 symtab.mangleMaybe(s: symtab.entry);
2715
2716 // Windows specific -- Make sure we resolve all dllexported symbols.
2717 for (Export &e : symtab.exports) {
2718 if (!e.forwardTo.empty())
2719 continue;
2720 e.sym = symtab.addGCRoot(sym: e.name, aliasEC: !e.data);
2721 if (e.source != ExportSource::Directives)
2722 e.symbolName = symtab.mangleMaybe(s: e.sym);
2723 }
2724
2725 symtab.resolveAlternateNames();
2726 });
2727
2728 ctx.forEachActiveSymtab(f: [&](SymbolTable &symtab) {
2729 // If any inputs are bitcode files, the LTO code generator may create
2730 // references to library functions that are not explicit in the bitcode
2731 // file's symbol table. If any of those library functions are defined in
2732 // a bitcode file in an archive member, we need to arrange to use LTO to
2733 // compile those archive members by adding them to the link beforehand.
2734 if (!symtab.bitcodeFileInstances.empty()) {
2735 llvm::Triple TT(
2736 symtab.bitcodeFileInstances.front()->obj->getTargetTriple());
2737 for (auto *s : lto::LTO::getRuntimeLibcallSymbols(TT))
2738 symtab.addLibcall(name: s);
2739 }
2740
2741 // Windows specific -- if __load_config_used can be resolved, resolve
2742 // it.
2743 if (symtab.findUnderscore(name: "_load_config_used"))
2744 symtab.addGCRoot(sym: symtab.mangle(sym: "_load_config_used"));
2745
2746 if (args.hasArg(Ids: OPT_include_optional)) {
2747 // Handle /includeoptional
2748 for (auto *arg : args.filtered(Ids: OPT_include_optional))
2749 if (isa_and_nonnull<LazyArchive>(Val: symtab.find(name: arg->getValue())))
2750 symtab.addGCRoot(sym: arg->getValue());
2751 }
2752 });
2753 } while (run());
2754 }
2755
2756 // Handle /includeglob
2757 for (StringRef pat : args::getStrings(args, id: OPT_incl_glob))
2758 ctx.forEachActiveSymtab(
2759 f: [&](SymbolTable &symtab) { symtab.addUndefinedGlob(arg: pat); });
2760
2761 // Create wrapped symbols for -wrap option.
2762 ctx.forEachSymtab(f: [&](SymbolTable &symtab) {
2763 addWrappedSymbols(symtab, args);
2764 // Load more object files that might be needed for wrapped symbols.
2765 if (!symtab.wrapped.empty())
2766 while (run())
2767 ;
2768 });
2769
2770 if (config->autoImport || config->stdcallFixup) {
2771 // MinGW specific.
2772 // Load any further object files that might be needed for doing automatic
2773 // imports, and do stdcall fixups.
2774 //
2775 // For cases with no automatically imported symbols, this iterates once
2776 // over the symbol table and doesn't do anything.
2777 //
2778 // For the normal case with a few automatically imported symbols, this
2779 // should only need to be run once, since each new object file imported
2780 // is an import library and wouldn't add any new undefined references,
2781 // but there's nothing stopping the __imp_ symbols from coming from a
2782 // normal object file as well (although that won't be used for the
2783 // actual autoimport later on). If this pass adds new undefined references,
2784 // we won't iterate further to resolve them.
2785 //
2786 // If stdcall fixups only are needed for loading import entries from
2787 // a DLL without import library, this also just needs running once.
2788 // If it ends up pulling in more object files from static libraries,
2789 // (and maybe doing more stdcall fixups along the way), this would need
2790 // to loop these two calls.
2791 ctx.forEachSymtab(f: [](SymbolTable &symtab) { symtab.loadMinGWSymbols(); });
2792 run();
2793 }
2794
2795 // At this point, we should not have any symbols that cannot be resolved.
2796 // If we are going to do codegen for link-time optimization, check for
2797 // unresolvable symbols first, so we don't spend time generating code that
2798 // will fail to link anyway.
2799 if (!config->forceUnresolved)
2800 ctx.forEachSymtab(f: [](SymbolTable &symtab) {
2801 if (!symtab.bitcodeFileInstances.empty())
2802 symtab.reportUnresolvable();
2803 });
2804 if (errorCount())
2805 return;
2806
2807 ctx.forEachSymtab(f: [](SymbolTable &symtab) {
2808 symtab.hadExplicitExports = !symtab.exports.empty();
2809 });
2810 if (config->mingw) {
2811 // In MinGW, all symbols are automatically exported if no symbols
2812 // are chosen to be exported.
2813 maybeExportMinGWSymbols(args);
2814 }
2815
2816 // Do LTO by compiling bitcode input files to a set of native COFF files then
2817 // link those files (unless -thinlto-index-only was given, in which case we
2818 // resolve symbols and write indices, but don't generate native code or link).
2819 ltoCompilationDone = true;
2820 ctx.forEachSymtab(f: [](SymbolTable &symtab) { symtab.compileBitcodeFiles(); });
2821
2822 ctx.forEachSymtab(f: [&](SymbolTable &symtab) {
2823 if (Defined *d =
2824 dyn_cast_or_null<Defined>(Val: symtab.findUnderscore(name: "_tls_used")))
2825 config->gcroot.push_back(x: d);
2826 });
2827
2828 // If -thinlto-index-only is given, we should create only "index
2829 // files" and not object files. Index file creation is already done
2830 // in addCombinedLTOObject, so we are done if that's the case.
2831 // Likewise, don't emit object files for other /lldemit options.
2832 if (config->emit != EmitKind::Obj || config->thinLTOIndexOnly)
2833 return;
2834
2835 // If we generated native object files from bitcode files, this resolves
2836 // references to the symbols we use from them.
2837 run();
2838
2839 // Apply symbol renames for -wrap.
2840 ctx.forEachSymtab(f: [](SymbolTable &symtab) {
2841 if (!symtab.wrapped.empty())
2842 wrapSymbols(symtab);
2843 });
2844
2845 if (isArm64EC(Machine: config->machine))
2846 createECExportThunks();
2847
2848 // Resolve remaining undefined symbols and warn about imported locals.
2849 std::vector<Undefined *> aliases;
2850 ctx.forEachSymtab(
2851 f: [&](SymbolTable &symtab) { symtab.resolveRemainingUndefines(aliases); });
2852
2853 if (errorCount())
2854 return;
2855
2856 if (ctx.hybridSymtab) {
2857 // On ARM64X, merge tls chunks, there may be only one true _tls_start and
2858 // _tls_end chunk.
2859 auto maybeReplaceWithNative = [&](StringRef name) {
2860 auto nativeSym = dyn_cast_or_null<DefinedRegular>(
2861 Val: ctx.hybridSymtab->findUnderscore(name));
2862 if (!nativeSym)
2863 return;
2864 if (auto ecSym =
2865 dyn_cast_or_null<DefinedRegular>(Val: ctx.symtab.findUnderscore(name)))
2866 nativeSym->getChunk()->replace(other: ecSym->getChunk());
2867 };
2868 maybeReplaceWithNative("_tls_start");
2869 maybeReplaceWithNative("_tls_end");
2870 }
2871
2872 ctx.forEachActiveSymtab(f: [](SymbolTable &symtab) {
2873 symtab.initializeECThunks();
2874 symtab.initializeLoadConfig();
2875 });
2876
2877 // Identify unreferenced COMDAT sections.
2878 if (config->doGC) {
2879 if (config->mingw) {
2880 // markLive doesn't traverse .eh_frame, but the personality function is
2881 // only reached that way. The proper solution would be to parse and
2882 // traverse the .eh_frame section, like the ELF linker does.
2883 // For now, just manually try to retain the known possible personality
2884 // functions. This doesn't bring in more object files, but only marks
2885 // functions that already have been included to be retained.
2886 ctx.forEachSymtab(f: [&](SymbolTable &symtab) {
2887 for (const char *n : {"__gxx_personality_v0", "__gcc_personality_v0",
2888 "rust_eh_personality"}) {
2889 Defined *d = dyn_cast_or_null<Defined>(Val: symtab.findUnderscore(name: n));
2890 if (d && !d->isGCRoot) {
2891 d->isGCRoot = true;
2892 config->gcroot.push_back(x: d);
2893 }
2894 }
2895 });
2896 }
2897
2898 markLive(ctx);
2899 }
2900
2901 ctx.symtab.initializeSameAddressThunks();
2902 for (auto alias : aliases) {
2903 assert(alias->kind() == Symbol::UndefinedKind);
2904 alias->resolveWeakAlias();
2905 }
2906
2907 if (config->mingw) {
2908 // Make sure the crtend.o object is the last object file. This object
2909 // file can contain terminating section chunks that need to be placed
2910 // last. GNU ld processes files and static libraries explicitly in the
2911 // order provided on the command line, while lld will pull in needed
2912 // files from static libraries only after the last object file on the
2913 // command line.
2914 for (auto i = ctx.objFileInstances.begin(), e = ctx.objFileInstances.end();
2915 i != e; i++) {
2916 ObjFile *file = *i;
2917 if (isCrtend(s: file->getName())) {
2918 ctx.objFileInstances.erase(position: i);
2919 ctx.objFileInstances.push_back(x: file);
2920 break;
2921 }
2922 }
2923 }
2924
2925 // Windows specific -- when we are creating a .dll file, we also
2926 // need to create a .lib file. In MinGW mode, we only do that when the
2927 // -implib option is given explicitly, for compatibility with GNU ld.
2928 if (config->dll || !ctx.symtab.exports.empty() ||
2929 (ctx.config.machine == ARM64X && !ctx.hybridSymtab->exports.empty())) {
2930 llvm::TimeTraceScope timeScope("Create .lib exports");
2931 ctx.forEachActiveSymtab(f: [](SymbolTable &symtab) { symtab.fixupExports(); });
2932 if (!config->noimplib && (!config->mingw || !config->implib.empty()))
2933 createImportLibrary(/*asLib=*/false);
2934 ctx.forEachActiveSymtab(
2935 f: [](SymbolTable &symtab) { symtab.assignExportOrdinals(); });
2936 }
2937
2938 // Handle /output-def (MinGW specific).
2939 if (auto *arg = args.getLastArg(Ids: OPT_output_def))
2940 writeDefFile(ctx, name: arg->getValue(), exports: ctx.symtab.exports);
2941
2942 // Set extra alignment for .comm symbols
2943 ctx.forEachSymtab(f: [&](SymbolTable &symtab) {
2944 for (auto pair : symtab.alignComm) {
2945 StringRef name = pair.first;
2946 uint32_t alignment = pair.second;
2947
2948 Symbol *sym = symtab.find(name);
2949 if (!sym) {
2950 Warn(ctx) << "/aligncomm symbol " << name << " not found";
2951 continue;
2952 }
2953
2954 // If the symbol isn't common, it must have been replaced with a regular
2955 // symbol, which will carry its own alignment.
2956 auto *dc = dyn_cast<DefinedCommon>(Val: sym);
2957 if (!dc)
2958 continue;
2959
2960 CommonChunk *c = dc->getChunk();
2961 c->setAlignment(std::max(a: c->getAlignment(), b: alignment));
2962 }
2963 });
2964
2965 // Windows specific -- Create an embedded or side-by-side manifest.
2966 // /manifestdependency: enables /manifest unless an explicit /manifest:no is
2967 // also passed.
2968 if (config->manifest == Configuration::Embed)
2969 addBuffer(mb: createManifestRes(), wholeArchive: false, lazy: false);
2970 else if (config->manifest == Configuration::SideBySide ||
2971 (config->manifest == Configuration::Default &&
2972 !config->manifestDependencies.empty()))
2973 createSideBySideManifest();
2974
2975 // Handle /order. We want to do this at this moment because we
2976 // need a complete list of comdat sections to warn on nonexistent
2977 // functions.
2978 if (auto *arg = args.getLastArg(Ids: OPT_order)) {
2979 if (args.hasArg(Ids: OPT_call_graph_ordering_file))
2980 Err(ctx) << "/order and /call-graph-order-file may not be used together";
2981 parseOrderFile(arg: arg->getValue());
2982 config->callGraphProfileSort = false;
2983 }
2984
2985 // Handle /call-graph-ordering-file and /call-graph-profile-sort (default on).
2986 if (config->callGraphProfileSort) {
2987 llvm::TimeTraceScope timeScope("Call graph");
2988 if (auto *arg = args.getLastArg(Ids: OPT_call_graph_ordering_file))
2989 parseCallGraphFile(path: arg->getValue());
2990 else
2991 readCallGraphsFromObjectFiles(ctx);
2992 }
2993
2994 // Handle /print-symbol-order.
2995 if (auto *arg = args.getLastArg(Ids: OPT_print_symbol_order))
2996 config->printSymbolOrder = arg->getValue();
2997
2998 // Needs to happen after the last call to addFile().
2999 convertResources();
3000
3001 // Identify identical COMDAT sections to merge them.
3002 if (config->doICF != ICFLevel::None) {
3003 findKeepUniqueSections(ctx);
3004 doICF(ctx);
3005 }
3006
3007 // Write the result.
3008 writeResult(ctx);
3009 // LTO cleanup may create time trace events. Wait for it to complete before
3010 // writing the time trace data.
3011 ctx.forEachSymtab(f: [](SymbolTable &symtab) { symtab.waitForLTOCleanup(); });
3012
3013 // Stop early so we can print the results.
3014 rootTimer.stop();
3015 if (config->showTiming)
3016 ctx.rootTimer.print();
3017
3018 // Clean up /linkreprofullpathrsp file
3019 reproFile.reset();
3020
3021 if (config->timeTraceEnabled) {
3022 // Manually stop the topmost "COFF link" scope, since we're shutting down.
3023 timeTraceProfilerEnd();
3024
3025 checkError(e: timeTraceProfilerWrite(
3026 PreferredFileName: args.getLastArgValue(Id: OPT_time_trace_eq).str(), FallbackFileName: config->outputFile));
3027 timeTraceProfilerCleanup();
3028 }
3029}
3030
3031} // namespace lld::coff
3032