[compiler-rt] r205308 - [ASan] Optional support for dynamic ASan runtime on Linux.

Alexey Samsonov samsonov at google.com
Tue Apr 1 06:16:31 PDT 2014


Author: samsonov
Date: Tue Apr  1 08:16:30 2014
New Revision: 205308

URL: http://llvm.org/viewvc/llvm-project?rev=205308&view=rev
Log:
[ASan] Optional support for dynamic ASan runtime on Linux.

Based on http://llvm-reviews.chandlerc.com/D3042 by Yuri Gribov!

Added:
    compiler-rt/trunk/test/asan/TestCases/Linux/asan_dlopen_test.cc
    compiler-rt/trunk/test/asan/TestCases/Linux/asan_preload_test-1.cc
    compiler-rt/trunk/test/asan/TestCases/Linux/asan_preload_test-2.cc
    compiler-rt/trunk/test/asan/TestCases/Linux/asan_rt_confict_test-1.cc
    compiler-rt/trunk/test/asan/TestCases/Linux/asan_rt_confict_test-2.cc
Modified:
    compiler-rt/trunk/CMakeLists.txt
    compiler-rt/trunk/cmake/Modules/AddCompilerRT.cmake
    compiler-rt/trunk/cmake/config-ix.cmake
    compiler-rt/trunk/lib/asan/CMakeLists.txt
    compiler-rt/trunk/lib/asan/asan_internal.h
    compiler-rt/trunk/lib/asan/asan_linux.cc
    compiler-rt/trunk/lib/asan/asan_mac.cc
    compiler-rt/trunk/lib/asan/asan_rtl.cc
    compiler-rt/trunk/lib/asan/asan_win.cc
    compiler-rt/trunk/lib/asan/tests/CMakeLists.txt
    compiler-rt/trunk/test/asan/CMakeLists.txt
    compiler-rt/trunk/test/asan/TestCases/Linux/interface_symbols_linux.c
    compiler-rt/trunk/test/asan/TestCases/sanity_check_pure_c.c
    compiler-rt/trunk/test/asan/Unit/lit.site.cfg.in
    compiler-rt/trunk/test/asan/lit.cfg
    compiler-rt/trunk/test/asan/lit.site.cfg.in
    compiler-rt/trunk/test/lit.common.configured.in
    compiler-rt/trunk/unittests/lit.common.unit.configured.in

Modified: compiler-rt/trunk/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/CMakeLists.txt?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/CMakeLists.txt (original)
+++ compiler-rt/trunk/CMakeLists.txt Tue Apr  1 08:16:30 2014
@@ -231,6 +231,8 @@ option(COMPILER_RT_DEBUG "Build runtimes
 # COMPILER_RT_DEBUG_PYBOOL is used by lit.common.configured.in.
 pythonize_bool(COMPILER_RT_DEBUG)
 
+option(COMPILER_RT_BUILD_SHARED_ASAN "Build shared version of AddressSanitizer runtime" OFF)
+
 #================================
 # Setup Compiler Flags
 #================================

Modified: compiler-rt/trunk/cmake/Modules/AddCompilerRT.cmake
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/cmake/Modules/AddCompilerRT.cmake?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/cmake/Modules/AddCompilerRT.cmake (original)
+++ compiler-rt/trunk/cmake/Modules/AddCompilerRT.cmake Tue Apr  1 08:16:30 2014
@@ -45,7 +45,7 @@ endmacro()
 #                         DEFS <compile definitions>)
 macro(add_compiler_rt_runtime name arch type)
   if(CAN_TARGET_${arch})
-    parse_arguments(LIB "SOURCES;CFLAGS;DEFS" "" ${ARGN})
+    parse_arguments(LIB "SOURCES;CFLAGS;DEFS;OUTPUT_NAME" "" ${ARGN})
     add_library(${name} ${type} ${LIB_SOURCES})
     # Setup compile flags and definitions.
     set_target_compile_flags(${name}
@@ -58,6 +58,10 @@ macro(add_compiler_rt_runtime name arch
     set_target_properties(${name} PROPERTIES
       ARCHIVE_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR}
       LIBRARY_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR})
+    if (LIB_OUTPUT_NAME)
+      set_target_properties(${name} PROPERTIES
+        OUTPUT_NAME ${LIB_OUTPUT_NAME})
+    endif()
     # Add installation command.
     install(TARGETS ${name}
       ARCHIVE DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}

Modified: compiler-rt/trunk/cmake/config-ix.cmake
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/cmake/config-ix.cmake?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/cmake/config-ix.cmake (original)
+++ compiler-rt/trunk/cmake/config-ix.cmake Tue Apr  1 08:16:30 2014
@@ -15,6 +15,7 @@ check_cxx_compiler_flag(-fno-rtti
 check_cxx_compiler_flag(-ffreestanding       COMPILER_RT_HAS_FFREESTANDING_FLAG)
 check_cxx_compiler_flag("-Werror -fno-function-sections" COMPILER_RT_HAS_FNO_FUNCTION_SECTIONS_FLAG)
 check_cxx_compiler_flag(-std=c++11           COMPILER_RT_HAS_STD_CXX11_FLAG)
+check_cxx_compiler_flag(-ftls-model=initial-exec COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC)
 
 check_cxx_compiler_flag(/GR COMPILER_RT_HAS_GR_FLAG)
 check_cxx_compiler_flag(/GS COMPILER_RT_HAS_GS_FLAG)

Modified: compiler-rt/trunk/lib/asan/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/CMakeLists.txt?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/asan/CMakeLists.txt Tue Apr  1 08:16:30 2014
@@ -21,7 +21,6 @@ set(ASAN_SOURCES
   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 @@ set(ASAN_SOURCES
   asan_thread.cc
   asan_win.cc)
 
+set(ASAN_PREINIT_SOURCES
+  asan_preinit.cc)
+
 include_directories(..)
 
 if(ANDROID)
@@ -46,6 +48,17 @@ if(ANDROID)
     ASAN_LOW_MEMORY=1)
 endif()
 
+set(ASAN_DYNAMIC_DEFINITIONS
+  ${ASAN_COMMON_DEFINITIONS} ASAN_DYNAMIC=1)
+
+set(ASAN_DYNAMIC_CFLAGS ${ASAN_CFLAGS})
+append_if(COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC
+  -ftls-model=initial-exec ASAN_DYNAMIC_CFLAGS)
+
+set(ASAN_DYNAMIC_LIBS stdc++ m c)
+append_if(COMPILER_RT_HAS_LIBPTHREAD pthread ASAN_DYNAMIC_LIBS)
+append_if(COMPILER_RT_HAS_LIBDL dl ASAN_DYNAMIC_LIBS)
+
 if (NOT MSVC)
   set(ASAN_ASM_SOURCES asan_asm_instrumentation.S)
   set_source_files_properties(${ASAN_ASM_SOURCES} PROPERTIES LANGUAGE C)
@@ -71,6 +84,14 @@ else()
     add_compiler_rt_object_library(RTAsan ${arch}
       SOURCES ${ASAN_SOURCES} CFLAGS ${ASAN_CFLAGS}
       DEFS ${ASAN_COMMON_DEFINITIONS})
+    add_compiler_rt_object_library(RTAsan_preinit ${arch}
+      SOURCES ${ASAN_PREINIT_SOURCES} CFLAGS ${ASAN_CFLAGS}
+      DEFS ${ASAN_COMMON_DEFINITIONS})
+    if (COMPILER_RT_BUILD_SHARED_ASAN)
+      add_compiler_rt_object_library(RTAsan_dynamic ${arch}
+        SOURCES ${ASAN_SOURCES} CFLAGS ${ASAN_DYNAMIC_CFLAGS}
+        DEFS ${ASAN_DYNAMIC_DEFINITIONS})
+    endif()
   endforeach()
 endif()
 
@@ -103,21 +124,41 @@ elseif(ANDROID)
 else()
   # Build separate libraries for each target.
   foreach(arch ${ASAN_SUPPORTED_ARCH})
-    set(ASAN_RUNTIME_OBJECTS
-      $<TARGET_OBJECTS:RTAsan.${arch}>
+    set(ASAN_COMMON_RUNTIME_OBJECTS
       $<TARGET_OBJECTS:RTInterception.${arch}>
       $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
       $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>)
     if (NOT WIN32)
       # We can't build Leak Sanitizer on Windows yet.
-      list(APPEND ASAN_RUNTIME_OBJECTS $<TARGET_OBJECTS:RTLSanCommon.${arch}>)
+      list(APPEND ASAN_COMMON_RUNTIME_OBJECTS
+           $<TARGET_OBJECTS:RTLSanCommon.${arch}>)
     endif()
 
     add_compiler_rt_runtime(clang_rt.asan-${arch} ${arch} STATIC
-      SOURCES ${ASAN_RUNTIME_OBJECTS}
+      SOURCES $<TARGET_OBJECTS:RTAsan_preinit.${arch}>
+              $<TARGET_OBJECTS:RTAsan.${arch}>
+              ${ASAN_COMMON_RUNTIME_OBJECTS}
       CFLAGS ${ASAN_CFLAGS}
       DEFS ${ASAN_COMMON_DEFINITIONS})
     add_dependencies(asan clang_rt.asan-${arch})
+
+    if (COMPILER_RT_BUILD_SHARED_ASAN)
+      add_compiler_rt_runtime(clang_rt.asan-preinit-${arch} ${arch} STATIC
+        SOURCES $<TARGET_OBJECTS:RTAsan_preinit.${arch}>
+        CFLAGS ${ASAN_CFLAGS}
+        DEFS ${ASAN_COMMON_DEFINITIONS})
+      add_dependencies(asan clang_rt.asan-preinit-${arch})
+
+      add_compiler_rt_runtime(clang_rt.asan-dynamic-${arch} ${arch} SHARED
+        OUTPUT_NAME clang_rt.asan-${arch}
+        SOURCES $<TARGET_OBJECTS:RTAsan_dynamic.${arch}>
+                ${ASAN_COMMON_RUNTIME_OBJECTS}
+        CFLAGS ${ASAN_DYNAMIC_CFLAGS}
+        DEFS ${ASAN_DYNAMIC_DEFINITIONS})
+      target_link_libraries(clang_rt.asan-dynamic-${arch} ${ASAN_DYNAMIC_LIBS})
+      add_dependencies(asan clang_rt.asan-dynamic-${arch})
+    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)

Modified: compiler-rt/trunk/lib/asan/asan_internal.h
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_internal.h?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_internal.h (original)
+++ compiler-rt/trunk/lib/asan/asan_internal.h Tue Apr  1 08:16:30 2014
@@ -49,6 +49,10 @@
 # define ASAN_USE_PREINIT_ARRAY (SANITIZER_LINUX && !SANITIZER_ANDROID)
 #endif
 
+#ifndef ASAN_DYNAMIC
+# define ASAN_DYNAMIC 0
+#endif
+
 // All internal functions in asan reside inside the __asan namespace
 // to avoid namespace collisions with the user programs.
 // Seperate namespace also makes it simpler to distinguish the asan run-time
@@ -69,6 +73,8 @@ void ReplaceSystemMalloc();
 
 // asan_linux.cc / asan_mac.cc / asan_win.cc
 void *AsanDoesNotSupportStaticLinkage();
+void AsanCheckDynamicRTPrereqs();
+void AsanCheckIncompatibleRT();
 
 void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp);
 void AsanOnSIGSEGV(int, void *siginfo, void *context);

Modified: compiler-rt/trunk/lib/asan/asan_linux.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_linux.cc?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_linux.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_linux.cc Tue Apr  1 08:16:30 2014
@@ -35,8 +35,11 @@
 
 #if SANITIZER_ANDROID
 #include <ucontext.h>
+extern "C" void* _DYNAMIC;
 #else
 #include <sys/ucontext.h>
+#include <dlfcn.h>
+#include <link.h>
 #endif
 
 // x86_64 FreeBSD 9.2 and older define 64-bit register names in both 64-bit
@@ -50,7 +53,17 @@
 # endif
 #endif
 
-extern "C" void* _DYNAMIC;
+typedef enum {
+  ASAN_RT_VERSION_UNDEFINED = 0,
+  ASAN_RT_VERSION_DYNAMIC,
+  ASAN_RT_VERSION_STATIC,
+} asan_rt_version_t;
+
+// FIXME: perhaps also store abi version here?
+extern "C" {
+SANITIZER_INTERFACE_ATTRIBUTE
+asan_rt_version_t  __asan_rt_version;
+}
 
 namespace __asan {
 
@@ -63,6 +76,67 @@ void *AsanDoesNotSupportStaticLinkage()
   return &_DYNAMIC;  // defined in link.h
 }
 
+static int FindFirstDSOCallback(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;
+}
+
+static bool IsDynamicRTName(const char *libname) {
+  return internal_strstr(libname, "libclang_rt.asan") ||
+    internal_strstr(libname, "libasan.so");
+}
+
+void AsanCheckDynamicRTPrereqs() {
+  // FIXME: can we do something like this for Android?
+#if !SANITIZER_ANDROID
+  // Ensure that dynamic RT is the first DSO in the list
+  const char *first_dso_name = 0;
+  dl_iterate_phdr(FindFirstDSOCallback, &first_dso_name);
+  if (first_dso_name && !IsDynamicRTName(first_dso_name)) {
+    Report("ASan runtime does not come first in initial library list; "
+           "you should either link runtime to your application or "
+           "manually preload it with LD_PRELOAD.\n");
+    Die();
+  }
+#endif
+}
+
+void AsanCheckIncompatibleRT() {
+#if !SANITIZER_ANDROID
+  if (ASAN_DYNAMIC) {
+    if (__asan_rt_version == ASAN_RT_VERSION_UNDEFINED) {
+      __asan_rt_version = ASAN_RT_VERSION_DYNAMIC;
+    } else if (__asan_rt_version != ASAN_RT_VERSION_DYNAMIC) {
+      Report("Your application is linked against "
+             "incompatible ASan runtimes.\n");
+      Die();
+    }
+  } else {
+    // Ensure that dynamic runtime is not present. We should detect it
+    // as early as possible, otherwise ASan interceptors could bind to
+    // the functions in dynamic ASan runtime instead of the functions in
+    // system libraries, causing crashes later in ASan initialization.
+    MemoryMappingLayout proc_maps(/*cache_enabled*/true);
+    char filename[128];
+    while (proc_maps.Next(0, 0, 0, filename, sizeof(filename), 0)) {
+      if (IsDynamicRTName(filename)) {
+        Report("Your application is linked against "
+               "incompatible ASan runtimes.\n");
+        Die();
+      }
+    }
+
+    CHECK_NE(__asan_rt_version, ASAN_RT_VERSION_DYNAMIC);
+    __asan_rt_version = ASAN_RT_VERSION_STATIC;
+  }
+#endif
+}
+
 void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
 #if defined(__arm__)
   ucontext_t *ucontext = (ucontext_t*)context;

Modified: compiler-rt/trunk/lib/asan/asan_mac.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_mac.cc?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_mac.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_mac.cc Tue Apr  1 08:16:30 2014
@@ -199,6 +199,12 @@ void *AsanDoesNotSupportStaticLinkage()
   return 0;
 }
 
+// No-op. Mac does not support static linkage anyway.
+void AsanCheckDynamicRTPrereqs() {}
+
+// No-op. Mac does not support static linkage anyway.
+void AsanCheckIncompatibleRT() {}
+
 bool AsanInterceptsSignal(int signum) {
   return (signum == SIGSEGV || signum == SIGBUS) &&
          common_flags()->handle_segv;

Modified: compiler-rt/trunk/lib/asan/asan_rtl.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_rtl.cc?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_rtl.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_rtl.cc Tue Apr  1 08:16:30 2014
@@ -637,6 +637,23 @@ void AsanInitFromRtl() {
   AsanInitInternal();
 }
 
+#if 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();
+    AsanCheckDynamicRTPrereqs();
+    if (!asan_inited)
+      __asan_init();
+  }
+};
+
+static AsanInitializer asan_initializer;
+#endif  // ASAN_DYNAMIC
+
 }  // namespace __asan
 
 // ---------------------- Interface ---------------- {{{1
@@ -688,6 +705,7 @@ void NOINLINE __asan_set_death_callback(
 // 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();
 }

Modified: compiler-rt/trunk/lib/asan/asan_win.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/asan_win.cc?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/asan_win.cc (original)
+++ compiler-rt/trunk/lib/asan/asan_win.cc Tue Apr  1 08:16:30 2014
@@ -70,6 +70,10 @@ void *AsanDoesNotSupportStaticLinkage()
   return 0;
 }
 
+void AsanCheckDynamicRTPrereqs() { UNIMPLEMENTED(); }
+
+void AsanCheckIncompatibleRT() {}
+
 void AsanPlatformThreadInit() {
   // Nothing here for now.
 }

Modified: compiler-rt/trunk/lib/asan/tests/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/lib/asan/tests/CMakeLists.txt?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/lib/asan/tests/CMakeLists.txt (original)
+++ compiler-rt/trunk/lib/asan/tests/CMakeLists.txt Tue Apr  1 08:16:30 2014
@@ -66,10 +66,16 @@ if(NOT ANDROID)
   list(APPEND ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS -fsanitize=address)
 endif()
 
+set(ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS
+  ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}
+  -shared-libasan)
+
 set(ASAN_UNITTEST_NOINST_LINKFLAGS
   ${ASAN_UNITTEST_COMMON_LINKFLAGS} -lm)
 append_if(COMPILER_RT_HAS_LIBDL -ldl ASAN_UNITTEST_NOINST_LINKFLAGS)
 append_if(COMPILER_RT_HAS_LIBPTHREAD -lpthread ASAN_UNITTEST_NOINST_LINKFLAGS)
+append_if(COMPILER_RT_HAS_LIBPTHREAD -lpthread
+          ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS)
 
 # Compile source for the given architecture, using compiler
 # options in ${ARGN}, and add it to the object list.
@@ -154,6 +160,11 @@ macro(add_asan_tests_for_arch arch)
   add_asan_test(AsanUnitTests "Asan-${arch}-Test" ${arch}
                 OBJECTS ${ASAN_INST_TEST_OBJECTS}
                 LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
+  if(COMPILER_RT_BUILD_SHARED_ASAN)
+    add_asan_test(AsanUnitTests "Asan-${arch}-Dynamic-Test" ${arch}
+                  OBJECTS ${ASAN_INST_TEST_OBJECTS}
+                  LINKFLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS})
+  endif()
 
   # Add static ASan runtime that will be linked with uninstrumented tests.
   set(ASAN_TEST_RUNTIME RTAsanTest.${arch})
@@ -194,6 +205,11 @@ macro(add_asan_tests_for_arch arch)
   add_asan_test(AsanBenchmarks "Asan-${arch}-Benchmark" ${arch}
                 OBJECTS ${ASAN_BENCHMARKS_OBJECTS}
                 LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
+  if(COMPILER_RT_BUILD_SHARED_ASAN)
+    add_asan_test(AsanBenchmarks "Asan-${arch}-Dynamic-Benchmark" ${arch}
+                  OBJECTS ${ASAN_BENCHMARKS_OBJECTS}
+                  LINKFLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS})
+  endif()
 endmacro()
 
 if(COMPILER_RT_CAN_EXECUTE_TESTS)

Modified: compiler-rt/trunk/test/asan/CMakeLists.txt
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/CMakeLists.txt?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/CMakeLists.txt (original)
+++ compiler-rt/trunk/test/asan/CMakeLists.txt Tue Apr  1 08:16:30 2014
@@ -21,29 +21,47 @@ if(CAN_TARGET_x86_64 OR CAN_TARGET_power
   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_BUILD_SHARED_ASAN)
+    set(ASAN_TEST_CONFIG_SUFFIX "64-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)
+  set(ASAN_TEST_TARGET_ARCH "i386")
   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_BUILD_SHARED_ASAN)
+    set(ASAN_TEST_CONFIG_SUFFIX "32-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
-  )
+  configure_lit_site_cfg(
+    ${CMAKE_CURRENT_SOURCE_DIR}/Unit/lit.site.cfg.in
+    ${CMAKE_CURRENT_BINARY_DIR}/Unit/lit.site.cfg)
 endif()
 
 set(ASAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})

Added: compiler-rt/trunk/test/asan/TestCases/Linux/asan_dlopen_test.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/asan_dlopen_test.cc?rev=205308&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/asan_dlopen_test.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/asan_dlopen_test.cc Tue Apr  1 08:16:30 2014
@@ -0,0 +1,14 @@
+// Test that dlopen of dynamic runtime is prohibited.
+//
+// RUN: %clangxx %s -DRT=\"%shared_libasan\" -o %t -ldl
+// RUN: not %t 2>&1 | FileCheck %s
+// REQUIRES: asan-dynamic-runtime
+
+#include <dlfcn.h>
+
+int main(int argc, char **argv) {
+  dlopen(RT, RTLD_LAZY);
+  return 0;
+}
+
+// CHECK: ASan runtime does not come first in initial library list

Added: compiler-rt/trunk/test/asan/TestCases/Linux/asan_preload_test-1.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/asan_preload_test-1.cc?rev=205308&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/asan_preload_test-1.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/asan_preload_test-1.cc Tue Apr  1 08:16:30 2014
@@ -0,0 +1,27 @@
+// Test that non-sanitized 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
+
+// REQUIRES: asan-dynamic-runtime
+
+#if BUILD_SO
+char dummy;
+void do_access(const void *p) {
+  // CHECK: AddressSanitizer: heap-buffer-overflow
+  dummy = ((const char *)p)[1];
+}
+#else
+#include <stdlib.h>
+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

Added: compiler-rt/trunk/test/asan/TestCases/Linux/asan_preload_test-2.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/asan_preload_test-2.cc?rev=205308&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/asan_preload_test-2.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/asan_preload_test-2.cc Tue Apr  1 08:16:30 2014
@@ -0,0 +1,21 @@
+// Test that preloaded runtime works with unsanitized executables.
+//
+// RUN: %clangxx %s -o %t
+// RUN: LD_PRELOAD=%shared_libasan not %t 2>&1 | FileCheck %s
+
+// REQUIRES: asan-dynamic-runtime
+
+#include <stdlib.h>
+
+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;
+}

Added: compiler-rt/trunk/test/asan/TestCases/Linux/asan_rt_confict_test-1.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/asan_rt_confict_test-1.cc?rev=205308&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/asan_rt_confict_test-1.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/asan_rt_confict_test-1.cc Tue Apr  1 08:16:30 2014
@@ -0,0 +1,12 @@
+// Test that preloading dynamic runtime to statically sanitized
+// executable is prohibited.
+//
+// RUN: %clangxx_asan_static %s -o %t
+// RUN: LD_PRELOAD=%shared_libasan not %t 2>&1 | FileCheck %s
+
+// REQUIRES: asan-dynamic-runtime
+
+#include <stdlib.h>
+int main(int argc, char **argv) { return 0; }
+
+// CHECK: Your application is linked against incompatible ASan runtimes

Added: compiler-rt/trunk/test/asan/TestCases/Linux/asan_rt_confict_test-2.cc
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/asan_rt_confict_test-2.cc?rev=205308&view=auto
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/asan_rt_confict_test-2.cc (added)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/asan_rt_confict_test-2.cc Tue Apr  1 08:16:30 2014
@@ -0,0 +1,24 @@
+// Test that mixed static/dynamic sanitization of program objects
+// is prohibited.
+//
+// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t.so
+// RUN: %clangxx_asan_static %s %t.so -o %t
+// RUN: not %t 2>&1 | FileCheck %s
+
+// REQUIRES: asan-dynamic-runtime
+
+#if BUILD_SO
+char dummy;
+void do_access(const void *p) { dummy = ((const char *)p)[1]; }
+#else
+#include <stdlib.h>
+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
+
+// CHECK: Your application is linked against incompatible ASan runtimes

Modified: compiler-rt/trunk/test/asan/TestCases/Linux/interface_symbols_linux.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/Linux/interface_symbols_linux.c?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/Linux/interface_symbols_linux.c (original)
+++ compiler-rt/trunk/test/asan/TestCases/Linux/interface_symbols_linux.c Tue Apr  1 08:16:30 2014
@@ -31,6 +31,6 @@
 
 // FIXME: nm -D on powerpc somewhy shows ASan interface symbols residing
 // in "initialized data section".
-// REQUIRES: x86_64-supported-target,i386-supported-target
+// REQUIRES: x86_64-supported-target,i386-supported-target,asan-static-runtime
 
 int main() { return 0; }

Modified: compiler-rt/trunk/test/asan/TestCases/sanity_check_pure_c.c
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/TestCases/sanity_check_pure_c.c?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/TestCases/sanity_check_pure_c.c (original)
+++ compiler-rt/trunk/test/asan/TestCases/sanity_check_pure_c.c Tue Apr  1 08:16:30 2014
@@ -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 <stdlib.h>

Modified: compiler-rt/trunk/test/asan/Unit/lit.site.cfg.in
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/Unit/lit.site.cfg.in?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/Unit/lit.site.cfg.in (original)
+++ compiler-rt/trunk/test/asan/Unit/lit.site.cfg.in Tue Apr  1 08:16:30 2014
@@ -1,9 +1,16 @@
 ## Autogenerated by LLVM/Clang configuration.
 # Do not edit!
 
+import os
+
 # Load common config for all compiler-rt unit tests.
 lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/unittests/lit.common.unit.configured")
 
+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-Unit'
 
@@ -13,6 +20,9 @@ config.name = 'AddressSanitizer-Unit'
 config.test_exec_root = "@COMPILER_RT_BINARY_DIR@/lib/asan/tests"
 config.test_source_root = config.test_exec_root
 
+# Set LD_LIBRARY_PATH to pick dynamic runtime up properly.
+push_ld_library_path(config, config.compiler_rt_libdir)
+
 # Enable leak detection in ASan unit tests on x86_64-linux.
 if config.host_os == 'Linux' and config.host_arch == 'x86_64':
   config.environment['ASAN_OPTIONS'] = 'detect_leaks=1'

Modified: compiler-rt/trunk/test/asan/lit.cfg
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/lit.cfg?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/lit.cfg (original)
+++ compiler-rt/trunk/test/asan/lit.cfg Tue Apr  1 08:16:30 2014
@@ -11,6 +11,11 @@ def get_required_attr(config, attr_name)
       "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
 
@@ -27,12 +32,21 @@ else:
 # FIXME: Review the set of required flags and check if it can be reduced.
 target_cflags = [get_required_attr(config, "target_cflags")] + extra_linkflags
 target_cxxflags = config.cxx_mode_flags + target_cflags
-clang_asan_cflags = ["-fsanitize=address",
-                     "-mno-omit-leaf-frame-pointer",
-                     "-fno-omit-frame-pointer",
-                     "-fno-optimize-sibling-calls",
-                     "-g"] + target_cflags
-clang_asan_cxxflags = config.cxx_mode_flags + clang_asan_cflags
+clang_asan_static_cflags = ["-fsanitize=address",
+                            "-mno-omit-leaf-frame-pointer",
+                            "-fno-omit-frame-pointer",
+                            "-fno-optimize-sibling-calls",
+                            "-g"] + target_cflags
+clang_asan_static_cxxflags = config.cxx_mode_flags + clang_asan_static_cflags
+
+if config.asan_dynamic:
+  clang_asan_cflags = clang_asan_static_cflags + ['-shared-libasan']
+  clang_asan_cxxflags = clang_asan_static_cxxflags + ['-shared-libasan']
+  config.available_features.add("asan-dynamic-runtime")
+else:
+  clang_asan_cflags = clang_asan_static_cflags
+  clang_asan_cxxflags = clang_asan_static_cxxflags
+  config.available_features.add("asan-static-runtime")
 
 asan_lit_source_dir = get_required_attr(config, "asan_lit_source_dir")
 if config.android == "TRUE":
@@ -49,6 +63,10 @@ config.substitutions.append( ("%clang ",
 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.so" % config.target_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(
@@ -76,14 +94,14 @@ config.available_features.add("asan-" +
 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.
+push_ld_library_path(config, config.compiler_rt_libdir)
+
+# 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']

Modified: compiler-rt/trunk/test/asan/lit.site.cfg.in
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/asan/lit.site.cfg.in?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/test/asan/lit.site.cfg.in (original)
+++ compiler-rt/trunk/test/asan/lit.site.cfg.in Tue Apr  1 08:16:30 2014
@@ -9,6 +9,8 @@ config.clang = "@ASAN_TEST_TARGET_CC@"
 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@
+config.target_arch = "@ASAN_TEST_TARGET_ARCH@"
 
 # Load common config for all compiler-rt lit tests.
 lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")

Modified: compiler-rt/trunk/test/lit.common.configured.in
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/test/lit.common.configured.in?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/test/lit.common.configured.in (original)
+++ compiler-rt/trunk/test/lit.common.configured.in Tue Apr  1 08:16:30 2014
@@ -9,6 +9,7 @@ def set_default(attr, value):
 # Generic config options for all compiler-rt lit tests.
 set_default("target_triple", "@TARGET_TRIPLE@")
 set_default("host_arch", "@HOST_ARCH@")
+set_default("target_arch", "@HOST_ARCH@")
 set_default("host_os", "@HOST_OS@")
 set_default("llvm_build_mode", "@LLVM_BUILD_MODE@")
 set_default("llvm_src_root", "@LLVM_SOURCE_DIR@")
@@ -20,6 +21,7 @@ set_default("compiler_id", "@COMPILER_RT
 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.

Modified: compiler-rt/trunk/unittests/lit.common.unit.configured.in
URL: http://llvm.org/viewvc/llvm-project/compiler-rt/trunk/unittests/lit.common.unit.configured.in?rev=205308&r1=205307&r2=205308&view=diff
==============================================================================
--- compiler-rt/trunk/unittests/lit.common.unit.configured.in (original)
+++ compiler-rt/trunk/unittests/lit.common.unit.configured.in Tue Apr  1 08:16:30 2014
@@ -7,6 +7,7 @@ config.llvm_src_root = "@LLVM_SOURCE_DIR
 config.llvm_obj_root = "@LLVM_BINARY_DIR@"
 config.llvm_tools_dir = "@LLVM_TOOLS_DIR@"
 config.compiler_rt_src_root = "@COMPILER_RT_SOURCE_DIR@"
+config.compiler_rt_libdir = "@COMPILER_RT_LIBRARY_OUTPUT_DIR@"
 config.llvm_build_mode = "@LLVM_BUILD_MODE@"
 config.host_arch = "@HOST_ARCH@"
 config.host_os = "@HOST_OS@"





More information about the llvm-commits mailing list