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 <cstdlib> 43 44 using namespace lld; 45 using namespace llvm; 46 using namespace llvm::sys; 47 48 enum Flavor { 49 Invalid, 50 Gnu, // -flavor gnu 51 WinLink, // -flavor link 52 Darwin, // -flavor darwin 53 DarwinOld, // -flavor darwinold 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", "darwinnew", 68 "ld64.lld.darwinnew", Darwin) 69 .CasesLower("darwinold", "ld64.lld.darwinold", DarwinOld) 70 .Default(Invalid); 71 } 72 73 static cl::TokenizerCallback getDefaultQuotingStyle() { 74 if (Triple(sys::getProcessTriple()).getOS() == Triple::Win32) 75 return cl::TokenizeWindowsCommandLine; 76 return cl::TokenizeGNUCommandLine; 77 } 78 79 static bool isPETargetName(StringRef s) { 80 return s == "i386pe" || s == "i386pep" || s == "thumb2pe" || s == "arm64pe"; 81 } 82 83 static bool isPETarget(std::vector<const char *> &v) { 84 for (auto it = v.begin(); it + 1 != v.end(); ++it) { 85 if (StringRef(*it) != "-m") 86 continue; 87 return isPETargetName(*(it + 1)); 88 } 89 // Expand response files (arguments in the form of @<filename>) 90 // to allow detecting the -m argument from arguments in them. 91 SmallVector<const char *, 256> expandedArgs(v.data(), v.data() + v.size()); 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 /// Universal linker main(). This linker emulates the gnu, darwin, or 140 /// windows linker based on the argv[0] or -flavor option. 141 static int lldMain(int argc, const char **argv, llvm::raw_ostream &stdoutOS, 142 llvm::raw_ostream &stderrOS, bool exitEarly = true) { 143 std::vector<const char *> args(argv, argv + argc); 144 #if 1 145 /* On FreeBSD we only build the ELF linker. */ 146 return !elf::link(args, exitEarly, stdoutOS, stderrOS); 147 #else 148 switch (parseFlavor(args)) { 149 case Gnu: 150 if (isPETarget(args)) 151 return !mingw::link(args, exitEarly, stdoutOS, stderrOS); 152 return !elf::link(args, exitEarly, stdoutOS, stderrOS); 153 case WinLink: 154 return !coff::link(args, exitEarly, stdoutOS, stderrOS); 155 case Darwin: 156 return !macho::link(args, exitEarly, stdoutOS, stderrOS); 157 case DarwinOld: 158 return !mach_o::link(args, exitEarly, stdoutOS, stderrOS); 159 case Wasm: 160 return !lld::wasm::link(args, exitEarly, stdoutOS, stderrOS); 161 default: 162 die("lld is a generic driver.\n" 163 "Invoke ld.lld (Unix), ld64.lld (macOS), lld-link (Windows), wasm-ld" 164 " (WebAssembly) instead"); 165 } 166 #endif 167 } 168 169 // Similar to lldMain except that exceptions are caught. 170 SafeReturn lld::safeLldMain(int argc, const char **argv, 171 llvm::raw_ostream &stdoutOS, 172 llvm::raw_ostream &stderrOS) { 173 int r = 0; 174 { 175 // The crash recovery is here only to be able to recover from arbitrary 176 // control flow when fatal() is called (through setjmp/longjmp or 177 // __try/__except). 178 llvm::CrashRecoveryContext crc; 179 if (!crc.RunSafely([&]() { 180 r = lldMain(argc, argv, stdoutOS, stderrOS, /*exitEarly=*/false); 181 })) 182 return {crc.RetCode, /*canRunAgain=*/false}; 183 } 184 185 // Cleanup memory and reset everything back in pristine condition. This path 186 // is only taken when LLD is in test, or when it is used as a library. 187 llvm::CrashRecoveryContext crc; 188 if (!crc.RunSafely([&]() { errorHandler().reset(); })) { 189 // The memory is corrupted beyond any possible recovery. 190 return {r, /*canRunAgain=*/false}; 191 } 192 return {r, /*canRunAgain=*/true}; 193 } 194 195 // When in lit tests, tells how many times the LLD tool should re-execute the 196 // main loop with the same inputs. When not in test, returns a value of 0 which 197 // signifies that LLD shall not release any memory after execution, to speed up 198 // process destruction. 199 static unsigned inTestVerbosity() { 200 unsigned v = 0; 201 StringRef(getenv("LLD_IN_TEST")).getAsInteger(10, v); 202 return v; 203 } 204 205 int main(int argc, const char **argv) { 206 InitLLVM x(argc, argv); 207 208 // Not running in lit tests, just take the shortest codepath with global 209 // exception handling and no memory cleanup on exit. 210 if (!inTestVerbosity()) 211 return lldMain(argc, argv, llvm::outs(), llvm::errs()); 212 213 Optional<int> mainRet; 214 CrashRecoveryContext::Enable(); 215 216 for (unsigned i = inTestVerbosity(); i > 0; --i) { 217 // Disable stdout/stderr for all iterations but the last one. 218 if (i != 1) 219 errorHandler().disableOutput = true; 220 221 // Execute one iteration. 222 auto r = safeLldMain(argc, argv, llvm::outs(), llvm::errs()); 223 if (!r.canRunAgain) 224 exitLld(r.ret); // Exit now, can't re-execute again. 225 226 if (!mainRet) { 227 mainRet = r.ret; 228 } else if (r.ret != *mainRet) { 229 // Exit now, to fail the tests if the result is different between runs. 230 return r.ret; 231 } 232 } 233 return *mainRet; 234 } 235