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 "lld/Common/Driver.h"
10#include "Config.h"
11#include "InputChunks.h"
12#include "InputElement.h"
13#include "MarkLive.h"
14#include "SymbolTable.h"
15#include "Writer.h"
16#include "lld/Common/Args.h"
17#include "lld/Common/CommonLinkerContext.h"
18#include "lld/Common/ErrorHandler.h"
19#include "lld/Common/Filesystem.h"
20#include "lld/Common/Memory.h"
21#include "lld/Common/Reproduce.h"
22#include "lld/Common/Strings.h"
23#include "lld/Common/Version.h"
24#include "llvm/ADT/Twine.h"
25#include "llvm/Config/llvm-config.h"
26#include "llvm/Object/Wasm.h"
27#include "llvm/Option/Arg.h"
28#include "llvm/Option/ArgList.h"
29#include "llvm/Support/CommandLine.h"
30#include "llvm/Support/Parallel.h"
31#include "llvm/Support/Path.h"
32#include "llvm/Support/Process.h"
33#include "llvm/Support/TarWriter.h"
34#include "llvm/Support/TargetSelect.h"
35#include "llvm/TargetParser/Host.h"
36#include <optional>
37
38#define DEBUG_TYPE "lld"
39
40using namespace llvm;
41using namespace llvm::object;
42using namespace llvm::opt;
43using namespace llvm::sys;
44using namespace llvm::wasm;
45
46namespace lld::wasm {
47Configuration *config;
48Ctx ctx;
49
50void Ctx::reset() {
51 objectFiles.clear();
52 stubFiles.clear();
53 sharedFiles.clear();
54 bitcodeFiles.clear();
55 syntheticFunctions.clear();
56 syntheticGlobals.clear();
57 syntheticTables.clear();
58 whyExtractRecords.clear();
59 isPic = false;
60 legacyFunctionTable = false;
61 emitBssSegments = false;
62}
63
64namespace {
65
66// Create enum with OPT_xxx values for each option in Options.td
67enum {
68 OPT_INVALID = 0,
69#define OPTION(...) LLVM_MAKE_OPT_ID(__VA_ARGS__),
70#include "Options.inc"
71#undef OPTION
72};
73
74// This function is called on startup. We need this for LTO since
75// LTO calls LLVM functions to compile bitcode files to native code.
76// Technically this can be delayed until we read bitcode files, but
77// we don't bother to do lazily because the initialization is fast.
78static void initLLVM() {
79 InitializeAllTargets();
80 InitializeAllTargetMCs();
81 InitializeAllAsmPrinters();
82 InitializeAllAsmParsers();
83}
84
85class LinkerDriver {
86public:
87 void linkerMain(ArrayRef<const char *> argsArr);
88
89private:
90 void createFiles(opt::InputArgList &args);
91 void addFile(StringRef path);
92 void addLibrary(StringRef name);
93
94 // True if we are in --whole-archive and --no-whole-archive.
95 bool inWholeArchive = false;
96
97 // True if we are in --start-lib and --end-lib.
98 bool inLib = false;
99
100 std::vector<InputFile *> files;
101};
102} // anonymous namespace
103
104bool link(ArrayRef<const char *> args, llvm::raw_ostream &stdoutOS,
105 llvm::raw_ostream &stderrOS, bool exitEarly, bool disableOutput) {
106 // This driver-specific context will be freed later by unsafeLldMain().
107 auto *ctx = new CommonLinkerContext;
108
109 ctx->e.initialize(stdoutOS, stderrOS, exitEarly, disableOutput);
110 ctx->e.cleanupCallback = []() { wasm::ctx.reset(); };
111 ctx->e.logName = args::getFilenameWithoutExe(path: args[0]);
112 ctx->e.errorLimitExceededMsg = "too many errors emitted, stopping now (use "
113 "-error-limit=0 to see all errors)";
114
115 config = make<Configuration>();
116 symtab = make<SymbolTable>();
117
118 initLLVM();
119 LinkerDriver().linkerMain(argsArr: args);
120
121 return errorCount() == 0;
122}
123
124// Create prefix string literals used in Options.td
125#define PREFIX(NAME, VALUE) \
126 static constexpr StringLiteral NAME##_init[] = VALUE; \
127 static constexpr ArrayRef<StringLiteral> NAME(NAME##_init, \
128 std::size(NAME##_init) - 1);
129#include "Options.inc"
130#undef PREFIX
131
132// Create table mapping all options defined in Options.td
133static constexpr opt::OptTable::Info optInfo[] = {
134#define OPTION(PREFIX, NAME, ID, KIND, GROUP, ALIAS, ALIASARGS, FLAGS, \
135 VISIBILITY, PARAM, HELPTEXT, HELPTEXTSFORVARIANTS, METAVAR, \
136 VALUES) \
137 {PREFIX, \
138 NAME, \
139 HELPTEXT, \
140 HELPTEXTSFORVARIANTS, \
141 METAVAR, \
142 OPT_##ID, \
143 opt::Option::KIND##Class, \
144 PARAM, \
145 FLAGS, \
146 VISIBILITY, \
147 OPT_##GROUP, \
148 OPT_##ALIAS, \
149 ALIASARGS, \
150 VALUES},
151#include "Options.inc"
152#undef OPTION
153};
154
155namespace {
156class WasmOptTable : public opt::GenericOptTable {
157public:
158 WasmOptTable() : opt::GenericOptTable(optInfo) {}
159 opt::InputArgList parse(ArrayRef<const char *> argv);
160};
161} // namespace
162
163// Set color diagnostics according to -color-diagnostics={auto,always,never}
164// or -no-color-diagnostics flags.
165static void handleColorDiagnostics(opt::InputArgList &args) {
166 auto *arg = args.getLastArg(Ids: OPT_color_diagnostics, Ids: OPT_color_diagnostics_eq,
167 Ids: OPT_no_color_diagnostics);
168 if (!arg)
169 return;
170 if (arg->getOption().getID() == OPT_color_diagnostics) {
171 lld::errs().enable_colors(enable: true);
172 } else if (arg->getOption().getID() == OPT_no_color_diagnostics) {
173 lld::errs().enable_colors(enable: false);
174 } else {
175 StringRef s = arg->getValue();
176 if (s == "always")
177 lld::errs().enable_colors(enable: true);
178 else if (s == "never")
179 lld::errs().enable_colors(enable: false);
180 else if (s != "auto")
181 error(msg: "unknown option: --color-diagnostics=" + s);
182 }
183}
184
185static cl::TokenizerCallback getQuotingStyle(opt::InputArgList &args) {
186 if (auto *arg = args.getLastArg(Ids: OPT_rsp_quoting)) {
187 StringRef s = arg->getValue();
188 if (s != "windows" && s != "posix")
189 error(msg: "invalid response file quoting: " + s);
190 if (s == "windows")
191 return cl::TokenizeWindowsCommandLine;
192 return cl::TokenizeGNUCommandLine;
193 }
194 if (Triple(sys::getProcessTriple()).isOSWindows())
195 return cl::TokenizeWindowsCommandLine;
196 return cl::TokenizeGNUCommandLine;
197}
198
199// Find a file by concatenating given paths.
200static std::optional<std::string> findFile(StringRef path1,
201 const Twine &path2) {
202 SmallString<128> s;
203 path::append(path&: s, a: path1, b: path2);
204 if (fs::exists(Path: s))
205 return std::string(s);
206 return std::nullopt;
207}
208
209opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> argv) {
210 SmallVector<const char *, 256> vec(argv.data(), argv.data() + argv.size());
211
212 unsigned missingIndex;
213 unsigned missingCount;
214
215 // We need to get the quoting style for response files before parsing all
216 // options so we parse here before and ignore all the options but
217 // --rsp-quoting.
218 opt::InputArgList args = this->ParseArgs(Args: vec, MissingArgIndex&: missingIndex, MissingArgCount&: missingCount);
219
220 // Expand response files (arguments in the form of @<filename>)
221 // and then parse the argument again.
222 cl::ExpandResponseFiles(Saver&: saver(), Tokenizer: getQuotingStyle(args), Argv&: vec);
223 args = this->ParseArgs(Args: vec, MissingArgIndex&: missingIndex, MissingArgCount&: missingCount);
224
225 handleColorDiagnostics(args);
226 if (missingCount)
227 error(msg: Twine(args.getArgString(Index: missingIndex)) + ": missing argument");
228
229 for (auto *arg : args.filtered(Ids: OPT_UNKNOWN))
230 error(msg: "unknown argument: " + arg->getAsString(Args: args));
231 return args;
232}
233
234// Currently we allow a ".imports" to live alongside a library. This can
235// be used to specify a list of symbols which can be undefined at link
236// time (imported from the environment. For example libc.a include an
237// import file that lists the syscall functions it relies on at runtime.
238// In the long run this information would be better stored as a symbol
239// attribute/flag in the object file itself.
240// See: https://github.com/WebAssembly/tool-conventions/issues/35
241static void readImportFile(StringRef filename) {
242 if (std::optional<MemoryBufferRef> buf = readFile(path: filename))
243 for (StringRef sym : args::getLines(mb: *buf))
244 config->allowUndefinedSymbols.insert(key: sym);
245}
246
247// Returns slices of MB by parsing MB as an archive file.
248// Each slice consists of a member file in the archive.
249std::vector<std::pair<MemoryBufferRef, uint64_t>> static getArchiveMembers(
250 MemoryBufferRef mb) {
251 std::unique_ptr<Archive> file =
252 CHECK(Archive::create(mb),
253 mb.getBufferIdentifier() + ": failed to parse archive");
254
255 std::vector<std::pair<MemoryBufferRef, uint64_t>> v;
256 Error err = Error::success();
257 for (const Archive::Child &c : file->children(Err&: err)) {
258 MemoryBufferRef mbref =
259 CHECK(c.getMemoryBufferRef(),
260 mb.getBufferIdentifier() +
261 ": could not get the buffer for a child of the archive");
262 v.push_back(x: std::make_pair(x&: mbref, y: c.getChildOffset()));
263 }
264 if (err)
265 fatal(msg: mb.getBufferIdentifier() +
266 ": Archive::children failed: " + toString(E: std::move(err)));
267
268 // Take ownership of memory buffers created for members of thin archives.
269 for (std::unique_ptr<MemoryBuffer> &mb : file->takeThinBuffers())
270 make<std::unique_ptr<MemoryBuffer>>(args: std::move(mb));
271
272 return v;
273}
274
275void LinkerDriver::addFile(StringRef path) {
276 std::optional<MemoryBufferRef> buffer = readFile(path);
277 if (!buffer)
278 return;
279 MemoryBufferRef mbref = *buffer;
280
281 switch (identify_magic(magic: mbref.getBuffer())) {
282 case file_magic::archive: {
283 SmallString<128> importFile = path;
284 path::replace_extension(path&: importFile, extension: ".imports");
285 if (fs::exists(Path: importFile))
286 readImportFile(filename: importFile.str());
287
288 auto members = getArchiveMembers(mb: mbref);
289
290 // Handle -whole-archive.
291 if (inWholeArchive) {
292 for (const auto &[m, offset] : members) {
293 auto *object = createObjectFile(mb: m, archiveName: path, offsetInArchive: offset);
294 // Mark object as live; object members are normally not
295 // live by default but -whole-archive is designed to treat
296 // them as such.
297 object->markLive();
298 files.push_back(x: object);
299 }
300
301 return;
302 }
303
304 std::unique_ptr<Archive> file =
305 CHECK(Archive::create(mbref), path + ": failed to parse archive");
306
307 for (const auto &[m, offset] : members) {
308 auto magic = identify_magic(magic: m.getBuffer());
309 if (magic == file_magic::wasm_object || magic == file_magic::bitcode)
310 files.push_back(x: createObjectFile(mb: m, archiveName: path, offsetInArchive: offset, lazy: true));
311 else
312 warn(msg: path + ": archive member '" + m.getBufferIdentifier() +
313 "' is neither Wasm object file nor LLVM bitcode");
314 }
315
316 return;
317 }
318 case file_magic::bitcode:
319 case file_magic::wasm_object:
320 files.push_back(x: createObjectFile(mb: mbref, archiveName: "", offsetInArchive: 0, lazy: inLib));
321 break;
322 case file_magic::unknown:
323 if (mbref.getBuffer().starts_with(Prefix: "#STUB")) {
324 files.push_back(x: make<StubFile>(args&: mbref));
325 break;
326 }
327 [[fallthrough]];
328 default:
329 error(msg: "unknown file type: " + mbref.getBufferIdentifier());
330 }
331}
332
333static std::optional<std::string> findFromSearchPaths(StringRef path) {
334 for (StringRef dir : config->searchPaths)
335 if (std::optional<std::string> s = findFile(path1: dir, path2: path))
336 return s;
337 return std::nullopt;
338}
339
340// This is for -l<basename>. We'll look for lib<basename>.a from
341// search paths.
342static std::optional<std::string> searchLibraryBaseName(StringRef name) {
343 for (StringRef dir : config->searchPaths) {
344 if (!config->isStatic)
345 if (std::optional<std::string> s = findFile(path1: dir, path2: "lib" + name + ".so"))
346 return s;
347 if (std::optional<std::string> s = findFile(path1: dir, path2: "lib" + name + ".a"))
348 return s;
349 }
350 return std::nullopt;
351}
352
353// This is for -l<namespec>.
354static std::optional<std::string> searchLibrary(StringRef name) {
355 if (name.starts_with(Prefix: ":"))
356 return findFromSearchPaths(path: name.substr(Start: 1));
357 return searchLibraryBaseName(name);
358}
359
360// Add a given library by searching it from input search paths.
361void LinkerDriver::addLibrary(StringRef name) {
362 if (std::optional<std::string> path = searchLibrary(name))
363 addFile(path: saver().save(S: *path));
364 else
365 error(msg: "unable to find library -l" + name, tag: ErrorTag::LibNotFound, args: {name});
366}
367
368void LinkerDriver::createFiles(opt::InputArgList &args) {
369 for (auto *arg : args) {
370 switch (arg->getOption().getID()) {
371 case OPT_library:
372 addLibrary(name: arg->getValue());
373 break;
374 case OPT_INPUT:
375 addFile(path: arg->getValue());
376 break;
377 case OPT_Bstatic:
378 config->isStatic = true;
379 break;
380 case OPT_Bdynamic:
381 config->isStatic = false;
382 break;
383 case OPT_whole_archive:
384 inWholeArchive = true;
385 break;
386 case OPT_no_whole_archive:
387 inWholeArchive = false;
388 break;
389 case OPT_start_lib:
390 if (inLib)
391 error(msg: "nested --start-lib");
392 inLib = true;
393 break;
394 case OPT_end_lib:
395 if (!inLib)
396 error(msg: "stray --end-lib");
397 inLib = false;
398 break;
399 }
400 }
401 if (files.empty() && errorCount() == 0)
402 error(msg: "no input files");
403}
404
405static StringRef getEntry(opt::InputArgList &args) {
406 auto *arg = args.getLastArg(Ids: OPT_entry, Ids: OPT_no_entry);
407 if (!arg) {
408 if (args.hasArg(Ids: OPT_relocatable))
409 return "";
410 if (args.hasArg(Ids: OPT_shared))
411 return "__wasm_call_ctors";
412 return "_start";
413 }
414 if (arg->getOption().getID() == OPT_no_entry)
415 return "";
416 return arg->getValue();
417}
418
419// Determines what we should do if there are remaining unresolved
420// symbols after the name resolution.
421static UnresolvedPolicy getUnresolvedSymbolPolicy(opt::InputArgList &args) {
422 UnresolvedPolicy errorOrWarn = args.hasFlag(Pos: OPT_error_unresolved_symbols,
423 Neg: OPT_warn_unresolved_symbols, Default: true)
424 ? UnresolvedPolicy::ReportError
425 : UnresolvedPolicy::Warn;
426
427 if (auto *arg = args.getLastArg(Ids: OPT_unresolved_symbols)) {
428 StringRef s = arg->getValue();
429 if (s == "ignore-all")
430 return UnresolvedPolicy::Ignore;
431 if (s == "import-dynamic")
432 return UnresolvedPolicy::ImportDynamic;
433 if (s == "report-all")
434 return errorOrWarn;
435 error(msg: "unknown --unresolved-symbols value: " + s);
436 }
437
438 return errorOrWarn;
439}
440
441// Parse --build-id or --build-id=<style>. We handle "tree" as a
442// synonym for "sha1" because all our hash functions including
443// -build-id=sha1 are actually tree hashes for performance reasons.
444static std::pair<BuildIdKind, SmallVector<uint8_t, 0>>
445getBuildId(opt::InputArgList &args) {
446 auto *arg = args.getLastArg(Ids: OPT_build_id, Ids: OPT_build_id_eq);
447 if (!arg)
448 return {BuildIdKind::None, {}};
449
450 if (arg->getOption().getID() == OPT_build_id)
451 return {BuildIdKind::Fast, {}};
452
453 StringRef s = arg->getValue();
454 if (s == "fast")
455 return {BuildIdKind::Fast, {}};
456 if (s == "sha1" || s == "tree")
457 return {BuildIdKind::Sha1, {}};
458 if (s == "uuid")
459 return {BuildIdKind::Uuid, {}};
460 if (s.starts_with(Prefix: "0x"))
461 return {BuildIdKind::Hexstring, parseHex(s: s.substr(Start: 2))};
462
463 if (s != "none")
464 error(msg: "unknown --build-id style: " + s);
465 return {BuildIdKind::None, {}};
466}
467
468// Initializes Config members by the command line options.
469static void readConfigs(opt::InputArgList &args) {
470 config->bsymbolic = args.hasArg(Ids: OPT_Bsymbolic);
471 config->checkFeatures =
472 args.hasFlag(Pos: OPT_check_features, Neg: OPT_no_check_features, Default: true);
473 config->compressRelocations = args.hasArg(Ids: OPT_compress_relocations);
474 config->demangle = args.hasFlag(Pos: OPT_demangle, Neg: OPT_no_demangle, Default: true);
475 config->disableVerify = args.hasArg(Ids: OPT_disable_verify);
476 config->emitRelocs = args.hasArg(Ids: OPT_emit_relocs);
477 config->experimentalPic = args.hasArg(Ids: OPT_experimental_pic);
478 config->entry = getEntry(args);
479 config->exportAll = args.hasArg(Ids: OPT_export_all);
480 config->exportTable = args.hasArg(Ids: OPT_export_table);
481 config->growableTable = args.hasArg(Ids: OPT_growable_table);
482
483 if (args.hasArg(Ids: OPT_import_memory_with_name)) {
484 config->memoryImport =
485 args.getLastArgValue(Id: OPT_import_memory_with_name).split(Separator: ",");
486 } else if (args.hasArg(Ids: OPT_import_memory)) {
487 config->memoryImport =
488 std::pair<llvm::StringRef, llvm::StringRef>(defaultModule, memoryName);
489 } else {
490 config->memoryImport =
491 std::optional<std::pair<llvm::StringRef, llvm::StringRef>>();
492 }
493
494 if (args.hasArg(Ids: OPT_export_memory_with_name)) {
495 config->memoryExport =
496 args.getLastArgValue(Id: OPT_export_memory_with_name);
497 } else if (args.hasArg(Ids: OPT_export_memory)) {
498 config->memoryExport = memoryName;
499 } else {
500 config->memoryExport = std::optional<llvm::StringRef>();
501 }
502
503 config->sharedMemory = args.hasArg(Ids: OPT_shared_memory);
504 config->soName = args.getLastArgValue(Id: OPT_soname);
505 config->importTable = args.hasArg(Ids: OPT_import_table);
506 config->importUndefined = args.hasArg(Ids: OPT_import_undefined);
507 config->ltoo = args::getInteger(args, key: OPT_lto_O, Default: 2);
508 if (config->ltoo > 3)
509 error(msg: "invalid optimization level for LTO: " + Twine(config->ltoo));
510 unsigned ltoCgo =
511 args::getInteger(args, key: OPT_lto_CGO, Default: args::getCGOptLevel(optLevelLTO: config->ltoo));
512 if (auto level = CodeGenOpt::getLevel(OL: ltoCgo))
513 config->ltoCgo = *level;
514 else
515 error(msg: "invalid codegen optimization level for LTO: " + Twine(ltoCgo));
516 config->ltoPartitions = args::getInteger(args, key: OPT_lto_partitions, Default: 1);
517 config->ltoDebugPassManager = args.hasArg(Ids: OPT_lto_debug_pass_manager);
518 config->mapFile = args.getLastArgValue(Id: OPT_Map);
519 config->optimize = args::getInteger(args, key: OPT_O, Default: 1);
520 config->outputFile = args.getLastArgValue(Id: OPT_o);
521 config->relocatable = args.hasArg(Ids: OPT_relocatable);
522 config->gcSections =
523 args.hasFlag(Pos: OPT_gc_sections, Neg: OPT_no_gc_sections, Default: !config->relocatable);
524 for (auto *arg : args.filtered(Ids: OPT_keep_section))
525 config->keepSections.insert(key: arg->getValue());
526 config->mergeDataSegments =
527 args.hasFlag(Pos: OPT_merge_data_segments, Neg: OPT_no_merge_data_segments,
528 Default: !config->relocatable);
529 config->pie = args.hasFlag(Pos: OPT_pie, Neg: OPT_no_pie, Default: false);
530 config->printGcSections =
531 args.hasFlag(Pos: OPT_print_gc_sections, Neg: OPT_no_print_gc_sections, Default: false);
532 config->saveTemps = args.hasArg(Ids: OPT_save_temps);
533 config->searchPaths = args::getStrings(args, id: OPT_library_path);
534 config->shared = args.hasArg(Ids: OPT_shared);
535 config->shlibSigCheck = !args.hasArg(Ids: OPT_no_shlib_sigcheck);
536 config->stripAll = args.hasArg(Ids: OPT_strip_all);
537 config->stripDebug = args.hasArg(Ids: OPT_strip_debug);
538 config->stackFirst = args.hasArg(Ids: OPT_stack_first);
539 config->trace = args.hasArg(Ids: OPT_trace);
540 config->thinLTOCacheDir = args.getLastArgValue(Id: OPT_thinlto_cache_dir);
541 config->thinLTOCachePolicy = CHECK(
542 parseCachePruningPolicy(args.getLastArgValue(OPT_thinlto_cache_policy)),
543 "--thinlto-cache-policy: invalid cache policy");
544 config->unresolvedSymbols = getUnresolvedSymbolPolicy(args);
545 config->whyExtract = args.getLastArgValue(Id: OPT_why_extract);
546 errorHandler().verbose = args.hasArg(Ids: OPT_verbose);
547 LLVM_DEBUG(errorHandler().verbose = true);
548
549 config->tableBase = args::getInteger(args, key: OPT_table_base, Default: 0);
550 config->globalBase = args::getInteger(args, key: OPT_global_base, Default: 0);
551 config->initialHeap = args::getInteger(args, key: OPT_initial_heap, Default: 0);
552 config->initialMemory = args::getInteger(args, key: OPT_initial_memory, Default: 0);
553 config->maxMemory = args::getInteger(args, key: OPT_max_memory, Default: 0);
554 config->noGrowableMemory = args.hasArg(Ids: OPT_no_growable_memory);
555 config->zStackSize =
556 args::getZOptionValue(args, id: OPT_z, key: "stack-size", Default: WasmPageSize);
557
558 // -Bdynamic by default if -pie or -shared is specified.
559 if (config->pie || config->shared)
560 config->isStatic = false;
561
562 if (config->maxMemory != 0 && config->noGrowableMemory) {
563 // Erroring out here is simpler than defining precedence rules.
564 error(msg: "--max-memory is incompatible with --no-growable-memory");
565 }
566
567 // Default value of exportDynamic depends on `-shared`
568 config->exportDynamic =
569 args.hasFlag(Pos: OPT_export_dynamic, Neg: OPT_no_export_dynamic, Default: config->shared);
570
571 // Parse wasm32/64.
572 if (auto *arg = args.getLastArg(Ids: OPT_m)) {
573 StringRef s = arg->getValue();
574 if (s == "wasm32")
575 config->is64 = false;
576 else if (s == "wasm64")
577 config->is64 = true;
578 else
579 error(msg: "invalid target architecture: " + s);
580 }
581
582 // --threads= takes a positive integer and provides the default value for
583 // --thinlto-jobs=.
584 if (auto *arg = args.getLastArg(Ids: OPT_threads)) {
585 StringRef v(arg->getValue());
586 unsigned threads = 0;
587 if (!llvm::to_integer(S: v, Num&: threads, Base: 0) || threads == 0)
588 error(msg: arg->getSpelling() + ": expected a positive integer, but got '" +
589 arg->getValue() + "'");
590 parallel::strategy = hardware_concurrency(ThreadCount: threads);
591 config->thinLTOJobs = v;
592 }
593 if (auto *arg = args.getLastArg(Ids: OPT_thinlto_jobs))
594 config->thinLTOJobs = arg->getValue();
595
596 if (auto *arg = args.getLastArg(Ids: OPT_features)) {
597 config->features =
598 std::optional<std::vector<std::string>>(std::vector<std::string>());
599 for (StringRef s : arg->getValues())
600 config->features->push_back(x: std::string(s));
601 }
602
603 if (auto *arg = args.getLastArg(Ids: OPT_extra_features)) {
604 config->extraFeatures =
605 std::optional<std::vector<std::string>>(std::vector<std::string>());
606 for (StringRef s : arg->getValues())
607 config->extraFeatures->push_back(x: std::string(s));
608 }
609
610 // Legacy --allow-undefined flag which is equivalent to
611 // --unresolve-symbols=ignore + --import-undefined
612 if (args.hasArg(Ids: OPT_allow_undefined)) {
613 config->importUndefined = true;
614 config->unresolvedSymbols = UnresolvedPolicy::Ignore;
615 }
616
617 if (args.hasArg(Ids: OPT_print_map))
618 config->mapFile = "-";
619
620 std::tie(args&: config->buildId, args&: config->buildIdVector) = getBuildId(args);
621}
622
623// Some Config members do not directly correspond to any particular
624// command line options, but computed based on other Config values.
625// This function initialize such members. See Config.h for the details
626// of these values.
627static void setConfigs() {
628 ctx.isPic = config->pie || config->shared;
629
630 if (ctx.isPic) {
631 if (config->exportTable)
632 error(msg: "-shared/-pie is incompatible with --export-table");
633 config->importTable = true;
634 } else {
635 // Default table base. Defaults to 1, reserving 0 for the NULL function
636 // pointer.
637 if (!config->tableBase)
638 config->tableBase = 1;
639 // The default offset for static/global data, for when --global-base is
640 // not specified on the command line. The precise value of 1024 is
641 // somewhat arbitrary, and pre-dates wasm-ld (Its the value that
642 // emscripten used prior to wasm-ld).
643 if (!config->globalBase && !config->relocatable && !config->stackFirst)
644 config->globalBase = 1024;
645 }
646
647 if (config->relocatable) {
648 if (config->exportTable)
649 error(msg: "--relocatable is incompatible with --export-table");
650 if (config->growableTable)
651 error(msg: "--relocatable is incompatible with --growable-table");
652 // Ignore any --import-table, as it's redundant.
653 config->importTable = true;
654 }
655
656 if (config->shared) {
657 if (config->memoryExport.has_value()) {
658 error(msg: "--export-memory is incompatible with --shared");
659 }
660 if (!config->memoryImport.has_value()) {
661 config->memoryImport =
662 std::pair<llvm::StringRef, llvm::StringRef>(defaultModule, memoryName);
663 }
664 }
665
666 // If neither export-memory nor import-memory is specified, default to
667 // exporting memory under its default name.
668 if (!config->memoryExport.has_value() && !config->memoryImport.has_value()) {
669 config->memoryExport = memoryName;
670 }
671}
672
673// Some command line options or some combinations of them are not allowed.
674// This function checks for such errors.
675static void checkOptions(opt::InputArgList &args) {
676 if (!config->stripDebug && !config->stripAll && config->compressRelocations)
677 error(msg: "--compress-relocations is incompatible with output debug"
678 " information. Please pass --strip-debug or --strip-all");
679
680 if (config->ltoPartitions == 0)
681 error(msg: "--lto-partitions: number of threads must be > 0");
682 if (!get_threadpool_strategy(Num: config->thinLTOJobs))
683 error(msg: "--thinlto-jobs: invalid job count: " + config->thinLTOJobs);
684
685 if (config->pie && config->shared)
686 error(msg: "-shared and -pie may not be used together");
687
688 if (config->outputFile.empty())
689 error(msg: "no output file specified");
690
691 if (config->importTable && config->exportTable)
692 error(msg: "--import-table and --export-table may not be used together");
693
694 if (config->relocatable) {
695 if (!config->entry.empty())
696 error(msg: "entry point specified for relocatable output file");
697 if (config->gcSections)
698 error(msg: "-r and --gc-sections may not be used together");
699 if (config->compressRelocations)
700 error(msg: "-r -and --compress-relocations may not be used together");
701 if (args.hasArg(Ids: OPT_undefined))
702 error(msg: "-r -and --undefined may not be used together");
703 if (config->pie)
704 error(msg: "-r and -pie may not be used together");
705 if (config->sharedMemory)
706 error(msg: "-r and --shared-memory may not be used together");
707 if (config->globalBase)
708 error(msg: "-r and --global-base may not by used together");
709 }
710
711 // To begin to prepare for Module Linking-style shared libraries, start
712 // warning about uses of `-shared` and related flags outside of Experimental
713 // mode, to give anyone using them a heads-up that they will be changing.
714 //
715 // Also, warn about flags which request explicit exports.
716 if (!config->experimentalPic) {
717 // -shared will change meaning when Module Linking is implemented.
718 if (config->shared) {
719 warn(msg: "creating shared libraries, with -shared, is not yet stable");
720 }
721
722 // -pie will change meaning when Module Linking is implemented.
723 if (config->pie) {
724 warn(msg: "creating PIEs, with -pie, is not yet stable");
725 }
726
727 if (config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic) {
728 warn(msg: "dynamic imports are not yet stable "
729 "(--unresolved-symbols=import-dynamic)");
730 }
731 }
732
733 if (config->bsymbolic && !config->shared) {
734 warn(msg: "-Bsymbolic is only meaningful when combined with -shared");
735 }
736
737 if (ctx.isPic) {
738 if (config->globalBase)
739 error(msg: "--global-base may not be used with -shared/-pie");
740 if (config->tableBase)
741 error(msg: "--table-base may not be used with -shared/-pie");
742 }
743}
744
745static const char *getReproduceOption(opt::InputArgList &args) {
746 if (auto *arg = args.getLastArg(Ids: OPT_reproduce))
747 return arg->getValue();
748 return getenv(name: "LLD_REPRODUCE");
749}
750
751// Force Sym to be entered in the output. Used for -u or equivalent.
752static Symbol *handleUndefined(StringRef name, const char *option) {
753 Symbol *sym = symtab->find(name);
754 if (!sym)
755 return nullptr;
756
757 // Since symbol S may not be used inside the program, LTO may
758 // eliminate it. Mark the symbol as "used" to prevent it.
759 sym->isUsedInRegularObj = true;
760
761 if (auto *lazySym = dyn_cast<LazySymbol>(Val: sym)) {
762 lazySym->extract();
763 if (!config->whyExtract.empty())
764 ctx.whyExtractRecords.emplace_back(Args&: option, Args: sym->getFile(), Args&: *sym);
765 }
766
767 return sym;
768}
769
770static void handleLibcall(StringRef name) {
771 Symbol *sym = symtab->find(name);
772 if (sym && sym->isLazy() && isa<BitcodeFile>(Val: sym->getFile())) {
773 if (!config->whyExtract.empty())
774 ctx.whyExtractRecords.emplace_back(Args: "<libcall>", Args: sym->getFile(), Args&: *sym);
775 cast<LazySymbol>(Val: sym)->extract();
776 }
777}
778
779static void writeWhyExtract() {
780 if (config->whyExtract.empty())
781 return;
782
783 std::error_code ec;
784 raw_fd_ostream os(config->whyExtract, ec, sys::fs::OF_None);
785 if (ec) {
786 error(msg: "cannot open --why-extract= file " + config->whyExtract + ": " +
787 ec.message());
788 return;
789 }
790
791 os << "reference\textracted\tsymbol\n";
792 for (auto &entry : ctx.whyExtractRecords) {
793 os << std::get<0>(t&: entry) << '\t' << toString(file: std::get<1>(t&: entry)) << '\t'
794 << toString(sym: std::get<2>(t&: entry)) << '\n';
795 }
796}
797
798// Equivalent of demote demoteSharedAndLazySymbols() in the ELF linker
799static void demoteLazySymbols() {
800 for (Symbol *sym : symtab->symbols()) {
801 if (auto* s = dyn_cast<LazySymbol>(Val: sym)) {
802 if (s->signature) {
803 LLVM_DEBUG(llvm::dbgs()
804 << "demoting lazy func: " << s->getName() << "\n");
805 replaceSymbol<UndefinedFunction>(s, arg: s->getName(), arg: std::nullopt,
806 arg: std::nullopt, arg: WASM_SYMBOL_BINDING_WEAK,
807 arg: s->getFile(), arg&: s->signature);
808 }
809 }
810 }
811}
812
813static UndefinedGlobal *
814createUndefinedGlobal(StringRef name, llvm::wasm::WasmGlobalType *type) {
815 auto *sym = cast<UndefinedGlobal>(Val: symtab->addUndefinedGlobal(
816 name, importName: std::nullopt, importModule: std::nullopt, flags: WASM_SYMBOL_UNDEFINED, file: nullptr, type));
817 config->allowUndefinedSymbols.insert(key: sym->getName());
818 sym->isUsedInRegularObj = true;
819 return sym;
820}
821
822static InputGlobal *createGlobal(StringRef name, bool isMutable) {
823 llvm::wasm::WasmGlobal wasmGlobal;
824 bool is64 = config->is64.value_or(u: false);
825 wasmGlobal.Type = {.Type: uint8_t(is64 ? WASM_TYPE_I64 : WASM_TYPE_I32), .Mutable: isMutable};
826 wasmGlobal.InitExpr = intConst(value: 0, is64);
827 wasmGlobal.SymbolName = name;
828 return make<InputGlobal>(args&: wasmGlobal, args: nullptr);
829}
830
831static GlobalSymbol *createGlobalVariable(StringRef name, bool isMutable) {
832 InputGlobal *g = createGlobal(name, isMutable);
833 return symtab->addSyntheticGlobal(name, flags: WASM_SYMBOL_VISIBILITY_HIDDEN, global: g);
834}
835
836static GlobalSymbol *createOptionalGlobal(StringRef name, bool isMutable) {
837 InputGlobal *g = createGlobal(name, isMutable);
838 return symtab->addOptionalGlobalSymbol(name, global: g);
839}
840
841// Create ABI-defined synthetic symbols
842static void createSyntheticSymbols() {
843 if (config->relocatable)
844 return;
845
846 static WasmSignature nullSignature = {{}, {}};
847 static WasmSignature i32ArgSignature = {{}, {ValType::I32}};
848 static WasmSignature i64ArgSignature = {{}, {ValType::I64}};
849 static llvm::wasm::WasmGlobalType globalTypeI32 = {.Type: WASM_TYPE_I32, .Mutable: false};
850 static llvm::wasm::WasmGlobalType globalTypeI64 = {.Type: WASM_TYPE_I64, .Mutable: false};
851 static llvm::wasm::WasmGlobalType mutableGlobalTypeI32 = {.Type: WASM_TYPE_I32,
852 .Mutable: true};
853 static llvm::wasm::WasmGlobalType mutableGlobalTypeI64 = {.Type: WASM_TYPE_I64,
854 .Mutable: true};
855 WasmSym::callCtors = symtab->addSyntheticFunction(
856 name: "__wasm_call_ctors", flags: WASM_SYMBOL_VISIBILITY_HIDDEN,
857 function: make<SyntheticFunction>(args&: nullSignature, args: "__wasm_call_ctors"));
858
859 bool is64 = config->is64.value_or(u: false);
860
861 if (ctx.isPic) {
862 WasmSym::stackPointer =
863 createUndefinedGlobal(name: "__stack_pointer", type: config->is64.value_or(u: false)
864 ? &mutableGlobalTypeI64
865 : &mutableGlobalTypeI32);
866 // For PIC code, we import two global variables (__memory_base and
867 // __table_base) from the environment and use these as the offset at
868 // which to load our static data and function table.
869 // See:
870 // https://github.com/WebAssembly/tool-conventions/blob/main/DynamicLinking.md
871 auto *globalType = is64 ? &globalTypeI64 : &globalTypeI32;
872 WasmSym::memoryBase = createUndefinedGlobal(name: "__memory_base", type: globalType);
873 WasmSym::tableBase = createUndefinedGlobal(name: "__table_base", type: globalType);
874 WasmSym::memoryBase->markLive();
875 WasmSym::tableBase->markLive();
876 } else {
877 // For non-PIC code
878 WasmSym::stackPointer = createGlobalVariable(name: "__stack_pointer", isMutable: true);
879 WasmSym::stackPointer->markLive();
880 }
881
882 if (config->sharedMemory) {
883 WasmSym::tlsBase = createGlobalVariable(name: "__tls_base", isMutable: true);
884 WasmSym::tlsSize = createGlobalVariable(name: "__tls_size", isMutable: false);
885 WasmSym::tlsAlign = createGlobalVariable(name: "__tls_align", isMutable: false);
886 WasmSym::initTLS = symtab->addSyntheticFunction(
887 name: "__wasm_init_tls", flags: WASM_SYMBOL_VISIBILITY_HIDDEN,
888 function: make<SyntheticFunction>(
889 args&: is64 ? i64ArgSignature : i32ArgSignature,
890 args: "__wasm_init_tls"));
891 }
892
893 if (ctx.isPic ||
894 config->unresolvedSymbols == UnresolvedPolicy::ImportDynamic) {
895 // For PIC code, or when dynamically importing addresses, we create
896 // synthetic functions that apply relocations. These get called from
897 // __wasm_call_ctors before the user-level constructors.
898 WasmSym::applyDataRelocs = symtab->addSyntheticFunction(
899 name: "__wasm_apply_data_relocs",
900 flags: WASM_SYMBOL_VISIBILITY_DEFAULT | WASM_SYMBOL_EXPORTED,
901 function: make<SyntheticFunction>(args&: nullSignature, args: "__wasm_apply_data_relocs"));
902 }
903}
904
905static void createOptionalSymbols() {
906 if (config->relocatable)
907 return;
908
909 WasmSym::dsoHandle = symtab->addOptionalDataSymbol(name: "__dso_handle");
910
911 if (!config->shared)
912 WasmSym::dataEnd = symtab->addOptionalDataSymbol(name: "__data_end");
913
914 if (!ctx.isPic) {
915 WasmSym::stackLow = symtab->addOptionalDataSymbol(name: "__stack_low");
916 WasmSym::stackHigh = symtab->addOptionalDataSymbol(name: "__stack_high");
917 WasmSym::globalBase = symtab->addOptionalDataSymbol(name: "__global_base");
918 WasmSym::heapBase = symtab->addOptionalDataSymbol(name: "__heap_base");
919 WasmSym::heapEnd = symtab->addOptionalDataSymbol(name: "__heap_end");
920 WasmSym::definedMemoryBase = symtab->addOptionalDataSymbol(name: "__memory_base");
921 WasmSym::definedTableBase = symtab->addOptionalDataSymbol(name: "__table_base");
922 }
923
924 // For non-shared memory programs we still need to define __tls_base since we
925 // allow object files built with TLS to be linked into single threaded
926 // programs, and such object files can contain references to this symbol.
927 //
928 // However, in this case __tls_base is immutable and points directly to the
929 // start of the `.tdata` static segment.
930 //
931 // __tls_size and __tls_align are not needed in this case since they are only
932 // needed for __wasm_init_tls (which we do not create in this case).
933 if (!config->sharedMemory)
934 WasmSym::tlsBase = createOptionalGlobal(name: "__tls_base", isMutable: false);
935}
936
937static void processStubLibrariesPreLTO() {
938 log(msg: "-- processStubLibrariesPreLTO");
939 for (auto &stub_file : ctx.stubFiles) {
940 LLVM_DEBUG(llvm::dbgs()
941 << "processing stub file: " << stub_file->getName() << "\n");
942 for (auto [name, deps]: stub_file->symbolDependencies) {
943 auto* sym = symtab->find(name);
944 // If the symbol is not present at all (yet), or if it is present but
945 // undefined, then mark the dependent symbols as used by a regular
946 // object so they will be preserved and exported by the LTO process.
947 if (!sym || sym->isUndefined()) {
948 for (const auto dep : deps) {
949 auto* needed = symtab->find(name: dep);
950 if (needed ) {
951 needed->isUsedInRegularObj = true;
952 }
953 }
954 }
955 }
956 }
957}
958
959static bool addStubSymbolDeps(const StubFile *stub_file, Symbol *sym,
960 ArrayRef<StringRef> deps) {
961 // The first stub library to define a given symbol sets this and
962 // definitions in later stub libraries are ignored.
963 if (sym->forceImport)
964 return false; // Already handled
965 sym->forceImport = true;
966 if (sym->traced)
967 message(msg: toString(file: stub_file) + ": importing " + sym->getName());
968 else
969 LLVM_DEBUG(llvm::dbgs() << toString(stub_file) << ": importing "
970 << sym->getName() << "\n");
971 bool depsAdded = false;
972 for (const auto dep : deps) {
973 auto *needed = symtab->find(name: dep);
974 if (!needed) {
975 error(msg: toString(file: stub_file) + ": undefined symbol: " + dep +
976 ". Required by " + toString(sym: *sym));
977 } else if (needed->isUndefined()) {
978 error(msg: toString(file: stub_file) + ": undefined symbol: " + toString(sym: *needed) +
979 ". Required by " + toString(sym: *sym));
980 } else {
981 if (needed->traced)
982 message(msg: toString(file: stub_file) + ": exported " + toString(sym: *needed) +
983 " due to import of " + sym->getName());
984 else
985 LLVM_DEBUG(llvm::dbgs()
986 << "force export: " << toString(*needed) << "\n");
987 needed->forceExport = true;
988 if (auto *lazy = dyn_cast<LazySymbol>(Val: needed)) {
989 depsAdded = true;
990 lazy->extract();
991 if (!config->whyExtract.empty())
992 ctx.whyExtractRecords.emplace_back(Args: toString(file: stub_file),
993 Args: sym->getFile(), Args&: *sym);
994 }
995 }
996 }
997 return depsAdded;
998}
999
1000static void processStubLibraries() {
1001 log(msg: "-- processStubLibraries");
1002 bool depsAdded = false;
1003 do {
1004 depsAdded = false;
1005 for (auto &stub_file : ctx.stubFiles) {
1006 LLVM_DEBUG(llvm::dbgs()
1007 << "processing stub file: " << stub_file->getName() << "\n");
1008
1009 // First look for any imported symbols that directly match
1010 // the names of the stub imports
1011 for (auto [name, deps]: stub_file->symbolDependencies) {
1012 auto* sym = symtab->find(name);
1013 if (sym && sym->isUndefined()) {
1014 depsAdded |= addStubSymbolDeps(stub_file, sym, deps);
1015 } else {
1016 if (sym && sym->traced)
1017 message(msg: toString(file: stub_file) + ": stub symbol not needed: " + name);
1018 else
1019 LLVM_DEBUG(llvm::dbgs()
1020 << "stub symbol not needed: `" << name << "`\n");
1021 }
1022 }
1023
1024 // Secondly looks for any symbols with an `importName` that matches
1025 for (Symbol *sym : symtab->symbols()) {
1026 if (sym->isUndefined() && sym->importName.has_value()) {
1027 auto it = stub_file->symbolDependencies.find(Val: sym->importName.value());
1028 if (it != stub_file->symbolDependencies.end()) {
1029 depsAdded |= addStubSymbolDeps(stub_file, sym, deps: it->second);
1030 }
1031 }
1032 }
1033 }
1034 } while (depsAdded);
1035
1036 log(msg: "-- done processStubLibraries");
1037}
1038
1039// Reconstructs command line arguments so that so that you can re-run
1040// the same command with the same inputs. This is for --reproduce.
1041static std::string createResponseFile(const opt::InputArgList &args) {
1042 SmallString<0> data;
1043 raw_svector_ostream os(data);
1044
1045 // Copy the command line to the output while rewriting paths.
1046 for (auto *arg : args) {
1047 switch (arg->getOption().getID()) {
1048 case OPT_reproduce:
1049 break;
1050 case OPT_INPUT:
1051 os << quote(s: relativeToRoot(path: arg->getValue())) << "\n";
1052 break;
1053 case OPT_o:
1054 // If -o path contains directories, "lld @response.txt" will likely
1055 // fail because the archive we are creating doesn't contain empty
1056 // directories for the output path (-o doesn't create directories).
1057 // Strip directories to prevent the issue.
1058 os << "-o " << quote(s: sys::path::filename(path: arg->getValue())) << "\n";
1059 break;
1060 default:
1061 os << toString(arg: *arg) << "\n";
1062 }
1063 }
1064 return std::string(data);
1065}
1066
1067// The --wrap option is a feature to rename symbols so that you can write
1068// wrappers for existing functions. If you pass `-wrap=foo`, all
1069// occurrences of symbol `foo` are resolved to `wrap_foo` (so, you are
1070// expected to write `wrap_foo` function as a wrapper). The original
1071// symbol becomes accessible as `real_foo`, so you can call that from your
1072// wrapper.
1073//
1074// This data structure is instantiated for each -wrap option.
1075struct WrappedSymbol {
1076 Symbol *sym;
1077 Symbol *real;
1078 Symbol *wrap;
1079};
1080
1081static Symbol *addUndefined(StringRef name) {
1082 return symtab->addUndefinedFunction(name, importName: std::nullopt, importModule: std::nullopt,
1083 flags: WASM_SYMBOL_UNDEFINED, file: nullptr, signature: nullptr,
1084 isCalledDirectly: false);
1085}
1086
1087// Handles -wrap option.
1088//
1089// This function instantiates wrapper symbols. At this point, they seem
1090// like they are not being used at all, so we explicitly set some flags so
1091// that LTO won't eliminate them.
1092static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &args) {
1093 std::vector<WrappedSymbol> v;
1094 DenseSet<StringRef> seen;
1095
1096 for (auto *arg : args.filtered(Ids: OPT_wrap)) {
1097 StringRef name = arg->getValue();
1098 if (!seen.insert(V: name).second)
1099 continue;
1100
1101 Symbol *sym = symtab->find(name);
1102 if (!sym)
1103 continue;
1104
1105 Symbol *real = addUndefined(name: saver().save(S: "__real_" + name));
1106 Symbol *wrap = addUndefined(name: saver().save(S: "__wrap_" + name));
1107 v.push_back(x: {.sym: sym, .real: real, .wrap: wrap});
1108
1109 // We want to tell LTO not to inline symbols to be overwritten
1110 // because LTO doesn't know the final symbol contents after renaming.
1111 real->canInline = false;
1112 sym->canInline = false;
1113
1114 // Tell LTO not to eliminate these symbols.
1115 sym->isUsedInRegularObj = true;
1116 wrap->isUsedInRegularObj = true;
1117 real->isUsedInRegularObj = false;
1118 }
1119 return v;
1120}
1121
1122// Do renaming for -wrap by updating pointers to symbols.
1123//
1124// When this function is executed, only InputFiles and symbol table
1125// contain pointers to symbol objects. We visit them to replace pointers,
1126// so that wrapped symbols are swapped as instructed by the command line.
1127static void wrapSymbols(ArrayRef<WrappedSymbol> wrapped) {
1128 DenseMap<Symbol *, Symbol *> map;
1129 for (const WrappedSymbol &w : wrapped) {
1130 map[w.sym] = w.wrap;
1131 map[w.real] = w.sym;
1132 }
1133
1134 // Update pointers in input files.
1135 parallelForEach(R&: ctx.objectFiles, Fn: [&](InputFile *file) {
1136 MutableArrayRef<Symbol *> syms = file->getMutableSymbols();
1137 for (size_t i = 0, e = syms.size(); i != e; ++i)
1138 if (Symbol *s = map.lookup(Val: syms[i]))
1139 syms[i] = s;
1140 });
1141
1142 // Update pointers in the symbol table.
1143 for (const WrappedSymbol &w : wrapped)
1144 symtab->wrap(sym: w.sym, real: w.real, wrap: w.wrap);
1145}
1146
1147static void splitSections() {
1148 // splitIntoPieces needs to be called on each MergeInputChunk
1149 // before calling finalizeContents().
1150 LLVM_DEBUG(llvm::dbgs() << "splitSections\n");
1151 parallelForEach(R&: ctx.objectFiles, Fn: [](ObjFile *file) {
1152 for (InputChunk *seg : file->segments) {
1153 if (auto *s = dyn_cast<MergeInputChunk>(Val: seg))
1154 s->splitIntoPieces();
1155 }
1156 for (InputChunk *sec : file->customSections) {
1157 if (auto *s = dyn_cast<MergeInputChunk>(Val: sec))
1158 s->splitIntoPieces();
1159 }
1160 });
1161}
1162
1163static bool isKnownZFlag(StringRef s) {
1164 // For now, we only support a very limited set of -z flags
1165 return s.starts_with(Prefix: "stack-size=");
1166}
1167
1168// Report a warning for an unknown -z option.
1169static void checkZOptions(opt::InputArgList &args) {
1170 for (auto *arg : args.filtered(Ids: OPT_z))
1171 if (!isKnownZFlag(s: arg->getValue()))
1172 warn(msg: "unknown -z value: " + StringRef(arg->getValue()));
1173}
1174
1175void LinkerDriver::linkerMain(ArrayRef<const char *> argsArr) {
1176 WasmOptTable parser;
1177 opt::InputArgList args = parser.parse(argv: argsArr.slice(N: 1));
1178
1179 // Interpret these flags early because error()/warn() depend on them.
1180 errorHandler().errorLimit = args::getInteger(args, key: OPT_error_limit, Default: 20);
1181 errorHandler().fatalWarnings =
1182 args.hasFlag(Pos: OPT_fatal_warnings, Neg: OPT_no_fatal_warnings, Default: false);
1183 checkZOptions(args);
1184
1185 // Handle --help
1186 if (args.hasArg(Ids: OPT_help)) {
1187 parser.printHelp(OS&: lld::outs(),
1188 Usage: (std::string(argsArr[0]) + " [options] file...").c_str(),
1189 Title: "LLVM Linker", ShowHidden: false);
1190 return;
1191 }
1192
1193 // Handle --version
1194 if (args.hasArg(Ids: OPT_version) || args.hasArg(Ids: OPT_v)) {
1195 lld::outs() << getLLDVersion() << "\n";
1196 return;
1197 }
1198
1199 // Handle --reproduce
1200 if (const char *path = getReproduceOption(args)) {
1201 Expected<std::unique_ptr<TarWriter>> errOrWriter =
1202 TarWriter::create(OutputPath: path, BaseDir: path::stem(path));
1203 if (errOrWriter) {
1204 tar = std::move(*errOrWriter);
1205 tar->append(Path: "response.txt", Data: createResponseFile(args));
1206 tar->append(Path: "version.txt", Data: getLLDVersion() + "\n");
1207 } else {
1208 error(msg: "--reproduce: " + toString(E: errOrWriter.takeError()));
1209 }
1210 }
1211
1212 // Parse and evaluate -mllvm options.
1213 std::vector<const char *> v;
1214 v.push_back(x: "wasm-ld (LLVM option parsing)");
1215 for (auto *arg : args.filtered(Ids: OPT_mllvm))
1216 v.push_back(x: arg->getValue());
1217 cl::ResetAllOptionOccurrences();
1218 cl::ParseCommandLineOptions(argc: v.size(), argv: v.data());
1219
1220 readConfigs(args);
1221 setConfigs();
1222
1223 createFiles(args);
1224 if (errorCount())
1225 return;
1226
1227 checkOptions(args);
1228 if (errorCount())
1229 return;
1230
1231 if (auto *arg = args.getLastArg(Ids: OPT_allow_undefined_file))
1232 readImportFile(filename: arg->getValue());
1233
1234 // Fail early if the output file or map file is not writable. If a user has a
1235 // long link, e.g. due to a large LTO link, they do not wish to run it and
1236 // find that it failed because there was a mistake in their command-line.
1237 if (auto e = tryCreateFile(path: config->outputFile))
1238 error(msg: "cannot open output file " + config->outputFile + ": " + e.message());
1239 if (auto e = tryCreateFile(path: config->mapFile))
1240 error(msg: "cannot open map file " + config->mapFile + ": " + e.message());
1241 if (errorCount())
1242 return;
1243
1244 // Handle --trace-symbol.
1245 for (auto *arg : args.filtered(Ids: OPT_trace_symbol))
1246 symtab->trace(name: arg->getValue());
1247
1248 for (auto *arg : args.filtered(Ids: OPT_export_if_defined))
1249 config->exportedSymbols.insert(key: arg->getValue());
1250
1251 for (auto *arg : args.filtered(Ids: OPT_export)) {
1252 config->exportedSymbols.insert(key: arg->getValue());
1253 config->requiredExports.push_back(x: arg->getValue());
1254 }
1255
1256 createSyntheticSymbols();
1257
1258 // Add all files to the symbol table. This will add almost all
1259 // symbols that we need to the symbol table.
1260 for (InputFile *f : files)
1261 symtab->addFile(file: f);
1262 if (errorCount())
1263 return;
1264
1265 // Handle the `--undefined <sym>` options.
1266 for (auto *arg : args.filtered(Ids: OPT_undefined))
1267 handleUndefined(name: arg->getValue(), option: "<internal>");
1268
1269 // Handle the `--export <sym>` options
1270 // This works like --undefined but also exports the symbol if its found
1271 for (auto &iter : config->exportedSymbols)
1272 handleUndefined(name: iter.first(), option: "--export");
1273
1274 Symbol *entrySym = nullptr;
1275 if (!config->relocatable && !config->entry.empty()) {
1276 entrySym = handleUndefined(name: config->entry, option: "--entry");
1277 if (entrySym && entrySym->isDefined())
1278 entrySym->forceExport = true;
1279 else
1280 error(msg: "entry symbol not defined (pass --no-entry to suppress): " +
1281 config->entry);
1282 }
1283
1284 // If the user code defines a `__wasm_call_dtors` function, remember it so
1285 // that we can call it from the command export wrappers. Unlike
1286 // `__wasm_call_ctors` which we synthesize, `__wasm_call_dtors` is defined
1287 // by libc/etc., because destructors are registered dynamically with
1288 // `__cxa_atexit` and friends.
1289 if (!config->relocatable && !config->shared &&
1290 !WasmSym::callCtors->isUsedInRegularObj &&
1291 WasmSym::callCtors->getName() != config->entry &&
1292 !config->exportedSymbols.count(Key: WasmSym::callCtors->getName())) {
1293 if (Symbol *callDtors =
1294 handleUndefined(name: "__wasm_call_dtors", option: "<internal>")) {
1295 if (auto *callDtorsFunc = dyn_cast<DefinedFunction>(Val: callDtors)) {
1296 if (callDtorsFunc->signature &&
1297 (!callDtorsFunc->signature->Params.empty() ||
1298 !callDtorsFunc->signature->Returns.empty())) {
1299 error(msg: "__wasm_call_dtors must have no argument or return values");
1300 }
1301 WasmSym::callDtors = callDtorsFunc;
1302 } else {
1303 error(msg: "__wasm_call_dtors must be a function");
1304 }
1305 }
1306 }
1307
1308 if (errorCount())
1309 return;
1310
1311 // Create wrapped symbols for -wrap option.
1312 std::vector<WrappedSymbol> wrapped = addWrappedSymbols(args);
1313
1314 // If any of our inputs are bitcode files, the LTO code generator may create
1315 // references to certain library functions that might not be explicit in the
1316 // bitcode file's symbol table. If any of those library functions are defined
1317 // in a bitcode file in an archive member, we need to arrange to use LTO to
1318 // compile those archive members by adding them to the link beforehand.
1319 //
1320 // We only need to add libcall symbols to the link before LTO if the symbol's
1321 // definition is in bitcode. Any other required libcall symbols will be added
1322 // to the link after LTO when we add the LTO object file to the link.
1323 if (!ctx.bitcodeFiles.empty()) {
1324 llvm::Triple TT(ctx.bitcodeFiles.front()->obj->getTargetTriple());
1325 for (auto *s : lto::LTO::getRuntimeLibcallSymbols(TT))
1326 handleLibcall(name: s);
1327 }
1328 if (errorCount())
1329 return;
1330
1331 // We process the stub libraries once beofore LTO to ensure that any possible
1332 // required exports are preserved by the LTO process.
1333 processStubLibrariesPreLTO();
1334
1335 // Do link-time optimization if given files are LLVM bitcode files.
1336 // This compiles bitcode files into real object files.
1337 symtab->compileBitcodeFiles();
1338 if (errorCount())
1339 return;
1340
1341 // The LTO process can generate new undefined symbols, specifically libcall
1342 // functions. Because those symbols might be declared in a stub library we
1343 // need the process the stub libraries once again after LTO to handle all
1344 // undefined symbols, including ones that didn't exist prior to LTO.
1345 processStubLibraries();
1346
1347 writeWhyExtract();
1348
1349 createOptionalSymbols();
1350
1351 // Resolve any variant symbols that were created due to signature
1352 // mismatchs.
1353 symtab->handleSymbolVariants();
1354 if (errorCount())
1355 return;
1356
1357 // Apply symbol renames for -wrap.
1358 if (!wrapped.empty())
1359 wrapSymbols(wrapped);
1360
1361 for (auto &iter : config->exportedSymbols) {
1362 Symbol *sym = symtab->find(name: iter.first());
1363 if (sym && sym->isDefined())
1364 sym->forceExport = true;
1365 }
1366
1367 if (!config->relocatable && !ctx.isPic) {
1368 // Add synthetic dummies for weak undefined functions. Must happen
1369 // after LTO otherwise functions may not yet have signatures.
1370 symtab->handleWeakUndefines();
1371 }
1372
1373 if (entrySym)
1374 entrySym->setHidden(false);
1375
1376 if (errorCount())
1377 return;
1378
1379 // Split WASM_SEG_FLAG_STRINGS sections into pieces in preparation for garbage
1380 // collection.
1381 splitSections();
1382
1383 // Any remaining lazy symbols should be demoted to Undefined
1384 demoteLazySymbols();
1385
1386 // Do size optimizations: garbage collection
1387 markLive();
1388
1389 // Provide the indirect function table if needed.
1390 WasmSym::indirectFunctionTable =
1391 symtab->resolveIndirectFunctionTable(/*required =*/false);
1392
1393 if (errorCount())
1394 return;
1395
1396 // Write the result to the file.
1397 writeResult();
1398}
1399
1400} // namespace lld::wasm
1401