Author: samsonov Date: Tue Apr 1 08:31:10 2014 New Revision: 205310 URL: http://llvm.org/viewvc/llvm-project?rev=205310&view=rev Log: Add support for dynamic ASan runtime (on Linux) to Clang driver.
Based on http://llvm-reviews.chandlerc.com/D3043 by Yuri Gribov! Modified: cfe/trunk/include/clang/Driver/Options.td cfe/trunk/include/clang/Driver/SanitizerArgs.h cfe/trunk/lib/Driver/SanitizerArgs.cpp cfe/trunk/lib/Driver/Tools.cpp cfe/trunk/test/Driver/sanitizer-ld.c Modified: cfe/trunk/include/clang/Driver/Options.td URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/Options.td?rev=205310&r1=205309&r2=205310&view=diff ============================================================================== --- cfe/trunk/include/clang/Driver/Options.td (original) +++ cfe/trunk/include/clang/Driver/Options.td Tue Apr 1 08:31:10 2014 @@ -357,6 +357,7 @@ def fapple_kext : Flag<["-"], "fapple-ke 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]>; Modified: cfe/trunk/include/clang/Driver/SanitizerArgs.h URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Driver/SanitizerArgs.h?rev=205310&r1=205309&r2=205310&view=diff ============================================================================== --- cfe/trunk/include/clang/Driver/SanitizerArgs.h (original) +++ cfe/trunk/include/clang/Driver/SanitizerArgs.h Tue Apr 1 08:31:10 2014 @@ -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; } Modified: cfe/trunk/lib/Driver/SanitizerArgs.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/SanitizerArgs.cpp?rev=205310&r1=205309&r2=205310&view=diff ============================================================================== --- cfe/trunk/lib/Driver/SanitizerArgs.cpp (original) +++ cfe/trunk/lib/Driver/SanitizerArgs.cpp Tue Apr 1 08:31:10 2014 @@ -27,6 +27,7 @@ void SanitizerArgs::clear() { MsanTrackOrigins = 0; AsanZeroBaseShadow = false; UbsanTrapOnError = false; + AsanSharedRuntime = false; } SanitizerArgs::SanitizerArgs() { @@ -168,9 +169,13 @@ SanitizerArgs::SanitizerArgs(const ToolC } } - 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, Modified: cfe/trunk/lib/Driver/Tools.cpp URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Driver/Tools.cpp?rev=205310&r1=205309&r2=205310&view=diff ============================================================================== --- cfe/trunk/lib/Driver/Tools.cpp (original) +++ cfe/trunk/lib/Driver/Tools.cpp Tue Apr 1 08:31:10 2014 @@ -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 T 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()) Modified: cfe/trunk/test/Driver/sanitizer-ld.c URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/Driver/sanitizer-ld.c?rev=205310&r1=205309&r2=205310&view=diff ============================================================================== --- cfe/trunk/test/Driver/sanitizer-ld.c (original) +++ cfe/trunk/test/Driver/sanitizer-ld.c Tue Apr 1 08:31:10 2014 @@ -16,6 +16,40 @@ // 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 \ // RUN: --sysroot=%S/Inputs/basic_freebsd_tree \ @@ -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 \ _______________________________________________ cfe-commits mailing list [email protected] http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits
