Index: CMakeLists.txt =================================================================== --- CMakeLists.txt +++ CMakeLists.txt @@ -230,6 +230,8 @@ # COMPILER_RT_DEBUG_PYBOOL is used by lit.common.configured.in. pythonize_bool(COMPILER_RT_DEBUG) +option(COMPILER_RT_INCLUDE_ASAN_SHARED "Build shared version of AddressSanitizer runtime" OFF) + #================================ # Setup Compiler Flags #================================ Index: cmake/Modules/AddCompilerRT.cmake =================================================================== --- cmake/Modules/AddCompilerRT.cmake +++ cmake/Modules/AddCompilerRT.cmake @@ -37,6 +37,32 @@ COMPILE_DEFINITIONS ${LIB_DEFS}) endmacro() +# Adds shared runtime for a given architecture and puts it in the proper +# directory in the build and install trees. +# add_compiler_rt_shared_runtime( +# SOURCES +# CFLAGS +# DEFS ) +macro(add_compiler_rt_shared_runtime name arch) + if(CAN_TARGET_${arch}) + parse_arguments(LIB "SOURCES;CFLAGS;DEFS" "" ${ARGN}) + add_library(${name} SHARED ${LIB_SOURCES}) + # Setup compile flags and definitions. + set_target_compile_flags(${name} + ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS}) + set_property(TARGET ${name} APPEND PROPERTY + COMPILE_DEFINITIONS ${LIB_DEFS}) + # Setup correct output directory in the build tree. + set_target_properties(${name} PROPERTIES + LIBRARY_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR}) + # Add installation command. + install(TARGETS ${name} + LIBRARY DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}) + else() + message(FATAL_ERROR "Archtecture ${arch} can't be targeted") + endif() +endmacro() + # Adds static runtime for a given architecture and puts it in the proper # directory in the build and install trees. # add_compiler_rt_static_runtime( Index: lib/asan/CMakeLists.txt =================================================================== --- lib/asan/CMakeLists.txt +++ lib/asan/CMakeLists.txt @@ -21,7 +21,6 @@ asan_new_delete.cc asan_poisoning.cc asan_posix.cc - asan_preinit.cc asan_report.cc asan_rtl.cc asan_stack.cc @@ -29,6 +28,9 @@ asan_thread.cc asan_win.cc) +set(ASAN_PREINIT_SOURCES + asan_preinit.cc) + include_directories(..) if(ANDROID) @@ -69,8 +71,18 @@ else() foreach(arch ${ASAN_SUPPORTED_ARCH}) add_compiler_rt_object_library(RTAsan ${arch} - SOURCES ${ASAN_SOURCES} CFLAGS ${ASAN_CFLAGS} + SOURCES ${ASAN_SOURCES} ${ASAN_PREINIT_SOURCES} CFLAGS ${ASAN_CFLAGS} DEFS ${ASAN_COMMON_DEFINITIONS}) + if (COMPILER_RT_INCLUDE_ASAN_DYNAMIC) + set(ASAN_DYNAMIC_DEFINITIONS + ${ASAN_COMMON_DEFINITIONS} ASAN_DYNAMIC) + add_compiler_rt_object_library(RTAsan_preinit ${arch} + SOURCES ${ASAN_PREINIT_SOURCES} CFLAGS ${ASAN_CFLAGS} + DEFS ${ASAN_COMMON_DEFINITIONS}) + add_compiler_rt_object_library(RTAsan_dynamic ${arch} + SOURCES ${ASAN_SOURCES} CFLAGS ${ASAN_CFLAGS} + DEFS ${ASAN_DYNAMIC_DEFINITIONS}) + endif() endforeach() endif() @@ -108,24 +120,53 @@ else() # Build separate libraries for each target. foreach(arch ${ASAN_SUPPORTED_ARCH}) - set(ASAN_RUNTIME_OBJECTS - $ + set(ASAN_COMMON_RUNTIME_OBJECTS $ $ $) if (NOT WIN32) # We can't build Leak Sanitizer on Windows yet. - list(APPEND ASAN_RUNTIME_OBJECTS $) + list(APPEND ASAN_COMMON_RUNTIME_OBJECTS $) endif() + set(ASAN_RUNTIME_OBJECTS + $ + ${ASAN_COMMON_RUNTIME_OBJECTS}) + add_compiler_rt_static_runtime(clang_rt.asan-${arch} ${arch} SOURCES ${ASAN_RUNTIME_OBJECTS} CFLAGS ${ASAN_CFLAGS} DEFS ${ASAN_COMMON_DEFINITIONS}) - add_dependencies(asan clang_rt.asan-${arch}) + add_dependencies(asan clang_rt.asan-${arch} clang_rt.asan-${arch}) + + if (COMPILER_RT_INCLUDE_ASAN_DYNAMIC) + set(ASAN_DYNAMIC_RUNTIME_OBJECTS + $ + ${ASAN_COMMON_RUNTIME_OBJECTS}) + add_compiler_rt_shared_runtime(clang_rt.asan-${arch}-dynamic ${arch} + SOURCES ${ASAN_DYNAMIC_RUNTIME_OBJECTS} + CFLAGS ${ASAN_CFLAGS} + DEFS ${ASAN_DYNAMIC_DEFINITIONS}) + target_link_libraries(clang_rt.asan-${arch}-dynamic pthread stdc++ dl m c) + add_dependencies(asan clang_rt.asan-${arch}-dynamic) + + set(ASAN_PREINIT_RUNTIME_OBJECTS + $) + add_compiler_rt_static_runtime(clang_rt.asan-${arch}-preinit ${arch} + SOURCES ${ASAN_PREINIT_RUNTIME_OBJECTS} + CFLAGS ${ASAN_CFLAGS} + DEFS ${ASAN_DYNAMIC_DEFINITIONS}) + add_dependencies(asan clang_rt.asan-${arch}-preinit) + endif() + if (UNIX AND NOT ${arch} STREQUAL "i386") add_sanitizer_rt_symbols(clang_rt.asan-${arch} asan.syms.extra) add_dependencies(asan clang_rt.asan-${arch}-symbols) + + if (COMPILER_RT_INCLUDE_ASAN_DYNAMIC) + add_sanitizer_rt_symbols(clang_rt.asan-${arch}-dynamic asan.syms.extra) + add_dependencies(asan clang_rt.asan-${arch}-dynamic-symbols) + endif() endif() if (WIN32) Index: lib/asan/asan_interface_internal.h =================================================================== --- lib/asan/asan_interface_internal.h +++ lib/asan/asan_interface_internal.h @@ -30,8 +30,8 @@ // v2=>v3: stack frame description (created by the compiler) // contains the function PC as the 3-rd field (see // DescribeAddressIfStack). - SANITIZER_INTERFACE_ATTRIBUTE void __asan_init_v3(); #define __asan_init __asan_init_v3 + SANITIZER_INTERFACE_ATTRIBUTE void __asan_init_v3(); // This structure describes an instrumented global variable. struct __asan_global { Index: lib/asan/asan_internal.h =================================================================== --- lib/asan/asan_internal.h +++ lib/asan/asan_internal.h @@ -70,6 +70,12 @@ // asan_linux.cc / asan_mac.cc / asan_win.cc void *AsanDoesNotSupportStaticLinkage(); +// asan_linux.cc / asan_mac.cc / asan_win.cc +void AsanCheckDynamicRTPrereqs(); + +// asan_linux.cc / asan_mac.cc / asan_win.cc +void AsanCheckIncompatibleRT(); + void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp); void AsanOnSIGSEGV(int, void *siginfo, void *context); Index: lib/asan/asan_linux.cc =================================================================== --- lib/asan/asan_linux.cc +++ lib/asan/asan_linux.cc @@ -35,12 +35,13 @@ #if SANITIZER_ANDROID #include +extern "C" void* _DYNAMIC; #else #include +#include +#include #endif -extern "C" void* _DYNAMIC; - namespace __asan { void MaybeReexec() { @@ -52,6 +53,51 @@ return &_DYNAMIC; // defined in link.h } +static int DsoCallback(struct dl_phdr_info *info, size_t size, + void *data) { + // Continue until the first dynamic library is found + if (!info->dlpi_name || info->dlpi_name[0] == 0) + return 0; + + *(const char **)data = info->dlpi_name; + return 1; +} + +void AsanCheckDynamicRTPrereqs() { + // FIXME: can we do something like this for Android? +#if !SANITIZER_ANDROID + // Asan dynamic RT should be the first dynamic library in the list + const char *first_library_name = 0; + dl_iterate_phdr(DsoCallback, &first_library_name); + if (first_library_name + && !internal_strstr(first_library_name, "libclang_rt.asan") + && !internal_strstr(first_library_name, "libasan.so")) { + Report( + "ASan runtime does not come first in initial library list; " + "you should either link to your application or " + "manually preload it with LD_PRELOAD.\n"); + Die(); + } + +#endif +} + +void AsanCheckIncompatibleRT() { +#if !SANITIZER_ANDROID + const char *badsym; +#if ASAN_DYNAMIC + badsym = "__asan_static"; +#else + badsym = "__asan_dynamic"; +#endif + if (dlsym(RTLD_DEFAULT, badsym)) { + Report("Your application is linked against " + "incompatible ASan runtimes.\n"); + Die(); + } +#endif +} + void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { #if defined(__arm__) ucontext_t *ucontext = (ucontext_t*)context; Index: lib/asan/asan_mac.cc =================================================================== --- lib/asan/asan_mac.cc +++ lib/asan/asan_mac.cc @@ -199,6 +199,14 @@ return 0; } +// Likewise. +void AsanCheckDynamicRTPrereqs() { +} + +// Likewise. +void AsanCheckIncompatibleRT() { +} + bool AsanInterceptsSignal(int signum) { return (signum == SIGSEGV || signum == SIGBUS) && common_flags()->handle_segv; Index: lib/asan/asan_rtl.cc =================================================================== --- lib/asan/asan_rtl.cc +++ lib/asan/asan_rtl.cc @@ -553,6 +553,24 @@ AsanInitInternal(); } +#ifdef ASAN_DYNAMIC +// Initialize runtime in case it's LD_PRELOAD-ed into unsanitized executable +// (and thus normal initializer from .preinit_array haven't run). + +class AsanInitializer { +public: // NOLINT + AsanInitializer() { + AsanCheckIncompatibleRT(); + if (!asan_inited) { + AsanCheckDynamicRTPrereqs(); + __asan_init(); + } + } +}; + +static AsanInitializer asan_initializer; +#endif + } // namespace __asan // ---------------------- Interface ---------------- {{{1 @@ -604,6 +622,17 @@ // Initialize as requested from instrumented application code. // We use this call as a trigger to wake up ASan from deactivated state. void __asan_init() { + AsanCheckIncompatibleRT(); AsanActivate(); AsanInitInternal(); } + +extern "C" { +SANITIZER_INTERFACE_ATTRIBUTE +#ifdef ASAN_DYNAMIC +int __asan_dynamic; +#else +int __asan_static; +#endif +}; + Index: lib/asan/asan_win.cc =================================================================== --- lib/asan/asan_win.cc +++ lib/asan/asan_win.cc @@ -70,6 +70,12 @@ return 0; } +void AsanCheckDynamicRTPrereqs() { +} + +void AsanCheckIncompatibleRT() { +} + void AsanPlatformThreadInit() { // Nothing here for now. } Index: lib/sanitizer_common/sanitizer_internal_defs.h =================================================================== --- lib/sanitizer_common/sanitizer_internal_defs.h +++ lib/sanitizer_common/sanitizer_internal_defs.h @@ -147,7 +147,12 @@ # define FORMAT(f, a) __attribute__((format(printf, f, a))) # define NOINLINE __attribute__((noinline)) # define NORETURN __attribute__((noreturn)) -# define THREADLOCAL __thread +# ifdef ASAN_DYNAMIC +# define THREADLOCAL __thread __attribute__((tls_model("initial-exec"))) +# else +// FIXME: mark as local-exec? +# define THREADLOCAL __thread +# endif # define NOTHROW throw() # define LIKELY(x) __builtin_expect(!!(x), 1) # define UNLIKELY(x) __builtin_expect(!!(x), 0) Index: test/asan/CMakeLists.txt =================================================================== --- test/asan/CMakeLists.txt +++ test/asan/CMakeLists.txt @@ -21,29 +21,51 @@ set(ASAN_TEST_CONFIG_SUFFIX "64") set(ASAN_TEST_BITS "64") set(ASAN_TEST_TARGET_CFLAGS ${TARGET_64_BIT_CFLAGS}) + set(ASAN_TEST_DYNAMIC False) configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in ${CMAKE_CURRENT_BINARY_DIR}/64bitConfig/lit.site.cfg ) list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/64bitConfig) + if(COMPILER_RT_INCLUDE_ASAN_DYNAMIC) + set(ASAN_TEST_DYNAMIC True) + configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/64bitConfig-dynamic/lit.site.cfg) + list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/64bitConfig-dynamic) + endif() endif() if(CAN_TARGET_i386) set(ASAN_TEST_CONFIG_SUFFIX "32") set(ASAN_TEST_BITS "32") set(ASAN_TEST_TARGET_CFLAGS ${TARGET_32_BIT_CFLAGS}) + set(ASAN_TEST_DYNAMIC False) configure_lit_site_cfg( ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig/lit.site.cfg ) list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig) + if(COMPILER_RT_INCLUDE_ASAN_DYNAMIC) + set(ASAN_TEST_DYNAMIC True) + configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig-dynamic/lit.site.cfg) + list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig-dynamic) + endif() endif() if(COMPILER_RT_INCLUDE_TESTS) -configure_lit_site_cfg( - ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in - ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg - ) + set(ASAN_TEST_DYNAMIC False) + configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg) + if(COMPILER_RT_INCLUDE_ASAN_DYNAMIC) + set(ASAN_TEST_DYNAMIC True) + configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/Unit-dynamic/lit.site.cfg) + endif() endif() set(ASAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS}) @@ -55,6 +77,9 @@ if(COMPILER_RT_INCLUDE_TESTS AND NOT CAN_TARGET_arm_android) list(APPEND ASAN_TEST_DEPS AsanUnitTests) list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit) + if(COMPILER_RT_INCLUDE_ASAN_DYNAMIC) + list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit-dynamic) + endif() endif() add_lit_testsuite(check-asan "Running the AddressSanitizer tests" ${ASAN_TESTSUITES} Index: test/asan/TestCases/Linux/DynamicRT/asan_dlopen_test.cc =================================================================== --- test/asan/TestCases/Linux/DynamicRT/asan_dlopen_test.cc +++ test/asan/TestCases/Linux/DynamicRT/asan_dlopen_test.cc @@ -0,0 +1,14 @@ +// Test that dlopen of runtime is detected. +// +// RUN: %clangxx %s -DRT=\"%shared_libasan\" -o %t -ldl +// RUN: not %t 2>&1 | FileCheck %s + +#include + +int main(int argc, char **argv) { + dlopen(RT, RTLD_LAZY); + return 0; +} + +// CHECK: ASan runtime does not come first in initial library list + Index: test/asan/TestCases/Linux/DynamicRT/asan_preload_test-1.cc =================================================================== --- test/asan/TestCases/Linux/DynamicRT/asan_preload_test-1.cc +++ test/asan/TestCases/Linux/DynamicRT/asan_preload_test-1.cc @@ -0,0 +1,25 @@ +// Test if legacy executables work with sanitized shared libs +// and preloaded runtime. +// +// RUN: %clangxx -DBUILD_SO=1 -fPIC -shared %s -o %t.so +// RUN: %clangxx %s %t.so -o %t +// +// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t.so +// RUN: LD_PRELOAD=%shared_libasan not %t 2>&1 | FileCheck %s + +#if BUILD_SO +char dummy; +void do_access(const void *p) { + // CHECK: AddressSanitizer: heap-buffer-overflow + dummy = ((const char *)p)[1]; +} +#else +#include +extern void do_access(const void *p); +int main(int argc, char **argv) { + void *p = malloc(1); + do_access(p); + free(p); + return 0; +} +#endif Index: test/asan/TestCases/Linux/DynamicRT/asan_preload_test-2.cc =================================================================== --- test/asan/TestCases/Linux/DynamicRT/asan_preload_test-2.cc +++ test/asan/TestCases/Linux/DynamicRT/asan_preload_test-2.cc @@ -0,0 +1,20 @@ +// Test that preloaded runtime works with unsanitized executables. +// +// RUN: %clangxx %s -o %t +// RUN: LD_PRELOAD=%shared_libasan not %t 2>&1 | FileCheck %s + +#include + +extern "C" void *memset(void *p, int val, size_t n); + +void do_access(void *p) { + // CHECK: AddressSanitizer: heap-buffer-overflow + memset(p, 0, 2); +} + +int main(int argc, char **argv) { + void *p = malloc(1); + do_access(p); + return 0; +} + Index: test/asan/TestCases/Linux/DynamicRT/asan_rt_confict_test-1.cc =================================================================== --- test/asan/TestCases/Linux/DynamicRT/asan_rt_confict_test-1.cc +++ test/asan/TestCases/Linux/DynamicRT/asan_rt_confict_test-1.cc @@ -0,0 +1,11 @@ +// Test that incompatible runtimes are detected. +// +// RUN: %clangxx_asan_static %s -o %t +// RUN: LD_PRELOAD=%shared_libasan not %t 2>&1 | FileCheck %s + +#include +int main(int argc, char **argv) { + return 0; +} + +// CHECK: Your application is linked against incompatible ASan runtimes Index: test/asan/TestCases/Linux/DynamicRT/lit.local.cfg =================================================================== --- test/asan/TestCases/Linux/DynamicRT/lit.local.cfg +++ test/asan/TestCases/Linux/DynamicRT/lit.local.cfg @@ -0,0 +1,3 @@ +if not config.asan_dynamic: + config.unsupported = True + Index: test/asan/TestCases/Linux/interception_malloc_test.cc =================================================================== --- test/asan/TestCases/Linux/interception_malloc_test.cc +++ test/asan/TestCases/Linux/interception_malloc_test.cc @@ -9,7 +9,9 @@ #include extern "C" void *__interceptor_malloc(size_t size); -extern "C" void *malloc(size_t size) { +extern "C" +__attribute__((no_sanitize_address)) // Malloc may be called from dlsym in __asan_init +void *malloc(size_t size) { write(2, "malloc call\n", sizeof("malloc call\n") - 1); return __interceptor_malloc(size); } Index: test/asan/TestCases/sanity_check_pure_c.c =================================================================== --- test/asan/TestCases/sanity_check_pure_c.c +++ test/asan/TestCases/sanity_check_pure_c.c @@ -3,7 +3,7 @@ // RUN: not %t 2>&1 | FileCheck %s // Sanity checking a test in pure C with -pie. -// RUN: %clang_asan -O2 %s -pie -o %t +// RUN: %clang_asan -O2 %s -pie -fPIE -o %t // RUN: not %t 2>&1 | FileCheck %s #include Index: test/asan/TestCases/start-deactivated.cc =================================================================== --- test/asan/TestCases/start-deactivated.cc +++ test/asan/TestCases/start-deactivated.cc @@ -7,6 +7,10 @@ // RUN: %clangxx -O0 %s -c -o %t.o // RUN: %clangxx_asan -O0 %t.o -o %t // RUN: ASAN_OPTIONS=start_deactivated=1 not %t 2>&1 | FileCheck %s +// +// dlsym's that check for __asan_static/__asan_dynamic call dlerror +// which in turn calls malloc which activates Asan: +// XFAIL: * #include #include Index: test/asan/Unit/lit.site.cfg.in =================================================================== --- test/asan/Unit/lit.site.cfg.in +++ test/asan/Unit/lit.site.cfg.in @@ -12,6 +12,7 @@ # FIXME: De-hardcode this path. config.test_exec_root = "@COMPILER_RT_BINARY_DIR@/lib/asan/tests" config.test_source_root = config.test_exec_root +config.asan_dynamic = @ASAN_TEST_DYNAMIC@ # Enable leak detection in ASan unit tests on x86_64-linux. if config.host_os == 'Linux' and config.host_arch == 'x86_64': Index: test/asan/lit.cfg =================================================================== --- test/asan/lit.cfg +++ test/asan/lit.cfg @@ -11,6 +11,11 @@ "to lit.site.cfg " % attr_name) return attr_value +def push_ld_library_path(config, new_path): + new_ld_library_path = os.path.pathsep.join( + (new_path, config.environment['LD_LIBRARY_PATH'])) + config.environment['LD_LIBRARY_PATH'] = new_ld_library_path + # Setup config name. config.name = 'AddressSanitizer' + config.name_suffix @@ -34,6 +39,12 @@ "-g"] + target_cflags clang_asan_cxxflags = config.cxx_mode_flags + clang_asan_cflags +if config.asan_dynamic: + clang_asan_static_cflags = list(clang_asan_cflags) + clang_asan_cflags.append('-shared-libasan') + clang_asan_static_cxxflags = list(clang_asan_cxxflags) + clang_asan_cxxflags.append('-shared-libasan') + asan_lit_source_dir = get_required_attr(config, "asan_lit_source_dir") if config.android == "TRUE": config.available_features.add('android') @@ -49,6 +60,10 @@ config.substitutions.append( ("%clangxx ", build_invocation(target_cxxflags)) ) config.substitutions.append( ("%clang_asan ", build_invocation(clang_asan_cflags)) ) config.substitutions.append( ("%clangxx_asan ", build_invocation(clang_asan_cxxflags)) ) +config.substitutions.append( ("%shared_libasan", "libclang_rt.asan-%s-dynamic.so" % config.host_arch)) +if config.asan_dynamic: + config.substitutions.append( ("%clang_asan_static ", build_invocation(clang_asan_static_cflags)) ) + config.substitutions.append( ("%clangxx_asan_static ", build_invocation(clang_asan_static_cxxflags)) ) # FIXME: De-hardcode this path. asan_source_dir = os.path.join( @@ -69,14 +84,16 @@ if config.host_os == 'Linux' and config.bits == '64': config.environment['ASAN_OPTIONS'] = 'detect_leaks=1' -# GCC-ASan uses dynamic runtime by default, so we have to set LD_LIBRARY_PATH -# to pick it up properly. +# Set LD_LIBRARY_PATH to pick dynamic runtime up properly. +if config.asan_dynamic: + libasan_dir = config.compiler_rt_libdir + push_ld_library_path(config, libasan_dir) + +# GCC-ASan uses dynamic runtime by default. if config.compiler_id == 'GNU': gcc_dir = os.path.dirname(config.clang) libasan_dir = os.path.join(gcc_dir, "..", "lib" + config.bits) - new_ld_library_path = os.path.pathsep.join( - (libasan_dir, config.environment['LD_LIBRARY_PATH'])) - config.environment['LD_LIBRARY_PATH'] = new_ld_library_path + push_ld_library_path(config, libasan_dir) # Default test suffixes. config.suffixes = ['.c', '.cc', '.cpp'] Index: test/asan/lit.site.cfg.in =================================================================== --- test/asan/lit.site.cfg.in +++ test/asan/lit.site.cfg.in @@ -9,6 +9,7 @@ config.llvm_tools_dir = "@ASAN_TEST_LLVM_TOOLS_DIR@" config.bits = "@ASAN_TEST_BITS@" config.android = "@CAN_TARGET_arm_android@" +config.asan_dynamic = @ASAN_TEST_DYNAMIC@ # Load common config for all compiler-rt lit tests. lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured") Index: test/lit.common.configured.in =================================================================== --- test/lit.common.configured.in +++ test/lit.common.configured.in @@ -20,6 +20,7 @@ set_default("compiler_rt_arch", "@COMPILER_RT_SUPPORTED_ARCH@") set_default("python_executable", "@PYTHON_EXECUTABLE@") set_default("compiler_rt_debug", @COMPILER_RT_DEBUG_PYBOOL@) +set_default("compiler_rt_libdir", "@COMPILER_RT_LIBRARY_OUTPUT_DIR@") # LLVM tools dir can be passed in lit parameters, so try to # apply substitution.