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