Vendor import of compiler-rt release_40 branch r292009:
https://llvm.org/svn/llvm-project/compiler-rt/branches/release_40@292009
This commit is contained in:
parent
3bce7d2fca
commit
5894cadf20
@ -94,7 +94,7 @@ endfunction()
|
||||
# OS <os list>
|
||||
# SOURCES <source files>
|
||||
# CFLAGS <compile flags>
|
||||
# LINKFLAGS <linker flags>
|
||||
# LINK_FLAGS <linker flags>
|
||||
# DEFS <compile definitions>
|
||||
# LINK_LIBS <linked libraries> (only for shared library)
|
||||
# OBJECT_LIBS <object libraries to use as sources>
|
||||
@ -107,7 +107,7 @@ function(add_compiler_rt_runtime name type)
|
||||
cmake_parse_arguments(LIB
|
||||
""
|
||||
"PARENT_TARGET"
|
||||
"OS;ARCHS;SOURCES;CFLAGS;LINKFLAGS;DEFS;LINK_LIBS;OBJECT_LIBS"
|
||||
"OS;ARCHS;SOURCES;CFLAGS;LINK_FLAGS;DEFS;LINK_LIBS;OBJECT_LIBS"
|
||||
${ARGN})
|
||||
set(libnames)
|
||||
if(APPLE)
|
||||
@ -116,7 +116,7 @@ function(add_compiler_rt_runtime name type)
|
||||
set(libname "${name}_${os}")
|
||||
else()
|
||||
set(libname "${name}_${os}_dynamic")
|
||||
set(extra_linkflags_${libname} ${DARWIN_${os}_LINKFLAGS} ${LIB_LINKFLAGS})
|
||||
set(extra_link_flags_${libname} ${DARWIN_${os}_LINK_FLAGS} ${LIB_LINK_FLAGS})
|
||||
endif()
|
||||
list_intersect(LIB_ARCHS_${libname} DARWIN_${os}_ARCHS LIB_ARCHS)
|
||||
if(LIB_ARCHS_${libname})
|
||||
@ -139,7 +139,7 @@ function(add_compiler_rt_runtime name type)
|
||||
else()
|
||||
set(libname "${name}-dynamic-${arch}")
|
||||
set(extra_cflags_${libname} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS})
|
||||
set(extra_linkflags_${libname} ${TARGET_${arch}_LINKFLAGS} ${LIB_LINKFLAGS})
|
||||
set(extra_link_flags_${libname} ${TARGET_${arch}_LINK_FLAGS} ${LIB_LINK_FLAGS})
|
||||
if(WIN32)
|
||||
set(output_name_${libname} ${name}_dynamic-${arch}${COMPILER_RT_OS_SUFFIX})
|
||||
else()
|
||||
@ -188,7 +188,7 @@ function(add_compiler_rt_runtime name type)
|
||||
|
||||
add_library(${libname} ${type} ${sources_${libname}})
|
||||
set_target_compile_flags(${libname} ${extra_cflags_${libname}})
|
||||
set_target_link_flags(${libname} ${extra_linkflags_${libname}})
|
||||
set_target_link_flags(${libname} ${extra_link_flags_${libname}})
|
||||
set_property(TARGET ${libname} APPEND PROPERTY
|
||||
COMPILE_DEFINITIONS ${LIB_DEFS})
|
||||
set_target_output_directories(${libname} ${COMPILER_RT_LIBRARY_OUTPUT_DIR})
|
||||
@ -243,7 +243,7 @@ endfunction()
|
||||
# when cross compiling, COMPILER_RT_TEST_COMPILER_CFLAGS help
|
||||
# in compilation and linking of unittests.
|
||||
string(REPLACE " " ";" COMPILER_RT_UNITTEST_CFLAGS "${COMPILER_RT_TEST_COMPILER_CFLAGS}")
|
||||
set(COMPILER_RT_UNITTEST_LINKFLAGS ${COMPILER_RT_UNITTEST_CFLAGS})
|
||||
set(COMPILER_RT_UNITTEST_LINK_FLAGS ${COMPILER_RT_UNITTEST_CFLAGS})
|
||||
|
||||
# Unittests support.
|
||||
set(COMPILER_RT_GTEST_PATH ${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest)
|
||||
|
@ -66,7 +66,7 @@ function(darwin_test_archs os valid_archs)
|
||||
file(WRITE ${SIMPLE_C} "#include <stdio.h>\nint main() { printf(__FILE__); return 0; }\n")
|
||||
|
||||
set(os_linker_flags)
|
||||
foreach(flag ${DARWIN_${os}_LINKFLAGS})
|
||||
foreach(flag ${DARWIN_${os}_LINK_FLAGS})
|
||||
set(os_linker_flags "${os_linker_flags} ${flag}")
|
||||
endforeach()
|
||||
endif()
|
||||
|
@ -1,16 +1,16 @@
|
||||
# Link a shared library with COMPILER_RT_TEST_COMPILER.
|
||||
# clang_link_shared(<output.so>
|
||||
# OBJECTS <list of input objects>
|
||||
# LINKFLAGS <list of link flags>
|
||||
# LINK_FLAGS <list of link flags>
|
||||
# DEPS <list of dependencies>)
|
||||
macro(clang_link_shared so_file)
|
||||
cmake_parse_arguments(SOURCE "" "" "OBJECTS;LINKFLAGS;DEPS" ${ARGN})
|
||||
cmake_parse_arguments(SOURCE "" "" "OBJECTS;LINK_FLAGS;DEPS" ${ARGN})
|
||||
if(NOT COMPILER_RT_STANDALONE_BUILD)
|
||||
list(APPEND SOURCE_DEPS clang)
|
||||
endif()
|
||||
add_custom_command(
|
||||
OUTPUT ${so_file}
|
||||
COMMAND ${COMPILER_RT_TEST_COMPILER} -o "${so_file}" -shared
|
||||
${SOURCE_LINKFLAGS} ${SOURCE_OBJECTS}
|
||||
${SOURCE_LINK_FLAGS} ${SOURCE_OBJECTS}
|
||||
DEPENDS ${SOURCE_DEPS})
|
||||
endmacro()
|
||||
|
@ -126,7 +126,7 @@ endfunction()
|
||||
# If successful, saves target flags for this architecture.
|
||||
macro(test_target_arch arch def)
|
||||
set(TARGET_${arch}_CFLAGS ${ARGN})
|
||||
set(TARGET_${arch}_LINKFLAGS ${ARGN})
|
||||
set(TARGET_${arch}_LINK_FLAGS ${ARGN})
|
||||
set(argstring "")
|
||||
foreach(arg ${ARGN})
|
||||
set(argstring "${argstring} ${arg}")
|
||||
@ -219,8 +219,18 @@ macro(load_llvm_config)
|
||||
set(LLVM_MAIN_SRC_DIR ${MAIN_SRC_DIR} CACHE PATH "Path to LLVM source tree")
|
||||
|
||||
# Make use of LLVM CMake modules.
|
||||
file(TO_CMAKE_PATH ${LLVM_BINARY_DIR} LLVM_BINARY_DIR_CMAKE_STYLE)
|
||||
set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR_CMAKE_STYLE}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")
|
||||
# --cmakedir is supported since llvm r291218 (4.0 release)
|
||||
execute_process(
|
||||
COMMAND ${LLVM_CONFIG_PATH} --cmakedir
|
||||
RESULT_VARIABLE HAD_ERROR
|
||||
OUTPUT_VARIABLE CONFIG_OUTPUT)
|
||||
if(NOT HAD_ERROR)
|
||||
string(STRIP "${CONFIG_OUTPUT}" LLVM_CMAKE_PATH)
|
||||
else()
|
||||
file(TO_CMAKE_PATH ${LLVM_BINARY_DIR} LLVM_BINARY_DIR_CMAKE_STYLE)
|
||||
set(LLVM_CMAKE_PATH "${LLVM_BINARY_DIR_CMAKE_STYLE}/lib${LLVM_LIBDIR_SUFFIX}/cmake/llvm")
|
||||
endif()
|
||||
|
||||
list(APPEND CMAKE_MODULE_PATH "${LLVM_CMAKE_PATH}")
|
||||
# Get some LLVM variables from LLVMConfig.
|
||||
include("${LLVM_CMAKE_PATH}/LLVMConfig.cmake")
|
||||
|
@ -48,13 +48,13 @@ endmacro()
|
||||
|
||||
# This function is only used on Darwin, where undefined symbols must be specified
|
||||
# in the linker invocation.
|
||||
function(add_weak_symbols libname linkflags)
|
||||
function(add_weak_symbols libname link_flags)
|
||||
file(STRINGS "${COMPILER_RT_SOURCE_DIR}/lib/${libname}/weak_symbols.txt" WEAK_SYMBOLS)
|
||||
set(local_linkflags ${${linkflags}})
|
||||
set(local_link_flags ${${link_flags}})
|
||||
foreach(SYMBOL ${WEAK_SYMBOLS})
|
||||
set(local_linkflags ${local_linkflags} -Wl,-U,${SYMBOL})
|
||||
set(local_link_flags ${local_link_flags} -Wl,-U,${SYMBOL})
|
||||
endforeach()
|
||||
set(${linkflags} ${local_linkflags} PARENT_SCOPE)
|
||||
set(${link_flags} ${local_link_flags} PARENT_SCOPE)
|
||||
endfunction()
|
||||
|
||||
macro(add_sanitizer_rt_version_list name)
|
||||
|
@ -29,6 +29,7 @@ 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(-fno-lto COMPILER_RT_HAS_FNO_LTO_FLAG)
|
||||
check_cxx_compiler_flag("-Werror -msse3" COMPILER_RT_HAS_MSSE3_FLAG)
|
||||
check_cxx_compiler_flag("-Werror -msse4.2" COMPILER_RT_HAS_MSSE4_2_FLAG)
|
||||
check_cxx_compiler_flag(--sysroot=. COMPILER_RT_HAS_SYSROOT_FLAG)
|
||||
|
||||
if(NOT WIN32 AND NOT CYGWIN)
|
||||
@ -241,26 +242,26 @@ if(APPLE)
|
||||
set(CMAKE_OSX_DEPLOYMENT_TARGET "")
|
||||
|
||||
set(DARWIN_COMMON_CFLAGS -stdlib=libc++)
|
||||
set(DARWIN_COMMON_LINKFLAGS
|
||||
set(DARWIN_COMMON_LINK_FLAGS
|
||||
-stdlib=libc++
|
||||
-lc++
|
||||
-lc++abi)
|
||||
|
||||
check_linker_flag("-fapplication-extension" COMPILER_RT_HAS_APP_EXTENSION)
|
||||
if(COMPILER_RT_HAS_APP_EXTENSION)
|
||||
list(APPEND DARWIN_COMMON_LINKFLAGS "-fapplication-extension")
|
||||
list(APPEND DARWIN_COMMON_LINK_FLAGS "-fapplication-extension")
|
||||
endif()
|
||||
|
||||
set(DARWIN_osx_CFLAGS
|
||||
${DARWIN_COMMON_CFLAGS}
|
||||
-mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION})
|
||||
set(DARWIN_osx_LINKFLAGS
|
||||
${DARWIN_COMMON_LINKFLAGS}
|
||||
set(DARWIN_osx_LINK_FLAGS
|
||||
${DARWIN_COMMON_LINK_FLAGS}
|
||||
-mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION})
|
||||
|
||||
if(DARWIN_osx_SYSROOT)
|
||||
list(APPEND DARWIN_osx_CFLAGS -isysroot ${DARWIN_osx_SYSROOT})
|
||||
list(APPEND DARWIN_osx_LINKFLAGS -isysroot ${DARWIN_osx_SYSROOT})
|
||||
list(APPEND DARWIN_osx_LINK_FLAGS -isysroot ${DARWIN_osx_SYSROOT})
|
||||
endif()
|
||||
|
||||
# Figure out which arches to use for each OS
|
||||
@ -283,8 +284,8 @@ if(APPLE)
|
||||
${DARWIN_COMMON_CFLAGS}
|
||||
${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG}
|
||||
-isysroot ${DARWIN_${platform}sim_SYSROOT})
|
||||
set(DARWIN_${platform}sim_LINKFLAGS
|
||||
${DARWIN_COMMON_LINKFLAGS}
|
||||
set(DARWIN_${platform}sim_LINK_FLAGS
|
||||
${DARWIN_COMMON_LINK_FLAGS}
|
||||
${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG}
|
||||
-isysroot ${DARWIN_${platform}sim_SYSROOT})
|
||||
|
||||
@ -311,8 +312,8 @@ if(APPLE)
|
||||
${DARWIN_COMMON_CFLAGS}
|
||||
${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG}
|
||||
-isysroot ${DARWIN_${platform}_SYSROOT})
|
||||
set(DARWIN_${platform}_LINKFLAGS
|
||||
${DARWIN_COMMON_LINKFLAGS}
|
||||
set(DARWIN_${platform}_LINK_FLAGS
|
||||
${DARWIN_COMMON_LINK_FLAGS}
|
||||
${DARWIN_${platform}_SANITIZER_MIN_VER_FLAG}
|
||||
-isysroot ${DARWIN_${platform}_SYSROOT})
|
||||
|
||||
|
@ -106,9 +106,9 @@ endif()
|
||||
add_compiler_rt_component(asan)
|
||||
|
||||
if(APPLE)
|
||||
add_weak_symbols("asan" WEAK_SYMBOL_LINKFLAGS)
|
||||
add_weak_symbols("ubsan" WEAK_SYMBOL_LINKFLAGS)
|
||||
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINKFLAGS)
|
||||
add_weak_symbols("asan" WEAK_SYMBOL_LINK_FLAGS)
|
||||
add_weak_symbols("ubsan" WEAK_SYMBOL_LINK_FLAGS)
|
||||
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
|
||||
|
||||
add_compiler_rt_runtime(clang_rt.asan
|
||||
SHARED
|
||||
@ -121,7 +121,7 @@ if(APPLE)
|
||||
RTLSanCommon
|
||||
RTUbsan
|
||||
CFLAGS ${ASAN_DYNAMIC_CFLAGS}
|
||||
LINKFLAGS ${WEAK_SYMBOL_LINKFLAGS}
|
||||
LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
|
||||
DEFS ${ASAN_DYNAMIC_DEFINITIONS}
|
||||
PARENT_TARGET asan)
|
||||
else()
|
||||
@ -188,7 +188,7 @@ else()
|
||||
RTAsan_dynamic_version_script_dummy
|
||||
RTUbsan_cxx
|
||||
CFLAGS ${ASAN_DYNAMIC_CFLAGS}
|
||||
LINKFLAGS ${ASAN_DYNAMIC_LINK_FLAGS}
|
||||
LINK_FLAGS ${ASAN_DYNAMIC_LINK_FLAGS}
|
||||
${VERSION_SCRIPT_FLAG}
|
||||
LINK_LIBS ${ASAN_DYNAMIC_LIBS}
|
||||
DEFS ${ASAN_DYNAMIC_DEFINITIONS}
|
||||
|
@ -77,12 +77,13 @@ static struct AsanDeactivatedFlags {
|
||||
|
||||
void Print() {
|
||||
Report(
|
||||
"quarantine_size_mb %d, max_redzone %d, poison_heap %d, "
|
||||
"malloc_context_size %d, alloc_dealloc_mismatch %d, "
|
||||
"allocator_may_return_null %d, coverage %d, coverage_dir %s, "
|
||||
"allocator_release_to_os_interval_ms %d\n",
|
||||
allocator_options.quarantine_size_mb, allocator_options.max_redzone,
|
||||
poison_heap, malloc_context_size,
|
||||
"quarantine_size_mb %d, thread_local_quarantine_size_kb %d, "
|
||||
"max_redzone %d, poison_heap %d, malloc_context_size %d, "
|
||||
"alloc_dealloc_mismatch %d, allocator_may_return_null %d, coverage %d, "
|
||||
"coverage_dir %s, allocator_release_to_os_interval_ms %d\n",
|
||||
allocator_options.quarantine_size_mb,
|
||||
allocator_options.thread_local_quarantine_size_kb,
|
||||
allocator_options.max_redzone, poison_heap, malloc_context_size,
|
||||
allocator_options.alloc_dealloc_mismatch,
|
||||
allocator_options.may_return_null, coverage, coverage_dir,
|
||||
allocator_options.release_to_os_interval_ms);
|
||||
@ -109,6 +110,7 @@ void AsanDeactivate() {
|
||||
|
||||
AllocatorOptions disabled = asan_deactivated_flags.allocator_options;
|
||||
disabled.quarantine_size_mb = 0;
|
||||
disabled.thread_local_quarantine_size_kb = 0;
|
||||
disabled.min_redzone = 16; // Redzone must be at least 16 bytes long.
|
||||
disabled.max_redzone = 16;
|
||||
disabled.alloc_dealloc_mismatch = false;
|
||||
|
@ -24,6 +24,7 @@
|
||||
ASAN_ACTIVATION_FLAG(int, redzone)
|
||||
ASAN_ACTIVATION_FLAG(int, max_redzone)
|
||||
ASAN_ACTIVATION_FLAG(int, quarantine_size_mb)
|
||||
ASAN_ACTIVATION_FLAG(int, thread_local_quarantine_size_kb)
|
||||
ASAN_ACTIVATION_FLAG(bool, alloc_dealloc_mismatch)
|
||||
ASAN_ACTIVATION_FLAG(bool, poison_heap)
|
||||
|
||||
|
@ -269,24 +269,24 @@ struct Allocator {
|
||||
}
|
||||
|
||||
void RePoisonChunk(uptr chunk) {
|
||||
// This could a user-facing chunk (with redzones), or some internal
|
||||
// This could be a user-facing chunk (with redzones), or some internal
|
||||
// housekeeping chunk, like TransferBatch. Start by assuming the former.
|
||||
AsanChunk *ac = GetAsanChunk((void *)chunk);
|
||||
uptr allocated_size = allocator.GetActuallyAllocatedSize((void *)ac);
|
||||
uptr beg = ac->Beg();
|
||||
uptr end = ac->Beg() + ac->UsedSize(true);
|
||||
uptr chunk_end = chunk + allocated_size;
|
||||
if (chunk < beg && beg < end && end <= chunk_end) {
|
||||
// Looks like a valid AsanChunk. Or maybe not. Be conservative and only
|
||||
// poison the redzones.
|
||||
if (chunk < beg && beg < end && end <= chunk_end &&
|
||||
ac->chunk_state == CHUNK_ALLOCATED) {
|
||||
// Looks like a valid AsanChunk in use, poison redzones only.
|
||||
PoisonShadow(chunk, beg - chunk, kAsanHeapLeftRedzoneMagic);
|
||||
uptr end_aligned_down = RoundDownTo(end, SHADOW_GRANULARITY);
|
||||
FastPoisonShadowPartialRightRedzone(
|
||||
end_aligned_down, end - end_aligned_down,
|
||||
chunk_end - end_aligned_down, kAsanHeapLeftRedzoneMagic);
|
||||
} else {
|
||||
// This can not be an AsanChunk. Poison everything. It may be reused as
|
||||
// AsanChunk later.
|
||||
// This is either not an AsanChunk or freed or quarantined AsanChunk.
|
||||
// In either case, poison everything.
|
||||
PoisonShadow(chunk, allocated_size, kAsanHeapLeftRedzoneMagic);
|
||||
}
|
||||
}
|
||||
|
@ -169,6 +169,11 @@ void InitializeFlags() {
|
||||
(ASAN_LOW_MEMORY) ? 1 << 6 : FIRST_32_SECOND_64(1 << 8, 1 << 10);
|
||||
f->thread_local_quarantine_size_kb = kDefaultThreadLocalQuarantineSizeKb;
|
||||
}
|
||||
if (f->thread_local_quarantine_size_kb == 0 && f->quarantine_size_mb > 0) {
|
||||
Report("%s: thread_local_quarantine_size_kb can be set to 0 only when "
|
||||
"quarantine_size_mb is set to 0\n", SanitizerToolName);
|
||||
Die();
|
||||
}
|
||||
if (!f->replace_str && common_flags()->intercept_strlen) {
|
||||
Report("WARNING: strlen interceptor is enabled even though replace_str=0. "
|
||||
"Use intercept_strlen=0 to disable it.");
|
||||
|
@ -36,8 +36,8 @@ append_list_if(COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG -Wno-variadic-macros ASAN_U
|
||||
|
||||
# This will ensure the target linker is used
|
||||
# during cross compilation
|
||||
set(ASAN_UNITTEST_COMMON_LINKFLAGS
|
||||
${COMPILER_RT_UNITTEST_LINKFLAGS})
|
||||
set(ASAN_UNITTEST_COMMON_LINK_FLAGS
|
||||
${COMPILER_RT_UNITTEST_LINK_FLAGS})
|
||||
|
||||
# -gline-tables-only must be enough for ASan, so use it if possible.
|
||||
if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang")
|
||||
@ -48,7 +48,7 @@ endif()
|
||||
if(MSVC)
|
||||
list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gcodeview)
|
||||
endif()
|
||||
list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -g)
|
||||
list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS -g)
|
||||
|
||||
# Use -D instead of definitions to please custom compile command.
|
||||
list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
|
||||
@ -58,12 +58,12 @@ list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
|
||||
|
||||
if(APPLE)
|
||||
list(APPEND ASAN_UNITTEST_COMMON_CFLAGS ${DARWIN_osx_CFLAGS})
|
||||
list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS ${DARWIN_osx_LINKFLAGS})
|
||||
list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS ${DARWIN_osx_LINK_FLAGS})
|
||||
|
||||
add_weak_symbols("asan" WEAK_SYMBOL_LINKFLAGS)
|
||||
add_weak_symbols("ubsan" WEAK_SYMBOL_LINKFLAGS)
|
||||
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINKFLAGS)
|
||||
list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS ${WEAK_SYMBOL_LINKFLAGS})
|
||||
add_weak_symbols("asan" WEAK_SYMBOL_LINK_FLAGS)
|
||||
add_weak_symbols("ubsan" WEAK_SYMBOL_LINK_FLAGS)
|
||||
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
|
||||
list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS})
|
||||
endif()
|
||||
|
||||
if(MSVC)
|
||||
@ -82,41 +82,41 @@ if(CAN_TARGET_x86_64 OR CAN_TARGET_i386)
|
||||
endif()
|
||||
|
||||
if(NOT MSVC)
|
||||
list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS --driver-mode=g++)
|
||||
list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS --driver-mode=g++)
|
||||
endif()
|
||||
|
||||
# x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests.
|
||||
if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE")
|
||||
list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS "-lc++")
|
||||
list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS "-lc++")
|
||||
endif()
|
||||
|
||||
# Unit tests on Mac depend on Foundation.
|
||||
if(APPLE)
|
||||
list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -framework Foundation)
|
||||
list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS -framework Foundation)
|
||||
endif()
|
||||
if(ANDROID)
|
||||
list(APPEND ASAN_UNITTEST_COMMON_LINKFLAGS -pie)
|
||||
list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS -pie)
|
||||
endif()
|
||||
|
||||
set(ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS
|
||||
${ASAN_UNITTEST_COMMON_LINKFLAGS})
|
||||
list(APPEND ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS -fsanitize=address)
|
||||
set(ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS
|
||||
${ASAN_UNITTEST_COMMON_LINK_FLAGS})
|
||||
list(APPEND ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS -fsanitize=address)
|
||||
|
||||
set(ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS
|
||||
${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS}
|
||||
set(ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS
|
||||
${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS}
|
||||
-shared-libasan)
|
||||
|
||||
set(ASAN_UNITTEST_INSTRUMENTED_LIBS)
|
||||
# NDK r10 requires -latomic almost always.
|
||||
append_list_if(ANDROID atomic ASAN_UNITTEST_INSTRUMENTED_LIBS)
|
||||
|
||||
set(ASAN_UNITTEST_NOINST_LINKFLAGS ${ASAN_UNITTEST_COMMON_LINKFLAGS})
|
||||
set(ASAN_UNITTEST_NOINST_LINK_FLAGS ${ASAN_UNITTEST_COMMON_LINK_FLAGS})
|
||||
if(NOT APPLE)
|
||||
append_list_if(COMPILER_RT_HAS_LIBM -lm ASAN_UNITTEST_NOINST_LINKFLAGS)
|
||||
append_list_if(COMPILER_RT_HAS_LIBDL -ldl ASAN_UNITTEST_NOINST_LINKFLAGS)
|
||||
append_list_if(COMPILER_RT_HAS_LIBRT -lrt ASAN_UNITTEST_NOINST_LINKFLAGS)
|
||||
append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_UNITTEST_NOINST_LINKFLAGS)
|
||||
append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS)
|
||||
append_list_if(COMPILER_RT_HAS_LIBM -lm ASAN_UNITTEST_NOINST_LINK_FLAGS)
|
||||
append_list_if(COMPILER_RT_HAS_LIBDL -ldl ASAN_UNITTEST_NOINST_LINK_FLAGS)
|
||||
append_list_if(COMPILER_RT_HAS_LIBRT -lrt ASAN_UNITTEST_NOINST_LINK_FLAGS)
|
||||
append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_UNITTEST_NOINST_LINK_FLAGS)
|
||||
append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS)
|
||||
endif()
|
||||
|
||||
# TODO(eugenis): move all -l flags above to _LIBS?
|
||||
@ -148,7 +148,7 @@ endmacro()
|
||||
# Link ASan unit test for a given architecture from a set
|
||||
# of objects in with given linker flags.
|
||||
macro(add_asan_test test_suite test_name arch kind)
|
||||
cmake_parse_arguments(TEST "WITH_TEST_RUNTIME" "" "OBJECTS;LINKFLAGS;SUBDIR" ${ARGN})
|
||||
cmake_parse_arguments(TEST "WITH_TEST_RUNTIME" "" "OBJECTS;LINK_FLAGS;SUBDIR" ${ARGN})
|
||||
get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)
|
||||
set(TEST_DEPS ${TEST_OBJECTS})
|
||||
if(NOT COMPILER_RT_STANDALONE_BUILD)
|
||||
@ -172,7 +172,7 @@ macro(add_asan_test test_suite test_name arch kind)
|
||||
SUBDIR ${TEST_SUBDIR}
|
||||
OBJECTS ${TEST_OBJECTS}
|
||||
DEPS ${TEST_DEPS}
|
||||
LINK_FLAGS ${TEST_LINKFLAGS}
|
||||
LINK_FLAGS ${TEST_LINK_FLAGS}
|
||||
${TARGET_LINK_FLAGS})
|
||||
endmacro()
|
||||
|
||||
@ -237,8 +237,8 @@ macro(add_asan_tests_for_arch_and_kind arch kind)
|
||||
endforeach()
|
||||
# Clang links the static CRT by default. Override that to use the dynamic
|
||||
# CRT.
|
||||
set(ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS
|
||||
${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS}
|
||||
set(ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS
|
||||
${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS}
|
||||
-Wl,-nodefaultlib:libcmt,-defaultlib:msvcrt,-defaultlib:oldnames)
|
||||
else()
|
||||
set(ASAN_INST_DYNAMIC_TEST_OBJECTS ${ASAN_INST_TEST_OBJECTS})
|
||||
@ -256,7 +256,7 @@ macro(add_asan_tests_for_arch_and_kind arch kind)
|
||||
add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Test"
|
||||
${arch} ${kind} SUBDIR "default"
|
||||
OBJECTS ${ASAN_INST_TEST_OBJECTS}
|
||||
LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
|
||||
LINK_FLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS})
|
||||
if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
|
||||
# Create the 'dynamic' folder where ASAN tests are produced.
|
||||
if(CMAKE_CONFIGURATION_TYPES)
|
||||
@ -270,7 +270,7 @@ macro(add_asan_tests_for_arch_and_kind arch kind)
|
||||
add_asan_test(AsanDynamicUnitTests "Asan-${arch}${kind}-Dynamic-Test"
|
||||
${arch} ${kind} SUBDIR "dynamic"
|
||||
OBJECTS ${ASAN_INST_DYNAMIC_TEST_OBJECTS}
|
||||
LINKFLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINKFLAGS})
|
||||
LINK_FLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS})
|
||||
endif()
|
||||
|
||||
# Add static ASan runtime that will be linked with uninstrumented tests.
|
||||
@ -307,7 +307,7 @@ macro(add_asan_tests_for_arch_and_kind arch kind)
|
||||
add_asan_test(AsanUnitTests "Asan-${arch}${kind}-Noinst-Test"
|
||||
${arch} ${kind} SUBDIR "default"
|
||||
OBJECTS ${ASAN_NOINST_TEST_OBJECTS}
|
||||
LINKFLAGS ${ASAN_UNITTEST_NOINST_LINKFLAGS}
|
||||
LINK_FLAGS ${ASAN_UNITTEST_NOINST_LINK_FLAGS}
|
||||
WITH_TEST_RUNTIME)
|
||||
|
||||
# Benchmarks.
|
||||
@ -319,7 +319,7 @@ macro(add_asan_tests_for_arch_and_kind arch kind)
|
||||
add_asan_test(AsanBenchmarks "Asan-${arch}${kind}-Benchmark"
|
||||
${arch} ${kind} SUBDIR "default"
|
||||
OBJECTS ${ASAN_BENCHMARKS_OBJECTS}
|
||||
LINKFLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
|
||||
LINK_FLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS})
|
||||
endmacro()
|
||||
|
||||
if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
|
||||
@ -347,7 +347,7 @@ if(ANDROID)
|
||||
${COMPILER_RT_GTEST_SOURCE}
|
||||
${ASAN_NOINST_TEST_SOURCES})
|
||||
set_target_compile_flags(AsanNoinstTest ${ASAN_UNITTEST_COMMON_CFLAGS})
|
||||
set_target_link_flags(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LINKFLAGS})
|
||||
set_target_link_flags(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LINK_FLAGS})
|
||||
target_link_libraries(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LIBS})
|
||||
|
||||
# Test with ASan instrumentation. Link with ASan dynamic runtime.
|
||||
@ -355,7 +355,7 @@ if(ANDROID)
|
||||
${COMPILER_RT_GTEST_SOURCE}
|
||||
${ASAN_INST_TEST_SOURCES})
|
||||
set_target_compile_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS})
|
||||
set_target_link_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LINKFLAGS})
|
||||
set_target_link_flags(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS})
|
||||
target_link_libraries(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LIBS})
|
||||
|
||||
# Setup correct output directory and link flags.
|
||||
|
@ -18,10 +18,14 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__adddf3vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vadd.f64 d0, d0, d1
|
||||
#else
|
||||
vmov d6, r0, r1 // move first param from r0/r1 pair into d6
|
||||
vmov d7, r2, r3 // move second param from r2/r3 pair into d7
|
||||
vadd.f64 d6, d6, d7
|
||||
vmov r0, r1, d6 // move result back to r0/r1 pair
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__adddf3vfp)
|
||||
|
||||
|
@ -18,10 +18,14 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__addsf3vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vadd.f32 s0, s0, s1
|
||||
#else
|
||||
vmov s14, r0 // move first param from r0 into float register
|
||||
vmov s15, r1 // move second param from r1 into float register
|
||||
vadd.f32 s14, s14, s15
|
||||
vmov r0, s14 // move result back to r0
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__addsf3vfp)
|
||||
|
||||
|
@ -43,8 +43,14 @@
|
||||
.thumb
|
||||
#endif
|
||||
|
||||
.p2align 2
|
||||
@ int __eqsf2(float a, float b)
|
||||
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__eqsf2)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vmov r0, s0
|
||||
vmov r1, s1
|
||||
#endif
|
||||
// Make copies of a and b with the sign bit shifted off the top. These will
|
||||
// be used to detect zeros and NaNs.
|
||||
#if __ARM_ARCH_ISA_THUMB == 1
|
||||
@ -166,16 +172,23 @@ LOCAL_LABEL(CHECK_NAN):
|
||||
JMP(lr)
|
||||
#endif
|
||||
END_COMPILERRT_FUNCTION(__eqsf2)
|
||||
|
||||
DEFINE_COMPILERRT_FUNCTION_ALIAS(__lesf2, __eqsf2)
|
||||
DEFINE_COMPILERRT_FUNCTION_ALIAS(__ltsf2, __eqsf2)
|
||||
DEFINE_COMPILERRT_FUNCTION_ALIAS(__nesf2, __eqsf2)
|
||||
|
||||
.p2align 2
|
||||
@ int __gtsf2(float a, float b)
|
||||
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__gtsf2)
|
||||
// Identical to the preceding except in that we return -1 for NaN values.
|
||||
// Given that the two paths share so much code, one might be tempted to
|
||||
// unify them; however, the extra code needed to do so makes the code size
|
||||
// to performance tradeoff very hard to justify for such small functions.
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vmov r0, s0
|
||||
vmov r1, s1
|
||||
#endif
|
||||
#if __ARM_ARCH_ISA_THUMB == 1
|
||||
push {r6, lr}
|
||||
lsls r2, r0, #1
|
||||
@ -215,6 +228,8 @@ LOCAL_LABEL(CHECK_NAN_2):
|
||||
6:
|
||||
pop {r6, pc}
|
||||
#else
|
||||
mov r2, r0, lsl #1
|
||||
mov r3, r1, lsl #1
|
||||
orrs r12, r2, r3, lsr #1
|
||||
it ne
|
||||
eorsne r12, r0, r1
|
||||
@ -233,10 +248,17 @@ LOCAL_LABEL(CHECK_NAN_2):
|
||||
JMP(lr)
|
||||
#endif
|
||||
END_COMPILERRT_FUNCTION(__gtsf2)
|
||||
|
||||
DEFINE_COMPILERRT_FUNCTION_ALIAS(__gesf2, __gtsf2)
|
||||
|
||||
.p2align 2
|
||||
@ int __unordsf2(float a, float b)
|
||||
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__unordsf2)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vmov r0, s0
|
||||
vmov r1, s1
|
||||
#endif
|
||||
// Return 1 for NaN values, 0 otherwise.
|
||||
lsls r2, r0, #1
|
||||
lsls r3, r1, #1
|
||||
@ -260,7 +282,15 @@ DEFINE_COMPILERRT_FUNCTION(__unordsf2)
|
||||
JMP(lr)
|
||||
END_COMPILERRT_FUNCTION(__unordsf2)
|
||||
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
DEFINE_COMPILERRT_FUNCTION(__aeabi_fcmpum):
|
||||
vmov s0, r0
|
||||
vmov s1, r1
|
||||
b SYMBOL_NAME(__unordsf2)
|
||||
END_COMPILERRT_FUNCTION(__aeabi_fcmpum)
|
||||
#else
|
||||
DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_fcmpun, __unordsf2)
|
||||
#endif
|
||||
|
||||
NO_EXEC_STACK_DIRECTIVE
|
||||
|
||||
|
@ -18,10 +18,14 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__divdf3vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vdiv.f64 d0, d0, d1
|
||||
#else
|
||||
vmov d6, r0, r1 // move first param from r0/r1 pair into d6
|
||||
vmov d7, r2, r3 // move second param from r2/r3 pair into d7
|
||||
vdiv.f64 d5, d6, d7
|
||||
vdiv.f64 d5, d6, d7
|
||||
vmov r0, r1, d5 // move result back to r0/r1 pair
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__divdf3vfp)
|
||||
|
||||
|
@ -18,10 +18,14 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__divsf3vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vdiv.f32 s0, s0, s1
|
||||
#else
|
||||
vmov s14, r0 // move first param from r0 into float register
|
||||
vmov s15, r1 // move second param from r1 into float register
|
||||
vdiv.f32 s13, s14, s15
|
||||
vmov r0, s13 // move result back to r0
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__divsf3vfp)
|
||||
|
||||
|
@ -19,9 +19,13 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__eqdf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcmp.f64 d0, d1
|
||||
#else
|
||||
vmov d6, r0, r1 // load r0/r1 pair in double register
|
||||
vmov d7, r2, r3 // load r2/r3 pair in double register
|
||||
vcmp.f64 d6, d7
|
||||
#endif
|
||||
vmrs apsr_nzcv, fpscr
|
||||
moveq r0, #1 // set result register to 1 if equal
|
||||
movne r0, #0
|
||||
|
@ -19,9 +19,13 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__eqsf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcmp.f32 s0, s1
|
||||
#else
|
||||
vmov s14, r0 // move from GPR 0 to float register
|
||||
vmov s15, r1 // move from GPR 1 to float register
|
||||
vcmp.f32 s14, s15
|
||||
#endif
|
||||
vmrs apsr_nzcv, fpscr
|
||||
moveq r0, #1 // set result register to 1 if equal
|
||||
movne r0, #0
|
||||
|
@ -19,9 +19,13 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__extendsfdf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcvt.f64.f32 d0, s0
|
||||
#else
|
||||
vmov s15, r0 // load float register from R0
|
||||
vcvt.f64.f32 d7, s15 // convert single to double
|
||||
vmov r0, r1, d7 // return result in r0/r1 pair
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__extendsfdf2vfp)
|
||||
|
||||
|
@ -19,9 +19,14 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__fixdfsivfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcvt.s32.f64 s0, d0
|
||||
vmov r0, s0
|
||||
#else
|
||||
vmov d7, r0, r1 // load double register from R0/R1
|
||||
vcvt.s32.f64 s15, d7 // convert double to 32-bit int into s15
|
||||
vmov r0, s15 // move s15 to result register
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__fixdfsivfp)
|
||||
|
||||
|
@ -19,9 +19,14 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__fixsfsivfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcvt.s32.f32 s0, s0
|
||||
vmov r0, s0
|
||||
#else
|
||||
vmov s15, r0 // load float register from R0
|
||||
vcvt.s32.f32 s15, s15 // convert single to 32-bit int into s15
|
||||
vmov r0, s15 // move s15 to result register
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__fixsfsivfp)
|
||||
|
||||
|
@ -20,9 +20,14 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__fixunsdfsivfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcvt.u32.f64 s0, d0
|
||||
vmov r0, s0
|
||||
#else
|
||||
vmov d7, r0, r1 // load double register from R0/R1
|
||||
vcvt.u32.f64 s15, d7 // convert double to 32-bit int into s15
|
||||
vmov r0, s15 // move s15 to result register
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__fixunsdfsivfp)
|
||||
|
||||
|
@ -20,9 +20,14 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__fixunssfsivfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcvt.u32.f32 s0, s0
|
||||
vmov r0, s0
|
||||
#else
|
||||
vmov s15, r0 // load float register from R0
|
||||
vcvt.u32.f32 s15, s15 // convert single to 32-bit unsigned into s15
|
||||
vmov r0, s15 // move s15 to result register
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__fixunssfsivfp)
|
||||
|
||||
|
@ -19,9 +19,14 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__floatsidfvfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vmov s0, r0
|
||||
vcvt.f64.s32 d0, s0
|
||||
#else
|
||||
vmov s15, r0 // move int to float register s15
|
||||
vcvt.f64.s32 d7, s15 // convert 32-bit int in s15 to double in d7
|
||||
vmov r0, r1, d7 // move d7 to result register pair r0/r1
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__floatsidfvfp)
|
||||
|
||||
|
@ -19,9 +19,14 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__floatsisfvfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vmov s0, r0
|
||||
vcvt.f32.s32 s0, s0
|
||||
#else
|
||||
vmov s15, r0 // move int to float register s15
|
||||
vcvt.f32.s32 s15, s15 // convert 32-bit int in s15 to float in s15
|
||||
vmov r0, s15 // move s15 to result register
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__floatsisfvfp)
|
||||
|
||||
|
@ -19,9 +19,14 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__floatunssidfvfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vmov s0, r0
|
||||
vcvt.f64.u32 d0, s0
|
||||
#else
|
||||
vmov s15, r0 // move int to float register s15
|
||||
vcvt.f64.u32 d7, s15 // convert 32-bit int in s15 to double in d7
|
||||
vmov r0, r1, d7 // move d7 to result register pair r0/r1
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__floatunssidfvfp)
|
||||
|
||||
|
@ -19,9 +19,14 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__floatunssisfvfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vmov s0, r0
|
||||
vcvt.f32.u32 s0, s0
|
||||
#else
|
||||
vmov s15, r0 // move int to float register s15
|
||||
vcvt.f32.u32 s15, s15 // convert 32-bit int in s15 to float in s15
|
||||
vmov r0, s15 // move s15 to result register
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__floatunssisfvfp)
|
||||
|
||||
|
@ -19,9 +19,13 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__gedf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcmp.f64 d0, d1
|
||||
#else
|
||||
vmov d6, r0, r1 // load r0/r1 pair in double register
|
||||
vmov d7, r2, r3 // load r2/r3 pair in double register
|
||||
vcmp.f64 d6, d7
|
||||
#endif
|
||||
vmrs apsr_nzcv, fpscr
|
||||
movge r0, #1 // set result register to 1 if greater than or equal
|
||||
movlt r0, #0
|
||||
|
@ -19,9 +19,13 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__gesf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcmp.f32 s0, s1
|
||||
#else
|
||||
vmov s14, r0 // move from GPR 0 to float register
|
||||
vmov s15, r1 // move from GPR 1 to float register
|
||||
vcmp.f32 s14, s15
|
||||
#endif
|
||||
vmrs apsr_nzcv, fpscr
|
||||
movge r0, #1 // set result register to 1 if greater than or equal
|
||||
movlt r0, #0
|
||||
|
@ -19,9 +19,13 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__gtdf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcmp.f64 d0, d1
|
||||
#else
|
||||
vmov d6, r0, r1 // load r0/r1 pair in double register
|
||||
vmov d7, r2, r3 // load r2/r3 pair in double register
|
||||
vcmp.f64 d6, d7
|
||||
#endif
|
||||
vmrs apsr_nzcv, fpscr
|
||||
movgt r0, #1 // set result register to 1 if equal
|
||||
movle r0, #0
|
||||
|
@ -19,9 +19,13 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__gtsf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcmp.f32 s0, s1
|
||||
#else
|
||||
vmov s14, r0 // move from GPR 0 to float register
|
||||
vmov s15, r1 // move from GPR 1 to float register
|
||||
vcmp.f32 s14, s15
|
||||
#endif
|
||||
vmrs apsr_nzcv, fpscr
|
||||
movgt r0, #1 // set result register to 1 if equal
|
||||
movle r0, #0
|
||||
|
@ -19,9 +19,13 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__ledf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcmp.f64 d0, d1
|
||||
#else
|
||||
vmov d6, r0, r1 // load r0/r1 pair in double register
|
||||
vmov d7, r2, r3 // load r2/r3 pair in double register
|
||||
vcmp.f64 d6, d7
|
||||
#endif
|
||||
vmrs apsr_nzcv, fpscr
|
||||
movls r0, #1 // set result register to 1 if equal
|
||||
movhi r0, #0
|
||||
|
@ -19,9 +19,13 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__lesf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcmp.f32 s0, s1
|
||||
#else
|
||||
vmov s14, r0 // move from GPR 0 to float register
|
||||
vmov s15, r1 // move from GPR 1 to float register
|
||||
vcmp.f32 s14, s15
|
||||
#endif
|
||||
vmrs apsr_nzcv, fpscr
|
||||
movls r0, #1 // set result register to 1 if equal
|
||||
movhi r0, #0
|
||||
|
@ -19,9 +19,13 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__ltdf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcmp.f64 d0, d1
|
||||
#else
|
||||
vmov d6, r0, r1 // load r0/r1 pair in double register
|
||||
vmov d7, r2, r3 // load r2/r3 pair in double register
|
||||
vcmp.f64 d6, d7
|
||||
#endif
|
||||
vmrs apsr_nzcv, fpscr
|
||||
movmi r0, #1 // set result register to 1 if equal
|
||||
movpl r0, #0
|
||||
|
@ -19,9 +19,13 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__ltsf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcmp.f32 s0, s1
|
||||
#else
|
||||
vmov s14, r0 // move from GPR 0 to float register
|
||||
vmov s15, r1 // move from GPR 1 to float register
|
||||
vcmp.f32 s14, s15
|
||||
#endif
|
||||
vmrs apsr_nzcv, fpscr
|
||||
movmi r0, #1 // set result register to 1 if equal
|
||||
movpl r0, #0
|
||||
|
@ -18,10 +18,14 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__muldf3vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vmul.f64 d0, d0, d1
|
||||
#else
|
||||
vmov d6, r0, r1 // move first param from r0/r1 pair into d6
|
||||
vmov d7, r2, r3 // move second param from r2/r3 pair into d7
|
||||
vmul.f64 d6, d6, d7
|
||||
vmul.f64 d6, d6, d7
|
||||
vmov r0, r1, d6 // move result back to r0/r1 pair
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__muldf3vfp)
|
||||
|
||||
|
@ -18,9 +18,13 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__mulsf3vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vmul.f32 s0, s0, s1
|
||||
#else
|
||||
vmov s14, r0 // move first param from r0 into float register
|
||||
vmov s15, r1 // move second param from r1 into float register
|
||||
vmul.f32 s13, s14, s15
|
||||
#endif
|
||||
vmov r0, s13 // move result back to r0
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__mulsf3vfp)
|
||||
|
@ -19,9 +19,13 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__nedf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcmp.f64 d0, d1
|
||||
#else
|
||||
vmov d6, r0, r1 // load r0/r1 pair in double register
|
||||
vmov d7, r2, r3 // load r2/r3 pair in double register
|
||||
vcmp.f64 d6, d7
|
||||
#endif
|
||||
vmrs apsr_nzcv, fpscr
|
||||
movne r0, #1 // set result register to 0 if unequal
|
||||
moveq r0, #0
|
||||
|
@ -18,7 +18,11 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__negdf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vneg.f64 d0, d0
|
||||
#else
|
||||
eor r1, r1, #-2147483648 // flip sign bit on double in r0/r1 pair
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__negdf2vfp)
|
||||
|
||||
|
@ -18,7 +18,11 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__negsf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vneg.f32 s0, s0
|
||||
#else
|
||||
eor r0, r0, #-2147483648 // flip sign bit on float in r0
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__negsf2vfp)
|
||||
|
||||
|
@ -19,9 +19,13 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__nesf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcmp.f32 s0, s1
|
||||
#else
|
||||
vmov s14, r0 // move from GPR 0 to float register
|
||||
vmov s15, r1 // move from GPR 1 to float register
|
||||
vcmp.f32 s14, s15
|
||||
#endif
|
||||
vmrs apsr_nzcv, fpscr
|
||||
movne r0, #1 // set result register to 1 if unequal
|
||||
moveq r0, #0
|
||||
|
@ -18,10 +18,14 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__subdf3vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vsub.f64 d0, d0, d1
|
||||
#else
|
||||
vmov d6, r0, r1 // move first param from r0/r1 pair into d6
|
||||
vmov d7, r2, r3 // move second param from r2/r3 pair into d7
|
||||
vsub.f64 d6, d6, d7
|
||||
vmov r0, r1, d6 // move result back to r0/r1 pair
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__subdf3vfp)
|
||||
|
||||
|
@ -12,17 +12,21 @@
|
||||
//
|
||||
// extern float __subsf3vfp(float a, float b);
|
||||
//
|
||||
// Returns the difference between two single precision floating point numbers
|
||||
// Returns the difference between two single precision floating point numbers
|
||||
// using the Darwin calling convention where single arguments are passsed
|
||||
// like 32-bit ints.
|
||||
//
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__subsf3vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vsub.f32 s0, s0, s1
|
||||
#elsee
|
||||
vmov s14, r0 // move first param from r0 into float register
|
||||
vmov s15, r1 // move second param from r1 into float register
|
||||
vsub.f32 s14, s14, s15
|
||||
vmov r0, s14 // move result back to r0
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__subsf3vfp)
|
||||
|
||||
|
@ -19,9 +19,13 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__truncdfsf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcvt.f32.f64 s0, d0
|
||||
#else
|
||||
vmov d7, r0, r1 // load double from r0/r1 pair
|
||||
vcvt.f32.f64 s15, d7 // convert double to single (trucate precision)
|
||||
vmov r0, s15 // return result in r0
|
||||
#endif
|
||||
bx lr
|
||||
END_COMPILERRT_FUNCTION(__truncdfsf2vfp)
|
||||
|
||||
|
@ -19,9 +19,13 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__unorddf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcmp.f64 d0, d1
|
||||
#else
|
||||
vmov d6, r0, r1 // load r0/r1 pair in double register
|
||||
vmov d7, r2, r3 // load r2/r3 pair in double register
|
||||
vcmp.f64 d6, d7
|
||||
vcmp.f64 d6, d7
|
||||
#endif
|
||||
vmrs apsr_nzcv, fpscr
|
||||
movvs r0, #1 // set result register to 1 if "overflow" (any NaNs)
|
||||
movvc r0, #0
|
||||
|
@ -19,9 +19,13 @@
|
||||
.syntax unified
|
||||
.p2align 2
|
||||
DEFINE_COMPILERRT_FUNCTION(__unordsf2vfp)
|
||||
#if defined(COMPILER_RT_ARMHF_TARGET)
|
||||
vcmp.f32 s0, s1
|
||||
#else
|
||||
vmov s14, r0 // move from GPR 0 to float register
|
||||
vmov s15, r1 // move from GPR 1 to float register
|
||||
vcmp.f32 s14, s15
|
||||
#endif
|
||||
vmrs apsr_nzcv, fpscr
|
||||
movvs r0, #1 // set result register to 1 if "overflow" (any NaNs)
|
||||
movvc r0, #0
|
||||
|
@ -69,15 +69,15 @@ macro(msan_compile obj_list source arch kind)
|
||||
endmacro()
|
||||
|
||||
macro(msan_link_shared so_list so_name arch kind)
|
||||
cmake_parse_arguments(SOURCE "" "" "OBJECTS;LINKFLAGS;DEPS" ${ARGN})
|
||||
cmake_parse_arguments(SOURCE "" "" "OBJECTS;LINK_FLAGS;DEPS" ${ARGN})
|
||||
set(output_so "${CMAKE_CURRENT_BINARY_DIR}/${so_name}.${arch}${kind}.so")
|
||||
get_target_flags_for_arch(${arch} TARGET_LINKFLAGS)
|
||||
get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)
|
||||
if(NOT COMPILER_RT_STANDALONE_BUILD)
|
||||
list(APPEND SOURCE_DEPS msan)
|
||||
endif()
|
||||
clang_link_shared(${output_so}
|
||||
OBJECTS ${SOURCE_OBJECTS}
|
||||
LINKFLAGS ${TARGET_LINKFLAGS} ${SOURCE_LINKFLAGS}
|
||||
LINK_FLAGS ${TARGET_LINK_FLAGS} ${SOURCE_LINK_FLAGS}
|
||||
DEPS ${SOURCE_DEPS})
|
||||
list(APPEND ${so_list} ${output_so})
|
||||
endmacro()
|
||||
|
@ -690,6 +690,7 @@ inline const char *ModuleArchToString(ModuleArch arch) {
|
||||
return "arm64";
|
||||
}
|
||||
CHECK(0 && "Invalid module arch");
|
||||
return "";
|
||||
}
|
||||
|
||||
const uptr kModuleUUIDSize = 16;
|
||||
|
@ -954,7 +954,9 @@ SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_init() {
|
||||
}
|
||||
SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov_dump() {
|
||||
coverage_data.DumpAll();
|
||||
#if SANITIZER_LINUX
|
||||
__sanitizer_dump_trace_pc_guard_coverage();
|
||||
#endif
|
||||
}
|
||||
SANITIZER_INTERFACE_ATTRIBUTE void
|
||||
__sanitizer_cov_module_init(s32 *guards, uptr npcs, u8 *counters,
|
||||
|
@ -78,10 +78,12 @@ void LibIgnore::OnLibraryLoaded(const char *name) {
|
||||
lib->templ, mod.full_name());
|
||||
lib->loaded = true;
|
||||
lib->name = internal_strdup(mod.full_name());
|
||||
const uptr idx = atomic_load(&loaded_count_, memory_order_relaxed);
|
||||
code_ranges_[idx].begin = range.beg;
|
||||
code_ranges_[idx].end = range.end;
|
||||
atomic_store(&loaded_count_, idx + 1, memory_order_release);
|
||||
const uptr idx =
|
||||
atomic_load(&ignored_ranges_count_, memory_order_relaxed);
|
||||
CHECK_LT(idx, kMaxLibs);
|
||||
ignored_code_ranges_[idx].begin = range.beg;
|
||||
ignored_code_ranges_[idx].end = range.end;
|
||||
atomic_store(&ignored_ranges_count_, idx + 1, memory_order_release);
|
||||
break;
|
||||
}
|
||||
}
|
||||
@ -92,6 +94,29 @@ void LibIgnore::OnLibraryLoaded(const char *name) {
|
||||
Die();
|
||||
}
|
||||
}
|
||||
|
||||
// Track instrumented ranges.
|
||||
if (track_instrumented_libs_) {
|
||||
for (const auto &mod : modules) {
|
||||
if (!mod.instrumented())
|
||||
continue;
|
||||
for (const auto &range : mod.ranges()) {
|
||||
if (!range.executable)
|
||||
continue;
|
||||
if (IsPcInstrumented(range.beg) && IsPcInstrumented(range.end - 1))
|
||||
continue;
|
||||
VReport(1, "Adding instrumented range %p-%p from library '%s'\n",
|
||||
range.beg, range.end, mod.full_name());
|
||||
const uptr idx =
|
||||
atomic_load(&instrumented_ranges_count_, memory_order_relaxed);
|
||||
CHECK_LT(idx, kMaxLibs);
|
||||
instrumented_code_ranges_[idx].begin = range.beg;
|
||||
instrumented_code_ranges_[idx].end = range.end;
|
||||
atomic_store(&instrumented_ranges_count_, idx + 1,
|
||||
memory_order_release);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LibIgnore::OnLibraryUnloaded() {
|
||||
|
@ -30,6 +30,9 @@ class LibIgnore {
|
||||
|
||||
// Must be called during initialization.
|
||||
void AddIgnoredLibrary(const char *name_templ);
|
||||
void IgnoreNoninstrumentedModules(bool enable) {
|
||||
track_instrumented_libs_ = enable;
|
||||
}
|
||||
|
||||
// Must be called after a new dynamic library is loaded.
|
||||
void OnLibraryLoaded(const char *name);
|
||||
@ -37,8 +40,14 @@ class LibIgnore {
|
||||
// Must be called after a dynamic library is unloaded.
|
||||
void OnLibraryUnloaded();
|
||||
|
||||
// Checks whether the provided PC belongs to one of the ignored libraries.
|
||||
bool IsIgnored(uptr pc) const;
|
||||
// Checks whether the provided PC belongs to one of the ignored libraries or
|
||||
// the PC should be ignored because it belongs to an non-instrumented module
|
||||
// (when ignore_noninstrumented_modules=1). Also returns true via
|
||||
// "pc_in_ignored_lib" if the PC is in an ignored library, false otherwise.
|
||||
bool IsIgnored(uptr pc, bool *pc_in_ignored_lib) const;
|
||||
|
||||
// Checks whether the provided PC belongs to an instrumented module.
|
||||
bool IsPcInstrumented(uptr pc) const;
|
||||
|
||||
private:
|
||||
struct Lib {
|
||||
@ -53,26 +62,48 @@ class LibIgnore {
|
||||
uptr end;
|
||||
};
|
||||
|
||||
inline bool IsInRange(uptr pc, const LibCodeRange &range) const {
|
||||
return (pc >= range.begin && pc < range.end);
|
||||
}
|
||||
|
||||
static const uptr kMaxLibs = 128;
|
||||
|
||||
// Hot part:
|
||||
atomic_uintptr_t loaded_count_;
|
||||
LibCodeRange code_ranges_[kMaxLibs];
|
||||
atomic_uintptr_t ignored_ranges_count_;
|
||||
LibCodeRange ignored_code_ranges_[kMaxLibs];
|
||||
|
||||
atomic_uintptr_t instrumented_ranges_count_;
|
||||
LibCodeRange instrumented_code_ranges_[kMaxLibs];
|
||||
|
||||
// Cold part:
|
||||
BlockingMutex mutex_;
|
||||
uptr count_;
|
||||
Lib libs_[kMaxLibs];
|
||||
bool track_instrumented_libs_;
|
||||
|
||||
// Disallow copying of LibIgnore objects.
|
||||
LibIgnore(const LibIgnore&); // not implemented
|
||||
void operator = (const LibIgnore&); // not implemented
|
||||
};
|
||||
|
||||
inline bool LibIgnore::IsIgnored(uptr pc) const {
|
||||
const uptr n = atomic_load(&loaded_count_, memory_order_acquire);
|
||||
inline bool LibIgnore::IsIgnored(uptr pc, bool *pc_in_ignored_lib) const {
|
||||
const uptr n = atomic_load(&ignored_ranges_count_, memory_order_acquire);
|
||||
for (uptr i = 0; i < n; i++) {
|
||||
if (pc >= code_ranges_[i].begin && pc < code_ranges_[i].end)
|
||||
if (IsInRange(pc, ignored_code_ranges_[i])) {
|
||||
*pc_in_ignored_lib = true;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
*pc_in_ignored_lib = false;
|
||||
if (track_instrumented_libs_ && !IsPcInstrumented(pc))
|
||||
return true;
|
||||
return false;
|
||||
}
|
||||
|
||||
inline bool LibIgnore::IsPcInstrumented(uptr pc) const {
|
||||
const uptr n = atomic_load(&instrumented_ranges_count_, memory_order_acquire);
|
||||
for (uptr i = 0; i < n; i++) {
|
||||
if (IsInRange(pc, instrumented_code_ranges_[i]))
|
||||
return true;
|
||||
}
|
||||
return false;
|
||||
|
@ -635,9 +635,12 @@ namespace __sanitizer {
|
||||
#ifndef __mips__
|
||||
#if defined(__sparc__)
|
||||
#if __GLIBC_PREREQ (2, 20)
|
||||
// On sparc glibc 2.19 and earlier sa_flags was unsigned long, and
|
||||
// __glibc_reserved0 didn't exist.
|
||||
// On sparc glibc 2.19 and earlier sa_flags was unsigned long.
|
||||
#if defined(__arch64__)
|
||||
// To maintain ABI compatibility on sparc64 when switching to an int,
|
||||
// __glibc_reserved0 was added.
|
||||
int __glibc_reserved0;
|
||||
#endif
|
||||
int sa_flags;
|
||||
#else
|
||||
unsigned long sa_flags;
|
||||
|
@ -49,18 +49,31 @@ class Quarantine {
|
||||
}
|
||||
|
||||
void Init(uptr size, uptr cache_size) {
|
||||
atomic_store(&max_size_, size, memory_order_release);
|
||||
// Thread local quarantine size can be zero only when global quarantine size
|
||||
// is zero (it allows us to perform just one atomic read per Put() call).
|
||||
CHECK((size == 0 && cache_size == 0) || cache_size != 0);
|
||||
|
||||
atomic_store(&max_size_, size, memory_order_relaxed);
|
||||
atomic_store(&min_size_, size / 10 * 9,
|
||||
memory_order_release); // 90% of max size.
|
||||
max_cache_size_ = cache_size;
|
||||
memory_order_relaxed); // 90% of max size.
|
||||
atomic_store(&max_cache_size_, cache_size, memory_order_relaxed);
|
||||
}
|
||||
|
||||
uptr GetSize() const { return atomic_load(&max_size_, memory_order_acquire); }
|
||||
uptr GetCacheSize() const { return max_cache_size_; }
|
||||
uptr GetSize() const { return atomic_load(&max_size_, memory_order_relaxed); }
|
||||
uptr GetCacheSize() const {
|
||||
return atomic_load(&max_cache_size_, memory_order_relaxed);
|
||||
}
|
||||
|
||||
void Put(Cache *c, Callback cb, Node *ptr, uptr size) {
|
||||
c->Enqueue(cb, ptr, size);
|
||||
if (c->Size() > max_cache_size_)
|
||||
uptr cache_size = GetCacheSize();
|
||||
if (cache_size) {
|
||||
c->Enqueue(cb, ptr, size);
|
||||
} else {
|
||||
// cache_size == 0 only when size == 0 (see Init).
|
||||
cb.Recycle(ptr);
|
||||
}
|
||||
// Check cache size anyway to accommodate for runtime cache_size change.
|
||||
if (c->Size() > cache_size)
|
||||
Drain(c, cb);
|
||||
}
|
||||
|
||||
@ -83,7 +96,7 @@ class Quarantine {
|
||||
char pad0_[kCacheLineSize];
|
||||
atomic_uintptr_t max_size_;
|
||||
atomic_uintptr_t min_size_;
|
||||
uptr max_cache_size_;
|
||||
atomic_uintptr_t max_cache_size_;
|
||||
char pad1_[kCacheLineSize];
|
||||
SpinMutex cache_mutex_;
|
||||
SpinMutex recycle_mutex_;
|
||||
@ -92,7 +105,7 @@ class Quarantine {
|
||||
|
||||
void NOINLINE Recycle(Callback cb) {
|
||||
Cache tmp;
|
||||
uptr min_size = atomic_load(&min_size_, memory_order_acquire);
|
||||
uptr min_size = atomic_load(&min_size_, memory_order_relaxed);
|
||||
{
|
||||
SpinMutexLock l(&cache_mutex_);
|
||||
while (cache_.Size() > min_size) {
|
||||
@ -205,6 +218,7 @@ class QuarantineCache {
|
||||
return b;
|
||||
}
|
||||
};
|
||||
|
||||
} // namespace __sanitizer
|
||||
|
||||
#endif // SANITIZER_QUARANTINE_H
|
||||
|
@ -80,10 +80,10 @@ endif()
|
||||
|
||||
if(APPLE)
|
||||
list(APPEND SANITIZER_TEST_CFLAGS_COMMON ${DARWIN_osx_CFLAGS})
|
||||
list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON ${DARWIN_osx_LINKFLAGS})
|
||||
list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON ${DARWIN_osx_LINK_FLAGS})
|
||||
|
||||
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINKFLAGS)
|
||||
list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON ${WEAK_SYMBOL_LINKFLAGS})
|
||||
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
|
||||
list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON ${WEAK_SYMBOL_LINK_FLAGS})
|
||||
endif()
|
||||
|
||||
# MSVC linker is allocating 1M for the stack by default, which is not
|
||||
|
@ -3,16 +3,23 @@ add_compiler_rt_component(scudo)
|
||||
include_directories(..)
|
||||
|
||||
set(SCUDO_CFLAGS ${SANITIZER_COMMON_CFLAGS})
|
||||
# SANITIZER_COMMON_CFLAGS include -fno-builtin, but we actually want builtins!
|
||||
list(APPEND SCUDO_CFLAGS -fbuiltin)
|
||||
append_rtti_flag(OFF SCUDO_CFLAGS)
|
||||
|
||||
set(SCUDO_SOURCES
|
||||
scudo_allocator.cpp
|
||||
scudo_flags.cpp
|
||||
scudo_crc32.cpp
|
||||
scudo_interceptors.cpp
|
||||
scudo_new_delete.cpp
|
||||
scudo_termination.cpp
|
||||
scudo_utils.cpp)
|
||||
|
||||
if (COMPILER_RT_HAS_MSSE4_2_FLAG)
|
||||
set_source_files_properties(scudo_crc32.cpp PROPERTIES COMPILE_FLAGS -msse4.2)
|
||||
endif()
|
||||
|
||||
if(COMPILER_RT_HAS_SCUDO)
|
||||
foreach(arch ${SCUDO_SUPPORTED_ARCH})
|
||||
add_compiler_rt_runtime(clang_rt.scudo
|
||||
|
@ -15,6 +15,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "scudo_allocator.h"
|
||||
#include "scudo_crc32.h"
|
||||
#include "scudo_utils.h"
|
||||
|
||||
#include "sanitizer_common/sanitizer_allocator_interface.h"
|
||||
@ -25,22 +26,6 @@
|
||||
|
||||
#include <cstring>
|
||||
|
||||
// Hardware CRC32 is supported at compilation via the following:
|
||||
// - for i386 & x86_64: -msse4.2
|
||||
// - for ARM & AArch64: -march=armv8-a+crc
|
||||
// An additional check must be performed at runtime as well to make sure the
|
||||
// emitted instructions are valid on the target host.
|
||||
#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
|
||||
# ifdef __SSE4_2__
|
||||
# include <smmintrin.h>
|
||||
# define HW_CRC32 FIRST_32_SECOND_64(_mm_crc32_u32, _mm_crc32_u64)
|
||||
# endif
|
||||
# ifdef __ARM_FEATURE_CRC32
|
||||
# include <arm_acle.h>
|
||||
# define HW_CRC32 FIRST_32_SECOND_64(__crc32cw, __crc32cd)
|
||||
# endif
|
||||
#endif
|
||||
|
||||
namespace __scudo {
|
||||
|
||||
#if SANITIZER_CAN_USE_ALLOCATOR64
|
||||
@ -84,10 +69,6 @@ static thread_local Xorshift128Plus Prng;
|
||||
// Global static cookie, initialized at start-up.
|
||||
static uptr Cookie;
|
||||
|
||||
enum : u8 {
|
||||
CRC32Software = 0,
|
||||
CRC32Hardware = 1,
|
||||
};
|
||||
// We default to software CRC32 if the alternatives are not supported, either
|
||||
// at compilation or at runtime.
|
||||
static atomic_uint8_t HashAlgorithm = { CRC32Software };
|
||||
@ -97,17 +78,9 @@ static atomic_uint8_t HashAlgorithm = { CRC32Software };
|
||||
// the checksumming function if available.
|
||||
INLINE u32 hashUptrs(uptr Pointer, uptr *Array, uptr ArraySize, u8 HashType) {
|
||||
u32 Crc;
|
||||
#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
|
||||
if (HashType == CRC32Hardware) {
|
||||
Crc = HW_CRC32(Cookie, Pointer);
|
||||
for (uptr i = 0; i < ArraySize; i++)
|
||||
Crc = HW_CRC32(Crc, Array[i]);
|
||||
return Crc;
|
||||
}
|
||||
#endif
|
||||
Crc = computeCRC32(Cookie, Pointer);
|
||||
Crc = computeCRC32(Cookie, Pointer, HashType);
|
||||
for (uptr i = 0; i < ArraySize; i++)
|
||||
Crc = computeCRC32(Crc, Array[i]);
|
||||
Crc = computeCRC32(Crc, Array[i], HashType);
|
||||
return Crc;
|
||||
}
|
||||
|
||||
|
53
lib/scudo/scudo_crc32.cpp
Normal file
53
lib/scudo/scudo_crc32.cpp
Normal file
@ -0,0 +1,53 @@
|
||||
//===-- scudo_crc32.cpp -----------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// CRC32 function leveraging hardware specific instructions. This has to be
|
||||
/// kept separated to restrict the use of compiler specific flags to this file.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Hardware CRC32 is supported at compilation via the following:
|
||||
// - for i386 & x86_64: -msse4.2
|
||||
// - for ARM & AArch64: -march=armv8-a+crc or -mcrc
|
||||
// An additional check must be performed at runtime as well to make sure the
|
||||
// emitted instructions are valid on the target host.
|
||||
#include "scudo_crc32.h"
|
||||
#include "scudo_utils.h"
|
||||
|
||||
#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
|
||||
# ifdef __SSE4_2__
|
||||
# include <smmintrin.h>
|
||||
# define CRC32_INTRINSIC FIRST_32_SECOND_64(_mm_crc32_u32, _mm_crc32_u64)
|
||||
# endif
|
||||
# ifdef __ARM_FEATURE_CRC32
|
||||
# include <arm_acle.h>
|
||||
# define CRC32_INTRINSIC FIRST_32_SECOND_64(__crc32cw, __crc32cd)
|
||||
# endif
|
||||
#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
|
||||
|
||||
namespace __scudo {
|
||||
|
||||
#if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
|
||||
INLINE u32 computeHardwareCRC32(u32 Crc, uptr Data) {
|
||||
return CRC32_INTRINSIC(Crc, Data);
|
||||
}
|
||||
|
||||
u32 computeCRC32(u32 Crc, uptr Data, u8 HashType) {
|
||||
if (HashType == CRC32Hardware) {
|
||||
return computeHardwareCRC32(Crc, Data);
|
||||
}
|
||||
return computeSoftwareCRC32(Crc, Data);
|
||||
}
|
||||
#else
|
||||
u32 computeCRC32(u32 Crc, uptr Data, u8 HashType) {
|
||||
return computeSoftwareCRC32(Crc, Data);
|
||||
}
|
||||
#endif // defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32)
|
||||
|
||||
} // namespace __scudo
|
30
lib/scudo/scudo_crc32.h
Normal file
30
lib/scudo/scudo_crc32.h
Normal file
@ -0,0 +1,30 @@
|
||||
//===-- scudo_crc32.h -------------------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// Header for scudo_crc32.cpp.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef SCUDO_CRC32_H_
|
||||
#define SCUDO_CRC32_H_
|
||||
|
||||
#include "sanitizer_common/sanitizer_internal_defs.h"
|
||||
|
||||
namespace __scudo {
|
||||
|
||||
enum : u8 {
|
||||
CRC32Software = 0,
|
||||
CRC32Hardware = 1,
|
||||
};
|
||||
|
||||
u32 computeCRC32(u32 Crc, uptr Data, u8 HashType);
|
||||
|
||||
} // namespace __scudo
|
||||
|
||||
#endif // SCUDO_CRC32_H_
|
@ -185,8 +185,7 @@ const static u32 CRC32Table[] = {
|
||||
0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d
|
||||
};
|
||||
|
||||
u32 computeCRC32(u32 Crc, uptr Data)
|
||||
{
|
||||
u32 computeSoftwareCRC32(u32 Crc, uptr Data) {
|
||||
for (uptr i = 0; i < sizeof(Data); i++) {
|
||||
Crc = CRC32Table[(Crc ^ Data) & 0xff] ^ (Crc >> 8);
|
||||
Data >>= 8;
|
||||
|
@ -53,8 +53,8 @@ struct Xorshift128Plus {
|
||||
u64 State[2];
|
||||
};
|
||||
|
||||
// Software CRC32 functions, to be used when SSE 4.2 support is not detected.
|
||||
u32 computeCRC32(u32 Crc, uptr Data);
|
||||
// Software CRC32 functions, to be used when hardware support is not detected.
|
||||
u32 computeSoftwareCRC32(u32 Crc, uptr Data);
|
||||
|
||||
} // namespace __scudo
|
||||
|
||||
|
@ -6,13 +6,13 @@ set_target_properties(stats PROPERTIES FOLDER "Compiler-RT Misc")
|
||||
if(APPLE)
|
||||
set(STATS_LIB_FLAVOR SHARED)
|
||||
|
||||
add_weak_symbols("asan" WEAK_SYMBOL_LINKFLAGS)
|
||||
add_weak_symbols("ubsan" WEAK_SYMBOL_LINKFLAGS)
|
||||
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINKFLAGS)
|
||||
add_weak_symbols("asan" WEAK_SYMBOL_LINK_FLAGS)
|
||||
add_weak_symbols("ubsan" WEAK_SYMBOL_LINK_FLAGS)
|
||||
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
|
||||
else()
|
||||
set(STATS_LIB_FLAVOR STATIC)
|
||||
|
||||
set(WEAK_SYMBOL_LINKFLAGS)
|
||||
set(WEAK_SYMBOL_LINK_FLAGS)
|
||||
endif()
|
||||
|
||||
add_compiler_rt_runtime(clang_rt.stats
|
||||
@ -23,7 +23,7 @@ add_compiler_rt_runtime(clang_rt.stats
|
||||
OBJECT_LIBS RTSanitizerCommon
|
||||
RTSanitizerCommonLibc
|
||||
CFLAGS ${SANITIZER_COMMON_CFLAGS}
|
||||
LINKFLAGS ${WEAK_SYMBOL_LINKFLAGS}
|
||||
LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
|
||||
PARENT_TARGET stats)
|
||||
|
||||
add_compiler_rt_runtime(clang_rt.stats_client
|
||||
@ -32,5 +32,5 @@ add_compiler_rt_runtime(clang_rt.stats_client
|
||||
OS ${SANITIZER_COMMON_SUPPORTED_OS}
|
||||
SOURCES stats_client.cc
|
||||
CFLAGS ${SANITIZER_COMMON_CFLAGS}
|
||||
LINKFLAGS ${WEAK_SYMBOL_LINKFLAGS}
|
||||
LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
|
||||
PARENT_TARGET stats)
|
||||
|
@ -108,8 +108,8 @@ if(APPLE)
|
||||
set_source_files_properties(${TSAN_ASM_SOURCES} PROPERTIES LANGUAGE C)
|
||||
endif()
|
||||
|
||||
add_weak_symbols("ubsan" WEAK_SYMBOL_LINKFLAGS)
|
||||
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINKFLAGS)
|
||||
add_weak_symbols("ubsan" WEAK_SYMBOL_LINK_FLAGS)
|
||||
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
|
||||
|
||||
add_compiler_rt_runtime(clang_rt.tsan
|
||||
SHARED
|
||||
@ -121,7 +121,7 @@ if(APPLE)
|
||||
RTSanitizerCommonLibc
|
||||
RTUbsan
|
||||
CFLAGS ${TSAN_RTL_CFLAGS}
|
||||
LINKFLAGS ${WEAK_SYMBOL_LINKFLAGS}
|
||||
LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
|
||||
PARENT_TARGET tsan)
|
||||
add_compiler_rt_object_libraries(RTTsan_dynamic
|
||||
OS ${TSAN_SUPPORTED_OS}
|
||||
|
@ -79,5 +79,8 @@ TSAN_FLAG(bool, die_after_fork, true,
|
||||
TSAN_FLAG(const char *, suppressions, "", "Suppressions file name.")
|
||||
TSAN_FLAG(bool, ignore_interceptors_accesses, false,
|
||||
"Ignore reads and writes from all interceptors.")
|
||||
TSAN_FLAG(bool, ignore_noninstrumented_modules, false,
|
||||
"Interceptors should only detect races when called from instrumented "
|
||||
"modules.")
|
||||
TSAN_FLAG(bool, shared_ptr_interceptor, true,
|
||||
"Track atomic reference counting in libc++ shared_ptr and weak_ptr.")
|
||||
|
@ -231,6 +231,8 @@ void InitializeLibIgnore() {
|
||||
if (0 == internal_strcmp(s->type, kSuppressionLib))
|
||||
libignore()->AddIgnoredLibrary(s->templ);
|
||||
}
|
||||
if (flags()->ignore_noninstrumented_modules)
|
||||
libignore()->IgnoreNoninstrumentedModules(true);
|
||||
libignore()->OnLibraryLoaded(0);
|
||||
}
|
||||
|
||||
@ -252,31 +254,20 @@ static unsigned g_thread_finalize_key;
|
||||
|
||||
ScopedInterceptor::ScopedInterceptor(ThreadState *thr, const char *fname,
|
||||
uptr pc)
|
||||
: thr_(thr)
|
||||
, pc_(pc)
|
||||
, in_ignored_lib_(false) {
|
||||
: thr_(thr), pc_(pc), in_ignored_lib_(false), ignoring_(false) {
|
||||
Initialize(thr);
|
||||
if (!thr_->is_inited)
|
||||
return;
|
||||
if (!thr_->ignore_interceptors)
|
||||
FuncEntry(thr, pc);
|
||||
if (!thr_->is_inited) return;
|
||||
if (!thr_->ignore_interceptors) FuncEntry(thr, pc);
|
||||
DPrintf("#%d: intercept %s()\n", thr_->tid, fname);
|
||||
if (!thr_->in_ignored_lib && libignore()->IsIgnored(pc)) {
|
||||
in_ignored_lib_ = true;
|
||||
thr_->in_ignored_lib = true;
|
||||
ThreadIgnoreBegin(thr_, pc_);
|
||||
}
|
||||
if (flags()->ignore_interceptors_accesses) ThreadIgnoreBegin(thr_, pc_);
|
||||
ignoring_ =
|
||||
!thr_->in_ignored_lib && (flags()->ignore_interceptors_accesses ||
|
||||
libignore()->IsIgnored(pc, &in_ignored_lib_));
|
||||
EnableIgnores();
|
||||
}
|
||||
|
||||
ScopedInterceptor::~ScopedInterceptor() {
|
||||
if (!thr_->is_inited)
|
||||
return;
|
||||
if (flags()->ignore_interceptors_accesses) ThreadIgnoreEnd(thr_, pc_);
|
||||
if (in_ignored_lib_) {
|
||||
thr_->in_ignored_lib = false;
|
||||
ThreadIgnoreEnd(thr_, pc_);
|
||||
}
|
||||
if (!thr_->is_inited) return;
|
||||
DisableIgnores();
|
||||
if (!thr_->ignore_interceptors) {
|
||||
ProcessPendingSignals(thr_);
|
||||
FuncExit(thr_);
|
||||
@ -284,20 +275,24 @@ ScopedInterceptor::~ScopedInterceptor() {
|
||||
}
|
||||
}
|
||||
|
||||
void ScopedInterceptor::UserCallbackStart() {
|
||||
if (flags()->ignore_interceptors_accesses) ThreadIgnoreEnd(thr_, pc_);
|
||||
if (in_ignored_lib_) {
|
||||
thr_->in_ignored_lib = false;
|
||||
ThreadIgnoreEnd(thr_, pc_);
|
||||
void ScopedInterceptor::EnableIgnores() {
|
||||
if (ignoring_) {
|
||||
ThreadIgnoreBegin(thr_, pc_);
|
||||
if (in_ignored_lib_) {
|
||||
DCHECK(!thr_->in_ignored_lib);
|
||||
thr_->in_ignored_lib = true;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void ScopedInterceptor::UserCallbackEnd() {
|
||||
if (in_ignored_lib_) {
|
||||
thr_->in_ignored_lib = true;
|
||||
ThreadIgnoreBegin(thr_, pc_);
|
||||
void ScopedInterceptor::DisableIgnores() {
|
||||
if (ignoring_) {
|
||||
ThreadIgnoreEnd(thr_, pc_);
|
||||
if (in_ignored_lib_) {
|
||||
DCHECK(thr_->in_ignored_lib);
|
||||
thr_->in_ignored_lib = false;
|
||||
}
|
||||
}
|
||||
if (flags()->ignore_interceptors_accesses) ThreadIgnoreBegin(thr_, pc_);
|
||||
}
|
||||
|
||||
#define TSAN_INTERCEPT(func) INTERCEPT_FUNCTION(func)
|
||||
|
@ -10,12 +10,13 @@ class ScopedInterceptor {
|
||||
public:
|
||||
ScopedInterceptor(ThreadState *thr, const char *fname, uptr pc);
|
||||
~ScopedInterceptor();
|
||||
void UserCallbackStart();
|
||||
void UserCallbackEnd();
|
||||
void DisableIgnores();
|
||||
void EnableIgnores();
|
||||
private:
|
||||
ThreadState *const thr_;
|
||||
const uptr pc_;
|
||||
bool in_ignored_lib_;
|
||||
bool ignoring_;
|
||||
};
|
||||
|
||||
} // namespace __tsan
|
||||
@ -39,10 +40,10 @@ class ScopedInterceptor {
|
||||
/**/
|
||||
|
||||
#define SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START() \
|
||||
si.UserCallbackStart();
|
||||
si.DisableIgnores();
|
||||
|
||||
#define SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END() \
|
||||
si.UserCallbackEnd();
|
||||
si.EnableIgnores();
|
||||
|
||||
#define TSAN_INTERCEPTOR(ret, func, ...) INTERCEPTOR(ret, func, __VA_ARGS__)
|
||||
|
||||
|
@ -77,8 +77,8 @@ macro(add_tsan_unittest testname)
|
||||
list(APPEND TEST_OBJECTS lib${TSAN_TEST_RUNTIME}.a)
|
||||
list(APPEND TEST_DEPS ${TSAN_TEST_RUNTIME})
|
||||
|
||||
add_weak_symbols("ubsan" WEAK_SYMBOL_LINKFLAGS)
|
||||
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINKFLAGS)
|
||||
add_weak_symbols("ubsan" WEAK_SYMBOL_LINK_FLAGS)
|
||||
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
|
||||
|
||||
# Intentionally do *not* link with `-fsanitize=thread`. We already link
|
||||
# against a static version of the runtime, and we don't want the dynamic
|
||||
@ -87,7 +87,7 @@ macro(add_tsan_unittest testname)
|
||||
OBJECTS ${TEST_OBJECTS}
|
||||
DEPS ${TEST_DEPS}
|
||||
LINK_FLAGS ${TARGET_LINK_FLAGS} ${DARWIN_osx_LINK_FLAGS}
|
||||
${WEAK_SYMBOL_LINKFLAGS} -lc++)
|
||||
${WEAK_SYMBOL_LINK_FLAGS} -lc++)
|
||||
endif()
|
||||
endforeach()
|
||||
endif()
|
||||
|
@ -56,8 +56,8 @@ if(APPLE)
|
||||
SOURCES ${UBSAN_STANDALONE_SOURCES}
|
||||
CFLAGS ${UBSAN_STANDALONE_CFLAGS})
|
||||
|
||||
add_weak_symbols("ubsan" WEAK_SYMBOL_LINKFLAGS)
|
||||
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINKFLAGS)
|
||||
add_weak_symbols("ubsan" WEAK_SYMBOL_LINK_FLAGS)
|
||||
add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
|
||||
|
||||
add_compiler_rt_runtime(clang_rt.ubsan
|
||||
SHARED
|
||||
@ -67,7 +67,7 @@ if(APPLE)
|
||||
RTUbsan_standalone
|
||||
RTSanitizerCommon
|
||||
RTSanitizerCommonLibc
|
||||
LINKFLAGS ${WEAK_SYMBOL_LINKFLAGS}
|
||||
LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
|
||||
PARENT_TARGET ubsan)
|
||||
endif()
|
||||
|
||||
|
@ -19,6 +19,9 @@
|
||||
#include <atomic>
|
||||
#include <cassert>
|
||||
|
||||
|
||||
extern "C" void __clear_cache(void* start, void* end);
|
||||
|
||||
namespace __xray {
|
||||
|
||||
uint64_t cycleFrequency() XRAY_NEVER_INSTRUMENT {
|
||||
@ -75,8 +78,8 @@ inline static bool patchSled(const bool Enable, const uint32_t FuncId,
|
||||
// B #32
|
||||
|
||||
uint32_t *FirstAddress = reinterpret_cast<uint32_t *>(Sled.Address);
|
||||
uint32_t *CurAddress = FirstAddress + 1;
|
||||
if (Enable) {
|
||||
uint32_t *CurAddress = FirstAddress + 1;
|
||||
*CurAddress = uint32_t(PatchOpcodes::PO_LdrW0_12);
|
||||
CurAddress++;
|
||||
*CurAddress = uint32_t(PatchOpcodes::PO_LdrX16_12);
|
||||
@ -88,6 +91,7 @@ inline static bool patchSled(const bool Enable, const uint32_t FuncId,
|
||||
*reinterpret_cast<void (**)()>(CurAddress) = TracingHook;
|
||||
CurAddress += 2;
|
||||
*CurAddress = uint32_t(PatchOpcodes::PO_LdpX0X30SP_16);
|
||||
CurAddress++;
|
||||
std::atomic_store_explicit(
|
||||
reinterpret_cast<std::atomic<uint32_t> *>(FirstAddress),
|
||||
uint32_t(PatchOpcodes::PO_StpX0X30SP_m16e), std::memory_order_release);
|
||||
@ -96,6 +100,8 @@ inline static bool patchSled(const bool Enable, const uint32_t FuncId,
|
||||
reinterpret_cast<std::atomic<uint32_t> *>(FirstAddress),
|
||||
uint32_t(PatchOpcodes::PO_B32), std::memory_order_release);
|
||||
}
|
||||
__clear_cache(reinterpret_cast<char*>(FirstAddress),
|
||||
reinterpret_cast<char*>(CurAddress));
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -5,8 +5,10 @@
|
||||
// RUN: FileCheck %s --check-prefix=CHECK-VALUE
|
||||
// RUN: %env_asan_opts=thread_local_quarantine_size_kb=64:quarantine_size_mb=64 %run %t 2>&1 | \
|
||||
// RUN: FileCheck %s --allow-empty --check-prefix=CHECK-SMALL-LOCAL-CACHE-SMALL-OVERHEAD
|
||||
// RUN: %env_asan_opts=thread_local_quarantine_size_kb=0:quarantine_size_mb=64 %run %t 2>&1 | \
|
||||
// RUN: FileCheck %s --check-prefix=CHECK-NO-LOCAL-CACHE-HUGE-OVERHEAD
|
||||
// RUN: %env_asan_opts=thread_local_quarantine_size_kb=0:quarantine_size_mb=0 %run %t 2>&1 | \
|
||||
// RUN: FileCheck %s --check-prefix=CHECK-QUARANTINE-DISABLED
|
||||
// RUN: %env_asan_opts=thread_local_quarantine_size_kb=0:quarantine_size_mb=64 not %run %t 2>&1 | \
|
||||
// RUN: FileCheck %s --check-prefix=CHECK-FOR-PARAMETER-ERROR
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
@ -37,4 +39,5 @@ int main() {
|
||||
|
||||
// CHECK-VALUE: thread_local_quarantine_size_kb=256K
|
||||
// CHECK-SMALL-LOCAL-CACHE-SMALL-OVERHEAD-NOT: Heap size limit exceeded
|
||||
// CHECK-NO-LOCAL-CACHE-HUGE-OVERHEAD: Heap size limit exceeded
|
||||
// CHECK-QUARANTINE-DISABLED-NOT: Heap size limit exceeded
|
||||
// CHECK-FOR-PARAMETER-ERROR: thread_local_quarantine_size_kb can be set to 0 only when quarantine_size_mb is set to 0
|
||||
|
@ -21,6 +21,7 @@
|
||||
// XFAIL: arm-linux-gnueabi
|
||||
|
||||
#if !defined(SHARED_LIB)
|
||||
|
||||
#include <assert.h>
|
||||
#include <dlfcn.h>
|
||||
#include <stdio.h>
|
||||
@ -32,13 +33,13 @@
|
||||
|
||||
#include "sanitizer/asan_interface.h"
|
||||
|
||||
constexpr unsigned nPtrs = 200;
|
||||
char *ptrs[nPtrs];
|
||||
|
||||
void test_malloc_shadow(char *p, size_t sz, bool expect_redzones) {
|
||||
// Last byte of the left redzone, if present.
|
||||
assert((char *)__asan_region_is_poisoned(p - 1, sz + 1) ==
|
||||
(expect_redzones ? p - 1 : nullptr));
|
||||
// The user memory.
|
||||
assert((char *)__asan_region_is_poisoned(p, sz) == nullptr);
|
||||
// First byte of the right redzone, if present.
|
||||
assert((char *)__asan_region_is_poisoned(p, sz + 1) ==
|
||||
(expect_redzones ? p + sz : nullptr));
|
||||
}
|
||||
@ -46,12 +47,29 @@ void test_malloc_shadow(char *p, size_t sz, bool expect_redzones) {
|
||||
typedef void (*Fn)();
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
constexpr unsigned nPtrs = 200;
|
||||
char *ptrs[nPtrs];
|
||||
|
||||
// Before activation: no redzones.
|
||||
for (size_t sz = 1; sz < nPtrs; ++sz) {
|
||||
ptrs[sz] = (char *)malloc(sz);
|
||||
test_malloc_shadow(ptrs[sz], sz, false);
|
||||
}
|
||||
|
||||
// Create a honey pot for the future, instrumented, allocations. Since the
|
||||
// quarantine is disabled, chunks are going to be recycled right away and
|
||||
// reused for the new allocations. New allocations must get the proper
|
||||
// redzones anyway, whether it's a fresh or reused allocation.
|
||||
constexpr size_t HoneyPotBlockSize = 4096;
|
||||
constexpr int HoneyPotSize = 200;
|
||||
char *honeyPot[HoneyPotSize];
|
||||
for (int i = 1; i < HoneyPotSize; ++i) {
|
||||
honeyPot[i] = (char *)malloc(HoneyPotBlockSize);
|
||||
test_malloc_shadow(honeyPot[i], HoneyPotBlockSize, false);
|
||||
}
|
||||
for (int i = 1; i < HoneyPotSize; ++i)
|
||||
free(honeyPot[i]);
|
||||
|
||||
std::string path = std::string(argv[0]) + "-so.so";
|
||||
void *dso = dlopen(path.c_str(), RTLD_NOW);
|
||||
if (!dso) {
|
||||
@ -67,11 +85,17 @@ int main(int argc, char *argv[]) {
|
||||
}
|
||||
|
||||
// After activation: redzones.
|
||||
for (int i = 1; i < HoneyPotSize; ++i) {
|
||||
honeyPot[i] = (char *)malloc(HoneyPotBlockSize);
|
||||
test_malloc_shadow(honeyPot[i], HoneyPotBlockSize, true);
|
||||
}
|
||||
{
|
||||
char *p = (char *)malloc(100);
|
||||
test_malloc_shadow(p, 100, true);
|
||||
char *p = (char *)malloc(HoneyPotBlockSize);
|
||||
test_malloc_shadow(p, HoneyPotBlockSize, true);
|
||||
free(p);
|
||||
}
|
||||
for (int i = 1; i < HoneyPotSize; ++i)
|
||||
free(honeyPot[i]);
|
||||
|
||||
// Pre-existing allocations got redzones, too.
|
||||
for (size_t sz = 1; sz < nPtrs; ++sz) {
|
||||
@ -93,7 +117,9 @@ int main(int argc, char *argv[]) {
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
#else // SHARED_LIB
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
|
||||
@ -101,6 +127,7 @@ extern "C" void do_another_bad_thing() {
|
||||
char *volatile p = (char *)malloc(100);
|
||||
printf("%hhx\n", p[105]);
|
||||
}
|
||||
|
||||
#endif // SHARED_LIB
|
||||
|
||||
// help=1 in activation flags lists only flags are are supported at activation
|
||||
|
@ -61,18 +61,18 @@ else:
|
||||
# GCC-ASan doesn't link in all the necessary libraries automatically, so
|
||||
# we have to do it ourselves.
|
||||
if config.compiler_id == 'GNU':
|
||||
extra_linkflags = ["-pthread", "-lstdc++", libdl_flag]
|
||||
extra_link_flags = ["-pthread", "-lstdc++", libdl_flag]
|
||||
else:
|
||||
extra_linkflags = []
|
||||
extra_link_flags = []
|
||||
|
||||
# BFD linker in 64-bit android toolchains fails to find libm.so, which is a
|
||||
# transitive shared library dependency (via asan runtime).
|
||||
if config.android:
|
||||
extra_linkflags += ["-lm"]
|
||||
extra_link_flags += ["-lm"]
|
||||
|
||||
# Setup default compiler flags used with -fsanitize=address option.
|
||||
# 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_cflags = [get_required_attr(config, "target_cflags")] + extra_link_flags
|
||||
target_cxxflags = config.cxx_mode_flags + target_cflags
|
||||
clang_asan_static_cflags = (["-fsanitize=address",
|
||||
"-mno-omit-leaf-frame-pointer",
|
||||
|
@ -1,6 +1,6 @@
|
||||
// RUN: rm -fr %t.prof
|
||||
// RUN: %clangxx_pgogen=%t.prof/ -o %t.gen -O2 %S/../Inputs/comdat_rename_1.cc %S/../Inputs/comdat_rename_2.cc
|
||||
// RUN: %clangxx_pgogen=%t.prof/ -o %t.gen -mllvm -do-comdat-renaming=true -O2 %S/../Inputs/comdat_rename_1.cc %S/../Inputs/comdat_rename_2.cc
|
||||
// RUN: %run %t.gen
|
||||
// RUN: llvm-profdata merge -o %t.profdata %t.prof/
|
||||
// RUN: %clangxx_profuse=%t.profdata -O2 -emit-llvm -S %S/../Inputs/comdat_rename_1.cc -o - | FileCheck %S/../Inputs/comdat_rename_1.cc
|
||||
// RUN: %clangxx_profuse=%t.profdata -O2 -emit-llvm -S %S/../Inputs/comdat_rename_2.cc -o - | FileCheck %S/../Inputs/comdat_rename_2.cc
|
||||
// RUN: %clangxx_profuse=%t.profdata -O2 -mllvm -do-comdat-renaming=true -emit-llvm -S %S/../Inputs/comdat_rename_1.cc -o - | FileCheck %S/../Inputs/comdat_rename_1.cc
|
||||
// RUN: %clangxx_profuse=%t.profdata -O2 -mllvm -do-comdat-renaming=true -emit-llvm -S %S/../Inputs/comdat_rename_2.cc -o - | FileCheck %S/../Inputs/comdat_rename_2.cc
|
||||
|
@ -34,9 +34,9 @@ if config.test_exec_root is None:
|
||||
raise SystemExit
|
||||
|
||||
if config.host_os in ['Linux']:
|
||||
extra_linkflags = ["-ldl"]
|
||||
extra_link_flags = ["-ldl"]
|
||||
else:
|
||||
extra_linkflags = []
|
||||
extra_link_flags = []
|
||||
|
||||
# Test suffixes.
|
||||
config.suffixes = ['.c', '.cc', '.cpp', '.m', '.mm', '.ll', '.test']
|
||||
@ -46,7 +46,7 @@ config.excludes = ['Inputs']
|
||||
|
||||
# Clang flags.
|
||||
target_cflags=[get_required_attr(config, "target_cflags")]
|
||||
clang_cflags = target_cflags + extra_linkflags
|
||||
clang_cflags = target_cflags + extra_link_flags
|
||||
clang_cxxflags = config.cxx_mode_flags + clang_cflags
|
||||
|
||||
def build_invocation(compile_flags, with_lto = False):
|
||||
|
53
test/tsan/Darwin/ignore-noninstrumented.mm
Normal file
53
test/tsan/Darwin/ignore-noninstrumented.mm
Normal file
@ -0,0 +1,53 @@
|
||||
// Check that ignore_noninstrumented_modules=1 supresses races from system libraries on OS X.
|
||||
|
||||
// RUN: %clang_tsan %s -o %t -framework Foundation
|
||||
|
||||
// Check that without the flag, there are false positives.
|
||||
// RUN: %deflake %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RACE
|
||||
|
||||
// With ignore_noninstrumented_modules=1, no races are reported.
|
||||
// RUN: %env_tsan_opts=ignore_noninstrumented_modules=1 %run %t 2>&1 | FileCheck %s
|
||||
|
||||
// With ignore_noninstrumented_modules=1, races in user's code are still reported.
|
||||
// RUN: %env_tsan_opts=ignore_noninstrumented_modules=1 %deflake %run %t race 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-RACE
|
||||
|
||||
#import <Foundation/Foundation.h>
|
||||
|
||||
#import "../test.h"
|
||||
|
||||
char global_buf[64];
|
||||
|
||||
void *Thread1(void *x) {
|
||||
barrier_wait(&barrier);
|
||||
strcpy(global_buf, "hello world");
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void *Thread2(void *x) {
|
||||
strcpy(global_buf, "world hello");
|
||||
barrier_wait(&barrier);
|
||||
return NULL;
|
||||
}
|
||||
|
||||
int main(int argc, char *argv[]) {
|
||||
fprintf(stderr, "Hello world.\n");
|
||||
|
||||
// NSUserDefaults uses XPC which triggers the false positive.
|
||||
NSDictionary *d = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
|
||||
fprintf(stderr, "d = %p\n", d);
|
||||
|
||||
if (argc > 1 && strcmp(argv[1], "race") == 0) {
|
||||
barrier_init(&barrier, 2);
|
||||
pthread_t t[2];
|
||||
pthread_create(&t[0], NULL, Thread1, NULL);
|
||||
pthread_create(&t[1], NULL, Thread2, NULL);
|
||||
pthread_join(t[0], NULL);
|
||||
pthread_join(t[1], NULL);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Done.\n");
|
||||
}
|
||||
|
||||
// CHECK: Hello world.
|
||||
// CHECK-RACE: SUMMARY: ThreadSanitizer: data race
|
||||
// CHECK: Done.
|
@ -3,7 +3,6 @@
|
||||
//
|
||||
// RUN: %clangxx_xray -fxray-instrument -std=c++11 %s -o %t
|
||||
// RUN: XRAY_OPTIONS="patch_premain=false" %run %t 2>&1 | FileCheck %s
|
||||
// REQUIRES: stable-runtime
|
||||
|
||||
#include "xray/xray_interface.h"
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user