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 #if 1 150 /* On FreeBSD we only build the ELF linker. */ 151 return !elf::link(args, exitEarly, stdoutOS, stderrOS); 152 #else 153 switch (parseFlavor(args)) { 154 case Gnu: 155 if (isPETarget(args)) 156 return !mingw::link(args, exitEarly, stdoutOS, stderrOS); 157 return !elf::link(args, exitEarly, stdoutOS, stderrOS); 158 case WinLink: 159 return !coff::link(args, exitEarly, stdoutOS, stderrOS); 160 case Darwin: 161 return !mach_o::link(args, exitEarly, stdoutOS, stderrOS); 162 case DarwinNew: 163 return !macho::link(args, exitEarly, stdoutOS, stderrOS); 164 case Wasm: 165 return !lld::wasm::link(args, exitEarly, stdoutOS, stderrOS); 166 default: 167 die("lld is a generic driver.\n" 168 "Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld" 169 " (WebAssembly) instead"); 170 } 171 #endif 172 } 173 174 // Similar to lldMain except that exceptions are caught. 175 SafeReturn lld::safeLldMain(int argc, const char **argv, 176 llvm::raw_ostream &stdoutOS, 177 llvm::raw_ostream &stderrOS) { 178 int r = 0; 179 { 180 // The crash recovery is here only to be able to recover from arbitrary 181 // control flow when fatal() is called (through setjmp/longjmp or 182 // __try/__except). 183 llvm::CrashRecoveryContext crc; 184 if (!crc.RunSafely([&]() { 185 r = lldMain(argc, argv, stdoutOS, stderrOS, /*exitEarly=*/false); 186 })) 187 return {crc.RetCode, /*canRunAgain=*/false}; 188 } 189 190 // Cleanup memory and reset everything back in pristine condition. This path 191 // is only taken when LLD is in test, or when it is used as a library. 192 llvm::CrashRecoveryContext crc; 193 if (!crc.RunSafely([&]() { errorHandler().reset(); })) { 194 // The memory is corrupted beyond any possible recovery. 195 return {r, /*canRunAgain=*/false}; 196 } 197 return {r, /*canRunAgain=*/true}; 198 } 199 200 // When in lit tests, tells how many times the LLD tool should re-execute the 201 // main loop with the same inputs. When not in test, returns a value of 0 which 202 // signifies that LLD shall not release any memory after execution, to speed up 203 // process destruction. 204 static unsigned inTestVerbosity() { 205 unsigned v = 0; 206 StringRef(getenv("LLD_IN_TEST")).getAsInteger(10, v); 207 return v; 208 } 209 210 int main(int argc, const char **argv) { 211 InitLLVM x(argc, argv); 212 213 // Not running in lit tests, just take the shortest codepath with global 214 // exception handling and no memory cleanup on exit. 215 if (!inTestVerbosity()) 216 return lldMain(argc, argv, llvm::outs(), llvm::errs()); 217 218 Optional<int> mainRet; 219 CrashRecoveryContext::Enable(); 220 221 for (unsigned i = inTestVerbosity(); i > 0; --i) { 222 // Disable stdout/stderr for all iterations but the last one. 223 if (i != 1) 224 errorHandler().disableOutput = true; 225 226 // Execute one iteration. 227 auto r = safeLldMain(argc, argv, llvm::outs(), llvm::errs()); 228 if (!r.canRunAgain) 229 exitLld(r.ret); // Exit now, can't re-execute again. 230 231 if (!mainRet) { 232 mainRet = r.ret; 233 } else if (r.ret != *mainRet) { 234 // Exit now, to fail the tests if the result is different between runs. 235 return r.ret; 236 } 237 } 238 return *mainRet; 239 } 240