xref: /freebsd/contrib/llvm-project/lld/tools/lld/lld.cpp (revision e92ffd9b626833ebdbf2742c8ffddc6cd94b963e)
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