1 //===- tools/lld/lld.cpp - Linker Driver Dispatcher -----------------------===// 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 // This file contains the main function of the lld executable. The main 10 // function is a thin wrapper which dispatches to the platform specific 11 // driver. 12 // 13 // lld is a single executable that contains four different linkers for ELF, 14 // COFF, WebAssembly and Mach-O. The main function dispatches according to 15 // argv[0] (i.e. command name). The most common name for each target is shown 16 // below: 17 // 18 // - ld.lld: ELF (Unix) 19 // - ld64: Mach-O (macOS) 20 // - lld-link: COFF (Windows) 21 // - ld-wasm: WebAssembly 22 // 23 // lld can be invoked as "lld" along with "-flavor" option. This is for 24 // backward compatibility and not recommended. 25 // 26 //===----------------------------------------------------------------------===// 27 28 #include "lld/Common/Driver.h" 29 #include "lld/Common/ErrorHandler.h" 30 #include "lld/Common/Memory.h" 31 #include "llvm/ADT/STLExtras.h" 32 #include "llvm/ADT/SmallVector.h" 33 #include "llvm/ADT/Twine.h" 34 #include "llvm/Support/CommandLine.h" 35 #include "llvm/Support/CrashRecoveryContext.h" 36 #include "llvm/Support/InitLLVM.h" 37 #include "llvm/Support/LLVMDriver.h" 38 #include "llvm/Support/Path.h" 39 #include "llvm/Support/PluginLoader.h" 40 #include "llvm/Support/Process.h" 41 #include "llvm/TargetParser/Host.h" 42 #include "llvm/TargetParser/Triple.h" 43 #include <cstdlib> 44 #include <optional> 45 46 using namespace lld; 47 using namespace llvm; 48 using namespace llvm::sys; 49 50 namespace lld { 51 extern bool inTestOutputDisabled; 52 53 // Bypass the crash recovery handler, which is only meant to be used in 54 // LLD-as-lib scenarios. 55 int unsafeLldMain(llvm::ArrayRef<const char *> args, 56 llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS, 57 llvm::ArrayRef<DriverDef> drivers, bool exitEarly); 58 } // namespace lld 59 60 // When in lit tests, tells how many times the LLD tool should re-execute the 61 // main loop with the same inputs. When not in test, returns a value of 0 which 62 // signifies that LLD shall not release any memory after execution, to speed up 63 // process destruction. 64 static unsigned inTestVerbosity() { 65 unsigned v = 0; 66 StringRef(getenv("LLD_IN_TEST")).getAsInteger(10, v); 67 return v; 68 } 69 70 #if 1 71 // On FreeBSD we only build the ELF linker. 72 LLD_HAS_DRIVER(elf) 73 #undef LLD_ALL_DRIVERS 74 #define LLD_ALL_DRIVERS { {lld::Gnu, &lld::elf::link} } 75 #else 76 LLD_HAS_DRIVER(coff) 77 LLD_HAS_DRIVER(elf) 78 LLD_HAS_DRIVER(mingw) 79 LLD_HAS_DRIVER(macho) 80 LLD_HAS_DRIVER(wasm) 81 #endif 82 83 int lld_main(int argc, char **argv, const llvm::ToolContext &) { 84 InitLLVM x(argc, argv); 85 sys::Process::UseANSIEscapeCodes(true); 86 87 if (::getenv("FORCE_LLD_DIAGNOSTICS_CRASH")) { 88 llvm::errs() 89 << "crashing due to environment variable FORCE_LLD_DIAGNOSTICS_CRASH\n"; 90 LLVM_BUILTIN_TRAP; 91 } 92 93 ArrayRef<const char *> args(argv, argv + argc); 94 95 // Not running in lit tests, just take the shortest codepath with global 96 // exception handling and no memory cleanup on exit. 97 if (!inTestVerbosity()) { 98 int r = 99 lld::unsafeLldMain(args, llvm::outs(), llvm::errs(), LLD_ALL_DRIVERS, 100 /*exitEarly=*/true); 101 return r; 102 } 103 104 std::optional<int> mainRet; 105 CrashRecoveryContext::Enable(); 106 107 for (unsigned i = inTestVerbosity(); i > 0; --i) { 108 // Disable stdout/stderr for all iterations but the last one. 109 inTestOutputDisabled = (i != 1); 110 111 // Execute one iteration. 112 auto r = lldMain(args, llvm::outs(), llvm::errs(), LLD_ALL_DRIVERS); 113 if (!r.canRunAgain) 114 exitLld(r.retCode); // Exit now, can't re-execute again. 115 116 if (!mainRet) { 117 mainRet = r.retCode; 118 } else if (r.retCode != *mainRet) { 119 // Exit now, to fail the tests if the result is different between runs. 120 return r.retCode; 121 } 122 } 123 return *mainRet; 124 } 125