Coverage Report

Created: 2019-07-24 05:18

/Users/buildslave/jenkins/workspace/clang-stage2-coverage-R/llvm/tools/clang/lib/Driver/ToolChains/FreeBSD.cpp
Line
Count
Source (jump to first uncovered line)
1
//===--- FreeBSD.cpp - FreeBSD 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 "FreeBSD.h"
10
#include "Arch/ARM.h"
11
#include "Arch/Mips.h"
12
#include "Arch/Sparc.h"
13
#include "CommonArgs.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/VirtualFileSystem.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 freebsd::Assembler::ConstructJob(Compilation &C, const JobAction &JA,
27
                                      const InputInfo &Output,
28
                                      const InputInfoList &Inputs,
29
                                      const ArgList &Args,
30
23
                                      const char *LinkingOutput) const {
31
23
  claimNoWarnArgs(Args);
32
23
  ArgStringList CmdArgs;
33
23
34
23
  // When building 32-bit code on FreeBSD/amd64, we have to explicitly
35
23
  // instruct as in the base system to assemble 32-bit code.
36
23
  switch (getToolChain().getArch()) {
37
23
  default:
38
1
    break;
39
23
  case llvm::Triple::x86:
40
0
    CmdArgs.push_back("--32");
41
0
    break;
42
23
  case llvm::Triple::ppc:
43
0
    CmdArgs.push_back("-a32");
44
0
    break;
45
23
  case llvm::Triple::mips:
46
17
  case llvm::Triple::mipsel:
47
17
  case llvm::Triple::mips64:
48
17
  case llvm::Triple::mips64el: {
49
17
    StringRef CPUName;
50
17
    StringRef ABIName;
51
17
    mips::getMipsCPUAndABI(Args, getToolChain().getTriple(), CPUName, ABIName);
52
17
53
17
    CmdArgs.push_back("-march");
54
17
    CmdArgs.push_back(CPUName.data());
55
17
56
17
    CmdArgs.push_back("-mabi");
57
17
    CmdArgs.push_back(mips::getGnuCompatibleMipsABIName(ABIName).data());
58
17
59
17
    if (getToolChain().getTriple().isLittleEndian())
60
4
      CmdArgs.push_back("-EL");
61
13
    else
62
13
      CmdArgs.push_back("-EB");
63
17
64
17
    if (Arg *A = Args.getLastArg(options::OPT_G)) {
65
1
      StringRef v = A->getValue();
66
1
      CmdArgs.push_back(Args.MakeArgString("-G" + v));
67
1
      A->claim();
68
1
    }
69
17
70
17
    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
71
17
    break;
72
17
  }
73
17
  case llvm::Triple::arm:
74
3
  case llvm::Triple::armeb:
75
3
  case llvm::Triple::thumb:
76
3
  case llvm::Triple::thumbeb: {
77
3
    arm::FloatABI ABI = arm::getARMFloatABI(getToolChain(), Args);
78
3
79
3
    if (ABI == arm::FloatABI::Hard)
80
1
      CmdArgs.push_back("-mfpu=vfp");
81
2
    else
82
2
      CmdArgs.push_back("-mfpu=softvfp");
83
3
84
3
    switch (getToolChain().getTriple().getEnvironment()) {
85
3
    case llvm::Triple::GNUEABIHF:
86
2
    case llvm::Triple::GNUEABI:
87
2
    case llvm::Triple::EABI:
88
2
      CmdArgs.push_back("-meabi=5");
89
2
      break;
90
2
91
2
    default:
92
1
      CmdArgs.push_back("-matpcs");
93
3
    }
94
3
    break;
95
3
  }
96
3
  case llvm::Triple::sparc:
97
2
  case llvm::Triple::sparcel:
98
2
  case llvm::Triple::sparcv9: {
99
2
    std::string CPU = getCPUName(Args, getToolChain().getTriple());
100
2
    CmdArgs.push_back(sparc::getSparcAsmModeForCPU(CPU, getToolChain().getTriple()));
101
2
    AddAssemblerKPIC(getToolChain(), Args, CmdArgs);
102
2
    break;
103
23
  }
104
23
  }
105
23
106
23
  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
107
23
108
23
  CmdArgs.push_back("-o");
109
23
  CmdArgs.push_back(Output.getFilename());
110
23
111
23
  for (const auto &II : Inputs)
112
23
    CmdArgs.push_back(II.getFilename());
113
23
114
23
  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
115
23
  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
116
23
}
117
118
void freebsd::Linker::ConstructJob(Compilation &C, const JobAction &JA,
119
                                   const InputInfo &Output,
120
                                   const InputInfoList &Inputs,
121
                                   const ArgList &Args,
122
53
                                   const char *LinkingOutput) const {
123
53
  const toolchains::FreeBSD &ToolChain =
124
53
      static_cast<const toolchains::FreeBSD &>(getToolChain());
125
53
  const Driver &D = ToolChain.getDriver();
126
53
  const llvm::Triple::ArchType Arch = ToolChain.getArch();
127
53
  const bool IsPIE =
128
53
      !Args.hasArg(options::OPT_shared) &&
129
53
      
(51
Args.hasArg(options::OPT_pie)51
||
ToolChain.isPIEDefault()49
);
130
53
  ArgStringList CmdArgs;
131
53
132
53
  // Silence warning for "clang -g foo.o -o foo"
133
53
  Args.ClaimAllArgs(options::OPT_g_Group);
134
53
  // and "clang -emit-llvm foo.o -o foo"
135
53
  Args.ClaimAllArgs(options::OPT_emit_llvm);
136
53
  // and for "clang -w foo.o -o foo". Other warning options are already
137
53
  // handled somewhere else.
138
53
  Args.ClaimAllArgs(options::OPT_w);
139
53
140
53
  if (!D.SysRoot.empty())
141
20
    CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot));
142
53
143
53
  if (IsPIE)
144
3
    CmdArgs.push_back("-pie");
145
53
146
53
  CmdArgs.push_back("--eh-frame-hdr");
147
53
  if (Args.hasArg(options::OPT_static)) {
148
1
    CmdArgs.push_back("-Bstatic");
149
52
  } else {
150
52
    if (Args.hasArg(options::OPT_rdynamic))
151
0
      CmdArgs.push_back("-export-dynamic");
152
52
    if (Args.hasArg(options::OPT_shared)) {
153
2
      CmdArgs.push_back("-Bshareable");
154
50
    } else {
155
50
      CmdArgs.push_back("-dynamic-linker");
156
50
      CmdArgs.push_back("/libexec/ld-elf.so.1");
157
50
    }
158
52
    if (ToolChain.getTriple().getOSMajorVersion() >= 9) {
159
14
      if (Arch == llvm::Triple::arm || 
Arch == llvm::Triple::sparc11
||
160
14
          
Arch == llvm::Triple::x8611
||
Arch == llvm::Triple::x86_649
) {
161
9
        CmdArgs.push_back("--hash-style=both");
162
9
      }
163
14
    }
164
52
    CmdArgs.push_back("--enable-new-dtags");
165
52
  }
166
53
167
53
  // Explicitly set the linker emulation for platforms that might not
168
53
  // be the default emulation for the linker.
169
53
  switch (Arch) {
170
53
  case llvm::Triple::x86:
171
7
    CmdArgs.push_back("-m");
172
7
    CmdArgs.push_back("elf_i386_fbsd");
173
7
    break;
174
53
  case llvm::Triple::ppc:
175
1
    CmdArgs.push_back("-m");
176
1
    CmdArgs.push_back("elf32ppc_fbsd");
177
1
    break;
178
53
  case llvm::Triple::mips:
179
4
    CmdArgs.push_back("-m");
180
4
    CmdArgs.push_back("elf32btsmip_fbsd");
181
4
    break;
182
53
  case llvm::Triple::mipsel:
183
2
    CmdArgs.push_back("-m");
184
2
    CmdArgs.push_back("elf32ltsmip_fbsd");
185
2
    break;
186
53
  case llvm::Triple::mips64:
187
4
    CmdArgs.push_back("-m");
188
4
    if (tools::mips::hasMipsAbiArg(Args, "n32"))
189
1
      CmdArgs.push_back("elf32btsmipn32_fbsd");
190
3
    else
191
3
      CmdArgs.push_back("elf64btsmip_fbsd");
192
4
    break;
193
53
  case llvm::Triple::mips64el:
194
3
    CmdArgs.push_back("-m");
195
3
    if (tools::mips::hasMipsAbiArg(Args, "n32"))
196
1
      CmdArgs.push_back("elf32ltsmipn32_fbsd");
197
2
    else
198
2
      CmdArgs.push_back("elf64ltsmip_fbsd");
199
3
    break;
200
53
  default:
201
32
    break;
202
53
  }
203
53
204
53
  if (Arg *A = Args.getLastArg(options::OPT_G)) {
205
1
    if (ToolChain.getTriple().isMIPS()) {
206
1
      StringRef v = A->getValue();
207
1
      CmdArgs.push_back(Args.MakeArgString("-G" + v));
208
1
      A->claim();
209
1
    }
210
1
  }
211
53
212
53
  if (Output.isFilename()) {
213
53
    CmdArgs.push_back("-o");
214
53
    CmdArgs.push_back(Output.getFilename());
215
53
  } else {
216
0
    assert(Output.isNothing() && "Invalid output.");
217
0
  }
218
53
219
53
  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
220
50
    const char *crt1 = nullptr;
221
50
    if (!Args.hasArg(options::OPT_shared)) {
222
48
      if (Args.hasArg(options::OPT_pg))
223
2
        crt1 = "gcrt1.o";
224
46
      else if (IsPIE)
225
3
        crt1 = "Scrt1.o";
226
43
      else
227
43
        crt1 = "crt1.o";
228
48
    }
229
50
    if (crt1)
230
48
      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crt1)));
231
50
232
50
    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crti.o")));
233
50
234
50
    const char *crtbegin = nullptr;
235
50
    if (Args.hasArg(options::OPT_static))
236
1
      crtbegin = "crtbeginT.o";
237
49
    else if (Args.hasArg(options::OPT_shared) || 
IsPIE47
)
238
5
      crtbegin = "crtbeginS.o";
239
44
    else
240
44
      crtbegin = "crtbegin.o";
241
50
242
50
    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath(crtbegin)));
243
50
  }
244
53
245
53
  Args.AddAllArgs(CmdArgs, options::OPT_L);
246
53
  ToolChain.AddFilePathLibArgs(Args, CmdArgs);
247
53
  Args.AddAllArgs(CmdArgs, options::OPT_T_Group);
248
53
  Args.AddAllArgs(CmdArgs, options::OPT_e);
249
53
  Args.AddAllArgs(CmdArgs, options::OPT_s);
250
53
  Args.AddAllArgs(CmdArgs, options::OPT_t);
251
53
  Args.AddAllArgs(CmdArgs, options::OPT_Z_Flag);
252
53
  Args.AddAllArgs(CmdArgs, options::OPT_r);
253
53
254
53
  if (D.isUsingLTO()) {
255
1
    assert(!Inputs.empty() && "Must have at least one input.");
256
1
    AddGoldPlugin(ToolChain, Args, CmdArgs, Output, Inputs[0],
257
1
                  D.getLTOMode() == LTOK_Thin);
258
1
  }
259
53
260
53
  bool NeedsSanitizerDeps = addSanitizerRuntimes(ToolChain, Args, CmdArgs);
261
53
  bool NeedsXRayDeps = addXRayRuntime(ToolChain, Args, CmdArgs);
262
53
  AddLinkerInputs(ToolChain, Inputs, Args, CmdArgs, JA);
263
53
264
53
  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
265
50
    addOpenMPRuntime(CmdArgs, ToolChain, Args);
266
50
    if (D.CCCIsCXX()) {
267
4
      if (ToolChain.ShouldLinkCXXStdlib(Args))
268
4
        ToolChain.AddCXXStdlibLibArgs(Args, CmdArgs);
269
4
      if (Args.hasArg(options::OPT_pg))
270
2
        CmdArgs.push_back("-lm_p");
271
2
      else
272
2
        CmdArgs.push_back("-lm");
273
4
    }
274
50
    if (NeedsSanitizerDeps)
275
4
      linkSanitizerRuntimeDeps(ToolChain, CmdArgs);
276
50
    if (NeedsXRayDeps)
277
0
      linkXRayRuntimeDeps(ToolChain, CmdArgs);
278
50
    // FIXME: For some reason GCC passes -lgcc and -lgcc_s before adding
279
50
    // the default system libraries. Just mimic this for now.
280
50
    if (Args.hasArg(options::OPT_pg))
281
2
      CmdArgs.push_back("-lgcc_p");
282
48
    else
283
48
      CmdArgs.push_back("-lgcc");
284
50
    if (Args.hasArg(options::OPT_static)) {
285
1
      CmdArgs.push_back("-lgcc_eh");
286
49
    } else if (Args.hasArg(options::OPT_pg)) {
287
2
      CmdArgs.push_back("-lgcc_eh_p");
288
47
    } else {
289
47
      CmdArgs.push_back("--as-needed");
290
47
      CmdArgs.push_back("-lgcc_s");
291
47
      CmdArgs.push_back("--no-as-needed");
292
47
    }
293
50
294
50
    if (Args.hasArg(options::OPT_pthread)) {
295
0
      if (Args.hasArg(options::OPT_pg))
296
0
        CmdArgs.push_back("-lpthread_p");
297
0
      else
298
0
        CmdArgs.push_back("-lpthread");
299
0
    }
300
50
301
50
    if (Args.hasArg(options::OPT_pg)) {
302
2
      if (Args.hasArg(options::OPT_shared))
303
0
        CmdArgs.push_back("-lc");
304
2
      else
305
2
        CmdArgs.push_back("-lc_p");
306
2
      CmdArgs.push_back("-lgcc_p");
307
48
    } else {
308
48
      CmdArgs.push_back("-lc");
309
48
      CmdArgs.push_back("-lgcc");
310
48
    }
311
50
312
50
    if (Args.hasArg(options::OPT_static)) {
313
1
      CmdArgs.push_back("-lgcc_eh");
314
49
    } else if (Args.hasArg(options::OPT_pg)) {
315
2
      CmdArgs.push_back("-lgcc_eh_p");
316
47
    } else {
317
47
      CmdArgs.push_back("--as-needed");
318
47
      CmdArgs.push_back("-lgcc_s");
319
47
      CmdArgs.push_back("--no-as-needed");
320
47
    }
321
50
  }
322
53
323
53
  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
324
50
    if (Args.hasArg(options::OPT_shared) || 
IsPIE48
)
325
5
      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtendS.o")));
326
45
    else
327
45
      CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtend.o")));
328
50
    CmdArgs.push_back(Args.MakeArgString(ToolChain.GetFilePath("crtn.o")));
329
50
  }
330
53
331
53
  ToolChain.addProfileRTLibs(Args, CmdArgs);
332
53
333
53
  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
334
53
  C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs));
335
53
}
336
337
/// FreeBSD - FreeBSD tool chain which can call as(1) and ld(1) directly.
338
339
FreeBSD::FreeBSD(const Driver &D, const llvm::Triple &Triple,
340
                 const ArgList &Args)
341
103
    : Generic_ELF(D, Triple, Args) {
342
103
343
103
  // When targeting 32-bit platforms, look for '/usr/lib32/crt1.o' and fall
344
103
  // back to '/usr/lib' if it doesn't exist.
345
103
  if ((Triple.getArch() == llvm::Triple::x86 || 
Triple.isMIPS32()90
||
346
103
       
Triple.getArch() == llvm::Triple::ppc70
) &&
347
103
      
D.getVFS().exists(getDriver().SysRoot + "/usr/lib32/crt1.o")35
)
348
6
    getFilePaths().push_back(getDriver().SysRoot + "/usr/lib32");
349
97
  else
350
97
    getFilePaths().push_back(getDriver().SysRoot + "/usr/lib");
351
103
}
352
353
8
ToolChain::CXXStdlibType FreeBSD::GetDefaultCXXStdlibType() const {
354
8
  if (getTriple().getOSMajorVersion() >= 10)
355
4
    return ToolChain::CST_Libcxx;
356
4
  return ToolChain::CST_Libstdcxx;
357
4
}
358
359
void FreeBSD::addLibStdCxxIncludePaths(
360
    const llvm::opt::ArgList &DriverArgs,
361
2
    llvm::opt::ArgStringList &CC1Args) const {
362
2
  addLibStdCXXIncludePaths(getDriver().SysRoot, "/usr/include/c++/4.2", "", "",
363
2
                           "", "", DriverArgs, CC1Args);
364
2
}
365
366
void FreeBSD::AddCXXStdlibLibArgs(const ArgList &Args,
367
4
                                  ArgStringList &CmdArgs) const {
368
4
  CXXStdlibType Type = GetCXXStdlibType(Args);
369
4
  bool Profiling = Args.hasArg(options::OPT_pg);
370
4
371
4
  switch (Type) {
372
4
  case ToolChain::CST_Libcxx:
373
2
    CmdArgs.push_back(Profiling ? 
"-lc++_p"1
:
"-lc++"1
);
374
2
    break;
375
4
376
4
  case ToolChain::CST_Libstdcxx:
377
2
    CmdArgs.push_back(Profiling ? 
"-lstdc++_p"1
:
"-lstdc++"1
);
378
2
    break;
379
4
  }
380
4
}
381
382
23
Tool *FreeBSD::buildAssembler() const {
383
23
  return new tools::freebsd::Assembler(*this);
384
23
}
385
386
53
Tool *FreeBSD::buildLinker() const { return new tools::freebsd::Linker(*this); }
387
388
108
llvm::ExceptionHandling FreeBSD::GetExceptionModel(const ArgList &Args) const {
389
108
  // FreeBSD uses SjLj exceptions on ARM oabi.
390
108
  switch (getTriple().getEnvironment()) {
391
108
  case llvm::Triple::GNUEABIHF:
392
6
  case llvm::Triple::GNUEABI:
393
6
  case llvm::Triple::EABI:
394
6
    return llvm::ExceptionHandling::None;
395
102
  default:
396
102
    if (getTriple().getArch() == llvm::Triple::arm ||
397
102
        
getTriple().getArch() == llvm::Triple::thumb100
)
398
2
      return llvm::ExceptionHandling::SjLj;
399
100
    return llvm::ExceptionHandling::None;
400
108
  }
401
108
}
402
403
59
bool FreeBSD::HasNativeLLVMSupport() const { return true; }
404
405
218
bool FreeBSD::isPIEDefault() const { return getSanitizerArgs().requiresPIE(); }
406
407
101
SanitizerMask FreeBSD::getSupportedSanitizers() const {
408
101
  const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
409
101
  const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
410
101
  const bool IsMIPS64 = getTriple().isMIPS64();
411
101
  SanitizerMask Res = ToolChain::getSupportedSanitizers();
412
101
  Res |= SanitizerKind::Address;
413
101
  Res |= SanitizerKind::PointerCompare;
414
101
  Res |= SanitizerKind::PointerSubtract;
415
101
  Res |= SanitizerKind::Vptr;
416
101
  if (IsX86_64 || 
IsMIPS6464
) {
417
52
    Res |= SanitizerKind::Leak;
418
52
    Res |= SanitizerKind::Thread;
419
52
  }
420
101
  if (IsX86 || 
IsX86_6489
) {
421
49
    Res |= SanitizerKind::Function;
422
49
    Res |= SanitizerKind::SafeStack;
423
49
    Res |= SanitizerKind::Fuzzer;
424
49
    Res |= SanitizerKind::FuzzerNoLink;
425
49
  }
426
101
  if (IsX86_64)
427
37
    Res |= SanitizerKind::Memory;
428
101
  return Res;
429
101
}