Coverage Report

Created: 2023-09-30 09:22

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