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/LLVMDriver.h"
37#include "llvm/Support/Path.h"
38#include "llvm/Support/PluginLoader.h"
39#include "llvm/Support/Process.h"
40#include "llvm/TargetParser/Host.h"
41#include "llvm/TargetParser/Triple.h"
42#include <cstdlib>
43#include <optional>
44
45using namespace lld;
46using namespace llvm;
47using namespace llvm::sys;
48
49namespace lld {
50extern bool inTestOutputDisabled;
51
52// Bypass the crash recovery handler, which is only meant to be used in
53// LLD-as-lib scenarios.
54int unsafeLldMain(llvm::ArrayRef<const char *> args,
55 llvm::raw_ostream &stdoutOS, llvm::raw_ostream &stderrOS,
56 llvm::ArrayRef<DriverDef> drivers, bool exitEarly);
57} // namespace lld
58
59// When in lit tests, tells how many times the LLD tool should re-execute the
60// main loop with the same inputs. When not in test, returns a value of 0 which
61// signifies that LLD shall not release any memory after execution, to speed up
62// process destruction.
63static unsigned inTestVerbosity() {
64 unsigned v = 0;
65 StringRef(getenv(name: "LLD_IN_TEST")).getAsInteger(Radix: 10, Result&: v);
66 return v;
67}
68
69LLD_HAS_DRIVER(coff)
70LLD_HAS_DRIVER(elf)
71LLD_HAS_DRIVER(mingw)
72LLD_HAS_DRIVER(macho)
73LLD_HAS_DRIVER(wasm)
74
75int lld_main(int argc, char **argv, const llvm::ToolContext &) {
76 sys::Process::UseANSIEscapeCodes(enable: true);
77
78 if (::getenv(name: "FORCE_LLD_DIAGNOSTICS_CRASH")) {
79 llvm::errs()
80 << "crashing due to environment variable FORCE_LLD_DIAGNOSTICS_CRASH\n";
81 LLVM_BUILTIN_TRAP;
82 }
83
84 ArrayRef<const char *> args(argv, argv + argc);
85
86 // Not running in lit tests, just take the shortest codepath with global
87 // exception handling and no memory cleanup on exit.
88 if (!inTestVerbosity()) {
89 int r =
90 lld::unsafeLldMain(args, stdoutOS&: llvm::outs(), stderrOS&: llvm::errs(), LLD_ALL_DRIVERS,
91 /*exitEarly=*/true);
92 return r;
93 }
94
95 std::optional<int> mainRet;
96 CrashRecoveryContext::Enable();
97
98 for (unsigned i = inTestVerbosity(); i > 0; --i) {
99 // Disable stdout/stderr for all iterations but the last one.
100 inTestOutputDisabled = (i != 1);
101
102 // Execute one iteration.
103 auto r = lldMain(args, stdoutOS&: llvm::outs(), stderrOS&: llvm::errs(), LLD_ALL_DRIVERS);
104 if (!r.canRunAgain)
105 exitLld(val: r.retCode); // Exit now, can't re-execute again.
106
107 if (!mainRet) {
108 mainRet = r.retCode;
109 } else if (r.retCode != *mainRet) {
110 // Exit now, to fail the tests if the result is different between runs.
111 return r.retCode;
112 }
113 }
114 return *mainRet;
115}
116

source code of lld/tools/lld/lld.cpp