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