xref: /llvm-project-15.0.7/lld/wasm/Driver.cpp (revision 5a127cdc)
1 //===- Driver.cpp ---------------------------------------------------------===//
2 //
3 //                             The LLVM Linker
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "lld/Common/Driver.h"
11 #include "Config.h"
12 #include "InputChunks.h"
13 #include "InputGlobal.h"
14 #include "MarkLive.h"
15 #include "SymbolTable.h"
16 #include "Writer.h"
17 #include "lld/Common/Args.h"
18 #include "lld/Common/ErrorHandler.h"
19 #include "lld/Common/Memory.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/ArgList.h"
26 #include "llvm/Support/CommandLine.h"
27 #include "llvm/Support/Path.h"
28 #include "llvm/Support/Process.h"
29 #include "llvm/Support/TargetSelect.h"
30 
31 #define DEBUG_TYPE "lld"
32 
33 using namespace llvm;
34 using namespace llvm::object;
35 using namespace llvm::sys;
36 using namespace llvm::wasm;
37 
38 using namespace lld;
39 using namespace lld::wasm;
40 
41 Configuration *lld::wasm::Config;
42 
43 namespace {
44 
45 // Create enum with OPT_xxx values for each option in Options.td
46 enum {
47   OPT_INVALID = 0,
48 #define OPTION(_1, _2, ID, _4, _5, _6, _7, _8, _9, _10, _11, _12) OPT_##ID,
49 #include "Options.inc"
50 #undef OPTION
51 };
52 
53 // This function is called on startup. We need this for LTO since
54 // LTO calls LLVM functions to compile bitcode files to native code.
55 // Technically this can be delayed until we read bitcode files, but
56 // we don't bother to do lazily because the initialization is fast.
57 static void initLLVM() {
58   InitializeAllTargets();
59   InitializeAllTargetMCs();
60   InitializeAllAsmPrinters();
61   InitializeAllAsmParsers();
62 }
63 
64 class LinkerDriver {
65 public:
66   void link(ArrayRef<const char *> ArgsArr);
67 
68 private:
69   void createFiles(opt::InputArgList &Args);
70   void addFile(StringRef Path);
71   void addLibrary(StringRef Name);
72 
73   // True if we are in --whole-archive and --no-whole-archive.
74   bool InWholeArchive = false;
75 
76   std::vector<InputFile *> Files;
77 };
78 } // anonymous namespace
79 
80 bool lld::wasm::link(ArrayRef<const char *> Args, bool CanExitEarly,
81                      raw_ostream &Error) {
82   errorHandler().LogName = args::getFilenameWithoutExe(Args[0]);
83   errorHandler().ErrorOS = &Error;
84   errorHandler().ColorDiagnostics = Error.has_colors();
85   errorHandler().ErrorLimitExceededMsg =
86       "too many errors emitted, stopping now (use "
87       "-error-limit=0 to see all errors)";
88 
89   Config = make<Configuration>();
90   Symtab = make<SymbolTable>();
91 
92   initLLVM();
93   LinkerDriver().link(Args);
94 
95   // Exit immediately if we don't need to return to the caller.
96   // This saves time because the overhead of calling destructors
97   // for all globally-allocated objects is not negligible.
98   if (CanExitEarly)
99     exitLld(errorCount() ? 1 : 0);
100 
101   freeArena();
102   return !errorCount();
103 }
104 
105 // Create prefix string literals used in Options.td
106 #define PREFIX(NAME, VALUE) const char *const NAME[] = VALUE;
107 #include "Options.inc"
108 #undef PREFIX
109 
110 // Create table mapping all options defined in Options.td
111 static const opt::OptTable::Info OptInfo[] = {
112 #define OPTION(X1, X2, ID, KIND, GROUP, ALIAS, X7, X8, X9, X10, X11, X12)      \
113   {X1, X2, X10,         X11,         OPT_##ID, opt::Option::KIND##Class,       \
114    X9, X8, OPT_##GROUP, OPT_##ALIAS, X7,       X12},
115 #include "Options.inc"
116 #undef OPTION
117 };
118 
119 namespace {
120 class WasmOptTable : public llvm::opt::OptTable {
121 public:
122   WasmOptTable() : OptTable(OptInfo) {}
123   opt::InputArgList parse(ArrayRef<const char *> Argv);
124 };
125 } // namespace
126 
127 // Set color diagnostics according to -color-diagnostics={auto,always,never}
128 // or -no-color-diagnostics flags.
129 static void handleColorDiagnostics(opt::InputArgList &Args) {
130   auto *Arg = Args.getLastArg(OPT_color_diagnostics, OPT_color_diagnostics_eq,
131                               OPT_no_color_diagnostics);
132   if (!Arg)
133     return;
134   if (Arg->getOption().getID() == OPT_color_diagnostics) {
135     errorHandler().ColorDiagnostics = true;
136   } else if (Arg->getOption().getID() == OPT_no_color_diagnostics) {
137     errorHandler().ColorDiagnostics = false;
138   } else {
139     StringRef S = Arg->getValue();
140     if (S == "always")
141       errorHandler().ColorDiagnostics = true;
142     else if (S == "never")
143       errorHandler().ColorDiagnostics = false;
144     else if (S != "auto")
145       error("unknown option: --color-diagnostics=" + S);
146   }
147 }
148 
149 // Find a file by concatenating given paths.
150 static Optional<std::string> findFile(StringRef Path1, const Twine &Path2) {
151   SmallString<128> S;
152   path::append(S, Path1, Path2);
153   if (fs::exists(S))
154     return S.str().str();
155   return None;
156 }
157 
158 opt::InputArgList WasmOptTable::parse(ArrayRef<const char *> Argv) {
159   SmallVector<const char *, 256> Vec(Argv.data(), Argv.data() + Argv.size());
160 
161   unsigned MissingIndex;
162   unsigned MissingCount;
163 
164   // Expand response files (arguments in the form of @<filename>)
165   cl::ExpandResponseFiles(Saver, cl::TokenizeGNUCommandLine, Vec);
166 
167   opt::InputArgList Args = this->ParseArgs(Vec, MissingIndex, MissingCount);
168 
169   handleColorDiagnostics(Args);
170   for (auto *Arg : Args.filtered(OPT_UNKNOWN))
171     error("unknown argument: " + Arg->getSpelling());
172   return Args;
173 }
174 
175 // Currently we allow a ".imports" to live alongside a library. This can
176 // be used to specify a list of symbols which can be undefined at link
177 // time (imported from the environment.  For example libc.a include an
178 // import file that lists the syscall functions it relies on at runtime.
179 // In the long run this information would be better stored as a symbol
180 // attribute/flag in the object file itself.
181 // See: https://github.com/WebAssembly/tool-conventions/issues/35
182 static void readImportFile(StringRef Filename) {
183   if (Optional<MemoryBufferRef> Buf = readFile(Filename))
184     for (StringRef Sym : args::getLines(*Buf))
185       Config->AllowUndefinedSymbols.insert(Sym);
186 }
187 
188 // Returns slices of MB by parsing MB as an archive file.
189 // Each slice consists of a member file in the archive.
190 std::vector<MemoryBufferRef> static getArchiveMembers(MemoryBufferRef MB) {
191   std::unique_ptr<Archive> File =
192       CHECK(Archive::create(MB),
193             MB.getBufferIdentifier() + ": failed to parse archive");
194 
195   std::vector<MemoryBufferRef> V;
196   Error Err = Error::success();
197   for (const ErrorOr<Archive::Child> &COrErr : File->children(Err)) {
198     Archive::Child C =
199         CHECK(COrErr, MB.getBufferIdentifier() +
200                           ": could not get the child of the archive");
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     // Handle -whole-archive.
227     if (InWholeArchive) {
228       for (MemoryBufferRef &M : getArchiveMembers(MBRef))
229         Files.push_back(createObjectFile(M));
230       return;
231     }
232 
233     SmallString<128> ImportFile = Path;
234     path::replace_extension(ImportFile, ".imports");
235     if (fs::exists(ImportFile))
236       readImportFile(ImportFile.str());
237 
238     Files.push_back(make<ArchiveFile>(MBRef));
239     return;
240   }
241   case file_magic::bitcode:
242   case file_magic::wasm_object:
243     Files.push_back(createObjectFile(MBRef));
244     break;
245   default:
246     error("unknown file type: " + MBRef.getBufferIdentifier());
247   }
248 }
249 
250 // Add a given library by searching it from input search paths.
251 void LinkerDriver::addLibrary(StringRef Name) {
252   for (StringRef Dir : Config->SearchPaths) {
253     if (Optional<std::string> S = findFile(Dir, "lib" + Name + ".a")) {
254       addFile(*S);
255       return;
256     }
257   }
258 
259   error("unable to find library -l" + Name);
260 }
261 
262 void LinkerDriver::createFiles(opt::InputArgList &Args) {
263   for (auto *Arg : Args) {
264     switch (Arg->getOption().getUnaliasedOption().getID()) {
265     case OPT_l:
266       addLibrary(Arg->getValue());
267       break;
268     case OPT_INPUT:
269       addFile(Arg->getValue());
270       break;
271     case OPT_whole_archive:
272       InWholeArchive = true;
273       break;
274     case OPT_no_whole_archive:
275       InWholeArchive = false;
276       break;
277     }
278   }
279 }
280 
281 static StringRef getEntry(opt::InputArgList &Args, StringRef Default) {
282   auto *Arg = Args.getLastArg(OPT_entry, OPT_no_entry);
283   if (!Arg)
284     return Default;
285   if (Arg->getOption().getID() == OPT_no_entry)
286     return "";
287   return Arg->getValue();
288 }
289 
290 static const uint8_t UnreachableFn[] = {
291     0x03 /* ULEB length */, 0x00 /* ULEB num locals */,
292     0x00 /* opcode unreachable */, 0x0b /* opcode end */
293 };
294 
295 // For weak undefined functions, there may be "call" instructions that reference
296 // the symbol. In this case, we need to synthesise a dummy/stub function that
297 // will abort at runtime, so that relocations can still provided an operand to
298 // the call instruction that passes Wasm validation.
299 static void handleWeakUndefines() {
300   for (Symbol *Sym : Symtab->getSymbols()) {
301     if (!Sym->isUndefined() || !Sym->isWeak())
302       continue;
303     auto *FuncSym = dyn_cast<FunctionSymbol>(Sym);
304     if (!FuncSym)
305       continue;
306 
307     // It is possible for undefined functions not to have a signature (eg. if
308     // added via "--undefined"), but weak undefined ones do have a signature.
309     assert(FuncSym->Signature);
310     const WasmSignature &Sig = *FuncSym->Signature;
311 
312     // Add a synthetic dummy for weak undefined functions.  These dummies will
313     // be GC'd if not used as the target of any "call" instructions.
314     std::string SymName = toString(*Sym);
315     StringRef DebugName = Saver.save("undefined function " + SymName);
316     auto *Func = make<SyntheticFunction>(Sig, Sym->getName(), DebugName);
317     Func->setBody(UnreachableFn);
318     // Ensure it compares equal to the null pointer, and so that table relocs
319     // don't pull in the stub body (only call-operand relocs should do that).
320     Func->setTableIndex(0);
321     Symtab->SyntheticFunctions.emplace_back(Func);
322     // Hide our dummy to prevent export.
323     uint32_t Flags = WASM_SYMBOL_VISIBILITY_HIDDEN;
324     replaceSymbol<DefinedFunction>(Sym, Sym->getName(), Flags, nullptr, Func);
325   }
326 }
327 
328 // Some Config members do not directly correspond to any particular
329 // command line options, but computed based on other Config values.
330 // This function initialize such members. See Config.h for the details
331 // of these values.
332 static void setConfigs(opt::InputArgList &Args) {
333   Config->AllowUndefined = Args.hasArg(OPT_allow_undefined);
334   Config->CompressRelocations = Args.hasArg(OPT_compress_relocations);
335   Config->Demangle = Args.hasFlag(OPT_demangle, OPT_no_demangle, true);
336   Config->DisableVerify = Args.hasArg(OPT_disable_verify);
337   Config->Entry = getEntry(Args, Args.hasArg(OPT_relocatable) ? "" : "_start");
338   Config->ExportAll = Args.hasArg(OPT_export_all);
339   Config->ExportDynamic = Args.hasFlag(OPT_export_dynamic,
340       OPT_no_export_dynamic, false);
341   Config->ExportTable = Args.hasArg(OPT_export_table);
342   errorHandler().FatalWarnings =
343       Args.hasFlag(OPT_fatal_warnings, OPT_no_fatal_warnings, false);
344   Config->ImportMemory = Args.hasArg(OPT_import_memory);
345   Config->SharedMemory = Args.hasArg(OPT_shared_memory);
346   Config->ImportTable = Args.hasArg(OPT_import_table);
347   Config->LTOO = args::getInteger(Args, OPT_lto_O, 2);
348   Config->LTOPartitions = args::getInteger(Args, OPT_lto_partitions, 1);
349   Config->Optimize = args::getInteger(Args, OPT_O, 0);
350   Config->OutputFile = Args.getLastArgValue(OPT_o);
351   Config->Relocatable = Args.hasArg(OPT_relocatable);
352   Config->GcSections =
353       Args.hasFlag(OPT_gc_sections, OPT_no_gc_sections, !Config->Relocatable);
354   Config->MergeDataSegments =
355       Args.hasFlag(OPT_merge_data_segments, OPT_no_merge_data_segments,
356                    !Config->Relocatable);
357   Config->Pie = Args.hasFlag(OPT_pie, OPT_no_pie, false);
358   Config->PrintGcSections =
359       Args.hasFlag(OPT_print_gc_sections, OPT_no_print_gc_sections, false);
360   Config->SaveTemps = Args.hasArg(OPT_save_temps);
361   Config->SearchPaths = args::getStrings(Args, OPT_L);
362   Config->Shared = Args.hasArg(OPT_shared);
363   Config->StripAll = Args.hasArg(OPT_strip_all);
364   Config->StripDebug = Args.hasArg(OPT_strip_debug);
365   Config->StackFirst = Args.hasArg(OPT_stack_first);
366   Config->ThinLTOCacheDir = Args.getLastArgValue(OPT_thinlto_cache_dir);
367   Config->ThinLTOCachePolicy = CHECK(
368       parseCachePruningPolicy(Args.getLastArgValue(OPT_thinlto_cache_policy)),
369       "--thinlto-cache-policy: invalid cache policy");
370   Config->ThinLTOJobs = args::getInteger(Args, OPT_thinlto_jobs, -1u);
371   errorHandler().Verbose = Args.hasArg(OPT_verbose);
372   ThreadsEnabled = Args.hasFlag(OPT_threads, OPT_no_threads, true);
373 
374   Config->InitialMemory = args::getInteger(Args, OPT_initial_memory, 0);
375   Config->GlobalBase = args::getInteger(Args, OPT_global_base, 1024);
376   Config->MaxMemory = args::getInteger(Args, OPT_max_memory, 0);
377   Config->ZStackSize =
378       args::getZOptionValue(Args, OPT_z, "stack-size", WasmPageSize);
379 }
380 
381 // Some command line options or some combinations of them are not allowed.
382 // This function checks for such errors.
383 static void checkOptions(opt::InputArgList &Args) {
384   if (!Config->StripDebug && !Config->StripAll && Config->CompressRelocations)
385     error("--compress-relocations is incompatible with output debug"
386           " information. Please pass --strip-debug or --strip-all");
387 
388   if (Config->LTOO > 3)
389     error("invalid optimization level for LTO: " + Twine(Config->LTOO));
390   if (Config->LTOPartitions == 0)
391     error("--lto-partitions: number of threads must be > 0");
392   if (Config->ThinLTOJobs == 0)
393     error("--thinlto-jobs: number of threads must be > 0");
394 
395   if (Config->Pie && Config->Shared)
396     error("-shared and -pie may not be used together");
397 
398   if (Config->OutputFile.empty())
399     error("no output file specified");
400 
401   if (Config->ImportTable && Config->ExportTable)
402     error("--import-table and --export-table may not be used together");
403 
404   if (Config->Relocatable) {
405     if (!Config->Entry.empty())
406       error("entry point specified for relocatable output file");
407     if (Config->GcSections)
408       error("-r and --gc-sections may not be used together");
409     if (Config->CompressRelocations)
410       error("-r -and --compress-relocations may not be used together");
411     if (Args.hasArg(OPT_undefined))
412       error("-r -and --undefined may not be used together");
413     if (Config->Pie)
414       error("-r and -pie may not be used together");
415   }
416 }
417 
418 // Force Sym to be entered in the output. Used for -u or equivalent.
419 static Symbol *handleUndefined(StringRef Name) {
420   Symbol *Sym = Symtab->find(Name);
421   if (!Sym)
422     return nullptr;
423 
424   // Since symbol S may not be used inside the program, LTO may
425   // eliminate it. Mark the symbol as "used" to prevent it.
426   Sym->IsUsedInRegularObj = true;
427 
428   if (auto *LazySym = dyn_cast<LazySymbol>(Sym))
429     LazySym->fetch();
430 
431   return Sym;
432 }
433 
434 static UndefinedGlobal *
435 createUndefinedGlobal(StringRef Name, llvm::wasm::WasmGlobalType *Type) {
436   auto *Sym =
437       cast<UndefinedGlobal>(Symtab->addUndefinedGlobal(Name, 0, nullptr, Type));
438   Config->AllowUndefinedSymbols.insert(Sym->getName());
439   Sym->IsUsedInRegularObj = true;
440   return Sym;
441 }
442 
443 // Create ABI-defined synthetic symbols
444 static void createSyntheticSymbols() {
445   static WasmSignature NullSignature = {{}, {}};
446   static llvm::wasm::WasmGlobalType GlobalTypeI32 = {WASM_TYPE_I32, false};
447   static llvm::wasm::WasmGlobalType MutableGlobalTypeI32 = {WASM_TYPE_I32,
448                                                             true};
449 
450   if (!Config->Relocatable)
451     WasmSym::CallCtors = Symtab->addSyntheticFunction(
452         "__wasm_call_ctors", WASM_SYMBOL_VISIBILITY_HIDDEN,
453         make<SyntheticFunction>(NullSignature, "__wasm_call_ctors"));
454 
455   // The __stack_pointer is imported in the shared library case, and exported
456   // in the non-shared (executable) case.
457   if (Config->Shared) {
458     WasmSym::StackPointer =
459         createUndefinedGlobal("__stack_pointer", &MutableGlobalTypeI32);
460   } else {
461     llvm::wasm::WasmGlobal Global;
462     Global.Type = {WASM_TYPE_I32, true};
463     Global.InitExpr.Value.Int32 = 0;
464     Global.InitExpr.Opcode = WASM_OPCODE_I32_CONST;
465     Global.SymbolName = "__stack_pointer";
466     auto *StackPointer = make<InputGlobal>(Global, nullptr);
467     StackPointer->Live = true;
468     // For non-PIC code
469     // TODO(sbc): Remove WASM_SYMBOL_VISIBILITY_HIDDEN when the mutable global
470     // spec proposal is implemented in all major browsers.
471     // See: https://github.com/WebAssembly/mutable-global
472     WasmSym::StackPointer = Symtab->addSyntheticGlobal(
473         "__stack_pointer", WASM_SYMBOL_VISIBILITY_HIDDEN, StackPointer);
474     WasmSym::HeapBase = Symtab->addSyntheticDataSymbol("__heap_base", 0);
475     WasmSym::DataEnd = Symtab->addSyntheticDataSymbol("__data_end", 0);
476 
477     // These two synthetic symbols exist purely for the embedder so we always
478     // want to export them.
479     WasmSym::HeapBase->ForceExport = true;
480     WasmSym::DataEnd->ForceExport = true;
481   }
482 
483   if (Config->Pic) {
484     // For PIC code, we import two global variables (__memory_base and
485     // __table_base) from the environment and use these as the offset at
486     // which to load our static data and function table.
487     // See:
488     // https://github.com/WebAssembly/tool-conventions/blob/master/DynamicLinking.md
489     WasmSym::MemoryBase =
490         createUndefinedGlobal("__memory_base", &GlobalTypeI32);
491     WasmSym::TableBase = createUndefinedGlobal("__table_base", &GlobalTypeI32);
492     WasmSym::MemoryBase->markLive();
493     WasmSym::TableBase->markLive();
494   }
495 
496   WasmSym::DsoHandle = Symtab->addSyntheticDataSymbol(
497       "__dso_handle", WASM_SYMBOL_VISIBILITY_HIDDEN);
498 }
499 
500 void LinkerDriver::link(ArrayRef<const char *> ArgsArr) {
501   WasmOptTable Parser;
502   opt::InputArgList Args = Parser.parse(ArgsArr.slice(1));
503 
504   // Handle --help
505   if (Args.hasArg(OPT_help)) {
506     Parser.PrintHelp(outs(),
507                      (std::string(ArgsArr[0]) + " [options] file...").c_str(),
508                      "LLVM Linker", false);
509     return;
510   }
511 
512   // Handle --version
513   if (Args.hasArg(OPT_version) || Args.hasArg(OPT_v)) {
514     outs() << getLLDVersion() << "\n";
515     return;
516   }
517 
518   // Parse and evaluate -mllvm options.
519   std::vector<const char *> V;
520   V.push_back("wasm-ld (LLVM option parsing)");
521   for (auto *Arg : Args.filtered(OPT_mllvm))
522     V.push_back(Arg->getValue());
523   cl::ParseCommandLineOptions(V.size(), V.data());
524 
525   errorHandler().ErrorLimit = args::getInteger(Args, OPT_error_limit, 20);
526 
527   setConfigs(Args);
528   checkOptions(Args);
529 
530   if (auto *Arg = Args.getLastArg(OPT_allow_undefined_file))
531     readImportFile(Arg->getValue());
532 
533   if (!Args.hasArg(OPT_INPUT)) {
534     error("no input files");
535     return;
536   }
537 
538   Config->Pic = Config->Pie || Config->Shared;
539 
540   if (Config->Pic) {
541     if (Config->ExportTable)
542       error("-shared/-pie is incompatible with --export-table");
543     Config->ImportTable = true;
544   }
545 
546   if (Config->Shared) {
547     Config->ExportDynamic = true;
548     Config->AllowUndefined = true;
549   }
550 
551   if (!Config->Relocatable)
552     createSyntheticSymbols();
553 
554   createFiles(Args);
555   if (errorCount())
556     return;
557 
558   // Add all files to the symbol table. This will add almost all
559   // symbols that we need to the symbol table.
560   for (InputFile *F : Files)
561     Symtab->addFile(F);
562   if (errorCount())
563     return;
564 
565   // Handle the `--undefined <sym>` options.
566   for (auto *Arg : Args.filtered(OPT_undefined))
567     handleUndefined(Arg->getValue());
568 
569   // Handle the `--export <sym>` options
570   // This works like --undefined but also exports the symbol if its found
571   for (auto *Arg : Args.filtered(OPT_export)) {
572     Symbol *Sym = handleUndefined(Arg->getValue());
573     if (Sym && Sym->isDefined())
574       Sym->ForceExport = true;
575     else if (!Config->AllowUndefined)
576       error(Twine("symbol exported via --export not found: ") +
577             Arg->getValue());
578   }
579 
580   Symbol *EntrySym = nullptr;
581   if (!Config->Relocatable) {
582     // Add synthetic dummies for weak undefined functions.
583     handleWeakUndefines();
584 
585     if (!Config->Shared && !Config->Entry.empty()) {
586       EntrySym = handleUndefined(Config->Entry);
587       if (EntrySym && EntrySym->isDefined())
588         EntrySym->ForceExport = true;
589       else
590         error("entry symbol not defined (pass --no-entry to supress): " +
591               Config->Entry);
592     }
593 
594     // Make sure we have resolved all symbols.
595     if (!Config->AllowUndefined)
596       Symtab->reportRemainingUndefines();
597   }
598 
599   if (errorCount())
600     return;
601 
602   // Do link-time optimization if given files are LLVM bitcode files.
603   // This compiles bitcode files into real object files.
604   Symtab->addCombinedLTOObject();
605   if (errorCount())
606     return;
607 
608   if (EntrySym)
609     EntrySym->setHidden(false);
610 
611   if (errorCount())
612     return;
613 
614   // Do size optimizations: garbage collection
615   markLive();
616 
617   // Write the result to the file.
618   writeResult();
619 }
620