forked from OSchip/llvm-project
Add support for dynamic ASan runtime (on Linux) to Clang driver.
Based on http://llvm-reviews.chandlerc.com/D3043 by Yuri Gribov! llvm-svn: 205310
This commit is contained in:
parent
1351030801
commit
bdfa6c2517
|
@ -357,6 +357,7 @@ def fapple_kext : Flag<["-"], "fapple-kext">, Group<f_Group>, Flags<[CC1Option]>
|
|||
HelpText<"Use Apple's kernel extensions ABI">;
|
||||
def fapple_pragma_pack : Flag<["-"], "fapple-pragma-pack">, Group<f_Group>, Flags<[CC1Option]>,
|
||||
HelpText<"Enable Apple gcc-compatible #pragma pack handling">;
|
||||
def shared_libasan : Flag<["-"], "shared-libasan">;
|
||||
def fasm : Flag<["-"], "fasm">, Group<f_Group>;
|
||||
|
||||
def fasm_blocks : Flag<["-"], "fasm-blocks">, Group<f_Group>, Flags<[CC1Option]>;
|
||||
|
|
|
@ -51,6 +51,7 @@ class SanitizerArgs {
|
|||
int MsanTrackOrigins;
|
||||
bool AsanZeroBaseShadow;
|
||||
bool UbsanTrapOnError;
|
||||
bool AsanSharedRuntime;
|
||||
|
||||
public:
|
||||
SanitizerArgs();
|
||||
|
@ -58,6 +59,7 @@ class SanitizerArgs {
|
|||
SanitizerArgs(const ToolChain &TC, const llvm::opt::ArgList &Args);
|
||||
|
||||
bool needsAsanRt() const { return Kind & NeedsAsanRt; }
|
||||
bool needsSharedAsanRt() const { return AsanSharedRuntime; }
|
||||
bool needsTsanRt() const { return Kind & NeedsTsanRt; }
|
||||
bool needsMsanRt() const { return Kind & NeedsMsanRt; }
|
||||
bool needsLeakDetection() const { return Kind & NeedsLeakDetection; }
|
||||
|
|
|
@ -27,6 +27,7 @@ void SanitizerArgs::clear() {
|
|||
MsanTrackOrigins = 0;
|
||||
AsanZeroBaseShadow = false;
|
||||
UbsanTrapOnError = false;
|
||||
AsanSharedRuntime = false;
|
||||
}
|
||||
|
||||
SanitizerArgs::SanitizerArgs() {
|
||||
|
@ -168,9 +169,13 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
|
|||
}
|
||||
}
|
||||
|
||||
if (NeedsAsan)
|
||||
if (NeedsAsan) {
|
||||
AsanSharedRuntime =
|
||||
(TC.getTriple().getEnvironment() == llvm::Triple::Android) ||
|
||||
Args.hasArg(options::OPT_shared_libasan);
|
||||
AsanZeroBaseShadow =
|
||||
(TC.getTriple().getEnvironment() == llvm::Triple::Android);
|
||||
}
|
||||
}
|
||||
|
||||
void SanitizerArgs::addArgs(const llvm::opt::ArgList &Args,
|
||||
|
|
|
@ -1883,15 +1883,29 @@ static void addProfileRT(
|
|||
CmdArgs.push_back(Args.MakeArgString(LibProfile));
|
||||
}
|
||||
|
||||
static void addSanitizerRTLinkFlags(
|
||||
const ToolChain &TC, const ArgList &Args, ArgStringList &CmdArgs,
|
||||
const StringRef Sanitizer, bool BeforeLibStdCXX,
|
||||
bool ExportSymbols = true) {
|
||||
// Sanitizer runtime has name "libclang_rt.<Sanitizer>-<ArchName>.a".
|
||||
static SmallString<128> getSanitizerRTLibName(const ToolChain &TC,
|
||||
const StringRef Sanitizer,
|
||||
bool Shared) {
|
||||
// Sanitizer runtime has name "libclang_rt.<Sanitizer>-<ArchName>.{a,so}"
|
||||
// (or "libclang_rt.<Sanitizer>-<ArchName>-android.so for Android)
|
||||
const char *EnvSuffix =
|
||||
TC.getTriple().getEnvironment() == llvm::Triple::Android ? "-android" : "";
|
||||
SmallString<128> LibSanitizer = getCompilerRTLibDir(TC);
|
||||
llvm::sys::path::append(LibSanitizer,
|
||||
(Twine("libclang_rt.") + Sanitizer + "-" +
|
||||
getArchNameForCompilerRTLib(TC) + ".a"));
|
||||
Twine("libclang_rt.") + Sanitizer + "-" +
|
||||
getArchNameForCompilerRTLib(TC) + EnvSuffix +
|
||||
(Shared ? ".so" : ".a"));
|
||||
return LibSanitizer;
|
||||
}
|
||||
|
||||
static void addSanitizerRTLinkFlags(const ToolChain &TC, const ArgList &Args,
|
||||
ArgStringList &CmdArgs,
|
||||
const StringRef Sanitizer,
|
||||
bool BeforeLibStdCXX,
|
||||
bool ExportSymbols = true,
|
||||
bool LinkDeps = true) {
|
||||
SmallString<128> LibSanitizer =
|
||||
getSanitizerRTLibName(TC, Sanitizer, /*Shared*/ false);
|
||||
|
||||
// Sanitizer runtime may need to come before -lstdc++ (or -lc++, libstdc++.a,
|
||||
// etc.) so that the linker picks custom versions of the global 'operator
|
||||
|
@ -1907,12 +1921,15 @@ static void addSanitizerRTLinkFlags(
|
|||
CmdArgs.insert(BeforeLibStdCXX ? CmdArgs.begin() : CmdArgs.end(),
|
||||
LibSanitizerArgs.begin(), LibSanitizerArgs.end());
|
||||
|
||||
CmdArgs.push_back("-lpthread");
|
||||
CmdArgs.push_back("-lrt");
|
||||
CmdArgs.push_back("-lm");
|
||||
// There's no libdl on FreeBSD.
|
||||
if (TC.getTriple().getOS() != llvm::Triple::FreeBSD)
|
||||
CmdArgs.push_back("-ldl");
|
||||
if (LinkDeps) {
|
||||
// Link sanitizer dependencies explicitly
|
||||
CmdArgs.push_back("-lpthread");
|
||||
CmdArgs.push_back("-lrt");
|
||||
CmdArgs.push_back("-lm");
|
||||
// There's no libdl on FreeBSD.
|
||||
if (TC.getTriple().getOS() != llvm::Triple::FreeBSD)
|
||||
CmdArgs.push_back("-ldl");
|
||||
}
|
||||
|
||||
// If possible, use a dynamic symbols file to export the symbols from the
|
||||
// runtime library. If we can't do so, use -export-dynamic instead to export
|
||||
|
@ -1929,17 +1946,23 @@ static void addSanitizerRTLinkFlags(
|
|||
/// If AddressSanitizer is enabled, add appropriate linker flags (Linux).
|
||||
/// This needs to be called before we add the C run-time (malloc, etc).
|
||||
static void addAsanRT(const ToolChain &TC, const ArgList &Args,
|
||||
ArgStringList &CmdArgs) {
|
||||
if (TC.getTriple().getEnvironment() == llvm::Triple::Android) {
|
||||
SmallString<128> LibAsan = getCompilerRTLibDir(TC);
|
||||
llvm::sys::path::append(LibAsan,
|
||||
(Twine("libclang_rt.asan-") +
|
||||
getArchNameForCompilerRTLib(TC) + "-android.so"));
|
||||
CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibAsan));
|
||||
} else {
|
||||
if (!Args.hasArg(options::OPT_shared))
|
||||
addSanitizerRTLinkFlags(TC, Args, CmdArgs, "asan", true);
|
||||
ArgStringList &CmdArgs, bool Shared) {
|
||||
if (Shared) {
|
||||
// Link dynamic runtime if necessary.
|
||||
SmallString<128> LibSanitizer =
|
||||
getSanitizerRTLibName(TC, "asan", Shared);
|
||||
CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibSanitizer));
|
||||
}
|
||||
|
||||
// Do not link static runtime to DSOs or if compiling for Android.
|
||||
if (Args.hasArg(options::OPT_shared) ||
|
||||
(TC.getTriple().getEnvironment() == llvm::Triple::Android))
|
||||
return;
|
||||
|
||||
const char *LibAsanStaticPart = Shared ? "asan-preinit" : "asan";
|
||||
addSanitizerRTLinkFlags(TC, Args, CmdArgs, LibAsanStaticPart,
|
||||
/*BeforeLibStdCXX*/ true, /*ExportSymbols*/ !Shared,
|
||||
/*LinkDeps*/ !Shared);
|
||||
}
|
||||
|
||||
/// If ThreadSanitizer is enabled, add appropriate linker flags (Linux).
|
||||
|
@ -2000,7 +2023,7 @@ static void addSanitizerRuntimes(const ToolChain &TC, const ArgList &Args,
|
|||
Sanitize.needsAsanRt() || Sanitize.needsTsanRt() ||
|
||||
Sanitize.needsMsanRt() || Sanitize.needsLsanRt());
|
||||
if (Sanitize.needsAsanRt())
|
||||
addAsanRT(TC, Args, CmdArgs);
|
||||
addAsanRT(TC, Args, CmdArgs, Sanitize.needsSharedAsanRt());
|
||||
if (Sanitize.needsTsanRt())
|
||||
addTsanRT(TC, Args, CmdArgs);
|
||||
if (Sanitize.needsMsanRt())
|
||||
|
|
|
@ -15,6 +15,40 @@
|
|||
// CHECK-ASAN-LINUX-NOT: "-export-dynamic"
|
||||
// CHECK-ASAN-LINUX: "--dynamic-list={{.*}}libclang_rt.asan-i386.a.syms"
|
||||
|
||||
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
|
||||
// RUN: -target i386-unknown-linux -fsanitize=address -shared-libasan \
|
||||
// RUN: -resource-dir=%S/Inputs/resource_dir \
|
||||
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-SHARED-ASAN-LINUX %s
|
||||
//
|
||||
// CHECK-SHARED-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
|
||||
// CHECK-SHARED-ASAN-LINUX-NOT: "-lc"
|
||||
// CHECK-SHARED-ASAN-LINUX-NOT: libclang_rt.asan-i386.a"
|
||||
// CHECK-SHARED-ASAN-LINUX: "-whole-archive" "{{.*}}libclang_rt.asan-preinit-i386.a" "-no-whole-archive"
|
||||
// CHECK-SHARED-ASAN-LINUX: libclang_rt.asan-i386.so"
|
||||
// CHECK-SHARED-ASAN-LINUX-NOT: "-lpthread"
|
||||
// CHECK-SHARED-ASAN-LINUX-NOT: "-lrt"
|
||||
// CHECK-SHARED-ASAN-LINUX-NOT: "-ldl"
|
||||
// CHECK-SHARED-ASAN-LINUX-NOT: "-export-dynamic"
|
||||
// CHECK-SHARED-ASAN-LINUX-NOT: "--dynamic-list"
|
||||
|
||||
// RUN: %clang -no-canonical-prefixes %s -### -o %t.so -shared 2>&1 \
|
||||
// RUN: -target i386-unknown-linux -fsanitize=address -shared-libasan \
|
||||
// RUN: -resource-dir=%S/Inputs/resource_dir \
|
||||
// RUN: --sysroot=%S/Inputs/basic_linux_tree \
|
||||
// RUN: | FileCheck --check-prefix=CHECK-DSO-SHARED-ASAN-LINUX %s
|
||||
//
|
||||
// CHECK-DSO-SHARED-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
|
||||
// CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-lc"
|
||||
// CHECK-DSO-SHARED-ASAN-LINUX-NOT: libclang_rt.asan-i386.a"
|
||||
// CHECK-DSO-SHARED-ASAN-LINUX-NOT: "libclang_rt.asan-preinit-i386.a"
|
||||
// CHECK-DSO-SHARED-ASAN-LINUX: libclang_rt.asan-i386.so"
|
||||
// CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-lpthread"
|
||||
// CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-lrt"
|
||||
// CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-ldl"
|
||||
// CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-export-dynamic"
|
||||
// CHECK-DSO-SHARED-ASAN-LINUX-NOT: "--dynamic-list"
|
||||
|
||||
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
|
||||
// RUN: -target i386-unknown-freebsd -fsanitize=address \
|
||||
// RUN: -resource-dir=%S/Inputs/resource_dir \
|
||||
|
@ -81,7 +115,6 @@
|
|||
// CHECK-ASAN-ARMv7: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}"
|
||||
// CHECK-ASAN-ARMv7-NOT: "-lc"
|
||||
// CHECK-ASAN-ARMv7: libclang_rt.asan-arm.a"
|
||||
//
|
||||
|
||||
// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \
|
||||
// RUN: -target arm-linux-androideabi -fsanitize=address \
|
||||
|
|
Loading…
Reference in New Issue