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