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. llvm-svn: 189356
This commit is contained in:
parent
03520b7fc7
commit
acab30e927
|
@ -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.
|
||||
|
|
|
@ -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()
|
||||
|
|
|
@ -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()
|
|
@ -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()
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
__asan_*;
|
||||
__sanitizer_syscall_pre_*;
|
||||
__sanitizer_syscall_post_*;
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
__asan_*
|
|
@ -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)
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
__msan_*;
|
||||
__sanitizer_syscall_pre_*;
|
||||
__sanitizer_syscall_post_*;
|
||||
};
|
|
@ -0,0 +1 @@
|
|||
__msan_*
|
|
@ -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 '};'
|
|
@ -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)++
|
||||
|
|
|
@ -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 "};"
|
||||
|
|
@ -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()
|
||||
|
|
|
@ -1,5 +0,0 @@
|
|||
{
|
||||
__tsan_*;
|
||||
__sanitizer_syscall_pre_*;
|
||||
__sanitizer_syscall_post_*;
|
||||
};
|
|
@ -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
|
|
@ -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()
|
||||
|
||||
|
|
|
@ -1 +0,0 @@
|
|||
{ __ubsan_*; };
|
|
@ -0,0 +1 @@
|
|||
__ubsan_*
|
Loading…
Reference in New Issue