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
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
/// 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).
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())
// 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 \
// 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 \