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/StringSwitch.h" 34 #include "llvm/ADT/Triple.h" 35 #include "llvm/ADT/Twine.h" 36 #include "llvm/Support/CommandLine.h" 37 #include "llvm/Support/CrashRecoveryContext.h" 38 #include "llvm/Support/Host.h" 39 #include "llvm/Support/InitLLVM.h" 40 #include "llvm/Support/Path.h" 41 #include "llvm/Support/PluginLoader.h" 42 #include "llvm/Support/Signals.h" 43 #include <cstdlib> 44 45 #if !defined(_MSC_VER) && !defined(__MINGW32__) 46 #include <signal.h> // for raise 47 #include <unistd.h> // for _exit 48 #endif 49 50 using namespace lld; 51 using namespace llvm; 52 using namespace llvm::sys; 53 54 enum Flavor { 55 Invalid, 56 Gnu, // -flavor gnu 57 WinLink, // -flavor link 58 Darwin, // -flavor darwin 59 DarwinNew, // -flavor darwinnew 60 Wasm, // -flavor wasm 61 }; 62 63 LLVM_ATTRIBUTE_NORETURN static void die(const Twine &s) { 64 llvm::errs() << s << "\n"; 65 exit(1); 66 } 67 68 static Flavor getFlavor(StringRef s) { 69 return StringSwitch<Flavor>(s) 70 .CasesLower("ld", "ld.lld", "gnu", Gnu) 71 .CasesLower("wasm", "ld-wasm", Wasm) 72 .CaseLower("link", WinLink) 73 .CasesLower("ld64", "ld64.lld", "darwin", Darwin) 74 .CasesLower("darwinnew", "ld64.lld.darwinnew", DarwinNew) 75 .Default(Invalid); 76 } 77 78 static cl::TokenizerCallback getDefaultQuotingStyle() { 79 if (Triple(sys::getProcessTriple()).getOS() == Triple::Win32) 80 return cl::TokenizeWindowsCommandLine; 81 return cl::TokenizeGNUCommandLine; 82 } 83 84 static bool isPETargetName(StringRef s) { 85 return s == "i386pe" || s == "i386pep" || s == "thumb2pe" || s == "arm64pe"; 86 } 87 88 static bool isPETarget(std::vector<const char *> &v) { 89 for (auto it = v.begin(); it + 1 != v.end(); ++it) { 90 if (StringRef(*it) != "-m") 91 continue; 92 return isPETargetName(*(it + 1)); 93 } 94 // Expand response files (arguments in the form of @<filename>) 95 // to allow detecting the -m argument from arguments in them. 96 SmallVector<const char *, 256> expandedArgs(v.data(), v.data() + v.size()); 97 cl::ExpandResponseFiles(saver, getDefaultQuotingStyle(), expandedArgs); 98 for (auto it = expandedArgs.begin(); it + 1 != expandedArgs.end(); ++it) { 99 if (StringRef(*it) != "-m") 100 continue; 101 return isPETargetName(*(it + 1)); 102 } 103 104 #ifdef LLD_DEFAULT_LD_LLD_IS_MINGW 105 return true; 106 #else 107 return false; 108 #endif 109 } 110 111 static Flavor parseProgname(StringRef progname) { 112 // Use GNU driver for "ld" by default. 113 if (progname == "ld") 114 return Gnu; 115 116 // Progname may be something like "lld-gnu". Parse it. 117 SmallVector<StringRef, 3> v; 118 progname.split(v, "-"); 119 for (StringRef s : v) 120 if (Flavor f = getFlavor(s)) 121 return f; 122 return Invalid; 123 } 124 125 static Flavor parseFlavor(std::vector<const char *> &v) { 126 // Parse -flavor option. 127 if (v.size() > 1 && v[1] == StringRef("-flavor")) { 128 if (v.size() <= 2) 129 die("missing arg value for '-flavor'"); 130 Flavor f = getFlavor(v[2]); 131 if (f == Invalid) 132 die("Unknown flavor: " + StringRef(v[2])); 133 v.erase(v.begin() + 1, v.begin() + 3); 134 return f; 135 } 136 137 // Deduct the flavor from argv[0]. 138 StringRef arg0 = path::filename(v[0]); 139 if (arg0.endswith_lower(".exe")) 140 arg0 = arg0.drop_back(4); 141 return parseProgname(arg0); 142 } 143 144 /// Universal linker main(). This linker emulates the gnu, darwin, or 145 /// windows linker based on the argv[0] or -flavor option. 146 static int lldMain(int argc, const char **argv, llvm::raw_ostream &stdoutOS, 147 llvm::raw_ostream &stderrOS, bool exitEarly = true) { 148 std::vector<const char *> args(argv, argv + argc); 149 #ifdef __FreeBSD__ 150 return !elf::link(args, exitEarly, stdoutOS, stderrOS); 151 #else 152 switch (parseFlavor(args)) { 153 case Gnu: 154 if (isPETarget(args)) 155 return !mingw::link(args, exitEarly, stdoutOS, stderrOS); 156 return !elf::link(args, exitEarly, stdoutOS, stderrOS); 157 case WinLink: 158 return !coff::link(args, exitEarly, stdoutOS, stderrOS); 159 case Darwin: 160 return !mach_o::link(args, exitEarly, stdoutOS, stderrOS); 161 case DarwinNew: 162 return !macho::link(args, exitEarly, stdoutOS, stderrOS); 163 case Wasm: 164 return !lld::wasm::link(args, exitEarly, stdoutOS, stderrOS); 165 default: 166 die("lld is a generic driver.\n" 167 "Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld" 168 " (WebAssembly) instead"); 169 } 170 #endif 171 } 172 173 // Similar to lldMain except that exceptions are caught. 174 SafeReturn lld::safeLldMain(int argc, const char **argv, 175 llvm::raw_ostream &stdoutOS, 176 llvm::raw_ostream &stderrOS) { 177 int r = 0; 178 { 179 // The crash recovery is here only to be able to recover from arbitrary 180 // control flow when fatal() is called (through setjmp/longjmp or 181 // __try/__except). 182 llvm::CrashRecoveryContext crc; 183 if (!crc.RunSafely([&]() { 184 r = lldMain(argc, argv, stdoutOS, stderrOS, /*exitEarly=*/false); 185 })) 186 return {crc.RetCode, /*canRunAgain=*/false}; 187 } 188 189 // Cleanup memory and reset everything back in pristine condition. This path 190 // is only taken when LLD is in test, or when it is used as a library. 191 llvm::CrashRecoveryContext crc; 192 if (!crc.RunSafely([&]() { errorHandler().reset(); })) { 193 // The memory is corrupted beyond any possible recovery. 194 return {r, /*canRunAgain=*/false}; 195 } 196 return {r, /*canRunAgain=*/true}; 197 } 198 199 // When in lit tests, tells how many times the LLD tool should re-execute the 200 // main loop with the same inputs. When not in test, returns a value of 0 which 201 // signifies that LLD shall not release any memory after execution, to speed up 202 // process destruction. 203 static unsigned inTestVerbosity() { 204 unsigned v = 0; 205 StringRef(getenv("LLD_IN_TEST")).getAsInteger(10, v); 206 return v; 207 } 208 209 int main(int argc, const char **argv) { 210 InitLLVM x(argc, argv); 211 212 // Not running in lit tests, just take the shortest codepath with global 213 // exception handling and no memory cleanup on exit. 214 if (!inTestVerbosity()) 215 return lldMain(argc, argv, llvm::outs(), llvm::errs()); 216 217 Optional<int> mainRet; 218 CrashRecoveryContext::Enable(); 219 220 for (unsigned i = inTestVerbosity(); i > 0; --i) { 221 // Disable stdout/stderr for all iterations but the last one. 222 if (i != 1) 223 errorHandler().disableOutput = true; 224 225 // Execute one iteration. 226 auto r = safeLldMain(argc, argv, llvm::outs(), llvm::errs()); 227 if (!r.canRunAgain) 228 exitLld(r.ret); // Exit now, can't re-execute again. 229 230 if (!mainRet) { 231 mainRet = r.ret; 232 } else if (r.ret != *mainRet) { 233 // Exit now, to fail the tests if the result is different between runs. 234 return r.ret; 235 } 236 } 237 return *mainRet; 238 } 239