/Users/buildslave/jenkins/sharedspace/clang-stage2-coverage-R@2/llvm/tools/lld/tools/lld/lld.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===- tools/lld/lld.cpp - Linker Driver Dispatcher -----------------------===// |
2 | | // |
3 | | // The LLVM Linker |
4 | | // |
5 | | // This file is distributed under the University of Illinois Open Source |
6 | | // License. See LICENSE.TXT for details. |
7 | | // |
8 | | //===----------------------------------------------------------------------===// |
9 | | // |
10 | | // This is the entry point to the lld driver. This is a thin wrapper which |
11 | | // dispatches to the given platform specific driver. |
12 | | // |
13 | | // If there is -flavor option, it is dispatched according to the arguments. |
14 | | // If the flavor parameter is not present, then it is dispatched according |
15 | | // to argv[0]. |
16 | | // |
17 | | //===----------------------------------------------------------------------===// |
18 | | |
19 | | #include "lld/Driver/Driver.h" |
20 | | #include "llvm/ADT/STLExtras.h" |
21 | | #include "llvm/ADT/StringSwitch.h" |
22 | | #include "llvm/ADT/Twine.h" |
23 | | #include "llvm/Support/ManagedStatic.h" |
24 | | #include "llvm/Support/Path.h" |
25 | | #include "llvm/Support/PrettyStackTrace.h" |
26 | | #include "llvm/Support/Signals.h" |
27 | | |
28 | | using namespace lld; |
29 | | using namespace llvm; |
30 | | using namespace llvm::sys; |
31 | | |
32 | | enum Flavor { |
33 | | Invalid, |
34 | | Gnu, // -flavor gnu |
35 | | WinLink, // -flavor link |
36 | | Darwin, // -flavor darwin |
37 | | }; |
38 | | |
39 | 0 | LLVM_ATTRIBUTE_NORETURN static void die(const Twine &S) { |
40 | 0 | errs() << S << "\n"; |
41 | 0 | exit(1); |
42 | 0 | } |
43 | | |
44 | 2.56k | static Flavor getFlavor(StringRef S) { |
45 | 2.56k | return StringSwitch<Flavor>(S) |
46 | 2.56k | .CasesLower("ld", "ld.lld", "gnu", Gnu) |
47 | 2.56k | .CaseLower("link", WinLink) |
48 | 2.56k | .CaseLower("darwin", Darwin) |
49 | 2.56k | .Default(Invalid); |
50 | 2.56k | } |
51 | | |
52 | 1.80k | static bool isPETarget(const std::vector<const char *> &V) { |
53 | 11.8k | for (auto It = V.begin(); It + 1 != V.end()11.8k ; ++It10.0k ) { |
54 | 10.2k | if (StringRef(*It) != "-m") |
55 | 10.0k | continue; |
56 | 138 | StringRef S = *(It + 1); |
57 | 138 | return S == "i386pe" || S == "i386pep"136 || S == "thumb2pe"109 || S == "arm64pe"108 ; |
58 | 10.2k | } |
59 | 1.66k | return false; |
60 | 1.80k | } |
61 | | |
62 | 2.08k | static Flavor parseProgname(StringRef Progname) { |
63 | 2.08k | #if __APPLE__ |
64 | 2.08k | // Use Darwin driver for "ld" on Darwin. |
65 | 2.08k | if (Progname == "ld") |
66 | 1 | return Darwin; |
67 | 2.08k | #endif |
68 | 2.08k | |
69 | 2.08k | #if LLVM_ON_UNIX |
70 | 2.08k | // Use GNU driver for "ld" on other Unix-like system. |
71 | 2.08k | if (2.08k Progname == "ld"2.08k ) |
72 | 0 | return Gnu; |
73 | 2.08k | #endif |
74 | 2.08k | |
75 | 2.08k | // Progname may be something like "lld-gnu". Parse it. |
76 | 2.08k | SmallVector<StringRef, 3> V; |
77 | 2.08k | Progname.split(V, "-"); |
78 | 2.08k | for (StringRef S : V) |
79 | 2.35k | if (Flavor 2.35k F2.35k = getFlavor(S)) |
80 | 2.08k | return F; |
81 | 0 | return Invalid; |
82 | 0 | } |
83 | | |
84 | 2.28k | static Flavor parseFlavor(std::vector<const char *> &V) { |
85 | 2.28k | // Parse -flavor option. |
86 | 2.28k | if (V.size() > 1 && 2.28k V[1] == StringRef("-flavor")2.28k ) { |
87 | 205 | if (V.size() <= 2) |
88 | 0 | die("missing arg value for '-flavor'"); |
89 | 205 | Flavor F = getFlavor(V[2]); |
90 | 205 | if (F == Invalid) |
91 | 0 | die("Unknown flavor: " + StringRef(V[2])); |
92 | 205 | V.erase(V.begin() + 1, V.begin() + 3); |
93 | 205 | return F; |
94 | 205 | } |
95 | 2.08k | |
96 | 2.08k | // Deduct the flavor from argv[0]. |
97 | 2.08k | StringRef Arg0 = path::filename(V[0]); |
98 | 2.08k | if (Arg0.endswith_lower(".exe")) |
99 | 0 | Arg0 = Arg0.drop_back(4); |
100 | 2.28k | return parseProgname(Arg0); |
101 | 2.28k | } |
102 | | |
103 | | /// Universal linker main(). This linker emulates the gnu, darwin, or |
104 | | /// windows linker based on the argv[0] or -flavor option. |
105 | 2.28k | int main(int Argc, const char **Argv) { |
106 | 2.28k | // Standard set up, so program fails gracefully. |
107 | 2.28k | sys::PrintStackTraceOnErrorSignal(Argv[0]); |
108 | 2.28k | PrettyStackTraceProgram StackPrinter(Argc, Argv); |
109 | 2.28k | llvm_shutdown_obj Shutdown; |
110 | 2.28k | |
111 | 2.28k | std::vector<const char *> Args(Argv, Argv + Argc); |
112 | 2.28k | switch (parseFlavor(Args)) { |
113 | 1.80k | case Gnu: |
114 | 1.80k | if (isPETarget(Args)) |
115 | 31 | return !mingw::link(Args); |
116 | 1.77k | return !elf::link(Args, true); |
117 | 275 | case WinLink: |
118 | 275 | return !coff::link(Args); |
119 | 206 | case Darwin: |
120 | 206 | return !mach_o::link(Args); |
121 | 0 | default: |
122 | 0 | die("lld is a generic driver.\n" |
123 | 0 | "Invoke ld.lld (Unix), ld (macOS) or lld-link (Windows) instead."); |
124 | 0 | } |
125 | 0 | } |