/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/ToolChains/DragonFly.cpp
Line | Count | Source (jump to first uncovered line) |
1 | | //===--- DragonFly.cpp - DragonFly ToolChain Implementations ----*- C++ -*-===// |
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 | | #include "DragonFly.h" |
10 | | #include "CommonArgs.h" |
11 | | #include "clang/Driver/Compilation.h" |
12 | | #include "clang/Driver/Driver.h" |
13 | | #include "clang/Driver/Options.h" |
14 | | #include "llvm/Option/ArgList.h" |
15 | | |
16 | | using namespace clang::driver; |
17 | | using namespace clang::driver::tools; |
18 | | using namespace clang::driver::toolchains; |
19 | | using namespace clang; |
20 | | using namespace llvm::opt; |
21 | | |
22 | | /// DragonFly Tools |
23 | | |
24 | | // For now, DragonFly Assemble does just about the same as for |
25 | | // FreeBSD, but this may change soon. |
26 | | void dragonfly::Assembler::ConstructJob(Compilation &C, const JobAction &JA, |
27 | | const InputInfo &Output, |
28 | | const InputInfoList &Inputs, |
29 | | const ArgList &Args, |
30 | 0 | const char *LinkingOutput) const { |
31 | 0 | claimNoWarnArgs(Args); |
32 | 0 | ArgStringList CmdArgs; |
33 | | |
34 | | // When building 32-bit code on DragonFly/pc64, we have to explicitly |
35 | | // instruct as in the base system to assemble 32-bit code. |
36 | 0 | if (getToolChain().getArch() == llvm::Triple::x86) |
37 | 0 | CmdArgs.push_back("--32"); |
38 | |
|
39 | 0 | Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); |
40 | |
|
41 | 0 | CmdArgs.push_back("-o"); |
42 | 0 | CmdArgs.push_back(Output.getFilename()); |
43 | |
|
44 | 0 | for (const auto &II : Inputs) |
45 | 0 | CmdArgs.push_back(II.getFilename()); |
46 | |
|
47 | 0 | const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as")); |
48 | 0 | C.addCommand(std::make_unique<Command>(JA, *this, |
49 | 0 | ResponseFileSupport::AtFileCurCP(), |
50 | 0 | Exec, CmdArgs, Inputs, Output)); |
51 | 0 | } |
52 | | |
53 | | void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA, |
54 | | const InputInfo &Output, |
55 | | const InputInfoList &Inputs, |
56 | | const ArgList &Args, |
57 | 1 | const char *LinkingOutput) const { |
58 | 1 | const Driver &D = getToolChain().getDriver(); |
59 | 1 | ArgStringList CmdArgs; |
60 | | |
61 | 1 | if (!D.SysRoot.empty()) |
62 | 0 | CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); |
63 | | |
64 | 1 | CmdArgs.push_back("--eh-frame-hdr"); |
65 | 1 | if (Args.hasArg(options::OPT_static)) { |
66 | 0 | CmdArgs.push_back("-Bstatic"); |
67 | 1 | } else { |
68 | 1 | if (Args.hasArg(options::OPT_rdynamic)) |
69 | 0 | CmdArgs.push_back("-export-dynamic"); |
70 | 1 | if (Args.hasArg(options::OPT_shared)) |
71 | 0 | CmdArgs.push_back("-Bshareable"); |
72 | 1 | else { |
73 | 1 | CmdArgs.push_back("-dynamic-linker"); |
74 | 1 | CmdArgs.push_back("/usr/libexec/ld-elf.so.2"); |
75 | 1 | } |
76 | 1 | CmdArgs.push_back("--hash-style=gnu"); |
77 | 1 | CmdArgs.push_back("--enable-new-dtags"); |
78 | 1 | } |
79 | | |
80 | | // When building 32-bit code on DragonFly/pc64, we have to explicitly |
81 | | // instruct ld in the base system to link 32-bit code. |
82 | 1 | if (getToolChain().getArch() == llvm::Triple::x86) { |
83 | 0 | CmdArgs.push_back("-m"); |
84 | 0 | CmdArgs.push_back("elf_i386"); |
85 | 0 | } |
86 | | |
87 | 1 | if (Output.isFilename()) { |
88 | 1 | CmdArgs.push_back("-o"); |
89 | 1 | CmdArgs.push_back(Output.getFilename()); |
90 | 0 | } else { |
91 | 0 | assert(Output.isNothing() && "Invalid output."); |
92 | 0 | } |
93 | | |
94 | 1 | if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { |
95 | 1 | if (!Args.hasArg(options::OPT_shared)) { |
96 | 1 | if (Args.hasArg(options::OPT_pg)) |
97 | 0 | CmdArgs.push_back( |
98 | 0 | Args.MakeArgString(getToolChain().GetFilePath("gcrt1.o"))); |
99 | 1 | else { |
100 | 1 | if (Args.hasArg(options::OPT_pie)) |
101 | 0 | CmdArgs.push_back( |
102 | 0 | Args.MakeArgString(getToolChain().GetFilePath("Scrt1.o"))); |
103 | 1 | else |
104 | 1 | CmdArgs.push_back( |
105 | 1 | Args.MakeArgString(getToolChain().GetFilePath("crt1.o"))); |
106 | 1 | } |
107 | 1 | } |
108 | 1 | CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o"))); |
109 | 1 | if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) |
110 | 0 | CmdArgs.push_back( |
111 | 0 | Args.MakeArgString(getToolChain().GetFilePath("crtbeginS.o"))); |
112 | 1 | else |
113 | 1 | CmdArgs.push_back( |
114 | 1 | Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o"))); |
115 | 1 | } |
116 | | |
117 | 1 | Args.AddAllArgs(CmdArgs, |
118 | 1 | {options::OPT_L, options::OPT_T_Group, options::OPT_e}); |
119 | | |
120 | 1 | AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA); |
121 | | |
122 | 1 | if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) { |
123 | 1 | CmdArgs.push_back("-L/usr/lib/gcc80"); |
124 | | |
125 | 1 | if (!Args.hasArg(options::OPT_static)) { |
126 | 1 | CmdArgs.push_back("-rpath"); |
127 | 1 | CmdArgs.push_back("/usr/lib/gcc80"); |
128 | 1 | } |
129 | | |
130 | 1 | if (D.CCCIsCXX()) { |
131 | 0 | if (getToolChain().ShouldLinkCXXStdlib(Args)) |
132 | 0 | getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs); |
133 | 0 | CmdArgs.push_back("-lm"); |
134 | 0 | } |
135 | | |
136 | 1 | if (Args.hasArg(options::OPT_pthread)) |
137 | 0 | CmdArgs.push_back("-lpthread"); |
138 | | |
139 | 1 | if (!Args.hasArg(options::OPT_nolibc)) { |
140 | 1 | CmdArgs.push_back("-lc"); |
141 | 1 | } |
142 | | |
143 | 1 | if (Args.hasArg(options::OPT_static) || |
144 | 1 | Args.hasArg(options::OPT_static_libgcc)) { |
145 | 0 | CmdArgs.push_back("-lgcc"); |
146 | 0 | CmdArgs.push_back("-lgcc_eh"); |
147 | 1 | } else { |
148 | 1 | if (Args.hasArg(options::OPT_shared_libgcc)) { |
149 | 0 | CmdArgs.push_back("-lgcc_pic"); |
150 | 0 | if (!Args.hasArg(options::OPT_shared)) |
151 | 0 | CmdArgs.push_back("-lgcc"); |
152 | 1 | } else { |
153 | 1 | CmdArgs.push_back("-lgcc"); |
154 | 1 | CmdArgs.push_back("--as-needed"); |
155 | 1 | CmdArgs.push_back("-lgcc_pic"); |
156 | 1 | CmdArgs.push_back("--no-as-needed"); |
157 | 1 | } |
158 | 1 | } |
159 | 1 | } |
160 | | |
161 | 1 | if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) { |
162 | 1 | if (Args.hasArg(options::OPT_shared) || Args.hasArg(options::OPT_pie)) |
163 | 0 | CmdArgs.push_back( |
164 | 0 | Args.MakeArgString(getToolChain().GetFilePath("crtendS.o"))); |
165 | 1 | else |
166 | 1 | CmdArgs.push_back( |
167 | 1 | Args.MakeArgString(getToolChain().GetFilePath("crtend.o"))); |
168 | 1 | CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o"))); |
169 | 1 | } |
170 | | |
171 | 1 | getToolChain().addProfileRTLibs(Args, CmdArgs); |
172 | | |
173 | 1 | const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath()); |
174 | 1 | C.addCommand(std::make_unique<Command>(JA, *this, |
175 | 1 | ResponseFileSupport::AtFileCurCP(), |
176 | 1 | Exec, CmdArgs, Inputs, Output)); |
177 | 1 | } |
178 | | |
179 | | /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. |
180 | | |
181 | | DragonFly::DragonFly(const Driver &D, const llvm::Triple &Triple, |
182 | | const ArgList &Args) |
183 | 2 | : Generic_ELF(D, Triple, Args) { |
184 | | |
185 | | // Path mangling to find libexec |
186 | 2 | getProgramPaths().push_back(getDriver().getInstalledDir()); |
187 | 2 | if (getDriver().getInstalledDir() != getDriver().Dir) |
188 | 0 | getProgramPaths().push_back(getDriver().Dir); |
189 | | |
190 | 2 | getFilePaths().push_back(getDriver().Dir + "/../lib"); |
191 | 2 | getFilePaths().push_back("/usr/lib"); |
192 | 2 | getFilePaths().push_back("/usr/lib/gcc80"); |
193 | 2 | } |
194 | | |
195 | 0 | Tool *DragonFly::buildAssembler() const { |
196 | 0 | return new tools::dragonfly::Assembler(*this); |
197 | 0 | } |
198 | | |
199 | 1 | Tool *DragonFly::buildLinker() const { |
200 | 1 | return new tools::dragonfly::Linker(*this); |
201 | 1 | } |