clang  14.0.0git
Solaris.cpp
Go to the documentation of this file.
1 //===--- Solaris.cpp - Solaris 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 "Solaris.h"
10 #include "CommonArgs.h"
12 #include "clang/Config/config.h"
14 #include "clang/Driver/Driver.h"
16 #include "clang/Driver/Options.h"
17 #include "llvm/Option/ArgList.h"
18 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/Path.h"
20 
21 using namespace clang::driver;
22 using namespace clang::driver::tools;
23 using namespace clang::driver::toolchains;
24 using namespace clang;
25 using namespace llvm::opt;
26 
28  const InputInfo &Output,
29  const InputInfoList &Inputs,
30  const ArgList &Args,
31  const char *LinkingOutput) const {
32  claimNoWarnArgs(Args);
33  ArgStringList CmdArgs;
34 
35  Args.AddAllArgValues(CmdArgs, options::OPT_Wa_COMMA, options::OPT_Xassembler);
36 
37  CmdArgs.push_back("-o");
38  CmdArgs.push_back(Output.getFilename());
39 
40  for (const auto &II : Inputs)
41  CmdArgs.push_back(II.getFilename());
42 
43  const char *Exec = Args.MakeArgString(getToolChain().GetProgramPath("as"));
44  C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
45  Exec, CmdArgs, Inputs, Output));
46 }
47 
49  const InputInfo &Output,
50  const InputInfoList &Inputs,
51  const ArgList &Args,
52  const char *LinkingOutput) const {
53  ArgStringList CmdArgs;
54 
55  // Demangle C++ names in errors
56  CmdArgs.push_back("-C");
57 
58  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_shared)) {
59  CmdArgs.push_back("-e");
60  CmdArgs.push_back("_start");
61  }
62 
63  if (Args.hasArg(options::OPT_static)) {
64  CmdArgs.push_back("-Bstatic");
65  CmdArgs.push_back("-dn");
66  } else {
67  CmdArgs.push_back("-Bdynamic");
68  if (Args.hasArg(options::OPT_shared)) {
69  CmdArgs.push_back("-shared");
70  }
71 
72  // libpthread has been folded into libc since Solaris 10, no need to do
73  // anything for pthreads. Claim argument to avoid warning.
74  Args.ClaimAllArgs(options::OPT_pthread);
75  Args.ClaimAllArgs(options::OPT_pthreads);
76  }
77 
78  if (Output.isFilename()) {
79  CmdArgs.push_back("-o");
80  CmdArgs.push_back(Output.getFilename());
81  } else {
82  assert(Output.isNothing() && "Invalid output.");
83  }
84 
85  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
86  if (!Args.hasArg(options::OPT_shared))
87  CmdArgs.push_back(
88  Args.MakeArgString(getToolChain().GetFilePath("crt1.o")));
89 
90  CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crti.o")));
91 
92  const Arg *Std = Args.getLastArg(options::OPT_std_EQ, options::OPT_ansi);
93  bool HaveAnsi = false;
94  const LangStandard *LangStd = nullptr;
95  if (Std) {
96  HaveAnsi = Std->getOption().matches(options::OPT_ansi);
97  if (!HaveAnsi)
98  LangStd = LangStandard::getLangStandardForName(Std->getValue());
99  }
100 
101  const char *values_X = "values-Xa.o";
102  // Use values-Xc.o for -ansi, -std=c*, -std=iso9899:199409.
103  if (HaveAnsi || (LangStd && !LangStd->isGNUMode()))
104  values_X = "values-Xc.o";
105  CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath(values_X)));
106 
107  const char *values_xpg = "values-xpg6.o";
108  // Use values-xpg4.o for -std=c90, -std=gnu90, -std=iso9899:199409.
109  if (LangStd && LangStd->getLanguage() == Language::C && !LangStd->isC99())
110  values_xpg = "values-xpg4.o";
111  CmdArgs.push_back(
112  Args.MakeArgString(getToolChain().GetFilePath(values_xpg)));
113  CmdArgs.push_back(
114  Args.MakeArgString(getToolChain().GetFilePath("crtbegin.o")));
115  }
116 
117  getToolChain().AddFilePathLibArgs(Args, CmdArgs);
118 
119  Args.AddAllArgs(CmdArgs, {options::OPT_L, options::OPT_T_Group,
120  options::OPT_e, options::OPT_r});
121 
122  bool NeedsSanitizerDeps = addSanitizerRuntimes(getToolChain(), Args, CmdArgs);
123  AddLinkerInputs(getToolChain(), Inputs, Args, CmdArgs, JA);
124 
125  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nodefaultlibs)) {
126  if (getToolChain().ShouldLinkCXXStdlib(Args))
127  getToolChain().AddCXXStdlibLibArgs(Args, CmdArgs);
128  if (Args.hasArg(options::OPT_fstack_protector) ||
129  Args.hasArg(options::OPT_fstack_protector_strong) ||
130  Args.hasArg(options::OPT_fstack_protector_all)) {
131  // Explicitly link ssp libraries, not folded into Solaris libc.
132  CmdArgs.push_back("-lssp_nonshared");
133  CmdArgs.push_back("-lssp");
134  }
135  CmdArgs.push_back("-lgcc_s");
136  CmdArgs.push_back("-lc");
137  if (!Args.hasArg(options::OPT_shared)) {
138  CmdArgs.push_back("-lgcc");
139  CmdArgs.push_back("-lm");
140  }
141  if (NeedsSanitizerDeps)
142  linkSanitizerRuntimeDeps(getToolChain(), CmdArgs);
143  }
144 
145  if (!Args.hasArg(options::OPT_nostdlib, options::OPT_nostartfiles)) {
146  CmdArgs.push_back(
147  Args.MakeArgString(getToolChain().GetFilePath("crtend.o")));
148  }
149  CmdArgs.push_back(Args.MakeArgString(getToolChain().GetFilePath("crtn.o")));
150 
151  getToolChain().addProfileRTLibs(Args, CmdArgs);
152 
153  const char *Exec = Args.MakeArgString(getToolChain().GetLinkerPath());
154  C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
155  Exec, CmdArgs, Inputs, Output));
156 }
157 
158 static StringRef getSolarisLibSuffix(const llvm::Triple &Triple) {
159  switch (Triple.getArch()) {
160  case llvm::Triple::x86:
161  case llvm::Triple::sparc:
162  break;
163  case llvm::Triple::x86_64:
164  return "/amd64";
165  case llvm::Triple::sparcv9:
166  return "/sparcv9";
167  default:
168  llvm_unreachable("Unsupported architecture");
169  }
170  return "";
171 }
172 
173 /// Solaris - Solaris tool chain which can call as(1) and ld(1) directly.
174 
175 Solaris::Solaris(const Driver &D, const llvm::Triple &Triple,
176  const ArgList &Args)
177  : Generic_ELF(D, Triple, Args) {
178 
179  GCCInstallation.init(Triple, Args);
180 
181  StringRef LibSuffix = getSolarisLibSuffix(Triple);
182  path_list &Paths = getFilePaths();
183  if (GCCInstallation.isValid()) {
184  // On Solaris gcc uses both an architecture-specific path with triple in it
185  // as well as a more generic lib path (+arch suffix).
186  addPathIfExists(D,
189  Paths);
190  addPathIfExists(D, GCCInstallation.getParentLibPath() + LibSuffix, Paths);
191  }
192 
193  // If we are currently running Clang inside of the requested system root,
194  // add its parent library path to those searched.
195  if (StringRef(D.Dir).startswith(D.SysRoot))
196  addPathIfExists(D, D.Dir + "/../lib", Paths);
197 
198  addPathIfExists(D, D.SysRoot + "/usr/lib" + LibSuffix, Paths);
199 }
200 
202  const bool IsX86 = getTriple().getArch() == llvm::Triple::x86;
203  const bool IsX86_64 = getTriple().getArch() == llvm::Triple::x86_64;
205  // FIXME: Omit X86_64 until 64-bit support is figured out.
206  if (IsX86) {
207  Res |= SanitizerKind::Address;
208  Res |= SanitizerKind::PointerCompare;
209  Res |= SanitizerKind::PointerSubtract;
210  }
211  if (IsX86 || IsX86_64)
212  Res |= SanitizerKind::Function;
213  Res |= SanitizerKind::Vptr;
214  return Res;
215 }
216 
218  return new tools::solaris::Assembler(*this);
219 }
220 
221 Tool *Solaris::buildLinker() const { return new tools::solaris::Linker(*this); }
222 
223 void Solaris::AddClangSystemIncludeArgs(const ArgList &DriverArgs,
224  ArgStringList &CC1Args) const {
225  const Driver &D = getDriver();
226 
227  if (DriverArgs.hasArg(clang::driver::options::OPT_nostdinc))
228  return;
229 
230  if (!DriverArgs.hasArg(options::OPT_nostdlibinc))
231  addSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/local/include");
232 
233  if (!DriverArgs.hasArg(options::OPT_nobuiltininc)) {
235  llvm::sys::path::append(P, "include");
236  addSystemInclude(DriverArgs, CC1Args, P);
237  }
238 
239  if (DriverArgs.hasArg(options::OPT_nostdlibinc))
240  return;
241 
242  // Check for configure-time C include directories.
243  StringRef CIncludeDirs(C_INCLUDE_DIRS);
244  if (CIncludeDirs != "") {
246  CIncludeDirs.split(dirs, ":");
247  for (StringRef dir : dirs) {
248  StringRef Prefix =
249  llvm::sys::path::is_absolute(dir) ? "" : StringRef(D.SysRoot);
250  addExternCSystemInclude(DriverArgs, CC1Args, Prefix + dir);
251  }
252  return;
253  }
254 
255  // Add include directories specific to the selected multilib set and multilib.
256  if (GCCInstallation.isValid()) {
257  const MultilibSet::IncludeDirsFunc &Callback =
259  if (Callback) {
260  for (const auto &Path : Callback(GCCInstallation.getMultilib()))
262  DriverArgs, CC1Args, GCCInstallation.getInstallPath() + Path);
263  }
264  }
265 
266  addExternCSystemInclude(DriverArgs, CC1Args, D.SysRoot + "/usr/include");
267 }
268 
270  const llvm::opt::ArgList &DriverArgs,
271  llvm::opt::ArgStringList &CC1Args) const {
272  // We need a detected GCC installation on Solaris (similar to Linux)
273  // to provide libstdc++'s headers.
274  if (!GCCInstallation.isValid())
275  return;
276 
277  // By default, look for the C++ headers in an include directory adjacent to
278  // the lib directory of the GCC installation.
279  // On Solaris this usually looks like /usr/gcc/X.Y/include/c++/X.Y.Z
280  StringRef LibDir = GCCInstallation.getParentLibPath();
281  StringRef TripleStr = GCCInstallation.getTriple().str();
283  const GCCVersion &Version = GCCInstallation.getVersion();
284 
285  // The primary search for libstdc++ supports multiarch variants.
286  addLibStdCXXIncludePaths(LibDir.str() + "/../include/c++/" + Version.Text,
287  TripleStr, Multilib.includeSuffix(), DriverArgs,
288  CC1Args);
289 }
clang::driver::toolchains::Solaris::buildLinker
Tool * buildLinker() const override
Definition: Solaris.cpp:221
clang::driver::toolchains
Definition: AIX.h:55
clang::LangStandard::isC99
bool isC99() const
isC99 - Language is a superset of C99.
Definition: LangStandard.h:90
Driver.h
clang::driver::Driver::Dir
std::string Dir
The path the driver executable was in, as invoked from the command line.
Definition: Driver.h:123
llvm::SmallVector
Definition: LLVM.h:38
clang::driver::toolchains::Generic_GCC::GCCInstallation
GCCInstallationDetector GCCInstallation
Definition: Gnu.h:288
clang::driver::tools
Definition: AIX.h:17
clang::driver::tools::solaris::Assembler::ConstructJob
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition: Solaris.cpp:27
clang::driver::ToolChain::getDriver
const Driver & getDriver() const
Definition: ToolChain.h:221
clang::driver::toolchains::Generic_GCC::GCCInstallationDetector::isValid
bool isValid() const
Check whether we detected a valid GCC install.
Definition: Gnu.h:224
clang::driver::toolchains::Solaris::getSupportedSanitizers
SanitizerMask getSupportedSanitizers() const override
Return sanitizers which are available in this toolchain.
Definition: Solaris.cpp:201
clang::driver::MultilibSet::IncludeDirsFunc
std::function< std::vector< std::string >(const Multilib &M)> IncludeDirsFunc
Definition: Multilib.h:120
clang::driver::toolchains::Generic_GCC::GCCInstallationDetector::init
void init(const llvm::Triple &TargetTriple, const llvm::opt::ArgList &Args, ArrayRef< std::string > ExtraTripleAliases=None)
Initialize a GCCInstallationDetector from the driver.
Definition: Gnu.cpp:1891
clang::driver::InputInfo
InputInfo - Wrapper for information about an input source.
Definition: InputInfo.h:22
clang::driver::ToolChain::addExternCSystemIncludeIfExists
static void addExternCSystemIncludeIfExists(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const Twine &Path)
Definition: ToolChain.cpp:867
clang::driver::toolchains::Solaris::addLibStdCxxIncludePaths
void addLibStdCxxIncludePaths(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Definition: Solaris.cpp:269
clang::driver::tools::AddLinkerInputs
void AddLinkerInputs(const ToolChain &TC, const InputInfoList &Inputs, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs, const JobAction &JA)
clang::driver::toolchains::Generic_GCC::GCCVersion
Struct to store and manipulate GCC versions.
Definition: Gnu.h:161
clang::driver::ToolChain::getFilePaths
path_list & getFilePaths()
Definition: ToolChain.h:259
clang::driver::Multilib::gccSuffix
const std::string & gccSuffix() const
Get the detected GCC installation path suffix for the multi-arch target variant.
Definition: Multilib.h:45
clang::driver::Tool
Tool - Information on a specific compilation tool.
Definition: Tool.h:32
clang::driver::toolchains::Generic_ELF
Definition: Gnu.h:362
clang::driver::tools::claimNoWarnArgs
void claimNoWarnArgs(const llvm::opt::ArgList &Args)
Options.h
clang::driver::InputInfo::isFilename
bool isFilename() const
Definition: InputInfo.h:75
clang::driver::toolchains::Generic_GCC::GCCVersion::Text
std::string Text
The unparsed text of the version.
Definition: Gnu.h:163
clang::driver::MultilibSet::includeDirsCallback
const IncludeDirsFunc & includeDirsCallback() const
Definition: Multilib.h:179
llvm::opt
Definition: DiagnosticOptions.h:19
Std
LangStandard::Kind Std
Definition: InterpolatingCompilationDatabase.cpp:134
DriverDiagnostic.h
clang::driver::InputInfo::isNothing
bool isNothing() const
Definition: InputInfo.h:74
clang::driver::toolchains::Generic_GCC::GCCInstallationDetector::getTriple
const llvm::Triple & getTriple() const
Get the GCC triple for the detected install.
Definition: Gnu.h:227
clang::driver::toolchains::Generic_GCC::GCCInstallationDetector::getParentLibPath
StringRef getParentLibPath() const
Get the detected GCC parent lib path.
Definition: Gnu.h:233
clang::driver::tools::addPathIfExists
void addPathIfExists(const Driver &D, const Twine &Path, ToolChain::path_list &Paths)
Definition: CommonArgs.cpp:122
llvm::SmallString< 128 >
clang::driver::ToolChain::getTriple
const llvm::Triple & getTriple() const
Definition: ToolChain.h:223
clang::Language::C
@ C
Languages that the frontend can parse and compile.
clang::driver::Driver::SysRoot
std::string SysRoot
sysroot, if present
Definition: Driver.h:151
clang::driver::Multilib
This corresponds to a single GCC Multilib, or a segment of one controlled by a command line flag.
Definition: Multilib.h:28
clang::driver::tools::solaris::Linker
Definition: Solaris.h:35
clang::driver::Driver::ResourceDir
std::string ResourceDir
The path to the compiler resource directory.
Definition: Driver.h:135
clang::driver::tools::solaris::Assembler
Definition: Solaris.h:22
clang::driver::tools::solaris::Linker::ConstructJob
void ConstructJob(Compilation &C, const JobAction &JA, const InputInfo &Output, const InputInfoList &Inputs, const llvm::opt::ArgList &TCArgs, const char *LinkingOutput) const override
ConstructJob - Construct jobs to perform the action JA, writing to Output and with Inputs,...
Definition: Solaris.cpp:48
clang::driver::toolchains::Solaris::AddClangSystemIncludeArgs
void AddClangSystemIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override
Add the clang cc1 arguments for system include paths.
Definition: Solaris.cpp:223
P
StringRef P
Definition: ASTMatchersInternal.cpp:563
clang::driver::ToolChain::getSupportedSanitizers
virtual SanitizerMask getSupportedSanitizers() const
Return sanitizers which are available in this toolchain.
Definition: ToolChain.cpp:998
Compilation.h
LangStandard.h
clang::LangStandard::getLanguage
clang::Language getLanguage() const
Get the language that this standard describes.
Definition: LangStandard.h:84
getSolarisLibSuffix
static StringRef getSolarisLibSuffix(const llvm::Triple &Triple)
Definition: Solaris.cpp:158
clang::LangStandard::getLangStandardForName
static const LangStandard * getLangStandardForName(StringRef Name)
Definition: LangStandards.cpp:37
clang::driver::toolchains::Generic_GCC::GCCInstallationDetector::getInstallPath
StringRef getInstallPath() const
Get the detected GCC installation path.
Definition: Gnu.h:230
clang::driver::Compilation
Compilation - A set of tasks to perform for a single driver invocation.
Definition: Compilation.h:45
clang::driver::toolchains::Generic_GCC::GCCInstallationDetector::getVersion
const GCCVersion & getVersion() const
Get the detected GCC version string.
Definition: Gnu.h:246
clang::LangStandard
LangStandard - Information about the properties of a particular language standard.
Definition: LangStandard.h:63
Solaris.h
clang::driver::toolchains::Generic_GCC::addLibStdCXXIncludePaths
bool addLibStdCXXIncludePaths(Twine IncludeDir, StringRef Triple, Twine IncludeSuffix, const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, bool DetectDebian=false) const
Definition: Gnu.cpp:2931
clang::driver::InputInfo::getFilename
const char * getFilename() const
Definition: InputInfo.h:83
clang::driver::tools::linkSanitizerRuntimeDeps
void linkSanitizerRuntimeDeps(const ToolChain &TC, llvm::opt::ArgStringList &CmdArgs)
CommonArgs.h
clang
Definition: CalledOnceCheck.h:17
clang::driver::Driver
Driver - Encapsulate logic for constructing compilation processes from a set of gcc-driver-like comma...
Definition: Driver.h:59
clang::driver::toolchains::Generic_GCC::GCCInstallationDetector::getMultilib
const Multilib & getMultilib() const
Get the detected Multilib.
Definition: Gnu.h:236
clang::driver::tools::addSanitizerRuntimes
bool addSanitizerRuntimes(const ToolChain &TC, const llvm::opt::ArgList &Args, llvm::opt::ArgStringList &CmdArgs)
clang::driver::ToolChain::Multilibs
MultilibSet Multilibs
Definition: ToolChain.h:181
clang::driver::Multilib::includeSuffix
const std::string & includeSuffix() const
Get the include directory suffix.
Definition: Multilib.h:67
clang::driver::ToolChain::addExternCSystemInclude
static void addExternCSystemInclude(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const Twine &Path)
Utility function to add a system include directory with extern "C" semantics to CC1 arguments.
Definition: ToolChain.cpp:860
clang::driver
Definition: Action.h:31
clang::driver::ResponseFileSupport::None
static constexpr ResponseFileSupport None()
Returns a ResponseFileSupport indicating that response files are not supported.
Definition: Job.h:78
clang::driver::ToolChain::addSystemInclude
static void addSystemInclude(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args, const Twine &Path)
Utility function to add a system include directory to CC1 arguments.
Definition: ToolChain.cpp:845
clang::driver::JobAction
Definition: Action.h:380
clang::driver::toolchains::Solaris::buildAssembler
Tool * buildAssembler() const override
Definition: Solaris.cpp:217
clang::LangStandard::isGNUMode
bool isGNUMode() const
isGNUMode - Language includes GNU extensions.
Definition: LangStandard.h:123
clang::SanitizerMask
Definition: Sanitizers.h:30