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