1 //===- tools/lld/lld.cpp - Linker Driver Dispatcher -----------------------===//
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 // This file contains the main function of the lld executable. The main
11 // function is a thin wrapper which dispatches to the platform specific
14 // lld is a single executable that contains four different linkers for ELF,
15 // COFF, WebAssembly and Mach-O. The main function dispatches according to
16 // argv[0] (i.e. command name). The most common name for each target is shown
19 // - ld.lld: ELF (Unix)
20 // - ld64: Mach-O (macOS)
21 // - lld-link: COFF (Windows)
22 // - ld-wasm: WebAssembly
24 // lld can be invoked as "lld" along with "-flavor" option. This is for
25 // backward compatibility and not recommended.
27 //===----------------------------------------------------------------------===//
29 #include "lld/Common/Driver.h"
30 #include "llvm/ADT/STLExtras.h"
31 #include "llvm/ADT/StringSwitch.h"
32 #include "llvm/ADT/Twine.h"
33 #include "llvm/Support/InitLLVM.h"
34 #include "llvm/Support/Path.h"
39 using namespace llvm::sys;
44 WinLink, // -flavor link
45 Darwin, // -flavor darwin
49 LLVM_ATTRIBUTE_NORETURN static void die(const Twine &S) {
54 static Flavor getFlavor(StringRef S) {
55 return StringSwitch<Flavor>(S)
56 .CasesLower("ld", "ld.lld", "gnu", Gnu)
57 .CasesLower("wasm", "ld-wasm", Wasm)
58 .CaseLower("link", WinLink)
59 .CasesLower("ld64", "ld64.lld", "darwin", Darwin)
63 static bool isPETarget(const std::vector<const char *> &V) {
64 for (auto It = V.begin(); It + 1 != V.end(); ++It) {
65 if (StringRef(*It) != "-m")
67 StringRef S = *(It + 1);
68 return S == "i386pe" || S == "i386pep" || S == "thumb2pe" || S == "arm64pe";
73 static Flavor parseProgname(StringRef Progname) {
75 // Use Darwin driver for "ld" on Darwin.
81 // Use GNU driver for "ld" on other Unix-like system.
86 // Progname may be something like "lld-gnu". Parse it.
87 SmallVector<StringRef, 3> V;
88 Progname.split(V, "-");
90 if (Flavor F = getFlavor(S))
95 static Flavor parseFlavor(std::vector<const char *> &V) {
96 // Parse -flavor option.
97 if (V.size() > 1 && V[1] == StringRef("-flavor")) {
99 die("missing arg value for '-flavor'");
100 Flavor F = getFlavor(V[2]);
102 die("Unknown flavor: " + StringRef(V[2]));
103 V.erase(V.begin() + 1, V.begin() + 3);
107 // Deduct the flavor from argv[0].
108 StringRef Arg0 = path::filename(V[0]);
109 if (Arg0.endswith_lower(".exe"))
110 Arg0 = Arg0.drop_back(4);
111 return parseProgname(Arg0);
114 // If this function returns true, lld calls _exit() so that it quickly
115 // exits without invoking destructors of globally allocated objects.
117 // We don't want to do that if we are running tests though, because
118 // doing that breaks leak sanitizer. So, lit sets this environment variable,
119 // and we use it to detect whether we are running tests or not.
120 static bool canExitEarly() { return StringRef(getenv("LLD_IN_TEST")) != "1"; }
122 /// Universal linker main(). This linker emulates the gnu, darwin, or
123 /// windows linker based on the argv[0] or -flavor option.
124 int main(int Argc, const char **Argv) {
125 InitLLVM X(Argc, Argv);
127 std::vector<const char *> Args(Argv, Argv + Argc);
129 return !elf::link(Args, true);
131 switch (parseFlavor(Args)) {
133 if (isPETarget(Args))
134 return !mingw::link(Args);
135 return !elf::link(Args, canExitEarly());
137 return !coff::link(Args, canExitEarly());
139 return !mach_o::link(Args, canExitEarly());
141 return !wasm::link(Args, canExitEarly());
143 die("lld is a generic driver.\n"
144 "Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-lld"
145 " (WebAssembly) instead");