summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlexey Samsonov <samsonov@google.com>2013-08-27 15:08:02 +0000
committerAlexey Samsonov <samsonov@google.com>2013-08-27 15:08:02 +0000
commite5fa243b20bf5e6a097bc58cbedfe6bed8a9b7d1 (patch)
tree44ec546168b34e749d09d3576ee21f598842a330
parent0e38a67cd2d877e8680d65878c86c9e7e4fa4b1d (diff)
Properly generate lists of exported symbols for sanitizer runtimes
This change adds a Python script that is invoked for the just-built sanitizer runtime to generate the list of exported symbols passed to the linker. By default, it contains interceptors and sanitizer interface functions, but can be extended with tool-specific lists. git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/trunk@189356 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--CMakeLists.txt1
-rw-r--r--cmake/Modules/AddCompilerRT.cmake12
-rw-r--r--cmake/Modules/SanitizerUtils.cmake22
-rw-r--r--lib/asan/CMakeLists.txt10
-rw-r--r--lib/asan/asan.syms5
-rw-r--r--lib/asan/asan.syms.extra1
-rw-r--r--lib/msan/CMakeLists.txt7
-rw-r--r--lib/msan/msan.syms5
-rw-r--r--lib/msan/msan.syms.extra1
-rwxr-xr-xlib/sanitizer_common/scripts/gen_dynamic_list.py76
-rw-r--r--lib/tsan/Makefile.old2
-rwxr-xr-xlib/tsan/gen_dynamic_list.sh56
-rw-r--r--lib/tsan/rtl/CMakeLists.txt7
-rw-r--r--lib/tsan/rtl/tsan.syms5
-rw-r--r--lib/tsan/rtl/tsan.syms.extra13
-rw-r--r--lib/ubsan/CMakeLists.txt12
-rw-r--r--lib/ubsan/ubsan.syms1
-rw-r--r--lib/ubsan/ubsan.syms.extra1
18 files changed, 137 insertions, 100 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 67cc51ed9..70178488d 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -40,6 +40,7 @@ set(COMPILER_RT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR})
# Setup custom SDK sysroots.
set(COMPILER_RT_DARWIN_SDK_SYSROOT ${COMPILER_RT_SOURCE_DIR}/SDKs/darwin)
set(COMPILER_RT_LINUX_SDK_SYSROOT ${COMPILER_RT_SOURCE_DIR}/SDKs/linux)
+include(SanitizerUtils)
# Detect whether the current target platform is 32-bit or 64-bit, and setup
# the correct commandline flags needed to attempt to target 32-bit and 64-bit.
diff --git a/cmake/Modules/AddCompilerRT.cmake b/cmake/Modules/AddCompilerRT.cmake
index bf114a401..1ece3eb90 100644
--- a/cmake/Modules/AddCompilerRT.cmake
+++ b/cmake/Modules/AddCompilerRT.cmake
@@ -36,11 +36,10 @@ endmacro()
# add_compiler_rt_static_runtime(<name> <arch>
# SOURCES <source files>
# CFLAGS <compile flags>
-# DEFS <compile definitions>
-# SYMS <symbols file>)
+# DEFS <compile definitions>)
macro(add_compiler_rt_static_runtime name arch)
if(CAN_TARGET_${arch})
- parse_arguments(LIB "SOURCES;CFLAGS;DEFS;SYMS" "" ${ARGN})
+ parse_arguments(LIB "SOURCES;CFLAGS;DEFS" "" ${ARGN})
add_library(${name} STATIC ${LIB_SOURCES})
# Setup compile flags and definitions.
set_target_compile_flags(${name}
@@ -53,13 +52,6 @@ macro(add_compiler_rt_static_runtime name arch)
# Add installation command.
install(TARGETS ${name}
ARCHIVE DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR})
- # Generate the .syms file if possible.
- if(LIB_SYMS)
- get_target_property(libfile ${name} LOCATION)
- configure_file(${LIB_SYMS} ${libfile}.syms)
- install(FILES ${libfile}.syms
- DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR})
- endif(LIB_SYMS)
else()
message(FATAL_ERROR "Archtecture ${arch} can't be targeted")
endif()
diff --git a/cmake/Modules/SanitizerUtils.cmake b/cmake/Modules/SanitizerUtils.cmake
new file mode 100644
index 000000000..7a4f8670c
--- /dev/null
+++ b/cmake/Modules/SanitizerUtils.cmake
@@ -0,0 +1,22 @@
+include(LLVMParseArguments)
+
+set(SANITIZER_GEN_DYNAMIC_LIST
+ ${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/scripts/gen_dynamic_list.py)
+
+# Create a target "<name>-symbols" that would generate the list of symbols
+# that need to be exported from sanitizer runtime "<name>". Function
+# interceptors are exported automatically, user can also provide files with
+# symbol names that should be exported as well.
+# add_sanitizer_rt_symbols(<name> <files with extra symbols to export>)
+macro(add_sanitizer_rt_symbols name)
+ get_target_property(libfile ${name} LOCATION)
+ set(symsfile "${libfile}.syms")
+ add_custom_target(${name}-symbols ALL
+ COMMAND ${SANITIZER_GEN_DYNAMIC_LIST} ${libfile} ${ARGN}
+ > ${symsfile}
+ DEPENDS ${name} ${SANITIZER_GEN_DYNAMIC_LIST} ${ARGN}
+ WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
+ VERBATIM
+ SOURCES ${SANITIZER_GEN_DYNAMIC_LIST} ${ARGN})
+ install(FILES ${symsfile} DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR})
+endmacro()
diff --git a/lib/asan/CMakeLists.txt b/lib/asan/CMakeLists.txt
index fe14cc3df..5a2ce5466 100644
--- a/lib/asan/CMakeLists.txt
+++ b/lib/asan/CMakeLists.txt
@@ -102,16 +102,16 @@ else()
add_compiler_rt_static_runtime(clang_rt.asan-${arch} ${arch}
SOURCES ${ASAN_SOURCES} ${ASAN_SOURCE_LIBS}
CFLAGS ${ASAN_CFLAGS}
- DEFS ${ASAN_COMMON_DEFINITIONS}
- SYMS asan.syms)
- list(APPEND ASAN_RUNTIME_LIBRARIES clang_rt.asan-${arch})
+ DEFS ${ASAN_COMMON_DEFINITIONS})
+ add_sanitizer_rt_symbols(clang_rt.asan-${arch} asan.syms.extra)
+ list(APPEND ASAN_RUNTIME_LIBRARIES clang_rt.asan-${arch}
+ clang_rt.asan-${arch}-symbols)
if (WIN32)
add_compiler_rt_static_runtime(clang_rt.asan_dll_thunk-${arch} ${arch}
SOURCES asan_dll_thunk.cc
CFLAGS ${ASAN_CFLAGS} -DASAN_DLL_THUNK
- DEFS ${ASAN_COMMON_DEFINITIONS}
- SYMS asan.syms)
+ DEFS ${ASAN_COMMON_DEFINITIONS})
list(APPEND ASAN_RUNTIME_LIBRARIES clang_rt.asan_dll_thunk-${arch})
endif()
endforeach()
diff --git a/lib/asan/asan.syms b/lib/asan/asan.syms
deleted file mode 100644
index fce367314..000000000
--- a/lib/asan/asan.syms
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- __asan_*;
- __sanitizer_syscall_pre_*;
- __sanitizer_syscall_post_*;
-};
diff --git a/lib/asan/asan.syms.extra b/lib/asan/asan.syms.extra
new file mode 100644
index 000000000..9e5ba4682
--- /dev/null
+++ b/lib/asan/asan.syms.extra
@@ -0,0 +1 @@
+__asan_*
diff --git a/lib/msan/CMakeLists.txt b/lib/msan/CMakeLists.txt
index b3e88ea29..98c296148 100644
--- a/lib/msan/CMakeLists.txt
+++ b/lib/msan/CMakeLists.txt
@@ -25,9 +25,10 @@ if(CAN_TARGET_${arch})
$<TARGET_OBJECTS:RTInterception.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
- CFLAGS ${MSAN_RTL_CFLAGS}
- SYMS msan.syms)
- list(APPEND MSAN_RUNTIME_LIBRARIES clang_rt.msan-${arch})
+ CFLAGS ${MSAN_RTL_CFLAGS})
+ add_sanitizer_rt_symbols(clang_rt.msan-${arch} msan.syms.extra)
+ list(APPEND MSAN_RUNTIME_LIBRARIES clang_rt.msan-${arch}
+ clang_rt.msan-${arch}-symbols)
endif()
add_compiler_rt_resource_file(msan_blacklist msan_blacklist.txt)
diff --git a/lib/msan/msan.syms b/lib/msan/msan.syms
deleted file mode 100644
index 24bbaba47..000000000
--- a/lib/msan/msan.syms
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- __msan_*;
- __sanitizer_syscall_pre_*;
- __sanitizer_syscall_post_*;
-};
diff --git a/lib/msan/msan.syms.extra b/lib/msan/msan.syms.extra
new file mode 100644
index 000000000..aad41cf11
--- /dev/null
+++ b/lib/msan/msan.syms.extra
@@ -0,0 +1 @@
+__msan_*
diff --git a/lib/sanitizer_common/scripts/gen_dynamic_list.py b/lib/sanitizer_common/scripts/gen_dynamic_list.py
new file mode 100755
index 000000000..23b861eed
--- /dev/null
+++ b/lib/sanitizer_common/scripts/gen_dynamic_list.py
@@ -0,0 +1,76 @@
+#!/usr/bin/env python
+#===- lib/sanitizer_common/scripts/gen_dynamic_list.py ---------------------===#
+#
+# The LLVM Compiler Infrastructure
+#
+# This file is distributed under the University of Illinois Open Source
+# License. See LICENSE.TXT for details.
+#
+#===------------------------------------------------------------------------===#
+#
+# Generates the list of functions that should be exported from sanitizer
+# runtimes. The output format is recognized by --dynamic-list linker option.
+# Usage:
+# gen_dynamic_list.py libclang_rt.*san*.a [ files ... ]
+#
+#===------------------------------------------------------------------------===#
+import re
+import os
+import subprocess
+import sys
+
+def get_global_functions(library):
+ functions = []
+ nm_proc = subprocess.Popen(['nm', library], stdout=subprocess.PIPE)
+ nm_out = nm_proc.communicate()[0].split('\n')
+ if nm_proc.returncode != 0:
+ raise subprocess.CalledProcessError(nm_proc.returncode, 'nm')
+ for line in nm_out:
+ cols = line.split(' ')
+ if (len(cols) == 3 and cols[1] in ('T', 'W')) :
+ functions.append(cols[2])
+ return functions
+
+result = []
+
+library = sys.argv[1]
+all_functions = get_global_functions(library)
+function_set = set(all_functions)
+new_delete = set(['_ZdaPv', '_ZdaPvRKSt9nothrow_t',
+ '_ZdlPv', '_ZdlPvRKSt9nothrow_t',
+ '_Znam', '_ZnamRKSt9nothrow_t',
+ '_Znwm', '_ZnwmRKSt9nothrow_t'])
+versioned_functions = set(['memcpy', 'pthread_cond_broadcast',
+ 'pthread_cond_destroy', 'pthread_cond_signal',
+ 'pthread_cond_timedwait', 'pthread_cond_wait',
+ 'realpath', 'sched_getaffinity'])
+for func in all_functions:
+ # Export new/delete operators.
+ if func in new_delete:
+ result.append(func)
+ continue
+ # Export interceptors.
+ match = re.match('__interceptor_(.*)', func)
+ if match:
+ result.append(func)
+ # We have to avoid exporting the interceptors for versioned library
+ # functions due to gold internal error.
+ orig_name = match.group(1)
+ if orig_name in function_set and orig_name not in versioned_functions:
+ result.append(orig_name)
+ continue
+ # Export sanitizer interface functions.
+ if re.match('__sanitizer_(.*)', func):
+ result.append(func)
+
+# Additional exported functions from files.
+for fname in sys.argv[2:]:
+ f = open(fname, 'r')
+ for line in f:
+ result.append(line.rstrip())
+
+print '{'
+result.sort()
+for f in result:
+ print ' ' + f + ';'
+print '};'
diff --git a/lib/tsan/Makefile.old b/lib/tsan/Makefile.old
index 64dff8370..3443a0753 100644
--- a/lib/tsan/Makefile.old
+++ b/lib/tsan/Makefile.old
@@ -64,8 +64,6 @@ run: all
presubmit:
../sanitizer_common/scripts/check_lint.sh
- #./gen_dynamic_list.sh > rtl/tsan.syms.new
- #diff rtl/tsan.syms rtl/tsan.syms.new
# Debug build with clang.
$(MAKE) -f Makefile.old clean
$(MAKE) -f Makefile.old run DEBUG=1 -j 16 CC=$(CLANG) CXX=$(CLANG)++
diff --git a/lib/tsan/gen_dynamic_list.sh b/lib/tsan/gen_dynamic_list.sh
deleted file mode 100755
index 4868b42be..000000000
--- a/lib/tsan/gen_dynamic_list.sh
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/bash
-set -e
-
-# Collect interceptor names from a source file.
-function collect() {
- while read line ; do
- if [[ $line =~ ^(.*)((TSAN_INTERCEPT|INTERCEPT_FUNCTION)\()([a-z,A-Z,0-9,_]+)(.*)$ ]] ; then
- results+=" ${BASH_REMATCH[4]}"
- results+=" __interceptor_${BASH_REMATCH[4]}"
- fi
- done < "$1"
-}
-
-# Interface functions.
-results+=" __tsan_init"
-results+=" __tsan_read*"
-results+=" __tsan_write*"
-results+=" __tsan_vptr*"
-results+=" __tsan_func*"
-results+=" __tsan_atomic*"
-results+=" __tsan_java*"
-results+=" __tsan_unaligned*"
-results+=" __tsan_release"
-results+=" __tsan_acquire"
-results+=" __sanitizer_unaligned*"
-results+=" __sanitizer_syscall*"
-results+=" _Znwm"
-results+=" _Znam"
-results+=" _ZnwmRKSt9nothrow_t"
-results+=" _ZnamRKSt9nothrow_t"
-results+=" _ZdlPv"
-results+=" _ZdlPvRKSt9nothrow_t"
-results+=" _ZdaPv"
-results+=" _ZdaPvRKSt9nothrow_t"
-results+=" Annotate*"
-results+=" WTFAnnotate*"
-results+=" RunningOnValgrind"
-
-collect rtl/tsan_interceptors.cc
-collect ../sanitizer_common/sanitizer_common_interceptors.inc
-
-results=`for i in $results; do echo $i; done | sort -f`
-echo "# AUTO GENERATED by compiler-rt/lib/tsan/gen_dynamic_list.sh; EDITING IS FUTILE."
-echo "{"
-NM=`nm rtl/libtsan.a`
-for i in $results; do
- # Remove symbols that are not present in the library.
- if [[ $NM =~ " $i" ]]; then
- echo " $i;"
- else if [[ $i == *"*" ]]; then
- echo " $i;"
- fi
- fi
-done
-echo "};"
-
diff --git a/lib/tsan/rtl/CMakeLists.txt b/lib/tsan/rtl/CMakeLists.txt
index f1a8ff4d6..461c3b8c1 100644
--- a/lib/tsan/rtl/CMakeLists.txt
+++ b/lib/tsan/rtl/CMakeLists.txt
@@ -45,7 +45,8 @@ if(CAN_TARGET_x86_64 AND UNIX AND NOT APPLE)
$<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
$<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
CFLAGS ${TSAN_CFLAGS}
- DEFS ${TSAN_COMMON_DEFINITIONS}
- SYMS tsan.syms)
- list(APPEND TSAN_RUNTIME_LIBRARIES clang_rt.tsan-${arch})
+ DEFS ${TSAN_COMMON_DEFINITIONS})
+ add_sanitizer_rt_symbols(clang_rt.tsan-${arch} tsan.syms.extra)
+ list(APPEND TSAN_RUNTIME_LIBRARIES clang_rt.tsan-${arch}
+ clang_rt.tsan-${arch}-symbols)
endif()
diff --git a/lib/tsan/rtl/tsan.syms b/lib/tsan/rtl/tsan.syms
deleted file mode 100644
index 4464a0a23..000000000
--- a/lib/tsan/rtl/tsan.syms
+++ /dev/null
@@ -1,5 +0,0 @@
-{
- __tsan_*;
- __sanitizer_syscall_pre_*;
- __sanitizer_syscall_post_*;
-};
diff --git a/lib/tsan/rtl/tsan.syms.extra b/lib/tsan/rtl/tsan.syms.extra
new file mode 100644
index 000000000..1558f66e4
--- /dev/null
+++ b/lib/tsan/rtl/tsan.syms.extra
@@ -0,0 +1,13 @@
+__tsan_init
+__tsan_read*
+__tsan_write*
+__tsan_vptr*
+__tsan_func*
+__tsan_atomic*
+__tsan_java*
+__tsan_unaligned*
+__tsan_release
+__tsan_acquire
+Annotate*
+WTFAnnotate*
+RunningOnValgrind
diff --git a/lib/ubsan/CMakeLists.txt b/lib/ubsan/CMakeLists.txt
index c8470bc6d..6a9c8c37c 100644
--- a/lib/ubsan/CMakeLists.txt
+++ b/lib/ubsan/CMakeLists.txt
@@ -34,17 +34,19 @@ else()
# Main UBSan runtime.
add_compiler_rt_static_runtime(clang_rt.ubsan-${arch} ${arch}
SOURCES ${UBSAN_SOURCES}
- CFLAGS ${UBSAN_CFLAGS}
- SYMS ubsan.syms)
+ CFLAGS ${UBSAN_CFLAGS})
+ add_sanitizer_rt_symbols(clang_rt.ubsan-${arch} ubsan.syms.extra)
# C++-specific parts of UBSan runtime. Requires a C++ ABI library.
add_compiler_rt_static_runtime(clang_rt.ubsan_cxx-${arch} ${arch}
SOURCES ${UBSAN_CXX_SOURCES}
- CFLAGS ${UBSAN_CFLAGS}
- SYMS ubsan.syms)
+ CFLAGS ${UBSAN_CFLAGS})
+ add_sanitizer_rt_symbols(clang_rt.ubsan_cxx-${arch} ubsan.syms.extra)
list(APPEND UBSAN_RUNTIME_LIBRARIES
clang_rt.san-${arch}
clang_rt.ubsan-${arch}
- clang_rt.ubsan_cxx-${arch})
+ clang_rt.ubsan-${arch}-symbols
+ clang_rt.ubsan_cxx-${arch}
+ clang_rt.ubsan_cxx-${arch}-symbols)
endforeach()
endif()
diff --git a/lib/ubsan/ubsan.syms b/lib/ubsan/ubsan.syms
deleted file mode 100644
index e74de33f0..000000000
--- a/lib/ubsan/ubsan.syms
+++ /dev/null
@@ -1 +0,0 @@
-{ __ubsan_*; };
diff --git a/lib/ubsan/ubsan.syms.extra b/lib/ubsan/ubsan.syms.extra
new file mode 100644
index 000000000..7f8be6944
--- /dev/null
+++ b/lib/ubsan/ubsan.syms.extra
@@ -0,0 +1 @@
+__ubsan_*