10b57cec5SDimitry Andric //===- tools/lld/lld.cpp - Linker Driver Dispatcher -----------------------===// 20b57cec5SDimitry Andric // 30b57cec5SDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 40b57cec5SDimitry Andric // See https://llvm.org/LICENSE.txt for license information. 50b57cec5SDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 60b57cec5SDimitry Andric // 70b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 80b57cec5SDimitry Andric // 90b57cec5SDimitry Andric // This file contains the main function of the lld executable. The main 100b57cec5SDimitry Andric // function is a thin wrapper which dispatches to the platform specific 110b57cec5SDimitry Andric // driver. 120b57cec5SDimitry Andric // 130b57cec5SDimitry Andric // lld is a single executable that contains four different linkers for ELF, 140b57cec5SDimitry Andric // COFF, WebAssembly and Mach-O. The main function dispatches according to 150b57cec5SDimitry Andric // argv[0] (i.e. command name). The most common name for each target is shown 160b57cec5SDimitry Andric // below: 170b57cec5SDimitry Andric // 180b57cec5SDimitry Andric // - ld.lld: ELF (Unix) 190b57cec5SDimitry Andric // - ld64: Mach-O (macOS) 200b57cec5SDimitry Andric // - lld-link: COFF (Windows) 210b57cec5SDimitry Andric // - ld-wasm: WebAssembly 220b57cec5SDimitry Andric // 230b57cec5SDimitry Andric // lld can be invoked as "lld" along with "-flavor" option. This is for 240b57cec5SDimitry Andric // backward compatibility and not recommended. 250b57cec5SDimitry Andric // 260b57cec5SDimitry Andric //===----------------------------------------------------------------------===// 270b57cec5SDimitry Andric 280b57cec5SDimitry Andric #include "lld/Common/Driver.h" 29e8d8bef9SDimitry Andric #include "lld/Common/ErrorHandler.h" 300b57cec5SDimitry Andric #include "lld/Common/Memory.h" 310b57cec5SDimitry Andric #include "llvm/ADT/STLExtras.h" 320b57cec5SDimitry Andric #include "llvm/ADT/SmallVector.h" 330b57cec5SDimitry Andric #include "llvm/ADT/Twine.h" 340b57cec5SDimitry Andric #include "llvm/Support/CommandLine.h" 35e8d8bef9SDimitry Andric #include "llvm/Support/CrashRecoveryContext.h" 36*06c3fb27SDimitry Andric #include "llvm/Support/LLVMDriver.h" 370b57cec5SDimitry Andric #include "llvm/Support/Path.h" 385ffd83dbSDimitry Andric #include "llvm/Support/PluginLoader.h" 39349cc55cSDimitry Andric #include "llvm/Support/Process.h" 40*06c3fb27SDimitry Andric #include "llvm/TargetParser/Host.h" 41*06c3fb27SDimitry Andric #include "llvm/TargetParser/Triple.h" 420b57cec5SDimitry Andric #include <cstdlib> 43bdd1243dSDimitry Andric #include <optional> 440b57cec5SDimitry Andric 450b57cec5SDimitry Andric using namespace lld; 460b57cec5SDimitry Andric using namespace llvm; 470b57cec5SDimitry Andric using namespace llvm::sys; 480b57cec5SDimitry Andric 49*06c3fb27SDimitry Andric namespace lld { 50*06c3fb27SDimitry Andric extern bool inTestOutputDisabled; 510b57cec5SDimitry Andric 52*06c3fb27SDimitry Andric // Bypass the crash recovery handler, which is only meant to be used in 53*06c3fb27SDimitry Andric // LLD-as-lib scenarios. 54*06c3fb27SDimitry Andric int unsafeLldMain(llvm::ArrayRef<const char *> args, 55*06c3fb27SDimitry Andric llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS, 56*06c3fb27SDimitry Andric llvm::ArrayRef<DriverDef> drivers, bool exitEarly); 57*06c3fb27SDimitry Andric } // namespace lld 58e8d8bef9SDimitry Andric 59e8d8bef9SDimitry Andric // When in lit tests, tells how many times the LLD tool should re-execute the 60e8d8bef9SDimitry Andric // main loop with the same inputs. When not in test, returns a value of 0 which 61e8d8bef9SDimitry Andric // signifies that LLD shall not release any memory after execution, to speed up 62e8d8bef9SDimitry Andric // process destruction. 63e8d8bef9SDimitry Andric static unsigned inTestVerbosity() { 64e8d8bef9SDimitry Andric unsigned v = 0; 65e8d8bef9SDimitry Andric StringRef(getenv("LLD_IN_TEST")).getAsInteger(10, v); 66e8d8bef9SDimitry Andric return v; 67e8d8bef9SDimitry Andric } 68e8d8bef9SDimitry Andric 69*06c3fb27SDimitry Andric #if 1 70*06c3fb27SDimitry Andric // On FreeBSD we only build the ELF linker. 71*06c3fb27SDimitry Andric LLD_HAS_DRIVER(elf) 72*06c3fb27SDimitry Andric #undef LLD_ALL_DRIVERS 73*06c3fb27SDimitry Andric #define LLD_ALL_DRIVERS { {lld::Gnu, &lld::elf::link} } 74*06c3fb27SDimitry Andric #else 75*06c3fb27SDimitry Andric LLD_HAS_DRIVER(coff) 76*06c3fb27SDimitry Andric LLD_HAS_DRIVER(elf) 77*06c3fb27SDimitry Andric LLD_HAS_DRIVER(mingw) 78*06c3fb27SDimitry Andric LLD_HAS_DRIVER(macho) 79*06c3fb27SDimitry Andric LLD_HAS_DRIVER(wasm) 80*06c3fb27SDimitry Andric #endif 81*06c3fb27SDimitry Andric 82*06c3fb27SDimitry Andric int lld_main(int argc, char **argv, const llvm::ToolContext &) { 83349cc55cSDimitry Andric sys::Process::UseANSIEscapeCodes(true); 84e8d8bef9SDimitry Andric 85753f127fSDimitry Andric if (::getenv("FORCE_LLD_DIAGNOSTICS_CRASH")) { 86753f127fSDimitry Andric llvm::errs() 87753f127fSDimitry Andric << "crashing due to environment variable FORCE_LLD_DIAGNOSTICS_CRASH\n"; 88753f127fSDimitry Andric LLVM_BUILTIN_TRAP; 89753f127fSDimitry Andric } 90753f127fSDimitry Andric 91*06c3fb27SDimitry Andric ArrayRef<const char *> args(argv, argv + argc); 92*06c3fb27SDimitry Andric 93e8d8bef9SDimitry Andric // Not running in lit tests, just take the shortest codepath with global 94e8d8bef9SDimitry Andric // exception handling and no memory cleanup on exit. 95*06c3fb27SDimitry Andric if (!inTestVerbosity()) { 96*06c3fb27SDimitry Andric int r = 97*06c3fb27SDimitry Andric lld::unsafeLldMain(args, llvm::outs(), llvm::errs(), LLD_ALL_DRIVERS, 98*06c3fb27SDimitry Andric /*exitEarly=*/true); 99*06c3fb27SDimitry Andric return r; 100*06c3fb27SDimitry Andric } 101e8d8bef9SDimitry Andric 102bdd1243dSDimitry Andric std::optional<int> mainRet; 103e8d8bef9SDimitry Andric CrashRecoveryContext::Enable(); 104e8d8bef9SDimitry Andric 105e8d8bef9SDimitry Andric for (unsigned i = inTestVerbosity(); i > 0; --i) { 106e8d8bef9SDimitry Andric // Disable stdout/stderr for all iterations but the last one. 10704eeddc0SDimitry Andric inTestOutputDisabled = (i != 1); 108e8d8bef9SDimitry Andric 109e8d8bef9SDimitry Andric // Execute one iteration. 110*06c3fb27SDimitry Andric auto r = lldMain(args, llvm::outs(), llvm::errs(), LLD_ALL_DRIVERS); 111e8d8bef9SDimitry Andric if (!r.canRunAgain) 112*06c3fb27SDimitry Andric exitLld(r.retCode); // Exit now, can't re-execute again. 113e8d8bef9SDimitry Andric 114e8d8bef9SDimitry Andric if (!mainRet) { 115*06c3fb27SDimitry Andric mainRet = r.retCode; 116*06c3fb27SDimitry Andric } else if (r.retCode != *mainRet) { 117e8d8bef9SDimitry Andric // Exit now, to fail the tests if the result is different between runs. 118*06c3fb27SDimitry Andric return r.retCode; 119e8d8bef9SDimitry Andric } 120e8d8bef9SDimitry Andric } 121e8d8bef9SDimitry Andric return *mainRet; 122e8d8bef9SDimitry Andric } 123