26 changes: 22 additions & 4 deletions compiler-rt/test/asan/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -21,29 +21,47 @@ if(CAN_TARGET_x86_64 OR CAN_TARGET_powerpc64)
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})
Expand Down
14 changes: 14 additions & 0 deletions compiler-rt/test/asan/TestCases/Linux/asan_dlopen_test.cc
Original file line number Diff line number Diff line change
@@ -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
27 changes: 27 additions & 0 deletions compiler-rt/test/asan/TestCases/Linux/asan_preload_test-1.cc
Original file line number Diff line number Diff line change
@@ -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
21 changes: 21 additions & 0 deletions compiler-rt/test/asan/TestCases/Linux/asan_preload_test-2.cc
Original file line number Diff line number Diff line change
@@ -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;
}
12 changes: 12 additions & 0 deletions compiler-rt/test/asan/TestCases/Linux/asan_rt_confict_test-1.cc
Original file line number Diff line number Diff line change
@@ -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
24 changes: 24 additions & 0 deletions compiler-rt/test/asan/TestCases/Linux/asan_rt_confict_test-2.cc
Original file line number Diff line number Diff line change
@@ -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
Original file line number Diff line number Diff line change
Expand Up @@ -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; }
2 changes: 1 addition & 1 deletion compiler-rt/test/asan/TestCases/sanity_check_pure_c.c
Original file line number Diff line number Diff line change
Expand Up @@ -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>
Expand Down
10 changes: 10 additions & 0 deletions compiler-rt/test/asan/Unit/lit.site.cfg.in
Original file line number Diff line number Diff line change
@@ -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'

Expand All @@ -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'
40 changes: 29 additions & 11 deletions compiler-rt/test/asan/lit.cfg
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand All @@ -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":
Expand All @@ -49,6 +63,10 @@ config.substitutions.append( ("%clang ", build_invocation(target_cflags)) )
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(
Expand Down Expand Up @@ -76,14 +94,14 @@ config.available_features.add("asan-" + config.bits + "-bits")
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']
Expand Down
2 changes: 2 additions & 0 deletions compiler-rt/test/asan/lit.site.cfg.in
Original file line number Diff line number Diff line change
Expand Up @@ -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")
Expand Down
2 changes: 2 additions & 0 deletions compiler-rt/test/lit.common.configured.in
Original file line number Diff line number Diff line change
Expand Up @@ -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@")
Expand All @@ -20,6 +21,7 @@ set_default("compiler_id", "@COMPILER_RT_TEST_COMPILER_ID@")
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.
Expand Down
1 change: 1 addition & 0 deletions compiler-rt/unittests/lit.common.unit.configured.in
Original file line number Diff line number Diff line change
Expand Up @@ -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@"
Expand Down