comparison clang/lib/Driver/ToolChains/Fuchsia.cpp @ 221:79ff65ed7e25

LLVM12 Original
author Shinji KONO <kono@ie.u-ryukyu.ac.jp>
date Tue, 15 Jun 2021 19:15:29 +0900
parents 0572611fdcc8
children 5f17cb93ff66
comparison
equal deleted inserted replaced
220:42394fc6a535 221:79ff65ed7e25
13 #include "clang/Driver/Driver.h" 13 #include "clang/Driver/Driver.h"
14 #include "clang/Driver/DriverDiagnostic.h" 14 #include "clang/Driver/DriverDiagnostic.h"
15 #include "clang/Driver/Options.h" 15 #include "clang/Driver/Options.h"
16 #include "clang/Driver/SanitizerArgs.h" 16 #include "clang/Driver/SanitizerArgs.h"
17 #include "llvm/Option/ArgList.h" 17 #include "llvm/Option/ArgList.h"
18 #include "llvm/ProfileData/InstrProf.h"
18 #include "llvm/Support/FileSystem.h" 19 #include "llvm/Support/FileSystem.h"
19 #include "llvm/Support/Path.h" 20 #include "llvm/Support/Path.h"
20 #include "llvm/Support/VirtualFileSystem.h" 21 #include "llvm/Support/VirtualFileSystem.h"
21 22
22 using namespace clang::driver; 23 using namespace clang::driver;
92 93
93 if (!Args.hasArg(options::OPT_shared)) { 94 if (!Args.hasArg(options::OPT_shared)) {
94 std::string Dyld = D.DyldPrefix; 95 std::string Dyld = D.DyldPrefix;
95 if (SanArgs.needsAsanRt() && SanArgs.needsSharedRt()) 96 if (SanArgs.needsAsanRt() && SanArgs.needsSharedRt())
96 Dyld += "asan/"; 97 Dyld += "asan/";
98 if (SanArgs.needsHwasanRt() && SanArgs.needsSharedRt())
99 Dyld += "hwasan/";
100 if (SanArgs.needsTsanRt() && SanArgs.needsSharedRt())
101 Dyld += "tsan/";
97 Dyld += "ld.so.1"; 102 Dyld += "ld.so.1";
98 CmdArgs.push_back("-dynamic-linker"); 103 CmdArgs.push_back("-dynamic-linker");
99 CmdArgs.push_back(Args.MakeArgString(Dyld)); 104 CmdArgs.push_back(Args.MakeArgString(Dyld));
100 } 105 }
101 106
161 166
162 if (!Args.hasArg(options::OPT_nolibc)) 167 if (!Args.hasArg(options::OPT_nolibc))
163 CmdArgs.push_back("-lc"); 168 CmdArgs.push_back("-lc");
164 } 169 }
165 170
166 C.addCommand(std::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); 171 C.addCommand(std::make_unique<Command>(JA, *this, ResponseFileSupport::None(),
172 Exec, CmdArgs, Inputs, Output));
167 } 173 }
168 174
169 /// Fuchsia - Fuchsia tool chain which can call as(1) and ld(1) directly. 175 /// Fuchsia - Fuchsia tool chain which can call as(1) and ld(1) directly.
170 176
171 Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple, 177 Fuchsia::Fuchsia(const Driver &D, const llvm::Triple &Triple,
181 getFilePaths().push_back(std::string(P.str())); 187 getFilePaths().push_back(std::string(P.str()));
182 } 188 }
183 189
184 auto FilePaths = [&](const Multilib &M) -> std::vector<std::string> { 190 auto FilePaths = [&](const Multilib &M) -> std::vector<std::string> {
185 std::vector<std::string> FP; 191 std::vector<std::string> FP;
186 if (D.CCCIsCXX()) { 192 SmallString<128> P(getStdlibPath());
187 if (auto CXXStdlibPath = getCXXStdlibPath()) { 193 llvm::sys::path::append(P, M.gccSuffix());
188 SmallString<128> P(*CXXStdlibPath); 194 FP.push_back(std::string(P.str()));
189 llvm::sys::path::append(P, M.gccSuffix());
190 FP.push_back(std::string(P.str()));
191 }
192 }
193 return FP; 195 return FP;
194 }; 196 };
195 197
196 Multilibs.push_back(Multilib()); 198 Multilibs.push_back(Multilib());
197 // Use the noexcept variant with -fno-exceptions to avoid the extra overhead. 199 // Use the noexcept variant with -fno-exceptions to avoid the extra overhead.
204 // Use the asan+noexcept variant with ASan and -fno-exceptions. 206 // Use the asan+noexcept variant with ASan and -fno-exceptions.
205 Multilibs.push_back(Multilib("asan+noexcept", {}, {}, 3) 207 Multilibs.push_back(Multilib("asan+noexcept", {}, {}, 3)
206 .flag("+fsanitize=address") 208 .flag("+fsanitize=address")
207 .flag("-fexceptions") 209 .flag("-fexceptions")
208 .flag("+fno-exceptions")); 210 .flag("+fno-exceptions"));
211 // HWASan has higher priority because we always want the instrumentated
212 // version.
213 Multilibs.push_back(
214 Multilib("hwasan", {}, {}, 4).flag("+fsanitize=hwaddress"));
215 // Use the hwasan+noexcept variant with HWASan and -fno-exceptions.
216 Multilibs.push_back(Multilib("hwasan+noexcept", {}, {}, 5)
217 .flag("+fsanitize=hwaddress")
218 .flag("-fexceptions")
219 .flag("+fno-exceptions"));
220 // Use the relative vtables ABI.
221 // TODO: Remove these multilibs once relative vtables are enabled by default
222 // for Fuchsia.
223 Multilibs.push_back(Multilib("relative-vtables", {}, {}, 6)
224 .flag("+fexperimental-relative-c++-abi-vtables"));
225 Multilibs.push_back(Multilib("relative-vtables+noexcept", {}, {}, 7)
226 .flag("+fexperimental-relative-c++-abi-vtables")
227 .flag("-fexceptions")
228 .flag("+fno-exceptions"));
229 Multilibs.push_back(Multilib("relative-vtables+asan", {}, {}, 8)
230 .flag("+fexperimental-relative-c++-abi-vtables")
231 .flag("+fsanitize=address"));
232 Multilibs.push_back(Multilib("relative-vtables+asan+noexcept", {}, {}, 9)
233 .flag("+fexperimental-relative-c++-abi-vtables")
234 .flag("+fsanitize=address")
235 .flag("-fexceptions")
236 .flag("+fno-exceptions"));
237 Multilibs.push_back(Multilib("relative-vtables+hwasan", {}, {}, 10)
238 .flag("+fexperimental-relative-c++-abi-vtables")
239 .flag("+fsanitize=hwaddress"));
240 Multilibs.push_back(Multilib("relative-vtables+hwasan+noexcept", {}, {}, 11)
241 .flag("+fexperimental-relative-c++-abi-vtables")
242 .flag("+fsanitize=hwaddress")
243 .flag("-fexceptions")
244 .flag("+fno-exceptions"));
245 // Use Itanium C++ ABI for the compat multilib.
246 Multilibs.push_back(Multilib("compat", {}, {}, 12).flag("+fc++-abi=itanium"));
247
209 Multilibs.FilterOut([&](const Multilib &M) { 248 Multilibs.FilterOut([&](const Multilib &M) {
210 std::vector<std::string> RD = FilePaths(M); 249 std::vector<std::string> RD = FilePaths(M);
211 return std::all_of(RD.begin(), RD.end(), [&](std::string P) { 250 return std::all_of(RD.begin(), RD.end(), [&](std::string P) {
212 return !getVFS().exists(P); 251 return !getVFS().exists(P);
213 }); 252 });
216 Multilib::flags_list Flags; 255 Multilib::flags_list Flags;
217 addMultilibFlag( 256 addMultilibFlag(
218 Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, true), 257 Args.hasFlag(options::OPT_fexceptions, options::OPT_fno_exceptions, true),
219 "fexceptions", Flags); 258 "fexceptions", Flags);
220 addMultilibFlag(getSanitizerArgs().needsAsanRt(), "fsanitize=address", Flags); 259 addMultilibFlag(getSanitizerArgs().needsAsanRt(), "fsanitize=address", Flags);
260 addMultilibFlag(getSanitizerArgs().needsHwasanRt(), "fsanitize=hwaddress",
261 Flags);
262
263 addMultilibFlag(
264 Args.hasFlag(options::OPT_fexperimental_relative_cxx_abi_vtables,
265 options::OPT_fno_experimental_relative_cxx_abi_vtables,
266 /*default=*/false),
267 "fexperimental-relative-c++-abi-vtables", Flags);
268 addMultilibFlag(Args.getLastArgValue(options::OPT_fcxx_abi_EQ) == "itanium",
269 "fc++-abi=itanium", Flags);
270
221 Multilibs.setFilePathsCallback(FilePaths); 271 Multilibs.setFilePathsCallback(FilePaths);
222 272
223 if (Multilibs.select(Flags, SelectedMultilib)) 273 if (Multilibs.select(Flags, SelectedMultilib))
224 if (!SelectedMultilib.isDefault()) 274 if (!SelectedMultilib.isDefault())
225 if (const auto &PathsCallback = Multilibs.filePathsCallback()) 275 if (const auto &PathsCallback = Multilibs.filePathsCallback())
310 ArgStringList &CC1Args) const { 360 ArgStringList &CC1Args) const {
311 if (DriverArgs.hasArg(options::OPT_nostdlibinc) || 361 if (DriverArgs.hasArg(options::OPT_nostdlibinc) ||
312 DriverArgs.hasArg(options::OPT_nostdincxx)) 362 DriverArgs.hasArg(options::OPT_nostdincxx))
313 return; 363 return;
314 364
365 const Driver &D = getDriver();
366 std::string Target = getTripleString();
367
368 auto AddCXXIncludePath = [&](StringRef Path) {
369 std::string Version = detectLibcxxVersion(Path);
370 if (Version.empty())
371 return;
372
373 // First add the per-target include path.
374 SmallString<128> TargetDir(Path);
375 llvm::sys::path::append(TargetDir, Target, "c++", Version);
376 if (getVFS().exists(TargetDir))
377 addSystemInclude(DriverArgs, CC1Args, TargetDir);
378
379 // Second add the generic one.
380 SmallString<128> Dir(Path);
381 llvm::sys::path::append(Dir, "c++", Version);
382 addSystemInclude(DriverArgs, CC1Args, Dir);
383 };
384
315 switch (GetCXXStdlibType(DriverArgs)) { 385 switch (GetCXXStdlibType(DriverArgs)) {
316 case ToolChain::CST_Libcxx: { 386 case ToolChain::CST_Libcxx: {
317 SmallString<128> P(getDriver().Dir); 387 SmallString<128> P(D.Dir);
318 llvm::sys::path::append(P, "..", "include", "c++", "v1"); 388 llvm::sys::path::append(P, "..", "include");
319 addSystemInclude(DriverArgs, CC1Args, P.str()); 389 AddCXXIncludePath(P);
320 break; 390 break;
321 } 391 }
322 392
323 default: 393 default:
324 llvm_unreachable("invalid stdlib name"); 394 llvm_unreachable("invalid stdlib name");
338 } 408 }
339 409
340 SanitizerMask Fuchsia::getSupportedSanitizers() const { 410 SanitizerMask Fuchsia::getSupportedSanitizers() const {
341 SanitizerMask Res = ToolChain::getSupportedSanitizers(); 411 SanitizerMask Res = ToolChain::getSupportedSanitizers();
342 Res |= SanitizerKind::Address; 412 Res |= SanitizerKind::Address;
413 Res |= SanitizerKind::HWAddress;
343 Res |= SanitizerKind::PointerCompare; 414 Res |= SanitizerKind::PointerCompare;
344 Res |= SanitizerKind::PointerSubtract; 415 Res |= SanitizerKind::PointerSubtract;
345 Res |= SanitizerKind::Fuzzer; 416 Res |= SanitizerKind::Fuzzer;
346 Res |= SanitizerKind::FuzzerNoLink; 417 Res |= SanitizerKind::FuzzerNoLink;
347 Res |= SanitizerKind::Leak; 418 Res |= SanitizerKind::Leak;
348 Res |= SanitizerKind::SafeStack; 419 Res |= SanitizerKind::SafeStack;
349 Res |= SanitizerKind::Scudo; 420 Res |= SanitizerKind::Scudo;
421 Res |= SanitizerKind::Thread;
350 return Res; 422 return Res;
351 } 423 }
352 424
353 SanitizerMask Fuchsia::getDefaultSanitizers() const { 425 SanitizerMask Fuchsia::getDefaultSanitizers() const {
354 SanitizerMask Res; 426 SanitizerMask Res;
363 // TODO: Enable SafeStack on RISC-V once tested. 435 // TODO: Enable SafeStack on RISC-V once tested.
364 break; 436 break;
365 } 437 }
366 return Res; 438 return Res;
367 } 439 }
440
441 void Fuchsia::addProfileRTLibs(const llvm::opt::ArgList &Args,
442 llvm::opt::ArgStringList &CmdArgs) const {
443 // Add linker option -u__llvm_profile_runtime to cause runtime
444 // initialization module to be linked in.
445 if (needsProfileRT(Args))
446 CmdArgs.push_back(Args.MakeArgString(
447 Twine("-u", llvm::getInstrProfRuntimeHookVarName())));
448 ToolChain::addProfileRTLibs(Args, CmdArgs);
449 }