/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 | | void dragonfly::Assembler::ConstructJob(Compilation &C, const JobAction &JA, |
24 | | const InputInfo &Output, |
25 | | const InputInfoList &Inputs, |
26 | | const ArgList &Args, |
27 | 0 | const char *LinkingOutput) const { |
28 | 0 | const auto &ToolChain = static_cast<const DragonFly &>(getToolChain()); |
29 | 0 | ArgStringList CmdArgs; |
30 | |
|
31 | 0 | claimNoWarnArgs(Args); |
32 | | |
33 | | // When building 32-bit code on DragonFly/pc64, we have to explicitly |
34 | | // instruct as in the base system to assemble 32-bit code. |
35 | 0 | if (ToolChain.getArch() == llvm::Triple::x86) |
36 | 0 | CmdArgs.push_back("--32"); |
37 | |
|
38 | 0 | Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler); |
39 | |
|
40 | 0 | CmdArgs.push_back("-o"); |
41 | 0 | CmdArgs.push_back(Output.getFilename()); |
42 | |
|
43 | 0 | for (const auto &II : Inputs) |
44 | 0 | CmdArgs.push_back(II.getFilename()); |
45 | |
|
46 | 0 | const char *Exec = Args.MakeArgString(ToolChain.GetProgramPath("as")); |
47 | 0 | C.addCommand(std::make_unique<Command>(JA, *this, |
48 | 0 | ResponseFileSupport::AtFileCurCP(), |
49 | 0 | Exec, CmdArgs, Inputs, Output)); |
50 | 0 | } |
51 | | |
52 | | void dragonfly::Linker::ConstructJob(Compilation &C, const JobAction &JA, |
53 | | const InputInfo &Output, |
54 | | const InputInfoList &Inputs, |
55 | | const ArgList &Args, |
56 | 15 | const char *LinkingOutput) const { |
57 | 15 | const auto &ToolChain = static_cast<const DragonFly &>(getToolChain()); |
58 | 15 | const Driver &D = ToolChain.getDriver(); |
59 | 15 | const llvm::Triple::ArchType Arch = ToolChain.getArch(); |
60 | 15 | ArgStringList CmdArgs; |
61 | 15 | bool Static = Args.hasArg(options::OPT_static); |
62 | 15 | bool Shared = Args.hasArg(options::OPT_shared); |
63 | 15 | bool Profiling = Args.hasArg(options::OPT_pg); |
64 | 15 | bool Pie = Args.hasArg(options::OPT_pie); |
65 | | |
66 | 15 | if (!D.SysRoot.empty()) |
67 | 1 | CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); |
68 | | |
69 | 15 | CmdArgs.push_back("--eh-frame-hdr"); |
70 | 15 | if (Static) { |
71 | 1 | CmdArgs.push_back("-Bstatic"); |
72 | 14 | } else { |
73 | 14 | if (Args.hasArg(options::OPT_rdynamic)) |
74 | 0 | CmdArgs.push_back("-export-dynamic"); |
75 | 14 | if (Shared) |
76 | 0 | CmdArgs.push_back("-shared"); |
77 | 14 | else if (!Args.hasArg(options::OPT_r)) { |
78 | 13 | CmdArgs.push_back("-dynamic-linker"); |
79 | 13 | CmdArgs.push_back("/usr/libexec/ld-elf.so.2"); |
80 | 13 | } |
81 | 14 | CmdArgs.push_back("--hash-style=gnu"); |
82 | 14 | CmdArgs.push_back("--enable-new-dtags"); |
83 | 14 | } |
84 | | |
85 | | // When building 32-bit code on DragonFly/pc64, we have to explicitly |
86 | | // instruct ld in the base system to link 32-bit code. |
87 | 15 | if (Arch == llvm::Triple::x86) { |
88 | 0 | CmdArgs.push_back("-m"); |
89 | 0 | CmdArgs.push_back("elf_i386"); |
90 | 0 | } |
91 | | |
92 | 15 | assert((Output.isFilename() || Output.isNothing()) && "Invalid output."); |
93 | 15 | if (Output.isFilename()) { |
94 | 15 | CmdArgs.push_back("-o"); |
95 | 15 | CmdArgs.push_back(Output.getFilename()); |
96 | 15 | } |
97 | | |
98 | 15 | if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, |
99 | 15 | options::OPT_r)) { |
100 | 11 | const char *crt1 = nullptr; |
101 | 11 | const char *crtbegin = nullptr; |
102 | 11 | if (!Shared) { |
103 | 11 | if (Profiling) |
104 | 0 | crt1 = "gcrt1.o"; |
105 | 11 | else { |
106 | 11 | if (Pie) |
107 | 0 | crt1 = "Scrt1.o"; |
108 | 11 | else |
109 | 11 | crt1 = "crt1.o"; |
110 | 11 | } |
111 | 11 | } |
112 | | |
113 | 11 | if (Shared || Pie) |
114 | 0 | crtbegin = "crtbeginS.o"; |
115 | 11 | else |
116 | 11 | crtbegin = "crtbegin.o"; |
117 | | |
118 | 11 | if (crt1) |
119 | 11 | CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1))); |
120 | 11 | CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o"))); |
121 | 11 | CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin))); |
122 | 11 | } |
123 | | |
124 | 15 | Args.addAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group, |
125 | 15 | options::OPT_s, options::OPT_t, options::OPT_r}); |
126 | 15 | ToolChain.AddFilePathLibArgs(Args, CmdArgs); |
127 | | |
128 | 15 | AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA); |
129 | | |
130 | 15 | if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs, |
131 | 15 | options::OPT_r)) { |
132 | 11 | if (!Static) { |
133 | 10 | CmdArgs.push_back("-rpath"); |
134 | 10 | CmdArgs.push_back("/usr/lib/gcc80"); |
135 | 10 | } |
136 | | |
137 | | // Use the static OpenMP runtime with -static-openmp |
138 | 11 | bool StaticOpenMP = Args.hasArg(options::OPT_static_openmp) && !Static4 ; |
139 | 11 | addOpenMPRuntime(CmdArgs, ToolChain, Args, StaticOpenMP); |
140 | | |
141 | 11 | if (D.CCCIsCXX()) { |
142 | 0 | if (ToolChain.ShouldLinkCXXStdlib(Args)) |
143 | 0 | ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs); |
144 | 0 | CmdArgs.push_back("-lm"); |
145 | 0 | } |
146 | | |
147 | | // Silence warnings when linking C code with a C++ '-stdlib' argument. |
148 | 11 | Args.ClaimAllArgs(options::OPT_stdlib_EQ); |
149 | | |
150 | | // Additional linker set-up and flags for Fortran. This is required in order |
151 | | // to generate executables. As Fortran runtime depends on the C runtime, |
152 | | // these dependencies need to be listed before the C runtime below (i.e. |
153 | | // AddRunTimeLibs). |
154 | 11 | if (D.IsFlangMode()) { |
155 | 0 | addFortranRuntimeLibraryPath(ToolChain, Args, CmdArgs); |
156 | 0 | addFortranRuntimeLibs(ToolChain, Args, CmdArgs); |
157 | 0 | CmdArgs.push_back("-lm"); |
158 | 0 | } |
159 | | |
160 | 11 | if (Args.hasArg(options::OPT_pthread)) |
161 | 0 | CmdArgs.push_back("-lpthread"); |
162 | | |
163 | 11 | if (!Args.hasArg(options::OPT_nolibc)) |
164 | 11 | CmdArgs.push_back("-lc"); |
165 | | |
166 | 11 | if (Static || Args.hasArg(options::OPT_static_libgcc)10 ) { |
167 | 1 | CmdArgs.push_back("-lgcc"); |
168 | 1 | CmdArgs.push_back("-lgcc_eh"); |
169 | 10 | } else { |
170 | 10 | if (Args.hasArg(options::OPT_shared_libgcc)) { |
171 | 0 | CmdArgs.push_back("-lgcc_pic"); |
172 | 0 | if (!Shared) |
173 | 0 | CmdArgs.push_back("-lgcc"); |
174 | 10 | } else { |
175 | 10 | CmdArgs.push_back("-lgcc"); |
176 | 10 | CmdArgs.push_back("--as-needed"); |
177 | 10 | CmdArgs.push_back("-lgcc_pic"); |
178 | 10 | CmdArgs.push_back("--no-as-needed"); |
179 | 10 | } |
180 | 10 | } |
181 | 11 | } |
182 | | |
183 | 15 | if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles, |
184 | 15 | options::OPT_r)) { |
185 | 11 | const char *crtend = nullptr; |
186 | 11 | if (Shared || Pie) |
187 | 0 | crtend ="crtendS.o"; |
188 | 11 | else |
189 | 11 | crtend = "crtend.o"; |
190 | | |
191 | 11 | CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend))); |
192 | 11 | CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o"))); |
193 | 11 | } |
194 | | |
195 | 15 | ToolChain.addProfileRTLibs(Args, CmdArgs); |
196 | | |
197 | 15 | const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath()); |
198 | 15 | C.addCommand(std::make_unique<Command>(JA, *this, |
199 | 15 | ResponseFileSupport::AtFileCurCP(), |
200 | 15 | Exec, CmdArgs, Inputs, Output)); |
201 | 15 | } |
202 | | |
203 | | /// DragonFly - DragonFly tool chain which can call as(1) and ld(1) directly. |
204 | | |
205 | | DragonFly::DragonFly(const Driver &D, const llvm::Triple &Triple, |
206 | | const ArgList &Args) |
207 | 19 | : Generic_ELF(D, Triple, Args) { |
208 | | |
209 | | // Path mangling to find libexec |
210 | 19 | getProgramPaths().push_back(getDriver().getInstalledDir()); |
211 | 19 | if (getDriver().getInstalledDir() != getDriver().Dir) |
212 | 0 | getProgramPaths().push_back(getDriver().Dir); |
213 | | |
214 | 19 | getFilePaths().push_back(getDriver().Dir + "/../lib"); |
215 | 19 | getFilePaths().push_back(concat(getDriver().SysRoot, "/usr/lib")); |
216 | 19 | getFilePaths().push_back(concat(getDriver().SysRoot, "/usr/lib/gcc80")); |
217 | 19 | } |
218 | | |
219 | | void DragonFly::AddClangSystemIncludeArgs( |
220 | | const llvm::opt::ArgList &DriverArgs, |
221 | 19 | llvm::opt::ArgStringList &CC1Args) const { |
222 | 19 | const Driver &D = getDriver(); |
223 | | |
224 | 19 | if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc)) |
225 | 0 | return; |
226 | | |
227 | 19 | if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) { |
228 | 19 | SmallString<128> Dir(D.ResourceDir); |
229 | 19 | llvm::sys::path::append(Dir, "include"); |
230 | 19 | addSystemInclude(DriverArgs, CC1Args, Dir.str()); |
231 | 19 | } |
232 | | |
233 | 19 | if (DriverArgs.hasArg(options::OPT_nostdlibinc)) |
234 | 0 | return; |
235 | | |
236 | 19 | addExternCSystemInclude(DriverArgs, CC1Args, |
237 | 19 | concat(D.SysRoot, "/usr/include")); |
238 | 19 | } |
239 | | |
240 | | void DragonFly::addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, |
241 | 0 | llvm::opt::ArgStringList &CC1Args) const { |
242 | 0 | addLibStdCXXIncludePaths(concat(getDriver().SysRoot, "/usr/include/c++/8.0"), "", "", |
243 | 0 | DriverArgs, CC1Args); |
244 | 0 | } |
245 | | |
246 | 0 | Tool *DragonFly::buildAssembler() const { |
247 | 0 | return new tools::dragonfly::Assembler(*this); |
248 | 0 | } |
249 | | |
250 | 15 | Tool *DragonFly::buildLinker() const { |
251 | 15 | return new tools::dragonfly::Linker(*this); |
252 | 15 | } |