aboutsummaryrefslogtreecommitdiff
path: root/test/sanitizer_common
diff options
context:
space:
mode:
Diffstat (limited to 'test/sanitizer_common')
-rw-r--r--test/sanitizer_common/CMakeLists.txt46
-rw-r--r--test/sanitizer_common/TestCases/Linux/aligned_alloc.c8
-rw-r--r--test/sanitizer_common/TestCases/Linux/clock_gettime.c11
-rw-r--r--test/sanitizer_common/TestCases/Linux/getpass.cc32
-rw-r--r--test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc19
-rw-r--r--test/sanitizer_common/TestCases/Linux/lit.local.cfg9
-rw-r--r--test/sanitizer_common/TestCases/Linux/mlock_test.cc13
-rw-r--r--test/sanitizer_common/TestCases/Linux/open_memstream.cc57
-rw-r--r--test/sanitizer_common/TestCases/Linux/ptrace.cc60
-rw-r--r--test/sanitizer_common/TestCases/Linux/timerfd.cc52
-rw-r--r--test/sanitizer_common/TestCases/corelimit.cc16
-rw-r--r--test/sanitizer_common/TestCases/malloc_hook.cc38
-rw-r--r--test/sanitizer_common/TestCases/print-stack-trace.cc24
-rw-r--r--test/sanitizer_common/TestCases/pthread_mutexattr_get.cc19
-rw-r--r--test/sanitizer_common/Unit/lit.site.cfg.in15
-rw-r--r--test/sanitizer_common/lit.common.cfg38
-rw-r--r--test/sanitizer_common/lit.site.cfg.in9
17 files changed, 466 insertions, 0 deletions
diff --git a/test/sanitizer_common/CMakeLists.txt b/test/sanitizer_common/CMakeLists.txt
new file mode 100644
index 000000000000..13eecbdc1b2b
--- /dev/null
+++ b/test/sanitizer_common/CMakeLists.txt
@@ -0,0 +1,46 @@
+set(SANITIZER_COMMON_LIT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR})
+
+set(SANITIZER_COMMON_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS})
+set(SANITIZER_COMMON_TESTSUITES)
+
+set(SUPPORTED_TOOLS)
+if(CMAKE_SYSTEM_NAME MATCHES "Darwin|Linux|FreeBSD" AND NOT ANDROID)
+ list(APPEND SUPPORTED_TOOLS asan)
+endif()
+if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT ANDROID)
+ list(APPEND SUPPORTED_TOOLS tsan)
+ list(APPEND SUPPORTED_TOOLS msan)
+ list(APPEND SUPPORTED_TOOLS lsan)
+endif()
+
+# Create a separate config for each tool we support.
+foreach(tool ${SUPPORTED_TOOLS})
+ string(TOUPPER ${tool} tool_toupper)
+ if(${tool_toupper}_SUPPORTED_ARCH)
+ set(SANITIZER_COMMON_LIT_TEST_MODE ${tool})
+ configure_lit_site_cfg(
+ ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
+ ${CMAKE_CURRENT_BINARY_DIR}/${tool}/lit.site.cfg)
+ list(APPEND SANITIZER_COMMON_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/${tool})
+ if(NOT COMPILER_RT_STANDALONE_BUILD)
+ list(APPEND SANITIZER_COMMON_TEST_DEPS ${tool})
+ endif()
+ endif()
+endforeach()
+
+# Unit tests.
+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)
+ list(APPEND SANITIZER_COMMON_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit)
+ list(APPEND SANITIZER_COMMON_TEST_DEPS SanitizerUnitTests)
+endif()
+
+if(SANITIZER_COMMON_TESTSUITES)
+ add_lit_testsuite(check-sanitizer "Running sanitizer_common tests"
+ ${SANITIZER_COMMON_TESTSUITES}
+ DEPENDS ${SANITIZER_COMMON_TEST_DEPS})
+ set_target_properties(check-sanitizer PROPERTIES FOLDER
+ "sanitizer_common tests")
+endif()
diff --git a/test/sanitizer_common/TestCases/Linux/aligned_alloc.c b/test/sanitizer_common/TestCases/Linux/aligned_alloc.c
new file mode 100644
index 000000000000..12af18dd32a1
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/aligned_alloc.c
@@ -0,0 +1,8 @@
+// RUN: %clang -std=c11 -O0 %s -o %t && %run %t
+#include <stdlib.h>
+extern void *aligned_alloc (size_t alignment, size_t size);
+int main() {
+ volatile void *p = aligned_alloc(128, 1024);
+ free((void*)p);
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Linux/clock_gettime.c b/test/sanitizer_common/TestCases/Linux/clock_gettime.c
new file mode 100644
index 000000000000..ec1386ef2414
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/clock_gettime.c
@@ -0,0 +1,11 @@
+// RUN: %clang %s -Wl,-as-needed -o %t && %run %t
+// Regression test for PR15823
+// (http://llvm.org/bugs/show_bug.cgi?id=15823).
+#include <stdio.h>
+#include <time.h>
+
+int main() {
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Linux/getpass.cc b/test/sanitizer_common/TestCases/Linux/getpass.cc
new file mode 100644
index 000000000000..c9a2276cc248
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/getpass.cc
@@ -0,0 +1,32 @@
+// RUN: %clangxx -O0 -g %s -lutil -o %t && %run %t | FileCheck %s
+#include <assert.h>
+#include <stdio.h>
+#include <unistd.h>
+#include <string.h>
+#include <pty.h>
+
+int
+main (int argc, char** argv)
+{
+ int master;
+ int pid = forkpty(&master, NULL, NULL, NULL);
+
+ if(pid == -1) {
+ fprintf(stderr, "forkpty failed\n");
+ return 1;
+ } else if (pid > 0) {
+ char buf[1024];
+ int res = read(master, buf, sizeof(buf));
+ write(1, buf, res);
+ write(master, "password\n", 9);
+ while ((res = read(master, buf, sizeof(buf))) > 0) write(1, buf, res);
+ } else {
+ char *s = getpass("prompt");
+ assert(strcmp(s, "password") == 0);
+ write(1, "done\n", 5);
+ }
+ return 0;
+}
+
+// CHECK: prompt
+// CHECK: done
diff --git a/test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc b/test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc
new file mode 100644
index 000000000000..a8b51d7a99c0
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/getpwnam_r_invalid_user.cc
@@ -0,0 +1,19 @@
+// Regression test for a crash in getpwnam_r and similar interceptors.
+// RUN: %clangxx -O0 -g %s -o %t && %run %t
+
+#include <assert.h>
+#include <pwd.h>
+#include <signal.h>
+#include <stdio.h>
+#include <sys/types.h>
+#include <unistd.h>
+
+int main(void) {
+ struct passwd pwd;
+ struct passwd *pwdres;
+ char buf[10000];
+ int res = getpwnam_r("no-such-user", &pwd, buf, sizeof(buf), &pwdres);
+ assert(res == 0);
+ assert(pwdres == 0);
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Linux/lit.local.cfg b/test/sanitizer_common/TestCases/Linux/lit.local.cfg
new file mode 100644
index 000000000000..57271b8078a4
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/lit.local.cfg
@@ -0,0 +1,9 @@
+def getRoot(config):
+ if not config.parent:
+ return config
+ return getRoot(config.parent)
+
+root = getRoot(config)
+
+if root.host_os not in ['Linux']:
+ config.unsupported = True
diff --git a/test/sanitizer_common/TestCases/Linux/mlock_test.cc b/test/sanitizer_common/TestCases/Linux/mlock_test.cc
new file mode 100644
index 000000000000..69ea7cb91c4f
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/mlock_test.cc
@@ -0,0 +1,13 @@
+// RUN: %clang %s -o %t && %run %t
+// XFAIL: lsan
+
+#include <assert.h>
+#include <sys/mman.h>
+
+int main() {
+ assert(0 == mlockall(MCL_CURRENT));
+ assert(0 == mlock((void *)0x12345, 0x5678));
+ assert(0 == munlockall());
+ assert(0 == munlock((void *)0x987, 0x654));
+}
+
diff --git a/test/sanitizer_common/TestCases/Linux/open_memstream.cc b/test/sanitizer_common/TestCases/Linux/open_memstream.cc
new file mode 100644
index 000000000000..6abe0bfb1483
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/open_memstream.cc
@@ -0,0 +1,57 @@
+// RUN: %clangxx -m64 -O0 -g -xc++ %s -o %t && %run %t
+// RUN: %clangxx -m64 -O3 -g -xc++ %s -o %t && %run %t
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+#ifndef __has_feature
+#define __has_feature(x) 0
+#endif
+
+#if __has_feature(memory_sanitizer)
+#include <sanitizer/msan_interface.h>
+static void check_mem_is_good(void *p, size_t s) {
+ __msan_check_mem_is_initialized(p, s);
+}
+#elif __has_feature(address_sanitizer)
+#include <sanitizer/asan_interface.h>
+static void check_mem_is_good(void *p, size_t s) {
+ assert(__asan_region_is_poisoned(p, s) == 0);
+}
+#else
+static void check_mem_is_good(void *p, size_t s) {}
+#endif
+
+static void run(void) {
+ char *buf;
+ size_t buf_len;
+ fprintf(stderr, " &buf %p, &buf_len %p\n", &buf, &buf_len);
+ FILE *fp = open_memstream(&buf, &buf_len);
+ fprintf(fp, "hello");
+ fflush(fp);
+ check_mem_is_good(&buf, sizeof(buf));
+ check_mem_is_good(&buf_len, sizeof(buf_len));
+ check_mem_is_good(buf, buf_len);
+
+ char *p = new char[1024];
+ memset(p, 'a', 1023);
+ p[1023] = 0;
+ for (int i = 0; i < 100; ++i)
+ fprintf(fp, "%s", p);
+ delete[] p;
+ fflush(fp);
+ fprintf(stderr, " %p addr %p, len %zu\n", &buf, buf, buf_len);
+ check_mem_is_good(&buf, sizeof(buf));
+ check_mem_is_good(&buf_len, sizeof(buf_len));
+ check_mem_is_good(buf, buf_len);
+ fclose(fp);
+ free(buf);
+}
+
+int main(void) {
+ for (int i = 0; i < 100; ++i)
+ run();
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Linux/ptrace.cc b/test/sanitizer_common/TestCases/Linux/ptrace.cc
new file mode 100644
index 000000000000..2bf0fd2f0f35
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/ptrace.cc
@@ -0,0 +1,60 @@
+// RUN: %clangxx -O0 %s -o %t && %run %t
+
+#include <assert.h>
+#include <signal.h>
+#include <stdio.h>
+#include <sys/ptrace.h>
+#include <sys/types.h>
+#include <sys/user.h>
+#include <sys/wait.h>
+#include <unistd.h>
+
+int main(void) {
+ pid_t pid;
+ pid = fork();
+ if (pid == 0) { // child
+ ptrace(PTRACE_TRACEME, 0, NULL, NULL);
+ execl("/bin/true", "true", NULL);
+ } else {
+ wait(NULL);
+ int res;
+
+#if __x86_64__
+ user_regs_struct regs;
+ res = ptrace(PTRACE_GETREGS, pid, NULL, &regs);
+ assert(!res);
+ if (regs.rip)
+ printf("%zx\n", regs.rip);
+
+ user_fpregs_struct fpregs;
+ res = ptrace(PTRACE_GETFPREGS, pid, NULL, &fpregs);
+ assert(!res);
+ if (fpregs.mxcsr)
+ printf("%x\n", fpregs.mxcsr);
+#endif // __x86_64__
+
+#if __powerpc64__
+ struct pt_regs regs;
+ res = ptrace((enum __ptrace_request)PTRACE_GETREGS, pid, NULL, &regs);
+ assert(!res);
+ if (regs.nip)
+ printf("%lx\n", regs.nip);
+
+ elf_fpregset_t fpregs;
+ res = ptrace((enum __ptrace_request)PTRACE_GETFPREGS, pid, NULL, &fpregs);
+ assert(!res);
+ if ((elf_greg_t)fpregs[32]) // fpscr
+ printf("%lx\n", (elf_greg_t)fpregs[32]);
+#endif // __powerpc64__
+
+ siginfo_t siginfo;
+ res = ptrace(PTRACE_GETSIGINFO, pid, NULL, &siginfo);
+ assert(!res);
+ assert(siginfo.si_pid == pid);
+
+ ptrace(PTRACE_CONT, pid, NULL, NULL);
+
+ wait(NULL);
+ }
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Linux/timerfd.cc b/test/sanitizer_common/TestCases/Linux/timerfd.cc
new file mode 100644
index 000000000000..e7613bb1d111
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Linux/timerfd.cc
@@ -0,0 +1,52 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t | FileCheck %s
+#include <assert.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include <sys/timerfd.h>
+#include <unistd.h>
+
+int main (int argc, char** argv)
+{
+ int fd = timerfd_create(CLOCK_REALTIME, 0);
+ assert(fd >= 0);
+
+ struct itimerspec its;
+ its.it_value.tv_sec = 0;
+ its.it_value.tv_nsec = 1000000;
+ its.it_interval.tv_sec = its.it_value.tv_sec;
+ its.it_interval.tv_nsec = its.it_value.tv_nsec;
+
+ int res = timerfd_settime(fd, 0, &its, NULL);
+ assert(res != -1);
+
+ struct itimerspec its2;
+ res = timerfd_settime(fd, 0, &its, &its2);
+ assert(res != -1);
+ assert(its2.it_interval.tv_sec == its.it_interval.tv_sec);
+ assert(its2.it_interval.tv_nsec == its.it_interval.tv_nsec);
+ assert(its2.it_value.tv_sec <= its.it_value.tv_sec);
+ assert(its2.it_value.tv_nsec <= its.it_value.tv_nsec);
+
+ struct itimerspec its3;
+ res = timerfd_gettime(fd, &its3);
+ assert(res != -1);
+ assert(its3.it_interval.tv_sec == its.it_interval.tv_sec);
+ assert(its3.it_interval.tv_nsec == its.it_interval.tv_nsec);
+ assert(its3.it_value.tv_sec <= its.it_value.tv_sec);
+ assert(its3.it_value.tv_nsec <= its.it_value.tv_nsec);
+
+
+ unsigned long long buf;
+ res = read(fd, &buf, sizeof(buf));
+ assert(res == 8);
+ assert(buf >= 1);
+
+ res = close(fd);
+ assert(res != -1);
+
+ printf("DONE\n");
+ // CHECK: DONE
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/corelimit.cc b/test/sanitizer_common/TestCases/corelimit.cc
new file mode 100644
index 000000000000..8f54940d04cc
--- /dev/null
+++ b/test/sanitizer_common/TestCases/corelimit.cc
@@ -0,0 +1,16 @@
+// RUN: %clangxx -O0 %s -o %t && %run %t
+// XFAIL: lsan
+
+#include <assert.h>
+#include <sys/time.h>
+#include <sys/resource.h>
+
+int main() {
+ struct rlimit lim_core;
+ getrlimit(RLIMIT_CORE, &lim_core);
+ void *p;
+ if (sizeof(p) == 8) {
+ assert(0 == lim_core.rlim_max);
+ }
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/malloc_hook.cc b/test/sanitizer_common/TestCases/malloc_hook.cc
new file mode 100644
index 000000000000..9702249c57e2
--- /dev/null
+++ b/test/sanitizer_common/TestCases/malloc_hook.cc
@@ -0,0 +1,38 @@
+// RUN: %clangxx -O2 %s -o %t && %run %t 2>&1 | FileCheck %s
+
+// Malloc/free hooks are not supported on Windows.
+// XFAIL: win32
+
+#include <stdlib.h>
+#include <unistd.h>
+#include <sanitizer/allocator_interface.h>
+
+extern "C" {
+const volatile void *global_ptr;
+
+// Note: avoid calling functions that allocate memory in malloc/free
+// to avoid infinite recursion.
+void __sanitizer_malloc_hook(const volatile void *ptr, size_t sz) {
+ if (__sanitizer_get_ownership(ptr)) {
+ write(1, "MallocHook\n", sizeof("MallocHook\n"));
+ global_ptr = ptr;
+ }
+}
+void __sanitizer_free_hook(const volatile void *ptr) {
+ if (__sanitizer_get_ownership(ptr) && ptr == global_ptr)
+ write(1, "FreeHook\n", sizeof("FreeHook\n"));
+}
+} // extern "C"
+
+int main() {
+ volatile int *x = new int;
+ // CHECK: MallocHook
+ // Check that malloc hook was called with correct argument.
+ if (global_ptr != (void*)x) {
+ _exit(1);
+ }
+ *x = 0;
+ delete x;
+ // CHECK: FreeHook
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/print-stack-trace.cc b/test/sanitizer_common/TestCases/print-stack-trace.cc
new file mode 100644
index 000000000000..1251f67b83cd
--- /dev/null
+++ b/test/sanitizer_common/TestCases/print-stack-trace.cc
@@ -0,0 +1,24 @@
+// RUN: %clangxx -O0 %s -o %t && %tool_options=stack_trace_format=DEFAULT %run %t 2>&1 | FileCheck %s
+// RUN: %clangxx -O3 %s -o %t && %tool_options=stack_trace_format=DEFAULT %run %t 2>&1 | FileCheck %s
+// RUN: %tool_options='stack_trace_format="frame:%n lineno:%l"' %run %t 2>&1 | FileCheck %s --check-prefix=CUSTOM
+// RUN: %tool_options=symbolize_inline_frames=false:stack_trace_format=DEFAULT %run %t 2>&1 | FileCheck %s --check-prefix=NOINLINE
+
+#include <sanitizer/common_interface_defs.h>
+
+static inline void FooBarBaz() {
+ __sanitizer_print_stack_trace();
+}
+
+int main() {
+ FooBarBaz();
+ return 0;
+}
+// CHECK: {{ #0 0x.* in __sanitizer_print_stack_trace}}
+// CHECK: {{ #1 0x.* in FooBarBaz(\(\))? .*print-stack-trace.cc:9}}
+// CHECK: {{ #2 0x.* in main.*print-stack-trace.cc:13}}
+
+// CUSTOM: frame:1 lineno:9
+// CUSTOM: frame:2 lineno:13
+
+// NOINLINE: #0 0x{{.*}} in __sanitizer_print_stack_trace
+// NOINLINE: #1 0x{{.*}} in main{{.*}}print-stack-trace.cc:9
diff --git a/test/sanitizer_common/TestCases/pthread_mutexattr_get.cc b/test/sanitizer_common/TestCases/pthread_mutexattr_get.cc
new file mode 100644
index 000000000000..26060f395c11
--- /dev/null
+++ b/test/sanitizer_common/TestCases/pthread_mutexattr_get.cc
@@ -0,0 +1,19 @@
+// RUN: %clangxx -O0 %s -o %t && %run %t
+
+#include <assert.h>
+#include <pthread.h>
+
+int main(void) {
+ pthread_mutexattr_t ma;
+ int res = pthread_mutexattr_init(&ma);
+ assert(res == 0);
+ res = pthread_mutexattr_setpshared(&ma, 1);
+ assert(res == 0);
+ int pshared;
+ res = pthread_mutexattr_getpshared(&ma, &pshared);
+ assert(res == 0);
+ assert(pshared == 1);
+ res = pthread_mutexattr_destroy(&ma);
+ assert(res == 0);
+ return 0;
+}
diff --git a/test/sanitizer_common/Unit/lit.site.cfg.in b/test/sanitizer_common/Unit/lit.site.cfg.in
new file mode 100644
index 000000000000..2600585702b2
--- /dev/null
+++ b/test/sanitizer_common/Unit/lit.site.cfg.in
@@ -0,0 +1,15 @@
+## Autogenerated by LLVM/Clang configuration.
+# Do not edit!
+
+# Load common config for all compiler-rt unit tests.
+lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/unittests/lit.common.unit.configured")
+
+# Setup config name.
+config.name = 'SanitizerCommon-Unit'
+
+# Setup test source and exec root. For unit tests, we define
+# it as build directory with sanitizer_common tests.
+# FIXME: De-hardcode this path.
+config.test_exec_root = os.path.join("@COMPILER_RT_BINARY_DIR@", "lib",
+ "sanitizer_common", "tests")
+config.test_source_root = config.test_exec_root
diff --git a/test/sanitizer_common/lit.common.cfg b/test/sanitizer_common/lit.common.cfg
new file mode 100644
index 000000000000..fb37815ff472
--- /dev/null
+++ b/test/sanitizer_common/lit.common.cfg
@@ -0,0 +1,38 @@
+# -*- Python -*-
+
+# Setup source root.
+config.test_source_root = os.path.join(os.path.dirname(__file__), "TestCases")
+
+config.name = "SanitizerCommon-" + config.tool_name
+
+if config.tool_name == "asan":
+ tool_cflags = ["-fsanitize=address"]
+ tool_options = "ASAN_OPTIONS"
+elif config.tool_name == "tsan":
+ tool_cflags = ["-fsanitize=thread"]
+ tool_options = "TSAN_OPTIONS"
+elif config.tool_name == "msan":
+ tool_cflags = ["-fsanitize=memory"]
+ tool_options = "MSAN_OPTIONS"
+elif config.tool_name == "lsan":
+ tool_cflags = ["-fsanitize=leak"]
+ tool_options = "LSAN_OPTIONS"
+else:
+ lit_config.fatal("Unknown tool for sanitizer_common tests: %r" % config.tool_name)
+
+config.available_features.add(config.tool_name)
+
+clang_cflags = config.debug_info_flags + tool_cflags + [config.target_cflags]
+clang_cxxflags = config.cxx_mode_flags + clang_cflags
+
+def build_invocation(compile_flags):
+ return " " + " ".join([config.clang] + compile_flags) + " "
+
+config.substitutions.append( ("%clang ", build_invocation(clang_cflags)) )
+config.substitutions.append( ("%clangxx ", build_invocation(clang_cxxflags)) )
+config.substitutions.append( ("%tool_options", tool_options) )
+
+config.suffixes = ['.c', '.cc', '.cpp']
+
+if config.host_os not in ['Linux', 'Darwin']:
+ config.unsupported = True
diff --git a/test/sanitizer_common/lit.site.cfg.in b/test/sanitizer_common/lit.site.cfg.in
new file mode 100644
index 000000000000..1e94aa567632
--- /dev/null
+++ b/test/sanitizer_common/lit.site.cfg.in
@@ -0,0 +1,9 @@
+# Load common config for all compiler-rt lit tests.
+lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
+
+# Tool-specific config options.
+config.tool_name = "@SANITIZER_COMMON_LIT_TEST_MODE@"
+
+# Load tool-specific config that would do the real work.
+lit_config.load_config(config, "@SANITIZER_COMMON_LIT_SOURCE_DIR@/lit.common.cfg")
+