Coverage Report

Created: 2020-09-22 08:39

/Users/buildslave/jenkins/workspace/coverage/llvm-project/clang/lib/Driver/ToolChains/OpenBSD.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- OpenBSD.cpp - OpenBSD 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 "OpenBSD.h"
10
#include "Arch/Mips.h"
11
#include "Arch/Sparc.h"
12
#include "CommonArgs.h"
13
#include "clang/Config/config.h"
14
#include "clang/Driver/Compilation.h"
15
#include "clang/Driver/Options.h"
16
#include "clang/Driver/SanitizerArgs.h"
17
#include "llvm/Option/ArgList.h"
18
#include "llvm/Support/Path.h"
19
20
using namespace clang::driver;
21
using namespace clang::driver::tools;
22
using namespace clang::driver::toolchains;
23
using namespace clang;
24
using namespace llvm::opt;
25
26
void openbsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
27
                                      const InputInfo &Output,
28
                                      const InputInfoList &Inputs,
29
                                      const ArgList &Args,
30
7
                                      const char *LinkingOutput) const {
31
7
  claimNoWarnArgs(Args);
32
7
  ArgStringList CmdArgs;
33
34
7
  switch (getToolChain().getArch()) {
35
1
  case llvm::Triple::x86:
36
    // When building 32-bit code on OpenBSD/amd64, we have to explicitly
37
    // instruct as in the base system to assemble 32-bit code.
38
1
    CmdArgs.push_back("--32");
39
1
    break;
40
41
1
  case llvm::Triple::ppc:
42
1
    CmdArgs.push_back("-mppc");
43
1
    CmdArgs.push_back("-many");
44
1
    break;
45
46
1
  case llvm::Triple::sparcv9: {
47
1
    CmdArgs.push_back("-64");
48
1
    std::string CPU = getCPUName(Args, getToolChain().getTriple());
49
1
    CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
50
1
    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
51
1
    break;
52
0
  }
53
54
4
  case llvm::Triple::mips64:
55
4
  case llvm::Triple::mips64el: {
56
4
    StringRef CPUName;
57
4
    StringRef ABIName;
58
4
    mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
59
60
4
    CmdArgs.push_back("-mabi");
61
4
    CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data());
62
63
4
    if (getToolChain().getTriple().isLittleEndian())
64
2
      CmdArgs.push_back("-EL");
65
2
    else
66
2
      CmdArgs.push_back("-EB");
67
68
4
    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
69
4
    break;
70
4
  }
71
72
0
  default:
73
0
    break;
74
7
  }
75
76
7
  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
77
78
7
  CmdArgs.push_back("-o");
79
7
  CmdArgs.push_back(Output.getFilename());
80
81
7
  for (const auto &II : Inputs)
82
7
    CmdArgs.push_back(II.getFilename());
83
84
7
  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
85
7
  C.addCommand(std::make_unique<Command>(
86
7
      JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
87
7
}
88
89
void openbsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
90
                                   const InputInfo &Output,
91
                                   const InputInfoList &Inputs,
92
                                   const ArgList &Args,
93
40
                                   const char *LinkingOutput) const {
94
40
  const toolchains::OpenBSD &ToolChain =
95
40
      static_cast<const toolchains::OpenBSD &>(getToolChain());
96
40
  const Driver &D = getToolChain().getDriver();
97
40
  ArgStringList CmdArgs;
98
99
  // Silence warning for "clang -g foo.o -o foo"
100
40
  Args.ClaimAllArgs(options::OPT_g_Group);
101
  // and "clang -emit-llvm foo.o -o foo"
102
40
  Args.ClaimAllArgs(options::OPT_emit_llvm);
103
  // and for "clang -w foo.o -o foo". Other warning options are already
104
  // handled somewhere else.
105
40
  Args.ClaimAllArgs(options::OPT_w);
106
107
40
  if (ToolChain.getArch() == llvm::Triple::mips64)
108
1
    CmdArgs.push_back("-EB");
109
39
  else if (ToolChain.getArch() == llvm::Triple::mips64el)
110
1
    CmdArgs.push_back("-EL");
111
112
40
  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
113
40
    CmdArgs.push_back("-e");
114
40
    CmdArgs.push_back("__start");
115
40
  }
116
117
40
  CmdArgs.push_back("--eh-frame-hdr");
118
40
  if (Args.hasArg(options::OPT_static)) {
119
5
    CmdArgs.push_back("-Bstatic");
120
35
  } else {
121
35
    if (Args.hasArg(options::OPT_rdynamic))
122
0
      CmdArgs.push_back("-export-dynamic");
123
35
    CmdArgs.push_back("-Bdynamic");
124
35
    if (Args.hasArg(options::OPT_shared)) {
125
0
      CmdArgs.push_back("-shared");
126
35
    } else {
127
35
      CmdArgs.push_back("-dynamic-linker");
128
35
      CmdArgs.push_back("/usr/libexec/ld.so");
129
35
    }
130
35
  }
131
132
40
  if (Args.hasArg(options::OPT_pie))
133
1
    CmdArgs.push_back("-pie");
134
40
  if (Args.hasArg(options::OPT_nopie) || 
Args.hasArg(options::OPT_pg)34
)
135
11
    CmdArgs.push_back("-nopie");
136
137
40
  if (Output.isFilename()) {
138
40
    CmdArgs.push_back("-o");
139
40
    CmdArgs.push_back(Output.getFilename());
140
0
  } else {
141
0
    assert(Output.isNothing() && "Invalid output.");
142
0
  }
143
144
40
  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
145
40
    const char *crt0 = nullptr;
146
40
    const char *crtbegin = nullptr;
147
40
    if (!Args.hasArg(options::OPT_shared)) {
148
40
      if (Args.hasArg(options::OPT_pg))
149
5
        crt0 = "gcrt0.o";
150
35
      else if (Args.hasArg(options::OPT_static) &&
151
5
               !Args.hasArg(options::OPT_nopie))
152
3
        crt0 = "rcrt0.o";
153
32
      else
154
32
        crt0 = "crt0.o";
155
40
      crtbegin = "crtbegin.o";
156
0
    } else {
157
0
      crtbegin = "crtbeginS.o";
158
0
    }
159
160
40
    if (crt0)
161
40
      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt0)));
162
40
    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
163
40
  }
164
165
40
  Args.AddAllArgs(CmdArgs, options::OPT_L);
166
40
  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
167
40
  Args.AddAllArgs(CmdArgs, {options::OPT_T_Group, options::OPT_e,
168
40
                            options::OPT_s, options::OPT_t,
169
40
                            options::OPT_Z_Flag, options::OPT_r});
170
171
40
  bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
172
40
  bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);
173
40
  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
174
175
40
  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
176
40
    if (D.CCCIsCXX()) {
177
8
      if (ToolChain.ShouldLinkCXXStdlib(Args))
178
8
        ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
179
8
      if (Args.hasArg(options::OPT_pg))
180
4
        CmdArgs.push_back("-lm_p");
181
4
      else
182
4
        CmdArgs.push_back("-lm");
183
8
    }
184
40
    if (NeedsSanitizerDeps) {
185
0
      CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins"));
186
0
      linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
187
0
    }
188
40
    if (NeedsXRayDeps) {
189
0
      CmdArgs.push_back(ToolChain.getCompilerRTArgString(Args, "builtins"));
190
0
      linkXRayRuntimeDeps(ToolChain, CmdArgs);
191
0
    }
192
    // FIXME: For some reason GCC passes -lgcc before adding
193
    // the default system libraries. Just mimic this for now.
194
40
    CmdArgs.push_back("-lcompiler_rt");
195
196
40
    if (Args.hasArg(options::OPT_pthread)) {
197
1
      if (!Args.hasArg(options::OPT_shared) && Args.hasArg(options::OPT_pg))
198
1
        CmdArgs.push_back("-lpthread_p");
199
0
      else
200
0
        CmdArgs.push_back("-lpthread");
201
1
    }
202
203
40
    if (!Args.hasArg(options::OPT_shared)) {
204
40
      if (Args.hasArg(options::OPT_pg))
205
5
        CmdArgs.push_back("-lc_p");
206
35
      else
207
35
        CmdArgs.push_back("-lc");
208
40
    }
209
210
40
    CmdArgs.push_back("-lcompiler_rt");
211
40
  }
212
213
40
  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
214
40
    const char *crtend = nullptr;
215
40
    if (!Args.hasArg(options::OPT_shared))
216
40
      crtend = "crtend.o";
217
0
    else
218
0
      crtend = "crtendS.o";
219
220
40
    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtend)));
221
40
  }
222
223
40
  const char *Exec = Args.MakeArgString(ToolChain.GetLinkerPath());
224
40
  C.addCommand(std::make_unique<Command>(
225
40
      JA, *this, ResponseFileSupport::AtFileCurCP(), Exec, CmdArgs, Inputs));
226
40
}
227
228
87
SanitizerMask OpenBSD::getSupportedSanitizers() const {
229
87
  const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
230
87
  const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
231
232
  // For future use, only UBsan at the moment
233
87
  SanitizerMask Res = ToolChain::getSupportedSanitizers();
234
235
87
  if (IsX86 || 
IsX86_6448
) {
236
44
    Res |= SanitizerKind::Vptr;
237
44
    Res |= SanitizerKind::Fuzzer;
238
44
    Res |= SanitizerKind::FuzzerNoLink;
239
44
  }
240
241
87
  return Res;
242
87
}
243
244
/// OpenBSD - OpenBSD tool chain which can call as(1) and ld(1) directly.
245
246
OpenBSD::OpenBSD(const Driver &D, const llvm::Triple &Triple,
247
                 const ArgList &Args)
248
87
    : Generic_ELF(D, Triple, Args) {
249
87
  getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
250
87
}
251
252
void OpenBSD::AddClangSystemIncludeArgs(
253
    const llvm::opt::ArgList &DriverArgs,
254
87
    llvm::opt::ArgStringList &CC1Args) const {
255
87
  const Driver &D = getDriver();
256
257
87
  if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
258
0
    return;
259
260
87
  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
261
87
    SmallString<128> Dir(D.ResourceDir);
262
87
    llvm::sys::path::append(Dir, "include");
263
87
    addSystemInclude(DriverArgs, CC1Args, Dir.str());
264
87
  }
265
266
87
  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
267
0
    return;
268
269
  // Check for configure-time C include directories.
270
87
  StringRef CIncludeDirs(C_INCLUDE_DIRS);
271
87
  if (CIncludeDirs != "") {
272
0
    SmallVector<StringRef, 5> dirs;
273
0
    CIncludeDirs.split(dirs, ":");
274
0
    for (StringRef dir : dirs) {
275
0
      StringRef Prefix =
276
0
          llvm::sys::path::is_absolute(dir) ? StringRef(D.SysRoot) : "";
277
0
      addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
278
0
    }
279
0
    return;
280
0
  }
281
282
87
  addExternCSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/include");
283
87
}
284
285
void OpenBSD::addLibCxxIncludePaths(const llvm::opt::ArgList &DriverArgs,
286
11
                                    llvm::opt::ArgStringList &CC1Args) const {
287
11
  addSystemInclude(DriverArgs, CC1Args,
288
11
                   getDriver().SysRoot + "/usr/include/c++/v1");
289
11
}
290
291
void OpenBSD::AddCXXStdlibLibArgs(const ArgList &Args,
292
8
                                  ArgStringList &CmdArgs) const {
293
8
  bool Profiling = Args.hasArg(options::OPT_pg);
294
295
4
  CmdArgs.push_back(Profiling ? "-lc++_p" : "-lc++");
296
4
  CmdArgs.push_back(Profiling ? "-lc++abi_p" : "-lc++abi");
297
8
}
298
299
std::string OpenBSD::getCompilerRT(const ArgList &Args,
300
                                   StringRef Component,
301
0
                                   FileType Type) const {
302
0
  SmallString<128> Path(getDriver().SysRoot);
303
0
  llvm::sys::path::append(Path, "/usr/lib/libcompiler_rt.a");
304
0
  return std::string(Path.str());
305
0
}
306
307
7
Tool *OpenBSD::buildAssembler() const {
308
7
  return new tools::openbsd::Assembler(*this);
309
7
}
310
311
40
Tool *OpenBSD::buildLinker() const { return new tools::openbsd::Linker(*this); }
312
313
41
bool OpenBSD::HasNativeLLVMSupport() const { return true; }