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