xref: /openbsd-src/gnu/llvm/lld/wasm/Driver.cpp (revision 1a8dbaac879b9f3335ad7fb25429ce63ac1d6bac)
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 "InputGlobal.h"
13 #include "MarkLive.h"
14 #include "SymbolTable.h"
15 #include "Writer.h"
16 #include "lld/Common/Args.h"
17 #include "lld/Common/ErrorHandler.h"
18 #include "lld/Common/Memory.h"
19 #include "lld/Common/Reproduce.h"
20 #include "lld/Common/Strings.h"
21 #include "lld/Common/Threads.h"
22 #include "lld/Common/Version.h"
23 #include "llvm/ADT/Twine.h"
24 #include "llvm/Object/Wasm.h"
25 #include "llvm/Option/Arg.h"
26 #include "llvm/Option/ArgList.h"
27 #include "llvm/Support/CommandLine.h"
28 #include "llvm/Support/Path.h"
29 #include "llvm/Support/Process.h"
30 #include "llvm/Support/TarWriter.h"
31 #include "llvm/Support/TargetSelect.h"
32 
33 #define DEBUG_TYPE "lld"
34 
35 using namespace llvm;
36 using namespace llvm::object;
37 using namespace llvm::sys;
38 using namespace llvm::wasm;
39 
40 namespace lld {
41 namespace wasm {
42 Configuration *config;
43 
44 namespace {
45 
46 // Create enum with OPT_xxx values for each option in Options.td
47 enum {
48   OPT_INVALID = 0,
49 #define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID,
50 #include "Options.inc"
51 #undef OPTION
52 };
53 
54 // This function is called on startup. We need this for LTO since
55 // LTO calls LLVM functions to compile bitcode files to native code.
56 // Technically this can be delayed until we read bitcode files, but
57 // we don't bother to do lazily because the initialization is fast.
58 static void initLLVM() {
59   InitializeAllTargets();
60   InitializeAllTargetMCs();
61   InitializeAllAsmPrinters();
62   InitializeAllAsmParsers();
63 }
64 
65 class LinkerDriver {
66 public:
67   void link(ArrayRef<const char *> argsArr);
68 
69 private:
70   void createFiles(opt::InputArgList &args);
71   void addFile(StringRef path);
72   void addLibrary(StringRef name);
73 
74   // True if we are in --whole-archive and --no-whole-archive.
75   bool inWholeArchive = false;
76 
77   std::vector<InputFile *> files;
78 };
79 } // anonymous namespace
80 
81 bool link(ArrayRef<const char *> args, bool canExitEarly, raw_ostream &stdoutOS,
82           raw_ostream &stderrOS) {
83   lld::stdoutOS = &stdoutOS;
84   lld::stderrOS = &stderrOS;
85 
86   errorHandler().logName = args::getFilenameWithoutExe(args[0]);
87   errorHandler().errorLimitExceededMsg =
88       "too many errors emitted, stopping now (use "
89       "-error-limit=0 to see all errors)";
90   stderrOS.enable_colors(stderrOS.has_colors());
91 
92   config = make<Configuration>();
93   symtab = make<SymbolTable>();
94 
95   initLLVM();
96   LinkerDriver().link(args);
97 
98   // Exit immediately if we don't need to return to the caller.
99   // This saves time because the overhead of calling destructors
100   // for all globally-allocated objects is not negligible.
101   if (canExitEarly)
102     exitLld(errorCount() ? 1 : 0);
103 
104   freeArena();
105   return !errorCount();
106 }
107 
108 // Create prefix string literals used in Options.td
109 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
110 #include "Options.inc"
111 #undef PREFIX
112 
113 // Create table mapping all options defined in Options.td
114 static const 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 llvm::opt::OptTable {
124 public:
125   WasmOptTable() : OptTable(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.
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 
152 // Find a file by concatenating given paths.
153 static Optional<std::string> findFile(StringRef path1, const Twine &path2) {
154   SmallString<128> s;
155   path::append(s, path1, path2);
156   if (fs::exists(s))
157     return s.str().str();
158   return None;
159 }
160 
161 opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> argv) {
162   SmallVector<const char *, 256> vec(argv.data(), argv.data() + argv.size());
163 
164   unsigned missingIndex;
165   unsigned missingCount;
166 
167   // Expand response files (arguments in the form of @<filename>)
168   cl::ExpandResponseFiles(saver, cl::TokenizeGNUCommandLine, vec);
169 
170   opt::InputArgList args = this->ParseArgs(vec, missingIndex, missingCount);
171 
172   handleColorDiagnostics(args);
173   for (auto *arg : args.filtered(OPT_UNKNOWN))
174     error("unknown argument: " + arg->getAsString(args));
175   return args;
176 }
177 
178 // Currently we allow a ".imports" to live alongside a library. This can
179 // be used to specify a list of symbols which can be undefined at link
180 // time (imported from the environment.  For example libc.a include an
181 // import file that lists the syscall functions it relies on at runtime.
182 // In the long run this information would be better stored as a symbol
183 // attribute/flag in the object file itself.
184 // See: https://github.com/WebAssembly/tool-conventions/issues/35
185 static void readImportFile(StringRef filename) {
186   if (Optional<MemoryBufferRef> buf = readFile(filename))
187     for (StringRef sym : args::getLines(*buf))
188       config->allowUndefinedSymbols.insert(sym);
189 }
190 
191 // Returns slices of MB by parsing MB as an archive file.
192 // Each slice consists of a member file in the archive.
193 std::vector<MemoryBufferRef> static getArchiveMembers(MemoryBufferRef mb) {
194   std::unique_ptr<Archive> file =
195       CHECK(Archive::create(mb),
196             mb.getBufferIdentifier() + ": failed to parse archive");
197 
198   std::vector<MemoryBufferRef> v;
199   Error err = Error::success();
200   for (const Archive::Child &c : file->children(err)) {
201     MemoryBufferRef mbref =
202         CHECK(c.getMemoryBufferRef(),
203               mb.getBufferIdentifier() +
204                   ": could not get the buffer for a child of the archive");
205     v.push_back(mbref);
206   }
207   if (err)
208     fatal(mb.getBufferIdentifier() +
209           ": Archive::children failed: " + toString(std::move(err)));
210 
211   // Take ownership of memory buffers created for members of thin archives.
212   for (std::unique_ptr<MemoryBuffer> &mb : file->takeThinBuffers())
213     make<std::unique_ptr<MemoryBuffer>>(std::move(mb));
214 
215   return v;
216 }
217 
218 void LinkerDriver::addFile(StringRef path) {
219   Optional<MemoryBufferRef> buffer = readFile(path);
220   if (!buffer.hasValue())
221     return;
222   MemoryBufferRef mbref = *buffer;
223 
224   switch (identify_magic(mbref.getBuffer())) {
225   case file_magic::archive: {
226     SmallString<128> importFile = path;
227     path::replace_extension(importFile, ".imports");
228     if (fs::exists(importFile))
229       readImportFile(importFile.str());
230 
231     // Handle -whole-archive.
232     if (inWholeArchive) {
233       for (MemoryBufferRef &m : getArchiveMembers(mbref))
234         files.push_back(createObjectFile(m, path));
235       return;
236     }
237 
238     std::unique_ptr<Archive> file =
239         CHECK(Archive::create(mbref), path + ": failed to parse archive");
240 
241     if (!file->isEmpty() && !file->hasSymbolTable()) {
242       error(mbref.getBufferIdentifier() +
243             ": archive has no index; run ranlib to add one");
244     }
245 
246     files.push_back(make<ArchiveFile>(mbref));
247     return;
248   }
249   case file_magic::bitcode:
250   case file_magic::wasm_object:
251     files.push_back(createObjectFile(mbref));
252     break;
253   default:
254     error("unknown file type: " + mbref.getBufferIdentifier());
255   }
256 }
257 
258 // Add a given library by searching it from input search paths.
259 void LinkerDriver::addLibrary(StringRef name) {
260   for (StringRef dir : config->searchPaths) {
261     if (Optional<std::string> s = findFile(dir, "lib" + name + ".a")) {
262       addFile(*s);
263       return;
264     }
265   }
266 
267   error("unable to find library -l" + name);
268 }
269 
270 void LinkerDriver::createFiles(opt::InputArgList &args) {
271   for (auto *arg : args) {
272     switch (arg->getOption().getID()) {
273     case OPT_l:
274       addLibrary(arg->getValue());
275       break;
276     case OPT_INPUT:
277       addFile(arg->getValue());
278       break;
279     case OPT_whole_archive:
280       inWholeArchive = true;
281       break;
282     case OPT_no_whole_archive:
283       inWholeArchive = false;
284       break;
285     }
286   }
287 }
288 
289 static StringRef getEntry(opt::InputArgList &args) {
290   auto *arg = args.getLastArg(OPT_entry, OPT_no_entry);
291   if (!arg) {
292     if (args.hasArg(OPT_relocatable))
293       return "";
294     if (args.hasArg(OPT_shared))
295       return "__wasm_call_ctors";
296     return "_start";
297   }
298   if (arg->getOption().getID() == OPT_no_entry)
299     return "";
300   return arg->getValue();
301 }
302 
303 // Initializes Config members by the command line options.
304 static void readConfigs(opt::InputArgList &args) {
305   config->allowUndefined = args.hasArg(OPT_allow_undefined);
306   config->checkFeatures =
307       args.hasFlag(OPT_check_features, OPT_no_check_features, true);
308   config->compressRelocations = args.hasArg(OPT_compress_relocations);
309   config->demangle = args.hasFlag(OPT_demangle, OPT_no_demangle, true);
310   config->disableVerify = args.hasArg(OPT_disable_verify);
311   config->emitRelocs = args.hasArg(OPT_emit_relocs);
312   config->entry = getEntry(args);
313   config->exportAll = args.hasArg(OPT_export_all);
314   config->exportTable = args.hasArg(OPT_export_table);
315   config->growableTable = args.hasArg(OPT_growable_table);
316   errorHandler().fatalWarnings =
317       args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
318   config->importMemory = args.hasArg(OPT_import_memory);
319   config->sharedMemory = args.hasArg(OPT_shared_memory);
320   config->importTable = args.hasArg(OPT_import_table);
321   config->ltoo = args::getInteger(args, OPT_lto_O, 2);
322   config->ltoPartitions = args::getInteger(args, OPT_lto_partitions, 1);
323   config->optimize = args::getInteger(args, OPT_O, 0);
324   config->outputFile = args.getLastArgValue(OPT_o);
325   config->relocatable = args.hasArg(OPT_relocatable);
326   config->gcSections =
327       args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !config->relocatable);
328   config->mergeDataSegments =
329       args.hasFlag(OPT_merge_data_segments, OPT_no_merge_data_segments,
330                    !config->relocatable);
331   config->pie = args.hasFlag(OPT_pie, OPT_no_pie, false);
332   config->printGcSections =
333       args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
334   config->saveTemps = args.hasArg(OPT_save_temps);
335   config->searchPaths = args::getStrings(args, OPT_L);
336   config->shared = args.hasArg(OPT_shared);
337   config->stripAll = args.hasArg(OPT_strip_all);
338   config->stripDebug = args.hasArg(OPT_strip_debug);
339   config->stackFirst = args.hasArg(OPT_stack_first);
340   config->trace = args.hasArg(OPT_trace);
341   config->thinLTOCacheDir = args.getLastArgValue(OPT_thinlto_cache_dir);
342   config->thinLTOCachePolicy = CHECK(
343       parseCachePruningPolicy(args.getLastArgValue(OPT_thinlto_cache_policy)),
344       "--thinlto-cache-policy: invalid cache policy");
345   config->thinLTOJobs = args::getInteger(args, OPT_thinlto_jobs, -1u);
346   errorHandler().verbose = args.hasArg(OPT_verbose);
347   LLVM_DEBUG(errorHandler().verbose = true);
348   threadsEnabled = args.hasFlag(OPT_threads, OPT_no_threads, true);
349 
350   config->initialMemory = args::getInteger(args, OPT_initial_memory, 0);
351   config->globalBase = args::getInteger(args, OPT_global_base, 1024);
352   config->maxMemory = args::getInteger(args, OPT_max_memory, 0);
353   config->zStackSize =
354       args::getZOptionValue(args, OPT_z, "stack-size", WasmPageSize);
355 
356   // Default value of exportDynamic depends on `-shared`
357   config->exportDynamic =
358       args.hasFlag(OPT_export_dynamic, OPT_no_export_dynamic, config->shared);
359 
360   if (auto *arg = args.getLastArg(OPT_features)) {
361     config->features =
362         llvm::Optional<std::vector<std::string>>(std::vector<std::string>());
363     for (StringRef s : arg->getValues())
364       config->features->push_back(s);
365   }
366 }
367 
368 // Some Config members do not directly correspond to any particular
369 // command line options, but computed based on other Config values.
370 // This function initialize such members. See Config.h for the details
371 // of these values.
372 static void setConfigs() {
373   config->isPic = config->pie || config->shared;
374 
375   if (config->isPic) {
376     if (config->exportTable)
377       error("-shared/-pie is incompatible with --export-table");
378     config->importTable = true;
379   }
380 
381   if (config->shared) {
382     config->importMemory = true;
383     config->allowUndefined = true;
384   }
385 }
386 
387 // Some command line options or some combinations of them are not allowed.
388 // This function checks for such errors.
389 static void checkOptions(opt::InputArgList &args) {
390   if (!config->stripDebug && !config->stripAll && config->compressRelocations)
391     error("--compress-relocations is incompatible with output debug"
392           " information. Please pass --strip-debug or --strip-all");
393 
394   if (config->ltoo > 3)
395     error("invalid optimization level for LTO: " + Twine(config->ltoo));
396   if (config->ltoPartitions == 0)
397     error("--lto-partitions: number of threads must be > 0");
398   if (config->thinLTOJobs == 0)
399     error("--thinlto-jobs: number of threads must be > 0");
400 
401   if (config->pie && config->shared)
402     error("-shared and -pie may not be used together");
403 
404   if (config->outputFile.empty())
405     error("no output file specified");
406 
407   if (config->importTable && config->exportTable)
408     error("--import-table and --export-table may not be used together");
409 
410   if (config->relocatable) {
411     if (!config->entry.empty())
412       error("entry point specified for relocatable output file");
413     if (config->gcSections)
414       error("-r and --gc-sections may not be used together");
415     if (config->compressRelocations)
416       error("-r -and --compress-relocations may not be used together");
417     if (args.hasArg(OPT_undefined))
418       error("-r -and --undefined may not be used together");
419     if (config->pie)
420       error("-r and -pie may not be used together");
421   }
422 }
423 
424 // Force Sym to be entered in the output. Used for -u or equivalent.
425 static Symbol *handleUndefined(StringRef name) {
426   Symbol *sym = symtab->find(name);
427   if (!sym)
428     return nullptr;
429 
430   // Since symbol S may not be used inside the program, LTO may
431   // eliminate it. Mark the symbol as "used" to prevent it.
432   sym->isUsedInRegularObj = true;
433 
434   if (auto *lazySym = dyn_cast<LazySymbol>(sym))
435     lazySym->fetch();
436 
437   return sym;
438 }
439 
440 static void handleLibcall(StringRef name) {
441   Symbol *sym = symtab->find(name);
442   if (!sym)
443     return;
444 
445   if (auto *lazySym = dyn_cast<LazySymbol>(sym)) {
446     MemoryBufferRef mb = lazySym->getMemberBuffer();
447     if (isBitcode(mb))
448       lazySym->fetch();
449   }
450 }
451 
452 static UndefinedGlobal *
453 createUndefinedGlobal(StringRef name, llvm::wasm::WasmGlobalType *type) {
454   auto *sym = cast<UndefinedGlobal>(symtab->addUndefinedGlobal(
455       name, name, defaultModule, WASM_SYMBOL_UNDEFINED, nullptr, type));
456   config->allowUndefinedSymbols.insert(sym->getName());
457   sym->isUsedInRegularObj = true;
458   return sym;
459 }
460 
461 static GlobalSymbol *createGlobalVariable(StringRef name, bool isMutable,
462                                           int value) {
463   llvm::wasm::WasmGlobal wasmGlobal;
464   wasmGlobal.Type = {WASM_TYPE_I32, isMutable};
465   wasmGlobal.InitExpr.Value.Int32 = value;
466   wasmGlobal.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
467   wasmGlobal.SymbolName = name;
468   return symtab->addSyntheticGlobal(name, WASM_SYMBOL_VISIBILITY_HIDDEN,
469                                     make<InputGlobal>(wasmGlobal, nullptr));
470 }
471 
472 // Create ABI-defined synthetic symbols
473 static void createSyntheticSymbols() {
474   if (config->relocatable)
475     return;
476 
477   static WasmSignature nullSignature = {{}, {}};
478   static WasmSignature i32ArgSignature = {{}, {ValType::I32}};
479   static llvm::wasm::WasmGlobalType globalTypeI32 = {WASM_TYPE_I32, false};
480   static llvm::wasm::WasmGlobalType mutableGlobalTypeI32 = {WASM_TYPE_I32,
481                                                             true};
482   WasmSym::callCtors = symtab->addSyntheticFunction(
483       "__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN,
484       make<SyntheticFunction>(nullSignature, "__wasm_call_ctors"));
485 
486   if (config->isPic) {
487     // For PIC code we create a synthetic function __wasm_apply_relocs which
488     // is called from __wasm_call_ctors before the user-level constructors.
489     WasmSym::applyRelocs = symtab->addSyntheticFunction(
490         "__wasm_apply_relocs", WASM_SYMBOL_VISIBILITY_HIDDEN,
491         make<SyntheticFunction>(nullSignature, "__wasm_apply_relocs"));
492   }
493 
494 
495   if (config->isPic) {
496     WasmSym::stackPointer =
497         createUndefinedGlobal("__stack_pointer", &mutableGlobalTypeI32);
498     // For PIC code, we import two global variables (__memory_base and
499     // __table_base) from the environment and use these as the offset at
500     // which to load our static data and function table.
501     // See:
502     // https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
503     WasmSym::memoryBase =
504         createUndefinedGlobal("__memory_base", &globalTypeI32);
505     WasmSym::tableBase = createUndefinedGlobal("__table_base", &globalTypeI32);
506     WasmSym::memoryBase->markLive();
507     WasmSym::tableBase->markLive();
508   } else {
509     // For non-PIC code
510     WasmSym::stackPointer = createGlobalVariable("__stack_pointer", true, 0);
511     WasmSym::stackPointer->markLive();
512   }
513 
514   if (config->sharedMemory && !config->shared) {
515     // Passive segments are used to avoid memory being reinitialized on each
516     // thread's instantiation. These passive segments are initialized and
517     // dropped in __wasm_init_memory, which is registered as the start function
518     WasmSym::initMemory = symtab->addSyntheticFunction(
519         "__wasm_init_memory", WASM_SYMBOL_VISIBILITY_HIDDEN,
520         make<SyntheticFunction>(nullSignature, "__wasm_init_memory"));
521     WasmSym::initMemoryFlag = symtab->addSyntheticDataSymbol(
522         "__wasm_init_memory_flag", WASM_SYMBOL_VISIBILITY_HIDDEN);
523     assert(WasmSym::initMemoryFlag);
524     WasmSym::tlsBase = createGlobalVariable("__tls_base", true, 0);
525     WasmSym::tlsSize = createGlobalVariable("__tls_size", false, 0);
526     WasmSym::tlsAlign = createGlobalVariable("__tls_align", false, 1);
527     WasmSym::initTLS = symtab->addSyntheticFunction(
528         "__wasm_init_tls", WASM_SYMBOL_VISIBILITY_HIDDEN,
529         make<SyntheticFunction>(i32ArgSignature, "__wasm_init_tls"));
530   }
531 }
532 
533 static void createOptionalSymbols() {
534   if (config->relocatable)
535     return;
536 
537   WasmSym::dsoHandle = symtab->addOptionalDataSymbol("__dso_handle");
538 
539   if (!config->shared)
540     WasmSym::dataEnd = symtab->addOptionalDataSymbol("__data_end");
541 
542   if (!config->isPic) {
543     WasmSym::globalBase = symtab->addOptionalDataSymbol("__global_base");
544     WasmSym::heapBase = symtab->addOptionalDataSymbol("__heap_base");
545     WasmSym::definedMemoryBase = symtab->addOptionalDataSymbol("__memory_base");
546     WasmSym::definedTableBase = symtab->addOptionalDataSymbol("__table_base");
547   }
548 }
549 
550 // Reconstructs command line arguments so that so that you can re-run
551 // the same command with the same inputs. This is for --reproduce.
552 static std::string createResponseFile(const opt::InputArgList &args) {
553   SmallString<0> data;
554   raw_svector_ostream os(data);
555 
556   // Copy the command line to the output while rewriting paths.
557   for (auto *arg : args) {
558     switch (arg->getOption().getID()) {
559     case OPT_reproduce:
560       break;
561     case OPT_INPUT:
562       os << quote(relativeToRoot(arg->getValue())) << "\n";
563       break;
564     case OPT_o:
565       // If -o path contains directories, "lld @response.txt" will likely
566       // fail because the archive we are creating doesn't contain empty
567       // directories for the output path (-o doesn't create directories).
568       // Strip directories to prevent the issue.
569       os << "-o " << quote(sys::path::filename(arg->getValue())) << "\n";
570       break;
571     default:
572       os << toString(*arg) << "\n";
573     }
574   }
575   return data.str();
576 }
577 
578 // The --wrap option is a feature to rename symbols so that you can write
579 // wrappers for existing functions. If you pass `-wrap=foo`, all
580 // occurrences of symbol `foo` are resolved to `wrap_foo` (so, you are
581 // expected to write `wrap_foo` function as a wrapper). The original
582 // symbol becomes accessible as `real_foo`, so you can call that from your
583 // wrapper.
584 //
585 // This data structure is instantiated for each -wrap option.
586 struct WrappedSymbol {
587   Symbol *sym;
588   Symbol *real;
589   Symbol *wrap;
590 };
591 
592 static Symbol *addUndefined(StringRef name) {
593   return symtab->addUndefinedFunction(name, "", "", WASM_SYMBOL_UNDEFINED,
594                                       nullptr, nullptr, false);
595 }
596 
597 // Handles -wrap option.
598 //
599 // This function instantiates wrapper symbols. At this point, they seem
600 // like they are not being used at all, so we explicitly set some flags so
601 // that LTO won't eliminate them.
602 static std::vector<WrappedSymbol> addWrappedSymbols(opt::InputArgList &args) {
603   std::vector<WrappedSymbol> v;
604   DenseSet<StringRef> seen;
605 
606   for (auto *arg : args.filtered(OPT_wrap)) {
607     StringRef name = arg->getValue();
608     if (!seen.insert(name).second)
609       continue;
610 
611     Symbol *sym = symtab->find(name);
612     if (!sym)
613       continue;
614 
615     Symbol *real = addUndefined(saver.save("__real_" + name));
616     Symbol *wrap = addUndefined(saver.save("__wrap_" + name));
617     v.push_back({sym, real, wrap});
618 
619     // We want to tell LTO not to inline symbols to be overwritten
620     // because LTO doesn't know the final symbol contents after renaming.
621     real->canInline = false;
622     sym->canInline = false;
623 
624     // Tell LTO not to eliminate these symbols.
625     sym->isUsedInRegularObj = true;
626     wrap->isUsedInRegularObj = true;
627     real->isUsedInRegularObj = false;
628   }
629   return v;
630 }
631 
632 // Do renaming for -wrap by updating pointers to symbols.
633 //
634 // When this function is executed, only InputFiles and symbol table
635 // contain pointers to symbol objects. We visit them to replace pointers,
636 // so that wrapped symbols are swapped as instructed by the command line.
637 static void wrapSymbols(ArrayRef<WrappedSymbol> wrapped) {
638   DenseMap<Symbol *, Symbol *> map;
639   for (const WrappedSymbol &w : wrapped) {
640     map[w.sym] = w.wrap;
641     map[w.real] = w.sym;
642   }
643 
644   // Update pointers in input files.
645   parallelForEach(symtab->objectFiles, [&](InputFile *file) {
646     MutableArrayRef<Symbol *> syms = file->getMutableSymbols();
647     for (size_t i = 0, e = syms.size(); i != e; ++i)
648       if (Symbol *s = map.lookup(syms[i]))
649         syms[i] = s;
650   });
651 
652   // Update pointers in the symbol table.
653   for (const WrappedSymbol &w : wrapped)
654     symtab->wrap(w.sym, w.real, w.wrap);
655 }
656 
657 void LinkerDriver::link(ArrayRef<const char *> argsArr) {
658   WasmOptTable parser;
659   opt::InputArgList args = parser.parse(argsArr.slice(1));
660 
661   // Handle --help
662   if (args.hasArg(OPT_help)) {
663     parser.PrintHelp(lld::outs(),
664                      (std::string(argsArr[0]) + " [options] file...").c_str(),
665                      "LLVM Linker", false);
666     return;
667   }
668 
669   // Handle --version
670   if (args.hasArg(OPT_version) || args.hasArg(OPT_v)) {
671     lld::outs() << getLLDVersion() << "\n";
672     return;
673   }
674 
675   // Handle --reproduce
676   if (auto *arg = args.getLastArg(OPT_reproduce)) {
677     StringRef path = arg->getValue();
678     Expected<std::unique_ptr<TarWriter>> errOrWriter =
679         TarWriter::create(path, path::stem(path));
680     if (errOrWriter) {
681       tar = std::move(*errOrWriter);
682       tar->append("response.txt", createResponseFile(args));
683       tar->append("version.txt", getLLDVersion() + "\n");
684     } else {
685       error("--reproduce: " + toString(errOrWriter.takeError()));
686     }
687   }
688 
689   // Parse and evaluate -mllvm options.
690   std::vector<const char *> v;
691   v.push_back("wasm-ld (LLVM option parsing)");
692   for (auto *arg : args.filtered(OPT_mllvm))
693     v.push_back(arg->getValue());
694   cl::ParseCommandLineOptions(v.size(), v.data());
695 
696   errorHandler().errorLimit = args::getInteger(args, OPT_error_limit, 20);
697 
698   readConfigs(args);
699   setConfigs();
700   checkOptions(args);
701 
702   if (auto *arg = args.getLastArg(OPT_allow_undefined_file))
703     readImportFile(arg->getValue());
704 
705   if (!args.hasArg(OPT_INPUT)) {
706     error("no input files");
707     return;
708   }
709 
710   // Handle --trace-symbol.
711   for (auto *arg : args.filtered(OPT_trace_symbol))
712     symtab->trace(arg->getValue());
713 
714   for (auto *arg : args.filtered(OPT_export))
715     config->exportedSymbols.insert(arg->getValue());
716 
717   createSyntheticSymbols();
718 
719   createFiles(args);
720   if (errorCount())
721     return;
722 
723   // Add all files to the symbol table. This will add almost all
724   // symbols that we need to the symbol table.
725   for (InputFile *f : files)
726     symtab->addFile(f);
727   if (errorCount())
728     return;
729 
730   // Handle the `--undefined <sym>` options.
731   for (auto *arg : args.filtered(OPT_undefined))
732     handleUndefined(arg->getValue());
733 
734   // Handle the `--export <sym>` options
735   // This works like --undefined but also exports the symbol if its found
736   for (auto *arg : args.filtered(OPT_export))
737     handleUndefined(arg->getValue());
738 
739   Symbol *entrySym = nullptr;
740   if (!config->relocatable && !config->entry.empty()) {
741     entrySym = handleUndefined(config->entry);
742     if (entrySym && entrySym->isDefined())
743       entrySym->forceExport = true;
744     else
745       error("entry symbol not defined (pass --no-entry to supress): " +
746             config->entry);
747   }
748 
749   createOptionalSymbols();
750 
751   if (errorCount())
752     return;
753 
754   // Create wrapped symbols for -wrap option.
755   std::vector<WrappedSymbol> wrapped = addWrappedSymbols(args);
756 
757   // If any of our inputs are bitcode files, the LTO code generator may create
758   // references to certain library functions that might not be explicit in the
759   // bitcode file's symbol table. If any of those library functions are defined
760   // in a bitcode file in an archive member, we need to arrange to use LTO to
761   // compile those archive members by adding them to the link beforehand.
762   //
763   // We only need to add libcall symbols to the link before LTO if the symbol's
764   // definition is in bitcode. Any other required libcall symbols will be added
765   // to the link after LTO when we add the LTO object file to the link.
766   if (!symtab->bitcodeFiles.empty())
767     for (auto *s : lto::LTO::getRuntimeLibcallSymbols())
768       handleLibcall(s);
769   if (errorCount())
770     return;
771 
772   // Do link-time optimization if given files are LLVM bitcode files.
773   // This compiles bitcode files into real object files.
774   symtab->addCombinedLTOObject();
775   if (errorCount())
776     return;
777 
778   // Resolve any variant symbols that were created due to signature
779   // mismatchs.
780   symtab->handleSymbolVariants();
781   if (errorCount())
782     return;
783 
784   // Apply symbol renames for -wrap.
785   if (!wrapped.empty())
786     wrapSymbols(wrapped);
787 
788   for (auto *arg : args.filtered(OPT_export)) {
789     Symbol *sym = symtab->find(arg->getValue());
790     if (sym && sym->isDefined())
791       sym->forceExport = true;
792     else if (!config->allowUndefined)
793       error(Twine("symbol exported via --export not found: ") +
794             arg->getValue());
795   }
796 
797   if (!config->relocatable) {
798     // Add synthetic dummies for weak undefined functions.  Must happen
799     // after LTO otherwise functions may not yet have signatures.
800     symtab->handleWeakUndefines();
801   }
802 
803   if (entrySym)
804     entrySym->setHidden(false);
805 
806   if (errorCount())
807     return;
808 
809   // Do size optimizations: garbage collection
810   markLive();
811 
812   // Write the result to the file.
813   writeResult();
814 }
815 
816 } // namespace wasm
817 } // namespace lld
818