Index: lib/Driver/Tools.cpp =================================================================== --- lib/Driver/Tools.cpp +++ lib/Driver/Tools.cpp @@ -1893,25 +1893,31 @@ Args.hasArg(options::OPT_coverage))) return; - SmallString<128> LibProfile = getCompilerRTLibDir(TC); - llvm::sys::path::append(LibProfile, - Twine("libclang_rt.profile-") + getArchNameForCompilerRTLib(TC) + ".a"); + CmdArgs.push_back(Args.MakeArgString("-L" + getCompilerRTLibDir(TC))); + CmdArgs.push_back(Args.MakeArgString("-lclang_rt.profile-" + + getArchNameForCompilerRTLib(TC))); +} - CmdArgs.push_back(Args.MakeArgString(LibProfile)); +static std::string getSanitizerRTLibName(const ToolChain &TC, + const StringRef Sanitizer) { + // Sanitizer runtime has name "clang_rt.-" + // (and possibly a -android suffix) + std::string Name = (Twine("clang_rt.") + Sanitizer + "-" + + getArchNameForCompilerRTLib(TC)).str(); + if (TC.getTriple().getEnvironment() == llvm::Triple::Android) { + Name += "-android"; + } + return Name; } -static SmallString<128> getSanitizerRTLibName(const ToolChain &TC, +static SmallString<128> getSanitizerRTLibPath(const ToolChain &TC, const StringRef Sanitizer, bool Shared) { // Sanitizer runtime has name "libclang_rt.-.{a,so}" - // (or "libclang_rt.--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) + EnvSuffix + - (Shared ? ".so" : ".a")); + llvm::sys::path::append(LibSanitizer, Twine("lib") + + getSanitizerRTLibName(TC, Sanitizer) + + (Shared ? ".so" : ".a")); return LibSanitizer; } @@ -1922,7 +1928,7 @@ bool ExportSymbols = true, bool LinkDeps = true) { SmallString<128> LibSanitizer = - getSanitizerRTLibName(TC, Sanitizer, /*Shared*/ false); + getSanitizerRTLibPath(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 @@ -1932,7 +1938,8 @@ // whole-archive. SmallVector LibSanitizerArgs; LibSanitizerArgs.push_back("-whole-archive"); - LibSanitizerArgs.push_back(Args.MakeArgString(LibSanitizer)); + LibSanitizerArgs.push_back(Args.MakeArgString("-l" + + getSanitizerRTLibName(TC, Sanitizer))); LibSanitizerArgs.push_back("-no-whole-archive"); CmdArgs.insert(BeforeLibStdCXX ? CmdArgs.begin() : CmdArgs.end(), @@ -1948,6 +1955,10 @@ CmdArgs.push_back("-ldl"); } + // Sanitizer directory should be near the end of the argument list so that + // the user can override it. + CmdArgs.push_back(Args.MakeArgString("-L" + getCompilerRTLibDir(TC))); + // 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 // all symbols from the binary. @@ -1967,7 +1978,7 @@ if (Shared) { // Link dynamic runtime if necessary. SmallString<128> LibSanitizer = - getSanitizerRTLibName(TC, "asan", Shared); + getSanitizerRTLibPath(TC, "asan", Shared); CmdArgs.insert(CmdArgs.begin(), Args.MakeArgString(LibSanitizer)); } Index: test/Driver/coverage-ld.c =================================================================== --- test/Driver/coverage-ld.c +++ test/Driver/coverage-ld.c @@ -7,7 +7,7 @@ // RUN: | FileCheck --check-prefix=CHECK-LINUX-I386 %s // // CHECK-LINUX-I386: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" -// CHECK-LINUX-I386: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}libclang_rt.profile-i386.a" {{.*}} "-lc" +// CHECK-LINUX-I386: "-L{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}linux" "-lclang_rt.profile-i386" {{.*}} "-lc" // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target x86_64-unknown-linux --coverage \ @@ -16,7 +16,7 @@ // RUN: | FileCheck --check-prefix=CHECK-LINUX-X86-64 %s // // CHECK-LINUX-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" -// CHECK-LINUX-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}linux{{/|\\\\}}libclang_rt.profile-x86_64.a" {{.*}} "-lc" +// CHECK-LINUX-X86-64: "-L{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}linux" "-lclang_rt.profile-x86_64" {{.*}} "-lc" // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target x86_64-unknown-freebsd --coverage \ @@ -25,4 +25,4 @@ // RUN: | FileCheck --check-prefix=CHECK-FREEBSD-X86-64 %s // // CHECK-FREEBSD-X86-64: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" -// CHECK-FREEBSD-X86-64: "{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}freebsd{{/|\\\\}}libclang_rt.profile-x86_64.a" +// CHECK-FREEBSD-X86-64: "-L{{.*}}/Inputs/resource_dir{{/|\\\\}}lib{{/|\\\\}}freebsd" "-lclang_rt.profile-x86_64" Index: test/Driver/sanitizer-ld.c =================================================================== --- test/Driver/sanitizer-ld.c +++ test/Driver/sanitizer-ld.c @@ -8,7 +8,7 @@ // // CHECK-ASAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-ASAN-LINUX-NOT: "-lc" -// CHECK-ASAN-LINUX: libclang_rt.asan-i386.a" +// CHECK-ASAN-LINUX: "-lclang_rt.asan-i386" // CHECK-ASAN-LINUX: "-lpthread" // CHECK-ASAN-LINUX: "-lrt" // CHECK-ASAN-LINUX: "-ldl" @@ -23,8 +23,8 @@ // // 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-NOT: clang_rt.asan-i386.a" +// CHECK-SHARED-ASAN-LINUX: "-whole-archive" "-lclang_rt.asan-preinit-i386" "-no-whole-archive" // CHECK-SHARED-ASAN-LINUX: libclang_rt.asan-i386.so" // CHECK-SHARED-ASAN-LINUX-NOT: "-lpthread" // CHECK-SHARED-ASAN-LINUX-NOT: "-lrt" @@ -40,8 +40,8 @@ // // 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-NOT: clang_rt.asan-i386" +// CHECK-DSO-SHARED-ASAN-LINUX-NOT: "clang_rt.asan-preinit-i386" // CHECK-DSO-SHARED-ASAN-LINUX: libclang_rt.asan-i386.so" // CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-lpthread" // CHECK-DSO-SHARED-ASAN-LINUX-NOT: "-lrt" @@ -57,9 +57,10 @@ // // CHECK-ASAN-FREEBSD: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-ASAN-FREEBSD-NOT: "-lc" -// CHECK-ASAN-FREEBSD: freebsd{{/|\\+}}libclang_rt.asan-i386.a" +// CHECK-ASAN-FREEBSD: "-lclang_rt.asan-i386" // CHECK-ASAN-FREEBSD: "-lpthread" // CHECK-ASAN-FREEBSD: "-lrt" +// CHECK-ASAN-FREEBSD: "-L{{.*}}freebsd" // CHECK-ASAN-FREEBSD: "-export-dynamic" // CHECK-ASAN-FREEBSD-NOT: "--dynamic-list" @@ -80,7 +81,7 @@ // // CHECK-ASAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-ASAN-LINUX-CXX-NOT: "-lc" -// CHECK-ASAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.asan-i386.a" "-no-whole-archive" +// CHECK-ASAN-LINUX-CXX: "-whole-archive" "-lclang_rt.asan-i386" "-no-whole-archive" // CHECK-ASAN-LINUX-CXX: "-lpthread" // CHECK-ASAN-LINUX-CXX: "-lrt" // CHECK-ASAN-LINUX-CXX: "-ldl" @@ -95,7 +96,7 @@ // // CHECK-ASAN-LINUX-CXX-STATIC: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-ASAN-LINUX-CXX-STATIC-NOT: stdc++ -// CHECK-ASAN-LINUX-CXX-STATIC: "-whole-archive" "{{.*}}libclang_rt.asan-i386.a" "-no-whole-archive" +// CHECK-ASAN-LINUX-CXX-STATIC: "-whole-archive" "-lclang_rt.asan-i386" "-no-whole-archive" // CHECK-ASAN-LINUX-CXX-STATIC: stdc++ // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ @@ -105,7 +106,7 @@ // // CHECK-ASAN-ARM: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-ASAN-ARM-NOT: "-lc" -// CHECK-ASAN-ARM: libclang_rt.asan-arm.a" +// CHECK-ASAN-ARM: "-lclang_rt.asan-arm" // // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target armv7l-linux-gnueabi -fsanitize=address \ @@ -114,7 +115,8 @@ // // CHECK-ASAN-ARMv7: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-ASAN-ARMv7-NOT: "-lc" -// CHECK-ASAN-ARMv7: libclang_rt.asan-arm.a" +// CHECK-ASAN-ARMv7: "-lclang_rt.asan-arm" +// // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target arm-linux-androideabi -fsanitize=address \ @@ -147,7 +149,7 @@ // // CHECK-TSAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-TSAN-LINUX-CXX-NOT: stdc++ -// CHECK-TSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.tsan-x86_64.a" "-no-whole-archive" +// CHECK-TSAN-LINUX-CXX: "-whole-archive" "-lclang_rt.tsan-x86_64" "-no-whole-archive" // CHECK-TSAN-LINUX-CXX: "-lpthread" // CHECK-TSAN-LINUX-CXX: "-lrt" // CHECK-TSAN-LINUX-CXX: "-ldl" @@ -163,7 +165,7 @@ // // CHECK-MSAN-LINUX-CXX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-MSAN-LINUX-CXX-NOT: stdc++ -// CHECK-MSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.msan-x86_64.a" "-no-whole-archive" +// CHECK-MSAN-LINUX-CXX: "-whole-archive" "-lclang_rt.msan-x86_64" "-no-whole-archive" // CHECK-MSAN-LINUX-CXX: "-lpthread" // CHECK-MSAN-LINUX-CXX: "-lrt" // CHECK-MSAN-LINUX-CXX: "-ldl" @@ -176,11 +178,11 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX %s // CHECK-UBSAN-LINUX: "{{.*}}ld{{(.exe)?}}" -// CHECK-UBSAN-LINUX-NOT: libclang_rt.asan -// CHECK-UBSAN-LINUX: "-whole-archive" "{{.*}}libclang_rt.san-i386.a" "-no-whole-archive" -// CHECK-UBSAN-LINUX-NOT: libclang_rt.asan -// CHECK-UBSAN-LINUX: "-whole-archive" "{{.*}}libclang_rt.ubsan-i386.a" "-no-whole-archive" -// CHECK-UBSAN-LINUX-NOT: libclang_rt.ubsan_cxx +// CHECK-UBSAN-LINUX-NOT: clang_rt.asan +// CHECK-UBSAN-LINUX: "-whole-archive" "-lclang_rt.san-i386" "-no-whole-archive" +// CHECK-UBSAN-LINUX-NOT: clang_rt.asan +// CHECK-UBSAN-LINUX: "-whole-archive" "-lclang_rt.ubsan-i386" "-no-whole-archive" +// CHECK-UBSAN-LINUX-NOT: clang_rt.ubsan_cxx // CHECK-UBSAN-LINUX: "-lpthread" // CHECK-UBSAN-LINUX-NOT: "-lstdc++" @@ -189,11 +191,11 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX-CXX %s // CHECK-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}" -// CHECK-UBSAN-LINUX-CXX-NOT: libclang_rt.asan -// CHECK-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.san-i386.a" "-no-whole-archive" -// CHECK-UBSAN-LINUX-CXX-NOT: libclang_rt.asan -// CHECK-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan-i386.a" "-no-whole-archive" -// CHECK-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan_cxx-i386.a" "-no-whole-archive" +// CHECK-UBSAN-LINUX-CXX-NOT: clang_rt.asan +// CHECK-UBSAN-LINUX-CXX: "-whole-archive" "-lclang_rt.san-i386" "-no-whole-archive" +// CHECK-UBSAN-LINUX-CXX-NOT: clang_rt.asan +// CHECK-UBSAN-LINUX-CXX: "-whole-archive" "-lclang_rt.ubsan-i386" "-no-whole-archive" +// CHECK-UBSAN-LINUX-CXX: "-whole-archive" "-lclang_rt.ubsan_cxx-i386" "-no-whole-archive" // CHECK-UBSAN-LINUX-CXX: "-lpthread" // CHECK-UBSAN-LINUX-CXX: "-lstdc++" @@ -202,11 +204,11 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-ASAN-UBSAN-LINUX %s // CHECK-ASAN-UBSAN-LINUX: "{{.*}}ld{{(.exe)?}}" -// CHECK-ASAN-UBSAN-LINUX-NOT: libclang_rt.san -// CHECK-ASAN-UBSAN-LINUX: "-whole-archive" "{{.*}}libclang_rt.asan-i386.a" "-no-whole-archive" -// CHECK-ASAN-UBSAN-LINUX-NOT: libclang_rt.san -// CHECK-ASAN-UBSAN-LINUX: "-whole-archive" "{{.*}}libclang_rt.ubsan-i386.a" "-no-whole-archive" -// CHECK-ASAN-UBSAN-LINUX-NOT: libclang_rt.ubsan_cxx +// CHECK-ASAN-UBSAN-LINUX-NOT: clang_rt.san +// CHECK-ASAN-UBSAN-LINUX: "-whole-archive" "-lclang_rt.asan-i386" "-no-whole-archive" +// CHECK-ASAN-UBSAN-LINUX-NOT: clang_rt.san +// CHECK-ASAN-UBSAN-LINUX: "-whole-archive" "-lclang_rt.ubsan-i386" "-no-whole-archive" +// CHECK-ASAN-UBSAN-LINUX-NOT: clang_rt.ubsan_cxx // CHECK-ASAN-UBSAN-LINUX: "-lpthread" // CHECK-ASAN-UBSAN-LINUX-NOT: "-lstdc++" @@ -215,11 +217,11 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-ASAN-UBSAN-LINUX-CXX %s // CHECK-ASAN-UBSAN-LINUX-CXX: "{{.*}}ld{{(.exe)?}}" -// CHECK-ASAN-UBSAN-LINUX-CXX-NOT: libclang_rt.san -// CHECK-ASAN-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.asan-i386.a" "-no-whole-archive" -// CHECK-ASAN-UBSAN-LINUX-CXX-NOT: libclang_rt.san -// CHECK-ASAN-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan-i386.a" "-no-whole-archive" -// CHECK-ASAN-UBSAN-LINUX-CXX: "-whole-archive" "{{.*}}libclang_rt.ubsan_cxx-i386.a" "-no-whole-archive" +// CHECK-ASAN-UBSAN-LINUX-CXX-NOT: clang_rt.san +// CHECK-ASAN-UBSAN-LINUX-CXX: "-whole-archive" "-lclang_rt.asan-i386" "-no-whole-archive" +// CHECK-ASAN-UBSAN-LINUX-CXX-NOT: clang_rt.san +// CHECK-ASAN-UBSAN-LINUX-CXX: "-whole-archive" "-lclang_rt.ubsan-i386" "-no-whole-archive" +// CHECK-ASAN-UBSAN-LINUX-CXX: "-whole-archive" "-lclang_rt.ubsan_cxx-i386" "-no-whole-archive" // CHECK-ASAN-UBSAN-LINUX-CXX: "-lpthread" // CHECK-ASAN-UBSAN-LINUX-CXX: "-lstdc++" @@ -229,7 +231,7 @@ // RUN: -shared \ // RUN: | FileCheck --check-prefix=CHECK-UBSAN-LINUX-SHARED %s // CHECK-UBSAN-LINUX-SHARED: "{{.*}}ld{{(.exe)?}}" -// CHECK-UBSAN-LINUX-SHARED: libclang_rt.ubsan-i386.a" +// CHECK-UBSAN-LINUX-SHARED: "-lclang_rt.ubsan-i386" // RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ // RUN: -target x86_64-unknown-linux -fsanitize=leak \ @@ -238,7 +240,7 @@ // // CHECK-LSAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-LSAN-LINUX-NOT: "-lc" -// CHECK-LSAN-LINUX: libclang_rt.lsan-x86_64.a" +// CHECK-LSAN-LINUX: "-lclang_rt.lsan-x86_64" // CHECK-LSAN-LINUX: "-lpthread" // CHECK-LSAN-LINUX: "-ldl" @@ -247,11 +249,11 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-LSAN-UBSAN-LINUX %s // CHECK-LSAN-UBSAN-LINUX: "{{.*}}ld{{(.exe)?}}" -// CHECK-LSAN-UBSAN-LINUX-NOT: libclang_rt.san -// CHECK-LSAN-UBSAN-LINUX: "-whole-archive" "{{.*}}libclang_rt.lsan-x86_64.a" "-no-whole-archive" -// CHECK-LSAN-UBSAN-LINUX-NOT: libclang_rt.san -// CHECK-LSAN-UBSAN-LINUX: "-whole-archive" "{{.*}}libclang_rt.ubsan-x86_64.a" "-no-whole-archive" -// CHECK-LSAN-UBSAN-LINUX-NOT: libclang_rt.ubsan_cxx +// CHECK-LSAN-UBSAN-LINUX-NOT: clang_rt.san +// CHECK-LSAN-UBSAN-LINUX: "-whole-archive" "-lclang_rt.lsan-x86_64" "-no-whole-archive" +// CHECK-LSAN-UBSAN-LINUX-NOT: clang_rt.san +// CHECK-LSAN-UBSAN-LINUX: "-whole-archive" "-lclang_rt.ubsan-x86_64" "-no-whole-archive" +// CHECK-LSAN-UBSAN-LINUX-NOT: clang_rt.ubsan_cxx // CHECK-LSAN-UBSAN-LINUX: "-lpthread" // CHECK-LSAN-UBSAN-LINUX-NOT: "-lstdc++" @@ -260,6 +262,6 @@ // RUN: --sysroot=%S/Inputs/basic_linux_tree \ // RUN: | FileCheck --check-prefix=CHECK-LSAN-ASAN-LINUX %s // CHECK-LSAN-ASAN-LINUX: "{{.*}}ld{{(.exe)?}}" -// CHECK-LSAN-ASAN-LINUX-NOT: libclang_rt.lsan -// CHECK-LSAN-ASAN-LINUX: libclang_rt.asan-x86_64 -// CHECK-LSAN-ASAN-LINUX-NOT: libclang_rt.lsan +// CHECK-LSAN-ASAN-LINUX-NOT: clang_rt.lsan +// CHECK-LSAN-ASAN-LINUX: clang_rt.asan-x86_64 +// CHECK-LSAN-ASAN-LINUX-NOT: clang_rt.lsan