summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
Diffstat (limited to 'lib')
-rw-r--r--lib/CMakeLists.txt54
-rw-r--r--lib/asan/.clang-format2
-rw-r--r--lib/asan/CMakeLists.txt338
-rw-r--r--lib/asan/scripts/CMakeLists.txt4
-rwxr-xr-xlib/asan/scripts/asan_device_setup467
-rwxr-xr-xlib/asan/scripts/asan_symbolize.py523
-rw-r--r--lib/asan/tests/CMakeLists.txt309
-rw-r--r--lib/asan/tests/asan_asm_test.cc274
-rw-r--r--lib/asan/tests/asan_benchmarks_test.cc85
-rw-r--r--lib/asan/tests/asan_exceptions_test.cc27
-rw-r--r--lib/asan/tests/asan_fake_stack_test.cc152
-rw-r--r--lib/asan/tests/asan_globals_test.cc45
-rw-r--r--lib/asan/tests/asan_interface_test.cc422
-rw-r--r--lib/asan/tests/asan_internal_interface_test.cc37
-rw-r--r--lib/asan/tests/asan_mac_test.cc236
-rw-r--r--lib/asan/tests/asan_mac_test.h19
-rw-r--r--lib/asan/tests/asan_mac_test_helpers.mm241
-rw-r--r--lib/asan/tests/asan_mem_test.cc242
-rw-r--r--lib/asan/tests/asan_noinst_test.cc273
-rw-r--r--lib/asan/tests/asan_oob_test.cc128
-rw-r--r--lib/asan/tests/asan_racy_double_free_test.cc32
-rw-r--r--lib/asan/tests/asan_str_test.cc635
-rw-r--r--lib/asan/tests/asan_test.cc1363
-rw-r--r--lib/asan/tests/asan_test.ignore3
-rw-r--r--lib/asan/tests/asan_test_config.h50
-rw-r--r--lib/asan/tests/asan_test_main.cc56
-rw-r--r--lib/asan/tests/asan_test_utils.h109
-rw-r--r--lib/builtins/CMakeLists.txt615
-rw-r--r--lib/builtins/Darwin-excludes/CMakeLists.txt4
-rw-r--r--lib/builtins/Darwin-excludes/README.TXT11
-rw-r--r--lib/builtins/Darwin-excludes/ios-armv7.txt57
-rw-r--r--lib/builtins/Darwin-excludes/ios-armv7s.txt57
-rw-r--r--lib/builtins/Darwin-excludes/ios.txt1
-rw-r--r--lib/builtins/Darwin-excludes/ios6-armv7.txt120
-rw-r--r--lib/builtins/Darwin-excludes/ios6-armv7s.txt120
-rw-r--r--lib/builtins/Darwin-excludes/ios7-arm64.txt16
-rw-r--r--lib/builtins/Darwin-excludes/iossim-i386.txt82
-rw-r--r--lib/builtins/Darwin-excludes/iossim-x86_64.txt12
-rw-r--r--lib/builtins/Darwin-excludes/iossim.txt1
-rw-r--r--lib/builtins/Darwin-excludes/osx-i386.txt35
-rw-r--r--lib/builtins/Darwin-excludes/osx.txt7
-rw-r--r--lib/builtins/macho_embedded/CMakeLists.txt4
-rw-r--r--lib/builtins/macho_embedded/arm.txt16
-rw-r--r--lib/builtins/macho_embedded/common.txt92
-rw-r--r--lib/builtins/macho_embedded/i386.txt7
-rw-r--r--lib/builtins/macho_embedded/thumb2-64.txt10
-rw-r--r--lib/builtins/macho_embedded/thumb2.txt14
-rw-r--r--lib/cfi/CMakeLists.txt41
-rw-r--r--lib/dfsan/.clang-format2
-rw-r--r--lib/dfsan/CMakeLists.txt57
-rwxr-xr-xlib/dfsan/scripts/build-libc-list.py96
-rwxr-xr-xlib/dfsan/scripts/check_custom_wrappers.sh54
-rw-r--r--lib/esan/CMakeLists.txt55
-rw-r--r--lib/fuzzer/CMakeLists.txt147
-rw-r--r--lib/fuzzer/afl/afl_driver.cpp378
-rwxr-xr-xlib/fuzzer/build.sh11
-rw-r--r--lib/fuzzer/dataflow/DataFlow.cpp217
-rwxr-xr-xlib/fuzzer/scripts/collect_data_flow.py79
-rwxr-xr-xlib/fuzzer/scripts/merge_data_flow.py36
-rwxr-xr-xlib/fuzzer/scripts/unbalanced_allocs.py93
-rw-r--r--lib/fuzzer/standalone/StandaloneFuzzTargetMain.c41
-rw-r--r--lib/fuzzer/tests/CMakeLists.txt64
-rw-r--r--lib/fuzzer/tests/FuzzerUnittest.cpp964
-rw-r--r--lib/hwasan/.clang-format2
-rw-r--r--lib/hwasan/CMakeLists.txt179
-rw-r--r--lib/interception/.clang-format2
-rw-r--r--lib/interception/CMakeLists.txt29
-rw-r--r--lib/interception/tests/CMakeLists.txt113
-rw-r--r--lib/interception/tests/interception_linux_test.cc68
-rw-r--r--lib/interception/tests/interception_test_main.cc22
-rw-r--r--lib/interception/tests/interception_win_test.cc637
-rw-r--r--lib/lsan/.clang-format2
-rw-r--r--lib/lsan/CMakeLists.txt78
-rw-r--r--lib/msan/.clang-format2
-rw-r--r--lib/msan/CMakeLists.txt86
-rw-r--r--lib/msan/tests/CMakeLists.txt142
-rw-r--r--lib/msan/tests/msan_loadable.cc27
-rw-r--r--lib/msan/tests/msan_test.cc4639
-rw-r--r--lib/msan/tests/msan_test_config.h20
-rw-r--r--lib/msan/tests/msan_test_main.cc21
-rw-r--r--lib/profile/CMakeLists.txt126
-rw-r--r--lib/safestack/.clang-format2
-rw-r--r--lib/safestack/CMakeLists.txt19
-rw-r--r--lib/sanitizer_common/.clang-format2
-rw-r--r--lib/sanitizer_common/.clang-tidy16
-rw-r--r--lib/sanitizer_common/CMakeLists.txt374
-rwxr-xr-xlib/sanitizer_common/scripts/check_lint.sh142
-rwxr-xr-xlib/sanitizer_common/scripts/cpplint.py4024
-rwxr-xr-xlib/sanitizer_common/scripts/gen_dynamic_list.py135
-rwxr-xr-xlib/sanitizer_common/scripts/litlint.py72
-rwxr-xr-xlib/sanitizer_common/scripts/litlint_test.py23
-rwxr-xr-xlib/sanitizer_common/scripts/sancov.py251
-rw-r--r--lib/sanitizer_common/tests/CMakeLists.txt218
-rw-r--r--lib/sanitizer_common/tests/malloc_stress_transfer_test.cc37
-rw-r--r--lib/sanitizer_common/tests/sanitizer_allocator_test.cc1430
-rw-r--r--lib/sanitizer_common/tests/sanitizer_allocator_testlib.cc203
-rw-r--r--lib/sanitizer_common/tests/sanitizer_atomic_test.cc128
-rw-r--r--lib/sanitizer_common/tests/sanitizer_bitvector_test.cc178
-rw-r--r--lib/sanitizer_common/tests/sanitizer_bvgraph_test.cc339
-rw-r--r--lib/sanitizer_common/tests/sanitizer_common_test.cc442
-rw-r--r--lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc496
-rw-r--r--lib/sanitizer_common/tests/sanitizer_flags_test.cc180
-rw-r--r--lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cc263
-rw-r--r--lib/sanitizer_common/tests/sanitizer_ioctl_test.cc105
-rw-r--r--lib/sanitizer_common/tests/sanitizer_libc_test.cc315
-rw-r--r--lib/sanitizer_common/tests/sanitizer_linux_test.cc296
-rw-r--r--lib/sanitizer_common/tests/sanitizer_list_test.cc189
-rw-r--r--lib/sanitizer_common/tests/sanitizer_mutex_test.cc137
-rw-r--r--lib/sanitizer_common/tests/sanitizer_nolibc_test.cc31
-rw-r--r--lib/sanitizer_common/tests/sanitizer_nolibc_test_main.cc19
-rw-r--r--lib/sanitizer_common/tests/sanitizer_posix_test.cc81
-rw-r--r--lib/sanitizer_common/tests/sanitizer_printf_test.cc161
-rw-r--r--lib/sanitizer_common/tests/sanitizer_procmaps_test.cc79
-rw-r--r--lib/sanitizer_common/tests/sanitizer_pthread_wrappers.h68
-rw-r--r--lib/sanitizer_common/tests/sanitizer_quarantine_test.cc180
-rw-r--r--lib/sanitizer_common/tests/sanitizer_ring_buffer_test.cc99
-rw-r--r--lib/sanitizer_common/tests/sanitizer_stackdepot_test.cc93
-rw-r--r--lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc157
-rw-r--r--lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc167
-rw-r--r--lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cc204
-rw-r--r--lib/sanitizer_common/tests/sanitizer_stoptheworld_testlib.cc53
-rw-r--r--lib/sanitizer_common/tests/sanitizer_suppressions_test.cc135
-rw-r--r--lib/sanitizer_common/tests/sanitizer_symbolizer_test.cc72
-rw-r--r--lib/sanitizer_common/tests/sanitizer_test_config.h30
-rw-r--r--lib/sanitizer_common/tests/sanitizer_test_main.cc24
-rw-r--r--lib/sanitizer_common/tests/sanitizer_test_utils.h139
-rw-r--r--lib/sanitizer_common/tests/sanitizer_thread_registry_test.cc236
-rw-r--r--lib/sanitizer_common/tests/sanitizer_type_traits_test.cc28
-rw-r--r--lib/sanitizer_common/tests/sanitizer_vector_test.cc51
-rw-r--r--lib/sanitizer_common/tests/standalone_malloc_test.cc87
-rw-r--r--lib/scudo/CMakeLists.txt142
-rw-r--r--lib/stats/CMakeLists.txt45
-rw-r--r--lib/tsan/.clang-format2
-rw-r--r--lib/tsan/CMakeLists.txt258
-rwxr-xr-xlib/tsan/analyze_libtsan.sh54
-rwxr-xr-xlib/tsan/check_analyze.sh56
-rwxr-xr-xlib/tsan/check_cmake.sh18
-rw-r--r--lib/tsan/dd/CMakeLists.txt52
-rw-r--r--lib/tsan/go/build.bat4
-rwxr-xr-xlib/tsan/go/buildgo.sh173
-rw-r--r--lib/tsan/tests/CMakeLists.txt72
-rw-r--r--lib/tsan/tests/rtl/CMakeLists.txt19
-rw-r--r--lib/tsan/tests/rtl/tsan_bench.cc105
-rw-r--r--lib/tsan/tests/rtl/tsan_mop.cc233
-rw-r--r--lib/tsan/tests/rtl/tsan_mutex.cc221
-rw-r--r--lib/tsan/tests/rtl/tsan_posix.cc155
-rw-r--r--lib/tsan/tests/rtl/tsan_posix_util.h77
-rw-r--r--lib/tsan/tests/rtl/tsan_string.cc82
-rw-r--r--lib/tsan/tests/rtl/tsan_test.cc66
-rw-r--r--lib/tsan/tests/rtl/tsan_test_util.h130
-rw-r--r--lib/tsan/tests/rtl/tsan_test_util_posix.cc478
-rw-r--r--lib/tsan/tests/rtl/tsan_thread.cc59
-rw-r--r--lib/tsan/tests/unit/CMakeLists.txt12
-rw-r--r--lib/tsan/tests/unit/tsan_clock_test.cc494
-rw-r--r--lib/tsan/tests/unit/tsan_dense_alloc_test.cc55
-rw-r--r--lib/tsan/tests/unit/tsan_flags_test.cc174
-rw-r--r--lib/tsan/tests/unit/tsan_mman_test.cc197
-rw-r--r--lib/tsan/tests/unit/tsan_mutex_test.cc126
-rw-r--r--lib/tsan/tests/unit/tsan_mutexset_test.cc127
-rw-r--r--lib/tsan/tests/unit/tsan_shadow_test.cc78
-rw-r--r--lib/tsan/tests/unit/tsan_stack_test.cc95
-rw-r--r--lib/tsan/tests/unit/tsan_sync_test.cc123
-rw-r--r--lib/tsan/tests/unit/tsan_unit_test_main.cc25
-rw-r--r--lib/ubsan/CMakeLists.txt227
-rw-r--r--lib/ubsan_minimal/CMakeLists.txt53
-rw-r--r--lib/xray/CMakeLists.txt296
-rw-r--r--lib/xray/tests/CMakeLists.txt132
-rw-r--r--lib/xray/tests/unit/CMakeLists.txt16
-rw-r--r--lib/xray/tests/unit/allocator_test.cc82
-rw-r--r--lib/xray/tests/unit/buffer_queue_test.cc235
-rw-r--r--lib/xray/tests/unit/fdr_controller_test.cc424
-rw-r--r--lib/xray/tests/unit/fdr_log_writer_test.cc162
-rw-r--r--lib/xray/tests/unit/function_call_trie_test.cc344
-rw-r--r--lib/xray/tests/unit/profile_collector_test.cc236
-rw-r--r--lib/xray/tests/unit/segmented_array_test.cc349
-rw-r--r--lib/xray/tests/unit/test_helpers.cc95
-rw-r--r--lib/xray/tests/unit/test_helpers.h78
-rw-r--r--lib/xray/tests/unit/xray_unit_test_main.cc18
178 files changed, 0 insertions, 34901 deletions
diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt
deleted file mode 100644
index b3731f653a01a..0000000000000
--- a/lib/CMakeLists.txt
+++ /dev/null
@@ -1,54 +0,0 @@
-# First, add the subdirectories which contain feature-based runtime libraries
-# and several convenience helper libraries.
-
-include(AddCompilerRT)
-include(SanitizerUtils)
-
-# Hoist the building of sanitizer_common on whether we're building either the
-# sanitizers or xray (or both).
-#
-#TODO: Refactor sanitizer_common into smaller pieces (e.g. flag parsing, utils).
-if (COMPILER_RT_HAS_SANITIZER_COMMON AND
- (COMPILER_RT_BUILD_SANITIZERS OR COMPILER_RT_BUILD_XRAY))
- add_subdirectory(sanitizer_common)
-endif()
-
-if(COMPILER_RT_BUILD_BUILTINS)
- add_subdirectory(builtins)
-endif()
-
-function(compiler_rt_build_runtime runtime)
- string(TOUPPER ${runtime} runtime_uppercase)
- if(COMPILER_RT_HAS_${runtime_uppercase})
- add_subdirectory(${runtime})
- if(${runtime} STREQUAL tsan)
- add_subdirectory(tsan/dd)
- endif()
- endif()
-endfunction()
-
-if(COMPILER_RT_BUILD_SANITIZERS)
- compiler_rt_build_runtime(interception)
-
- if(COMPILER_RT_HAS_SANITIZER_COMMON)
- add_subdirectory(stats)
- add_subdirectory(lsan)
- add_subdirectory(ubsan)
- endif()
-
- foreach(sanitizer ${COMPILER_RT_SANITIZERS_TO_BUILD})
- compiler_rt_build_runtime(${sanitizer})
- endforeach()
-endif()
-
-if(COMPILER_RT_BUILD_PROFILE AND COMPILER_RT_HAS_PROFILE)
- compiler_rt_build_runtime(profile)
-endif()
-
-if(COMPILER_RT_BUILD_XRAY)
- compiler_rt_build_runtime(xray)
-endif()
-
-if(COMPILER_RT_BUILD_LIBFUZZER)
- compiler_rt_build_runtime(fuzzer)
-endif()
diff --git a/lib/asan/.clang-format b/lib/asan/.clang-format
deleted file mode 100644
index 560308c91deec..0000000000000
--- a/lib/asan/.clang-format
+++ /dev/null
@@ -1,2 +0,0 @@
-BasedOnStyle: Google
-AllowShortIfStatementsOnASingleLine: false
diff --git a/lib/asan/CMakeLists.txt b/lib/asan/CMakeLists.txt
deleted file mode 100644
index 726da27d052f1..0000000000000
--- a/lib/asan/CMakeLists.txt
+++ /dev/null
@@ -1,338 +0,0 @@
-# Build for the AddressSanitizer runtime support library.
-
-set(ASAN_SOURCES
- asan_allocator.cc
- asan_activation.cc
- asan_debugging.cc
- asan_descriptions.cc
- asan_errors.cc
- asan_fake_stack.cc
- asan_flags.cc
- asan_fuchsia.cc
- asan_globals.cc
- asan_globals_win.cc
- asan_interceptors.cc
- asan_interceptors_memintrinsics.cc
- asan_linux.cc
- asan_mac.cc
- asan_malloc_linux.cc
- asan_malloc_mac.cc
- asan_malloc_win.cc
- asan_memory_profile.cc
- asan_poisoning.cc
- asan_posix.cc
- asan_premap_shadow.cc
- asan_report.cc
- asan_rtems.cc
- asan_rtl.cc
- asan_shadow_setup.cc
- asan_stack.cc
- asan_stats.cc
- asan_suppressions.cc
- asan_thread.cc
- asan_win.cc)
-
-set(ASAN_CXX_SOURCES
- asan_new_delete.cc)
-
-set(ASAN_PREINIT_SOURCES
- asan_preinit.cc)
-
-SET(ASAN_HEADERS
- asan_activation.h
- asan_activation_flags.inc
- asan_allocator.h
- asan_descriptions.h
- asan_errors.h
- asan_fake_stack.h
- asan_flags.h
- asan_flags.inc
- asan_init_version.h
- asan_interceptors.h
- asan_interceptors_memintrinsics.h
- asan_interface.inc
- asan_interface_internal.h
- asan_internal.h
- asan_lock.h
- asan_malloc_local.h
- asan_mapping.h
- asan_mapping_myriad.h
- asan_poisoning.h
- asan_premap_shadow.h
- asan_report.h
- asan_scariness_score.h
- asan_stack.h
- asan_stats.h
- asan_suppressions.h
- asan_thread.h)
-
-include_directories(..)
-
-set(ASAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})
-set(ASAN_COMMON_DEFINITIONS ${COMPILER_RT_ASAN_SHADOW_SCALE_DEFINITION})
-
-append_rtti_flag(OFF ASAN_CFLAGS)
-
-set(ASAN_DYNAMIC_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS})
-
-if(ANDROID)
-# Put most Sanitizer shared libraries in the global group. For more details, see
-# android-changes-for-ndk-developers.md#changes-to-library-search-order
- if (COMPILER_RT_HAS_Z_GLOBAL)
- list(APPEND ASAN_DYNAMIC_LINK_FLAGS -Wl,-z,global)
- endif()
-endif()
-
-set(ASAN_DYNAMIC_DEFINITIONS
- ${ASAN_COMMON_DEFINITIONS} ASAN_DYNAMIC=1)
-append_list_if(WIN32 INTERCEPTION_DYNAMIC_CRT ASAN_DYNAMIC_DEFINITIONS)
-
-set(ASAN_DYNAMIC_CFLAGS ${ASAN_CFLAGS})
-append_list_if(COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC
- -ftls-model=initial-exec ASAN_DYNAMIC_CFLAGS)
-append_list_if(MSVC /DEBUG ASAN_DYNAMIC_LINK_FLAGS)
-
-set(ASAN_DYNAMIC_LIBS ${SANITIZER_CXX_ABI_LIBRARY} ${SANITIZER_COMMON_LINK_LIBS})
-
-append_list_if(COMPILER_RT_HAS_LIBDL dl ASAN_DYNAMIC_LIBS)
-append_list_if(COMPILER_RT_HAS_LIBRT rt ASAN_DYNAMIC_LIBS)
-append_list_if(COMPILER_RT_HAS_LIBM m ASAN_DYNAMIC_LIBS)
-append_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread ASAN_DYNAMIC_LIBS)
-append_list_if(COMPILER_RT_HAS_LIBLOG log ASAN_DYNAMIC_LIBS)
-append_list_if(MINGW "${MINGW_LIBRARIES}" ASAN_DYNAMIC_LIBS)
-
-if (TARGET cxx-headers OR HAVE_LIBCXX)
- set(ASAN_DEPS cxx-headers)
-endif()
-
-# Compile ASan sources into an object library.
-
-add_compiler_rt_object_libraries(RTAsan_dynamic
- OS ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${ASAN_SUPPORTED_ARCH}
- SOURCES ${ASAN_SOURCES} ${ASAN_CXX_SOURCES}
- ADDITIONAL_HEADERS ${ASAN_HEADERS}
- CFLAGS ${ASAN_DYNAMIC_CFLAGS}
- DEFS ${ASAN_DYNAMIC_DEFINITIONS}
- DEPS ${ASAN_DEPS})
-
-if(NOT APPLE)
- add_compiler_rt_object_libraries(RTAsan
- ARCHS ${ASAN_SUPPORTED_ARCH}
- SOURCES ${ASAN_SOURCES}
- ADDITIONAL_HEADERS ${ASAN_HEADERS}
- CFLAGS ${ASAN_CFLAGS}
- DEFS ${ASAN_COMMON_DEFINITIONS}
- DEPS ${ASAN_DEPS})
- add_compiler_rt_object_libraries(RTAsan_cxx
- ARCHS ${ASAN_SUPPORTED_ARCH}
- SOURCES ${ASAN_CXX_SOURCES}
- ADDITIONAL_HEADERS ${ASAN_HEADERS}
- CFLAGS ${ASAN_CFLAGS}
- DEFS ${ASAN_COMMON_DEFINITIONS}
- DEPS ${ASAN_DEPS})
- add_compiler_rt_object_libraries(RTAsan_preinit
- ARCHS ${ASAN_SUPPORTED_ARCH}
- SOURCES ${ASAN_PREINIT_SOURCES}
- ADDITIONAL_HEADERS ${ASAN_HEADERS}
- CFLAGS ${ASAN_CFLAGS}
- DEFS ${ASAN_COMMON_DEFINITIONS}
- DEPS ${ASAN_DEPS})
-
- file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.cc "")
- add_compiler_rt_object_libraries(RTAsan_dynamic_version_script_dummy
- ARCHS ${ASAN_SUPPORTED_ARCH}
- SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dummy.cc
- CFLAGS ${ASAN_DYNAMIC_CFLAGS}
- DEFS ${ASAN_DYNAMIC_DEFINITIONS}
- DEPS ${ASAN_DEPS})
-endif()
-
-# Build ASan runtimes shipped with Clang.
-add_compiler_rt_component(asan)
-
-if(APPLE)
- add_weak_symbols("asan" WEAK_SYMBOL_LINK_FLAGS)
- add_weak_symbols("lsan" WEAK_SYMBOL_LINK_FLAGS)
- add_weak_symbols("ubsan" WEAK_SYMBOL_LINK_FLAGS)
- add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
- add_weak_symbols("xray" WEAK_SYMBOL_LINK_FLAGS)
-
- add_compiler_rt_runtime(clang_rt.asan
- SHARED
- OS ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${ASAN_SUPPORTED_ARCH}
- OBJECT_LIBS RTAsan_dynamic
- RTInterception
- RTSanitizerCommon
- RTSanitizerCommonLibc
- RTSanitizerCommonCoverage
- RTSanitizerCommonSymbolizer
- RTLSanCommon
- RTUbsan
- CFLAGS ${ASAN_DYNAMIC_CFLAGS}
- LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
- DEFS ${ASAN_DYNAMIC_DEFINITIONS}
- PARENT_TARGET asan)
-else()
- # Build separate libraries for each target.
-
- set(ASAN_COMMON_RUNTIME_OBJECT_LIBS
- RTInterception
- RTSanitizerCommon
- RTSanitizerCommonLibc
- RTSanitizerCommonCoverage
- RTSanitizerCommonSymbolizer
- RTLSanCommon
- RTUbsan)
-
- add_compiler_rt_runtime(clang_rt.asan
- STATIC
- ARCHS ${ASAN_SUPPORTED_ARCH}
- OBJECT_LIBS RTAsan_preinit
- RTAsan
- ${ASAN_COMMON_RUNTIME_OBJECT_LIBS}
- CFLAGS ${ASAN_CFLAGS}
- DEFS ${ASAN_COMMON_DEFINITIONS}
- PARENT_TARGET asan)
-
- add_compiler_rt_runtime(clang_rt.asan_cxx
- STATIC
- ARCHS ${ASAN_SUPPORTED_ARCH}
- OBJECT_LIBS RTAsan_cxx
- RTUbsan_cxx
- CFLAGS ${ASAN_CFLAGS}
- DEFS ${ASAN_COMMON_DEFINITIONS}
- PARENT_TARGET asan)
-
- add_compiler_rt_runtime(clang_rt.asan-preinit
- STATIC
- ARCHS ${ASAN_SUPPORTED_ARCH}
- OBJECT_LIBS RTAsan_preinit
- CFLAGS ${ASAN_CFLAGS}
- DEFS ${ASAN_COMMON_DEFINITIONS}
- PARENT_TARGET asan)
-
- foreach(arch ${ASAN_SUPPORTED_ARCH})
- if (UNIX)
- add_sanitizer_rt_version_list(clang_rt.asan-dynamic-${arch}
- LIBS clang_rt.asan-${arch} clang_rt.asan_cxx-${arch}
- EXTRA asan.syms.extra)
- set(VERSION_SCRIPT_FLAG
- -Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/clang_rt.asan-dynamic-${arch}.vers)
- # The Solaris 11.4 linker supports a subset of GNU ld version scripts,
- # but requires a special option to enable it.
- if (OS_NAME MATCHES "SunOS")
- list(APPEND VERSION_SCRIPT_FLAG -Wl,-z,gnu-version-script-compat)
- endif()
- set_property(SOURCE
- ${CMAKE_CURRENT_BINARY_DIR}/dummy.cc
- APPEND PROPERTY
- OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clang_rt.asan-dynamic-${arch}.vers)
- else()
- set(VERSION_SCRIPT_FLAG)
- endif()
-
- set(ASAN_DYNAMIC_WEAK_INTERCEPTION)
- if (WIN32)
- add_compiler_rt_object_libraries(AsanWeakInterception
- ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${arch}
- SOURCES asan_win_weak_interception.cc
- CFLAGS ${ASAN_CFLAGS} -DSANITIZER_DYNAMIC
- DEFS ${ASAN_COMMON_DEFINITIONS}
- DEPS ${ASAN_DEPS})
- set(ASAN_DYNAMIC_WEAK_INTERCEPTION
- AsanWeakInterception
- UbsanWeakInterception
- SancovWeakInterception
- SanitizerCommonWeakInterception)
- endif()
-
- add_compiler_rt_runtime(clang_rt.asan
- SHARED
- ARCHS ${arch}
- OBJECT_LIBS ${ASAN_COMMON_RUNTIME_OBJECT_LIBS}
- RTAsan_dynamic
- # The only purpose of RTAsan_dynamic_version_script_dummy is to
- # carry a dependency of the shared runtime on the version script.
- # Replacing it with a straightforward
- # add_dependencies(clang_rt.asan-dynamic-${arch} clang_rt.asan-dynamic-${arch}-version-list)
- # generates an order-only dependency in ninja.
- RTAsan_dynamic_version_script_dummy
- RTUbsan_cxx
- ${ASAN_DYNAMIC_WEAK_INTERCEPTION}
- CFLAGS ${ASAN_DYNAMIC_CFLAGS}
- LINK_FLAGS ${ASAN_DYNAMIC_LINK_FLAGS}
- ${VERSION_SCRIPT_FLAG}
- LINK_LIBS ${ASAN_DYNAMIC_LIBS}
- DEFS ${ASAN_DYNAMIC_DEFINITIONS}
- PARENT_TARGET asan)
-
- if (SANITIZER_USE_SYMBOLS AND NOT ${arch} STREQUAL "i386")
- add_sanitizer_rt_symbols(clang_rt.asan_cxx
- ARCHS ${arch})
- add_dependencies(asan clang_rt.asan_cxx-${arch}-symbols)
- add_sanitizer_rt_symbols(clang_rt.asan
- ARCHS ${arch}
- EXTRA asan.syms.extra)
- add_dependencies(asan clang_rt.asan-${arch}-symbols)
- endif()
-
- if (WIN32)
- add_compiler_rt_object_libraries(AsanDllThunk
- ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${arch}
- SOURCES asan_globals_win.cc
- asan_win_dll_thunk.cc
- CFLAGS ${ASAN_CFLAGS} -DSANITIZER_DLL_THUNK
- DEFS ${ASAN_COMMON_DEFINITIONS}
- DEPS ${ASAN_DEPS})
-
- add_compiler_rt_runtime(clang_rt.asan_dll_thunk
- STATIC
- ARCHS ${arch}
- OBJECT_LIBS AsanDllThunk
- UbsanDllThunk
- SancovDllThunk
- SanitizerCommonDllThunk
- SOURCES $<TARGET_OBJECTS:RTInterception.${arch}>
- PARENT_TARGET asan)
-
- set(DYNAMIC_RUNTIME_THUNK_CFLAGS "-DSANITIZER_DYNAMIC_RUNTIME_THUNK")
- if(MSVC)
- list(APPEND DYNAMIC_RUNTIME_THUNK_CFLAGS "-Zl")
- elseif(CMAKE_C_COMPILER_ID MATCHES Clang)
- list(APPEND DYNAMIC_RUNTIME_THUNK_CFLAGS "-nodefaultlibs")
- endif()
-
- add_compiler_rt_object_libraries(AsanDynamicRuntimeThunk
- ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${arch}
- SOURCES asan_globals_win.cc
- asan_win_dynamic_runtime_thunk.cc
- CFLAGS ${ASAN_CFLAGS} ${DYNAMIC_RUNTIME_THUNK_CFLAGS}
- DEFS ${ASAN_COMMON_DEFINITIONS}
- DEPS ${ASAN_DEPS})
-
- add_compiler_rt_runtime(clang_rt.asan_dynamic_runtime_thunk
- STATIC
- ARCHS ${arch}
- OBJECT_LIBS AsanDynamicRuntimeThunk
- UbsanDynamicRuntimeThunk
- SancovDynamicRuntimeThunk
- SanitizerCommonDynamicRuntimeThunk
- CFLAGS ${ASAN_CFLAGS} ${DYNAMIC_RUNTIME_THUNK_CFLAGS}
- DEFS ${ASAN_COMMON_DEFINITIONS}
- PARENT_TARGET asan)
- endif()
- endforeach()
-endif()
-
-add_compiler_rt_resource_file(asan_blacklist asan_blacklist.txt asan)
-
-add_subdirectory(scripts)
-
-if(COMPILER_RT_INCLUDE_TESTS)
- add_subdirectory(tests)
-endif()
diff --git a/lib/asan/scripts/CMakeLists.txt b/lib/asan/scripts/CMakeLists.txt
deleted file mode 100644
index e5ab8ebed0242..0000000000000
--- a/lib/asan/scripts/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-if(ANDROID)
- add_compiler_rt_script(asan_device_setup)
- add_dependencies(asan asan_device_setup)
-endif()
diff --git a/lib/asan/scripts/asan_device_setup b/lib/asan/scripts/asan_device_setup
deleted file mode 100755
index 5e679e366514a..0000000000000
--- a/lib/asan/scripts/asan_device_setup
+++ /dev/null
@@ -1,467 +0,0 @@
-#!/bin/bash
-#===- lib/asan/scripts/asan_device_setup -----------------------------------===#
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-# Prepare Android device to run ASan applications.
-#
-#===------------------------------------------------------------------------===#
-
-set -e
-
-HERE="$(cd "$(dirname "$0")" && pwd)"
-
-revert=no
-extra_options=
-device=
-lib=
-use_su=0
-
-function usage {
- echo "usage: $0 [--revert] [--device device-id] [--lib path] [--extra-options options]"
- echo " --revert: Uninstall ASan from the device."
- echo " --lib: Path to ASan runtime library."
- echo " --extra-options: Extra ASAN_OPTIONS."
- echo " --device: Install to the given device. Use 'adb devices' to find"
- echo " device-id."
- echo " --use-su: Use 'su -c' prefix for every adb command instead of using"
- echo " 'adb root' once."
- echo
- exit 1
-}
-
-function adb_push {
- if [ $use_su -eq 0 ]; then
- $ADB push "$1" "$2"
- else
- local FILENAME=$(basename $1)
- $ADB push "$1" "/data/local/tmp/$FILENAME"
- $ADB shell su -c "rm \\\"$2/$FILENAME\\\"" >&/dev/null
- $ADB shell su -c "cat \\\"/data/local/tmp/$FILENAME\\\" > \\\"$2/$FILENAME\\\""
- $ADB shell su -c "rm \\\"/data/local/tmp/$FILENAME\\\""
- fi
-}
-
-function adb_remount {
- if [ $use_su -eq 0 ]; then
- $ADB remount
- else
- local STORAGE=`$ADB shell mount | grep /system | cut -d ' ' -f1`
- if [ "$STORAGE" != "" ]; then
- echo Remounting $STORAGE at /system
- $ADB shell su -c "mount -o rw,remount $STORAGE /system"
- else
- echo Failed to get storage device name for "/system" mount point
- fi
- fi
-}
-
-function adb_shell {
- if [ $use_su -eq 0 ]; then
- $ADB shell $@
- else
- $ADB shell su -c "$*"
- fi
-}
-
-function adb_root {
- if [ $use_su -eq 0 ]; then
- $ADB root
- fi
-}
-
-function adb_wait_for_device {
- $ADB wait-for-device
-}
-
-function adb_pull {
- if [ $use_su -eq 0 ]; then
- $ADB pull "$1" "$2"
- else
- local FILENAME=$(basename $1)
- $ADB shell rm "/data/local/tmp/$FILENAME" >&/dev/null
- $ADB shell su -c "[ -f \\\"$1\\\" ] && cat \\\"$1\\\" > \\\"/data/local/tmp/$FILENAME\\\" && chown root.shell \\\"/data/local/tmp/$FILENAME\\\" && chmod 755 \\\"/data/local/tmp/$FILENAME\\\"" &&
- $ADB pull "/data/local/tmp/$FILENAME" "$2" >&/dev/null && $ADB shell "rm \"/data/local/tmp/$FILENAME\""
- fi
-}
-
-function get_device_arch { # OUT OUT64
- local _outvar=$1
- local _outvar64=$2
- local _ABI=$(adb_shell getprop ro.product.cpu.abi)
- local _ARCH=
- local _ARCH64=
- if [[ $_ABI == x86* ]]; then
- _ARCH=i386
- elif [[ $_ABI == armeabi* ]]; then
- _ARCH=arm
- elif [[ $_ABI == arm64-v8a* ]]; then
- _ARCH=arm
- _ARCH64=aarch64
- else
- echo "Unrecognized device ABI: $_ABI"
- exit 1
- fi
- eval $_outvar=\$_ARCH
- eval $_outvar64=\$_ARCH64
-}
-
-while [[ $# > 0 ]]; do
- case $1 in
- --revert)
- revert=yes
- ;;
- --extra-options)
- shift
- if [[ $# == 0 ]]; then
- echo "--extra-options requires an argument."
- exit 1
- fi
- extra_options="$1"
- ;;
- --lib)
- shift
- if [[ $# == 0 ]]; then
- echo "--lib requires an argument."
- exit 1
- fi
- lib="$1"
- ;;
- --device)
- shift
- if [[ $# == 0 ]]; then
- echo "--device requires an argument."
- exit 1
- fi
- device="$1"
- ;;
- --use-su)
- use_su=1
- ;;
- *)
- usage
- ;;
- esac
- shift
-done
-
-ADB=${ADB:-adb}
-if [[ x$device != x ]]; then
- ADB="$ADB -s $device"
-fi
-
-if [ $use_su -eq 1 ]; then
- # Test if 'su' is present on the device
- SU_TEST_OUT=`$ADB shell su -c "echo foo" 2>&1 | sed 's/\r$//'`
- if [ $? != 0 -o "$SU_TEST_OUT" != "foo" ]; then
- echo "ERROR: Cannot use 'su -c':"
- echo "$ adb shell su -c \"echo foo\""
- echo $SU_TEST_OUT
- echo "Check that 'su' binary is correctly installed on the device or omit"
- echo " --use-su flag"
- exit 1
- fi
-fi
-
-echo '>> Remounting /system rw'
-adb_wait_for_device
-adb_root
-adb_wait_for_device
-adb_remount
-adb_wait_for_device
-
-get_device_arch ARCH ARCH64
-echo "Target architecture: $ARCH"
-ASAN_RT="libclang_rt.asan-$ARCH-android.so"
-if [[ -n $ARCH64 ]]; then
- echo "Target architecture: $ARCH64"
- ASAN_RT64="libclang_rt.asan-$ARCH64-android.so"
-fi
-
-RELEASE=$(adb_shell getprop ro.build.version.release)
-PRE_L=0
-if echo "$RELEASE" | grep '^4\.' >&/dev/null; then
- PRE_L=1
-fi
-ANDROID_O=0
-if echo "$RELEASE" | grep '^8\.0\.' >&/dev/null; then
- # 8.0.x is for Android O
- ANDROID_O=1
-fi
-
-if [[ x$revert == xyes ]]; then
- echo '>> Uninstalling ASan'
-
- if ! adb_shell ls -l /system/bin/app_process | grep -o '\->.*app_process' >&/dev/null; then
- echo '>> Pre-L device detected.'
- adb_shell mv /system/bin/app_process.real /system/bin/app_process
- adb_shell rm /system/bin/asanwrapper
- elif ! adb_shell ls -l /system/bin/app_process64.real | grep -o 'No such file or directory' >&/dev/null; then
- # 64-bit installation.
- adb_shell mv /system/bin/app_process32.real /system/bin/app_process32
- adb_shell mv /system/bin/app_process64.real /system/bin/app_process64
- adb_shell rm /system/bin/asanwrapper
- adb_shell rm /system/bin/asanwrapper64
- else
- # 32-bit installation.
- adb_shell rm /system/bin/app_process.wrap
- adb_shell rm /system/bin/asanwrapper
- adb_shell rm /system/bin/app_process
- adb_shell ln -s /system/bin/app_process32 /system/bin/app_process
- fi
-
- if [[ ANDROID_O -eq 1 ]]; then
- adb_shell mv /system/etc/ld.config.txt.saved /system/etc/ld.config.txt
- fi
-
- echo '>> Restarting shell'
- adb_shell stop
- adb_shell start
-
- # Remove the library on the last step to give a chance to the 'su' binary to
- # be executed without problem.
- adb_shell rm /system/lib/$ASAN_RT
-
- echo '>> Done'
- exit 0
-fi
-
-if [[ -d "$lib" ]]; then
- ASAN_RT_PATH="$lib"
-elif [[ -f "$lib" && "$lib" == *"$ASAN_RT" ]]; then
- ASAN_RT_PATH=$(dirname "$lib")
-elif [[ -f "$HERE/$ASAN_RT" ]]; then
- ASAN_RT_PATH="$HERE"
-elif [[ $(basename "$HERE") == "bin" ]]; then
- # We could be in the toolchain's base directory.
- # Consider ../lib, ../lib/asan, ../lib/linux,
- # ../lib/clang/$VERSION/lib/linux, and ../lib64/clang/$VERSION/lib/linux.
- P=$(ls "$HERE"/../lib/"$ASAN_RT" \
- "$HERE"/../lib/asan/"$ASAN_RT" \
- "$HERE"/../lib/linux/"$ASAN_RT" \
- "$HERE"/../lib/clang/*/lib/linux/"$ASAN_RT" \
- "$HERE"/../lib64/clang/*/lib/linux/"$ASAN_RT" 2>/dev/null | sort | tail -1)
- if [[ -n "$P" ]]; then
- ASAN_RT_PATH="$(dirname "$P")"
- fi
-fi
-
-if [[ -z "$ASAN_RT_PATH" || ! -f "$ASAN_RT_PATH/$ASAN_RT" ]]; then
- echo ">> ASan runtime library not found"
- exit 1
-fi
-
-if [[ -n "$ASAN_RT64" ]]; then
- if [[ -z "$ASAN_RT_PATH" || ! -f "$ASAN_RT_PATH/$ASAN_RT64" ]]; then
- echo ">> ASan runtime library not found"
- exit 1
- fi
-fi
-
-TMPDIRBASE=$(mktemp -d)
-TMPDIROLD="$TMPDIRBASE/old"
-TMPDIR="$TMPDIRBASE/new"
-mkdir "$TMPDIROLD"
-
-if ! adb_shell ls -l /system/bin/app_process | grep -o '\->.*app_process' >&/dev/null; then
-
- if adb_pull /system/bin/app_process.real /dev/null >&/dev/null; then
- echo '>> Old-style ASan installation detected. Reverting.'
- adb_shell mv /system/bin/app_process.real /system/bin/app_process
- fi
-
- echo '>> Pre-L device detected. Setting up app_process symlink.'
- adb_shell mv /system/bin/app_process /system/bin/app_process32
- adb_shell ln -s /system/bin/app_process32 /system/bin/app_process
-fi
-
-echo '>> Copying files from the device'
-if [[ -n "$ASAN_RT64" ]]; then
- adb_pull /system/lib/"$ASAN_RT" "$TMPDIROLD" || true
- adb_pull /system/lib64/"$ASAN_RT64" "$TMPDIROLD" || true
- adb_pull /system/bin/app_process32 "$TMPDIROLD" || true
- adb_pull /system/bin/app_process32.real "$TMPDIROLD" || true
- adb_pull /system/bin/app_process64 "$TMPDIROLD" || true
- adb_pull /system/bin/app_process64.real "$TMPDIROLD" || true
- adb_pull /system/bin/asanwrapper "$TMPDIROLD" || true
- adb_pull /system/bin/asanwrapper64 "$TMPDIROLD" || true
-else
- adb_pull /system/lib/"$ASAN_RT" "$TMPDIROLD" || true
- adb_pull /system/bin/app_process32 "$TMPDIROLD" || true
- adb_pull /system/bin/app_process.wrap "$TMPDIROLD" || true
- adb_pull /system/bin/asanwrapper "$TMPDIROLD" || true
-fi
-cp -r "$TMPDIROLD" "$TMPDIR"
-
-if [[ -f "$TMPDIR/app_process.wrap" || -f "$TMPDIR/app_process64.real" ]]; then
- echo ">> Previous installation detected"
-else
- echo ">> New installation"
-fi
-
-echo '>> Generating wrappers'
-
-cp "$ASAN_RT_PATH/$ASAN_RT" "$TMPDIR/"
-if [[ -n "$ASAN_RT64" ]]; then
- cp "$ASAN_RT_PATH/$ASAN_RT64" "$TMPDIR/"
-fi
-
-ASAN_OPTIONS=start_deactivated=1
-
-# The name of a symlink to libclang_rt.asan-$ARCH-android.so used in LD_PRELOAD.
-# The idea is to have the same name in lib and lib64 to keep it from falling
-# apart when a 64-bit process spawns a 32-bit one, inheriting the environment.
-ASAN_RT_SYMLINK=symlink-to-libclang_rt.asan
-
-function generate_zygote_wrapper { # from, to
- local _from=$1
- local _to=$2
- if [[ PRE_L -eq 0 ]]; then
- # LD_PRELOAD parsing is broken in N if it starts with ":". Luckily, it is
- # unset in the system environment since L.
- local _ld_preload=$ASAN_RT_SYMLINK
- else
- local _ld_preload=\$LD_PRELOAD:$ASAN_RT_SYMLINK
- fi
- cat <<EOF >"$TMPDIR/$_from"
-#!/system/bin/sh-from-zygote
-ASAN_OPTIONS=$ASAN_OPTIONS \\
-ASAN_ACTIVATION_OPTIONS=include_if_exists=/data/local/tmp/asan.options.%b \\
-LD_PRELOAD=$_ld_preload \\
-exec $_to \$@
-
-EOF
-}
-
-# On Android-L not allowing user segv handler breaks some applications.
-# Since ~May 2017 this is the default setting; included for compatibility with
-# older library versions.
-if [[ PRE_L -eq 0 ]]; then
- ASAN_OPTIONS="$ASAN_OPTIONS,allow_user_segv_handler=1"
-fi
-
-if [[ x$extra_options != x ]] ; then
- ASAN_OPTIONS="$ASAN_OPTIONS,$extra_options"
-fi
-
-# Zygote wrapper.
-if [[ -f "$TMPDIR/app_process64" ]]; then
- # A 64-bit device.
- if [[ ! -f "$TMPDIR/app_process64.real" ]]; then
- # New installation.
- mv "$TMPDIR/app_process32" "$TMPDIR/app_process32.real"
- mv "$TMPDIR/app_process64" "$TMPDIR/app_process64.real"
- fi
- generate_zygote_wrapper "app_process32" "/system/bin/app_process32.real"
- generate_zygote_wrapper "app_process64" "/system/bin/app_process64.real"
-else
- # A 32-bit device.
- generate_zygote_wrapper "app_process.wrap" "/system/bin/app_process32"
-fi
-
-# General command-line tool wrapper (use for anything that's not started as
-# zygote).
-cat <<EOF >"$TMPDIR/asanwrapper"
-#!/system/bin/sh
-LD_PRELOAD=$ASAN_RT_SYMLINK \\
-exec \$@
-
-EOF
-
-if [[ -n "$ASAN_RT64" ]]; then
- cat <<EOF >"$TMPDIR/asanwrapper64"
-#!/system/bin/sh
-LD_PRELOAD=$ASAN_RT_SYMLINK \\
-exec \$@
-
-EOF
-fi
-
-function install { # from, to, chmod, chcon
- local _from=$1
- local _to=$2
- local _mode=$3
- local _context=$4
- local _basename="$(basename "$_from")"
- echo "Installing $_to/$_basename $_mode $_context"
- adb_push "$_from" "$_to/$_basename"
- adb_shell chown root.shell "$_to/$_basename"
- if [[ -n "$_mode" ]]; then
- adb_shell chmod "$_mode" "$_to/$_basename"
- fi
- if [[ -n "$_context" ]]; then
- adb_shell chcon "$_context" "$_to/$_basename"
- fi
-}
-
-if ! ( cd "$TMPDIRBASE" && diff -qr old/ new/ ) ; then
- # Make SELinux happy by keeping app_process wrapper and the shell
- # it runs on in zygote domain.
- ENFORCING=0
- if adb_shell getenforce | grep Enforcing >/dev/null; then
- # Sometimes shell is not allowed to change file contexts.
- # Temporarily switch to permissive.
- ENFORCING=1
- adb_shell setenforce 0
- fi
-
- if [[ PRE_L -eq 1 ]]; then
- CTX=u:object_r:system_file:s0
- else
- CTX=u:object_r:zygote_exec:s0
- fi
-
- echo '>> Pushing files to the device'
-
- if [[ -n "$ASAN_RT64" ]]; then
- install "$TMPDIR/$ASAN_RT" /system/lib 644
- install "$TMPDIR/$ASAN_RT64" /system/lib64 644
- install "$TMPDIR/app_process32" /system/bin 755 $CTX
- install "$TMPDIR/app_process32.real" /system/bin 755 $CTX
- install "$TMPDIR/app_process64" /system/bin 755 $CTX
- install "$TMPDIR/app_process64.real" /system/bin 755 $CTX
- install "$TMPDIR/asanwrapper" /system/bin 755
- install "$TMPDIR/asanwrapper64" /system/bin 755
-
- adb_shell rm -f /system/lib/$ASAN_RT_SYMLINK
- adb_shell ln -s $ASAN_RT /system/lib/$ASAN_RT_SYMLINK
- adb_shell rm -f /system/lib64/$ASAN_RT_SYMLINK
- adb_shell ln -s $ASAN_RT64 /system/lib64/$ASAN_RT_SYMLINK
- else
- install "$TMPDIR/$ASAN_RT" /system/lib 644
- install "$TMPDIR/app_process32" /system/bin 755 $CTX
- install "$TMPDIR/app_process.wrap" /system/bin 755 $CTX
- install "$TMPDIR/asanwrapper" /system/bin 755 $CTX
-
- adb_shell rm -f /system/lib/$ASAN_RT_SYMLINK
- adb_shell ln -s $ASAN_RT /system/lib/$ASAN_RT_SYMLINK
-
- adb_shell rm /system/bin/app_process
- adb_shell ln -s /system/bin/app_process.wrap /system/bin/app_process
- fi
-
- adb_shell cp /system/bin/sh /system/bin/sh-from-zygote
- adb_shell chcon $CTX /system/bin/sh-from-zygote
-
- if [[ ANDROID_O -eq 1 ]]; then
- # For Android O, the linker namespace is temporarily disabled.
- adb_shell mv /system/etc/ld.config.txt /system/etc/ld.config.txt.saved
- fi
-
- if [ $ENFORCING == 1 ]; then
- adb_shell setenforce 1
- fi
-
- echo '>> Restarting shell (asynchronous)'
- adb_shell stop
- adb_shell start
-
- echo '>> Please wait until the device restarts'
-else
- echo '>> Device is up to date'
-fi
-
-rm -r "$TMPDIRBASE"
diff --git a/lib/asan/scripts/asan_symbolize.py b/lib/asan/scripts/asan_symbolize.py
deleted file mode 100755
index 2dbb05283c1e7..0000000000000
--- a/lib/asan/scripts/asan_symbolize.py
+++ /dev/null
@@ -1,523 +0,0 @@
-#!/usr/bin/env python
-#===- lib/asan/scripts/asan_symbolize.py -----------------------------------===#
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-import argparse
-import bisect
-import getopt
-import os
-import re
-import subprocess
-import sys
-
-symbolizers = {}
-DEBUG = False
-demangle = False
-binutils_prefix = None
-sysroot_path = None
-binary_name_filter = None
-fix_filename_patterns = None
-logfile = sys.stdin
-allow_system_symbolizer = True
-force_system_symbolizer = False
-
-# FIXME: merge the code that calls fix_filename().
-def fix_filename(file_name):
- if fix_filename_patterns:
- for path_to_cut in fix_filename_patterns:
- file_name = re.sub('.*' + path_to_cut, '', file_name)
- file_name = re.sub('.*asan_[a-z_]*.cc:[0-9]*', '_asan_rtl_', file_name)
- file_name = re.sub('.*crtstuff.c:0', '???:0', file_name)
- return file_name
-
-def sysroot_path_filter(binary_name):
- return sysroot_path + binary_name
-
-def is_valid_arch(s):
- return s in ["i386", "x86_64", "x86_64h", "arm", "armv6", "armv7", "armv7s",
- "armv7k", "arm64", "powerpc64", "powerpc64le", "s390x", "s390"]
-
-def guess_arch(addr):
- # Guess which arch we're running. 10 = len('0x') + 8 hex digits.
- if len(addr) > 10:
- return 'x86_64'
- else:
- return 'i386'
-
-class Symbolizer(object):
- def __init__(self):
- pass
-
- def symbolize(self, addr, binary, offset):
- """Symbolize the given address (pair of binary and offset).
-
- Overriden in subclasses.
- Args:
- addr: virtual address of an instruction.
- binary: path to executable/shared object containing this instruction.
- offset: instruction offset in the @binary.
- Returns:
- list of strings (one string for each inlined frame) describing
- the code locations for this instruction (that is, function name, file
- name, line and column numbers).
- """
- return None
-
-
-class LLVMSymbolizer(Symbolizer):
- def __init__(self, symbolizer_path, default_arch, system, dsym_hints=[]):
- super(LLVMSymbolizer, self).__init__()
- self.symbolizer_path = symbolizer_path
- self.default_arch = default_arch
- self.system = system
- self.dsym_hints = dsym_hints
- self.pipe = self.open_llvm_symbolizer()
-
- def open_llvm_symbolizer(self):
- cmd = [self.symbolizer_path,
- '--use-symbol-table=true',
- '--demangle=%s' % demangle,
- '--functions=linkage',
- '--inlining=true',
- '--default-arch=%s' % self.default_arch]
- if self.system == 'Darwin':
- for hint in self.dsym_hints:
- cmd.append('--dsym-hint=%s' % hint)
- if DEBUG:
- print(' '.join(cmd))
- try:
- result = subprocess.Popen(cmd, stdin=subprocess.PIPE,
- stdout=subprocess.PIPE,
- bufsize=0,
- universal_newlines=True)
- except OSError:
- result = None
- return result
-
- def symbolize(self, addr, binary, offset):
- """Overrides Symbolizer.symbolize."""
- if not self.pipe:
- return None
- result = []
- try:
- symbolizer_input = '"%s" %s' % (binary, offset)
- if DEBUG:
- print(symbolizer_input)
- self.pipe.stdin.write("%s\n" % symbolizer_input)
- while True:
- function_name = self.pipe.stdout.readline().rstrip()
- if not function_name:
- break
- file_name = self.pipe.stdout.readline().rstrip()
- file_name = fix_filename(file_name)
- if (not function_name.startswith('??') or
- not file_name.startswith('??')):
- # Append only non-trivial frames.
- result.append('%s in %s %s' % (addr, function_name,
- file_name))
- except Exception:
- result = []
- if not result:
- result = None
- return result
-
-
-def LLVMSymbolizerFactory(system, default_arch, dsym_hints=[]):
- symbolizer_path = os.getenv('LLVM_SYMBOLIZER_PATH')
- if not symbolizer_path:
- symbolizer_path = os.getenv('ASAN_SYMBOLIZER_PATH')
- if not symbolizer_path:
- # Assume llvm-symbolizer is in PATH.
- symbolizer_path = 'llvm-symbolizer'
- return LLVMSymbolizer(symbolizer_path, default_arch, system, dsym_hints)
-
-
-class Addr2LineSymbolizer(Symbolizer):
- def __init__(self, binary):
- super(Addr2LineSymbolizer, self).__init__()
- self.binary = binary
- self.pipe = self.open_addr2line()
- self.output_terminator = -1
-
- def open_addr2line(self):
- addr2line_tool = 'addr2line'
- if binutils_prefix:
- addr2line_tool = binutils_prefix + addr2line_tool
- cmd = [addr2line_tool, '-fi']
- if demangle:
- cmd += ['--demangle']
- cmd += ['-e', self.binary]
- if DEBUG:
- print(' '.join(cmd))
- return subprocess.Popen(cmd,
- stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- bufsize=0,
- universal_newlines=True)
-
- def symbolize(self, addr, binary, offset):
- """Overrides Symbolizer.symbolize."""
- if self.binary != binary:
- return None
- lines = []
- try:
- self.pipe.stdin.write("%s\n" % offset)
- self.pipe.stdin.write("%s\n" % self.output_terminator)
- is_first_frame = True
- while True:
- function_name = self.pipe.stdout.readline().rstrip()
- file_name = self.pipe.stdout.readline().rstrip()
- if is_first_frame:
- is_first_frame = False
- elif function_name in ['', '??']:
- assert file_name == function_name
- break
- lines.append((function_name, file_name));
- except Exception:
- lines.append(('??', '??:0'))
- return ['%s in %s %s' % (addr, function, fix_filename(file)) for (function, file) in lines]
-
-class UnbufferedLineConverter(object):
- """
- Wrap a child process that responds to each line of input with one line of
- output. Uses pty to trick the child into providing unbuffered output.
- """
- def __init__(self, args, close_stderr=False):
- # Local imports so that the script can start on Windows.
- import pty
- import termios
- pid, fd = pty.fork()
- if pid == 0:
- # We're the child. Transfer control to command.
- if close_stderr:
- dev_null = os.open('/dev/null', 0)
- os.dup2(dev_null, 2)
- os.execvp(args[0], args)
- else:
- # Disable echoing.
- attr = termios.tcgetattr(fd)
- attr[3] = attr[3] & ~termios.ECHO
- termios.tcsetattr(fd, termios.TCSANOW, attr)
- # Set up a file()-like interface to the child process
- self.r = os.fdopen(fd, "r", 1)
- self.w = os.fdopen(os.dup(fd), "w", 1)
-
- def convert(self, line):
- self.w.write(line + "\n")
- return self.readline()
-
- def readline(self):
- return self.r.readline().rstrip()
-
-
-class DarwinSymbolizer(Symbolizer):
- def __init__(self, addr, binary, arch):
- super(DarwinSymbolizer, self).__init__()
- self.binary = binary
- self.arch = arch
- self.open_atos()
-
- def open_atos(self):
- if DEBUG:
- print('atos -o %s -arch %s' % (self.binary, self.arch))
- cmdline = ['atos', '-o', self.binary, '-arch', self.arch]
- self.atos = UnbufferedLineConverter(cmdline, close_stderr=True)
-
- def symbolize(self, addr, binary, offset):
- """Overrides Symbolizer.symbolize."""
- if self.binary != binary:
- return None
- if not os.path.exists(binary):
- # If the binary doesn't exist atos will exit which will lead to IOError
- # exceptions being raised later on so just don't try to symbolize.
- return ['{} ({}:{}+{})'.format(addr, binary, self.arch, offset)]
- atos_line = self.atos.convert('0x%x' % int(offset, 16))
- while "got symbolicator for" in atos_line:
- atos_line = self.atos.readline()
- # A well-formed atos response looks like this:
- # foo(type1, type2) (in object.name) (filename.cc:80)
- match = re.match('^(.*) \(in (.*)\) \((.*:\d*)\)$', atos_line)
- if DEBUG:
- print('atos_line: ', atos_line)
- if match:
- function_name = match.group(1)
- function_name = re.sub('\(.*?\)', '', function_name)
- file_name = fix_filename(match.group(3))
- return ['%s in %s %s' % (addr, function_name, file_name)]
- else:
- return ['%s in %s' % (addr, atos_line)]
-
-
-# Chain several symbolizers so that if one symbolizer fails, we fall back
-# to the next symbolizer in chain.
-class ChainSymbolizer(Symbolizer):
- def __init__(self, symbolizer_list):
- super(ChainSymbolizer, self).__init__()
- self.symbolizer_list = symbolizer_list
-
- def symbolize(self, addr, binary, offset):
- """Overrides Symbolizer.symbolize."""
- for symbolizer in self.symbolizer_list:
- if symbolizer:
- result = symbolizer.symbolize(addr, binary, offset)
- if result:
- return result
- return None
-
- def append_symbolizer(self, symbolizer):
- self.symbolizer_list.append(symbolizer)
-
-
-def BreakpadSymbolizerFactory(binary):
- suffix = os.getenv('BREAKPAD_SUFFIX')
- if suffix:
- filename = binary + suffix
- if os.access(filename, os.F_OK):
- return BreakpadSymbolizer(filename)
- return None
-
-
-def SystemSymbolizerFactory(system, addr, binary, arch):
- if system == 'Darwin':
- return DarwinSymbolizer(addr, binary, arch)
- elif system in ['Linux', 'FreeBSD', 'NetBSD', 'SunOS']:
- return Addr2LineSymbolizer(binary)
-
-
-class BreakpadSymbolizer(Symbolizer):
- def __init__(self, filename):
- super(BreakpadSymbolizer, self).__init__()
- self.filename = filename
- lines = file(filename).readlines()
- self.files = []
- self.symbols = {}
- self.address_list = []
- self.addresses = {}
- # MODULE mac x86_64 A7001116478B33F18FF9BEDE9F615F190 t
- fragments = lines[0].rstrip().split()
- self.arch = fragments[2]
- self.debug_id = fragments[3]
- self.binary = ' '.join(fragments[4:])
- self.parse_lines(lines[1:])
-
- def parse_lines(self, lines):
- cur_function_addr = ''
- for line in lines:
- fragments = line.split()
- if fragments[0] == 'FILE':
- assert int(fragments[1]) == len(self.files)
- self.files.append(' '.join(fragments[2:]))
- elif fragments[0] == 'PUBLIC':
- self.symbols[int(fragments[1], 16)] = ' '.join(fragments[3:])
- elif fragments[0] in ['CFI', 'STACK']:
- pass
- elif fragments[0] == 'FUNC':
- cur_function_addr = int(fragments[1], 16)
- if not cur_function_addr in self.symbols.keys():
- self.symbols[cur_function_addr] = ' '.join(fragments[4:])
- else:
- # Line starting with an address.
- addr = int(fragments[0], 16)
- self.address_list.append(addr)
- # Tuple of symbol address, size, line, file number.
- self.addresses[addr] = (cur_function_addr,
- int(fragments[1], 16),
- int(fragments[2]),
- int(fragments[3]))
- self.address_list.sort()
-
- def get_sym_file_line(self, addr):
- key = None
- if addr in self.addresses.keys():
- key = addr
- else:
- index = bisect.bisect_left(self.address_list, addr)
- if index == 0:
- return None
- else:
- key = self.address_list[index - 1]
- sym_id, size, line_no, file_no = self.addresses[key]
- symbol = self.symbols[sym_id]
- filename = self.files[file_no]
- if addr < key + size:
- return symbol, filename, line_no
- else:
- return None
-
- def symbolize(self, addr, binary, offset):
- if self.binary != binary:
- return None
- res = self.get_sym_file_line(int(offset, 16))
- if res:
- function_name, file_name, line_no = res
- result = ['%s in %s %s:%d' % (
- addr, function_name, file_name, line_no)]
- print(result)
- return result
- else:
- return None
-
-
-class SymbolizationLoop(object):
- def __init__(self, binary_name_filter=None, dsym_hint_producer=None):
- if sys.platform == 'win32':
- # ASan on Windows uses dbghelp.dll to symbolize in-process, which works
- # even in sandboxed processes. Nothing needs to be done here.
- self.process_line = self.process_line_echo
- else:
- # Used by clients who may want to supply a different binary name.
- # E.g. in Chrome several binaries may share a single .dSYM.
- self.binary_name_filter = binary_name_filter
- self.dsym_hint_producer = dsym_hint_producer
- self.system = os.uname()[0]
- if self.system not in ['Linux', 'Darwin', 'FreeBSD', 'NetBSD','SunOS']:
- raise Exception('Unknown system')
- self.llvm_symbolizers = {}
- self.last_llvm_symbolizer = None
- self.dsym_hints = set([])
- self.frame_no = 0
- self.process_line = self.process_line_posix
-
- def symbolize_address(self, addr, binary, offset, arch):
- # On non-Darwin (i.e. on platforms without .dSYM debug info) always use
- # a single symbolizer binary.
- # On Darwin, if the dsym hint producer is present:
- # 1. check whether we've seen this binary already; if so,
- # use |llvm_symbolizers[binary]|, which has already loaded the debug
- # info for this binary (might not be the case for
- # |last_llvm_symbolizer|);
- # 2. otherwise check if we've seen all the hints for this binary already;
- # if so, reuse |last_llvm_symbolizer| which has the full set of hints;
- # 3. otherwise create a new symbolizer and pass all currently known
- # .dSYM hints to it.
- result = None
- if not force_system_symbolizer:
- if not binary in self.llvm_symbolizers:
- use_new_symbolizer = True
- if self.system == 'Darwin' and self.dsym_hint_producer:
- dsym_hints_for_binary = set(self.dsym_hint_producer(binary))
- use_new_symbolizer = bool(dsym_hints_for_binary - self.dsym_hints)
- self.dsym_hints |= dsym_hints_for_binary
- if self.last_llvm_symbolizer and not use_new_symbolizer:
- self.llvm_symbolizers[binary] = self.last_llvm_symbolizer
- else:
- self.last_llvm_symbolizer = LLVMSymbolizerFactory(
- self.system, arch, self.dsym_hints)
- self.llvm_symbolizers[binary] = self.last_llvm_symbolizer
- # Use the chain of symbolizers:
- # Breakpad symbolizer -> LLVM symbolizer -> addr2line/atos
- # (fall back to next symbolizer if the previous one fails).
- if not binary in symbolizers:
- symbolizers[binary] = ChainSymbolizer(
- [BreakpadSymbolizerFactory(binary), self.llvm_symbolizers[binary]])
- result = symbolizers[binary].symbolize(addr, binary, offset)
- else:
- symbolizers[binary] = ChainSymbolizer([])
- if result is None:
- if not allow_system_symbolizer:
- raise Exception('Failed to launch or use llvm-symbolizer.')
- # Initialize system symbolizer only if other symbolizers failed.
- symbolizers[binary].append_symbolizer(
- SystemSymbolizerFactory(self.system, addr, binary, arch))
- result = symbolizers[binary].symbolize(addr, binary, offset)
- # The system symbolizer must produce some result.
- assert result
- return result
-
- def get_symbolized_lines(self, symbolized_lines):
- if not symbolized_lines:
- return [self.current_line]
- else:
- result = []
- for symbolized_frame in symbolized_lines:
- result.append(' #%s %s' % (str(self.frame_no), symbolized_frame.rstrip()))
- self.frame_no += 1
- return result
-
- def process_logfile(self):
- self.frame_no = 0
- for line in logfile:
- processed = self.process_line(line)
- print('\n'.join(processed))
-
- def process_line_echo(self, line):
- return [line.rstrip()]
-
- def process_line_posix(self, line):
- self.current_line = line.rstrip()
- #0 0x7f6e35cf2e45 (/blah/foo.so+0x11fe45)
- stack_trace_line_format = (
- '^( *#([0-9]+) *)(0x[0-9a-f]+) *\((.*)\+(0x[0-9a-f]+)\)')
- match = re.match(stack_trace_line_format, line)
- if not match:
- return [self.current_line]
- if DEBUG:
- print(line)
- _, frameno_str, addr, binary, offset = match.groups()
- arch = ""
- # Arch can be embedded in the filename, e.g.: "libabc.dylib:x86_64h"
- colon_pos = binary.rfind(":")
- if colon_pos != -1:
- maybe_arch = binary[colon_pos+1:]
- if is_valid_arch(maybe_arch):
- arch = maybe_arch
- binary = binary[0:colon_pos]
- if arch == "":
- arch = guess_arch(addr)
- if frameno_str == '0':
- # Assume that frame #0 is the first frame of new stack trace.
- self.frame_no = 0
- original_binary = binary
- if self.binary_name_filter:
- binary = self.binary_name_filter(binary)
- symbolized_line = self.symbolize_address(addr, binary, offset, arch)
- if not symbolized_line:
- if original_binary != binary:
- symbolized_line = self.symbolize_address(addr, original_binary, offset, arch)
- return self.get_symbolized_lines(symbolized_line)
-
-
-if __name__ == '__main__':
- parser = argparse.ArgumentParser(
- formatter_class=argparse.RawDescriptionHelpFormatter,
- description='ASan symbolization script',
- epilog='Example of use:\n'
- 'asan_symbolize.py -c "$HOME/opt/cross/bin/arm-linux-gnueabi-" '
- '-s "$HOME/SymbolFiles" < asan.log')
- parser.add_argument('path_to_cut', nargs='*',
- help='pattern to be cut from the result file path ')
- parser.add_argument('-d','--demangle', action='store_true',
- help='demangle function names')
- parser.add_argument('-s', metavar='SYSROOT',
- help='set path to sysroot for sanitized binaries')
- parser.add_argument('-c', metavar='CROSS_COMPILE',
- help='set prefix for binutils')
- parser.add_argument('-l','--logfile', default=sys.stdin,
- type=argparse.FileType('r'),
- help='set log file name to parse, default is stdin')
- parser.add_argument('--force-system-symbolizer', action='store_true',
- help='don\'t use llvm-symbolizer')
- args = parser.parse_args()
- if args.path_to_cut:
- fix_filename_patterns = args.path_to_cut
- if args.demangle:
- demangle = True
- if args.s:
- binary_name_filter = sysroot_path_filter
- sysroot_path = args.s
- if args.c:
- binutils_prefix = args.c
- if args.logfile:
- logfile = args.logfile
- else:
- logfile = sys.stdin
- if args.force_system_symbolizer:
- force_system_symbolizer = True
- if force_system_symbolizer:
- assert(allow_system_symbolizer)
- loop = SymbolizationLoop(binary_name_filter)
- loop.process_logfile()
diff --git a/lib/asan/tests/CMakeLists.txt b/lib/asan/tests/CMakeLists.txt
deleted file mode 100644
index 9e640d1d8b012..0000000000000
--- a/lib/asan/tests/CMakeLists.txt
+++ /dev/null
@@ -1,309 +0,0 @@
-# Testing rules for AddressSanitizer.
-#
-# These are broken into two buckets. One set of tests directly interacts with
-# the runtime library and checks its functionality. These are the
-# no-instrumentation tests.
-#
-# Another group of tests relies upon the ability to compile the test with
-# address sanitizer instrumentation pass. These tests form "integration" tests
-# and have some elements of version skew -- they test the *host* compiler's
-# instrumentation against the just-built runtime library.
-
-include(CheckCXXCompilerFlag)
-include(CompilerRTCompile)
-
-include_directories(..)
-include_directories(../..)
-
-set(ASAN_UNITTEST_HEADERS
- asan_mac_test.h
- asan_test_config.h
- asan_test_utils.h)
-
-set(ASAN_UNITTEST_COMMON_CFLAGS
- ${COMPILER_RT_UNITTEST_CFLAGS}
- ${COMPILER_RT_GTEST_CFLAGS}
- ${COMPILER_RT_ASAN_SHADOW_SCALE_LLVM_FLAG}
- -I${COMPILER_RT_SOURCE_DIR}/include
- -I${COMPILER_RT_SOURCE_DIR}/lib
- -I${COMPILER_RT_SOURCE_DIR}/lib/asan
- -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/tests
- -fno-rtti
- -O2
- -Wno-format
- -Werror=sign-compare
- -Wno-non-virtual-dtor)
-append_list_if(COMPILER_RT_HAS_WVARIADIC_MACROS_FLAG -Wno-variadic-macros ASAN_UNITTEST_COMMON_CFLAGS)
-
-# This will ensure the target linker is used
-# during cross compilation
-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")
- list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gline-tables-only)
-else()
- list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -g)
-endif()
-if(MSVC)
- list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -gcodeview)
-endif()
-list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS -g)
-
-# Use -D instead of definitions to please custom compile command.
-list(APPEND ASAN_UNITTEST_COMMON_CFLAGS
- ${COMPILER_RT_ASAN_SHADOW_SCALE_FLAG}
- -DASAN_HAS_BLACKLIST=1
- -DASAN_HAS_EXCEPTIONS=1
- -DASAN_UAR=0)
-
-if(APPLE)
- list(APPEND ASAN_UNITTEST_COMMON_CFLAGS ${DARWIN_osx_CFLAGS})
- list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS ${DARWIN_osx_LINK_FLAGS})
-
- 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()
-
-set(ASAN_BLACKLIST_FILE "${CMAKE_CURRENT_SOURCE_DIR}/asan_test.ignore")
-set(ASAN_UNITTEST_INSTRUMENTED_CFLAGS
- ${ASAN_UNITTEST_COMMON_CFLAGS}
- -fsanitize=address
- "-fsanitize-blacklist=${ASAN_BLACKLIST_FILE}"
-)
-if(CAN_TARGET_x86_64 OR CAN_TARGET_i386)
- list(APPEND ASAN_UNITTEST_INSTRUMENTED_CFLAGS -mllvm -asan-instrument-assembly)
-endif()
-
-if(NOT MSVC)
- 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_LINK_FLAGS "-lc++")
-endif()
-
-# Unit tests on Mac depend on Foundation.
-if(APPLE)
- list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS -framework Foundation)
-endif()
-if(ANDROID)
- list(APPEND ASAN_UNITTEST_COMMON_LINK_FLAGS -pie)
-endif()
-
-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_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_LINK_FLAGS ${ASAN_UNITTEST_COMMON_LINK_FLAGS})
-if(NOT APPLE)
- 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?
-set(ASAN_UNITTEST_NOINST_LIBS)
-append_list_if(COMPILER_RT_HAS_LIBLOG log ASAN_UNITTEST_NOINST_LIBS)
-# NDK r10 requires -latomic almost always.
-append_list_if(ANDROID atomic ASAN_UNITTEST_NOINST_LIBS)
-
-# Main AddressSanitizer unit tests.
-add_custom_target(AsanUnitTests)
-set_target_properties(AsanUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
-
-# AddressSanitizer unit tests with dynamic runtime (on platforms where it's
-# not the default).
-add_custom_target(AsanDynamicUnitTests)
-set_target_properties(AsanDynamicUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
-# ASan benchmarks (not actively used now).
-add_custom_target(AsanBenchmarks)
-set_target_properties(AsanBenchmarks PROPERTIES FOLDER "Compiler-RT Tests")
-
-set(ASAN_NOINST_TEST_SOURCES
- ${COMPILER_RT_GTEST_SOURCE}
- asan_fake_stack_test.cc
- asan_noinst_test.cc
- asan_test_main.cc)
-
-set(ASAN_INST_TEST_SOURCES
- ${COMPILER_RT_GTEST_SOURCE}
- asan_asm_test.cc
- asan_globals_test.cc
- asan_interface_test.cc
- asan_internal_interface_test.cc
- asan_test.cc
- asan_oob_test.cc
- asan_mem_test.cc
- asan_str_test.cc
- asan_test_main.cc)
-if(APPLE)
- list(APPEND ASAN_INST_TEST_SOURCES asan_mac_test.cc asan_mac_test_helpers.mm)
-endif()
-
-set(ASAN_BENCHMARKS_SOURCES
- ${COMPILER_RT_GTEST_SOURCE}
- asan_benchmarks_test.cc)
-
-function(add_asan_tests arch test_runtime)
- cmake_parse_arguments(TEST "" "KIND" "CFLAGS" ${ARGN})
-
- # Closure to keep the values.
- function(generate_asan_tests test_objects test_suite testname)
- generate_compiler_rt_tests(${test_objects} ${test_suite} ${testname} ${arch}
- COMPILE_DEPS ${ASAN_UNITTEST_HEADERS} ${ASAN_BLACKLIST_FILE}
- DEPS gtest asan
- KIND ${TEST_KIND}
- ${ARGN}
- )
- set("${test_objects}" "${${test_objects}}" PARENT_SCOPE)
- endfunction()
-
- set(ASAN_INST_TEST_OBJECTS)
- generate_asan_tests(ASAN_INST_TEST_OBJECTS AsanUnitTests
- "Asan-${arch}${TEST_KIND}-Test"
- SUBDIR "default"
- LINK_FLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS}
- SOURCES ${ASAN_INST_TEST_SOURCES}
- CFLAGS ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} ${TEST_CFLAGS})
-
- if(COMPILER_RT_ASAN_HAS_STATIC_RUNTIME)
- set(dynamic_test_name "Asan-${arch}${TEST_KIND}-Dynamic-Test")
- if(MSVC)
-
- # With the MSVC CRT, the choice between static and dynamic CRT is made at
- # compile time with a macro. Simulate the effect of passing /MD to clang-cl.
- set(ASAN_DYNAMIC_TEST_OBJECTS)
- generate_asan_tests(ASAN_DYNAMIC_TEST_OBJECTS
- AsanDynamicUnitTests "${dynamic_test_name}"
- SUBDIR "dynamic"
- CFLAGS ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS} -D_MT -D_DLL
- SOURCES ${ASAN_INST_TEST_SOURCES}
- LINK_FLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS}
- -Wl,-nodefaultlib:libcmt,-defaultlib:msvcrt,-defaultlib:oldnames
- )
- else()
-
- # Otherwise, reuse ASAN_INST_TEST_OBJECTS.
- add_compiler_rt_test(AsanDynamicUnitTests "${dynamic_test_name}" "${arch}"
- SUBDIR "dynamic"
- OBJECTS ${ASAN_INST_TEST_OBJECTS}
- DEPS asan ${ASAN_INST_TEST_OBJECTS}
- LINK_FLAGS ${ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS}
- )
- endif()
- endif()
-
- # Uninstrumented tests.
- set(ASAN_NOINST_TEST_OBJECTS)
- generate_asan_tests(ASAN_NOINST_TEST_OBJECTS
- AsanUnitTests "Asan-${arch}${TEST_KIND}-Noinst-Test"
- SUBDIR "default"
- CFLAGS ${ASAN_UNITTEST_COMMON_CFLAGS}
- LINK_FLAGS ${ASAN_UNITTEST_NOINST_LINK_FLAGS}
- SOURCES ${ASAN_NOINST_TEST_SOURCES}
- RUNTIME ${test_runtime})
-
- set(ASAN_BENCHMARK_OBJECTS)
- generate_asan_tests(ASAN_BENCHMARK_OBJECTS
- AsanBenchmarks "Asan-${arch}${TEST_KIND}-Benchmark"
- SUBDIR "default"
- CFLAGS ${ASAN_UNITTEST_INSTRUMENTED_CFLAGS}
- SOURCES ${ASAN_BENCHMARKS_SOURCES}
- LINK_FLAGS ${ASAN_UNITTEST_INSTRUMENTED_LINK_FLAGS})
-endfunction()
-
-if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
- set(ASAN_TEST_ARCH ${ASAN_SUPPORTED_ARCH})
- if(APPLE)
- darwin_filter_host_archs(ASAN_SUPPORTED_ARCH ASAN_TEST_ARCH)
- endif()
- if(OS_NAME MATCHES "SunOS")
- list(REMOVE_ITEM ASAN_TEST_ARCH x86_64)
- endif()
-
- foreach(arch ${ASAN_TEST_ARCH})
-
- # Add static ASan runtime that will be linked with uninstrumented tests.
- set(ASAN_TEST_RUNTIME RTAsanTest.${arch})
- if(APPLE)
- set(ASAN_TEST_RUNTIME_OBJECTS
- $<TARGET_OBJECTS:RTAsan_dynamic.osx>
- $<TARGET_OBJECTS:RTInterception.osx>
- $<TARGET_OBJECTS:RTSanitizerCommon.osx>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.osx>
- $<TARGET_OBJECTS:RTSanitizerCommonCoverage.osx>
- $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.osx>
- $<TARGET_OBJECTS:RTLSanCommon.osx>
- $<TARGET_OBJECTS:RTUbsan.osx>)
- else()
- set(ASAN_TEST_RUNTIME_OBJECTS
- $<TARGET_OBJECTS:RTAsan.${arch}>
- $<TARGET_OBJECTS:RTAsan_cxx.${arch}>
- $<TARGET_OBJECTS:RTInterception.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
- $<TARGET_OBJECTS:RTLSanCommon.${arch}>
- $<TARGET_OBJECTS:RTUbsan.${arch}>
- $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>)
- endif()
- add_library(${ASAN_TEST_RUNTIME} STATIC ${ASAN_TEST_RUNTIME_OBJECTS})
- set_target_properties(${ASAN_TEST_RUNTIME} PROPERTIES
- ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- FOLDER "Compiler-RT Runtime tests")
-
- add_asan_tests(${arch} ${ASAN_TEST_RUNTIME} KIND "-inline")
- add_asan_tests(${arch} ${ASAN_TEST_RUNTIME} KIND "-calls"
- CFLAGS -mllvm -asan-instrumentation-with-call-threshold=0)
- endforeach()
-endif()
-
-if(ANDROID)
- foreach(arch ${ASAN_SUPPORTED_ARCH})
- # Test w/o ASan instrumentation. Link it with ASan statically.
- add_executable(AsanNoinstTest # FIXME: .arch?
- $<TARGET_OBJECTS:RTAsan.${arch}>
- $<TARGET_OBJECTS:RTInterception.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
- $<TARGET_OBJECTS:RTUbsan.${arch}>
- $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
- ${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_LINK_FLAGS})
- target_link_libraries(AsanNoinstTest ${ASAN_UNITTEST_NOINST_LIBS})
-
- # Test with ASan instrumentation. Link with ASan dynamic runtime.
- add_executable(AsanTest
- ${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_LINK_FLAGS})
- target_link_libraries(AsanTest ${ASAN_UNITTEST_INSTRUMENTED_LIBS})
-
- # Setup correct output directory and link flags.
- set_target_properties(AsanNoinstTest AsanTest PROPERTIES
- RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
- # Add unit tests to the test suite.
- add_dependencies(AsanUnitTests AsanNoinstTest AsanTest)
- endforeach()
-endif()
diff --git a/lib/asan/tests/asan_asm_test.cc b/lib/asan/tests/asan_asm_test.cc
deleted file mode 100644
index 91f8aacd6eeb1..0000000000000
--- a/lib/asan/tests/asan_asm_test.cc
+++ /dev/null
@@ -1,274 +0,0 @@
-//===-- asan_asm_test.cc --------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-//===----------------------------------------------------------------------===//
-#include "asan_test_utils.h"
-
-#if defined(__linux__) && \
- (!defined(ASAN_SHADOW_SCALE) || ASAN_SHADOW_SCALE == 3)
-
-// Assembly instrumentation is broken on x86 Android (x86 + PIC + shared runtime
-// library). See https://github.com/google/sanitizers/issues/353
-#if defined(__x86_64__) || \
- (defined(__i386__) && defined(__SSE2__) && !defined(__ANDROID__))
-
-#include <emmintrin.h>
-
-namespace {
-
-template<typename T> void asm_write(T *ptr, T val);
-template<typename T> T asm_read(T *ptr);
-template<typename T> void asm_rep_movs(T *dst, T *src, size_t n);
-
-} // End of anonymous namespace
-
-#endif // defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__))
-
-#if defined(__x86_64__)
-
-namespace {
-
-#define DECLARE_ASM_WRITE(Type, Size, Mov, Reg) \
-template<> void asm_write<Type>(Type *ptr, Type val) { \
- __asm__( \
- Mov " %[val], (%[ptr]) \n\t" \
- : \
- : [ptr] "r" (ptr), [val] Reg (val) \
- : "memory" \
- ); \
-}
-
-#define DECLARE_ASM_READ(Type, Size, Mov, Reg) \
-template<> Type asm_read<Type>(Type *ptr) { \
- Type res; \
- __asm__( \
- Mov " (%[ptr]), %[res] \n\t" \
- : [res] Reg (res) \
- : [ptr] "r" (ptr) \
- : "memory" \
- ); \
- return res; \
-}
-
-#define DECLARE_ASM_REP_MOVS(Type, Movs) \
- template <> \
- void asm_rep_movs<Type>(Type * dst, Type * src, size_t size) { \
- __asm__("rep " Movs " \n\t" \
- : "+D"(dst), "+S"(src), "+c"(size) \
- : \
- : "memory"); \
- }
-
-DECLARE_ASM_WRITE(U8, "8", "movq", "r");
-DECLARE_ASM_READ(U8, "8", "movq", "=r");
-DECLARE_ASM_REP_MOVS(U8, "movsq");
-
-} // End of anonymous namespace
-
-#endif // defined(__x86_64__)
-
-#if defined(__i386__) && defined(__SSE2__) && !defined(__ANDROID__)
-
-namespace {
-
-#define DECLARE_ASM_WRITE(Type, Size, Mov, Reg) \
-template<> void asm_write<Type>(Type *ptr, Type val) { \
- __asm__( \
- Mov " %[val], (%[ptr]) \n\t" \
- : \
- : [ptr] "r" (ptr), [val] Reg (val) \
- : "memory" \
- ); \
-}
-
-#define DECLARE_ASM_READ(Type, Size, Mov, Reg) \
-template<> Type asm_read<Type>(Type *ptr) { \
- Type res; \
- __asm__( \
- Mov " (%[ptr]), %[res] \n\t" \
- : [res] Reg (res) \
- : [ptr] "r" (ptr) \
- : "memory" \
- ); \
- return res; \
-}
-
-#define DECLARE_ASM_REP_MOVS(Type, Movs) \
- template <> \
- void asm_rep_movs<Type>(Type * dst, Type * src, size_t size) { \
- __asm__("rep " Movs " \n\t" \
- : "+D"(dst), "+S"(src), "+c"(size) \
- : \
- : "memory"); \
- }
-
-} // End of anonymous namespace
-
-#endif // defined(__i386__) && defined(__SSE2__)
-
-#if defined(__x86_64__) || \
- (defined(__i386__) && defined(__SSE2__) && !defined(__ANDROID__))
-
-namespace {
-
-DECLARE_ASM_WRITE(U1, "1", "movb", "r");
-DECLARE_ASM_WRITE(U2, "2", "movw", "r");
-DECLARE_ASM_WRITE(U4, "4", "movl", "r");
-DECLARE_ASM_WRITE(__m128i, "16", "movaps", "x");
-
-DECLARE_ASM_READ(U1, "1", "movb", "=r");
-DECLARE_ASM_READ(U2, "2", "movw", "=r");
-DECLARE_ASM_READ(U4, "4", "movl", "=r");
-DECLARE_ASM_READ(__m128i, "16", "movaps", "=x");
-
-DECLARE_ASM_REP_MOVS(U1, "movsb");
-DECLARE_ASM_REP_MOVS(U2, "movsw");
-DECLARE_ASM_REP_MOVS(U4, "movsl");
-
-template<typename T> void TestAsmWrite(const char *DeathPattern) {
- T *buf = new T;
- EXPECT_DEATH(asm_write(&buf[1], static_cast<T>(0)), DeathPattern);
- T var = 0x12;
- asm_write(&var, static_cast<T>(0x21));
- ASSERT_EQ(static_cast<T>(0x21), var);
- delete buf;
-}
-
-template<> void TestAsmWrite<__m128i>(const char *DeathPattern) {
- char *buf = new char[16];
- char *p = buf + 16;
- if (((uintptr_t) p % 16) != 0)
- p = buf + 8;
- assert(((uintptr_t) p % 16) == 0);
- __m128i val = _mm_set1_epi16(0x1234);
- EXPECT_DEATH(asm_write<__m128i>((__m128i*) p, val), DeathPattern);
- __m128i var = _mm_set1_epi16(0x4321);
- asm_write(&var, val);
- ASSERT_EQ(0x1234, _mm_extract_epi16(var, 0));
- delete [] buf;
-}
-
-template<typename T> void TestAsmRead(const char *DeathPattern) {
- T *buf = new T;
- EXPECT_DEATH(asm_read(&buf[1]), DeathPattern);
- T var = 0x12;
- ASSERT_EQ(static_cast<T>(0x12), asm_read(&var));
- delete buf;
-}
-
-template<> void TestAsmRead<__m128i>(const char *DeathPattern) {
- char *buf = new char[16];
- char *p = buf + 16;
- if (((uintptr_t) p % 16) != 0)
- p = buf + 8;
- assert(((uintptr_t) p % 16) == 0);
- EXPECT_DEATH(asm_read<__m128i>((__m128i*) p), DeathPattern);
- __m128i val = _mm_set1_epi16(0x1234);
- ASSERT_EQ(0x1234, _mm_extract_epi16(asm_read(&val), 0));
- delete [] buf;
-}
-
-U4 AsmLoad(U4 *a) {
- U4 r;
- __asm__("movl (%[a]), %[r] \n\t" : [r] "=r" (r) : [a] "r" (a) : "memory");
- return r;
-}
-
-void AsmStore(U4 r, U4 *a) {
- __asm__("movl %[r], (%[a]) \n\t" : : [a] "r" (a), [r] "r" (r) : "memory");
-}
-
-template <typename T>
-void TestAsmRepMovs(const char *DeathPatternRead,
- const char *DeathPatternWrite) {
- T src_good[4] = { 0x0, 0x1, 0x2, 0x3 };
- T dst_good[4] = {};
- asm_rep_movs(dst_good, src_good, 4);
- ASSERT_EQ(static_cast<T>(0x0), dst_good[0]);
- ASSERT_EQ(static_cast<T>(0x1), dst_good[1]);
- ASSERT_EQ(static_cast<T>(0x2), dst_good[2]);
- ASSERT_EQ(static_cast<T>(0x3), dst_good[3]);
-
- T dst_bad[3];
- EXPECT_DEATH(asm_rep_movs(dst_bad, src_good, 4), DeathPatternWrite);
-
- T src_bad[3] = { 0x0, 0x1, 0x2 };
- EXPECT_DEATH(asm_rep_movs(dst_good, src_bad, 4), DeathPatternRead);
-
- T* dp = dst_bad + 4;
- T* sp = src_bad + 4;
- asm_rep_movs(dp, sp, 0);
-}
-
-} // End of anonymous namespace
-
-TEST(AddressSanitizer, asm_load_store) {
- U4* buf = new U4[2];
- EXPECT_DEATH(AsmLoad(&buf[3]), "READ of size 4");
- EXPECT_DEATH(AsmStore(0x1234, &buf[3]), "WRITE of size 4");
- delete [] buf;
-}
-
-TEST(AddressSanitizer, asm_rw) {
- TestAsmWrite<U1>("WRITE of size 1");
- TestAsmWrite<U2>("WRITE of size 2");
- TestAsmWrite<U4>("WRITE of size 4");
-#if defined(__x86_64__)
- TestAsmWrite<U8>("WRITE of size 8");
-#endif // defined(__x86_64__)
- TestAsmWrite<__m128i>("WRITE of size 16");
-
- TestAsmRead<U1>("READ of size 1");
- TestAsmRead<U2>("READ of size 2");
- TestAsmRead<U4>("READ of size 4");
-#if defined(__x86_64__)
- TestAsmRead<U8>("READ of size 8");
-#endif // defined(__x86_64__)
- TestAsmRead<__m128i>("READ of size 16");
-}
-
-TEST(AddressSanitizer, asm_flags) {
- long magic = 0x1234;
- long r = 0x0;
-
-#if defined(__x86_64__) && !defined(__ILP32__)
- __asm__("xorq %%rax, %%rax \n\t"
- "movq (%[p]), %%rax \n\t"
- "sete %%al \n\t"
- "movzbq %%al, %[r] \n\t"
- : [r] "=r"(r)
- : [p] "r"(&magic)
- : "rax", "memory");
-#else
- __asm__("xorl %%eax, %%eax \n\t"
- "movl (%[p]), %%eax \n\t"
- "sete %%al \n\t"
- "movzbl %%al, %[r] \n\t"
- : [r] "=r"(r)
- : [p] "r"(&magic)
- : "eax", "memory");
-#endif // defined(__x86_64__) && !defined(__ILP32__)
-
- ASSERT_EQ(0x1, r);
-}
-
-TEST(AddressSanitizer, asm_rep_movs) {
- TestAsmRepMovs<U1>("READ of size 1", "WRITE of size 1");
- TestAsmRepMovs<U2>("READ of size 2", "WRITE of size 2");
- TestAsmRepMovs<U4>("READ of size 4", "WRITE of size 4");
-#if defined(__x86_64__)
- TestAsmRepMovs<U8>("READ of size 8", "WRITE of size 8");
-#endif // defined(__x86_64__)
-}
-
-#endif // defined(__x86_64__) || (defined(__i386__) && defined(__SSE2__))
-
-#endif // defined(__linux__)
diff --git a/lib/asan/tests/asan_benchmarks_test.cc b/lib/asan/tests/asan_benchmarks_test.cc
deleted file mode 100644
index fc522de475faa..0000000000000
--- a/lib/asan/tests/asan_benchmarks_test.cc
+++ /dev/null
@@ -1,85 +0,0 @@
-//===-- asan_benchmarks_test.cc ----------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-// Some benchmarks for the instrumented code.
-//===----------------------------------------------------------------------===//
-
-#include "asan_test_utils.h"
-
-template<class T>
-__attribute__((noinline))
-static void ManyAccessFunc(T *x, size_t n_elements, size_t n_iter) {
- for (size_t iter = 0; iter < n_iter; iter++) {
- break_optimization(0);
- // hand unroll the loop to stress the reg alloc.
- for (size_t i = 0; i <= n_elements - 16; i += 16) {
- x[i + 0] = i;
- x[i + 1] = i;
- x[i + 2] = i;
- x[i + 3] = i;
- x[i + 4] = i;
- x[i + 5] = i;
- x[i + 6] = i;
- x[i + 7] = i;
- x[i + 8] = i;
- x[i + 9] = i;
- x[i + 10] = i;
- x[i + 11] = i;
- x[i + 12] = i;
- x[i + 13] = i;
- x[i + 14] = i;
- x[i + 15] = i;
- }
- }
-}
-
-TEST(AddressSanitizer, ManyAccessBenchmark) {
- size_t kLen = 1024;
- int *int_array = new int[kLen];
- ManyAccessFunc(int_array, kLen, 1 << 24);
- delete [] int_array;
-}
-
-// access 7 char elements in a 7 byte array (i.e. on the border).
-__attribute__((noinline))
-static void BorderAccessFunc(char *x, size_t n_iter) {
- for (size_t iter = 0; iter < n_iter; iter++) {
- break_optimization(x);
- x[0] = 0;
- x[1] = 0;
- x[2] = 0;
- x[3] = 0;
- x[4] = 0;
- x[5] = 0;
- x[6] = 0;
- }
-}
-
-TEST(AddressSanitizer, BorderAccessBenchmark) {
- char *char_7_array = new char[7];
- BorderAccessFunc(char_7_array, 1 << 30);
- delete [] char_7_array;
-}
-
-static void FunctionWithLargeStack() {
- int stack[1000];
- Ident(stack);
-}
-
-TEST(AddressSanitizer, FakeStackBenchmark) {
- for (int i = 0; i < 10000000; i++)
- Ident(&FunctionWithLargeStack)();
-}
-
-int main(int argc, char **argv) {
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/lib/asan/tests/asan_exceptions_test.cc b/lib/asan/tests/asan_exceptions_test.cc
deleted file mode 100644
index ecd406de7561f..0000000000000
--- a/lib/asan/tests/asan_exceptions_test.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-// See http://llvm.org/bugs/show_bug.cgi?id=11468
-#include <stdio.h>
-#include <string>
-
-class Action {
- public:
- Action() {}
- void PrintString(const std::string& msg) const {
- fprintf(stderr, "%s\n", msg.c_str());
- }
- void Throw(const char& arg) const {
- PrintString("PrintString called!"); // this line is important
- throw arg;
- }
-};
-
-int main() {
- const Action a;
- fprintf(stderr, "&a before = %p\n", &a);
- try {
- a.Throw('c');
- } catch(const char&) {
- fprintf(stderr, "&a in catch = %p\n", &a);
- }
- fprintf(stderr, "&a final = %p\n", &a);
- return 0;
-}
diff --git a/lib/asan/tests/asan_fake_stack_test.cc b/lib/asan/tests/asan_fake_stack_test.cc
deleted file mode 100644
index 516142f0c3b73..0000000000000
--- a/lib/asan/tests/asan_fake_stack_test.cc
+++ /dev/null
@@ -1,152 +0,0 @@
-//===-- asan_fake_stack_test.cc -------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-// Tests for FakeStack.
-// This test file should be compiled w/o asan instrumentation.
-//===----------------------------------------------------------------------===//
-
-#include "asan_fake_stack.h"
-#include "asan_test_utils.h"
-#include "sanitizer_common/sanitizer_common.h"
-
-#include <assert.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-#include <map>
-
-namespace __asan {
-
-TEST(FakeStack, FlagsSize) {
- EXPECT_EQ(FakeStack::SizeRequiredForFlags(10), 1U << 5);
- EXPECT_EQ(FakeStack::SizeRequiredForFlags(11), 1U << 6);
- EXPECT_EQ(FakeStack::SizeRequiredForFlags(20), 1U << 15);
-}
-
-TEST(FakeStack, RequiredSize) {
- // for (int i = 15; i < 20; i++) {
- // uptr alloc_size = FakeStack::RequiredSize(i);
- // printf("%zdK ==> %zd\n", 1 << (i - 10), alloc_size);
- // }
- EXPECT_EQ(FakeStack::RequiredSize(15), 365568U);
- EXPECT_EQ(FakeStack::RequiredSize(16), 727040U);
- EXPECT_EQ(FakeStack::RequiredSize(17), 1449984U);
- EXPECT_EQ(FakeStack::RequiredSize(18), 2895872U);
- EXPECT_EQ(FakeStack::RequiredSize(19), 5787648U);
-}
-
-TEST(FakeStack, FlagsOffset) {
- for (uptr stack_size_log = 15; stack_size_log <= 20; stack_size_log++) {
- uptr stack_size = 1UL << stack_size_log;
- uptr offset = 0;
- for (uptr class_id = 0; class_id < FakeStack::kNumberOfSizeClasses;
- class_id++) {
- uptr frame_size = FakeStack::BytesInSizeClass(class_id);
- uptr num_flags = stack_size / frame_size;
- EXPECT_EQ(offset, FakeStack::FlagsOffset(stack_size_log, class_id));
- // printf("%zd: %zd => %zd %zd\n", stack_size_log, class_id, offset,
- // FakeStack::FlagsOffset(stack_size_log, class_id));
- offset += num_flags;
- }
- }
-}
-
-#if !defined(_WIN32) // FIXME: Fails due to OOM on Windows.
-TEST(FakeStack, CreateDestroy) {
- for (int i = 0; i < 1000; i++) {
- for (uptr stack_size_log = 20; stack_size_log <= 22; stack_size_log++) {
- FakeStack *fake_stack = FakeStack::Create(stack_size_log);
- fake_stack->Destroy(0);
- }
- }
-}
-#endif
-
-TEST(FakeStack, ModuloNumberOfFrames) {
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, 0), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, (1<<15)), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, (1<<10)), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, (1<<9)), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, (1<<8)), 1U<<8);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 0, (1<<15) + 1), 1U);
-
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 1, 0), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 1, 1<<9), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 1, 1<<8), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 1, 1<<7), 1U<<7);
-
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 5, 0), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 5, 1), 1U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 5, 15), 15U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 5, 16), 0U);
- EXPECT_EQ(FakeStack::ModuloNumberOfFrames(15, 5, 17), 1U);
-}
-
-TEST(FakeStack, GetFrame) {
- const uptr stack_size_log = 20;
- const uptr stack_size = 1 << stack_size_log;
- FakeStack *fs = FakeStack::Create(stack_size_log);
- u8 *base = fs->GetFrame(stack_size_log, 0, 0);
- EXPECT_EQ(base, reinterpret_cast<u8 *>(fs) +
- fs->SizeRequiredForFlags(stack_size_log) + 4096);
- EXPECT_EQ(base + 0*stack_size + 64 * 7, fs->GetFrame(stack_size_log, 0, 7U));
- EXPECT_EQ(base + 1*stack_size + 128 * 3, fs->GetFrame(stack_size_log, 1, 3U));
- EXPECT_EQ(base + 2*stack_size + 256 * 5, fs->GetFrame(stack_size_log, 2, 5U));
- fs->Destroy(0);
-}
-
-TEST(FakeStack, Allocate) {
- const uptr stack_size_log = 19;
- FakeStack *fs = FakeStack::Create(stack_size_log);
- std::map<FakeFrame *, uptr> s;
- for (int iter = 0; iter < 2; iter++) {
- s.clear();
- for (uptr cid = 0; cid < FakeStack::kNumberOfSizeClasses; cid++) {
- uptr n = FakeStack::NumberOfFrames(stack_size_log, cid);
- uptr bytes_in_class = FakeStack::BytesInSizeClass(cid);
- for (uptr j = 0; j < n; j++) {
- FakeFrame *ff = fs->Allocate(stack_size_log, cid, 0);
- uptr x = reinterpret_cast<uptr>(ff);
- EXPECT_TRUE(s.insert(std::make_pair(ff, cid)).second);
- EXPECT_EQ(x, fs->AddrIsInFakeStack(x));
- EXPECT_EQ(x, fs->AddrIsInFakeStack(x + 1));
- EXPECT_EQ(x, fs->AddrIsInFakeStack(x + bytes_in_class - 1));
- EXPECT_NE(x, fs->AddrIsInFakeStack(x + bytes_in_class));
- }
- // We are out of fake stack, so Allocate should return 0.
- EXPECT_EQ(0UL, fs->Allocate(stack_size_log, cid, 0));
- }
- for (std::map<FakeFrame *, uptr>::iterator it = s.begin(); it != s.end();
- ++it) {
- fs->Deallocate(reinterpret_cast<uptr>(it->first), it->second);
- }
- }
- fs->Destroy(0);
-}
-
-static void RecursiveFunction(FakeStack *fs, int depth) {
- uptr class_id = depth / 3;
- FakeFrame *ff = fs->Allocate(fs->stack_size_log(), class_id, 0);
- if (depth) {
- RecursiveFunction(fs, depth - 1);
- RecursiveFunction(fs, depth - 1);
- }
- fs->Deallocate(reinterpret_cast<uptr>(ff), class_id);
-}
-
-TEST(FakeStack, RecursiveStressTest) {
- const uptr stack_size_log = 16;
- FakeStack *fs = FakeStack::Create(stack_size_log);
- RecursiveFunction(fs, 22); // with 26 runs for 2-3 seconds.
- fs->Destroy(0);
-}
-
-} // namespace __asan
diff --git a/lib/asan/tests/asan_globals_test.cc b/lib/asan/tests/asan_globals_test.cc
deleted file mode 100644
index 5042ef07378d3..0000000000000
--- a/lib/asan/tests/asan_globals_test.cc
+++ /dev/null
@@ -1,45 +0,0 @@
-//===-- asan_globals_test.cc ----------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-// Some globals in a separate file.
-//===----------------------------------------------------------------------===//
-#include "asan_test_utils.h"
-
-char glob1[1];
-char glob2[2];
-char glob3[3];
-char glob4[4];
-char glob5[5];
-char glob6[6];
-char glob7[7];
-char glob8[8];
-char glob9[9];
-char glob10[10];
-char glob11[11];
-char glob12[12];
-char glob13[13];
-char glob14[14];
-char glob15[15];
-char glob16[16];
-char glob17[17];
-char glob1000[1000];
-char glob10000[10000];
-char glob100000[100000];
-
-static char static10[10];
-
-int GlobalsTest(int zero) {
- static char func_static15[15];
- glob5[zero] = 0;
- static10[zero] = 0;
- func_static15[zero] = 0;
- return glob5[1] + func_static15[2];
-}
diff --git a/lib/asan/tests/asan_interface_test.cc b/lib/asan/tests/asan_interface_test.cc
deleted file mode 100644
index b5c8303cb84b4..0000000000000
--- a/lib/asan/tests/asan_interface_test.cc
+++ /dev/null
@@ -1,422 +0,0 @@
-//===-- asan_interface_test.cc --------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-//===----------------------------------------------------------------------===//
-#include "asan_test_utils.h"
-#include "sanitizer_common/sanitizer_internal_defs.h"
-#include <sanitizer/allocator_interface.h>
-#include <sanitizer/asan_interface.h>
-#include <vector>
-
-TEST(AddressSanitizerInterface, GetEstimatedAllocatedSize) {
- EXPECT_EQ(0U, __sanitizer_get_estimated_allocated_size(0));
- const size_t sizes[] = { 1, 30, 1<<30 };
- for (size_t i = 0; i < 3; i++) {
- EXPECT_EQ(sizes[i], __sanitizer_get_estimated_allocated_size(sizes[i]));
- }
-}
-
-static const char* kGetAllocatedSizeErrorMsg =
- "attempting to call __sanitizer_get_allocated_size";
-
-TEST(AddressSanitizerInterface, GetAllocatedSizeAndOwnershipTest) {
- const size_t kArraySize = 100;
- char *array = Ident((char*)malloc(kArraySize));
- int *int_ptr = Ident(new int);
-
- // Allocated memory is owned by allocator. Allocated size should be
- // equal to requested size.
- EXPECT_EQ(true, __sanitizer_get_ownership(array));
- EXPECT_EQ(kArraySize, __sanitizer_get_allocated_size(array));
- EXPECT_EQ(true, __sanitizer_get_ownership(int_ptr));
- EXPECT_EQ(sizeof(int), __sanitizer_get_allocated_size(int_ptr));
-
- // We cannot call GetAllocatedSize from the memory we didn't map,
- // and from the interior pointers (not returned by previous malloc).
- void *wild_addr = (void*)0x1;
- EXPECT_FALSE(__sanitizer_get_ownership(wild_addr));
- EXPECT_DEATH(__sanitizer_get_allocated_size(wild_addr),
- kGetAllocatedSizeErrorMsg);
- EXPECT_FALSE(__sanitizer_get_ownership(array + kArraySize / 2));
- EXPECT_DEATH(__sanitizer_get_allocated_size(array + kArraySize / 2),
- kGetAllocatedSizeErrorMsg);
-
- // NULL is not owned, but is a valid argument for
- // __sanitizer_get_allocated_size().
- EXPECT_FALSE(__sanitizer_get_ownership(NULL));
- EXPECT_EQ(0U, __sanitizer_get_allocated_size(NULL));
-
- // When memory is freed, it's not owned, and call to GetAllocatedSize
- // is forbidden.
- free(array);
- EXPECT_FALSE(__sanitizer_get_ownership(array));
- EXPECT_DEATH(__sanitizer_get_allocated_size(array),
- kGetAllocatedSizeErrorMsg);
- delete int_ptr;
-
- void *zero_alloc = Ident(malloc(0));
- if (zero_alloc != 0) {
- // If malloc(0) is not null, this pointer is owned and should have valid
- // allocated size.
- EXPECT_TRUE(__sanitizer_get_ownership(zero_alloc));
- // Allocated size is 0 or 1 depending on the allocator used.
- EXPECT_LT(__sanitizer_get_allocated_size(zero_alloc), 2U);
- }
- free(zero_alloc);
-}
-
-TEST(AddressSanitizerInterface, GetCurrentAllocatedBytesTest) {
- size_t before_malloc, after_malloc, after_free;
- char *array;
- const size_t kMallocSize = 100;
- before_malloc = __sanitizer_get_current_allocated_bytes();
-
- array = Ident((char*)malloc(kMallocSize));
- after_malloc = __sanitizer_get_current_allocated_bytes();
- EXPECT_EQ(before_malloc + kMallocSize, after_malloc);
-
- free(array);
- after_free = __sanitizer_get_current_allocated_bytes();
- EXPECT_EQ(before_malloc, after_free);
-}
-
-TEST(AddressSanitizerInterface, GetHeapSizeTest) {
- // ASan allocator does not keep huge chunks in free list, but unmaps them.
- // The chunk should be greater than the quarantine size,
- // otherwise it will be stuck in quarantine instead of being unmaped.
- static const size_t kLargeMallocSize = (1 << 28) + 1; // 256M
- free(Ident(malloc(kLargeMallocSize))); // Drain quarantine.
- size_t old_heap_size = __sanitizer_get_heap_size();
- for (int i = 0; i < 3; i++) {
- // fprintf(stderr, "allocating %zu bytes:\n", kLargeMallocSize);
- free(Ident(malloc(kLargeMallocSize)));
- EXPECT_EQ(old_heap_size, __sanitizer_get_heap_size());
- }
-}
-
-#if !defined(__NetBSD__)
-static const size_t kManyThreadsMallocSizes[] = {5, 1UL<<10, 1UL<<14, 357};
-static const size_t kManyThreadsIterations = 250;
-static const size_t kManyThreadsNumThreads =
- (SANITIZER_WORDSIZE == 32) ? 40 : 200;
-
-static void *ManyThreadsWithStatsWorker(void *arg) {
- (void)arg;
- for (size_t iter = 0; iter < kManyThreadsIterations; iter++) {
- for (size_t size_index = 0; size_index < 4; size_index++) {
- free(Ident(malloc(kManyThreadsMallocSizes[size_index])));
- }
- }
- // Just one large allocation.
- free(Ident(malloc(1 << 20)));
- return 0;
-}
-
-TEST(AddressSanitizerInterface, ManyThreadsWithStatsStressTest) {
- size_t before_test, after_test, i;
- pthread_t threads[kManyThreadsNumThreads];
- before_test = __sanitizer_get_current_allocated_bytes();
- for (i = 0; i < kManyThreadsNumThreads; i++) {
- PTHREAD_CREATE(&threads[i], 0,
- (void* (*)(void *x))ManyThreadsWithStatsWorker, (void*)i);
- }
- for (i = 0; i < kManyThreadsNumThreads; i++) {
- PTHREAD_JOIN(threads[i], 0);
- }
- after_test = __sanitizer_get_current_allocated_bytes();
- // ASan stats also reflect memory usage of internal ASan RTL structs,
- // so we can't check for equality here.
- EXPECT_LT(after_test, before_test + (1UL<<20));
-}
-#endif
-
-static void DoDoubleFree() {
- int *x = Ident(new int);
- delete Ident(x);
- delete Ident(x);
-}
-
-static void MyDeathCallback() {
- fprintf(stderr, "MyDeathCallback\n");
- fflush(0); // On Windows, stderr doesn't flush on crash.
-}
-
-TEST(AddressSanitizerInterface, DeathCallbackTest) {
- __asan_set_death_callback(MyDeathCallback);
- EXPECT_DEATH(DoDoubleFree(), "MyDeathCallback");
- __asan_set_death_callback(NULL);
-}
-
-#define GOOD_ACCESS(ptr, offset) \
- EXPECT_FALSE(__asan_address_is_poisoned(ptr + offset))
-
-#define BAD_ACCESS(ptr, offset) \
- EXPECT_TRUE(__asan_address_is_poisoned(ptr + offset))
-
-#if !defined(ASAN_SHADOW_SCALE) || ASAN_SHADOW_SCALE == 3
-static const char* kUseAfterPoisonErrorMessage = "use-after-poison";
-
-TEST(AddressSanitizerInterface, SimplePoisonMemoryRegionTest) {
- char *array = Ident((char*)malloc(120));
- // poison array[40..80)
- __asan_poison_memory_region(array + 40, 40);
- GOOD_ACCESS(array, 39);
- GOOD_ACCESS(array, 80);
- BAD_ACCESS(array, 40);
- BAD_ACCESS(array, 60);
- BAD_ACCESS(array, 79);
- char value;
- EXPECT_DEATH(value = Ident(array[40]), kUseAfterPoisonErrorMessage);
- __asan_unpoison_memory_region(array + 40, 40);
- // access previously poisoned memory.
- GOOD_ACCESS(array, 40);
- GOOD_ACCESS(array, 79);
- free(array);
-}
-
-TEST(AddressSanitizerInterface, OverlappingPoisonMemoryRegionTest) {
- char *array = Ident((char*)malloc(120));
- // Poison [0..40) and [80..120)
- __asan_poison_memory_region(array, 40);
- __asan_poison_memory_region(array + 80, 40);
- BAD_ACCESS(array, 20);
- GOOD_ACCESS(array, 60);
- BAD_ACCESS(array, 100);
- // Poison whole array - [0..120)
- __asan_poison_memory_region(array, 120);
- BAD_ACCESS(array, 60);
- // Unpoison [24..96)
- __asan_unpoison_memory_region(array + 24, 72);
- BAD_ACCESS(array, 23);
- GOOD_ACCESS(array, 24);
- GOOD_ACCESS(array, 60);
- GOOD_ACCESS(array, 95);
- BAD_ACCESS(array, 96);
- free(array);
-}
-#endif // !defined(ASAN_SHADOW_SCALE) || ASAN_SHADOW_SCALE == 3
-
-TEST(AddressSanitizerInterface, PushAndPopWithPoisoningTest) {
- // Vector of capacity 20
- char *vec = Ident((char*)malloc(20));
- __asan_poison_memory_region(vec, 20);
- for (size_t i = 0; i < 7; i++) {
- // Simulate push_back.
- __asan_unpoison_memory_region(vec + i, 1);
- GOOD_ACCESS(vec, i);
- BAD_ACCESS(vec, i + 1);
- }
- for (size_t i = 7; i > 0; i--) {
- // Simulate pop_back.
- __asan_poison_memory_region(vec + i - 1, 1);
- BAD_ACCESS(vec, i - 1);
- if (i > 1) GOOD_ACCESS(vec, i - 2);
- }
- free(vec);
-}
-
-#if !defined(ASAN_SHADOW_SCALE) || ASAN_SHADOW_SCALE == 3
-// Make sure that each aligned block of size "2^granularity" doesn't have
-// "true" value before "false" value.
-static void MakeShadowValid(bool *shadow, int length, int granularity) {
- bool can_be_poisoned = true;
- for (int i = length - 1; i >= 0; i--) {
- if (!shadow[i])
- can_be_poisoned = false;
- if (!can_be_poisoned)
- shadow[i] = false;
- if (i % (1 << granularity) == 0) {
- can_be_poisoned = true;
- }
- }
-}
-
-TEST(AddressSanitizerInterface, PoisoningStressTest) {
- const size_t kSize = 24;
- bool expected[kSize];
- char *arr = Ident((char*)malloc(kSize));
- for (size_t l1 = 0; l1 < kSize; l1++) {
- for (size_t s1 = 1; l1 + s1 <= kSize; s1++) {
- for (size_t l2 = 0; l2 < kSize; l2++) {
- for (size_t s2 = 1; l2 + s2 <= kSize; s2++) {
- // Poison [l1, l1+s1), [l2, l2+s2) and check result.
- __asan_unpoison_memory_region(arr, kSize);
- __asan_poison_memory_region(arr + l1, s1);
- __asan_poison_memory_region(arr + l2, s2);
- memset(expected, false, kSize);
- memset(expected + l1, true, s1);
- MakeShadowValid(expected, kSize, /*granularity*/ 3);
- memset(expected + l2, true, s2);
- MakeShadowValid(expected, kSize, /*granularity*/ 3);
- for (size_t i = 0; i < kSize; i++) {
- ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));
- }
- // Unpoison [l1, l1+s1) and [l2, l2+s2) and check result.
- __asan_poison_memory_region(arr, kSize);
- __asan_unpoison_memory_region(arr + l1, s1);
- __asan_unpoison_memory_region(arr + l2, s2);
- memset(expected, true, kSize);
- memset(expected + l1, false, s1);
- MakeShadowValid(expected, kSize, /*granularity*/ 3);
- memset(expected + l2, false, s2);
- MakeShadowValid(expected, kSize, /*granularity*/ 3);
- for (size_t i = 0; i < kSize; i++) {
- ASSERT_EQ(expected[i], __asan_address_is_poisoned(arr + i));
- }
- }
- }
- }
- }
- free(arr);
-}
-#endif // !defined(ASAN_SHADOW_SCALE) || ASAN_SHADOW_SCALE == 3
-
-TEST(AddressSanitizerInterface, GlobalRedzones) {
- GOOD_ACCESS(glob1, 1 - 1);
- GOOD_ACCESS(glob2, 2 - 1);
- GOOD_ACCESS(glob3, 3 - 1);
- GOOD_ACCESS(glob4, 4 - 1);
- GOOD_ACCESS(glob5, 5 - 1);
- GOOD_ACCESS(glob6, 6 - 1);
- GOOD_ACCESS(glob7, 7 - 1);
- GOOD_ACCESS(glob8, 8 - 1);
- GOOD_ACCESS(glob9, 9 - 1);
- GOOD_ACCESS(glob10, 10 - 1);
- GOOD_ACCESS(glob11, 11 - 1);
- GOOD_ACCESS(glob12, 12 - 1);
- GOOD_ACCESS(glob13, 13 - 1);
- GOOD_ACCESS(glob14, 14 - 1);
- GOOD_ACCESS(glob15, 15 - 1);
- GOOD_ACCESS(glob16, 16 - 1);
- GOOD_ACCESS(glob17, 17 - 1);
- GOOD_ACCESS(glob1000, 1000 - 1);
- GOOD_ACCESS(glob10000, 10000 - 1);
- GOOD_ACCESS(glob100000, 100000 - 1);
-
- BAD_ACCESS(glob1, 1);
- BAD_ACCESS(glob2, 2);
- BAD_ACCESS(glob3, 3);
- BAD_ACCESS(glob4, 4);
- BAD_ACCESS(glob5, 5);
- BAD_ACCESS(glob6, 6);
- BAD_ACCESS(glob7, 7);
- BAD_ACCESS(glob8, 8);
- BAD_ACCESS(glob9, 9);
- BAD_ACCESS(glob10, 10);
- BAD_ACCESS(glob11, 11);
- BAD_ACCESS(glob12, 12);
- BAD_ACCESS(glob13, 13);
- BAD_ACCESS(glob14, 14);
- BAD_ACCESS(glob15, 15);
- BAD_ACCESS(glob16, 16);
- BAD_ACCESS(glob17, 17);
- BAD_ACCESS(glob1000, 1000);
- BAD_ACCESS(glob1000, 1100); // Redzone is at least 101 bytes.
- BAD_ACCESS(glob10000, 10000);
- BAD_ACCESS(glob10000, 11000); // Redzone is at least 1001 bytes.
- BAD_ACCESS(glob100000, 100000);
- BAD_ACCESS(glob100000, 110000); // Redzone is at least 10001 bytes.
-}
-
-TEST(AddressSanitizerInterface, PoisonedRegion) {
- size_t rz = 16;
- for (size_t size = 1; size <= 64; size++) {
- char *p = new char[size];
- for (size_t beg = 0; beg < size + rz; beg++) {
- for (size_t end = beg; end < size + rz; end++) {
- void *first_poisoned = __asan_region_is_poisoned(p + beg, end - beg);
- if (beg == end) {
- EXPECT_FALSE(first_poisoned);
- } else if (beg < size && end <= size) {
- EXPECT_FALSE(first_poisoned);
- } else if (beg >= size) {
- EXPECT_EQ(p + beg, first_poisoned);
- } else {
- EXPECT_GT(end, size);
- EXPECT_EQ(p + size, first_poisoned);
- }
- }
- }
- delete [] p;
- }
-}
-
-// This is a performance benchmark for manual runs.
-// asan's memset interceptor calls mem_is_zero for the entire shadow region.
-// the profile should look like this:
-// 89.10% [.] __memset_sse2
-// 10.50% [.] __sanitizer::mem_is_zero
-// I.e. mem_is_zero should consume ~ SHADOW_GRANULARITY less CPU cycles
-// than memset itself.
-TEST(AddressSanitizerInterface, DISABLED_StressLargeMemset) {
- size_t size = 1 << 20;
- char *x = new char[size];
- for (int i = 0; i < 100000; i++)
- Ident(memset)(x, 0, size);
- delete [] x;
-}
-
-// Same here, but we run memset with small sizes.
-TEST(AddressSanitizerInterface, DISABLED_StressSmallMemset) {
- size_t size = 32;
- char *x = new char[size];
- for (int i = 0; i < 100000000; i++)
- Ident(memset)(x, 0, size);
- delete [] x;
-}
-static const char *kInvalidPoisonMessage = "invalid-poison-memory-range";
-static const char *kInvalidUnpoisonMessage = "invalid-unpoison-memory-range";
-
-TEST(AddressSanitizerInterface, DISABLED_InvalidPoisonAndUnpoisonCallsTest) {
- char *array = Ident((char*)malloc(120));
- __asan_unpoison_memory_region(array, 120);
- // Try to unpoison not owned memory
- EXPECT_DEATH(__asan_unpoison_memory_region(array, 121),
- kInvalidUnpoisonMessage);
- EXPECT_DEATH(__asan_unpoison_memory_region(array - 1, 120),
- kInvalidUnpoisonMessage);
-
- __asan_poison_memory_region(array, 120);
- // Try to poison not owned memory.
- EXPECT_DEATH(__asan_poison_memory_region(array, 121), kInvalidPoisonMessage);
- EXPECT_DEATH(__asan_poison_memory_region(array - 1, 120),
- kInvalidPoisonMessage);
- free(array);
-}
-
-TEST(AddressSanitizerInterface, GetOwnershipStressTest) {
- std::vector<char *> pointers;
- std::vector<size_t> sizes;
- const size_t kNumMallocs = 1 << 9;
- for (size_t i = 0; i < kNumMallocs; i++) {
- size_t size = i * 100 + 1;
- pointers.push_back((char*)malloc(size));
- sizes.push_back(size);
- }
- for (size_t i = 0; i < 4000000; i++) {
- EXPECT_FALSE(__sanitizer_get_ownership(&pointers));
- EXPECT_FALSE(__sanitizer_get_ownership((void*)0x1234));
- size_t idx = i % kNumMallocs;
- EXPECT_TRUE(__sanitizer_get_ownership(pointers[idx]));
- EXPECT_EQ(sizes[idx], __sanitizer_get_allocated_size(pointers[idx]));
- }
- for (size_t i = 0, n = pointers.size(); i < n; i++)
- free(pointers[i]);
-}
-
-TEST(AddressSanitizerInterface, HandleNoReturnTest) {
- char array[40];
- __asan_poison_memory_region(array, sizeof(array));
- BAD_ACCESS(array, 20);
- __asan_handle_no_return();
- // It unpoisons the whole thread stack.
- GOOD_ACCESS(array, 20);
-}
diff --git a/lib/asan/tests/asan_internal_interface_test.cc b/lib/asan/tests/asan_internal_interface_test.cc
deleted file mode 100644
index e247bb4299faf..0000000000000
--- a/lib/asan/tests/asan_internal_interface_test.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-//===-- asan_internal_interface_test.cc -----------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-//===----------------------------------------------------------------------===//
-#include "asan_interface_internal.h"
-#include "asan_test_utils.h"
-#include <vector>
-
-TEST(AddressSanitizerInternalInterface, SetShadow) {
- std::vector<char> buffer(17, 0xff);
-
- __asan_set_shadow_00((uptr)buffer.data(), buffer.size());
- EXPECT_EQ(std::vector<char>(buffer.size(), 0x00), buffer);
-
- __asan_set_shadow_f1((uptr)buffer.data(), buffer.size());
- EXPECT_EQ(std::vector<char>(buffer.size(), 0xf1), buffer);
-
- __asan_set_shadow_f2((uptr)buffer.data(), buffer.size());
- EXPECT_EQ(std::vector<char>(buffer.size(), 0xf2), buffer);
-
- __asan_set_shadow_f3((uptr)buffer.data(), buffer.size());
- EXPECT_EQ(std::vector<char>(buffer.size(), 0xf3), buffer);
-
- __asan_set_shadow_f5((uptr)buffer.data(), buffer.size());
- EXPECT_EQ(std::vector<char>(buffer.size(), 0xf5), buffer);
-
- __asan_set_shadow_f8((uptr)buffer.data(), buffer.size());
- EXPECT_EQ(std::vector<char>(buffer.size(), 0xf8), buffer);
-}
diff --git a/lib/asan/tests/asan_mac_test.cc b/lib/asan/tests/asan_mac_test.cc
deleted file mode 100644
index dfa6d7596d742..0000000000000
--- a/lib/asan/tests/asan_mac_test.cc
+++ /dev/null
@@ -1,236 +0,0 @@
-//===-- asan_test_mac.cc --------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-//===----------------------------------------------------------------------===//
-
-#include "asan_test_utils.h"
-
-#include "asan_mac_test.h"
-
-#include <malloc/malloc.h>
-#include <AvailabilityMacros.h> // For MAC_OS_X_VERSION_*
-#include <CoreFoundation/CFString.h>
-
-TEST(AddressSanitizerMac, CFAllocatorDefaultDoubleFree) {
- EXPECT_DEATH(
- CFAllocatorDefaultDoubleFree(NULL),
- "attempting double-free");
-}
-
-void CFAllocator_DoubleFreeOnPthread() {
- pthread_t child;
- PTHREAD_CREATE(&child, NULL, CFAllocatorDefaultDoubleFree, NULL);
- PTHREAD_JOIN(child, NULL); // Shouldn't be reached.
-}
-
-TEST(AddressSanitizerMac, CFAllocatorDefaultDoubleFree_ChildPhread) {
- EXPECT_DEATH(CFAllocator_DoubleFreeOnPthread(), "attempting double-free");
-}
-
-namespace {
-
-void *GLOB;
-
-void *CFAllocatorAllocateToGlob(void *unused) {
- GLOB = CFAllocatorAllocate(NULL, 100, /*hint*/0);
- return NULL;
-}
-
-void *CFAllocatorDeallocateFromGlob(void *unused) {
- char *p = (char*)GLOB;
- p[100] = 'A'; // ASan should report an error here.
- CFAllocatorDeallocate(NULL, GLOB);
- return NULL;
-}
-
-void CFAllocator_PassMemoryToAnotherThread() {
- pthread_t th1, th2;
- PTHREAD_CREATE(&th1, NULL, CFAllocatorAllocateToGlob, NULL);
- PTHREAD_JOIN(th1, NULL);
- PTHREAD_CREATE(&th2, NULL, CFAllocatorDeallocateFromGlob, NULL);
- PTHREAD_JOIN(th2, NULL);
-}
-
-TEST(AddressSanitizerMac, CFAllocator_PassMemoryToAnotherThread) {
- EXPECT_DEATH(CFAllocator_PassMemoryToAnotherThread(),
- "heap-buffer-overflow");
-}
-
-} // namespace
-
-// TODO(glider): figure out whether we still need these tests. Is it correct
-// to intercept the non-default CFAllocators?
-TEST(AddressSanitizerMac, DISABLED_CFAllocatorSystemDefaultDoubleFree) {
- EXPECT_DEATH(
- CFAllocatorSystemDefaultDoubleFree(),
- "attempting double-free");
-}
-
-// We're intercepting malloc, so kCFAllocatorMalloc is routed to ASan.
-TEST(AddressSanitizerMac, CFAllocatorMallocDoubleFree) {
- EXPECT_DEATH(CFAllocatorMallocDoubleFree(), "attempting double-free");
-}
-
-TEST(AddressSanitizerMac, DISABLED_CFAllocatorMallocZoneDoubleFree) {
- EXPECT_DEATH(CFAllocatorMallocZoneDoubleFree(), "attempting double-free");
-}
-
-// For libdispatch tests below we check that ASan got to the shadow byte
-// legend, i.e. managed to print the thread stacks (this almost certainly
-// means that the libdispatch task creation has been intercepted correctly).
-TEST(AddressSanitizerMac, GCDDispatchAsync) {
- // Make sure the whole ASan report is printed, i.e. that we don't die
- // on a CHECK.
- EXPECT_DEATH(TestGCDDispatchAsync(), "Shadow byte legend");
-}
-
-TEST(AddressSanitizerMac, GCDDispatchSync) {
- // Make sure the whole ASan report is printed, i.e. that we don't die
- // on a CHECK.
- EXPECT_DEATH(TestGCDDispatchSync(), "Shadow byte legend");
-}
-
-
-TEST(AddressSanitizerMac, GCDReuseWqthreadsAsync) {
- // Make sure the whole ASan report is printed, i.e. that we don't die
- // on a CHECK.
- EXPECT_DEATH(TestGCDReuseWqthreadsAsync(), "Shadow byte legend");
-}
-
-TEST(AddressSanitizerMac, GCDReuseWqthreadsSync) {
- // Make sure the whole ASan report is printed, i.e. that we don't die
- // on a CHECK.
- EXPECT_DEATH(TestGCDReuseWqthreadsSync(), "Shadow byte legend");
-}
-
-TEST(AddressSanitizerMac, GCDDispatchAfter) {
- // Make sure the whole ASan report is printed, i.e. that we don't die
- // on a CHECK.
- EXPECT_DEATH(TestGCDDispatchAfter(), "Shadow byte legend");
-}
-
-TEST(AddressSanitizerMac, GCDSourceEvent) {
- // Make sure the whole ASan report is printed, i.e. that we don't die
- // on a CHECK.
- EXPECT_DEATH(TestGCDSourceEvent(), "Shadow byte legend");
-}
-
-TEST(AddressSanitizerMac, GCDSourceCancel) {
- // Make sure the whole ASan report is printed, i.e. that we don't die
- // on a CHECK.
- EXPECT_DEATH(TestGCDSourceCancel(), "Shadow byte legend");
-}
-
-TEST(AddressSanitizerMac, GCDGroupAsync) {
- // Make sure the whole ASan report is printed, i.e. that we don't die
- // on a CHECK.
- EXPECT_DEATH(TestGCDGroupAsync(), "Shadow byte legend");
-}
-
-void *MallocIntrospectionLockWorker(void *_) {
- const int kNumPointers = 100;
- int i;
- void *pointers[kNumPointers];
- for (i = 0; i < kNumPointers; i++) {
- pointers[i] = malloc(i + 1);
- }
- for (i = 0; i < kNumPointers; i++) {
- free(pointers[i]);
- }
-
- return NULL;
-}
-
-void *MallocIntrospectionLockForker(void *_) {
- pid_t result = fork();
- if (result == -1) {
- perror("fork");
- }
- assert(result != -1);
- if (result == 0) {
- // Call malloc in the child process to make sure we won't deadlock.
- void *ptr = malloc(42);
- free(ptr);
- exit(0);
- } else {
- // Return in the parent process.
- return NULL;
- }
-}
-
-TEST(AddressSanitizerMac, MallocIntrospectionLock) {
- // Incorrect implementation of force_lock and force_unlock in our malloc zone
- // will cause forked processes to deadlock.
- // TODO(glider): need to detect that none of the child processes deadlocked.
- const int kNumWorkers = 5, kNumIterations = 100;
- int i, iter;
- for (iter = 0; iter < kNumIterations; iter++) {
- pthread_t workers[kNumWorkers], forker;
- for (i = 0; i < kNumWorkers; i++) {
- PTHREAD_CREATE(&workers[i], 0, MallocIntrospectionLockWorker, 0);
- }
- PTHREAD_CREATE(&forker, 0, MallocIntrospectionLockForker, 0);
- for (i = 0; i < kNumWorkers; i++) {
- PTHREAD_JOIN(workers[i], 0);
- }
- PTHREAD_JOIN(forker, 0);
- }
-}
-
-void *TSDAllocWorker(void *test_key) {
- if (test_key) {
- void *mem = malloc(10);
- pthread_setspecific(*(pthread_key_t*)test_key, mem);
- }
- return NULL;
-}
-
-TEST(AddressSanitizerMac, DISABLED_TSDWorkqueueTest) {
- pthread_t th;
- pthread_key_t test_key;
- pthread_key_create(&test_key, CallFreeOnWorkqueue);
- PTHREAD_CREATE(&th, NULL, TSDAllocWorker, &test_key);
- PTHREAD_JOIN(th, NULL);
- pthread_key_delete(test_key);
-}
-
-// Test that CFStringCreateCopy does not copy constant strings.
-TEST(AddressSanitizerMac, CFStringCreateCopy) {
- CFStringRef str = CFSTR("Hello world!\n");
- CFStringRef str2 = CFStringCreateCopy(0, str);
- EXPECT_EQ(str, str2);
-}
-
-TEST(AddressSanitizerMac, NSObjectOOB) {
- // Make sure that our allocators are used for NSObjects.
- EXPECT_DEATH(TestOOBNSObjects(), "heap-buffer-overflow");
-}
-
-// Make sure that correct pointer is passed to free() when deallocating a
-// NSURL object.
-// See https://github.com/google/sanitizers/issues/70.
-TEST(AddressSanitizerMac, NSURLDeallocation) {
- TestNSURLDeallocation();
-}
-
-// See https://github.com/google/sanitizers/issues/109.
-TEST(AddressSanitizerMac, Mstats) {
- malloc_statistics_t stats1, stats2;
- malloc_zone_statistics(/*all zones*/NULL, &stats1);
- const size_t kMallocSize = 100000;
- void *alloc = Ident(malloc(kMallocSize));
- malloc_zone_statistics(/*all zones*/NULL, &stats2);
- EXPECT_GT(stats2.blocks_in_use, stats1.blocks_in_use);
- EXPECT_GE(stats2.size_in_use - stats1.size_in_use, kMallocSize);
- free(alloc);
- // Even the default OSX allocator may not change the stats after free().
-}
-
diff --git a/lib/asan/tests/asan_mac_test.h b/lib/asan/tests/asan_mac_test.h
deleted file mode 100644
index 441547a5a3dcb..0000000000000
--- a/lib/asan/tests/asan_mac_test.h
+++ /dev/null
@@ -1,19 +0,0 @@
-extern "C" {
- void *CFAllocatorDefaultDoubleFree(void *unused);
- void CFAllocatorSystemDefaultDoubleFree();
- void CFAllocatorMallocDoubleFree();
- void CFAllocatorMallocZoneDoubleFree();
- void CallFreeOnWorkqueue(void *mem);
- void TestGCDDispatchAsync();
- void TestGCDDispatchSync();
- void TestGCDReuseWqthreadsAsync();
- void TestGCDReuseWqthreadsSync();
- void TestGCDDispatchAfter();
- void TestGCDInTSDDestructor();
- void TestGCDSourceEvent();
- void TestGCDSourceCancel();
- void TestGCDGroupAsync();
- void TestOOBNSObjects();
- void TestNSURLDeallocation();
- void TestPassCFMemoryToAnotherThread();
-}
diff --git a/lib/asan/tests/asan_mac_test_helpers.mm b/lib/asan/tests/asan_mac_test_helpers.mm
deleted file mode 100644
index 3f8fa26d95b8d..0000000000000
--- a/lib/asan/tests/asan_mac_test_helpers.mm
+++ /dev/null
@@ -1,241 +0,0 @@
-// Mac OS X 10.6 or higher only.
-#include <dispatch/dispatch.h>
-#include <pthread.h> // for pthread_yield_np()
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <unistd.h>
-
-#import <CoreFoundation/CFBase.h>
-#import <Foundation/NSObject.h>
-#import <Foundation/NSURL.h>
-
-// This is a (void*)(void*) function so it can be passed to pthread_create.
-void *CFAllocatorDefaultDoubleFree(void *unused) {
- void *mem = CFAllocatorAllocate(kCFAllocatorDefault, 5, 0);
- CFAllocatorDeallocate(kCFAllocatorDefault, mem);
- CFAllocatorDeallocate(kCFAllocatorDefault, mem);
- return 0;
-}
-
-void CFAllocatorSystemDefaultDoubleFree() {
- void *mem = CFAllocatorAllocate(kCFAllocatorSystemDefault, 5, 0);
- CFAllocatorDeallocate(kCFAllocatorSystemDefault, mem);
- CFAllocatorDeallocate(kCFAllocatorSystemDefault, mem);
-}
-
-void CFAllocatorMallocDoubleFree() {
- void *mem = CFAllocatorAllocate(kCFAllocatorMalloc, 5, 0);
- CFAllocatorDeallocate(kCFAllocatorMalloc, mem);
- CFAllocatorDeallocate(kCFAllocatorMalloc, mem);
-}
-
-void CFAllocatorMallocZoneDoubleFree() {
- void *mem = CFAllocatorAllocate(kCFAllocatorMallocZone, 5, 0);
- CFAllocatorDeallocate(kCFAllocatorMallocZone, mem);
- CFAllocatorDeallocate(kCFAllocatorMallocZone, mem);
-}
-
-__attribute__((noinline))
-void access_memory(char *a) {
- *a = 0;
-}
-
-// Test the +load instrumentation.
-// Because the +load methods are invoked before anything else is initialized,
-// it makes little sense to wrap the code below into a gTest test case.
-// If AddressSanitizer doesn't instrument the +load method below correctly,
-// everything will just crash.
-
-char kStartupStr[] =
- "If your test didn't crash, AddressSanitizer is instrumenting "
- "the +load methods correctly.";
-
-@interface LoadSomething : NSObject {
-}
-@end
-
-@implementation LoadSomething
-
-+(void) load {
- for (size_t i = 0; i < strlen(kStartupStr); i++) {
- access_memory(&kStartupStr[i]); // make sure no optimizations occur.
- }
- // Don't print anything here not to interfere with the death tests.
-}
-
-@end
-
-void worker_do_alloc(int size) {
- char * volatile mem = (char * volatile)malloc(size);
- mem[0] = 0; // Ok
- free(mem);
-}
-
-void worker_do_crash(int size) {
- char * volatile mem = (char * volatile)malloc(size);
- access_memory(&mem[size]); // BOOM
- free(mem);
-}
-
-// Used by the GCD tests to avoid a race between the worker thread reporting a
-// memory error and the main thread which may exit with exit code 0 before
-// that.
-void wait_forever() {
- volatile bool infinite = true;
- while (infinite) pthread_yield_np();
-}
-
-// Tests for the Grand Central Dispatch. See
-// http://developer.apple.com/library/mac/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html
-// for the reference.
-void TestGCDDispatchAsync() {
- dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
- dispatch_block_t block = ^{ worker_do_crash(1024); };
- // dispatch_async() runs the task on a worker thread that does not go through
- // pthread_create(). We need to verify that AddressSanitizer notices that the
- // thread has started.
- dispatch_async(queue, block);
- wait_forever();
-}
-
-void TestGCDDispatchSync() {
- dispatch_queue_t queue = dispatch_get_global_queue(2, 0);
- dispatch_block_t block = ^{ worker_do_crash(1024); };
- // dispatch_sync() runs the task on a worker thread that does not go through
- // pthread_create(). We need to verify that AddressSanitizer notices that the
- // thread has started.
- dispatch_sync(queue, block);
- wait_forever();
-}
-
-// libdispatch spawns a rather small number of threads and reuses them. We need
-// to make sure AddressSanitizer handles the reusing correctly.
-void TestGCDReuseWqthreadsAsync() {
- dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
- dispatch_block_t block_alloc = ^{ worker_do_alloc(1024); };
- dispatch_block_t block_crash = ^{ worker_do_crash(1024); };
- for (int i = 0; i < 100; i++) {
- dispatch_async(queue, block_alloc);
- }
- dispatch_async(queue, block_crash);
- wait_forever();
-}
-
-// Try to trigger abnormal behaviour of dispatch_sync() being unhandled by us.
-void TestGCDReuseWqthreadsSync() {
- dispatch_queue_t queue[4];
- queue[0] = dispatch_get_global_queue(2, 0);
- queue[1] = dispatch_get_global_queue(0, 0);
- queue[2] = dispatch_get_global_queue(-2, 0);
- queue[3] = dispatch_queue_create("my_queue", NULL);
- dispatch_block_t block_alloc = ^{ worker_do_alloc(1024); };
- dispatch_block_t block_crash = ^{ worker_do_crash(1024); };
- for (int i = 0; i < 1000; i++) {
- dispatch_sync(queue[i % 4], block_alloc);
- }
- dispatch_sync(queue[3], block_crash);
- wait_forever();
-}
-
-void TestGCDDispatchAfter() {
- dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
- dispatch_block_t block_crash = ^{ worker_do_crash(1024); };
- // Schedule the event one second from the current time.
- dispatch_time_t milestone =
- dispatch_time(DISPATCH_TIME_NOW, 1LL * NSEC_PER_SEC);
- dispatch_after(milestone, queue, block_crash);
- wait_forever();
-}
-
-void worker_do_deallocate(void *ptr) {
- free(ptr);
-}
-
-void CallFreeOnWorkqueue(void *tsd) {
- dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
- dispatch_block_t block_dealloc = ^{ worker_do_deallocate(tsd); };
- dispatch_async(queue, block_dealloc);
- // Do not wait for the worker to free the memory -- nobody is going to touch
- // it.
-}
-
-void TestGCDSourceEvent() {
- dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
- dispatch_source_t timer =
- dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
- // Schedule the timer one second from the current time.
- dispatch_time_t milestone =
- dispatch_time(DISPATCH_TIME_NOW, 1LL * NSEC_PER_SEC);
-
- dispatch_source_set_timer(timer, milestone, DISPATCH_TIME_FOREVER, 0);
- char * volatile mem = (char * volatile)malloc(10);
- dispatch_source_set_event_handler(timer, ^{
- access_memory(&mem[10]);
- });
- dispatch_resume(timer);
- wait_forever();
-}
-
-void TestGCDSourceCancel() {
- dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
- dispatch_source_t timer =
- dispatch_source_create(DISPATCH_SOURCE_TYPE_TIMER, 0, 0, queue);
- // Schedule the timer one second from the current time.
- dispatch_time_t milestone =
- dispatch_time(DISPATCH_TIME_NOW, 1LL * NSEC_PER_SEC);
-
- dispatch_source_set_timer(timer, milestone, DISPATCH_TIME_FOREVER, 0);
- char * volatile mem = (char * volatile)malloc(10);
- // Both dispatch_source_set_cancel_handler() and
- // dispatch_source_set_event_handler() use dispatch_barrier_async_f().
- // It's tricky to test dispatch_source_set_cancel_handler() separately,
- // so we test both here.
- dispatch_source_set_event_handler(timer, ^{
- dispatch_source_cancel(timer);
- });
- dispatch_source_set_cancel_handler(timer, ^{
- access_memory(&mem[10]);
- });
- dispatch_resume(timer);
- wait_forever();
-}
-
-void TestGCDGroupAsync() {
- dispatch_queue_t queue = dispatch_get_global_queue(0, 0);
- dispatch_group_t group = dispatch_group_create();
- char * volatile mem = (char * volatile)malloc(10);
- dispatch_group_async(group, queue, ^{
- access_memory(&mem[10]);
- });
- dispatch_group_wait(group, DISPATCH_TIME_FOREVER);
- wait_forever();
-}
-
-@interface FixedArray : NSObject {
- int items[10];
-}
-@end
-
-@implementation FixedArray
--(int) access: (int)index {
- return items[index];
-}
-@end
-
-void TestOOBNSObjects() {
- id anObject = [FixedArray new];
- [anObject access:1];
- [anObject access:11];
- [anObject release];
-}
-
-void TestNSURLDeallocation() {
- NSURL *base =
- [[NSURL alloc] initWithString:@"file://localhost/Users/glider/Library/"];
- volatile NSURL *u =
- [[NSURL alloc] initWithString:@"Saved Application State"
- relativeToURL:base];
- [u release];
- [base release];
-}
diff --git a/lib/asan/tests/asan_mem_test.cc b/lib/asan/tests/asan_mem_test.cc
deleted file mode 100644
index c3208868464e1..0000000000000
--- a/lib/asan/tests/asan_mem_test.cc
+++ /dev/null
@@ -1,242 +0,0 @@
-//===-- asan_mem_test.cc --------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-//===----------------------------------------------------------------------===//
-#include "asan_test_utils.h"
-#include <vector>
-
-template<typename T>
-void MemSetOOBTestTemplate(size_t length) {
- if (length == 0) return;
- size_t size = Ident(sizeof(T) * length);
- T *array = Ident((T*)malloc(size));
- int element = Ident(42);
- int zero = Ident(0);
- void *(*MEMSET)(void *s, int c, size_t n) = Ident(memset);
- // memset interval inside array
- MEMSET(array, element, size);
- MEMSET(array, element, size - 1);
- MEMSET(array + length - 1, element, sizeof(T));
- MEMSET(array, element, 1);
-
- // memset 0 bytes
- MEMSET(array - 10, element, zero);
- MEMSET(array - 1, element, zero);
- MEMSET(array, element, zero);
- MEMSET(array + length, 0, zero);
- MEMSET(array + length + 1, 0, zero);
-
- // try to memset bytes to the right of array
- EXPECT_DEATH(MEMSET(array, 0, size + 1),
- RightOOBWriteMessage(0));
- EXPECT_DEATH(MEMSET((char*)(array + length) - 1, element, 6),
- RightOOBWriteMessage(0));
- EXPECT_DEATH(MEMSET(array + 1, element, size + sizeof(T)),
- RightOOBWriteMessage(0));
- // whole interval is to the right
- EXPECT_DEATH(MEMSET(array + length + 1, 0, 10),
- RightOOBWriteMessage(sizeof(T)));
-
- // try to memset bytes to the left of array
- EXPECT_DEATH(MEMSET((char*)array - 1, element, size),
- LeftOOBWriteMessage(1));
- EXPECT_DEATH(MEMSET((char*)array - 5, 0, 6),
- LeftOOBWriteMessage(5));
- if (length >= 100) {
- // Large OOB, we find it only if the redzone is large enough.
- EXPECT_DEATH(memset(array - 5, element, size + 5 * sizeof(T)),
- LeftOOBWriteMessage(5 * sizeof(T)));
- }
- // whole interval is to the left
- EXPECT_DEATH(MEMSET(array - 2, 0, sizeof(T)),
- LeftOOBWriteMessage(2 * sizeof(T)));
-
- // try to memset bytes both to the left & to the right
- EXPECT_DEATH(MEMSET((char*)array - 2, element, size + 4),
- LeftOOBWriteMessage(2));
-
- free(array);
-}
-
-TEST(AddressSanitizer, MemSetOOBTest) {
- MemSetOOBTestTemplate<char>(100);
- MemSetOOBTestTemplate<int>(5);
- MemSetOOBTestTemplate<double>(256);
- // We can test arrays of structres/classes here, but what for?
-}
-
-// Try to allocate two arrays of 'size' bytes that are near each other.
-// Strictly speaking we are not guaranteed to find such two pointers,
-// but given the structure of asan's allocator we will.
-static bool AllocateTwoAdjacentArrays(char **x1, char **x2, size_t size) {
- std::vector<uintptr_t> v;
- bool res = false;
- for (size_t i = 0; i < 1000U && !res; i++) {
- v.push_back(reinterpret_cast<uintptr_t>(new char[size]));
- if (i == 0) continue;
- sort(v.begin(), v.end());
- for (size_t j = 1; j < v.size(); j++) {
- assert(v[j] > v[j-1]);
- if ((size_t)(v[j] - v[j-1]) < size * 2) {
- *x2 = reinterpret_cast<char*>(v[j]);
- *x1 = reinterpret_cast<char*>(v[j-1]);
- res = true;
- break;
- }
- }
- }
-
- for (size_t i = 0; i < v.size(); i++) {
- char *p = reinterpret_cast<char *>(v[i]);
- if (res && p == *x1) continue;
- if (res && p == *x2) continue;
- delete [] p;
- }
- return res;
-}
-
-TEST(AddressSanitizer, LargeOOBInMemset) {
- for (size_t size = 200; size < 100000; size += size / 2) {
- char *x1, *x2;
- if (!Ident(AllocateTwoAdjacentArrays)(&x1, &x2, size))
- continue;
- // fprintf(stderr, " large oob memset: %p %p %zd\n", x1, x2, size);
- // Do a memset on x1 with huge out-of-bound access that will end up in x2.
- EXPECT_DEATH(Ident(memset)(x1, 0, size * 2),
- "is located 0 bytes to the right");
- delete [] x1;
- delete [] x2;
- return;
- }
- assert(0 && "Did not find two adjacent malloc-ed pointers");
-}
-
-// Same test for memcpy and memmove functions
-template <typename T, class M>
-void MemTransferOOBTestTemplate(size_t length) {
- if (length == 0) return;
- size_t size = Ident(sizeof(T) * length);
- T *src = Ident((T*)malloc(size));
- T *dest = Ident((T*)malloc(size));
- int zero = Ident(0);
-
- // valid transfer of bytes between arrays
- M::transfer(dest, src, size);
- M::transfer(dest + 1, src, size - sizeof(T));
- M::transfer(dest, src + length - 1, sizeof(T));
- M::transfer(dest, src, 1);
-
- // transfer zero bytes
- M::transfer(dest - 1, src, 0);
- M::transfer(dest + length, src, zero);
- M::transfer(dest, src - 1, zero);
- M::transfer(dest, src, zero);
-
- // try to change mem to the right of dest
- EXPECT_DEATH(M::transfer(dest + 1, src, size),
- RightOOBWriteMessage(0));
- EXPECT_DEATH(M::transfer((char*)(dest + length) - 1, src, 5),
- RightOOBWriteMessage(0));
-
- // try to change mem to the left of dest
- EXPECT_DEATH(M::transfer(dest - 2, src, size),
- LeftOOBWriteMessage(2 * sizeof(T)));
- EXPECT_DEATH(M::transfer((char*)dest - 3, src, 4),
- LeftOOBWriteMessage(3));
-
- // try to access mem to the right of src
- EXPECT_DEATH(M::transfer(dest, src + 2, size),
- RightOOBReadMessage(0));
- EXPECT_DEATH(M::transfer(dest, (char*)(src + length) - 3, 6),
- RightOOBReadMessage(0));
-
- // try to access mem to the left of src
- EXPECT_DEATH(M::transfer(dest, src - 1, size),
- LeftOOBReadMessage(sizeof(T)));
- EXPECT_DEATH(M::transfer(dest, (char*)src - 6, 7),
- LeftOOBReadMessage(6));
-
- // Generally we don't need to test cases where both accessing src and writing
- // to dest address to poisoned memory.
-
- T *big_src = Ident((T*)malloc(size * 2));
- T *big_dest = Ident((T*)malloc(size * 2));
- // try to change mem to both sides of dest
- EXPECT_DEATH(M::transfer(dest - 1, big_src, size * 2),
- LeftOOBWriteMessage(sizeof(T)));
- // try to access mem to both sides of src
- EXPECT_DEATH(M::transfer(big_dest, src - 2, size * 2),
- LeftOOBReadMessage(2 * sizeof(T)));
-
- free(src);
- free(dest);
- free(big_src);
- free(big_dest);
-}
-
-class MemCpyWrapper {
- public:
- static void* transfer(void *to, const void *from, size_t size) {
- return Ident(memcpy)(to, from, size);
- }
-};
-
-TEST(AddressSanitizer, MemCpyOOBTest) {
- MemTransferOOBTestTemplate<char, MemCpyWrapper>(100);
- MemTransferOOBTestTemplate<int, MemCpyWrapper>(1024);
-}
-
-class MemMoveWrapper {
- public:
- static void* transfer(void *to, const void *from, size_t size) {
- return Ident(memmove)(to, from, size);
- }
-};
-
-TEST(AddressSanitizer, MemMoveOOBTest) {
- MemTransferOOBTestTemplate<char, MemMoveWrapper>(100);
- MemTransferOOBTestTemplate<int, MemMoveWrapper>(1024);
-}
-
-
-TEST(AddressSanitizer, MemCmpOOBTest) {
- size_t size = Ident(100);
- char *s1 = MallocAndMemsetString(size);
- char *s2 = MallocAndMemsetString(size);
- // Normal memcmp calls.
- Ident(memcmp(s1, s2, size));
- Ident(memcmp(s1 + size - 1, s2 + size - 1, 1));
- Ident(memcmp(s1 - 1, s2 - 1, 0));
- // One of arguments points to not allocated memory.
- EXPECT_DEATH(Ident(memcmp)(s1 - 1, s2, 1), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(memcmp)(s1, s2 - 1, 1), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(memcmp)(s1 + size, s2, 1), RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(memcmp)(s1, s2 + size, 1), RightOOBReadMessage(0));
- // Hit unallocated memory and die.
- EXPECT_DEATH(Ident(memcmp)(s1 + 1, s2 + 1, size), RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(memcmp)(s1 + size - 1, s2, 2), RightOOBReadMessage(0));
- // Zero bytes are not terminators and don't prevent from OOB.
- s1[size - 1] = '\0';
- s2[size - 1] = '\0';
- EXPECT_DEATH(Ident(memcmp)(s1, s2, size + 1), RightOOBReadMessage(0));
-
- // Even if the buffers differ in the first byte, we still assume that
- // memcmp may access the whole buffer and thus reporting the overflow here:
- s1[0] = 1;
- s2[0] = 123;
- EXPECT_DEATH(Ident(memcmp)(s1, s2, size + 1), RightOOBReadMessage(0));
-
- free(s1);
- free(s2);
-}
-
-
-
diff --git a/lib/asan/tests/asan_noinst_test.cc b/lib/asan/tests/asan_noinst_test.cc
deleted file mode 100644
index 3e366842c65ff..0000000000000
--- a/lib/asan/tests/asan_noinst_test.cc
+++ /dev/null
@@ -1,273 +0,0 @@
-//===-- asan_noinst_test.cc -----------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-// This test file should be compiled w/o asan instrumentation.
-//===----------------------------------------------------------------------===//
-
-#include "asan_allocator.h"
-#include "asan_internal.h"
-#include "asan_mapping.h"
-#include "asan_test_utils.h"
-#include <sanitizer/allocator_interface.h>
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h> // for memset()
-#include <algorithm>
-#include <vector>
-#include <limits>
-
-using namespace __sanitizer;
-
-// ATTENTION!
-// Please don't call intercepted functions (including malloc() and friends)
-// in this test. The static runtime library is linked explicitly (without
-// -fsanitize=address), thus the interceptors do not work correctly on OS X.
-
-// Make sure __asan_init is called before any test case is run.
-struct AsanInitCaller {
- AsanInitCaller() {
- __asan_init();
- }
-};
-static AsanInitCaller asan_init_caller;
-
-TEST(AddressSanitizer, InternalSimpleDeathTest) {
- EXPECT_DEATH(exit(1), "");
-}
-
-static void MallocStress(size_t n) {
- u32 seed = my_rand();
- BufferedStackTrace stack1;
- stack1.trace_buffer[0] = 0xa123;
- stack1.trace_buffer[1] = 0xa456;
- stack1.size = 2;
-
- BufferedStackTrace stack2;
- stack2.trace_buffer[0] = 0xb123;
- stack2.trace_buffer[1] = 0xb456;
- stack2.size = 2;
-
- BufferedStackTrace stack3;
- stack3.trace_buffer[0] = 0xc123;
- stack3.trace_buffer[1] = 0xc456;
- stack3.size = 2;
-
- std::vector<void *> vec;
- for (size_t i = 0; i < n; i++) {
- if ((i % 3) == 0) {
- if (vec.empty()) continue;
- size_t idx = my_rand_r(&seed) % vec.size();
- void *ptr = vec[idx];
- vec[idx] = vec.back();
- vec.pop_back();
- __asan::asan_free(ptr, &stack1, __asan::FROM_MALLOC);
- } else {
- size_t size = my_rand_r(&seed) % 1000 + 1;
- switch ((my_rand_r(&seed) % 128)) {
- case 0: size += 1024; break;
- case 1: size += 2048; break;
- case 2: size += 4096; break;
- }
- size_t alignment = 1 << (my_rand_r(&seed) % 10 + 1);
- char *ptr = (char*)__asan::asan_memalign(alignment, size,
- &stack2, __asan::FROM_MALLOC);
- EXPECT_EQ(size, __asan::asan_malloc_usable_size(ptr, 0, 0));
- vec.push_back(ptr);
- ptr[0] = 0;
- ptr[size-1] = 0;
- ptr[size/2] = 0;
- }
- }
- for (size_t i = 0; i < vec.size(); i++)
- __asan::asan_free(vec[i], &stack3, __asan::FROM_MALLOC);
-}
-
-
-TEST(AddressSanitizer, NoInstMallocTest) {
- MallocStress(ASAN_LOW_MEMORY ? 300000 : 1000000);
-}
-
-TEST(AddressSanitizer, ThreadedMallocStressTest) {
- const int kNumThreads = 4;
- const int kNumIterations = (ASAN_LOW_MEMORY) ? 10000 : 100000;
- pthread_t t[kNumThreads];
- for (int i = 0; i < kNumThreads; i++) {
- PTHREAD_CREATE(&t[i], 0, (void* (*)(void *x))MallocStress,
- (void*)kNumIterations);
- }
- for (int i = 0; i < kNumThreads; i++) {
- PTHREAD_JOIN(t[i], 0);
- }
-}
-
-static void PrintShadow(const char *tag, uptr ptr, size_t size) {
- fprintf(stderr, "%s shadow: %lx size % 3ld: ", tag, (long)ptr, (long)size);
- uptr prev_shadow = 0;
- for (sptr i = -32; i < (sptr)size + 32; i++) {
- uptr shadow = __asan::MemToShadow(ptr + i);
- if (i == 0 || i == (sptr)size)
- fprintf(stderr, ".");
- if (shadow != prev_shadow) {
- prev_shadow = shadow;
- fprintf(stderr, "%02x", (int)*(u8*)shadow);
- }
- }
- fprintf(stderr, "\n");
-}
-
-TEST(AddressSanitizer, DISABLED_InternalPrintShadow) {
- for (size_t size = 1; size <= 513; size++) {
- char *ptr = new char[size];
- PrintShadow("m", (uptr)ptr, size);
- delete [] ptr;
- PrintShadow("f", (uptr)ptr, size);
- }
-}
-
-TEST(AddressSanitizer, QuarantineTest) {
- BufferedStackTrace stack;
- stack.trace_buffer[0] = 0x890;
- stack.size = 1;
-
- const int size = 1024;
- void *p = __asan::asan_malloc(size, &stack);
- __asan::asan_free(p, &stack, __asan::FROM_MALLOC);
- size_t i;
- size_t max_i = 1 << 30;
- for (i = 0; i < max_i; i++) {
- void *p1 = __asan::asan_malloc(size, &stack);
- __asan::asan_free(p1, &stack, __asan::FROM_MALLOC);
- if (p1 == p) break;
- }
- EXPECT_GE(i, 10000U);
- EXPECT_LT(i, max_i);
-}
-
-#if !defined(__NetBSD__)
-void *ThreadedQuarantineTestWorker(void *unused) {
- (void)unused;
- u32 seed = my_rand();
- BufferedStackTrace stack;
- stack.trace_buffer[0] = 0x890;
- stack.size = 1;
-
- for (size_t i = 0; i < 1000; i++) {
- void *p = __asan::asan_malloc(1 + (my_rand_r(&seed) % 4000), &stack);
- __asan::asan_free(p, &stack, __asan::FROM_MALLOC);
- }
- return NULL;
-}
-
-// Check that the thread local allocators are flushed when threads are
-// destroyed.
-TEST(AddressSanitizer, ThreadedQuarantineTest) {
- // Run the routine once to warm up ASAN internal structures to get more
- // predictable incremental memory changes.
- pthread_t t;
- PTHREAD_CREATE(&t, NULL, ThreadedQuarantineTestWorker, 0);
- PTHREAD_JOIN(t, 0);
-
- const int n_threads = 3000;
- size_t mmaped1 = __sanitizer_get_heap_size();
- for (int i = 0; i < n_threads; i++) {
- pthread_t t;
- PTHREAD_CREATE(&t, NULL, ThreadedQuarantineTestWorker, 0);
- PTHREAD_JOIN(t, 0);
- size_t mmaped2 = __sanitizer_get_heap_size();
- // Figure out why this much memory is required.
- EXPECT_LT(mmaped2 - mmaped1, 320U * (1 << 20));
- }
-}
-#endif
-
-void *ThreadedOneSizeMallocStress(void *unused) {
- (void)unused;
- BufferedStackTrace stack;
- stack.trace_buffer[0] = 0x890;
- stack.size = 1;
- const size_t kNumMallocs = 1000;
- for (int iter = 0; iter < 1000; iter++) {
- void *p[kNumMallocs];
- for (size_t i = 0; i < kNumMallocs; i++) {
- p[i] = __asan::asan_malloc(32, &stack);
- }
- for (size_t i = 0; i < kNumMallocs; i++) {
- __asan::asan_free(p[i], &stack, __asan::FROM_MALLOC);
- }
- }
- return NULL;
-}
-
-TEST(AddressSanitizer, ThreadedOneSizeMallocStressTest) {
- const int kNumThreads = 4;
- pthread_t t[kNumThreads];
- for (int i = 0; i < kNumThreads; i++) {
- PTHREAD_CREATE(&t[i], 0, ThreadedOneSizeMallocStress, 0);
- }
- for (int i = 0; i < kNumThreads; i++) {
- PTHREAD_JOIN(t[i], 0);
- }
-}
-
-TEST(AddressSanitizer, ShadowRegionIsPoisonedTest) {
- using __asan::kHighMemEnd;
- // Check that __asan_region_is_poisoned works for shadow regions.
- uptr ptr = kLowShadowBeg + 200;
- EXPECT_EQ(ptr, __asan_region_is_poisoned(ptr, 100));
- ptr = kShadowGapBeg + 200;
- EXPECT_EQ(ptr, __asan_region_is_poisoned(ptr, 100));
- ptr = kHighShadowBeg + 200;
- EXPECT_EQ(ptr, __asan_region_is_poisoned(ptr, 100));
-}
-
-// Test __asan_load1 & friends.
-TEST(AddressSanitizer, LoadStoreCallbacks) {
- typedef void (*CB)(uptr p);
- CB cb[2][5] = {
- {
- __asan_load1, __asan_load2, __asan_load4, __asan_load8, __asan_load16,
- }, {
- __asan_store1, __asan_store2, __asan_store4, __asan_store8,
- __asan_store16,
- }
- };
-
- uptr buggy_ptr;
-
- __asan_test_only_reported_buggy_pointer = &buggy_ptr;
- BufferedStackTrace stack;
- stack.trace_buffer[0] = 0x890;
- stack.size = 1;
-
- for (uptr len = 16; len <= 32; len++) {
- char *ptr = (char*) __asan::asan_malloc(len, &stack);
- uptr p = reinterpret_cast<uptr>(ptr);
- for (uptr is_write = 0; is_write <= 1; is_write++) {
- for (uptr size_log = 0; size_log <= 4; size_log++) {
- uptr size = 1 << size_log;
- CB call = cb[is_write][size_log];
- // Iterate only size-aligned offsets.
- for (uptr offset = 0; offset <= len; offset += size) {
- buggy_ptr = 0;
- call(p + offset);
- if (offset + size <= len)
- EXPECT_EQ(buggy_ptr, 0U);
- else
- EXPECT_EQ(buggy_ptr, p + offset);
- }
- }
- }
- __asan::asan_free(ptr, &stack, __asan::FROM_MALLOC);
- }
- __asan_test_only_reported_buggy_pointer = 0;
-}
diff --git a/lib/asan/tests/asan_oob_test.cc b/lib/asan/tests/asan_oob_test.cc
deleted file mode 100644
index 0c6bea2858649..0000000000000
--- a/lib/asan/tests/asan_oob_test.cc
+++ /dev/null
@@ -1,128 +0,0 @@
-//===-- asan_oob_test.cc --------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-//===----------------------------------------------------------------------===//
-#include "asan_test_utils.h"
-
-NOINLINE void asan_write_sized_aligned(uint8_t *p, size_t size) {
- EXPECT_EQ(0U, ((uintptr_t)p % size));
- if (size == 1) asan_write((uint8_t*)p);
- else if (size == 2) asan_write((uint16_t*)p);
- else if (size == 4) asan_write((uint32_t*)p);
- else if (size == 8) asan_write((uint64_t*)p);
-}
-
-template<typename T>
-NOINLINE void oob_test(int size, int off) {
- char *p = (char*)malloc_aaa(size);
- // fprintf(stderr, "writing %d byte(s) into [%p,%p) with offset %d\n",
- // sizeof(T), p, p + size, off);
- asan_write((T*)(p + off));
- free_aaa(p);
-}
-
-template<typename T>
-void OOBTest() {
- char expected_str[100];
- for (int size = sizeof(T); size < 20; size += 5) {
- for (int i = -5; i < 0; i++) {
- const char *str =
- "is located.*%d byte.*to the left";
- sprintf(expected_str, str, abs(i));
- EXPECT_DEATH(oob_test<T>(size, i), expected_str);
- }
-
- for (int i = 0; i < (int)(size - sizeof(T) + 1); i++)
- oob_test<T>(size, i);
-
- for (int i = size - sizeof(T) + 1; i <= (int)(size + 2 * sizeof(T)); i++) {
- const char *str =
- "is located.*%d byte.*to the right";
- int off = i >= size ? (i - size) : 0;
- // we don't catch unaligned partially OOB accesses.
- if (i % sizeof(T)) continue;
- sprintf(expected_str, str, off);
- EXPECT_DEATH(oob_test<T>(size, i), expected_str);
- }
- }
-
- EXPECT_DEATH(oob_test<T>(kLargeMalloc, -1),
- "is located.*1 byte.*to the left");
- EXPECT_DEATH(oob_test<T>(kLargeMalloc, kLargeMalloc),
- "is located.*0 byte.*to the right");
-}
-
-// TODO(glider): the following tests are EXTREMELY slow on Darwin:
-// AddressSanitizer.OOB_char (125503 ms)
-// AddressSanitizer.OOB_int (126890 ms)
-// AddressSanitizer.OOBRightTest (315605 ms)
-// AddressSanitizer.SimpleStackTest (366559 ms)
-
-TEST(AddressSanitizer, OOB_char) {
- OOBTest<U1>();
-}
-
-TEST(AddressSanitizer, OOB_int) {
- OOBTest<U4>();
-}
-
-TEST(AddressSanitizer, OOBRightTest) {
- size_t max_access_size = SANITIZER_WORDSIZE == 64 ? 8 : 4;
- for (size_t access_size = 1; access_size <= max_access_size;
- access_size *= 2) {
- for (size_t alloc_size = 1; alloc_size <= 8; alloc_size++) {
- for (size_t offset = 0; offset <= 8; offset += access_size) {
- void *p = malloc(alloc_size);
- // allocated: [p, p + alloc_size)
- // accessed: [p + offset, p + offset + access_size)
- uint8_t *addr = (uint8_t*)p + offset;
- if (offset + access_size <= alloc_size) {
- asan_write_sized_aligned(addr, access_size);
- } else {
- int outside_bytes = offset > alloc_size ? (offset - alloc_size) : 0;
- const char *str =
- "is located.%d *byte.*to the right";
- char expected_str[100];
- sprintf(expected_str, str, outside_bytes);
- EXPECT_DEATH(asan_write_sized_aligned(addr, access_size),
- expected_str);
- }
- free(p);
- }
- }
- }
-}
-
-TEST(AddressSanitizer, LargeOOBRightTest) {
- size_t large_power_of_two = 1 << 19;
- for (size_t i = 16; i <= 256; i *= 2) {
- size_t size = large_power_of_two - i;
- char *p = Ident(new char[size]);
- EXPECT_DEATH(p[size] = 0, "is located 0 bytes to the right");
- delete [] p;
- }
-}
-
-TEST(AddressSanitizer, DISABLED_DemoOOBLeftLow) {
- oob_test<U1>(10, -1);
-}
-
-TEST(AddressSanitizer, DISABLED_DemoOOBLeftHigh) {
- oob_test<U1>(kLargeMalloc, -1);
-}
-
-TEST(AddressSanitizer, DISABLED_DemoOOBRightLow) {
- oob_test<U1>(10, 10);
-}
-
-TEST(AddressSanitizer, DISABLED_DemoOOBRightHigh) {
- oob_test<U1>(kLargeMalloc, kLargeMalloc);
-}
diff --git a/lib/asan/tests/asan_racy_double_free_test.cc b/lib/asan/tests/asan_racy_double_free_test.cc
deleted file mode 100644
index 23240e714d561..0000000000000
--- a/lib/asan/tests/asan_racy_double_free_test.cc
+++ /dev/null
@@ -1,32 +0,0 @@
-#include <pthread.h>
-#include <stdlib.h>
-#include <stdio.h>
-
-const int N = 1000;
-void *x[N];
-
-void *Thread1(void *unused) {
- for (int i = 0; i < N; i++) {
- fprintf(stderr, "%s %d\n", __func__, i);
- free(x[i]);
- }
- return NULL;
-}
-
-void *Thread2(void *unused) {
- for (int i = 0; i < N; i++) {
- fprintf(stderr, "%s %d\n", __func__, i);
- free(x[i]);
- }
- return NULL;
-}
-
-int main() {
- for (int i = 0; i < N; i++)
- x[i] = malloc(128);
- pthread_t t[2];
- pthread_create(&t[0], 0, Thread1, 0);
- pthread_create(&t[1], 0, Thread2, 0);
- pthread_join(t[0], 0);
- pthread_join(t[1], 0);
-}
diff --git a/lib/asan/tests/asan_str_test.cc b/lib/asan/tests/asan_str_test.cc
deleted file mode 100644
index 5cf4e05c81c82..0000000000000
--- a/lib/asan/tests/asan_str_test.cc
+++ /dev/null
@@ -1,635 +0,0 @@
-//=-- asan_str_test.cc ----------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-//===----------------------------------------------------------------------===//
-#include "asan_test_utils.h"
-
-#if defined(__APPLE__)
-#include <AvailabilityMacros.h> // For MAC_OS_X_VERSION_*
-#endif
-
-// Used for string functions tests
-static char global_string[] = "global";
-static size_t global_string_length = 6;
-
-const char kStackReadUnderflow[] =
-#if !GTEST_USES_SIMPLE_RE
- ASAN_PCRE_DOTALL
- "READ.*"
-#endif
- "underflows this variable";
-const char kStackReadOverflow[] =
-#if !GTEST_USES_SIMPLE_RE
- ASAN_PCRE_DOTALL
- "READ.*"
-#endif
- "overflows this variable";
-
-namespace {
-enum class OOBKind {
- Heap,
- Stack,
- Global,
-};
-
-string LeftOOBReadMessage(OOBKind oob_kind, int oob_distance) {
- return oob_kind == OOBKind::Stack ? kStackReadUnderflow
- : ::LeftOOBReadMessage(oob_distance);
-}
-
-string RightOOBReadMessage(OOBKind oob_kind, int oob_distance) {
- return oob_kind == OOBKind::Stack ? kStackReadOverflow
- : ::RightOOBReadMessage(oob_distance);
-}
-} // namespace
-
-// Input to a test is a zero-terminated string str with given length
-// Accesses to the bytes to the left and to the right of str
-// are presumed to produce OOB errors
-void StrLenOOBTestTemplate(char *str, size_t length, OOBKind oob_kind) {
- // Normal strlen calls
- EXPECT_EQ(strlen(str), length);
- if (length > 0) {
- EXPECT_EQ(length - 1, strlen(str + 1));
- EXPECT_EQ(0U, strlen(str + length));
- }
- // Arg of strlen is not malloced, OOB access
- if (oob_kind != OOBKind::Global) {
- // We don't insert RedZones to the left of global variables
- EXPECT_DEATH(Ident(strlen(str - 1)), LeftOOBReadMessage(oob_kind, 1));
- EXPECT_DEATH(Ident(strlen(str - 5)), LeftOOBReadMessage(oob_kind, 5));
- }
- EXPECT_DEATH(Ident(strlen(str + length + 1)),
- RightOOBReadMessage(oob_kind, 0));
- // Overwrite terminator
- str[length] = 'a';
- // String is not zero-terminated, strlen will lead to OOB access
- EXPECT_DEATH(Ident(strlen(str)), RightOOBReadMessage(oob_kind, 0));
- EXPECT_DEATH(Ident(strlen(str + length)), RightOOBReadMessage(oob_kind, 0));
- // Restore terminator
- str[length] = 0;
-}
-TEST(AddressSanitizer, StrLenOOBTest) {
- // Check heap-allocated string
- size_t length = Ident(10);
- char *heap_string = Ident((char*)malloc(length + 1));
- char stack_string[10 + 1];
- break_optimization(&stack_string);
- for (size_t i = 0; i < length; i++) {
- heap_string[i] = 'a';
- stack_string[i] = 'b';
- }
- heap_string[length] = 0;
- stack_string[length] = 0;
- StrLenOOBTestTemplate(heap_string, length, OOBKind::Heap);
- StrLenOOBTestTemplate(stack_string, length, OOBKind::Stack);
- StrLenOOBTestTemplate(global_string, global_string_length, OOBKind::Global);
- free(heap_string);
-}
-
-// 32-bit android libc++-based NDK toolchain links wcslen statically, disabling
-// the interceptor.
-#if !defined(__ANDROID__) || defined(__LP64__)
-TEST(AddressSanitizer, WcsLenTest) {
- EXPECT_EQ(0U, wcslen(Ident(L"")));
- size_t hello_len = 13;
- size_t hello_size = (hello_len + 1) * sizeof(wchar_t);
- EXPECT_EQ(hello_len, wcslen(Ident(L"Hello, World!")));
- wchar_t *heap_string = Ident((wchar_t*)malloc(hello_size));
- memcpy(heap_string, L"Hello, World!", hello_size);
- EXPECT_EQ(hello_len, Ident(wcslen(heap_string)));
- EXPECT_DEATH(Ident(wcslen(heap_string + 14)), RightOOBReadMessage(0));
- free(heap_string);
-}
-#endif
-
-#if SANITIZER_TEST_HAS_STRNLEN
-TEST(AddressSanitizer, StrNLenOOBTest) {
- size_t size = Ident(123);
- char *str = MallocAndMemsetString(size);
- // Normal strnlen calls.
- Ident(strnlen(str - 1, 0));
- Ident(strnlen(str, size));
- Ident(strnlen(str + size - 1, 1));
- str[size - 1] = '\0';
- Ident(strnlen(str, 2 * size));
- // Argument points to not allocated memory.
- EXPECT_DEATH(Ident(strnlen(str - 1, 1)), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(strnlen(str + size, 1)), RightOOBReadMessage(0));
- // Overwrite the terminating '\0' and hit unallocated memory.
- str[size - 1] = 'z';
- EXPECT_DEATH(Ident(strnlen(str, size + 1)), RightOOBReadMessage(0));
- free(str);
-}
-#endif // SANITIZER_TEST_HAS_STRNLEN
-
-// This test fails with the WinASan dynamic runtime because we fail to intercept
-// strdup.
-#if defined(_MSC_VER) && defined(_DLL)
-#define MAYBE_StrDupOOBTest DISABLED_StrDupOOBTest
-#else
-#define MAYBE_StrDupOOBTest StrDupOOBTest
-#endif
-
-TEST(AddressSanitizer, MAYBE_StrDupOOBTest) {
- size_t size = Ident(42);
- char *str = MallocAndMemsetString(size);
- char *new_str;
- // Normal strdup calls.
- str[size - 1] = '\0';
- new_str = strdup(str);
- free(new_str);
- new_str = strdup(str + size - 1);
- free(new_str);
- // Argument points to not allocated memory.
- EXPECT_DEATH(Ident(strdup(str - 1)), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(strdup(str + size)), RightOOBReadMessage(0));
- // Overwrite the terminating '\0' and hit unallocated memory.
- str[size - 1] = 'z';
- EXPECT_DEATH(Ident(strdup(str)), RightOOBReadMessage(0));
- free(str);
-}
-
-#if SANITIZER_TEST_HAS_STRNDUP
-TEST(AddressSanitizer, MAYBE_StrNDupOOBTest) {
- size_t size = Ident(42);
- char *str = MallocAndMemsetString(size);
- char *new_str;
- // Normal strndup calls.
- str[size - 1] = '\0';
- new_str = strndup(str, size - 13);
- free(new_str);
- new_str = strndup(str + size - 1, 13);
- free(new_str);
- // Argument points to not allocated memory.
- EXPECT_DEATH(Ident(strndup(str - 1, 13)), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(strndup(str + size, 13)), RightOOBReadMessage(0));
- // Overwrite the terminating '\0' and hit unallocated memory.
- str[size - 1] = 'z';
- EXPECT_DEATH(Ident(strndup(str, size + 13)), RightOOBReadMessage(0));
- // Check handling of non 0 terminated strings.
- Ident(new_str = strndup(str + size - 1, 0));
- free(new_str);
- Ident(new_str = strndup(str + size - 1, 1));
- free(new_str);
- EXPECT_DEATH(Ident(strndup(str + size - 1, 2)), RightOOBReadMessage(0));
- free(str);
-}
-#endif // SANITIZER_TEST_HAS_STRNDUP
-
-TEST(AddressSanitizer, StrCpyOOBTest) {
- size_t to_size = Ident(30);
- size_t from_size = Ident(6); // less than to_size
- char *to = Ident((char*)malloc(to_size));
- char *from = Ident((char*)malloc(from_size));
- // Normal strcpy calls.
- strcpy(from, "hello");
- strcpy(to, from);
- strcpy(to + to_size - from_size, from);
- // Length of "from" is too small.
- EXPECT_DEATH(Ident(strcpy(from, "hello2")), RightOOBWriteMessage(0));
- // "to" or "from" points to not allocated memory.
- EXPECT_DEATH(Ident(strcpy(to - 1, from)), LeftOOBWriteMessage(1));
- EXPECT_DEATH(Ident(strcpy(to, from - 1)), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(strcpy(to, from + from_size)), RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(strcpy(to + to_size, from)), RightOOBWriteMessage(0));
- // Overwrite the terminating '\0' character and hit unallocated memory.
- from[from_size - 1] = '!';
- EXPECT_DEATH(Ident(strcpy(to, from)), RightOOBReadMessage(0));
- free(to);
- free(from);
-}
-
-TEST(AddressSanitizer, StrNCpyOOBTest) {
- size_t to_size = Ident(20);
- size_t from_size = Ident(6); // less than to_size
- char *to = Ident((char*)malloc(to_size));
- // From is a zero-terminated string "hello\0" of length 6
- char *from = Ident((char*)malloc(from_size));
- strcpy(from, "hello");
- // copy 0 bytes
- strncpy(to, from, 0);
- strncpy(to - 1, from - 1, 0);
- // normal strncpy calls
- strncpy(to, from, from_size);
- strncpy(to, from, to_size);
- strncpy(to, from + from_size - 1, to_size);
- strncpy(to + to_size - 1, from, 1);
- // One of {to, from} points to not allocated memory
- EXPECT_DEATH(Ident(strncpy(to, from - 1, from_size)),
- LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(strncpy(to - 1, from, from_size)),
- LeftOOBWriteMessage(1));
- EXPECT_DEATH(Ident(strncpy(to, from + from_size, 1)),
- RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(strncpy(to + to_size, from, 1)),
- RightOOBWriteMessage(0));
- // Length of "to" is too small
- EXPECT_DEATH(Ident(strncpy(to + to_size - from_size + 1, from, from_size)),
- RightOOBWriteMessage(0));
- EXPECT_DEATH(Ident(strncpy(to + 1, from, to_size)),
- RightOOBWriteMessage(0));
- // Overwrite terminator in from
- from[from_size - 1] = '!';
- // normal strncpy call
- strncpy(to, from, from_size);
- // Length of "from" is too small
- EXPECT_DEATH(Ident(strncpy(to, from, to_size)),
- RightOOBReadMessage(0));
- free(to);
- free(from);
-}
-
-// Users may have different definitions of "strchr" and "index", so provide
-// function pointer typedefs and overload RunStrChrTest implementation.
-// We can't use macro for RunStrChrTest body here, as this macro would
-// confuse EXPECT_DEATH gtest macro.
-typedef char*(*PointerToStrChr1)(const char*, int);
-typedef char*(*PointerToStrChr2)(char*, int);
-
-template<typename StrChrFn>
-static void RunStrChrTestImpl(StrChrFn *StrChr) {
- size_t size = Ident(100);
- char *str = MallocAndMemsetString(size);
- str[10] = 'q';
- str[11] = '\0';
- EXPECT_EQ(str, StrChr(str, 'z'));
- EXPECT_EQ(str + 10, StrChr(str, 'q'));
- EXPECT_EQ(NULL, StrChr(str, 'a'));
- // StrChr argument points to not allocated memory.
- EXPECT_DEATH(Ident(StrChr(str - 1, 'z')), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(StrChr(str + size, 'z')), RightOOBReadMessage(0));
- // Overwrite the terminator and hit not allocated memory.
- str[11] = 'z';
- EXPECT_DEATH(Ident(StrChr(str, 'a')), RightOOBReadMessage(0));
- free(str);
-}
-
-// Prefer to use the standard signature if both are available.
-UNUSED static void RunStrChrTest(PointerToStrChr1 StrChr, ...) {
- RunStrChrTestImpl(StrChr);
-}
-UNUSED static void RunStrChrTest(PointerToStrChr2 StrChr, int) {
- RunStrChrTestImpl(StrChr);
-}
-
-TEST(AddressSanitizer, StrChrAndIndexOOBTest) {
- RunStrChrTest(&strchr, 0);
-// No index() on Windows and on Android L.
-#if !defined(_WIN32) && !defined(__ANDROID__)
- RunStrChrTest(&index, 0);
-#endif
-}
-
-TEST(AddressSanitizer, StrCmpAndFriendsLogicTest) {
- // strcmp
- EXPECT_EQ(0, strcmp("", ""));
- EXPECT_EQ(0, strcmp("abcd", "abcd"));
- EXPECT_GT(0, strcmp("ab", "ac"));
- EXPECT_GT(0, strcmp("abc", "abcd"));
- EXPECT_LT(0, strcmp("acc", "abc"));
- EXPECT_LT(0, strcmp("abcd", "abc"));
-
- // strncmp
- EXPECT_EQ(0, strncmp("a", "b", 0));
- EXPECT_EQ(0, strncmp("abcd", "abcd", 10));
- EXPECT_EQ(0, strncmp("abcd", "abcef", 3));
- EXPECT_GT(0, strncmp("abcde", "abcfa", 4));
- EXPECT_GT(0, strncmp("a", "b", 5));
- EXPECT_GT(0, strncmp("bc", "bcde", 4));
- EXPECT_LT(0, strncmp("xyz", "xyy", 10));
- EXPECT_LT(0, strncmp("baa", "aaa", 1));
- EXPECT_LT(0, strncmp("zyx", "", 2));
-
-#if !defined(_WIN32) // no str[n]casecmp on Windows.
- // strcasecmp
- EXPECT_EQ(0, strcasecmp("", ""));
- EXPECT_EQ(0, strcasecmp("zzz", "zzz"));
- EXPECT_EQ(0, strcasecmp("abCD", "ABcd"));
- EXPECT_GT(0, strcasecmp("aB", "Ac"));
- EXPECT_GT(0, strcasecmp("ABC", "ABCd"));
- EXPECT_LT(0, strcasecmp("acc", "abc"));
- EXPECT_LT(0, strcasecmp("ABCd", "abc"));
-
- // strncasecmp
- EXPECT_EQ(0, strncasecmp("a", "b", 0));
- EXPECT_EQ(0, strncasecmp("abCD", "ABcd", 10));
- EXPECT_EQ(0, strncasecmp("abCd", "ABcef", 3));
- EXPECT_GT(0, strncasecmp("abcde", "ABCfa", 4));
- EXPECT_GT(0, strncasecmp("a", "B", 5));
- EXPECT_GT(0, strncasecmp("bc", "BCde", 4));
- EXPECT_LT(0, strncasecmp("xyz", "xyy", 10));
- EXPECT_LT(0, strncasecmp("Baa", "aaa", 1));
- EXPECT_LT(0, strncasecmp("zyx", "", 2));
-#endif
-
- // memcmp
- EXPECT_EQ(0, memcmp("a", "b", 0));
- EXPECT_EQ(0, memcmp("ab\0c", "ab\0c", 4));
- EXPECT_GT(0, memcmp("\0ab", "\0ac", 3));
- EXPECT_GT(0, memcmp("abb\0", "abba", 4));
- EXPECT_LT(0, memcmp("ab\0cd", "ab\0c\0", 5));
- EXPECT_LT(0, memcmp("zza", "zyx", 3));
-}
-
-typedef int(*PointerToStrCmp)(const char*, const char*);
-void RunStrCmpTest(PointerToStrCmp StrCmp) {
- size_t size = Ident(100);
- int fill = 'o';
- char *s1 = MallocAndMemsetString(size, fill);
- char *s2 = MallocAndMemsetString(size, fill);
- s1[size - 1] = '\0';
- s2[size - 1] = '\0';
- // Normal StrCmp calls
- Ident(StrCmp(s1, s2));
- Ident(StrCmp(s1, s2 + size - 1));
- Ident(StrCmp(s1 + size - 1, s2 + size - 1));
- // One of arguments points to not allocated memory.
- EXPECT_DEATH(Ident(StrCmp)(s1 - 1, s2), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(StrCmp)(s1, s2 - 1), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(StrCmp)(s1 + size, s2), RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(StrCmp)(s1, s2 + size), RightOOBReadMessage(0));
- // Hit unallocated memory and die.
- s1[size - 1] = fill;
- EXPECT_DEATH(Ident(StrCmp)(s1, s1), RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(StrCmp)(s1 + size - 1, s2), RightOOBReadMessage(0));
- free(s1);
- free(s2);
-}
-
-TEST(AddressSanitizer, StrCmpOOBTest) {
- RunStrCmpTest(&strcmp);
-}
-
-#if !defined(_WIN32) // no str[n]casecmp on Windows.
-TEST(AddressSanitizer, StrCaseCmpOOBTest) {
- RunStrCmpTest(&strcasecmp);
-}
-#endif
-
-typedef int(*PointerToStrNCmp)(const char*, const char*, size_t);
-void RunStrNCmpTest(PointerToStrNCmp StrNCmp) {
- size_t size = Ident(100);
- char *s1 = MallocAndMemsetString(size);
- char *s2 = MallocAndMemsetString(size);
- s1[size - 1] = '\0';
- s2[size - 1] = '\0';
- // Normal StrNCmp calls
- Ident(StrNCmp(s1, s2, size + 2));
- s1[size - 1] = 'z';
- s2[size - 1] = 'x';
- Ident(StrNCmp(s1 + size - 2, s2 + size - 2, size));
- s2[size - 1] = 'z';
- Ident(StrNCmp(s1 - 1, s2 - 1, 0));
- Ident(StrNCmp(s1 + size - 1, s2 + size - 1, 1));
- // One of arguments points to not allocated memory.
- EXPECT_DEATH(Ident(StrNCmp)(s1 - 1, s2, 1), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(StrNCmp)(s1, s2 - 1, 1), LeftOOBReadMessage(1));
- EXPECT_DEATH(Ident(StrNCmp)(s1 + size, s2, 1), RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(StrNCmp)(s1, s2 + size, 1), RightOOBReadMessage(0));
- // Hit unallocated memory and die.
- EXPECT_DEATH(Ident(StrNCmp)(s1 + 1, s2 + 1, size), RightOOBReadMessage(0));
- EXPECT_DEATH(Ident(StrNCmp)(s1 + size - 1, s2, 2), RightOOBReadMessage(0));
- free(s1);
- free(s2);
-}
-
-TEST(AddressSanitizer, StrNCmpOOBTest) {
- RunStrNCmpTest(&strncmp);
-}
-
-#if !defined(_WIN32) // no str[n]casecmp on Windows.
-TEST(AddressSanitizer, StrNCaseCmpOOBTest) {
- RunStrNCmpTest(&strncasecmp);
-}
-#endif
-
-TEST(AddressSanitizer, StrCatOOBTest) {
- // strcat() reads strlen(to) bytes from |to| before concatenating.
- size_t to_size = Ident(100);
- char *to = MallocAndMemsetString(to_size);
- to[0] = '\0';
- size_t from_size = Ident(20);
- char *from = MallocAndMemsetString(from_size);
- from[from_size - 1] = '\0';
- // Normal strcat calls.
- strcat(to, from);
- strcat(to, from);
- strcat(to + from_size, from + from_size - 2);
- // Passing an invalid pointer is an error even when concatenating an empty
- // string.
- EXPECT_DEATH(strcat(to - 1, from + from_size - 1), LeftOOBAccessMessage(1));
- // One of arguments points to not allocated memory.
- EXPECT_DEATH(strcat(to - 1, from), LeftOOBAccessMessage(1));
- EXPECT_DEATH(strcat(to, from - 1), LeftOOBReadMessage(1));
- EXPECT_DEATH(strcat(to, from + from_size), RightOOBReadMessage(0));
-
- // "from" is not zero-terminated.
- from[from_size - 1] = 'z';
- EXPECT_DEATH(strcat(to, from), RightOOBReadMessage(0));
- from[from_size - 1] = '\0';
- // "to" is too short to fit "from".
- memset(to, 'z', to_size);
- to[to_size - from_size + 1] = '\0';
- EXPECT_DEATH(strcat(to, from), RightOOBWriteMessage(0));
- // length of "to" is just enough.
- strcat(to, from + 1);
-
- free(to);
- free(from);
-}
-
-TEST(AddressSanitizer, StrNCatOOBTest) {
- // strncat() reads strlen(to) bytes from |to| before concatenating.
- size_t to_size = Ident(100);
- char *to = MallocAndMemsetString(to_size);
- to[0] = '\0';
- size_t from_size = Ident(20);
- char *from = MallocAndMemsetString(from_size);
- // Normal strncat calls.
- strncat(to, from, 0);
- strncat(to, from, from_size);
- from[from_size - 1] = '\0';
- strncat(to, from, 2 * from_size);
- // Catenating empty string with an invalid string is still an error.
- EXPECT_DEATH(strncat(to - 1, from, 0), LeftOOBAccessMessage(1));
- strncat(to, from + from_size - 1, 10);
- // One of arguments points to not allocated memory.
- EXPECT_DEATH(strncat(to - 1, from, 2), LeftOOBAccessMessage(1));
- EXPECT_DEATH(strncat(to, from - 1, 2), LeftOOBReadMessage(1));
- EXPECT_DEATH(strncat(to, from + from_size, 2), RightOOBReadMessage(0));
-
- memset(from, 'z', from_size);
- memset(to, 'z', to_size);
- to[0] = '\0';
- // "from" is too short.
- EXPECT_DEATH(strncat(to, from, from_size + 1), RightOOBReadMessage(0));
- // "to" is too short to fit "from".
- to[0] = 'z';
- to[to_size - from_size + 1] = '\0';
- EXPECT_DEATH(strncat(to, from, from_size - 1), RightOOBWriteMessage(0));
- // "to" is just enough.
- strncat(to, from, from_size - 2);
-
- free(to);
- free(from);
-}
-
-static string OverlapErrorMessage(const string &func) {
- return func + "-param-overlap";
-}
-
-TEST(AddressSanitizer, StrArgsOverlapTest) {
- size_t size = Ident(100);
- char *str = Ident((char*)malloc(size));
-
-// Do not check memcpy() on OS X 10.7 and later, where it actually aliases
-// memmove().
-#if !defined(__APPLE__) || !defined(MAC_OS_X_VERSION_10_7) || \
- (MAC_OS_X_VERSION_MAX_ALLOWED < MAC_OS_X_VERSION_10_7)
- // Check "memcpy". Use Ident() to avoid inlining.
-#if PLATFORM_HAS_DIFFERENT_MEMCPY_AND_MEMMOVE
- memset(str, 'z', size);
- Ident(memcpy)(str + 1, str + 11, 10);
- Ident(memcpy)(str, str, 0);
- EXPECT_DEATH(Ident(memcpy)(str, str + 14, 15), OverlapErrorMessage("memcpy"));
- EXPECT_DEATH(Ident(memcpy)(str + 14, str, 15), OverlapErrorMessage("memcpy"));
-#endif
-#endif
-
- // We do not treat memcpy with to==from as a bug.
- // See http://llvm.org/bugs/show_bug.cgi?id=11763.
- // EXPECT_DEATH(Ident(memcpy)(str + 20, str + 20, 1),
- // OverlapErrorMessage("memcpy"));
-
- // Check "strcpy".
- memset(str, 'z', size);
- str[9] = '\0';
- strcpy(str + 10, str);
- EXPECT_DEATH(strcpy(str + 9, str), OverlapErrorMessage("strcpy"));
- EXPECT_DEATH(strcpy(str, str + 4), OverlapErrorMessage("strcpy"));
- strcpy(str, str + 5);
-
- // Check "strncpy".
- memset(str, 'z', size);
- strncpy(str, str + 10, 10);
- EXPECT_DEATH(strncpy(str, str + 9, 10), OverlapErrorMessage("strncpy"));
- EXPECT_DEATH(strncpy(str + 9, str, 10), OverlapErrorMessage("strncpy"));
- str[10] = '\0';
- strncpy(str + 11, str, 20);
- EXPECT_DEATH(strncpy(str + 10, str, 20), OverlapErrorMessage("strncpy"));
-
- // Check "strcat".
- memset(str, 'z', size);
- str[10] = '\0';
- str[20] = '\0';
- strcat(str, str + 10);
- EXPECT_DEATH(strcat(str, str + 11), OverlapErrorMessage("strcat"));
- str[10] = '\0';
- strcat(str + 11, str);
- EXPECT_DEATH(strcat(str, str + 9), OverlapErrorMessage("strcat"));
- EXPECT_DEATH(strcat(str + 9, str), OverlapErrorMessage("strcat"));
- EXPECT_DEATH(strcat(str + 10, str), OverlapErrorMessage("strcat"));
-
- // Check "strncat".
- memset(str, 'z', size);
- str[10] = '\0';
- strncat(str, str + 10, 10); // from is empty
- EXPECT_DEATH(strncat(str, str + 11, 10), OverlapErrorMessage("strncat"));
- str[10] = '\0';
- str[20] = '\0';
- strncat(str + 5, str, 5);
- str[10] = '\0';
- EXPECT_DEATH(strncat(str + 5, str, 6), OverlapErrorMessage("strncat"));
- EXPECT_DEATH(strncat(str, str + 9, 10), OverlapErrorMessage("strncat"));
-
- free(str);
-}
-
-typedef void(*PointerToCallAtoi)(const char*);
-
-void RunAtoiOOBTest(PointerToCallAtoi Atoi) {
- char *array = MallocAndMemsetString(10, '1');
- // Invalid pointer to the string.
- EXPECT_DEATH(Atoi(array + 11), RightOOBReadMessage(1));
- EXPECT_DEATH(Atoi(array - 1), LeftOOBReadMessage(1));
- // Die if a buffer doesn't have terminating NULL.
- EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));
- // Make last symbol a terminating NULL
- array[9] = '\0';
- Atoi(array);
- // Sometimes we need to detect overflow if no digits are found.
- memset(array, ' ', 10);
- EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));
- array[9] = '-';
- EXPECT_DEATH(Atoi(array), RightOOBReadMessage(0));
- EXPECT_DEATH(Atoi(array + 9), RightOOBReadMessage(0));
- free(array);
-}
-
-#if !defined(_WIN32) // FIXME: Fix and enable on Windows.
-void CallAtoi(const char *nptr) {
- Ident(atoi(nptr));
-}
-void CallAtol(const char *nptr) {
- Ident(atol(nptr));
-}
-void CallAtoll(const char *nptr) {
- Ident(atoll(nptr));
-}
-TEST(AddressSanitizer, AtoiAndFriendsOOBTest) {
- RunAtoiOOBTest(&CallAtoi);
- RunAtoiOOBTest(&CallAtol);
- RunAtoiOOBTest(&CallAtoll);
-}
-#endif
-
-typedef void(*PointerToCallStrtol)(const char*, char**, int);
-
-void RunStrtolOOBTest(PointerToCallStrtol Strtol) {
- char *array = MallocAndMemsetString(3);
- array[0] = '1';
- array[1] = '2';
- array[2] = '3';
- // Invalid pointer to the string.
- EXPECT_DEATH(Strtol(array + 3, NULL, 0), RightOOBReadMessage(0));
- EXPECT_DEATH(Strtol(array - 1, NULL, 0), LeftOOBReadMessage(1));
- // Buffer overflow if there is no terminating null (depends on base).
- EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
- array[2] = 'z';
- EXPECT_DEATH(Strtol(array, NULL, 36), RightOOBReadMessage(0));
- // Add terminating zero to get rid of overflow.
- array[2] = '\0';
- Strtol(array, NULL, 36);
- // Sometimes we need to detect overflow if no digits are found.
- array[0] = array[1] = array[2] = ' ';
- EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
- array[2] = '+';
- EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
- array[2] = '-';
- EXPECT_DEATH(Strtol(array, NULL, 0), RightOOBReadMessage(0));
- free(array);
-}
-
-#if !defined(_WIN32) // FIXME: Fix and enable on Windows.
-void CallStrtol(const char *nptr, char **endptr, int base) {
- Ident(strtol(nptr, endptr, base));
-}
-void CallStrtoll(const char *nptr, char **endptr, int base) {
- Ident(strtoll(nptr, endptr, base));
-}
-TEST(AddressSanitizer, StrtollOOBTest) {
- RunStrtolOOBTest(&CallStrtoll);
-}
-TEST(AddressSanitizer, StrtolOOBTest) {
- RunStrtolOOBTest(&CallStrtol);
-}
-#endif
diff --git a/lib/asan/tests/asan_test.cc b/lib/asan/tests/asan_test.cc
deleted file mode 100644
index 464e99f614d5b..0000000000000
--- a/lib/asan/tests/asan_test.cc
+++ /dev/null
@@ -1,1363 +0,0 @@
-//===-- asan_test.cc ------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-//===----------------------------------------------------------------------===//
-#include "asan_test_utils.h"
-
-#include <errno.h>
-#include <stdarg.h>
-
-#ifdef _LIBCPP_GET_C_LOCALE
-#define SANITIZER_GET_C_LOCALE _LIBCPP_GET_C_LOCALE
-#else
-#if defined(__FreeBSD__)
-#define SANITIZER_GET_C_LOCALE 0
-#elif defined(__NetBSD__)
-#define SANITIZER_GET_C_LOCALE LC_C_LOCALE
-#endif
-#endif
-
-#if defined(__sun__) && defined(__svr4__)
-using std::_setjmp;
-using std::_longjmp;
-#endif
-
-NOINLINE void *malloc_fff(size_t size) {
- void *res = malloc/**/(size); break_optimization(0); return res;}
-NOINLINE void *malloc_eee(size_t size) {
- void *res = malloc_fff(size); break_optimization(0); return res;}
-NOINLINE void *malloc_ddd(size_t size) {
- void *res = malloc_eee(size); break_optimization(0); return res;}
-NOINLINE void *malloc_ccc(size_t size) {
- void *res = malloc_ddd(size); break_optimization(0); return res;}
-NOINLINE void *malloc_bbb(size_t size) {
- void *res = malloc_ccc(size); break_optimization(0); return res;}
-NOINLINE void *malloc_aaa(size_t size) {
- void *res = malloc_bbb(size); break_optimization(0); return res;}
-
-NOINLINE void free_ccc(void *p) { free(p); break_optimization(0);}
-NOINLINE void free_bbb(void *p) { free_ccc(p); break_optimization(0);}
-NOINLINE void free_aaa(void *p) { free_bbb(p); break_optimization(0);}
-
-template<typename T>
-NOINLINE void uaf_test(int size, int off) {
- void *p = malloc_aaa(size);
- free_aaa(p);
- for (int i = 1; i < 100; i++)
- free_aaa(malloc_aaa(i));
- fprintf(stderr, "writing %ld byte(s) at %p with offset %d\n",
- (long)sizeof(T), p, off);
- asan_write((T *)((char *)p + off));
-}
-
-TEST(AddressSanitizer, HasFeatureAddressSanitizerTest) {
-#if defined(__has_feature) && __has_feature(address_sanitizer)
- bool asan = 1;
-#elif defined(__SANITIZE_ADDRESS__)
- bool asan = 1;
-#else
- bool asan = 0;
-#endif
- EXPECT_EQ(true, asan);
-}
-
-TEST(AddressSanitizer, SimpleDeathTest) {
- EXPECT_DEATH(exit(1), "");
-}
-
-TEST(AddressSanitizer, VariousMallocsTest) {
- int *a = (int*)malloc(100 * sizeof(int));
- a[50] = 0;
- free(a);
-
- int *r = (int*)malloc(10);
- r = (int*)realloc(r, 2000 * sizeof(int));
- r[1000] = 0;
- free(r);
-
- int *b = new int[100];
- b[50] = 0;
- delete [] b;
-
- int *c = new int;
- *c = 0;
- delete c;
-
-#if SANITIZER_TEST_HAS_POSIX_MEMALIGN
- void *pm = 0;
- // Valid allocation.
- int pm_res = posix_memalign(&pm, kPageSize, kPageSize);
- EXPECT_EQ(0, pm_res);
- EXPECT_NE(nullptr, pm);
- free(pm);
-#endif // SANITIZER_TEST_HAS_POSIX_MEMALIGN
-
-#if SANITIZER_TEST_HAS_MEMALIGN
- int *ma = (int*)memalign(kPageSize, kPageSize);
- EXPECT_EQ(0U, (uintptr_t)ma % kPageSize);
- ma[123] = 0;
- free(ma);
-#endif // SANITIZER_TEST_HAS_MEMALIGN
-}
-
-TEST(AddressSanitizer, CallocTest) {
- int *a = (int*)calloc(100, sizeof(int));
- EXPECT_EQ(0, a[10]);
- free(a);
-}
-
-TEST(AddressSanitizer, CallocReturnsZeroMem) {
- size_t sizes[] = {16, 1000, 10000, 100000, 2100000};
- for (size_t s = 0; s < sizeof(sizes)/sizeof(sizes[0]); s++) {
- size_t size = sizes[s];
- for (size_t iter = 0; iter < 5; iter++) {
- char *x = Ident((char*)calloc(1, size));
- EXPECT_EQ(x[0], 0);
- EXPECT_EQ(x[size - 1], 0);
- EXPECT_EQ(x[size / 2], 0);
- EXPECT_EQ(x[size / 3], 0);
- EXPECT_EQ(x[size / 4], 0);
- memset(x, 0x42, size);
- free(Ident(x));
-#if !defined(_WIN32)
- // FIXME: OOM on Windows. We should just make this a lit test
- // with quarantine size set to 1.
- free(Ident(malloc(Ident(1 << 27)))); // Try to drain the quarantine.
-#endif
- }
- }
-}
-
-// No valloc on Windows or Android.
-#if !defined(_WIN32) && !defined(__ANDROID__)
-TEST(AddressSanitizer, VallocTest) {
- void *a = valloc(100);
- EXPECT_EQ(0U, (uintptr_t)a % kPageSize);
- free(a);
-}
-#endif
-
-#if SANITIZER_TEST_HAS_PVALLOC
-TEST(AddressSanitizer, PvallocTest) {
- char *a = (char*)pvalloc(kPageSize + 100);
- EXPECT_EQ(0U, (uintptr_t)a % kPageSize);
- a[kPageSize + 101] = 1; // we should not report an error here.
- free(a);
-
- a = (char*)pvalloc(0); // pvalloc(0) should allocate at least one page.
- EXPECT_EQ(0U, (uintptr_t)a % kPageSize);
- a[101] = 1; // we should not report an error here.
- free(a);
-}
-#endif // SANITIZER_TEST_HAS_PVALLOC
-
-#if !defined(_WIN32)
-// FIXME: Use an equivalent of pthread_setspecific on Windows.
-void *TSDWorker(void *test_key) {
- if (test_key) {
- pthread_setspecific(*(pthread_key_t*)test_key, (void*)0xfeedface);
- }
- return NULL;
-}
-
-void TSDDestructor(void *tsd) {
- // Spawning a thread will check that the current thread id is not -1.
- pthread_t th;
- PTHREAD_CREATE(&th, NULL, TSDWorker, NULL);
- PTHREAD_JOIN(th, NULL);
-}
-
-// This tests triggers the thread-specific data destruction fiasco which occurs
-// if we don't manage the TSD destructors ourselves. We create a new pthread
-// key with a non-NULL destructor which is likely to be put after the destructor
-// of AsanThread in the list of destructors.
-// In this case the TSD for AsanThread will be destroyed before TSDDestructor
-// is called for the child thread, and a CHECK will fail when we call
-// pthread_create() to spawn the grandchild.
-TEST(AddressSanitizer, DISABLED_TSDTest) {
- pthread_t th;
- pthread_key_t test_key;
- pthread_key_create(&test_key, TSDDestructor);
- PTHREAD_CREATE(&th, NULL, TSDWorker, &test_key);
- PTHREAD_JOIN(th, NULL);
- pthread_key_delete(test_key);
-}
-#endif
-
-TEST(AddressSanitizer, UAF_char) {
- const char *uaf_string = "AddressSanitizer:.*heap-use-after-free";
- EXPECT_DEATH(uaf_test<U1>(1, 0), uaf_string);
- EXPECT_DEATH(uaf_test<U1>(10, 0), uaf_string);
- EXPECT_DEATH(uaf_test<U1>(10, 10), uaf_string);
- EXPECT_DEATH(uaf_test<U1>(kLargeMalloc, 0), uaf_string);
- EXPECT_DEATH(uaf_test<U1>(kLargeMalloc, kLargeMalloc / 2), uaf_string);
-}
-
-TEST(AddressSanitizer, UAF_long_double) {
- if (sizeof(long double) == sizeof(double)) return;
- long double *p = Ident(new long double[10]);
- EXPECT_DEATH(Ident(p)[12] = 0, "WRITE of size 1[026]");
- EXPECT_DEATH(Ident(p)[0] = Ident(p)[12], "READ of size 1[026]");
- delete [] Ident(p);
-}
-
-#if !defined(_WIN32)
-struct Packed5 {
- int x;
- char c;
-} __attribute__((packed));
-#else
-# pragma pack(push, 1)
-struct Packed5 {
- int x;
- char c;
-};
-# pragma pack(pop)
-#endif
-
-TEST(AddressSanitizer, UAF_Packed5) {
- static_assert(sizeof(Packed5) == 5, "Please check the keywords used");
- Packed5 *p = Ident(new Packed5[2]);
- EXPECT_DEATH(p[0] = p[3], "READ of size 5");
- EXPECT_DEATH(p[3] = p[0], "WRITE of size 5");
- delete [] Ident(p);
-}
-
-#if ASAN_HAS_BLACKLIST
-TEST(AddressSanitizer, IgnoreTest) {
- int *x = Ident(new int);
- delete Ident(x);
- *x = 0;
-}
-#endif // ASAN_HAS_BLACKLIST
-
-struct StructWithBitField {
- int bf1:1;
- int bf2:1;
- int bf3:1;
- int bf4:29;
-};
-
-TEST(AddressSanitizer, BitFieldPositiveTest) {
- StructWithBitField *x = new StructWithBitField;
- delete Ident(x);
- EXPECT_DEATH(x->bf1 = 0, "use-after-free");
- EXPECT_DEATH(x->bf2 = 0, "use-after-free");
- EXPECT_DEATH(x->bf3 = 0, "use-after-free");
- EXPECT_DEATH(x->bf4 = 0, "use-after-free");
-}
-
-struct StructWithBitFields_8_24 {
- int a:8;
- int b:24;
-};
-
-TEST(AddressSanitizer, BitFieldNegativeTest) {
- StructWithBitFields_8_24 *x = Ident(new StructWithBitFields_8_24);
- x->a = 0;
- x->b = 0;
- delete Ident(x);
-}
-
-#if ASAN_NEEDS_SEGV
-namespace {
-
-const char kSEGVCrash[] = "AddressSanitizer: SEGV on unknown address";
-const char kOverriddenSigactionHandler[] = "Test sigaction handler\n";
-const char kOverriddenSignalHandler[] = "Test signal handler\n";
-
-TEST(AddressSanitizer, WildAddressTest) {
- char *c = (char*)0x123;
- EXPECT_DEATH(*c = 0, kSEGVCrash);
-}
-
-void my_sigaction_sighandler(int, siginfo_t*, void*) {
- fprintf(stderr, kOverriddenSigactionHandler);
- exit(1);
-}
-
-void my_signal_sighandler(int signum) {
- fprintf(stderr, kOverriddenSignalHandler);
- exit(1);
-}
-
-TEST(AddressSanitizer, SignalTest) {
- struct sigaction sigact;
- memset(&sigact, 0, sizeof(sigact));
- sigact.sa_sigaction = my_sigaction_sighandler;
- sigact.sa_flags = SA_SIGINFO;
- char *c = (char *)0x123;
-
- EXPECT_DEATH(*c = 0, kSEGVCrash);
-
- // ASan should allow to set sigaction()...
- EXPECT_EQ(0, sigaction(SIGSEGV, &sigact, 0));
-#ifdef __APPLE__
- EXPECT_EQ(0, sigaction(SIGBUS, &sigact, 0));
-#endif
- EXPECT_DEATH(*c = 0, kOverriddenSigactionHandler);
-
- // ... and signal().
- EXPECT_NE(SIG_ERR, signal(SIGSEGV, my_signal_sighandler));
- EXPECT_DEATH(*c = 0, kOverriddenSignalHandler);
-}
-} // namespace
-#endif
-
-static void TestLargeMalloc(size_t size) {
- char buff[1024];
- sprintf(buff, "is located 1 bytes to the left of %lu-byte", (long)size);
- EXPECT_DEATH(Ident((char*)malloc(size))[-1] = 0, buff);
-}
-
-TEST(AddressSanitizer, LargeMallocTest) {
- const int max_size = (SANITIZER_WORDSIZE == 32) ? 1 << 26 : 1 << 28;
- for (int i = 113; i < max_size; i = i * 2 + 13) {
- TestLargeMalloc(i);
- }
-}
-
-#if !GTEST_USES_SIMPLE_RE
-TEST(AddressSanitizer, HugeMallocTest) {
- if (SANITIZER_WORDSIZE != 64 || ASAN_AVOID_EXPENSIVE_TESTS) return;
- size_t n_megs = 4100;
- EXPECT_DEATH(Ident((char*)malloc(n_megs << 20))[-1] = 0,
- "is located 1 bytes to the left|"
- "AddressSanitizer failed to allocate");
-}
-#endif
-
-#if SANITIZER_TEST_HAS_MEMALIGN
-void MemalignRun(size_t align, size_t size, int idx) {
- char *p = (char *)memalign(align, size);
- Ident(p)[idx] = 0;
- free(p);
-}
-
-TEST(AddressSanitizer, memalign) {
- for (int align = 16; align <= (1 << 23); align *= 2) {
- size_t size = align * 5;
- EXPECT_DEATH(MemalignRun(align, size, -1),
- "is located 1 bytes to the left");
- EXPECT_DEATH(MemalignRun(align, size, size + 1),
- "is located 1 bytes to the right");
- }
-}
-#endif // SANITIZER_TEST_HAS_MEMALIGN
-
-void *ManyThreadsWorker(void *a) {
- for (int iter = 0; iter < 100; iter++) {
- for (size_t size = 100; size < 2000; size *= 2) {
- free(Ident(malloc(size)));
- }
- }
- return 0;
-}
-
-#if !defined(__aarch64__) && !defined(__powerpc64__)
-// FIXME: Infinite loop in AArch64 (PR24389).
-// FIXME: Also occasional hang on powerpc. Maybe same problem as on AArch64?
-TEST(AddressSanitizer, ManyThreadsTest) {
- const size_t kNumThreads =
- (SANITIZER_WORDSIZE == 32 || ASAN_AVOID_EXPENSIVE_TESTS) ? 30 : 1000;
- pthread_t t[kNumThreads];
- for (size_t i = 0; i < kNumThreads; i++) {
- PTHREAD_CREATE(&t[i], 0, ManyThreadsWorker, (void*)i);
- }
- for (size_t i = 0; i < kNumThreads; i++) {
- PTHREAD_JOIN(t[i], 0);
- }
-}
-#endif
-
-TEST(AddressSanitizer, ReallocTest) {
- const int kMinElem = 5;
- int *ptr = (int*)malloc(sizeof(int) * kMinElem);
- ptr[3] = 3;
- for (int i = 0; i < 10000; i++) {
- ptr = (int*)realloc(ptr,
- (my_rand() % 1000 + kMinElem) * sizeof(int));
- EXPECT_EQ(3, ptr[3]);
- }
- free(ptr);
- // Realloc pointer returned by malloc(0).
- int *ptr2 = Ident((int*)malloc(0));
- ptr2 = Ident((int*)realloc(ptr2, sizeof(*ptr2)));
- *ptr2 = 42;
- EXPECT_EQ(42, *ptr2);
- free(ptr2);
-}
-
-TEST(AddressSanitizer, ReallocFreedPointerTest) {
- void *ptr = Ident(malloc(42));
- ASSERT_TRUE(NULL != ptr);
- free(ptr);
- EXPECT_DEATH(ptr = realloc(ptr, 77), "attempting double-free");
-}
-
-TEST(AddressSanitizer, ReallocInvalidPointerTest) {
- void *ptr = Ident(malloc(42));
- EXPECT_DEATH(ptr = realloc((int*)ptr + 1, 77), "attempting free.*not malloc");
- free(ptr);
-}
-
-TEST(AddressSanitizer, ZeroSizeMallocTest) {
- // Test that malloc(0) and similar functions don't return NULL.
- void *ptr = Ident(malloc(0));
- EXPECT_TRUE(NULL != ptr);
- free(ptr);
-#if SANITIZER_TEST_HAS_POSIX_MEMALIGN
- int pm_res = posix_memalign(&ptr, 1<<20, 0);
- EXPECT_EQ(0, pm_res);
- EXPECT_TRUE(NULL != ptr);
- free(ptr);
-#endif // SANITIZER_TEST_HAS_POSIX_MEMALIGN
- int *int_ptr = new int[0];
- int *int_ptr2 = new int[0];
- EXPECT_TRUE(NULL != int_ptr);
- EXPECT_TRUE(NULL != int_ptr2);
- EXPECT_NE(int_ptr, int_ptr2);
- delete[] int_ptr;
- delete[] int_ptr2;
-}
-
-#if SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE
-static const char *kMallocUsableSizeErrorMsg =
- "AddressSanitizer: attempting to call malloc_usable_size()";
-
-TEST(AddressSanitizer, MallocUsableSizeTest) {
- const size_t kArraySize = 100;
- char *array = Ident((char*)malloc(kArraySize));
- int *int_ptr = Ident(new int);
- EXPECT_EQ(0U, malloc_usable_size(NULL));
- EXPECT_EQ(kArraySize, malloc_usable_size(array));
- EXPECT_EQ(sizeof(int), malloc_usable_size(int_ptr));
- EXPECT_DEATH(malloc_usable_size((void*)0x123), kMallocUsableSizeErrorMsg);
- EXPECT_DEATH(malloc_usable_size(array + kArraySize / 2),
- kMallocUsableSizeErrorMsg);
- free(array);
- EXPECT_DEATH(malloc_usable_size(array), kMallocUsableSizeErrorMsg);
- delete int_ptr;
-}
-#endif // SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE
-
-void WrongFree() {
- int *x = (int*)malloc(100 * sizeof(int));
- // Use the allocated memory, otherwise Clang will optimize it out.
- Ident(x);
- free(x + 1);
-}
-
-#if !defined(_WIN32) // FIXME: This should be a lit test.
-TEST(AddressSanitizer, WrongFreeTest) {
- EXPECT_DEATH(WrongFree(), ASAN_PCRE_DOTALL
- "ERROR: AddressSanitizer: attempting free.*not malloc"
- ".*is located 4 bytes inside of 400-byte region"
- ".*allocated by thread");
-}
-#endif
-
-void DoubleFree() {
- int *x = (int*)malloc(100 * sizeof(int));
- fprintf(stderr, "DoubleFree: x=%p\n", (void *)x);
- free(x);
- free(x);
- fprintf(stderr, "should have failed in the second free(%p)\n", (void *)x);
- abort();
-}
-
-#if !defined(_WIN32) // FIXME: This should be a lit test.
-TEST(AddressSanitizer, DoubleFreeTest) {
- EXPECT_DEATH(DoubleFree(), ASAN_PCRE_DOTALL
- "ERROR: AddressSanitizer: attempting double-free"
- ".*is located 0 bytes inside of 400-byte region"
- ".*freed by thread T0 here"
- ".*previously allocated by thread T0 here");
-}
-#endif
-
-template<int kSize>
-NOINLINE void SizedStackTest() {
- char a[kSize];
- char *A = Ident((char*)&a);
- const char *expected_death = "AddressSanitizer: stack-buffer-";
- for (size_t i = 0; i < kSize; i++)
- A[i] = i;
- EXPECT_DEATH(A[-1] = 0, expected_death);
- EXPECT_DEATH(A[-5] = 0, expected_death);
- EXPECT_DEATH(A[kSize] = 0, expected_death);
- EXPECT_DEATH(A[kSize + 1] = 0, expected_death);
- EXPECT_DEATH(A[kSize + 5] = 0, expected_death);
- if (kSize > 16)
- EXPECT_DEATH(A[kSize + 31] = 0, expected_death);
-}
-
-TEST(AddressSanitizer, SimpleStackTest) {
- SizedStackTest<1>();
- SizedStackTest<2>();
- SizedStackTest<3>();
- SizedStackTest<4>();
- SizedStackTest<5>();
- SizedStackTest<6>();
- SizedStackTest<7>();
- SizedStackTest<16>();
- SizedStackTest<25>();
- SizedStackTest<34>();
- SizedStackTest<43>();
- SizedStackTest<51>();
- SizedStackTest<62>();
- SizedStackTest<64>();
- SizedStackTest<128>();
-}
-
-#if !defined(_WIN32)
-// FIXME: It's a bit hard to write multi-line death test expectations
-// in a portable way. Anyways, this should just be turned into a lit test.
-TEST(AddressSanitizer, ManyStackObjectsTest) {
- char XXX[10];
- char YYY[20];
- char ZZZ[30];
- Ident(XXX);
- Ident(YYY);
- EXPECT_DEATH(Ident(ZZZ)[-1] = 0, ASAN_PCRE_DOTALL "XXX.*YYY.*ZZZ");
-}
-#endif
-
-#if 0 // This test requires online symbolizer.
-// Moved to lit_tests/stack-oob-frames.cc.
-// Reenable here once we have online symbolizer by default.
-NOINLINE static void Frame0(int frame, char *a, char *b, char *c) {
- char d[4] = {0};
- char *D = Ident(d);
- switch (frame) {
- case 3: a[5]++; break;
- case 2: b[5]++; break;
- case 1: c[5]++; break;
- case 0: D[5]++; break;
- }
-}
-NOINLINE static void Frame1(int frame, char *a, char *b) {
- char c[4] = {0}; Frame0(frame, a, b, c);
- break_optimization(0);
-}
-NOINLINE static void Frame2(int frame, char *a) {
- char b[4] = {0}; Frame1(frame, a, b);
- break_optimization(0);
-}
-NOINLINE static void Frame3(int frame) {
- char a[4] = {0}; Frame2(frame, a);
- break_optimization(0);
-}
-
-TEST(AddressSanitizer, GuiltyStackFrame0Test) {
- EXPECT_DEATH(Frame3(0), "located .*in frame <.*Frame0");
-}
-TEST(AddressSanitizer, GuiltyStackFrame1Test) {
- EXPECT_DEATH(Frame3(1), "located .*in frame <.*Frame1");
-}
-TEST(AddressSanitizer, GuiltyStackFrame2Test) {
- EXPECT_DEATH(Frame3(2), "located .*in frame <.*Frame2");
-}
-TEST(AddressSanitizer, GuiltyStackFrame3Test) {
- EXPECT_DEATH(Frame3(3), "located .*in frame <.*Frame3");
-}
-#endif
-
-NOINLINE void LongJmpFunc1(jmp_buf buf) {
- // create three red zones for these two stack objects.
- int a;
- int b;
-
- int *A = Ident(&a);
- int *B = Ident(&b);
- *A = *B;
- longjmp(buf, 1);
-}
-
-NOINLINE void TouchStackFunc() {
- int a[100]; // long array will intersect with redzones from LongJmpFunc1.
- int *A = Ident(a);
- for (int i = 0; i < 100; i++)
- A[i] = i*i;
-}
-
-// Test that we handle longjmp and do not report false positives on stack.
-TEST(AddressSanitizer, LongJmpTest) {
- static jmp_buf buf;
- if (!setjmp(buf)) {
- LongJmpFunc1(buf);
- } else {
- TouchStackFunc();
- }
-}
-
-#if !defined(_WIN32) // Only basic longjmp is available on Windows.
-NOINLINE void UnderscopeLongJmpFunc1(jmp_buf buf) {
- // create three red zones for these two stack objects.
- int a;
- int b;
-
- int *A = Ident(&a);
- int *B = Ident(&b);
- *A = *B;
- _longjmp(buf, 1);
-}
-
-NOINLINE void SigLongJmpFunc1(sigjmp_buf buf) {
- // create three red zones for these two stack objects.
- int a;
- int b;
-
- int *A = Ident(&a);
- int *B = Ident(&b);
- *A = *B;
- siglongjmp(buf, 1);
-}
-
-#if !defined(__ANDROID__) && !defined(__arm__) && \
- !defined(__aarch64__) && !defined(__mips__) && \
- !defined(__mips64) && !defined(__s390__)
-NOINLINE void BuiltinLongJmpFunc1(jmp_buf buf) {
- // create three red zones for these two stack objects.
- int a;
- int b;
-
- int *A = Ident(&a);
- int *B = Ident(&b);
- *A = *B;
- __builtin_longjmp((void**)buf, 1);
-}
-
-// Does not work on ARM:
-// https://github.com/google/sanitizers/issues/185
-TEST(AddressSanitizer, BuiltinLongJmpTest) {
- static jmp_buf buf;
- if (!__builtin_setjmp((void**)buf)) {
- BuiltinLongJmpFunc1(buf);
- } else {
- TouchStackFunc();
- }
-}
-#endif // !defined(__ANDROID__) && !defined(__arm__) &&
- // !defined(__aarch64__) && !defined(__mips__)
- // !defined(__mips64) && !defined(__s390__)
-
-TEST(AddressSanitizer, UnderscopeLongJmpTest) {
- static jmp_buf buf;
- if (!_setjmp(buf)) {
- UnderscopeLongJmpFunc1(buf);
- } else {
- TouchStackFunc();
- }
-}
-
-TEST(AddressSanitizer, SigLongJmpTest) {
- static sigjmp_buf buf;
- if (!sigsetjmp(buf, 1)) {
- SigLongJmpFunc1(buf);
- } else {
- TouchStackFunc();
- }
-}
-#endif
-
-// FIXME: Why does clang-cl define __EXCEPTIONS?
-#if defined(__EXCEPTIONS) && !defined(_WIN32)
-NOINLINE void ThrowFunc() {
- // create three red zones for these two stack objects.
- int a;
- int b;
-
- int *A = Ident(&a);
- int *B = Ident(&b);
- *A = *B;
- ASAN_THROW(1);
-}
-
-TEST(AddressSanitizer, CxxExceptionTest) {
- if (ASAN_UAR) return;
- // TODO(kcc): this test crashes on 32-bit for some reason...
- if (SANITIZER_WORDSIZE == 32) return;
- try {
- ThrowFunc();
- } catch(...) {}
- TouchStackFunc();
-}
-#endif
-
-void *ThreadStackReuseFunc1(void *unused) {
- // create three red zones for these two stack objects.
- int a;
- int b;
-
- int *A = Ident(&a);
- int *B = Ident(&b);
- *A = *B;
- pthread_exit(0);
- return 0;
-}
-
-void *ThreadStackReuseFunc2(void *unused) {
- TouchStackFunc();
- return 0;
-}
-
-#if !defined(__thumb__)
-TEST(AddressSanitizer, ThreadStackReuseTest) {
- pthread_t t;
- PTHREAD_CREATE(&t, 0, ThreadStackReuseFunc1, 0);
- PTHREAD_JOIN(t, 0);
- PTHREAD_CREATE(&t, 0, ThreadStackReuseFunc2, 0);
- PTHREAD_JOIN(t, 0);
-}
-#endif
-
-#if defined(__SSE2__)
-#include <emmintrin.h>
-TEST(AddressSanitizer, Store128Test) {
- char *a = Ident((char*)malloc(Ident(12)));
- char *p = a;
- if (((uintptr_t)a % 16) != 0)
- p = a + 8;
- assert(((uintptr_t)p % 16) == 0);
- __m128i value_wide = _mm_set1_epi16(0x1234);
- EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide),
- "AddressSanitizer: heap-buffer-overflow");
- EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide),
- "WRITE of size 16");
- EXPECT_DEATH(_mm_store_si128((__m128i*)p, value_wide),
- "located 0 bytes to the right of 12-byte");
- free(a);
-}
-#endif
-
-// FIXME: All tests that use this function should be turned into lit tests.
-string RightOOBErrorMessage(int oob_distance, bool is_write) {
- assert(oob_distance >= 0);
- char expected_str[100];
- sprintf(expected_str, ASAN_PCRE_DOTALL
-#if !GTEST_USES_SIMPLE_RE
- "buffer-overflow.*%s.*"
-#endif
- "located %d bytes to the right",
-#if !GTEST_USES_SIMPLE_RE
- is_write ? "WRITE" : "READ",
-#endif
- oob_distance);
- return string(expected_str);
-}
-
-string RightOOBWriteMessage(int oob_distance) {
- return RightOOBErrorMessage(oob_distance, /*is_write*/true);
-}
-
-string RightOOBReadMessage(int oob_distance) {
- return RightOOBErrorMessage(oob_distance, /*is_write*/false);
-}
-
-// FIXME: All tests that use this function should be turned into lit tests.
-string LeftOOBErrorMessage(int oob_distance, bool is_write) {
- assert(oob_distance > 0);
- char expected_str[100];
- sprintf(expected_str,
-#if !GTEST_USES_SIMPLE_RE
- ASAN_PCRE_DOTALL "%s.*"
-#endif
- "located %d bytes to the left",
-#if !GTEST_USES_SIMPLE_RE
- is_write ? "WRITE" : "READ",
-#endif
- oob_distance);
- return string(expected_str);
-}
-
-string LeftOOBWriteMessage(int oob_distance) {
- return LeftOOBErrorMessage(oob_distance, /*is_write*/true);
-}
-
-string LeftOOBReadMessage(int oob_distance) {
- return LeftOOBErrorMessage(oob_distance, /*is_write*/false);
-}
-
-string LeftOOBAccessMessage(int oob_distance) {
- assert(oob_distance > 0);
- char expected_str[100];
- sprintf(expected_str, "located %d bytes to the left", oob_distance);
- return string(expected_str);
-}
-
-char* MallocAndMemsetString(size_t size, char ch) {
- char *s = Ident((char*)malloc(size));
- memset(s, ch, size);
- return s;
-}
-
-char* MallocAndMemsetString(size_t size) {
- return MallocAndMemsetString(size, 'z');
-}
-
-#if defined(__linux__) && !defined(__ANDROID__)
-#define READ_TEST(READ_N_BYTES) \
- char *x = new char[10]; \
- int fd = open("/proc/self/stat", O_RDONLY); \
- ASSERT_GT(fd, 0); \
- EXPECT_DEATH(READ_N_BYTES, \
- ASAN_PCRE_DOTALL \
- "AddressSanitizer: heap-buffer-overflow" \
- ".* is located 0 bytes to the right of 10-byte region"); \
- close(fd); \
- delete [] x; \
-
-TEST(AddressSanitizer, pread) {
- READ_TEST(pread(fd, x, 15, 0));
-}
-
-TEST(AddressSanitizer, pread64) {
- READ_TEST(pread64(fd, x, 15, 0));
-}
-
-TEST(AddressSanitizer, read) {
- READ_TEST(read(fd, x, 15));
-}
-#endif // defined(__linux__) && !defined(__ANDROID__)
-
-// This test case fails
-// Clang optimizes memcpy/memset calls which lead to unaligned access
-TEST(AddressSanitizer, DISABLED_MemIntrinsicUnalignedAccessTest) {
- int size = Ident(4096);
- char *s = Ident((char*)malloc(size));
- EXPECT_DEATH(memset(s + size - 1, 0, 2), RightOOBWriteMessage(0));
- free(s);
-}
-
-NOINLINE static int LargeFunction(bool do_bad_access) {
- int *x = new int[100];
- x[0]++;
- x[1]++;
- x[2]++;
- x[3]++;
- x[4]++;
- x[5]++;
- x[6]++;
- x[7]++;
- x[8]++;
- x[9]++;
-
- x[do_bad_access ? 100 : 0]++; int res = __LINE__;
-
- x[10]++;
- x[11]++;
- x[12]++;
- x[13]++;
- x[14]++;
- x[15]++;
- x[16]++;
- x[17]++;
- x[18]++;
- x[19]++;
-
- delete[] x;
- return res;
-}
-
-// Test the we have correct debug info for the failing instruction.
-// This test requires the in-process symbolizer to be enabled by default.
-TEST(AddressSanitizer, DISABLED_LargeFunctionSymbolizeTest) {
- int failing_line = LargeFunction(false);
- char expected_warning[128];
- sprintf(expected_warning, "LargeFunction.*asan_test.*:%d", failing_line);
- EXPECT_DEATH(LargeFunction(true), expected_warning);
-}
-
-// Check that we unwind and symbolize correctly.
-TEST(AddressSanitizer, DISABLED_MallocFreeUnwindAndSymbolizeTest) {
- int *a = (int*)malloc_aaa(sizeof(int));
- *a = 1;
- free_aaa(a);
- EXPECT_DEATH(*a = 1, "free_ccc.*free_bbb.*free_aaa.*"
- "malloc_fff.*malloc_eee.*malloc_ddd");
-}
-
-static bool TryToSetThreadName(const char *name) {
-#if defined(__linux__) && defined(PR_SET_NAME)
- return 0 == prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0);
-#else
- return false;
-#endif
-}
-
-void *ThreadedTestAlloc(void *a) {
- EXPECT_EQ(true, TryToSetThreadName("AllocThr"));
- int **p = (int**)a;
- *p = new int;
- return 0;
-}
-
-void *ThreadedTestFree(void *a) {
- EXPECT_EQ(true, TryToSetThreadName("FreeThr"));
- int **p = (int**)a;
- delete *p;
- return 0;
-}
-
-void *ThreadedTestUse(void *a) {
- EXPECT_EQ(true, TryToSetThreadName("UseThr"));
- int **p = (int**)a;
- **p = 1;
- return 0;
-}
-
-void ThreadedTestSpawn() {
- pthread_t t;
- int *x;
- PTHREAD_CREATE(&t, 0, ThreadedTestAlloc, &x);
- PTHREAD_JOIN(t, 0);
- PTHREAD_CREATE(&t, 0, ThreadedTestFree, &x);
- PTHREAD_JOIN(t, 0);
- PTHREAD_CREATE(&t, 0, ThreadedTestUse, &x);
- PTHREAD_JOIN(t, 0);
-}
-
-#if !defined(_WIN32) // FIXME: This should be a lit test.
-TEST(AddressSanitizer, ThreadedTest) {
- EXPECT_DEATH(ThreadedTestSpawn(),
- ASAN_PCRE_DOTALL
- "Thread T.*created"
- ".*Thread T.*created"
- ".*Thread T.*created");
-}
-#endif
-
-void *ThreadedTestFunc(void *unused) {
- // Check if prctl(PR_SET_NAME) is supported. Return if not.
- if (!TryToSetThreadName("TestFunc"))
- return 0;
- EXPECT_DEATH(ThreadedTestSpawn(),
- ASAN_PCRE_DOTALL
- "WRITE .*thread T. .UseThr."
- ".*freed by thread T. .FreeThr. here:"
- ".*previously allocated by thread T. .AllocThr. here:"
- ".*Thread T. .UseThr. created by T.*TestFunc"
- ".*Thread T. .FreeThr. created by T"
- ".*Thread T. .AllocThr. created by T"
- "");
- return 0;
-}
-
-TEST(AddressSanitizer, ThreadNamesTest) {
- // Run ThreadedTestFunc in a separate thread because it tries to set a
- // thread name and we don't want to change the main thread's name.
- pthread_t t;
- PTHREAD_CREATE(&t, 0, ThreadedTestFunc, 0);
- PTHREAD_JOIN(t, 0);
-}
-
-#if ASAN_NEEDS_SEGV
-TEST(AddressSanitizer, ShadowGapTest) {
-#if SANITIZER_WORDSIZE == 32
- char *addr = (char*)0x23000000;
-#else
-# if defined(__powerpc64__)
- char *addr = (char*)0x024000800000;
-# elif defined(__s390x__)
- char *addr = (char*)0x11000000000000;
-# else
- char *addr = (char*)0x0000100000080000;
-# endif
-#endif
- EXPECT_DEATH(*addr = 1, "AddressSanitizer: (SEGV|BUS) on unknown");
-}
-#endif // ASAN_NEEDS_SEGV
-
-extern "C" {
-NOINLINE static void UseThenFreeThenUse() {
- char *x = Ident((char*)malloc(8));
- *x = 1;
- free_aaa(x);
- *x = 2;
-}
-}
-
-TEST(AddressSanitizer, UseThenFreeThenUseTest) {
- EXPECT_DEATH(UseThenFreeThenUse(), "freed by thread");
-}
-
-TEST(AddressSanitizer, StrDupTest) {
- free(strdup(Ident("123")));
-}
-
-// Currently we create and poison redzone at right of global variables.
-static char static110[110];
-const char ConstGlob[7] = {1, 2, 3, 4, 5, 6, 7};
-static const char StaticConstGlob[3] = {9, 8, 7};
-
-TEST(AddressSanitizer, GlobalTest) {
- static char func_static15[15];
-
- static char fs1[10];
- static char fs2[10];
- static char fs3[10];
-
- glob5[Ident(0)] = 0;
- glob5[Ident(1)] = 0;
- glob5[Ident(2)] = 0;
- glob5[Ident(3)] = 0;
- glob5[Ident(4)] = 0;
-
- EXPECT_DEATH(glob5[Ident(5)] = 0,
- "0 bytes to the right of global variable.*glob5.* size 5");
- EXPECT_DEATH(glob5[Ident(5+6)] = 0,
- "6 bytes to the right of global variable.*glob5.* size 5");
- Ident(static110); // avoid optimizations
- static110[Ident(0)] = 0;
- static110[Ident(109)] = 0;
- EXPECT_DEATH(static110[Ident(110)] = 0,
- "0 bytes to the right of global variable");
- EXPECT_DEATH(static110[Ident(110+7)] = 0,
- "7 bytes to the right of global variable");
-
- Ident(func_static15); // avoid optimizations
- func_static15[Ident(0)] = 0;
- EXPECT_DEATH(func_static15[Ident(15)] = 0,
- "0 bytes to the right of global variable");
- EXPECT_DEATH(func_static15[Ident(15 + 9)] = 0,
- "9 bytes to the right of global variable");
-
- Ident(fs1);
- Ident(fs2);
- Ident(fs3);
-
- // We don't create left redzones, so this is not 100% guaranteed to fail.
- // But most likely will.
- EXPECT_DEATH(fs2[Ident(-1)] = 0, "is located.*of global variable");
-
- EXPECT_DEATH(Ident(Ident(ConstGlob)[8]),
- "is located 1 bytes to the right of .*ConstGlob");
- EXPECT_DEATH(Ident(Ident(StaticConstGlob)[5]),
- "is located 2 bytes to the right of .*StaticConstGlob");
-
- // call stuff from another file.
- GlobalsTest(0);
-}
-
-TEST(AddressSanitizer, GlobalStringConstTest) {
- static const char *zoo = "FOOBAR123";
- const char *p = Ident(zoo);
- EXPECT_DEATH(Ident(p[15]), "is ascii string 'FOOBAR123'");
-}
-
-TEST(AddressSanitizer, FileNameInGlobalReportTest) {
- static char zoo[10];
- const char *p = Ident(zoo);
- // The file name should be present in the report.
- EXPECT_DEATH(Ident(p[15]), "zoo.*asan_test.");
-}
-
-int *ReturnsPointerToALocalObject() {
- int a = 0;
- return Ident(&a);
-}
-
-#if ASAN_UAR == 1
-TEST(AddressSanitizer, LocalReferenceReturnTest) {
- int *(*f)() = Ident(ReturnsPointerToALocalObject);
- int *p = f();
- // Call 'f' a few more times, 'p' should still be poisoned.
- for (int i = 0; i < 32; i++)
- f();
- EXPECT_DEATH(*p = 1, "AddressSanitizer: stack-use-after-return");
- EXPECT_DEATH(*p = 1, "is located.*in frame .*ReturnsPointerToALocal");
-}
-#endif
-
-template <int kSize>
-NOINLINE static void FuncWithStack() {
- char x[kSize];
- Ident(x)[0] = 0;
- Ident(x)[kSize-1] = 0;
-}
-
-static void LotsOfStackReuse() {
- int LargeStack[10000];
- Ident(LargeStack)[0] = 0;
- for (int i = 0; i < 10000; i++) {
- FuncWithStack<128 * 1>();
- FuncWithStack<128 * 2>();
- FuncWithStack<128 * 4>();
- FuncWithStack<128 * 8>();
- FuncWithStack<128 * 16>();
- FuncWithStack<128 * 32>();
- FuncWithStack<128 * 64>();
- FuncWithStack<128 * 128>();
- FuncWithStack<128 * 256>();
- FuncWithStack<128 * 512>();
- Ident(LargeStack)[0] = 0;
- }
-}
-
-TEST(AddressSanitizer, StressStackReuseTest) {
- LotsOfStackReuse();
-}
-
-TEST(AddressSanitizer, ThreadedStressStackReuseTest) {
- const int kNumThreads = 20;
- pthread_t t[kNumThreads];
- for (int i = 0; i < kNumThreads; i++) {
- PTHREAD_CREATE(&t[i], 0, (void* (*)(void *x))LotsOfStackReuse, 0);
- }
- for (int i = 0; i < kNumThreads; i++) {
- PTHREAD_JOIN(t[i], 0);
- }
-}
-
-// pthread_exit tries to perform unwinding stuff that leads to dlopen'ing
-// libgcc_s.so. dlopen in its turn calls malloc to store "libgcc_s.so" string
-// that confuses LSan on Thumb because it fails to understand that this
-// allocation happens in dynamic linker and should be ignored.
-#if !defined(__thumb__)
-static void *PthreadExit(void *a) {
- pthread_exit(0);
- return 0;
-}
-
-TEST(AddressSanitizer, PthreadExitTest) {
- pthread_t t;
- for (int i = 0; i < 1000; i++) {
- PTHREAD_CREATE(&t, 0, PthreadExit, 0);
- PTHREAD_JOIN(t, 0);
- }
-}
-#endif
-
-// FIXME: Why does clang-cl define __EXCEPTIONS?
-#if defined(__EXCEPTIONS) && !defined(_WIN32)
-NOINLINE static void StackReuseAndException() {
- int large_stack[1000];
- Ident(large_stack);
- ASAN_THROW(1);
-}
-
-// TODO(kcc): support exceptions with use-after-return.
-TEST(AddressSanitizer, DISABLED_StressStackReuseAndExceptionsTest) {
- for (int i = 0; i < 10000; i++) {
- try {
- StackReuseAndException();
- } catch(...) {
- }
- }
-}
-#endif
-
-#if !defined(_WIN32)
-TEST(AddressSanitizer, MlockTest) {
- EXPECT_EQ(0, mlockall(MCL_CURRENT));
- EXPECT_EQ(0, mlock((void*)0x12345, 0x5678));
- EXPECT_EQ(0, munlockall());
- EXPECT_EQ(0, munlock((void*)0x987, 0x654));
-}
-#endif
-
-struct LargeStruct {
- int foo[100];
-};
-
-// Test for bug http://llvm.org/bugs/show_bug.cgi?id=11763.
-// Struct copy should not cause asan warning even if lhs == rhs.
-TEST(AddressSanitizer, LargeStructCopyTest) {
- LargeStruct a;
- *Ident(&a) = *Ident(&a);
-}
-
-ATTRIBUTE_NO_SANITIZE_ADDRESS
-static void NoSanitizeAddress() {
- char *foo = new char[10];
- Ident(foo)[10] = 0;
- delete [] foo;
-}
-
-TEST(AddressSanitizer, AttributeNoSanitizeAddressTest) {
- Ident(NoSanitizeAddress)();
-}
-
-// The new/delete/etc mismatch checks don't work on Android,
-// as calls to new/delete go through malloc/free.
-// OS X support is tracked here:
-// https://github.com/google/sanitizers/issues/131
-// Windows support is tracked here:
-// https://github.com/google/sanitizers/issues/309
-#if !defined(__ANDROID__) && \
- !defined(__APPLE__) && \
- !defined(_WIN32)
-static string MismatchStr(const string &str) {
- return string("AddressSanitizer: alloc-dealloc-mismatch \\(") + str;
-}
-
-static string MismatchOrNewDeleteTypeStr(const string &mismatch_str) {
- return "(" + MismatchStr(mismatch_str) +
- ")|(AddressSanitizer: new-delete-type-mismatch)";
-}
-
-TEST(AddressSanitizer, AllocDeallocMismatch) {
- EXPECT_DEATH(free(Ident(new int)),
- MismatchStr("operator new vs free"));
- EXPECT_DEATH(free(Ident(new int[2])),
- MismatchStr("operator new \\[\\] vs free"));
- EXPECT_DEATH(
- delete (Ident(new int[2])),
- MismatchOrNewDeleteTypeStr("operator new \\[\\] vs operator delete"));
- EXPECT_DEATH(delete (Ident((int *)malloc(2 * sizeof(int)))),
- MismatchOrNewDeleteTypeStr("malloc vs operator delete"));
- EXPECT_DEATH(delete [] (Ident(new int)),
- MismatchStr("operator new vs operator delete \\[\\]"));
- EXPECT_DEATH(delete [] (Ident((int*)malloc(2 * sizeof(int)))),
- MismatchStr("malloc vs operator delete \\[\\]"));
-}
-#endif
-
-// ------------------ demo tests; run each one-by-one -------------
-// e.g. --gtest_filter=*DemoOOBLeftHigh --gtest_also_run_disabled_tests
-TEST(AddressSanitizer, DISABLED_DemoThreadedTest) {
- ThreadedTestSpawn();
-}
-
-void *SimpleBugOnSTack(void *x = 0) {
- char a[20];
- Ident(a)[20] = 0;
- return 0;
-}
-
-TEST(AddressSanitizer, DISABLED_DemoStackTest) {
- SimpleBugOnSTack();
-}
-
-TEST(AddressSanitizer, DISABLED_DemoThreadStackTest) {
- pthread_t t;
- PTHREAD_CREATE(&t, 0, SimpleBugOnSTack, 0);
- PTHREAD_JOIN(t, 0);
-}
-
-TEST(AddressSanitizer, DISABLED_DemoUAFLowIn) {
- uaf_test<U1>(10, 0);
-}
-TEST(AddressSanitizer, DISABLED_DemoUAFLowLeft) {
- uaf_test<U1>(10, -2);
-}
-TEST(AddressSanitizer, DISABLED_DemoUAFLowRight) {
- uaf_test<U1>(10, 10);
-}
-
-TEST(AddressSanitizer, DISABLED_DemoUAFHigh) {
- uaf_test<U1>(kLargeMalloc, 0);
-}
-
-TEST(AddressSanitizer, DISABLED_DemoOOM) {
- size_t size = SANITIZER_WORDSIZE == 64 ? (size_t)(1ULL << 40) : (0xf0000000);
- printf("%p\n", malloc(size));
-}
-
-TEST(AddressSanitizer, DISABLED_DemoDoubleFreeTest) {
- DoubleFree();
-}
-
-TEST(AddressSanitizer, DISABLED_DemoNullDerefTest) {
- int *a = 0;
- Ident(a)[10] = 0;
-}
-
-TEST(AddressSanitizer, DISABLED_DemoFunctionStaticTest) {
- static char a[100];
- static char b[100];
- static char c[100];
- Ident(a);
- Ident(b);
- Ident(c);
- Ident(a)[5] = 0;
- Ident(b)[105] = 0;
- Ident(a)[5] = 0;
-}
-
-TEST(AddressSanitizer, DISABLED_DemoTooMuchMemoryTest) {
- const size_t kAllocSize = (1 << 28) - 1024;
- size_t total_size = 0;
- while (true) {
- void *x = malloc(kAllocSize);
- memset(x, 0, kAllocSize);
- total_size += kAllocSize;
- fprintf(stderr, "total: %ldM %p\n", (long)total_size >> 20, x);
- }
-}
-
-#if !defined(__NetBSD__) && !defined(__i386__)
-// https://github.com/google/sanitizers/issues/66
-TEST(AddressSanitizer, BufferOverflowAfterManyFrees) {
- for (int i = 0; i < 1000000; i++) {
- delete [] (Ident(new char [8644]));
- }
- char *x = new char[8192];
- EXPECT_DEATH(x[Ident(8192)] = 0, "AddressSanitizer: heap-buffer-overflow");
- delete [] Ident(x);
-}
-#endif
-
-
-// Test that instrumentation of stack allocations takes into account
-// AllocSize of a type, and not its StoreSize (16 vs 10 bytes for long double).
-// See http://llvm.org/bugs/show_bug.cgi?id=12047 for more details.
-TEST(AddressSanitizer, LongDoubleNegativeTest) {
- long double a, b;
- static long double c;
- memcpy(Ident(&a), Ident(&b), sizeof(long double));
- memcpy(Ident(&c), Ident(&b), sizeof(long double));
-}
-
-#if !defined(_WIN32)
-TEST(AddressSanitizer, pthread_getschedparam) {
- int policy;
- struct sched_param param;
- EXPECT_DEATH(
- pthread_getschedparam(pthread_self(), &policy, Ident(&param) + 2),
- "AddressSanitizer: stack-buffer-.*flow");
- EXPECT_DEATH(
- pthread_getschedparam(pthread_self(), Ident(&policy) - 1, &param),
- "AddressSanitizer: stack-buffer-.*flow");
- int res = pthread_getschedparam(pthread_self(), &policy, &param);
- ASSERT_EQ(0, res);
-}
-#endif
-
-#if SANITIZER_TEST_HAS_PRINTF_L
-static int vsnprintf_l_wrapper(char *s, size_t n,
- locale_t l, const char *format, ...) {
- va_list va;
- va_start(va, format);
- int res = vsnprintf_l(s, n , l, format, va);
- va_end(va);
- return res;
-}
-
-TEST(AddressSanitizer, snprintf_l) {
- char buff[5];
- // Check that snprintf_l() works fine with Asan.
- int res = snprintf_l(buff, 5, SANITIZER_GET_C_LOCALE, "%s", "snprintf_l()");
- EXPECT_EQ(12, res);
- // Check that vsnprintf_l() works fine with Asan.
- res = vsnprintf_l_wrapper(buff, 5, SANITIZER_GET_C_LOCALE, "%s",
- "vsnprintf_l()");
- EXPECT_EQ(13, res);
-
- EXPECT_DEATH(
- snprintf_l(buff, 10, SANITIZER_GET_C_LOCALE, "%s", "snprintf_l()"),
- "AddressSanitizer: stack-buffer-overflow");
- EXPECT_DEATH(vsnprintf_l_wrapper(buff, 10, SANITIZER_GET_C_LOCALE, "%s",
- "vsnprintf_l()"),
- "AddressSanitizer: stack-buffer-overflow");
-}
-#endif
diff --git a/lib/asan/tests/asan_test.ignore b/lib/asan/tests/asan_test.ignore
deleted file mode 100644
index ea5c26099e75c..0000000000000
--- a/lib/asan/tests/asan_test.ignore
+++ /dev/null
@@ -1,3 +0,0 @@
-# blacklisted functions for instrumented ASan unit test
-fun:*IgnoreTest*
-fun:*SomeOtherFunc*
diff --git a/lib/asan/tests/asan_test_config.h b/lib/asan/tests/asan_test_config.h
deleted file mode 100644
index 8493f41ef4dcc..0000000000000
--- a/lib/asan/tests/asan_test_config.h
+++ /dev/null
@@ -1,50 +0,0 @@
-//===-- asan_test_config.h --------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-//===----------------------------------------------------------------------===//
-#if !defined(INCLUDED_FROM_ASAN_TEST_UTILS_H)
-# error "This file should be included into asan_test_utils.h only"
-#endif
-
-#ifndef ASAN_TEST_CONFIG_H
-#define ASAN_TEST_CONFIG_H
-
-#include <string>
-
-using std::string;
-
-#ifndef ASAN_UAR
-# error "please define ASAN_UAR"
-#endif
-
-#ifndef ASAN_HAS_EXCEPTIONS
-# error "please define ASAN_HAS_EXCEPTIONS"
-#endif
-
-#ifndef ASAN_HAS_BLACKLIST
-# error "please define ASAN_HAS_BLACKLIST"
-#endif
-
-#ifndef ASAN_NEEDS_SEGV
-# if defined(_WIN32)
-# define ASAN_NEEDS_SEGV 0
-# else
-# define ASAN_NEEDS_SEGV 1
-# endif
-#endif
-
-#ifndef ASAN_AVOID_EXPENSIVE_TESTS
-# define ASAN_AVOID_EXPENSIVE_TESTS 0
-#endif
-
-#define ASAN_PCRE_DOTALL ""
-
-#endif // ASAN_TEST_CONFIG_H
diff --git a/lib/asan/tests/asan_test_main.cc b/lib/asan/tests/asan_test_main.cc
deleted file mode 100644
index 0c1b93c7fda7d..0000000000000
--- a/lib/asan/tests/asan_test_main.cc
+++ /dev/null
@@ -1,56 +0,0 @@
-//===-- asan_test_main.cc -------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-//===----------------------------------------------------------------------===//
-#include "asan_test_utils.h"
-#include "sanitizer_common/sanitizer_platform.h"
-
-// Default ASAN_OPTIONS for the unit tests.
-extern "C" const char* __asan_default_options() {
-#if SANITIZER_MAC
- // On Darwin, we default to `abort_on_error=1`, which would make tests run
- // much slower. Let's override this and run lit tests with 'abort_on_error=0'
- // and make sure we do not overwhelm the syslog while testing. Also, let's
- // turn symbolization off to speed up testing, especially when not running
- // with llvm-symbolizer but with atos.
- return "symbolize=false:abort_on_error=0:log_to_syslog=0";
-#elif SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT
- // On PowerPC and ARM Thumb, a couple tests involving pthread_exit fail due to
- // leaks detected by LSan. Symbolized leak report is required to apply a
- // suppression for this known problem.
- return "";
-#else
- // Let's turn symbolization off to speed up testing (more than 3 times speedup
- // observed).
- return "symbolize=false";
-#endif
-}
-
-namespace __sanitizer {
-bool ReexecDisabled() {
-#if __has_feature(address_sanitizer) && SANITIZER_MAC
- // Allow re-exec in instrumented unit tests on Darwin. Technically, we only
- // need this for 10.10 and below, where re-exec is required for the
- // interceptors to work, but to avoid duplicating the version detection logic,
- // let's just allow re-exec for all Darwin versions. On newer OS versions,
- // returning 'false' doesn't do anything anyway, because we don't re-exec.
- return false;
-#else
- return true;
-#endif
-}
-} // namespace __sanitizer
-
-int main(int argc, char **argv) {
- testing::GTEST_FLAG(death_test_style) = "threadsafe";
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/lib/asan/tests/asan_test_utils.h b/lib/asan/tests/asan_test_utils.h
deleted file mode 100644
index d7b6f82e29783..0000000000000
--- a/lib/asan/tests/asan_test_utils.h
+++ /dev/null
@@ -1,109 +0,0 @@
-//===-- asan_test_utils.h ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef ASAN_TEST_UTILS_H
-#define ASAN_TEST_UTILS_H
-
-#if !defined(SANITIZER_EXTERNAL_TEST_CONFIG)
-# define INCLUDED_FROM_ASAN_TEST_UTILS_H
-# include "asan_test_config.h"
-# undef INCLUDED_FROM_ASAN_TEST_UTILS_H
-#endif
-
-#include "sanitizer_test_utils.h"
-#include "sanitizer_pthread_wrappers.h"
-
-#include <stdio.h>
-#include <signal.h>
-#include <stdlib.h>
-#include <string.h>
-#include <stdint.h>
-#include <assert.h>
-#include <algorithm>
-#include <setjmp.h>
-
-#if !defined(_WIN32)
-# include <strings.h>
-# include <sys/mman.h>
-#endif
-
-#ifdef __linux__
-# include <sys/prctl.h>
-# include <sys/types.h>
-# include <sys/stat.h>
-# include <fcntl.h>
-#include <unistd.h>
-#endif
-
-#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__NetBSD__)
-#include <malloc.h>
-#endif
-
-#if ASAN_HAS_EXCEPTIONS
-# define ASAN_THROW(x) throw (x)
-#else
-# define ASAN_THROW(x)
-#endif
-
-typedef uint8_t U1;
-typedef uint16_t U2;
-typedef uint32_t U4;
-typedef uint64_t U8;
-
-static const int kPageSize = 4096;
-
-// Big enough to be handled by secondary allocator and small enough to fit into
-// quarantine for all configurations.
-const size_t kLargeMalloc = 1 << 22;
-
-extern void free_aaa(void *p);
-extern void *malloc_aaa(size_t size);
-
-template<typename T>
-NOINLINE void asan_write(T *a) {
- *a = 0;
-}
-
-string RightOOBErrorMessage(int oob_distance, bool is_write);
-string RightOOBWriteMessage(int oob_distance);
-string RightOOBReadMessage(int oob_distance);
-string LeftOOBErrorMessage(int oob_distance, bool is_write);
-string LeftOOBWriteMessage(int oob_distance);
-string LeftOOBReadMessage(int oob_distance);
-string LeftOOBAccessMessage(int oob_distance);
-char* MallocAndMemsetString(size_t size, char ch);
-char* MallocAndMemsetString(size_t size);
-
-extern char glob1[1];
-extern char glob2[2];
-extern char glob3[3];
-extern char glob4[4];
-extern char glob5[5];
-extern char glob6[6];
-extern char glob7[7];
-extern char glob8[8];
-extern char glob9[9];
-extern char glob10[10];
-extern char glob11[11];
-extern char glob12[12];
-extern char glob13[13];
-extern char glob14[14];
-extern char glob15[15];
-extern char glob16[16];
-extern char glob17[17];
-extern char glob1000[1000];
-extern char glob10000[10000];
-extern char glob100000[100000];
-extern int GlobalsTest(int x);
-
-#endif // ASAN_TEST_UTILS_H
diff --git a/lib/builtins/CMakeLists.txt b/lib/builtins/CMakeLists.txt
deleted file mode 100644
index 77947417bfed8..0000000000000
--- a/lib/builtins/CMakeLists.txt
+++ /dev/null
@@ -1,615 +0,0 @@
-# This directory contains a large amount of C code which provides
-# generic implementations of the core runtime library along with optimized
-# architecture-specific code in various subdirectories.
-
-if (CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR)
- cmake_minimum_required(VERSION 3.4.3)
-
- project(CompilerRTBuiltins C ASM)
- set(COMPILER_RT_STANDALONE_BUILD TRUE)
- set(COMPILER_RT_BUILTINS_STANDALONE_BUILD TRUE)
- list(INSERT CMAKE_MODULE_PATH 0
- "${CMAKE_SOURCE_DIR}/../../cmake"
- "${CMAKE_SOURCE_DIR}/../../cmake/Modules")
- include(base-config-ix)
- include(CompilerRTUtils)
-
- load_llvm_config()
- construct_compiler_rt_default_triple()
-
- if(APPLE)
- include(CompilerRTDarwinUtils)
- endif()
- include(AddCompilerRT)
-endif()
-
-include(builtin-config-ix)
-
-# TODO: Need to add a mechanism for logging errors when builtin source files are
-# added to a sub-directory and not this CMakeLists file.
-set(GENERIC_SOURCES
- absvdi2.c
- absvsi2.c
- absvti2.c
- adddf3.c
- addsf3.c
- addtf3.c
- addvdi3.c
- addvsi3.c
- addvti3.c
- apple_versioning.c
- ashldi3.c
- ashlti3.c
- ashrdi3.c
- ashrti3.c
- bswapdi2.c
- bswapsi2.c
- clzdi2.c
- clzsi2.c
- clzti2.c
- cmpdi2.c
- cmpti2.c
- comparedf2.c
- comparesf2.c
- ctzdi2.c
- ctzsi2.c
- ctzti2.c
- divdc3.c
- divdf3.c
- divdi3.c
- divmoddi4.c
- divmodsi4.c
- divsc3.c
- divsf3.c
- divsi3.c
- divtc3.c
- divti3.c
- divtf3.c
- extendsfdf2.c
- extendhfsf2.c
- ffsdi2.c
- ffssi2.c
- ffsti2.c
- fixdfdi.c
- fixdfsi.c
- fixdfti.c
- fixsfdi.c
- fixsfsi.c
- fixsfti.c
- fixunsdfdi.c
- fixunsdfsi.c
- fixunsdfti.c
- fixunssfdi.c
- fixunssfsi.c
- fixunssfti.c
- floatdidf.c
- floatdisf.c
- floatsidf.c
- floatsisf.c
- floattidf.c
- floattisf.c
- floatundidf.c
- floatundisf.c
- floatunsidf.c
- floatunsisf.c
- floatuntidf.c
- floatuntisf.c
- int_util.c
- lshrdi3.c
- lshrti3.c
- moddi3.c
- modsi3.c
- modti3.c
- muldc3.c
- muldf3.c
- muldi3.c
- mulodi4.c
- mulosi4.c
- muloti4.c
- mulsc3.c
- mulsf3.c
- multi3.c
- multf3.c
- mulvdi3.c
- mulvsi3.c
- mulvti3.c
- negdf2.c
- negdi2.c
- negsf2.c
- negti2.c
- negvdi2.c
- negvsi2.c
- negvti2.c
- os_version_check.c
- paritydi2.c
- paritysi2.c
- parityti2.c
- popcountdi2.c
- popcountsi2.c
- popcountti2.c
- powidf2.c
- powisf2.c
- powitf2.c
- subdf3.c
- subsf3.c
- subvdi3.c
- subvsi3.c
- subvti3.c
- subtf3.c
- trampoline_setup.c
- truncdfhf2.c
- truncdfsf2.c
- truncsfhf2.c
- ucmpdi2.c
- ucmpti2.c
- udivdi3.c
- udivmoddi4.c
- udivmodsi4.c
- udivmodti4.c
- udivsi3.c
- udivti3.c
- umoddi3.c
- umodsi3.c
- umodti3.c)
-
-set(GENERIC_TF_SOURCES
- comparetf2.c
- extenddftf2.c
- extendsftf2.c
- fixtfdi.c
- fixtfsi.c
- fixtfti.c
- fixunstfdi.c
- fixunstfsi.c
- fixunstfti.c
- floatditf.c
- floatsitf.c
- floattitf.c
- floatunditf.c
- floatunsitf.c
- floatuntitf.c
- multc3.c
- trunctfdf2.c
- trunctfsf2.c)
-
-option(COMPILER_RT_EXCLUDE_ATOMIC_BUILTIN
- "Skip the atomic builtin (these should normally be provided by a shared library)"
- On)
-
-if(NOT FUCHSIA AND NOT COMPILER_RT_BAREMETAL_BUILD)
- set(GENERIC_SOURCES
- ${GENERIC_SOURCES}
- emutls.c
- enable_execute_stack.c
- eprintf.c)
-endif()
-
-if(COMPILER_RT_HAS_ATOMIC_KEYWORD AND NOT COMPILER_RT_EXCLUDE_ATOMIC_BUILTIN)
- set(GENERIC_SOURCES
- ${GENERIC_SOURCES}
- atomic.c)
-endif()
-
-if(APPLE)
- set(GENERIC_SOURCES
- ${GENERIC_SOURCES}
- atomic_flag_clear.c
- atomic_flag_clear_explicit.c
- atomic_flag_test_and_set.c
- atomic_flag_test_and_set_explicit.c
- atomic_signal_fence.c
- atomic_thread_fence.c)
-endif()
-
-if (HAVE_UNWIND_H)
- set(GENERIC_SOURCES
- ${GENERIC_SOURCES}
- gcc_personality_v0.c)
-endif ()
-
-if (NOT FUCHSIA)
- set(GENERIC_SOURCES
- ${GENERIC_SOURCES}
- clear_cache.c)
-endif()
-
-# These sources work on all x86 variants, but only x86 variants.
-set(x86_ARCH_SOURCES
- cpu_model.c
- divxc3.c
- fixxfdi.c
- fixxfti.c
- fixunsxfdi.c
- fixunsxfsi.c
- fixunsxfti.c
- floatdixf.c
- floattixf.c
- floatundixf.c
- floatuntixf.c
- mulxc3.c
- powixf2.c
-)
-
-if (NOT MSVC)
- set(x86_64_SOURCES
- x86_64/floatdidf.c
- x86_64/floatdisf.c
- x86_64/floatdixf.c
- x86_64/floatundidf.S
- x86_64/floatundisf.S
- x86_64/floatundixf.S)
- filter_builtin_sources(x86_64_SOURCES EXCLUDE x86_64_SOURCES "${x86_64_SOURCES};${GENERIC_SOURCES}")
- set(x86_64h_SOURCES ${x86_64_SOURCES})
-
- if (WIN32)
- set(x86_64_SOURCES
- ${x86_64_SOURCES}
- x86_64/chkstk.S
- x86_64/chkstk2.S)
- endif()
-
- set(i386_SOURCES
- i386/ashldi3.S
- i386/ashrdi3.S
- i386/divdi3.S
- i386/floatdidf.S
- i386/floatdisf.S
- i386/floatdixf.S
- i386/floatundidf.S
- i386/floatundisf.S
- i386/floatundixf.S
- i386/lshrdi3.S
- i386/moddi3.S
- i386/muldi3.S
- i386/udivdi3.S
- i386/umoddi3.S)
- filter_builtin_sources(i386_SOURCES EXCLUDE i386_SOURCES "${i386_SOURCES};${GENERIC_SOURCES}")
-
- if (WIN32)
- set(i386_SOURCES
- ${i386_SOURCES}
- i386/chkstk.S
- i386/chkstk2.S)
- endif()
-else () # MSVC
- # Use C versions of functions when building on MSVC
- # MSVC's assembler takes Intel syntax, not AT&T syntax.
- # Also use only MSVC compilable builtin implementations.
- set(x86_64_SOURCES
- x86_64/floatdidf.c
- x86_64/floatdisf.c
- x86_64/floatdixf.c
- ${GENERIC_SOURCES})
- set(x86_64h_SOURCES ${x86_64_SOURCES})
- set(i386_SOURCES ${GENERIC_SOURCES})
-endif () # if (NOT MSVC)
-
-set(x86_64h_SOURCES ${x86_64h_SOURCES} ${x86_ARCH_SOURCES})
-set(x86_64_SOURCES ${x86_64_SOURCES} ${x86_ARCH_SOURCES})
-set(i386_SOURCES ${i386_SOURCES} ${x86_ARCH_SOURCES})
-set(i686_SOURCES ${i686_SOURCES} ${x86_ARCH_SOURCES})
-
-set(arm_SOURCES
- arm/bswapdi2.S
- arm/bswapsi2.S
- arm/clzdi2.S
- arm/clzsi2.S
- arm/comparesf2.S
- arm/divmodsi4.S
- arm/divsi3.S
- arm/modsi3.S
- arm/sync_fetch_and_add_4.S
- arm/sync_fetch_and_add_8.S
- arm/sync_fetch_and_and_4.S
- arm/sync_fetch_and_and_8.S
- arm/sync_fetch_and_max_4.S
- arm/sync_fetch_and_max_8.S
- arm/sync_fetch_and_min_4.S
- arm/sync_fetch_and_min_8.S
- arm/sync_fetch_and_nand_4.S
- arm/sync_fetch_and_nand_8.S
- arm/sync_fetch_and_or_4.S
- arm/sync_fetch_and_or_8.S
- arm/sync_fetch_and_sub_4.S
- arm/sync_fetch_and_sub_8.S
- arm/sync_fetch_and_umax_4.S
- arm/sync_fetch_and_umax_8.S
- arm/sync_fetch_and_umin_4.S
- arm/sync_fetch_and_umin_8.S
- arm/sync_fetch_and_xor_4.S
- arm/sync_fetch_and_xor_8.S
- arm/udivmodsi4.S
- arm/udivsi3.S
- arm/umodsi3.S)
-filter_builtin_sources(arm_SOURCES EXCLUDE arm_SOURCES "${arm_SOURCES};${GENERIC_SOURCES}")
-
-set(thumb1_SOURCES
- arm/divsi3.S
- arm/udivsi3.S
- arm/comparesf2.S
- arm/addsf3.S
- ${GENERIC_SOURCES})
-
-set(arm_EABI_SOURCES
- arm/aeabi_cdcmp.S
- arm/aeabi_cdcmpeq_check_nan.c
- arm/aeabi_cfcmp.S
- arm/aeabi_cfcmpeq_check_nan.c
- arm/aeabi_dcmp.S
- arm/aeabi_div0.c
- arm/aeabi_drsub.c
- arm/aeabi_fcmp.S
- arm/aeabi_frsub.c
- arm/aeabi_idivmod.S
- arm/aeabi_ldivmod.S
- arm/aeabi_memcmp.S
- arm/aeabi_memcpy.S
- arm/aeabi_memmove.S
- arm/aeabi_memset.S
- arm/aeabi_uidivmod.S
- arm/aeabi_uldivmod.S)
-
-set(arm_Thumb1_JT_SOURCES
- arm/switch16.S
- arm/switch32.S
- arm/switch8.S
- arm/switchu8.S)
-set(arm_Thumb1_SjLj_EH_SOURCES
- arm/restore_vfp_d8_d15_regs.S
- arm/save_vfp_d8_d15_regs.S)
-set(arm_Thumb1_VFPv2_SOURCES
- arm/adddf3vfp.S
- arm/addsf3vfp.S
- arm/divdf3vfp.S
- arm/divsf3vfp.S
- arm/eqdf2vfp.S
- arm/eqsf2vfp.S
- arm/extendsfdf2vfp.S
- arm/fixdfsivfp.S
- arm/fixsfsivfp.S
- arm/fixunsdfsivfp.S
- arm/fixunssfsivfp.S
- arm/floatsidfvfp.S
- arm/floatsisfvfp.S
- arm/floatunssidfvfp.S
- arm/floatunssisfvfp.S
- arm/gedf2vfp.S
- arm/gesf2vfp.S
- arm/gtdf2vfp.S
- arm/gtsf2vfp.S
- arm/ledf2vfp.S
- arm/lesf2vfp.S
- arm/ltdf2vfp.S
- arm/ltsf2vfp.S
- arm/muldf3vfp.S
- arm/mulsf3vfp.S
- arm/nedf2vfp.S
- arm/negdf2vfp.S
- arm/negsf2vfp.S
- arm/nesf2vfp.S
- arm/subdf3vfp.S
- arm/subsf3vfp.S
- arm/truncdfsf2vfp.S
- arm/unorddf2vfp.S
- arm/unordsf2vfp.S)
-set(arm_Thumb1_icache_SOURCES
- arm/sync_synchronize.S)
-set(arm_Thumb1_SOURCES
- ${arm_Thumb1_JT_SOURCES}
- ${arm_Thumb1_SjLj_EH_SOURCES}
- ${arm_Thumb1_VFPv2_SOURCES}
- ${arm_Thumb1_icache_SOURCES})
-
-if(MINGW)
- set(arm_SOURCES
- arm/aeabi_idivmod.S
- arm/aeabi_ldivmod.S
- arm/aeabi_uidivmod.S
- arm/aeabi_uldivmod.S
- arm/chkstk.S
- divmoddi4.c
- divmodsi4.c
- divdi3.c
- divsi3.c
- fixdfdi.c
- fixsfdi.c
- fixunsdfdi.c
- fixunssfdi.c
- floatdidf.c
- floatdisf.c
- floatundidf.c
- floatundisf.c
- mingw_fixfloat.c
- moddi3.c
- udivmoddi4.c
- udivmodsi4.c
- udivsi3.c
- umoddi3.c
- emutls.c)
- filter_builtin_sources(arm_SOURCES EXCLUDE arm_SOURCES "${arm_SOURCES};${GENERIC_SOURCES}")
-elseif(NOT WIN32)
- # TODO the EABI sources should only be added to EABI targets
- set(arm_SOURCES
- ${arm_SOURCES}
- ${arm_EABI_SOURCES}
- ${arm_Thumb1_SOURCES})
-
- set(thumb1_SOURCES
- ${thumb1_SOURCES}
- ${arm_EABI_SOURCES})
-endif()
-
-set(aarch64_SOURCES
- ${GENERIC_TF_SOURCES}
- ${GENERIC_SOURCES})
-
-if (MINGW)
- set(aarch64_SOURCES
- ${aarch64_SOURCES}
- aarch64/chkstk.S)
-endif()
-
-set(armhf_SOURCES ${arm_SOURCES})
-set(armv7_SOURCES ${arm_SOURCES})
-set(armv7s_SOURCES ${arm_SOURCES})
-set(armv7k_SOURCES ${arm_SOURCES})
-set(arm64_SOURCES ${aarch64_SOURCES})
-
-# macho_embedded archs
-set(armv6m_SOURCES ${thumb1_SOURCES})
-set(armv7m_SOURCES ${arm_SOURCES})
-set(armv7em_SOURCES ${arm_SOURCES})
-
-# hexagon arch
-set(hexagon_SOURCES ${GENERIC_SOURCES} ${GENERIC_TF_SOURCES})
-set(hexagon_SOURCES
- hexagon/common_entry_exit_abi1.S
- hexagon/common_entry_exit_abi2.S
- hexagon/common_entry_exit_legacy.S
- hexagon/dfaddsub.S
- hexagon/dfdiv.S
- hexagon/dffma.S
- hexagon/dfminmax.S
- hexagon/dfmul.S
- hexagon/dfsqrt.S
- hexagon/divdi3.S
- hexagon/divsi3.S
- hexagon/fabs_opt.S
- hexagon/fastmath2_dlib_asm.S
- hexagon/fastmath2_ldlib_asm.S
- hexagon/fastmath_dlib_asm.S
- hexagon/fma_opt.S
- hexagon/fmax_opt.S
- hexagon/fmin_opt.S
- hexagon/memcpy_forward_vp4cp4n2.S
- hexagon/memcpy_likely_aligned.S
- hexagon/moddi3.S
- hexagon/modsi3.S
- hexagon/sfdiv_opt.S
- hexagon/sfsqrt_opt.S
- hexagon/udivdi3.S
- hexagon/udivmoddi4.S
- hexagon/udivmodsi4.S
- hexagon/udivsi3.S
- hexagon/umoddi3.S
- hexagon/umodsi3.S)
-
-
-set(mips_SOURCES ${GENERIC_SOURCES})
-set(mipsel_SOURCES ${mips_SOURCES})
-set(mips64_SOURCES ${GENERIC_TF_SOURCES}
- ${mips_SOURCES})
-set(mips64el_SOURCES ${GENERIC_TF_SOURCES}
- ${mips_SOURCES})
-
-set(powerpc64_SOURCES
- ppc/divtc3.c
- ppc/fixtfdi.c
- ppc/fixunstfti.c
- ppc/fixunstfdi.c
- ppc/floattitf.c
- ppc/floatditf.c
- ppc/floatunditf.c
- ppc/gcc_qadd.c
- ppc/gcc_qdiv.c
- ppc/gcc_qmul.c
- ppc/gcc_qsub.c
- ppc/multc3.c
- ${GENERIC_SOURCES})
-set(powerpc64le_SOURCES ${powerpc64_SOURCES})
-
-set(riscv_SOURCES ${GENERIC_SOURCES} ${GENERIC_TF_SOURCES})
-set(riscv32_SOURCES
- riscv/mulsi3.S
- ${riscv_SOURCES})
-set(riscv64_SOURCES ${riscv_SOURCES})
-
-set(wasm32_SOURCES
- ${GENERIC_TF_SOURCES}
- ${GENERIC_SOURCES})
-set(wasm64_SOURCES
- ${GENERIC_TF_SOURCES}
- ${GENERIC_SOURCES})
-
-add_custom_target(builtins)
-set_target_properties(builtins PROPERTIES FOLDER "Compiler-RT Misc")
-
-if (APPLE)
- add_subdirectory(Darwin-excludes)
- add_subdirectory(macho_embedded)
- darwin_add_builtin_libraries(${BUILTIN_SUPPORTED_OS})
-else ()
- set(BUILTIN_CFLAGS "")
-
- append_list_if(COMPILER_RT_HAS_STD_C11_FLAG -std=c11 BUILTIN_CFLAGS)
-
- # These flags would normally be added to CMAKE_C_FLAGS by the llvm
- # cmake step. Add them manually if this is a standalone build.
- if(COMPILER_RT_STANDALONE_BUILD)
- append_list_if(COMPILER_RT_HAS_FPIC_FLAG -fPIC BUILTIN_CFLAGS)
- append_list_if(COMPILER_RT_HAS_FNO_BUILTIN_FLAG -fno-builtin BUILTIN_CFLAGS)
- append_list_if(COMPILER_RT_HAS_VISIBILITY_HIDDEN_FLAG -fvisibility=hidden BUILTIN_CFLAGS)
- if(NOT COMPILER_RT_DEBUG)
- append_list_if(COMPILER_RT_HAS_OMIT_FRAME_POINTER_FLAG -fomit-frame-pointer BUILTIN_CFLAGS)
- endif()
- endif()
-
- set(BUILTIN_DEFS "")
-
- append_list_if(COMPILER_RT_HAS_VISIBILITY_HIDDEN_FLAG VISIBILITY_HIDDEN BUILTIN_DEFS)
-
- foreach (arch ${BUILTIN_SUPPORTED_ARCH})
- if (CAN_TARGET_${arch})
- # NOTE: some architectures (e.g. i386) have multiple names. Ensure that
- # we catch them all.
- set(_arch ${arch})
- if("${arch}" STREQUAL "armv6m")
- set(_arch "arm|armv6m")
- elseif("${arch}" MATCHES "^(armhf|armv7|armv7s|armv7k|armv7m|armv7em)$")
- set(_arch "arm")
- endif()
-
- # For ARM archs, exclude any VFP builtins if VFP is not supported
- if (${arch} MATCHES "^(arm|armhf|armv7|armv7s|armv7k|armv7m|armv7em)$")
- string(REPLACE ";" " " _TARGET_${arch}_CFLAGS "${TARGET_${arch}_CFLAGS}")
- check_compile_definition(__VFP_FP__ "${CMAKE_C_FLAGS} ${_TARGET_${arch}_CFLAGS}" COMPILER_RT_HAS_${arch}_VFP)
- if(NOT COMPILER_RT_HAS_${arch}_VFP)
- list(REMOVE_ITEM ${arch}_SOURCES ${arm_Thumb1_VFPv2_SOURCES} ${arm_Thumb1_SjLj_EH_SOURCES})
- endif()
- endif()
-
- # Filter out generic versions of routines that are re-implemented in
- # architecture specific manner. This prevents multiple definitions of the
- # same symbols, making the symbol selection non-deterministic.
- foreach (_file ${${arch}_SOURCES})
- if (${_file} MATCHES ${_arch}/*)
- get_filename_component(_name ${_file} NAME)
- string(REPLACE ".S" ".c" _cname "${_name}")
- list(REMOVE_ITEM ${arch}_SOURCES ${_cname})
- endif ()
- endforeach ()
-
- # Needed for clear_cache on debug mode, due to r7's usage in inline asm.
- # Release mode already sets it via -O2/3, Debug mode doesn't.
- if (${arch} STREQUAL "armhf")
- list(APPEND BUILTIN_CFLAGS -fomit-frame-pointer -DCOMPILER_RT_ARMHF_TARGET)
- endif()
-
- # For RISCV32, we must force enable int128 for compiling long
- # double routines.
- if("${arch}" STREQUAL "riscv32")
- list(APPEND BUILTIN_CFLAGS -fforce-enable-int128)
- endif()
-
- add_compiler_rt_runtime(clang_rt.builtins
- STATIC
- ARCHS ${arch}
- SOURCES ${${arch}_SOURCES}
- DEFS ${BUILTIN_DEFS}
- CFLAGS ${BUILTIN_CFLAGS}
- PARENT_TARGET builtins)
- endif ()
- endforeach ()
-endif ()
-
-add_dependencies(compiler-rt builtins)
diff --git a/lib/builtins/Darwin-excludes/CMakeLists.txt b/lib/builtins/Darwin-excludes/CMakeLists.txt
deleted file mode 100644
index 266e422152436..0000000000000
--- a/lib/builtins/Darwin-excludes/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-file(GLOB filter_files ${CMAKE_CURRENT_SOURCE_DIR}/*.txt)
-foreach(filter_file ${filter_files})
- set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${filter_file})
-endforeach()
diff --git a/lib/builtins/Darwin-excludes/README.TXT b/lib/builtins/Darwin-excludes/README.TXT
deleted file mode 100644
index 173eccca6decd..0000000000000
--- a/lib/builtins/Darwin-excludes/README.TXT
+++ /dev/null
@@ -1,11 +0,0 @@
-This folder contains list of symbols that should be excluded from the builtin
-libraries for Darwin. There are two reasons symbols are excluded:
-
-(1) They aren't supported on Darwin
-(2) They are contained within the OS on the minimum supported target
-
-The builtin libraries must contain all symbols not provided by the lowest
-supported target OS. Meaning if minimum deployment target is iOS 6, all builtins
-not included in the ios6-<arch>.txt files need to be included. The one catch is
-that this is per-architecture. Since iOS 6 doesn't support arm64, when supporting
-iOS 6, the minimum deployment target for arm64 binaries is iOS 7.
diff --git a/lib/builtins/Darwin-excludes/ios-armv7.txt b/lib/builtins/Darwin-excludes/ios-armv7.txt
deleted file mode 100644
index 6aa542f7fe4ad..0000000000000
--- a/lib/builtins/Darwin-excludes/ios-armv7.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-absvti2
-addtf3
-addvti3
-aeabi_cdcmp
-aeabi_cdcmpeq_check_nan
-aeabi_cfcmp
-aeabi_cfcmpeq_check_nan
-aeabi_dcmp
-aeabi_div0
-aeabi_drsub
-aeabi_fcmp
-aeabi_frsub
-aeabi_idivmod
-aeabi_ldivmod
-aeabi_memcmp
-aeabi_memcpy
-aeabi_memmove
-aeabi_memset
-aeabi_uidivmod
-aeabi_uldivmod
-ashlti3
-ashrti3
-clzti2
-cmpti2
-ctzti2
-divtf3
-divti3
-ffsti2
-fixdfti
-fixsfti
-fixunsdfti
-fixunssfti
-fixunsxfti
-fixxfti
-floattidf
-floattisf
-floattixf
-floatuntidf
-floatuntisf
-floatuntixf
-lshrti3
-modti3
-multf3
-multi3
-mulvti3
-negti2
-negvti2
-parityti2
-popcountti2
-powitf2
-subtf3
-subvti3
-trampoline_setup
-ucmpti2
-udivmodti4
-udivti3
-umodti3
diff --git a/lib/builtins/Darwin-excludes/ios-armv7s.txt b/lib/builtins/Darwin-excludes/ios-armv7s.txt
deleted file mode 100644
index 28167aa4c5db7..0000000000000
--- a/lib/builtins/Darwin-excludes/ios-armv7s.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-absvti2
-addtf3
-addvti3
-aeabi_cdcmp
-aeabi_cdcmpeq_check_nan
-aeabi_cfcmp
-aeabi_cfcmpeq_check_nan
-aeabi_dcmp
-aeabi_div0
-aeabi_drsub
-aeabi_fcmp
-aeabi_frsub
-aeabi_idivmod
-aeabi_ldivmod
-aeabi_memcmp
-aeabi_memcpy
-aeabi_memmove
-aeabi_memset
-aeabi_uidivmod
-aeabi_uldivmod
-ashlti3
-ashrti3
-clzti2
-cmpti2
-ctzti2
-divtf3
-divti3
-ffsti2
-fixdfti
-fixsfti
-fixunsdfti
-fixunssfti
-fixunsxfti
-fixxfti
-floattidf
-floattisf
-floattixf
-floatuntidf
-floatuntisf
-floatuntixf
-lshrti3
-modti3
-multf
-multi3
-mulvti3
-negti2
-negvti2
-parityti2
-popcountti2
-powitf2
-subtf3
-subvti3
-trampoline_setup
-ucmpti2
-udivmodti4
-udivti3
-umodti3
diff --git a/lib/builtins/Darwin-excludes/ios.txt b/lib/builtins/Darwin-excludes/ios.txt
deleted file mode 100644
index 5db24000a1740..0000000000000
--- a/lib/builtins/Darwin-excludes/ios.txt
+++ /dev/null
@@ -1 +0,0 @@
-apple_versioning
diff --git a/lib/builtins/Darwin-excludes/ios6-armv7.txt b/lib/builtins/Darwin-excludes/ios6-armv7.txt
deleted file mode 100644
index b01fa711a357b..0000000000000
--- a/lib/builtins/Darwin-excludes/ios6-armv7.txt
+++ /dev/null
@@ -1,120 +0,0 @@
-absvdi2
-absvsi2
-adddf3
-adddf3vfp
-addsf3
-addsf3vfp
-addvdi3
-addvsi3
-ashldi3
-ashrdi3
-bswapdi2
-bswapsi2
-clzdi2
-clzsi2
-cmpdi2
-ctzdi2
-ctzsi2
-divdc3
-divdf3
-divdf3vfp
-divdi3
-divmodsi4
-divsc3
-divsf3
-divsf3vfp
-divsi3
-eqdf2
-eqdf2vfp
-eqsf2
-eqsf2vfp
-extendsfdf2
-extendsfdf2vfp
-ffsdi2
-fixdfdi
-fixdfsi
-fixdfsivfp
-fixsfdi
-fixsfsi
-fixsfsivfp
-fixunsdfdi
-fixunsdfsi
-fixunsdfsivfp
-fixunssfdi
-fixunssfsi
-fixunssfsivfp
-floatdidf
-floatdisf
-floatsidf
-floatsidfvfp
-floatsisf
-floatsisfvfp
-floatundidf
-floatundisf
-floatunsidf
-floatunsisf
-floatunssidfvfp
-floatunssisfvfp
-gcc_personality_sj0
-gedf2
-gedf2vfp
-gesf2
-gesf2vfp
-gtdf2
-gtdf2vfp
-gtsf2
-gtsf2vfp
-ledf2
-ledf2vfp
-lesf2
-lesf2vfp
-lshrdi3
-ltdf2
-ltdf2vfp
-ltsf2
-ltsf2vfp
-moddi3
-modsi3
-muldc3
-muldf3
-muldf3vfp
-muldi3
-mulodi4
-mulosi4
-mulsc3
-mulsf3
-mulsf3vfp
-mulvdi3
-mulvsi3
-nedf2
-nedf2vfp
-negdi2
-negvdi2
-negvsi2
-nesf2
-nesf2vfp
-paritydi2
-paritysi2
-popcountdi2
-popcountsi2
-powidf2
-powisf2
-subdf3
-subdf3vfp
-subsf3
-subsf3vfp
-subvdi3
-subvsi3
-truncdfsf2
-truncdfsf2vfp
-ucmpdi2
-udivdi3
-udivmoddi4
-udivmodsi4
-udivsi3
-umoddi3
-umodsi3
-unorddf2
-unorddf2vfp
-unordsf2
-unordsf2vfp
diff --git a/lib/builtins/Darwin-excludes/ios6-armv7s.txt b/lib/builtins/Darwin-excludes/ios6-armv7s.txt
deleted file mode 100644
index b01fa711a357b..0000000000000
--- a/lib/builtins/Darwin-excludes/ios6-armv7s.txt
+++ /dev/null
@@ -1,120 +0,0 @@
-absvdi2
-absvsi2
-adddf3
-adddf3vfp
-addsf3
-addsf3vfp
-addvdi3
-addvsi3
-ashldi3
-ashrdi3
-bswapdi2
-bswapsi2
-clzdi2
-clzsi2
-cmpdi2
-ctzdi2
-ctzsi2
-divdc3
-divdf3
-divdf3vfp
-divdi3
-divmodsi4
-divsc3
-divsf3
-divsf3vfp
-divsi3
-eqdf2
-eqdf2vfp
-eqsf2
-eqsf2vfp
-extendsfdf2
-extendsfdf2vfp
-ffsdi2
-fixdfdi
-fixdfsi
-fixdfsivfp
-fixsfdi
-fixsfsi
-fixsfsivfp
-fixunsdfdi
-fixunsdfsi
-fixunsdfsivfp
-fixunssfdi
-fixunssfsi
-fixunssfsivfp
-floatdidf
-floatdisf
-floatsidf
-floatsidfvfp
-floatsisf
-floatsisfvfp
-floatundidf
-floatundisf
-floatunsidf
-floatunsisf
-floatunssidfvfp
-floatunssisfvfp
-gcc_personality_sj0
-gedf2
-gedf2vfp
-gesf2
-gesf2vfp
-gtdf2
-gtdf2vfp
-gtsf2
-gtsf2vfp
-ledf2
-ledf2vfp
-lesf2
-lesf2vfp
-lshrdi3
-ltdf2
-ltdf2vfp
-ltsf2
-ltsf2vfp
-moddi3
-modsi3
-muldc3
-muldf3
-muldf3vfp
-muldi3
-mulodi4
-mulosi4
-mulsc3
-mulsf3
-mulsf3vfp
-mulvdi3
-mulvsi3
-nedf2
-nedf2vfp
-negdi2
-negvdi2
-negvsi2
-nesf2
-nesf2vfp
-paritydi2
-paritysi2
-popcountdi2
-popcountsi2
-powidf2
-powisf2
-subdf3
-subdf3vfp
-subsf3
-subsf3vfp
-subvdi3
-subvsi3
-truncdfsf2
-truncdfsf2vfp
-ucmpdi2
-udivdi3
-udivmoddi4
-udivmodsi4
-udivsi3
-umoddi3
-umodsi3
-unorddf2
-unorddf2vfp
-unordsf2
-unordsf2vfp
diff --git a/lib/builtins/Darwin-excludes/ios7-arm64.txt b/lib/builtins/Darwin-excludes/ios7-arm64.txt
deleted file mode 100644
index 5e4caf9e9fb73..0000000000000
--- a/lib/builtins/Darwin-excludes/ios7-arm64.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-clzti2
-divti3
-fixdfti
-fixsfti
-fixunsdfti
-floattidf
-floattisf
-floatuntidf
-floatuntisf
-gcc_personality_v0
-modti3
-powidf2
-powisf2
-udivmodti4
-udivti3
-umodti3
diff --git a/lib/builtins/Darwin-excludes/iossim-i386.txt b/lib/builtins/Darwin-excludes/iossim-i386.txt
deleted file mode 100644
index 60c0e2d650565..0000000000000
--- a/lib/builtins/Darwin-excludes/iossim-i386.txt
+++ /dev/null
@@ -1,82 +0,0 @@
-absvti2
-addtf3
-addvti3
-ashlti3
-ashrti3
-clzti2
-cmpti2
-ctzti2
-divti3
-divtf3
-ffsti2
-fixdfti
-fixsfti
-fixunsdfti
-fixunssfti
-fixunsxfti
-fixxfti
-floattidf
-floattisf
-floattixf
-floatuntidf
-floatuntisf
-floatuntixf
-lshrti3
-modti3
-muloti4
-multi3
-multf3
-mulvti3
-negti2
-negvti2
-parityti2
-popcountti2
-powitf2
-subvti3
-subtf3
-trampoline_setup
-ucmpti2
-udivmodti4
-udivti3
-umodti3
-absvti2
-addtf3
-addvti3
-ashlti3
-ashrti3
-clzti2
-cmpti2
-ctzti2
-divti3
-divtf3
-ffsti2
-fixdfti
-fixsfti
-fixunsdfti
-fixunssfti
-fixunsxfti
-fixxfti
-floattidf
-floattisf
-floattixf
-floatuntidf
-floatuntisf
-floatuntixf
-lshrti3
-modti3
-muloti4
-multi3
-multf3
-mulvti3
-negti2
-negvti2
-parityti2
-popcountti2
-powitf2
-subvti3
-subtf3
-trampoline_setup
-ucmpti2
-udivmodti4
-udivti3
-umodti3
diff --git a/lib/builtins/Darwin-excludes/iossim-x86_64.txt b/lib/builtins/Darwin-excludes/iossim-x86_64.txt
deleted file mode 100644
index de1574e6ce3d9..0000000000000
--- a/lib/builtins/Darwin-excludes/iossim-x86_64.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-addtf3
-divtf3
-multf3
-powitf2
-subtf3
-trampoline_setup
-addtf3
-divtf3
-multf3
-powitf2
-subtf3
-trampoline_setup
diff --git a/lib/builtins/Darwin-excludes/iossim.txt b/lib/builtins/Darwin-excludes/iossim.txt
deleted file mode 100644
index 5db24000a1740..0000000000000
--- a/lib/builtins/Darwin-excludes/iossim.txt
+++ /dev/null
@@ -1 +0,0 @@
-apple_versioning
diff --git a/lib/builtins/Darwin-excludes/osx-i386.txt b/lib/builtins/Darwin-excludes/osx-i386.txt
deleted file mode 100644
index f2ee7fef0c631..0000000000000
--- a/lib/builtins/Darwin-excludes/osx-i386.txt
+++ /dev/null
@@ -1,35 +0,0 @@
-absvti2
-addvti3
-ashlti3
-ashrti3
-clzti2
-cmpti2
-ctzti2
-divti3
-ffsti2
-fixdfti
-fixsfti
-fixunsdfti
-fixunssfti
-fixunsxfti
-fixxfti
-floattidf
-floattisf
-floattixf
-floatuntidf
-floatuntisf
-floatuntixf
-lshrti3
-modti3
-muloti4
-multi3
-mulvti3
-negti2
-negvti2
-parityti2
-popcountti2
-subvti3
-ucmpti2
-udivmodti4
-udivti3
-umodti3
diff --git a/lib/builtins/Darwin-excludes/osx.txt b/lib/builtins/Darwin-excludes/osx.txt
deleted file mode 100644
index 6f9d0a7b245d3..0000000000000
--- a/lib/builtins/Darwin-excludes/osx.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-apple_versioning
-addtf3
-divtf3
-multf3
-powitf2
-subtf3
-trampoline_setup
diff --git a/lib/builtins/macho_embedded/CMakeLists.txt b/lib/builtins/macho_embedded/CMakeLists.txt
deleted file mode 100644
index 266e422152436..0000000000000
--- a/lib/builtins/macho_embedded/CMakeLists.txt
+++ /dev/null
@@ -1,4 +0,0 @@
-file(GLOB filter_files ${CMAKE_CURRENT_SOURCE_DIR}/*.txt)
-foreach(filter_file ${filter_files})
- set_property(DIRECTORY APPEND PROPERTY CMAKE_CONFIGURE_DEPENDS ${filter_file})
-endforeach()
diff --git a/lib/builtins/macho_embedded/arm.txt b/lib/builtins/macho_embedded/arm.txt
deleted file mode 100644
index 4b1683a6baef8..0000000000000
--- a/lib/builtins/macho_embedded/arm.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-aeabi_cdcmpeq
-aeabi_cdrcmple
-aeabi_cfcmpeq
-aeabi_cfrcmple
-aeabi_dcmpeq
-aeabi_dcmpge
-aeabi_dcmpgt
-aeabi_dcmple
-aeabi_dcmplt
-aeabi_drsub
-aeabi_fcmpeq
-aeabi_fcmpge
-aeabi_fcmpgt
-aeabi_fcmple
-aeabi_fcmplt
-aeabi_frsub
diff --git a/lib/builtins/macho_embedded/common.txt b/lib/builtins/macho_embedded/common.txt
deleted file mode 100644
index 6ac85a771fcbe..0000000000000
--- a/lib/builtins/macho_embedded/common.txt
+++ /dev/null
@@ -1,92 +0,0 @@
-absvdi2
-absvsi2
-addvdi3
-addvsi3
-ashldi3
-ashrdi3
-clzdi2
-clzsi2
-cmpdi2
-ctzdi2
-ctzsi2
-divdc3
-divdi3
-divsc3
-divmodsi4
-udivmodsi4
-do_global_dtors
-ffsdi2
-fixdfdi
-fixsfdi
-fixunsdfdi
-fixunsdfsi
-fixunssfdi
-fixunssfsi
-floatdidf
-floatdisf
-floatundidf
-floatundisf
-gcc_bcmp
-lshrdi3
-moddi3
-muldc3
-muldi3
-mulsc3
-mulvdi3
-mulvsi3
-negdi2
-negvdi2
-negvsi2
-paritydi2
-paritysi2
-popcountdi2
-popcountsi2
-powidf2
-powisf2
-subvdi3
-subvsi3
-ucmpdi2
-udiv_w_sdiv
-udivdi3
-udivmoddi4
-umoddi3
-adddf3
-addsf3
-cmpdf2
-cmpsf2
-div0
-divdf3
-divsf3
-divsi3
-extendsfdf2
-extendhfsf2
-ffssi2
-fixdfsi
-fixsfsi
-floatsidf
-floatsisf
-floatunsidf
-floatunsisf
-comparedf2
-comparesf2
-modsi3
-muldf3
-mulsf3
-negdf2
-negsf2
-subdf3
-subsf3
-truncdfhf2
-truncdfsf2
-truncsfhf2
-udivsi3
-umodsi3
-unorddf2
-unordsf2
-atomic_flag_clear
-atomic_flag_clear_explicit
-atomic_flag_test_and_set
-atomic_flag_test_and_set_explicit
-atomic_signal_fence
-atomic_thread_fence
-int_util
diff --git a/lib/builtins/macho_embedded/i386.txt b/lib/builtins/macho_embedded/i386.txt
deleted file mode 100644
index b92e44bb35ae3..0000000000000
--- a/lib/builtins/macho_embedded/i386.txt
+++ /dev/null
@@ -1,7 +0,0 @@
-i686.get_pc_thunk.eax
-i686.get_pc_thunk.ebp
-i686.get_pc_thunk.ebx
-i686.get_pc_thunk.ecx
-i686.get_pc_thunk.edi
-i686.get_pc_thunk.edx
-i686.get_pc_thunk.esi
diff --git a/lib/builtins/macho_embedded/thumb2-64.txt b/lib/builtins/macho_embedded/thumb2-64.txt
deleted file mode 100644
index 1c72fb1c3c64e..0000000000000
--- a/lib/builtins/macho_embedded/thumb2-64.txt
+++ /dev/null
@@ -1,10 +0,0 @@
-sync_fetch_and_add_8
-sync_fetch_and_sub_8
-sync_fetch_and_and_8
-sync_fetch_and_or_8
-sync_fetch_and_xor_8
-sync_fetch_and_nand_8
-sync_fetch_and_max_8
-sync_fetch_and_umax_8
-sync_fetch_and_min_8
-sync_fetch_and_umin_8
diff --git a/lib/builtins/macho_embedded/thumb2.txt b/lib/builtins/macho_embedded/thumb2.txt
deleted file mode 100644
index 6add5ecd2dc71..0000000000000
--- a/lib/builtins/macho_embedded/thumb2.txt
+++ /dev/null
@@ -1,14 +0,0 @@
-switch16
-switch32
-switch8
-switchu8
-sync_fetch_and_add_4
-sync_fetch_and_sub_4
-sync_fetch_and_and_4
-sync_fetch_and_or_4
-sync_fetch_and_xor_4
-sync_fetch_and_nand_4
-sync_fetch_and_max_4
-sync_fetch_and_umax_4
-sync_fetch_and_min_4
-sync_fetch_and_umin_4
diff --git a/lib/cfi/CMakeLists.txt b/lib/cfi/CMakeLists.txt
deleted file mode 100644
index 463a1fd599153..0000000000000
--- a/lib/cfi/CMakeLists.txt
+++ /dev/null
@@ -1,41 +0,0 @@
-add_compiler_rt_component(cfi)
-
-if(OS_NAME MATCHES "Linux" OR OS_NAME MATCHES "FreeBSD" OR OS_NAME MATCHES "NetBSD")
- set(CFI_SOURCES cfi.cc)
-
- include_directories(..)
-
- set(CFI_CFLAGS
- ${SANITIZER_COMMON_CFLAGS}
- )
-
- set(CFI_DIAG_CFLAGS
- -DCFI_ENABLE_DIAG=1
- )
-
- foreach(arch ${CFI_SUPPORTED_ARCH})
- add_compiler_rt_runtime(clang_rt.cfi
- STATIC
- ARCHS ${arch}
- SOURCES ${CFI_SOURCES}
- OBJECT_LIBS RTInterception
- RTSanitizerCommon
- RTSanitizerCommonLibc
- CFLAGS ${CFI_CFLAGS}
- PARENT_TARGET cfi)
- add_compiler_rt_runtime(clang_rt.cfi_diag
- STATIC
- ARCHS ${arch}
- SOURCES ${CFI_SOURCES}
- OBJECT_LIBS RTInterception
- RTSanitizerCommon
- RTSanitizerCommonLibc
- RTSanitizerCommonCoverage
- RTSanitizerCommonSymbolizer
- RTUbsan
- CFLAGS ${CFI_CFLAGS} ${CFI_DIAG_CFLAGS}
- PARENT_TARGET cfi)
- endforeach()
-endif()
-
-add_compiler_rt_resource_file(cfi_blacklist cfi_blacklist.txt cfi)
diff --git a/lib/dfsan/.clang-format b/lib/dfsan/.clang-format
deleted file mode 100644
index 560308c91deec..0000000000000
--- a/lib/dfsan/.clang-format
+++ /dev/null
@@ -1,2 +0,0 @@
-BasedOnStyle: Google
-AllowShortIfStatementsOnASingleLine: false
diff --git a/lib/dfsan/CMakeLists.txt b/lib/dfsan/CMakeLists.txt
deleted file mode 100644
index b3ae713cf02c5..0000000000000
--- a/lib/dfsan/CMakeLists.txt
+++ /dev/null
@@ -1,57 +0,0 @@
-include_directories(..)
-
-# Runtime library sources and build flags.
-set(DFSAN_RTL_SOURCES
- dfsan.cc
- dfsan_custom.cc
- dfsan_interceptors.cc)
-
-set(DFSAN_RTL_HEADERS
- dfsan.h
- dfsan_flags.inc
- dfsan_platform.h)
-
-set(DFSAN_COMMON_CFLAGS ${SANITIZER_COMMON_CFLAGS})
-append_rtti_flag(OFF DFSAN_COMMON_CFLAGS)
-# Prevent clang from generating libc calls.
-append_list_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding DFSAN_COMMON_CFLAGS)
-
-# Static runtime library.
-add_compiler_rt_component(dfsan)
-
-foreach(arch ${DFSAN_SUPPORTED_ARCH})
- set(DFSAN_CFLAGS ${DFSAN_COMMON_CFLAGS})
- append_list_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE DFSAN_CFLAGS)
- add_compiler_rt_runtime(clang_rt.dfsan
- STATIC
- ARCHS ${arch}
- SOURCES ${DFSAN_RTL_SOURCES}
- $<TARGET_OBJECTS:RTInterception.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
- ADDITIONAL_HEADERS ${DFSAN_RTL_HEADERS}
- CFLAGS ${DFSAN_CFLAGS}
- PARENT_TARGET dfsan)
- add_sanitizer_rt_symbols(clang_rt.dfsan
- ARCHS ${arch}
- EXTRA dfsan.syms.extra)
- add_dependencies(dfsan
- clang_rt.dfsan-${arch}-symbols)
-endforeach()
-
-set(dfsan_abilist_dir ${COMPILER_RT_OUTPUT_DIR}/share)
-set(dfsan_abilist_filename ${dfsan_abilist_dir}/dfsan_abilist.txt)
-add_custom_target(dfsan_abilist ALL
- DEPENDS ${dfsan_abilist_filename})
-add_custom_command(OUTPUT ${dfsan_abilist_filename}
- VERBATIM
- COMMAND
- ${CMAKE_COMMAND} -E make_directory ${dfsan_abilist_dir}
- COMMAND
- cat ${CMAKE_CURRENT_SOURCE_DIR}/done_abilist.txt
- ${CMAKE_CURRENT_SOURCE_DIR}/libc_ubuntu1404_abilist.txt
- > ${dfsan_abilist_filename}
- DEPENDS done_abilist.txt libc_ubuntu1404_abilist.txt)
-add_dependencies(dfsan dfsan_abilist)
-install(FILES ${dfsan_abilist_filename}
- DESTINATION ${COMPILER_RT_INSTALL_PATH}/share)
diff --git a/lib/dfsan/scripts/build-libc-list.py b/lib/dfsan/scripts/build-libc-list.py
deleted file mode 100755
index eddb6c07e99d8..0000000000000
--- a/lib/dfsan/scripts/build-libc-list.py
+++ /dev/null
@@ -1,96 +0,0 @@
-#!/usr/bin/env python
-#===- lib/dfsan/scripts/build-libc-list.py ---------------------------------===#
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-# The purpose of this script is to identify every function symbol in a set of
-# libraries (in this case, libc and libgcc) so that they can be marked as
-# uninstrumented, thus allowing the instrumentation pass to treat calls to those
-# functions correctly.
-
-import os
-import subprocess
-import sys
-from optparse import OptionParser
-
-def defined_function_list(object):
- functions = []
- readelf_proc = subprocess.Popen(['readelf', '-s', '-W', object],
- stdout=subprocess.PIPE)
- readelf = readelf_proc.communicate()[0].split('\n')
- if readelf_proc.returncode != 0:
- raise subprocess.CalledProcessError(readelf_proc.returncode, 'readelf')
- for line in readelf:
- if (line[31:35] == 'FUNC' or line[31:36] == 'IFUNC') and \
- line[39:44] != 'LOCAL' and \
- line[55:58] != 'UND':
- function_name = line[59:].split('@')[0]
- functions.append(function_name)
- return functions
-
-p = OptionParser()
-
-p.add_option('--libc-dso-path', metavar='PATH',
- help='path to libc DSO directory',
- default='/lib/x86_64-linux-gnu')
-p.add_option('--libc-archive-path', metavar='PATH',
- help='path to libc archive directory',
- default='/usr/lib/x86_64-linux-gnu')
-
-p.add_option('--libgcc-dso-path', metavar='PATH',
- help='path to libgcc DSO directory',
- default='/lib/x86_64-linux-gnu')
-p.add_option('--libgcc-archive-path', metavar='PATH',
- help='path to libgcc archive directory',
- default='/usr/lib/gcc/x86_64-linux-gnu/4.6')
-
-p.add_option('--with-libstdcxx', action='store_true',
- dest='with_libstdcxx',
- help='include libstdc++ in the list (inadvisable)')
-p.add_option('--libstdcxx-dso-path', metavar='PATH',
- help='path to libstdc++ DSO directory',
- default='/usr/lib/x86_64-linux-gnu')
-
-(options, args) = p.parse_args()
-
-libs = [os.path.join(options.libc_dso_path, name) for name in
- ['ld-linux-x86-64.so.2',
- 'libanl.so.1',
- 'libBrokenLocale.so.1',
- 'libcidn.so.1',
- 'libcrypt.so.1',
- 'libc.so.6',
- 'libdl.so.2',
- 'libm.so.6',
- 'libnsl.so.1',
- 'libpthread.so.0',
- 'libresolv.so.2',
- 'librt.so.1',
- 'libthread_db.so.1',
- 'libutil.so.1']]
-libs += [os.path.join(options.libc_archive_path, name) for name in
- ['libc_nonshared.a',
- 'libpthread_nonshared.a']]
-
-libs.append(os.path.join(options.libgcc_dso_path, 'libgcc_s.so.1'))
-libs.append(os.path.join(options.libgcc_archive_path, 'libgcc.a'))
-
-if options.with_libstdcxx:
- libs.append(os.path.join(options.libstdcxx_dso_path, 'libstdc++.so.6'))
-
-functions = []
-for l in libs:
- if os.path.exists(l):
- functions += defined_function_list(l)
- else:
- print >> sys.stderr, 'warning: library %s not found' % l
-
-functions = list(set(functions))
-functions.sort()
-
-for f in functions:
- print 'fun:%s=uninstrumented' % f
diff --git a/lib/dfsan/scripts/check_custom_wrappers.sh b/lib/dfsan/scripts/check_custom_wrappers.sh
deleted file mode 100755
index 9a80cb9c6ffd6..0000000000000
--- a/lib/dfsan/scripts/check_custom_wrappers.sh
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/sh
-
-DFSAN_DIR=$(dirname "$0")/../
-DFSAN_CUSTOM_TESTS=${DFSAN_DIR}/../../test/dfsan/custom.cc
-DFSAN_CUSTOM_WRAPPERS=${DFSAN_DIR}/dfsan_custom.cc
-DFSAN_ABI_LIST=${DFSAN_DIR}/done_abilist.txt
-
-DIFFOUT=$(mktemp -q /tmp/tmp.XXXXXXXXXX)
-ERRORLOG=$(mktemp -q /tmp/tmp.XXXXXXXXXX)
-DIFF_A=$(mktemp -q /tmp/tmp.XXXXXXXXXX)
-DIFF_B=$(mktemp -q /tmp/tmp.XXXXXXXXXX)
-
-on_exit() {
- rm -f ${DIFFOUT} 2> /dev/null
- rm -f ${ERRORLOG} 2> /dev/null
- rm -f ${DIFF_A} 2> /dev/null
- rm -f ${DIFF_B} 2> /dev/null
-}
-
-# Ignore __sanitizer_cov_trace* because they are implemented elsewhere.
-trap on_exit EXIT
-grep -E "^fun:.*=custom" ${DFSAN_ABI_LIST} \
- | grep -v "dfsan_get_label\|__sanitizer_cov_trace" \
- | sed "s/^fun:\(.*\)=custom.*/\1/" | sort > $DIFF_A
-grep -E "__dfsw.*\(" ${DFSAN_CUSTOM_WRAPPERS} \
- | grep -v "__sanitizer_cov_trace" \
- | sed "s/.*__dfsw_\(.*\)(.*/\1/" | sort > $DIFF_B
-diff -u $DIFF_A $DIFF_B > ${DIFFOUT}
-if [ $? -ne 0 ]
-then
- echo -n "The following differences between the ABI list and ">> ${ERRORLOG}
- echo "the implemented custom wrappers have been found:" >> ${ERRORLOG}
- cat ${DIFFOUT} >> ${ERRORLOG}
-fi
-
-grep -E __dfsw_ ${DFSAN_CUSTOM_WRAPPERS} \
- | grep -v "__sanitizer_cov_trace" \
- | sed "s/.*__dfsw_\([^(]*\).*/\1/" | sort > $DIFF_A
-grep -E "^[[:space:]]*test_.*\(\);" ${DFSAN_CUSTOM_TESTS} \
- | sed "s/.*test_\(.*\)();/\1/" | sort > $DIFF_B
-diff -u $DIFF_A $DIFF_B > ${DIFFOUT}
-if [ $? -ne 0 ]
-then
- echo -n "The following differences between the implemented " >> ${ERRORLOG}
- echo "custom wrappers and the tests have been found:" >> ${ERRORLOG}
- cat ${DIFFOUT} >> ${ERRORLOG}
-fi
-
-if [ -s ${ERRORLOG} ]
-then
- cat ${ERRORLOG}
- exit 1
-fi
-
diff --git a/lib/esan/CMakeLists.txt b/lib/esan/CMakeLists.txt
deleted file mode 100644
index c880971e3dd97..0000000000000
--- a/lib/esan/CMakeLists.txt
+++ /dev/null
@@ -1,55 +0,0 @@
-# Build for the EfficiencySanitizer runtime support library.
-
-add_compiler_rt_component(esan)
-
-set(ESAN_RTL_CFLAGS ${SANITIZER_COMMON_CFLAGS})
-append_rtti_flag(OFF ESAN_RTL_CFLAGS)
-
-include_directories(..)
-
-set(ESAN_SOURCES
- esan.cpp
- esan_flags.cpp
- esan_interface.cpp
- esan_interceptors.cpp
- esan_linux.cpp
- esan_sideline_linux.cpp
- esan_sideline_bsd.cpp
- cache_frag.cpp
- working_set.cpp
- working_set_posix.cpp)
-
-set(ESAN_HEADERS
- cache_frag.h
- esan.h
- esan_circular_buffer.h
- esan_flags.h
- esan_flags.inc
- esan_hashtable.h
- esan_interface_internal.h
- esan_shadow.h
- esan_sideline.h
- working_set.h)
-
-foreach (arch ${ESAN_SUPPORTED_ARCH})
- add_compiler_rt_runtime(clang_rt.esan
- STATIC
- ARCHS ${arch}
- SOURCES ${ESAN_SOURCES}
- $<TARGET_OBJECTS:RTInterception.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
- ADDITIONAL_HEADERS ${ESAN_HEADERS}
- CFLAGS ${ESAN_RTL_CFLAGS})
- add_sanitizer_rt_symbols(clang_rt.esan
- ARCHS ${arch}
- EXTRA esan.syms.extra)
- add_dependencies(esan
- clang_rt.esan-${arch}
- clang_rt.esan-${arch}-symbols)
-endforeach()
-
-if (COMPILER_RT_INCLUDE_TESTS)
- # TODO(bruening): add tests via add_subdirectory(tests)
-endif()
diff --git a/lib/fuzzer/CMakeLists.txt b/lib/fuzzer/CMakeLists.txt
deleted file mode 100644
index caea9734fe532..0000000000000
--- a/lib/fuzzer/CMakeLists.txt
+++ /dev/null
@@ -1,147 +0,0 @@
-set(LIBFUZZER_SOURCES
- FuzzerCrossOver.cpp
- FuzzerDataFlowTrace.cpp
- FuzzerDriver.cpp
- FuzzerExtFunctionsDlsym.cpp
- FuzzerExtFunctionsWeak.cpp
- FuzzerExtFunctionsWindows.cpp
- FuzzerExtraCounters.cpp
- FuzzerIO.cpp
- FuzzerIOPosix.cpp
- FuzzerIOWindows.cpp
- FuzzerLoop.cpp
- FuzzerMerge.cpp
- FuzzerMutate.cpp
- FuzzerSHA1.cpp
- FuzzerShmemFuchsia.cpp
- FuzzerShmemPosix.cpp
- FuzzerShmemWindows.cpp
- FuzzerTracePC.cpp
- FuzzerUtil.cpp
- FuzzerUtilDarwin.cpp
- FuzzerUtilFuchsia.cpp
- FuzzerUtilLinux.cpp
- FuzzerUtilPosix.cpp
- FuzzerUtilWindows.cpp)
-
-set(LIBFUZZER_HEADERS
- FuzzerBuiltins.h
- FuzzerBuiltinsMsvc.h
- FuzzerCommand.h
- FuzzerCorpus.h
- FuzzerDataFlowTrace.h
- FuzzerDefs.h
- FuzzerDictionary.h
- FuzzerExtFunctions.def
- FuzzerExtFunctions.h
- FuzzerFlags.def
- FuzzerIO.h
- FuzzerInterface.h
- FuzzerInternal.h
- FuzzerMerge.h
- FuzzerMutate.h
- FuzzerOptions.h
- FuzzerRandom.h
- FuzzerSHA1.h
- FuzzerShmem.h
- FuzzerTracePC.h
- FuzzerUtil.h
- FuzzerValueBitMap.h)
-
-CHECK_CXX_SOURCE_COMPILES("
- static thread_local int blah;
- int main() {
- return 0;
- }
- " HAS_THREAD_LOCAL)
-
-set(LIBFUZZER_CFLAGS ${SANITIZER_COMMON_CFLAGS})
-
-if(OS_NAME MATCHES "Linux|Fuchsia" AND COMPILER_RT_LIBCXX_PATH)
- list(APPEND LIBFUZZER_CFLAGS -nostdinc++ -D_LIBCPP_ABI_VERSION=Fuzzer)
- # Remove -stdlib= which is unused when passing -nostdinc++.
- string(REGEX REPLACE "-stdlib=[a-zA-Z+]*" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
-elseif(TARGET cxx-headers OR HAVE_LIBCXX)
- set(LIBFUZZER_DEPS cxx-headers)
-endif()
-
-append_list_if(COMPILER_RT_HAS_OMIT_FRAME_POINTER_FLAG -fno-omit-frame-pointer LIBFUZZER_CFLAGS)
-
-if (CMAKE_CXX_FLAGS MATCHES "fsanitize-coverage")
- list(APPEND LIBFUZZER_CFLAGS -fno-sanitize-coverage=trace-pc-guard,edge,trace-cmp,indirect-calls,8bit-counters)
-endif()
-
-if(NOT HAS_THREAD_LOCAL)
- list(APPEND LIBFUZZER_CFLAGS -Dthread_local=__thread)
-endif()
-
-set(FUZZER_SUPPORTED_OS ${SANITIZER_COMMON_SUPPORTED_OS})
-
-add_compiler_rt_object_libraries(RTfuzzer
- OS ${FUZZER_SUPPORTED_OS}
- ARCHS ${FUZZER_SUPPORTED_ARCH}
- SOURCES ${LIBFUZZER_SOURCES}
- ADDITIONAL_HEADERS ${LIBFUZZER_HEADERS}
- CFLAGS ${LIBFUZZER_CFLAGS}
- DEPS ${LIBFUZZER_DEPS})
-
-add_compiler_rt_object_libraries(RTfuzzer_main
- OS ${FUZZER_SUPPORTED_OS}
- ARCHS ${FUZZER_SUPPORTED_ARCH}
- SOURCES FuzzerMain.cpp
- CFLAGS ${LIBFUZZER_CFLAGS}
- DEPS ${LIBFUZZER_DEPS})
-
-add_compiler_rt_runtime(clang_rt.fuzzer
- STATIC
- OS ${FUZZER_SUPPORTED_OS}
- ARCHS ${FUZZER_SUPPORTED_ARCH}
- OBJECT_LIBS RTfuzzer RTfuzzer_main
- CFLAGS ${LIBFUZZER_CFLAGS}
- PARENT_TARGET fuzzer)
-
-add_compiler_rt_runtime(clang_rt.fuzzer_no_main
- STATIC
- OS ${FUZZER_SUPPORTED_OS}
- ARCHS ${FUZZER_SUPPORTED_ARCH}
- OBJECT_LIBS RTfuzzer
- CFLAGS ${LIBFUZZER_CFLAGS}
- PARENT_TARGET fuzzer)
-
-if(OS_NAME MATCHES "Linux|Fuchsia" AND COMPILER_RT_LIBCXX_PATH)
- macro(partially_link_libcxx name dir arch)
- set(cxx_${arch}_merge_dir "${CMAKE_CURRENT_BINARY_DIR}/cxx_${arch}_merge.dir")
- file(MAKE_DIRECTORY ${cxx_${arch}_merge_dir})
- add_custom_command(TARGET clang_rt.${name}-${arch} POST_BUILD
- COMMAND ${CMAKE_LINKER} --whole-archive "$<TARGET_LINKER_FILE:clang_rt.${name}-${arch}>" --no-whole-archive ${dir}/lib/libc++.a -r -o ${name}.o
- COMMAND ${CMAKE_OBJCOPY} --localize-hidden ${name}.o
- COMMAND ${CMAKE_COMMAND} -E remove "$<TARGET_LINKER_FILE:clang_rt.${name}-${arch}>"
- COMMAND ${CMAKE_AR} qcs "$<TARGET_LINKER_FILE:clang_rt.${name}-${arch}>" ${name}.o
- WORKING_DIRECTORY ${cxx_${arch}_merge_dir}
- )
- endmacro()
-
- foreach(arch ${FUZZER_SUPPORTED_ARCH})
- get_target_flags_for_arch(${arch} TARGET_CFLAGS)
- set(LIBCXX_${arch}_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/libcxx_fuzzer_${arch})
- add_custom_libcxx(libcxx_fuzzer_${arch} ${LIBCXX_${arch}_PREFIX}
- CFLAGS ${TARGET_CFLAGS}
- -D_LIBCPP_DISABLE_VISIBILITY_ANNOTATIONS=1
- -fvisibility=hidden
- CMAKE_ARGS -DCMAKE_CXX_COMPILER_WORKS=ON
- -DLIBCXX_ENABLE_EXCEPTIONS=OFF
- -DLIBCXX_ENABLE_SHARED=OFF
- -DLIBCXX_ABI_NAMESPACE=Fuzzer
- -DLIBCXX_CXX_ABI=none)
- target_compile_options(RTfuzzer.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1)
- add_dependencies(RTfuzzer.${arch} libcxx_fuzzer_${arch}-build)
- target_compile_options(RTfuzzer_main.${arch} PRIVATE -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1)
- add_dependencies(RTfuzzer_main.${arch} libcxx_fuzzer_${arch}-build)
- partially_link_libcxx(fuzzer_no_main ${LIBCXX_${arch}_PREFIX} ${arch})
- partially_link_libcxx(fuzzer ${LIBCXX_${arch}_PREFIX} ${arch})
- endforeach()
-endif()
-
-if(COMPILER_RT_INCLUDE_TESTS)
- add_subdirectory(tests)
-endif()
diff --git a/lib/fuzzer/afl/afl_driver.cpp b/lib/fuzzer/afl/afl_driver.cpp
deleted file mode 100644
index 5a10c0d27f3ac..0000000000000
--- a/lib/fuzzer/afl/afl_driver.cpp
+++ /dev/null
@@ -1,378 +0,0 @@
-//===- afl_driver.cpp - a glue between AFL and libFuzzer --------*- C++ -* ===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//===----------------------------------------------------------------------===//
-
-/* This file allows to fuzz libFuzzer-style target functions
- (LLVMFuzzerTestOneInput) with AFL using AFL's persistent (in-process) mode.
-
-Usage:
-################################################################################
-cat << EOF > test_fuzzer.cc
-#include <stddef.h>
-#include <stdint.h>
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t *data, size_t size) {
- if (size > 0 && data[0] == 'H')
- if (size > 1 && data[1] == 'I')
- if (size > 2 && data[2] == '!')
- __builtin_trap();
- return 0;
-}
-EOF
-# Build your target with -fsanitize-coverage=trace-pc-guard using fresh clang.
-clang -g -fsanitize-coverage=trace-pc-guard test_fuzzer.cc -c
-# Build afl-llvm-rt.o.c from the AFL distribution.
-clang -c -w $AFL_HOME/llvm_mode/afl-llvm-rt.o.c
-# Build this file, link it with afl-llvm-rt.o.o and the target code.
-clang++ afl_driver.cpp test_fuzzer.o afl-llvm-rt.o.o
-# Run AFL:
-rm -rf IN OUT; mkdir IN OUT; echo z > IN/z;
-$AFL_HOME/afl-fuzz -i IN -o OUT ./a.out
-################################################################################
-Environment Variables:
-There are a few environment variables that can be set to use features that
-afl-fuzz doesn't have.
-
-AFL_DRIVER_STDERR_DUPLICATE_FILENAME: Setting this *appends* stderr to the file
-specified. If the file does not exist, it is created. This is useful for getting
-stack traces (when using ASAN for example) or original error messages on hard to
-reproduce bugs.
-
-AFL_DRIVER_EXTRA_STATS_FILENAME: Setting this causes afl_driver to write extra
-statistics to the file specified. Currently these are peak_rss_mb
-(the peak amount of virtual memory used in MB) and slowest_unit_time_secs. If
-the file does not exist it is created. If the file does exist then
-afl_driver assumes it was restarted by afl-fuzz and will try to read old
-statistics from the file. If that fails then the process will quit.
-
-*/
-#include <assert.h>
-#include <errno.h>
-#include <signal.h>
-#include <stdint.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <string.h>
-#include <sys/resource.h>
-#include <sys/time.h>
-#include <unistd.h>
-
-#include <fstream>
-#include <iostream>
-#include <vector>
-
-// Platform detection. Copied from FuzzerInternal.h
-#ifdef __linux__
-#define LIBFUZZER_LINUX 1
-#define LIBFUZZER_APPLE 0
-#define LIBFUZZER_NETBSD 0
-#define LIBFUZZER_FREEBSD 0
-#define LIBFUZZER_OPENBSD 0
-#elif __APPLE__
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_APPLE 1
-#define LIBFUZZER_NETBSD 0
-#define LIBFUZZER_FREEBSD 0
-#define LIBFUZZER_OPENBSD 0
-#elif __NetBSD__
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_APPLE 0
-#define LIBFUZZER_NETBSD 1
-#define LIBFUZZER_FREEBSD 0
-#define LIBFUZZER_OPENBSD 0
-#elif __FreeBSD__
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_APPLE 0
-#define LIBFUZZER_NETBSD 0
-#define LIBFUZZER_FREEBSD 1
-#define LIBFUZZER_OPENBSD 0
-#elif __OpenBSD__
-#define LIBFUZZER_LINUX 0
-#define LIBFUZZER_APPLE 0
-#define LIBFUZZER_NETBSD 0
-#define LIBFUZZER_FREEBSD 0
-#define LIBFUZZER_OPENBSD 1
-#else
-#error "Support for your platform has not been implemented"
-#endif
-
-// Used to avoid repeating error checking boilerplate. If cond is false, a
-// fatal error has occurred in the program. In this event print error_message
-// to stderr and abort(). Otherwise do nothing. Note that setting
-// AFL_DRIVER_STDERR_DUPLICATE_FILENAME may cause error_message to be appended
-// to the file as well, if the error occurs after the duplication is performed.
-#define CHECK_ERROR(cond, error_message) \
- if (!(cond)) { \
- fprintf(stderr, "%s\n", (error_message)); \
- abort(); \
- }
-
-// libFuzzer interface is thin, so we don't include any libFuzzer headers.
-extern "C" {
-int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size);
-__attribute__((weak)) int LLVMFuzzerInitialize(int *argc, char ***argv);
-}
-
-// Notify AFL about persistent mode.
-static volatile char AFL_PERSISTENT[] = "##SIG_AFL_PERSISTENT##";
-extern "C" int __afl_persistent_loop(unsigned int);
-static volatile char suppress_warning2 = AFL_PERSISTENT[0];
-
-// Notify AFL about deferred forkserver.
-static volatile char AFL_DEFER_FORKSVR[] = "##SIG_AFL_DEFER_FORKSRV##";
-extern "C" void __afl_manual_init();
-static volatile char suppress_warning1 = AFL_DEFER_FORKSVR[0];
-
-// Input buffer.
-static const size_t kMaxAflInputSize = 1 << 20;
-static uint8_t AflInputBuf[kMaxAflInputSize];
-
-// Variables we need for writing to the extra stats file.
-static FILE *extra_stats_file = NULL;
-static uint32_t previous_peak_rss = 0;
-static time_t slowest_unit_time_secs = 0;
-static const int kNumExtraStats = 2;
-static const char *kExtraStatsFormatString = "peak_rss_mb : %u\n"
- "slowest_unit_time_sec : %u\n";
-
-// Experimental feature to use afl_driver without AFL's deferred mode.
-// Needs to run before __afl_auto_init.
-__attribute__((constructor(0))) void __decide_deferred_forkserver(void) {
- if (getenv("AFL_DRIVER_DONT_DEFER")) {
- if (unsetenv("__AFL_DEFER_FORKSRV")) {
- perror("Failed to unset __AFL_DEFER_FORKSRV");
- abort();
- }
- }
-}
-
-// Copied from FuzzerUtil.cpp.
-size_t GetPeakRSSMb() {
- struct rusage usage;
- if (getrusage(RUSAGE_SELF, &usage))
- return 0;
- if (LIBFUZZER_LINUX || LIBFUZZER_NETBSD || LIBFUZZER_FREEBSD ||
- LIBFUZZER_OPENBSD) {
- // ru_maxrss is in KiB
- return usage.ru_maxrss >> 10;
- } else if (LIBFUZZER_APPLE) {
- // ru_maxrss is in bytes
- return usage.ru_maxrss >> 20;
- }
- assert(0 && "GetPeakRSSMb() is not implemented for your platform");
- return 0;
-}
-
-// Based on SetSigaction in FuzzerUtil.cpp
-static void SetSigaction(int signum,
- void (*callback)(int, siginfo_t *, void *)) {
- struct sigaction sigact;
- memset(&sigact, 0, sizeof(sigact));
- sigact.sa_sigaction = callback;
- if (sigaction(signum, &sigact, 0)) {
- fprintf(stderr, "libFuzzer: sigaction failed with %d\n", errno);
- exit(1);
- }
-}
-
-// Write extra stats to the file specified by the user. If none is specified
-// this function will never be called.
-static void write_extra_stats() {
- uint32_t peak_rss = GetPeakRSSMb();
-
- if (peak_rss < previous_peak_rss)
- peak_rss = previous_peak_rss;
-
- int chars_printed = fprintf(extra_stats_file, kExtraStatsFormatString,
- peak_rss, slowest_unit_time_secs);
-
- CHECK_ERROR(chars_printed != 0, "Failed to write extra_stats_file");
-
- CHECK_ERROR(fclose(extra_stats_file) == 0,
- "Failed to close extra_stats_file");
-}
-
-// Call write_extra_stats before we exit.
-static void crash_handler(int, siginfo_t *, void *) {
- // Make sure we don't try calling write_extra_stats again if we crashed while
- // trying to call it.
- static bool first_crash = true;
- CHECK_ERROR(first_crash,
- "Crashed in crash signal handler. This is a bug in the fuzzer.");
-
- first_crash = false;
- write_extra_stats();
-}
-
-// If the user has specified an extra_stats_file through the environment
-// variable AFL_DRIVER_EXTRA_STATS_FILENAME, then perform necessary set up
-// to write stats to it on exit. If no file is specified, do nothing. Otherwise
-// install signal and exit handlers to write to the file when the process exits.
-// Then if the file doesn't exist create it and set extra stats to 0. But if it
-// does exist then read the initial values of the extra stats from the file
-// and check that the file is writable.
-static void maybe_initialize_extra_stats() {
- // If AFL_DRIVER_EXTRA_STATS_FILENAME isn't set then we have nothing to do.
- char *extra_stats_filename = getenv("AFL_DRIVER_EXTRA_STATS_FILENAME");
- if (!extra_stats_filename)
- return;
-
- // Open the file and find the previous peak_rss_mb value.
- // This is necessary because the fuzzing process is restarted after N
- // iterations are completed. So we may need to get this value from a previous
- // process to be accurate.
- extra_stats_file = fopen(extra_stats_filename, "r");
-
- // If extra_stats_file already exists: read old stats from it.
- if (extra_stats_file) {
- int matches = fscanf(extra_stats_file, kExtraStatsFormatString,
- &previous_peak_rss, &slowest_unit_time_secs);
-
- // Make sure we have read a real extra stats file and that we have used it
- // to set slowest_unit_time_secs and previous_peak_rss.
- CHECK_ERROR(matches == kNumExtraStats, "Extra stats file is corrupt");
-
- CHECK_ERROR(fclose(extra_stats_file) == 0, "Failed to close file");
-
- // Now open the file for writing.
- extra_stats_file = fopen(extra_stats_filename, "w");
- CHECK_ERROR(extra_stats_file,
- "Failed to open extra stats file for writing");
- } else {
- // Looks like this is the first time in a fuzzing job this is being called.
- extra_stats_file = fopen(extra_stats_filename, "w+");
- CHECK_ERROR(extra_stats_file, "failed to create extra stats file");
- }
-
- // Make sure that crash_handler gets called on any kind of fatal error.
- int crash_signals[] = {SIGSEGV, SIGBUS, SIGABRT, SIGILL, SIGFPE, SIGINT,
- SIGTERM};
-
- const size_t num_signals = sizeof(crash_signals) / sizeof(crash_signals[0]);
-
- for (size_t idx = 0; idx < num_signals; idx++)
- SetSigaction(crash_signals[idx], crash_handler);
-
- // Make sure it gets called on other kinds of exits.
- atexit(write_extra_stats);
-}
-
-// If the user asks us to duplicate stderr, then do it.
-static void maybe_duplicate_stderr() {
- char* stderr_duplicate_filename =
- getenv("AFL_DRIVER_STDERR_DUPLICATE_FILENAME");
-
- if (!stderr_duplicate_filename)
- return;
-
- FILE* stderr_duplicate_stream =
- freopen(stderr_duplicate_filename, "a+", stderr);
-
- if (!stderr_duplicate_stream) {
- fprintf(
- stderr,
- "Failed to duplicate stderr to AFL_DRIVER_STDERR_DUPLICATE_FILENAME");
- abort();
- }
-}
-
-// Define LLVMFuzzerMutate to avoid link failures for targets that use it
-// with libFuzzer's LLVMFuzzerCustomMutator.
-extern "C" size_t LLVMFuzzerMutate(uint8_t *Data, size_t Size, size_t MaxSize) {
- assert(false && "LLVMFuzzerMutate should not be called from afl_driver");
- return 0;
-}
-
-// Execute any files provided as parameters.
-int ExecuteFilesOnyByOne(int argc, char **argv) {
- for (int i = 1; i < argc; i++) {
- std::ifstream in(argv[i], std::ios::binary);
- in.seekg(0, in.end);
- size_t length = in.tellg();
- in.seekg (0, in.beg);
- std::cout << "Reading " << length << " bytes from " << argv[i] << std::endl;
- // Allocate exactly length bytes so that we reliably catch buffer overflows.
- std::vector<char> bytes(length);
- in.read(bytes.data(), bytes.size());
- assert(in);
- LLVMFuzzerTestOneInput(reinterpret_cast<const uint8_t *>(bytes.data()),
- bytes.size());
- std::cout << "Execution successful" << std::endl;
- }
- return 0;
-}
-
-int main(int argc, char **argv) {
- fprintf(stderr,
- "======================= INFO =========================\n"
- "This binary is built for AFL-fuzz.\n"
- "To run the target function on individual input(s) execute this:\n"
- " %s < INPUT_FILE\n"
- "or\n"
- " %s INPUT_FILE1 [INPUT_FILE2 ... ]\n"
- "To fuzz with afl-fuzz execute this:\n"
- " afl-fuzz [afl-flags] %s [-N]\n"
- "afl-fuzz will run N iterations before "
- "re-spawning the process (default: 1000)\n"
- "======================================================\n",
- argv[0], argv[0], argv[0]);
- if (LLVMFuzzerInitialize)
- LLVMFuzzerInitialize(&argc, &argv);
- // Do any other expensive one-time initialization here.
-
- maybe_duplicate_stderr();
- maybe_initialize_extra_stats();
-
- if (!getenv("AFL_DRIVER_DONT_DEFER"))
- __afl_manual_init();
-
- int N = 1000;
- if (argc == 2 && argv[1][0] == '-')
- N = atoi(argv[1] + 1);
- else if(argc == 2 && (N = atoi(argv[1])) > 0)
- fprintf(stderr, "WARNING: using the deprecated call style `%s %d`\n",
- argv[0], N);
- else if (argc > 1)
- return ExecuteFilesOnyByOne(argc, argv);
-
- assert(N > 0);
-
- // Call LLVMFuzzerTestOneInput here so that coverage caused by initialization
- // on the first execution of LLVMFuzzerTestOneInput is ignored.
- uint8_t dummy_input[1] = {0};
- LLVMFuzzerTestOneInput(dummy_input, 1);
-
- time_t unit_time_secs;
- int num_runs = 0;
- while (__afl_persistent_loop(N)) {
- ssize_t n_read = read(0, AflInputBuf, kMaxAflInputSize);
- if (n_read > 0) {
- // Copy AflInputBuf into a separate buffer to let asan find buffer
- // overflows. Don't use unique_ptr/etc to avoid extra dependencies.
- uint8_t *copy = new uint8_t[n_read];
- memcpy(copy, AflInputBuf, n_read);
-
- struct timeval unit_start_time;
- CHECK_ERROR(gettimeofday(&unit_start_time, NULL) == 0,
- "Calling gettimeofday failed");
-
- num_runs++;
- LLVMFuzzerTestOneInput(copy, n_read);
-
- struct timeval unit_stop_time;
- CHECK_ERROR(gettimeofday(&unit_stop_time, NULL) == 0,
- "Calling gettimeofday failed");
-
- // Update slowest_unit_time_secs if we see a new max.
- unit_time_secs = unit_stop_time.tv_sec - unit_start_time.tv_sec;
- if (slowest_unit_time_secs < unit_time_secs)
- slowest_unit_time_secs = unit_time_secs;
-
- delete[] copy;
- }
- }
- fprintf(stderr, "%s: successfully executed %d input(s)\n", argv[0], num_runs);
-}
diff --git a/lib/fuzzer/build.sh b/lib/fuzzer/build.sh
deleted file mode 100755
index 504e54e3a819e..0000000000000
--- a/lib/fuzzer/build.sh
+++ /dev/null
@@ -1,11 +0,0 @@
-#!/bin/sh
-LIBFUZZER_SRC_DIR=$(dirname $0)
-CXX="${CXX:-clang}"
-for f in $LIBFUZZER_SRC_DIR/*.cpp; do
- $CXX -g -O2 -fno-omit-frame-pointer -std=c++11 $f -c &
-done
-wait
-rm -f libFuzzer.a
-ar ru libFuzzer.a Fuzzer*.o
-rm -f Fuzzer*.o
-
diff --git a/lib/fuzzer/dataflow/DataFlow.cpp b/lib/fuzzer/dataflow/DataFlow.cpp
deleted file mode 100644
index a79c796ac456c..0000000000000
--- a/lib/fuzzer/dataflow/DataFlow.cpp
+++ /dev/null
@@ -1,217 +0,0 @@
-/*===- DataFlow.cpp - a standalone DataFlow tracer -------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// An experimental data-flow tracer for fuzz targets.
-// It is based on DFSan and SanitizerCoverage.
-// https://clang.llvm.org/docs/DataFlowSanitizer.html
-// https://clang.llvm.org/docs/SanitizerCoverage.html#tracing-data-flow
-//
-// It executes the fuzz target on the given input while monitoring the
-// data flow for every instrumented comparison instruction.
-//
-// The output shows which functions depend on which bytes of the input.
-//
-// Build:
-// 1. Compile this file with -fsanitize=dataflow
-// 2. Build the fuzz target with -g -fsanitize=dataflow
-// -fsanitize-coverage=trace-pc-guard,pc-table,func,trace-cmp
-// 3. Link those together with -fsanitize=dataflow
-//
-// -fsanitize-coverage=trace-cmp inserts callbacks around every comparison
-// instruction, DFSan modifies the calls to pass the data flow labels.
-// The callbacks update the data flow label for the current function.
-// See e.g. __dfsw___sanitizer_cov_trace_cmp1 below.
-//
-// -fsanitize-coverage=trace-pc-guard,pc-table,func instruments function
-// entries so that the comparison callback knows that current function.
-//
-//
-// Run:
-// # Collect data flow for INPUT_FILE, write to OUTPUT_FILE (default: stdout)
-// ./a.out INPUT_FILE [OUTPUT_FILE]
-//
-// # Print all instrumented functions. llvm-symbolizer must be present in PATH
-// ./a.out
-//
-// Example output:
-// ===============
-// F0 11111111111111
-// F1 10000000000000
-// ===============
-// "FN xxxxxxxxxx": tells what bytes of the input does the function N depend on.
-// The byte string is LEN+1 bytes. The last byte is set if the function
-// depends on the input length.
-//===----------------------------------------------------------------------===*/
-
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-#include <stdint.h>
-#include <string.h>
-
-#include <execinfo.h> // backtrace_symbols_fd
-
-#include <sanitizer/dfsan_interface.h>
-
-extern "C" {
-extern int LLVMFuzzerTestOneInput(const unsigned char *Data, size_t Size);
-__attribute__((weak)) extern int LLVMFuzzerInitialize(int *argc, char ***argv);
-} // extern "C"
-
-static size_t InputLen;
-static size_t NumFuncs;
-static const uintptr_t *FuncsBeg;
-static __thread size_t CurrentFunc;
-static dfsan_label *FuncLabels; // Array of NumFuncs elements.
-static char *PrintableStringForLabel; // InputLen + 2 bytes.
-static bool LabelSeen[1 << 8 * sizeof(dfsan_label)];
-
-// Prints all instrumented functions.
-static int PrintFunctions() {
- // We don't have the symbolizer integrated with dfsan yet.
- // So use backtrace_symbols_fd and pipe it through llvm-symbolizer.
- // TODO(kcc): this is pretty ugly and may break in lots of ways.
- // We'll need to make a proper in-process symbolizer work with DFSan.
- FILE *Pipe = popen("sed 's/(+/ /g; s/).*//g' "
- "| llvm-symbolizer "
- "| grep 'dfs\\$' "
- "| sed 's/dfs\\$//g'", "w");
- for (size_t I = 0; I < NumFuncs; I++) {
- uintptr_t PC = FuncsBeg[I * 2];
- void *const Buf[1] = {(void*)PC};
- backtrace_symbols_fd(Buf, 1, fileno(Pipe));
- }
- pclose(Pipe);
- return 0;
-}
-
-extern "C"
-void SetBytesForLabel(dfsan_label L, char *Bytes) {
- if (LabelSeen[L])
- return;
- LabelSeen[L] = true;
- assert(L);
- if (L <= InputLen + 1) {
- Bytes[L - 1] = '1';
- } else {
- auto *DLI = dfsan_get_label_info(L);
- SetBytesForLabel(DLI->l1, Bytes);
- SetBytesForLabel(DLI->l2, Bytes);
- }
-}
-
-static char *GetPrintableStringForLabel(dfsan_label L) {
- memset(PrintableStringForLabel, '0', InputLen + 1);
- PrintableStringForLabel[InputLen + 1] = 0;
- memset(LabelSeen, 0, sizeof(LabelSeen));
- SetBytesForLabel(L, PrintableStringForLabel);
- return PrintableStringForLabel;
-}
-
-static void PrintDataFlow(FILE *Out) {
- for (size_t I = 0; I < NumFuncs; I++)
- if (FuncLabels[I])
- fprintf(Out, "F%zd %s\n", I, GetPrintableStringForLabel(FuncLabels[I]));
-}
-
-int main(int argc, char **argv) {
- if (LLVMFuzzerInitialize)
- LLVMFuzzerInitialize(&argc, &argv);
- if (argc == 1)
- return PrintFunctions();
- assert(argc == 4 || argc == 5);
- size_t Beg = atoi(argv[1]);
- size_t End = atoi(argv[2]);
- assert(Beg < End);
-
- const char *Input = argv[3];
- fprintf(stderr, "INFO: reading '%s'\n", Input);
- FILE *In = fopen(Input, "r");
- assert(In);
- fseek(In, 0, SEEK_END);
- InputLen = ftell(In);
- fseek(In, 0, SEEK_SET);
- unsigned char *Buf = (unsigned char*)malloc(InputLen);
- size_t NumBytesRead = fread(Buf, 1, InputLen, In);
- assert(NumBytesRead == InputLen);
- PrintableStringForLabel = (char*)malloc(InputLen + 2);
- fclose(In);
-
- fprintf(stderr, "INFO: running '%s'\n", Input);
- for (size_t I = 1; I <= InputLen; I++) {
- dfsan_label L = dfsan_create_label("", nullptr);
- assert(L == I);
- size_t Idx = I - 1;
- if (Idx >= Beg && Idx < End)
- dfsan_set_label(L, Buf + Idx, 1);
- }
- dfsan_label SizeL = dfsan_create_label("", nullptr);
- assert(SizeL == InputLen + 1);
- dfsan_set_label(SizeL, &InputLen, sizeof(InputLen));
-
- LLVMFuzzerTestOneInput(Buf, InputLen);
- free(Buf);
-
- bool OutIsStdout = argc == 4;
- fprintf(stderr, "INFO: writing dataflow to %s\n",
- OutIsStdout ? "<stdout>" : argv[4]);
- FILE *Out = OutIsStdout ? stdout : fopen(argv[4], "w");
- PrintDataFlow(Out);
- if (!OutIsStdout) fclose(Out);
-}
-
-extern "C" {
-
-void __sanitizer_cov_trace_pc_guard_init(uint32_t *start,
- uint32_t *stop) {
- assert(NumFuncs == 0 && "This tool does not support DSOs");
- assert(start < stop && "The code is not instrumented for coverage");
- if (start == stop || *start) return; // Initialize only once.
- for (uint32_t *x = start; x < stop; x++)
- *x = ++NumFuncs; // The first index is 1.
- FuncLabels = (dfsan_label*)calloc(NumFuncs, sizeof(dfsan_label));
- fprintf(stderr, "INFO: %zd instrumented function(s) observed\n", NumFuncs);
-}
-
-void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
- const uintptr_t *pcs_end) {
- assert(NumFuncs == (pcs_end - pcs_beg) / 2);
- FuncsBeg = pcs_beg;
-}
-
-void __sanitizer_cov_trace_pc_indir(uint64_t x){} // unused.
-
-void __sanitizer_cov_trace_pc_guard(uint32_t *guard){
- uint32_t FuncNum = *guard - 1; // Guards start from 1.
- assert(FuncNum < NumFuncs);
- CurrentFunc = FuncNum;
-}
-
-void __dfsw___sanitizer_cov_trace_switch(uint64_t Val, uint64_t *Cases,
- dfsan_label L1, dfsan_label UnusedL) {
- assert(CurrentFunc < NumFuncs);
- FuncLabels[CurrentFunc] = dfsan_union(FuncLabels[CurrentFunc], L1);
-}
-
-#define HOOK(Name, Type) \
- void Name(Type Arg1, Type Arg2, dfsan_label L1, dfsan_label L2) { \
- assert(CurrentFunc < NumFuncs); \
- FuncLabels[CurrentFunc] = \
- dfsan_union(FuncLabels[CurrentFunc], dfsan_union(L1, L2)); \
- }
-
-HOOK(__dfsw___sanitizer_cov_trace_const_cmp1, uint8_t)
-HOOK(__dfsw___sanitizer_cov_trace_const_cmp2, uint16_t)
-HOOK(__dfsw___sanitizer_cov_trace_const_cmp4, uint32_t)
-HOOK(__dfsw___sanitizer_cov_trace_const_cmp8, uint64_t)
-HOOK(__dfsw___sanitizer_cov_trace_cmp1, uint8_t)
-HOOK(__dfsw___sanitizer_cov_trace_cmp2, uint16_t)
-HOOK(__dfsw___sanitizer_cov_trace_cmp4, uint32_t)
-HOOK(__dfsw___sanitizer_cov_trace_cmp8, uint64_t)
-
-} // extern "C"
diff --git a/lib/fuzzer/scripts/collect_data_flow.py b/lib/fuzzer/scripts/collect_data_flow.py
deleted file mode 100755
index 3edff66bb9d16..0000000000000
--- a/lib/fuzzer/scripts/collect_data_flow.py
+++ /dev/null
@@ -1,79 +0,0 @@
-#!/usr/bin/env python
-#===- lib/fuzzer/scripts/collect_data_flow.py ------------------------------===#
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-# Runs the data-flow tracer several times on the same input in order to collect
-# the complete trace for all input bytes (running it on all bytes at once
-# may fail if DFSan runs out of labels).
-# Usage:
-#
-# # Collect dataflow for one input, store it in OUTPUT (default is stdout)
-# collect_data_flow.py BINARY INPUT [OUTPUT]
-#
-# # Collect dataflow for all inputs in CORPUS_DIR, store them in OUTPUT_DIR
-# collect_data_flow.py BINARY CORPUS_DIR OUTPUT_DIR
-#===------------------------------------------------------------------------===#
-import atexit
-import hashlib
-import sys
-import os
-import subprocess
-import tempfile
-import shutil
-
-tmpdir = ""
-
-def cleanup(d):
- print("removing: %s" % d)
- shutil.rmtree(d)
-
-def collect_dataflow_for_corpus(self, exe, corpus_dir, output_dir):
- print("Collecting dataflow for corpus: %s output_dir: %s" % (corpus_dir,
- output_dir))
- assert not os.path.exists(output_dir)
- os.mkdir(output_dir)
- for root, dirs, files in os.walk(corpus_dir):
- for f in files:
- path = os.path.join(root, f)
- sha1 = hashlib.sha1(open(path).read()).hexdigest()
- output = os.path.join(output_dir, sha1)
- subprocess.call([self, exe, path, output])
- functions_txt = open(os.path.join(output_dir, "functions.txt"), "w")
- subprocess.call([exe], stdout=functions_txt)
-
-
-def main(argv):
- exe = argv[1]
- inp = argv[2]
- if os.path.isdir(inp):
- return collect_dataflow_for_corpus(argv[0], exe, inp, argv[3])
- size = os.path.getsize(inp)
- q = [[0, size]]
- tmpdir = tempfile.mkdtemp(prefix="libfuzzer-tmp-")
- atexit.register(cleanup, tmpdir)
- print "tmpdir: ", tmpdir
- outputs = []
- while len(q):
- r = q.pop()
- print "******* Trying: ", r
- tmpfile = os.path.join(tmpdir, str(r[0]) + "-" + str(r[1]))
- ret = subprocess.call([exe, str(r[0]), str(r[1]), inp, tmpfile])
- if ret and r[1] - r[0] >= 2:
- q.append([r[0], (r[1] + r[0]) / 2])
- q.append([(r[1] + r[0]) / 2, r[1]])
- else:
- outputs.append(tmpfile)
- print "******* Success: ", r
- f = sys.stdout
- if len(argv) >= 4:
- f = open(argv[3], "w")
- merge = os.path.join(os.path.dirname(argv[0]), "merge_data_flow.py")
- subprocess.call([merge] + outputs, stdout=f)
-
-if __name__ == '__main__':
- main(sys.argv)
diff --git a/lib/fuzzer/scripts/merge_data_flow.py b/lib/fuzzer/scripts/merge_data_flow.py
deleted file mode 100755
index d2f5081e7b8cc..0000000000000
--- a/lib/fuzzer/scripts/merge_data_flow.py
+++ /dev/null
@@ -1,36 +0,0 @@
-#!/usr/bin/env python
-#===- lib/fuzzer/scripts/merge_data_flow.py ------------------------------===#
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-# Merge several data flow traces into one.
-# Usage:
-# merge_data_flow.py trace1 trace2 ... > result
-#===------------------------------------------------------------------------===#
-import sys
-import fileinput
-from array import array
-
-def Merge(a, b):
- res = array('b')
- for i in range(0, len(a)):
- res.append(ord('1' if a[i] == '1' or b[i] == '1' else '0'))
- return res.tostring()
-
-def main(argv):
- D = {}
- for line in fileinput.input():
- [F,BV] = line.strip().split(' ')
- if F in D:
- D[F] = Merge(D[F], BV)
- else:
- D[F] = BV;
- for F in D.keys():
- print("%s %s" % (F, D[F]))
-
-if __name__ == '__main__':
- main(sys.argv)
diff --git a/lib/fuzzer/scripts/unbalanced_allocs.py b/lib/fuzzer/scripts/unbalanced_allocs.py
deleted file mode 100755
index 74478ad55af0c..0000000000000
--- a/lib/fuzzer/scripts/unbalanced_allocs.py
+++ /dev/null
@@ -1,93 +0,0 @@
-#!/usr/bin/env python
-#===- lib/fuzzer/scripts/unbalanced_allocs.py ------------------------------===#
-#
-# The LLVM Compiler Infrastructure
-#
-# This file is distributed under the University of Illinois Open Source
-# License. See LICENSE.TXT for details.
-#
-#===------------------------------------------------------------------------===#
-#
-# Post-process -trace_malloc=2 output and printout only allocations and frees
-# unbalanced inside of fuzzer runs.
-# Usage:
-# my_fuzzer -trace_malloc=2 -runs=10 2>&1 | unbalanced_allocs.py -skip=5
-#
-#===------------------------------------------------------------------------===#
-
-import argparse
-import sys
-
-_skip = 0
-
-def PrintStack(line, stack):
- global _skip
- if _skip > 0:
- return
- print('Unbalanced ' + line.rstrip());
- for l in stack:
- print(l.rstrip())
-
-def ProcessStack(line, f):
- stack = []
- while line and line.startswith(' #'):
- stack += [line]
- line = f.readline()
- return line, stack
-
-def ProcessFree(line, f, allocs):
- if not line.startswith('FREE['):
- return f.readline()
-
- addr = int(line.split()[1], 16)
- next_line, stack = ProcessStack(f.readline(), f)
- if addr in allocs:
- del allocs[addr]
- else:
- PrintStack(line, stack)
- return next_line
-
-def ProcessMalloc(line, f, allocs):
- if not line.startswith('MALLOC['):
- return ProcessFree(line, f, allocs)
-
- addr = int(line.split()[1], 16)
- assert not addr in allocs
-
- next_line, stack = ProcessStack(f.readline(), f)
- allocs[addr] = (line, stack)
- return next_line
-
-def ProcessRun(line, f):
- if not line.startswith('MallocFreeTracer: START'):
- return ProcessMalloc(line, f, {})
-
- allocs = {}
- print(line.rstrip())
- line = f.readline()
- while line:
- if line.startswith('MallocFreeTracer: STOP'):
- global _skip
- _skip = _skip - 1
- for _, (l, s) in allocs.items():
- PrintStack(l, s)
- print(line.rstrip())
- return f.readline()
- line = ProcessMalloc(line, f, allocs)
- return line
-
-def ProcessFile(f):
- line = f.readline()
- while line:
- line = ProcessRun(line, f);
-
-def main(argv):
- parser = argparse.ArgumentParser()
- parser.add_argument('--skip', default=0, help='number of runs to ignore')
- args = parser.parse_args()
- global _skip
- _skip = int(args.skip) + 1
- ProcessFile(sys.stdin)
-
-if __name__ == '__main__':
- main(sys.argv)
diff --git a/lib/fuzzer/standalone/StandaloneFuzzTargetMain.c b/lib/fuzzer/standalone/StandaloneFuzzTargetMain.c
deleted file mode 100644
index 0d76ea49e7964..0000000000000
--- a/lib/fuzzer/standalone/StandaloneFuzzTargetMain.c
+++ /dev/null
@@ -1,41 +0,0 @@
-/*===- StandaloneFuzzTargetMain.c - standalone main() for fuzz targets. ---===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// This main() function can be linked to a fuzz target (i.e. a library
-// that exports LLVMFuzzerTestOneInput() and possibly LLVMFuzzerInitialize())
-// instead of libFuzzer. This main() function will not perform any fuzzing
-// but will simply feed all input files one by one to the fuzz target.
-//
-// Use this file to provide reproducers for bugs when linking against libFuzzer
-// or other fuzzing engine is undesirable.
-//===----------------------------------------------------------------------===*/
-#include <assert.h>
-#include <stdio.h>
-#include <stdlib.h>
-
-extern int LLVMFuzzerTestOneInput(const unsigned char *data, size_t size);
-__attribute__((weak)) extern int LLVMFuzzerInitialize(int *argc, char ***argv);
-int main(int argc, char **argv) {
- fprintf(stderr, "StandaloneFuzzTargetMain: running %d inputs\n", argc - 1);
- if (LLVMFuzzerInitialize)
- LLVMFuzzerInitialize(&argc, &argv);
- for (int i = 1; i < argc; i++) {
- fprintf(stderr, "Running: %s\n", argv[i]);
- FILE *f = fopen(argv[i], "r");
- assert(f);
- fseek(f, 0, SEEK_END);
- size_t len = ftell(f);
- fseek(f, 0, SEEK_SET);
- unsigned char *buf = (unsigned char*)malloc(len);
- size_t n_read = fread(buf, 1, len, f);
- assert(n_read == len);
- LLVMFuzzerTestOneInput(buf, len);
- free(buf);
- fprintf(stderr, "Done: %s: (%zd bytes)\n", argv[i], n_read);
- }
-}
diff --git a/lib/fuzzer/tests/CMakeLists.txt b/lib/fuzzer/tests/CMakeLists.txt
deleted file mode 100644
index 6abb72def3e19..0000000000000
--- a/lib/fuzzer/tests/CMakeLists.txt
+++ /dev/null
@@ -1,64 +0,0 @@
-include(CompilerRTCompile)
-
-set(LIBFUZZER_UNITTEST_CFLAGS
- ${COMPILER_RT_UNITTEST_CFLAGS}
- ${COMPILER_RT_GTEST_CFLAGS}
- -I${COMPILER_RT_SOURCE_DIR}/lib/fuzzer
- -fno-rtti
- -O2)
-
-if (APPLE)
- set(FUZZER_SUPPORTED_OS osx)
-endif()
-
-add_custom_target(FuzzerUnitTests)
-set_target_properties(FuzzerUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
-
-set(LIBFUZZER_UNITTEST_LINK_FLAGS ${COMPILER_RT_UNITTEST_LINK_FLAGS})
-list(APPEND LIBFUZZER_UNITTEST_LINK_FLAGS --driver-mode=g++)
-
-if(APPLE OR CMAKE_SYSTEM_NAME STREQUAL "FreeBSD")
- list(APPEND LIBFUZZER_UNITTEST_LINK_FLAGS -lc++ -lpthread)
-elseif(NOT WIN32)
- list(APPEND LIBFUZZER_UNITTEST_LINK_FLAGS -lstdc++ -lpthread)
-endif()
-
-if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" AND COMPILER_RT_LIBCXX_PATH)
- list(APPEND LIBFUZZER_UNITTEST_CFLAGS -nostdinc++)
-endif()
-
-if(COMPILER_RT_DEFAULT_TARGET_ARCH IN_LIST FUZZER_SUPPORTED_ARCH)
- # libFuzzer unit tests are only run on the host machine.
- set(arch ${COMPILER_RT_DEFAULT_TARGET_ARCH})
-
- set(LIBFUZZER_TEST_RUNTIME RTFuzzerTest.${arch})
- if(APPLE)
- set(LIBFUZZER_TEST_RUNTIME_OBJECTS
- $<TARGET_OBJECTS:RTfuzzer.osx>)
- else()
- set(LIBFUZZER_TEST_RUNTIME_OBJECTS
- $<TARGET_OBJECTS:RTfuzzer.${arch}>)
- endif()
- add_library(${LIBFUZZER_TEST_RUNTIME} STATIC
- ${LIBFUZZER_TEST_RUNTIME_OBJECTS})
- set_target_properties(${LIBFUZZER_TEST_RUNTIME} PROPERTIES
- ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- FOLDER "Compiler-RT Runtime tests")
-
- if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" AND COMPILER_RT_LIBCXX_PATH)
- set(LIBFUZZER_TEST_RUNTIME_DEPS libcxx_fuzzer_${arch}-build)
- set(LIBFUZZER_TEST_RUNTIME_CFLAGS -isystem ${LIBCXX_${arch}_PREFIX}/include/c++/v1)
- set(LIBFUZZER_TEST_RUNTIME_LINK_FLAGS ${LIBCXX_${arch}_PREFIX}/lib/libc++.a)
- endif()
-
- set(FuzzerTestObjects)
- generate_compiler_rt_tests(FuzzerTestObjects
- FuzzerUnitTests "Fuzzer-${arch}-Test" ${arch}
- SOURCES FuzzerUnittest.cpp ${COMPILER_RT_GTEST_SOURCE}
- RUNTIME ${LIBFUZZER_TEST_RUNTIME}
- DEPS gtest ${LIBFUZZER_TEST_RUNTIME_DEPS}
- CFLAGS ${LIBFUZZER_UNITTEST_CFLAGS} ${LIBFUZZER_TEST_RUNTIME_CFLAGS}
- LINK_FLAGS ${LIBFUZZER_UNITTEST_LINK_FLAGS} ${LIBFUZZER_TEST_RUNTIME_LINK_FLAGS})
- set_target_properties(FuzzerUnitTests PROPERTIES
- RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
-endif()
diff --git a/lib/fuzzer/tests/FuzzerUnittest.cpp b/lib/fuzzer/tests/FuzzerUnittest.cpp
deleted file mode 100644
index 7cdd44582329e..0000000000000
--- a/lib/fuzzer/tests/FuzzerUnittest.cpp
+++ /dev/null
@@ -1,964 +0,0 @@
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-
-// Avoid ODR violations (LibFuzzer is built without ASan and this test is built
-// with ASan) involving C++ standard library types when using libcxx.
-#define _LIBCPP_HAS_NO_ASAN
-
-// Do not attempt to use LLVM ostream from gtest.
-#define GTEST_NO_LLVM_RAW_OSTREAM 1
-
-#include "FuzzerCorpus.h"
-#include "FuzzerDictionary.h"
-#include "FuzzerInternal.h"
-#include "FuzzerMerge.h"
-#include "FuzzerMutate.h"
-#include "FuzzerRandom.h"
-#include "FuzzerTracePC.h"
-#include "gtest/gtest.h"
-#include <memory>
-#include <set>
-#include <sstream>
-
-using namespace fuzzer;
-
-// For now, have LLVMFuzzerTestOneInput just to make it link.
-// Later we may want to make unittests that actually call LLVMFuzzerTestOneInput.
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
- abort();
-}
-
-TEST(Fuzzer, Basename) {
- EXPECT_EQ(Basename("foo/bar"), "bar");
- EXPECT_EQ(Basename("bar"), "bar");
- EXPECT_EQ(Basename("/bar"), "bar");
- EXPECT_EQ(Basename("foo/x"), "x");
- EXPECT_EQ(Basename("foo/"), "");
-#if LIBFUZZER_WINDOWS
- EXPECT_EQ(Basename("foo\\bar"), "bar");
- EXPECT_EQ(Basename("foo\\bar/baz"), "baz");
- EXPECT_EQ(Basename("\\bar"), "bar");
- EXPECT_EQ(Basename("foo\\x"), "x");
- EXPECT_EQ(Basename("foo\\"), "");
-#endif
-}
-
-TEST(Fuzzer, CrossOver) {
- std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
- fuzzer::EF = t.get();
- Random Rand(0);
- std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
- Unit A({0, 1, 2}), B({5, 6, 7});
- Unit C;
- Unit Expected[] = {
- { 0 },
- { 0, 1 },
- { 0, 5 },
- { 0, 1, 2 },
- { 0, 1, 5 },
- { 0, 5, 1 },
- { 0, 5, 6 },
- { 0, 1, 2, 5 },
- { 0, 1, 5, 2 },
- { 0, 1, 5, 6 },
- { 0, 5, 1, 2 },
- { 0, 5, 1, 6 },
- { 0, 5, 6, 1 },
- { 0, 5, 6, 7 },
- { 0, 1, 2, 5, 6 },
- { 0, 1, 5, 2, 6 },
- { 0, 1, 5, 6, 2 },
- { 0, 1, 5, 6, 7 },
- { 0, 5, 1, 2, 6 },
- { 0, 5, 1, 6, 2 },
- { 0, 5, 1, 6, 7 },
- { 0, 5, 6, 1, 2 },
- { 0, 5, 6, 1, 7 },
- { 0, 5, 6, 7, 1 },
- { 0, 1, 2, 5, 6, 7 },
- { 0, 1, 5, 2, 6, 7 },
- { 0, 1, 5, 6, 2, 7 },
- { 0, 1, 5, 6, 7, 2 },
- { 0, 5, 1, 2, 6, 7 },
- { 0, 5, 1, 6, 2, 7 },
- { 0, 5, 1, 6, 7, 2 },
- { 0, 5, 6, 1, 2, 7 },
- { 0, 5, 6, 1, 7, 2 },
- { 0, 5, 6, 7, 1, 2 }
- };
- for (size_t Len = 1; Len < 8; Len++) {
- Set<Unit> FoundUnits, ExpectedUnitsWitThisLength;
- for (int Iter = 0; Iter < 3000; Iter++) {
- C.resize(Len);
- size_t NewSize = MD->CrossOver(A.data(), A.size(), B.data(), B.size(),
- C.data(), C.size());
- C.resize(NewSize);
- FoundUnits.insert(C);
- }
- for (const Unit &U : Expected)
- if (U.size() <= Len)
- ExpectedUnitsWitThisLength.insert(U);
- EXPECT_EQ(ExpectedUnitsWitThisLength, FoundUnits);
- }
-}
-
-TEST(Fuzzer, Hash) {
- uint8_t A[] = {'a', 'b', 'c'};
- fuzzer::Unit U(A, A + sizeof(A));
- EXPECT_EQ("a9993e364706816aba3e25717850c26c9cd0d89d", fuzzer::Hash(U));
- U.push_back('d');
- EXPECT_EQ("81fe8bfe87576c3ecb22426f8e57847382917acf", fuzzer::Hash(U));
-}
-
-typedef size_t (MutationDispatcher::*Mutator)(uint8_t *Data, size_t Size,
- size_t MaxSize);
-
-void TestEraseBytes(Mutator M, int NumIter) {
- std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
- fuzzer::EF = t.get();
- uint8_t REM0[8] = {0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
- uint8_t REM1[8] = {0x00, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
- uint8_t REM2[8] = {0x00, 0x11, 0x33, 0x44, 0x55, 0x66, 0x77};
- uint8_t REM3[8] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x77};
- uint8_t REM4[8] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x66, 0x77};
- uint8_t REM5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x66, 0x77};
- uint8_t REM6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x77};
- uint8_t REM7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
-
- uint8_t REM8[6] = {0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
- uint8_t REM9[6] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55};
- uint8_t REM10[6] = {0x00, 0x11, 0x22, 0x55, 0x66, 0x77};
-
- uint8_t REM11[5] = {0x33, 0x44, 0x55, 0x66, 0x77};
- uint8_t REM12[5] = {0x00, 0x11, 0x22, 0x33, 0x44};
- uint8_t REM13[5] = {0x00, 0x44, 0x55, 0x66, 0x77};
-
-
- Random Rand(0);
- std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
- int FoundMask = 0;
- for (int i = 0; i < NumIter; i++) {
- uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
- size_t NewSize = (*MD.*M)(T, sizeof(T), sizeof(T));
- if (NewSize == 7 && !memcmp(REM0, T, 7)) FoundMask |= 1 << 0;
- if (NewSize == 7 && !memcmp(REM1, T, 7)) FoundMask |= 1 << 1;
- if (NewSize == 7 && !memcmp(REM2, T, 7)) FoundMask |= 1 << 2;
- if (NewSize == 7 && !memcmp(REM3, T, 7)) FoundMask |= 1 << 3;
- if (NewSize == 7 && !memcmp(REM4, T, 7)) FoundMask |= 1 << 4;
- if (NewSize == 7 && !memcmp(REM5, T, 7)) FoundMask |= 1 << 5;
- if (NewSize == 7 && !memcmp(REM6, T, 7)) FoundMask |= 1 << 6;
- if (NewSize == 7 && !memcmp(REM7, T, 7)) FoundMask |= 1 << 7;
-
- if (NewSize == 6 && !memcmp(REM8, T, 6)) FoundMask |= 1 << 8;
- if (NewSize == 6 && !memcmp(REM9, T, 6)) FoundMask |= 1 << 9;
- if (NewSize == 6 && !memcmp(REM10, T, 6)) FoundMask |= 1 << 10;
-
- if (NewSize == 5 && !memcmp(REM11, T, 5)) FoundMask |= 1 << 11;
- if (NewSize == 5 && !memcmp(REM12, T, 5)) FoundMask |= 1 << 12;
- if (NewSize == 5 && !memcmp(REM13, T, 5)) FoundMask |= 1 << 13;
- }
- EXPECT_EQ(FoundMask, (1 << 14) - 1);
-}
-
-TEST(FuzzerMutate, EraseBytes1) {
- TestEraseBytes(&MutationDispatcher::Mutate_EraseBytes, 200);
-}
-TEST(FuzzerMutate, EraseBytes2) {
- TestEraseBytes(&MutationDispatcher::Mutate, 2000);
-}
-
-void TestInsertByte(Mutator M, int NumIter) {
- std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
- fuzzer::EF = t.get();
- Random Rand(0);
- std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
- int FoundMask = 0;
- uint8_t INS0[8] = {0xF1, 0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
- uint8_t INS1[8] = {0x00, 0xF2, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
- uint8_t INS2[8] = {0x00, 0x11, 0xF3, 0x22, 0x33, 0x44, 0x55, 0x66};
- uint8_t INS3[8] = {0x00, 0x11, 0x22, 0xF4, 0x33, 0x44, 0x55, 0x66};
- uint8_t INS4[8] = {0x00, 0x11, 0x22, 0x33, 0xF5, 0x44, 0x55, 0x66};
- uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF6, 0x55, 0x66};
- uint8_t INS6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF7, 0x66};
- uint8_t INS7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF8};
- for (int i = 0; i < NumIter; i++) {
- uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
- size_t NewSize = (*MD.*M)(T, 7, 8);
- if (NewSize == 8 && !memcmp(INS0, T, 8)) FoundMask |= 1 << 0;
- if (NewSize == 8 && !memcmp(INS1, T, 8)) FoundMask |= 1 << 1;
- if (NewSize == 8 && !memcmp(INS2, T, 8)) FoundMask |= 1 << 2;
- if (NewSize == 8 && !memcmp(INS3, T, 8)) FoundMask |= 1 << 3;
- if (NewSize == 8 && !memcmp(INS4, T, 8)) FoundMask |= 1 << 4;
- if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
- if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
- if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
- }
- EXPECT_EQ(FoundMask, 255);
-}
-
-TEST(FuzzerMutate, InsertByte1) {
- TestInsertByte(&MutationDispatcher::Mutate_InsertByte, 1 << 15);
-}
-TEST(FuzzerMutate, InsertByte2) {
- TestInsertByte(&MutationDispatcher::Mutate, 1 << 17);
-}
-
-void TestInsertRepeatedBytes(Mutator M, int NumIter) {
- std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
- fuzzer::EF = t.get();
- Random Rand(0);
- std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
- int FoundMask = 0;
- uint8_t INS0[7] = {0x00, 0x11, 0x22, 0x33, 'a', 'a', 'a'};
- uint8_t INS1[7] = {0x00, 0x11, 0x22, 'a', 'a', 'a', 0x33};
- uint8_t INS2[7] = {0x00, 0x11, 'a', 'a', 'a', 0x22, 0x33};
- uint8_t INS3[7] = {0x00, 'a', 'a', 'a', 0x11, 0x22, 0x33};
- uint8_t INS4[7] = {'a', 'a', 'a', 0x00, 0x11, 0x22, 0x33};
-
- uint8_t INS5[8] = {0x00, 0x11, 0x22, 0x33, 'b', 'b', 'b', 'b'};
- uint8_t INS6[8] = {0x00, 0x11, 0x22, 'b', 'b', 'b', 'b', 0x33};
- uint8_t INS7[8] = {0x00, 0x11, 'b', 'b', 'b', 'b', 0x22, 0x33};
- uint8_t INS8[8] = {0x00, 'b', 'b', 'b', 'b', 0x11, 0x22, 0x33};
- uint8_t INS9[8] = {'b', 'b', 'b', 'b', 0x00, 0x11, 0x22, 0x33};
-
- for (int i = 0; i < NumIter; i++) {
- uint8_t T[8] = {0x00, 0x11, 0x22, 0x33};
- size_t NewSize = (*MD.*M)(T, 4, 8);
- if (NewSize == 7 && !memcmp(INS0, T, 7)) FoundMask |= 1 << 0;
- if (NewSize == 7 && !memcmp(INS1, T, 7)) FoundMask |= 1 << 1;
- if (NewSize == 7 && !memcmp(INS2, T, 7)) FoundMask |= 1 << 2;
- if (NewSize == 7 && !memcmp(INS3, T, 7)) FoundMask |= 1 << 3;
- if (NewSize == 7 && !memcmp(INS4, T, 7)) FoundMask |= 1 << 4;
-
- if (NewSize == 8 && !memcmp(INS5, T, 8)) FoundMask |= 1 << 5;
- if (NewSize == 8 && !memcmp(INS6, T, 8)) FoundMask |= 1 << 6;
- if (NewSize == 8 && !memcmp(INS7, T, 8)) FoundMask |= 1 << 7;
- if (NewSize == 8 && !memcmp(INS8, T, 8)) FoundMask |= 1 << 8;
- if (NewSize == 8 && !memcmp(INS9, T, 8)) FoundMask |= 1 << 9;
-
- }
- EXPECT_EQ(FoundMask, (1 << 10) - 1);
-}
-
-TEST(FuzzerMutate, InsertRepeatedBytes1) {
- TestInsertRepeatedBytes(&MutationDispatcher::Mutate_InsertRepeatedBytes, 10000);
-}
-TEST(FuzzerMutate, InsertRepeatedBytes2) {
- TestInsertRepeatedBytes(&MutationDispatcher::Mutate, 300000);
-}
-
-void TestChangeByte(Mutator M, int NumIter) {
- std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
- fuzzer::EF = t.get();
- Random Rand(0);
- std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
- int FoundMask = 0;
- uint8_t CH0[8] = {0xF0, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
- uint8_t CH1[8] = {0x00, 0xF1, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
- uint8_t CH2[8] = {0x00, 0x11, 0xF2, 0x33, 0x44, 0x55, 0x66, 0x77};
- uint8_t CH3[8] = {0x00, 0x11, 0x22, 0xF3, 0x44, 0x55, 0x66, 0x77};
- uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0xF4, 0x55, 0x66, 0x77};
- uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0xF5, 0x66, 0x77};
- uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0xF5, 0x77};
- uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
- for (int i = 0; i < NumIter; i++) {
- uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
- size_t NewSize = (*MD.*M)(T, 8, 9);
- if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
- if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
- if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
- if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
- if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
- if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
- if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
- if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
- }
- EXPECT_EQ(FoundMask, 255);
-}
-
-TEST(FuzzerMutate, ChangeByte1) {
- TestChangeByte(&MutationDispatcher::Mutate_ChangeByte, 1 << 15);
-}
-TEST(FuzzerMutate, ChangeByte2) {
- TestChangeByte(&MutationDispatcher::Mutate, 1 << 17);
-}
-
-void TestChangeBit(Mutator M, int NumIter) {
- std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
- fuzzer::EF = t.get();
- Random Rand(0);
- std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
- int FoundMask = 0;
- uint8_t CH0[8] = {0x01, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
- uint8_t CH1[8] = {0x00, 0x13, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
- uint8_t CH2[8] = {0x00, 0x11, 0x02, 0x33, 0x44, 0x55, 0x66, 0x77};
- uint8_t CH3[8] = {0x00, 0x11, 0x22, 0x37, 0x44, 0x55, 0x66, 0x77};
- uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x54, 0x55, 0x66, 0x77};
- uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x54, 0x66, 0x77};
- uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x76, 0x77};
- uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0xF7};
- for (int i = 0; i < NumIter; i++) {
- uint8_t T[9] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
- size_t NewSize = (*MD.*M)(T, 8, 9);
- if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
- if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
- if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
- if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
- if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
- if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
- if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
- if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
- }
- EXPECT_EQ(FoundMask, 255);
-}
-
-TEST(FuzzerMutate, ChangeBit1) {
- TestChangeBit(&MutationDispatcher::Mutate_ChangeBit, 1 << 16);
-}
-TEST(FuzzerMutate, ChangeBit2) {
- TestChangeBit(&MutationDispatcher::Mutate, 1 << 18);
-}
-
-void TestShuffleBytes(Mutator M, int NumIter) {
- std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
- fuzzer::EF = t.get();
- Random Rand(0);
- std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
- int FoundMask = 0;
- uint8_t CH0[7] = {0x00, 0x22, 0x11, 0x33, 0x44, 0x55, 0x66};
- uint8_t CH1[7] = {0x11, 0x00, 0x33, 0x22, 0x44, 0x55, 0x66};
- uint8_t CH2[7] = {0x00, 0x33, 0x11, 0x22, 0x44, 0x55, 0x66};
- uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x44, 0x55, 0x66, 0x33};
- uint8_t CH4[7] = {0x00, 0x11, 0x22, 0x33, 0x55, 0x44, 0x66};
- for (int i = 0; i < NumIter; i++) {
- uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
- size_t NewSize = (*MD.*M)(T, 7, 7);
- if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
- if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
- if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
- if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
- if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
- }
- EXPECT_EQ(FoundMask, 31);
-}
-
-TEST(FuzzerMutate, ShuffleBytes1) {
- TestShuffleBytes(&MutationDispatcher::Mutate_ShuffleBytes, 1 << 17);
-}
-TEST(FuzzerMutate, ShuffleBytes2) {
- TestShuffleBytes(&MutationDispatcher::Mutate, 1 << 20);
-}
-
-void TestCopyPart(Mutator M, int NumIter) {
- std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
- fuzzer::EF = t.get();
- Random Rand(0);
- std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
- int FoundMask = 0;
- uint8_t CH0[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11};
- uint8_t CH1[7] = {0x55, 0x66, 0x22, 0x33, 0x44, 0x55, 0x66};
- uint8_t CH2[7] = {0x00, 0x55, 0x66, 0x33, 0x44, 0x55, 0x66};
- uint8_t CH3[7] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x66};
- uint8_t CH4[7] = {0x00, 0x11, 0x11, 0x22, 0x33, 0x55, 0x66};
-
- for (int i = 0; i < NumIter; i++) {
- uint8_t T[7] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66};
- size_t NewSize = (*MD.*M)(T, 7, 7);
- if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
- if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
- if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
- if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
- if (NewSize == 7 && !memcmp(CH4, T, 7)) FoundMask |= 1 << 4;
- }
-
- uint8_t CH5[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22};
- uint8_t CH6[8] = {0x22, 0x33, 0x44, 0x00, 0x11, 0x22, 0x33, 0x44};
- uint8_t CH7[8] = {0x00, 0x11, 0x22, 0x00, 0x11, 0x22, 0x33, 0x44};
- uint8_t CH8[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x22, 0x33, 0x44};
- uint8_t CH9[8] = {0x00, 0x11, 0x22, 0x22, 0x33, 0x44, 0x33, 0x44};
-
- for (int i = 0; i < NumIter; i++) {
- uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
- size_t NewSize = (*MD.*M)(T, 5, 8);
- if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
- if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
- if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
- if (NewSize == 8 && !memcmp(CH8, T, 8)) FoundMask |= 1 << 8;
- if (NewSize == 8 && !memcmp(CH9, T, 8)) FoundMask |= 1 << 9;
- }
-
- EXPECT_EQ(FoundMask, 1023);
-}
-
-TEST(FuzzerMutate, CopyPart1) {
- TestCopyPart(&MutationDispatcher::Mutate_CopyPart, 1 << 10);
-}
-TEST(FuzzerMutate, CopyPart2) {
- TestCopyPart(&MutationDispatcher::Mutate, 1 << 13);
-}
-TEST(FuzzerMutate, CopyPartNoInsertAtMaxSize) {
- // This (non exhaustively) tests if `Mutate_CopyPart` tries to perform an
- // insert on an input of size `MaxSize`. Performing an insert in this case
- // will lead to the mutation failing.
- std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
- fuzzer::EF = t.get();
- Random Rand(0);
- std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
- uint8_t Data[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x00, 0x11, 0x22};
- size_t MaxSize = sizeof(Data);
- for (int count = 0; count < (1 << 18); ++count) {
- size_t NewSize = MD->Mutate_CopyPart(Data, MaxSize, MaxSize);
- ASSERT_EQ(NewSize, MaxSize);
- }
-}
-
-void TestAddWordFromDictionary(Mutator M, int NumIter) {
- std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
- fuzzer::EF = t.get();
- Random Rand(0);
- std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
- uint8_t Word1[4] = {0xAA, 0xBB, 0xCC, 0xDD};
- uint8_t Word2[3] = {0xFF, 0xEE, 0xEF};
- MD->AddWordToManualDictionary(Word(Word1, sizeof(Word1)));
- MD->AddWordToManualDictionary(Word(Word2, sizeof(Word2)));
- int FoundMask = 0;
- uint8_t CH0[7] = {0x00, 0x11, 0x22, 0xAA, 0xBB, 0xCC, 0xDD};
- uint8_t CH1[7] = {0x00, 0x11, 0xAA, 0xBB, 0xCC, 0xDD, 0x22};
- uint8_t CH2[7] = {0x00, 0xAA, 0xBB, 0xCC, 0xDD, 0x11, 0x22};
- uint8_t CH3[7] = {0xAA, 0xBB, 0xCC, 0xDD, 0x00, 0x11, 0x22};
- uint8_t CH4[6] = {0x00, 0x11, 0x22, 0xFF, 0xEE, 0xEF};
- uint8_t CH5[6] = {0x00, 0x11, 0xFF, 0xEE, 0xEF, 0x22};
- uint8_t CH6[6] = {0x00, 0xFF, 0xEE, 0xEF, 0x11, 0x22};
- uint8_t CH7[6] = {0xFF, 0xEE, 0xEF, 0x00, 0x11, 0x22};
- for (int i = 0; i < NumIter; i++) {
- uint8_t T[7] = {0x00, 0x11, 0x22};
- size_t NewSize = (*MD.*M)(T, 3, 7);
- if (NewSize == 7 && !memcmp(CH0, T, 7)) FoundMask |= 1 << 0;
- if (NewSize == 7 && !memcmp(CH1, T, 7)) FoundMask |= 1 << 1;
- if (NewSize == 7 && !memcmp(CH2, T, 7)) FoundMask |= 1 << 2;
- if (NewSize == 7 && !memcmp(CH3, T, 7)) FoundMask |= 1 << 3;
- if (NewSize == 6 && !memcmp(CH4, T, 6)) FoundMask |= 1 << 4;
- if (NewSize == 6 && !memcmp(CH5, T, 6)) FoundMask |= 1 << 5;
- if (NewSize == 6 && !memcmp(CH6, T, 6)) FoundMask |= 1 << 6;
- if (NewSize == 6 && !memcmp(CH7, T, 6)) FoundMask |= 1 << 7;
- }
- EXPECT_EQ(FoundMask, 255);
-}
-
-TEST(FuzzerMutate, AddWordFromDictionary1) {
- TestAddWordFromDictionary(
- &MutationDispatcher::Mutate_AddWordFromManualDictionary, 1 << 15);
-}
-
-TEST(FuzzerMutate, AddWordFromDictionary2) {
- TestAddWordFromDictionary(&MutationDispatcher::Mutate, 1 << 15);
-}
-
-void TestChangeASCIIInteger(Mutator M, int NumIter) {
- std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
- fuzzer::EF = t.get();
- Random Rand(0);
- std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
-
- uint8_t CH0[8] = {'1', '2', '3', '4', '5', '6', '7', '7'};
- uint8_t CH1[8] = {'1', '2', '3', '4', '5', '6', '7', '9'};
- uint8_t CH2[8] = {'2', '4', '6', '9', '1', '3', '5', '6'};
- uint8_t CH3[8] = {'0', '6', '1', '7', '2', '8', '3', '9'};
- int FoundMask = 0;
- for (int i = 0; i < NumIter; i++) {
- uint8_t T[8] = {'1', '2', '3', '4', '5', '6', '7', '8'};
- size_t NewSize = (*MD.*M)(T, 8, 8);
- /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
- else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
- else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
- else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
- else if (NewSize == 8) FoundMask |= 1 << 4;
- }
- EXPECT_EQ(FoundMask, 31);
-}
-
-TEST(FuzzerMutate, ChangeASCIIInteger1) {
- TestChangeASCIIInteger(&MutationDispatcher::Mutate_ChangeASCIIInteger,
- 1 << 15);
-}
-
-TEST(FuzzerMutate, ChangeASCIIInteger2) {
- TestChangeASCIIInteger(&MutationDispatcher::Mutate, 1 << 15);
-}
-
-void TestChangeBinaryInteger(Mutator M, int NumIter) {
- std::unique_ptr<ExternalFunctions> t(new ExternalFunctions());
- fuzzer::EF = t.get();
- Random Rand(0);
- std::unique_ptr<MutationDispatcher> MD(new MutationDispatcher(Rand, {}));
-
- uint8_t CH0[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x79};
- uint8_t CH1[8] = {0x00, 0x11, 0x22, 0x31, 0x44, 0x55, 0x66, 0x77};
- uint8_t CH2[8] = {0xff, 0x10, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
- uint8_t CH3[8] = {0x00, 0x11, 0x2a, 0x33, 0x44, 0x55, 0x66, 0x77};
- uint8_t CH4[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x4f, 0x66, 0x77};
- uint8_t CH5[8] = {0xff, 0xee, 0xdd, 0xcc, 0xbb, 0xaa, 0x99, 0x88};
- uint8_t CH6[8] = {0x00, 0x11, 0x22, 0x00, 0x00, 0x00, 0x08, 0x77}; // Size
- uint8_t CH7[8] = {0x00, 0x08, 0x00, 0x33, 0x44, 0x55, 0x66, 0x77}; // Sw(Size)
-
- int FoundMask = 0;
- for (int i = 0; i < NumIter; i++) {
- uint8_t T[8] = {0x00, 0x11, 0x22, 0x33, 0x44, 0x55, 0x66, 0x77};
- size_t NewSize = (*MD.*M)(T, 8, 8);
- /**/ if (NewSize == 8 && !memcmp(CH0, T, 8)) FoundMask |= 1 << 0;
- else if (NewSize == 8 && !memcmp(CH1, T, 8)) FoundMask |= 1 << 1;
- else if (NewSize == 8 && !memcmp(CH2, T, 8)) FoundMask |= 1 << 2;
- else if (NewSize == 8 && !memcmp(CH3, T, 8)) FoundMask |= 1 << 3;
- else if (NewSize == 8 && !memcmp(CH4, T, 8)) FoundMask |= 1 << 4;
- else if (NewSize == 8 && !memcmp(CH5, T, 8)) FoundMask |= 1 << 5;
- else if (NewSize == 8 && !memcmp(CH6, T, 8)) FoundMask |= 1 << 6;
- else if (NewSize == 8 && !memcmp(CH7, T, 8)) FoundMask |= 1 << 7;
- }
- EXPECT_EQ(FoundMask, 255);
-}
-
-TEST(FuzzerMutate, ChangeBinaryInteger1) {
- TestChangeBinaryInteger(&MutationDispatcher::Mutate_ChangeBinaryInteger,
- 1 << 12);
-}
-
-TEST(FuzzerMutate, ChangeBinaryInteger2) {
- TestChangeBinaryInteger(&MutationDispatcher::Mutate, 1 << 15);
-}
-
-
-TEST(FuzzerDictionary, ParseOneDictionaryEntry) {
- Unit U;
- EXPECT_FALSE(ParseOneDictionaryEntry("", &U));
- EXPECT_FALSE(ParseOneDictionaryEntry(" ", &U));
- EXPECT_FALSE(ParseOneDictionaryEntry("\t ", &U));
- EXPECT_FALSE(ParseOneDictionaryEntry(" \" ", &U));
- EXPECT_FALSE(ParseOneDictionaryEntry(" zz\" ", &U));
- EXPECT_FALSE(ParseOneDictionaryEntry(" \"zz ", &U));
- EXPECT_FALSE(ParseOneDictionaryEntry(" \"\" ", &U));
- EXPECT_TRUE(ParseOneDictionaryEntry("\"a\"", &U));
- EXPECT_EQ(U, Unit({'a'}));
- EXPECT_TRUE(ParseOneDictionaryEntry("\"abc\"", &U));
- EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
- EXPECT_TRUE(ParseOneDictionaryEntry("abc=\"abc\"", &U));
- EXPECT_EQ(U, Unit({'a', 'b', 'c'}));
- EXPECT_FALSE(ParseOneDictionaryEntry("\"\\\"", &U));
- EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\\\"", &U));
- EXPECT_EQ(U, Unit({'\\'}));
- EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xAB\"", &U));
- EXPECT_EQ(U, Unit({0xAB}));
- EXPECT_TRUE(ParseOneDictionaryEntry("\"\\xABz\\xDE\"", &U));
- EXPECT_EQ(U, Unit({0xAB, 'z', 0xDE}));
- EXPECT_TRUE(ParseOneDictionaryEntry("\"#\"", &U));
- EXPECT_EQ(U, Unit({'#'}));
- EXPECT_TRUE(ParseOneDictionaryEntry("\"\\\"\"", &U));
- EXPECT_EQ(U, Unit({'"'}));
-}
-
-TEST(FuzzerDictionary, ParseDictionaryFile) {
- Vector<Unit> Units;
- EXPECT_FALSE(ParseDictionaryFile("zzz\n", &Units));
- EXPECT_FALSE(ParseDictionaryFile("", &Units));
- EXPECT_TRUE(ParseDictionaryFile("\n", &Units));
- EXPECT_EQ(Units.size(), 0U);
- EXPECT_TRUE(ParseDictionaryFile("#zzzz a b c d\n", &Units));
- EXPECT_EQ(Units.size(), 0U);
- EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
- EXPECT_EQ(Units.size(), 0U);
- EXPECT_TRUE(ParseDictionaryFile(" #zzzz\n", &Units));
- EXPECT_EQ(Units.size(), 0U);
- EXPECT_TRUE(ParseDictionaryFile(" #zzzz\naaa=\"aa\"", &Units));
- EXPECT_EQ(Units, Vector<Unit>({Unit({'a', 'a'})}));
- EXPECT_TRUE(
- ParseDictionaryFile(" #zzzz\naaa=\"aa\"\n\nabc=\"abc\"", &Units));
- EXPECT_EQ(Units,
- Vector<Unit>({Unit({'a', 'a'}), Unit({'a', 'b', 'c'})}));
-}
-
-TEST(FuzzerUtil, Base64) {
- EXPECT_EQ("", Base64({}));
- EXPECT_EQ("YQ==", Base64({'a'}));
- EXPECT_EQ("eA==", Base64({'x'}));
- EXPECT_EQ("YWI=", Base64({'a', 'b'}));
- EXPECT_EQ("eHk=", Base64({'x', 'y'}));
- EXPECT_EQ("YWJj", Base64({'a', 'b', 'c'}));
- EXPECT_EQ("eHl6", Base64({'x', 'y', 'z'}));
- EXPECT_EQ("YWJjeA==", Base64({'a', 'b', 'c', 'x'}));
- EXPECT_EQ("YWJjeHk=", Base64({'a', 'b', 'c', 'x', 'y'}));
- EXPECT_EQ("YWJjeHl6", Base64({'a', 'b', 'c', 'x', 'y', 'z'}));
-}
-
-TEST(Corpus, Distribution) {
- DataFlowTrace DFT;
- Random Rand(0);
- std::unique_ptr<InputCorpus> C(new InputCorpus(""));
- size_t N = 10;
- size_t TriesPerUnit = 1<<16;
- for (size_t i = 0; i < N; i++)
- C->AddToCorpus(Unit{static_cast<uint8_t>(i)}, 1, false, false, {}, DFT,
- nullptr);
-
- Vector<size_t> Hist(N);
- for (size_t i = 0; i < N * TriesPerUnit; i++) {
- Hist[C->ChooseUnitIdxToMutate(Rand)]++;
- }
- for (size_t i = 0; i < N; i++) {
- // A weak sanity check that every unit gets invoked.
- EXPECT_GT(Hist[i], TriesPerUnit / N / 3);
- }
-}
-
-TEST(Merge, Bad) {
- const char *kInvalidInputs[] = {
- "",
- "x",
- "3\nx",
- "2\n3",
- "2\n2",
- "2\n2\nA\n",
- "2\n2\nA\nB\nC\n",
- "0\n0\n",
- "1\n1\nA\nDONE 0",
- "1\n1\nA\nSTARTED 1",
- };
- Merger M;
- for (auto S : kInvalidInputs) {
- // fprintf(stderr, "TESTING:\n%s\n", S);
- EXPECT_FALSE(M.Parse(S, false));
- }
-}
-
-void EQ(const Vector<uint32_t> &A, const Vector<uint32_t> &B) {
- EXPECT_EQ(A, B);
-}
-
-void EQ(const Vector<std::string> &A, const Vector<std::string> &B) {
- Set<std::string> a(A.begin(), A.end());
- Set<std::string> b(B.begin(), B.end());
- EXPECT_EQ(a, b);
-}
-
-static void Merge(const std::string &Input,
- const Vector<std::string> Result,
- size_t NumNewFeatures) {
- Merger M;
- Vector<std::string> NewFiles;
- EXPECT_TRUE(M.Parse(Input, true));
- std::stringstream SS;
- M.PrintSummary(SS);
- EXPECT_EQ(NumNewFeatures, M.Merge(&NewFiles));
- EXPECT_EQ(M.AllFeatures(), M.ParseSummary(SS));
- EQ(NewFiles, Result);
-}
-
-TEST(Merge, Good) {
- Merger M;
-
- EXPECT_TRUE(M.Parse("1\n0\nAA\n", false));
- EXPECT_EQ(M.Files.size(), 1U);
- EXPECT_EQ(M.NumFilesInFirstCorpus, 0U);
- EXPECT_EQ(M.Files[0].Name, "AA");
- EXPECT_TRUE(M.LastFailure.empty());
- EXPECT_EQ(M.FirstNotProcessedFile, 0U);
-
- EXPECT_TRUE(M.Parse("2\n1\nAA\nBB\nSTARTED 0 42\n", false));
- EXPECT_EQ(M.Files.size(), 2U);
- EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);
- EXPECT_EQ(M.Files[0].Name, "AA");
- EXPECT_EQ(M.Files[1].Name, "BB");
- EXPECT_EQ(M.LastFailure, "AA");
- EXPECT_EQ(M.FirstNotProcessedFile, 1U);
-
- EXPECT_TRUE(M.Parse("3\n1\nAA\nBB\nC\n"
- "STARTED 0 1000\n"
- "DONE 0 1 2 3\n"
- "STARTED 1 1001\n"
- "DONE 1 4 5 6 \n"
- "STARTED 2 1002\n"
- "", true));
- EXPECT_EQ(M.Files.size(), 3U);
- EXPECT_EQ(M.NumFilesInFirstCorpus, 1U);
- EXPECT_EQ(M.Files[0].Name, "AA");
- EXPECT_EQ(M.Files[0].Size, 1000U);
- EXPECT_EQ(M.Files[1].Name, "BB");
- EXPECT_EQ(M.Files[1].Size, 1001U);
- EXPECT_EQ(M.Files[2].Name, "C");
- EXPECT_EQ(M.Files[2].Size, 1002U);
- EXPECT_EQ(M.LastFailure, "C");
- EXPECT_EQ(M.FirstNotProcessedFile, 3U);
- EQ(M.Files[0].Features, {1, 2, 3});
- EQ(M.Files[1].Features, {4, 5, 6});
-
-
- Vector<std::string> NewFiles;
-
- EXPECT_TRUE(M.Parse("3\n2\nAA\nBB\nC\n"
- "STARTED 0 1000\nDONE 0 1 2 3\n"
- "STARTED 1 1001\nDONE 1 4 5 6 \n"
- "STARTED 2 1002\nDONE 2 6 1 3 \n"
- "", true));
- EXPECT_EQ(M.Files.size(), 3U);
- EXPECT_EQ(M.NumFilesInFirstCorpus, 2U);
- EXPECT_TRUE(M.LastFailure.empty());
- EXPECT_EQ(M.FirstNotProcessedFile, 3U);
- EQ(M.Files[0].Features, {1, 2, 3});
- EQ(M.Files[1].Features, {4, 5, 6});
- EQ(M.Files[2].Features, {1, 3, 6});
- EXPECT_EQ(0U, M.Merge(&NewFiles));
- EQ(NewFiles, {});
-
- EXPECT_TRUE(M.Parse("3\n1\nA\nB\nC\n"
- "STARTED 0 1000\nDONE 0 1 2 3\n"
- "STARTED 1 1001\nDONE 1 4 5 6 \n"
- "STARTED 2 1002\nDONE 2 6 1 3\n"
- "", true));
- EQ(M.Files[0].Features, {1, 2, 3});
- EQ(M.Files[1].Features, {4, 5, 6});
- EQ(M.Files[2].Features, {1, 3, 6});
- EXPECT_EQ(3U, M.Merge(&NewFiles));
- EQ(NewFiles, {"B"});
-
- // Same as the above, but with InitialFeatures.
- EXPECT_TRUE(M.Parse("2\n0\nB\nC\n"
- "STARTED 0 1001\nDONE 0 4 5 6 \n"
- "STARTED 1 1002\nDONE 1 6 1 3\n"
- "", true));
- EQ(M.Files[0].Features, {4, 5, 6});
- EQ(M.Files[1].Features, {1, 3, 6});
- Set<uint32_t> InitialFeatures;
- InitialFeatures.insert(1);
- InitialFeatures.insert(2);
- InitialFeatures.insert(3);
- EXPECT_EQ(3U, M.Merge(InitialFeatures, &NewFiles));
- EQ(NewFiles, {"B"});
-}
-
-TEST(Merge, Merge) {
-
- Merge("3\n1\nA\nB\nC\n"
- "STARTED 0 1000\nDONE 0 1 2 3\n"
- "STARTED 1 1001\nDONE 1 4 5 6 \n"
- "STARTED 2 1002\nDONE 2 6 1 3 \n",
- {"B"}, 3);
-
- Merge("3\n0\nA\nB\nC\n"
- "STARTED 0 2000\nDONE 0 1 2 3\n"
- "STARTED 1 1001\nDONE 1 4 5 6 \n"
- "STARTED 2 1002\nDONE 2 6 1 3 \n",
- {"A", "B", "C"}, 6);
-
- Merge("4\n0\nA\nB\nC\nD\n"
- "STARTED 0 2000\nDONE 0 1 2 3\n"
- "STARTED 1 1101\nDONE 1 4 5 6 \n"
- "STARTED 2 1102\nDONE 2 6 1 3 100 \n"
- "STARTED 3 1000\nDONE 3 1 \n",
- {"A", "B", "C", "D"}, 7);
-
- Merge("4\n1\nA\nB\nC\nD\n"
- "STARTED 0 2000\nDONE 0 4 5 6 7 8\n"
- "STARTED 1 1100\nDONE 1 1 2 3 \n"
- "STARTED 2 1100\nDONE 2 2 3 \n"
- "STARTED 3 1000\nDONE 3 1 \n",
- {"B", "D"}, 3);
-}
-
-TEST(Fuzzer, ForEachNonZeroByte) {
- const size_t N = 64;
- alignas(64) uint8_t Ar[N + 8] = {
- 0, 0, 0, 0, 0, 0, 0, 0,
- 1, 2, 0, 0, 0, 0, 0, 0,
- 0, 0, 3, 0, 4, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 5, 0, 6, 0, 0,
- 0, 0, 0, 0, 0, 0, 7, 0,
- 0, 0, 0, 0, 0, 0, 0, 0,
- 0, 0, 0, 0, 0, 0, 0, 8,
- 9, 9, 9, 9, 9, 9, 9, 9,
- };
- typedef Vector<std::pair<size_t, uint8_t> > Vec;
- Vec Res, Expected;
- auto CB = [&](size_t FirstFeature, size_t Idx, uint8_t V) {
- Res.push_back({FirstFeature + Idx, V});
- };
- ForEachNonZeroByte(Ar, Ar + N, 100, CB);
- Expected = {{108, 1}, {109, 2}, {118, 3}, {120, 4},
- {135, 5}, {137, 6}, {146, 7}, {163, 8}};
- EXPECT_EQ(Res, Expected);
-
- Res.clear();
- ForEachNonZeroByte(Ar + 9, Ar + N, 109, CB);
- Expected = { {109, 2}, {118, 3}, {120, 4},
- {135, 5}, {137, 6}, {146, 7}, {163, 8}};
- EXPECT_EQ(Res, Expected);
-
- Res.clear();
- ForEachNonZeroByte(Ar + 9, Ar + N - 9, 109, CB);
- Expected = { {109, 2}, {118, 3}, {120, 4},
- {135, 5}, {137, 6}, {146, 7}};
- EXPECT_EQ(Res, Expected);
-}
-
-// FuzzerCommand unit tests. The arguments in the two helper methods below must
-// match.
-static void makeCommandArgs(Vector<std::string> *ArgsToAdd) {
- assert(ArgsToAdd);
- ArgsToAdd->clear();
- ArgsToAdd->push_back("foo");
- ArgsToAdd->push_back("-bar=baz");
- ArgsToAdd->push_back("qux");
- ArgsToAdd->push_back(Command::ignoreRemainingArgs());
- ArgsToAdd->push_back("quux");
- ArgsToAdd->push_back("-grault=garply");
-}
-
-static std::string makeCmdLine(const char *separator, const char *suffix) {
- std::string CmdLine("foo -bar=baz qux ");
- if (strlen(separator) != 0) {
- CmdLine += separator;
- CmdLine += " ";
- }
- CmdLine += Command::ignoreRemainingArgs();
- CmdLine += " quux -grault=garply";
- if (strlen(suffix) != 0) {
- CmdLine += " ";
- CmdLine += suffix;
- }
- return CmdLine;
-}
-
-TEST(FuzzerCommand, Create) {
- std::string CmdLine;
-
- // Default constructor
- Command DefaultCmd;
-
- CmdLine = DefaultCmd.toString();
- EXPECT_EQ(CmdLine, "");
-
- // Explicit constructor
- Vector<std::string> ArgsToAdd;
- makeCommandArgs(&ArgsToAdd);
- Command InitializedCmd(ArgsToAdd);
-
- CmdLine = InitializedCmd.toString();
- EXPECT_EQ(CmdLine, makeCmdLine("", ""));
-
- // Compare each argument
- auto InitializedArgs = InitializedCmd.getArguments();
- auto i = ArgsToAdd.begin();
- auto j = InitializedArgs.begin();
- while (i != ArgsToAdd.end() && j != InitializedArgs.end()) {
- EXPECT_EQ(*i++, *j++);
- }
- EXPECT_EQ(i, ArgsToAdd.end());
- EXPECT_EQ(j, InitializedArgs.end());
-
- // Copy constructor
- Command CopiedCmd(InitializedCmd);
-
- CmdLine = CopiedCmd.toString();
- EXPECT_EQ(CmdLine, makeCmdLine("", ""));
-
- // Assignment operator
- Command AssignedCmd;
- AssignedCmd = CopiedCmd;
-
- CmdLine = AssignedCmd.toString();
- EXPECT_EQ(CmdLine, makeCmdLine("", ""));
-}
-
-TEST(FuzzerCommand, ModifyArguments) {
- Vector<std::string> ArgsToAdd;
- makeCommandArgs(&ArgsToAdd);
- Command Cmd;
- std::string CmdLine;
-
- Cmd.addArguments(ArgsToAdd);
- CmdLine = Cmd.toString();
- EXPECT_EQ(CmdLine, makeCmdLine("", ""));
-
- Cmd.addArgument("waldo");
- EXPECT_TRUE(Cmd.hasArgument("waldo"));
-
- CmdLine = Cmd.toString();
- EXPECT_EQ(CmdLine, makeCmdLine("waldo", ""));
-
- Cmd.removeArgument("waldo");
- EXPECT_FALSE(Cmd.hasArgument("waldo"));
-
- CmdLine = Cmd.toString();
- EXPECT_EQ(CmdLine, makeCmdLine("", ""));
-}
-
-TEST(FuzzerCommand, ModifyFlags) {
- Vector<std::string> ArgsToAdd;
- makeCommandArgs(&ArgsToAdd);
- Command Cmd(ArgsToAdd);
- std::string Value, CmdLine;
- ASSERT_FALSE(Cmd.hasFlag("fred"));
-
- Value = Cmd.getFlagValue("fred");
- EXPECT_EQ(Value, "");
-
- CmdLine = Cmd.toString();
- EXPECT_EQ(CmdLine, makeCmdLine("", ""));
-
- Cmd.addFlag("fred", "plugh");
- EXPECT_TRUE(Cmd.hasFlag("fred"));
-
- Value = Cmd.getFlagValue("fred");
- EXPECT_EQ(Value, "plugh");
-
- CmdLine = Cmd.toString();
- EXPECT_EQ(CmdLine, makeCmdLine("-fred=plugh", ""));
-
- Cmd.removeFlag("fred");
- EXPECT_FALSE(Cmd.hasFlag("fred"));
-
- Value = Cmd.getFlagValue("fred");
- EXPECT_EQ(Value, "");
-
- CmdLine = Cmd.toString();
- EXPECT_EQ(CmdLine, makeCmdLine("", ""));
-}
-
-TEST(FuzzerCommand, SetOutput) {
- Vector<std::string> ArgsToAdd;
- makeCommandArgs(&ArgsToAdd);
- Command Cmd(ArgsToAdd);
- std::string CmdLine;
- ASSERT_FALSE(Cmd.hasOutputFile());
- ASSERT_FALSE(Cmd.isOutAndErrCombined());
-
- Cmd.combineOutAndErr(true);
- EXPECT_TRUE(Cmd.isOutAndErrCombined());
-
- CmdLine = Cmd.toString();
- EXPECT_EQ(CmdLine, makeCmdLine("", "2>&1"));
-
- Cmd.combineOutAndErr(false);
- EXPECT_FALSE(Cmd.isOutAndErrCombined());
-
- Cmd.setOutputFile("xyzzy");
- EXPECT_TRUE(Cmd.hasOutputFile());
-
- CmdLine = Cmd.toString();
- EXPECT_EQ(CmdLine, makeCmdLine("", ">xyzzy"));
-
- Cmd.setOutputFile("thud");
- EXPECT_TRUE(Cmd.hasOutputFile());
-
- CmdLine = Cmd.toString();
- EXPECT_EQ(CmdLine, makeCmdLine("", ">thud"));
-
- Cmd.combineOutAndErr();
- EXPECT_TRUE(Cmd.isOutAndErrCombined());
-
- CmdLine = Cmd.toString();
- EXPECT_EQ(CmdLine, makeCmdLine("", ">thud 2>&1"));
-}
-
-int main(int argc, char **argv) {
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/lib/hwasan/.clang-format b/lib/hwasan/.clang-format
deleted file mode 100644
index 560308c91deec..0000000000000
--- a/lib/hwasan/.clang-format
+++ /dev/null
@@ -1,2 +0,0 @@
-BasedOnStyle: Google
-AllowShortIfStatementsOnASingleLine: false
diff --git a/lib/hwasan/CMakeLists.txt b/lib/hwasan/CMakeLists.txt
deleted file mode 100644
index 20ab94dc04467..0000000000000
--- a/lib/hwasan/CMakeLists.txt
+++ /dev/null
@@ -1,179 +0,0 @@
-include_directories(..)
-
-# Runtime library sources and build flags.
-set(HWASAN_RTL_SOURCES
- hwasan.cc
- hwasan_allocator.cc
- hwasan_dynamic_shadow.cc
- hwasan_interceptors.cc
- hwasan_linux.cc
- hwasan_memintrinsics.cc
- hwasan_poisoning.cc
- hwasan_report.cc
- hwasan_thread.cc
- hwasan_thread_list.cc
- )
-
-set(HWASAN_RTL_CXX_SOURCES
- hwasan_new_delete.cc)
-
-set(HWASAN_RTL_HEADERS
- hwasan.h
- hwasan_allocator.h
- hwasan_dynamic_shadow.h
- hwasan_flags.h
- hwasan_flags.inc
- hwasan_interface_internal.h
- hwasan_mapping.h
- hwasan_poisoning.h
- hwasan_report.h
- hwasan_thread.h
- hwasan_thread_list.h
- )
-
-set(HWASAN_DEFINITIONS)
-append_list_if(COMPILER_RT_HWASAN_WITH_INTERCEPTORS HWASAN_WITH_INTERCEPTORS=1 HWASAN_DEFINITIONS)
-
-set(HWASAN_RTL_CFLAGS ${SANITIZER_COMMON_CFLAGS})
-append_rtti_flag(OFF HWASAN_RTL_CFLAGS)
-append_list_if(COMPILER_RT_HAS_FPIC_FLAG -fPIC HWASAN_RTL_CFLAGS)
-# Prevent clang from generating libc calls.
-append_list_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding HWASAN_RTL_CFLAGS)
-
-set(HWASAN_DYNAMIC_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS})
-
-if(ANDROID)
-# Put most Sanitizer shared libraries in the global group. For more details, see
-# android-changes-for-ndk-developers.md#changes-to-library-search-order
- if (COMPILER_RT_HAS_Z_GLOBAL)
- list(APPEND HWASAN_DYNAMIC_LINK_FLAGS -Wl,-z,global)
- endif()
-endif()
-
-set(HWASAN_DYNAMIC_CFLAGS ${HWASAN_RTL_CFLAGS})
-append_list_if(COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC
- -ftls-model=initial-exec HWASAN_DYNAMIC_CFLAGS)
-append_list_if(MSVC /DEBUG HWASAN_DYNAMIC_LINK_FLAGS)
-
-set(HWASAN_DYNAMIC_LIBS ${SANITIZER_CXX_ABI_LIBRARY} ${SANITIZER_COMMON_LINK_LIBS})
-
-append_list_if(COMPILER_RT_HAS_LIBDL dl HWASAN_DYNAMIC_LIBS)
-append_list_if(COMPILER_RT_HAS_LIBRT rt HWASAN_DYNAMIC_LIBS)
-append_list_if(COMPILER_RT_HAS_LIBM m HWASAN_DYNAMIC_LIBS)
-append_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread HWASAN_DYNAMIC_LIBS)
-
-if (TARGET cxx-headers OR HAVE_LIBCXX)
- set(HWASAN_DEPS cxx-headers)
-endif()
-
-# Static runtime library.
-add_compiler_rt_component(hwasan)
-
-add_compiler_rt_object_libraries(RTHwasan
- ARCHS ${HWASAN_SUPPORTED_ARCH}
- SOURCES ${HWASAN_RTL_SOURCES}
- ADDITIONAL_HEADERS ${HWASAN_RTL_HEADERS}
- CFLAGS ${HWASAN_RTL_CFLAGS}
- DEFS ${HWASAN_DEFINITIONS}
- DEPS ${HWASAN_DEPS})
-add_compiler_rt_object_libraries(RTHwasan_cxx
- ARCHS ${HWASAN_SUPPORTED_ARCH}
- SOURCES ${HWASAN_RTL_CXX_SOURCES}
- ADDITIONAL_HEADERS ${HWASAN_RTL_HEADERS}
- CFLAGS ${HWASAN_RTL_CFLAGS}
- DEFS ${HWASAN_DEFINITIONS}
- DEPS ${HWASAN_DEPS})
-add_compiler_rt_object_libraries(RTHwasan_dynamic
- ARCHS ${HWASAN_SUPPORTED_ARCH}
- SOURCES ${HWASAN_RTL_SOURCES} ${HWASAN_RTL_CXX_SOURCES}
- ADDITIONAL_HEADERS ${HWASAN_RTL_HEADERS}
- CFLAGS ${HWASAN_DYNAMIC_CFLAGS}
- DEFS ${HWASAN_DEFINITIONS}
- DEPS ${HWASAN_DEPS})
-
-file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/dummy.cc "")
-add_compiler_rt_object_libraries(RTHwasan_dynamic_version_script_dummy
- ARCHS ${HWASAN_SUPPORTED_ARCH}
- SOURCES ${CMAKE_CURRENT_BINARY_DIR}/dummy.cc
- CFLAGS ${HWASAN_DYNAMIC_CFLAGS}
- DEFS ${HWASAN_DEFINITIONS}
- DEPS ${HWASAN_DEPS})
-
-foreach(arch ${HWASAN_SUPPORTED_ARCH})
- add_compiler_rt_runtime(clang_rt.hwasan
- STATIC
- ARCHS ${arch}
- OBJECT_LIBS RTHwasan
- RTInterception
- RTSanitizerCommon
- RTSanitizerCommonLibc
- RTSanitizerCommonCoverage
- RTSanitizerCommonSymbolizer
- RTUbsan
- CFLAGS ${HWASAN_RTL_CFLAGS}
- PARENT_TARGET hwasan)
- add_compiler_rt_runtime(clang_rt.hwasan_cxx
- STATIC
- ARCHS ${arch}
- OBJECT_LIBS RTHwasan_cxx
- RTUbsan_cxx
- CFLAGS ${HWASAN_RTL_CFLAGS}
- PARENT_TARGET hwasan)
-
- if (UNIX)
- add_sanitizer_rt_version_list(clang_rt.hwasan-dynamic-${arch}
- LIBS clang_rt.hwasan-${arch} clang_rt.hwasan_cxx-${arch}
- EXTRA hwasan.syms.extra)
- set(VERSION_SCRIPT_FLAG
- -Wl,--version-script,${CMAKE_CURRENT_BINARY_DIR}/clang_rt.hwasan-dynamic-${arch}.vers)
- set_property(SOURCE
- ${CMAKE_CURRENT_BINARY_DIR}/dummy.cc
- APPEND PROPERTY
- OBJECT_DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/clang_rt.hwasan-dynamic-${arch}.vers)
- else()
- set(VERSION_SCRIPT_FLAG)
- endif()
-
-
- add_compiler_rt_runtime(clang_rt.hwasan
- SHARED
- ARCHS ${arch}
- OBJECT_LIBS
- RTHwasan_dynamic
- RTInterception
- RTSanitizerCommon
- RTSanitizerCommonLibc
- RTSanitizerCommonCoverage
- RTSanitizerCommonSymbolizer
- RTUbsan
- RTUbsan_cxx
- # The only purpose of RTHWAsan_dynamic_version_script_dummy is to
- # carry a dependency of the shared runtime on the version script.
- # Replacing it with a straightforward
- # add_dependencies(clang_rt.asan-dynamic-${arch} clang_rt.asan-dynamic-${arch}-version-list)
- # generates an order-only dependency in ninja.
- RTHwasan_dynamic_version_script_dummy
- CFLAGS ${HWASAN_DYNAMIC_CFLAGS}
- LINK_FLAGS ${HWASAN_DYNAMIC_LINK_FLAGS}
- ${VERSION_SCRIPT_FLAG}
- LINK_LIBS ${HWASAN_DYNAMIC_LIBS}
- DEFS ${ASAN_DYNAMIC_DEFINITIONS}
- PARENT_TARGET hwasan)
-
- if(SANITIZER_USE_SYMBOLS)
- add_sanitizer_rt_symbols(clang_rt.hwasan
- ARCHS ${arch}
- EXTRA hwasan.syms.extra)
- add_sanitizer_rt_symbols(clang_rt.hwasan_cxx
- ARCHS ${arch}
- EXTRA hwasan.syms.extra)
- add_dependencies(hwasan clang_rt.hwasan-${arch}-symbols
- clang_rt.hwasan_cxx-${arch}-symbols)
- endif()
-endforeach()
-
-add_compiler_rt_resource_file(hwasan_blacklist hwasan_blacklist.txt hwasan)
-
-# if(COMPILER_RT_INCLUDE_TESTS)
-# add_subdirectory(tests)
-# endif()
diff --git a/lib/interception/.clang-format b/lib/interception/.clang-format
deleted file mode 100644
index 560308c91deec..0000000000000
--- a/lib/interception/.clang-format
+++ /dev/null
@@ -1,2 +0,0 @@
-BasedOnStyle: Google
-AllowShortIfStatementsOnASingleLine: false
diff --git a/lib/interception/CMakeLists.txt b/lib/interception/CMakeLists.txt
deleted file mode 100644
index c0ac974d726ae..0000000000000
--- a/lib/interception/CMakeLists.txt
+++ /dev/null
@@ -1,29 +0,0 @@
-# Build for the runtime interception helper library.
-
-set(INTERCEPTION_SOURCES
- interception_linux.cc
- interception_mac.cc
- interception_win.cc
- interception_type_test.cc)
-
-set(INTERCEPTION_HEADERS
- interception.h
- interception_linux.h
- interception_mac.h
- interception_win.h)
-
-include_directories(..)
-
-set(INTERCEPTION_CFLAGS ${SANITIZER_COMMON_CFLAGS})
-append_rtti_flag(OFF INTERCEPTION_CFLAGS)
-
-add_compiler_rt_object_libraries(RTInterception
- OS ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES ${INTERCEPTION_SOURCES}
- ADDITIONAL_HEADERS ${INTERCEPTION_HEADERS}
- CFLAGS ${INTERCEPTION_CFLAGS})
-
-if(COMPILER_RT_INCLUDE_TESTS)
- add_subdirectory(tests)
-endif()
diff --git a/lib/interception/tests/CMakeLists.txt b/lib/interception/tests/CMakeLists.txt
deleted file mode 100644
index 1da0a455bf331..0000000000000
--- a/lib/interception/tests/CMakeLists.txt
+++ /dev/null
@@ -1,113 +0,0 @@
-include(CompilerRTCompile)
-
-filter_available_targets(INTERCEPTION_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el)
-
-set(INTERCEPTION_UNITTESTS
- interception_linux_test.cc
- interception_test_main.cc
- interception_win_test.cc
-)
-
-set(INTERCEPTION_TEST_HEADERS)
-
-set(INTERCEPTION_TEST_CFLAGS_COMMON
- ${COMPILER_RT_UNITTEST_CFLAGS}
- ${COMPILER_RT_GTEST_CFLAGS}
- -I${COMPILER_RT_SOURCE_DIR}/include
- -I${COMPILER_RT_SOURCE_DIR}/lib
- -I${COMPILER_RT_SOURCE_DIR}/lib/interception
- -fno-rtti
- -O2
- -Werror=sign-compare
- -Wno-non-virtual-dtor)
-
-# -gline-tables-only must be enough for these tests, so use it if possible.
-if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang")
- list(APPEND INTERCEPTION_TEST_CFLAGS_COMMON -gline-tables-only)
-else()
- list(APPEND INTERCEPTION_TEST_CFLAGS_COMMON -g)
-endif()
-if(MSVC)
- list(APPEND INTERCEPTION_TEST_CFLAGS_COMMON -gcodeview)
- list(APPEND INTERCEPTION_TEST_LINK_FLAGS_COMMON -Wl,-largeaddressaware)
-endif()
-list(APPEND INTERCEPTION_TEST_LINK_FLAGS_COMMON -g)
-
-if(NOT MSVC)
- list(APPEND INTERCEPTION_TEST_LINK_FLAGS_COMMON --driver-mode=g++)
-endif()
-
-if(ANDROID)
- list(APPEND INTERCEPTION_TEST_LINK_FLAGS_COMMON -pie)
-endif()
-
-set(INTERCEPTION_TEST_LINK_LIBS)
-append_list_if(COMPILER_RT_HAS_LIBLOG log INTERCEPTION_TEST_LINK_LIBS)
-# NDK r10 requires -latomic almost always.
-append_list_if(ANDROID atomic INTERCEPTION_TEST_LINK_LIBS)
-
-append_list_if(COMPILER_RT_HAS_LIBDL -ldl INTERCEPTION_TEST_LINK_FLAGS_COMMON)
-append_list_if(COMPILER_RT_HAS_LIBRT -lrt INTERCEPTION_TEST_LINK_FLAGS_COMMON)
-append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread INTERCEPTION_TEST_LINK_FLAGS_COMMON)
-# x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests. Also,
-# 'libm' shall be specified explicitly to build i386 tests.
-if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE")
- list(APPEND INTERCEPTION_TEST_LINK_FLAGS_COMMON "-lc++ -lm")
-endif()
-
-include_directories(..)
-include_directories(../..)
-
-# Adds static library which contains interception object file
-# (universal binary on Mac and arch-specific object files on Linux).
-macro(add_interceptor_lib library)
- add_library(${library} STATIC ${ARGN})
- set_target_properties(${library} PROPERTIES
- ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- FOLDER "Compiler-RT Runtime tests")
-endmacro()
-
-function(get_interception_lib_for_arch arch lib)
- if(APPLE)
- set(tgt_name "RTInterception.test.osx")
- else()
- set(tgt_name "RTInterception.test.${arch}")
- endif()
- set(${lib} "${tgt_name}" PARENT_SCOPE)
-endfunction()
-
-# Interception unit tests testsuite.
-add_custom_target(InterceptionUnitTests)
-set_target_properties(InterceptionUnitTests PROPERTIES
- FOLDER "Compiler-RT Tests")
-
-# Adds interception tests for architecture.
-macro(add_interception_tests_for_arch arch)
- set(INTERCEPTION_TEST_OBJECTS)
- get_interception_lib_for_arch(${arch} INTERCEPTION_COMMON_LIB)
- generate_compiler_rt_tests(INTERCEPTION_TEST_OBJECTS
- InterceptionUnitTests "Interception-${arch}-Test" ${arch}
- RUNTIME ${INTERCEPTION_COMMON_LIB}
- SOURCES ${INTERCEPTION_UNITTESTS} ${COMPILER_RT_GTEST_SOURCE}
- COMPILE_DEPS ${INTERCEPTION_TEST_HEADERS}
- DEPS gtest
- CFLAGS ${INTERCEPTION_TEST_CFLAGS_COMMON}
- LINK_FLAGS ${INTERCEPTION_TEST_LINK_FLAGS_COMMON})
-endmacro()
-
-if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID AND NOT APPLE)
- # We use just-built clang to build interception unittests, so we must
- # be sure that produced binaries would work.
- if(APPLE)
- add_interceptor_lib("RTInterception.test.osx"
- $<TARGET_OBJECTS:RTInterception.osx>)
- else()
- foreach(arch ${INTERCEPTION_UNITTEST_SUPPORTED_ARCH})
- add_interceptor_lib("RTInterception.test.${arch}"
- $<TARGET_OBJECTS:RTInterception.${arch}>)
- endforeach()
- endif()
- foreach(arch ${INTERCEPTION_UNITTEST_SUPPORTED_ARCH})
- add_interception_tests_for_arch(${arch})
- endforeach()
-endif()
diff --git a/lib/interception/tests/interception_linux_test.cc b/lib/interception/tests/interception_linux_test.cc
deleted file mode 100644
index cc09aa09df3a4..0000000000000
--- a/lib/interception/tests/interception_linux_test.cc
+++ /dev/null
@@ -1,68 +0,0 @@
-//===-- interception_linux_test.cc ----------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
-// Tests for interception_linux.h.
-//
-//===----------------------------------------------------------------------===//
-
-// Do not declare isdigit in ctype.h.
-#define __NO_CTYPE
-
-#include "interception/interception.h"
-
-#include "gtest/gtest.h"
-
-// Too slow for debug build
-#if !SANITIZER_DEBUG
-#if SANITIZER_LINUX
-
-static int InterceptorFunctionCalled;
-
-DECLARE_REAL(int, isdigit, int);
-
-INTERCEPTOR(int, isdigit, int d) {
- ++InterceptorFunctionCalled;
- return d >= '0' && d <= '9';
-}
-
-namespace __interception {
-
-TEST(Interception, GetRealFunctionAddress) {
- uptr malloc_address = 0;
- EXPECT_TRUE(GetRealFunctionAddress("malloc", &malloc_address, 0, 0));
- EXPECT_NE(0U, malloc_address);
-
- uptr dummy_address = 0;
- EXPECT_TRUE(
- GetRealFunctionAddress("dummy_doesnt_exist__", &dummy_address, 0, 0));
- EXPECT_EQ(0U, dummy_address);
-}
-
-TEST(Interception, Basic) {
- ASSERT_TRUE(INTERCEPT_FUNCTION(isdigit));
-
- // After interception, the counter should be incremented.
- InterceptorFunctionCalled = 0;
- EXPECT_NE(0, isdigit('1'));
- EXPECT_EQ(1, InterceptorFunctionCalled);
- EXPECT_EQ(0, isdigit('a'));
- EXPECT_EQ(2, InterceptorFunctionCalled);
-
- // Calling the REAL function should not affect the counter.
- InterceptorFunctionCalled = 0;
- EXPECT_NE(0, REAL(isdigit)('1'));
- EXPECT_EQ(0, REAL(isdigit)('a'));
- EXPECT_EQ(0, InterceptorFunctionCalled);
-}
-
-} // namespace __interception
-
-#endif // SANITIZER_LINUX
-#endif // #if !SANITIZER_DEBUG
diff --git a/lib/interception/tests/interception_test_main.cc b/lib/interception/tests/interception_test_main.cc
deleted file mode 100644
index 311da51ecfcec..0000000000000
--- a/lib/interception/tests/interception_test_main.cc
+++ /dev/null
@@ -1,22 +0,0 @@
-//===-- interception_test_main.cc------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of AddressSanitizer, an address sanity checker.
-//
-// Testing the machinery for providing replacements/wrappers for system
-// functions.
-//===----------------------------------------------------------------------===//
-
-#include "gtest/gtest.h"
-
-int main(int argc, char **argv) {
- testing::GTEST_FLAG(death_test_style) = "threadsafe";
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/lib/interception/tests/interception_win_test.cc b/lib/interception/tests/interception_win_test.cc
deleted file mode 100644
index 37ef994f83da1..0000000000000
--- a/lib/interception/tests/interception_win_test.cc
+++ /dev/null
@@ -1,637 +0,0 @@
-//===-- interception_win_test.cc ------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
-// Tests for interception_win.h.
-//
-//===----------------------------------------------------------------------===//
-#include "interception/interception.h"
-
-#include "gtest/gtest.h"
-
-// Too slow for debug build
-#if !SANITIZER_DEBUG
-#if SANITIZER_WINDOWS
-
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-namespace __interception {
-namespace {
-
-enum FunctionPrefixKind {
- FunctionPrefixNone,
- FunctionPrefixPadding,
- FunctionPrefixHotPatch,
- FunctionPrefixDetour,
-};
-
-typedef bool (*TestOverrideFunction)(uptr, uptr, uptr*);
-typedef int (*IdentityFunction)(int);
-
-#if SANITIZER_WINDOWS64
-
-const u8 kIdentityCodeWithPrologue[] = {
- 0x55, // push rbp
- 0x48, 0x89, 0xE5, // mov rbp,rsp
- 0x8B, 0xC1, // mov eax,ecx
- 0x5D, // pop rbp
- 0xC3, // ret
-};
-
-const u8 kIdentityCodeWithPushPop[] = {
- 0x55, // push rbp
- 0x48, 0x89, 0xE5, // mov rbp,rsp
- 0x53, // push rbx
- 0x50, // push rax
- 0x58, // pop rax
- 0x8B, 0xC1, // mov rax,rcx
- 0x5B, // pop rbx
- 0x5D, // pop rbp
- 0xC3, // ret
-};
-
-const u8 kIdentityTwiceOffset = 16;
-const u8 kIdentityTwice[] = {
- 0x55, // push rbp
- 0x48, 0x89, 0xE5, // mov rbp,rsp
- 0x8B, 0xC1, // mov eax,ecx
- 0x5D, // pop rbp
- 0xC3, // ret
- 0x90, 0x90, 0x90, 0x90,
- 0x90, 0x90, 0x90, 0x90,
- 0x55, // push rbp
- 0x48, 0x89, 0xE5, // mov rbp,rsp
- 0x8B, 0xC1, // mov eax,ecx
- 0x5D, // pop rbp
- 0xC3, // ret
-};
-
-const u8 kIdentityCodeWithMov[] = {
- 0x89, 0xC8, // mov eax, ecx
- 0xC3, // ret
-};
-
-const u8 kIdentityCodeWithJump[] = {
- 0xE9, 0x04, 0x00, 0x00,
- 0x00, // jmp + 4
- 0xCC, 0xCC, 0xCC, 0xCC,
- 0x89, 0xC8, // mov eax, ecx
- 0xC3, // ret
-};
-
-#else
-
-const u8 kIdentityCodeWithPrologue[] = {
- 0x55, // push ebp
- 0x8B, 0xEC, // mov ebp,esp
- 0x8B, 0x45, 0x08, // mov eax,dword ptr [ebp + 8]
- 0x5D, // pop ebp
- 0xC3, // ret
-};
-
-const u8 kIdentityCodeWithPushPop[] = {
- 0x55, // push ebp
- 0x8B, 0xEC, // mov ebp,esp
- 0x53, // push ebx
- 0x50, // push eax
- 0x58, // pop eax
- 0x8B, 0x45, 0x08, // mov eax,dword ptr [ebp + 8]
- 0x5B, // pop ebx
- 0x5D, // pop ebp
- 0xC3, // ret
-};
-
-const u8 kIdentityTwiceOffset = 8;
-const u8 kIdentityTwice[] = {
- 0x55, // push ebp
- 0x8B, 0xEC, // mov ebp,esp
- 0x8B, 0x45, 0x08, // mov eax,dword ptr [ebp + 8]
- 0x5D, // pop ebp
- 0xC3, // ret
- 0x55, // push ebp
- 0x8B, 0xEC, // mov ebp,esp
- 0x8B, 0x45, 0x08, // mov eax,dword ptr [ebp + 8]
- 0x5D, // pop ebp
- 0xC3, // ret
-};
-
-const u8 kIdentityCodeWithMov[] = {
- 0x8B, 0x44, 0x24, 0x04, // mov eax,dword ptr [esp + 4]
- 0xC3, // ret
-};
-
-const u8 kIdentityCodeWithJump[] = {
- 0xE9, 0x04, 0x00, 0x00,
- 0x00, // jmp + 4
- 0xCC, 0xCC, 0xCC, 0xCC,
- 0x8B, 0x44, 0x24, 0x04, // mov eax,dword ptr [esp + 4]
- 0xC3, // ret
-};
-
-#endif
-
-const u8 kPatchableCode1[] = {
- 0xB8, 0x4B, 0x00, 0x00, 0x00, // mov eax,4B
- 0x33, 0xC9, // xor ecx,ecx
- 0xC3, // ret
-};
-
-const u8 kPatchableCode2[] = {
- 0x55, // push ebp
- 0x8B, 0xEC, // mov ebp,esp
- 0x33, 0xC0, // xor eax,eax
- 0x5D, // pop ebp
- 0xC3, // ret
-};
-
-const u8 kPatchableCode3[] = {
- 0x55, // push ebp
- 0x8B, 0xEC, // mov ebp,esp
- 0x6A, 0x00, // push 0
- 0xE8, 0x3D, 0xFF, 0xFF, 0xFF, // call <func>
-};
-
-const u8 kPatchableCode4[] = {
- 0xE9, 0xCC, 0xCC, 0xCC, 0xCC, // jmp <label>
- 0x90, 0x90, 0x90, 0x90,
-};
-
-const u8 kPatchableCode5[] = {
- 0x55, // push ebp
- 0x8b, 0xec, // mov ebp,esp
- 0x8d, 0xa4, 0x24, 0x30, 0xfd, 0xff, 0xff, // lea esp,[esp-2D0h]
- 0x54, // push esp
-};
-
-#if SANITIZER_WINDOWS64
-u8 kLoadGlobalCode[] = {
- 0x8B, 0x05, 0x00, 0x00, 0x00, 0x00, // mov eax [rip + global]
- 0xC3, // ret
-};
-#endif
-
-const u8 kUnpatchableCode1[] = {
- 0xC3, // ret
-};
-
-const u8 kUnpatchableCode2[] = {
- 0x33, 0xC9, // xor ecx,ecx
- 0xC3, // ret
-};
-
-const u8 kUnpatchableCode3[] = {
- 0x75, 0xCC, // jne <label>
- 0x33, 0xC9, // xor ecx,ecx
- 0xC3, // ret
-};
-
-const u8 kUnpatchableCode4[] = {
- 0x74, 0xCC, // jne <label>
- 0x33, 0xC9, // xor ecx,ecx
- 0xC3, // ret
-};
-
-const u8 kUnpatchableCode5[] = {
- 0xEB, 0x02, // jmp <label>
- 0x33, 0xC9, // xor ecx,ecx
- 0xC3, // ret
-};
-
-const u8 kUnpatchableCode6[] = {
- 0xE8, 0xCC, 0xCC, 0xCC, 0xCC, // call <func>
- 0x90, 0x90, 0x90, 0x90,
-};
-
-// A buffer holding the dynamically generated code under test.
-u8* ActiveCode;
-const size_t ActiveCodeLength = 4096;
-
-int InterceptorFunction(int x);
-
-/// Allocate code memory more than 2GB away from Base.
-u8 *AllocateCode2GBAway(u8 *Base) {
- // Find a 64K aligned location after Base plus 2GB.
- size_t TwoGB = 0x80000000;
- size_t AllocGranularity = 0x10000;
- Base = (u8 *)((((uptr)Base + TwoGB + AllocGranularity)) & ~(AllocGranularity - 1));
-
- // Check if that location is free, and if not, loop over regions until we find
- // one that is.
- MEMORY_BASIC_INFORMATION mbi = {};
- while (sizeof(mbi) == VirtualQuery(Base, &mbi, sizeof(mbi))) {
- if (mbi.State & MEM_FREE) break;
- Base += mbi.RegionSize;
- }
-
- // Allocate one RWX page at the free location.
- return (u8 *)::VirtualAlloc(Base, ActiveCodeLength, MEM_COMMIT | MEM_RESERVE,
- PAGE_EXECUTE_READWRITE);
-}
-
-template<class T>
-static void LoadActiveCode(
- const T &code,
- uptr *entry_point,
- FunctionPrefixKind prefix_kind = FunctionPrefixNone) {
- if (ActiveCode == nullptr) {
- ActiveCode = AllocateCode2GBAway((u8*)&InterceptorFunction);
- ASSERT_NE(ActiveCode, nullptr) << "failed to allocate RWX memory 2GB away";
- }
-
- size_t position = 0;
-
- // Add padding to avoid memory violation when scanning the prefix.
- for (int i = 0; i < 16; ++i)
- ActiveCode[position++] = 0xC3; // Instruction 'ret'.
-
- // Add function padding.
- size_t padding = 0;
- if (prefix_kind == FunctionPrefixPadding)
- padding = 16;
- else if (prefix_kind == FunctionPrefixDetour ||
- prefix_kind == FunctionPrefixHotPatch)
- padding = FIRST_32_SECOND_64(5, 6);
- // Insert |padding| instructions 'nop'.
- for (size_t i = 0; i < padding; ++i)
- ActiveCode[position++] = 0x90;
-
- // Keep track of the entry point.
- *entry_point = (uptr)&ActiveCode[position];
-
- // Add the detour instruction (i.e. mov edi, edi)
- if (prefix_kind == FunctionPrefixDetour) {
-#if SANITIZER_WINDOWS64
- // Note that "mov edi,edi" is NOP in 32-bit only, in 64-bit it clears
- // higher bits of RDI.
- // Use 66,90H as NOP for Windows64.
- ActiveCode[position++] = 0x66;
- ActiveCode[position++] = 0x90;
-#else
- // mov edi,edi.
- ActiveCode[position++] = 0x8B;
- ActiveCode[position++] = 0xFF;
-#endif
-
- }
-
- // Copy the function body.
- for (size_t i = 0; i < sizeof(T); ++i)
- ActiveCode[position++] = code[i];
-}
-
-int InterceptorFunctionCalled;
-IdentityFunction InterceptedRealFunction;
-
-int InterceptorFunction(int x) {
- ++InterceptorFunctionCalled;
- return InterceptedRealFunction(x);
-}
-
-} // namespace
-
-// Tests for interception_win.h
-TEST(Interception, InternalGetProcAddress) {
- HMODULE ntdll_handle = ::GetModuleHandle("ntdll");
- ASSERT_NE(nullptr, ntdll_handle);
- uptr DbgPrint_expected = (uptr)::GetProcAddress(ntdll_handle, "DbgPrint");
- uptr isdigit_expected = (uptr)::GetProcAddress(ntdll_handle, "isdigit");
- uptr DbgPrint_adddress = InternalGetProcAddress(ntdll_handle, "DbgPrint");
- uptr isdigit_address = InternalGetProcAddress(ntdll_handle, "isdigit");
-
- EXPECT_EQ(DbgPrint_expected, DbgPrint_adddress);
- EXPECT_EQ(isdigit_expected, isdigit_address);
- EXPECT_NE(DbgPrint_adddress, isdigit_address);
-}
-
-template<class T>
-static void TestIdentityFunctionPatching(
- const T &code,
- TestOverrideFunction override,
- FunctionPrefixKind prefix_kind = FunctionPrefixNone) {
- uptr identity_address;
- LoadActiveCode(code, &identity_address, prefix_kind);
- IdentityFunction identity = (IdentityFunction)identity_address;
-
- // Validate behavior before dynamic patching.
- InterceptorFunctionCalled = 0;
- EXPECT_EQ(0, identity(0));
- EXPECT_EQ(42, identity(42));
- EXPECT_EQ(0, InterceptorFunctionCalled);
-
- // Patch the function.
- uptr real_identity_address = 0;
- bool success = override(identity_address,
- (uptr)&InterceptorFunction,
- &real_identity_address);
- EXPECT_TRUE(success);
- EXPECT_NE(0U, real_identity_address);
- IdentityFunction real_identity = (IdentityFunction)real_identity_address;
- InterceptedRealFunction = real_identity;
-
- // Don't run tests if hooking failed or the real function is not valid.
- if (!success || !real_identity_address)
- return;
-
- // Calling the redirected function.
- InterceptorFunctionCalled = 0;
- EXPECT_EQ(0, identity(0));
- EXPECT_EQ(42, identity(42));
- EXPECT_EQ(2, InterceptorFunctionCalled);
-
- // Calling the real function.
- InterceptorFunctionCalled = 0;
- EXPECT_EQ(0, real_identity(0));
- EXPECT_EQ(42, real_identity(42));
- EXPECT_EQ(0, InterceptorFunctionCalled);
-
- TestOnlyReleaseTrampolineRegions();
-}
-
-#if !SANITIZER_WINDOWS64
-TEST(Interception, OverrideFunctionWithDetour) {
- TestOverrideFunction override = OverrideFunctionWithDetour;
- FunctionPrefixKind prefix = FunctionPrefixDetour;
- TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
- TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
- TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix);
- TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix);
-}
-#endif // !SANITIZER_WINDOWS64
-
-TEST(Interception, OverrideFunctionWithRedirectJump) {
- TestOverrideFunction override = OverrideFunctionWithRedirectJump;
- TestIdentityFunctionPatching(kIdentityCodeWithJump, override);
-}
-
-TEST(Interception, OverrideFunctionWithHotPatch) {
- TestOverrideFunction override = OverrideFunctionWithHotPatch;
- FunctionPrefixKind prefix = FunctionPrefixHotPatch;
- TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix);
-}
-
-TEST(Interception, OverrideFunctionWithTrampoline) {
- TestOverrideFunction override = OverrideFunctionWithTrampoline;
- FunctionPrefixKind prefix = FunctionPrefixNone;
- TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
- TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
-
- prefix = FunctionPrefixPadding;
- TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
- TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
-}
-
-TEST(Interception, OverrideFunction) {
- TestOverrideFunction override = OverrideFunction;
- FunctionPrefixKind prefix = FunctionPrefixNone;
- TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
- TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
- TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix);
-
- prefix = FunctionPrefixPadding;
- TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
- TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
- TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix);
- TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix);
-
- prefix = FunctionPrefixHotPatch;
- TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
- TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
- TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix);
- TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix);
-
- prefix = FunctionPrefixDetour;
- TestIdentityFunctionPatching(kIdentityCodeWithPrologue, override, prefix);
- TestIdentityFunctionPatching(kIdentityCodeWithPushPop, override, prefix);
- TestIdentityFunctionPatching(kIdentityCodeWithMov, override, prefix);
- TestIdentityFunctionPatching(kIdentityCodeWithJump, override, prefix);
-}
-
-template<class T>
-static void TestIdentityFunctionMultiplePatching(
- const T &code,
- TestOverrideFunction override,
- FunctionPrefixKind prefix_kind = FunctionPrefixNone) {
- uptr identity_address;
- LoadActiveCode(code, &identity_address, prefix_kind);
-
- // Patch the function.
- uptr real_identity_address = 0;
- bool success = override(identity_address,
- (uptr)&InterceptorFunction,
- &real_identity_address);
- EXPECT_TRUE(success);
- EXPECT_NE(0U, real_identity_address);
-
- // Re-patching the function should not work.
- success = override(identity_address,
- (uptr)&InterceptorFunction,
- &real_identity_address);
- EXPECT_FALSE(success);
-
- TestOnlyReleaseTrampolineRegions();
-}
-
-TEST(Interception, OverrideFunctionMultiplePatchingIsFailing) {
-#if !SANITIZER_WINDOWS64
- TestIdentityFunctionMultiplePatching(kIdentityCodeWithPrologue,
- OverrideFunctionWithDetour,
- FunctionPrefixDetour);
-#endif
-
- TestIdentityFunctionMultiplePatching(kIdentityCodeWithMov,
- OverrideFunctionWithHotPatch,
- FunctionPrefixHotPatch);
-
- TestIdentityFunctionMultiplePatching(kIdentityCodeWithPushPop,
- OverrideFunctionWithTrampoline,
- FunctionPrefixPadding);
-}
-
-TEST(Interception, OverrideFunctionTwice) {
- uptr identity_address1;
- LoadActiveCode(kIdentityTwice, &identity_address1);
- uptr identity_address2 = identity_address1 + kIdentityTwiceOffset;
- IdentityFunction identity1 = (IdentityFunction)identity_address1;
- IdentityFunction identity2 = (IdentityFunction)identity_address2;
-
- // Patch the two functions.
- uptr real_identity_address = 0;
- EXPECT_TRUE(OverrideFunction(identity_address1,
- (uptr)&InterceptorFunction,
- &real_identity_address));
- EXPECT_TRUE(OverrideFunction(identity_address2,
- (uptr)&InterceptorFunction,
- &real_identity_address));
- IdentityFunction real_identity = (IdentityFunction)real_identity_address;
- InterceptedRealFunction = real_identity;
-
- // Calling the redirected function.
- InterceptorFunctionCalled = 0;
- EXPECT_EQ(42, identity1(42));
- EXPECT_EQ(42, identity2(42));
- EXPECT_EQ(2, InterceptorFunctionCalled);
-
- TestOnlyReleaseTrampolineRegions();
-}
-
-template<class T>
-static bool TestFunctionPatching(
- const T &code,
- TestOverrideFunction override,
- FunctionPrefixKind prefix_kind = FunctionPrefixNone) {
- uptr address;
- LoadActiveCode(code, &address, prefix_kind);
- uptr unused_real_address = 0;
- bool result = override(
- address, (uptr)&InterceptorFunction, &unused_real_address);
-
- TestOnlyReleaseTrampolineRegions();
- return result;
-}
-
-TEST(Interception, PatchableFunction) {
- TestOverrideFunction override = OverrideFunction;
- // Test without function padding.
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override));
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode2, override));
-#if SANITIZER_WINDOWS64
- EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override));
-#else
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode3, override));
-#endif
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override));
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode5, override));
-
-#if SANITIZER_WINDOWS64
- EXPECT_TRUE(TestFunctionPatching(kLoadGlobalCode, override));
-#endif
-
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override));
-}
-
-#if !SANITIZER_WINDOWS64
-TEST(Interception, PatchableFunctionWithDetour) {
- TestOverrideFunction override = OverrideFunctionWithDetour;
- // Without the prefix, no function can be detoured.
- EXPECT_FALSE(TestFunctionPatching(kPatchableCode1, override));
- EXPECT_FALSE(TestFunctionPatching(kPatchableCode2, override));
- EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override));
- EXPECT_FALSE(TestFunctionPatching(kPatchableCode4, override));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override));
-
- // With the prefix, all functions can be detoured.
- FunctionPrefixKind prefix = FunctionPrefixDetour;
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override, prefix));
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode2, override, prefix));
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode3, override, prefix));
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override, prefix));
- EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode1, override, prefix));
- EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode2, override, prefix));
- EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode3, override, prefix));
- EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode4, override, prefix));
- EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode5, override, prefix));
- EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode6, override, prefix));
-}
-#endif // !SANITIZER_WINDOWS64
-
-TEST(Interception, PatchableFunctionWithRedirectJump) {
- TestOverrideFunction override = OverrideFunctionWithRedirectJump;
- EXPECT_FALSE(TestFunctionPatching(kPatchableCode1, override));
- EXPECT_FALSE(TestFunctionPatching(kPatchableCode2, override));
- EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override));
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override));
-}
-
-TEST(Interception, PatchableFunctionWithHotPatch) {
- TestOverrideFunction override = OverrideFunctionWithHotPatch;
- FunctionPrefixKind prefix = FunctionPrefixHotPatch;
-
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override, prefix));
- EXPECT_FALSE(TestFunctionPatching(kPatchableCode2, override, prefix));
- EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override, prefix));
- EXPECT_FALSE(TestFunctionPatching(kPatchableCode4, override, prefix));
-
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override, prefix));
- EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode2, override, prefix));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override, prefix));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override, prefix));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override, prefix));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override, prefix));
-}
-
-TEST(Interception, PatchableFunctionWithTrampoline) {
- TestOverrideFunction override = OverrideFunctionWithTrampoline;
- FunctionPrefixKind prefix = FunctionPrefixPadding;
-
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override, prefix));
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode2, override, prefix));
-#if SANITIZER_WINDOWS64
- EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override, prefix));
-#else
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode3, override, prefix));
-#endif
- EXPECT_FALSE(TestFunctionPatching(kPatchableCode4, override, prefix));
-
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override, prefix));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode2, override, prefix));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override, prefix));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override, prefix));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override, prefix));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override, prefix));
-}
-
-TEST(Interception, PatchableFunctionPadding) {
- TestOverrideFunction override = OverrideFunction;
- FunctionPrefixKind prefix = FunctionPrefixPadding;
-
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode1, override, prefix));
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode2, override, prefix));
-#if SANITIZER_WINDOWS64
- EXPECT_FALSE(TestFunctionPatching(kPatchableCode3, override, prefix));
-#else
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode3, override, prefix));
-#endif
- EXPECT_TRUE(TestFunctionPatching(kPatchableCode4, override, prefix));
-
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode1, override, prefix));
- EXPECT_TRUE(TestFunctionPatching(kUnpatchableCode2, override, prefix));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode3, override, prefix));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode4, override, prefix));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode5, override, prefix));
- EXPECT_FALSE(TestFunctionPatching(kUnpatchableCode6, override, prefix));
-}
-
-TEST(Interception, EmptyExportTable) {
- // We try to get a pointer to a function from an executable that doesn't
- // export any symbol (empty export table).
- uptr FunPtr = InternalGetProcAddress((void *)GetModuleHandleA(0), "example");
- EXPECT_EQ(0U, FunPtr);
-}
-
-} // namespace __interception
-
-#endif // SANITIZER_WINDOWS
-#endif // #if !SANITIZER_DEBUG
diff --git a/lib/lsan/.clang-format b/lib/lsan/.clang-format
deleted file mode 100644
index 560308c91deec..0000000000000
--- a/lib/lsan/.clang-format
+++ /dev/null
@@ -1,2 +0,0 @@
-BasedOnStyle: Google
-AllowShortIfStatementsOnASingleLine: false
diff --git a/lib/lsan/CMakeLists.txt b/lib/lsan/CMakeLists.txt
deleted file mode 100644
index 34f686135ac47..0000000000000
--- a/lib/lsan/CMakeLists.txt
+++ /dev/null
@@ -1,78 +0,0 @@
-include_directories(..)
-
-set(LSAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})
-append_rtti_flag(OFF LSAN_CFLAGS)
-
-set(LSAN_COMMON_SOURCES
- lsan_common.cc
- lsan_common_linux.cc
- lsan_common_mac.cc)
-
-set(LSAN_SOURCES
- lsan.cc
- lsan_allocator.cc
- lsan_linux.cc
- lsan_interceptors.cc
- lsan_mac.cc
- lsan_malloc_mac.cc
- lsan_preinit.cc
- lsan_thread.cc)
-
-set(LSAN_HEADERS
- lsan.h
- lsan_allocator.h
- lsan_common.h
- lsan_flags.inc
- lsan_thread.h)
-
-set(LSAN_SRC_DIR ${CMAKE_CURRENT_SOURCE_DIR})
-
-add_compiler_rt_object_libraries(RTLSanCommon
- OS ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${LSAN_COMMON_SUPPORTED_ARCH}
- SOURCES ${LSAN_COMMON_SOURCES}
- ADDITIONAL_HEADERS ${LSAN_HEADERS}
- CFLAGS ${LSAN_CFLAGS})
-
-if(COMPILER_RT_HAS_LSAN)
- add_compiler_rt_component(lsan)
- if(APPLE)
- set(LSAN_LINK_LIBS ${SANITIZER_COMMON_LINK_LIBS})
-
- add_weak_symbols("lsan" WEAK_SYMBOL_LINK_FLAGS)
- add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
-
- add_compiler_rt_runtime(clang_rt.lsan
- SHARED
- OS ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${LSAN_SUPPORTED_ARCH}
- SOURCES ${LSAN_SOURCES}
- ADDITIONAL_HEADERS ${LSAN_HEADERS}
- OBJECT_LIBS RTLSanCommon
- RTInterception
- RTSanitizerCommon
- RTSanitizerCommonLibc
- RTSanitizerCommonCoverage
- RTSanitizerCommonSymbolizer
- CFLAGS ${LSAN_CFLAGS}
- LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS}
- LINK_LIBS ${LSAN_LINK_LIBS}
- PARENT_TARGET lsan)
- else()
- foreach(arch ${LSAN_SUPPORTED_ARCH})
- add_compiler_rt_runtime(clang_rt.lsan
- STATIC
- ARCHS ${arch}
- SOURCES ${LSAN_SOURCES}
- $<TARGET_OBJECTS:RTInterception.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
- $<TARGET_OBJECTS:RTLSanCommon.${arch}>
- ADDITIONAL_HEADERS ${LSAN_HEADERS}
- CFLAGS ${LSAN_CFLAGS}
- PARENT_TARGET lsan)
- endforeach()
- endif()
-endif()
diff --git a/lib/msan/.clang-format b/lib/msan/.clang-format
deleted file mode 100644
index 560308c91deec..0000000000000
--- a/lib/msan/.clang-format
+++ /dev/null
@@ -1,2 +0,0 @@
-BasedOnStyle: Google
-AllowShortIfStatementsOnASingleLine: false
diff --git a/lib/msan/CMakeLists.txt b/lib/msan/CMakeLists.txt
deleted file mode 100644
index 15cc513c20e94..0000000000000
--- a/lib/msan/CMakeLists.txt
+++ /dev/null
@@ -1,86 +0,0 @@
-include_directories(..)
-
-# Runtime library sources and build flags.
-set(MSAN_RTL_SOURCES
- msan.cc
- msan_allocator.cc
- msan_chained_origin_depot.cc
- msan_interceptors.cc
- msan_linux.cc
- msan_report.cc
- msan_thread.cc
- msan_poisoning.cc
- )
-
-set(MSAN_RTL_CXX_SOURCES
- msan_new_delete.cc)
-
-set(MSAN_RTL_HEADERS
- msan.h
- msan_allocator.h
- msan_chained_origin_depot.h
- msan_flags.h
- msan_flags.inc
- msan_interface_internal.h
- msan_origin.h
- msan_poisoning.h
- msan_report.h
- msan_thread.h)
-
-set(MSAN_RTL_CFLAGS ${SANITIZER_COMMON_CFLAGS})
-if(CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
- append_list_if(COMPILER_RT_HAS_FTLS_MODEL_INITIAL_EXEC -ftls-model=initial-exec MSAN_RTL_CFLAGS)
-endif()
-append_rtti_flag(OFF MSAN_RTL_CFLAGS)
-if(NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
- append_list_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE MSAN_RTL_CFLAGS)
-endif()
-# Prevent clang from generating libc calls.
-append_list_if(COMPILER_RT_HAS_FFREESTANDING_FLAG -ffreestanding MSAN_RTL_CFLAGS)
-
-set(MSAN_RUNTIME_LIBRARIES)
-
-# Static runtime library.
-add_compiler_rt_component(msan)
-
-foreach(arch ${MSAN_SUPPORTED_ARCH})
- add_compiler_rt_runtime(clang_rt.msan
- STATIC
- ARCHS ${arch}
- SOURCES ${MSAN_RTL_SOURCES}
- $<TARGET_OBJECTS:RTInterception.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
- $<TARGET_OBJECTS:RTUbsan.${arch}>
- ADDITIONAL_HEADERS ${MSAN_RTL_HEADERS}
- CFLAGS ${MSAN_RTL_CFLAGS}
- PARENT_TARGET msan)
- add_compiler_rt_runtime(clang_rt.msan_cxx
- STATIC
- ARCHS ${arch}
- SOURCES ${MSAN_RTL_CXX_SOURCES}
- $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
- ADDITIONAL_HEADERS ${MSAN_RTL_HEADERS}
- CFLAGS ${MSAN_RTL_CFLAGS}
- PARENT_TARGET msan)
- list(APPEND MSAN_RUNTIME_LIBRARIES clang_rt.msan-${arch}
- clang_rt.msan_cxx-${arch})
- if(SANITIZER_USE_SYMBOLS)
- add_sanitizer_rt_symbols(clang_rt.msan
- ARCHS ${arch}
- EXTRA msan.syms.extra)
- add_sanitizer_rt_symbols(clang_rt.msan_cxx
- ARCHS ${arch}
- EXTRA msan.syms.extra)
- add_dependencies(msan clang_rt.msan-${arch}-symbols
- clang_rt.msan_cxx-${arch}-symbols)
- endif()
-endforeach()
-
-add_compiler_rt_resource_file(msan_blacklist msan_blacklist.txt msan)
-
-if(COMPILER_RT_INCLUDE_TESTS)
- add_subdirectory(tests)
-endif()
diff --git a/lib/msan/tests/CMakeLists.txt b/lib/msan/tests/CMakeLists.txt
deleted file mode 100644
index e9f4e34bfe617..0000000000000
--- a/lib/msan/tests/CMakeLists.txt
+++ /dev/null
@@ -1,142 +0,0 @@
-include(CheckCXXCompilerFlag)
-include(CompilerRTCompile)
-include(CompilerRTLink)
-
-include_directories(..)
-include_directories(../..)
-
-set(MSAN_LIBCXX_CFLAGS
- -fsanitize=memory
- -fsanitize-memory-track-origins
- -Wno-pedantic)
-
-# Unittest sources and build flags.
-set(MSAN_UNITTEST_SOURCES msan_test.cc msan_test_main.cc)
-set(MSAN_LOADABLE_SOURCE msan_loadable.cc)
-set(MSAN_UNITTEST_HEADERS
- msan_test_config.h
- ../../../include/sanitizer/msan_interface.h
-)
-set(MSAN_UNITTEST_COMMON_CFLAGS
- -nostdinc++
- -isystem ${COMPILER_RT_LIBCXX_PATH}/include
- ${COMPILER_RT_UNITTEST_CFLAGS}
- ${COMPILER_RT_GTEST_CFLAGS}
- -I${COMPILER_RT_SOURCE_DIR}/include
- -I${COMPILER_RT_SOURCE_DIR}/lib
- -I${COMPILER_RT_SOURCE_DIR}/lib/msan
- -g
- -O2
- -fno-exceptions
- -fno-omit-frame-pointer
- -mno-omit-leaf-frame-pointer
- -Wno-deprecated-declarations
- -Wno-unused-variable
- -Wno-zero-length-array
- -Wno-uninitialized
- -Werror=sign-compare
- -Wno-gnu-zero-variadic-macro-arguments
-)
-# Remove -stdlib= which is unused when passing -nostdinc++.
-string(REGEX REPLACE "-stdlib=[a-zA-Z+]*" "" CMAKE_CXX_FLAGS ${CMAKE_CXX_FLAGS})
-
-set(MSAN_UNITTEST_INSTRUMENTED_CFLAGS
- ${MSAN_UNITTEST_COMMON_CFLAGS}
- -fsanitize=memory
- -fsanitize-memory-track-origins
- -mllvm -msan-keep-going=1
-)
-set(MSAN_UNITTEST_LINK_FLAGS
- -fsanitize=memory
- # Don't need -stdlib=libc++ because we explicitly list libc++.so in the linker
- # inputs.
- # FIXME: we build libcxx without cxxabi and need libstdc++ to provide it.
- -lstdc++
-)
-
-append_list_if(COMPILER_RT_HAS_LIBDL -ldl MSAN_UNITTEST_LINK_FLAGS)
-
-macro(msan_compile obj_list source arch kind cflags)
- sanitizer_test_compile(
- ${obj_list} ${source} ${arch}
- KIND ${kind}
- COMPILE_DEPS ${MSAN_UNITTEST_HEADERS}
- DEPS gtest msan
- CFLAGS ${MSAN_UNITTEST_INSTRUMENTED_CFLAGS} ${cflags}
- )
-endmacro()
-
-macro(msan_link_shared so_list so_name arch kind)
- 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_LINK_FLAGS)
- if(NOT COMPILER_RT_STANDALONE_BUILD)
- list(APPEND SOURCE_DEPS msan)
- endif()
- clang_link_shared(${output_so}
- OBJECTS ${SOURCE_OBJECTS}
- LINK_FLAGS ${TARGET_LINK_FLAGS} ${SOURCE_LINK_FLAGS}
- DEPS ${SOURCE_DEPS})
- list(APPEND ${so_list} ${output_so})
-endmacro()
-
-# Main MemorySanitizer unit tests.
-add_custom_target(MsanUnitTests)
-set_target_properties(MsanUnitTests PROPERTIES FOLDER "MSan unit tests")
-
-# Adds MSan unit tests and benchmarks for architecture.
-macro(add_msan_tests_for_arch arch kind cflags)
- # Build gtest instrumented with MSan.
- set(MSAN_INST_GTEST)
- msan_compile(MSAN_INST_GTEST ${COMPILER_RT_GTEST_SOURCE} ${arch} "${kind}"
- "${cflags}")
-
- # Instrumented tests.
- set(MSAN_INST_TEST_OBJECTS)
- foreach (SOURCE ${MSAN_UNITTEST_SOURCES})
- msan_compile(MSAN_INST_TEST_OBJECTS ${SOURCE} ${arch} "${kind}" "${cflags}")
- endforeach(SOURCE)
-
- # Instrumented loadable module objects.
- set(MSAN_INST_LOADABLE_OBJECTS)
- msan_compile(MSAN_INST_LOADABLE_OBJECTS ${MSAN_LOADABLE_SOURCE} ${arch} "${kind}"
- "-fPIC;${cflags}")
-
- # Instrumented loadable library tests.
- set(MSAN_LOADABLE_SO)
- msan_link_shared(MSAN_LOADABLE_SO "libmsan_loadable" ${arch} "${kind}"
- OBJECTS ${MSAN_INST_LOADABLE_OBJECTS}
- DEPS ${MSAN_INST_LOADABLE_OBJECTS})
-
- set(MSAN_TEST_OBJECTS ${MSAN_INST_TEST_OBJECTS} ${MSAN_INST_GTEST})
- set(MSAN_TEST_DEPS ${MSAN_TEST_OBJECTS} libcxx_msan_${arch}-build
- ${MSAN_LOADABLE_SO})
- if(NOT COMPILER_RT_STANDALONE_BUILD)
- list(APPEND MSAN_TEST_DEPS msan)
- endif()
- get_target_flags_for_arch(${arch} TARGET_LINK_FLAGS)
- add_compiler_rt_test(MsanUnitTests "Msan-${arch}${kind}-Test" ${arch}
- OBJECTS ${MSAN_TEST_OBJECTS} ${MSAN_LIBCXX_SO}
- DEPS ${MSAN_TEST_DEPS}
- LINK_FLAGS ${MSAN_UNITTEST_LINK_FLAGS}
- ${TARGET_LINK_FLAGS}
- "-Wl,-rpath=${CMAKE_CURRENT_BINARY_DIR}"
- "-Wl,-rpath=${LIBCXX_PREFIX}/lib")
-endmacro()
-
-# We should only build MSan unit tests if we can build instrumented libcxx.
-if(COMPILER_RT_CAN_EXECUTE_TESTS AND COMPILER_RT_LIBCXX_PATH)
- foreach(arch ${MSAN_SUPPORTED_ARCH})
- get_target_flags_for_arch(${arch} TARGET_CFLAGS)
- set(LIBCXX_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/../libcxx_msan_${arch})
- add_custom_libcxx(libcxx_msan_${arch} ${LIBCXX_PREFIX}
- DEPS ${MSAN_RUNTIME_LIBRARIES}
- CFLAGS ${MSAN_LIBCXX_CFLAGS} ${TARGET_CFLAGS}
- USE_TOOLCHAIN)
- set(MSAN_LIBCXX_SO ${LIBCXX_PREFIX}/lib/libc++.so)
-
- add_msan_tests_for_arch(${arch} "" "")
- add_msan_tests_for_arch(${arch} "-with-call"
- "-mllvm;-msan-instrumentation-with-call-threshold=0")
- endforeach()
-endif()
diff --git a/lib/msan/tests/msan_loadable.cc b/lib/msan/tests/msan_loadable.cc
deleted file mode 100644
index 06e880f90dee1..0000000000000
--- a/lib/msan/tests/msan_loadable.cc
+++ /dev/null
@@ -1,27 +0,0 @@
-//===-- msan_loadable.cc --------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of MemorySanitizer.
-//
-// MemorySanitizer unit tests.
-//===----------------------------------------------------------------------===//
-
-#include "msan/msan_interface_internal.h"
-#include <stdlib.h>
-
-static void *dso_global;
-
-// No name mangling.
-extern "C" {
-
-void **get_dso_global() {
- return &dso_global;
-}
-
-}
diff --git a/lib/msan/tests/msan_test.cc b/lib/msan/tests/msan_test.cc
deleted file mode 100644
index 19f46abdc5740..0000000000000
--- a/lib/msan/tests/msan_test.cc
+++ /dev/null
@@ -1,4639 +0,0 @@
-//===-- msan_test.cc ------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of MemorySanitizer.
-//
-// MemorySanitizer unit tests.
-//===----------------------------------------------------------------------===//
-
-#ifndef MSAN_EXTERNAL_TEST_CONFIG
-#include "msan_test_config.h"
-#endif // MSAN_EXTERNAL_TEST_CONFIG
-
-#include "sanitizer_common/tests/sanitizer_test_utils.h"
-
-#include "sanitizer/allocator_interface.h"
-#include "sanitizer/msan_interface.h"
-
-#if defined(__FreeBSD__)
-# define _KERNEL // To declare 'shminfo' structure.
-# include <sys/shm.h>
-# undef _KERNEL
-extern "C" {
-// <sys/shm.h> doesn't declare these functions in _KERNEL mode.
-void *shmat(int, const void *, int);
-int shmget(key_t, size_t, int);
-int shmctl(int, int, struct shmid_ds *);
-int shmdt(const void *);
-}
-#endif
-
-#include <inttypes.h>
-#include <stdlib.h>
-#include <stdarg.h>
-#include <stdio.h>
-#include <wchar.h>
-#include <math.h>
-
-#include <arpa/inet.h>
-#include <dlfcn.h>
-#include <grp.h>
-#include <unistd.h>
-#include <link.h>
-#include <limits.h>
-#include <sys/time.h>
-#include <poll.h>
-#include <sys/types.h>
-#include <sys/stat.h>
-#include <fcntl.h>
-#include <sys/resource.h>
-#include <sys/ioctl.h>
-#include <sys/statvfs.h>
-#include <sys/utsname.h>
-#include <sys/mman.h>
-#include <dirent.h>
-#include <pwd.h>
-#include <sys/socket.h>
-#include <netdb.h>
-#include <wordexp.h>
-#include <sys/ipc.h>
-#include <sys/shm.h>
-
-#if defined(__NetBSD__)
-# include <signal.h>
-# include <netinet/in.h>
-# include <sys/uio.h>
-# include <sys/mount.h>
-# include <sys/sysctl.h>
-# include <net/if.h>
-# include <net/if_ether.h>
-#elif defined(__FreeBSD__)
-# include <signal.h>
-# include <netinet/in.h>
-# include <pthread_np.h>
-# include <sys/uio.h>
-# include <sys/mount.h>
-# include <sys/sysctl.h>
-# include <net/ethernet.h>
-# define f_namelen f_namemax // FreeBSD names this statfs field so.
-# define cpu_set_t cpuset_t
-extern "C" {
-// FreeBSD's <ssp/string.h> defines mempcpy() to be a macro expanding into
-// a __builtin___mempcpy_chk() call, but since Msan RTL defines it as an
-// ordinary function, we can declare it here to complete the tests.
-void *mempcpy(void *dest, const void *src, size_t n);
-}
-#else
-# include <malloc.h>
-# include <sys/sysinfo.h>
-# include <sys/vfs.h>
-# include <mntent.h>
-# include <netinet/ether.h>
-# if defined(__linux__)
-# include <sys/uio.h>
-# endif
-#endif
-
-#if defined(__i386__) || defined(__x86_64__)
-# include <emmintrin.h>
-# define MSAN_HAS_M128 1
-#else
-# define MSAN_HAS_M128 0
-#endif
-
-#ifdef __AVX2__
-# include <immintrin.h>
-#endif
-
-#if defined(__FreeBSD__) || defined(__NetBSD__)
-# define FILE_TO_READ "/bin/cat"
-# define DIR_TO_READ "/bin"
-# define SUBFILE_TO_READ "cat"
-# define SYMLINK_TO_READ "/usr/bin/tar"
-# define SUPERUSER_GROUP "wheel"
-#else
-# define FILE_TO_READ "/proc/self/stat"
-# define DIR_TO_READ "/proc/self"
-# define SUBFILE_TO_READ "stat"
-# define SYMLINK_TO_READ "/proc/self/exe"
-# define SUPERUSER_GROUP "root"
-#endif
-
-static uintptr_t GetPageSize() {
- return sysconf(_SC_PAGESIZE);
-}
-
-const size_t kMaxPathLength = 4096;
-
-typedef unsigned char U1;
-typedef unsigned short U2; // NOLINT
-typedef unsigned int U4;
-typedef unsigned long long U8; // NOLINT
-typedef signed char S1;
-typedef signed short S2; // NOLINT
-typedef signed int S4;
-typedef signed long long S8; // NOLINT
-#define NOINLINE __attribute__((noinline))
-#define INLINE __attribute__((always_inline))
-
-static bool TrackingOrigins() {
- S8 x;
- __msan_set_origin(&x, sizeof(x), 0x1234);
- U4 origin = __msan_get_origin(&x);
- __msan_set_origin(&x, sizeof(x), 0);
- return __msan_origin_is_descendant_or_same(origin, 0x1234);
-}
-
-#define EXPECT_ORIGIN(expected, origin) \
- EXPECT_TRUE(__msan_origin_is_descendant_or_same((origin), (expected)))
-
-#define EXPECT_UMR(action) \
- do { \
- __msan_set_expect_umr(1); \
- action; \
- __msan_set_expect_umr(0); \
- } while (0)
-
-#define EXPECT_UMR_O(action, origin) \
- do { \
- __msan_set_expect_umr(1); \
- action; \
- __msan_set_expect_umr(0); \
- if (TrackingOrigins()) EXPECT_ORIGIN(origin, __msan_get_umr_origin()); \
- } while (0)
-
-#define EXPECT_POISONED(x) ExpectPoisoned(x)
-
-template<typename T>
-void ExpectPoisoned(const T& t) {
- EXPECT_NE(-1, __msan_test_shadow((void*)&t, sizeof(t)));
-}
-
-#define EXPECT_POISONED_O(x, origin) \
- ExpectPoisonedWithOrigin(x, origin)
-
-template<typename T>
-void ExpectPoisonedWithOrigin(const T& t, unsigned origin) {
- EXPECT_NE(-1, __msan_test_shadow((void*)&t, sizeof(t)));
- if (TrackingOrigins()) EXPECT_ORIGIN(origin, __msan_get_origin((void *)&t));
-}
-
-#define EXPECT_NOT_POISONED(x) EXPECT_EQ(true, TestForNotPoisoned((x)))
-#define EXPECT_NOT_POISONED2(data, size) \
- EXPECT_EQ(true, TestForNotPoisoned((data), (size)))
-
-bool TestForNotPoisoned(const void *data, size_t size) {
- return __msan_test_shadow(data, size) == -1;
-}
-
-template<typename T>
-bool TestForNotPoisoned(const T& t) {
- return TestForNotPoisoned((void *)&t, sizeof(t));
-}
-
-static U8 poisoned_array[100];
-template<class T>
-T *GetPoisoned(int i = 0, T val = 0) {
- T *res = (T*)&poisoned_array[i];
- *res = val;
- __msan_poison(&poisoned_array[i], sizeof(T));
- return res;
-}
-
-template<class T>
-T *GetPoisonedO(int i, U4 origin, T val = 0) {
- T *res = (T*)&poisoned_array[i];
- *res = val;
- __msan_poison(&poisoned_array[i], sizeof(T));
- __msan_set_origin(&poisoned_array[i], sizeof(T), origin);
- return res;
-}
-
-template<typename T>
-T Poisoned(T v = 0, T s = (T)(-1)) {
- __msan_partial_poison(&v, &s, sizeof(T));
- return v;
-}
-
-template<class T> NOINLINE T ReturnPoisoned() { return *GetPoisoned<T>(); }
-
-static volatile int g_one = 1;
-static volatile int g_zero = 0;
-static volatile int g_0 = 0;
-static volatile int g_1 = 1;
-
-S4 a_s4[100];
-S8 a_s8[100];
-
-// Check that malloc poisons memory.
-// A lot of tests below depend on this.
-TEST(MemorySanitizerSanity, PoisonInMalloc) {
- int *x = (int*)malloc(sizeof(int));
- EXPECT_POISONED(*x);
- free(x);
-}
-
-TEST(MemorySanitizer, NegativeTest1) {
- S4 *x = GetPoisoned<S4>();
- if (g_one)
- *x = 0;
- EXPECT_NOT_POISONED(*x);
-}
-
-TEST(MemorySanitizer, PositiveTest1) {
- // Load to store.
- EXPECT_POISONED(*GetPoisoned<S1>());
- EXPECT_POISONED(*GetPoisoned<S2>());
- EXPECT_POISONED(*GetPoisoned<S4>());
- EXPECT_POISONED(*GetPoisoned<S8>());
-
- // S->S conversions.
- EXPECT_POISONED(*GetPoisoned<S1>());
- EXPECT_POISONED(*GetPoisoned<S1>());
- EXPECT_POISONED(*GetPoisoned<S1>());
-
- EXPECT_POISONED(*GetPoisoned<S2>());
- EXPECT_POISONED(*GetPoisoned<S2>());
- EXPECT_POISONED(*GetPoisoned<S2>());
-
- EXPECT_POISONED(*GetPoisoned<S4>());
- EXPECT_POISONED(*GetPoisoned<S4>());
- EXPECT_POISONED(*GetPoisoned<S4>());
-
- EXPECT_POISONED(*GetPoisoned<S8>());
- EXPECT_POISONED(*GetPoisoned<S8>());
- EXPECT_POISONED(*GetPoisoned<S8>());
-
- // ZExt
- EXPECT_POISONED(*GetPoisoned<U1>());
- EXPECT_POISONED(*GetPoisoned<U1>());
- EXPECT_POISONED(*GetPoisoned<U1>());
- EXPECT_POISONED(*GetPoisoned<U2>());
- EXPECT_POISONED(*GetPoisoned<U2>());
- EXPECT_POISONED(*GetPoisoned<U4>());
-
- // Unary ops.
- EXPECT_POISONED(- *GetPoisoned<S4>());
-
- EXPECT_UMR(a_s4[g_zero] = 100 / *GetPoisoned<S4>(0, 1));
-
-
- a_s4[g_zero] = 1 - *GetPoisoned<S4>();
- a_s4[g_zero] = 1 + *GetPoisoned<S4>();
-}
-
-TEST(MemorySanitizer, Phi1) {
- S4 c;
- if (g_one) {
- c = *GetPoisoned<S4>();
- } else {
- break_optimization(0);
- c = 0;
- }
- EXPECT_POISONED(c);
-}
-
-TEST(MemorySanitizer, Phi2) {
- S4 i = *GetPoisoned<S4>();
- S4 n = g_one;
- EXPECT_UMR(for (; i < g_one; i++););
- EXPECT_POISONED(i);
-}
-
-NOINLINE void Arg1ExpectUMR(S4 a1) { EXPECT_POISONED(a1); }
-NOINLINE void Arg2ExpectUMR(S4 a1, S4 a2) { EXPECT_POISONED(a2); }
-NOINLINE void Arg3ExpectUMR(S1 a1, S4 a2, S8 a3) { EXPECT_POISONED(a3); }
-
-TEST(MemorySanitizer, ArgTest) {
- Arg1ExpectUMR(*GetPoisoned<S4>());
- Arg2ExpectUMR(0, *GetPoisoned<S4>());
- Arg3ExpectUMR(0, 1, *GetPoisoned<S8>());
-}
-
-
-TEST(MemorySanitizer, CallAndRet) {
- ReturnPoisoned<S1>();
- ReturnPoisoned<S2>();
- ReturnPoisoned<S4>();
- ReturnPoisoned<S8>();
-
- EXPECT_POISONED(ReturnPoisoned<S1>());
- EXPECT_POISONED(ReturnPoisoned<S2>());
- EXPECT_POISONED(ReturnPoisoned<S4>());
- EXPECT_POISONED(ReturnPoisoned<S8>());
-}
-
-// malloc() in the following test may be optimized to produce a compile-time
-// undef value. Check that we trap on the volatile assignment anyway.
-TEST(MemorySanitizer, DISABLED_MallocNoIdent) {
- S4 *x = (int*)malloc(sizeof(S4));
- EXPECT_POISONED(*x);
- free(x);
-}
-
-TEST(MemorySanitizer, Malloc) {
- S4 *x = (int*)Ident(malloc(sizeof(S4)));
- EXPECT_POISONED(*x);
- free(x);
-}
-
-TEST(MemorySanitizer, Realloc) {
- S4 *x = (int*)Ident(realloc(0, sizeof(S4)));
- EXPECT_POISONED(x[0]);
- x[0] = 1;
- x = (int*)Ident(realloc(x, 2 * sizeof(S4)));
- EXPECT_NOT_POISONED(x[0]); // Ok, was inited before.
- EXPECT_POISONED(x[1]);
- x = (int*)Ident(realloc(x, 3 * sizeof(S4)));
- EXPECT_NOT_POISONED(x[0]); // Ok, was inited before.
- EXPECT_POISONED(x[2]);
- EXPECT_POISONED(x[1]);
- x[2] = 1; // Init this here. Check that after realloc it is poisoned again.
- x = (int*)Ident(realloc(x, 2 * sizeof(S4)));
- EXPECT_NOT_POISONED(x[0]); // Ok, was inited before.
- EXPECT_POISONED(x[1]);
- x = (int*)Ident(realloc(x, 3 * sizeof(S4)));
- EXPECT_POISONED(x[1]);
- EXPECT_POISONED(x[2]);
- free(x);
-}
-
-TEST(MemorySanitizer, Calloc) {
- S4 *x = (int*)Ident(calloc(1, sizeof(S4)));
- EXPECT_NOT_POISONED(*x); // Should not be poisoned.
- EXPECT_EQ(0, *x);
- free(x);
-}
-
-TEST(MemorySanitizer, CallocReturnsZeroMem) {
- size_t sizes[] = {16, 1000, 10000, 100000, 2100000};
- for (size_t s = 0; s < sizeof(sizes)/sizeof(sizes[0]); s++) {
- size_t size = sizes[s];
- for (size_t iter = 0; iter < 5; iter++) {
- char *x = Ident((char*)calloc(1, size));
- EXPECT_EQ(x[0], 0);
- EXPECT_EQ(x[size - 1], 0);
- EXPECT_EQ(x[size / 2], 0);
- EXPECT_EQ(x[size / 3], 0);
- EXPECT_EQ(x[size / 4], 0);
- memset(x, 0x42, size);
- free(Ident(x));
- }
- }
-}
-
-TEST(MemorySanitizer, AndOr) {
- U4 *p = GetPoisoned<U4>();
- // We poison two bytes in the midle of a 4-byte word to make the test
- // correct regardless of endianness.
- ((U1*)p)[1] = 0;
- ((U1*)p)[2] = 0xff;
- EXPECT_NOT_POISONED(*p & 0x00ffff00);
- EXPECT_NOT_POISONED(*p & 0x00ff0000);
- EXPECT_NOT_POISONED(*p & 0x0000ff00);
- EXPECT_POISONED(*p & 0xff000000);
- EXPECT_POISONED(*p & 0x000000ff);
- EXPECT_POISONED(*p & 0x0000ffff);
- EXPECT_POISONED(*p & 0xffff0000);
-
- EXPECT_NOT_POISONED(*p | 0xff0000ff);
- EXPECT_NOT_POISONED(*p | 0xff00ffff);
- EXPECT_NOT_POISONED(*p | 0xffff00ff);
- EXPECT_POISONED(*p | 0xff000000);
- EXPECT_POISONED(*p | 0x000000ff);
- EXPECT_POISONED(*p | 0x0000ffff);
- EXPECT_POISONED(*p | 0xffff0000);
-
- EXPECT_POISONED(*GetPoisoned<bool>() & *GetPoisoned<bool>());
-}
-
-template<class T>
-static bool applyNot(T value, T shadow) {
- __msan_partial_poison(&value, &shadow, sizeof(T));
- return !value;
-}
-
-TEST(MemorySanitizer, Not) {
- EXPECT_NOT_POISONED(applyNot<U4>(0x0, 0x0));
- EXPECT_NOT_POISONED(applyNot<U4>(0xFFFFFFFF, 0x0));
- EXPECT_POISONED(applyNot<U4>(0xFFFFFFFF, 0xFFFFFFFF));
- EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x0FFFFFFF));
- EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x00FFFFFF));
- EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x0000FFFF));
- EXPECT_NOT_POISONED(applyNot<U4>(0xFF000000, 0x00000000));
- EXPECT_POISONED(applyNot<U4>(0xFF000000, 0xFF000000));
- EXPECT_NOT_POISONED(applyNot<U4>(0xFF800000, 0xFF000000));
- EXPECT_POISONED(applyNot<U4>(0x00008000, 0x00008000));
-
- EXPECT_NOT_POISONED(applyNot<U1>(0x0, 0x0));
- EXPECT_NOT_POISONED(applyNot<U1>(0xFF, 0xFE));
- EXPECT_NOT_POISONED(applyNot<U1>(0xFF, 0x0));
- EXPECT_POISONED(applyNot<U1>(0xFF, 0xFF));
-
- EXPECT_POISONED(applyNot<void*>((void*)0xFFFFFF, (void*)(-1)));
- EXPECT_NOT_POISONED(applyNot<void*>((void*)0xFFFFFF, (void*)(-2)));
-}
-
-TEST(MemorySanitizer, Shift) {
- U4 *up = GetPoisoned<U4>();
- ((U1*)up)[0] = 0;
- ((U1*)up)[3] = 0xff;
- EXPECT_NOT_POISONED(*up >> 30);
- EXPECT_NOT_POISONED(*up >> 24);
- EXPECT_POISONED(*up >> 23);
- EXPECT_POISONED(*up >> 10);
-
- EXPECT_NOT_POISONED(*up << 30);
- EXPECT_NOT_POISONED(*up << 24);
- EXPECT_POISONED(*up << 23);
- EXPECT_POISONED(*up << 10);
-
- S4 *sp = (S4*)up;
- EXPECT_NOT_POISONED(*sp >> 30);
- EXPECT_NOT_POISONED(*sp >> 24);
- EXPECT_POISONED(*sp >> 23);
- EXPECT_POISONED(*sp >> 10);
-
- sp = GetPoisoned<S4>();
- ((S1*)sp)[1] = 0;
- ((S1*)sp)[2] = 0;
- EXPECT_POISONED(*sp >> 31);
-
- EXPECT_POISONED(100 >> *GetPoisoned<S4>());
- EXPECT_POISONED(100U >> *GetPoisoned<S4>());
-}
-
-NOINLINE static int GetPoisonedZero() {
- int *zero = new int;
- *zero = 0;
- __msan_poison(zero, sizeof(*zero));
- int res = *zero;
- delete zero;
- return res;
-}
-
-TEST(MemorySanitizer, LoadFromDirtyAddress) {
- int *a = new int;
- *a = 0;
- EXPECT_UMR(break_optimization((void*)(U8)a[GetPoisonedZero()]));
- delete a;
-}
-
-TEST(MemorySanitizer, StoreToDirtyAddress) {
- int *a = new int;
- EXPECT_UMR(a[GetPoisonedZero()] = 0);
- break_optimization(a);
- delete a;
-}
-
-
-NOINLINE void StackTestFunc() {
- S4 p4;
- S4 ok4 = 1;
- S2 p2;
- S2 ok2 = 1;
- S1 p1;
- S1 ok1 = 1;
- break_optimization(&p4);
- break_optimization(&ok4);
- break_optimization(&p2);
- break_optimization(&ok2);
- break_optimization(&p1);
- break_optimization(&ok1);
-
- EXPECT_POISONED(p4);
- EXPECT_POISONED(p2);
- EXPECT_POISONED(p1);
- EXPECT_NOT_POISONED(ok1);
- EXPECT_NOT_POISONED(ok2);
- EXPECT_NOT_POISONED(ok4);
-}
-
-TEST(MemorySanitizer, StackTest) {
- StackTestFunc();
-}
-
-NOINLINE void StackStressFunc() {
- int foo[10000];
- break_optimization(foo);
-}
-
-TEST(MemorySanitizer, DISABLED_StackStressTest) {
- for (int i = 0; i < 1000000; i++)
- StackStressFunc();
-}
-
-template<class T>
-void TestFloatingPoint() {
- static volatile T v;
- static T g[100];
- break_optimization(&g);
- T *x = GetPoisoned<T>();
- T *y = GetPoisoned<T>(1);
- EXPECT_POISONED(*x);
- EXPECT_POISONED((long long)*x);
- EXPECT_POISONED((int)*x);
- g[0] = *x;
- g[1] = *x + *y;
- g[2] = *x - *y;
- g[3] = *x * *y;
-}
-
-TEST(MemorySanitizer, FloatingPointTest) {
- TestFloatingPoint<float>();
- TestFloatingPoint<double>();
-}
-
-TEST(MemorySanitizer, DynMem) {
- S4 x = 0;
- S4 *y = GetPoisoned<S4>();
- memcpy(y, &x, g_one * sizeof(S4));
- EXPECT_NOT_POISONED(*y);
-}
-
-static char *DynRetTestStr;
-
-TEST(MemorySanitizer, DynRet) {
- ReturnPoisoned<S8>();
- EXPECT_NOT_POISONED(atoi("0"));
-}
-
-TEST(MemorySanitizer, DynRet1) {
- ReturnPoisoned<S8>();
-}
-
-struct LargeStruct {
- S4 x[10];
-};
-
-NOINLINE
-LargeStruct LargeRetTest() {
- LargeStruct res;
- res.x[0] = *GetPoisoned<S4>();
- res.x[1] = *GetPoisoned<S4>();
- res.x[2] = *GetPoisoned<S4>();
- res.x[3] = *GetPoisoned<S4>();
- res.x[4] = *GetPoisoned<S4>();
- res.x[5] = *GetPoisoned<S4>();
- res.x[6] = *GetPoisoned<S4>();
- res.x[7] = *GetPoisoned<S4>();
- res.x[8] = *GetPoisoned<S4>();
- res.x[9] = *GetPoisoned<S4>();
- return res;
-}
-
-TEST(MemorySanitizer, strcmp) {
- char s1[10];
- char s2[10];
- strncpy(s1, "foo", 10);
- s2[0] = 'f';
- s2[1] = 'n';
- EXPECT_GT(strcmp(s1, s2), 0);
- s2[1] = 'o';
- int res;
- EXPECT_UMR(res = strcmp(s1, s2));
- EXPECT_NOT_POISONED(res);
- EXPECT_EQ(strncmp(s1, s2, 1), 0);
-}
-
-TEST(MemorySanitizer, LargeRet) {
- LargeStruct a = LargeRetTest();
- EXPECT_POISONED(a.x[0]);
- EXPECT_POISONED(a.x[9]);
-}
-
-TEST(MemorySanitizer, strerror) {
- char *buf = strerror(EINVAL);
- EXPECT_NOT_POISONED(strlen(buf));
- buf = strerror(123456);
- EXPECT_NOT_POISONED(strlen(buf));
-}
-
-TEST(MemorySanitizer, strerror_r) {
- errno = 0;
- char buf[1000];
- char *res = (char*) (size_t) strerror_r(EINVAL, buf, sizeof(buf));
- ASSERT_EQ(0, errno);
- if (!res) res = buf; // POSIX version success.
- EXPECT_NOT_POISONED(strlen(res));
-}
-
-TEST(MemorySanitizer, fread) {
- char *x = new char[32];
- FILE *f = fopen(FILE_TO_READ, "r");
- ASSERT_TRUE(f != NULL);
- fread(x, 1, 32, f);
- EXPECT_NOT_POISONED(x[0]);
- EXPECT_NOT_POISONED(x[16]);
- EXPECT_NOT_POISONED(x[31]);
- fclose(f);
- delete[] x;
-}
-
-TEST(MemorySanitizer, read) {
- char *x = new char[32];
- int fd = open(FILE_TO_READ, O_RDONLY);
- ASSERT_GT(fd, 0);
- int sz = read(fd, x, 32);
- ASSERT_EQ(sz, 32);
- EXPECT_NOT_POISONED(x[0]);
- EXPECT_NOT_POISONED(x[16]);
- EXPECT_NOT_POISONED(x[31]);
- close(fd);
- delete[] x;
-}
-
-TEST(MemorySanitizer, pread) {
- char *x = new char[32];
- int fd = open(FILE_TO_READ, O_RDONLY);
- ASSERT_GT(fd, 0);
- int sz = pread(fd, x, 32, 0);
- ASSERT_EQ(sz, 32);
- EXPECT_NOT_POISONED(x[0]);
- EXPECT_NOT_POISONED(x[16]);
- EXPECT_NOT_POISONED(x[31]);
- close(fd);
- delete[] x;
-}
-
-TEST(MemorySanitizer, readv) {
- char buf[2011];
- struct iovec iov[2];
- iov[0].iov_base = buf + 1;
- iov[0].iov_len = 5;
- iov[1].iov_base = buf + 10;
- iov[1].iov_len = 2000;
- int fd = open(FILE_TO_READ, O_RDONLY);
- ASSERT_GT(fd, 0);
- int sz = readv(fd, iov, 2);
- ASSERT_GE(sz, 0);
- ASSERT_LE(sz, 5 + 2000);
- ASSERT_GT((size_t)sz, iov[0].iov_len);
- EXPECT_POISONED(buf[0]);
- EXPECT_NOT_POISONED(buf[1]);
- EXPECT_NOT_POISONED(buf[5]);
- EXPECT_POISONED(buf[6]);
- EXPECT_POISONED(buf[9]);
- EXPECT_NOT_POISONED(buf[10]);
- EXPECT_NOT_POISONED(buf[10 + (sz - 1) - 5]);
- EXPECT_POISONED(buf[11 + (sz - 1) - 5]);
- close(fd);
-}
-
-TEST(MemorySanitizer, preadv) {
- char buf[2011];
- struct iovec iov[2];
- iov[0].iov_base = buf + 1;
- iov[0].iov_len = 5;
- iov[1].iov_base = buf + 10;
- iov[1].iov_len = 2000;
- int fd = open(FILE_TO_READ, O_RDONLY);
- ASSERT_GT(fd, 0);
- int sz = preadv(fd, iov, 2, 3);
- ASSERT_GE(sz, 0);
- ASSERT_LE(sz, 5 + 2000);
- ASSERT_GT((size_t)sz, iov[0].iov_len);
- EXPECT_POISONED(buf[0]);
- EXPECT_NOT_POISONED(buf[1]);
- EXPECT_NOT_POISONED(buf[5]);
- EXPECT_POISONED(buf[6]);
- EXPECT_POISONED(buf[9]);
- EXPECT_NOT_POISONED(buf[10]);
- EXPECT_NOT_POISONED(buf[10 + (sz - 1) - 5]);
- EXPECT_POISONED(buf[11 + (sz - 1) - 5]);
- close(fd);
-}
-
-// FIXME: fails now.
-TEST(MemorySanitizer, DISABLED_ioctl) {
- struct winsize ws;
- EXPECT_EQ(ioctl(2, TIOCGWINSZ, &ws), 0);
- EXPECT_NOT_POISONED(ws.ws_col);
-}
-
-TEST(MemorySanitizer, readlink) {
- char *x = new char[1000];
- readlink(SYMLINK_TO_READ, x, 1000);
- EXPECT_NOT_POISONED(x[0]);
- delete [] x;
-}
-
-TEST(MemorySanitizer, readlinkat) {
- char *x = new char[1000];
- readlinkat(AT_FDCWD, SYMLINK_TO_READ, x, 1000);
- EXPECT_NOT_POISONED(x[0]);
- delete[] x;
-}
-
-TEST(MemorySanitizer, stat) {
- struct stat* st = new struct stat;
- int res = stat(FILE_TO_READ, st);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(st->st_dev);
- EXPECT_NOT_POISONED(st->st_mode);
- EXPECT_NOT_POISONED(st->st_size);
-}
-
-TEST(MemorySanitizer, fstatat) {
- struct stat* st = new struct stat;
- int dirfd = open(DIR_TO_READ, O_RDONLY);
- ASSERT_GT(dirfd, 0);
- int res = fstatat(dirfd, SUBFILE_TO_READ, st, 0);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(st->st_dev);
- EXPECT_NOT_POISONED(st->st_mode);
- EXPECT_NOT_POISONED(st->st_size);
- close(dirfd);
-}
-
-#if !defined(__NetBSD__)
-TEST(MemorySanitizer, statfs) {
- struct statfs st;
- int res = statfs("/", &st);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(st.f_type);
- EXPECT_NOT_POISONED(st.f_bfree);
- EXPECT_NOT_POISONED(st.f_namelen);
-}
-#endif
-
-TEST(MemorySanitizer, statvfs) {
- struct statvfs st;
- int res = statvfs("/", &st);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(st.f_bsize);
- EXPECT_NOT_POISONED(st.f_blocks);
- EXPECT_NOT_POISONED(st.f_bfree);
- EXPECT_NOT_POISONED(st.f_namemax);
-}
-
-TEST(MemorySanitizer, fstatvfs) {
- struct statvfs st;
- int fd = open("/", O_RDONLY | O_DIRECTORY);
- int res = fstatvfs(fd, &st);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(st.f_bsize);
- EXPECT_NOT_POISONED(st.f_blocks);
- EXPECT_NOT_POISONED(st.f_bfree);
- EXPECT_NOT_POISONED(st.f_namemax);
- close(fd);
-}
-
-TEST(MemorySanitizer, pipe) {
- int* pipefd = new int[2];
- int res = pipe(pipefd);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(pipefd[0]);
- EXPECT_NOT_POISONED(pipefd[1]);
- close(pipefd[0]);
- close(pipefd[1]);
-}
-
-TEST(MemorySanitizer, pipe2) {
- int* pipefd = new int[2];
- int res = pipe2(pipefd, O_NONBLOCK);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(pipefd[0]);
- EXPECT_NOT_POISONED(pipefd[1]);
- close(pipefd[0]);
- close(pipefd[1]);
-}
-
-TEST(MemorySanitizer, socketpair) {
- int sv[2];
- int res = socketpair(AF_UNIX, SOCK_STREAM, 0, sv);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(sv[0]);
- EXPECT_NOT_POISONED(sv[1]);
- close(sv[0]);
- close(sv[1]);
-}
-
-TEST(MemorySanitizer, poll) {
- int* pipefd = new int[2];
- int res = pipe(pipefd);
- ASSERT_EQ(0, res);
-
- char data = 42;
- res = write(pipefd[1], &data, 1);
- ASSERT_EQ(1, res);
-
- pollfd fds[2];
- fds[0].fd = pipefd[0];
- fds[0].events = POLLIN;
- fds[1].fd = pipefd[1];
- fds[1].events = POLLIN;
- res = poll(fds, 2, 500);
- ASSERT_EQ(1, res);
- EXPECT_NOT_POISONED(fds[0].revents);
- EXPECT_NOT_POISONED(fds[1].revents);
-
- close(pipefd[0]);
- close(pipefd[1]);
-}
-
-#if !defined (__FreeBSD__) && !defined (__NetBSD__)
-TEST(MemorySanitizer, ppoll) {
- int* pipefd = new int[2];
- int res = pipe(pipefd);
- ASSERT_EQ(0, res);
-
- char data = 42;
- res = write(pipefd[1], &data, 1);
- ASSERT_EQ(1, res);
-
- pollfd fds[2];
- fds[0].fd = pipefd[0];
- fds[0].events = POLLIN;
- fds[1].fd = pipefd[1];
- fds[1].events = POLLIN;
- sigset_t ss;
- sigemptyset(&ss);
- res = ppoll(fds, 2, NULL, &ss);
- ASSERT_EQ(1, res);
- EXPECT_NOT_POISONED(fds[0].revents);
- EXPECT_NOT_POISONED(fds[1].revents);
-
- close(pipefd[0]);
- close(pipefd[1]);
-}
-#endif
-
-TEST(MemorySanitizer, poll_positive) {
- int* pipefd = new int[2];
- int res = pipe(pipefd);
- ASSERT_EQ(0, res);
-
- pollfd fds[2];
- fds[0].fd = pipefd[0];
- fds[0].events = POLLIN;
- // fds[1].fd uninitialized
- fds[1].events = POLLIN;
- EXPECT_UMR(poll(fds, 2, 0));
-
- close(pipefd[0]);
- close(pipefd[1]);
-}
-
-TEST(MemorySanitizer, bind_getsockname) {
- int sock = socket(AF_UNIX, SOCK_STREAM, 0);
-
- struct sockaddr_in sai;
- memset(&sai, 0, sizeof(sai));
- sai.sin_family = AF_UNIX;
- int res = bind(sock, (struct sockaddr *)&sai, sizeof(sai));
-
- ASSERT_EQ(0, res);
- char buf[200];
- socklen_t addrlen;
- EXPECT_UMR(getsockname(sock, (struct sockaddr *)&buf, &addrlen));
-
- addrlen = sizeof(buf);
- res = getsockname(sock, (struct sockaddr *)&buf, &addrlen);
- EXPECT_NOT_POISONED(addrlen);
- EXPECT_NOT_POISONED(buf[0]);
- EXPECT_NOT_POISONED(buf[addrlen - 1]);
- EXPECT_POISONED(buf[addrlen]);
- close(sock);
-}
-
-class SocketAddr {
- public:
- virtual ~SocketAddr() = default;
- virtual struct sockaddr *ptr() = 0;
- virtual size_t size() const = 0;
-
- template <class... Args>
- static std::unique_ptr<SocketAddr> Create(int family, Args... args);
-};
-
-class SocketAddr4 : public SocketAddr {
- public:
- SocketAddr4() { EXPECT_POISONED(sai_); }
- explicit SocketAddr4(uint16_t port) {
- memset(&sai_, 0, sizeof(sai_));
- sai_.sin_family = AF_INET;
- sai_.sin_port = port;
- sai_.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- }
-
- sockaddr *ptr() override { return reinterpret_cast<sockaddr *>(&sai_); }
-
- size_t size() const override { return sizeof(sai_); }
-
- private:
- sockaddr_in sai_;
-};
-
-class SocketAddr6 : public SocketAddr {
- public:
- SocketAddr6() { EXPECT_POISONED(sai_); }
- explicit SocketAddr6(uint16_t port) {
- memset(&sai_, 0, sizeof(sai_));
- sai_.sin6_family = AF_INET6;
- sai_.sin6_port = port;
- sai_.sin6_addr = in6addr_loopback;
- }
-
- sockaddr *ptr() override { return reinterpret_cast<sockaddr *>(&sai_); }
-
- size_t size() const override { return sizeof(sai_); }
-
- private:
- sockaddr_in6 sai_;
-};
-
-template <class... Args>
-std::unique_ptr<SocketAddr> SocketAddr::Create(int family, Args... args) {
- if (family == AF_INET)
- return std::unique_ptr<SocketAddr>(new SocketAddr4(args...));
- return std::unique_ptr<SocketAddr>(new SocketAddr6(args...));
-}
-
-class MemorySanitizerIpTest : public ::testing::TestWithParam<int> {
- public:
- void SetUp() override {
- ASSERT_TRUE(GetParam() == AF_INET || GetParam() == AF_INET6);
- }
-
- template <class... Args>
- std::unique_ptr<SocketAddr> CreateSockAddr(Args... args) const {
- return SocketAddr::Create(GetParam(), args...);
- }
-
- int CreateSocket(int socket_type) const {
- return socket(GetParam(), socket_type, 0);
- }
-};
-
-std::vector<int> GetAvailableIpSocketFamilies() {
- std::vector<int> result;
-
- for (int i : {AF_INET, AF_INET6}) {
- int s = socket(i, SOCK_STREAM, 0);
- if (s > 0) {
- auto sai = SocketAddr::Create(i, 0);
- if (bind(s, sai->ptr(), sai->size()) == 0) result.push_back(i);
- close(s);
- }
- }
-
- return result;
-}
-
-INSTANTIATE_TEST_CASE_P(IpTests, MemorySanitizerIpTest,
- ::testing::ValuesIn(GetAvailableIpSocketFamilies()));
-
-TEST_P(MemorySanitizerIpTest, accept) {
- int listen_socket = CreateSocket(SOCK_STREAM);
- ASSERT_LT(0, listen_socket);
-
- auto sai = CreateSockAddr(0);
- int res = bind(listen_socket, sai->ptr(), sai->size());
- ASSERT_EQ(0, res);
-
- res = listen(listen_socket, 1);
- ASSERT_EQ(0, res);
-
- socklen_t sz = sai->size();
- res = getsockname(listen_socket, sai->ptr(), &sz);
- ASSERT_EQ(0, res);
- ASSERT_EQ(sai->size(), sz);
-
- int connect_socket = CreateSocket(SOCK_STREAM);
- ASSERT_LT(0, connect_socket);
- res = fcntl(connect_socket, F_SETFL, O_NONBLOCK);
- ASSERT_EQ(0, res);
- res = connect(connect_socket, sai->ptr(), sai->size());
- // On FreeBSD this connection completes immediately.
- if (res != 0) {
- ASSERT_EQ(-1, res);
- ASSERT_EQ(EINPROGRESS, errno);
- }
-
- __msan_poison(sai->ptr(), sai->size());
- int new_sock = accept(listen_socket, sai->ptr(), &sz);
- ASSERT_LT(0, new_sock);
- ASSERT_EQ(sai->size(), sz);
- EXPECT_NOT_POISONED2(sai->ptr(), sai->size());
-
- __msan_poison(sai->ptr(), sai->size());
- res = getpeername(new_sock, sai->ptr(), &sz);
- ASSERT_EQ(0, res);
- ASSERT_EQ(sai->size(), sz);
- EXPECT_NOT_POISONED2(sai->ptr(), sai->size());
-
- close(new_sock);
- close(connect_socket);
- close(listen_socket);
-}
-
-TEST_P(MemorySanitizerIpTest, recvmsg) {
- int server_socket = CreateSocket(SOCK_DGRAM);
- ASSERT_LT(0, server_socket);
-
- auto sai = CreateSockAddr(0);
- int res = bind(server_socket, sai->ptr(), sai->size());
- ASSERT_EQ(0, res);
-
- socklen_t sz = sai->size();
- res = getsockname(server_socket, sai->ptr(), &sz);
- ASSERT_EQ(0, res);
- ASSERT_EQ(sai->size(), sz);
-
- int client_socket = CreateSocket(SOCK_DGRAM);
- ASSERT_LT(0, client_socket);
-
- auto client_sai = CreateSockAddr(0);
- res = bind(client_socket, client_sai->ptr(), client_sai->size());
- ASSERT_EQ(0, res);
-
- sz = client_sai->size();
- res = getsockname(client_socket, client_sai->ptr(), &sz);
- ASSERT_EQ(0, res);
- ASSERT_EQ(client_sai->size(), sz);
-
- const char *s = "message text";
- struct iovec iov;
- iov.iov_base = (void *)s;
- iov.iov_len = strlen(s) + 1;
- struct msghdr msg;
- memset(&msg, 0, sizeof(msg));
- msg.msg_name = sai->ptr();
- msg.msg_namelen = sai->size();
- msg.msg_iov = &iov;
- msg.msg_iovlen = 1;
- res = sendmsg(client_socket, &msg, 0);
- ASSERT_LT(0, res);
-
- char buf[1000];
- struct iovec recv_iov;
- recv_iov.iov_base = (void *)&buf;
- recv_iov.iov_len = sizeof(buf);
- auto recv_sai = CreateSockAddr();
- struct msghdr recv_msg;
- memset(&recv_msg, 0, sizeof(recv_msg));
- recv_msg.msg_name = recv_sai->ptr();
- recv_msg.msg_namelen = recv_sai->size();
- recv_msg.msg_iov = &recv_iov;
- recv_msg.msg_iovlen = 1;
- res = recvmsg(server_socket, &recv_msg, 0);
- ASSERT_LT(0, res);
-
- ASSERT_EQ(recv_sai->size(), recv_msg.msg_namelen);
- EXPECT_NOT_POISONED2(recv_sai->ptr(), recv_sai->size());
- EXPECT_STREQ(s, buf);
-
- close(server_socket);
- close(client_socket);
-}
-
-#define EXPECT_HOSTENT_NOT_POISONED(he) \
- do { \
- EXPECT_NOT_POISONED(*(he)); \
- ASSERT_NE((void *)0, (he)->h_name); \
- ASSERT_NE((void *)0, (he)->h_aliases); \
- ASSERT_NE((void *)0, (he)->h_addr_list); \
- EXPECT_NOT_POISONED(strlen((he)->h_name)); \
- char **p = (he)->h_aliases; \
- while (*p) { \
- EXPECT_NOT_POISONED(strlen(*p)); \
- ++p; \
- } \
- char **q = (he)->h_addr_list; \
- while (*q) { \
- EXPECT_NOT_POISONED(*q[0]); \
- ++q; \
- } \
- EXPECT_NOT_POISONED(*q); \
- } while (0)
-
-TEST(MemorySanitizer, gethostent) {
- struct hostent *he = gethostent();
- ASSERT_NE((void *)NULL, he);
- EXPECT_HOSTENT_NOT_POISONED(he);
-}
-
-#ifndef MSAN_TEST_DISABLE_GETHOSTBYNAME
-
-TEST(MemorySanitizer, gethostbyname) {
- struct hostent *he = gethostbyname("localhost");
- ASSERT_NE((void *)NULL, he);
- EXPECT_HOSTENT_NOT_POISONED(he);
-}
-
-#endif // MSAN_TEST_DISABLE_GETHOSTBYNAME
-
-TEST(MemorySanitizer, getaddrinfo) {
- struct addrinfo *ai;
- struct addrinfo hints;
- memset(&hints, 0, sizeof(hints));
- hints.ai_family = AF_INET;
- int res = getaddrinfo("localhost", NULL, &hints, &ai);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(*ai);
- ASSERT_EQ(sizeof(sockaddr_in), ai->ai_addrlen);
- EXPECT_NOT_POISONED(*(sockaddr_in *)ai->ai_addr);
-}
-
-TEST(MemorySanitizer, getnameinfo) {
- struct sockaddr_in sai;
- memset(&sai, 0, sizeof(sai));
- sai.sin_family = AF_INET;
- sai.sin_port = 80;
- sai.sin_addr.s_addr = htonl(INADDR_LOOPBACK);
- char host[500];
- char serv[500];
- int res = getnameinfo((struct sockaddr *)&sai, sizeof(sai), host,
- sizeof(host), serv, sizeof(serv), 0);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(host[0]);
- EXPECT_POISONED(host[sizeof(host) - 1]);
-
- ASSERT_NE(0U, strlen(host));
- EXPECT_NOT_POISONED(serv[0]);
- EXPECT_POISONED(serv[sizeof(serv) - 1]);
- ASSERT_NE(0U, strlen(serv));
-}
-
-TEST(MemorySanitizer, gethostbyname2) {
- struct hostent *he = gethostbyname2("localhost", AF_INET);
- ASSERT_NE((void *)NULL, he);
- EXPECT_HOSTENT_NOT_POISONED(he);
-}
-
-TEST(MemorySanitizer, gethostbyaddr) {
- in_addr_t addr = inet_addr("127.0.0.1");
- EXPECT_NOT_POISONED(addr);
- struct hostent *he = gethostbyaddr(&addr, sizeof(addr), AF_INET);
- ASSERT_NE((void *)NULL, he);
- EXPECT_HOSTENT_NOT_POISONED(he);
-}
-
-#if !defined(__NetBSD__)
-TEST(MemorySanitizer, gethostent_r) {
- char buf[2000];
- struct hostent he;
- struct hostent *result;
- int err;
- int res = gethostent_r(&he, buf, sizeof(buf), &result, &err);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(result);
- ASSERT_NE((void *)NULL, result);
- EXPECT_HOSTENT_NOT_POISONED(result);
- EXPECT_NOT_POISONED(err);
-}
-#endif
-
-#if !defined(__NetBSD__)
-TEST(MemorySanitizer, gethostbyname_r) {
- char buf[2000];
- struct hostent he;
- struct hostent *result;
- int err;
- int res = gethostbyname_r("localhost", &he, buf, sizeof(buf), &result, &err);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(result);
- ASSERT_NE((void *)NULL, result);
- EXPECT_HOSTENT_NOT_POISONED(result);
- EXPECT_NOT_POISONED(err);
-}
-#endif
-
-#if !defined(__NetBSD__)
-TEST(MemorySanitizer, gethostbyname_r_bad_host_name) {
- char buf[2000];
- struct hostent he;
- struct hostent *result;
- int err;
- int res = gethostbyname_r("bad-host-name", &he, buf, sizeof(buf), &result, &err);
- ASSERT_EQ((struct hostent *)0, result);
- EXPECT_NOT_POISONED(err);
-}
-#endif
-
-#if !defined(__NetBSD__)
-TEST(MemorySanitizer, gethostbyname_r_erange) {
- char buf[5];
- struct hostent he;
- struct hostent *result;
- int err;
- gethostbyname_r("localhost", &he, buf, sizeof(buf), &result, &err);
- ASSERT_EQ(ERANGE, errno);
- EXPECT_NOT_POISONED(err);
-}
-#endif
-
-#if !defined(__NetBSD__)
-TEST(MemorySanitizer, gethostbyname2_r) {
- char buf[2000];
- struct hostent he;
- struct hostent *result;
- int err;
- int res = gethostbyname2_r("localhost", AF_INET, &he, buf, sizeof(buf),
- &result, &err);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(result);
- ASSERT_NE((void *)NULL, result);
- EXPECT_HOSTENT_NOT_POISONED(result);
- EXPECT_NOT_POISONED(err);
-}
-#endif
-
-#if !defined(__NetBSD__)
-TEST(MemorySanitizer, gethostbyaddr_r) {
- char buf[2000];
- struct hostent he;
- struct hostent *result;
- int err;
- in_addr_t addr = inet_addr("127.0.0.1");
- EXPECT_NOT_POISONED(addr);
- int res = gethostbyaddr_r(&addr, sizeof(addr), AF_INET, &he, buf, sizeof(buf),
- &result, &err);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(result);
- ASSERT_NE((void *)NULL, result);
- EXPECT_HOSTENT_NOT_POISONED(result);
- EXPECT_NOT_POISONED(err);
-}
-#endif
-
-TEST(MemorySanitizer, getsockopt) {
- int sock = socket(AF_UNIX, SOCK_STREAM, 0);
- struct linger l[2];
- socklen_t sz = sizeof(l[0]);
- int res = getsockopt(sock, SOL_SOCKET, SO_LINGER, &l[0], &sz);
- ASSERT_EQ(0, res);
- ASSERT_EQ(sizeof(l[0]), sz);
- EXPECT_NOT_POISONED(l[0]);
- EXPECT_POISONED(*(char *)(l + 1));
-}
-
-TEST(MemorySanitizer, getcwd) {
- char path[PATH_MAX + 1];
- char* res = getcwd(path, sizeof(path));
- ASSERT_TRUE(res != NULL);
- EXPECT_NOT_POISONED(path[0]);
-}
-
-TEST(MemorySanitizer, getcwd_gnu) {
- char* res = getcwd(NULL, 0);
- ASSERT_TRUE(res != NULL);
- EXPECT_NOT_POISONED(res[0]);
- free(res);
-}
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, get_current_dir_name) {
- char* res = get_current_dir_name();
- ASSERT_TRUE(res != NULL);
- EXPECT_NOT_POISONED(res[0]);
- free(res);
-}
-#endif
-
-TEST(MemorySanitizer, shmctl) {
- int id = shmget(IPC_PRIVATE, 4096, 0644 | IPC_CREAT);
- ASSERT_GT(id, -1);
-
- struct shmid_ds ds;
- int res = shmctl(id, IPC_STAT, &ds);
- ASSERT_GT(res, -1);
- EXPECT_NOT_POISONED(ds);
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
- struct shminfo si;
- res = shmctl(id, IPC_INFO, (struct shmid_ds *)&si);
- ASSERT_GT(res, -1);
- EXPECT_NOT_POISONED(si);
-
- struct shm_info s_i;
- res = shmctl(id, SHM_INFO, (struct shmid_ds *)&s_i);
- ASSERT_GT(res, -1);
- EXPECT_NOT_POISONED(s_i);
-#endif
-
- res = shmctl(id, IPC_RMID, 0);
- ASSERT_GT(res, -1);
-}
-
-TEST(MemorySanitizer, shmat) {
- const int kShmSize = 4096;
- void *mapping_start = mmap(NULL, kShmSize + SHMLBA, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- ASSERT_NE(MAP_FAILED, mapping_start);
-
- void *p = (void *)(((unsigned long)mapping_start + SHMLBA - 1) / SHMLBA * SHMLBA);
- // p is now SHMLBA-aligned;
-
- ((char *)p)[10] = *GetPoisoned<U1>();
- ((char *)p)[kShmSize - 1] = *GetPoisoned<U1>();
-
- int res = munmap(mapping_start, kShmSize + SHMLBA);
- ASSERT_EQ(0, res);
-
- int id = shmget(IPC_PRIVATE, kShmSize, 0644 | IPC_CREAT);
- ASSERT_GT(id, -1);
-
- void *q = shmat(id, p, 0);
- ASSERT_EQ(p, q);
-
- EXPECT_NOT_POISONED(((char *)q)[0]);
- EXPECT_NOT_POISONED(((char *)q)[10]);
- EXPECT_NOT_POISONED(((char *)q)[kShmSize - 1]);
-
- res = shmdt(q);
- ASSERT_EQ(0, res);
-
- res = shmctl(id, IPC_RMID, 0);
- ASSERT_GT(res, -1);
-}
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, random_r) {
- int32_t x;
- char z[64];
- memset(z, 0, sizeof(z));
-
- struct random_data buf;
- memset(&buf, 0, sizeof(buf));
-
- int res = initstate_r(0, z, sizeof(z), &buf);
- ASSERT_EQ(0, res);
-
- res = random_r(&buf, &x);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(x);
-}
-#endif
-
-TEST(MemorySanitizer, confstr) {
- char buf[3];
- size_t res = confstr(_CS_PATH, buf, sizeof(buf));
- ASSERT_GT(res, sizeof(buf));
- EXPECT_NOT_POISONED(buf[0]);
- EXPECT_NOT_POISONED(buf[sizeof(buf) - 1]);
-
- char buf2[1000];
- res = confstr(_CS_PATH, buf2, sizeof(buf2));
- ASSERT_LT(res, sizeof(buf2));
- EXPECT_NOT_POISONED(buf2[0]);
- EXPECT_NOT_POISONED(buf2[res - 1]);
- EXPECT_POISONED(buf2[res]);
- ASSERT_EQ(res, strlen(buf2) + 1);
-}
-
-TEST(MemorySanitizer, opendir) {
- DIR *dir = opendir(".");
- closedir(dir);
-
- char name[10] = ".";
- __msan_poison(name, sizeof(name));
- EXPECT_UMR(dir = opendir(name));
- closedir(dir);
-}
-
-TEST(MemorySanitizer, readdir) {
- DIR *dir = opendir(".");
- struct dirent *d = readdir(dir);
- ASSERT_TRUE(d != NULL);
- EXPECT_NOT_POISONED(d->d_name[0]);
- closedir(dir);
-}
-
-TEST(MemorySanitizer, readdir_r) {
- DIR *dir = opendir(".");
- struct dirent d;
- struct dirent *pd;
- int res = readdir_r(dir, &d, &pd);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(pd);
- EXPECT_NOT_POISONED(d.d_name[0]);
- closedir(dir);
-}
-
-TEST(MemorySanitizer, realpath) {
- const char* relpath = ".";
- char path[PATH_MAX + 1];
- char* res = realpath(relpath, path);
- ASSERT_TRUE(res != NULL);
- EXPECT_NOT_POISONED(path[0]);
-}
-
-TEST(MemorySanitizer, realpath_null) {
- const char* relpath = ".";
- char* res = realpath(relpath, NULL);
- printf("%d, %s\n", errno, strerror(errno));
- ASSERT_TRUE(res != NULL);
- EXPECT_NOT_POISONED(res[0]);
- free(res);
-}
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, canonicalize_file_name) {
- const char* relpath = ".";
- char* res = canonicalize_file_name(relpath);
- ASSERT_TRUE(res != NULL);
- EXPECT_NOT_POISONED(res[0]);
- free(res);
-}
-#endif
-
-extern char **environ;
-
-TEST(MemorySanitizer, setenv) {
- setenv("AAA", "BBB", 1);
- for (char **envp = environ; *envp; ++envp) {
- EXPECT_NOT_POISONED(*envp);
- EXPECT_NOT_POISONED(*envp[0]);
- }
-}
-
-TEST(MemorySanitizer, putenv) {
- char s[] = "AAA=BBB";
- putenv(s);
- for (char **envp = environ; *envp; ++envp) {
- EXPECT_NOT_POISONED(*envp);
- EXPECT_NOT_POISONED(*envp[0]);
- }
-}
-
-TEST(MemorySanitizer, memcpy) {
- char* x = new char[2];
- char* y = new char[2];
- x[0] = 1;
- x[1] = *GetPoisoned<char>();
- memcpy(y, x, 2);
- EXPECT_NOT_POISONED(y[0]);
- EXPECT_POISONED(y[1]);
-}
-
-void TestUnalignedMemcpy(unsigned left, unsigned right, bool src_is_aligned,
- bool src_is_poisoned, bool dst_is_poisoned) {
- fprintf(stderr, "%s(%d, %d, %d, %d, %d)\n", __func__, left, right,
- src_is_aligned, src_is_poisoned, dst_is_poisoned);
-
- const unsigned sz = 20;
- U4 dst_origin, src_origin;
- char *dst = (char *)malloc(sz);
- if (dst_is_poisoned)
- dst_origin = __msan_get_origin(dst);
- else
- memset(dst, 0, sz);
-
- char *src = (char *)malloc(sz);
- if (src_is_poisoned)
- src_origin = __msan_get_origin(src);
- else
- memset(src, 0, sz);
-
- memcpy(dst + left, src_is_aligned ? src + left : src, sz - left - right);
-
- for (unsigned i = 0; i < (left & (~3U)); ++i)
- if (dst_is_poisoned)
- EXPECT_POISONED_O(dst[i], dst_origin);
- else
- EXPECT_NOT_POISONED(dst[i]);
-
- for (unsigned i = 0; i < (right & (~3U)); ++i)
- if (dst_is_poisoned)
- EXPECT_POISONED_O(dst[sz - i - 1], dst_origin);
- else
- EXPECT_NOT_POISONED(dst[sz - i - 1]);
-
- for (unsigned i = left; i < sz - right; ++i)
- if (src_is_poisoned)
- EXPECT_POISONED_O(dst[i], src_origin);
- else
- EXPECT_NOT_POISONED(dst[i]);
-
- free(dst);
- free(src);
-}
-
-TEST(MemorySanitizer, memcpy_unaligned) {
- for (int i = 0; i < 10; ++i)
- for (int j = 0; j < 10; ++j)
- for (int aligned = 0; aligned < 2; ++aligned)
- for (int srcp = 0; srcp < 2; ++srcp)
- for (int dstp = 0; dstp < 2; ++dstp)
- TestUnalignedMemcpy(i, j, aligned, srcp, dstp);
-}
-
-TEST(MemorySanitizer, memmove) {
- char* x = new char[2];
- char* y = new char[2];
- x[0] = 1;
- x[1] = *GetPoisoned<char>();
- memmove(y, x, 2);
- EXPECT_NOT_POISONED(y[0]);
- EXPECT_POISONED(y[1]);
-}
-
-TEST(MemorySanitizer, memccpy_nomatch) {
- char* x = new char[5];
- char* y = new char[5];
- strcpy(x, "abc");
- memccpy(y, x, 'd', 4);
- EXPECT_NOT_POISONED(y[0]);
- EXPECT_NOT_POISONED(y[1]);
- EXPECT_NOT_POISONED(y[2]);
- EXPECT_NOT_POISONED(y[3]);
- EXPECT_POISONED(y[4]);
- delete[] x;
- delete[] y;
-}
-
-TEST(MemorySanitizer, memccpy_match) {
- char* x = new char[5];
- char* y = new char[5];
- strcpy(x, "abc");
- memccpy(y, x, 'b', 4);
- EXPECT_NOT_POISONED(y[0]);
- EXPECT_NOT_POISONED(y[1]);
- EXPECT_POISONED(y[2]);
- EXPECT_POISONED(y[3]);
- EXPECT_POISONED(y[4]);
- delete[] x;
- delete[] y;
-}
-
-TEST(MemorySanitizer, memccpy_nomatch_positive) {
- char* x = new char[5];
- char* y = new char[5];
- strcpy(x, "abc");
- EXPECT_UMR(memccpy(y, x, 'd', 5));
- delete[] x;
- delete[] y;
-}
-
-TEST(MemorySanitizer, memccpy_match_positive) {
- char* x = new char[5];
- char* y = new char[5];
- x[0] = 'a';
- x[2] = 'b';
- EXPECT_UMR(memccpy(y, x, 'b', 5));
- delete[] x;
- delete[] y;
-}
-
-TEST(MemorySanitizer, bcopy) {
- char* x = new char[2];
- char* y = new char[2];
- x[0] = 1;
- x[1] = *GetPoisoned<char>();
- bcopy(x, y, 2);
- EXPECT_NOT_POISONED(y[0]);
- EXPECT_POISONED(y[1]);
-}
-
-TEST(MemorySanitizer, strdup) {
- char buf[4] = "abc";
- __msan_poison(buf + 2, sizeof(*buf));
- char *x = strdup(buf);
- EXPECT_NOT_POISONED(x[0]);
- EXPECT_NOT_POISONED(x[1]);
- EXPECT_POISONED(x[2]);
- EXPECT_NOT_POISONED(x[3]);
- free(x);
-}
-
-TEST(MemorySanitizer, strndup) {
- char buf[4] = "abc";
- __msan_poison(buf + 2, sizeof(*buf));
- char *x;
- EXPECT_UMR(x = strndup(buf, 3));
- EXPECT_NOT_POISONED(x[0]);
- EXPECT_NOT_POISONED(x[1]);
- EXPECT_POISONED(x[2]);
- EXPECT_NOT_POISONED(x[3]);
- free(x);
- // Check handling of non 0 terminated strings.
- buf[3] = 'z';
- __msan_poison(buf + 3, sizeof(*buf));
- EXPECT_UMR(x = strndup(buf + 3, 1));
- EXPECT_POISONED(x[0]);
- EXPECT_NOT_POISONED(x[1]);
- free(x);
-}
-
-TEST(MemorySanitizer, strndup_short) {
- char buf[4] = "abc";
- __msan_poison(buf + 1, sizeof(*buf));
- __msan_poison(buf + 2, sizeof(*buf));
- char *x;
- EXPECT_UMR(x = strndup(buf, 2));
- EXPECT_NOT_POISONED(x[0]);
- EXPECT_POISONED(x[1]);
- EXPECT_NOT_POISONED(x[2]);
- free(x);
-}
-
-
-template<class T, int size>
-void TestOverlapMemmove() {
- T *x = new T[size];
- ASSERT_GE(size, 3);
- x[2] = 0;
- memmove(x, x + 1, (size - 1) * sizeof(T));
- EXPECT_NOT_POISONED(x[1]);
- EXPECT_POISONED(x[0]);
- EXPECT_POISONED(x[2]);
- delete [] x;
-}
-
-TEST(MemorySanitizer, overlap_memmove) {
- TestOverlapMemmove<U1, 10>();
- TestOverlapMemmove<U1, 1000>();
- TestOverlapMemmove<U8, 4>();
- TestOverlapMemmove<U8, 1000>();
-}
-
-TEST(MemorySanitizer, strcpy) { // NOLINT
- char* x = new char[3];
- char* y = new char[3];
- x[0] = 'a';
- x[1] = *GetPoisoned<char>(1, 1);
- x[2] = 0;
- strcpy(y, x); // NOLINT
- EXPECT_NOT_POISONED(y[0]);
- EXPECT_POISONED(y[1]);
- EXPECT_NOT_POISONED(y[2]);
-}
-
-TEST(MemorySanitizer, strncpy) { // NOLINT
- char* x = new char[3];
- char* y = new char[5];
- x[0] = 'a';
- x[1] = *GetPoisoned<char>(1, 1);
- x[2] = '\0';
- strncpy(y, x, 4); // NOLINT
- EXPECT_NOT_POISONED(y[0]);
- EXPECT_POISONED(y[1]);
- EXPECT_NOT_POISONED(y[2]);
- EXPECT_NOT_POISONED(y[3]);
- EXPECT_POISONED(y[4]);
-}
-
-TEST(MemorySanitizer, stpcpy) { // NOLINT
- char* x = new char[3];
- char* y = new char[3];
- x[0] = 'a';
- x[1] = *GetPoisoned<char>(1, 1);
- x[2] = 0;
- char *res = stpcpy(y, x); // NOLINT
- ASSERT_EQ(res, y + 2);
- EXPECT_NOT_POISONED(y[0]);
- EXPECT_POISONED(y[1]);
- EXPECT_NOT_POISONED(y[2]);
-}
-
-TEST(MemorySanitizer, strcat) { // NOLINT
- char a[10];
- char b[] = "def";
- strcpy(a, "abc");
- __msan_poison(b + 1, 1);
- strcat(a, b);
- EXPECT_NOT_POISONED(a[3]);
- EXPECT_POISONED(a[4]);
- EXPECT_NOT_POISONED(a[5]);
- EXPECT_NOT_POISONED(a[6]);
- EXPECT_POISONED(a[7]);
-}
-
-TEST(MemorySanitizer, strncat) { // NOLINT
- char a[10];
- char b[] = "def";
- strcpy(a, "abc");
- __msan_poison(b + 1, 1);
- strncat(a, b, 5);
- EXPECT_NOT_POISONED(a[3]);
- EXPECT_POISONED(a[4]);
- EXPECT_NOT_POISONED(a[5]);
- EXPECT_NOT_POISONED(a[6]);
- EXPECT_POISONED(a[7]);
-}
-
-TEST(MemorySanitizer, strncat_overflow) { // NOLINT
- char a[10];
- char b[] = "def";
- strcpy(a, "abc");
- __msan_poison(b + 1, 1);
- strncat(a, b, 2);
- EXPECT_NOT_POISONED(a[3]);
- EXPECT_POISONED(a[4]);
- EXPECT_NOT_POISONED(a[5]);
- EXPECT_POISONED(a[6]);
- EXPECT_POISONED(a[7]);
-}
-
-TEST(MemorySanitizer, wcscat) {
- wchar_t a[10];
- wchar_t b[] = L"def";
- wcscpy(a, L"abc");
-
- wcscat(a, b);
- EXPECT_EQ(6U, wcslen(a));
- EXPECT_POISONED(a[7]);
-
- a[3] = 0;
- __msan_poison(b + 1, sizeof(wchar_t));
- EXPECT_UMR(wcscat(a, b));
-
- __msan_unpoison(b + 1, sizeof(wchar_t));
- __msan_poison(a + 2, sizeof(wchar_t));
- EXPECT_UMR(wcscat(a, b));
-}
-
-TEST(MemorySanitizer, wcsncat) {
- wchar_t a[10];
- wchar_t b[] = L"def";
- wcscpy(a, L"abc");
-
- wcsncat(a, b, 5);
- EXPECT_EQ(6U, wcslen(a));
- EXPECT_POISONED(a[7]);
-
- a[3] = 0;
- __msan_poison(a + 4, sizeof(wchar_t) * 6);
- wcsncat(a, b, 2);
- EXPECT_EQ(5U, wcslen(a));
- EXPECT_POISONED(a[6]);
-
- a[3] = 0;
- __msan_poison(b + 1, sizeof(wchar_t));
- EXPECT_UMR(wcsncat(a, b, 2));
-
- __msan_unpoison(b + 1, sizeof(wchar_t));
- __msan_poison(a + 2, sizeof(wchar_t));
- EXPECT_UMR(wcsncat(a, b, 2));
-}
-
-#define TEST_STRTO_INT(func_name, char_type, str_prefix) \
- TEST(MemorySanitizer, func_name) { \
- char_type *e; \
- EXPECT_EQ(1U, func_name(str_prefix##"1", &e, 10)); \
- EXPECT_NOT_POISONED((S8)e); \
- }
-
-#define TEST_STRTO_FLOAT(func_name, char_type, str_prefix) \
- TEST(MemorySanitizer, func_name) { \
- char_type *e; \
- EXPECT_NE(0, func_name(str_prefix##"1.5", &e)); \
- EXPECT_NOT_POISONED((S8)e); \
- }
-
-#define TEST_STRTO_FLOAT_LOC(func_name, char_type, str_prefix) \
- TEST(MemorySanitizer, func_name) { \
- locale_t loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0); \
- char_type *e; \
- EXPECT_NE(0, func_name(str_prefix##"1.5", &e, loc)); \
- EXPECT_NOT_POISONED((S8)e); \
- freelocale(loc); \
- }
-
-#define TEST_STRTO_INT_LOC(func_name, char_type, str_prefix) \
- TEST(MemorySanitizer, func_name) { \
- locale_t loc = newlocale(LC_NUMERIC_MASK, "C", (locale_t)0); \
- char_type *e; \
- ASSERT_EQ(1U, func_name(str_prefix##"1", &e, 10, loc)); \
- EXPECT_NOT_POISONED((S8)e); \
- freelocale(loc); \
- }
-
-TEST_STRTO_INT(strtol, char, )
-TEST_STRTO_INT(strtoll, char, )
-TEST_STRTO_INT(strtoul, char, )
-TEST_STRTO_INT(strtoull, char, )
-TEST_STRTO_INT(strtouq, char, )
-
-TEST_STRTO_FLOAT(strtof, char, )
-TEST_STRTO_FLOAT(strtod, char, )
-TEST_STRTO_FLOAT(strtold, char, )
-
-TEST_STRTO_FLOAT_LOC(strtof_l, char, )
-TEST_STRTO_FLOAT_LOC(strtod_l, char, )
-TEST_STRTO_FLOAT_LOC(strtold_l, char, )
-
-TEST_STRTO_INT_LOC(strtol_l, char, )
-TEST_STRTO_INT_LOC(strtoll_l, char, )
-TEST_STRTO_INT_LOC(strtoul_l, char, )
-TEST_STRTO_INT_LOC(strtoull_l, char, )
-
-TEST_STRTO_INT(wcstol, wchar_t, L)
-TEST_STRTO_INT(wcstoll, wchar_t, L)
-TEST_STRTO_INT(wcstoul, wchar_t, L)
-TEST_STRTO_INT(wcstoull, wchar_t, L)
-
-TEST_STRTO_FLOAT(wcstof, wchar_t, L)
-TEST_STRTO_FLOAT(wcstod, wchar_t, L)
-TEST_STRTO_FLOAT(wcstold, wchar_t, L)
-
-TEST_STRTO_FLOAT_LOC(wcstof_l, wchar_t, L)
-TEST_STRTO_FLOAT_LOC(wcstod_l, wchar_t, L)
-TEST_STRTO_FLOAT_LOC(wcstold_l, wchar_t, L)
-
-TEST_STRTO_INT_LOC(wcstol_l, wchar_t, L)
-TEST_STRTO_INT_LOC(wcstoll_l, wchar_t, L)
-TEST_STRTO_INT_LOC(wcstoul_l, wchar_t, L)
-TEST_STRTO_INT_LOC(wcstoull_l, wchar_t, L)
-
-
-TEST(MemorySanitizer, strtoimax) {
- char *e;
- ASSERT_EQ(1, strtoimax("1", &e, 10));
- EXPECT_NOT_POISONED((S8) e);
-}
-
-TEST(MemorySanitizer, strtoumax) {
- char *e;
- ASSERT_EQ(1U, strtoumax("1", &e, 10));
- EXPECT_NOT_POISONED((S8) e);
-}
-
-#ifdef __GLIBC__
-extern "C" float __strtof_l(const char *nptr, char **endptr, locale_t loc);
-TEST_STRTO_FLOAT_LOC(__strtof_l, char, )
-extern "C" double __strtod_l(const char *nptr, char **endptr, locale_t loc);
-TEST_STRTO_FLOAT_LOC(__strtod_l, char, )
-extern "C" long double __strtold_l(const char *nptr, char **endptr,
- locale_t loc);
-TEST_STRTO_FLOAT_LOC(__strtold_l, char, )
-
-extern "C" float __wcstof_l(const wchar_t *nptr, wchar_t **endptr, locale_t loc);
-TEST_STRTO_FLOAT_LOC(__wcstof_l, wchar_t, L)
-extern "C" double __wcstod_l(const wchar_t *nptr, wchar_t **endptr, locale_t loc);
-TEST_STRTO_FLOAT_LOC(__wcstod_l, wchar_t, L)
-extern "C" long double __wcstold_l(const wchar_t *nptr, wchar_t **endptr,
- locale_t loc);
-TEST_STRTO_FLOAT_LOC(__wcstold_l, wchar_t, L)
-#endif // __GLIBC__
-
-TEST(MemorySanitizer, modf) {
- double x, y;
- x = modf(2.1, &y);
- EXPECT_NOT_POISONED(y);
-}
-
-TEST(MemorySanitizer, modff) {
- float x, y;
- x = modff(2.1, &y);
- EXPECT_NOT_POISONED(y);
-}
-
-TEST(MemorySanitizer, modfl) {
- long double x, y;
- x = modfl(2.1, &y);
- EXPECT_NOT_POISONED(y);
-}
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, sincos) {
- double s, c;
- sincos(0.2, &s, &c);
- EXPECT_NOT_POISONED(s);
- EXPECT_NOT_POISONED(c);
-}
-#endif
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, sincosf) {
- float s, c;
- sincosf(0.2, &s, &c);
- EXPECT_NOT_POISONED(s);
- EXPECT_NOT_POISONED(c);
-}
-#endif
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, sincosl) {
- long double s, c;
- sincosl(0.2, &s, &c);
- EXPECT_NOT_POISONED(s);
- EXPECT_NOT_POISONED(c);
-}
-#endif
-
-TEST(MemorySanitizer, remquo) {
- int quo;
- double res = remquo(29.0, 3.0, &quo);
- ASSERT_NE(0.0, res);
- EXPECT_NOT_POISONED(quo);
-}
-
-TEST(MemorySanitizer, remquof) {
- int quo;
- float res = remquof(29.0, 3.0, &quo);
- ASSERT_NE(0.0, res);
- EXPECT_NOT_POISONED(quo);
-}
-
-#if !defined(__NetBSD__)
-TEST(MemorySanitizer, remquol) {
- int quo;
- long double res = remquof(29.0, 3.0, &quo);
- ASSERT_NE(0.0, res);
- EXPECT_NOT_POISONED(quo);
-}
-#endif
-
-TEST(MemorySanitizer, lgamma) {
- double res = lgamma(1.1);
- ASSERT_NE(0.0, res);
- EXPECT_NOT_POISONED(signgam);
-}
-
-TEST(MemorySanitizer, lgammaf) {
- float res = lgammaf(1.1);
- ASSERT_NE(0.0, res);
- EXPECT_NOT_POISONED(signgam);
-}
-
-#if !defined(__NetBSD__)
-TEST(MemorySanitizer, lgammal) {
- long double res = lgammal(1.1);
- ASSERT_NE(0.0, res);
- EXPECT_NOT_POISONED(signgam);
-}
-#endif
-
-TEST(MemorySanitizer, lgamma_r) {
- int sgn;
- double res = lgamma_r(1.1, &sgn);
- ASSERT_NE(0.0, res);
- EXPECT_NOT_POISONED(sgn);
-}
-
-TEST(MemorySanitizer, lgammaf_r) {
- int sgn;
- float res = lgammaf_r(1.1, &sgn);
- ASSERT_NE(0.0, res);
- EXPECT_NOT_POISONED(sgn);
-}
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, lgammal_r) {
- int sgn;
- long double res = lgammal_r(1.1, &sgn);
- ASSERT_NE(0.0, res);
- EXPECT_NOT_POISONED(sgn);
-}
-#endif
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, drand48_r) {
- struct drand48_data buf;
- srand48_r(0, &buf);
- double d;
- drand48_r(&buf, &d);
- EXPECT_NOT_POISONED(d);
-}
-#endif
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, lrand48_r) {
- struct drand48_data buf;
- srand48_r(0, &buf);
- long d;
- lrand48_r(&buf, &d);
- EXPECT_NOT_POISONED(d);
-}
-#endif
-
-TEST(MemorySanitizer, sprintf) { // NOLINT
- char buff[10];
- break_optimization(buff);
- EXPECT_POISONED(buff[0]);
- int res = sprintf(buff, "%d", 1234567); // NOLINT
- ASSERT_EQ(res, 7);
- ASSERT_EQ(buff[0], '1');
- ASSERT_EQ(buff[1], '2');
- ASSERT_EQ(buff[2], '3');
- ASSERT_EQ(buff[6], '7');
- ASSERT_EQ(buff[7], 0);
- EXPECT_POISONED(buff[8]);
-}
-
-TEST(MemorySanitizer, snprintf) {
- char buff[10];
- break_optimization(buff);
- EXPECT_POISONED(buff[0]);
- int res = snprintf(buff, sizeof(buff), "%d", 1234567);
- ASSERT_EQ(res, 7);
- ASSERT_EQ(buff[0], '1');
- ASSERT_EQ(buff[1], '2');
- ASSERT_EQ(buff[2], '3');
- ASSERT_EQ(buff[6], '7');
- ASSERT_EQ(buff[7], 0);
- EXPECT_POISONED(buff[8]);
-}
-
-TEST(MemorySanitizer, swprintf) {
- wchar_t buff[10];
- ASSERT_EQ(4U, sizeof(wchar_t));
- break_optimization(buff);
- EXPECT_POISONED(buff[0]);
- int res = swprintf(buff, 9, L"%d", 1234567);
- ASSERT_EQ(res, 7);
- ASSERT_EQ(buff[0], '1');
- ASSERT_EQ(buff[1], '2');
- ASSERT_EQ(buff[2], '3');
- ASSERT_EQ(buff[6], '7');
- ASSERT_EQ(buff[7], L'\0');
- EXPECT_POISONED(buff[8]);
-}
-
-TEST(MemorySanitizer, asprintf) { // NOLINT
- char *pbuf;
- EXPECT_POISONED(pbuf);
- int res = asprintf(&pbuf, "%d", 1234567); // NOLINT
- ASSERT_EQ(res, 7);
- EXPECT_NOT_POISONED(pbuf);
- ASSERT_EQ(pbuf[0], '1');
- ASSERT_EQ(pbuf[1], '2');
- ASSERT_EQ(pbuf[2], '3');
- ASSERT_EQ(pbuf[6], '7');
- ASSERT_EQ(pbuf[7], 0);
- free(pbuf);
-}
-
-TEST(MemorySanitizer, mbstowcs) {
- const char *x = "abc";
- wchar_t buff[10];
- int res = mbstowcs(buff, x, 2);
- EXPECT_EQ(2, res);
- EXPECT_EQ(L'a', buff[0]);
- EXPECT_EQ(L'b', buff[1]);
- EXPECT_POISONED(buff[2]);
- res = mbstowcs(buff, x, 10);
- EXPECT_EQ(3, res);
- EXPECT_NOT_POISONED(buff[3]);
-}
-
-TEST(MemorySanitizer, wcstombs) {
- const wchar_t *x = L"abc";
- char buff[10];
- int res = wcstombs(buff, x, 4);
- EXPECT_EQ(res, 3);
- EXPECT_EQ(buff[0], 'a');
- EXPECT_EQ(buff[1], 'b');
- EXPECT_EQ(buff[2], 'c');
-}
-
-TEST(MemorySanitizer, wcsrtombs) {
- const wchar_t *x = L"abc";
- const wchar_t *p = x;
- char buff[10];
- mbstate_t mbs;
- memset(&mbs, 0, sizeof(mbs));
- int res = wcsrtombs(buff, &p, 4, &mbs);
- EXPECT_EQ(res, 3);
- EXPECT_EQ(buff[0], 'a');
- EXPECT_EQ(buff[1], 'b');
- EXPECT_EQ(buff[2], 'c');
- EXPECT_EQ(buff[3], '\0');
- EXPECT_POISONED(buff[4]);
-}
-
-TEST(MemorySanitizer, wcsnrtombs) {
- const wchar_t *x = L"abc";
- const wchar_t *p = x;
- char buff[10];
- mbstate_t mbs;
- memset(&mbs, 0, sizeof(mbs));
- int res = wcsnrtombs(buff, &p, 2, 4, &mbs);
- EXPECT_EQ(res, 2);
- EXPECT_EQ(buff[0], 'a');
- EXPECT_EQ(buff[1], 'b');
- EXPECT_POISONED(buff[2]);
-}
-
-TEST(MemorySanitizer, wcrtomb) {
- wchar_t x = L'a';
- char buff[10];
- mbstate_t mbs;
- memset(&mbs, 0, sizeof(mbs));
- size_t res = wcrtomb(buff, x, &mbs);
- EXPECT_EQ(res, (size_t)1);
- EXPECT_EQ(buff[0], 'a');
-}
-
-TEST(MemorySanitizer, wmemset) {
- wchar_t x[25];
- break_optimization(x);
- EXPECT_POISONED(x[0]);
- wmemset(x, L'A', 10);
- EXPECT_EQ(x[0], L'A');
- EXPECT_EQ(x[9], L'A');
- EXPECT_POISONED(x[10]);
-}
-
-TEST(MemorySanitizer, mbtowc) {
- const char *x = "abc";
- wchar_t wx;
- int res = mbtowc(&wx, x, 3);
- EXPECT_GT(res, 0);
- EXPECT_NOT_POISONED(wx);
-}
-
-TEST(MemorySanitizer, mbrtowc) {
- mbstate_t mbs = {};
-
- wchar_t wc;
- size_t res = mbrtowc(&wc, "\377", 1, &mbs);
- EXPECT_EQ(res, -1ULL);
-
- res = mbrtowc(&wc, "abc", 3, &mbs);
- EXPECT_GT(res, 0ULL);
- EXPECT_NOT_POISONED(wc);
-}
-
-TEST(MemorySanitizer, wcsftime) {
- wchar_t x[100];
- time_t t = time(NULL);
- struct tm tms;
- struct tm *tmres = localtime_r(&t, &tms);
- ASSERT_NE((void *)0, tmres);
- size_t res = wcsftime(x, sizeof(x) / sizeof(x[0]), L"%Y-%m-%d", tmres);
- EXPECT_GT(res, 0UL);
- EXPECT_EQ(res, wcslen(x));
-}
-
-TEST(MemorySanitizer, gettimeofday) {
- struct timeval tv;
- struct timezone tz;
- break_optimization(&tv);
- break_optimization(&tz);
- ASSERT_EQ(16U, sizeof(tv));
- ASSERT_EQ(8U, sizeof(tz));
- EXPECT_POISONED(tv.tv_sec);
- EXPECT_POISONED(tv.tv_usec);
- EXPECT_POISONED(tz.tz_minuteswest);
- EXPECT_POISONED(tz.tz_dsttime);
- ASSERT_EQ(0, gettimeofday(&tv, &tz));
- EXPECT_NOT_POISONED(tv.tv_sec);
- EXPECT_NOT_POISONED(tv.tv_usec);
- EXPECT_NOT_POISONED(tz.tz_minuteswest);
- EXPECT_NOT_POISONED(tz.tz_dsttime);
-}
-
-TEST(MemorySanitizer, clock_gettime) {
- struct timespec tp;
- EXPECT_POISONED(tp.tv_sec);
- EXPECT_POISONED(tp.tv_nsec);
- ASSERT_EQ(0, clock_gettime(CLOCK_REALTIME, &tp));
- EXPECT_NOT_POISONED(tp.tv_sec);
- EXPECT_NOT_POISONED(tp.tv_nsec);
-}
-
-TEST(MemorySanitizer, clock_getres) {
- struct timespec tp;
- EXPECT_POISONED(tp.tv_sec);
- EXPECT_POISONED(tp.tv_nsec);
- ASSERT_EQ(0, clock_getres(CLOCK_REALTIME, 0));
- EXPECT_POISONED(tp.tv_sec);
- EXPECT_POISONED(tp.tv_nsec);
- ASSERT_EQ(0, clock_getres(CLOCK_REALTIME, &tp));
- EXPECT_NOT_POISONED(tp.tv_sec);
- EXPECT_NOT_POISONED(tp.tv_nsec);
-}
-
-TEST(MemorySanitizer, getitimer) {
- struct itimerval it1, it2;
- int res;
- EXPECT_POISONED(it1.it_interval.tv_sec);
- EXPECT_POISONED(it1.it_interval.tv_usec);
- EXPECT_POISONED(it1.it_value.tv_sec);
- EXPECT_POISONED(it1.it_value.tv_usec);
- res = getitimer(ITIMER_VIRTUAL, &it1);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(it1.it_interval.tv_sec);
- EXPECT_NOT_POISONED(it1.it_interval.tv_usec);
- EXPECT_NOT_POISONED(it1.it_value.tv_sec);
- EXPECT_NOT_POISONED(it1.it_value.tv_usec);
-
- it1.it_interval.tv_sec = it1.it_value.tv_sec = 10000;
- it1.it_interval.tv_usec = it1.it_value.tv_usec = 0;
-
- res = setitimer(ITIMER_VIRTUAL, &it1, &it2);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(it2.it_interval.tv_sec);
- EXPECT_NOT_POISONED(it2.it_interval.tv_usec);
- EXPECT_NOT_POISONED(it2.it_value.tv_sec);
- EXPECT_NOT_POISONED(it2.it_value.tv_usec);
-
- // Check that old_value can be 0, and disable the timer.
- memset(&it1, 0, sizeof(it1));
- res = setitimer(ITIMER_VIRTUAL, &it1, 0);
- ASSERT_EQ(0, res);
-}
-
-TEST(MemorySanitizer, setitimer_null) {
- setitimer(ITIMER_VIRTUAL, 0, 0);
- // Not testing the return value, since it the behaviour seems to differ
- // between libc implementations and POSIX.
- // Should never crash, though.
-}
-
-TEST(MemorySanitizer, time) {
- time_t t;
- EXPECT_POISONED(t);
- time_t t2 = time(&t);
- ASSERT_NE(t2, (time_t)-1);
- EXPECT_NOT_POISONED(t);
-}
-
-TEST(MemorySanitizer, strptime) {
- struct tm time;
- char *p = strptime("11/1/2013-05:39", "%m/%d/%Y-%H:%M", &time);
- ASSERT_TRUE(p != NULL);
- EXPECT_NOT_POISONED(time.tm_sec);
- EXPECT_NOT_POISONED(time.tm_hour);
- EXPECT_NOT_POISONED(time.tm_year);
-}
-
-TEST(MemorySanitizer, localtime) {
- time_t t = 123;
- struct tm *time = localtime(&t);
- ASSERT_TRUE(time != NULL);
- EXPECT_NOT_POISONED(time->tm_sec);
- EXPECT_NOT_POISONED(time->tm_hour);
- EXPECT_NOT_POISONED(time->tm_year);
- EXPECT_NOT_POISONED(time->tm_isdst);
- EXPECT_NE(0U, strlen(time->tm_zone));
-}
-
-TEST(MemorySanitizer, localtime_r) {
- time_t t = 123;
- struct tm time;
- struct tm *res = localtime_r(&t, &time);
- ASSERT_TRUE(res != NULL);
- EXPECT_NOT_POISONED(time.tm_sec);
- EXPECT_NOT_POISONED(time.tm_hour);
- EXPECT_NOT_POISONED(time.tm_year);
- EXPECT_NOT_POISONED(time.tm_isdst);
- EXPECT_NE(0U, strlen(time.tm_zone));
-}
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-/* Creates a temporary file with contents similar to /etc/fstab to be used
- with getmntent{_r}. */
-class TempFstabFile {
- public:
- TempFstabFile() : fd (-1) { }
- ~TempFstabFile() {
- if (fd >= 0)
- close (fd);
- }
-
- bool Create(void) {
- snprintf(tmpfile, sizeof(tmpfile), "/tmp/msan.getmntent.tmp.XXXXXX");
-
- fd = mkstemp(tmpfile);
- if (fd == -1)
- return false;
-
- const char entry[] = "/dev/root / ext4 errors=remount-ro 0 1";
- size_t entrylen = sizeof(entry);
-
- size_t bytesWritten = write(fd, entry, entrylen);
- if (entrylen != bytesWritten)
- return false;
-
- return true;
- }
-
- const char* FileName(void) {
- return tmpfile;
- }
-
- private:
- char tmpfile[128];
- int fd;
-};
-#endif
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, getmntent) {
- TempFstabFile fstabtmp;
- ASSERT_TRUE(fstabtmp.Create());
- FILE *fp = setmntent(fstabtmp.FileName(), "r");
-
- struct mntent *mnt = getmntent(fp);
- ASSERT_TRUE(mnt != NULL);
- ASSERT_NE(0U, strlen(mnt->mnt_fsname));
- ASSERT_NE(0U, strlen(mnt->mnt_dir));
- ASSERT_NE(0U, strlen(mnt->mnt_type));
- ASSERT_NE(0U, strlen(mnt->mnt_opts));
- EXPECT_NOT_POISONED(mnt->mnt_freq);
- EXPECT_NOT_POISONED(mnt->mnt_passno);
- fclose(fp);
-}
-#endif
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, getmntent_r) {
- TempFstabFile fstabtmp;
- ASSERT_TRUE(fstabtmp.Create());
- FILE *fp = setmntent(fstabtmp.FileName(), "r");
-
- struct mntent mntbuf;
- char buf[1000];
- struct mntent *mnt = getmntent_r(fp, &mntbuf, buf, sizeof(buf));
- ASSERT_TRUE(mnt != NULL);
- ASSERT_NE(0U, strlen(mnt->mnt_fsname));
- ASSERT_NE(0U, strlen(mnt->mnt_dir));
- ASSERT_NE(0U, strlen(mnt->mnt_type));
- ASSERT_NE(0U, strlen(mnt->mnt_opts));
- EXPECT_NOT_POISONED(mnt->mnt_freq);
- EXPECT_NOT_POISONED(mnt->mnt_passno);
- fclose(fp);
-}
-#endif
-
-#if !defined(__NetBSD__)
-TEST(MemorySanitizer, ether) {
- const char *asc = "11:22:33:44:55:66";
- struct ether_addr *paddr = ether_aton(asc);
- EXPECT_NOT_POISONED(*paddr);
-
- struct ether_addr addr;
- paddr = ether_aton_r(asc, &addr);
- ASSERT_EQ(paddr, &addr);
- EXPECT_NOT_POISONED(addr);
-
- char *s = ether_ntoa(&addr);
- ASSERT_NE(0U, strlen(s));
-
- char buf[100];
- s = ether_ntoa_r(&addr, buf);
- ASSERT_EQ(s, buf);
- ASSERT_NE(0U, strlen(buf));
-}
-#endif
-
-TEST(MemorySanitizer, mmap) {
- const int size = 4096;
- void *p1, *p2;
- p1 = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
- __msan_poison(p1, size);
- munmap(p1, size);
- for (int i = 0; i < 1000; i++) {
- p2 = mmap(0, size, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
- if (p2 == p1)
- break;
- else
- munmap(p2, size);
- }
- if (p1 == p2) {
- EXPECT_NOT_POISONED(*(char*)p2);
- munmap(p2, size);
- }
-}
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-// FIXME: enable and add ecvt.
-// FIXME: check why msandr does nt handle fcvt.
-TEST(MemorySanitizer, fcvt) {
- int a, b;
- break_optimization(&a);
- break_optimization(&b);
- EXPECT_POISONED(a);
- EXPECT_POISONED(b);
- char *str = fcvt(12345.6789, 10, &a, &b);
- EXPECT_NOT_POISONED(a);
- EXPECT_NOT_POISONED(b);
- ASSERT_NE(nullptr, str);
- EXPECT_NOT_POISONED(str[0]);
- ASSERT_NE(0U, strlen(str));
-}
-#endif
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, fcvt_long) {
- int a, b;
- break_optimization(&a);
- break_optimization(&b);
- EXPECT_POISONED(a);
- EXPECT_POISONED(b);
- char *str = fcvt(111111112345.6789, 10, &a, &b);
- EXPECT_NOT_POISONED(a);
- EXPECT_NOT_POISONED(b);
- ASSERT_NE(nullptr, str);
- EXPECT_NOT_POISONED(str[0]);
- ASSERT_NE(0U, strlen(str));
-}
-#endif
-
-TEST(MemorySanitizer, memchr) {
- char x[10];
- break_optimization(x);
- EXPECT_POISONED(x[0]);
- x[2] = '2';
- void *res;
- EXPECT_UMR(res = memchr(x, '2', 10));
- EXPECT_NOT_POISONED(res);
- x[0] = '0';
- x[1] = '1';
- res = memchr(x, '2', 10);
- EXPECT_EQ(&x[2], res);
- EXPECT_UMR(res = memchr(x, '3', 10));
- EXPECT_NOT_POISONED(res);
-}
-
-TEST(MemorySanitizer, memrchr) {
- char x[10];
- break_optimization(x);
- EXPECT_POISONED(x[0]);
- x[9] = '9';
- void *res;
- EXPECT_UMR(res = memrchr(x, '9', 10));
- EXPECT_NOT_POISONED(res);
- x[0] = '0';
- x[1] = '1';
- res = memrchr(x, '0', 2);
- EXPECT_EQ(&x[0], res);
- EXPECT_UMR(res = memrchr(x, '7', 10));
- EXPECT_NOT_POISONED(res);
-}
-
-TEST(MemorySanitizer, frexp) {
- int x;
- x = *GetPoisoned<int>();
- double r = frexp(1.1, &x);
- EXPECT_NOT_POISONED(r);
- EXPECT_NOT_POISONED(x);
-
- x = *GetPoisoned<int>();
- float rf = frexpf(1.1, &x);
- EXPECT_NOT_POISONED(rf);
- EXPECT_NOT_POISONED(x);
-
- x = *GetPoisoned<int>();
- double rl = frexpl(1.1, &x);
- EXPECT_NOT_POISONED(rl);
- EXPECT_NOT_POISONED(x);
-}
-
-namespace {
-
-static int cnt;
-
-void SigactionHandler(int signo, siginfo_t* si, void* uc) {
- ASSERT_EQ(signo, SIGPROF);
- ASSERT_TRUE(si != NULL);
- EXPECT_NOT_POISONED(si->si_errno);
- EXPECT_NOT_POISONED(si->si_pid);
-#ifdef _UC_MACHINE_PC
- EXPECT_NOT_POISONED(_UC_MACHINE_PC((ucontext_t*)uc));
-#else
-# if __linux__
-# if defined(__x86_64__)
- EXPECT_NOT_POISONED(((ucontext_t*)uc)->uc_mcontext.gregs[REG_RIP]);
-# elif defined(__i386__)
- EXPECT_NOT_POISONED(((ucontext_t*)uc)->uc_mcontext.gregs[REG_EIP]);
-# endif
-# endif
-#endif
- ++cnt;
-}
-
-TEST(MemorySanitizer, sigaction) {
- struct sigaction act = {};
- struct sigaction oldact = {};
- struct sigaction origact = {};
-
- sigaction(SIGPROF, 0, &origact);
-
- act.sa_flags |= SA_SIGINFO;
- act.sa_sigaction = &SigactionHandler;
- sigaction(SIGPROF, &act, 0);
-
- kill(getpid(), SIGPROF);
-
- act.sa_flags &= ~SA_SIGINFO;
- act.sa_handler = SIG_DFL;
- sigaction(SIGPROF, &act, 0);
-
- act.sa_flags &= ~SA_SIGINFO;
- act.sa_handler = SIG_IGN;
- sigaction(SIGPROF, &act, &oldact);
- EXPECT_FALSE(oldact.sa_flags & SA_SIGINFO);
- EXPECT_EQ(SIG_DFL, oldact.sa_handler);
- kill(getpid(), SIGPROF);
-
- act.sa_flags |= SA_SIGINFO;
- act.sa_sigaction = &SigactionHandler;
- sigaction(SIGPROF, &act, &oldact);
- EXPECT_FALSE(oldact.sa_flags & SA_SIGINFO);
- EXPECT_EQ(SIG_IGN, oldact.sa_handler);
- kill(getpid(), SIGPROF);
-
- act.sa_flags &= ~SA_SIGINFO;
- act.sa_handler = SIG_DFL;
- sigaction(SIGPROF, &act, &oldact);
- EXPECT_TRUE(oldact.sa_flags & SA_SIGINFO);
- EXPECT_EQ(&SigactionHandler, oldact.sa_sigaction);
- EXPECT_EQ(2, cnt);
-
- sigaction(SIGPROF, &origact, 0);
-}
-
-} // namespace
-
-
-TEST(MemorySanitizer, sigemptyset) {
- sigset_t s;
- EXPECT_POISONED(s);
- int res = sigemptyset(&s);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(s);
-}
-
-TEST(MemorySanitizer, sigfillset) {
- sigset_t s;
- EXPECT_POISONED(s);
- int res = sigfillset(&s);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(s);
-}
-
-TEST(MemorySanitizer, sigpending) {
- sigset_t s;
- EXPECT_POISONED(s);
- int res = sigpending(&s);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(s);
-}
-
-TEST(MemorySanitizer, sigprocmask) {
- sigset_t s;
- EXPECT_POISONED(s);
- int res = sigprocmask(SIG_BLOCK, 0, &s);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(s);
-}
-
-struct StructWithDtor {
- ~StructWithDtor();
-};
-
-NOINLINE StructWithDtor::~StructWithDtor() {
- break_optimization(0);
-}
-
-TEST(MemorySanitizer, Invoke) {
- StructWithDtor s; // Will cause the calls to become invokes.
- EXPECT_NOT_POISONED(0);
- EXPECT_POISONED(*GetPoisoned<int>());
- EXPECT_NOT_POISONED(0);
- EXPECT_POISONED(*GetPoisoned<int>());
- EXPECT_POISONED(ReturnPoisoned<S4>());
-}
-
-TEST(MemorySanitizer, ptrtoint) {
- // Test that shadow is propagated through pointer-to-integer conversion.
- unsigned char c = 0;
- __msan_poison(&c, 1);
- uintptr_t u = (uintptr_t)c << 8;
- EXPECT_NOT_POISONED(u & 0xFF00FF);
- EXPECT_POISONED(u & 0xFF00);
-
- break_optimization(&u);
- void* p = (void*)u;
-
- break_optimization(&p);
- EXPECT_POISONED(p);
- EXPECT_NOT_POISONED(((uintptr_t)p) & 0xFF00FF);
- EXPECT_POISONED(((uintptr_t)p) & 0xFF00);
-}
-
-static void vaargsfn2(int guard, ...) {
- va_list vl;
- va_start(vl, guard);
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_POISONED(va_arg(vl, double));
- va_end(vl);
-}
-
-static void vaargsfn(int guard, ...) {
- va_list vl;
- va_start(vl, guard);
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_POISONED(va_arg(vl, int));
- // The following call will overwrite __msan_param_tls.
- // Checks after it test that arg shadow was somehow saved across the call.
- vaargsfn2(1, 2, 3, 4, *GetPoisoned<double>());
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_POISONED(va_arg(vl, int));
- va_end(vl);
-}
-
-TEST(MemorySanitizer, VAArgTest) {
- int* x = GetPoisoned<int>();
- int* y = GetPoisoned<int>(4);
- vaargsfn(1, 13, *x, 42, *y);
-}
-
-static void vaargsfn_many(int guard, ...) {
- va_list vl;
- va_start(vl, guard);
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_POISONED(va_arg(vl, int));
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_POISONED(va_arg(vl, int));
- va_end(vl);
-}
-
-TEST(MemorySanitizer, VAArgManyTest) {
- int* x = GetPoisoned<int>();
- int* y = GetPoisoned<int>(4);
- vaargsfn_many(1, 2, *x, 3, 4, 5, 6, 7, 8, 9, *y);
-}
-
-static void vaargsfn_manyfix(int g1, int g2, int g3, int g4, int g5, int g6, int g7, int g8, int g9, ...) {
- va_list vl;
- va_start(vl, g9);
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_POISONED(va_arg(vl, int));
- va_end(vl);
-}
-
-TEST(MemorySanitizer, VAArgManyFixTest) {
- int* x = GetPoisoned<int>();
- int* y = GetPoisoned<int>();
- vaargsfn_manyfix(1, *x, 3, 4, 5, 6, 7, 8, 9, 10, *y);
-}
-
-static void vaargsfn_pass2(va_list vl) {
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_POISONED(va_arg(vl, int));
-}
-
-static void vaargsfn_pass(int guard, ...) {
- va_list vl;
- va_start(vl, guard);
- EXPECT_POISONED(va_arg(vl, int));
- vaargsfn_pass2(vl);
- va_end(vl);
-}
-
-TEST(MemorySanitizer, VAArgPass) {
- int* x = GetPoisoned<int>();
- int* y = GetPoisoned<int>(4);
- vaargsfn_pass(1, *x, 2, 3, *y);
-}
-
-static void vaargsfn_copy2(va_list vl) {
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_POISONED(va_arg(vl, int));
-}
-
-static void vaargsfn_copy(int guard, ...) {
- va_list vl;
- va_start(vl, guard);
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_POISONED(va_arg(vl, int));
- va_list vl2;
- va_copy(vl2, vl);
- vaargsfn_copy2(vl2);
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_POISONED(va_arg(vl, int));
- va_end(vl);
-}
-
-TEST(MemorySanitizer, VAArgCopy) {
- int* x = GetPoisoned<int>();
- int* y = GetPoisoned<int>(4);
- vaargsfn_copy(1, 2, *x, 3, *y);
-}
-
-static void vaargsfn_ptr(int guard, ...) {
- va_list vl;
- va_start(vl, guard);
- EXPECT_NOT_POISONED(va_arg(vl, int*));
- EXPECT_POISONED(va_arg(vl, int*));
- EXPECT_NOT_POISONED(va_arg(vl, int*));
- EXPECT_POISONED(va_arg(vl, double*));
- va_end(vl);
-}
-
-TEST(MemorySanitizer, VAArgPtr) {
- int** x = GetPoisoned<int*>();
- double** y = GetPoisoned<double*>(8);
- int z;
- vaargsfn_ptr(1, &z, *x, &z, *y);
-}
-
-static void vaargsfn_overflow(int guard, ...) {
- va_list vl;
- va_start(vl, guard);
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_POISONED(va_arg(vl, int));
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_NOT_POISONED(va_arg(vl, int));
-
- EXPECT_NOT_POISONED(va_arg(vl, double));
- EXPECT_NOT_POISONED(va_arg(vl, double));
- EXPECT_NOT_POISONED(va_arg(vl, double));
- EXPECT_POISONED(va_arg(vl, double));
- EXPECT_NOT_POISONED(va_arg(vl, double));
- EXPECT_POISONED(va_arg(vl, int*));
- EXPECT_NOT_POISONED(va_arg(vl, double));
- EXPECT_NOT_POISONED(va_arg(vl, double));
-
- EXPECT_POISONED(va_arg(vl, int));
- EXPECT_POISONED(va_arg(vl, double));
- EXPECT_POISONED(va_arg(vl, int*));
-
- EXPECT_NOT_POISONED(va_arg(vl, int));
- EXPECT_NOT_POISONED(va_arg(vl, double));
- EXPECT_NOT_POISONED(va_arg(vl, int*));
-
- EXPECT_POISONED(va_arg(vl, int));
- EXPECT_POISONED(va_arg(vl, double));
- EXPECT_POISONED(va_arg(vl, int*));
-
- va_end(vl);
-}
-
-TEST(MemorySanitizer, VAArgOverflow) {
- int* x = GetPoisoned<int>();
- double* y = GetPoisoned<double>(8);
- int** p = GetPoisoned<int*>(16);
- int z;
- vaargsfn_overflow(1,
- 1, 2, *x, 4, 5, 6,
- 1.1, 2.2, 3.3, *y, 5.5, *p, 7.7, 8.8,
- // the following args will overflow for sure
- *x, *y, *p,
- 7, 9.9, &z,
- *x, *y, *p);
-}
-
-static void vaargsfn_tlsoverwrite2(int guard, ...) {
- va_list vl;
- va_start(vl, guard);
- for (int i = 0; i < 20; ++i)
- EXPECT_NOT_POISONED(va_arg(vl, int));
- va_end(vl);
-}
-
-static void vaargsfn_tlsoverwrite(int guard, ...) {
- // This call will overwrite TLS contents unless it's backed up somewhere.
- vaargsfn_tlsoverwrite2(2,
- 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42,
- 42, 42, 42, 42, 42); // 20x
- va_list vl;
- va_start(vl, guard);
- for (int i = 0; i < 20; ++i)
- EXPECT_POISONED(va_arg(vl, int));
- va_end(vl);
-}
-
-TEST(MemorySanitizer, VAArgTLSOverwrite) {
- int* x = GetPoisoned<int>();
- vaargsfn_tlsoverwrite(1,
- *x, *x, *x, *x, *x,
- *x, *x, *x, *x, *x,
- *x, *x, *x, *x, *x,
- *x, *x, *x, *x, *x); // 20x
-
-}
-
-struct StructByVal {
- int a, b, c, d, e, f;
-};
-
-static void vaargsfn_structbyval(int guard, ...) {
- va_list vl;
- va_start(vl, guard);
- {
- StructByVal s = va_arg(vl, StructByVal);
- EXPECT_NOT_POISONED(s.a);
- EXPECT_POISONED(s.b);
- EXPECT_NOT_POISONED(s.c);
- EXPECT_POISONED(s.d);
- EXPECT_NOT_POISONED(s.e);
- EXPECT_POISONED(s.f);
- }
- {
- StructByVal s = va_arg(vl, StructByVal);
- EXPECT_NOT_POISONED(s.a);
- EXPECT_POISONED(s.b);
- EXPECT_NOT_POISONED(s.c);
- EXPECT_POISONED(s.d);
- EXPECT_NOT_POISONED(s.e);
- EXPECT_POISONED(s.f);
- }
- va_end(vl);
-}
-
-TEST(MemorySanitizer, VAArgStructByVal) {
- StructByVal s;
- s.a = 1;
- s.b = *GetPoisoned<int>();
- s.c = 2;
- s.d = *GetPoisoned<int>();
- s.e = 3;
- s.f = *GetPoisoned<int>();
- vaargsfn_structbyval(0, s, s);
-}
-
-NOINLINE void StructByValTestFunc(struct StructByVal s) {
- EXPECT_NOT_POISONED(s.a);
- EXPECT_POISONED(s.b);
- EXPECT_NOT_POISONED(s.c);
- EXPECT_POISONED(s.d);
- EXPECT_NOT_POISONED(s.e);
- EXPECT_POISONED(s.f);
-}
-
-NOINLINE void StructByValTestFunc1(struct StructByVal s) {
- StructByValTestFunc(s);
-}
-
-NOINLINE void StructByValTestFunc2(int z, struct StructByVal s) {
- StructByValTestFunc(s);
-}
-
-TEST(MemorySanitizer, StructByVal) {
- // Large aggregates are passed as "byval" pointer argument in LLVM.
- struct StructByVal s;
- s.a = 1;
- s.b = *GetPoisoned<int>();
- s.c = 2;
- s.d = *GetPoisoned<int>();
- s.e = 3;
- s.f = *GetPoisoned<int>();
- StructByValTestFunc(s);
- StructByValTestFunc1(s);
- StructByValTestFunc2(0, s);
-}
-
-
-#if MSAN_HAS_M128
-NOINLINE __m128i m128Eq(__m128i *a, __m128i *b) { return _mm_cmpeq_epi16(*a, *b); }
-NOINLINE __m128i m128Lt(__m128i *a, __m128i *b) { return _mm_cmplt_epi16(*a, *b); }
-TEST(MemorySanitizer, m128) {
- __m128i a = _mm_set1_epi16(0x1234);
- __m128i b = _mm_set1_epi16(0x7890);
- EXPECT_NOT_POISONED(m128Eq(&a, &b));
- EXPECT_NOT_POISONED(m128Lt(&a, &b));
-}
-// FIXME: add more tests for __m128i.
-#endif // MSAN_HAS_M128
-
-// We should not complain when copying this poisoned hole.
-struct StructWithHole {
- U4 a;
- // 4-byte hole.
- U8 b;
-};
-
-NOINLINE StructWithHole ReturnStructWithHole() {
- StructWithHole res;
- __msan_poison(&res, sizeof(res));
- res.a = 1;
- res.b = 2;
- return res;
-}
-
-TEST(MemorySanitizer, StructWithHole) {
- StructWithHole a = ReturnStructWithHole();
- break_optimization(&a);
-}
-
-template <class T>
-NOINLINE T ReturnStruct() {
- T res;
- __msan_poison(&res, sizeof(res));
- res.a = 1;
- return res;
-}
-
-template <class T>
-NOINLINE void TestReturnStruct() {
- T s1 = ReturnStruct<T>();
- EXPECT_NOT_POISONED(s1.a);
- EXPECT_POISONED(s1.b);
-}
-
-struct SSS1 {
- int a, b, c;
-};
-struct SSS2 {
- int b, a, c;
-};
-struct SSS3 {
- int b, c, a;
-};
-struct SSS4 {
- int c, b, a;
-};
-
-struct SSS5 {
- int a;
- float b;
-};
-struct SSS6 {
- int a;
- double b;
-};
-struct SSS7 {
- S8 b;
- int a;
-};
-struct SSS8 {
- S2 b;
- S8 a;
-};
-
-TEST(MemorySanitizer, IntStruct3) {
- TestReturnStruct<SSS1>();
- TestReturnStruct<SSS2>();
- TestReturnStruct<SSS3>();
- TestReturnStruct<SSS4>();
- TestReturnStruct<SSS5>();
- TestReturnStruct<SSS6>();
- TestReturnStruct<SSS7>();
- TestReturnStruct<SSS8>();
-}
-
-struct LongStruct {
- U1 a1, b1;
- U2 a2, b2;
- U4 a4, b4;
- U8 a8, b8;
-};
-
-NOINLINE LongStruct ReturnLongStruct1() {
- LongStruct res;
- __msan_poison(&res, sizeof(res));
- res.a1 = res.a2 = res.a4 = res.a8 = 111;
- // leaves b1, .., b8 poisoned.
- return res;
-}
-
-NOINLINE LongStruct ReturnLongStruct2() {
- LongStruct res;
- __msan_poison(&res, sizeof(res));
- res.b1 = res.b2 = res.b4 = res.b8 = 111;
- // leaves a1, .., a8 poisoned.
- return res;
-}
-
-TEST(MemorySanitizer, LongStruct) {
- LongStruct s1 = ReturnLongStruct1();
- __msan_print_shadow(&s1, sizeof(s1));
- EXPECT_NOT_POISONED(s1.a1);
- EXPECT_NOT_POISONED(s1.a2);
- EXPECT_NOT_POISONED(s1.a4);
- EXPECT_NOT_POISONED(s1.a8);
-
- EXPECT_POISONED(s1.b1);
- EXPECT_POISONED(s1.b2);
- EXPECT_POISONED(s1.b4);
- EXPECT_POISONED(s1.b8);
-
- LongStruct s2 = ReturnLongStruct2();
- __msan_print_shadow(&s2, sizeof(s2));
- EXPECT_NOT_POISONED(s2.b1);
- EXPECT_NOT_POISONED(s2.b2);
- EXPECT_NOT_POISONED(s2.b4);
- EXPECT_NOT_POISONED(s2.b8);
-
- EXPECT_POISONED(s2.a1);
- EXPECT_POISONED(s2.a2);
- EXPECT_POISONED(s2.a4);
- EXPECT_POISONED(s2.a8);
-}
-
-#if defined(__FreeBSD__) || defined(__NetBSD__)
-#define MSAN_TEST_PRLIMIT 0
-#elif defined(__GLIBC__)
-#define MSAN_TEST_PRLIMIT __GLIBC_PREREQ(2, 13)
-#else
-#define MSAN_TEST_PRLIMIT 1
-#endif
-
-TEST(MemorySanitizer, getrlimit) {
- struct rlimit limit;
- __msan_poison(&limit, sizeof(limit));
- int result = getrlimit(RLIMIT_DATA, &limit);
- ASSERT_EQ(result, 0);
- EXPECT_NOT_POISONED(limit.rlim_cur);
- EXPECT_NOT_POISONED(limit.rlim_max);
-
-#if MSAN_TEST_PRLIMIT
- struct rlimit limit2;
- __msan_poison(&limit2, sizeof(limit2));
- result = prlimit(getpid(), RLIMIT_DATA, &limit, &limit2);
- ASSERT_EQ(result, 0);
- EXPECT_NOT_POISONED(limit2.rlim_cur);
- EXPECT_NOT_POISONED(limit2.rlim_max);
-
- __msan_poison(&limit, sizeof(limit));
- result = prlimit(getpid(), RLIMIT_DATA, nullptr, &limit);
- ASSERT_EQ(result, 0);
- EXPECT_NOT_POISONED(limit.rlim_cur);
- EXPECT_NOT_POISONED(limit.rlim_max);
-
- result = prlimit(getpid(), RLIMIT_DATA, &limit, nullptr);
- ASSERT_EQ(result, 0);
-#endif
-}
-
-TEST(MemorySanitizer, getrusage) {
- struct rusage usage;
- __msan_poison(&usage, sizeof(usage));
- int result = getrusage(RUSAGE_SELF, &usage);
- ASSERT_EQ(result, 0);
- EXPECT_NOT_POISONED(usage.ru_utime.tv_sec);
- EXPECT_NOT_POISONED(usage.ru_utime.tv_usec);
- EXPECT_NOT_POISONED(usage.ru_stime.tv_sec);
- EXPECT_NOT_POISONED(usage.ru_stime.tv_usec);
- EXPECT_NOT_POISONED(usage.ru_maxrss);
- EXPECT_NOT_POISONED(usage.ru_minflt);
- EXPECT_NOT_POISONED(usage.ru_majflt);
- EXPECT_NOT_POISONED(usage.ru_inblock);
- EXPECT_NOT_POISONED(usage.ru_oublock);
- EXPECT_NOT_POISONED(usage.ru_nvcsw);
- EXPECT_NOT_POISONED(usage.ru_nivcsw);
-}
-
-#if defined(__FreeBSD__) || defined(__NetBSD__)
-static void GetProgramPath(char *buf, size_t sz) {
-#if defined(__FreeBSD__)
- int mib[4] = { CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1 };
-#elif defined(__NetBSD__)
- int mib[4] = { CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME};
-#endif
- int res = sysctl(mib, 4, buf, &sz, NULL, 0);
- ASSERT_EQ(0, res);
-}
-#elif defined(__GLIBC__)
-static void GetProgramPath(char *buf, size_t sz) {
- extern char *program_invocation_name;
- int res = snprintf(buf, sz, "%s", program_invocation_name);
- ASSERT_GE(res, 0);
- ASSERT_LT((size_t)res, sz);
-}
-#else
-# error "TODO: port this"
-#endif
-
-static void dladdr_testfn() {}
-
-TEST(MemorySanitizer, dladdr) {
- Dl_info info;
- __msan_poison(&info, sizeof(info));
- int result = dladdr((const void*)dladdr_testfn, &info);
- ASSERT_NE(result, 0);
- EXPECT_NOT_POISONED((unsigned long)info.dli_fname);
- if (info.dli_fname)
- EXPECT_NOT_POISONED(strlen(info.dli_fname));
- EXPECT_NOT_POISONED((unsigned long)info.dli_fbase);
- EXPECT_NOT_POISONED((unsigned long)info.dli_sname);
- if (info.dli_sname)
- EXPECT_NOT_POISONED(strlen(info.dli_sname));
- EXPECT_NOT_POISONED((unsigned long)info.dli_saddr);
-}
-
-#ifndef MSAN_TEST_DISABLE_DLOPEN
-
-static int dl_phdr_callback(struct dl_phdr_info *info, size_t size, void *data) {
- (*(int *)data)++;
- EXPECT_NOT_POISONED(info->dlpi_addr);
- EXPECT_NOT_POISONED(strlen(info->dlpi_name));
- EXPECT_NOT_POISONED(info->dlpi_phnum);
- for (int i = 0; i < info->dlpi_phnum; ++i)
- EXPECT_NOT_POISONED(info->dlpi_phdr[i]);
- return 0;
-}
-
-// Compute the path to our loadable DSO. We assume it's in the same
-// directory. Only use string routines that we intercept so far to do this.
-static void GetPathToLoadable(char *buf, size_t sz) {
- char program_path[kMaxPathLength];
- GetProgramPath(program_path, sizeof(program_path));
-
- const char *last_slash = strrchr(program_path, '/');
- ASSERT_NE(nullptr, last_slash);
- size_t dir_len = (size_t)(last_slash - program_path);
-#if defined(__x86_64__)
- static const char basename[] = "libmsan_loadable.x86_64.so";
-#elif defined(__MIPSEB__) || defined(MIPSEB)
- static const char basename[] = "libmsan_loadable.mips64.so";
-#elif defined(__mips64)
- static const char basename[] = "libmsan_loadable.mips64el.so";
-#elif defined(__aarch64__)
- static const char basename[] = "libmsan_loadable.aarch64.so";
-#elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_BIG_ENDIAN__
- static const char basename[] = "libmsan_loadable.powerpc64.so";
-#elif defined(__powerpc64__) && __BYTE_ORDER__ == __ORDER_LITTLE_ENDIAN__
- static const char basename[] = "libmsan_loadable.powerpc64le.so";
-#endif
- int res = snprintf(buf, sz, "%.*s/%s",
- (int)dir_len, program_path, basename);
- ASSERT_GE(res, 0);
- ASSERT_LT((size_t)res, sz);
-}
-
-TEST(MemorySanitizer, dl_iterate_phdr) {
- char path[kMaxPathLength];
- GetPathToLoadable(path, sizeof(path));
-
- // Having at least one dlopen'ed library in the process makes this more
- // entertaining.
- void *lib = dlopen(path, RTLD_LAZY);
- ASSERT_NE((void*)0, lib);
-
- int count = 0;
- int result = dl_iterate_phdr(dl_phdr_callback, &count);
- ASSERT_GT(count, 0);
-
- dlclose(lib);
-}
-
-TEST(MemorySanitizer, dlopen) {
- char path[kMaxPathLength];
- GetPathToLoadable(path, sizeof(path));
-
- // We need to clear shadow for globals when doing dlopen. In order to test
- // this, we have to poison the shadow for the DSO before we load it. In
- // general this is difficult, but the loader tends to reload things in the
- // same place, so we open, close, and then reopen. The global should always
- // start out clean after dlopen.
- for (int i = 0; i < 2; i++) {
- void *lib = dlopen(path, RTLD_LAZY);
- if (lib == NULL) {
- printf("dlerror: %s\n", dlerror());
- ASSERT_TRUE(lib != NULL);
- }
- void **(*get_dso_global)() = (void **(*)())dlsym(lib, "get_dso_global");
- ASSERT_TRUE(get_dso_global != NULL);
- void **dso_global = get_dso_global();
- EXPECT_NOT_POISONED(*dso_global);
- __msan_poison(dso_global, sizeof(*dso_global));
- EXPECT_POISONED(*dso_global);
- dlclose(lib);
- }
-}
-
-// Regression test for a crash in dlopen() interceptor.
-TEST(MemorySanitizer, dlopenFailed) {
- const char *path = "/libmsan_loadable_does_not_exist.so";
- void *lib = dlopen(path, RTLD_LAZY);
- ASSERT_TRUE(lib == NULL);
-}
-
-#endif // MSAN_TEST_DISABLE_DLOPEN
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, sched_getaffinity) {
- cpu_set_t mask;
- int res = sched_getaffinity(getpid(), sizeof(mask), &mask);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(mask);
-}
-#endif
-
-TEST(MemorySanitizer, scanf) {
- const char *input = "42 hello";
- int* d = new int;
- char* s = new char[7];
- int res = sscanf(input, "%d %5s", d, s);
- printf("res %d\n", res);
- ASSERT_EQ(res, 2);
- EXPECT_NOT_POISONED(*d);
- EXPECT_NOT_POISONED(s[0]);
- EXPECT_NOT_POISONED(s[1]);
- EXPECT_NOT_POISONED(s[2]);
- EXPECT_NOT_POISONED(s[3]);
- EXPECT_NOT_POISONED(s[4]);
- EXPECT_NOT_POISONED(s[5]);
- EXPECT_POISONED(s[6]);
- delete[] s;
- delete d;
-}
-
-static void *SimpleThread_threadfn(void* data) {
- return new int;
-}
-
-TEST(MemorySanitizer, SimpleThread) {
- pthread_t t;
- void *p;
- int res = pthread_create(&t, NULL, SimpleThread_threadfn, NULL);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(t);
- res = pthread_join(t, &p);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(p);
- delete (int*)p;
-}
-
-static void *SmallStackThread_threadfn(void* data) {
- return 0;
-}
-
-#ifdef PTHREAD_STACK_MIN
-# define SMALLSTACKSIZE PTHREAD_STACK_MIN
-# define SMALLPRESTACKSIZE PTHREAD_STACK_MIN
-#else
-# define SMALLSTACKSIZE 64 * 1024
-# define SMALLPRESTACKSIZE 16 * 1024
-#endif
-
-TEST(MemorySanitizer, SmallStackThread) {
- pthread_attr_t attr;
- pthread_t t;
- void *p;
- int res;
- res = pthread_attr_init(&attr);
- ASSERT_EQ(0, res);
- res = pthread_attr_setstacksize(&attr, SMALLSTACKSIZE);
- ASSERT_EQ(0, res);
- res = pthread_create(&t, &attr, SmallStackThread_threadfn, NULL);
- ASSERT_EQ(0, res);
- res = pthread_join(t, &p);
- ASSERT_EQ(0, res);
- res = pthread_attr_destroy(&attr);
- ASSERT_EQ(0, res);
-}
-
-TEST(MemorySanitizer, SmallPreAllocatedStackThread) {
- pthread_attr_t attr;
- pthread_t t;
- int res;
- res = pthread_attr_init(&attr);
- ASSERT_EQ(0, res);
- void *stack;
- const size_t kStackSize = SMALLPRESTACKSIZE;
- res = posix_memalign(&stack, 4096, kStackSize);
- ASSERT_EQ(0, res);
- res = pthread_attr_setstack(&attr, stack, kStackSize);
- ASSERT_EQ(0, res);
- res = pthread_create(&t, &attr, SmallStackThread_threadfn, NULL);
- EXPECT_EQ(0, res);
- res = pthread_join(t, NULL);
- ASSERT_EQ(0, res);
- res = pthread_attr_destroy(&attr);
- ASSERT_EQ(0, res);
-}
-
-TEST(MemorySanitizer, pthread_attr_get) {
- pthread_attr_t attr;
- int res;
- res = pthread_attr_init(&attr);
- ASSERT_EQ(0, res);
- {
- int v;
- res = pthread_attr_getdetachstate(&attr, &v);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(v);
- }
- {
- size_t v;
- res = pthread_attr_getguardsize(&attr, &v);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(v);
- }
- {
- struct sched_param v;
- res = pthread_attr_getschedparam(&attr, &v);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(v);
- }
- {
- int v;
- res = pthread_attr_getschedpolicy(&attr, &v);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(v);
- }
- {
- int v;
- res = pthread_attr_getinheritsched(&attr, &v);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(v);
- }
- {
- int v;
- res = pthread_attr_getscope(&attr, &v);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(v);
- }
- {
- size_t v;
- res = pthread_attr_getstacksize(&attr, &v);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(v);
- }
- {
- void *v;
- size_t w;
- res = pthread_attr_getstack(&attr, &v, &w);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(v);
- EXPECT_NOT_POISONED(w);
- }
-#if !defined(__NetBSD__)
- {
- cpu_set_t v;
- res = pthread_attr_getaffinity_np(&attr, sizeof(v), &v);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(v);
- }
-#endif
- res = pthread_attr_destroy(&attr);
- ASSERT_EQ(0, res);
-}
-
-TEST(MemorySanitizer, pthread_getschedparam) {
- int policy;
- struct sched_param param;
- int res = pthread_getschedparam(pthread_self(), &policy, &param);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(policy);
- EXPECT_NOT_POISONED(param.sched_priority);
-}
-
-TEST(MemorySanitizer, pthread_key_create) {
- pthread_key_t key;
- int res = pthread_key_create(&key, NULL);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(key);
- res = pthread_key_delete(key);
- ASSERT_EQ(0, res);
-}
-
-namespace {
-struct SignalCondArg {
- pthread_cond_t* cond;
- pthread_mutex_t* mu;
- bool broadcast;
-};
-
-void *SignalCond(void *param) {
- SignalCondArg *arg = reinterpret_cast<SignalCondArg *>(param);
- pthread_mutex_lock(arg->mu);
- if (arg->broadcast)
- pthread_cond_broadcast(arg->cond);
- else
- pthread_cond_signal(arg->cond);
- pthread_mutex_unlock(arg->mu);
- return 0;
-}
-} // namespace
-
-TEST(MemorySanitizer, pthread_cond_wait) {
- pthread_cond_t cond;
- pthread_mutex_t mu;
- SignalCondArg args = {&cond, &mu, false};
- pthread_cond_init(&cond, 0);
- pthread_mutex_init(&mu, 0);
- pthread_mutex_lock(&mu);
-
- // signal
- pthread_t thr;
- pthread_create(&thr, 0, SignalCond, &args);
- int res = pthread_cond_wait(&cond, &mu);
- ASSERT_EQ(0, res);
- pthread_join(thr, 0);
-
- // broadcast
- args.broadcast = true;
- pthread_create(&thr, 0, SignalCond, &args);
- res = pthread_cond_wait(&cond, &mu);
- ASSERT_EQ(0, res);
- pthread_join(thr, 0);
-
- pthread_mutex_unlock(&mu);
- pthread_mutex_destroy(&mu);
- pthread_cond_destroy(&cond);
-}
-
-TEST(MemorySanitizer, tmpnam) {
- char s[L_tmpnam];
- char *res = tmpnam(s);
- ASSERT_EQ(s, res);
- EXPECT_NOT_POISONED(strlen(res));
-}
-
-TEST(MemorySanitizer, tempnam) {
- char *res = tempnam(NULL, "zzz");
- EXPECT_NOT_POISONED(strlen(res));
- free(res);
-}
-
-TEST(MemorySanitizer, posix_memalign) {
- void *p;
- EXPECT_POISONED(p);
- int res = posix_memalign(&p, 4096, 13);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(p);
- EXPECT_EQ(0U, (uintptr_t)p % 4096);
- free(p);
-}
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, memalign) {
- void *p = memalign(4096, 13);
- EXPECT_EQ(0U, (uintptr_t)p % 4096);
- free(p);
-}
-#endif
-
-TEST(MemorySanitizer, valloc) {
- void *a = valloc(100);
- uintptr_t PageSize = GetPageSize();
- EXPECT_EQ(0U, (uintptr_t)a % PageSize);
- free(a);
-}
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, pvalloc) {
- uintptr_t PageSize = GetPageSize();
- void *p = pvalloc(PageSize + 100);
- EXPECT_EQ(0U, (uintptr_t)p % PageSize);
- EXPECT_EQ(2 * PageSize, __sanitizer_get_allocated_size(p));
- free(p);
-
- p = pvalloc(0); // pvalloc(0) should allocate at least one page.
- EXPECT_EQ(0U, (uintptr_t)p % PageSize);
- EXPECT_EQ(PageSize, __sanitizer_get_allocated_size(p));
- free(p);
-}
-#endif
-
-TEST(MemorySanitizer, inet_pton) {
- const char *s = "1:0:0:0:0:0:0:8";
- unsigned char buf[sizeof(struct in6_addr)];
- int res = inet_pton(AF_INET6, s, buf);
- ASSERT_EQ(1, res);
- EXPECT_NOT_POISONED(buf[0]);
- EXPECT_NOT_POISONED(buf[sizeof(struct in6_addr) - 1]);
-
- char s_out[INET6_ADDRSTRLEN];
- EXPECT_POISONED(s_out[3]);
- const char *q = inet_ntop(AF_INET6, buf, s_out, INET6_ADDRSTRLEN);
- ASSERT_NE((void*)0, q);
- EXPECT_NOT_POISONED(s_out[3]);
-}
-
-TEST(MemorySanitizer, inet_aton) {
- const char *s = "127.0.0.1";
- struct in_addr in[2];
- int res = inet_aton(s, in);
- ASSERT_NE(0, res);
- EXPECT_NOT_POISONED(in[0]);
- EXPECT_POISONED(*(char *)(in + 1));
-}
-
-TEST(MemorySanitizer, uname) {
- struct utsname u;
- int res = uname(&u);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(strlen(u.sysname));
- EXPECT_NOT_POISONED(strlen(u.nodename));
- EXPECT_NOT_POISONED(strlen(u.release));
- EXPECT_NOT_POISONED(strlen(u.version));
- EXPECT_NOT_POISONED(strlen(u.machine));
-}
-
-TEST(MemorySanitizer, gethostname) {
- char buf[100];
- int res = gethostname(buf, 100);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(strlen(buf));
-}
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, sysinfo) {
- struct sysinfo info;
- int res = sysinfo(&info);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(info);
-}
-#endif
-
-TEST(MemorySanitizer, getpwuid) {
- struct passwd *p = getpwuid(0); // root
- ASSERT_TRUE(p != NULL);
- EXPECT_NOT_POISONED(p->pw_name);
- ASSERT_TRUE(p->pw_name != NULL);
- EXPECT_NOT_POISONED(p->pw_name[0]);
- EXPECT_NOT_POISONED(p->pw_uid);
- ASSERT_EQ(0U, p->pw_uid);
-}
-
-TEST(MemorySanitizer, getpwuid_r) {
- struct passwd pwd;
- struct passwd *pwdres;
- char buf[10000];
- int res = getpwuid_r(0, &pwd, buf, sizeof(buf), &pwdres);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(pwd.pw_name);
- ASSERT_TRUE(pwd.pw_name != NULL);
- EXPECT_NOT_POISONED(pwd.pw_name[0]);
- EXPECT_NOT_POISONED(pwd.pw_uid);
- ASSERT_EQ(0U, pwd.pw_uid);
- EXPECT_NOT_POISONED(pwdres);
-}
-
-TEST(MemorySanitizer, getpwnam_r) {
- struct passwd pwd;
- struct passwd *pwdres;
- char buf[10000];
- int res = getpwnam_r("root", &pwd, buf, sizeof(buf), &pwdres);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(pwd.pw_name);
- ASSERT_TRUE(pwd.pw_name != NULL);
- EXPECT_NOT_POISONED(pwd.pw_name[0]);
- EXPECT_NOT_POISONED(pwd.pw_uid);
- ASSERT_EQ(0U, pwd.pw_uid);
- EXPECT_NOT_POISONED(pwdres);
-}
-
-TEST(MemorySanitizer, getpwnam_r_positive) {
- struct passwd pwd;
- struct passwd *pwdres;
- char s[5];
- strncpy(s, "abcd", 5);
- __msan_poison(s, 5);
- char buf[10000];
- int res;
- EXPECT_UMR(res = getpwnam_r(s, &pwd, buf, sizeof(buf), &pwdres));
-}
-
-TEST(MemorySanitizer, getgrnam_r) {
- struct group grp;
- struct group *grpres;
- char buf[10000];
- int res = getgrnam_r(SUPERUSER_GROUP, &grp, buf, sizeof(buf), &grpres);
- ASSERT_EQ(0, res);
- // Note that getgrnam_r() returns 0 if the matching group is not found.
- ASSERT_NE(nullptr, grpres);
- EXPECT_NOT_POISONED(grp.gr_name);
- ASSERT_TRUE(grp.gr_name != NULL);
- EXPECT_NOT_POISONED(grp.gr_name[0]);
- EXPECT_NOT_POISONED(grp.gr_gid);
- EXPECT_NOT_POISONED(grpres);
-}
-
-TEST(MemorySanitizer, getpwent) {
- setpwent();
- struct passwd *p = getpwent();
- ASSERT_TRUE(p != NULL);
- EXPECT_NOT_POISONED(p->pw_name);
- ASSERT_TRUE(p->pw_name != NULL);
- EXPECT_NOT_POISONED(p->pw_name[0]);
- EXPECT_NOT_POISONED(p->pw_uid);
-}
-
-TEST(MemorySanitizer, getpwent_r) {
- struct passwd pwd;
- struct passwd *pwdres;
- char buf[10000];
- setpwent();
- int res = getpwent_r(&pwd, buf, sizeof(buf), &pwdres);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(pwd.pw_name);
- ASSERT_TRUE(pwd.pw_name != NULL);
- EXPECT_NOT_POISONED(pwd.pw_name[0]);
- EXPECT_NOT_POISONED(pwd.pw_uid);
- EXPECT_NOT_POISONED(pwdres);
-}
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, fgetpwent) {
- FILE *fp = fopen("/etc/passwd", "r");
- struct passwd *p = fgetpwent(fp);
- ASSERT_TRUE(p != NULL);
- EXPECT_NOT_POISONED(p->pw_name);
- ASSERT_TRUE(p->pw_name != NULL);
- EXPECT_NOT_POISONED(p->pw_name[0]);
- EXPECT_NOT_POISONED(p->pw_uid);
- fclose(fp);
-}
-#endif
-
-TEST(MemorySanitizer, getgrent) {
- setgrent();
- struct group *p = getgrent();
- ASSERT_TRUE(p != NULL);
- EXPECT_NOT_POISONED(p->gr_name);
- ASSERT_TRUE(p->gr_name != NULL);
- EXPECT_NOT_POISONED(p->gr_name[0]);
- EXPECT_NOT_POISONED(p->gr_gid);
-}
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, fgetgrent) {
- FILE *fp = fopen("/etc/group", "r");
- struct group *grp = fgetgrent(fp);
- ASSERT_TRUE(grp != NULL);
- EXPECT_NOT_POISONED(grp->gr_name);
- ASSERT_TRUE(grp->gr_name != NULL);
- EXPECT_NOT_POISONED(grp->gr_name[0]);
- EXPECT_NOT_POISONED(grp->gr_gid);
- for (char **p = grp->gr_mem; *p; ++p) {
- EXPECT_NOT_POISONED((*p)[0]);
- EXPECT_TRUE(strlen(*p) > 0);
- }
- fclose(fp);
-}
-#endif
-
-TEST(MemorySanitizer, getgrent_r) {
- struct group grp;
- struct group *grpres;
- char buf[10000];
- setgrent();
- int res = getgrent_r(&grp, buf, sizeof(buf), &grpres);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(grp.gr_name);
- ASSERT_TRUE(grp.gr_name != NULL);
- EXPECT_NOT_POISONED(grp.gr_name[0]);
- EXPECT_NOT_POISONED(grp.gr_gid);
- EXPECT_NOT_POISONED(grpres);
-}
-
-#if !defined(__FreeBSD__) && !defined(__NetBSD__)
-TEST(MemorySanitizer, fgetgrent_r) {
- FILE *fp = fopen("/etc/group", "r");
- struct group grp;
- struct group *grpres;
- char buf[10000];
- setgrent();
- int res = fgetgrent_r(fp, &grp, buf, sizeof(buf), &grpres);
- ASSERT_EQ(0, res);
- EXPECT_NOT_POISONED(grp.gr_name);
- ASSERT_TRUE(grp.gr_name != NULL);
- EXPECT_NOT_POISONED(grp.gr_name[0]);
- EXPECT_NOT_POISONED(grp.gr_gid);
- EXPECT_NOT_POISONED(grpres);
- fclose(fp);
-}
-#endif
-
-TEST(MemorySanitizer, getgroups) {
- int n = getgroups(0, 0);
- gid_t *gids = new gid_t[n];
- int res = getgroups(n, gids);
- ASSERT_EQ(n, res);
- for (int i = 0; i < n; ++i)
- EXPECT_NOT_POISONED(gids[i]);
-}
-
-TEST(MemorySanitizer, getgroups_zero) {
- gid_t group;
- int n = getgroups(0, &group);
- ASSERT_GE(n, 0);
-}
-
-TEST(MemorySanitizer, getgroups_negative) {
- gid_t group;
- int n = getgroups(-1, 0);
- ASSERT_EQ(-1, n);
-
- n = getgroups(-1, 0);
- ASSERT_EQ(-1, n);
-}
-
-TEST(MemorySanitizer, wordexp) {
- wordexp_t w;
- int res = wordexp("a b c", &w, 0);
- ASSERT_EQ(0, res);
- ASSERT_EQ(3U, w.we_wordc);
- ASSERT_STREQ("a", w.we_wordv[0]);
- ASSERT_STREQ("b", w.we_wordv[1]);
- ASSERT_STREQ("c", w.we_wordv[2]);
-}
-
-template<class T>
-static bool applySlt(T value, T shadow) {
- __msan_partial_poison(&value, &shadow, sizeof(T));
- volatile bool zzz = true;
- // This "|| zzz" trick somehow makes LLVM emit "icmp slt" instead of
- // a shift-and-trunc to get at the highest bit.
- volatile bool v = value < 0 || zzz;
- return v;
-}
-
-TEST(MemorySanitizer, SignedCompareWithZero) {
- EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0xF));
- EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0xFF));
- EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0xFFFFFF));
- EXPECT_NOT_POISONED(applySlt<S4>(0xF, 0x7FFFFFF));
- EXPECT_UMR(applySlt<S4>(0xF, 0x80FFFFFF));
- EXPECT_UMR(applySlt<S4>(0xF, 0xFFFFFFFF));
-}
-
-template <class T, class S>
-static T poisoned(T Va, S Sa) {
- char SIZE_CHECK1[(ssize_t)sizeof(T) - (ssize_t)sizeof(S)];
- char SIZE_CHECK2[(ssize_t)sizeof(S) - (ssize_t)sizeof(T)];
- T a;
- a = Va;
- __msan_partial_poison(&a, &Sa, sizeof(T));
- return a;
-}
-
-TEST(MemorySanitizer, ICmpRelational) {
- EXPECT_NOT_POISONED(poisoned(0, 0) < poisoned(0, 0));
- EXPECT_NOT_POISONED(poisoned(0U, 0) < poisoned(0U, 0));
- EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) < poisoned(0LL, 0LLU));
- EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) < poisoned(0LLU, 0LLU));
- EXPECT_POISONED(poisoned(0xFF, 0xFF) < poisoned(0xFF, 0xFF));
- EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) <
- poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));
- EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) <
- poisoned(-1, 0xFFFFFFFFU));
-
- EXPECT_NOT_POISONED(poisoned(0, 0) <= poisoned(0, 0));
- EXPECT_NOT_POISONED(poisoned(0U, 0) <= poisoned(0U, 0));
- EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) <= poisoned(0LL, 0LLU));
- EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) <= poisoned(0LLU, 0LLU));
- EXPECT_POISONED(poisoned(0xFF, 0xFF) <= poisoned(0xFF, 0xFF));
- EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) <=
- poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));
- EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) <=
- poisoned(-1, 0xFFFFFFFFU));
-
- EXPECT_NOT_POISONED(poisoned(0, 0) > poisoned(0, 0));
- EXPECT_NOT_POISONED(poisoned(0U, 0) > poisoned(0U, 0));
- EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) > poisoned(0LL, 0LLU));
- EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) > poisoned(0LLU, 0LLU));
- EXPECT_POISONED(poisoned(0xFF, 0xFF) > poisoned(0xFF, 0xFF));
- EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) >
- poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));
- EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) >
- poisoned(-1, 0xFFFFFFFFU));
-
- EXPECT_NOT_POISONED(poisoned(0, 0) >= poisoned(0, 0));
- EXPECT_NOT_POISONED(poisoned(0U, 0) >= poisoned(0U, 0));
- EXPECT_NOT_POISONED(poisoned(0LL, 0LLU) >= poisoned(0LL, 0LLU));
- EXPECT_NOT_POISONED(poisoned(0LLU, 0LLU) >= poisoned(0LLU, 0LLU));
- EXPECT_POISONED(poisoned(0xFF, 0xFF) >= poisoned(0xFF, 0xFF));
- EXPECT_POISONED(poisoned(0xFFFFFFFFU, 0xFFFFFFFFU) >=
- poisoned(0xFFFFFFFFU, 0xFFFFFFFFU));
- EXPECT_POISONED(poisoned(-1, 0xFFFFFFFFU) >=
- poisoned(-1, 0xFFFFFFFFU));
-
- EXPECT_POISONED(poisoned(6, 0xF) > poisoned(7, 0));
- EXPECT_POISONED(poisoned(0xF, 0xF) > poisoned(7, 0));
- // Note that "icmp op X, Y" is approximated with "or shadow(X), shadow(Y)"
- // and therefore may generate false positives in some cases, e.g. the
- // following one:
- // EXPECT_NOT_POISONED(poisoned(-1, 0x80000000U) >= poisoned(-1, 0U));
-}
-
-#if MSAN_HAS_M128
-TEST(MemorySanitizer, ICmpVectorRelational) {
- EXPECT_NOT_POISONED(
- _mm_cmplt_epi16(poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0)),
- poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0))));
- EXPECT_NOT_POISONED(
- _mm_cmplt_epi16(poisoned(_mm_set1_epi32(0), _mm_set1_epi32(0)),
- poisoned(_mm_set1_epi32(0), _mm_set1_epi32(0))));
- EXPECT_POISONED(
- _mm_cmplt_epi16(poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0xFFFF)),
- poisoned(_mm_set1_epi16(0), _mm_set1_epi16(0xFFFF))));
- EXPECT_POISONED(_mm_cmpgt_epi16(poisoned(_mm_set1_epi16(6), _mm_set1_epi16(0xF)),
- poisoned(_mm_set1_epi16(7), _mm_set1_epi16(0))));
-}
-
-TEST(MemorySanitizer, stmxcsr_ldmxcsr) {
- U4 x = _mm_getcsr();
- EXPECT_NOT_POISONED(x);
-
- _mm_setcsr(x);
-
- __msan_poison(&x, sizeof(x));
- U4 origin = __LINE__;
- __msan_set_origin(&x, sizeof(x), origin);
- EXPECT_UMR_O(_mm_setcsr(x), origin);
-}
-#endif
-
-// Volatile bitfield store is implemented as load-mask-store
-// Test that we don't warn on the store of (uninitialized) padding.
-struct VolatileBitfieldStruct {
- volatile unsigned x : 1;
- unsigned y : 1;
-};
-
-TEST(MemorySanitizer, VolatileBitfield) {
- VolatileBitfieldStruct *S = new VolatileBitfieldStruct;
- S->x = 1;
- EXPECT_NOT_POISONED((unsigned)S->x);
- EXPECT_POISONED((unsigned)S->y);
-}
-
-TEST(MemorySanitizer, UnalignedLoad) {
- char x[32] __attribute__((aligned(8)));
- U4 origin = __LINE__;
- for (unsigned i = 0; i < sizeof(x) / 4; ++i)
- __msan_set_origin(x + 4 * i, 4, origin + i);
-
- memset(x + 8, 0, 16);
- EXPECT_POISONED_O(__sanitizer_unaligned_load16(x + 6), origin + 1);
- EXPECT_POISONED_O(__sanitizer_unaligned_load16(x + 7), origin + 1);
- EXPECT_NOT_POISONED(__sanitizer_unaligned_load16(x + 8));
- EXPECT_NOT_POISONED(__sanitizer_unaligned_load16(x + 9));
- EXPECT_NOT_POISONED(__sanitizer_unaligned_load16(x + 22));
- EXPECT_POISONED_O(__sanitizer_unaligned_load16(x + 23), origin + 6);
- EXPECT_POISONED_O(__sanitizer_unaligned_load16(x + 24), origin + 6);
-
- EXPECT_POISONED_O(__sanitizer_unaligned_load32(x + 4), origin + 1);
- EXPECT_POISONED_O(__sanitizer_unaligned_load32(x + 7), origin + 1);
- EXPECT_NOT_POISONED(__sanitizer_unaligned_load32(x + 8));
- EXPECT_NOT_POISONED(__sanitizer_unaligned_load32(x + 9));
- EXPECT_NOT_POISONED(__sanitizer_unaligned_load32(x + 20));
- EXPECT_POISONED_O(__sanitizer_unaligned_load32(x + 21), origin + 6);
- EXPECT_POISONED_O(__sanitizer_unaligned_load32(x + 24), origin + 6);
-
- EXPECT_POISONED_O(__sanitizer_unaligned_load64(x), origin);
- EXPECT_POISONED_O(__sanitizer_unaligned_load64(x + 1), origin);
- EXPECT_POISONED_O(__sanitizer_unaligned_load64(x + 7), origin + 1);
- EXPECT_NOT_POISONED(__sanitizer_unaligned_load64(x + 8));
- EXPECT_NOT_POISONED(__sanitizer_unaligned_load64(x + 9));
- EXPECT_NOT_POISONED(__sanitizer_unaligned_load64(x + 16));
- EXPECT_POISONED_O(__sanitizer_unaligned_load64(x + 17), origin + 6);
- EXPECT_POISONED_O(__sanitizer_unaligned_load64(x + 21), origin + 6);
- EXPECT_POISONED_O(__sanitizer_unaligned_load64(x + 24), origin + 6);
-}
-
-TEST(MemorySanitizer, UnalignedStore16) {
- char x[5] __attribute__((aligned(4)));
- U2 y2 = 0;
- U4 origin = __LINE__;
- __msan_poison(&y2, 1);
- __msan_set_origin(&y2, 1, origin);
-
- __sanitizer_unaligned_store16(x + 1, y2);
- EXPECT_POISONED_O(x[0], origin);
- EXPECT_POISONED_O(x[1], origin);
- EXPECT_NOT_POISONED(x[2]);
- EXPECT_POISONED_O(x[3], origin);
-}
-
-TEST(MemorySanitizer, UnalignedStore32) {
- char x[8] __attribute__((aligned(4)));
- U4 y4 = 0;
- U4 origin = __LINE__;
- __msan_poison(&y4, 2);
- __msan_set_origin(&y4, 2, origin);
-
- __sanitizer_unaligned_store32(x + 3, y4);
- EXPECT_POISONED_O(x[0], origin);
- EXPECT_POISONED_O(x[1], origin);
- EXPECT_POISONED_O(x[2], origin);
- EXPECT_POISONED_O(x[3], origin);
- EXPECT_POISONED_O(x[4], origin);
- EXPECT_NOT_POISONED(x[5]);
- EXPECT_NOT_POISONED(x[6]);
- EXPECT_POISONED_O(x[7], origin);
-}
-
-TEST(MemorySanitizer, UnalignedStore64) {
- char x[16] __attribute__((aligned(8)));
- U8 y8 = 0;
- U4 origin = __LINE__;
- __msan_poison(&y8, 3);
- __msan_poison(((char *)&y8) + sizeof(y8) - 2, 1);
- __msan_set_origin(&y8, 8, origin);
-
- __sanitizer_unaligned_store64(x + 3, y8);
- EXPECT_POISONED_O(x[0], origin);
- EXPECT_POISONED_O(x[1], origin);
- EXPECT_POISONED_O(x[2], origin);
- EXPECT_POISONED_O(x[3], origin);
- EXPECT_POISONED_O(x[4], origin);
- EXPECT_POISONED_O(x[5], origin);
- EXPECT_NOT_POISONED(x[6]);
- EXPECT_NOT_POISONED(x[7]);
- EXPECT_NOT_POISONED(x[8]);
- EXPECT_POISONED_O(x[9], origin);
- EXPECT_NOT_POISONED(x[10]);
- EXPECT_POISONED_O(x[11], origin);
-}
-
-TEST(MemorySanitizer, UnalignedStore16_precise) {
- char x[8] __attribute__((aligned(4)));
- U2 y = 0;
- U4 originx1 = __LINE__;
- U4 originx2 = __LINE__;
- U4 originy = __LINE__;
- __msan_poison(x, sizeof(x));
- __msan_set_origin(x, 4, originx1);
- __msan_set_origin(x + 4, 4, originx2);
- __msan_poison(((char *)&y) + 1, 1);
- __msan_set_origin(&y, sizeof(y), originy);
-
- __sanitizer_unaligned_store16(x + 3, y);
- EXPECT_POISONED_O(x[0], originx1);
- EXPECT_POISONED_O(x[1], originx1);
- EXPECT_POISONED_O(x[2], originx1);
- EXPECT_NOT_POISONED(x[3]);
- EXPECT_POISONED_O(x[4], originy);
- EXPECT_POISONED_O(x[5], originy);
- EXPECT_POISONED_O(x[6], originy);
- EXPECT_POISONED_O(x[7], originy);
-}
-
-TEST(MemorySanitizer, UnalignedStore16_precise2) {
- char x[8] __attribute__((aligned(4)));
- U2 y = 0;
- U4 originx1 = __LINE__;
- U4 originx2 = __LINE__;
- U4 originy = __LINE__;
- __msan_poison(x, sizeof(x));
- __msan_set_origin(x, 4, originx1);
- __msan_set_origin(x + 4, 4, originx2);
- __msan_poison(((char *)&y), 1);
- __msan_set_origin(&y, sizeof(y), originy);
-
- __sanitizer_unaligned_store16(x + 3, y);
- EXPECT_POISONED_O(x[0], originy);
- EXPECT_POISONED_O(x[1], originy);
- EXPECT_POISONED_O(x[2], originy);
- EXPECT_POISONED_O(x[3], originy);
- EXPECT_NOT_POISONED(x[4]);
- EXPECT_POISONED_O(x[5], originx2);
- EXPECT_POISONED_O(x[6], originx2);
- EXPECT_POISONED_O(x[7], originx2);
-}
-
-TEST(MemorySanitizer, UnalignedStore64_precise) {
- char x[12] __attribute__((aligned(8)));
- U8 y = 0;
- U4 originx1 = __LINE__;
- U4 originx2 = __LINE__;
- U4 originx3 = __LINE__;
- U4 originy = __LINE__;
- __msan_poison(x, sizeof(x));
- __msan_set_origin(x, 4, originx1);
- __msan_set_origin(x + 4, 4, originx2);
- __msan_set_origin(x + 8, 4, originx3);
- __msan_poison(((char *)&y) + 1, 1);
- __msan_poison(((char *)&y) + 7, 1);
- __msan_set_origin(&y, sizeof(y), originy);
-
- __sanitizer_unaligned_store64(x + 2, y);
- EXPECT_POISONED_O(x[0], originy);
- EXPECT_POISONED_O(x[1], originy);
- EXPECT_NOT_POISONED(x[2]);
- EXPECT_POISONED_O(x[3], originy);
-
- EXPECT_NOT_POISONED(x[4]);
- EXPECT_NOT_POISONED(x[5]);
- EXPECT_NOT_POISONED(x[6]);
- EXPECT_NOT_POISONED(x[7]);
-
- EXPECT_NOT_POISONED(x[8]);
- EXPECT_POISONED_O(x[9], originy);
- EXPECT_POISONED_O(x[10], originy);
- EXPECT_POISONED_O(x[11], originy);
-}
-
-TEST(MemorySanitizer, UnalignedStore64_precise2) {
- char x[12] __attribute__((aligned(8)));
- U8 y = 0;
- U4 originx1 = __LINE__;
- U4 originx2 = __LINE__;
- U4 originx3 = __LINE__;
- U4 originy = __LINE__;
- __msan_poison(x, sizeof(x));
- __msan_set_origin(x, 4, originx1);
- __msan_set_origin(x + 4, 4, originx2);
- __msan_set_origin(x + 8, 4, originx3);
- __msan_poison(((char *)&y) + 3, 3);
- __msan_set_origin(&y, sizeof(y), originy);
-
- __sanitizer_unaligned_store64(x + 2, y);
- EXPECT_POISONED_O(x[0], originx1);
- EXPECT_POISONED_O(x[1], originx1);
- EXPECT_NOT_POISONED(x[2]);
- EXPECT_NOT_POISONED(x[3]);
-
- EXPECT_NOT_POISONED(x[4]);
- EXPECT_POISONED_O(x[5], originy);
- EXPECT_POISONED_O(x[6], originy);
- EXPECT_POISONED_O(x[7], originy);
-
- EXPECT_NOT_POISONED(x[8]);
- EXPECT_NOT_POISONED(x[9]);
- EXPECT_POISONED_O(x[10], originx3);
- EXPECT_POISONED_O(x[11], originx3);
-}
-
-#if (defined(__x86_64__) && defined(__clang__))
-namespace {
-typedef U1 V16x8 __attribute__((__vector_size__(16)));
-typedef U2 V8x16 __attribute__((__vector_size__(16)));
-typedef U4 V4x32 __attribute__((__vector_size__(16)));
-typedef U8 V2x64 __attribute__((__vector_size__(16)));
-typedef U4 V8x32 __attribute__((__vector_size__(32)));
-typedef U8 V4x64 __attribute__((__vector_size__(32)));
-typedef U4 V2x32 __attribute__((__vector_size__(8)));
-typedef U2 V4x16 __attribute__((__vector_size__(8)));
-typedef U1 V8x8 __attribute__((__vector_size__(8)));
-
-V8x16 shift_sse2_left_scalar(V8x16 x, U4 y) {
- return _mm_slli_epi16(x, y);
-}
-
-V8x16 shift_sse2_left(V8x16 x, V8x16 y) {
- return _mm_sll_epi16(x, y);
-}
-
-TEST(VectorShiftTest, sse2_left_scalar) {
- V8x16 v = {Poisoned<U2>(0, 3), Poisoned<U2>(0, 7), 2, 3, 4, 5, 6, 7};
- V8x16 u = shift_sse2_left_scalar(v, 2);
- EXPECT_POISONED(u[0]);
- EXPECT_POISONED(u[1]);
- EXPECT_NOT_POISONED(u[0] | (3U << 2));
- EXPECT_NOT_POISONED(u[1] | (7U << 2));
- u[0] = u[1] = 0;
- EXPECT_NOT_POISONED(u);
-}
-
-TEST(VectorShiftTest, sse2_left_scalar_by_uninit) {
- V8x16 v = {0, 1, 2, 3, 4, 5, 6, 7};
- V8x16 u = shift_sse2_left_scalar(v, Poisoned<U4>());
- EXPECT_POISONED(u[0]);
- EXPECT_POISONED(u[1]);
- EXPECT_POISONED(u[2]);
- EXPECT_POISONED(u[3]);
- EXPECT_POISONED(u[4]);
- EXPECT_POISONED(u[5]);
- EXPECT_POISONED(u[6]);
- EXPECT_POISONED(u[7]);
-}
-
-TEST(VectorShiftTest, sse2_left) {
- V8x16 v = {Poisoned<U2>(0, 3), Poisoned<U2>(0, 7), 2, 3, 4, 5, 6, 7};
- // Top 64 bits of shift count don't affect the result.
- V2x64 s = {2, Poisoned<U8>()};
- V8x16 u = shift_sse2_left(v, s);
- EXPECT_POISONED(u[0]);
- EXPECT_POISONED(u[1]);
- EXPECT_NOT_POISONED(u[0] | (3U << 2));
- EXPECT_NOT_POISONED(u[1] | (7U << 2));
- u[0] = u[1] = 0;
- EXPECT_NOT_POISONED(u);
-}
-
-TEST(VectorShiftTest, sse2_left_by_uninit) {
- V8x16 v = {Poisoned<U2>(0, 3), Poisoned<U2>(0, 7), 2, 3, 4, 5, 6, 7};
- V2x64 s = {Poisoned<U8>(), Poisoned<U8>()};
- V8x16 u = shift_sse2_left(v, s);
- EXPECT_POISONED(u[0]);
- EXPECT_POISONED(u[1]);
- EXPECT_POISONED(u[2]);
- EXPECT_POISONED(u[3]);
- EXPECT_POISONED(u[4]);
- EXPECT_POISONED(u[5]);
- EXPECT_POISONED(u[6]);
- EXPECT_POISONED(u[7]);
-}
-
-#ifdef __AVX2__
-V4x32 shift_avx2_left(V4x32 x, V4x32 y) {
- return _mm_sllv_epi32(x, y);
-}
-// This is variable vector shift that's only available starting with AVX2.
-// V4x32 shift_avx2_left(V4x32 x, V4x32 y) {
-TEST(VectorShiftTest, avx2_left) {
- V4x32 v = {Poisoned<U2>(0, 3), Poisoned<U2>(0, 7), 2, 3};
- V4x32 s = {2, Poisoned<U4>(), 3, Poisoned<U4>()};
- V4x32 u = shift_avx2_left(v, s);
- EXPECT_POISONED(u[0]);
- EXPECT_NOT_POISONED(u[0] | (~7U));
- EXPECT_POISONED(u[1]);
- EXPECT_POISONED(u[1] | (~31U));
- EXPECT_NOT_POISONED(u[2]);
- EXPECT_POISONED(u[3]);
- EXPECT_POISONED(u[3] | (~31U));
-}
-#endif // __AVX2__
-} // namespace
-
-TEST(VectorPackTest, sse2_packssdw_128) {
- const unsigned S2_max = (1 << 15) - 1;
- V4x32 a = {Poisoned<U4>(0, 0xFF0000), Poisoned<U4>(0, 0xFFFF0000),
- S2_max + 100, 4};
- V4x32 b = {Poisoned<U4>(0, 0xFF), S2_max + 10000, Poisoned<U4>(0, 0xFF00),
- S2_max};
-
- V8x16 c = _mm_packs_epi32(a, b);
-
- EXPECT_POISONED(c[0]);
- EXPECT_POISONED(c[1]);
- EXPECT_NOT_POISONED(c[2]);
- EXPECT_NOT_POISONED(c[3]);
- EXPECT_POISONED(c[4]);
- EXPECT_NOT_POISONED(c[5]);
- EXPECT_POISONED(c[6]);
- EXPECT_NOT_POISONED(c[7]);
-
- EXPECT_EQ(c[2], S2_max);
- EXPECT_EQ(c[3], 4);
- EXPECT_EQ(c[5], S2_max);
- EXPECT_EQ(c[7], S2_max);
-}
-
-TEST(VectorPackTest, mmx_packuswb) {
- const unsigned U1_max = (1 << 8) - 1;
- V4x16 a = {Poisoned<U2>(0, 0xFF00), Poisoned<U2>(0, 0xF000U), U1_max + 100,
- 4};
- V4x16 b = {Poisoned<U2>(0, 0xFF), U1_max - 1, Poisoned<U2>(0, 0xF), U1_max};
- V8x8 c = _mm_packs_pu16(a, b);
-
- EXPECT_POISONED(c[0]);
- EXPECT_POISONED(c[1]);
- EXPECT_NOT_POISONED(c[2]);
- EXPECT_NOT_POISONED(c[3]);
- EXPECT_POISONED(c[4]);
- EXPECT_NOT_POISONED(c[5]);
- EXPECT_POISONED(c[6]);
- EXPECT_NOT_POISONED(c[7]);
-
- EXPECT_EQ(c[2], U1_max);
- EXPECT_EQ(c[3], 4);
- EXPECT_EQ(c[5], U1_max - 1);
- EXPECT_EQ(c[7], U1_max);
-}
-
-TEST(VectorSadTest, sse2_psad_bw) {
- V16x8 a = {Poisoned<U1>(), 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13, 14, 15};
- V16x8 b = {100, 101, 102, 103, 104, 105, 106, 107,
- 108, 109, 110, 111, 112, 113, 114, 115};
- V2x64 c = _mm_sad_epu8(a, b);
-
- EXPECT_POISONED(c[0]);
- EXPECT_NOT_POISONED(c[1]);
-
- EXPECT_EQ(800U, c[1]);
-}
-
-TEST(VectorMaddTest, mmx_pmadd_wd) {
- V4x16 a = {Poisoned<U2>(), 1, 2, 3};
- V4x16 b = {100, 101, 102, 103};
- V2x32 c = _mm_madd_pi16(a, b);
-
- EXPECT_POISONED(c[0]);
- EXPECT_NOT_POISONED(c[1]);
-
- EXPECT_EQ((unsigned)(2 * 102 + 3 * 103), c[1]);
-}
-
-TEST(VectorCmpTest, mm_cmpneq_ps) {
- V4x32 c;
- c = _mm_cmpneq_ps(V4x32{Poisoned<U4>(), 1, 2, 3}, V4x32{4, 5, Poisoned<U4>(), 6});
- EXPECT_POISONED(c[0]);
- EXPECT_NOT_POISONED(c[1]);
- EXPECT_POISONED(c[2]);
- EXPECT_NOT_POISONED(c[3]);
-
- c = _mm_cmpneq_ps(V4x32{0, 1, 2, 3}, V4x32{4, 5, 6, 7});
- EXPECT_NOT_POISONED(c);
-}
-
-TEST(VectorCmpTest, mm_cmpneq_sd) {
- V2x64 c;
- c = _mm_cmpneq_sd(V2x64{Poisoned<U8>(), 1}, V2x64{2, 3});
- EXPECT_POISONED(c[0]);
- c = _mm_cmpneq_sd(V2x64{1, 2}, V2x64{Poisoned<U8>(), 3});
- EXPECT_POISONED(c[0]);
- c = _mm_cmpneq_sd(V2x64{1, 2}, V2x64{3, 4});
- EXPECT_NOT_POISONED(c[0]);
- c = _mm_cmpneq_sd(V2x64{1, Poisoned<U8>()}, V2x64{2, Poisoned<U8>()});
- EXPECT_NOT_POISONED(c[0]);
- c = _mm_cmpneq_sd(V2x64{1, Poisoned<U8>()}, V2x64{1, Poisoned<U8>()});
- EXPECT_NOT_POISONED(c[0]);
-}
-
-TEST(VectorCmpTest, builtin_ia32_ucomisdlt) {
- U4 c;
- c = __builtin_ia32_ucomisdlt(V2x64{Poisoned<U8>(), 1}, V2x64{2, 3});
- EXPECT_POISONED(c);
- c = __builtin_ia32_ucomisdlt(V2x64{1, 2}, V2x64{Poisoned<U8>(), 3});
- EXPECT_POISONED(c);
- c = __builtin_ia32_ucomisdlt(V2x64{1, 2}, V2x64{3, 4});
- EXPECT_NOT_POISONED(c);
- c = __builtin_ia32_ucomisdlt(V2x64{1, Poisoned<U8>()}, V2x64{2, Poisoned<U8>()});
- EXPECT_NOT_POISONED(c);
- c = __builtin_ia32_ucomisdlt(V2x64{1, Poisoned<U8>()}, V2x64{1, Poisoned<U8>()});
- EXPECT_NOT_POISONED(c);
-}
-
-#endif // defined(__x86_64__) && defined(__clang__)
-
-TEST(MemorySanitizerOrigins, SetGet) {
- EXPECT_EQ(TrackingOrigins(), !!__msan_get_track_origins());
- if (!TrackingOrigins()) return;
- int x;
- __msan_set_origin(&x, sizeof(x), 1234);
- EXPECT_ORIGIN(1234U, __msan_get_origin(&x));
- __msan_set_origin(&x, sizeof(x), 5678);
- EXPECT_ORIGIN(5678U, __msan_get_origin(&x));
- __msan_set_origin(&x, sizeof(x), 0);
- EXPECT_ORIGIN(0U, __msan_get_origin(&x));
-}
-
-namespace {
-struct S {
- U4 dummy;
- U2 a;
- U2 b;
-};
-
-TEST(MemorySanitizerOrigins, InitializedStoreDoesNotChangeOrigin) {
- if (!TrackingOrigins()) return;
-
- S s;
- U4 origin = rand(); // NOLINT
- s.a = *GetPoisonedO<U2>(0, origin);
- EXPECT_ORIGIN(origin, __msan_get_origin(&s.a));
- EXPECT_ORIGIN(origin, __msan_get_origin(&s.b));
-
- s.b = 42;
- EXPECT_ORIGIN(origin, __msan_get_origin(&s.a));
- EXPECT_ORIGIN(origin, __msan_get_origin(&s.b));
-}
-} // namespace
-
-template<class T, class BinaryOp>
-INLINE
-void BinaryOpOriginTest(BinaryOp op) {
- U4 ox = rand(); //NOLINT
- U4 oy = rand(); //NOLINT
- T *x = GetPoisonedO<T>(0, ox, 0);
- T *y = GetPoisonedO<T>(1, oy, 0);
- T *z = GetPoisonedO<T>(2, 0, 0);
-
- *z = op(*x, *y);
- U4 origin = __msan_get_origin(z);
- EXPECT_POISONED_O(*z, origin);
- EXPECT_EQ(true, __msan_origin_is_descendant_or_same(origin, ox) ||
- __msan_origin_is_descendant_or_same(origin, oy));
-
- // y is poisoned, x is not.
- *x = 10101;
- *y = *GetPoisonedO<T>(1, oy);
- break_optimization(x);
- __msan_set_origin(z, sizeof(*z), 0);
- *z = op(*x, *y);
- EXPECT_POISONED_O(*z, oy);
- EXPECT_ORIGIN(oy, __msan_get_origin(z));
-
- // x is poisoned, y is not.
- *x = *GetPoisonedO<T>(0, ox);
- *y = 10101010;
- break_optimization(y);
- __msan_set_origin(z, sizeof(*z), 0);
- *z = op(*x, *y);
- EXPECT_POISONED_O(*z, ox);
- EXPECT_ORIGIN(ox, __msan_get_origin(z));
-}
-
-template<class T> INLINE T XOR(const T &a, const T&b) { return a ^ b; }
-template<class T> INLINE T ADD(const T &a, const T&b) { return a + b; }
-template<class T> INLINE T SUB(const T &a, const T&b) { return a - b; }
-template<class T> INLINE T MUL(const T &a, const T&b) { return a * b; }
-template<class T> INLINE T AND(const T &a, const T&b) { return a & b; }
-template<class T> INLINE T OR (const T &a, const T&b) { return a | b; }
-
-TEST(MemorySanitizerOrigins, BinaryOp) {
- if (!TrackingOrigins()) return;
- BinaryOpOriginTest<S8>(XOR<S8>);
- BinaryOpOriginTest<U8>(ADD<U8>);
- BinaryOpOriginTest<S4>(SUB<S4>);
- BinaryOpOriginTest<S4>(MUL<S4>);
- BinaryOpOriginTest<U4>(OR<U4>);
- BinaryOpOriginTest<U4>(AND<U4>);
- BinaryOpOriginTest<double>(ADD<U4>);
- BinaryOpOriginTest<float>(ADD<S4>);
- BinaryOpOriginTest<double>(ADD<double>);
- BinaryOpOriginTest<float>(ADD<double>);
-}
-
-TEST(MemorySanitizerOrigins, Unary) {
- if (!TrackingOrigins()) return;
- EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);
- EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);
- EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);
- EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__), __LINE__);
-
- EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
- EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
- EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
- EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
-
- EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);
- EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);
- EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);
- EXPECT_POISONED_O(*GetPoisonedO<U4>(0, __LINE__), __LINE__);
-
- EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
- EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
- EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
- EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
-
- EXPECT_POISONED_O((void*)*GetPoisonedO<S8>(0, __LINE__), __LINE__);
- EXPECT_POISONED_O((U8)*GetPoisonedO<void*>(0, __LINE__), __LINE__);
-}
-
-TEST(MemorySanitizerOrigins, EQ) {
- if (!TrackingOrigins()) return;
- EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__) <= 11, __LINE__);
- EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__) == 11, __LINE__);
- EXPECT_POISONED_O(*GetPoisonedO<float>(0, __LINE__) == 1.1, __LINE__);
-}
-
-TEST(MemorySanitizerOrigins, DIV) {
- if (!TrackingOrigins()) return;
- EXPECT_POISONED_O(*GetPoisonedO<U8>(0, __LINE__) / 100, __LINE__);
- unsigned o = __LINE__;
- EXPECT_UMR_O(volatile unsigned y = 100 / *GetPoisonedO<S4>(0, o, 1), o);
-}
-
-TEST(MemorySanitizerOrigins, SHIFT) {
- if (!TrackingOrigins()) return;
- EXPECT_POISONED_O(*GetPoisonedO<U8>(0, __LINE__) >> 10, __LINE__);
- EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__) >> 10, __LINE__);
- EXPECT_POISONED_O(*GetPoisonedO<S8>(0, __LINE__) << 10, __LINE__);
- EXPECT_POISONED_O(10U << *GetPoisonedO<U8>(0, __LINE__), __LINE__);
- EXPECT_POISONED_O(-10 >> *GetPoisonedO<S8>(0, __LINE__), __LINE__);
- EXPECT_POISONED_O(-10 << *GetPoisonedO<S8>(0, __LINE__), __LINE__);
-}
-
-template<class T, int N>
-void MemCpyTest() {
- int ox = __LINE__;
- T *x = new T[N];
- T *y = new T[N];
- T *z = new T[N];
- T *q = new T[N];
- __msan_poison(x, N * sizeof(T));
- __msan_set_origin(x, N * sizeof(T), ox);
- __msan_set_origin(y, N * sizeof(T), 777777);
- __msan_set_origin(z, N * sizeof(T), 888888);
- EXPECT_NOT_POISONED(x);
- memcpy(y, x, N * sizeof(T));
- EXPECT_POISONED_O(y[0], ox);
- EXPECT_POISONED_O(y[N/2], ox);
- EXPECT_POISONED_O(y[N-1], ox);
- EXPECT_NOT_POISONED(x);
-#if !defined(__NetBSD__)
- void *res = mempcpy(q, x, N * sizeof(T));
- ASSERT_EQ(q + N, res);
- EXPECT_POISONED_O(q[0], ox);
- EXPECT_POISONED_O(q[N/2], ox);
- EXPECT_POISONED_O(q[N-1], ox);
- EXPECT_NOT_POISONED(x);
-#endif
- memmove(z, x, N * sizeof(T));
- EXPECT_POISONED_O(z[0], ox);
- EXPECT_POISONED_O(z[N/2], ox);
- EXPECT_POISONED_O(z[N-1], ox);
-}
-
-TEST(MemorySanitizerOrigins, LargeMemCpy) {
- if (!TrackingOrigins()) return;
- MemCpyTest<U1, 10000>();
- MemCpyTest<U8, 10000>();
-}
-
-TEST(MemorySanitizerOrigins, SmallMemCpy) {
- if (!TrackingOrigins()) return;
- MemCpyTest<U8, 1>();
- MemCpyTest<U8, 2>();
- MemCpyTest<U8, 3>();
-}
-
-TEST(MemorySanitizerOrigins, Select) {
- if (!TrackingOrigins()) return;
- EXPECT_NOT_POISONED(g_one ? 1 : *GetPoisonedO<S4>(0, __LINE__));
- EXPECT_POISONED_O(*GetPoisonedO<S4>(0, __LINE__), __LINE__);
- S4 x;
- break_optimization(&x);
- x = g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 0;
-
- EXPECT_POISONED_O(g_1 ? *GetPoisonedO<S4>(0, __LINE__) : 1, __LINE__);
- EXPECT_POISONED_O(g_0 ? 1 : *GetPoisonedO<S4>(0, __LINE__), __LINE__);
-}
-
-NOINLINE int RetvalOriginTest(U4 origin) {
- int *a = new int;
- break_optimization(a);
- __msan_set_origin(a, sizeof(*a), origin);
- int res = *a;
- delete a;
- return res;
-}
-
-TEST(MemorySanitizerOrigins, Retval) {
- if (!TrackingOrigins()) return;
- EXPECT_POISONED_O(RetvalOriginTest(__LINE__), __LINE__);
-}
-
-NOINLINE void ParamOriginTest(int param, U4 origin) {
- EXPECT_POISONED_O(param, origin);
-}
-
-TEST(MemorySanitizerOrigins, Param) {
- if (!TrackingOrigins()) return;
- int *a = new int;
- U4 origin = __LINE__;
- break_optimization(a);
- __msan_set_origin(a, sizeof(*a), origin);
- ParamOriginTest(*a, origin);
- delete a;
-}
-
-TEST(MemorySanitizerOrigins, Invoke) {
- if (!TrackingOrigins()) return;
- StructWithDtor s; // Will cause the calls to become invokes.
- EXPECT_POISONED_O(RetvalOriginTest(__LINE__), __LINE__);
-}
-
-TEST(MemorySanitizerOrigins, strlen) {
- S8 alignment;
- break_optimization(&alignment);
- char x[4] = {'a', 'b', 0, 0};
- __msan_poison(&x[2], 1);
- U4 origin = __LINE__;
- __msan_set_origin(x, sizeof(x), origin);
- EXPECT_UMR_O(volatile unsigned y = strlen(x), origin);
-}
-
-TEST(MemorySanitizerOrigins, wcslen) {
- wchar_t w[3] = {'a', 'b', 0};
- U4 origin = __LINE__;
- __msan_set_origin(w, sizeof(w), origin);
- __msan_poison(&w[2], sizeof(wchar_t));
- EXPECT_UMR_O(volatile unsigned y = wcslen(w), origin);
-}
-
-#if MSAN_HAS_M128
-TEST(MemorySanitizerOrigins, StoreIntrinsic) {
- __m128 x, y;
- U4 origin = __LINE__;
- __msan_set_origin(&x, sizeof(x), origin);
- __msan_poison(&x, sizeof(x));
- _mm_storeu_ps((float*)&y, x);
- EXPECT_POISONED_O(y, origin);
-}
-#endif
-
-NOINLINE void RecursiveMalloc(int depth) {
- static int count;
- count++;
- if ((count % (1024 * 1024)) == 0)
- printf("RecursiveMalloc: %d\n", count);
- int *x1 = new int;
- int *x2 = new int;
- break_optimization(x1);
- break_optimization(x2);
- if (depth > 0) {
- RecursiveMalloc(depth-1);
- RecursiveMalloc(depth-1);
- }
- delete x1;
- delete x2;
-}
-
-TEST(MemorySanitizer, Select) {
- int x;
- int volatile* p = &x;
- int z = *p ? 1 : 0;
- EXPECT_POISONED(z);
-}
-
-TEST(MemorySanitizer, SelectPartial) {
- // Precise instrumentation of select.
- // Some bits of the result do not depend on select condition, and must stay
- // initialized even if select condition is not. These are the bits that are
- // equal and initialized in both left and right select arguments.
- U4 x = 0xFFFFABCDU;
- U4 x_s = 0xFFFF0000U;
- __msan_partial_poison(&x, &x_s, sizeof(x));
- U4 y = 0xAB00U;
- U1 cond = true;
- __msan_poison(&cond, sizeof(cond));
- U4 z = cond ? x : y;
- __msan_print_shadow(&z, sizeof(z));
- EXPECT_POISONED(z & 0xFFU);
- EXPECT_NOT_POISONED(z & 0xFF00U);
- EXPECT_POISONED(z & 0xFF0000U);
- EXPECT_POISONED(z & 0xFF000000U);
- EXPECT_EQ(0xAB00U, z & 0xFF00U);
-}
-
-TEST(MemorySanitizerStress, DISABLED_MallocStackTrace) {
- RecursiveMalloc(22);
-}
-
-TEST(MemorySanitizerAllocator, get_estimated_allocated_size) {
- size_t sizes[] = {0, 20, 5000, 1<<20};
- for (size_t i = 0; i < sizeof(sizes) / sizeof(*sizes); ++i) {
- size_t alloc_size = __sanitizer_get_estimated_allocated_size(sizes[i]);
- EXPECT_EQ(alloc_size, sizes[i]);
- }
-}
-
-TEST(MemorySanitizerAllocator, get_allocated_size_and_ownership) {
- char *array = reinterpret_cast<char*>(malloc(100));
- int *int_ptr = new int;
-
- EXPECT_TRUE(__sanitizer_get_ownership(array));
- EXPECT_EQ(100U, __sanitizer_get_allocated_size(array));
-
- EXPECT_TRUE(__sanitizer_get_ownership(int_ptr));
- EXPECT_EQ(sizeof(*int_ptr), __sanitizer_get_allocated_size(int_ptr));
-
- void *wild_addr = reinterpret_cast<void*>(0x1);
- EXPECT_FALSE(__sanitizer_get_ownership(wild_addr));
- EXPECT_EQ(0U, __sanitizer_get_allocated_size(wild_addr));
-
- EXPECT_FALSE(__sanitizer_get_ownership(array + 50));
- EXPECT_EQ(0U, __sanitizer_get_allocated_size(array + 50));
-
- // NULL is a valid argument for GetAllocatedSize but is not owned.
- EXPECT_FALSE(__sanitizer_get_ownership(NULL));
- EXPECT_EQ(0U, __sanitizer_get_allocated_size(NULL));
-
- free(array);
- EXPECT_FALSE(__sanitizer_get_ownership(array));
- EXPECT_EQ(0U, __sanitizer_get_allocated_size(array));
-
- delete int_ptr;
-}
-
-TEST(MemorySanitizer, MlockTest) {
- EXPECT_EQ(0, mlockall(MCL_CURRENT));
- EXPECT_EQ(0, mlock((void*)0x12345, 0x5678));
- EXPECT_EQ(0, munlockall());
- EXPECT_EQ(0, munlock((void*)0x987, 0x654));
-}
-
-// Test that LargeAllocator unpoisons memory before releasing it to the OS.
-TEST(MemorySanitizer, LargeAllocatorUnpoisonsOnFree) {
- void *p = malloc(1024 * 1024);
- free(p);
-
- typedef void *(*mmap_fn)(void *, size_t, int, int, int, off_t);
- mmap_fn real_mmap = (mmap_fn)dlsym(RTLD_NEXT, "mmap");
-
- // Allocate the page that was released to the OS in free() with the real mmap,
- // bypassing the interceptor.
- char *q = (char *)real_mmap(p, 4096, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANONYMOUS, -1, 0);
- ASSERT_NE((char *)0, q);
-
- ASSERT_TRUE(q <= p);
- ASSERT_TRUE(q + 4096 > p);
-
- EXPECT_NOT_POISONED(q[0]);
- EXPECT_NOT_POISONED(q[10]);
- EXPECT_NOT_POISONED(q[100]);
-
- munmap(q, 4096);
-}
-
-#if SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE
-TEST(MemorySanitizer, MallocUsableSizeTest) {
- const size_t kArraySize = 100;
- char *array = Ident((char*)malloc(kArraySize));
- int *int_ptr = Ident(new int);
- EXPECT_EQ(0U, malloc_usable_size(NULL));
- EXPECT_EQ(kArraySize, malloc_usable_size(array));
- EXPECT_EQ(sizeof(int), malloc_usable_size(int_ptr));
- free(array);
- delete int_ptr;
-}
-#endif // SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE
diff --git a/lib/msan/tests/msan_test_config.h b/lib/msan/tests/msan_test_config.h
deleted file mode 100644
index 5404c434d09f3..0000000000000
--- a/lib/msan/tests/msan_test_config.h
+++ /dev/null
@@ -1,20 +0,0 @@
-//===-- msan_test_config.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of MemorySanitizer.
-//
-// MemorySanitizer unit tests.
-//===----------------------------------------------------------------------===//
-
-#ifndef MSAN_TEST_CONFIG_H
-#define MSAN_TEST_CONFIG_H
-
-#include "gtest/gtest.h"
-
-#endif // MSAN_TEST_CONFIG_H
diff --git a/lib/msan/tests/msan_test_main.cc b/lib/msan/tests/msan_test_main.cc
deleted file mode 100644
index c8c5fefb19f5d..0000000000000
--- a/lib/msan/tests/msan_test_main.cc
+++ /dev/null
@@ -1,21 +0,0 @@
-//===-- msan_test_main.cc -------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of MemorySanitizer.
-//
-//===----------------------------------------------------------------------===//
-#ifndef MSAN_EXTERNAL_TEST_CONFIG
-#include "msan_test_config.h"
-#endif // MSAN_EXTERNAL_TEST_CONFIG
-
-int main(int argc, char **argv) {
- testing::GTEST_FLAG(death_test_style) = "threadsafe";
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/lib/profile/CMakeLists.txt b/lib/profile/CMakeLists.txt
deleted file mode 100644
index 488673dd2c227..0000000000000
--- a/lib/profile/CMakeLists.txt
+++ /dev/null
@@ -1,126 +0,0 @@
-
-CHECK_CXX_SOURCE_COMPILES("
-#ifdef _MSC_VER
-#include <Intrin.h> /* Workaround for PR19898. */
-#include <windows.h>
-#endif
-int main() {
-#ifdef _MSC_VER
- volatile LONG val = 1;
- MemoryBarrier();
- InterlockedCompareExchange(&val, 0, 1);
- InterlockedIncrement(&val);
- InterlockedDecrement(&val);
-#else
- volatile unsigned long val = 1;
- __sync_synchronize();
- __sync_val_compare_and_swap(&val, 1, 0);
- __sync_add_and_fetch(&val, 1);
- __sync_sub_and_fetch(&val, 1);
-#endif
- return 0;
- }
-" COMPILER_RT_TARGET_HAS_ATOMICS)
-
-CHECK_CXX_SOURCE_COMPILES("
-#if defined(__linux__)
-#include <unistd.h>
-#endif
-#include <fcntl.h>
-int fd;
-int main() {
- struct flock s_flock;
-
- s_flock.l_type = F_WRLCK;
- fcntl(fd, F_SETLKW, &s_flock);
- return 0;
-}
-
-" COMPILER_RT_TARGET_HAS_FCNTL_LCK)
-
-CHECK_CXX_SOURCE_COMPILES("
-#include <sys/utsname.h>
-int main() {
- return 0;
-}
-
-" COMPILER_RT_TARGET_HAS_UNAME)
-
-add_compiler_rt_component(profile)
-
-set(PROFILE_SOURCES
- GCDAProfiling.c
- InstrProfiling.c
- InstrProfilingValue.c
- InstrProfilingBuffer.c
- InstrProfilingFile.c
- InstrProfilingMerge.c
- InstrProfilingMergeFile.c
- InstrProfilingNameVar.c
- InstrProfilingWriter.c
- InstrProfilingPlatformDarwin.c
- InstrProfilingPlatformFuchsia.c
- InstrProfilingPlatformLinux.c
- InstrProfilingPlatformOther.c
- InstrProfilingRuntime.cc
- InstrProfilingUtil.c)
-
-set(PROFILE_HEADERS
- InstrProfData.inc
- InstrProfiling.h
- InstrProfilingInternal.h
- InstrProfilingPort.h
- InstrProfilingUtil.h
- WindowsMMap.h)
-
-if(WIN32)
- list(APPEND PROFILE_SOURCES WindowsMMap.c)
-endif()
-
-if(FUCHSIA OR UNIX)
- set(EXTRA_FLAGS
- -fPIC
- -Wno-pedantic)
-endif()
-
-if(COMPILER_RT_TARGET_HAS_ATOMICS)
- set(EXTRA_FLAGS
- ${EXTRA_FLAGS}
- -DCOMPILER_RT_HAS_ATOMICS=1)
-endif()
-
-if(COMPILER_RT_TARGET_HAS_FCNTL_LCK)
- set(EXTRA_FLAGS
- ${EXTRA_FLAGS}
- -DCOMPILER_RT_HAS_FCNTL_LCK=1)
-endif()
-
-if(COMPILER_RT_TARGET_HAS_UNAME)
- set(EXTRA_FLAGS
- ${EXTRA_FLAGS}
- -DCOMPILER_RT_HAS_UNAME=1)
-endif()
-
-# This appears to be a C-only warning banning the use of locals in aggregate
-# initializers. All other compilers accept this, though.
-# nonstandard extension used : 'identifier' : cannot be initialized using address of automatic variable
-append_list_if(COMPILER_RT_HAS_WD4221_FLAG /wd4221 EXTRA_FLAGS)
-
-if(APPLE)
- add_compiler_rt_runtime(clang_rt.profile
- STATIC
- OS ${PROFILE_SUPPORTED_OS}
- ARCHS ${PROFILE_SUPPORTED_ARCH}
- CFLAGS ${EXTRA_FLAGS}
- SOURCES ${PROFILE_SOURCES}
- ADDITIONAL_HEADERS ${PROFILE_HEADERS}
- PARENT_TARGET profile)
-else()
- add_compiler_rt_runtime(clang_rt.profile
- STATIC
- ARCHS ${PROFILE_SUPPORTED_ARCH}
- CFLAGS ${EXTRA_FLAGS}
- SOURCES ${PROFILE_SOURCES}
- ADDITIONAL_HEADERS ${PROFILE_HEADERS}
- PARENT_TARGET profile)
-endif()
diff --git a/lib/safestack/.clang-format b/lib/safestack/.clang-format
deleted file mode 100644
index 560308c91deec..0000000000000
--- a/lib/safestack/.clang-format
+++ /dev/null
@@ -1,2 +0,0 @@
-BasedOnStyle: Google
-AllowShortIfStatementsOnASingleLine: false
diff --git a/lib/safestack/CMakeLists.txt b/lib/safestack/CMakeLists.txt
deleted file mode 100644
index cc874a3fe8f18..0000000000000
--- a/lib/safestack/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-add_compiler_rt_component(safestack)
-
-set(SAFESTACK_SOURCES safestack.cc)
-
-include_directories(..)
-
-set(SAFESTACK_CFLAGS ${SANITIZER_COMMON_CFLAGS})
-
-foreach(arch ${SAFESTACK_SUPPORTED_ARCH})
- add_compiler_rt_runtime(clang_rt.safestack
- STATIC
- ARCHS ${arch}
- SOURCES ${SAFESTACK_SOURCES}
- $<TARGET_OBJECTS:RTInterception.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonNoLibc.${arch}>
- CFLAGS ${SAFESTACK_CFLAGS}
- PARENT_TARGET safestack)
-endforeach()
diff --git a/lib/sanitizer_common/.clang-format b/lib/sanitizer_common/.clang-format
deleted file mode 100644
index 560308c91deec..0000000000000
--- a/lib/sanitizer_common/.clang-format
+++ /dev/null
@@ -1,2 +0,0 @@
-BasedOnStyle: Google
-AllowShortIfStatementsOnASingleLine: false
diff --git a/lib/sanitizer_common/.clang-tidy b/lib/sanitizer_common/.clang-tidy
deleted file mode 100644
index 6c71abff0d382..0000000000000
--- a/lib/sanitizer_common/.clang-tidy
+++ /dev/null
@@ -1,16 +0,0 @@
-Checks: '-*,clang-diagnostic-*,llvm-*,misc-*,readability-identifier-naming'
-CheckOptions:
- - key: readability-identifier-naming.ClassCase
- value: CamelCase
- - key: readability-identifier-naming.EnumCase
- value: CamelCase
- - key: readability-identifier-naming.FunctionCase
- value: CamelCase
- - key: readability-identifier-naming.UnionCase
- value: CamelCase
- - key: readability-identifier-naming.GlobalConstantCase
- value: CamelCase
- - key: readability-identifier-naming.GlobalConstantPrefix
- value: "k"
- - key: readability-identifier-naming.VariableCase
- value: lower_case
diff --git a/lib/sanitizer_common/CMakeLists.txt b/lib/sanitizer_common/CMakeLists.txt
deleted file mode 100644
index f7bf4b009720e..0000000000000
--- a/lib/sanitizer_common/CMakeLists.txt
+++ /dev/null
@@ -1,374 +0,0 @@
-# Build system for the common Sanitizer runtime support library components.
-# These components are shared between AddressSanitizer and ThreadSanitizer.
-
-set(SANITIZER_SOURCES_NOTERMINATION
- sanitizer_allocator.cc
- sanitizer_common.cc
- sanitizer_deadlock_detector1.cc
- sanitizer_deadlock_detector2.cc
- sanitizer_errno.cc
- sanitizer_file.cc
- sanitizer_flags.cc
- sanitizer_flag_parser.cc
- sanitizer_fuchsia.cc
- sanitizer_libc.cc
- sanitizer_libignore.cc
- sanitizer_linux.cc
- sanitizer_linux_s390.cc
- sanitizer_mac.cc
- sanitizer_netbsd.cc
- sanitizer_openbsd.cc
- sanitizer_persistent_allocator.cc
- sanitizer_platform_limits_freebsd.cc
- sanitizer_platform_limits_linux.cc
- sanitizer_platform_limits_netbsd.cc
- sanitizer_platform_limits_openbsd.cc
- sanitizer_platform_limits_posix.cc
- sanitizer_platform_limits_solaris.cc
- sanitizer_posix.cc
- sanitizer_printf.cc
- sanitizer_procmaps_common.cc
- sanitizer_procmaps_bsd.cc
- sanitizer_procmaps_linux.cc
- sanitizer_procmaps_mac.cc
- sanitizer_procmaps_solaris.cc
- sanitizer_rtems.cc
- sanitizer_solaris.cc
- sanitizer_stoptheworld_mac.cc
- sanitizer_suppressions.cc
- sanitizer_tls_get_addr.cc
- sanitizer_thread_registry.cc
- sanitizer_type_traits.cc
- sanitizer_win.cc)
-
-if(UNIX AND NOT APPLE AND NOT OS_NAME MATCHES "SunOS")
- list(APPEND SANITIZER_SOURCES_NOTERMINATION
- sanitizer_linux_x86_64.S)
- list(APPEND SANITIZER_SOURCES_NOTERMINATION
- sanitizer_linux_mips64.S)
-endif()
-
-set(SANITIZER_SOURCES
- ${SANITIZER_SOURCES_NOTERMINATION} sanitizer_termination.cc)
-
-# Libc functions stubs. These sources should be linked instead of
-# SANITIZER_LIBCDEP_SOURCES when sanitizer_common library must not depend on
-# libc.
-set(SANITIZER_NOLIBC_SOURCES
- sanitizer_common_nolibc.cc)
-
-set(SANITIZER_LIBCDEP_SOURCES
- sanitizer_common_libcdep.cc
- sanitizer_allocator_checks.cc
- sanitizer_linux_libcdep.cc
- sanitizer_mac_libcdep.cc
- sanitizer_posix_libcdep.cc
- sanitizer_stoptheworld_linux_libcdep.cc)
-
-set(SANITIZER_COVERAGE_SOURCES
- sancov_flags.cc
- sanitizer_coverage_fuchsia.cc
- sanitizer_coverage_libcdep_new.cc
- sanitizer_coverage_win_sections.cc)
-
-set(SANITIZER_SYMBOLIZER_SOURCES
- sanitizer_allocator_report.cc
- sanitizer_stackdepot.cc
- sanitizer_stacktrace.cc
- sanitizer_stacktrace_libcdep.cc
- sanitizer_stacktrace_printer.cc
- sanitizer_stacktrace_sparc.cc
- sanitizer_symbolizer.cc
- sanitizer_symbolizer_libbacktrace.cc
- sanitizer_symbolizer_libcdep.cc
- sanitizer_symbolizer_mac.cc
- sanitizer_symbolizer_markup.cc
- sanitizer_symbolizer_posix_libcdep.cc
- sanitizer_symbolizer_report.cc
- sanitizer_symbolizer_win.cc
- sanitizer_unwind_linux_libcdep.cc
- sanitizer_unwind_win.cc)
-
-# Explicitly list all sanitizer_common headers. Not all of these are
-# included in sanitizer_common source files, but we need to depend on
-# headers when building our custom unit tests.
-set(SANITIZER_IMPL_HEADERS
- sancov_flags.h
- sancov_flags.inc
- sanitizer_addrhashmap.h
- sanitizer_allocator.h
- sanitizer_allocator_bytemap.h
- sanitizer_allocator_checks.h
- sanitizer_allocator_combined.h
- sanitizer_allocator_interface.h
- sanitizer_allocator_internal.h
- sanitizer_allocator_local_cache.h
- sanitizer_allocator_primary32.h
- sanitizer_allocator_primary64.h
- sanitizer_allocator_report.h
- sanitizer_allocator_secondary.h
- sanitizer_allocator_size_class_map.h
- sanitizer_allocator_stats.h
- sanitizer_asm.h
- sanitizer_atomic.h
- sanitizer_atomic_clang.h
- sanitizer_atomic_clang_mips.h
- sanitizer_atomic_clang_other.h
- sanitizer_atomic_clang_x86.h
- sanitizer_atomic_msvc.h
- sanitizer_bitvector.h
- sanitizer_bvgraph.h
- sanitizer_common.h
- sanitizer_common_interceptors.inc
- sanitizer_common_interceptors_format.inc
- sanitizer_common_interceptors_ioctl.inc
- sanitizer_common_interface.inc
- sanitizer_common_interface_posix.inc
- sanitizer_common_syscalls.inc
- sanitizer_coverage_interface.inc
- sanitizer_dbghelp.h
- sanitizer_deadlock_detector.h
- sanitizer_deadlock_detector_interface.h
- sanitizer_errno.h
- sanitizer_errno_codes.h
- sanitizer_file.h
- sanitizer_flag_parser.h
- sanitizer_flags.h
- sanitizer_flags.inc
- sanitizer_freebsd.h
- sanitizer_fuchsia.h
- sanitizer_getauxval.h
- sanitizer_interceptors_ioctl_netbsd.inc
- sanitizer_interface_internal.h
- sanitizer_internal_defs.h
- sanitizer_lfstack.h
- sanitizer_libc.h
- sanitizer_libignore.h
- sanitizer_linux.h
- sanitizer_list.h
- sanitizer_local_address_space_view.h
- sanitizer_mac.h
- sanitizer_malloc_mac.inc
- sanitizer_mutex.h
- sanitizer_persistent_allocator.h
- sanitizer_placement_new.h
- sanitizer_platform.h
- sanitizer_platform_interceptors.h
- sanitizer_platform_limits_netbsd.h
- sanitizer_platform_limits_openbsd.h
- sanitizer_platform_limits_posix.h
- sanitizer_platform_limits_solaris.h
- sanitizer_posix.h
- sanitizer_procmaps.h
- sanitizer_quarantine.h
- sanitizer_report_decorator.h
- sanitizer_ring_buffer.h
- sanitizer_rtems.h
- sanitizer_signal_interceptors.inc
- sanitizer_stackdepot.h
- sanitizer_stackdepotbase.h
- sanitizer_stacktrace.h
- sanitizer_stacktrace_printer.h
- sanitizer_stoptheworld.h
- sanitizer_suppressions.h
- sanitizer_symbolizer.h
- sanitizer_symbolizer_fuchsia.h
- sanitizer_symbolizer_internal.h
- sanitizer_symbolizer_libbacktrace.h
- sanitizer_symbolizer_mac.h
- sanitizer_symbolizer_rtems.h
- sanitizer_syscall_generic.inc
- sanitizer_syscall_linux_aarch64.inc
- sanitizer_syscall_linux_arm.inc
- sanitizer_syscall_linux_x86_64.inc
- sanitizer_syscalls_netbsd.inc
- sanitizer_thread_registry.h
- sanitizer_tls_get_addr.h
- sanitizer_vector.h
- sanitizer_win.h
- sanitizer_win_defs.h
- sanitizer_win_dll_thunk.h
- sanitizer_win_weak_interception.h)
-
-include_directories(..)
-
-set(SANITIZER_COMMON_DEFINITIONS
- HAVE_RPC_XDR_H=${HAVE_RPC_XDR_H})
-
-set(SANITIZER_CFLAGS ${SANITIZER_COMMON_CFLAGS})
-append_rtti_flag(OFF SANITIZER_CFLAGS)
-
-append_list_if(SANITIZER_LIMIT_FRAME_SIZE -Wframe-larger-than=570
- SANITIZER_CFLAGS)
-append_list_if(COMPILER_RT_HAS_WGLOBAL_CONSTRUCTORS_FLAG -Wglobal-constructors
- SANITIZER_CFLAGS)
-
-if (LLVM_ENABLE_PEDANTIC AND UNIX AND NOT APPLE)
- # With -pedantic, our .S files raise warnings about empty macro arguments
- # from __USER_LABEL_PREFIX__ being an empty arg to GLUE(). Unfortunately,
- # there is no simple way to test for an empty define, nor to disable just
- # that warning or to disable -pedantic. There is also no simple way to
- # remove -pedantic from just this file (we'd have to remove from
- # CMAKE_C*_FLAGS and re-add as a source property to all the non-.S files).
- set_source_files_properties(sanitizer_linux_x86_64.S
- PROPERTIES COMPILE_FLAGS "-w")
- set_source_files_properties(sanitizer_linux_mips64.S
- PROPERTIES COMPILE_FLAGS "-w")
-endif ()
-
-if(APPLE)
- set(OS_OPTION OS ${SANITIZER_COMMON_SUPPORTED_OS})
-endif()
-
-add_compiler_rt_object_libraries(RTSanitizerCommon
- ${OS_OPTION}
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES ${SANITIZER_SOURCES}
- ADDITIONAL_HEADERS ${SANITIZER_IMPL_HEADERS}
- CFLAGS ${SANITIZER_CFLAGS}
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
-add_compiler_rt_object_libraries(RTSanitizerCommonNoTermination
- ${OS_OPTION}
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES ${SANITIZER_SOURCES_NOTERMINATION}
- ADDITIONAL_HEADERS ${SANITIZER_IMPL_HEADERS}
- CFLAGS ${SANITIZER_CFLAGS}
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
-add_compiler_rt_object_libraries(RTSanitizerCommonNoLibc
- ${OS_OPTION}
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES ${SANITIZER_NOLIBC_SOURCES}
- ADDITIONAL_HEADERS ${SANITIZER_IMPL_HEADERS}
- CFLAGS ${SANITIZER_CFLAGS}
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
-add_compiler_rt_object_libraries(RTSanitizerCommonLibc
- ${OS_OPTION}
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES ${SANITIZER_LIBCDEP_SOURCES}
- ADDITIONAL_HEADERS ${SANITIZER_IMPL_HEADERS}
- CFLAGS ${SANITIZER_CFLAGS}
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
-add_compiler_rt_object_libraries(RTSanitizerCommonCoverage
- ${OS_OPTION}
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES ${SANITIZER_COVERAGE_SOURCES}
- ADDITIONAL_HEADERS ${SANITIZER_IMPL_HEADERS}
- CFLAGS ${SANITIZER_CFLAGS}
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
-add_compiler_rt_object_libraries(RTSanitizerCommonSymbolizer
- ${OS_OPTION}
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES ${SANITIZER_SYMBOLIZER_SOURCES}
- ADDITIONAL_HEADERS ${SANITIZER_IMPL_HEADERS}
- CFLAGS ${SANITIZER_CFLAGS}
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
-
-set(SANITIZER_NO_WEAK_HOOKS_CFLAGS ${SANITIZER_CFLAGS})
-list(APPEND SANITIZER_NO_WEAK_HOOKS_CFLAGS "-DSANITIZER_SUPPORTS_WEAK_HOOKS=0")
-add_compiler_rt_object_libraries(RTSanitizerCommonNoHooks
- ${OS_OPTION}
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES ${SANITIZER_SOURCES}
- ADDITIONAL_HEADERS ${SANITIZER_IMPL_HEADERS}
- CFLAGS ${SANITIZER_NO_WEAK_HOOKS_CFLAGS}
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
-add_compiler_rt_object_libraries(RTSanitizerCommonLibcNoHooks
- ${OS_OPTION}
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES ${SANITIZER_LIBCDEP_SOURCES}
- ADDITIONAL_HEADERS ${SANITIZER_IMPL_HEADERS}
- CFLAGS ${SANITIZER_NO_WEAK_HOOKS_CFLAGS}
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
-add_compiler_rt_object_libraries(RTSanitizerCommonSymbolizerNoHooks
- ${OS_OPTION}
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES ${SANITIZER_SYMBOLIZER_SOURCES}
- ADDITIONAL_HEADERS ${SANITIZER_IMPL_HEADERS}
- CFLAGS ${SANITIZER_NO_WEAK_HOOKS_CFLAGS}
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
-
-if(OS_NAME MATCHES "SunOS")
- # Solaris ld doesn't support the non-standard GNU ld extension of adding
- # __start_SECNAME and __stop_SECNAME labels to sections whose names are
- # valid C identifiers. Instead we add our own definitions for the
- # __sancov_guards section.
- add_compiler_rt_object_libraries(SancovBegin
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES sancov_begin.S
- CFLAGS ${SANITIZER_CFLAGS}
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
-
- add_compiler_rt_runtime(clang_rt.sancov_begin
- STATIC
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- OBJECT_LIBS SancovBegin
- CFLAGS ${SANITIZER_CFLAGS}
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
-
- add_compiler_rt_object_libraries(SancovEnd
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES sancov_end.S
- CFLAGS ${SANITIZER_CFLAGS}
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
-
- add_compiler_rt_runtime(clang_rt.sancov_end
- STATIC
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- OBJECT_LIBS SancovEnd
- CFLAGS ${SANITIZER_CFLAGS}
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
-endif()
-
-if(WIN32)
- add_compiler_rt_object_libraries(SanitizerCommonWeakInterception
- ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES sanitizer_win_weak_interception.cc
- CFLAGS ${SANITIZER_CFLAGS} -DSANITIZER_DYNAMIC
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
- add_compiler_rt_object_libraries(SancovWeakInterception
- ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES sanitizer_coverage_win_weak_interception.cc
- CFLAGS ${SANITIZER_CFLAGS} -DSANITIZER_DYNAMIC
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
-
- add_compiler_rt_object_libraries(SanitizerCommonDllThunk
- ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES sanitizer_win_dll_thunk.cc
- CFLAGS ${SANITIZER_CFLAGS} -DSANITIZER_DLL_THUNK
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
- add_compiler_rt_object_libraries(SancovDllThunk
- ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES sanitizer_coverage_win_dll_thunk.cc
- sanitizer_coverage_win_sections.cc
- CFLAGS ${SANITIZER_CFLAGS} -DSANITIZER_DLL_THUNK
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
-
- set(DYNAMIC_RUNTIME_THUNK_CFLAGS "-DSANITIZER_DYNAMIC_RUNTIME_THUNK")
- if(MSVC)
- list(APPEND DYNAMIC_RUNTIME_THUNK_CFLAGS "-Zl")
- elseif(CMAKE_C_COMPILER_ID MATCHES Clang)
- list(APPEND DYNAMIC_RUNTIME_THUNK_CFLAGS "-nodefaultlibs")
- endif()
- add_compiler_rt_object_libraries(SanitizerCommonDynamicRuntimeThunk
- ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES sanitizer_win_dynamic_runtime_thunk.cc
- CFLAGS ${SANITIZER_CFLAGS} ${DYNAMIC_RUNTIME_THUNK_CFLAGS}
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
- add_compiler_rt_object_libraries(SancovDynamicRuntimeThunk
- ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- SOURCES sanitizer_coverage_win_dynamic_runtime_thunk.cc
- sanitizer_coverage_win_sections.cc
- CFLAGS ${SANITIZER_CFLAGS} ${DYNAMIC_RUNTIME_THUNK_CFLAGS}
- DEFS ${SANITIZER_COMMON_DEFINITIONS})
-endif()
-
-# Unit tests for common sanitizer runtime.
-if(COMPILER_RT_INCLUDE_TESTS)
- add_subdirectory(tests)
-endif()
diff --git a/lib/sanitizer_common/scripts/check_lint.sh b/lib/sanitizer_common/scripts/check_lint.sh
deleted file mode 100755
index ec07138cac1c5..0000000000000
--- a/lib/sanitizer_common/scripts/check_lint.sh
+++ /dev/null
@@ -1,142 +0,0 @@
-#!/bin/sh
-
-SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)"
-
-# Guess path to LLVM_CHECKOUT if not provided
-if [ "${LLVM_CHECKOUT}" = "" ]; then
- LLVM_CHECKOUT="${SCRIPT_DIR}/../../../../../"
-fi
-
-# python tools setup
-CPPLINT=${SCRIPT_DIR}/cpplint.py
-LITLINT=${SCRIPT_DIR}/litlint.py
-if [ "${PYTHON_EXECUTABLE}" != "" ]; then
- CPPLINT="${PYTHON_EXECUTABLE} ${CPPLINT}"
- LITLINT="${PYTHON_EXECUTABLE} ${LITLINT}"
-fi
-
-# Filters
-# TODO: remove some of these filters
-COMMON_LINT_FILTER=-build/include,-build/header_guard,-legal/copyright,-whitespace/comments,-readability/casting,\
--build/namespaces,-readability/braces
-ASAN_RTL_LINT_FILTER=${COMMON_LINT_FILTER},-runtime/int
-ASAN_TEST_LINT_FILTER=${COMMON_LINT_FILTER},-runtime/sizeof,-runtime/int,-runtime/printf,-runtime/threadsafe_fn
-ASAN_LIT_TEST_LINT_FILTER=${ASAN_TEST_LINT_FILTER},-whitespace/line_length
-TSAN_RTL_LINT_FILTER=${COMMON_LINT_FILTER}
-TSAN_TEST_LINT_FILTER=${TSAN_RTL_LINT_FILTER},-runtime/threadsafe_fn,-runtime/int
-TSAN_LIT_TEST_LINT_FILTER=${TSAN_TEST_LINT_FILTER},-whitespace/line_length
-MSAN_RTL_LINT_FILTER=${COMMON_LINT_FILTER}
-LSAN_RTL_LINT_FILTER=${COMMON_LINT_FILTER}
-LSAN_LIT_TEST_LINT_FILTER=${LSAN_RTL_LINT_FILTER},-whitespace/line_length
-DFSAN_RTL_LINT_FILTER=${COMMON_LINT_FILTER},-runtime/int,-runtime/printf,-runtime/references,-readability/function
-SCUDO_RTL_LINT_FILTER=${COMMON_LINT_FILTER}
-COMMON_RTL_INC_LINT_FILTER=${COMMON_LINT_FILTER},-runtime/int,-runtime/sizeof,-runtime/printf,-readability/fn_size
-SANITIZER_INCLUDES_LINT_FILTER=${COMMON_LINT_FILTER},-runtime/int
-
-MKTEMP_DIR=$(mktemp -qd /tmp/check_lint.XXXXXXXXXX)
-MKTEMP="mktemp -q ${MKTEMP_DIR}/tmp.XXXXXXXXXX"
-cleanup() {
- rm -rf $MKTEMP_DIR
-}
-trap cleanup EXIT
-
-cd ${LLVM_CHECKOUT}
-
-EXITSTATUS=0
-ERROR_LOG=$(${MKTEMP})
-
-run_lint() {
- FILTER=$1
- shift
- TASK_LOG=$(${MKTEMP})
- ${CPPLINT} --filter=${FILTER} "$@" 2>$TASK_LOG
- if [ "$?" != "0" ]; then
- cat $TASK_LOG | grep -v "Done processing" | grep -v "Total errors found" \
- | grep -v "Skipping input" >> $ERROR_LOG
- fi
- if [ "${SILENT}" != "1" ]; then
- cat $TASK_LOG
- fi
- ${LITLINT} "$@" 2>>$ERROR_LOG
-}
-
-if [ "${COMPILER_RT}" = "" ]; then
- COMPILER_RT=projects/compiler-rt
-fi
-LIT_TESTS=${COMPILER_RT}/test
-# Headers
-SANITIZER_INCLUDES=${COMPILER_RT}/include/sanitizer
-run_lint ${SANITIZER_INCLUDES_LINT_FILTER} ${SANITIZER_INCLUDES}/*.h &
-
-# Sanitizer_common
-COMMON_RTL=${COMPILER_RT}/lib/sanitizer_common
-run_lint ${COMMON_RTL_INC_LINT_FILTER} ${COMMON_RTL}/*.cc \
- ${COMMON_RTL}/*.h \
- ${COMMON_RTL}/tests/*.cc &
-
-# Interception
-INTERCEPTION=${COMPILER_RT}/lib/interception
-run_lint ${ASAN_RTL_LINT_FILTER} ${INTERCEPTION}/*.cc \
- ${INTERCEPTION}/*.h &
-
-# ASan
-ASAN_RTL=${COMPILER_RT}/lib/asan
-run_lint ${ASAN_RTL_LINT_FILTER} ${ASAN_RTL}/*.cc \
- ${ASAN_RTL}/*.h &
-run_lint ${ASAN_TEST_LINT_FILTER} ${ASAN_RTL}/tests/*.cc \
- ${ASAN_RTL}/tests/*.h &
-run_lint ${ASAN_LIT_TEST_LINT_FILTER} ${LIT_TESTS}/asan/*/*.cc &
-
-# TSan
-TSAN_RTL=${COMPILER_RT}/lib/tsan
-run_lint ${TSAN_RTL_LINT_FILTER} ${TSAN_RTL}/rtl/*.cc \
- ${TSAN_RTL}/rtl/*.h &
-run_lint ${TSAN_TEST_LINT_FILTER} ${TSAN_RTL}/tests/rtl/*.cc \
- ${TSAN_RTL}/tests/rtl/*.h \
- ${TSAN_RTL}/tests/unit/*.cc &
-run_lint ${TSAN_LIT_TEST_LINT_FILTER} ${LIT_TESTS}/tsan/*.cc &
-
-# MSan
-MSAN_RTL=${COMPILER_RT}/lib/msan
-run_lint ${MSAN_RTL_LINT_FILTER} ${MSAN_RTL}/*.cc \
- ${MSAN_RTL}/*.h &
-
-# LSan
-LSAN_RTL=${COMPILER_RT}/lib/lsan
-run_lint ${LSAN_RTL_LINT_FILTER} ${LSAN_RTL}/*.cc \
- ${LSAN_RTL}/*.h &
-run_lint ${LSAN_LIT_TEST_LINT_FILTER} ${LIT_TESTS}/lsan/*/*.cc &
-
-# DFSan
-DFSAN_RTL=${COMPILER_RT}/lib/dfsan
-run_lint ${DFSAN_RTL_LINT_FILTER} ${DFSAN_RTL}/*.cc \
- ${DFSAN_RTL}/*.h &
-${DFSAN_RTL}/scripts/check_custom_wrappers.sh >> $ERROR_LOG
-
-# Scudo
-SCUDO_RTL=${COMPILER_RT}/lib/scudo
-run_lint ${SCUDO_RTL_LINT_FILTER} ${SCUDO_RTL}/*.cpp \
- ${SCUDO_RTL}/*.h &
-
-# Misc files
-FILES=${COMMON_RTL}/*.inc
-TMPFILES=""
-for FILE in $FILES; do
- TMPFILE="$(${MKTEMP}).$(basename ${FILE}).cc"
- cp -f $FILE $TMPFILE
- run_lint ${COMMON_RTL_INC_LINT_FILTER} $TMPFILE &
- TMPFILES="$TMPFILES $TMPFILE"
-done
-
-wait
-
-for temp in $TMPFILES; do
- rm -f $temp
-done
-
-if [ -s $ERROR_LOG ]; then
- cat $ERROR_LOG
- exit 1
-fi
-
-exit 0
diff --git a/lib/sanitizer_common/scripts/cpplint.py b/lib/sanitizer_common/scripts/cpplint.py
deleted file mode 100755
index d45c47f7ed0cd..0000000000000
--- a/lib/sanitizer_common/scripts/cpplint.py
+++ /dev/null
@@ -1,4024 +0,0 @@
-#!/usr/bin/env python
-#
-# Copyright (c) 2009 Google Inc. All rights reserved.
-#
-# Redistribution and use in source and binary forms, with or without
-# modification, are permitted provided that the following conditions are
-# met:
-#
-# * Redistributions of source code must retain the above copyright
-# notice, this list of conditions and the following disclaimer.
-# * Redistributions in binary form must reproduce the above
-# copyright notice, this list of conditions and the following disclaimer
-# in the documentation and/or other materials provided with the
-# distribution.
-# * Neither the name of Google Inc. nor the names of its
-# contributors may be used to endorse or promote products derived from
-# this software without specific prior written permission.
-#
-# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-# "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-# LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-# A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-# OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-# SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-# LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-# DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-# THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-# (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
-
-# Here are some issues that I've had people identify in my code during reviews,
-# that I think are possible to flag automatically in a lint tool. If these were
-# caught by lint, it would save time both for myself and that of my reviewers.
-# Most likely, some of these are beyond the scope of the current lint framework,
-# but I think it is valuable to retain these wish-list items even if they cannot
-# be immediately implemented.
-#
-# Suggestions
-# -----------
-# - Check for no 'explicit' for multi-arg ctor
-# - Check for boolean assign RHS in parens
-# - Check for ctor initializer-list colon position and spacing
-# - Check that if there's a ctor, there should be a dtor
-# - Check accessors that return non-pointer member variables are
-# declared const
-# - Check accessors that return non-const pointer member vars are
-# *not* declared const
-# - Check for using public includes for testing
-# - Check for spaces between brackets in one-line inline method
-# - Check for no assert()
-# - Check for spaces surrounding operators
-# - Check for 0 in pointer context (should be NULL)
-# - Check for 0 in char context (should be '\0')
-# - Check for camel-case method name conventions for methods
-# that are not simple inline getters and setters
-# - Do not indent namespace contents
-# - Avoid inlining non-trivial constructors in header files
-# - Check for old-school (void) cast for call-sites of functions
-# ignored return value
-# - Check gUnit usage of anonymous namespace
-# - Check for class declaration order (typedefs, consts, enums,
-# ctor(s?), dtor, friend declarations, methods, member vars)
-#
-
-"""Does google-lint on c++ files.
-
-The goal of this script is to identify places in the code that *may*
-be in non-compliance with google style. It does not attempt to fix
-up these problems -- the point is to educate. It does also not
-attempt to find all problems, or to ensure that everything it does
-find is legitimately a problem.
-
-In particular, we can get very confused by /* and // inside strings!
-We do a small hack, which is to ignore //'s with "'s after them on the
-same line, but it is far from perfect (in either direction).
-"""
-
-import codecs
-import copy
-import getopt
-import math # for log
-import os
-import re
-import sre_compile
-import string
-import sys
-import unicodedata
-
-
-_USAGE = """
-Syntax: cpplint.py [--verbose=#] [--output=vs7] [--filter=-x,+y,...]
- [--counting=total|toplevel|detailed]
- <file> [file] ...
-
- The style guidelines this tries to follow are those in
- http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml
-
- Every problem is given a confidence score from 1-5, with 5 meaning we are
- certain of the problem, and 1 meaning it could be a legitimate construct.
- This will miss some errors, and is not a substitute for a code review.
-
- To suppress false-positive errors of a certain category, add a
- 'NOLINT(category)' comment to the line. NOLINT or NOLINT(*)
- suppresses errors of all categories on that line.
-
- The files passed in will be linted; at least one file must be provided.
- Linted extensions are .cc, .cpp, and .h. Other file types will be ignored.
-
- Flags:
-
- output=vs7
- By default, the output is formatted to ease emacs parsing. Visual Studio
- compatible output (vs7) may also be used. Other formats are unsupported.
-
- verbose=#
- Specify a number 0-5 to restrict errors to certain verbosity levels.
-
- filter=-x,+y,...
- Specify a comma-separated list of category-filters to apply: only
- error messages whose category names pass the filters will be printed.
- (Category names are printed with the message and look like
- "[whitespace/indent]".) Filters are evaluated left to right.
- "-FOO" and "FOO" means "do not print categories that start with FOO".
- "+FOO" means "do print categories that start with FOO".
-
- Examples: --filter=-whitespace,+whitespace/braces
- --filter=whitespace,runtime/printf,+runtime/printf_format
- --filter=-,+build/include_what_you_use
-
- To see a list of all the categories used in cpplint, pass no arg:
- --filter=
-
- counting=total|toplevel|detailed
- The total number of errors found is always printed. If
- 'toplevel' is provided, then the count of errors in each of
- the top-level categories like 'build' and 'whitespace' will
- also be printed. If 'detailed' is provided, then a count
- is provided for each category like 'build/class'.
-
- root=subdir
- The root directory used for deriving header guard CPP variable.
- By default, the header guard CPP variable is calculated as the relative
- path to the directory that contains .git, .hg, or .svn. When this flag
- is specified, the relative path is calculated from the specified
- directory. If the specified directory does not exist, this flag is
- ignored.
-
- Examples:
- Assuing that src/.git exists, the header guard CPP variables for
- src/chrome/browser/ui/browser.h are:
-
- No flag => CHROME_BROWSER_UI_BROWSER_H_
- --root=chrome => BROWSER_UI_BROWSER_H_
- --root=chrome/browser => UI_BROWSER_H_
-"""
-
-# We categorize each error message we print. Here are the categories.
-# We want an explicit list so we can list them all in cpplint --filter=.
-# If you add a new error message with a new category, add it to the list
-# here! cpplint_unittest.py should tell you if you forget to do this.
-# \ used for clearer layout -- pylint: disable-msg=C6013
-_ERROR_CATEGORIES = [
- 'build/class',
- 'build/deprecated',
- 'build/endif_comment',
- 'build/explicit_make_pair',
- 'build/forward_decl',
- 'build/header_guard',
- 'build/include',
- 'build/include_alpha',
- 'build/include_order',
- 'build/include_what_you_use',
- 'build/namespaces',
- 'build/printf_format',
- 'build/storage_class',
- 'legal/copyright',
- 'readability/alt_tokens',
- 'readability/braces',
- 'readability/casting',
- 'readability/check',
- 'readability/constructors',
- 'readability/fn_size',
- 'readability/function',
- 'readability/multiline_comment',
- 'readability/multiline_string',
- 'readability/namespace',
- 'readability/nolint',
- 'readability/streams',
- 'readability/todo',
- 'readability/utf8',
- 'runtime/arrays',
- 'runtime/casting',
- 'runtime/explicit',
- 'runtime/int',
- 'runtime/init',
- 'runtime/invalid_increment',
- 'runtime/member_string_references',
- 'runtime/memset',
- 'runtime/operator',
- 'runtime/printf',
- 'runtime/printf_format',
- 'runtime/references',
- 'runtime/rtti',
- 'runtime/sizeof',
- 'runtime/string',
- 'runtime/threadsafe_fn',
- 'whitespace/blank_line',
- 'whitespace/braces',
- 'whitespace/comma',
- 'whitespace/comments',
- 'whitespace/empty_loop_body',
- 'whitespace/end_of_line',
- 'whitespace/ending_newline',
- 'whitespace/forcolon',
- 'whitespace/indent',
- 'whitespace/labels',
- 'whitespace/line_length',
- 'whitespace/newline',
- 'whitespace/operators',
- 'whitespace/parens',
- 'whitespace/semicolon',
- 'whitespace/tab',
- 'whitespace/todo'
- ]
-
-# The default state of the category filter. This is overrided by the --filter=
-# flag. By default all errors are on, so only add here categories that should be
-# off by default (i.e., categories that must be enabled by the --filter= flags).
-# All entries here should start with a '-' or '+', as in the --filter= flag.
-_DEFAULT_FILTERS = ['-build/include_alpha']
-
-# We used to check for high-bit characters, but after much discussion we
-# decided those were OK, as long as they were in UTF-8 and didn't represent
-# hard-coded international strings, which belong in a separate i18n file.
-
-# Headers that we consider STL headers.
-_STL_HEADERS = frozenset([
- 'algobase.h', 'algorithm', 'alloc.h', 'bitset', 'deque', 'exception',
- 'function.h', 'functional', 'hash_map', 'hash_map.h', 'hash_set',
- 'hash_set.h', 'iterator', 'list', 'list.h', 'map', 'memory', 'new',
- 'pair.h', 'pthread_alloc', 'queue', 'set', 'set.h', 'sstream', 'stack',
- 'stl_alloc.h', 'stl_relops.h', 'type_traits.h',
- 'utility', 'vector', 'vector.h',
- ])
-
-
-# Non-STL C++ system headers.
-_CPP_HEADERS = frozenset([
- 'algo.h', 'builtinbuf.h', 'bvector.h', 'cassert', 'cctype',
- 'cerrno', 'cfloat', 'ciso646', 'climits', 'clocale', 'cmath',
- 'complex', 'complex.h', 'csetjmp', 'csignal', 'cstdarg', 'cstddef',
- 'cstdio', 'cstdlib', 'cstring', 'ctime', 'cwchar', 'cwctype',
- 'defalloc.h', 'deque.h', 'editbuf.h', 'exception', 'fstream',
- 'fstream.h', 'hashtable.h', 'heap.h', 'indstream.h', 'iomanip',
- 'iomanip.h', 'ios', 'iosfwd', 'iostream', 'iostream.h', 'istream',
- 'istream.h', 'iterator.h', 'limits', 'map.h', 'multimap.h', 'multiset.h',
- 'numeric', 'ostream', 'ostream.h', 'parsestream.h', 'pfstream.h',
- 'PlotFile.h', 'procbuf.h', 'pthread_alloc.h', 'rope', 'rope.h',
- 'ropeimpl.h', 'SFile.h', 'slist', 'slist.h', 'stack.h', 'stdexcept',
- 'stdiostream.h', 'streambuf', 'streambuf.h', 'stream.h', 'strfile.h',
- 'string', 'strstream', 'strstream.h', 'tempbuf.h', 'tree.h', 'typeinfo',
- 'valarray',
- ])
-
-
-# Assertion macros. These are defined in base/logging.h and
-# testing/base/gunit.h. Note that the _M versions need to come first
-# for substring matching to work.
-_CHECK_MACROS = [
- 'DCHECK', 'CHECK',
- 'EXPECT_TRUE_M', 'EXPECT_TRUE',
- 'ASSERT_TRUE_M', 'ASSERT_TRUE',
- 'EXPECT_FALSE_M', 'EXPECT_FALSE',
- 'ASSERT_FALSE_M', 'ASSERT_FALSE',
- ]
-
-# Replacement macros for CHECK/DCHECK/EXPECT_TRUE/EXPECT_FALSE
-_CHECK_REPLACEMENT = dict([(m, {}) for m in _CHECK_MACROS])
-
-for op, replacement in [('==', 'EQ'), ('!=', 'NE'),
- ('>=', 'GE'), ('>', 'GT'),
- ('<=', 'LE'), ('<', 'LT')]:
- _CHECK_REPLACEMENT['DCHECK'][op] = 'DCHECK_%s' % replacement
- _CHECK_REPLACEMENT['CHECK'][op] = 'CHECK_%s' % replacement
- _CHECK_REPLACEMENT['EXPECT_TRUE'][op] = 'EXPECT_%s' % replacement
- _CHECK_REPLACEMENT['ASSERT_TRUE'][op] = 'ASSERT_%s' % replacement
- _CHECK_REPLACEMENT['EXPECT_TRUE_M'][op] = 'EXPECT_%s_M' % replacement
- _CHECK_REPLACEMENT['ASSERT_TRUE_M'][op] = 'ASSERT_%s_M' % replacement
-
-for op, inv_replacement in [('==', 'NE'), ('!=', 'EQ'),
- ('>=', 'LT'), ('>', 'LE'),
- ('<=', 'GT'), ('<', 'GE')]:
- _CHECK_REPLACEMENT['EXPECT_FALSE'][op] = 'EXPECT_%s' % inv_replacement
- _CHECK_REPLACEMENT['ASSERT_FALSE'][op] = 'ASSERT_%s' % inv_replacement
- _CHECK_REPLACEMENT['EXPECT_FALSE_M'][op] = 'EXPECT_%s_M' % inv_replacement
- _CHECK_REPLACEMENT['ASSERT_FALSE_M'][op] = 'ASSERT_%s_M' % inv_replacement
-
-# Alternative tokens and their replacements. For full list, see section 2.5
-# Alternative tokens [lex.digraph] in the C++ standard.
-#
-# Digraphs (such as '%:') are not included here since it's a mess to
-# match those on a word boundary.
-_ALT_TOKEN_REPLACEMENT = {
- 'and': '&&',
- 'bitor': '|',
- 'or': '||',
- 'xor': '^',
- 'compl': '~',
- 'bitand': '&',
- 'and_eq': '&=',
- 'or_eq': '|=',
- 'xor_eq': '^=',
- 'not': '!',
- 'not_eq': '!='
- }
-
-# Compile regular expression that matches all the above keywords. The "[ =()]"
-# bit is meant to avoid matching these keywords outside of boolean expressions.
-#
-# False positives include C-style multi-line comments (http://go/nsiut )
-# and multi-line strings (http://go/beujw ), but those have always been
-# troublesome for cpplint.
-_ALT_TOKEN_REPLACEMENT_PATTERN = re.compile(
- r'[ =()](' + ('|'.join(_ALT_TOKEN_REPLACEMENT.keys())) + r')(?=[ (]|$)')
-
-
-# These constants define types of headers for use with
-# _IncludeState.CheckNextIncludeOrder().
-_C_SYS_HEADER = 1
-_CPP_SYS_HEADER = 2
-_LIKELY_MY_HEADER = 3
-_POSSIBLE_MY_HEADER = 4
-_OTHER_HEADER = 5
-
-# These constants define the current inline assembly state
-_NO_ASM = 0 # Outside of inline assembly block
-_INSIDE_ASM = 1 # Inside inline assembly block
-_END_ASM = 2 # Last line of inline assembly block
-_BLOCK_ASM = 3 # The whole block is an inline assembly block
-
-# Match start of assembly blocks
-_MATCH_ASM = re.compile(r'^\s*(?:asm|_asm|__asm|__asm__)'
- r'(?:\s+(volatile|__volatile__))?'
- r'\s*[{(]')
-
-
-_regexp_compile_cache = {}
-
-# Finds occurrences of NOLINT or NOLINT(...).
-_RE_SUPPRESSION = re.compile(r'\bNOLINT\b(\([^)]*\))?')
-
-# {str, set(int)}: a map from error categories to sets of linenumbers
-# on which those errors are expected and should be suppressed.
-_error_suppressions = {}
-
-# The root directory used for deriving header guard CPP variable.
-# This is set by --root flag.
-_root = None
-
-def ParseNolintSuppressions(filename, raw_line, linenum, error):
- """Updates the global list of error-suppressions.
-
- Parses any NOLINT comments on the current line, updating the global
- error_suppressions store. Reports an error if the NOLINT comment
- was malformed.
-
- Args:
- filename: str, the name of the input file.
- raw_line: str, the line of input text, with comments.
- linenum: int, the number of the current line.
- error: function, an error handler.
- """
- # FIXME(adonovan): "NOLINT(" is misparsed as NOLINT(*).
- matched = _RE_SUPPRESSION.search(raw_line)
- if matched:
- category = matched.group(1)
- if category in (None, '(*)'): # => "suppress all"
- _error_suppressions.setdefault(None, set()).add(linenum)
- else:
- if category.startswith('(') and category.endswith(')'):
- category = category[1:-1]
- if category in _ERROR_CATEGORIES:
- _error_suppressions.setdefault(category, set()).add(linenum)
- else:
- error(filename, linenum, 'readability/nolint', 5,
- 'Unknown NOLINT error category: %s' % category)
-
-
-def ResetNolintSuppressions():
- "Resets the set of NOLINT suppressions to empty."
- _error_suppressions.clear()
-
-
-def IsErrorSuppressedByNolint(category, linenum):
- """Returns true if the specified error category is suppressed on this line.
-
- Consults the global error_suppressions map populated by
- ParseNolintSuppressions/ResetNolintSuppressions.
-
- Args:
- category: str, the category of the error.
- linenum: int, the current line number.
- Returns:
- bool, True iff the error should be suppressed due to a NOLINT comment.
- """
- return (linenum in _error_suppressions.get(category, set()) or
- linenum in _error_suppressions.get(None, set()))
-
-def Match(pattern, s):
- """Matches the string with the pattern, caching the compiled regexp."""
- # The regexp compilation caching is inlined in both Match and Search for
- # performance reasons; factoring it out into a separate function turns out
- # to be noticeably expensive.
- if not pattern in _regexp_compile_cache:
- _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
- return _regexp_compile_cache[pattern].match(s)
-
-
-def Search(pattern, s):
- """Searches the string for the pattern, caching the compiled regexp."""
- if not pattern in _regexp_compile_cache:
- _regexp_compile_cache[pattern] = sre_compile.compile(pattern)
- return _regexp_compile_cache[pattern].search(s)
-
-
-class _IncludeState(dict):
- """Tracks line numbers for includes, and the order in which includes appear.
-
- As a dict, an _IncludeState object serves as a mapping between include
- filename and line number on which that file was included.
-
- Call CheckNextIncludeOrder() once for each header in the file, passing
- in the type constants defined above. Calls in an illegal order will
- raise an _IncludeError with an appropriate error message.
-
- """
- # self._section will move monotonically through this set. If it ever
- # needs to move backwards, CheckNextIncludeOrder will raise an error.
- _INITIAL_SECTION = 0
- _MY_H_SECTION = 1
- _C_SECTION = 2
- _CPP_SECTION = 3
- _OTHER_H_SECTION = 4
-
- _TYPE_NAMES = {
- _C_SYS_HEADER: 'C system header',
- _CPP_SYS_HEADER: 'C++ system header',
- _LIKELY_MY_HEADER: 'header this file implements',
- _POSSIBLE_MY_HEADER: 'header this file may implement',
- _OTHER_HEADER: 'other header',
- }
- _SECTION_NAMES = {
- _INITIAL_SECTION: "... nothing. (This can't be an error.)",
- _MY_H_SECTION: 'a header this file implements',
- _C_SECTION: 'C system header',
- _CPP_SECTION: 'C++ system header',
- _OTHER_H_SECTION: 'other header',
- }
-
- def __init__(self):
- dict.__init__(self)
- # The name of the current section.
- self._section = self._INITIAL_SECTION
- # The path of last found header.
- self._last_header = ''
-
- def CanonicalizeAlphabeticalOrder(self, header_path):
- """Returns a path canonicalized for alphabetical comparison.
-
- - replaces "-" with "_" so they both cmp the same.
- - removes '-inl' since we don't require them to be after the main header.
- - lowercase everything, just in case.
-
- Args:
- header_path: Path to be canonicalized.
-
- Returns:
- Canonicalized path.
- """
- return header_path.replace('-inl.h', '.h').replace('-', '_').lower()
-
- def IsInAlphabeticalOrder(self, header_path):
- """Check if a header is in alphabetical order with the previous header.
-
- Args:
- header_path: Header to be checked.
-
- Returns:
- Returns true if the header is in alphabetical order.
- """
- canonical_header = self.CanonicalizeAlphabeticalOrder(header_path)
- if self._last_header > canonical_header:
- return False
- self._last_header = canonical_header
- return True
-
- def CheckNextIncludeOrder(self, header_type):
- """Returns a non-empty error message if the next header is out of order.
-
- This function also updates the internal state to be ready to check
- the next include.
-
- Args:
- header_type: One of the _XXX_HEADER constants defined above.
-
- Returns:
- The empty string if the header is in the right order, or an
- error message describing what's wrong.
-
- """
- error_message = ('Found %s after %s' %
- (self._TYPE_NAMES[header_type],
- self._SECTION_NAMES[self._section]))
-
- last_section = self._section
-
- if header_type == _C_SYS_HEADER:
- if self._section <= self._C_SECTION:
- self._section = self._C_SECTION
- else:
- self._last_header = ''
- return error_message
- elif header_type == _CPP_SYS_HEADER:
- if self._section <= self._CPP_SECTION:
- self._section = self._CPP_SECTION
- else:
- self._last_header = ''
- return error_message
- elif header_type == _LIKELY_MY_HEADER:
- if self._section <= self._MY_H_SECTION:
- self._section = self._MY_H_SECTION
- else:
- self._section = self._OTHER_H_SECTION
- elif header_type == _POSSIBLE_MY_HEADER:
- if self._section <= self._MY_H_SECTION:
- self._section = self._MY_H_SECTION
- else:
- # This will always be the fallback because we're not sure
- # enough that the header is associated with this file.
- self._section = self._OTHER_H_SECTION
- else:
- assert header_type == _OTHER_HEADER
- self._section = self._OTHER_H_SECTION
-
- if last_section != self._section:
- self._last_header = ''
-
- return ''
-
-
-class _CppLintState(object):
- """Maintains module-wide state.."""
-
- def __init__(self):
- self.verbose_level = 1 # global setting.
- self.error_count = 0 # global count of reported errors
- # filters to apply when emitting error messages
- self.filters = _DEFAULT_FILTERS[:]
- self.counting = 'total' # In what way are we counting errors?
- self.errors_by_category = {} # string to int dict storing error counts
-
- # output format:
- # "emacs" - format that emacs can parse (default)
- # "vs7" - format that Microsoft Visual Studio 7 can parse
- self.output_format = 'emacs'
-
- def SetOutputFormat(self, output_format):
- """Sets the output format for errors."""
- self.output_format = output_format
-
- def SetVerboseLevel(self, level):
- """Sets the module's verbosity, and returns the previous setting."""
- last_verbose_level = self.verbose_level
- self.verbose_level = level
- return last_verbose_level
-
- def SetCountingStyle(self, counting_style):
- """Sets the module's counting options."""
- self.counting = counting_style
-
- def SetFilters(self, filters):
- """Sets the error-message filters.
-
- These filters are applied when deciding whether to emit a given
- error message.
-
- Args:
- filters: A string of comma-separated filters (eg "+whitespace/indent").
- Each filter should start with + or -; else we die.
-
- Raises:
- ValueError: The comma-separated filters did not all start with '+' or '-'.
- E.g. "-,+whitespace,-whitespace/indent,whitespace/badfilter"
- """
- # Default filters always have less priority than the flag ones.
- self.filters = _DEFAULT_FILTERS[:]
- for filt in filters.split(','):
- clean_filt = filt.strip()
- if clean_filt:
- self.filters.append(clean_filt)
- for filt in self.filters:
- if not (filt.startswith('+') or filt.startswith('-')):
- raise ValueError('Every filter in --filters must start with + or -'
- ' (%s does not)' % filt)
-
- def ResetErrorCounts(self):
- """Sets the module's error statistic back to zero."""
- self.error_count = 0
- self.errors_by_category = {}
-
- def IncrementErrorCount(self, category):
- """Bumps the module's error statistic."""
- self.error_count += 1
- if self.counting in ('toplevel', 'detailed'):
- if self.counting != 'detailed':
- category = category.split('/')[0]
- if category not in self.errors_by_category:
- self.errors_by_category[category] = 0
- self.errors_by_category[category] += 1
-
- def PrintErrorCounts(self):
- """Print a summary of errors by category, and the total."""
- for category, count in self.errors_by_category.iteritems():
- sys.stderr.write('Category \'%s\' errors found: %d\n' %
- (category, count))
- sys.stderr.write('Total errors found: %d\n' % self.error_count)
-
-_cpplint_state = _CppLintState()
-
-
-def _OutputFormat():
- """Gets the module's output format."""
- return _cpplint_state.output_format
-
-
-def _SetOutputFormat(output_format):
- """Sets the module's output format."""
- _cpplint_state.SetOutputFormat(output_format)
-
-
-def _VerboseLevel():
- """Returns the module's verbosity setting."""
- return _cpplint_state.verbose_level
-
-
-def _SetVerboseLevel(level):
- """Sets the module's verbosity, and returns the previous setting."""
- return _cpplint_state.SetVerboseLevel(level)
-
-
-def _SetCountingStyle(level):
- """Sets the module's counting options."""
- _cpplint_state.SetCountingStyle(level)
-
-
-def _Filters():
- """Returns the module's list of output filters, as a list."""
- return _cpplint_state.filters
-
-
-def _SetFilters(filters):
- """Sets the module's error-message filters.
-
- These filters are applied when deciding whether to emit a given
- error message.
-
- Args:
- filters: A string of comma-separated filters (eg "whitespace/indent").
- Each filter should start with + or -; else we die.
- """
- _cpplint_state.SetFilters(filters)
-
-
-class _FunctionState(object):
- """Tracks current function name and the number of lines in its body."""
-
- _NORMAL_TRIGGER = 250 # for --v=0, 500 for --v=1, etc.
- _TEST_TRIGGER = 400 # about 50% more than _NORMAL_TRIGGER.
-
- def __init__(self):
- self.in_a_function = False
- self.lines_in_function = 0
- self.current_function = ''
-
- def Begin(self, function_name):
- """Start analyzing function body.
-
- Args:
- function_name: The name of the function being tracked.
- """
- self.in_a_function = True
- self.lines_in_function = 0
- self.current_function = function_name
-
- def Count(self):
- """Count line in current function body."""
- if self.in_a_function:
- self.lines_in_function += 1
-
- def Check(self, error, filename, linenum):
- """Report if too many lines in function body.
-
- Args:
- error: The function to call with any errors found.
- filename: The name of the current file.
- linenum: The number of the line to check.
- """
- if Match(r'T(EST|est)', self.current_function):
- base_trigger = self._TEST_TRIGGER
- else:
- base_trigger = self._NORMAL_TRIGGER
- trigger = base_trigger * 2**_VerboseLevel()
-
- if self.lines_in_function > trigger:
- error_level = int(math.log(self.lines_in_function / base_trigger, 2))
- # 50 => 0, 100 => 1, 200 => 2, 400 => 3, 800 => 4, 1600 => 5, ...
- if error_level > 5:
- error_level = 5
- error(filename, linenum, 'readability/fn_size', error_level,
- 'Small and focused functions are preferred:'
- ' %s has %d non-comment lines'
- ' (error triggered by exceeding %d lines).' % (
- self.current_function, self.lines_in_function, trigger))
-
- def End(self):
- """Stop analyzing function body."""
- self.in_a_function = False
-
-
-class _IncludeError(Exception):
- """Indicates a problem with the include order in a file."""
- pass
-
-
-class FileInfo:
- """Provides utility functions for filenames.
-
- FileInfo provides easy access to the components of a file's path
- relative to the project root.
- """
-
- def __init__(self, filename):
- self._filename = filename
-
- def FullName(self):
- """Make Windows paths like Unix."""
- return os.path.abspath(self._filename).replace('\\', '/')
-
- def RepositoryName(self):
- """FullName after removing the local path to the repository.
-
- If we have a real absolute path name here we can try to do something smart:
- detecting the root of the checkout and truncating /path/to/checkout from
- the name so that we get header guards that don't include things like
- "C:\Documents and Settings\..." or "/home/username/..." in them and thus
- people on different computers who have checked the source out to different
- locations won't see bogus errors.
- """
- fullname = self.FullName()
-
- if os.path.exists(fullname):
- project_dir = os.path.dirname(fullname)
-
- if os.path.exists(os.path.join(project_dir, ".svn")):
- # If there's a .svn file in the current directory, we recursively look
- # up the directory tree for the top of the SVN checkout
- root_dir = project_dir
- one_up_dir = os.path.dirname(root_dir)
- while os.path.exists(os.path.join(one_up_dir, ".svn")):
- root_dir = os.path.dirname(root_dir)
- one_up_dir = os.path.dirname(one_up_dir)
-
- prefix = os.path.commonprefix([root_dir, project_dir])
- return fullname[len(prefix) + 1:]
-
- # Not SVN <= 1.6? Try to find a git, hg, or svn top level directory by
- # searching up from the current path.
- root_dir = os.path.dirname(fullname)
- while (root_dir != os.path.dirname(root_dir) and
- not os.path.exists(os.path.join(root_dir, ".git")) and
- not os.path.exists(os.path.join(root_dir, ".hg")) and
- not os.path.exists(os.path.join(root_dir, ".svn"))):
- root_dir = os.path.dirname(root_dir)
-
- if (os.path.exists(os.path.join(root_dir, ".git")) or
- os.path.exists(os.path.join(root_dir, ".hg")) or
- os.path.exists(os.path.join(root_dir, ".svn"))):
- prefix = os.path.commonprefix([root_dir, project_dir])
- return fullname[len(prefix) + 1:]
-
- # Don't know what to do; header guard warnings may be wrong...
- return fullname
-
- def Split(self):
- """Splits the file into the directory, basename, and extension.
-
- For 'chrome/browser/browser.cc', Split() would
- return ('chrome/browser', 'browser', '.cc')
-
- Returns:
- A tuple of (directory, basename, extension).
- """
-
- googlename = self.RepositoryName()
- project, rest = os.path.split(googlename)
- return (project,) + os.path.splitext(rest)
-
- def BaseName(self):
- """File base name - text after the final slash, before the final period."""
- return self.Split()[1]
-
- def Extension(self):
- """File extension - text following the final period."""
- return self.Split()[2]
-
- def NoExtension(self):
- """File has no source file extension."""
- return '/'.join(self.Split()[0:2])
-
- def IsSource(self):
- """File has a source file extension."""
- return self.Extension()[1:] in ('c', 'cc', 'cpp', 'cxx')
-
-
-def _ShouldPrintError(category, confidence, linenum):
- """If confidence >= verbose, category passes filter and is not suppressed."""
-
- # There are three ways we might decide not to print an error message:
- # a "NOLINT(category)" comment appears in the source,
- # the verbosity level isn't high enough, or the filters filter it out.
- if IsErrorSuppressedByNolint(category, linenum):
- return False
- if confidence < _cpplint_state.verbose_level:
- return False
-
- is_filtered = False
- for one_filter in _Filters():
- if one_filter.startswith('-'):
- if category.startswith(one_filter[1:]):
- is_filtered = True
- elif one_filter.startswith('+'):
- if category.startswith(one_filter[1:]):
- is_filtered = False
- else:
- assert False # should have been checked for in SetFilter.
- if is_filtered:
- return False
-
- return True
-
-
-def Error(filename, linenum, category, confidence, message):
- """Logs the fact we've found a lint error.
-
- We log where the error was found, and also our confidence in the error,
- that is, how certain we are this is a legitimate style regression, and
- not a misidentification or a use that's sometimes justified.
-
- False positives can be suppressed by the use of
- "cpplint(category)" comments on the offending line. These are
- parsed into _error_suppressions.
-
- Args:
- filename: The name of the file containing the error.
- linenum: The number of the line containing the error.
- category: A string used to describe the "category" this bug
- falls under: "whitespace", say, or "runtime". Categories
- may have a hierarchy separated by slashes: "whitespace/indent".
- confidence: A number from 1-5 representing a confidence score for
- the error, with 5 meaning that we are certain of the problem,
- and 1 meaning that it could be a legitimate construct.
- message: The error message.
- """
- if _ShouldPrintError(category, confidence, linenum):
- _cpplint_state.IncrementErrorCount(category)
- if _cpplint_state.output_format == 'vs7':
- sys.stderr.write('%s(%s): %s [%s] [%d]\n' % (
- filename, linenum, message, category, confidence))
- elif _cpplint_state.output_format == 'eclipse':
- sys.stderr.write('%s:%s: warning: %s [%s] [%d]\n' % (
- filename, linenum, message, category, confidence))
- else:
- sys.stderr.write('%s:%s: %s [%s] [%d]\n' % (
- filename, linenum, message, category, confidence))
-
-
-# Matches standard C++ escape esequences per 2.13.2.3 of the C++ standard.
-_RE_PATTERN_CLEANSE_LINE_ESCAPES = re.compile(
- r'\\([abfnrtv?"\\\']|\d+|x[0-9a-fA-F]+)')
-# Matches strings. Escape codes should already be removed by ESCAPES.
-_RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES = re.compile(r'"[^"]*"')
-# Matches characters. Escape codes should already be removed by ESCAPES.
-_RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES = re.compile(r"'.'")
-# Matches multi-line C++ comments.
-# This RE is a little bit more complicated than one might expect, because we
-# have to take care of space removals tools so we can handle comments inside
-# statements better.
-# The current rule is: We only clear spaces from both sides when we're at the
-# end of the line. Otherwise, we try to remove spaces from the right side,
-# if this doesn't work we try on left side but only if there's a non-character
-# on the right.
-_RE_PATTERN_CLEANSE_LINE_C_COMMENTS = re.compile(
- r"""(\s*/\*.*\*/\s*$|
- /\*.*\*/\s+|
- \s+/\*.*\*/(?=\W)|
- /\*.*\*/)""", re.VERBOSE)
-
-
-def IsCppString(line):
- """Does line terminate so, that the next symbol is in string constant.
-
- This function does not consider single-line nor multi-line comments.
-
- Args:
- line: is a partial line of code starting from the 0..n.
-
- Returns:
- True, if next character appended to 'line' is inside a
- string constant.
- """
-
- line = line.replace(r'\\', 'XX') # after this, \\" does not match to \"
- return ((line.count('"') - line.count(r'\"') - line.count("'\"'")) & 1) == 1
-
-
-def FindNextMultiLineCommentStart(lines, lineix):
- """Find the beginning marker for a multiline comment."""
- while lineix < len(lines):
- if lines[lineix].strip().startswith('/*'):
- # Only return this marker if the comment goes beyond this line
- if lines[lineix].strip().find('*/', 2) < 0:
- return lineix
- lineix += 1
- return len(lines)
-
-
-def FindNextMultiLineCommentEnd(lines, lineix):
- """We are inside a comment, find the end marker."""
- while lineix < len(lines):
- if lines[lineix].strip().endswith('*/'):
- return lineix
- lineix += 1
- return len(lines)
-
-
-def RemoveMultiLineCommentsFromRange(lines, begin, end):
- """Clears a range of lines for multi-line comments."""
- # Having // dummy comments makes the lines non-empty, so we will not get
- # unnecessary blank line warnings later in the code.
- for i in range(begin, end):
- lines[i] = '// dummy'
-
-
-def RemoveMultiLineComments(filename, lines, error):
- """Removes multiline (c-style) comments from lines."""
- lineix = 0
- while lineix < len(lines):
- lineix_begin = FindNextMultiLineCommentStart(lines, lineix)
- if lineix_begin >= len(lines):
- return
- lineix_end = FindNextMultiLineCommentEnd(lines, lineix_begin)
- if lineix_end >= len(lines):
- error(filename, lineix_begin + 1, 'readability/multiline_comment', 5,
- 'Could not find end of multi-line comment')
- return
- RemoveMultiLineCommentsFromRange(lines, lineix_begin, lineix_end + 1)
- lineix = lineix_end + 1
-
-
-def CleanseComments(line):
- """Removes //-comments and single-line C-style /* */ comments.
-
- Args:
- line: A line of C++ source.
-
- Returns:
- The line with single-line comments removed.
- """
- commentpos = line.find('//')
- if commentpos != -1 and not IsCppString(line[:commentpos]):
- line = line[:commentpos].rstrip()
- # get rid of /* ... */
- return _RE_PATTERN_CLEANSE_LINE_C_COMMENTS.sub('', line)
-
-
-class CleansedLines(object):
- """Holds 3 copies of all lines with different preprocessing applied to them.
-
- 1) elided member contains lines without strings and comments,
- 2) lines member contains lines without comments, and
- 3) raw_lines member contains all the lines without processing.
- All these three members are of <type 'list'>, and of the same length.
- """
-
- def __init__(self, lines):
- self.elided = []
- self.lines = []
- self.raw_lines = lines
- self.num_lines = len(lines)
- for linenum in range(len(lines)):
- self.lines.append(CleanseComments(lines[linenum]))
- elided = self._CollapseStrings(lines[linenum])
- self.elided.append(CleanseComments(elided))
-
- def NumLines(self):
- """Returns the number of lines represented."""
- return self.num_lines
-
- @staticmethod
- def _CollapseStrings(elided):
- """Collapses strings and chars on a line to simple "" or '' blocks.
-
- We nix strings first so we're not fooled by text like '"http://"'
-
- Args:
- elided: The line being processed.
-
- Returns:
- The line with collapsed strings.
- """
- if not _RE_PATTERN_INCLUDE.match(elided):
- # Remove escaped characters first to make quote/single quote collapsing
- # basic. Things that look like escaped characters shouldn't occur
- # outside of strings and chars.
- elided = _RE_PATTERN_CLEANSE_LINE_ESCAPES.sub('', elided)
- elided = _RE_PATTERN_CLEANSE_LINE_SINGLE_QUOTES.sub("''", elided)
- elided = _RE_PATTERN_CLEANSE_LINE_DOUBLE_QUOTES.sub('""', elided)
- return elided
-
-
-def FindEndOfExpressionInLine(line, startpos, depth, startchar, endchar):
- """Find the position just after the matching endchar.
-
- Args:
- line: a CleansedLines line.
- startpos: start searching at this position.
- depth: nesting level at startpos.
- startchar: expression opening character.
- endchar: expression closing character.
-
- Returns:
- Index just after endchar.
- """
- for i in xrange(startpos, len(line)):
- if line[i] == startchar:
- depth += 1
- elif line[i] == endchar:
- depth -= 1
- if depth == 0:
- return i + 1
- return -1
-
-
-def CloseExpression(clean_lines, linenum, pos):
- """If input points to ( or { or [, finds the position that closes it.
-
- If lines[linenum][pos] points to a '(' or '{' or '[', finds the
- linenum/pos that correspond to the closing of the expression.
-
- Args:
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- pos: A position on the line.
-
- Returns:
- A tuple (line, linenum, pos) pointer *past* the closing brace, or
- (line, len(lines), -1) if we never find a close. Note we ignore
- strings and comments when matching; and the line we return is the
- 'cleansed' line at linenum.
- """
-
- line = clean_lines.elided[linenum]
- startchar = line[pos]
- if startchar not in '({[':
- return (line, clean_lines.NumLines(), -1)
- if startchar == '(': endchar = ')'
- if startchar == '[': endchar = ']'
- if startchar == '{': endchar = '}'
-
- # Check first line
- end_pos = FindEndOfExpressionInLine(line, pos, 0, startchar, endchar)
- if end_pos > -1:
- return (line, linenum, end_pos)
- tail = line[pos:]
- num_open = tail.count(startchar) - tail.count(endchar)
- while linenum < clean_lines.NumLines() - 1:
- linenum += 1
- line = clean_lines.elided[linenum]
- delta = line.count(startchar) - line.count(endchar)
- if num_open + delta <= 0:
- return (line, linenum,
- FindEndOfExpressionInLine(line, 0, num_open, startchar, endchar))
- num_open += delta
-
- # Did not find endchar before end of file, give up
- return (line, clean_lines.NumLines(), -1)
-
-def CheckForCopyright(filename, lines, error):
- """Logs an error if no Copyright message appears at the top of the file."""
-
- # We'll say it should occur by line 10. Don't forget there's a
- # dummy line at the front.
- for line in xrange(1, min(len(lines), 11)):
- if re.search(r'Copyright', lines[line], re.I): break
- else: # means no copyright line was found
- error(filename, 0, 'legal/copyright', 5,
- 'No copyright message found. '
- 'You should have a line: "Copyright [year] <Copyright Owner>"')
-
-
-def GetHeaderGuardCPPVariable(filename):
- """Returns the CPP variable that should be used as a header guard.
-
- Args:
- filename: The name of a C++ header file.
-
- Returns:
- The CPP variable that should be used as a header guard in the
- named file.
-
- """
-
- # Restores original filename in case that cpplint is invoked from Emacs's
- # flymake.
- filename = re.sub(r'_flymake\.h$', '.h', filename)
- filename = re.sub(r'/\.flymake/([^/]*)$', r'/\1', filename)
-
- fileinfo = FileInfo(filename)
- file_path_from_root = fileinfo.RepositoryName()
- if _root:
- file_path_from_root = re.sub('^' + _root + os.sep, '', file_path_from_root)
- return re.sub(r'[-./\s]', '_', file_path_from_root).upper() + '_'
-
-
-def CheckForHeaderGuard(filename, lines, error):
- """Checks that the file contains a header guard.
-
- Logs an error if no #ifndef header guard is present. For other
- headers, checks that the full pathname is used.
-
- Args:
- filename: The name of the C++ header file.
- lines: An array of strings, each representing a line of the file.
- error: The function to call with any errors found.
- """
-
- cppvar = GetHeaderGuardCPPVariable(filename)
-
- ifndef = None
- ifndef_linenum = 0
- define = None
- endif = None
- endif_linenum = 0
- for linenum, line in enumerate(lines):
- linesplit = line.split()
- if len(linesplit) >= 2:
- # find the first occurrence of #ifndef and #define, save arg
- if not ifndef and linesplit[0] == '#ifndef':
- # set ifndef to the header guard presented on the #ifndef line.
- ifndef = linesplit[1]
- ifndef_linenum = linenum
- if not define and linesplit[0] == '#define':
- define = linesplit[1]
- # find the last occurrence of #endif, save entire line
- if line.startswith('#endif'):
- endif = line
- endif_linenum = linenum
-
- if not ifndef:
- error(filename, 0, 'build/header_guard', 5,
- 'No #ifndef header guard found, suggested CPP variable is: %s' %
- cppvar)
- return
-
- if not define:
- error(filename, 0, 'build/header_guard', 5,
- 'No #define header guard found, suggested CPP variable is: %s' %
- cppvar)
- return
-
- # The guard should be PATH_FILE_H_, but we also allow PATH_FILE_H__
- # for backward compatibility.
- if ifndef != cppvar:
- error_level = 0
- if ifndef != cppvar + '_':
- error_level = 5
-
- ParseNolintSuppressions(filename, lines[ifndef_linenum], ifndef_linenum,
- error)
- error(filename, ifndef_linenum, 'build/header_guard', error_level,
- '#ifndef header guard has wrong style, please use: %s' % cppvar)
-
- if define != ifndef:
- error(filename, 0, 'build/header_guard', 5,
- '#ifndef and #define don\'t match, suggested CPP variable is: %s' %
- cppvar)
- return
-
- if endif != ('#endif // %s' % cppvar):
- error_level = 0
- if endif != ('#endif // %s' % (cppvar + '_')):
- error_level = 5
-
- ParseNolintSuppressions(filename, lines[endif_linenum], endif_linenum,
- error)
- error(filename, endif_linenum, 'build/header_guard', error_level,
- '#endif line should be "#endif // %s"' % cppvar)
-
-
-def CheckForUnicodeReplacementCharacters(filename, lines, error):
- """Logs an error for each line containing Unicode replacement characters.
-
- These indicate that either the file contained invalid UTF-8 (likely)
- or Unicode replacement characters (which it shouldn't). Note that
- it's possible for this to throw off line numbering if the invalid
- UTF-8 occurred adjacent to a newline.
-
- Args:
- filename: The name of the current file.
- lines: An array of strings, each representing a line of the file.
- error: The function to call with any errors found.
- """
- for linenum, line in enumerate(lines):
- if u'\ufffd' in line:
- error(filename, linenum, 'readability/utf8', 5,
- 'Line contains invalid UTF-8 (or Unicode replacement character).')
-
-
-def CheckForNewlineAtEOF(filename, lines, error):
- """Logs an error if there is no newline char at the end of the file.
-
- Args:
- filename: The name of the current file.
- lines: An array of strings, each representing a line of the file.
- error: The function to call with any errors found.
- """
-
- # The array lines() was created by adding two newlines to the
- # original file (go figure), then splitting on \n.
- # To verify that the file ends in \n, we just have to make sure the
- # last-but-two element of lines() exists and is empty.
- if len(lines) < 3 or lines[-2]:
- error(filename, len(lines) - 2, 'whitespace/ending_newline', 5,
- 'Could not find a newline character at the end of the file.')
-
-
-def CheckForMultilineCommentsAndStrings(filename, clean_lines, linenum, error):
- """Logs an error if we see /* ... */ or "..." that extend past one line.
-
- /* ... */ comments are legit inside macros, for one line.
- Otherwise, we prefer // comments, so it's ok to warn about the
- other. Likewise, it's ok for strings to extend across multiple
- lines, as long as a line continuation character (backslash)
- terminates each line. Although not currently prohibited by the C++
- style guide, it's ugly and unnecessary. We don't do well with either
- in this lint program, so we warn about both.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- error: The function to call with any errors found.
- """
- line = clean_lines.elided[linenum]
-
- # Remove all \\ (escaped backslashes) from the line. They are OK, and the
- # second (escaped) slash may trigger later \" detection erroneously.
- line = line.replace('\\\\', '')
-
- if line.count('/*') > line.count('*/'):
- error(filename, linenum, 'readability/multiline_comment', 5,
- 'Complex multi-line /*...*/-style comment found. '
- 'Lint may give bogus warnings. '
- 'Consider replacing these with //-style comments, '
- 'with #if 0...#endif, '
- 'or with more clearly structured multi-line comments.')
-
- if (line.count('"') - line.count('\\"')) % 2:
- error(filename, linenum, 'readability/multiline_string', 5,
- 'Multi-line string ("...") found. This lint script doesn\'t '
- 'do well with such strings, and may give bogus warnings. They\'re '
- 'ugly and unnecessary, and you should use concatenation instead".')
-
-
-threading_list = (
- ('asctime(', 'asctime_r('),
- ('ctime(', 'ctime_r('),
- ('getgrgid(', 'getgrgid_r('),
- ('getgrnam(', 'getgrnam_r('),
- ('getlogin(', 'getlogin_r('),
- ('getpwnam(', 'getpwnam_r('),
- ('getpwuid(', 'getpwuid_r('),
- ('gmtime(', 'gmtime_r('),
- ('localtime(', 'localtime_r('),
- ('rand(', 'rand_r('),
- ('readdir(', 'readdir_r('),
- ('strtok(', 'strtok_r('),
- ('ttyname(', 'ttyname_r('),
- )
-
-
-def CheckPosixThreading(filename, clean_lines, linenum, error):
- """Checks for calls to thread-unsafe functions.
-
- Much code has been originally written without consideration of
- multi-threading. Also, engineers are relying on their old experience;
- they have learned posix before threading extensions were added. These
- tests guide the engineers to use thread-safe functions (when using
- posix directly).
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- error: The function to call with any errors found.
- """
- line = clean_lines.elided[linenum]
- for single_thread_function, multithread_safe_function in threading_list:
- ix = line.find(single_thread_function)
- # Comparisons made explicit for clarity -- pylint: disable-msg=C6403
- if ix >= 0 and (ix == 0 or (not line[ix - 1].isalnum() and
- line[ix - 1] not in ('_', '.', '>'))):
- error(filename, linenum, 'runtime/threadsafe_fn', 2,
- 'Consider using ' + multithread_safe_function +
- '...) instead of ' + single_thread_function +
- '...) for improved thread safety.')
-
-
-# Matches invalid increment: *count++, which moves pointer instead of
-# incrementing a value.
-_RE_PATTERN_INVALID_INCREMENT = re.compile(
- r'^\s*\*\w+(\+\+|--);')
-
-
-def CheckInvalidIncrement(filename, clean_lines, linenum, error):
- """Checks for invalid increment *count++.
-
- For example following function:
- void increment_counter(int* count) {
- *count++;
- }
- is invalid, because it effectively does count++, moving pointer, and should
- be replaced with ++*count, (*count)++ or *count += 1.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- error: The function to call with any errors found.
- """
- line = clean_lines.elided[linenum]
- if _RE_PATTERN_INVALID_INCREMENT.match(line):
- error(filename, linenum, 'runtime/invalid_increment', 5,
- 'Changing pointer instead of value (or unused value of operator*).')
-
-
-class _BlockInfo(object):
- """Stores information about a generic block of code."""
-
- def __init__(self, seen_open_brace):
- self.seen_open_brace = seen_open_brace
- self.open_parentheses = 0
- self.inline_asm = _NO_ASM
-
- def CheckBegin(self, filename, clean_lines, linenum, error):
- """Run checks that applies to text up to the opening brace.
-
- This is mostly for checking the text after the class identifier
- and the "{", usually where the base class is specified. For other
- blocks, there isn't much to check, so we always pass.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- error: The function to call with any errors found.
- """
- pass
-
- def CheckEnd(self, filename, clean_lines, linenum, error):
- """Run checks that applies to text after the closing brace.
-
- This is mostly used for checking end of namespace comments.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- error: The function to call with any errors found.
- """
- pass
-
-
-class _ClassInfo(_BlockInfo):
- """Stores information about a class."""
-
- def __init__(self, name, class_or_struct, clean_lines, linenum):
- _BlockInfo.__init__(self, False)
- self.name = name
- self.starting_linenum = linenum
- self.is_derived = False
- if class_or_struct == 'struct':
- self.access = 'public'
- else:
- self.access = 'private'
-
- # Try to find the end of the class. This will be confused by things like:
- # class A {
- # } *x = { ...
- #
- # But it's still good enough for CheckSectionSpacing.
- self.last_line = 0
- depth = 0
- for i in range(linenum, clean_lines.NumLines()):
- line = clean_lines.elided[i]
- depth += line.count('{') - line.count('}')
- if not depth:
- self.last_line = i
- break
-
- def CheckBegin(self, filename, clean_lines, linenum, error):
- # Look for a bare ':'
- if Search('(^|[^:]):($|[^:])', clean_lines.elided[linenum]):
- self.is_derived = True
-
-
-class _NamespaceInfo(_BlockInfo):
- """Stores information about a namespace."""
-
- def __init__(self, name, linenum):
- _BlockInfo.__init__(self, False)
- self.name = name or ''
- self.starting_linenum = linenum
-
- def CheckEnd(self, filename, clean_lines, linenum, error):
- """Check end of namespace comments."""
- line = clean_lines.raw_lines[linenum]
-
- # Check how many lines is enclosed in this namespace. Don't issue
- # warning for missing namespace comments if there aren't enough
- # lines. However, do apply checks if there is already an end of
- # namespace comment and it's incorrect.
- #
- # TODO(unknown): We always want to check end of namespace comments
- # if a namespace is large, but sometimes we also want to apply the
- # check if a short namespace contained nontrivial things (something
- # other than forward declarations). There is currently no logic on
- # deciding what these nontrivial things are, so this check is
- # triggered by namespace size only, which works most of the time.
- if (linenum - self.starting_linenum < 10
- and not Match(r'};*\s*(//|/\*).*\bnamespace\b', line)):
- return
-
- # Look for matching comment at end of namespace.
- #
- # Note that we accept C style "/* */" comments for terminating
- # namespaces, so that code that terminate namespaces inside
- # preprocessor macros can be cpplint clean. Example: http://go/nxpiz
- #
- # We also accept stuff like "// end of namespace <name>." with the
- # period at the end.
- #
- # Besides these, we don't accept anything else, otherwise we might
- # get false negatives when existing comment is a substring of the
- # expected namespace. Example: http://go/ldkdc, http://cl/23548205
- if self.name:
- # Named namespace
- if not Match((r'};*\s*(//|/\*).*\bnamespace\s+' + re.escape(self.name) +
- r'[\*/\.\\\s]*$'),
- line):
- error(filename, linenum, 'readability/namespace', 5,
- 'Namespace should be terminated with "// namespace %s"' %
- self.name)
- else:
- # Anonymous namespace
- if not Match(r'};*\s*(//|/\*).*\bnamespace[\*/\.\\\s]*$', line):
- error(filename, linenum, 'readability/namespace', 5,
- 'Namespace should be terminated with "// namespace"')
-
-
-class _PreprocessorInfo(object):
- """Stores checkpoints of nesting stacks when #if/#else is seen."""
-
- def __init__(self, stack_before_if):
- # The entire nesting stack before #if
- self.stack_before_if = stack_before_if
-
- # The entire nesting stack up to #else
- self.stack_before_else = []
-
- # Whether we have already seen #else or #elif
- self.seen_else = False
-
-
-class _NestingState(object):
- """Holds states related to parsing braces."""
-
- def __init__(self):
- # Stack for tracking all braces. An object is pushed whenever we
- # see a "{", and popped when we see a "}". Only 3 types of
- # objects are possible:
- # - _ClassInfo: a class or struct.
- # - _NamespaceInfo: a namespace.
- # - _BlockInfo: some other type of block.
- self.stack = []
-
- # Stack of _PreprocessorInfo objects.
- self.pp_stack = []
-
- def SeenOpenBrace(self):
- """Check if we have seen the opening brace for the innermost block.
-
- Returns:
- True if we have seen the opening brace, False if the innermost
- block is still expecting an opening brace.
- """
- return (not self.stack) or self.stack[-1].seen_open_brace
-
- def InNamespaceBody(self):
- """Check if we are currently one level inside a namespace body.
-
- Returns:
- True if top of the stack is a namespace block, False otherwise.
- """
- return self.stack and isinstance(self.stack[-1], _NamespaceInfo)
-
- def UpdatePreprocessor(self, line):
- """Update preprocessor stack.
-
- We need to handle preprocessors due to classes like this:
- #ifdef SWIG
- struct ResultDetailsPageElementExtensionPoint {
- #else
- struct ResultDetailsPageElementExtensionPoint : public Extension {
- #endif
- (see http://go/qwddn for original example)
-
- We make the following assumptions (good enough for most files):
- - Preprocessor condition evaluates to true from #if up to first
- #else/#elif/#endif.
-
- - Preprocessor condition evaluates to false from #else/#elif up
- to #endif. We still perform lint checks on these lines, but
- these do not affect nesting stack.
-
- Args:
- line: current line to check.
- """
- if Match(r'^\s*#\s*(if|ifdef|ifndef)\b', line):
- # Beginning of #if block, save the nesting stack here. The saved
- # stack will allow us to restore the parsing state in the #else case.
- self.pp_stack.append(_PreprocessorInfo(copy.deepcopy(self.stack)))
- elif Match(r'^\s*#\s*(else|elif)\b', line):
- # Beginning of #else block
- if self.pp_stack:
- if not self.pp_stack[-1].seen_else:
- # This is the first #else or #elif block. Remember the
- # whole nesting stack up to this point. This is what we
- # keep after the #endif.
- self.pp_stack[-1].seen_else = True
- self.pp_stack[-1].stack_before_else = copy.deepcopy(self.stack)
-
- # Restore the stack to how it was before the #if
- self.stack = copy.deepcopy(self.pp_stack[-1].stack_before_if)
- else:
- # TODO(unknown): unexpected #else, issue warning?
- pass
- elif Match(r'^\s*#\s*endif\b', line):
- # End of #if or #else blocks.
- if self.pp_stack:
- # If we saw an #else, we will need to restore the nesting
- # stack to its former state before the #else, otherwise we
- # will just continue from where we left off.
- if self.pp_stack[-1].seen_else:
- # Here we can just use a shallow copy since we are the last
- # reference to it.
- self.stack = self.pp_stack[-1].stack_before_else
- # Drop the corresponding #if
- self.pp_stack.pop()
- else:
- # TODO(unknown): unexpected #endif, issue warning?
- pass
-
- def Update(self, filename, clean_lines, linenum, error):
- """Update nesting state with current line.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- error: The function to call with any errors found.
- """
- line = clean_lines.elided[linenum]
-
- # Update pp_stack first
- self.UpdatePreprocessor(line)
-
- # Count parentheses. This is to avoid adding struct arguments to
- # the nesting stack.
- if self.stack:
- inner_block = self.stack[-1]
- depth_change = line.count('(') - line.count(')')
- inner_block.open_parentheses += depth_change
-
- # Also check if we are starting or ending an inline assembly block.
- if inner_block.inline_asm in (_NO_ASM, _END_ASM):
- if (depth_change != 0 and
- inner_block.open_parentheses == 1 and
- _MATCH_ASM.match(line)):
- # Enter assembly block
- inner_block.inline_asm = _INSIDE_ASM
- else:
- # Not entering assembly block. If previous line was _END_ASM,
- # we will now shift to _NO_ASM state.
- inner_block.inline_asm = _NO_ASM
- elif (inner_block.inline_asm == _INSIDE_ASM and
- inner_block.open_parentheses == 0):
- # Exit assembly block
- inner_block.inline_asm = _END_ASM
-
- # Consume namespace declaration at the beginning of the line. Do
- # this in a loop so that we catch same line declarations like this:
- # namespace proto2 { namespace bridge { class MessageSet; } }
- while True:
- # Match start of namespace. The "\b\s*" below catches namespace
- # declarations even if it weren't followed by a whitespace, this
- # is so that we don't confuse our namespace checker. The
- # missing spaces will be flagged by CheckSpacing.
- namespace_decl_match = Match(r'^\s*namespace\b\s*([:\w]+)?(.*)$', line)
- if not namespace_decl_match:
- break
-
- new_namespace = _NamespaceInfo(namespace_decl_match.group(1), linenum)
- self.stack.append(new_namespace)
-
- line = namespace_decl_match.group(2)
- if line.find('{') != -1:
- new_namespace.seen_open_brace = True
- line = line[line.find('{') + 1:]
-
- # Look for a class declaration in whatever is left of the line
- # after parsing namespaces. The regexp accounts for decorated classes
- # such as in:
- # class LOCKABLE API Object {
- # };
- #
- # Templates with class arguments may confuse the parser, for example:
- # template <class T
- # class Comparator = less<T>,
- # class Vector = vector<T> >
- # class HeapQueue {
- #
- # Because this parser has no nesting state about templates, by the
- # time it saw "class Comparator", it may think that it's a new class.
- # Nested templates have a similar problem:
- # template <
- # typename ExportedType,
- # typename TupleType,
- # template <typename, typename> class ImplTemplate>
- #
- # To avoid these cases, we ignore classes that are followed by '=' or '>'
- class_decl_match = Match(
- r'\s*(template\s*<[\w\s<>,:]*>\s*)?'
- '(class|struct)\s+([A-Z_]+\s+)*(\w+(?:::\w+)*)'
- '(([^=>]|<[^<>]*>)*)$', line)
- if (class_decl_match and
- (not self.stack or self.stack[-1].open_parentheses == 0)):
- self.stack.append(_ClassInfo(
- class_decl_match.group(4), class_decl_match.group(2),
- clean_lines, linenum))
- line = class_decl_match.group(5)
-
- # If we have not yet seen the opening brace for the innermost block,
- # run checks here.
- if not self.SeenOpenBrace():
- self.stack[-1].CheckBegin(filename, clean_lines, linenum, error)
-
- # Update access control if we are inside a class/struct
- if self.stack and isinstance(self.stack[-1], _ClassInfo):
- access_match = Match(r'\s*(public|private|protected)\s*:', line)
- if access_match:
- self.stack[-1].access = access_match.group(1)
-
- # Consume braces or semicolons from what's left of the line
- while True:
- # Match first brace, semicolon, or closed parenthesis.
- matched = Match(r'^[^{;)}]*([{;)}])(.*)$', line)
- if not matched:
- break
-
- token = matched.group(1)
- if token == '{':
- # If namespace or class hasn't seen a opening brace yet, mark
- # namespace/class head as complete. Push a new block onto the
- # stack otherwise.
- if not self.SeenOpenBrace():
- self.stack[-1].seen_open_brace = True
- else:
- self.stack.append(_BlockInfo(True))
- if _MATCH_ASM.match(line):
- self.stack[-1].inline_asm = _BLOCK_ASM
- elif token == ';' or token == ')':
- # If we haven't seen an opening brace yet, but we already saw
- # a semicolon, this is probably a forward declaration. Pop
- # the stack for these.
- #
- # Similarly, if we haven't seen an opening brace yet, but we
- # already saw a closing parenthesis, then these are probably
- # function arguments with extra "class" or "struct" keywords.
- # Also pop these stack for these.
- if not self.SeenOpenBrace():
- self.stack.pop()
- else: # token == '}'
- # Perform end of block checks and pop the stack.
- if self.stack:
- self.stack[-1].CheckEnd(filename, clean_lines, linenum, error)
- self.stack.pop()
- line = matched.group(2)
-
- def InnermostClass(self):
- """Get class info on the top of the stack.
-
- Returns:
- A _ClassInfo object if we are inside a class, or None otherwise.
- """
- for i in range(len(self.stack), 0, -1):
- classinfo = self.stack[i - 1]
- if isinstance(classinfo, _ClassInfo):
- return classinfo
- return None
-
- def CheckClassFinished(self, filename, error):
- """Checks that all classes have been completely parsed.
-
- Call this when all lines in a file have been processed.
- Args:
- filename: The name of the current file.
- error: The function to call with any errors found.
- """
- # Note: This test can result in false positives if #ifdef constructs
- # get in the way of brace matching. See the testBuildClass test in
- # cpplint_unittest.py for an example of this.
- for obj in self.stack:
- if isinstance(obj, _ClassInfo):
- error(filename, obj.starting_linenum, 'build/class', 5,
- 'Failed to find complete declaration of class %s' %
- obj.name)
-
-
-def CheckForNonStandardConstructs(filename, clean_lines, linenum,
- nesting_state, error):
- """Logs an error if we see certain non-ANSI constructs ignored by gcc-2.
-
- Complain about several constructs which gcc-2 accepts, but which are
- not standard C++. Warning about these in lint is one way to ease the
- transition to new compilers.
- - put storage class first (e.g. "static const" instead of "const static").
- - "%lld" instead of %qd" in printf-type functions.
- - "%1$d" is non-standard in printf-type functions.
- - "\%" is an undefined character escape sequence.
- - text after #endif is not allowed.
- - invalid inner-style forward declaration.
- - >? and <? operators, and their >?= and <?= cousins.
-
- Additionally, check for constructor/destructor style violations and reference
- members, as it is very convenient to do so while checking for
- gcc-2 compliance.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- nesting_state: A _NestingState instance which maintains information about
- the current stack of nested blocks being parsed.
- error: A callable to which errors are reported, which takes 4 arguments:
- filename, line number, error level, and message
- """
-
- # Remove comments from the line, but leave in strings for now.
- line = clean_lines.lines[linenum]
-
- if Search(r'printf\s*\(.*".*%[-+ ]?\d*q', line):
- error(filename, linenum, 'runtime/printf_format', 3,
- '%q in format strings is deprecated. Use %ll instead.')
-
- if Search(r'printf\s*\(.*".*%\d+\$', line):
- error(filename, linenum, 'runtime/printf_format', 2,
- '%N$ formats are unconventional. Try rewriting to avoid them.')
-
- # Remove escaped backslashes before looking for undefined escapes.
- line = line.replace('\\\\', '')
-
- if Search(r'("|\').*\\(%|\[|\(|{)', line):
- error(filename, linenum, 'build/printf_format', 3,
- '%, [, (, and { are undefined character escapes. Unescape them.')
-
- # For the rest, work with both comments and strings removed.
- line = clean_lines.elided[linenum]
-
- if Search(r'\b(const|volatile|void|char|short|int|long'
- r'|float|double|signed|unsigned'
- r'|schar|u?int8|u?int16|u?int32|u?int64)'
- r'\s+(register|static|extern|typedef)\b',
- line):
- error(filename, linenum, 'build/storage_class', 5,
- 'Storage class (static, extern, typedef, etc) should be first.')
-
- if Match(r'\s*#\s*endif\s*[^/\s]+', line):
- error(filename, linenum, 'build/endif_comment', 5,
- 'Uncommented text after #endif is non-standard. Use a comment.')
-
- if Match(r'\s*class\s+(\w+\s*::\s*)+\w+\s*;', line):
- error(filename, linenum, 'build/forward_decl', 5,
- 'Inner-style forward declarations are invalid. Remove this line.')
-
- if Search(r'(\w+|[+-]?\d+(\.\d*)?)\s*(<|>)\?=?\s*(\w+|[+-]?\d+)(\.\d*)?',
- line):
- error(filename, linenum, 'build/deprecated', 3,
- '>? and <? (max and min) operators are non-standard and deprecated.')
-
- if Search(r'^\s*const\s*string\s*&\s*\w+\s*;', line):
- # TODO(unknown): Could it be expanded safely to arbitrary references,
- # without triggering too many false positives? The first
- # attempt triggered 5 warnings for mostly benign code in the regtest, hence
- # the restriction.
- # Here's the original regexp, for the reference:
- # type_name = r'\w+((\s*::\s*\w+)|(\s*<\s*\w+?\s*>))?'
- # r'\s*const\s*' + type_name + '\s*&\s*\w+\s*;'
- error(filename, linenum, 'runtime/member_string_references', 2,
- 'const string& members are dangerous. It is much better to use '
- 'alternatives, such as pointers or simple constants.')
-
- # Everything else in this function operates on class declarations.
- # Return early if the top of the nesting stack is not a class, or if
- # the class head is not completed yet.
- classinfo = nesting_state.InnermostClass()
- if not classinfo or not classinfo.seen_open_brace:
- return
-
- # The class may have been declared with namespace or classname qualifiers.
- # The constructor and destructor will not have those qualifiers.
- base_classname = classinfo.name.split('::')[-1]
-
- # Look for single-argument constructors that aren't marked explicit.
- # Technically a valid construct, but against style.
- args = Match(r'\s+(?:inline\s+)?%s\s*\(([^,()]+)\)'
- % re.escape(base_classname),
- line)
- if (args and
- args.group(1) != 'void' and
- not Match(r'(const\s+)?%s\s*(?:<\w+>\s*)?&' % re.escape(base_classname),
- args.group(1).strip())):
- error(filename, linenum, 'runtime/explicit', 5,
- 'Single-argument constructors should be marked explicit.')
-
-
-def CheckSpacingForFunctionCall(filename, line, linenum, error):
- """Checks for the correctness of various spacing around function calls.
-
- Args:
- filename: The name of the current file.
- line: The text of the line to check.
- linenum: The number of the line to check.
- error: The function to call with any errors found.
- """
-
- # Since function calls often occur inside if/for/while/switch
- # expressions - which have their own, more liberal conventions - we
- # first see if we should be looking inside such an expression for a
- # function call, to which we can apply more strict standards.
- fncall = line # if there's no control flow construct, look at whole line
- for pattern in (r'\bif\s*\((.*)\)\s*{',
- r'\bfor\s*\((.*)\)\s*{',
- r'\bwhile\s*\((.*)\)\s*[{;]',
- r'\bswitch\s*\((.*)\)\s*{'):
- match = Search(pattern, line)
- if match:
- fncall = match.group(1) # look inside the parens for function calls
- break
-
- # Except in if/for/while/switch, there should never be space
- # immediately inside parens (eg "f( 3, 4 )"). We make an exception
- # for nested parens ( (a+b) + c ). Likewise, there should never be
- # a space before a ( when it's a function argument. I assume it's a
- # function argument when the char before the whitespace is legal in
- # a function name (alnum + _) and we're not starting a macro. Also ignore
- # pointers and references to arrays and functions coz they're too tricky:
- # we use a very simple way to recognize these:
- # " (something)(maybe-something)" or
- # " (something)(maybe-something," or
- # " (something)[something]"
- # Note that we assume the contents of [] to be short enough that
- # they'll never need to wrap.
- if ( # Ignore control structures.
- not Search(r'\b(if|for|while|switch|return|delete)\b', fncall) and
- # Ignore pointers/references to functions.
- not Search(r' \([^)]+\)\([^)]*(\)|,$)', fncall) and
- # Ignore pointers/references to arrays.
- not Search(r' \([^)]+\)\[[^\]]+\]', fncall)):
- if Search(r'\w\s*\(\s(?!\s*\\$)', fncall): # a ( used for a fn call
- error(filename, linenum, 'whitespace/parens', 4,
- 'Extra space after ( in function call')
- elif Search(r'\(\s+(?!(\s*\\)|\()', fncall):
- error(filename, linenum, 'whitespace/parens', 2,
- 'Extra space after (')
- if (Search(r'\w\s+\(', fncall) and
- not Search(r'#\s*define|typedef', fncall) and
- not Search(r'\w\s+\((\w+::)?\*\w+\)\(', fncall)):
- error(filename, linenum, 'whitespace/parens', 4,
- 'Extra space before ( in function call')
- # If the ) is followed only by a newline or a { + newline, assume it's
- # part of a control statement (if/while/etc), and don't complain
- if Search(r'[^)]\s+\)\s*[^{\s]', fncall):
- # If the closing parenthesis is preceded by only whitespaces,
- # try to give a more descriptive error message.
- if Search(r'^\s+\)', fncall):
- error(filename, linenum, 'whitespace/parens', 2,
- 'Closing ) should be moved to the previous line')
- else:
- error(filename, linenum, 'whitespace/parens', 2,
- 'Extra space before )')
-
-
-def IsBlankLine(line):
- """Returns true if the given line is blank.
-
- We consider a line to be blank if the line is empty or consists of
- only white spaces.
-
- Args:
- line: A line of a string.
-
- Returns:
- True, if the given line is blank.
- """
- return not line or line.isspace()
-
-
-def CheckForFunctionLengths(filename, clean_lines, linenum,
- function_state, error):
- """Reports for long function bodies.
-
- For an overview why this is done, see:
- http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Write_Short_Functions
-
- Uses a simplistic algorithm assuming other style guidelines
- (especially spacing) are followed.
- Only checks unindented functions, so class members are unchecked.
- Trivial bodies are unchecked, so constructors with huge initializer lists
- may be missed.
- Blank/comment lines are not counted so as to avoid encouraging the removal
- of vertical space and comments just to get through a lint check.
- NOLINT *on the last line of a function* disables this check.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- function_state: Current function name and lines in body so far.
- error: The function to call with any errors found.
- """
- lines = clean_lines.lines
- line = lines[linenum]
- raw = clean_lines.raw_lines
- raw_line = raw[linenum]
- joined_line = ''
-
- starting_func = False
- regexp = r'(\w(\w|::|\*|\&|\s)*)\(' # decls * & space::name( ...
- match_result = Match(regexp, line)
- if match_result:
- # If the name is all caps and underscores, figure it's a macro and
- # ignore it, unless it's TEST or TEST_F.
- function_name = match_result.group(1).split()[-1]
- if function_name == 'TEST' or function_name == 'TEST_F' or (
- not Match(r'[A-Z_]+$', function_name)):
- starting_func = True
-
- if starting_func:
- body_found = False
- for start_linenum in xrange(linenum, clean_lines.NumLines()):
- start_line = lines[start_linenum]
- joined_line += ' ' + start_line.lstrip()
- if Search(r'(;|})', start_line): # Declarations and trivial functions
- body_found = True
- break # ... ignore
- elif Search(r'{', start_line):
- body_found = True
- function = Search(r'((\w|:)*)\(', line).group(1)
- if Match(r'TEST', function): # Handle TEST... macros
- parameter_regexp = Search(r'(\(.*\))', joined_line)
- if parameter_regexp: # Ignore bad syntax
- function += parameter_regexp.group(1)
- else:
- function += '()'
- function_state.Begin(function)
- break
- if not body_found:
- # No body for the function (or evidence of a non-function) was found.
- error(filename, linenum, 'readability/fn_size', 5,
- 'Lint failed to find start of function body.')
- elif Match(r'^\}\s*$', line): # function end
- function_state.Check(error, filename, linenum)
- function_state.End()
- elif not Match(r'^\s*$', line):
- function_state.Count() # Count non-blank/non-comment lines.
-
-
-_RE_PATTERN_TODO = re.compile(r'^//(\s*)TODO(\(.+?\))?:?(\s|$)?')
-
-
-def CheckComment(comment, filename, linenum, error):
- """Checks for common mistakes in TODO comments.
-
- Args:
- comment: The text of the comment from the line in question.
- filename: The name of the current file.
- linenum: The number of the line to check.
- error: The function to call with any errors found.
- """
- match = _RE_PATTERN_TODO.match(comment)
- if match:
- # One whitespace is correct; zero whitespace is handled elsewhere.
- leading_whitespace = match.group(1)
- if len(leading_whitespace) > 1:
- error(filename, linenum, 'whitespace/todo', 2,
- 'Too many spaces before TODO')
-
- username = match.group(2)
- if not username:
- error(filename, linenum, 'readability/todo', 2,
- 'Missing username in TODO; it should look like '
- '"// TODO(my_username): Stuff."')
-
- middle_whitespace = match.group(3)
- # Comparisons made explicit for correctness -- pylint: disable-msg=C6403
- if middle_whitespace != ' ' and middle_whitespace != '':
- error(filename, linenum, 'whitespace/todo', 2,
- 'TODO(my_username) should be followed by a space')
-
-def CheckAccess(filename, clean_lines, linenum, nesting_state, error):
- """Checks for improper use of DISALLOW* macros.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- nesting_state: A _NestingState instance which maintains information about
- the current stack of nested blocks being parsed.
- error: The function to call with any errors found.
- """
- line = clean_lines.elided[linenum] # get rid of comments and strings
-
- matched = Match((r'\s*(DISALLOW_COPY_AND_ASSIGN|'
- r'DISALLOW_EVIL_CONSTRUCTORS|'
- r'DISALLOW_IMPLICIT_CONSTRUCTORS)'), line)
- if not matched:
- return
- if nesting_state.stack and isinstance(nesting_state.stack[-1], _ClassInfo):
- if nesting_state.stack[-1].access != 'private':
- error(filename, linenum, 'readability/constructors', 3,
- '%s must be in the private: section' % matched.group(1))
-
- else:
- # Found DISALLOW* macro outside a class declaration, or perhaps it
- # was used inside a function when it should have been part of the
- # class declaration. We could issue a warning here, but it
- # probably resulted in a compiler error already.
- pass
-
-
-def FindNextMatchingAngleBracket(clean_lines, linenum, init_suffix):
- """Find the corresponding > to close a template.
-
- Args:
- clean_lines: A CleansedLines instance containing the file.
- linenum: Current line number.
- init_suffix: Remainder of the current line after the initial <.
-
- Returns:
- True if a matching bracket exists.
- """
- line = init_suffix
- nesting_stack = ['<']
- while True:
- # Find the next operator that can tell us whether < is used as an
- # opening bracket or as a less-than operator. We only want to
- # warn on the latter case.
- #
- # We could also check all other operators and terminate the search
- # early, e.g. if we got something like this "a<b+c", the "<" is
- # most likely a less-than operator, but then we will get false
- # positives for default arguments (e.g. http://go/prccd) and
- # other template expressions (e.g. http://go/oxcjq).
- match = Search(r'^[^<>(),;\[\]]*([<>(),;\[\]])(.*)$', line)
- if match:
- # Found an operator, update nesting stack
- operator = match.group(1)
- line = match.group(2)
-
- if nesting_stack[-1] == '<':
- # Expecting closing angle bracket
- if operator in ('<', '(', '['):
- nesting_stack.append(operator)
- elif operator == '>':
- nesting_stack.pop()
- if not nesting_stack:
- # Found matching angle bracket
- return True
- elif operator == ',':
- # Got a comma after a bracket, this is most likely a template
- # argument. We have not seen a closing angle bracket yet, but
- # it's probably a few lines later if we look for it, so just
- # return early here.
- return True
- else:
- # Got some other operator.
- return False
-
- else:
- # Expecting closing parenthesis or closing bracket
- if operator in ('<', '(', '['):
- nesting_stack.append(operator)
- elif operator in (')', ']'):
- # We don't bother checking for matching () or []. If we got
- # something like (] or [), it would have been a syntax error.
- nesting_stack.pop()
-
- else:
- # Scan the next line
- linenum += 1
- if linenum >= len(clean_lines.elided):
- break
- line = clean_lines.elided[linenum]
-
- # Exhausted all remaining lines and still no matching angle bracket.
- # Most likely the input was incomplete, otherwise we should have
- # seen a semicolon and returned early.
- return True
-
-
-def FindPreviousMatchingAngleBracket(clean_lines, linenum, init_prefix):
- """Find the corresponding < that started a template.
-
- Args:
- clean_lines: A CleansedLines instance containing the file.
- linenum: Current line number.
- init_prefix: Part of the current line before the initial >.
-
- Returns:
- True if a matching bracket exists.
- """
- line = init_prefix
- nesting_stack = ['>']
- while True:
- # Find the previous operator
- match = Search(r'^(.*)([<>(),;\[\]])[^<>(),;\[\]]*$', line)
- if match:
- # Found an operator, update nesting stack
- operator = match.group(2)
- line = match.group(1)
-
- if nesting_stack[-1] == '>':
- # Expecting opening angle bracket
- if operator in ('>', ')', ']'):
- nesting_stack.append(operator)
- elif operator == '<':
- nesting_stack.pop()
- if not nesting_stack:
- # Found matching angle bracket
- return True
- elif operator == ',':
- # Got a comma before a bracket, this is most likely a
- # template argument. The opening angle bracket is probably
- # there if we look for it, so just return early here.
- return True
- else:
- # Got some other operator.
- return False
-
- else:
- # Expecting opening parenthesis or opening bracket
- if operator in ('>', ')', ']'):
- nesting_stack.append(operator)
- elif operator in ('(', '['):
- nesting_stack.pop()
-
- else:
- # Scan the previous line
- linenum -= 1
- if linenum < 0:
- break
- line = clean_lines.elided[linenum]
-
- # Exhausted all earlier lines and still no matching angle bracket.
- return False
-
-
-def CheckSpacing(filename, clean_lines, linenum, nesting_state, error):
- """Checks for the correctness of various spacing issues in the code.
-
- Things we check for: spaces around operators, spaces after
- if/for/while/switch, no spaces around parens in function calls, two
- spaces between code and comment, don't start a block with a blank
- line, don't end a function with a blank line, don't add a blank line
- after public/protected/private, don't have too many blank lines in a row.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- nesting_state: A _NestingState instance which maintains information about
- the current stack of nested blocks being parsed.
- error: The function to call with any errors found.
- """
-
- raw = clean_lines.raw_lines
- line = raw[linenum]
-
- # Before nixing comments, check if the line is blank for no good
- # reason. This includes the first line after a block is opened, and
- # blank lines at the end of a function (ie, right before a line like '}'
- #
- # Skip all the blank line checks if we are immediately inside a
- # namespace body. In other words, don't issue blank line warnings
- # for this block:
- # namespace {
- #
- # }
- #
- # A warning about missing end of namespace comments will be issued instead.
- if IsBlankLine(line) and not nesting_state.InNamespaceBody():
- elided = clean_lines.elided
- prev_line = elided[linenum - 1]
- prevbrace = prev_line.rfind('{')
- # TODO(unknown): Don't complain if line before blank line, and line after,
- # both start with alnums and are indented the same amount.
- # This ignores whitespace at the start of a namespace block
- # because those are not usually indented.
- if prevbrace != -1 and prev_line[prevbrace:].find('}') == -1:
- # OK, we have a blank line at the start of a code block. Before we
- # complain, we check if it is an exception to the rule: The previous
- # non-empty line has the parameters of a function header that are indented
- # 4 spaces (because they did not fit in a 80 column line when placed on
- # the same line as the function name). We also check for the case where
- # the previous line is indented 6 spaces, which may happen when the
- # initializers of a constructor do not fit into a 80 column line.
- exception = False
- if Match(r' {6}\w', prev_line): # Initializer list?
- # We are looking for the opening column of initializer list, which
- # should be indented 4 spaces to cause 6 space indentation afterwards.
- search_position = linenum-2
- while (search_position >= 0
- and Match(r' {6}\w', elided[search_position])):
- search_position -= 1
- exception = (search_position >= 0
- and elided[search_position][:5] == ' :')
- else:
- # Search for the function arguments or an initializer list. We use a
- # simple heuristic here: If the line is indented 4 spaces; and we have a
- # closing paren, without the opening paren, followed by an opening brace
- # or colon (for initializer lists) we assume that it is the last line of
- # a function header. If we have a colon indented 4 spaces, it is an
- # initializer list.
- exception = (Match(r' {4}\w[^\(]*\)\s*(const\s*)?(\{\s*$|:)',
- prev_line)
- or Match(r' {4}:', prev_line))
-
- if not exception:
- error(filename, linenum, 'whitespace/blank_line', 2,
- 'Blank line at the start of a code block. Is this needed?')
- # Ignore blank lines at the end of a block in a long if-else
- # chain, like this:
- # if (condition1) {
- # // Something followed by a blank line
- #
- # } else if (condition2) {
- # // Something else
- # }
- if linenum + 1 < clean_lines.NumLines():
- next_line = raw[linenum + 1]
- if (next_line
- and Match(r'\s*}', next_line)
- and next_line.find('} else ') == -1):
- error(filename, linenum, 'whitespace/blank_line', 3,
- 'Blank line at the end of a code block. Is this needed?')
-
- matched = Match(r'\s*(public|protected|private):', prev_line)
- if matched:
- error(filename, linenum, 'whitespace/blank_line', 3,
- 'Do not leave a blank line after "%s:"' % matched.group(1))
-
- # Next, we complain if there's a comment too near the text
- commentpos = line.find('//')
- if commentpos != -1:
- # Check if the // may be in quotes. If so, ignore it
- # Comparisons made explicit for clarity -- pylint: disable-msg=C6403
- if (line.count('"', 0, commentpos) -
- line.count('\\"', 0, commentpos)) % 2 == 0: # not in quotes
- # Allow one space for new scopes, two spaces otherwise:
- if (not Match(r'^\s*{ //', line) and
- ((commentpos >= 1 and
- line[commentpos-1] not in string.whitespace) or
- (commentpos >= 2 and
- line[commentpos-2] not in string.whitespace))):
- error(filename, linenum, 'whitespace/comments', 2,
- 'At least two spaces is best between code and comments')
- # There should always be a space between the // and the comment
- commentend = commentpos + 2
- if commentend < len(line) and not line[commentend] == ' ':
- # but some lines are exceptions -- e.g. if they're big
- # comment delimiters like:
- # //----------------------------------------------------------
- # or are an empty C++ style Doxygen comment, like:
- # ///
- # or they begin with multiple slashes followed by a space:
- # //////// Header comment
- match = (Search(r'[=/-]{4,}\s*$', line[commentend:]) or
- Search(r'^/$', line[commentend:]) or
- Search(r'^/+ ', line[commentend:]))
- if not match:
- error(filename, linenum, 'whitespace/comments', 4,
- 'Should have a space between // and comment')
- CheckComment(line[commentpos:], filename, linenum, error)
-
- line = clean_lines.elided[linenum] # get rid of comments and strings
-
- # Don't try to do spacing checks for operator methods
- line = re.sub(r'operator(==|!=|<|<<|<=|>=|>>|>)\(', 'operator\(', line)
-
- # We allow no-spaces around = within an if: "if ( (a=Foo()) == 0 )".
- # Otherwise not. Note we only check for non-spaces on *both* sides;
- # sometimes people put non-spaces on one side when aligning ='s among
- # many lines (not that this is behavior that I approve of...)
- if Search(r'[\w.]=[\w.]', line) and not Search(r'\b(if|while) ', line):
- error(filename, linenum, 'whitespace/operators', 4,
- 'Missing spaces around =')
-
- # It's ok not to have spaces around binary operators like + - * /, but if
- # there's too little whitespace, we get concerned. It's hard to tell,
- # though, so we punt on this one for now. TODO.
-
- # You should always have whitespace around binary operators.
- #
- # Check <= and >= first to avoid false positives with < and >, then
- # check non-include lines for spacing around < and >.
- match = Search(r'[^<>=!\s](==|!=|<=|>=)[^<>=!\s]', line)
- if match:
- error(filename, linenum, 'whitespace/operators', 3,
- 'Missing spaces around %s' % match.group(1))
- # We allow no-spaces around << when used like this: 10<<20, but
- # not otherwise (particularly, not when used as streams)
- match = Search(r'(\S)(?:L|UL|ULL|l|ul|ull)?<<(\S)', line)
- if match and not (match.group(1).isdigit() and match.group(2).isdigit()):
- error(filename, linenum, 'whitespace/operators', 3,
- 'Missing spaces around <<')
- elif not Match(r'#.*include', line):
- # Avoid false positives on ->
- reduced_line = line.replace('->', '')
-
- # Look for < that is not surrounded by spaces. This is only
- # triggered if both sides are missing spaces, even though
- # technically should should flag if at least one side is missing a
- # space. This is done to avoid some false positives with shifts.
- match = Search(r'[^\s<]<([^\s=<].*)', reduced_line)
- if (match and
- not FindNextMatchingAngleBracket(clean_lines, linenum, match.group(1))):
- error(filename, linenum, 'whitespace/operators', 3,
- 'Missing spaces around <')
-
- # Look for > that is not surrounded by spaces. Similar to the
- # above, we only trigger if both sides are missing spaces to avoid
- # false positives with shifts.
- match = Search(r'^(.*[^\s>])>[^\s=>]', reduced_line)
- if (match and
- not FindPreviousMatchingAngleBracket(clean_lines, linenum,
- match.group(1))):
- error(filename, linenum, 'whitespace/operators', 3,
- 'Missing spaces around >')
-
- # We allow no-spaces around >> for almost anything. This is because
- # C++11 allows ">>" to close nested templates, which accounts for
- # most cases when ">>" is not followed by a space.
- #
- # We still warn on ">>" followed by alpha character, because that is
- # likely due to ">>" being used for right shifts, e.g.:
- # value >> alpha
- #
- # When ">>" is used to close templates, the alphanumeric letter that
- # follows would be part of an identifier, and there should still be
- # a space separating the template type and the identifier.
- # type<type<type>> alpha
- match = Search(r'>>[a-zA-Z_]', line)
- if match:
- error(filename, linenum, 'whitespace/operators', 3,
- 'Missing spaces around >>')
-
- # There shouldn't be space around unary operators
- match = Search(r'(!\s|~\s|[\s]--[\s;]|[\s]\+\+[\s;])', line)
- if match:
- error(filename, linenum, 'whitespace/operators', 4,
- 'Extra space for operator %s' % match.group(1))
-
- # A pet peeve of mine: no spaces after an if, while, switch, or for
- match = Search(r' (if\(|for\(|while\(|switch\()', line)
- if match:
- error(filename, linenum, 'whitespace/parens', 5,
- 'Missing space before ( in %s' % match.group(1))
-
- # For if/for/while/switch, the left and right parens should be
- # consistent about how many spaces are inside the parens, and
- # there should either be zero or one spaces inside the parens.
- # We don't want: "if ( foo)" or "if ( foo )".
- # Exception: "for ( ; foo; bar)" and "for (foo; bar; )" are allowed.
- match = Search(r'\b(if|for|while|switch)\s*'
- r'\(([ ]*)(.).*[^ ]+([ ]*)\)\s*{\s*$',
- line)
- if match:
- if len(match.group(2)) != len(match.group(4)):
- if not (match.group(3) == ';' and
- len(match.group(2)) == 1 + len(match.group(4)) or
- not match.group(2) and Search(r'\bfor\s*\(.*; \)', line)):
- error(filename, linenum, 'whitespace/parens', 5,
- 'Mismatching spaces inside () in %s' % match.group(1))
- if not len(match.group(2)) in [0, 1]:
- error(filename, linenum, 'whitespace/parens', 5,
- 'Should have zero or one spaces inside ( and ) in %s' %
- match.group(1))
-
- # You should always have a space after a comma (either as fn arg or operator)
- if Search(r',[^\s]', line):
- error(filename, linenum, 'whitespace/comma', 3,
- 'Missing space after ,')
-
- # You should always have a space after a semicolon
- # except for few corner cases
- # TODO(unknown): clarify if 'if (1) { return 1;}' is requires one more
- # space after ;
- if Search(r';[^\s};\\)/]', line):
- error(filename, linenum, 'whitespace/semicolon', 3,
- 'Missing space after ;')
-
- # Next we will look for issues with function calls.
- CheckSpacingForFunctionCall(filename, line, linenum, error)
-
- # Except after an opening paren, or after another opening brace (in case of
- # an initializer list, for instance), you should have spaces before your
- # braces. And since you should never have braces at the beginning of a line,
- # this is an easy test.
- if Search(r'[^ ({]{', line):
- error(filename, linenum, 'whitespace/braces', 5,
- 'Missing space before {')
-
- # Make sure '} else {' has spaces.
- if Search(r'}else', line):
- error(filename, linenum, 'whitespace/braces', 5,
- 'Missing space before else')
-
- # You shouldn't have spaces before your brackets, except maybe after
- # 'delete []' or 'new char * []'.
- if Search(r'\w\s+\[', line) and not Search(r'delete\s+\[', line):
- error(filename, linenum, 'whitespace/braces', 5,
- 'Extra space before [')
-
- # You shouldn't have a space before a semicolon at the end of the line.
- # There's a special case for "for" since the style guide allows space before
- # the semicolon there.
- if Search(r':\s*;\s*$', line):
- error(filename, linenum, 'whitespace/semicolon', 5,
- 'Semicolon defining empty statement. Use {} instead.')
- elif Search(r'^\s*;\s*$', line):
- error(filename, linenum, 'whitespace/semicolon', 5,
- 'Line contains only semicolon. If this should be an empty statement, '
- 'use {} instead.')
- elif (Search(r'\s+;\s*$', line) and
- not Search(r'\bfor\b', line)):
- error(filename, linenum, 'whitespace/semicolon', 5,
- 'Extra space before last semicolon. If this should be an empty '
- 'statement, use {} instead.')
-
- # In range-based for, we wanted spaces before and after the colon, but
- # not around "::" tokens that might appear.
- if (Search('for *\(.*[^:]:[^: ]', line) or
- Search('for *\(.*[^: ]:[^:]', line)):
- error(filename, linenum, 'whitespace/forcolon', 2,
- 'Missing space around colon in range-based for loop')
-
-
-def CheckSectionSpacing(filename, clean_lines, class_info, linenum, error):
- """Checks for additional blank line issues related to sections.
-
- Currently the only thing checked here is blank line before protected/private.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- class_info: A _ClassInfo objects.
- linenum: The number of the line to check.
- error: The function to call with any errors found.
- """
- # Skip checks if the class is small, where small means 25 lines or less.
- # 25 lines seems like a good cutoff since that's the usual height of
- # terminals, and any class that can't fit in one screen can't really
- # be considered "small".
- #
- # Also skip checks if we are on the first line. This accounts for
- # classes that look like
- # class Foo { public: ... };
- #
- # If we didn't find the end of the class, last_line would be zero,
- # and the check will be skipped by the first condition.
- if (class_info.last_line - class_info.starting_linenum <= 24 or
- linenum <= class_info.starting_linenum):
- return
-
- matched = Match(r'\s*(public|protected|private):', clean_lines.lines[linenum])
- if matched:
- # Issue warning if the line before public/protected/private was
- # not a blank line, but don't do this if the previous line contains
- # "class" or "struct". This can happen two ways:
- # - We are at the beginning of the class.
- # - We are forward-declaring an inner class that is semantically
- # private, but needed to be public for implementation reasons.
- # Also ignores cases where the previous line ends with a backslash as can be
- # common when defining classes in C macros.
- prev_line = clean_lines.lines[linenum - 1]
- if (not IsBlankLine(prev_line) and
- not Search(r'\b(class|struct)\b', prev_line) and
- not Search(r'\\$', prev_line)):
- # Try a bit harder to find the beginning of the class. This is to
- # account for multi-line base-specifier lists, e.g.:
- # class Derived
- # : public Base {
- end_class_head = class_info.starting_linenum
- for i in range(class_info.starting_linenum, linenum):
- if Search(r'\{\s*$', clean_lines.lines[i]):
- end_class_head = i
- break
- if end_class_head < linenum - 1:
- error(filename, linenum, 'whitespace/blank_line', 3,
- '"%s:" should be preceded by a blank line' % matched.group(1))
-
-
-def GetPreviousNonBlankLine(clean_lines, linenum):
- """Return the most recent non-blank line and its line number.
-
- Args:
- clean_lines: A CleansedLines instance containing the file contents.
- linenum: The number of the line to check.
-
- Returns:
- A tuple with two elements. The first element is the contents of the last
- non-blank line before the current line, or the empty string if this is the
- first non-blank line. The second is the line number of that line, or -1
- if this is the first non-blank line.
- """
-
- prevlinenum = linenum - 1
- while prevlinenum >= 0:
- prevline = clean_lines.elided[prevlinenum]
- if not IsBlankLine(prevline): # if not a blank line...
- return (prevline, prevlinenum)
- prevlinenum -= 1
- return ('', -1)
-
-
-def CheckBraces(filename, clean_lines, linenum, error):
- """Looks for misplaced braces (e.g. at the end of line).
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- error: The function to call with any errors found.
- """
-
- line = clean_lines.elided[linenum] # get rid of comments and strings
-
- if Match(r'\s*{\s*$', line):
- # We allow an open brace to start a line in the case where someone
- # is using braces in a block to explicitly create a new scope,
- # which is commonly used to control the lifetime of
- # stack-allocated variables. We don't detect this perfectly: we
- # just don't complain if the last non-whitespace character on the
- # previous non-blank line is ';', ':', '{', or '}', or if the previous
- # line starts a preprocessor block.
- prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
- if (not Search(r'[;:}{]\s*$', prevline) and
- not Match(r'\s*#', prevline)):
- error(filename, linenum, 'whitespace/braces', 4,
- '{ should almost always be at the end of the previous line')
-
- # An else clause should be on the same line as the preceding closing brace.
- if Match(r'\s*else\s*', line):
- prevline = GetPreviousNonBlankLine(clean_lines, linenum)[0]
- if Match(r'\s*}\s*$', prevline):
- error(filename, linenum, 'whitespace/newline', 4,
- 'An else should appear on the same line as the preceding }')
-
- # If braces come on one side of an else, they should be on both.
- # However, we have to worry about "else if" that spans multiple lines!
- if Search(r'}\s*else[^{]*$', line) or Match(r'[^}]*else\s*{', line):
- if Search(r'}\s*else if([^{]*)$', line): # could be multi-line if
- # find the ( after the if
- pos = line.find('else if')
- pos = line.find('(', pos)
- if pos > 0:
- (endline, _, endpos) = CloseExpression(clean_lines, linenum, pos)
- if endline[endpos:].find('{') == -1: # must be brace after if
- error(filename, linenum, 'readability/braces', 5,
- 'If an else has a brace on one side, it should have it on both')
- else: # common case: else not followed by a multi-line if
- error(filename, linenum, 'readability/braces', 5,
- 'If an else has a brace on one side, it should have it on both')
-
- # Likewise, an else should never have the else clause on the same line
- if Search(r'\belse [^\s{]', line) and not Search(r'\belse if\b', line):
- error(filename, linenum, 'whitespace/newline', 4,
- 'Else clause should never be on same line as else (use 2 lines)')
-
- # In the same way, a do/while should never be on one line
- if Match(r'\s*do [^\s{]', line):
- error(filename, linenum, 'whitespace/newline', 4,
- 'do/while clauses should not be on a single line')
-
- # Braces shouldn't be followed by a ; unless they're defining a struct
- # or initializing an array.
- # We can't tell in general, but we can for some common cases.
- prevlinenum = linenum
- while True:
- (prevline, prevlinenum) = GetPreviousNonBlankLine(clean_lines, prevlinenum)
- if Match(r'\s+{.*}\s*;', line) and not prevline.count(';'):
- line = prevline + line
- else:
- break
- if (Search(r'{.*}\s*;', line) and
- line.count('{') == line.count('}') and
- not Search(r'struct|class|enum|\s*=\s*{', line)):
- error(filename, linenum, 'readability/braces', 4,
- "You don't need a ; after a }")
-
-
-def CheckEmptyLoopBody(filename, clean_lines, linenum, error):
- """Loop for empty loop body with only a single semicolon.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- error: The function to call with any errors found.
- """
-
- # Search for loop keywords at the beginning of the line. Because only
- # whitespaces are allowed before the keywords, this will also ignore most
- # do-while-loops, since those lines should start with closing brace.
- line = clean_lines.elided[linenum]
- if Match(r'\s*(for|while)\s*\(', line):
- # Find the end of the conditional expression
- (end_line, end_linenum, end_pos) = CloseExpression(
- clean_lines, linenum, line.find('('))
-
- # Output warning if what follows the condition expression is a semicolon.
- # No warning for all other cases, including whitespace or newline, since we
- # have a separate check for semicolons preceded by whitespace.
- if end_pos >= 0 and Match(r';', end_line[end_pos:]):
- error(filename, end_linenum, 'whitespace/empty_loop_body', 5,
- 'Empty loop bodies should use {} or continue')
-
-
-def ReplaceableCheck(operator, macro, line):
- """Determine whether a basic CHECK can be replaced with a more specific one.
-
- For example suggest using CHECK_EQ instead of CHECK(a == b) and
- similarly for CHECK_GE, CHECK_GT, CHECK_LE, CHECK_LT, CHECK_NE.
-
- Args:
- operator: The C++ operator used in the CHECK.
- macro: The CHECK or EXPECT macro being called.
- line: The current source line.
-
- Returns:
- True if the CHECK can be replaced with a more specific one.
- """
-
- # This matches decimal and hex integers, strings, and chars (in that order).
- match_constant = r'([-+]?(\d+|0[xX][0-9a-fA-F]+)[lLuU]{0,3}|".*"|\'.*\')'
-
- # Expression to match two sides of the operator with something that
- # looks like a literal, since CHECK(x == iterator) won't compile.
- # This means we can't catch all the cases where a more specific
- # CHECK is possible, but it's less annoying than dealing with
- # extraneous warnings.
- match_this = (r'\s*' + macro + r'\((\s*' +
- match_constant + r'\s*' + operator + r'[^<>].*|'
- r'.*[^<>]' + operator + r'\s*' + match_constant +
- r'\s*\))')
-
- # Don't complain about CHECK(x == NULL) or similar because
- # CHECK_EQ(x, NULL) won't compile (requires a cast).
- # Also, don't complain about more complex boolean expressions
- # involving && or || such as CHECK(a == b || c == d).
- return Match(match_this, line) and not Search(r'NULL|&&|\|\|', line)
-
-
-def CheckCheck(filename, clean_lines, linenum, error):
- """Checks the use of CHECK and EXPECT macros.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- error: The function to call with any errors found.
- """
-
- # Decide the set of replacement macros that should be suggested
- raw_lines = clean_lines.raw_lines
- current_macro = ''
- for macro in _CHECK_MACROS:
- if raw_lines[linenum].find(macro) >= 0:
- current_macro = macro
- break
- if not current_macro:
- # Don't waste time here if line doesn't contain 'CHECK' or 'EXPECT'
- return
-
- line = clean_lines.elided[linenum] # get rid of comments and strings
-
- # Encourage replacing plain CHECKs with CHECK_EQ/CHECK_NE/etc.
- for operator in ['==', '!=', '>=', '>', '<=', '<']:
- if ReplaceableCheck(operator, current_macro, line):
- error(filename, linenum, 'readability/check', 2,
- 'Consider using %s instead of %s(a %s b)' % (
- _CHECK_REPLACEMENT[current_macro][operator],
- current_macro, operator))
- break
-
-
-def CheckAltTokens(filename, clean_lines, linenum, error):
- """Check alternative keywords being used in boolean expressions.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- error: The function to call with any errors found.
- """
- line = clean_lines.elided[linenum]
-
- # Avoid preprocessor lines
- if Match(r'^\s*#', line):
- return
-
- # Last ditch effort to avoid multi-line comments. This will not help
- # if the comment started before the current line or ended after the
- # current line, but it catches most of the false positives. At least,
- # it provides a way to workaround this warning for people who use
- # multi-line comments in preprocessor macros.
- #
- # TODO(unknown): remove this once cpplint has better support for
- # multi-line comments.
- if line.find('/*') >= 0 or line.find('*/') >= 0:
- return
-
- for match in _ALT_TOKEN_REPLACEMENT_PATTERN.finditer(line):
- error(filename, linenum, 'readability/alt_tokens', 2,
- 'Use operator %s instead of %s' % (
- _ALT_TOKEN_REPLACEMENT[match.group(1)], match.group(1)))
-
-
-def GetLineWidth(line):
- """Determines the width of the line in column positions.
-
- Args:
- line: A string, which may be a Unicode string.
-
- Returns:
- The width of the line in column positions, accounting for Unicode
- combining characters and wide characters.
- """
- if isinstance(line, unicode):
- width = 0
- for uc in unicodedata.normalize('NFC', line):
- if unicodedata.east_asian_width(uc) in ('W', 'F'):
- width += 2
- elif not unicodedata.combining(uc):
- width += 1
- return width
- else:
- return len(line)
-
-
-def CheckStyle(filename, clean_lines, linenum, file_extension, nesting_state,
- error):
- """Checks rules from the 'C++ style rules' section of cppguide.html.
-
- Most of these rules are hard to test (naming, comment style), but we
- do what we can. In particular we check for 2-space indents, line lengths,
- tab usage, spaces inside code, etc.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- file_extension: The extension (without the dot) of the filename.
- nesting_state: A _NestingState instance which maintains information about
- the current stack of nested blocks being parsed.
- error: The function to call with any errors found.
- """
-
- raw_lines = clean_lines.raw_lines
- line = raw_lines[linenum]
-
- if line.find('\t') != -1:
- error(filename, linenum, 'whitespace/tab', 1,
- 'Tab found; better to use spaces')
-
- # One or three blank spaces at the beginning of the line is weird; it's
- # hard to reconcile that with 2-space indents.
- # NOTE: here are the conditions rob pike used for his tests. Mine aren't
- # as sophisticated, but it may be worth becoming so: RLENGTH==initial_spaces
- # if(RLENGTH > 20) complain = 0;
- # if(match($0, " +(error|private|public|protected):")) complain = 0;
- # if(match(prev, "&& *$")) complain = 0;
- # if(match(prev, "\\|\\| *$")) complain = 0;
- # if(match(prev, "[\",=><] *$")) complain = 0;
- # if(match($0, " <<")) complain = 0;
- # if(match(prev, " +for \\(")) complain = 0;
- # if(prevodd && match(prevprev, " +for \\(")) complain = 0;
- initial_spaces = 0
- cleansed_line = clean_lines.elided[linenum]
- while initial_spaces < len(line) and line[initial_spaces] == ' ':
- initial_spaces += 1
- if line and line[-1].isspace():
- error(filename, linenum, 'whitespace/end_of_line', 4,
- 'Line ends in whitespace. Consider deleting these extra spaces.')
- # There are certain situations we allow one space, notably for labels
- elif ((initial_spaces == 1 or initial_spaces == 3) and
- not Match(r'\s*\w+\s*:\s*$', cleansed_line)):
- error(filename, linenum, 'whitespace/indent', 3,
- 'Weird number of spaces at line-start. '
- 'Are you using a 2-space indent?')
- # Labels should always be indented at least one space.
- elif not initial_spaces and line[:2] != '//' and Search(r'[^:]:\s*$',
- line):
- error(filename, linenum, 'whitespace/labels', 4,
- 'Labels should always be indented at least one space. '
- 'If this is a member-initializer list in a constructor or '
- 'the base class list in a class definition, the colon should '
- 'be on the following line.')
-
-
- # Check if the line is a header guard.
- is_header_guard = False
- if file_extension == 'h':
- cppvar = GetHeaderGuardCPPVariable(filename)
- if (line.startswith('#ifndef %s' % cppvar) or
- line.startswith('#define %s' % cppvar) or
- line.startswith('#endif // %s' % cppvar)):
- is_header_guard = True
- # #include lines and header guards can be long, since there's no clean way to
- # split them.
- #
- # URLs can be long too. It's possible to split these, but it makes them
- # harder to cut&paste.
- #
- # The "$Id:...$" comment may also get very long without it being the
- # developers fault.
- if (not line.startswith('#include') and not is_header_guard and
- not Match(r'^\s*//.*http(s?)://\S*$', line) and
- not Match(r'^// \$Id:.*#[0-9]+ \$$', line)):
- line_width = GetLineWidth(line)
- if line_width > 100:
- error(filename, linenum, 'whitespace/line_length', 4,
- 'Lines should very rarely be longer than 100 characters')
- elif line_width > 80:
- error(filename, linenum, 'whitespace/line_length', 2,
- 'Lines should be <= 80 characters long')
-
- if (cleansed_line.count(';') > 1 and
- # for loops are allowed two ;'s (and may run over two lines).
- cleansed_line.find('for') == -1 and
- (GetPreviousNonBlankLine(clean_lines, linenum)[0].find('for') == -1 or
- GetPreviousNonBlankLine(clean_lines, linenum)[0].find(';') != -1) and
- # It's ok to have many commands in a switch case that fits in 1 line
- not ((cleansed_line.find('case ') != -1 or
- cleansed_line.find('default:') != -1) and
- cleansed_line.find('break;') != -1)):
- error(filename, linenum, 'whitespace/newline', 0,
- 'More than one command on the same line')
-
- # Some more style checks
- CheckBraces(filename, clean_lines, linenum, error)
- CheckEmptyLoopBody(filename, clean_lines, linenum, error)
- CheckAccess(filename, clean_lines, linenum, nesting_state, error)
- CheckSpacing(filename, clean_lines, linenum, nesting_state, error)
- CheckCheck(filename, clean_lines, linenum, error)
- CheckAltTokens(filename, clean_lines, linenum, error)
- classinfo = nesting_state.InnermostClass()
- if classinfo:
- CheckSectionSpacing(filename, clean_lines, classinfo, linenum, error)
-
-
-_RE_PATTERN_INCLUDE_NEW_STYLE = re.compile(r'#include +"[^/]+\.h"')
-_RE_PATTERN_INCLUDE = re.compile(r'^\s*#\s*include\s*([<"])([^>"]*)[>"].*$')
-# Matches the first component of a filename delimited by -s and _s. That is:
-# _RE_FIRST_COMPONENT.match('foo').group(0) == 'foo'
-# _RE_FIRST_COMPONENT.match('foo.cc').group(0) == 'foo'
-# _RE_FIRST_COMPONENT.match('foo-bar_baz.cc').group(0) == 'foo'
-# _RE_FIRST_COMPONENT.match('foo_bar-baz.cc').group(0) == 'foo'
-_RE_FIRST_COMPONENT = re.compile(r'^[^-_.]+')
-
-
-def _DropCommonSuffixes(filename):
- """Drops common suffixes like _test.cc or -inl.h from filename.
-
- For example:
- >>> _DropCommonSuffixes('foo/foo-inl.h')
- 'foo/foo'
- >>> _DropCommonSuffixes('foo/bar/foo.cc')
- 'foo/bar/foo'
- >>> _DropCommonSuffixes('foo/foo_internal.h')
- 'foo/foo'
- >>> _DropCommonSuffixes('foo/foo_unusualinternal.h')
- 'foo/foo_unusualinternal'
-
- Args:
- filename: The input filename.
-
- Returns:
- The filename with the common suffix removed.
- """
- for suffix in ('test.cc', 'regtest.cc', 'unittest.cc',
- 'inl.h', 'impl.h', 'internal.h'):
- if (filename.endswith(suffix) and len(filename) > len(suffix) and
- filename[-len(suffix) - 1] in ('-', '_')):
- return filename[:-len(suffix) - 1]
- return os.path.splitext(filename)[0]
-
-
-def _IsTestFilename(filename):
- """Determines if the given filename has a suffix that identifies it as a test.
-
- Args:
- filename: The input filename.
-
- Returns:
- True if 'filename' looks like a test, False otherwise.
- """
- if (filename.endswith('_test.cc') or
- filename.endswith('_unittest.cc') or
- filename.endswith('_regtest.cc')):
- return True
- else:
- return False
-
-
-def _ClassifyInclude(fileinfo, include, is_system):
- """Figures out what kind of header 'include' is.
-
- Args:
- fileinfo: The current file cpplint is running over. A FileInfo instance.
- include: The path to a #included file.
- is_system: True if the #include used <> rather than "".
-
- Returns:
- One of the _XXX_HEADER constants.
-
- For example:
- >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'stdio.h', True)
- _C_SYS_HEADER
- >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'string', True)
- _CPP_SYS_HEADER
- >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/foo.h', False)
- _LIKELY_MY_HEADER
- >>> _ClassifyInclude(FileInfo('foo/foo_unknown_extension.cc'),
- ... 'bar/foo_other_ext.h', False)
- _POSSIBLE_MY_HEADER
- >>> _ClassifyInclude(FileInfo('foo/foo.cc'), 'foo/bar.h', False)
- _OTHER_HEADER
- """
- # This is a list of all standard c++ header files, except
- # those already checked for above.
- is_stl_h = include in _STL_HEADERS
- is_cpp_h = is_stl_h or include in _CPP_HEADERS
-
- if is_system:
- if is_cpp_h:
- return _CPP_SYS_HEADER
- else:
- return _C_SYS_HEADER
-
- # If the target file and the include we're checking share a
- # basename when we drop common extensions, and the include
- # lives in . , then it's likely to be owned by the target file.
- target_dir, target_base = (
- os.path.split(_DropCommonSuffixes(fileinfo.RepositoryName())))
- include_dir, include_base = os.path.split(_DropCommonSuffixes(include))
- if target_base == include_base and (
- include_dir == target_dir or
- include_dir == os.path.normpath(target_dir + '/../public')):
- return _LIKELY_MY_HEADER
-
- # If the target and include share some initial basename
- # component, it's possible the target is implementing the
- # include, so it's allowed to be first, but we'll never
- # complain if it's not there.
- target_first_component = _RE_FIRST_COMPONENT.match(target_base)
- include_first_component = _RE_FIRST_COMPONENT.match(include_base)
- if (target_first_component and include_first_component and
- target_first_component.group(0) ==
- include_first_component.group(0)):
- return _POSSIBLE_MY_HEADER
-
- return _OTHER_HEADER
-
-
-
-def CheckIncludeLine(filename, clean_lines, linenum, include_state, error):
- """Check rules that are applicable to #include lines.
-
- Strings on #include lines are NOT removed from elided line, to make
- certain tasks easier. However, to prevent false positives, checks
- applicable to #include lines in CheckLanguage must be put here.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- include_state: An _IncludeState instance in which the headers are inserted.
- error: The function to call with any errors found.
- """
- fileinfo = FileInfo(filename)
-
- line = clean_lines.lines[linenum]
-
- # "include" should use the new style "foo/bar.h" instead of just "bar.h"
- if _RE_PATTERN_INCLUDE_NEW_STYLE.search(line):
- error(filename, linenum, 'build/include', 4,
- 'Include the directory when naming .h files')
-
- # we shouldn't include a file more than once. actually, there are a
- # handful of instances where doing so is okay, but in general it's
- # not.
- match = _RE_PATTERN_INCLUDE.search(line)
- if match:
- include = match.group(2)
- is_system = (match.group(1) == '<')
- if include in include_state:
- error(filename, linenum, 'build/include', 4,
- '"%s" already included at %s:%s' %
- (include, filename, include_state[include]))
- else:
- include_state[include] = linenum
-
- # We want to ensure that headers appear in the right order:
- # 1) for foo.cc, foo.h (preferred location)
- # 2) c system files
- # 3) cpp system files
- # 4) for foo.cc, foo.h (deprecated location)
- # 5) other google headers
- #
- # We classify each include statement as one of those 5 types
- # using a number of techniques. The include_state object keeps
- # track of the highest type seen, and complains if we see a
- # lower type after that.
- error_message = include_state.CheckNextIncludeOrder(
- _ClassifyInclude(fileinfo, include, is_system))
- if error_message:
- error(filename, linenum, 'build/include_order', 4,
- '%s. Should be: %s.h, c system, c++ system, other.' %
- (error_message, fileinfo.BaseName()))
- if not include_state.IsInAlphabeticalOrder(include):
- error(filename, linenum, 'build/include_alpha', 4,
- 'Include "%s" not in alphabetical order' % include)
-
- # Look for any of the stream classes that are part of standard C++.
- match = _RE_PATTERN_INCLUDE.match(line)
- if match:
- include = match.group(2)
- if Match(r'(f|ind|io|i|o|parse|pf|stdio|str|)?stream$', include):
- # Many unit tests use cout, so we exempt them.
- if not _IsTestFilename(filename):
- error(filename, linenum, 'readability/streams', 3,
- 'Streams are highly discouraged.')
-
-
-def _GetTextInside(text, start_pattern):
- """Retrieves all the text between matching open and close parentheses.
-
- Given a string of lines and a regular expression string, retrieve all the text
- following the expression and between opening punctuation symbols like
- (, [, or {, and the matching close-punctuation symbol. This properly nested
- occurrences of the punctuations, so for the text like
- printf(a(), b(c()));
- a call to _GetTextInside(text, r'printf\(') will return 'a(), b(c())'.
- start_pattern must match string having an open punctuation symbol at the end.
-
- Args:
- text: The lines to extract text. Its comments and strings must be elided.
- It can be single line and can span multiple lines.
- start_pattern: The regexp string indicating where to start extracting
- the text.
- Returns:
- The extracted text.
- None if either the opening string or ending punctuation could not be found.
- """
- # TODO(sugawarayu): Audit cpplint.py to see what places could be profitably
- # rewritten to use _GetTextInside (and use inferior regexp matching today).
-
- # Give opening punctuations to get the matching close-punctuations.
- matching_punctuation = {'(': ')', '{': '}', '[': ']'}
- closing_punctuation = set(matching_punctuation.itervalues())
-
- # Find the position to start extracting text.
- match = re.search(start_pattern, text, re.M)
- if not match: # start_pattern not found in text.
- return None
- start_position = match.end(0)
-
- assert start_position > 0, (
- 'start_pattern must ends with an opening punctuation.')
- assert text[start_position - 1] in matching_punctuation, (
- 'start_pattern must ends with an opening punctuation.')
- # Stack of closing punctuations we expect to have in text after position.
- punctuation_stack = [matching_punctuation[text[start_position - 1]]]
- position = start_position
- while punctuation_stack and position < len(text):
- if text[position] == punctuation_stack[-1]:
- punctuation_stack.pop()
- elif text[position] in closing_punctuation:
- # A closing punctuation without matching opening punctuations.
- return None
- elif text[position] in matching_punctuation:
- punctuation_stack.append(matching_punctuation[text[position]])
- position += 1
- if punctuation_stack:
- # Opening punctuations left without matching close-punctuations.
- return None
- # punctuations match.
- return text[start_position:position - 1]
-
-
-def CheckLanguage(filename, clean_lines, linenum, file_extension, include_state,
- error):
- """Checks rules from the 'C++ language rules' section of cppguide.html.
-
- Some of these rules are hard to test (function overloading, using
- uint32 inappropriately), but we do the best we can.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- file_extension: The extension (without the dot) of the filename.
- include_state: An _IncludeState instance in which the headers are inserted.
- error: The function to call with any errors found.
- """
- # If the line is empty or consists of entirely a comment, no need to
- # check it.
- line = clean_lines.elided[linenum]
- if not line:
- return
-
- match = _RE_PATTERN_INCLUDE.search(line)
- if match:
- CheckIncludeLine(filename, clean_lines, linenum, include_state, error)
- return
-
- # Create an extended_line, which is the concatenation of the current and
- # next lines, for more effective checking of code that may span more than one
- # line.
- if linenum + 1 < clean_lines.NumLines():
- extended_line = line + clean_lines.elided[linenum + 1]
- else:
- extended_line = line
-
- # Make Windows paths like Unix.
- fullname = os.path.abspath(filename).replace('\\', '/')
-
- # TODO(unknown): figure out if they're using default arguments in fn proto.
-
- # Check for non-const references in functions. This is tricky because &
- # is also used to take the address of something. We allow <> for templates,
- # (ignoring whatever is between the braces) and : for classes.
- # These are complicated re's. They try to capture the following:
- # paren (for fn-prototype start), typename, &, varname. For the const
- # version, we're willing for const to be before typename or after
- # Don't check the implementation on same line.
- fnline = line.split('{', 1)[0]
- if (len(re.findall(r'\([^()]*\b(?:[\w:]|<[^()]*>)+(\s?&|&\s?)\w+', fnline)) >
- len(re.findall(r'\([^()]*\bconst\s+(?:typename\s+)?(?:struct\s+)?'
- r'(?:[\w:]|<[^()]*>)+(\s?&|&\s?)\w+', fnline)) +
- len(re.findall(r'\([^()]*\b(?:[\w:]|<[^()]*>)+\s+const(\s?&|&\s?)[\w]+',
- fnline))):
-
- # We allow non-const references in a few standard places, like functions
- # called "swap()" or iostream operators like "<<" or ">>". We also filter
- # out for loops, which lint otherwise mistakenly thinks are functions.
- if not Search(
- r'(for|swap|Swap|operator[<>][<>])\s*\(\s*'
- r'(?:(?:typename\s*)?[\w:]|<.*>)+\s*&',
- fnline):
- error(filename, linenum, 'runtime/references', 2,
- 'Is this a non-const reference? '
- 'If so, make const or use a pointer.')
-
- # Check to see if they're using an conversion function cast.
- # I just try to capture the most common basic types, though there are more.
- # Parameterless conversion functions, such as bool(), are allowed as they are
- # probably a member operator declaration or default constructor.
- match = Search(
- r'(\bnew\s+)?\b' # Grab 'new' operator, if it's there
- r'(int|float|double|bool|char|int32|uint32|int64|uint64)\([^)]', line)
- if match:
- # gMock methods are defined using some variant of MOCK_METHODx(name, type)
- # where type may be float(), int(string), etc. Without context they are
- # virtually indistinguishable from int(x) casts. Likewise, gMock's
- # MockCallback takes a template parameter of the form return_type(arg_type),
- # which looks much like the cast we're trying to detect.
- if (match.group(1) is None and # If new operator, then this isn't a cast
- not (Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(', line) or
- Match(r'^\s*MockCallback<.*>', line))):
- # Try a bit harder to catch gmock lines: the only place where
- # something looks like an old-style cast is where we declare the
- # return type of the mocked method, and the only time when we
- # are missing context is if MOCK_METHOD was split across
- # multiple lines (for example http://go/hrfhr ), so we only need
- # to check the previous line for MOCK_METHOD.
- if (linenum == 0 or
- not Match(r'^\s*MOCK_(CONST_)?METHOD\d+(_T)?\(\S+,\s*$',
- clean_lines.elided[linenum - 1])):
- error(filename, linenum, 'readability/casting', 4,
- 'Using deprecated casting style. '
- 'Use static_cast<%s>(...) instead' %
- match.group(2))
-
- CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
- 'static_cast',
- r'\((int|float|double|bool|char|u?int(16|32|64))\)', error)
-
- # This doesn't catch all cases. Consider (const char * const)"hello".
- #
- # (char *) "foo" should always be a const_cast (reinterpret_cast won't
- # compile).
- if CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
- 'const_cast', r'\((char\s?\*+\s?)\)\s*"', error):
- pass
- else:
- # Check pointer casts for other than string constants
- CheckCStyleCast(filename, linenum, line, clean_lines.raw_lines[linenum],
- 'reinterpret_cast', r'\((\w+\s?\*+\s?)\)', error)
-
- # In addition, we look for people taking the address of a cast. This
- # is dangerous -- casts can assign to temporaries, so the pointer doesn't
- # point where you think.
- if Search(
- r'(&\([^)]+\)[\w(])|(&(static|dynamic|reinterpret)_cast\b)', line):
- error(filename, linenum, 'runtime/casting', 4,
- ('Are you taking an address of a cast? '
- 'This is dangerous: could be a temp var. '
- 'Take the address before doing the cast, rather than after'))
-
- # Check for people declaring static/global STL strings at the top level.
- # This is dangerous because the C++ language does not guarantee that
- # globals with constructors are initialized before the first access.
- match = Match(
- r'((?:|static +)(?:|const +))string +([a-zA-Z0-9_:]+)\b(.*)',
- line)
- # Make sure it's not a function.
- # Function template specialization looks like: "string foo<Type>(...".
- # Class template definitions look like: "string Foo<Type>::Method(...".
- if match and not Match(r'\s*(<.*>)?(::[a-zA-Z0-9_]+)?\s*\(([^"]|$)',
- match.group(3)):
- error(filename, linenum, 'runtime/string', 4,
- 'For a static/global string constant, use a C style string instead: '
- '"%schar %s[]".' %
- (match.group(1), match.group(2)))
-
- # Check that we're not using RTTI outside of testing code.
- if Search(r'\bdynamic_cast<', line) and not _IsTestFilename(filename):
- error(filename, linenum, 'runtime/rtti', 5,
- 'Do not use dynamic_cast<>. If you need to cast within a class '
- "hierarchy, use static_cast<> to upcast. Google doesn't support "
- 'RTTI.')
-
- if Search(r'\b([A-Za-z0-9_]*_)\(\1\)', line):
- error(filename, linenum, 'runtime/init', 4,
- 'You seem to be initializing a member variable with itself.')
-
- if file_extension == 'h':
- # TODO(unknown): check that 1-arg constructors are explicit.
- # How to tell it's a constructor?
- # (handled in CheckForNonStandardConstructs for now)
- # TODO(unknown): check that classes have DISALLOW_EVIL_CONSTRUCTORS
- # (level 1 error)
- pass
-
- # Check if people are using the verboten C basic types. The only exception
- # we regularly allow is "unsigned short port" for port.
- if Search(r'\bshort port\b', line):
- if not Search(r'\bunsigned short port\b', line):
- error(filename, linenum, 'runtime/int', 4,
- 'Use "unsigned short" for ports, not "short"')
- else:
- match = Search(r'\b(short|long(?! +double)|long long)\b', line)
- if match:
- error(filename, linenum, 'runtime/int', 4,
- 'Use int16/int64/etc, rather than the C type %s' % match.group(1))
-
- # When snprintf is used, the second argument shouldn't be a literal.
- match = Search(r'snprintf\s*\(([^,]*),\s*([0-9]*)\s*,', line)
- if match and match.group(2) != '0':
- # If 2nd arg is zero, snprintf is used to calculate size.
- error(filename, linenum, 'runtime/printf', 3,
- 'If you can, use sizeof(%s) instead of %s as the 2nd arg '
- 'to snprintf.' % (match.group(1), match.group(2)))
-
- # Check if some verboten C functions are being used.
- if Search(r'\bsprintf\b', line):
- error(filename, linenum, 'runtime/printf', 5,
- 'Never use sprintf. Use snprintf instead.')
- match = Search(r'\b(strcpy|strcat)\b', line)
- if match:
- error(filename, linenum, 'runtime/printf', 4,
- 'Almost always, snprintf is better than %s' % match.group(1))
-
- if Search(r'\bsscanf\b', line):
- error(filename, linenum, 'runtime/printf', 1,
- 'sscanf can be ok, but is slow and can overflow buffers.')
-
- # Check if some verboten operator overloading is going on
- # TODO(unknown): catch out-of-line unary operator&:
- # class X {};
- # int operator&(const X& x) { return 42; } // unary operator&
- # The trick is it's hard to tell apart from binary operator&:
- # class Y { int operator&(const Y& x) { return 23; } }; // binary operator&
- if Search(r'\boperator\s*&\s*\(\s*\)', line):
- error(filename, linenum, 'runtime/operator', 4,
- 'Unary operator& is dangerous. Do not use it.')
-
- # Check for suspicious usage of "if" like
- # } if (a == b) {
- if Search(r'\}\s*if\s*\(', line):
- error(filename, linenum, 'readability/braces', 4,
- 'Did you mean "else if"? If not, start a new line for "if".')
-
- # Check for potential format string bugs like printf(foo).
- # We constrain the pattern not to pick things like DocidForPrintf(foo).
- # Not perfect but it can catch printf(foo.c_str()) and printf(foo->c_str())
- # TODO(sugawarayu): Catch the following case. Need to change the calling
- # convention of the whole function to process multiple line to handle it.
- # printf(
- # boy_this_is_a_really_long_variable_that_cannot_fit_on_the_prev_line);
- printf_args = _GetTextInside(line, r'(?i)\b(string)?printf\s*\(')
- if printf_args:
- match = Match(r'([\w.\->()]+)$', printf_args)
- if match and match.group(1) != '__VA_ARGS__':
- function_name = re.search(r'\b((?:string)?printf)\s*\(',
- line, re.I).group(1)
- error(filename, linenum, 'runtime/printf', 4,
- 'Potential format string bug. Do %s("%%s", %s) instead.'
- % (function_name, match.group(1)))
-
- # Check for potential memset bugs like memset(buf, sizeof(buf), 0).
- match = Search(r'memset\s*\(([^,]*),\s*([^,]*),\s*0\s*\)', line)
- if match and not Match(r"^''|-?[0-9]+|0x[0-9A-Fa-f]$", match.group(2)):
- error(filename, linenum, 'runtime/memset', 4,
- 'Did you mean "memset(%s, 0, %s)"?'
- % (match.group(1), match.group(2)))
-
- if Search(r'\busing namespace\b', line):
- error(filename, linenum, 'build/namespaces', 5,
- 'Do not use namespace using-directives. '
- 'Use using-declarations instead.')
-
- # Detect variable-length arrays.
- match = Match(r'\s*(.+::)?(\w+) [a-z]\w*\[(.+)];', line)
- if (match and match.group(2) != 'return' and match.group(2) != 'delete' and
- match.group(3).find(']') == -1):
- # Split the size using space and arithmetic operators as delimiters.
- # If any of the resulting tokens are not compile time constants then
- # report the error.
- tokens = re.split(r'\s|\+|\-|\*|\/|<<|>>]', match.group(3))
- is_const = True
- skip_next = False
- for tok in tokens:
- if skip_next:
- skip_next = False
- continue
-
- if Search(r'sizeof\(.+\)', tok): continue
- if Search(r'arraysize\(\w+\)', tok): continue
-
- tok = tok.lstrip('(')
- tok = tok.rstrip(')')
- if not tok: continue
- if Match(r'\d+', tok): continue
- if Match(r'0[xX][0-9a-fA-F]+', tok): continue
- if Match(r'k[A-Z0-9]\w*', tok): continue
- if Match(r'(.+::)?k[A-Z0-9]\w*', tok): continue
- if Match(r'(.+::)?[A-Z][A-Z0-9_]*', tok): continue
- # A catch all for tricky sizeof cases, including 'sizeof expression',
- # 'sizeof(*type)', 'sizeof(const type)', 'sizeof(struct StructName)'
- # requires skipping the next token because we split on ' ' and '*'.
- if tok.startswith('sizeof'):
- skip_next = True
- continue
- is_const = False
- break
- if not is_const:
- error(filename, linenum, 'runtime/arrays', 1,
- 'Do not use variable-length arrays. Use an appropriately named '
- "('k' followed by CamelCase) compile-time constant for the size.")
-
- # If DISALLOW_EVIL_CONSTRUCTORS, DISALLOW_COPY_AND_ASSIGN, or
- # DISALLOW_IMPLICIT_CONSTRUCTORS is present, then it should be the last thing
- # in the class declaration.
- match = Match(
- (r'\s*'
- r'(DISALLOW_(EVIL_CONSTRUCTORS|COPY_AND_ASSIGN|IMPLICIT_CONSTRUCTORS))'
- r'\(.*\);$'),
- line)
- if match and linenum + 1 < clean_lines.NumLines():
- next_line = clean_lines.elided[linenum + 1]
- # We allow some, but not all, declarations of variables to be present
- # in the statement that defines the class. The [\w\*,\s]* fragment of
- # the regular expression below allows users to declare instances of
- # the class or pointers to instances, but not less common types such
- # as function pointers or arrays. It's a tradeoff between allowing
- # reasonable code and avoiding trying to parse more C++ using regexps.
- if not Search(r'^\s*}[\w\*,\s]*;', next_line):
- error(filename, linenum, 'readability/constructors', 3,
- match.group(1) + ' should be the last thing in the class')
-
- # Check for use of unnamed namespaces in header files. Registration
- # macros are typically OK, so we allow use of "namespace {" on lines
- # that end with backslashes.
- if (file_extension == 'h'
- and Search(r'\bnamespace\s*{', line)
- and line[-1] != '\\'):
- error(filename, linenum, 'build/namespaces', 4,
- 'Do not use unnamed namespaces in header files. See '
- 'http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml#Namespaces'
- ' for more information.')
-
-
-def CheckCStyleCast(filename, linenum, line, raw_line, cast_type, pattern,
- error):
- """Checks for a C-style cast by looking for the pattern.
-
- This also handles sizeof(type) warnings, due to similarity of content.
-
- Args:
- filename: The name of the current file.
- linenum: The number of the line to check.
- line: The line of code to check.
- raw_line: The raw line of code to check, with comments.
- cast_type: The string for the C++ cast to recommend. This is either
- reinterpret_cast, static_cast, or const_cast, depending.
- pattern: The regular expression used to find C-style casts.
- error: The function to call with any errors found.
-
- Returns:
- True if an error was emitted.
- False otherwise.
- """
- match = Search(pattern, line)
- if not match:
- return False
-
- # e.g., sizeof(int)
- sizeof_match = Match(r'.*sizeof\s*$', line[0:match.start(1) - 1])
- if sizeof_match:
- error(filename, linenum, 'runtime/sizeof', 1,
- 'Using sizeof(type). Use sizeof(varname) instead if possible')
- return True
-
- # operator++(int) and operator--(int)
- if (line[0:match.start(1) - 1].endswith(' operator++') or
- line[0:match.start(1) - 1].endswith(' operator--')):
- return False
-
- remainder = line[match.end(0):]
-
- # The close paren is for function pointers as arguments to a function.
- # eg, void foo(void (*bar)(int));
- # The semicolon check is a more basic function check; also possibly a
- # function pointer typedef.
- # eg, void foo(int); or void foo(int) const;
- # The equals check is for function pointer assignment.
- # eg, void *(*foo)(int) = ...
- # The > is for MockCallback<...> ...
- #
- # Right now, this will only catch cases where there's a single argument, and
- # it's unnamed. It should probably be expanded to check for multiple
- # arguments with some unnamed.
- function_match = Match(r'\s*(\)|=|(const)?\s*(;|\{|throw\(\)|>))', remainder)
- if function_match:
- if (not function_match.group(3) or
- function_match.group(3) == ';' or
- ('MockCallback<' not in raw_line and
- '/*' not in raw_line)):
- error(filename, linenum, 'readability/function', 3,
- 'All parameters should be named in a function')
- return True
-
- # At this point, all that should be left is actual casts.
- error(filename, linenum, 'readability/casting', 4,
- 'Using C-style cast. Use %s<%s>(...) instead' %
- (cast_type, match.group(1)))
-
- return True
-
-
-_HEADERS_CONTAINING_TEMPLATES = (
- ('<deque>', ('deque',)),
- ('<functional>', ('unary_function', 'binary_function',
- 'plus', 'minus', 'multiplies', 'divides', 'modulus',
- 'negate',
- 'equal_to', 'not_equal_to', 'greater', 'less',
- 'greater_equal', 'less_equal',
- 'logical_and', 'logical_or', 'logical_not',
- 'unary_negate', 'not1', 'binary_negate', 'not2',
- 'bind1st', 'bind2nd',
- 'pointer_to_unary_function',
- 'pointer_to_binary_function',
- 'ptr_fun',
- 'mem_fun_t', 'mem_fun', 'mem_fun1_t', 'mem_fun1_ref_t',
- 'mem_fun_ref_t',
- 'const_mem_fun_t', 'const_mem_fun1_t',
- 'const_mem_fun_ref_t', 'const_mem_fun1_ref_t',
- 'mem_fun_ref',
- )),
- ('<limits>', ('numeric_limits',)),
- ('<list>', ('list',)),
- ('<map>', ('map', 'multimap',)),
- ('<memory>', ('allocator',)),
- ('<queue>', ('queue', 'priority_queue',)),
- ('<set>', ('set', 'multiset',)),
- ('<stack>', ('stack',)),
- ('<string>', ('char_traits', 'basic_string',)),
- ('<utility>', ('pair',)),
- ('<vector>', ('vector',)),
-
- # gcc extensions.
- # Note: std::hash is their hash, ::hash is our hash
- ('<hash_map>', ('hash_map', 'hash_multimap',)),
- ('<hash_set>', ('hash_set', 'hash_multiset',)),
- ('<slist>', ('slist',)),
- )
-
-_RE_PATTERN_STRING = re.compile(r'\bstring\b')
-
-_re_pattern_algorithm_header = []
-for _template in ('copy', 'max', 'min', 'min_element', 'sort', 'swap',
- 'transform'):
- # Match max<type>(..., ...), max(..., ...), but not foo->max, foo.max or
- # type::max().
- _re_pattern_algorithm_header.append(
- (re.compile(r'[^>.]\b' + _template + r'(<.*?>)?\([^\)]'),
- _template,
- '<algorithm>'))
-
-_re_pattern_templates = []
-for _header, _templates in _HEADERS_CONTAINING_TEMPLATES:
- for _template in _templates:
- _re_pattern_templates.append(
- (re.compile(r'(\<|\b)' + _template + r'\s*\<'),
- _template + '<>',
- _header))
-
-
-def FilesBelongToSameModule(filename_cc, filename_h):
- """Check if these two filenames belong to the same module.
-
- The concept of a 'module' here is a as follows:
- foo.h, foo-inl.h, foo.cc, foo_test.cc and foo_unittest.cc belong to the
- same 'module' if they are in the same directory.
- some/path/public/xyzzy and some/path/internal/xyzzy are also considered
- to belong to the same module here.
-
- If the filename_cc contains a longer path than the filename_h, for example,
- '/absolute/path/to/base/sysinfo.cc', and this file would include
- 'base/sysinfo.h', this function also produces the prefix needed to open the
- header. This is used by the caller of this function to more robustly open the
- header file. We don't have access to the real include paths in this context,
- so we need this guesswork here.
-
- Known bugs: tools/base/bar.cc and base/bar.h belong to the same module
- according to this implementation. Because of this, this function gives
- some false positives. This should be sufficiently rare in practice.
-
- Args:
- filename_cc: is the path for the .cc file
- filename_h: is the path for the header path
-
- Returns:
- Tuple with a bool and a string:
- bool: True if filename_cc and filename_h belong to the same module.
- string: the additional prefix needed to open the header file.
- """
-
- if not filename_cc.endswith('.cc'):
- return (False, '')
- filename_cc = filename_cc[:-len('.cc')]
- if filename_cc.endswith('_unittest'):
- filename_cc = filename_cc[:-len('_unittest')]
- elif filename_cc.endswith('_test'):
- filename_cc = filename_cc[:-len('_test')]
- filename_cc = filename_cc.replace('/public/', '/')
- filename_cc = filename_cc.replace('/internal/', '/')
-
- if not filename_h.endswith('.h'):
- return (False, '')
- filename_h = filename_h[:-len('.h')]
- if filename_h.endswith('-inl'):
- filename_h = filename_h[:-len('-inl')]
- filename_h = filename_h.replace('/public/', '/')
- filename_h = filename_h.replace('/internal/', '/')
-
- files_belong_to_same_module = filename_cc.endswith(filename_h)
- common_path = ''
- if files_belong_to_same_module:
- common_path = filename_cc[:-len(filename_h)]
- return files_belong_to_same_module, common_path
-
-
-def UpdateIncludeState(filename, include_state, io=codecs):
- """Fill up the include_state with new includes found from the file.
-
- Args:
- filename: the name of the header to read.
- include_state: an _IncludeState instance in which the headers are inserted.
- io: The io factory to use to read the file. Provided for testability.
-
- Returns:
- True if a header was successfully added. False otherwise.
- """
- headerfile = None
- try:
- headerfile = io.open(filename, 'r', 'utf8', 'replace')
- except IOError:
- return False
- linenum = 0
- for line in headerfile:
- linenum += 1
- clean_line = CleanseComments(line)
- match = _RE_PATTERN_INCLUDE.search(clean_line)
- if match:
- include = match.group(2)
- # The value formatting is cute, but not really used right now.
- # What matters here is that the key is in include_state.
- include_state.setdefault(include, '%s:%d' % (filename, linenum))
- return True
-
-
-def CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error,
- io=codecs):
- """Reports for missing stl includes.
-
- This function will output warnings to make sure you are including the headers
- necessary for the stl containers and functions that you use. We only give one
- reason to include a header. For example, if you use both equal_to<> and
- less<> in a .h file, only one (the latter in the file) of these will be
- reported as a reason to include the <functional>.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- include_state: An _IncludeState instance.
- error: The function to call with any errors found.
- io: The IO factory to use to read the header file. Provided for unittest
- injection.
- """
- required = {} # A map of header name to linenumber and the template entity.
- # Example of required: { '<functional>': (1219, 'less<>') }
-
- for linenum in xrange(clean_lines.NumLines()):
- line = clean_lines.elided[linenum]
- if not line or line[0] == '#':
- continue
-
- # String is special -- it is a non-templatized type in STL.
- matched = _RE_PATTERN_STRING.search(line)
- if matched:
- # Don't warn about strings in non-STL namespaces:
- # (We check only the first match per line; good enough.)
- prefix = line[:matched.start()]
- if prefix.endswith('std::') or not prefix.endswith('::'):
- required['<string>'] = (linenum, 'string')
-
- for pattern, template, header in _re_pattern_algorithm_header:
- if pattern.search(line):
- required[header] = (linenum, template)
-
- # The following function is just a speed up, no semantics are changed.
- if not '<' in line: # Reduces the cpu time usage by skipping lines.
- continue
-
- for pattern, template, header in _re_pattern_templates:
- if pattern.search(line):
- required[header] = (linenum, template)
-
- # The policy is that if you #include something in foo.h you don't need to
- # include it again in foo.cc. Here, we will look at possible includes.
- # Let's copy the include_state so it is only messed up within this function.
- include_state = include_state.copy()
-
- # Did we find the header for this file (if any) and successfully load it?
- header_found = False
-
- # Use the absolute path so that matching works properly.
- abs_filename = FileInfo(filename).FullName()
-
- # For Emacs's flymake.
- # If cpplint is invoked from Emacs's flymake, a temporary file is generated
- # by flymake and that file name might end with '_flymake.cc'. In that case,
- # restore original file name here so that the corresponding header file can be
- # found.
- # e.g. If the file name is 'foo_flymake.cc', we should search for 'foo.h'
- # instead of 'foo_flymake.h'
- abs_filename = re.sub(r'_flymake\.cc$', '.cc', abs_filename)
-
- # include_state is modified during iteration, so we iterate over a copy of
- # the keys.
- header_keys = include_state.keys()
- for header in header_keys:
- (same_module, common_path) = FilesBelongToSameModule(abs_filename, header)
- fullpath = common_path + header
- if same_module and UpdateIncludeState(fullpath, include_state, io):
- header_found = True
-
- # If we can't find the header file for a .cc, assume it's because we don't
- # know where to look. In that case we'll give up as we're not sure they
- # didn't include it in the .h file.
- # TODO(unknown): Do a better job of finding .h files so we are confident that
- # not having the .h file means there isn't one.
- if filename.endswith('.cc') and not header_found:
- return
-
- # All the lines have been processed, report the errors found.
- for required_header_unstripped in required:
- template = required[required_header_unstripped][1]
- if required_header_unstripped.strip('<>"') not in include_state:
- error(filename, required[required_header_unstripped][0],
- 'build/include_what_you_use', 4,
- 'Add #include ' + required_header_unstripped + ' for ' + template)
-
-
-_RE_PATTERN_EXPLICIT_MAKEPAIR = re.compile(r'\bmake_pair\s*<')
-
-
-def CheckMakePairUsesDeduction(filename, clean_lines, linenum, error):
- """Check that make_pair's template arguments are deduced.
-
- G++ 4.6 in C++0x mode fails badly if make_pair's template arguments are
- specified explicitly, and such use isn't intended in any case.
-
- Args:
- filename: The name of the current file.
- clean_lines: A CleansedLines instance containing the file.
- linenum: The number of the line to check.
- error: The function to call with any errors found.
- """
- raw = clean_lines.raw_lines
- line = raw[linenum]
- match = _RE_PATTERN_EXPLICIT_MAKEPAIR.search(line)
- if match:
- error(filename, linenum, 'build/explicit_make_pair',
- 4, # 4 = high confidence
- 'For C++11-compatibility, omit template arguments from make_pair'
- ' OR use pair directly OR if appropriate, construct a pair directly')
-
-
-def ProcessLine(filename, file_extension, clean_lines, line,
- include_state, function_state, nesting_state, error,
- extra_check_functions=[]):
- """Processes a single line in the file.
-
- Args:
- filename: Filename of the file that is being processed.
- file_extension: The extension (dot not included) of the file.
- clean_lines: An array of strings, each representing a line of the file,
- with comments stripped.
- line: Number of line being processed.
- include_state: An _IncludeState instance in which the headers are inserted.
- function_state: A _FunctionState instance which counts function lines, etc.
- nesting_state: A _NestingState instance which maintains information about
- the current stack of nested blocks being parsed.
- error: A callable to which errors are reported, which takes 4 arguments:
- filename, line number, error level, and message
- extra_check_functions: An array of additional check functions that will be
- run on each source line. Each function takes 4
- arguments: filename, clean_lines, line, error
- """
- raw_lines = clean_lines.raw_lines
- ParseNolintSuppressions(filename, raw_lines[line], line, error)
- nesting_state.Update(filename, clean_lines, line, error)
- if nesting_state.stack and nesting_state.stack[-1].inline_asm != _NO_ASM:
- return
- CheckForFunctionLengths(filename, clean_lines, line, function_state, error)
- CheckForMultilineCommentsAndStrings(filename, clean_lines, line, error)
- CheckStyle(filename, clean_lines, line, file_extension, nesting_state, error)
- CheckLanguage(filename, clean_lines, line, file_extension, include_state,
- error)
- CheckForNonStandardConstructs(filename, clean_lines, line,
- nesting_state, error)
- CheckPosixThreading(filename, clean_lines, line, error)
- CheckInvalidIncrement(filename, clean_lines, line, error)
- CheckMakePairUsesDeduction(filename, clean_lines, line, error)
- for check_fn in extra_check_functions:
- check_fn(filename, clean_lines, line, error)
-
-def ProcessFileData(filename, file_extension, lines, error,
- extra_check_functions=[]):
- """Performs lint checks and reports any errors to the given error function.
-
- Args:
- filename: Filename of the file that is being processed.
- file_extension: The extension (dot not included) of the file.
- lines: An array of strings, each representing a line of the file, with the
- last element being empty if the file is terminated with a newline.
- error: A callable to which errors are reported, which takes 4 arguments:
- filename, line number, error level, and message
- extra_check_functions: An array of additional check functions that will be
- run on each source line. Each function takes 4
- arguments: filename, clean_lines, line, error
- """
- lines = (['// marker so line numbers and indices both start at 1'] + lines +
- ['// marker so line numbers end in a known way'])
-
- include_state = _IncludeState()
- function_state = _FunctionState()
- nesting_state = _NestingState()
-
- ResetNolintSuppressions()
-
- CheckForCopyright(filename, lines, error)
-
- if file_extension == 'h':
- CheckForHeaderGuard(filename, lines, error)
-
- RemoveMultiLineComments(filename, lines, error)
- clean_lines = CleansedLines(lines)
- for line in xrange(clean_lines.NumLines()):
- ProcessLine(filename, file_extension, clean_lines, line,
- include_state, function_state, nesting_state, error,
- extra_check_functions)
- nesting_state.CheckClassFinished(filename, error)
-
- CheckForIncludeWhatYouUse(filename, clean_lines, include_state, error)
-
- # We check here rather than inside ProcessLine so that we see raw
- # lines rather than "cleaned" lines.
- CheckForUnicodeReplacementCharacters(filename, lines, error)
-
- CheckForNewlineAtEOF(filename, lines, error)
-
-def ProcessFile(filename, vlevel, extra_check_functions=[]):
- """Does google-lint on a single file.
-
- Args:
- filename: The name of the file to parse.
-
- vlevel: The level of errors to report. Every error of confidence
- >= verbose_level will be reported. 0 is a good default.
-
- extra_check_functions: An array of additional check functions that will be
- run on each source line. Each function takes 4
- arguments: filename, clean_lines, line, error
- """
-
- _SetVerboseLevel(vlevel)
-
- try:
- # Support the UNIX convention of using "-" for stdin. Note that
- # we are not opening the file with universal newline support
- # (which codecs doesn't support anyway), so the resulting lines do
- # contain trailing '\r' characters if we are reading a file that
- # has CRLF endings.
- # If after the split a trailing '\r' is present, it is removed
- # below. If it is not expected to be present (i.e. os.linesep !=
- # '\r\n' as in Windows), a warning is issued below if this file
- # is processed.
-
- if filename == '-':
- lines = codecs.StreamReaderWriter(sys.stdin,
- codecs.getreader('utf8'),
- codecs.getwriter('utf8'),
- 'replace').read().split('\n')
- else:
- lines = codecs.open(filename, 'r', 'utf8', 'replace').read().split('\n')
-
- carriage_return_found = False
- # Remove trailing '\r'.
- for linenum in range(len(lines)):
- if lines[linenum].endswith('\r'):
- lines[linenum] = lines[linenum].rstrip('\r')
- carriage_return_found = True
-
- except IOError:
- sys.stderr.write(
- "Skipping input '%s': Can't open for reading\n" % filename)
- return
-
- # Note, if no dot is found, this will give the entire filename as the ext.
- file_extension = filename[filename.rfind('.') + 1:]
-
- # When reading from stdin, the extension is unknown, so no cpplint tests
- # should rely on the extension.
- if (filename != '-' and file_extension != 'cc' and file_extension != 'h'
- and file_extension != 'cpp'):
- sys.stderr.write('Ignoring %s; not a .cc or .h file\n' % filename)
- else:
- ProcessFileData(filename, file_extension, lines, Error,
- extra_check_functions)
- if carriage_return_found and os.linesep != '\r\n':
- # Use 0 for linenum since outputting only one error for potentially
- # several lines.
- Error(filename, 0, 'whitespace/newline', 1,
- 'One or more unexpected \\r (^M) found;'
- 'better to use only a \\n')
-
- sys.stderr.write('Done processing %s\n' % filename)
-
-
-def PrintUsage(message):
- """Prints a brief usage string and exits, optionally with an error message.
-
- Args:
- message: The optional error message.
- """
- sys.stderr.write(_USAGE)
- if message:
- sys.exit('\nFATAL ERROR: ' + message)
- else:
- sys.exit(1)
-
-
-def PrintCategories():
- """Prints a list of all the error-categories used by error messages.
-
- These are the categories used to filter messages via --filter.
- """
- sys.stderr.write(''.join(' %s\n' % cat for cat in _ERROR_CATEGORIES))
- sys.exit(0)
-
-
-def ParseArguments(args):
- """Parses the command line arguments.
-
- This may set the output format and verbosity level as side-effects.
-
- Args:
- args: The command line arguments:
-
- Returns:
- The list of filenames to lint.
- """
- try:
- (opts, filenames) = getopt.getopt(args, '', ['help', 'output=', 'verbose=',
- 'counting=',
- 'filter=',
- 'root='])
- except getopt.GetoptError:
- PrintUsage('Invalid arguments.')
-
- verbosity = _VerboseLevel()
- output_format = _OutputFormat()
- filters = ''
- counting_style = ''
-
- for (opt, val) in opts:
- if opt == '--help':
- PrintUsage(None)
- elif opt == '--output':
- if not val in ('emacs', 'vs7', 'eclipse'):
- PrintUsage('The only allowed output formats are emacs, vs7 and eclipse.')
- output_format = val
- elif opt == '--verbose':
- verbosity = int(val)
- elif opt == '--filter':
- filters = val
- if not filters:
- PrintCategories()
- elif opt == '--counting':
- if val not in ('total', 'toplevel', 'detailed'):
- PrintUsage('Valid counting options are total, toplevel, and detailed')
- counting_style = val
- elif opt == '--root':
- global _root
- _root = val
-
- if not filenames:
- PrintUsage('No files were specified.')
-
- _SetOutputFormat(output_format)
- _SetVerboseLevel(verbosity)
- _SetFilters(filters)
- _SetCountingStyle(counting_style)
-
- return filenames
-
-
-def main():
- filenames = ParseArguments(sys.argv[1:])
-
- # Change stderr to write with replacement characters so we don't die
- # if we try to print something containing non-ASCII characters.
- sys.stderr = codecs.StreamReaderWriter(sys.stderr,
- codecs.getreader('utf8'),
- codecs.getwriter('utf8'),
- 'replace')
-
- _cpplint_state.ResetErrorCounts()
- for filename in filenames:
- ProcessFile(filename, _cpplint_state.verbose_level)
- _cpplint_state.PrintErrorCounts()
-
- sys.exit(_cpplint_state.error_count > 0)
-
-
-if __name__ == '__main__':
- main()
diff --git a/lib/sanitizer_common/scripts/gen_dynamic_list.py b/lib/sanitizer_common/scripts/gen_dynamic_list.py
deleted file mode 100755
index 4a9c7af955480..0000000000000
--- a/lib/sanitizer_common/scripts/gen_dynamic_list.py
+++ /dev/null
@@ -1,135 +0,0 @@
-#!/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 ... ]
-#
-#===------------------------------------------------------------------------===#
-from __future__ import print_function
-import argparse
-import os
-import re
-import subprocess
-import sys
-import platform
-
-new_delete = set([
- '_Znam', '_ZnamRKSt9nothrow_t', # operator new[](unsigned long)
- '_Znwm', '_ZnwmRKSt9nothrow_t', # operator new(unsigned long)
- '_Znaj', '_ZnajRKSt9nothrow_t', # operator new[](unsigned int)
- '_Znwj', '_ZnwjRKSt9nothrow_t', # operator new(unsigned int)
- # operator new(unsigned long, std::align_val_t)
- '_ZnwmSt11align_val_t', '_ZnwmSt11align_val_tRKSt9nothrow_t',
- # operator new(unsigned int, std::align_val_t)
- '_ZnwjSt11align_val_t', '_ZnwjSt11align_val_tRKSt9nothrow_t',
- # operator new[](unsigned long, std::align_val_t)
- '_ZnamSt11align_val_t', '_ZnamSt11align_val_tRKSt9nothrow_t',
- # operator new[](unsigned int, std::align_val_t)
- '_ZnajSt11align_val_t', '_ZnajSt11align_val_tRKSt9nothrow_t',
- '_ZdaPv', '_ZdaPvRKSt9nothrow_t', # operator delete[](void *)
- '_ZdlPv', '_ZdlPvRKSt9nothrow_t', # operator delete(void *)
- '_ZdaPvm', # operator delete[](void*, unsigned long)
- '_ZdlPvm', # operator delete(void*, unsigned long)
- '_ZdaPvj', # operator delete[](void*, unsigned int)
- '_ZdlPvj', # operator delete(void*, unsigned int)
- # operator delete(void*, std::align_val_t)
- '_ZdlPvSt11align_val_t', '_ZdlPvSt11align_val_tRKSt9nothrow_t',
- # operator delete[](void*, std::align_val_t)
- '_ZdaPvSt11align_val_t', '_ZdaPvSt11align_val_tRKSt9nothrow_t',
- # operator delete(void*, unsigned long, std::align_val_t)
- '_ZdlPvmSt11align_val_t',
- # operator delete[](void*, unsigned long, std::align_val_t)
- '_ZdaPvmSt11align_val_t',
- # operator delete(void*, unsigned int, std::align_val_t)
- '_ZdlPvjSt11align_val_t',
- # operator delete[](void*, unsigned int, std::align_val_t)
- '_ZdaPvjSt11align_val_t',
- ])
-
-versioned_functions = set(['memcpy', 'pthread_attr_getaffinity_np',
- 'pthread_cond_broadcast',
- 'pthread_cond_destroy', 'pthread_cond_init',
- 'pthread_cond_signal', 'pthread_cond_timedwait',
- 'pthread_cond_wait', 'realpath',
- 'sched_getaffinity'])
-
-def get_global_functions(library):
- functions = []
- nm = os.environ.get('NM', 'nm')
- nm_proc = subprocess.Popen([nm, library], stdout=subprocess.PIPE,
- stderr=subprocess.PIPE)
- nm_out = nm_proc.communicate()[0].decode().split('\n')
- if nm_proc.returncode != 0:
- raise subprocess.CalledProcessError(nm_proc.returncode, nm)
- func_symbols = ['T', 'W']
- # On PowerPC, nm prints function descriptors from .data section.
- if platform.uname()[4] in ["powerpc", "ppc64"]:
- func_symbols += ['D']
- for line in nm_out:
- cols = line.split(' ')
- if len(cols) == 3 and cols[1] in func_symbols :
- functions.append(cols[2])
- return functions
-
-def main(argv):
- parser = argparse.ArgumentParser()
- parser.add_argument('--version-list', action='store_true')
- parser.add_argument('--extra', default=[], action='append')
- parser.add_argument('libraries', default=[], nargs='+')
- parser.add_argument('-o', '--output', required=True)
- args = parser.parse_args()
-
- result = []
-
- all_functions = []
- for library in args.libraries:
- all_functions.extend(get_global_functions(library))
- function_set = set(all_functions)
- 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 (args.version_list or 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 args.extra:
- f = open(fname, 'r')
- for line in f:
- result.append(line.rstrip())
- # Print the resulting list in the format recognized by ld.
- with open(args.output, 'w') as f:
- print('{', file=f)
- if args.version_list:
- print('global:', file=f)
- result.sort()
- for sym in result:
- print(u' %s;' % sym, file=f)
- if args.version_list:
- print('local:', file=f)
- print(' *;', file=f)
- print('};', file=f)
-
-if __name__ == '__main__':
- main(sys.argv)
diff --git a/lib/sanitizer_common/scripts/litlint.py b/lib/sanitizer_common/scripts/litlint.py
deleted file mode 100755
index 81b89c2144381..0000000000000
--- a/lib/sanitizer_common/scripts/litlint.py
+++ /dev/null
@@ -1,72 +0,0 @@
-#!/usr/bin/env python
-#
-# litlint
-#
-# Ensure RUN commands in lit tests are free of common errors.
-#
-# If any errors are detected, litlint returns a nonzero exit code.
-#
-
-import optparse
-import re
-import sys
-
-# Compile regex once for all files
-runRegex = re.compile(r'(?<!-o)(?<!%run) %t\s')
-
-def LintLine(s):
- """ Validate a line
-
- Args:
- s: str, the line to validate
-
- Returns:
- Returns an error message and a 1-based column number if an error was
- detected, otherwise (None, None).
- """
-
- # Check that RUN command can be executed with an emulator
- m = runRegex.search(s)
- if m:
- start, end = m.span()
- return ('missing %run before %t', start + 2)
-
- # No errors
- return (None, None)
-
-
-def LintFile(p):
- """ Check that each RUN command can be executed with an emulator
-
- Args:
- p: str, valid path to a file
-
- Returns:
- The number of errors detected.
- """
- errs = 0
- with open(p, 'r') as f:
- for i, s in enumerate(f.readlines(), start=1):
- msg, col = LintLine(s)
- if msg != None:
- errs += 1
- errorMsg = 'litlint: {}:{}:{}: error: {}.\n{}{}\n'
- arrow = (col-1) * ' ' + '^'
- sys.stderr.write(errorMsg.format(p, i, col, msg, s, arrow))
- return errs
-
-
-if __name__ == "__main__":
- # Parse args
- parser = optparse.OptionParser()
- parser.add_option('--filter') # ignored
- (options, filenames) = parser.parse_args()
-
- # Lint each file
- errs = 0
- for p in filenames:
- errs += LintFile(p)
-
- # If errors, return nonzero
- if errs > 0:
- sys.exit(1)
diff --git a/lib/sanitizer_common/scripts/litlint_test.py b/lib/sanitizer_common/scripts/litlint_test.py
deleted file mode 100755
index 3ce482d704442..0000000000000
--- a/lib/sanitizer_common/scripts/litlint_test.py
+++ /dev/null
@@ -1,23 +0,0 @@
-#!/usr/bin/python
-
-# Tests for litlint.py
-#
-# Usage: python litlint_test.py
-#
-# Returns nonzero if any test fails
-
-import litlint
-import unittest
-
-class TestLintLine(unittest.TestCase):
- def test_missing_run(self):
- f = litlint.LintLine
- self.assertEqual(f(' %t '), ('missing %run before %t', 2))
- self.assertEqual(f(' %t\n'), ('missing %run before %t', 2))
- self.assertEqual(f(' %t.so '), (None, None))
- self.assertEqual(f(' %t.o '), (None, None))
- self.assertEqual(f('%run %t '), (None, None))
- self.assertEqual(f('-o %t '), (None, None))
-
-if __name__ == '__main__':
- unittest.main()
diff --git a/lib/sanitizer_common/scripts/sancov.py b/lib/sanitizer_common/scripts/sancov.py
deleted file mode 100755
index 35606396b78e6..0000000000000
--- a/lib/sanitizer_common/scripts/sancov.py
+++ /dev/null
@@ -1,251 +0,0 @@
-#!/usr/bin/env python
-# Merge or print the coverage data collected by asan's coverage.
-# Input files are sequences of 4-byte integers.
-# We need to merge these integers into a set and then
-# either print them (as hex) or dump them into another file.
-import array
-import bisect
-import glob
-import os.path
-import struct
-import subprocess
-import sys
-
-prog_name = ""
-
-def Usage():
- sys.stderr.write(
- "Usage: \n" + \
- " " + prog_name + " merge FILE [FILE...] > OUTPUT\n" \
- " " + prog_name + " print FILE [FILE...]\n" \
- " " + prog_name + " unpack FILE [FILE...]\n" \
- " " + prog_name + " rawunpack FILE [FILE ...]\n" \
- " " + prog_name + " missing BINARY < LIST_OF_PCS\n" \
- "\n")
- exit(1)
-
-def CheckBits(bits):
- if bits != 32 and bits != 64:
- raise Exception("Wrong bitness: %d" % bits)
-
-def TypeCodeForBits(bits):
- CheckBits(bits)
- return 'L' if bits == 64 else 'I'
-
-def TypeCodeForStruct(bits):
- CheckBits(bits)
- return 'Q' if bits == 64 else 'I'
-
-kMagic32SecondHalf = 0xFFFFFF32;
-kMagic64SecondHalf = 0xFFFFFF64;
-kMagicFirstHalf = 0xC0BFFFFF;
-
-def MagicForBits(bits):
- CheckBits(bits)
- if sys.byteorder == 'little':
- return [kMagic64SecondHalf if bits == 64 else kMagic32SecondHalf, kMagicFirstHalf]
- else:
- return [kMagicFirstHalf, kMagic64SecondHalf if bits == 64 else kMagic32SecondHalf]
-
-def ReadMagicAndReturnBitness(f, path):
- magic_bytes = f.read(8)
- magic_words = struct.unpack('II', magic_bytes);
- bits = 0
- idx = 1 if sys.byteorder == 'little' else 0
- if magic_words[idx] == kMagicFirstHalf:
- if magic_words[1-idx] == kMagic64SecondHalf:
- bits = 64
- elif magic_words[1-idx] == kMagic32SecondHalf:
- bits = 32
- if bits == 0:
- raise Exception('Bad magic word in %s' % path)
- return bits
-
-def ReadOneFile(path):
- with open(path, mode="rb") as f:
- f.seek(0, 2)
- size = f.tell()
- f.seek(0, 0)
- if size < 8:
- raise Exception('File %s is short (< 8 bytes)' % path)
- bits = ReadMagicAndReturnBitness(f, path)
- size -= 8
- w = size * 8 // bits
- s = struct.unpack_from(TypeCodeForStruct(bits) * (w), f.read(size))
- sys.stderr.write(
- "%s: read %d %d-bit PCs from %s\n" % (prog_name, w, bits, path))
- return s
-
-def Merge(files):
- s = set()
- for f in files:
- s = s.union(set(ReadOneFile(f)))
- sys.stderr.write(
- "%s: %d files merged; %d PCs total\n" % (prog_name, len(files), len(s))
- )
- return sorted(s)
-
-def PrintFiles(files):
- if len(files) > 1:
- s = Merge(files)
- else: # If there is just on file, print the PCs in order.
- s = ReadOneFile(files[0])
- sys.stderr.write("%s: 1 file merged; %d PCs total\n" % (prog_name, len(s)))
- for i in s:
- print("0x%x" % i)
-
-def MergeAndPrint(files):
- if sys.stdout.isatty():
- Usage()
- s = Merge(files)
- bits = 32
- if max(s) > 0xFFFFFFFF:
- bits = 64
- stdout_buf = getattr(sys.stdout, 'buffer', sys.stdout)
- array.array('I', MagicForBits(bits)).tofile(stdout_buf)
- a = struct.pack(TypeCodeForStruct(bits) * len(s), *s)
- stdout_buf.write(a)
-
-
-def UnpackOneFile(path):
- with open(path, mode="rb") as f:
- sys.stderr.write("%s: unpacking %s\n" % (prog_name, path))
- while True:
- header = f.read(12)
- if not header: return
- if len(header) < 12:
- break
- pid, module_length, blob_size = struct.unpack('iII', header)
- module = f.read(module_length).decode('utf-8')
- blob = f.read(blob_size)
- assert(len(module) == module_length)
- assert(len(blob) == blob_size)
- extracted_file = "%s.%d.sancov" % (module, pid)
- sys.stderr.write("%s: extracting %s\n" % (prog_name, extracted_file))
- # The packed file may contain multiple blobs for the same pid/module
- # pair. Append to the end of the file instead of overwriting.
- with open(extracted_file, 'ab') as f2:
- f2.write(blob)
- # fail
- raise Exception('Error reading file %s' % path)
-
-
-def Unpack(files):
- for f in files:
- UnpackOneFile(f)
-
-def UnpackOneRawFile(path, map_path):
- mem_map = []
- with open(map_path, mode="rt") as f_map:
- sys.stderr.write("%s: reading map %s\n" % (prog_name, map_path))
- bits = int(f_map.readline())
- if bits != 32 and bits != 64:
- raise Exception('Wrong bits size in the map')
- for line in f_map:
- parts = line.rstrip().split()
- mem_map.append((int(parts[0], 16),
- int(parts[1], 16),
- int(parts[2], 16),
- ' '.join(parts[3:])))
- mem_map.sort(key=lambda m : m[0])
- mem_map_keys = [m[0] for m in mem_map]
-
- with open(path, mode="rb") as f:
- sys.stderr.write("%s: unpacking %s\n" % (prog_name, path))
-
- f.seek(0, 2)
- size = f.tell()
- f.seek(0, 0)
- pcs = struct.unpack_from(TypeCodeForStruct(bits) * (size * 8 // bits), f.read(size))
- mem_map_pcs = [[] for i in range(0, len(mem_map))]
-
- for pc in pcs:
- if pc == 0: continue
- map_idx = bisect.bisect(mem_map_keys, pc) - 1
- (start, end, base, module_path) = mem_map[map_idx]
- assert pc >= start
- if pc >= end:
- sys.stderr.write("warning: %s: pc %x outside of any known mapping\n" % (prog_name, pc))
- continue
- mem_map_pcs[map_idx].append(pc - base)
-
- for ((start, end, base, module_path), pc_list) in zip(mem_map, mem_map_pcs):
- if len(pc_list) == 0: continue
- assert path.endswith('.sancov.raw')
- dst_path = module_path + '.' + os.path.basename(path)[:-4]
- sys.stderr.write("%s: writing %d PCs to %s\n" % (prog_name, len(pc_list), dst_path))
- sorted_pc_list = sorted(pc_list)
- pc_buffer = struct.pack(TypeCodeForStruct(bits) * len(pc_list), *sorted_pc_list)
- with open(dst_path, 'ab+') as f2:
- array.array('I', MagicForBits(bits)).tofile(f2)
- f2.seek(0, 2)
- f2.write(pc_buffer)
-
-def RawUnpack(files):
- for f in files:
- if not f.endswith('.sancov.raw'):
- raise Exception('Unexpected raw file name %s' % f)
- f_map = f[:-3] + 'map'
- UnpackOneRawFile(f, f_map)
-
-def GetInstrumentedPCs(binary):
- # This looks scary, but all it does is extract all offsets where we call:
- # - __sanitizer_cov() or __sanitizer_cov_with_check(),
- # - with call or callq,
- # - directly or via PLT.
- cmd = "objdump -d %s | " \
- "grep '^\s\+[0-9a-f]\+:.*\scall\(q\|\)\s\+[0-9a-f]\+ <__sanitizer_cov\(_with_check\|\|_trace_pc_guard\)\(@plt\|\)>' | " \
- "grep '^\s\+[0-9a-f]\+' -o" % binary
- proc = subprocess.Popen(cmd, stdin=subprocess.PIPE, stdout=subprocess.PIPE,
- shell=True)
- proc.stdin.close()
- # The PCs we get from objdump are off by 4 bytes, as they point to the
- # beginning of the callq instruction. Empirically this is true on x86 and
- # x86_64.
- return set(int(line.strip(), 16) + 4 for line in proc.stdout)
-
-def PrintMissing(binary):
- if not os.path.isfile(binary):
- raise Exception('File not found: %s' % binary)
- instrumented = GetInstrumentedPCs(binary)
- sys.stderr.write("%s: found %d instrumented PCs in %s\n" % (prog_name,
- len(instrumented),
- binary))
- covered = set(int(line, 16) for line in sys.stdin)
- sys.stderr.write("%s: read %d PCs from stdin\n" % (prog_name, len(covered)))
- missing = instrumented - covered
- sys.stderr.write("%s: %d PCs missing from coverage\n" % (prog_name, len(missing)))
- if (len(missing) > len(instrumented) - len(covered)):
- sys.stderr.write(
- "%s: WARNING: stdin contains PCs not found in binary\n" % prog_name
- )
- for pc in sorted(missing):
- print("0x%x" % pc)
-
-if __name__ == '__main__':
- prog_name = sys.argv[0]
- if len(sys.argv) <= 2:
- Usage();
-
- if sys.argv[1] == "missing":
- if len(sys.argv) != 3:
- Usage()
- PrintMissing(sys.argv[2])
- exit(0)
-
- file_list = []
- for f in sys.argv[2:]:
- file_list += glob.glob(f)
- if not file_list:
- Usage()
-
- if sys.argv[1] == "print":
- PrintFiles(file_list)
- elif sys.argv[1] == "merge":
- MergeAndPrint(file_list)
- elif sys.argv[1] == "unpack":
- Unpack(file_list)
- elif sys.argv[1] == "rawunpack":
- RawUnpack(file_list)
- else:
- Usage()
diff --git a/lib/sanitizer_common/tests/CMakeLists.txt b/lib/sanitizer_common/tests/CMakeLists.txt
deleted file mode 100644
index 21ffe2528c25e..0000000000000
--- a/lib/sanitizer_common/tests/CMakeLists.txt
+++ /dev/null
@@ -1,218 +0,0 @@
-include(CompilerRTCompile)
-
-clang_compiler_add_cxx_check()
-
-# FIXME: use SANITIZER_COMMON_SUPPORTED_ARCH here
-filter_available_targets(SANITIZER_UNITTEST_SUPPORTED_ARCH x86_64 i386 mips64 mips64el)
-if(APPLE)
- darwin_filter_host_archs(SANITIZER_UNITTEST_SUPPORTED_ARCH SANITIZER_UNITTEST_SUPPORTED_ARCH)
-endif()
-
-set(SANITIZER_UNITTESTS
- sanitizer_allocator_test.cc
- sanitizer_atomic_test.cc
- sanitizer_bitvector_test.cc
- sanitizer_bvgraph_test.cc
- sanitizer_common_test.cc
- sanitizer_deadlock_detector_test.cc
- sanitizer_flags_test.cc
- sanitizer_format_interceptor_test.cc
- sanitizer_ioctl_test.cc
- sanitizer_libc_test.cc
- sanitizer_linux_test.cc
- sanitizer_list_test.cc
- sanitizer_mutex_test.cc
- sanitizer_nolibc_test.cc
- sanitizer_posix_test.cc
- sanitizer_printf_test.cc
- sanitizer_procmaps_test.cc
- sanitizer_ring_buffer_test.cc
- sanitizer_quarantine_test.cc
- sanitizer_stackdepot_test.cc
- sanitizer_stacktrace_printer_test.cc
- sanitizer_stacktrace_test.cc
- sanitizer_stoptheworld_test.cc
- sanitizer_suppressions_test.cc
- sanitizer_symbolizer_test.cc
- sanitizer_test_main.cc
- sanitizer_thread_registry_test.cc
- sanitizer_type_traits_test.cc
- sanitizer_vector_test.cc)
-
-set(SANITIZER_TEST_HEADERS
- sanitizer_pthread_wrappers.h
- sanitizer_test_config.h
- sanitizer_test_utils.h)
-foreach(header ${SANITIZER_IMPL_HEADERS})
- list(APPEND SANITIZER_TEST_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../${header})
-endforeach()
-
-set(SANITIZER_TEST_CFLAGS_COMMON
- ${COMPILER_RT_UNITTEST_CFLAGS}
- ${COMPILER_RT_GTEST_CFLAGS}
- -I${COMPILER_RT_SOURCE_DIR}/include
- -I${COMPILER_RT_SOURCE_DIR}/lib
- -I${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common
- -fno-rtti
- -O2
- -Werror=sign-compare
- -Wno-non-virtual-dtor
- -Wno-gnu-zero-variadic-macro-arguments)
-
-# -gline-tables-only must be enough for these tests, so use it if possible.
-if(COMPILER_RT_TEST_COMPILER_ID MATCHES "Clang")
- list(APPEND SANITIZER_TEST_CFLAGS_COMMON -gline-tables-only)
-else()
- list(APPEND SANITIZER_TEST_CFLAGS_COMMON -g)
-endif()
-if(MSVC)
- list(APPEND SANITIZER_TEST_CFLAGS_COMMON -gcodeview)
-endif()
-list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON -g)
-
-if(NOT MSVC)
- list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON --driver-mode=g++)
-endif()
-
-if(ANDROID)
- list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON -pie)
-endif()
-
-if(APPLE)
- list(APPEND SANITIZER_TEST_CFLAGS_COMMON ${DARWIN_osx_CFLAGS})
- list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON ${DARWIN_osx_LINK_FLAGS})
-
- 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
-# enough for the unittests. Some unittests require more than 2M.
-# The default stack size for clang is 8M.
-if(MSVC)
- list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON -Wl,/STACK:0xC00000)
-endif()
-
-set(SANITIZER_TEST_LINK_LIBS)
-append_list_if(COMPILER_RT_HAS_LIBLOG log SANITIZER_TEST_LINK_LIBS)
-# NDK r10 requires -latomic almost always.
-append_list_if(ANDROID atomic SANITIZER_TEST_LINK_LIBS)
-
-append_list_if(COMPILER_RT_HAS_LIBDL -ldl SANITIZER_TEST_LINK_FLAGS_COMMON)
-append_list_if(COMPILER_RT_HAS_LIBRT -lrt SANITIZER_TEST_LINK_FLAGS_COMMON)
-append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread SANITIZER_TEST_LINK_FLAGS_COMMON)
-# x86_64 FreeBSD 9.2 additionally requires libc++ to build the tests. Also,
-# 'libm' shall be specified explicitly to build i386 tests.
-if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE")
- list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON "-lc++ -lm")
-endif()
-
-include_directories(..)
-include_directories(../..)
-
-# Adds static library which contains sanitizer_common object file
-# (universal binary on Mac and arch-specific object files on Linux).
-macro(add_sanitizer_common_lib library)
- add_library(${library} STATIC ${ARGN})
- set_target_properties(${library} PROPERTIES
- ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- FOLDER "Compiler-RT Runtime tests")
-endmacro()
-
-function(get_sanitizer_common_lib_for_arch arch lib)
- if(APPLE)
- set(tgt_name "RTSanitizerCommon.test.osx")
- else()
- set(tgt_name "RTSanitizerCommon.test.${arch}")
- endif()
- set(${lib} "${tgt_name}" PARENT_SCOPE)
-endfunction()
-
-# Sanitizer_common unit tests testsuite.
-add_custom_target(SanitizerUnitTests)
-set_target_properties(SanitizerUnitTests PROPERTIES FOLDER "Compiler-RT Tests")
-
-# Adds sanitizer tests for architecture.
-macro(add_sanitizer_tests_for_arch arch)
- set(extra_flags)
- if( CMAKE_SIZEOF_VOID_P EQUAL 4 )
- list(APPEND extra_flags "-D_LARGEFILE_SOURCE")
- list(APPEND extra_flags "-D_FILE_OFFSET_BITS=64")
- endif()
- get_sanitizer_common_lib_for_arch(${arch} SANITIZER_COMMON_LIB)
-
- set(SANITIZER_TEST_OBJECTS)
- generate_compiler_rt_tests(SANITIZER_TEST_OBJECTS SanitizerUnitTests
- "Sanitizer-${arch}-Test" ${arch}
- RUNTIME "${SANITIZER_COMMON_LIB}"
- SOURCES ${SANITIZER_UNITTESTS} ${COMPILER_RT_GTEST_SOURCE}
- COMPILE_DEPS ${SANITIZER_TEST_HEADERS}
- DEPS gtest
- CFLAGS ${SANITIZER_TEST_CFLAGS_COMMON} ${extra_flags}
- LINK_FLAGS ${SANITIZER_TEST_LINK_FLAGS_COMMON} ${extra_flags})
-
- if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" AND "${arch}" STREQUAL "x86_64")
- # Test that the libc-independent part of sanitizer_common is indeed
- # independent of libc, by linking this binary without libc (here) and
- # executing it (unit test in sanitizer_nolibc_test.cc).
- clang_compile(sanitizer_nolibc_test_main.${arch}.o
- sanitizer_nolibc_test_main.cc
- CFLAGS ${SANITIZER_TEST_CFLAGS_COMMON} ${TARGET_FLAGS}
- DEPS ${SANITIZER_TEST_COMPILE_DEPS})
- add_compiler_rt_test(SanitizerUnitTests "Sanitizer-${arch}-Test-Nolibc" ${arch}
- OBJECTS sanitizer_nolibc_test_main.${arch}.o
- -Wl,-whole-archive
- libRTSanitizerCommon.test.nolibc.${arch}.a
- -Wl,-no-whole-archive
- DEPS sanitizer_nolibc_test_main.${arch}.o
- RTSanitizerCommon.test.nolibc.${arch}
- LINK_FLAGS -nostdlib ${TARGET_FLAGS})
- endif()
-endmacro()
-
-if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
- # We use just-built clang to build sanitizer_common unittests, so we must
- # be sure that produced binaries would work.
- if(APPLE)
- add_sanitizer_common_lib("RTSanitizerCommon.test.osx"
- $<TARGET_OBJECTS:RTSanitizerCommon.osx>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.osx>
- $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.osx>)
- else()
- if(CAN_TARGET_x86_64)
- add_sanitizer_common_lib("RTSanitizerCommon.test.nolibc.x86_64"
- $<TARGET_OBJECTS:RTSanitizerCommon.x86_64>
- $<TARGET_OBJECTS:RTSanitizerCommonNoLibc.x86_64>)
- endif()
- foreach(arch ${SANITIZER_UNITTEST_SUPPORTED_ARCH})
- add_sanitizer_common_lib("RTSanitizerCommon.test.${arch}"
- $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>)
- endforeach()
- endif()
- foreach(arch ${SANITIZER_UNITTEST_SUPPORTED_ARCH})
- add_sanitizer_tests_for_arch(${arch})
- endforeach()
-endif()
-
-if(ANDROID)
- foreach(arch ${SANITIZER_COMMON_SUPPORTED_ARCH})
- add_executable(SanitizerTest
- ${SANITIZER_UNITTESTS}
- ${COMPILER_RT_GTEST_SOURCE}
- $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>)
- set_target_compile_flags(SanitizerTest
- ${SANITIZER_COMMON_CFLAGS}
- ${SANITIZER_TEST_CFLAGS_COMMON})
- # Setup correct output directory and link flags.
- set_target_properties(SanitizerTest PROPERTIES
- RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
- set_target_link_flags(SanitizerTest ${SANITIZER_TEST_LINK_FLAGS_COMMON})
- target_link_libraries(SanitizerTest ${SANITIZER_TEST_LINK_LIBS})
- # Add unit test to test suite.
- add_dependencies(SanitizerUnitTests SanitizerTest)
- endforeach()
-endif()
diff --git a/lib/sanitizer_common/tests/malloc_stress_transfer_test.cc b/lib/sanitizer_common/tests/malloc_stress_transfer_test.cc
deleted file mode 100644
index 3e03c4bddfd75..0000000000000
--- a/lib/sanitizer_common/tests/malloc_stress_transfer_test.cc
+++ /dev/null
@@ -1,37 +0,0 @@
-#include <thread>
-#include <iostream>
-
-const size_t kAllocSize = 16;
-const size_t kInitialNumAllocs = 1 << 10;
-const size_t kPeriodicNumAllocs = 1 << 10;
-const size_t kNumIterations = 1 << 7;
-const size_t kNumThreads = 16;
-
-void Thread() {
- // int sp;
- // std::cerr << "Thread starting, sp = " << &sp << std::endl;
- char *InitialAllocations[kInitialNumAllocs];
- char *PeriodicaAllocations[kPeriodicNumAllocs];
- for (auto &p : InitialAllocations) p = new char[kAllocSize];
- for (size_t i = 0; i < kNumIterations; i++) {
- for (size_t j = 0; j < kPeriodicNumAllocs; j++) {
- for (auto &p : PeriodicaAllocations) {
- p = new char[kAllocSize];
- *p = 0;
- }
- for (auto p : PeriodicaAllocations) delete [] p;
- }
- }
- for (auto p : InitialAllocations) delete [] p;
-}
-
-int main() {
-// Thread();
-// return 0;
- std::thread *Threads[kNumThreads];
- for (auto &T : Threads) T = new std::thread(&Thread);
- for (auto T : Threads) {
- T->join();
- delete T;
- }
-}
diff --git a/lib/sanitizer_common/tests/sanitizer_allocator_test.cc b/lib/sanitizer_common/tests/sanitizer_allocator_test.cc
deleted file mode 100644
index 3123a1d5abf44..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_allocator_test.cc
+++ /dev/null
@@ -1,1430 +0,0 @@
-//===-- sanitizer_allocator_test.cc ---------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
-// Tests for sanitizer_allocator.h.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_allocator.h"
-#include "sanitizer_common/sanitizer_allocator_internal.h"
-#include "sanitizer_common/sanitizer_common.h"
-
-#include "sanitizer_test_utils.h"
-#include "sanitizer_pthread_wrappers.h"
-
-#include "gtest/gtest.h"
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <algorithm>
-#include <vector>
-#include <random>
-#include <set>
-
-using namespace __sanitizer;
-
-// Too slow for debug build
-#if !SANITIZER_DEBUG
-
-#if SANITIZER_CAN_USE_ALLOCATOR64
-#if SANITIZER_WINDOWS
-// On Windows 64-bit there is no easy way to find a large enough fixed address
-// space that is always available. Thus, a dynamically allocated address space
-// is used instead (i.e. ~(uptr)0).
-static const uptr kAllocatorSpace = ~(uptr)0;
-static const uptr kAllocatorSize = 0x8000000000ULL; // 500G
-static const u64 kAddressSpaceSize = 1ULL << 47;
-typedef DefaultSizeClassMap SizeClassMap;
-#elif SANITIZER_ANDROID && defined(__aarch64__)
-static const uptr kAllocatorSpace = 0x3000000000ULL;
-static const uptr kAllocatorSize = 0x2000000000ULL;
-static const u64 kAddressSpaceSize = 1ULL << 39;
-typedef VeryCompactSizeClassMap SizeClassMap;
-#else
-static const uptr kAllocatorSpace = 0x700000000000ULL;
-static const uptr kAllocatorSize = 0x010000000000ULL; // 1T.
-static const u64 kAddressSpaceSize = 1ULL << 47;
-typedef DefaultSizeClassMap SizeClassMap;
-#endif
-
-template <typename AddressSpaceViewTy>
-struct AP64 { // Allocator Params. Short name for shorter demangled names..
- static const uptr kSpaceBeg = kAllocatorSpace;
- static const uptr kSpaceSize = kAllocatorSize;
- static const uptr kMetadataSize = 16;
- typedef ::SizeClassMap SizeClassMap;
- typedef NoOpMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags = 0;
- using AddressSpaceView = AddressSpaceViewTy;
-};
-
-template <typename AddressSpaceViewTy>
-struct AP64Dyn {
- static const uptr kSpaceBeg = ~(uptr)0;
- static const uptr kSpaceSize = kAllocatorSize;
- static const uptr kMetadataSize = 16;
- typedef ::SizeClassMap SizeClassMap;
- typedef NoOpMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags = 0;
- using AddressSpaceView = AddressSpaceViewTy;
-};
-
-template <typename AddressSpaceViewTy>
-struct AP64Compact {
- static const uptr kSpaceBeg = ~(uptr)0;
- static const uptr kSpaceSize = kAllocatorSize;
- static const uptr kMetadataSize = 16;
- typedef CompactSizeClassMap SizeClassMap;
- typedef NoOpMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags = 0;
- using AddressSpaceView = AddressSpaceViewTy;
-};
-
-template <typename AddressSpaceViewTy>
-struct AP64VeryCompact {
- static const uptr kSpaceBeg = ~(uptr)0;
- static const uptr kSpaceSize = 1ULL << 37;
- static const uptr kMetadataSize = 16;
- typedef VeryCompactSizeClassMap SizeClassMap;
- typedef NoOpMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags = 0;
- using AddressSpaceView = AddressSpaceViewTy;
-};
-
-template <typename AddressSpaceViewTy>
-struct AP64Dense {
- static const uptr kSpaceBeg = kAllocatorSpace;
- static const uptr kSpaceSize = kAllocatorSize;
- static const uptr kMetadataSize = 16;
- typedef DenseSizeClassMap SizeClassMap;
- typedef NoOpMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags = 0;
- using AddressSpaceView = AddressSpaceViewTy;
-};
-
-template <typename AddressSpaceView>
-using Allocator64ASVT = SizeClassAllocator64<AP64<AddressSpaceView>>;
-using Allocator64 = Allocator64ASVT<LocalAddressSpaceView>;
-
-template <typename AddressSpaceView>
-using Allocator64DynamicASVT = SizeClassAllocator64<AP64Dyn<AddressSpaceView>>;
-using Allocator64Dynamic = Allocator64DynamicASVT<LocalAddressSpaceView>;
-
-template <typename AddressSpaceView>
-using Allocator64CompactASVT =
- SizeClassAllocator64<AP64Compact<AddressSpaceView>>;
-using Allocator64Compact = Allocator64CompactASVT<LocalAddressSpaceView>;
-
-template <typename AddressSpaceView>
-using Allocator64VeryCompactASVT =
- SizeClassAllocator64<AP64VeryCompact<AddressSpaceView>>;
-using Allocator64VeryCompact =
- Allocator64VeryCompactASVT<LocalAddressSpaceView>;
-
-template <typename AddressSpaceView>
-using Allocator64DenseASVT = SizeClassAllocator64<AP64Dense<AddressSpaceView>>;
-using Allocator64Dense = Allocator64DenseASVT<LocalAddressSpaceView>;
-
-#elif defined(__mips64)
-static const u64 kAddressSpaceSize = 1ULL << 40;
-#elif defined(__aarch64__)
-static const u64 kAddressSpaceSize = 1ULL << 39;
-#elif defined(__s390x__)
-static const u64 kAddressSpaceSize = 1ULL << 53;
-#elif defined(__s390__)
-static const u64 kAddressSpaceSize = 1ULL << 31;
-#else
-static const u64 kAddressSpaceSize = 1ULL << 32;
-#endif
-
-static const uptr kRegionSizeLog = FIRST_32_SECOND_64(20, 24);
-static const uptr kFlatByteMapSize = kAddressSpaceSize >> kRegionSizeLog;
-
-template <typename AddressSpaceViewTy>
-struct AP32Compact {
- static const uptr kSpaceBeg = 0;
- static const u64 kSpaceSize = kAddressSpaceSize;
- static const uptr kMetadataSize = 16;
- typedef CompactSizeClassMap SizeClassMap;
- static const uptr kRegionSizeLog = ::kRegionSizeLog;
- using AddressSpaceView = AddressSpaceViewTy;
- using ByteMap = FlatByteMap<kFlatByteMapSize, AddressSpaceView>;
- typedef NoOpMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags = 0;
-};
-template <typename AddressSpaceView>
-using Allocator32CompactASVT =
- SizeClassAllocator32<AP32Compact<AddressSpaceView>>;
-using Allocator32Compact = Allocator32CompactASVT<LocalAddressSpaceView>;
-
-template <class SizeClassMap>
-void TestSizeClassMap() {
- typedef SizeClassMap SCMap;
- SCMap::Print();
- SCMap::Validate();
-}
-
-TEST(SanitizerCommon, DefaultSizeClassMap) {
- TestSizeClassMap<DefaultSizeClassMap>();
-}
-
-TEST(SanitizerCommon, CompactSizeClassMap) {
- TestSizeClassMap<CompactSizeClassMap>();
-}
-
-TEST(SanitizerCommon, VeryCompactSizeClassMap) {
- TestSizeClassMap<VeryCompactSizeClassMap>();
-}
-
-TEST(SanitizerCommon, InternalSizeClassMap) {
- TestSizeClassMap<InternalSizeClassMap>();
-}
-
-TEST(SanitizerCommon, DenseSizeClassMap) {
- TestSizeClassMap<VeryCompactSizeClassMap>();
-}
-
-template <class Allocator>
-void TestSizeClassAllocator() {
- Allocator *a = new Allocator;
- a->Init(kReleaseToOSIntervalNever);
- SizeClassAllocatorLocalCache<Allocator> cache;
- memset(&cache, 0, sizeof(cache));
- cache.Init(0);
-
- static const uptr sizes[] = {
- 1, 16, 30, 40, 100, 1000, 10000,
- 50000, 60000, 100000, 120000, 300000, 500000, 1000000, 2000000
- };
-
- std::vector<void *> allocated;
-
- uptr last_total_allocated = 0;
- for (int i = 0; i < 3; i++) {
- // Allocate a bunch of chunks.
- for (uptr s = 0; s < ARRAY_SIZE(sizes); s++) {
- uptr size = sizes[s];
- if (!a->CanAllocate(size, 1)) continue;
- // printf("s = %ld\n", size);
- uptr n_iter = std::max((uptr)6, 4000000 / size);
- // fprintf(stderr, "size: %ld iter: %ld\n", size, n_iter);
- for (uptr i = 0; i < n_iter; i++) {
- uptr class_id0 = Allocator::SizeClassMapT::ClassID(size);
- char *x = (char*)cache.Allocate(a, class_id0);
- x[0] = 0;
- x[size - 1] = 0;
- x[size / 2] = 0;
- allocated.push_back(x);
- CHECK_EQ(x, a->GetBlockBegin(x));
- CHECK_EQ(x, a->GetBlockBegin(x + size - 1));
- CHECK(a->PointerIsMine(x));
- CHECK(a->PointerIsMine(x + size - 1));
- CHECK(a->PointerIsMine(x + size / 2));
- CHECK_GE(a->GetActuallyAllocatedSize(x), size);
- uptr class_id = a->GetSizeClass(x);
- CHECK_EQ(class_id, Allocator::SizeClassMapT::ClassID(size));
- uptr *metadata = reinterpret_cast<uptr*>(a->GetMetaData(x));
- metadata[0] = reinterpret_cast<uptr>(x) + 1;
- metadata[1] = 0xABCD;
- }
- }
- // Deallocate all.
- for (uptr i = 0; i < allocated.size(); i++) {
- void *x = allocated[i];
- uptr *metadata = reinterpret_cast<uptr*>(a->GetMetaData(x));
- CHECK_EQ(metadata[0], reinterpret_cast<uptr>(x) + 1);
- CHECK_EQ(metadata[1], 0xABCD);
- cache.Deallocate(a, a->GetSizeClass(x), x);
- }
- allocated.clear();
- uptr total_allocated = a->TotalMemoryUsed();
- if (last_total_allocated == 0)
- last_total_allocated = total_allocated;
- CHECK_EQ(last_total_allocated, total_allocated);
- }
-
- // Check that GetBlockBegin never crashes.
- for (uptr x = 0, step = kAddressSpaceSize / 100000;
- x < kAddressSpaceSize - step; x += step)
- if (a->PointerIsMine(reinterpret_cast<void *>(x)))
- Ident(a->GetBlockBegin(reinterpret_cast<void *>(x)));
-
- a->TestOnlyUnmap();
- delete a;
-}
-
-#if SANITIZER_CAN_USE_ALLOCATOR64
-// These tests can fail on Windows if memory is somewhat full and lit happens
-// to run them all at the same time. FIXME: Make them not flaky and reenable.
-#if !SANITIZER_WINDOWS
-TEST(SanitizerCommon, SizeClassAllocator64) {
- TestSizeClassAllocator<Allocator64>();
-}
-
-TEST(SanitizerCommon, SizeClassAllocator64Dynamic) {
- TestSizeClassAllocator<Allocator64Dynamic>();
-}
-
-#if !SANITIZER_ANDROID
-//FIXME(kostyak): find values so that those work on Android as well.
-TEST(SanitizerCommon, SizeClassAllocator64Compact) {
- TestSizeClassAllocator<Allocator64Compact>();
-}
-
-TEST(SanitizerCommon, SizeClassAllocator64Dense) {
- TestSizeClassAllocator<Allocator64Dense>();
-}
-#endif
-
-TEST(SanitizerCommon, SizeClassAllocator64VeryCompact) {
- TestSizeClassAllocator<Allocator64VeryCompact>();
-}
-#endif
-#endif
-
-TEST(SanitizerCommon, SizeClassAllocator32Compact) {
- TestSizeClassAllocator<Allocator32Compact>();
-}
-
-template <typename AddressSpaceViewTy>
-struct AP32SeparateBatches {
- static const uptr kSpaceBeg = 0;
- static const u64 kSpaceSize = kAddressSpaceSize;
- static const uptr kMetadataSize = 16;
- typedef DefaultSizeClassMap SizeClassMap;
- static const uptr kRegionSizeLog = ::kRegionSizeLog;
- using AddressSpaceView = AddressSpaceViewTy;
- using ByteMap = FlatByteMap<kFlatByteMapSize, AddressSpaceView>;
- typedef NoOpMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags =
- SizeClassAllocator32FlagMasks::kUseSeparateSizeClassForBatch;
-};
-template <typename AddressSpaceView>
-using Allocator32SeparateBatchesASVT =
- SizeClassAllocator32<AP32SeparateBatches<AddressSpaceView>>;
-using Allocator32SeparateBatches =
- Allocator32SeparateBatchesASVT<LocalAddressSpaceView>;
-
-TEST(SanitizerCommon, SizeClassAllocator32SeparateBatches) {
- TestSizeClassAllocator<Allocator32SeparateBatches>();
-}
-
-template <class Allocator>
-void SizeClassAllocatorMetadataStress() {
- Allocator *a = new Allocator;
- a->Init(kReleaseToOSIntervalNever);
- SizeClassAllocatorLocalCache<Allocator> cache;
- memset(&cache, 0, sizeof(cache));
- cache.Init(0);
-
- const uptr kNumAllocs = 1 << 13;
- void *allocated[kNumAllocs];
- void *meta[kNumAllocs];
- for (uptr i = 0; i < kNumAllocs; i++) {
- void *x = cache.Allocate(a, 1 + i % (Allocator::kNumClasses - 1));
- allocated[i] = x;
- meta[i] = a->GetMetaData(x);
- }
- // Get Metadata kNumAllocs^2 times.
- for (uptr i = 0; i < kNumAllocs * kNumAllocs; i++) {
- uptr idx = i % kNumAllocs;
- void *m = a->GetMetaData(allocated[idx]);
- EXPECT_EQ(m, meta[idx]);
- }
- for (uptr i = 0; i < kNumAllocs; i++) {
- cache.Deallocate(a, 1 + i % (Allocator::kNumClasses - 1), allocated[i]);
- }
-
- a->TestOnlyUnmap();
- delete a;
-}
-
-#if SANITIZER_CAN_USE_ALLOCATOR64
-// These tests can fail on Windows if memory is somewhat full and lit happens
-// to run them all at the same time. FIXME: Make them not flaky and reenable.
-#if !SANITIZER_WINDOWS
-TEST(SanitizerCommon, SizeClassAllocator64MetadataStress) {
- SizeClassAllocatorMetadataStress<Allocator64>();
-}
-
-TEST(SanitizerCommon, SizeClassAllocator64DynamicMetadataStress) {
- SizeClassAllocatorMetadataStress<Allocator64Dynamic>();
-}
-
-#if !SANITIZER_ANDROID
-TEST(SanitizerCommon, SizeClassAllocator64CompactMetadataStress) {
- SizeClassAllocatorMetadataStress<Allocator64Compact>();
-}
-#endif
-
-#endif
-#endif // SANITIZER_CAN_USE_ALLOCATOR64
-TEST(SanitizerCommon, SizeClassAllocator32CompactMetadataStress) {
- SizeClassAllocatorMetadataStress<Allocator32Compact>();
-}
-
-template <class Allocator>
-void SizeClassAllocatorGetBlockBeginStress(u64 TotalSize) {
- Allocator *a = new Allocator;
- a->Init(kReleaseToOSIntervalNever);
- SizeClassAllocatorLocalCache<Allocator> cache;
- memset(&cache, 0, sizeof(cache));
- cache.Init(0);
-
- uptr max_size_class = Allocator::SizeClassMapT::kLargestClassID;
- uptr size = Allocator::SizeClassMapT::Size(max_size_class);
- // Make sure we correctly compute GetBlockBegin() w/o overflow.
- for (size_t i = 0; i <= TotalSize / size; i++) {
- void *x = cache.Allocate(a, max_size_class);
- void *beg = a->GetBlockBegin(x);
- // if ((i & (i - 1)) == 0)
- // fprintf(stderr, "[%zd] %p %p\n", i, x, beg);
- EXPECT_EQ(x, beg);
- }
-
- a->TestOnlyUnmap();
- delete a;
-}
-
-#if SANITIZER_CAN_USE_ALLOCATOR64
-// These tests can fail on Windows if memory is somewhat full and lit happens
-// to run them all at the same time. FIXME: Make them not flaky and reenable.
-#if !SANITIZER_WINDOWS
-TEST(SanitizerCommon, SizeClassAllocator64GetBlockBegin) {
- SizeClassAllocatorGetBlockBeginStress<Allocator64>(
- 1ULL << (SANITIZER_ANDROID ? 31 : 33));
-}
-TEST(SanitizerCommon, SizeClassAllocator64DynamicGetBlockBegin) {
- SizeClassAllocatorGetBlockBeginStress<Allocator64Dynamic>(
- 1ULL << (SANITIZER_ANDROID ? 31 : 33));
-}
-#if !SANITIZER_ANDROID
-TEST(SanitizerCommon, SizeClassAllocator64CompactGetBlockBegin) {
- SizeClassAllocatorGetBlockBeginStress<Allocator64Compact>(1ULL << 33);
-}
-#endif
-TEST(SanitizerCommon, SizeClassAllocator64VeryCompactGetBlockBegin) {
- // Does not have > 4Gb for each class.
- SizeClassAllocatorGetBlockBeginStress<Allocator64VeryCompact>(1ULL << 31);
-}
-TEST(SanitizerCommon, SizeClassAllocator32CompactGetBlockBegin) {
- SizeClassAllocatorGetBlockBeginStress<Allocator32Compact>(1ULL << 33);
-}
-#endif
-#endif // SANITIZER_CAN_USE_ALLOCATOR64
-
-struct TestMapUnmapCallback {
- static int map_count, unmap_count;
- void OnMap(uptr p, uptr size) const { map_count++; }
- void OnUnmap(uptr p, uptr size) const { unmap_count++; }
-};
-int TestMapUnmapCallback::map_count;
-int TestMapUnmapCallback::unmap_count;
-
-#if SANITIZER_CAN_USE_ALLOCATOR64
-// These tests can fail on Windows if memory is somewhat full and lit happens
-// to run them all at the same time. FIXME: Make them not flaky and reenable.
-#if !SANITIZER_WINDOWS
-
-template <typename AddressSpaceViewTy = LocalAddressSpaceView>
-struct AP64WithCallback {
- static const uptr kSpaceBeg = kAllocatorSpace;
- static const uptr kSpaceSize = kAllocatorSize;
- static const uptr kMetadataSize = 16;
- typedef ::SizeClassMap SizeClassMap;
- typedef TestMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags = 0;
- using AddressSpaceView = AddressSpaceViewTy;
-};
-
-TEST(SanitizerCommon, SizeClassAllocator64MapUnmapCallback) {
- TestMapUnmapCallback::map_count = 0;
- TestMapUnmapCallback::unmap_count = 0;
- typedef SizeClassAllocator64<AP64WithCallback<>> Allocator64WithCallBack;
- Allocator64WithCallBack *a = new Allocator64WithCallBack;
- a->Init(kReleaseToOSIntervalNever);
- EXPECT_EQ(TestMapUnmapCallback::map_count, 1); // Allocator state.
- SizeClassAllocatorLocalCache<Allocator64WithCallBack> cache;
- memset(&cache, 0, sizeof(cache));
- cache.Init(0);
- AllocatorStats stats;
- stats.Init();
- const size_t kNumChunks = 128;
- uint32_t chunks[kNumChunks];
- a->GetFromAllocator(&stats, 30, chunks, kNumChunks);
- // State + alloc + metadata + freearray.
- EXPECT_EQ(TestMapUnmapCallback::map_count, 4);
- a->TestOnlyUnmap();
- EXPECT_EQ(TestMapUnmapCallback::unmap_count, 1); // The whole thing.
- delete a;
-}
-#endif
-#endif
-
-template <typename AddressSpaceViewTy = LocalAddressSpaceView>
-struct AP32WithCallback {
- static const uptr kSpaceBeg = 0;
- static const u64 kSpaceSize = kAddressSpaceSize;
- static const uptr kMetadataSize = 16;
- typedef CompactSizeClassMap SizeClassMap;
- static const uptr kRegionSizeLog = ::kRegionSizeLog;
- using AddressSpaceView = AddressSpaceViewTy;
- using ByteMap = FlatByteMap<kFlatByteMapSize, AddressSpaceView>;
- typedef TestMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags = 0;
-};
-
-TEST(SanitizerCommon, SizeClassAllocator32MapUnmapCallback) {
- TestMapUnmapCallback::map_count = 0;
- TestMapUnmapCallback::unmap_count = 0;
- typedef SizeClassAllocator32<AP32WithCallback<>> Allocator32WithCallBack;
- Allocator32WithCallBack *a = new Allocator32WithCallBack;
- a->Init(kReleaseToOSIntervalNever);
- EXPECT_EQ(TestMapUnmapCallback::map_count, 0);
- SizeClassAllocatorLocalCache<Allocator32WithCallBack> cache;
- memset(&cache, 0, sizeof(cache));
- cache.Init(0);
- AllocatorStats stats;
- stats.Init();
- a->AllocateBatch(&stats, &cache, 32);
- EXPECT_EQ(TestMapUnmapCallback::map_count, 1);
- a->TestOnlyUnmap();
- EXPECT_EQ(TestMapUnmapCallback::unmap_count, 1);
- delete a;
- // fprintf(stderr, "Map: %d Unmap: %d\n",
- // TestMapUnmapCallback::map_count,
- // TestMapUnmapCallback::unmap_count);
-}
-
-TEST(SanitizerCommon, LargeMmapAllocatorMapUnmapCallback) {
- TestMapUnmapCallback::map_count = 0;
- TestMapUnmapCallback::unmap_count = 0;
- LargeMmapAllocator<TestMapUnmapCallback> a;
- a.Init();
- AllocatorStats stats;
- stats.Init();
- void *x = a.Allocate(&stats, 1 << 20, 1);
- EXPECT_EQ(TestMapUnmapCallback::map_count, 1);
- a.Deallocate(&stats, x);
- EXPECT_EQ(TestMapUnmapCallback::unmap_count, 1);
-}
-
-// Don't test OOM conditions on Win64 because it causes other tests on the same
-// machine to OOM.
-#if SANITIZER_CAN_USE_ALLOCATOR64 && !SANITIZER_WINDOWS64 && !SANITIZER_ANDROID
-TEST(SanitizerCommon, SizeClassAllocator64Overflow) {
- Allocator64 a;
- a.Init(kReleaseToOSIntervalNever);
- SizeClassAllocatorLocalCache<Allocator64> cache;
- memset(&cache, 0, sizeof(cache));
- cache.Init(0);
- AllocatorStats stats;
- stats.Init();
-
- const size_t kNumChunks = 128;
- uint32_t chunks[kNumChunks];
- bool allocation_failed = false;
- for (int i = 0; i < 1000000; i++) {
- if (!a.GetFromAllocator(&stats, 52, chunks, kNumChunks)) {
- allocation_failed = true;
- break;
- }
- }
- EXPECT_EQ(allocation_failed, true);
-
- a.TestOnlyUnmap();
-}
-#endif
-
-TEST(SanitizerCommon, LargeMmapAllocator) {
- LargeMmapAllocator<NoOpMapUnmapCallback> a;
- a.Init();
- AllocatorStats stats;
- stats.Init();
-
- static const int kNumAllocs = 1000;
- char *allocated[kNumAllocs];
- static const uptr size = 4000;
- // Allocate some.
- for (int i = 0; i < kNumAllocs; i++) {
- allocated[i] = (char *)a.Allocate(&stats, size, 1);
- CHECK(a.PointerIsMine(allocated[i]));
- }
- // Deallocate all.
- CHECK_GT(a.TotalMemoryUsed(), size * kNumAllocs);
- for (int i = 0; i < kNumAllocs; i++) {
- char *p = allocated[i];
- CHECK(a.PointerIsMine(p));
- a.Deallocate(&stats, p);
- }
- // Check that non left.
- CHECK_EQ(a.TotalMemoryUsed(), 0);
-
- // Allocate some more, also add metadata.
- for (int i = 0; i < kNumAllocs; i++) {
- char *x = (char *)a.Allocate(&stats, size, 1);
- CHECK_GE(a.GetActuallyAllocatedSize(x), size);
- uptr *meta = reinterpret_cast<uptr*>(a.GetMetaData(x));
- *meta = i;
- allocated[i] = x;
- }
- for (int i = 0; i < kNumAllocs * kNumAllocs; i++) {
- char *p = allocated[i % kNumAllocs];
- CHECK(a.PointerIsMine(p));
- CHECK(a.PointerIsMine(p + 2000));
- }
- CHECK_GT(a.TotalMemoryUsed(), size * kNumAllocs);
- // Deallocate all in reverse order.
- for (int i = 0; i < kNumAllocs; i++) {
- int idx = kNumAllocs - i - 1;
- char *p = allocated[idx];
- uptr *meta = reinterpret_cast<uptr*>(a.GetMetaData(p));
- CHECK_EQ(*meta, idx);
- CHECK(a.PointerIsMine(p));
- a.Deallocate(&stats, p);
- }
- CHECK_EQ(a.TotalMemoryUsed(), 0);
-
- // Test alignments. Test with 512MB alignment on x64 non-Windows machines.
- // Windows doesn't overcommit, and many machines do not have 51.2GB of swap.
- uptr max_alignment =
- (SANITIZER_WORDSIZE == 64 && !SANITIZER_WINDOWS) ? (1 << 28) : (1 << 24);
- for (uptr alignment = 8; alignment <= max_alignment; alignment *= 2) {
- const uptr kNumAlignedAllocs = 100;
- for (uptr i = 0; i < kNumAlignedAllocs; i++) {
- uptr size = ((i % 10) + 1) * 4096;
- char *p = allocated[i] = (char *)a.Allocate(&stats, size, alignment);
- CHECK_EQ(p, a.GetBlockBegin(p));
- CHECK_EQ(p, a.GetBlockBegin(p + size - 1));
- CHECK_EQ(p, a.GetBlockBegin(p + size / 2));
- CHECK_EQ(0, (uptr)allocated[i] % alignment);
- p[0] = p[size - 1] = 0;
- }
- for (uptr i = 0; i < kNumAlignedAllocs; i++) {
- a.Deallocate(&stats, allocated[i]);
- }
- }
-
- // Regression test for boundary condition in GetBlockBegin().
- uptr page_size = GetPageSizeCached();
- char *p = (char *)a.Allocate(&stats, page_size, 1);
- CHECK_EQ(p, a.GetBlockBegin(p));
- CHECK_EQ(p, (char *)a.GetBlockBegin(p + page_size - 1));
- CHECK_NE(p, (char *)a.GetBlockBegin(p + page_size));
- a.Deallocate(&stats, p);
-}
-
-template
-<class PrimaryAllocator, class SecondaryAllocator, class AllocatorCache>
-void TestCombinedAllocator() {
- typedef
- CombinedAllocator<PrimaryAllocator, AllocatorCache, SecondaryAllocator>
- Allocator;
- Allocator *a = new Allocator;
- a->Init(kReleaseToOSIntervalNever);
- std::mt19937 r;
-
- AllocatorCache cache;
- memset(&cache, 0, sizeof(cache));
- a->InitCache(&cache);
-
- EXPECT_EQ(a->Allocate(&cache, -1, 1), (void*)0);
- EXPECT_EQ(a->Allocate(&cache, -1, 1024), (void*)0);
- EXPECT_EQ(a->Allocate(&cache, (uptr)-1 - 1024, 1), (void*)0);
- EXPECT_EQ(a->Allocate(&cache, (uptr)-1 - 1024, 1024), (void*)0);
- EXPECT_EQ(a->Allocate(&cache, (uptr)-1 - 1023, 1024), (void*)0);
- EXPECT_EQ(a->Allocate(&cache, -1, 1), (void*)0);
-
- const uptr kNumAllocs = 100000;
- const uptr kNumIter = 10;
- for (uptr iter = 0; iter < kNumIter; iter++) {
- std::vector<void*> allocated;
- for (uptr i = 0; i < kNumAllocs; i++) {
- uptr size = (i % (1 << 14)) + 1;
- if ((i % 1024) == 0)
- size = 1 << (10 + (i % 14));
- void *x = a->Allocate(&cache, size, 1);
- uptr *meta = reinterpret_cast<uptr*>(a->GetMetaData(x));
- CHECK_EQ(*meta, 0);
- *meta = size;
- allocated.push_back(x);
- }
-
- std::shuffle(allocated.begin(), allocated.end(), r);
-
- // Test ForEachChunk(...)
- {
- std::set<void *> reported_chunks;
- auto cb = [](uptr chunk, void *arg) {
- auto reported_chunks_ptr = reinterpret_cast<std::set<void *> *>(arg);
- auto pair =
- reported_chunks_ptr->insert(reinterpret_cast<void *>(chunk));
- // Check chunk is never reported more than once.
- ASSERT_TRUE(pair.second);
- };
- a->ForEachChunk(cb, reinterpret_cast<void *>(&reported_chunks));
- for (const auto &allocated_ptr : allocated) {
- ASSERT_NE(reported_chunks.find(allocated_ptr), reported_chunks.end());
- }
- }
-
- for (uptr i = 0; i < kNumAllocs; i++) {
- void *x = allocated[i];
- uptr *meta = reinterpret_cast<uptr*>(a->GetMetaData(x));
- CHECK_NE(*meta, 0);
- CHECK(a->PointerIsMine(x));
- *meta = 0;
- a->Deallocate(&cache, x);
- }
- allocated.clear();
- a->SwallowCache(&cache);
- }
- a->DestroyCache(&cache);
- a->TestOnlyUnmap();
-}
-
-#if SANITIZER_CAN_USE_ALLOCATOR64
-TEST(SanitizerCommon, CombinedAllocator64) {
- TestCombinedAllocator<Allocator64,
- LargeMmapAllocator<>,
- SizeClassAllocatorLocalCache<Allocator64> > ();
-}
-
-TEST(SanitizerCommon, CombinedAllocator64Dynamic) {
- TestCombinedAllocator<Allocator64Dynamic,
- LargeMmapAllocator<>,
- SizeClassAllocatorLocalCache<Allocator64Dynamic> > ();
-}
-
-#if !SANITIZER_ANDROID
-TEST(SanitizerCommon, CombinedAllocator64Compact) {
- TestCombinedAllocator<Allocator64Compact,
- LargeMmapAllocator<>,
- SizeClassAllocatorLocalCache<Allocator64Compact> > ();
-}
-#endif
-
-TEST(SanitizerCommon, CombinedAllocator64VeryCompact) {
- TestCombinedAllocator<Allocator64VeryCompact,
- LargeMmapAllocator<>,
- SizeClassAllocatorLocalCache<Allocator64VeryCompact> > ();
-}
-#endif
-
-TEST(SanitizerCommon, CombinedAllocator32Compact) {
- TestCombinedAllocator<Allocator32Compact,
- LargeMmapAllocator<>,
- SizeClassAllocatorLocalCache<Allocator32Compact> > ();
-}
-
-template <class AllocatorCache>
-void TestSizeClassAllocatorLocalCache() {
- AllocatorCache cache;
- typedef typename AllocatorCache::Allocator Allocator;
- Allocator *a = new Allocator();
-
- a->Init(kReleaseToOSIntervalNever);
- memset(&cache, 0, sizeof(cache));
- cache.Init(0);
-
- const uptr kNumAllocs = 10000;
- const int kNumIter = 100;
- uptr saved_total = 0;
- for (int class_id = 1; class_id <= 5; class_id++) {
- for (int it = 0; it < kNumIter; it++) {
- void *allocated[kNumAllocs];
- for (uptr i = 0; i < kNumAllocs; i++) {
- allocated[i] = cache.Allocate(a, class_id);
- }
- for (uptr i = 0; i < kNumAllocs; i++) {
- cache.Deallocate(a, class_id, allocated[i]);
- }
- cache.Drain(a);
- uptr total_allocated = a->TotalMemoryUsed();
- if (it)
- CHECK_EQ(saved_total, total_allocated);
- saved_total = total_allocated;
- }
- }
-
- a->TestOnlyUnmap();
- delete a;
-}
-
-#if SANITIZER_CAN_USE_ALLOCATOR64
-// These tests can fail on Windows if memory is somewhat full and lit happens
-// to run them all at the same time. FIXME: Make them not flaky and reenable.
-#if !SANITIZER_WINDOWS
-TEST(SanitizerCommon, SizeClassAllocator64LocalCache) {
- TestSizeClassAllocatorLocalCache<
- SizeClassAllocatorLocalCache<Allocator64> >();
-}
-
-TEST(SanitizerCommon, SizeClassAllocator64DynamicLocalCache) {
- TestSizeClassAllocatorLocalCache<
- SizeClassAllocatorLocalCache<Allocator64Dynamic> >();
-}
-
-#if !SANITIZER_ANDROID
-TEST(SanitizerCommon, SizeClassAllocator64CompactLocalCache) {
- TestSizeClassAllocatorLocalCache<
- SizeClassAllocatorLocalCache<Allocator64Compact> >();
-}
-#endif
-TEST(SanitizerCommon, SizeClassAllocator64VeryCompactLocalCache) {
- TestSizeClassAllocatorLocalCache<
- SizeClassAllocatorLocalCache<Allocator64VeryCompact> >();
-}
-#endif
-#endif
-
-TEST(SanitizerCommon, SizeClassAllocator32CompactLocalCache) {
- TestSizeClassAllocatorLocalCache<
- SizeClassAllocatorLocalCache<Allocator32Compact> >();
-}
-
-#if SANITIZER_CAN_USE_ALLOCATOR64
-typedef SizeClassAllocatorLocalCache<Allocator64> AllocatorCache;
-static AllocatorCache static_allocator_cache;
-
-void *AllocatorLeakTestWorker(void *arg) {
- typedef AllocatorCache::Allocator Allocator;
- Allocator *a = (Allocator*)(arg);
- static_allocator_cache.Allocate(a, 10);
- static_allocator_cache.Drain(a);
- return 0;
-}
-
-TEST(SanitizerCommon, AllocatorLeakTest) {
- typedef AllocatorCache::Allocator Allocator;
- Allocator a;
- a.Init(kReleaseToOSIntervalNever);
- uptr total_used_memory = 0;
- for (int i = 0; i < 100; i++) {
- pthread_t t;
- PTHREAD_CREATE(&t, 0, AllocatorLeakTestWorker, &a);
- PTHREAD_JOIN(t, 0);
- if (i == 0)
- total_used_memory = a.TotalMemoryUsed();
- EXPECT_EQ(a.TotalMemoryUsed(), total_used_memory);
- }
-
- a.TestOnlyUnmap();
-}
-
-// Struct which is allocated to pass info to new threads. The new thread frees
-// it.
-struct NewThreadParams {
- AllocatorCache *thread_cache;
- AllocatorCache::Allocator *allocator;
- uptr class_id;
-};
-
-// Called in a new thread. Just frees its argument.
-static void *DeallocNewThreadWorker(void *arg) {
- NewThreadParams *params = reinterpret_cast<NewThreadParams*>(arg);
- params->thread_cache->Deallocate(params->allocator, params->class_id, params);
- return NULL;
-}
-
-// The allocator cache is supposed to be POD and zero initialized. We should be
-// able to call Deallocate on a zeroed cache, and it will self-initialize.
-TEST(Allocator, AllocatorCacheDeallocNewThread) {
- AllocatorCache::Allocator allocator;
- allocator.Init(kReleaseToOSIntervalNever);
- AllocatorCache main_cache;
- AllocatorCache child_cache;
- memset(&main_cache, 0, sizeof(main_cache));
- memset(&child_cache, 0, sizeof(child_cache));
-
- uptr class_id = DefaultSizeClassMap::ClassID(sizeof(NewThreadParams));
- NewThreadParams *params = reinterpret_cast<NewThreadParams*>(
- main_cache.Allocate(&allocator, class_id));
- params->thread_cache = &child_cache;
- params->allocator = &allocator;
- params->class_id = class_id;
- pthread_t t;
- PTHREAD_CREATE(&t, 0, DeallocNewThreadWorker, params);
- PTHREAD_JOIN(t, 0);
-
- allocator.TestOnlyUnmap();
-}
-#endif
-
-TEST(Allocator, Basic) {
- char *p = (char*)InternalAlloc(10);
- EXPECT_NE(p, (char*)0);
- char *p2 = (char*)InternalAlloc(20);
- EXPECT_NE(p2, (char*)0);
- EXPECT_NE(p2, p);
- InternalFree(p);
- InternalFree(p2);
-}
-
-TEST(Allocator, Stress) {
- const int kCount = 1000;
- char *ptrs[kCount];
- unsigned rnd = 42;
- for (int i = 0; i < kCount; i++) {
- uptr sz = my_rand_r(&rnd) % 1000;
- char *p = (char*)InternalAlloc(sz);
- EXPECT_NE(p, (char*)0);
- ptrs[i] = p;
- }
- for (int i = 0; i < kCount; i++) {
- InternalFree(ptrs[i]);
- }
-}
-
-TEST(Allocator, LargeAlloc) {
- void *p = InternalAlloc(10 << 20);
- InternalFree(p);
-}
-
-TEST(Allocator, ScopedBuffer) {
- const int kSize = 512;
- {
- InternalMmapVector<int> int_buf(kSize);
- EXPECT_EQ((uptr)kSize, int_buf.size()); // NOLINT
- }
- InternalMmapVector<char> char_buf(kSize);
- EXPECT_EQ((uptr)kSize, char_buf.size()); // NOLINT
- internal_memset(char_buf.data(), 'c', kSize);
- for (int i = 0; i < kSize; i++) {
- EXPECT_EQ('c', char_buf[i]);
- }
-}
-
-void IterationTestCallback(uptr chunk, void *arg) {
- reinterpret_cast<std::set<uptr> *>(arg)->insert(chunk);
-}
-
-template <class Allocator>
-void TestSizeClassAllocatorIteration() {
- Allocator *a = new Allocator;
- a->Init(kReleaseToOSIntervalNever);
- SizeClassAllocatorLocalCache<Allocator> cache;
- memset(&cache, 0, sizeof(cache));
- cache.Init(0);
-
- static const uptr sizes[] = {1, 16, 30, 40, 100, 1000, 10000,
- 50000, 60000, 100000, 120000, 300000, 500000, 1000000, 2000000};
-
- std::vector<void *> allocated;
-
- // Allocate a bunch of chunks.
- for (uptr s = 0; s < ARRAY_SIZE(sizes); s++) {
- uptr size = sizes[s];
- if (!a->CanAllocate(size, 1)) continue;
- // printf("s = %ld\n", size);
- uptr n_iter = std::max((uptr)6, 80000 / size);
- // fprintf(stderr, "size: %ld iter: %ld\n", size, n_iter);
- for (uptr j = 0; j < n_iter; j++) {
- uptr class_id0 = Allocator::SizeClassMapT::ClassID(size);
- void *x = cache.Allocate(a, class_id0);
- allocated.push_back(x);
- }
- }
-
- std::set<uptr> reported_chunks;
- a->ForceLock();
- a->ForEachChunk(IterationTestCallback, &reported_chunks);
- a->ForceUnlock();
-
- for (uptr i = 0; i < allocated.size(); i++) {
- // Don't use EXPECT_NE. Reporting the first mismatch is enough.
- ASSERT_NE(reported_chunks.find(reinterpret_cast<uptr>(allocated[i])),
- reported_chunks.end());
- }
-
- a->TestOnlyUnmap();
- delete a;
-}
-
-#if SANITIZER_CAN_USE_ALLOCATOR64
-// These tests can fail on Windows if memory is somewhat full and lit happens
-// to run them all at the same time. FIXME: Make them not flaky and reenable.
-#if !SANITIZER_WINDOWS
-TEST(SanitizerCommon, SizeClassAllocator64Iteration) {
- TestSizeClassAllocatorIteration<Allocator64>();
-}
-TEST(SanitizerCommon, SizeClassAllocator64DynamicIteration) {
- TestSizeClassAllocatorIteration<Allocator64Dynamic>();
-}
-#endif
-#endif
-
-TEST(SanitizerCommon, SizeClassAllocator32Iteration) {
- TestSizeClassAllocatorIteration<Allocator32Compact>();
-}
-
-TEST(SanitizerCommon, LargeMmapAllocatorIteration) {
- LargeMmapAllocator<NoOpMapUnmapCallback> a;
- a.Init();
- AllocatorStats stats;
- stats.Init();
-
- static const uptr kNumAllocs = 1000;
- char *allocated[kNumAllocs];
- static const uptr size = 40;
- // Allocate some.
- for (uptr i = 0; i < kNumAllocs; i++)
- allocated[i] = (char *)a.Allocate(&stats, size, 1);
-
- std::set<uptr> reported_chunks;
- a.ForceLock();
- a.ForEachChunk(IterationTestCallback, &reported_chunks);
- a.ForceUnlock();
-
- for (uptr i = 0; i < kNumAllocs; i++) {
- // Don't use EXPECT_NE. Reporting the first mismatch is enough.
- ASSERT_NE(reported_chunks.find(reinterpret_cast<uptr>(allocated[i])),
- reported_chunks.end());
- }
- for (uptr i = 0; i < kNumAllocs; i++)
- a.Deallocate(&stats, allocated[i]);
-}
-
-TEST(SanitizerCommon, LargeMmapAllocatorBlockBegin) {
- LargeMmapAllocator<NoOpMapUnmapCallback> a;
- a.Init();
- AllocatorStats stats;
- stats.Init();
-
- static const uptr kNumAllocs = 1024;
- static const uptr kNumExpectedFalseLookups = 10000000;
- char *allocated[kNumAllocs];
- static const uptr size = 4096;
- // Allocate some.
- for (uptr i = 0; i < kNumAllocs; i++) {
- allocated[i] = (char *)a.Allocate(&stats, size, 1);
- }
-
- a.ForceLock();
- for (uptr i = 0; i < kNumAllocs * kNumAllocs; i++) {
- // if ((i & (i - 1)) == 0) fprintf(stderr, "[%zd]\n", i);
- char *p1 = allocated[i % kNumAllocs];
- EXPECT_EQ(p1, a.GetBlockBeginFastLocked(p1));
- EXPECT_EQ(p1, a.GetBlockBeginFastLocked(p1 + size / 2));
- EXPECT_EQ(p1, a.GetBlockBeginFastLocked(p1 + size - 1));
- EXPECT_EQ(p1, a.GetBlockBeginFastLocked(p1 - 100));
- }
-
- for (uptr i = 0; i < kNumExpectedFalseLookups; i++) {
- void *p = reinterpret_cast<void *>(i % 1024);
- EXPECT_EQ((void *)0, a.GetBlockBeginFastLocked(p));
- p = reinterpret_cast<void *>(~0L - (i % 1024));
- EXPECT_EQ((void *)0, a.GetBlockBeginFastLocked(p));
- }
- a.ForceUnlock();
-
- for (uptr i = 0; i < kNumAllocs; i++)
- a.Deallocate(&stats, allocated[i]);
-}
-
-
-// Don't test OOM conditions on Win64 because it causes other tests on the same
-// machine to OOM.
-#if SANITIZER_CAN_USE_ALLOCATOR64 && !SANITIZER_WINDOWS64 && !SANITIZER_ANDROID
-typedef SizeClassMap<3, 4, 8, 63, 128, 16> SpecialSizeClassMap;
-template <typename AddressSpaceViewTy = LocalAddressSpaceView>
-struct AP64_SpecialSizeClassMap {
- static const uptr kSpaceBeg = kAllocatorSpace;
- static const uptr kSpaceSize = kAllocatorSize;
- static const uptr kMetadataSize = 0;
- typedef SpecialSizeClassMap SizeClassMap;
- typedef NoOpMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags = 0;
- using AddressSpaceView = AddressSpaceViewTy;
-};
-
-// Regression test for out-of-memory condition in PopulateFreeList().
-TEST(SanitizerCommon, SizeClassAllocator64PopulateFreeListOOM) {
- // In a world where regions are small and chunks are huge...
- typedef SizeClassAllocator64<AP64_SpecialSizeClassMap<>> SpecialAllocator64;
- const uptr kRegionSize =
- kAllocatorSize / SpecialSizeClassMap::kNumClassesRounded;
- SpecialAllocator64 *a = new SpecialAllocator64;
- a->Init(kReleaseToOSIntervalNever);
- SizeClassAllocatorLocalCache<SpecialAllocator64> cache;
- memset(&cache, 0, sizeof(cache));
- cache.Init(0);
-
- // ...one man is on a mission to overflow a region with a series of
- // successive allocations.
-
- const uptr kClassID = 107;
- const uptr kAllocationSize = SpecialSizeClassMap::Size(kClassID);
- ASSERT_LT(2 * kAllocationSize, kRegionSize);
- ASSERT_GT(3 * kAllocationSize, kRegionSize);
- EXPECT_NE(cache.Allocate(a, kClassID), nullptr);
- EXPECT_NE(cache.Allocate(a, kClassID), nullptr);
- EXPECT_EQ(cache.Allocate(a, kClassID), nullptr);
-
- const uptr Class2 = 100;
- const uptr Size2 = SpecialSizeClassMap::Size(Class2);
- ASSERT_EQ(Size2 * 8, kRegionSize);
- char *p[7];
- for (int i = 0; i < 7; i++) {
- p[i] = (char*)cache.Allocate(a, Class2);
- EXPECT_NE(p[i], nullptr);
- fprintf(stderr, "p[%d] %p s = %lx\n", i, (void*)p[i], Size2);
- p[i][Size2 - 1] = 42;
- if (i) ASSERT_LT(p[i - 1], p[i]);
- }
- EXPECT_EQ(cache.Allocate(a, Class2), nullptr);
- cache.Deallocate(a, Class2, p[0]);
- cache.Drain(a);
- ASSERT_EQ(p[6][Size2 - 1], 42);
- a->TestOnlyUnmap();
- delete a;
-}
-
-#endif
-
-#if SANITIZER_CAN_USE_ALLOCATOR64
-
-class NoMemoryMapper {
- public:
- uptr last_request_buffer_size;
-
- NoMemoryMapper() : last_request_buffer_size(0) {}
-
- uptr MapPackedCounterArrayBuffer(uptr buffer_size) {
- last_request_buffer_size = buffer_size;
- return 0;
- }
- void UnmapPackedCounterArrayBuffer(uptr buffer, uptr buffer_size) {}
-};
-
-class RedZoneMemoryMapper {
- public:
- RedZoneMemoryMapper() {
- const auto page_size = GetPageSize();
- buffer = MmapOrDie(3ULL * page_size, "");
- MprotectNoAccess(reinterpret_cast<uptr>(buffer), page_size);
- MprotectNoAccess(reinterpret_cast<uptr>(buffer) + page_size * 2, page_size);
- }
- ~RedZoneMemoryMapper() {
- UnmapOrDie(buffer, 3 * GetPageSize());
- }
-
- uptr MapPackedCounterArrayBuffer(uptr buffer_size) {
- const auto page_size = GetPageSize();
- CHECK_EQ(buffer_size, page_size);
- memset(reinterpret_cast<void*>(reinterpret_cast<uptr>(buffer) + page_size),
- 0, page_size);
- return reinterpret_cast<uptr>(buffer) + page_size;
- }
- void UnmapPackedCounterArrayBuffer(uptr buffer, uptr buffer_size) {}
-
- private:
- void *buffer;
-};
-
-TEST(SanitizerCommon, SizeClassAllocator64PackedCounterArray) {
- NoMemoryMapper no_memory_mapper;
- typedef Allocator64::PackedCounterArray<NoMemoryMapper>
- NoMemoryPackedCounterArray;
-
- for (int i = 0; i < 64; i++) {
- // Various valid counter's max values packed into one word.
- NoMemoryPackedCounterArray counters_2n(1, 1ULL << i, &no_memory_mapper);
- EXPECT_EQ(8ULL, no_memory_mapper.last_request_buffer_size);
-
- // Check the "all bit set" values too.
- NoMemoryPackedCounterArray counters_2n1_1(1, ~0ULL >> i, &no_memory_mapper);
- EXPECT_EQ(8ULL, no_memory_mapper.last_request_buffer_size);
-
- // Verify the packing ratio, the counter is expected to be packed into the
- // closest power of 2 bits.
- NoMemoryPackedCounterArray counters(64, 1ULL << i, &no_memory_mapper);
- EXPECT_EQ(8ULL * RoundUpToPowerOfTwo(i + 1),
- no_memory_mapper.last_request_buffer_size);
- }
-
- RedZoneMemoryMapper memory_mapper;
- typedef Allocator64::PackedCounterArray<RedZoneMemoryMapper>
- RedZonePackedCounterArray;
- // Go through 1, 2, 4, 8, .. 64 bits per counter.
- for (int i = 0; i < 7; i++) {
- // Make sure counters request one memory page for the buffer.
- const u64 kNumCounters = (GetPageSize() / 8) * (64 >> i);
- RedZonePackedCounterArray counters(kNumCounters,
- 1ULL << ((1 << i) - 1),
- &memory_mapper);
- counters.Inc(0);
- for (u64 c = 1; c < kNumCounters - 1; c++) {
- ASSERT_EQ(0ULL, counters.Get(c));
- counters.Inc(c);
- ASSERT_EQ(1ULL, counters.Get(c - 1));
- }
- ASSERT_EQ(0ULL, counters.Get(kNumCounters - 1));
- counters.Inc(kNumCounters - 1);
-
- if (i > 0) {
- counters.IncRange(0, kNumCounters - 1);
- for (u64 c = 0; c < kNumCounters; c++)
- ASSERT_EQ(2ULL, counters.Get(c));
- }
- }
-}
-
-class RangeRecorder {
- public:
- std::string reported_pages;
-
- RangeRecorder()
- : page_size_scaled_log(
- Log2(GetPageSizeCached() >> Allocator64::kCompactPtrScale)),
- last_page_reported(0) {}
-
- void ReleasePageRangeToOS(u32 from, u32 to) {
- from >>= page_size_scaled_log;
- to >>= page_size_scaled_log;
- ASSERT_LT(from, to);
- if (!reported_pages.empty())
- ASSERT_LT(last_page_reported, from);
- reported_pages.append(from - last_page_reported, '.');
- reported_pages.append(to - from, 'x');
- last_page_reported = to;
- }
- private:
- const uptr page_size_scaled_log;
- u32 last_page_reported;
-};
-
-TEST(SanitizerCommon, SizeClassAllocator64FreePagesRangeTracker) {
- typedef Allocator64::FreePagesRangeTracker<RangeRecorder> RangeTracker;
-
- // 'x' denotes a page to be released, '.' denotes a page to be kept around.
- const char* test_cases[] = {
- "",
- ".",
- "x",
- "........",
- "xxxxxxxxxxx",
- "..............xxxxx",
- "xxxxxxxxxxxxxxxxxx.....",
- "......xxxxxxxx........",
- "xxx..........xxxxxxxxxxxxxxx",
- "......xxxx....xxxx........",
- "xxx..........xxxxxxxx....xxxxxxx",
- "x.x.x.x.x.x.x.x.x.x.x.x.",
- ".x.x.x.x.x.x.x.x.x.x.x.x",
- ".x.x.x.x.x.x.x.x.x.x.x.x.",
- "x.x.x.x.x.x.x.x.x.x.x.x.x",
- };
-
- for (auto test_case : test_cases) {
- RangeRecorder range_recorder;
- RangeTracker tracker(&range_recorder);
- for (int i = 0; test_case[i] != 0; i++)
- tracker.NextPage(test_case[i] == 'x');
- tracker.Done();
- // Strip trailing '.'-pages before comparing the results as they are not
- // going to be reported to range_recorder anyway.
- const char* last_x = strrchr(test_case, 'x');
- std::string expected(
- test_case,
- last_x == nullptr ? 0 : (last_x - test_case + 1));
- EXPECT_STREQ(expected.c_str(), range_recorder.reported_pages.c_str());
- }
-}
-
-class ReleasedPagesTrackingMemoryMapper {
- public:
- std::set<u32> reported_pages;
-
- uptr MapPackedCounterArrayBuffer(uptr buffer_size) {
- reported_pages.clear();
- return reinterpret_cast<uptr>(calloc(1, buffer_size));
- }
- void UnmapPackedCounterArrayBuffer(uptr buffer, uptr buffer_size) {
- free(reinterpret_cast<void*>(buffer));
- }
-
- void ReleasePageRangeToOS(u32 from, u32 to) {
- uptr page_size_scaled =
- GetPageSizeCached() >> Allocator64::kCompactPtrScale;
- for (u32 i = from; i < to; i += page_size_scaled)
- reported_pages.insert(i);
- }
-};
-
-template <class Allocator>
-void TestReleaseFreeMemoryToOS() {
- ReleasedPagesTrackingMemoryMapper memory_mapper;
- const uptr kAllocatedPagesCount = 1024;
- const uptr page_size = GetPageSizeCached();
- const uptr page_size_scaled = page_size >> Allocator::kCompactPtrScale;
- std::mt19937 r;
- uint32_t rnd_state = 42;
-
- for (uptr class_id = 1; class_id <= Allocator::SizeClassMapT::kLargestClassID;
- class_id++) {
- const uptr chunk_size = Allocator::SizeClassMapT::Size(class_id);
- const uptr chunk_size_scaled = chunk_size >> Allocator::kCompactPtrScale;
- const uptr max_chunks =
- kAllocatedPagesCount * GetPageSizeCached() / chunk_size;
-
- // Generate the random free list.
- std::vector<u32> free_array;
- bool in_free_range = false;
- uptr current_range_end = 0;
- for (uptr i = 0; i < max_chunks; i++) {
- if (i == current_range_end) {
- in_free_range = (my_rand_r(&rnd_state) & 1U) == 1;
- current_range_end += my_rand_r(&rnd_state) % 100 + 1;
- }
- if (in_free_range)
- free_array.push_back(i * chunk_size_scaled);
- }
- if (free_array.empty())
- continue;
- // Shuffle free_list to verify that ReleaseFreeMemoryToOS does not depend on
- // the list ordering.
- std::shuffle(free_array.begin(), free_array.end(), r);
-
- Allocator::ReleaseFreeMemoryToOS(&free_array[0], free_array.size(),
- chunk_size, kAllocatedPagesCount,
- &memory_mapper);
-
- // Verify that there are no released pages touched by used chunks and all
- // ranges of free chunks big enough to contain the entire memory pages had
- // these pages released.
- uptr verified_released_pages = 0;
- std::set<u32> free_chunks(free_array.begin(), free_array.end());
-
- u32 current_chunk = 0;
- in_free_range = false;
- u32 current_free_range_start = 0;
- for (uptr i = 0; i <= max_chunks; i++) {
- bool is_free_chunk = free_chunks.find(current_chunk) != free_chunks.end();
-
- if (is_free_chunk) {
- if (!in_free_range) {
- in_free_range = true;
- current_free_range_start = current_chunk;
- }
- } else {
- // Verify that this used chunk does not touch any released page.
- for (uptr i_page = current_chunk / page_size_scaled;
- i_page <= (current_chunk + chunk_size_scaled - 1) /
- page_size_scaled;
- i_page++) {
- bool page_released =
- memory_mapper.reported_pages.find(i_page * page_size_scaled) !=
- memory_mapper.reported_pages.end();
- ASSERT_EQ(false, page_released);
- }
-
- if (in_free_range) {
- in_free_range = false;
- // Verify that all entire memory pages covered by this range of free
- // chunks were released.
- u32 page = RoundUpTo(current_free_range_start, page_size_scaled);
- while (page + page_size_scaled <= current_chunk) {
- bool page_released =
- memory_mapper.reported_pages.find(page) !=
- memory_mapper.reported_pages.end();
- ASSERT_EQ(true, page_released);
- verified_released_pages++;
- page += page_size_scaled;
- }
- }
- }
-
- current_chunk += chunk_size_scaled;
- }
-
- ASSERT_EQ(memory_mapper.reported_pages.size(), verified_released_pages);
- }
-}
-
-TEST(SanitizerCommon, SizeClassAllocator64ReleaseFreeMemoryToOS) {
- TestReleaseFreeMemoryToOS<Allocator64>();
-}
-
-#if !SANITIZER_ANDROID
-TEST(SanitizerCommon, SizeClassAllocator64CompactReleaseFreeMemoryToOS) {
- TestReleaseFreeMemoryToOS<Allocator64Compact>();
-}
-
-TEST(SanitizerCommon, SizeClassAllocator64VeryCompactReleaseFreeMemoryToOS) {
- TestReleaseFreeMemoryToOS<Allocator64VeryCompact>();
-}
-#endif // !SANITIZER_ANDROID
-
-#endif // SANITIZER_CAN_USE_ALLOCATOR64
-
-TEST(SanitizerCommon, TwoLevelByteMap) {
- const u64 kSize1 = 1 << 6, kSize2 = 1 << 12;
- const u64 n = kSize1 * kSize2;
- TwoLevelByteMap<kSize1, kSize2> m;
- m.Init();
- for (u64 i = 0; i < n; i += 7) {
- m.set(i, (i % 100) + 1);
- }
- for (u64 j = 0; j < n; j++) {
- if (j % 7)
- EXPECT_EQ(m[j], 0);
- else
- EXPECT_EQ(m[j], (j % 100) + 1);
- }
-
- m.TestOnlyUnmap();
-}
-
-template <typename AddressSpaceView>
-using TestByteMapASVT =
- TwoLevelByteMap<1 << 12, 1 << 13, AddressSpaceView, TestMapUnmapCallback>;
-using TestByteMap = TestByteMapASVT<LocalAddressSpaceView>;
-
-struct TestByteMapParam {
- TestByteMap *m;
- size_t shard;
- size_t num_shards;
-};
-
-void *TwoLevelByteMapUserThread(void *param) {
- TestByteMapParam *p = (TestByteMapParam*)param;
- for (size_t i = p->shard; i < p->m->size(); i += p->num_shards) {
- size_t val = (i % 100) + 1;
- p->m->set(i, val);
- EXPECT_EQ((*p->m)[i], val);
- }
- return 0;
-}
-
-TEST(SanitizerCommon, ThreadedTwoLevelByteMap) {
- TestByteMap m;
- m.Init();
- TestMapUnmapCallback::map_count = 0;
- TestMapUnmapCallback::unmap_count = 0;
- static const int kNumThreads = 4;
- pthread_t t[kNumThreads];
- TestByteMapParam p[kNumThreads];
- for (int i = 0; i < kNumThreads; i++) {
- p[i].m = &m;
- p[i].shard = i;
- p[i].num_shards = kNumThreads;
- PTHREAD_CREATE(&t[i], 0, TwoLevelByteMapUserThread, &p[i]);
- }
- for (int i = 0; i < kNumThreads; i++) {
- PTHREAD_JOIN(t[i], 0);
- }
- EXPECT_EQ((uptr)TestMapUnmapCallback::map_count, m.size1());
- EXPECT_EQ((uptr)TestMapUnmapCallback::unmap_count, 0UL);
- m.TestOnlyUnmap();
- EXPECT_EQ((uptr)TestMapUnmapCallback::map_count, m.size1());
- EXPECT_EQ((uptr)TestMapUnmapCallback::unmap_count, m.size1());
-}
-
-#endif // #if !SANITIZER_DEBUG
diff --git a/lib/sanitizer_common/tests/sanitizer_allocator_testlib.cc b/lib/sanitizer_common/tests/sanitizer_allocator_testlib.cc
deleted file mode 100644
index d2920d8f7f67c..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_allocator_testlib.cc
+++ /dev/null
@@ -1,203 +0,0 @@
-//===-- sanitizer_allocator_testlib.cc ------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// Malloc replacement library based on CombinedAllocator.
-// The primary purpose of this file is an end-to-end integration test
-// for CombinedAllocator.
-//===----------------------------------------------------------------------===//
-/* Usage:
-clang++ -std=c++11 -fno-exceptions -g -fPIC -I. -I../include -Isanitizer \
- sanitizer_common/tests/sanitizer_allocator_testlib.cc \
- $(\ls sanitizer_common/sanitizer_*.cc | grep -v sanitizer_common_nolibc.cc) \
- sanitizer_common/sanitizer_linux_x86_64.S \
- -shared -lpthread -o testmalloc.so
-LD_PRELOAD=`pwd`/testmalloc.so /your/app
-*/
-#include "sanitizer_common/sanitizer_allocator.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include <stddef.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <string.h>
-#include <pthread.h>
-
-#ifndef SANITIZER_MALLOC_HOOK
-# define SANITIZER_MALLOC_HOOK(p, s)
-#endif
-
-#ifndef SANITIZER_FREE_HOOK
-# define SANITIZER_FREE_HOOK(p)
-#endif
-
-static const uptr kAllocatorSpace = 0x600000000000ULL;
-static const uptr kAllocatorSize = 0x10000000000ULL; // 1T.
-
-struct __AP64 {
- static const uptr kSpaceBeg = ~(uptr)0;
- static const uptr kSpaceSize = kAllocatorSize;
- static const uptr kMetadataSize = 0;
- typedef CompactSizeClassMap SizeClassMap;
- typedef NoOpMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags =
- SizeClassAllocator64FlagMasks::kRandomShuffleChunks;
-};
-
-namespace {
-
-typedef SizeClassAllocator64<__AP64> PrimaryAllocator;
-typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
-typedef LargeMmapAllocator<> SecondaryAllocator;
-typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
- SecondaryAllocator> Allocator;
-
-static Allocator allocator;
-static bool global_inited;
-static THREADLOCAL AllocatorCache cache;
-static THREADLOCAL bool thread_inited;
-static pthread_key_t pkey;
-
-static void thread_dtor(void *v) {
- if ((uptr)v != 3) {
- pthread_setspecific(pkey, (void*)((uptr)v + 1));
- return;
- }
- allocator.SwallowCache(&cache);
-}
-
-static size_t GetRss() {
- if (FILE *f = fopen("/proc/self/statm", "r")) {
- size_t size = 0, rss = 0;
- fscanf(f, "%zd %zd", &size, &rss);
- fclose(f);
- return rss << 12; // rss is in pages.
- }
- return 0;
-}
-
-struct AtExit {
- ~AtExit() {
- allocator.PrintStats();
- Printf("RSS: %zdM\n", GetRss() >> 20);
- }
-};
-
-static AtExit at_exit;
-
-static void NOINLINE thread_init() {
- if (!global_inited) {
- global_inited = true;
- allocator.Init(false /*may_return_null*/);
- pthread_key_create(&pkey, thread_dtor);
- }
- thread_inited = true;
- pthread_setspecific(pkey, (void*)1);
- cache.Init(nullptr);
-}
-} // namespace
-
-extern "C" {
-void *malloc(size_t size) {
- if (UNLIKELY(!thread_inited))
- thread_init();
- void *p = allocator.Allocate(&cache, size, 8);
- SANITIZER_MALLOC_HOOK(p, size);
- return p;
-}
-
-void free(void *p) {
- if (UNLIKELY(!thread_inited))
- thread_init();
- SANITIZER_FREE_HOOK(p);
- allocator.Deallocate(&cache, p);
-}
-
-void *calloc(size_t nmemb, size_t size) {
- if (UNLIKELY(!thread_inited))
- thread_init();
- size *= nmemb;
- void *p = allocator.Allocate(&cache, size, 8, false);
- memset(p, 0, size);
- SANITIZER_MALLOC_HOOK(p, size);
- return p;
-}
-
-void *realloc(void *p, size_t size) {
- if (UNLIKELY(!thread_inited))
- thread_init();
- if (p) {
- SANITIZER_FREE_HOOK(p);
- }
- p = allocator.Reallocate(&cache, p, size, 8);
- if (p) {
- SANITIZER_MALLOC_HOOK(p, size);
- }
- return p;
-}
-
-#if SANITIZER_INTERCEPT_MEMALIGN
-void *memalign(size_t alignment, size_t size) {
- if (UNLIKELY(!thread_inited))
- thread_init();
- void *p = allocator.Allocate(&cache, size, alignment);
- SANITIZER_MALLOC_HOOK(p, size);
- return p;
-}
-#endif // SANITIZER_INTERCEPT_MEMALIGN
-
-int posix_memalign(void **memptr, size_t alignment, size_t size) {
- if (UNLIKELY(!thread_inited))
- thread_init();
- *memptr = allocator.Allocate(&cache, size, alignment);
- SANITIZER_MALLOC_HOOK(*memptr, size);
- return 0;
-}
-
-void *valloc(size_t size) {
- if (UNLIKELY(!thread_inited))
- thread_init();
- if (size == 0)
- size = GetPageSizeCached();
- void *p = allocator.Allocate(&cache, size, GetPageSizeCached());
- SANITIZER_MALLOC_HOOK(p, size);
- return p;
-}
-
-#if SANITIZER_INTERCEPT_CFREE
-void cfree(void *p) ALIAS("free");
-#endif // SANITIZER_INTERCEPT_CFREE
-#if SANITIZER_INTERCEPT_PVALLOC
-void *pvalloc(size_t size) ALIAS("valloc");
-#endif // SANITIZER_INTERCEPT_PVALLOC
-#if SANITIZER_INTERCEPT_MEMALIGN
-void *__libc_memalign(size_t alignment, size_t size) ALIAS("memalign");
-#endif // SANITIZER_INTERCEPT_MEMALIGN
-
-void malloc_usable_size() {
-}
-
-#if SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
-void mallinfo() {
-}
-
-void mallopt() {
-}
-#endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
-} // extern "C"
-
-namespace std {
- struct nothrow_t;
-}
-
-void *operator new(size_t size) ALIAS("malloc");
-void *operator new[](size_t size) ALIAS("malloc");
-void *operator new(size_t size, std::nothrow_t const&) ALIAS("malloc");
-void *operator new[](size_t size, std::nothrow_t const&) ALIAS("malloc");
-void operator delete(void *ptr) throw() ALIAS("free");
-void operator delete[](void *ptr) throw() ALIAS("free");
-void operator delete(void *ptr, std::nothrow_t const&) ALIAS("free");
-void operator delete[](void *ptr, std::nothrow_t const&) ALIAS("free");
diff --git a/lib/sanitizer_common/tests/sanitizer_atomic_test.cc b/lib/sanitizer_common/tests/sanitizer_atomic_test.cc
deleted file mode 100644
index 56bcd35c826c1..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_atomic_test.cc
+++ /dev/null
@@ -1,128 +0,0 @@
-//===-- sanitizer_atomic_test.cc ------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_atomic.h"
-#include "gtest/gtest.h"
-
-namespace __sanitizer {
-
-template<typename T>
-struct ValAndMagic {
- typename T::Type magic0;
- T a;
- typename T::Type magic1;
-
- static ValAndMagic<T> *sink;
-};
-
-template<typename T>
-ValAndMagic<T> *ValAndMagic<T>::sink;
-
-template<typename T, memory_order load_mo, memory_order store_mo>
-void CheckStoreLoad() {
- typedef typename T::Type Type;
- ValAndMagic<T> val;
- // Prevent the compiler from scalarizing the struct.
- ValAndMagic<T>::sink = &val;
- // Ensure that surrounding memory is not overwritten.
- val.magic0 = val.magic1 = (Type)-3;
- for (u64 i = 0; i < 100; i++) {
- // Generate a value that occupies all bytes of the variable.
- u64 v = i;
- v |= v << 8;
- v |= v << 16;
- v |= v << 32;
- val.a.val_dont_use = (Type)v;
- EXPECT_EQ(atomic_load(&val.a, load_mo), (Type)v);
- val.a.val_dont_use = (Type)-1;
- atomic_store(&val.a, (Type)v, store_mo);
- EXPECT_EQ(val.a.val_dont_use, (Type)v);
- }
- EXPECT_EQ(val.magic0, (Type)-3);
- EXPECT_EQ(val.magic1, (Type)-3);
-}
-
-TEST(SanitizerCommon, AtomicStoreLoad) {
- CheckStoreLoad<atomic_uint8_t, memory_order_relaxed, memory_order_relaxed>();
- CheckStoreLoad<atomic_uint8_t, memory_order_consume, memory_order_relaxed>();
- CheckStoreLoad<atomic_uint8_t, memory_order_acquire, memory_order_relaxed>();
- CheckStoreLoad<atomic_uint8_t, memory_order_relaxed, memory_order_release>();
- CheckStoreLoad<atomic_uint8_t, memory_order_seq_cst, memory_order_seq_cst>();
-
- CheckStoreLoad<atomic_uint16_t, memory_order_relaxed, memory_order_relaxed>();
- CheckStoreLoad<atomic_uint16_t, memory_order_consume, memory_order_relaxed>();
- CheckStoreLoad<atomic_uint16_t, memory_order_acquire, memory_order_relaxed>();
- CheckStoreLoad<atomic_uint16_t, memory_order_relaxed, memory_order_release>();
- CheckStoreLoad<atomic_uint16_t, memory_order_seq_cst, memory_order_seq_cst>();
-
- CheckStoreLoad<atomic_uint32_t, memory_order_relaxed, memory_order_relaxed>();
- CheckStoreLoad<atomic_uint32_t, memory_order_consume, memory_order_relaxed>();
- CheckStoreLoad<atomic_uint32_t, memory_order_acquire, memory_order_relaxed>();
- CheckStoreLoad<atomic_uint32_t, memory_order_relaxed, memory_order_release>();
- CheckStoreLoad<atomic_uint32_t, memory_order_seq_cst, memory_order_seq_cst>();
-
- CheckStoreLoad<atomic_uint64_t, memory_order_relaxed, memory_order_relaxed>();
- CheckStoreLoad<atomic_uint64_t, memory_order_consume, memory_order_relaxed>();
- CheckStoreLoad<atomic_uint64_t, memory_order_acquire, memory_order_relaxed>();
- CheckStoreLoad<atomic_uint64_t, memory_order_relaxed, memory_order_release>();
- CheckStoreLoad<atomic_uint64_t, memory_order_seq_cst, memory_order_seq_cst>();
-
- CheckStoreLoad<atomic_uintptr_t, memory_order_relaxed, memory_order_relaxed>
- ();
- CheckStoreLoad<atomic_uintptr_t, memory_order_consume, memory_order_relaxed>
- ();
- CheckStoreLoad<atomic_uintptr_t, memory_order_acquire, memory_order_relaxed>
- ();
- CheckStoreLoad<atomic_uintptr_t, memory_order_relaxed, memory_order_release>
- ();
- CheckStoreLoad<atomic_uintptr_t, memory_order_seq_cst, memory_order_seq_cst>
- ();
-}
-
-// Clang crashes while compiling this test for Android:
-// http://llvm.org/bugs/show_bug.cgi?id=15587
-#if !SANITIZER_ANDROID
-template<typename T>
-void CheckAtomicCompareExchange() {
- typedef typename T::Type Type;
- {
- Type old_val = 42;
- Type new_val = 24;
- Type var = old_val;
- EXPECT_TRUE(atomic_compare_exchange_strong((T*)&var, &old_val, new_val,
- memory_order_relaxed));
- EXPECT_FALSE(atomic_compare_exchange_strong((T*)&var, &old_val, new_val,
- memory_order_relaxed));
- EXPECT_EQ(new_val, old_val);
- }
- {
- Type old_val = 42;
- Type new_val = 24;
- Type var = old_val;
- EXPECT_TRUE(atomic_compare_exchange_weak((T*)&var, &old_val, new_val,
- memory_order_relaxed));
- EXPECT_FALSE(atomic_compare_exchange_weak((T*)&var, &old_val, new_val,
- memory_order_relaxed));
- EXPECT_EQ(new_val, old_val);
- }
-}
-
-TEST(SanitizerCommon, AtomicCompareExchangeTest) {
- CheckAtomicCompareExchange<atomic_uint8_t>();
- CheckAtomicCompareExchange<atomic_uint16_t>();
- CheckAtomicCompareExchange<atomic_uint32_t>();
- CheckAtomicCompareExchange<atomic_uint64_t>();
- CheckAtomicCompareExchange<atomic_uintptr_t>();
-}
-#endif //!SANITIZER_ANDROID
-
-} // namespace __sanitizer
diff --git a/lib/sanitizer_common/tests/sanitizer_bitvector_test.cc b/lib/sanitizer_common/tests/sanitizer_bitvector_test.cc
deleted file mode 100644
index 669365b80ecbf..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_bitvector_test.cc
+++ /dev/null
@@ -1,178 +0,0 @@
-//===-- sanitizer_bitvector_test.cc ---------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of Sanitizer runtime.
-// Tests for sanitizer_bitvector.h.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_bitvector.h"
-
-#include "sanitizer_test_utils.h"
-
-#include "gtest/gtest.h"
-
-#include <algorithm>
-#include <vector>
-#include <random>
-#include <set>
-
-using namespace __sanitizer;
-using namespace std;
-
-
-// Check the 'bv' == 's' and that the indexes go in increasing order.
-// Also check the BV::Iterator
-template <class BV>
-static void CheckBV(const BV &bv, const set<uptr> &s) {
- BV t;
- t.copyFrom(bv);
- set<uptr> t_s(s);
- uptr last_idx = bv.size();
- uptr count = 0;
- for (typename BV::Iterator it(bv); it.hasNext();) {
- uptr idx = it.next();
- count++;
- if (last_idx != bv.size())
- EXPECT_LT(last_idx, idx);
- last_idx = idx;
- EXPECT_TRUE(s.count(idx));
- }
- EXPECT_EQ(count, s.size());
-
- last_idx = bv.size();
- while (!t.empty()) {
- uptr idx = t.getAndClearFirstOne();
- if (last_idx != bv.size())
- EXPECT_LT(last_idx, idx);
- last_idx = idx;
- EXPECT_TRUE(t_s.erase(idx));
- }
- EXPECT_TRUE(t_s.empty());
-}
-
-template <class BV>
-void Print(const BV &bv) {
- BV t;
- t.copyFrom(bv);
- while (!t.empty()) {
- uptr idx = t.getAndClearFirstOne();
- fprintf(stderr, "%lu ", idx);
- }
- fprintf(stderr, "\n");
-}
-
-void Print(const set<uptr> &s) {
- for (set<uptr>::iterator it = s.begin(); it != s.end(); ++it) {
- fprintf(stderr, "%lu ", *it);
- }
- fprintf(stderr, "\n");
-}
-
-template <class BV>
-void TestBitVector(uptr expected_size) {
- std::mt19937 r;
- BV bv, bv1, t_bv;
- EXPECT_EQ(expected_size, BV::kSize);
- bv.clear();
- EXPECT_TRUE(bv.empty());
- bv.setBit(5);
- EXPECT_FALSE(bv.empty());
- EXPECT_FALSE(bv.getBit(4));
- EXPECT_FALSE(bv.getBit(6));
- EXPECT_TRUE(bv.getBit(5));
- bv.clearBit(5);
- EXPECT_FALSE(bv.getBit(5));
-
- // test random bits
- bv.clear();
- set<uptr> s;
- for (uptr it = 0; it < 1000; it++) {
- uptr bit = ((uptr)my_rand() % bv.size());
- EXPECT_EQ(bv.getBit(bit), s.count(bit) == 1);
- switch (my_rand() % 2) {
- case 0:
- EXPECT_EQ(bv.setBit(bit), s.insert(bit).second);
- break;
- case 1:
- size_t old_size = s.size();
- s.erase(bit);
- EXPECT_EQ(bv.clearBit(bit), old_size > s.size());
- break;
- }
- EXPECT_EQ(bv.getBit(bit), s.count(bit) == 1);
- }
-
- vector<uptr>bits(bv.size());
- // Test setUnion, setIntersection, setDifference,
- // intersectsWith, and getAndClearFirstOne.
- for (uptr it = 0; it < 30; it++) {
- // iota
- for (size_t j = 0; j < bits.size(); j++) bits[j] = j;
- std::shuffle(bits.begin(), bits.end(), r);
- set<uptr> s, s1, t_s;
- bv.clear();
- bv1.clear();
- uptr n_bits = ((uptr)my_rand() % bv.size()) + 1;
- uptr n_bits1 = (uptr)my_rand() % (bv.size() / 2);
- EXPECT_TRUE(n_bits > 0 && n_bits <= bv.size());
- EXPECT_TRUE(n_bits1 < bv.size() / 2);
- for (uptr i = 0; i < n_bits; i++) {
- bv.setBit(bits[i]);
- s.insert(bits[i]);
- }
- CheckBV(bv, s);
- for (uptr i = 0; i < n_bits1; i++) {
- bv1.setBit(bits[bv.size() / 2 + i]);
- s1.insert(bits[bv.size() / 2 + i]);
- }
- CheckBV(bv1, s1);
-
- vector<uptr> vec;
- set_intersection(s.begin(), s.end(), s1.begin(), s1.end(),
- back_insert_iterator<vector<uptr> >(vec));
- EXPECT_EQ(bv.intersectsWith(bv1), !vec.empty());
-
- // setUnion
- t_s = s;
- t_bv.copyFrom(bv);
- t_s.insert(s1.begin(), s1.end());
- EXPECT_EQ(t_bv.setUnion(bv1), s.size() != t_s.size());
- CheckBV(t_bv, t_s);
-
- // setIntersection
- t_s = set<uptr>(vec.begin(), vec.end());
- t_bv.copyFrom(bv);
- EXPECT_EQ(t_bv.setIntersection(bv1), s.size() != t_s.size());
- CheckBV(t_bv, t_s);
-
- // setDifference
- vec.clear();
- set_difference(s.begin(), s.end(), s1.begin(), s1.end(),
- back_insert_iterator<vector<uptr> >(vec));
- t_s = set<uptr>(vec.begin(), vec.end());
- t_bv.copyFrom(bv);
- EXPECT_EQ(t_bv.setDifference(bv1), s.size() != t_s.size());
- CheckBV(t_bv, t_s);
- }
-}
-
-TEST(SanitizerCommon, BasicBitVector) {
- TestBitVector<BasicBitVector<u8> >(8);
- TestBitVector<BasicBitVector<u16> >(16);
- TestBitVector<BasicBitVector<> >(SANITIZER_WORDSIZE);
-}
-
-TEST(SanitizerCommon, TwoLevelBitVector) {
- uptr ws = SANITIZER_WORDSIZE;
- TestBitVector<TwoLevelBitVector<1, BasicBitVector<u8> > >(8 * 8);
- TestBitVector<TwoLevelBitVector<> >(ws * ws);
- TestBitVector<TwoLevelBitVector<2> >(ws * ws * 2);
- TestBitVector<TwoLevelBitVector<3> >(ws * ws * 3);
- TestBitVector<TwoLevelBitVector<3, BasicBitVector<u16> > >(16 * 16 * 3);
-}
diff --git a/lib/sanitizer_common/tests/sanitizer_bvgraph_test.cc b/lib/sanitizer_common/tests/sanitizer_bvgraph_test.cc
deleted file mode 100644
index 3b39f8dd734aa..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_bvgraph_test.cc
+++ /dev/null
@@ -1,339 +0,0 @@
-//===-- sanitizer_bvgraph_test.cc -----------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of Sanitizer runtime.
-// Tests for sanitizer_bvgraph.h.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_bvgraph.h"
-
-#include "sanitizer_test_utils.h"
-
-#include "gtest/gtest.h"
-
-#include <algorithm>
-#include <vector>
-#include <set>
-
-using namespace __sanitizer;
-using namespace std;
-
-typedef BasicBitVector<u8> BV1;
-typedef BasicBitVector<> BV2;
-typedef TwoLevelBitVector<> BV3;
-typedef TwoLevelBitVector<3, BasicBitVector<u8> > BV4;
-
-template<class G>
-void PrintGraph(const G &g) {
- for (uptr i = 0; i < g.size(); i++) {
- for (uptr j = 0; j < g.size(); j++) {
- fprintf(stderr, "%d", g.hasEdge(i, j));
- }
- fprintf(stderr, "\n");
- }
-}
-
-
-class SimpleGraph {
- public:
- void clear() { s_.clear(); }
- bool addEdge(uptr from, uptr to) {
- return s_.insert(idx(from, to)).second;
- }
- bool removeEdge(uptr from, uptr to) {
- return s_.erase(idx(from, to));
- }
- template <class G>
- void checkSameAs(G *g) {
- for (set<uptr>::iterator it = s_.begin(); it != s_.end(); ++it) {
- uptr from = *it >> 16;
- uptr to = *it & ((1 << 16) - 1);
- EXPECT_TRUE(g->removeEdge(from, to));
- }
- EXPECT_TRUE(g->empty());
- }
- private:
- uptr idx(uptr from, uptr to) {
- CHECK_LE(from|to, 1 << 16);
- return (from << 16) + to;
- }
- set<uptr> s_;
-};
-
-template <class BV>
-void BasicTest() {
- BVGraph<BV> g;
- g.clear();
- BV target;
- SimpleGraph s_g;
- set<uptr> s;
- set<uptr> s_target;
- int num_reachable = 0;
- for (int it = 0; it < 1000; it++) {
- target.clear();
- s_target.clear();
- for (int t = 0; t < 4; t++) {
- uptr idx = (uptr)my_rand() % g.size();
- EXPECT_EQ(target.setBit(idx), s_target.insert(idx).second);
- }
- uptr from = my_rand() % g.size();
- uptr to = my_rand() % g.size();
- EXPECT_EQ(g.addEdge(from, to), s_g.addEdge(from, to));
- EXPECT_TRUE(g.hasEdge(from, to));
- for (int i = 0; i < 10; i++) {
- from = my_rand() % g.size();
- bool is_reachable = g.isReachable(from, target);
- if (is_reachable) {
- uptr path[BV::kSize];
- uptr len;
- for (len = 1; len < BV::kSize; len++) {
- if (g.findPath(from, target, path, len) == len)
- break;
- }
- EXPECT_LT(len, BV::kSize);
- EXPECT_TRUE(target.getBit(path[len - 1]));
- // fprintf(stderr, "reachable: %zd; path %zd {%zd %zd %zd}\n",
- // from, len, path[0], path[1], path[2]);
- num_reachable++;
- }
- }
- }
- EXPECT_GT(num_reachable, 0);
-}
-
-TEST(BVGraph, BasicTest) {
- BasicTest<BV1>();
- BasicTest<BV2>();
- BasicTest<BV3>();
- BasicTest<BV4>();
-}
-
-template <class BV>
-void RemoveEdges() {
- SimpleGraph s_g;
- BVGraph<BV> g;
- g.clear();
- BV bv;
- set<uptr> s;
- for (int it = 0; it < 100; it++) {
- s.clear();
- bv.clear();
- s_g.clear();
- g.clear();
- for (uptr j = 0; j < g.size() * 2; j++) {
- uptr from = my_rand() % g.size();
- uptr to = my_rand() % g.size();
- EXPECT_EQ(g.addEdge(from, to), s_g.addEdge(from, to));
- }
- for (uptr j = 0; j < 5; j++) {
- uptr idx = my_rand() % g.size();
- s.insert(idx);
- bv.setBit(idx);
- }
-
- if (it % 2) {
- g.removeEdgesFrom(bv);
- for (set<uptr>::iterator from = s.begin(); from != s.end(); ++from) {
- for (uptr to = 0; to < g.size(); to++)
- s_g.removeEdge(*from, to);
- }
- } else {
- g.removeEdgesTo(bv);
- for (set<uptr>::iterator to = s.begin(); to != s.end(); ++to) {
- for (uptr from = 0; from < g.size(); from++)
- s_g.removeEdge(from, *to);
- }
- }
- s_g.checkSameAs(&g);
- }
-}
-
-TEST(BVGraph, RemoveEdges) {
- RemoveEdges<BV1>();
- RemoveEdges<BV2>();
- RemoveEdges<BV3>();
- RemoveEdges<BV4>();
-}
-
-template <class BV>
-void Test_isReachable() {
- uptr path[5];
- BVGraph<BV> g;
- g.clear();
- BV target;
- target.clear();
- uptr t0 = 0;
- uptr t1 = g.size() - 1;
- target.setBit(t0);
- target.setBit(t1);
-
- uptr f0 = 1;
- uptr f1 = 2;
- uptr f2 = g.size() / 2;
- uptr f3 = g.size() - 2;
-
- EXPECT_FALSE(g.isReachable(f0, target));
- EXPECT_FALSE(g.isReachable(f1, target));
- EXPECT_FALSE(g.isReachable(f2, target));
- EXPECT_FALSE(g.isReachable(f3, target));
-
- g.addEdge(f0, f1);
- g.addEdge(f1, f2);
- g.addEdge(f2, f3);
- EXPECT_FALSE(g.isReachable(f0, target));
- EXPECT_FALSE(g.isReachable(f1, target));
- EXPECT_FALSE(g.isReachable(f2, target));
- EXPECT_FALSE(g.isReachable(f3, target));
-
- g.addEdge(f1, t0);
- EXPECT_TRUE(g.isReachable(f0, target));
- EXPECT_TRUE(g.isReachable(f1, target));
- EXPECT_FALSE(g.isReachable(f2, target));
- EXPECT_FALSE(g.isReachable(f3, target));
- EXPECT_EQ(g.findPath(f0, target, path, ARRAY_SIZE(path)), 3U);
- EXPECT_EQ(path[0], f0);
- EXPECT_EQ(path[1], f1);
- EXPECT_EQ(path[2], t0);
- EXPECT_EQ(g.findPath(f1, target, path, ARRAY_SIZE(path)), 2U);
- EXPECT_EQ(path[0], f1);
- EXPECT_EQ(path[1], t0);
-
- g.addEdge(f3, t1);
- EXPECT_TRUE(g.isReachable(f0, target));
- EXPECT_TRUE(g.isReachable(f1, target));
- EXPECT_TRUE(g.isReachable(f2, target));
- EXPECT_TRUE(g.isReachable(f3, target));
-}
-
-TEST(BVGraph, isReachable) {
- Test_isReachable<BV1>();
- Test_isReachable<BV2>();
- Test_isReachable<BV3>();
- Test_isReachable<BV4>();
-}
-
-template <class BV>
-void LongCycle() {
- BVGraph<BV> g;
- g.clear();
- vector<uptr> path_vec(g.size());
- uptr *path = path_vec.data();
- uptr start = 5;
- for (uptr i = start; i < g.size() - 1; i++) {
- g.addEdge(i, i + 1);
- for (uptr j = 0; j < start; j++)
- g.addEdge(i, j);
- }
- // Bad graph that looks like this:
- // 00000000000000
- // 00000000000000
- // 00000000000000
- // 00000000000000
- // 00000000000000
- // 11111010000000
- // 11111001000000
- // 11111000100000
- // 11111000010000
- // 11111000001000
- // 11111000000100
- // 11111000000010
- // 11111000000001
- // if (g.size() <= 64) PrintGraph(g);
- BV target;
- for (uptr i = start + 1; i < g.size(); i += 11) {
- // if ((i & (i - 1)) == 0) fprintf(stderr, "Path: : %zd\n", i);
- target.clear();
- target.setBit(i);
- EXPECT_TRUE(g.isReachable(start, target));
- EXPECT_EQ(g.findPath(start, target, path, g.size()), i - start + 1);
- }
-}
-
-TEST(BVGraph, LongCycle) {
- LongCycle<BV1>();
- LongCycle<BV2>();
- LongCycle<BV3>();
- LongCycle<BV4>();
-}
-
-template <class BV>
-void ShortestPath() {
- uptr path[8];
- BVGraph<BV> g;
- g.clear();
- BV t7;
- t7.clear();
- t7.setBit(7);
- // 1=>2=>3=>4=>5=>6=>7
- // 1=>7
- g.addEdge(1, 2);
- g.addEdge(2, 3);
- g.addEdge(3, 4);
- g.addEdge(4, 5);
- g.addEdge(5, 6);
- g.addEdge(6, 7);
- g.addEdge(1, 7);
- EXPECT_TRUE(g.isReachable(1, t7));
- // No path of length 1.
- EXPECT_EQ(0U, g.findPath(1, t7, path, 1));
- // Trying to find a path of len 2..6 gives path of len 2.
- EXPECT_EQ(2U, g.findPath(1, t7, path, 2));
- EXPECT_EQ(2U, g.findPath(1, t7, path, 3));
- EXPECT_EQ(2U, g.findPath(1, t7, path, 4));
- EXPECT_EQ(2U, g.findPath(1, t7, path, 5));
- EXPECT_EQ(2U, g.findPath(1, t7, path, 6));
- // Trying to find a path of len 7 gives path of len 7, because this is DFS.
- EXPECT_EQ(7U, g.findPath(1, t7, path, 7));
- // But findShortestPath will find the shortest path.
- EXPECT_EQ(2U, g.findShortestPath(1, t7, path, 2));
- EXPECT_EQ(2U, g.findShortestPath(1, t7, path, 7));
-}
-
-TEST(BVGraph, ShortestPath) {
- ShortestPath<BV1>();
- ShortestPath<BV2>();
- ShortestPath<BV3>();
- ShortestPath<BV4>();
-}
-
-template <class BV>
-void RunAddEdgesTest() {
- BVGraph<BV> g;
- BV from;
- const int kMaxEdges = 10;
- uptr added_edges[kMaxEdges];
- g.clear();
- from.clear();
- EXPECT_EQ(0U, g.addEdges(from, 0, added_edges, kMaxEdges));
- EXPECT_EQ(0U, g.addEdges(from, 1, added_edges, kMaxEdges));
- from.setBit(0);
- EXPECT_EQ(1U, g.addEdges(from, 1, added_edges, kMaxEdges));
- EXPECT_EQ(0U, added_edges[0]);
- EXPECT_EQ(0U, g.addEdges(from, 1, added_edges, kMaxEdges));
-
- from.clear();
- from.setBit(1);
- EXPECT_EQ(1U, g.addEdges(from, 4, added_edges, kMaxEdges));
- EXPECT_TRUE(g.hasEdge(1, 4));
- EXPECT_FALSE(g.hasEdge(1, 5));
- EXPECT_EQ(1U, added_edges[0]);
- from.setBit(2);
- from.setBit(3);
- EXPECT_EQ(2U, g.addEdges(from, 4, added_edges, kMaxEdges));
- EXPECT_TRUE(g.hasEdge(2, 4));
- EXPECT_FALSE(g.hasEdge(2, 5));
- EXPECT_TRUE(g.hasEdge(3, 4));
- EXPECT_FALSE(g.hasEdge(3, 5));
- EXPECT_EQ(2U, added_edges[0]);
- EXPECT_EQ(3U, added_edges[1]);
-}
-
-TEST(BVGraph, AddEdgesTest) {
- RunAddEdgesTest<BV2>();
-}
diff --git a/lib/sanitizer_common/tests/sanitizer_common_test.cc b/lib/sanitizer_common/tests/sanitizer_common_test.cc
deleted file mode 100644
index 6b091de60d6d9..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_common_test.cc
+++ /dev/null
@@ -1,442 +0,0 @@
-//===-- sanitizer_common_test.cc ------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
-//
-//===----------------------------------------------------------------------===//
-#include <algorithm>
-
-#include "sanitizer_common/sanitizer_allocator_internal.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_file.h"
-#include "sanitizer_common/sanitizer_flags.h"
-#include "sanitizer_common/sanitizer_libc.h"
-#include "sanitizer_common/sanitizer_platform.h"
-
-#include "sanitizer_pthread_wrappers.h"
-
-#include "gtest/gtest.h"
-
-namespace __sanitizer {
-
-static bool IsSorted(const uptr *array, uptr n) {
- for (uptr i = 1; i < n; i++) {
- if (array[i] < array[i - 1]) return false;
- }
- return true;
-}
-
-TEST(SanitizerCommon, SortTest) {
- uptr array[100];
- uptr n = 100;
- // Already sorted.
- for (uptr i = 0; i < n; i++) {
- array[i] = i;
- }
- Sort(array, n);
- EXPECT_TRUE(IsSorted(array, n));
- // Reverse order.
- for (uptr i = 0; i < n; i++) {
- array[i] = n - 1 - i;
- }
- Sort(array, n);
- EXPECT_TRUE(IsSorted(array, n));
- // Mixed order.
- for (uptr i = 0; i < n; i++) {
- array[i] = (i % 2 == 0) ? i : n - 1 - i;
- }
- Sort(array, n);
- EXPECT_TRUE(IsSorted(array, n));
- // All equal.
- for (uptr i = 0; i < n; i++) {
- array[i] = 42;
- }
- Sort(array, n);
- EXPECT_TRUE(IsSorted(array, n));
- // All but one sorted.
- for (uptr i = 0; i < n - 1; i++) {
- array[i] = i;
- }
- array[n - 1] = 42;
- Sort(array, n);
- EXPECT_TRUE(IsSorted(array, n));
- // Minimal case - sort three elements.
- array[0] = 1;
- array[1] = 0;
- Sort(array, 2);
- EXPECT_TRUE(IsSorted(array, 2));
-}
-
-TEST(SanitizerCommon, MmapAlignedOrDieOnFatalError) {
- uptr PageSize = GetPageSizeCached();
- for (uptr size = 1; size <= 32; size *= 2) {
- for (uptr alignment = 1; alignment <= 32; alignment *= 2) {
- for (int iter = 0; iter < 100; iter++) {
- uptr res = (uptr)MmapAlignedOrDieOnFatalError(
- size * PageSize, alignment * PageSize, "MmapAlignedOrDieTest");
- EXPECT_EQ(0U, res % (alignment * PageSize));
- internal_memset((void*)res, 1, size * PageSize);
- UnmapOrDie((void*)res, size * PageSize);
- }
- }
- }
-}
-
-TEST(SanitizerCommon, InternalMmapVectorRoundUpCapacity) {
- InternalMmapVector<uptr> v;
- v.reserve(1);
- CHECK_EQ(v.capacity(), GetPageSizeCached() / sizeof(uptr));
-}
-
-TEST(SanitizerCommon, InternalMmapVectorReize) {
- InternalMmapVector<uptr> v;
- CHECK_EQ(0U, v.size());
- CHECK_GE(v.capacity(), v.size());
-
- v.reserve(1000);
- CHECK_EQ(0U, v.size());
- CHECK_GE(v.capacity(), 1000U);
-
- v.resize(10000);
- CHECK_EQ(10000U, v.size());
- CHECK_GE(v.capacity(), v.size());
- uptr cap = v.capacity();
-
- v.resize(100);
- CHECK_EQ(100U, v.size());
- CHECK_EQ(v.capacity(), cap);
-
- v.reserve(10);
- CHECK_EQ(100U, v.size());
- CHECK_EQ(v.capacity(), cap);
-}
-
-TEST(SanitizerCommon, InternalMmapVector) {
- InternalMmapVector<uptr> vector;
- for (uptr i = 0; i < 100; i++) {
- EXPECT_EQ(i, vector.size());
- vector.push_back(i);
- }
- for (uptr i = 0; i < 100; i++) {
- EXPECT_EQ(i, vector[i]);
- }
- for (int i = 99; i >= 0; i--) {
- EXPECT_EQ((uptr)i, vector.back());
- vector.pop_back();
- EXPECT_EQ((uptr)i, vector.size());
- }
- InternalMmapVector<uptr> empty_vector;
- CHECK_GT(empty_vector.capacity(), 0U);
- CHECK_EQ(0U, empty_vector.size());
-}
-
-TEST(SanitizerCommon, InternalMmapVectorEq) {
- InternalMmapVector<uptr> vector1;
- InternalMmapVector<uptr> vector2;
- for (uptr i = 0; i < 100; i++) {
- vector1.push_back(i);
- vector2.push_back(i);
- }
- EXPECT_TRUE(vector1 == vector2);
- EXPECT_FALSE(vector1 != vector2);
-
- vector1.push_back(1);
- EXPECT_FALSE(vector1 == vector2);
- EXPECT_TRUE(vector1 != vector2);
-
- vector2.push_back(1);
- EXPECT_TRUE(vector1 == vector2);
- EXPECT_FALSE(vector1 != vector2);
-
- vector1[55] = 1;
- EXPECT_FALSE(vector1 == vector2);
- EXPECT_TRUE(vector1 != vector2);
-}
-
-TEST(SanitizerCommon, InternalMmapVectorSwap) {
- InternalMmapVector<uptr> vector1;
- InternalMmapVector<uptr> vector2;
- InternalMmapVector<uptr> vector3;
- InternalMmapVector<uptr> vector4;
- for (uptr i = 0; i < 100; i++) {
- vector1.push_back(i);
- vector2.push_back(i);
- vector3.push_back(-i);
- vector4.push_back(-i);
- }
- EXPECT_NE(vector2, vector3);
- EXPECT_NE(vector1, vector4);
- vector1.swap(vector3);
- EXPECT_EQ(vector2, vector3);
- EXPECT_EQ(vector1, vector4);
-}
-
-void TestThreadInfo(bool main) {
- uptr stk_addr = 0;
- uptr stk_size = 0;
- uptr tls_addr = 0;
- uptr tls_size = 0;
- GetThreadStackAndTls(main, &stk_addr, &stk_size, &tls_addr, &tls_size);
-
- int stack_var;
- EXPECT_NE(stk_addr, (uptr)0);
- EXPECT_NE(stk_size, (uptr)0);
- EXPECT_GT((uptr)&stack_var, stk_addr);
- EXPECT_LT((uptr)&stack_var, stk_addr + stk_size);
-
-#if SANITIZER_LINUX && defined(__x86_64__)
- static __thread int thread_var;
- EXPECT_NE(tls_addr, (uptr)0);
- EXPECT_NE(tls_size, (uptr)0);
- EXPECT_GT((uptr)&thread_var, tls_addr);
- EXPECT_LT((uptr)&thread_var, tls_addr + tls_size);
-
- // Ensure that tls and stack do not intersect.
- uptr tls_end = tls_addr + tls_size;
- EXPECT_TRUE(tls_addr < stk_addr || tls_addr >= stk_addr + stk_size);
- EXPECT_TRUE(tls_end < stk_addr || tls_end >= stk_addr + stk_size);
- EXPECT_TRUE((tls_addr < stk_addr) == (tls_end < stk_addr));
-#endif
-}
-
-static void *WorkerThread(void *arg) {
- TestThreadInfo(false);
- return 0;
-}
-
-TEST(SanitizerCommon, ThreadStackTlsMain) {
- InitTlsSize();
- TestThreadInfo(true);
-}
-
-TEST(SanitizerCommon, ThreadStackTlsWorker) {
- InitTlsSize();
- pthread_t t;
- PTHREAD_CREATE(&t, 0, WorkerThread, 0);
- PTHREAD_JOIN(t, 0);
-}
-
-bool UptrLess(uptr a, uptr b) {
- return a < b;
-}
-
-TEST(SanitizerCommon, InternalLowerBound) {
- static const uptr kSize = 5;
- int arr[kSize];
- arr[0] = 1;
- arr[1] = 3;
- arr[2] = 5;
- arr[3] = 7;
- arr[4] = 11;
-
- EXPECT_EQ(0u, InternalLowerBound(arr, 0, kSize, 0, UptrLess));
- EXPECT_EQ(0u, InternalLowerBound(arr, 0, kSize, 1, UptrLess));
- EXPECT_EQ(1u, InternalLowerBound(arr, 0, kSize, 2, UptrLess));
- EXPECT_EQ(1u, InternalLowerBound(arr, 0, kSize, 3, UptrLess));
- EXPECT_EQ(2u, InternalLowerBound(arr, 0, kSize, 4, UptrLess));
- EXPECT_EQ(2u, InternalLowerBound(arr, 0, kSize, 5, UptrLess));
- EXPECT_EQ(3u, InternalLowerBound(arr, 0, kSize, 6, UptrLess));
- EXPECT_EQ(3u, InternalLowerBound(arr, 0, kSize, 7, UptrLess));
- EXPECT_EQ(4u, InternalLowerBound(arr, 0, kSize, 8, UptrLess));
- EXPECT_EQ(4u, InternalLowerBound(arr, 0, kSize, 9, UptrLess));
- EXPECT_EQ(4u, InternalLowerBound(arr, 0, kSize, 10, UptrLess));
- EXPECT_EQ(4u, InternalLowerBound(arr, 0, kSize, 11, UptrLess));
- EXPECT_EQ(5u, InternalLowerBound(arr, 0, kSize, 12, UptrLess));
-}
-
-TEST(SanitizerCommon, InternalLowerBoundVsStdLowerBound) {
- std::vector<int> data;
- auto create_item = [] (size_t i, size_t j) {
- auto v = i * 10000 + j;
- return ((v << 6) + (v >> 6) + 0x9e3779b9) % 100;
- };
- for (size_t i = 0; i < 1000; ++i) {
- data.resize(i);
- for (size_t j = 0; j < i; ++j) {
- data[j] = create_item(i, j);
- }
-
- std::sort(data.begin(), data.end());
-
- for (size_t j = 0; j < i; ++j) {
- int val = create_item(i, j);
- for (auto to_find : {val - 1, val, val + 1}) {
- uptr expected =
- std::lower_bound(data.begin(), data.end(), to_find) - data.begin();
- EXPECT_EQ(expected, InternalLowerBound(data.data(), 0, data.size(),
- to_find, std::less<int>()));
- }
- }
- }
-}
-
-#if SANITIZER_LINUX && !SANITIZER_ANDROID
-TEST(SanitizerCommon, FindPathToBinary) {
- char *true_path = FindPathToBinary("true");
- EXPECT_NE((char*)0, internal_strstr(true_path, "/bin/true"));
- InternalFree(true_path);
- EXPECT_EQ(0, FindPathToBinary("unexisting_binary.ergjeorj"));
-}
-#elif SANITIZER_WINDOWS
-TEST(SanitizerCommon, FindPathToBinary) {
- // ntdll.dll should be on PATH in all supported test environments on all
- // supported Windows versions.
- char *ntdll_path = FindPathToBinary("ntdll.dll");
- EXPECT_NE((char*)0, internal_strstr(ntdll_path, "ntdll.dll"));
- InternalFree(ntdll_path);
- EXPECT_EQ(0, FindPathToBinary("unexisting_binary.ergjeorj"));
-}
-#endif
-
-TEST(SanitizerCommon, StripPathPrefix) {
- EXPECT_EQ(0, StripPathPrefix(0, "prefix"));
- EXPECT_STREQ("foo", StripPathPrefix("foo", 0));
- EXPECT_STREQ("dir/file.cc",
- StripPathPrefix("/usr/lib/dir/file.cc", "/usr/lib/"));
- EXPECT_STREQ("/file.cc", StripPathPrefix("/usr/myroot/file.cc", "/myroot"));
- EXPECT_STREQ("file.h", StripPathPrefix("/usr/lib/./file.h", "/usr/lib/"));
-}
-
-TEST(SanitizerCommon, RemoveANSIEscapeSequencesFromString) {
- RemoveANSIEscapeSequencesFromString(nullptr);
- const char *buffs[22] = {
- "Default", "Default",
- "\033[95mLight magenta", "Light magenta",
- "\033[30mBlack\033[32mGreen\033[90mGray", "BlackGreenGray",
- "\033[106mLight cyan \033[107mWhite ", "Light cyan White ",
- "\033[31mHello\033[0m World", "Hello World",
- "\033[38;5;82mHello \033[38;5;198mWorld", "Hello World",
- "123[653456789012", "123[653456789012",
- "Normal \033[5mBlink \033[25mNormal", "Normal Blink Normal",
- "\033[106m\033[107m", "",
- "", "",
- " ", " ",
- };
-
- for (size_t i = 0; i < ARRAY_SIZE(buffs); i+=2) {
- char *buffer_copy = internal_strdup(buffs[i]);
- RemoveANSIEscapeSequencesFromString(buffer_copy);
- EXPECT_STREQ(buffer_copy, buffs[i+1]);
- InternalFree(buffer_copy);
- }
-}
-
-TEST(SanitizerCommon, InternalScopedString) {
- InternalScopedString str(10);
- EXPECT_EQ(0U, str.length());
- EXPECT_STREQ("", str.data());
-
- str.append("foo");
- EXPECT_EQ(3U, str.length());
- EXPECT_STREQ("foo", str.data());
-
- int x = 1234;
- str.append("%d", x);
- EXPECT_EQ(7U, str.length());
- EXPECT_STREQ("foo1234", str.data());
-
- str.append("%d", x);
- EXPECT_EQ(9U, str.length());
- EXPECT_STREQ("foo123412", str.data());
-
- str.clear();
- EXPECT_EQ(0U, str.length());
- EXPECT_STREQ("", str.data());
-
- str.append("0123456789");
- EXPECT_EQ(9U, str.length());
- EXPECT_STREQ("012345678", str.data());
-}
-
-#if SANITIZER_LINUX || SANITIZER_FREEBSD || \
- SANITIZER_OPENBSD || SANITIZER_MAC || SANITIZER_IOS
-TEST(SanitizerCommon, GetRandom) {
- u8 buffer_1[32], buffer_2[32];
- for (bool blocking : { false, true }) {
- EXPECT_FALSE(GetRandom(nullptr, 32, blocking));
- EXPECT_FALSE(GetRandom(buffer_1, 0, blocking));
- EXPECT_FALSE(GetRandom(buffer_1, 512, blocking));
- EXPECT_EQ(ARRAY_SIZE(buffer_1), ARRAY_SIZE(buffer_2));
- for (uptr size = 4; size <= ARRAY_SIZE(buffer_1); size += 4) {
- for (uptr i = 0; i < 100; i++) {
- EXPECT_TRUE(GetRandom(buffer_1, size, blocking));
- EXPECT_TRUE(GetRandom(buffer_2, size, blocking));
- EXPECT_NE(internal_memcmp(buffer_1, buffer_2, size), 0);
- }
- }
- }
-}
-#endif
-
-TEST(SanitizerCommon, ReservedAddressRangeInit) {
- uptr init_size = 0xffff;
- ReservedAddressRange address_range;
- uptr res = address_range.Init(init_size);
- CHECK_NE(res, (void*)-1);
- UnmapOrDie((void*)res, init_size);
- // Should be able to map into the same space now.
- ReservedAddressRange address_range2;
- uptr res2 = address_range2.Init(init_size, nullptr, res);
- CHECK_EQ(res, res2);
-
- // TODO(flowerhack): Once this is switched to the "real" implementation
- // (rather than passing through to MmapNoAccess*), enforce and test "no
- // double initializations allowed"
-}
-
-TEST(SanitizerCommon, ReservedAddressRangeMap) {
- constexpr uptr init_size = 0xffff;
- ReservedAddressRange address_range;
- uptr res = address_range.Init(init_size);
- CHECK_NE(res, (void*) -1);
-
- // Valid mappings should succeed.
- CHECK_EQ(res, address_range.Map(res, init_size));
-
- // Valid mappings should be readable.
- unsigned char buffer[init_size];
- memcpy(buffer, reinterpret_cast<void *>(res), init_size);
-
- // TODO(flowerhack): Once this is switched to the "real" implementation, make
- // sure you can only mmap into offsets in the Init range.
-}
-
-TEST(SanitizerCommon, ReservedAddressRangeUnmap) {
- uptr PageSize = GetPageSizeCached();
- uptr init_size = PageSize * 8;
- ReservedAddressRange address_range;
- uptr base_addr = address_range.Init(init_size);
- CHECK_NE(base_addr, (void*)-1);
- CHECK_EQ(base_addr, address_range.Map(base_addr, init_size));
-
- // Unmapping the entire range should succeed.
- address_range.Unmap(base_addr, init_size);
-
- // Map a new range.
- base_addr = address_range.Init(init_size);
- CHECK_EQ(base_addr, address_range.Map(base_addr, init_size));
-
- // Windows doesn't allow partial unmappings.
- #if !SANITIZER_WINDOWS
-
- // Unmapping at the beginning should succeed.
- address_range.Unmap(base_addr, PageSize);
-
- // Unmapping at the end should succeed.
- uptr new_start = reinterpret_cast<uptr>(address_range.base()) +
- address_range.size() - PageSize;
- address_range.Unmap(new_start, PageSize);
-
- #endif
-
- // Unmapping in the middle of the ReservedAddressRange should fail.
- EXPECT_DEATH(address_range.Unmap(base_addr + (PageSize * 2), PageSize), ".*");
-}
-
-} // namespace __sanitizer
diff --git a/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc b/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc
deleted file mode 100644
index 7835eef76d063..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_deadlock_detector_test.cc
+++ /dev/null
@@ -1,496 +0,0 @@
-//===-- sanitizer_deadlock_detector_test.cc -------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of Sanitizer runtime.
-// Tests for sanitizer_deadlock_detector.h
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_deadlock_detector.h"
-
-#include "sanitizer_test_utils.h"
-
-#include "gtest/gtest.h"
-
-#include <algorithm>
-#include <vector>
-#include <set>
-
-using namespace __sanitizer;
-using namespace std;
-
-typedef BasicBitVector<u8> BV1;
-typedef BasicBitVector<> BV2;
-typedef TwoLevelBitVector<> BV3;
-typedef TwoLevelBitVector<3, BasicBitVector<u8> > BV4;
-
-// Poor man's unique_ptr.
-template<class BV>
-struct ScopedDD {
- ScopedDD() {
- dp = new DeadlockDetector<BV>;
- dp->clear();
- dtls.clear();
- }
- ~ScopedDD() { delete dp; }
- DeadlockDetector<BV> *dp;
- DeadlockDetectorTLS<BV> dtls;
-};
-
-template <class BV>
-void RunBasicTest() {
- uptr path[10];
- ScopedDD<BV> sdd;
- DeadlockDetector<BV> &d = *sdd.dp;
- DeadlockDetectorTLS<BV> &dtls = sdd.dtls;
- set<uptr> s;
- for (size_t i = 0; i < d.size() * 3; i++) {
- uptr node = d.newNode(0);
- EXPECT_TRUE(s.insert(node).second);
- }
-
- d.clear();
- s.clear();
- // Add size() nodes.
- for (size_t i = 0; i < d.size(); i++) {
- uptr node = d.newNode(0);
- EXPECT_TRUE(s.insert(node).second);
- }
- // Remove all nodes.
- for (set<uptr>::iterator it = s.begin(); it != s.end(); ++it)
- d.removeNode(*it);
- // The nodes should be reused.
- for (size_t i = 0; i < d.size(); i++) {
- uptr node = d.newNode(0);
- EXPECT_FALSE(s.insert(node).second);
- }
-
- // Cycle: n1->n2->n1
- {
- d.clear();
- dtls.clear();
- uptr n1 = d.newNode(1);
- uptr n2 = d.newNode(2);
- EXPECT_FALSE(d.onLock(&dtls, n1));
- EXPECT_FALSE(d.onLock(&dtls, n2));
- d.onUnlock(&dtls, n2);
- d.onUnlock(&dtls, n1);
-
- EXPECT_FALSE(d.onLock(&dtls, n2));
- EXPECT_EQ(0U, d.findPathToLock(&dtls, n1, path, 1));
- EXPECT_EQ(2U, d.findPathToLock(&dtls, n1, path, 10));
- EXPECT_EQ(2U, d.findPathToLock(&dtls, n1, path, 2));
- EXPECT_TRUE(d.onLock(&dtls, n1));
- EXPECT_EQ(path[0], n1);
- EXPECT_EQ(path[1], n2);
- EXPECT_EQ(d.getData(n1), 1U);
- EXPECT_EQ(d.getData(n2), 2U);
- d.onUnlock(&dtls, n1);
- d.onUnlock(&dtls, n2);
- }
-
- // Cycle: n1->n2->n3->n1
- {
- d.clear();
- dtls.clear();
- uptr n1 = d.newNode(1);
- uptr n2 = d.newNode(2);
- uptr n3 = d.newNode(3);
-
- EXPECT_FALSE(d.onLock(&dtls, n1));
- EXPECT_FALSE(d.onLock(&dtls, n2));
- d.onUnlock(&dtls, n2);
- d.onUnlock(&dtls, n1);
-
- EXPECT_FALSE(d.onLock(&dtls, n2));
- EXPECT_FALSE(d.onLock(&dtls, n3));
- d.onUnlock(&dtls, n3);
- d.onUnlock(&dtls, n2);
-
- EXPECT_FALSE(d.onLock(&dtls, n3));
- EXPECT_EQ(0U, d.findPathToLock(&dtls, n1, path, 2));
- EXPECT_EQ(3U, d.findPathToLock(&dtls, n1, path, 10));
- EXPECT_TRUE(d.onLock(&dtls, n1));
- EXPECT_EQ(path[0], n1);
- EXPECT_EQ(path[1], n2);
- EXPECT_EQ(path[2], n3);
- EXPECT_EQ(d.getData(n1), 1U);
- EXPECT_EQ(d.getData(n2), 2U);
- EXPECT_EQ(d.getData(n3), 3U);
- d.onUnlock(&dtls, n1);
- d.onUnlock(&dtls, n3);
- }
-}
-
-TEST(DeadlockDetector, BasicTest) {
- RunBasicTest<BV1>();
- RunBasicTest<BV2>();
- RunBasicTest<BV3>();
- RunBasicTest<BV4>();
-}
-
-template <class BV>
-void RunRemoveNodeTest() {
- ScopedDD<BV> sdd;
- DeadlockDetector<BV> &d = *sdd.dp;
- DeadlockDetectorTLS<BV> &dtls = sdd.dtls;
-
- uptr l0 = d.newNode(0);
- uptr l1 = d.newNode(1);
- uptr l2 = d.newNode(2);
- uptr l3 = d.newNode(3);
- uptr l4 = d.newNode(4);
- uptr l5 = d.newNode(5);
-
- // l0=>l1=>l2
- d.onLock(&dtls, l0);
- d.onLock(&dtls, l1);
- d.onLock(&dtls, l2);
- d.onUnlock(&dtls, l1);
- d.onUnlock(&dtls, l0);
- d.onUnlock(&dtls, l2);
- // l3=>l4=>l5
- d.onLock(&dtls, l3);
- d.onLock(&dtls, l4);
- d.onLock(&dtls, l5);
- d.onUnlock(&dtls, l4);
- d.onUnlock(&dtls, l3);
- d.onUnlock(&dtls, l5);
-
- set<uptr> locks;
- locks.insert(l0);
- locks.insert(l1);
- locks.insert(l2);
- locks.insert(l3);
- locks.insert(l4);
- locks.insert(l5);
- for (uptr i = 6; i < d.size(); i++) {
- uptr lt = d.newNode(i);
- locks.insert(lt);
- d.onLock(&dtls, lt);
- d.onUnlock(&dtls, lt);
- d.removeNode(lt);
- }
- EXPECT_EQ(locks.size(), d.size());
- // l2=>l0
- EXPECT_FALSE(d.onLock(&dtls, l2));
- EXPECT_TRUE(d.onLock(&dtls, l0));
- d.onUnlock(&dtls, l2);
- d.onUnlock(&dtls, l0);
- // l4=>l3
- EXPECT_FALSE(d.onLock(&dtls, l4));
- EXPECT_TRUE(d.onLock(&dtls, l3));
- d.onUnlock(&dtls, l4);
- d.onUnlock(&dtls, l3);
-
- EXPECT_EQ(d.size(), d.testOnlyGetEpoch());
-
- d.removeNode(l2);
- d.removeNode(l3);
- locks.clear();
- // make sure no edges from or to l0,l1,l4,l5 left.
- for (uptr i = 4; i < d.size(); i++) {
- uptr lt = d.newNode(i);
- locks.insert(lt);
- uptr a, b;
- // l0 => lt?
- a = l0; b = lt;
- EXPECT_FALSE(d.onLock(&dtls, a));
- EXPECT_FALSE(d.onLock(&dtls, b));
- d.onUnlock(&dtls, a);
- d.onUnlock(&dtls, b);
- // l1 => lt?
- a = l1; b = lt;
- EXPECT_FALSE(d.onLock(&dtls, a));
- EXPECT_FALSE(d.onLock(&dtls, b));
- d.onUnlock(&dtls, a);
- d.onUnlock(&dtls, b);
- // lt => l4?
- a = lt; b = l4;
- EXPECT_FALSE(d.onLock(&dtls, a));
- EXPECT_FALSE(d.onLock(&dtls, b));
- d.onUnlock(&dtls, a);
- d.onUnlock(&dtls, b);
- // lt => l5?
- a = lt; b = l5;
- EXPECT_FALSE(d.onLock(&dtls, a));
- EXPECT_FALSE(d.onLock(&dtls, b));
- d.onUnlock(&dtls, a);
- d.onUnlock(&dtls, b);
-
- d.removeNode(lt);
- }
- // Still the same epoch.
- EXPECT_EQ(d.size(), d.testOnlyGetEpoch());
- EXPECT_EQ(locks.size(), d.size() - 4);
- // l2 and l3 should have ben reused.
- EXPECT_EQ(locks.count(l2), 1U);
- EXPECT_EQ(locks.count(l3), 1U);
-}
-
-TEST(DeadlockDetector, RemoveNodeTest) {
- RunRemoveNodeTest<BV1>();
- RunRemoveNodeTest<BV2>();
- RunRemoveNodeTest<BV3>();
- RunRemoveNodeTest<BV4>();
-}
-
-template <class BV>
-void RunMultipleEpochsTest() {
- ScopedDD<BV> sdd;
- DeadlockDetector<BV> &d = *sdd.dp;
- DeadlockDetectorTLS<BV> &dtls = sdd.dtls;
-
- set<uptr> locks;
- for (uptr i = 0; i < d.size(); i++) {
- EXPECT_TRUE(locks.insert(d.newNode(i)).second);
- }
- EXPECT_EQ(d.testOnlyGetEpoch(), d.size());
- for (uptr i = 0; i < d.size(); i++) {
- EXPECT_TRUE(locks.insert(d.newNode(i)).second);
- EXPECT_EQ(d.testOnlyGetEpoch(), d.size() * 2);
- }
- locks.clear();
-
- uptr l0 = d.newNode(0);
- uptr l1 = d.newNode(0);
- d.onLock(&dtls, l0);
- d.onLock(&dtls, l1);
- d.onUnlock(&dtls, l0);
- EXPECT_EQ(d.testOnlyGetEpoch(), 3 * d.size());
- for (uptr i = 0; i < d.size(); i++) {
- EXPECT_TRUE(locks.insert(d.newNode(i)).second);
- }
- EXPECT_EQ(d.testOnlyGetEpoch(), 4 * d.size());
-
-#if !SANITIZER_DEBUG
- // EXPECT_DEATH clones a thread with 4K stack,
- // which is overflown by tsan memory accesses functions in debug mode.
-
- // Can not handle the locks from the previous epoch.
- // The caller should update the lock id.
- EXPECT_DEATH(d.onLock(&dtls, l0), "CHECK failed.*current_epoch_");
-#endif
-}
-
-TEST(DeadlockDetector, MultipleEpochsTest) {
- RunMultipleEpochsTest<BV1>();
- RunMultipleEpochsTest<BV2>();
- RunMultipleEpochsTest<BV3>();
- RunMultipleEpochsTest<BV4>();
-}
-
-template <class BV>
-void RunCorrectEpochFlush() {
- ScopedDD<BV> sdd;
- DeadlockDetector<BV> &d = *sdd.dp;
- DeadlockDetectorTLS<BV> &dtls = sdd.dtls;
- vector<uptr> locks1;
- for (uptr i = 0; i < d.size(); i++)
- locks1.push_back(d.newNode(i));
- EXPECT_EQ(d.testOnlyGetEpoch(), d.size());
- d.onLock(&dtls, locks1[3]);
- d.onLock(&dtls, locks1[4]);
- d.onLock(&dtls, locks1[5]);
-
- // We have a new epoch, old locks in dtls will have to be forgotten.
- uptr l0 = d.newNode(0);
- EXPECT_EQ(d.testOnlyGetEpoch(), d.size() * 2);
- uptr l1 = d.newNode(0);
- EXPECT_EQ(d.testOnlyGetEpoch(), d.size() * 2);
- d.onLock(&dtls, l0);
- d.onLock(&dtls, l1);
- EXPECT_TRUE(d.testOnlyHasEdgeRaw(0, 1));
- EXPECT_FALSE(d.testOnlyHasEdgeRaw(1, 0));
- EXPECT_FALSE(d.testOnlyHasEdgeRaw(3, 0));
- EXPECT_FALSE(d.testOnlyHasEdgeRaw(4, 0));
- EXPECT_FALSE(d.testOnlyHasEdgeRaw(5, 0));
-}
-
-TEST(DeadlockDetector, CorrectEpochFlush) {
- RunCorrectEpochFlush<BV1>();
- RunCorrectEpochFlush<BV2>();
-}
-
-template <class BV>
-void RunTryLockTest() {
- ScopedDD<BV> sdd;
- DeadlockDetector<BV> &d = *sdd.dp;
- DeadlockDetectorTLS<BV> &dtls = sdd.dtls;
-
- uptr l0 = d.newNode(0);
- uptr l1 = d.newNode(0);
- uptr l2 = d.newNode(0);
- EXPECT_FALSE(d.onLock(&dtls, l0));
- EXPECT_FALSE(d.onTryLock(&dtls, l1));
- EXPECT_FALSE(d.onLock(&dtls, l2));
- EXPECT_TRUE(d.isHeld(&dtls, l0));
- EXPECT_TRUE(d.isHeld(&dtls, l1));
- EXPECT_TRUE(d.isHeld(&dtls, l2));
- EXPECT_FALSE(d.testOnlyHasEdge(l0, l1));
- EXPECT_TRUE(d.testOnlyHasEdge(l1, l2));
- d.onUnlock(&dtls, l0);
- d.onUnlock(&dtls, l1);
- d.onUnlock(&dtls, l2);
-}
-
-TEST(DeadlockDetector, TryLockTest) {
- RunTryLockTest<BV1>();
- RunTryLockTest<BV2>();
-}
-
-template <class BV>
-void RunOnFirstLockTest() {
- ScopedDD<BV> sdd;
- DeadlockDetector<BV> &d = *sdd.dp;
- DeadlockDetectorTLS<BV> &dtls = sdd.dtls;
-
- uptr l0 = d.newNode(0);
- uptr l1 = d.newNode(0);
- EXPECT_FALSE(d.onFirstLock(&dtls, l0)); // dtls has old epoch.
- d.onLock(&dtls, l0);
- d.onUnlock(&dtls, l0);
-
- EXPECT_TRUE(d.onFirstLock(&dtls, l0)); // Ok, same ecpoch, first lock.
- EXPECT_FALSE(d.onFirstLock(&dtls, l1)); // Second lock.
- d.onLock(&dtls, l1);
- d.onUnlock(&dtls, l1);
- d.onUnlock(&dtls, l0);
-
- EXPECT_TRUE(d.onFirstLock(&dtls, l0)); // Ok
- d.onUnlock(&dtls, l0);
-
- vector<uptr> locks1;
- for (uptr i = 0; i < d.size(); i++)
- locks1.push_back(d.newNode(i));
-
- EXPECT_TRUE(d.onFirstLock(&dtls, l0)); // Epoch has changed, but not in dtls.
-
- uptr l3 = d.newNode(0);
- d.onLock(&dtls, l3);
- d.onUnlock(&dtls, l3);
-
- EXPECT_FALSE(d.onFirstLock(&dtls, l0)); // Epoch has changed in dtls.
-}
-
-TEST(DeadlockDetector, onFirstLockTest) {
- RunOnFirstLockTest<BV2>();
-}
-
-template <class BV>
-void RunRecusriveLockTest() {
- ScopedDD<BV> sdd;
- DeadlockDetector<BV> &d = *sdd.dp;
- DeadlockDetectorTLS<BV> &dtls = sdd.dtls;
-
- uptr l0 = d.newNode(0);
- uptr l1 = d.newNode(0);
- uptr l2 = d.newNode(0);
- uptr l3 = d.newNode(0);
-
- EXPECT_FALSE(d.onLock(&dtls, l0));
- EXPECT_FALSE(d.onLock(&dtls, l1));
- EXPECT_FALSE(d.onLock(&dtls, l0)); // Recurisve.
- EXPECT_FALSE(d.onLock(&dtls, l2));
- d.onUnlock(&dtls, l0);
- EXPECT_FALSE(d.onLock(&dtls, l3));
- d.onUnlock(&dtls, l0);
- d.onUnlock(&dtls, l1);
- d.onUnlock(&dtls, l2);
- d.onUnlock(&dtls, l3);
- EXPECT_TRUE(d.testOnlyHasEdge(l0, l1));
- EXPECT_TRUE(d.testOnlyHasEdge(l0, l2));
- EXPECT_TRUE(d.testOnlyHasEdge(l0, l3));
-}
-
-TEST(DeadlockDetector, RecusriveLockTest) {
- RunRecusriveLockTest<BV2>();
-}
-
-template <class BV>
-void RunLockContextTest() {
- ScopedDD<BV> sdd;
- DeadlockDetector<BV> &d = *sdd.dp;
- DeadlockDetectorTLS<BV> &dtls = sdd.dtls;
-
- uptr l0 = d.newNode(0);
- uptr l1 = d.newNode(0);
- uptr l2 = d.newNode(0);
- uptr l3 = d.newNode(0);
- uptr l4 = d.newNode(0);
- EXPECT_FALSE(d.onLock(&dtls, l0, 10));
- EXPECT_FALSE(d.onLock(&dtls, l1, 11));
- EXPECT_FALSE(d.onLock(&dtls, l2, 12));
- EXPECT_FALSE(d.onLock(&dtls, l3, 13));
- EXPECT_EQ(10U, d.findLockContext(&dtls, l0));
- EXPECT_EQ(11U, d.findLockContext(&dtls, l1));
- EXPECT_EQ(12U, d.findLockContext(&dtls, l2));
- EXPECT_EQ(13U, d.findLockContext(&dtls, l3));
- d.onUnlock(&dtls, l0);
- EXPECT_EQ(0U, d.findLockContext(&dtls, l0));
- EXPECT_EQ(11U, d.findLockContext(&dtls, l1));
- EXPECT_EQ(12U, d.findLockContext(&dtls, l2));
- EXPECT_EQ(13U, d.findLockContext(&dtls, l3));
- d.onUnlock(&dtls, l2);
- EXPECT_EQ(0U, d.findLockContext(&dtls, l0));
- EXPECT_EQ(11U, d.findLockContext(&dtls, l1));
- EXPECT_EQ(0U, d.findLockContext(&dtls, l2));
- EXPECT_EQ(13U, d.findLockContext(&dtls, l3));
-
- EXPECT_FALSE(d.onLock(&dtls, l4, 14));
- EXPECT_EQ(14U, d.findLockContext(&dtls, l4));
-}
-
-TEST(DeadlockDetector, LockContextTest) {
- RunLockContextTest<BV2>();
-}
-
-template <class BV>
-void RunRemoveEdgesTest() {
- ScopedDD<BV> sdd;
- DeadlockDetector<BV> &d = *sdd.dp;
- DeadlockDetectorTLS<BV> &dtls = sdd.dtls;
- vector<uptr> node(BV::kSize);
- u32 stk_from = 0, stk_to = 0;
- int unique_tid = 0;
- for (size_t i = 0; i < BV::kSize; i++)
- node[i] = d.newNode(0);
-
- for (size_t i = 0; i < BV::kSize; i++)
- EXPECT_FALSE(d.onLock(&dtls, node[i], i + 1));
- for (size_t i = 0; i < BV::kSize; i++) {
- for (uptr j = i + 1; j < BV::kSize; j++) {
- EXPECT_TRUE(
- d.findEdge(node[i], node[j], &stk_from, &stk_to, &unique_tid));
- EXPECT_EQ(stk_from, i + 1);
- EXPECT_EQ(stk_to, j + 1);
- }
- }
- EXPECT_EQ(d.testOnlyGetEpoch(), d.size());
- // Remove and re-create half of the nodes.
- for (uptr i = 1; i < BV::kSize; i += 2)
- d.removeNode(node[i]);
- for (uptr i = 1; i < BV::kSize; i += 2)
- node[i] = d.newNode(0);
- EXPECT_EQ(d.testOnlyGetEpoch(), d.size());
- // The edges from or to the removed nodes should be gone.
- for (size_t i = 0; i < BV::kSize; i++) {
- for (uptr j = i + 1; j < BV::kSize; j++) {
- if ((i % 2) || (j % 2))
- EXPECT_FALSE(
- d.findEdge(node[i], node[j], &stk_from, &stk_to, &unique_tid));
- else
- EXPECT_TRUE(
- d.findEdge(node[i], node[j], &stk_from, &stk_to, &unique_tid));
- }
- }
-}
-
-TEST(DeadlockDetector, RemoveEdgesTest) {
- RunRemoveEdgesTest<BV1>();
-}
diff --git a/lib/sanitizer_common/tests/sanitizer_flags_test.cc b/lib/sanitizer_common/tests/sanitizer_flags_test.cc
deleted file mode 100644
index f3fe139e6ee87..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_flags_test.cc
+++ /dev/null
@@ -1,180 +0,0 @@
-//===-- sanitizer_flags_test.cc -------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_flags.h"
-#include "sanitizer_common/sanitizer_flag_parser.h"
-#include "sanitizer_common/sanitizer_libc.h"
-#include "sanitizer_common/sanitizer_allocator_internal.h"
-#include "gtest/gtest.h"
-
-#include <string.h>
-
-namespace __sanitizer {
-
-static const char kFlagName[] = "flag_name";
-static const char kFlagDesc[] = "flag description";
-
-template <typename T>
-static void TestFlag(T start_value, const char *env, T final_value) {
- T flag = start_value;
-
- FlagParser parser;
- RegisterFlag(&parser, kFlagName, kFlagDesc, &flag);
-
- parser.ParseString(env);
-
- EXPECT_EQ(final_value, flag);
-}
-
-template <>
-void TestFlag(const char *start_value, const char *env,
- const char *final_value) {
- const char *flag = start_value;
-
- FlagParser parser;
- RegisterFlag(&parser, kFlagName, kFlagDesc, &flag);
-
- parser.ParseString(env);
-
- EXPECT_EQ(0, internal_strcmp(final_value, flag));
-
- // Reporting unrecognized flags is needed to reset them.
- ReportUnrecognizedFlags();
-}
-
-TEST(SanitizerCommon, BooleanFlags) {
- TestFlag(false, "flag_name=1", true);
- TestFlag(false, "flag_name=yes", true);
- TestFlag(false, "flag_name=true", true);
- TestFlag(true, "flag_name=0", false);
- TestFlag(true, "flag_name=no", false);
- TestFlag(true, "flag_name=false", false);
-
- EXPECT_DEATH(TestFlag(false, "flag_name", true), "expected '='");
- EXPECT_DEATH(TestFlag(false, "flag_name=", true),
- "Invalid value for bool option: ''");
- EXPECT_DEATH(TestFlag(false, "flag_name=2", true),
- "Invalid value for bool option: '2'");
- EXPECT_DEATH(TestFlag(false, "flag_name=-1", true),
- "Invalid value for bool option: '-1'");
- EXPECT_DEATH(TestFlag(false, "flag_name=on", true),
- "Invalid value for bool option: 'on'");
-}
-
-TEST(SanitizerCommon, HandleSignalMode) {
- TestFlag(kHandleSignalNo, "flag_name=1", kHandleSignalYes);
- TestFlag(kHandleSignalNo, "flag_name=yes", kHandleSignalYes);
- TestFlag(kHandleSignalNo, "flag_name=true", kHandleSignalYes);
- TestFlag(kHandleSignalYes, "flag_name=0", kHandleSignalNo);
- TestFlag(kHandleSignalYes, "flag_name=no", kHandleSignalNo);
- TestFlag(kHandleSignalYes, "flag_name=false", kHandleSignalNo);
- TestFlag(kHandleSignalNo, "flag_name=2", kHandleSignalExclusive);
- TestFlag(kHandleSignalYes, "flag_name=exclusive", kHandleSignalExclusive);
-
- EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name", kHandleSignalNo),
- "expected '='");
- EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=", kHandleSignalNo),
- "Invalid value for signal handler option: ''");
- EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=3", kHandleSignalNo),
- "Invalid value for signal handler option: '3'");
- EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=-1", kHandleSignalNo),
- "Invalid value for signal handler option: '-1'");
- EXPECT_DEATH(TestFlag(kHandleSignalNo, "flag_name=on", kHandleSignalNo),
- "Invalid value for signal handler option: 'on'");
-}
-
-TEST(SanitizerCommon, IntFlags) {
- TestFlag(-11, 0, -11);
- TestFlag(-11, "flag_name=0", 0);
- TestFlag(-11, "flag_name=42", 42);
- TestFlag(-11, "flag_name=-42", -42);
-
- // Unrecognized flags are ignored.
- TestFlag(-11, "--flag_name=42", -11);
- TestFlag(-11, "zzzzzzz=42", -11);
-
- EXPECT_DEATH(TestFlag(-11, "flag_name", 0), "expected '='");
- EXPECT_DEATH(TestFlag(-11, "flag_name=42U", 0),
- "Invalid value for int option");
-}
-
-TEST(SanitizerCommon, StrFlags) {
- TestFlag("zzz", 0, "zzz");
- TestFlag("zzz", "flag_name=", "");
- TestFlag("zzz", "flag_name=abc", "abc");
- TestFlag("", "flag_name=abc", "abc");
- TestFlag("", "flag_name='abc zxc'", "abc zxc");
- // TestStrFlag("", "flag_name=\"abc qwe\" asd", "abc qwe");
-}
-
-static void TestTwoFlags(const char *env, bool expected_flag1,
- const char *expected_flag2,
- const char *name1 = "flag1",
- const char *name2 = "flag2") {
- bool flag1 = !expected_flag1;
- const char *flag2 = "";
-
- FlagParser parser;
- RegisterFlag(&parser, name1, kFlagDesc, &flag1);
- RegisterFlag(&parser, name2, kFlagDesc, &flag2);
-
- parser.ParseString(env);
-
- EXPECT_EQ(expected_flag1, flag1);
- EXPECT_EQ(0, internal_strcmp(flag2, expected_flag2));
-
- // Reporting unrecognized flags is needed to reset them.
- ReportUnrecognizedFlags();
-}
-
-TEST(SanitizerCommon, MultipleFlags) {
- TestTwoFlags("flag1=1 flag2='zzz'", true, "zzz");
- TestTwoFlags("flag2='qxx' flag1=0", false, "qxx");
- TestTwoFlags("flag1=false:flag2='zzz'", false, "zzz");
- TestTwoFlags("flag2=qxx:flag1=yes", true, "qxx");
- TestTwoFlags("flag2=qxx\nflag1=yes", true, "qxx");
- TestTwoFlags("flag2=qxx\r\nflag1=yes", true, "qxx");
- TestTwoFlags("flag2=qxx\tflag1=yes", true, "qxx");
-}
-
-TEST(SanitizerCommon, CommonSuffixFlags) {
- TestTwoFlags("flag=1 other_flag='zzz'", true, "zzz", "flag", "other_flag");
- TestTwoFlags("other_flag='zzz' flag=1", true, "zzz", "flag", "other_flag");
- TestTwoFlags("other_flag=' flag=0 ' flag=1", true, " flag=0 ", "flag",
- "other_flag");
- TestTwoFlags("flag=1 other_flag=' flag=0 '", true, " flag=0 ", "flag",
- "other_flag");
-}
-
-TEST(SanitizerCommon, CommonFlags) {
- CommonFlags cf;
- FlagParser parser;
- RegisterCommonFlags(&parser, &cf);
-
- cf.SetDefaults();
- EXPECT_TRUE(cf.symbolize);
- EXPECT_STREQ(".", cf.coverage_dir);
-
- cf.symbolize = false;
- cf.coverage = true;
- cf.heap_profile = true;
- cf.log_path = "path/one";
-
- parser.ParseString("symbolize=1:heap_profile=false log_path='path/two'");
- EXPECT_TRUE(cf.symbolize);
- EXPECT_TRUE(cf.coverage);
- EXPECT_FALSE(cf.heap_profile);
- EXPECT_STREQ("path/two", cf.log_path);
-}
-
-} // namespace __sanitizer
diff --git a/lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cc b/lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cc
deleted file mode 100644
index 2f0494f82b0af..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_format_interceptor_test.cc
+++ /dev/null
@@ -1,263 +0,0 @@
-//===-- sanitizer_format_interceptor_test.cc ------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Tests for *scanf interceptors implementation in sanitizer_common.
-//
-//===----------------------------------------------------------------------===//
-#include <algorithm>
-#include <vector>
-
-#include "interception/interception.h"
-#include "sanitizer_test_utils.h"
-#include "sanitizer_common/sanitizer_libc.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "gtest/gtest.h"
-
-using namespace __sanitizer;
-
-#define COMMON_INTERCEPTOR_READ_WRITE_RANGE(ctx, ptr, size) \
- do { \
- ((std::vector<unsigned> *)ctx)->push_back(size); \
- ptr = ptr; \
- } while (0)
-
-#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
- COMMON_INTERCEPTOR_READ_WRITE_RANGE(ctx, ptr, size)
-
-#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
- COMMON_INTERCEPTOR_READ_WRITE_RANGE(ctx, ptr, size)
-
-#define SANITIZER_INTERCEPT_PRINTF 1
-#include "sanitizer_common/sanitizer_common_interceptors_format.inc"
-
-static const unsigned I = sizeof(int);
-static const unsigned L = sizeof(long);
-static const unsigned LL = sizeof(long long);
-static const unsigned S = sizeof(short);
-static const unsigned C = sizeof(char);
-static const unsigned LC = sizeof(wchar_t);
-static const unsigned D = sizeof(double);
-static const unsigned LD = sizeof(long double);
-static const unsigned F = sizeof(float);
-static const unsigned P = sizeof(char *);
-
-static void verifyFormatResults(const char *format, unsigned n,
- const std::vector<unsigned> &computed_sizes,
- va_list expected_sizes) {
- // "+ 1" because of format string
- ASSERT_EQ(n + 1,
- computed_sizes.size()) << "Unexpected number of format arguments: '"
- << format << "'";
- for (unsigned i = 0; i < n; ++i)
- EXPECT_EQ(va_arg(expected_sizes, unsigned), computed_sizes[i + 1])
- << "Unexpect write size for argument " << i << ", format string '"
- << format << "'";
-}
-
-static const char test_buf[] = "Test string.";
-static const size_t test_buf_size = sizeof(test_buf);
-
-static const unsigned SCANF_ARGS_MAX = 16;
-
-static void testScanf3(void *ctx, int result, bool allowGnuMalloc,
- const char *format, ...) {
- va_list ap;
- va_start(ap, format);
- scanf_common(ctx, result, allowGnuMalloc, format, ap);
- va_end(ap);
-}
-
-static void testScanf2(const char *format, int scanf_result,
- bool allowGnuMalloc, unsigned n,
- va_list expected_sizes) {
- std::vector<unsigned> scanf_sizes;
- // 16 args should be enough.
- testScanf3((void *)&scanf_sizes, scanf_result, allowGnuMalloc, format,
- test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,
- test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,
- test_buf, test_buf, test_buf, test_buf);
- verifyFormatResults(format, n, scanf_sizes, expected_sizes);
-}
-
-static void testScanf(const char *format, unsigned n, ...) {
- va_list ap;
- va_start(ap, n);
- testScanf2(format, SCANF_ARGS_MAX, /* allowGnuMalloc */ true, n, ap);
- va_end(ap);
-}
-
-static void testScanfPartial(const char *format, int scanf_result, unsigned n,
- ...) {
- va_list ap;
- va_start(ap, n);
- testScanf2(format, scanf_result, /* allowGnuMalloc */ true, n, ap);
- va_end(ap);
-}
-
-static void testScanfNoGnuMalloc(const char *format, unsigned n, ...) {
- va_list ap;
- va_start(ap, n);
- testScanf2(format, SCANF_ARGS_MAX, /* allowGnuMalloc */ false, n, ap);
- va_end(ap);
-}
-
-TEST(SanitizerCommonInterceptors, Scanf) {
- testScanf("%d", 1, I);
- testScanf("%d%d%d", 3, I, I, I);
- testScanf("ab%u%dc", 2, I, I);
- testScanf("%ld", 1, L);
- testScanf("%llu", 1, LL);
- testScanf("%qd", 1, LL);
- testScanf("a %hd%hhx", 2, S, C);
- testScanf("%c", 1, C);
- testScanf("%lc", 1, LC);
-
- testScanf("%%", 0);
- testScanf("a%%", 0);
- testScanf("a%%b", 0);
- testScanf("a%%%%b", 0);
- testScanf("a%%b%%", 0);
- testScanf("a%%%%%%b", 0);
- testScanf("a%%%%%b", 0);
- testScanf("a%%%%%f", 1, F);
- testScanf("a%%%lxb", 1, L);
- testScanf("a%lf%%%lxb", 2, D, L);
- testScanf("%nf", 1, I);
-
- testScanf("%10s", 1, 11);
- testScanf("%10c", 1, 10);
- testScanf("%10ls", 1, 11 * LC);
- testScanf("%10lc", 1, 10 * LC);
- testScanf("%%10s", 0);
- testScanf("%*10s", 0);
- testScanf("%*d", 0);
-
- testScanf("%4d%8f%c", 3, I, F, C);
- testScanf("%s%d", 2, test_buf_size, I);
- testScanf("%[abc]", 1, test_buf_size);
- testScanf("%4[bcdef]", 1, 5);
- testScanf("%[]]", 1, test_buf_size);
- testScanf("%8[^]%d0-9-]%c", 2, 9, C);
-
- testScanf("%*[^:]%n:%d:%1[ ]%n", 4, I, I, 2, I);
-
- testScanf("%*d%u", 1, I);
-
- testScanf("%c%d", 2, C, I);
- testScanf("%A%lf", 2, F, D);
-
- testScanf("%ms %Lf", 2, P, LD);
- testScanf("s%Las", 1, LD);
- testScanf("%ar", 1, F);
-
- // In the cases with std::min below the format spec can be interpreted as
- // either floating-something, or (GNU extension) callee-allocated string.
- // Our conservative implementation reports one of the two possibilities with
- // the least store range.
- testScanf("%a[", 0);
- testScanf("%a[]", 0);
- testScanf("%a[]]", 1, std::min(F, P));
- testScanf("%a[abc]", 1, std::min(F, P));
- testScanf("%a[^abc]", 1, std::min(F, P));
- testScanf("%a[ab%c] %d", 0);
- testScanf("%a[^ab%c] %d", 0);
- testScanf("%as", 1, std::min(F, P));
- testScanf("%aS", 1, std::min(F, P));
- testScanf("%a13S", 1, std::min(F, P));
- testScanf("%alS", 1, std::min(F, P));
-
- testScanfNoGnuMalloc("s%Las", 1, LD);
- testScanfNoGnuMalloc("%ar", 1, F);
- testScanfNoGnuMalloc("%a[", 1, F);
- testScanfNoGnuMalloc("%a[]", 1, F);
- testScanfNoGnuMalloc("%a[]]", 1, F);
- testScanfNoGnuMalloc("%a[abc]", 1, F);
- testScanfNoGnuMalloc("%a[^abc]", 1, F);
- testScanfNoGnuMalloc("%a[ab%c] %d", 3, F, C, I);
- testScanfNoGnuMalloc("%a[^ab%c] %d", 3, F, C, I);
- testScanfNoGnuMalloc("%as", 1, F);
- testScanfNoGnuMalloc("%aS", 1, F);
- testScanfNoGnuMalloc("%a13S", 1, F);
- testScanfNoGnuMalloc("%alS", 1, F);
-
- testScanf("%5$d", 0);
- testScanf("%md", 0);
- testScanf("%m10s", 0);
-
- testScanfPartial("%d%d%d%d //1\n", 1, 1, I);
- testScanfPartial("%d%d%d%d //2\n", 2, 2, I, I);
- testScanfPartial("%d%d%d%d //3\n", 3, 3, I, I, I);
- testScanfPartial("%d%d%d%d //4\n", 4, 4, I, I, I, I);
-
- testScanfPartial("%d%n%n%d //1\n", 1, 3, I, I, I);
- testScanfPartial("%d%n%n%d //2\n", 2, 4, I, I, I, I);
-
- testScanfPartial("%d%n%n%d %s %s", 3, 5, I, I, I, I, test_buf_size);
- testScanfPartial("%d%n%n%d %s %s", 4, 6, I, I, I, I, test_buf_size,
- test_buf_size);
-}
-
-static void testPrintf3(void *ctx, const char *format, ...) {
- va_list ap;
- va_start(ap, format);
- printf_common(ctx, format, ap);
- va_end(ap);
-}
-
-static void testPrintf2(const char *format, unsigned n,
- va_list expected_sizes) {
- std::vector<unsigned> printf_sizes;
- // 16 args should be enough.
- testPrintf3((void *)&printf_sizes, format,
- test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,
- test_buf, test_buf, test_buf, test_buf, test_buf, test_buf,
- test_buf, test_buf, test_buf, test_buf);
- verifyFormatResults(format, n, printf_sizes, expected_sizes);
-}
-
-static void testPrintf(const char *format, unsigned n, ...) {
- va_list ap;
- va_start(ap, n);
- testPrintf2(format, n, ap);
- va_end(ap);
-}
-
-TEST(SanitizerCommonInterceptors, Printf) {
- // Only test functionality which differs from scanf
-
- // Indexed arguments
- testPrintf("%5$d", 0);
- testPrintf("%.*5$d", 0);
-
- // errno
- testPrintf("%0-m", 0);
-
- // Dynamic width
- testPrintf("%*n", 1, I);
- testPrintf("%*.10n", 1, I);
-
- // Precision
- testPrintf("%10.10n", 1, I);
- testPrintf("%.3s", 1, 3);
- testPrintf("%.20s", 1, test_buf_size);
-
- // Dynamic precision
- testPrintf("%.*n", 1, I);
- testPrintf("%10.*n", 1, I);
-
- // Dynamic precision for strings is not implemented yet.
- testPrintf("%.*s", 1, 0);
-
- // Checks for wide-character strings are not implemented yet.
- testPrintf("%ls", 1, 0);
-
- testPrintf("%m", 0);
- testPrintf("%m%s", 1, test_buf_size);
- testPrintf("%s%m%s", 2, test_buf_size, test_buf_size);
-}
diff --git a/lib/sanitizer_common/tests/sanitizer_ioctl_test.cc b/lib/sanitizer_common/tests/sanitizer_ioctl_test.cc
deleted file mode 100644
index 6e2a20b85d6ab..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_ioctl_test.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-//===-- sanitizer_ioctl_test.cc -------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Tests for ioctl interceptor implementation in sanitizer_common.
-//
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_LINUX
-
-#include <linux/input.h>
-#include <vector>
-
-#include "interception/interception.h"
-#include "sanitizer_test_utils.h"
-#include "sanitizer_common/sanitizer_platform_limits_posix.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "gtest/gtest.h"
-
-
-using namespace __sanitizer;
-
-#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, sz) \
- do { \
- (void) ctx; \
- (void) ptr; \
- (void) sz; \
- } while (0)
-#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, sz) \
- do { \
- (void) ctx; \
- (void) ptr; \
- (void) sz; \
- } while (0)
-
-#include "sanitizer_common/sanitizer_common_interceptors_ioctl.inc"
-
-static struct IoctlInit {
- IoctlInit() {
- ioctl_init();
- // Avoid unused function warnings.
- (void)&ioctl_common_pre;
- (void)&ioctl_common_post;
- (void)&ioctl_decode;
- }
-} ioctl_static_initializer;
-
-TEST(SanitizerIoctl, Fixup) {
- EXPECT_EQ((unsigned)FIONBIO, ioctl_request_fixup(FIONBIO));
-
- EXPECT_EQ(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(0, 16)));
- EXPECT_EQ(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(1, 16)));
- EXPECT_EQ(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(1, 17)));
- EXPECT_EQ(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(31, 16)));
- EXPECT_NE(EVIOCGBIT(0, 0), ioctl_request_fixup(EVIOCGBIT(32, 16)));
-
- EXPECT_EQ(EVIOCGABS(0), ioctl_request_fixup(EVIOCGABS(0)));
- EXPECT_EQ(EVIOCGABS(0), ioctl_request_fixup(EVIOCGABS(5)));
- EXPECT_EQ(EVIOCGABS(0), ioctl_request_fixup(EVIOCGABS(63)));
- EXPECT_NE(EVIOCGABS(0), ioctl_request_fixup(EVIOCGABS(64)));
-
- EXPECT_EQ(EVIOCSABS(0), ioctl_request_fixup(EVIOCSABS(0)));
- EXPECT_EQ(EVIOCSABS(0), ioctl_request_fixup(EVIOCSABS(5)));
- EXPECT_EQ(EVIOCSABS(0), ioctl_request_fixup(EVIOCSABS(63)));
- EXPECT_NE(EVIOCSABS(0), ioctl_request_fixup(EVIOCSABS(64)));
-
- const ioctl_desc *desc = ioctl_lookup(EVIOCGKEY(16));
- EXPECT_NE((void *)0, desc);
- EXPECT_EQ(EVIOCGKEY(0), desc->req);
-}
-
-// Test decoding KVM ioctl numbers.
-TEST(SanitizerIoctl, KVM_GET_MP_STATE) {
- ioctl_desc desc;
- unsigned int desc_value = SANITIZER_MIPS ? 0x4004ae98U : 0x8004ae98U;
- bool res = ioctl_decode(desc_value, &desc);
- EXPECT_TRUE(res);
- EXPECT_EQ(ioctl_desc::WRITE, desc.type);
- EXPECT_EQ(4U, desc.size);
-}
-
-TEST(SanitizerIoctl, KVM_GET_LAPIC) {
- ioctl_desc desc;
- unsigned int desc_value = SANITIZER_MIPS ? 0x4400ae8eU : 0x8400ae8eU;
- bool res = ioctl_decode(desc_value, &desc);
- EXPECT_TRUE(res);
- EXPECT_EQ(ioctl_desc::WRITE, desc.type);
- EXPECT_EQ(1024U, desc.size);
-}
-
-TEST(SanitizerIoctl, KVM_GET_MSR_INDEX_LIST) {
- ioctl_desc desc;
- bool res = ioctl_decode(0xc004ae02U, &desc);
- EXPECT_TRUE(res);
- EXPECT_EQ(ioctl_desc::READWRITE, desc.type);
- EXPECT_EQ(4U, desc.size);
-}
-
-#endif // SANITIZER_LINUX
diff --git a/lib/sanitizer_common/tests/sanitizer_libc_test.cc b/lib/sanitizer_common/tests/sanitizer_libc_test.cc
deleted file mode 100644
index 2f61601cdff95..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_libc_test.cc
+++ /dev/null
@@ -1,315 +0,0 @@
-//===-- sanitizer_libc_test.cc --------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// Tests for sanitizer_libc.h.
-//===----------------------------------------------------------------------===//
-#include <algorithm>
-#include <fstream>
-
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_file.h"
-#include "sanitizer_common/sanitizer_libc.h"
-#include "sanitizer_common/sanitizer_platform.h"
-#include "gtest/gtest.h"
-
-#if SANITIZER_WINDOWS
-#define NOMINMAX
-#include <windows.h>
-#undef NOMINMAX
-#endif
-#if SANITIZER_POSIX
-# include <sys/stat.h>
-# include "sanitizer_common/sanitizer_posix.h"
-#endif
-
-using namespace __sanitizer;
-
-// A regression test for internal_memmove() implementation.
-TEST(SanitizerCommon, InternalMemmoveRegression) {
- char src[] = "Hello World";
- char *dest = src + 6;
- __sanitizer::internal_memmove(dest, src, 5);
- EXPECT_EQ(dest[0], src[0]);
- EXPECT_EQ(dest[4], src[4]);
-}
-
-TEST(SanitizerCommon, mem_is_zero) {
- size_t size = 128;
- char *x = new char[size];
- memset(x, 0, size);
- for (size_t pos = 0; pos < size; pos++) {
- x[pos] = 1;
- for (size_t beg = 0; beg < size; beg++) {
- for (size_t end = beg; end < size; end++) {
- // fprintf(stderr, "pos %zd beg %zd end %zd \n", pos, beg, end);
- if (beg <= pos && pos < end)
- EXPECT_FALSE(__sanitizer::mem_is_zero(x + beg, end - beg));
- else
- EXPECT_TRUE(__sanitizer::mem_is_zero(x + beg, end - beg));
- }
- }
- x[pos] = 0;
- }
- delete [] x;
-}
-
-struct stat_and_more {
- struct stat st;
- unsigned char z;
-};
-
-static void temp_file_name(char *buf, size_t bufsize, const char *prefix) {
-#if SANITIZER_WINDOWS
- buf[0] = '\0';
- char tmp_dir[MAX_PATH];
- if (!::GetTempPathA(MAX_PATH, tmp_dir))
- return;
- // GetTempFileNameA needs a MAX_PATH buffer.
- char tmp_path[MAX_PATH];
- if (!::GetTempFileNameA(tmp_dir, prefix, 0, tmp_path))
- return;
- internal_strncpy(buf, tmp_path, bufsize);
-#else
- const char *tmpdir = "/tmp";
-#if SANITIZER_ANDROID
- // I don't know a way to query temp directory location on Android without
- // going through Java interfaces. The code below is not ideal, but should
- // work. May require "adb root", but it is needed for almost any use of ASan
- // on Android already.
- tmpdir = GetEnv("EXTERNAL_STORAGE");
-#endif
- internal_snprintf(buf, bufsize, "%s/%sXXXXXX", tmpdir, prefix);
- ASSERT_TRUE(mkstemp(buf));
-#endif
-}
-
-static void Unlink(const char *path) {
-#if SANITIZER_WINDOWS
- // No sanitizer needs to delete a file on Windows yet. If we ever do, we can
- // add a portable wrapper and test it from here.
- ::DeleteFileA(&path[0]);
-#else
- internal_unlink(path);
-#endif
-}
-
-TEST(SanitizerCommon, FileOps) {
- const char *str1 = "qwerty";
- uptr len1 = internal_strlen(str1);
- const char *str2 = "zxcv";
- uptr len2 = internal_strlen(str2);
-
- char tmpfile[128];
- temp_file_name(tmpfile, sizeof(tmpfile), "sanitizer_common.fileops.tmp.");
- fd_t fd = OpenFile(tmpfile, WrOnly);
- ASSERT_NE(fd, kInvalidFd);
- ASSERT_TRUE(WriteToFile(fd, "A", 1));
- CloseFile(fd);
-
- fd = OpenFile(tmpfile, WrOnly);
- ASSERT_NE(fd, kInvalidFd);
-#if SANITIZER_POSIX && !SANITIZER_MAC
- EXPECT_EQ(internal_lseek(fd, 0, SEEK_END), 0u);
-#endif
- uptr bytes_written = 0;
- EXPECT_TRUE(WriteToFile(fd, str1, len1, &bytes_written));
- EXPECT_EQ(len1, bytes_written);
- EXPECT_TRUE(WriteToFile(fd, str2, len2, &bytes_written));
- EXPECT_EQ(len2, bytes_written);
- CloseFile(fd);
-
- EXPECT_TRUE(FileExists(tmpfile));
-
- fd = OpenFile(tmpfile, RdOnly);
- ASSERT_NE(fd, kInvalidFd);
-
-#if SANITIZER_POSIX
- // The stat wrappers are posix-only.
- uptr fsize = internal_filesize(fd);
- EXPECT_EQ(len1 + len2, fsize);
-
- struct stat st1, st2, st3;
- EXPECT_EQ(0u, internal_stat(tmpfile, &st1));
- EXPECT_EQ(0u, internal_lstat(tmpfile, &st2));
- EXPECT_EQ(0u, internal_fstat(fd, &st3));
- EXPECT_EQ(fsize, (uptr)st3.st_size);
-
- // Verify that internal_fstat does not write beyond the end of the supplied
- // buffer.
- struct stat_and_more sam;
- memset(&sam, 0xAB, sizeof(sam));
- EXPECT_EQ(0u, internal_fstat(fd, &sam.st));
- EXPECT_EQ(0xAB, sam.z);
- EXPECT_NE(0xAB, sam.st.st_size);
- EXPECT_NE(0, sam.st.st_size);
-#endif
-
- char buf[64] = {};
- uptr bytes_read = 0;
- EXPECT_TRUE(ReadFromFile(fd, buf, len1, &bytes_read));
- EXPECT_EQ(len1, bytes_read);
- EXPECT_EQ(0, internal_memcmp(buf, str1, len1));
- EXPECT_EQ((char)0, buf[len1 + 1]);
- internal_memset(buf, 0, len1);
- EXPECT_TRUE(ReadFromFile(fd, buf, len2, &bytes_read));
- EXPECT_EQ(len2, bytes_read);
- EXPECT_EQ(0, internal_memcmp(buf, str2, len2));
- CloseFile(fd);
-
- Unlink(tmpfile);
-}
-
-class SanitizerCommonFileTest : public ::testing::TestWithParam<uptr> {
- void SetUp() override {
- data_.resize(GetParam());
- std::generate(data_.begin(), data_.end(), [] {
- return rand() % 256; // NOLINT
- });
-
- temp_file_name(file_name_, sizeof(file_name_),
- "sanitizer_common.ReadFile.tmp.");
-
- std::ofstream f(file_name_, std::ios::out | std::ios::binary);
- if (!data_.empty())
- f.write(data_.data(), data_.size());
- }
-
- void TearDown() override { Unlink(file_name_); }
-
- protected:
- char file_name_[256];
- std::vector<char> data_;
-};
-
-TEST_P(SanitizerCommonFileTest, ReadFileToBuffer) {
- char *buff;
- uptr size;
- uptr len;
- EXPECT_TRUE(ReadFileToBuffer(file_name_, &buff, &len, &size));
- EXPECT_EQ(data_, std::vector<char>(buff, buff + size));
- UnmapOrDie(buff, len);
-}
-
-TEST_P(SanitizerCommonFileTest, ReadFileToBufferHalf) {
- char *buff;
- uptr size;
- uptr len;
- data_.resize(data_.size() / 2);
- EXPECT_TRUE(ReadFileToBuffer(file_name_, &buff, &len, &size, data_.size()));
- EXPECT_EQ(data_, std::vector<char>(buff, buff + size));
- UnmapOrDie(buff, len);
-}
-
-TEST_P(SanitizerCommonFileTest, ReadFileToVector) {
- InternalMmapVector<char> buff;
- EXPECT_TRUE(ReadFileToVector(file_name_, &buff));
- EXPECT_EQ(data_, std::vector<char>(buff.begin(), buff.end()));
-}
-
-TEST_P(SanitizerCommonFileTest, ReadFileToVectorHalf) {
- InternalMmapVector<char> buff;
- data_.resize(data_.size() / 2);
- EXPECT_TRUE(ReadFileToVector(file_name_, &buff, data_.size()));
- EXPECT_EQ(data_, std::vector<char>(buff.begin(), buff.end()));
-}
-
-INSTANTIATE_TEST_CASE_P(FileSizes, SanitizerCommonFileTest,
- ::testing::Values(0, 1, 7, 13, 32, 4096, 4097, 1048575,
- 1048576, 1048577));
-
-static const size_t kStrlcpyBufSize = 8;
-void test_internal_strlcpy(char *dbuf, const char *sbuf) {
- uptr retval = 0;
- retval = internal_strlcpy(dbuf, sbuf, kStrlcpyBufSize);
- EXPECT_EQ(internal_strncmp(dbuf, sbuf, kStrlcpyBufSize - 1), 0);
- EXPECT_EQ(internal_strlen(dbuf),
- std::min(internal_strlen(sbuf), (uptr)(kStrlcpyBufSize - 1)));
- EXPECT_EQ(retval, internal_strlen(sbuf));
-
- // Test with shorter maxlen.
- uptr maxlen = 2;
- if (internal_strlen(sbuf) > maxlen) {
- retval = internal_strlcpy(dbuf, sbuf, maxlen);
- EXPECT_EQ(internal_strncmp(dbuf, sbuf, maxlen - 1), 0);
- EXPECT_EQ(internal_strlen(dbuf), maxlen - 1);
- }
-}
-
-TEST(SanitizerCommon, InternalStrFunctions) {
- const char *haystack = "haystack";
- EXPECT_EQ(haystack + 2, internal_strchr(haystack, 'y'));
- EXPECT_EQ(haystack + 2, internal_strchrnul(haystack, 'y'));
- EXPECT_EQ(0, internal_strchr(haystack, 'z'));
- EXPECT_EQ(haystack + 8, internal_strchrnul(haystack, 'z'));
-
- char dbuf[kStrlcpyBufSize] = {};
- const char *samesizestr = "1234567";
- const char *shortstr = "123";
- const char *longerstr = "123456789";
-
- // Test internal_strlcpy.
- internal_strlcpy(dbuf, shortstr, 0);
- EXPECT_EQ(dbuf[0], 0);
- EXPECT_EQ(dbuf[0], 0);
- test_internal_strlcpy(dbuf, samesizestr);
- test_internal_strlcpy(dbuf, shortstr);
- test_internal_strlcpy(dbuf, longerstr);
-
- // Test internal_strlcat.
- char dcatbuf[kStrlcpyBufSize] = {};
- uptr retval = 0;
- retval = internal_strlcat(dcatbuf, "aaa", 0);
- EXPECT_EQ(internal_strlen(dcatbuf), (uptr)0);
- EXPECT_EQ(retval, (uptr)3);
-
- retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize);
- EXPECT_EQ(internal_strcmp(dcatbuf, "123"), 0);
- EXPECT_EQ(internal_strlen(dcatbuf), (uptr)3);
- EXPECT_EQ(retval, (uptr)3);
-
- retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize);
- EXPECT_EQ(internal_strcmp(dcatbuf, "123123"), 0);
- EXPECT_EQ(internal_strlen(dcatbuf), (uptr)6);
- EXPECT_EQ(retval, (uptr)6);
-
- retval = internal_strlcat(dcatbuf, "123", kStrlcpyBufSize);
- EXPECT_EQ(internal_strcmp(dcatbuf, "1231231"), 0);
- EXPECT_EQ(internal_strlen(dcatbuf), (uptr)7);
- EXPECT_EQ(retval, (uptr)9);
-}
-
-// FIXME: File manipulations are not yet supported on Windows
-#if SANITIZER_POSIX && !SANITIZER_MAC
-TEST(SanitizerCommon, InternalMmapWithOffset) {
- char tmpfile[128];
- temp_file_name(tmpfile, sizeof(tmpfile),
- "sanitizer_common.internalmmapwithoffset.tmp.");
- fd_t fd = OpenFile(tmpfile, RdWr);
- ASSERT_NE(fd, kInvalidFd);
-
- uptr page_size = GetPageSizeCached();
- uptr res = internal_ftruncate(fd, page_size * 2);
- ASSERT_FALSE(internal_iserror(res));
-
- res = internal_lseek(fd, page_size, SEEK_SET);
- ASSERT_FALSE(internal_iserror(res));
-
- res = internal_write(fd, "AB", 2);
- ASSERT_FALSE(internal_iserror(res));
-
- char *p = (char *)MapWritableFileToMemory(nullptr, page_size, fd, page_size);
- ASSERT_NE(nullptr, p);
-
- ASSERT_EQ('A', p[0]);
- ASSERT_EQ('B', p[1]);
-
- CloseFile(fd);
- UnmapOrDie(p, page_size);
- internal_unlink(tmpfile);
-}
-#endif
diff --git a/lib/sanitizer_common/tests/sanitizer_linux_test.cc b/lib/sanitizer_common/tests/sanitizer_linux_test.cc
deleted file mode 100644
index fbac9cc1438e8..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_linux_test.cc
+++ /dev/null
@@ -1,296 +0,0 @@
-//===-- sanitizer_linux_test.cc -------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Tests for sanitizer_linux.h
-//
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_LINUX
-
-#include "sanitizer_common/sanitizer_linux.h"
-
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_file.h"
-#include "gtest/gtest.h"
-
-#include <pthread.h>
-#include <sched.h>
-#include <stdlib.h>
-
-#include <algorithm>
-#include <vector>
-
-namespace __sanitizer {
-
-struct TidReporterArgument {
- TidReporterArgument() {
- pthread_mutex_init(&terminate_thread_mutex, NULL);
- pthread_mutex_init(&tid_reported_mutex, NULL);
- pthread_cond_init(&terminate_thread_cond, NULL);
- pthread_cond_init(&tid_reported_cond, NULL);
- terminate_thread = false;
- }
-
- ~TidReporterArgument() {
- pthread_mutex_destroy(&terminate_thread_mutex);
- pthread_mutex_destroy(&tid_reported_mutex);
- pthread_cond_destroy(&terminate_thread_cond);
- pthread_cond_destroy(&tid_reported_cond);
- }
-
- tid_t reported_tid;
- // For signaling to spawned threads that they should terminate.
- pthread_cond_t terminate_thread_cond;
- pthread_mutex_t terminate_thread_mutex;
- bool terminate_thread;
- // For signaling to main thread that a child thread has reported its tid.
- pthread_cond_t tid_reported_cond;
- pthread_mutex_t tid_reported_mutex;
-
- private:
- // Disallow evil constructors
- TidReporterArgument(const TidReporterArgument &);
- void operator=(const TidReporterArgument &);
-};
-
-class ThreadListerTest : public ::testing::Test {
- protected:
- virtual void SetUp() {
- pthread_t pthread_id;
- tid_t tid;
- for (uptr i = 0; i < kThreadCount; i++) {
- SpawnTidReporter(&pthread_id, &tid);
- pthread_ids_.push_back(pthread_id);
- tids_.push_back(tid);
- }
- }
-
- virtual void TearDown() {
- pthread_mutex_lock(&thread_arg.terminate_thread_mutex);
- thread_arg.terminate_thread = true;
- pthread_cond_broadcast(&thread_arg.terminate_thread_cond);
- pthread_mutex_unlock(&thread_arg.terminate_thread_mutex);
- for (uptr i = 0; i < pthread_ids_.size(); i++)
- pthread_join(pthread_ids_[i], NULL);
- }
-
- void SpawnTidReporter(pthread_t *pthread_id, tid_t *tid);
-
- static const uptr kThreadCount = 20;
-
- std::vector<pthread_t> pthread_ids_;
- std::vector<tid_t> tids_;
-
- TidReporterArgument thread_arg;
-};
-
-// Writes its TID once to reported_tid and waits until signaled to terminate.
-void *TidReporterThread(void *argument) {
- TidReporterArgument *arg = reinterpret_cast<TidReporterArgument *>(argument);
- pthread_mutex_lock(&arg->tid_reported_mutex);
- arg->reported_tid = GetTid();
- pthread_cond_broadcast(&arg->tid_reported_cond);
- pthread_mutex_unlock(&arg->tid_reported_mutex);
-
- pthread_mutex_lock(&arg->terminate_thread_mutex);
- while (!arg->terminate_thread)
- pthread_cond_wait(&arg->terminate_thread_cond,
- &arg->terminate_thread_mutex);
- pthread_mutex_unlock(&arg->terminate_thread_mutex);
- return NULL;
-}
-
-void ThreadListerTest::SpawnTidReporter(pthread_t *pthread_id, tid_t *tid) {
- pthread_mutex_lock(&thread_arg.tid_reported_mutex);
- thread_arg.reported_tid = -1;
- ASSERT_EQ(0, pthread_create(pthread_id, NULL,
- TidReporterThread,
- &thread_arg));
- while (thread_arg.reported_tid == (tid_t)(-1))
- pthread_cond_wait(&thread_arg.tid_reported_cond,
- &thread_arg.tid_reported_mutex);
- pthread_mutex_unlock(&thread_arg.tid_reported_mutex);
- *tid = thread_arg.reported_tid;
-}
-
-static std::vector<tid_t> ReadTidsToVector(ThreadLister *thread_lister) {
- std::vector<tid_t> listed_tids;
- InternalMmapVector<tid_t> threads(128);
- EXPECT_TRUE(thread_lister->ListThreads(&threads));
- return std::vector<tid_t>(threads.begin(), threads.end());
-}
-
-static bool Includes(std::vector<tid_t> first, std::vector<tid_t> second) {
- std::sort(first.begin(), first.end());
- std::sort(second.begin(), second.end());
- return std::includes(first.begin(), first.end(),
- second.begin(), second.end());
-}
-
-static bool HasElement(const std::vector<tid_t> &vector, tid_t element) {
- return std::find(vector.begin(), vector.end(), element) != vector.end();
-}
-
-// ThreadLister's output should include the current thread's TID and the TID of
-// every thread we spawned.
-TEST_F(ThreadListerTest, ThreadListerSeesAllSpawnedThreads) {
- tid_t self_tid = GetTid();
- ThreadLister thread_lister(getpid());
- std::vector<tid_t> listed_tids = ReadTidsToVector(&thread_lister);
- ASSERT_TRUE(HasElement(listed_tids, self_tid));
- ASSERT_TRUE(Includes(listed_tids, tids_));
-}
-
-TEST_F(ThreadListerTest, DoNotForgetThreads) {
- ThreadLister thread_lister(getpid());
-
- // Run the loop body twice, because ThreadLister might behave differently if
- // called on a freshly created object.
- for (uptr i = 0; i < 2; i++) {
- std::vector<tid_t> listed_tids = ReadTidsToVector(&thread_lister);
- ASSERT_TRUE(Includes(listed_tids, tids_));
- }
-}
-
-// If new threads have spawned during ThreadLister object's lifetime, calling
-// relisting should cause ThreadLister to recognize their existence.
-TEST_F(ThreadListerTest, NewThreads) {
- ThreadLister thread_lister(getpid());
- std::vector<tid_t> threads_before_extra = ReadTidsToVector(&thread_lister);
-
- pthread_t extra_pthread_id;
- tid_t extra_tid;
- SpawnTidReporter(&extra_pthread_id, &extra_tid);
- // Register the new thread so it gets terminated in TearDown().
- pthread_ids_.push_back(extra_pthread_id);
-
- // It would be very bizarre if the new TID had been listed before we even
- // spawned that thread, but it would also cause a false success in this test,
- // so better check for that.
- ASSERT_FALSE(HasElement(threads_before_extra, extra_tid));
-
- std::vector<tid_t> threads_after_extra = ReadTidsToVector(&thread_lister);
- ASSERT_TRUE(HasElement(threads_after_extra, extra_tid));
-}
-
-TEST(SanitizerCommon, SetEnvTest) {
- const char kEnvName[] = "ENV_FOO";
- SetEnv(kEnvName, "value");
- EXPECT_STREQ("value", getenv(kEnvName));
- unsetenv(kEnvName);
- EXPECT_EQ(0, getenv(kEnvName));
-}
-
-#if (defined(__x86_64__) || defined(__i386__)) && !SANITIZER_ANDROID
-void *thread_self_offset_test_func(void *arg) {
- bool result =
- *(uptr *)((char *)ThreadSelf() + ThreadSelfOffset()) == ThreadSelf();
- return (void *)result;
-}
-
-TEST(SanitizerLinux, ThreadSelfOffset) {
- EXPECT_TRUE((bool)thread_self_offset_test_func(0));
- pthread_t tid;
- void *result;
- ASSERT_EQ(0, pthread_create(&tid, 0, thread_self_offset_test_func, 0));
- ASSERT_EQ(0, pthread_join(tid, &result));
- EXPECT_TRUE((bool)result);
-}
-
-// libpthread puts the thread descriptor at the end of stack space.
-void *thread_descriptor_size_test_func(void *arg) {
- uptr descr_addr = ThreadSelf();
- pthread_attr_t attr;
- pthread_getattr_np(pthread_self(), &attr);
- void *stackaddr;
- size_t stacksize;
- pthread_attr_getstack(&attr, &stackaddr, &stacksize);
- return (void *)((uptr)stackaddr + stacksize - descr_addr);
-}
-
-TEST(SanitizerLinux, ThreadDescriptorSize) {
- pthread_t tid;
- void *result;
- ASSERT_EQ(0, pthread_create(&tid, 0, thread_descriptor_size_test_func, 0));
- ASSERT_EQ(0, pthread_join(tid, &result));
- EXPECT_EQ((uptr)result, ThreadDescriptorSize());
-}
-#endif
-
-TEST(SanitizerCommon, LibraryNameIs) {
- EXPECT_FALSE(LibraryNameIs("", ""));
-
- char full_name[256];
- const char *paths[] = { "", "/", "/path/to/" };
- const char *suffixes[] = { "", "-linux", ".1.2", "-linux.1.2" };
- const char *base_names[] = { "lib", "lib.0", "lib-i386" };
- const char *wrong_names[] = { "", "lib.9", "lib-x86_64" };
- for (uptr i = 0; i < ARRAY_SIZE(paths); i++)
- for (uptr j = 0; j < ARRAY_SIZE(suffixes); j++) {
- for (uptr k = 0; k < ARRAY_SIZE(base_names); k++) {
- internal_snprintf(full_name, ARRAY_SIZE(full_name), "%s%s%s.so",
- paths[i], base_names[k], suffixes[j]);
- EXPECT_TRUE(LibraryNameIs(full_name, base_names[k]))
- << "Full name " << full_name
- << " doesn't match base name " << base_names[k];
- for (uptr m = 0; m < ARRAY_SIZE(wrong_names); m++)
- EXPECT_FALSE(LibraryNameIs(full_name, wrong_names[m]))
- << "Full name " << full_name
- << " matches base name " << wrong_names[m];
- }
- }
-}
-
-#if defined(__mips64)
-// Effectively, this is a test for ThreadDescriptorSize() which is used to
-// compute ThreadSelf().
-TEST(SanitizerLinux, ThreadSelfTest) {
- ASSERT_EQ(pthread_self(), ThreadSelf());
-}
-#endif
-
-TEST(SanitizerCommon, StartSubprocessTest) {
- int pipe_fds[2];
- ASSERT_EQ(0, pipe(pipe_fds));
-#if SANITIZER_ANDROID
- const char *shell = "/system/bin/sh";
-#else
- const char *shell = "/bin/sh";
-#endif
- const char *argv[] = {shell, "-c", "echo -n 'hello'", (char *)NULL};
- int pid = StartSubprocess(shell, argv,
- /* stdin */ kInvalidFd, /* stdout */ pipe_fds[1]);
- ASSERT_GT(pid, 0);
-
- // wait for process to finish.
- while (IsProcessRunning(pid)) {
- }
- ASSERT_FALSE(IsProcessRunning(pid));
-
- char buffer[256];
- {
- char *ptr = buffer;
- uptr bytes_read;
- while (ReadFromFile(pipe_fds[0], ptr, 256, &bytes_read)) {
- if (!bytes_read) {
- break;
- }
- ptr += bytes_read;
- }
- ASSERT_EQ(5, ptr - buffer);
- *ptr = 0;
- }
- ASSERT_EQ(0, strcmp(buffer, "hello")) << "Buffer: " << buffer;
- internal_close(pipe_fds[0]);
-}
-
-} // namespace __sanitizer
-
-#endif // SANITIZER_LINUX
diff --git a/lib/sanitizer_common/tests/sanitizer_list_test.cc b/lib/sanitizer_common/tests/sanitizer_list_test.cc
deleted file mode 100644
index ede9771cb2496..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_list_test.cc
+++ /dev/null
@@ -1,189 +0,0 @@
-//===-- sanitizer_list_test.cc --------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_list.h"
-#include "gtest/gtest.h"
-
-namespace __sanitizer {
-
-struct ListItem {
- ListItem *next;
-};
-
-typedef IntrusiveList<ListItem> List;
-
-static List static_list;
-
-static void SetList(List *l, ListItem *x = 0,
- ListItem *y = 0, ListItem *z = 0) {
- l->clear();
- if (x) l->push_back(x);
- if (y) l->push_back(y);
- if (z) l->push_back(z);
-}
-
-static void CheckList(List *l, ListItem *i1, ListItem *i2 = 0, ListItem *i3 = 0,
- ListItem *i4 = 0, ListItem *i5 = 0, ListItem *i6 = 0) {
- if (i1) {
- CHECK_EQ(l->front(), i1);
- l->pop_front();
- }
- if (i2) {
- CHECK_EQ(l->front(), i2);
- l->pop_front();
- }
- if (i3) {
- CHECK_EQ(l->front(), i3);
- l->pop_front();
- }
- if (i4) {
- CHECK_EQ(l->front(), i4);
- l->pop_front();
- }
- if (i5) {
- CHECK_EQ(l->front(), i5);
- l->pop_front();
- }
- if (i6) {
- CHECK_EQ(l->front(), i6);
- l->pop_front();
- }
- CHECK(l->empty());
-}
-
-TEST(SanitizerCommon, IntrusiveList) {
- ListItem items[6];
- CHECK_EQ(static_list.size(), 0);
-
- List l;
- l.clear();
-
- ListItem *x = &items[0];
- ListItem *y = &items[1];
- ListItem *z = &items[2];
- ListItem *a = &items[3];
- ListItem *b = &items[4];
- ListItem *c = &items[5];
-
- CHECK_EQ(l.size(), 0);
- l.push_back(x);
- CHECK_EQ(l.size(), 1);
- CHECK_EQ(l.back(), x);
- CHECK_EQ(l.front(), x);
- l.pop_front();
- CHECK(l.empty());
- l.CheckConsistency();
-
- l.push_front(x);
- CHECK_EQ(l.size(), 1);
- CHECK_EQ(l.back(), x);
- CHECK_EQ(l.front(), x);
- l.pop_front();
- CHECK(l.empty());
- l.CheckConsistency();
-
- l.push_front(x);
- l.push_front(y);
- l.push_front(z);
- CHECK_EQ(l.size(), 3);
- CHECK_EQ(l.front(), z);
- CHECK_EQ(l.back(), x);
- l.CheckConsistency();
-
- l.pop_front();
- CHECK_EQ(l.size(), 2);
- CHECK_EQ(l.front(), y);
- CHECK_EQ(l.back(), x);
- l.pop_front();
- l.pop_front();
- CHECK(l.empty());
- l.CheckConsistency();
-
- l.push_back(x);
- l.push_back(y);
- l.push_back(z);
- CHECK_EQ(l.size(), 3);
- CHECK_EQ(l.front(), x);
- CHECK_EQ(l.back(), z);
- l.CheckConsistency();
-
- l.pop_front();
- CHECK_EQ(l.size(), 2);
- CHECK_EQ(l.front(), y);
- CHECK_EQ(l.back(), z);
- l.pop_front();
- l.pop_front();
- CHECK(l.empty());
- l.CheckConsistency();
-
- l.push_back(x);
- l.push_back(y);
- l.push_back(z);
- l.extract(x, y);
- CHECK_EQ(l.size(), 2);
- CHECK_EQ(l.front(), x);
- CHECK_EQ(l.back(), z);
- l.CheckConsistency();
- l.extract(x, z);
- CHECK_EQ(l.size(), 1);
- CHECK_EQ(l.front(), x);
- CHECK_EQ(l.back(), x);
- l.CheckConsistency();
- l.pop_front();
- CHECK(l.empty());
-
- List l1, l2;
- l1.clear();
- l2.clear();
-
- l1.append_front(&l2);
- CHECK(l1.empty());
- CHECK(l2.empty());
-
- l1.append_back(&l2);
- CHECK(l1.empty());
- CHECK(l2.empty());
-
- SetList(&l1, x);
- CheckList(&l1, x);
-
- SetList(&l1, x, y, z);
- SetList(&l2, a, b, c);
- l1.append_back(&l2);
- CheckList(&l1, x, y, z, a, b, c);
- CHECK(l2.empty());
-
- SetList(&l1, x, y);
- SetList(&l2);
- l1.append_front(&l2);
- CheckList(&l1, x, y);
- CHECK(l2.empty());
-}
-
-TEST(SanitizerCommon, IntrusiveListAppendEmpty) {
- ListItem i;
- List l;
- l.clear();
- l.push_back(&i);
- List l2;
- l2.clear();
- l.append_back(&l2);
- CHECK_EQ(l.back(), &i);
- CHECK_EQ(l.front(), &i);
- CHECK_EQ(l.size(), 1);
- l.append_front(&l2);
- CHECK_EQ(l.back(), &i);
- CHECK_EQ(l.front(), &i);
- CHECK_EQ(l.size(), 1);
-}
-
-} // namespace __sanitizer
diff --git a/lib/sanitizer_common/tests/sanitizer_mutex_test.cc b/lib/sanitizer_common/tests/sanitizer_mutex_test.cc
deleted file mode 100644
index d14e7c2fba217..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_mutex_test.cc
+++ /dev/null
@@ -1,137 +0,0 @@
-//===-- sanitizer_mutex_test.cc -------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_mutex.h"
-#include "sanitizer_common/sanitizer_common.h"
-
-#include "sanitizer_pthread_wrappers.h"
-
-#include "gtest/gtest.h"
-
-#include <string.h>
-
-namespace __sanitizer {
-
-template<typename MutexType>
-class TestData {
- public:
- explicit TestData(MutexType *mtx)
- : mtx_(mtx) {
- for (int i = 0; i < kSize; i++)
- data_[i] = 0;
- }
-
- void Write() {
- Lock l(mtx_);
- T v0 = data_[0];
- for (int i = 0; i < kSize; i++) {
- CHECK_EQ(data_[i], v0);
- data_[i]++;
- }
- }
-
- void TryWrite() {
- if (!mtx_->TryLock())
- return;
- T v0 = data_[0];
- for (int i = 0; i < kSize; i++) {
- CHECK_EQ(data_[i], v0);
- data_[i]++;
- }
- mtx_->Unlock();
- }
-
- void Backoff() {
- volatile T data[kSize] = {};
- for (int i = 0; i < kSize; i++) {
- data[i]++;
- CHECK_EQ(data[i], 1);
- }
- }
-
- private:
- typedef GenericScopedLock<MutexType> Lock;
- static const int kSize = 64;
- typedef u64 T;
- MutexType *mtx_;
- char pad_[kCacheLineSize];
- T data_[kSize];
-};
-
-const int kThreads = 8;
-#if SANITIZER_DEBUG
-const int kIters = 16*1024;
-#else
-const int kIters = 64*1024;
-#endif
-
-template<typename MutexType>
-static void *lock_thread(void *param) {
- TestData<MutexType> *data = (TestData<MutexType>*)param;
- for (int i = 0; i < kIters; i++) {
- data->Write();
- data->Backoff();
- }
- return 0;
-}
-
-template<typename MutexType>
-static void *try_thread(void *param) {
- TestData<MutexType> *data = (TestData<MutexType>*)param;
- for (int i = 0; i < kIters; i++) {
- data->TryWrite();
- data->Backoff();
- }
- return 0;
-}
-
-template<typename MutexType>
-static void check_locked(MutexType *mtx) {
- GenericScopedLock<MutexType> l(mtx);
- mtx->CheckLocked();
-}
-
-TEST(SanitizerCommon, SpinMutex) {
- SpinMutex mtx;
- mtx.Init();
- TestData<SpinMutex> data(&mtx);
- pthread_t threads[kThreads];
- for (int i = 0; i < kThreads; i++)
- PTHREAD_CREATE(&threads[i], 0, lock_thread<SpinMutex>, &data);
- for (int i = 0; i < kThreads; i++)
- PTHREAD_JOIN(threads[i], 0);
-}
-
-TEST(SanitizerCommon, SpinMutexTry) {
- SpinMutex mtx;
- mtx.Init();
- TestData<SpinMutex> data(&mtx);
- pthread_t threads[kThreads];
- for (int i = 0; i < kThreads; i++)
- PTHREAD_CREATE(&threads[i], 0, try_thread<SpinMutex>, &data);
- for (int i = 0; i < kThreads; i++)
- PTHREAD_JOIN(threads[i], 0);
-}
-
-TEST(SanitizerCommon, BlockingMutex) {
- u64 mtxmem[1024] = {};
- BlockingMutex *mtx = new(mtxmem) BlockingMutex(LINKER_INITIALIZED);
- TestData<BlockingMutex> data(mtx);
- pthread_t threads[kThreads];
- for (int i = 0; i < kThreads; i++)
- PTHREAD_CREATE(&threads[i], 0, lock_thread<BlockingMutex>, &data);
- for (int i = 0; i < kThreads; i++)
- PTHREAD_JOIN(threads[i], 0);
- check_locked(mtx);
-}
-
-} // namespace __sanitizer
diff --git a/lib/sanitizer_common/tests/sanitizer_nolibc_test.cc b/lib/sanitizer_common/tests/sanitizer_nolibc_test.cc
deleted file mode 100644
index d0d5a5e138985..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_nolibc_test.cc
+++ /dev/null
@@ -1,31 +0,0 @@
-//===-- sanitizer_nolibc_test.cc ------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
-// Tests for libc independence of sanitizer_common.
-//
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_platform.h"
-
-#include "gtest/gtest.h"
-
-#include <stdlib.h>
-
-extern const char *argv0;
-
-#if SANITIZER_LINUX && defined(__x86_64__)
-TEST(SanitizerCommon, NolibcMain) {
- std::string NolibcTestPath = argv0;
- NolibcTestPath += "-Nolibc";
- int status = system(NolibcTestPath.c_str());
- EXPECT_EQ(true, WIFEXITED(status));
- EXPECT_EQ(0, WEXITSTATUS(status));
-}
-#endif
diff --git a/lib/sanitizer_common/tests/sanitizer_nolibc_test_main.cc b/lib/sanitizer_common/tests/sanitizer_nolibc_test_main.cc
deleted file mode 100644
index e761f00c56fc0..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_nolibc_test_main.cc
+++ /dev/null
@@ -1,19 +0,0 @@
-//===-- sanitizer_nolibc_test_main.cc -------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
-// Tests for libc independence of sanitizer_common.
-//
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_libc.h"
-
-extern "C" void _start() {
- __sanitizer::internal__exit(0);
-}
diff --git a/lib/sanitizer_common/tests/sanitizer_posix_test.cc b/lib/sanitizer_common/tests/sanitizer_posix_test.cc
deleted file mode 100644
index b7cca83622aa7..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_posix_test.cc
+++ /dev/null
@@ -1,81 +0,0 @@
-//===-- sanitizer_posix_test.cc -------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Tests for POSIX-specific code.
-//
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_POSIX
-
-#include "sanitizer_common/sanitizer_common.h"
-#include "gtest/gtest.h"
-
-#include <pthread.h>
-#include <sys/mman.h>
-
-namespace __sanitizer {
-
-static pthread_key_t key;
-static bool destructor_executed;
-
-extern "C"
-void destructor(void *arg) {
- uptr iter = reinterpret_cast<uptr>(arg);
- if (iter > 1) {
- ASSERT_EQ(0, pthread_setspecific(key, reinterpret_cast<void *>(iter - 1)));
- return;
- }
- destructor_executed = true;
-}
-
-extern "C"
-void *thread_func(void *arg) {
- return reinterpret_cast<void*>(pthread_setspecific(key, arg));
-}
-
-static void SpawnThread(uptr iteration) {
- destructor_executed = false;
- pthread_t tid;
- ASSERT_EQ(0, pthread_create(&tid, 0, &thread_func,
- reinterpret_cast<void *>(iteration)));
- void *retval;
- ASSERT_EQ(0, pthread_join(tid, &retval));
- ASSERT_EQ(0, retval);
-}
-
-TEST(SanitizerCommon, PthreadDestructorIterations) {
- ASSERT_EQ(0, pthread_key_create(&key, &destructor));
- SpawnThread(GetPthreadDestructorIterations());
- EXPECT_TRUE(destructor_executed);
- SpawnThread(GetPthreadDestructorIterations() + 1);
- EXPECT_FALSE(destructor_executed);
- ASSERT_EQ(0, pthread_key_delete(key));
-}
-
-TEST(SanitizerCommon, IsAccessibleMemoryRange) {
- const int page_size = GetPageSize();
- uptr mem = (uptr)mmap(0, 3 * page_size, PROT_READ | PROT_WRITE,
- MAP_PRIVATE | MAP_ANON, -1, 0);
- // Protect the middle page.
- mprotect((void *)(mem + page_size), page_size, PROT_NONE);
- EXPECT_TRUE(IsAccessibleMemoryRange(mem, page_size - 1));
- EXPECT_TRUE(IsAccessibleMemoryRange(mem, page_size));
- EXPECT_FALSE(IsAccessibleMemoryRange(mem, page_size + 1));
- EXPECT_TRUE(IsAccessibleMemoryRange(mem + page_size - 1, 1));
- EXPECT_FALSE(IsAccessibleMemoryRange(mem + page_size - 1, 2));
- EXPECT_FALSE(IsAccessibleMemoryRange(mem + 2 * page_size - 1, 1));
- EXPECT_TRUE(IsAccessibleMemoryRange(mem + 2 * page_size, page_size));
- EXPECT_FALSE(IsAccessibleMemoryRange(mem, 3 * page_size));
- EXPECT_FALSE(IsAccessibleMemoryRange(0x0, 2));
-}
-
-} // namespace __sanitizer
-
-#endif // SANITIZER_POSIX
diff --git a/lib/sanitizer_common/tests/sanitizer_printf_test.cc b/lib/sanitizer_common/tests/sanitizer_printf_test.cc
deleted file mode 100644
index 75fe6667864f8..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_printf_test.cc
+++ /dev/null
@@ -1,161 +0,0 @@
-//===-- sanitizer_printf_test.cc ------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Tests for sanitizer_printf.cc
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_libc.h"
-#include "gtest/gtest.h"
-
-#include <string.h>
-#include <limits.h>
-
-namespace __sanitizer {
-
-TEST(Printf, Basic) {
- char buf[1024];
- uptr len = internal_snprintf(buf, sizeof(buf),
- "a%db%zdc%ue%zuf%xh%zxq%pe%sr",
- (int)-1, (uptr)-2, // NOLINT
- (unsigned)-4, (uptr)5, // NOLINT
- (unsigned)10, (uptr)11, // NOLINT
- (void*)0x123, "_string_");
- EXPECT_EQ(len, strlen(buf));
-
- std::string expectedString = "a-1b-2c4294967292e5fahbq0x";
- expectedString += std::string(SANITIZER_POINTER_FORMAT_LENGTH - 3, '0');
- expectedString += "123e_string_r";
- EXPECT_STREQ(expectedString.c_str(), buf);
-}
-
-TEST(Printf, OverflowStr) {
- char buf[] = "123456789";
- uptr len = internal_snprintf(buf, 4, "%s", "abcdef"); // NOLINT
- EXPECT_EQ(len, (uptr)6);
- EXPECT_STREQ("abc", buf);
- EXPECT_EQ(buf[3], 0);
- EXPECT_EQ(buf[4], '5');
- EXPECT_EQ(buf[5], '6');
- EXPECT_EQ(buf[6], '7');
- EXPECT_EQ(buf[7], '8');
- EXPECT_EQ(buf[8], '9');
- EXPECT_EQ(buf[9], 0);
-}
-
-TEST(Printf, OverflowInt) {
- char buf[] = "123456789";
- internal_snprintf(buf, 4, "%d", -123456789); // NOLINT
- EXPECT_STREQ("-12", buf);
- EXPECT_EQ(buf[3], 0);
- EXPECT_EQ(buf[4], '5');
- EXPECT_EQ(buf[5], '6');
- EXPECT_EQ(buf[6], '7');
- EXPECT_EQ(buf[7], '8');
- EXPECT_EQ(buf[8], '9');
- EXPECT_EQ(buf[9], 0);
-}
-
-TEST(Printf, OverflowUint) {
- char buf[] = "123456789";
- uptr val;
- if (sizeof(val) == 4) {
- val = (uptr)0x12345678;
- } else {
- val = (uptr)0x123456789ULL;
- }
- internal_snprintf(buf, 4, "a%zx", val); // NOLINT
- EXPECT_STREQ("a12", buf);
- EXPECT_EQ(buf[3], 0);
- EXPECT_EQ(buf[4], '5');
- EXPECT_EQ(buf[5], '6');
- EXPECT_EQ(buf[6], '7');
- EXPECT_EQ(buf[7], '8');
- EXPECT_EQ(buf[8], '9');
- EXPECT_EQ(buf[9], 0);
-}
-
-TEST(Printf, OverflowPtr) {
- char buf[] = "123456789";
- void *p;
- if (sizeof(p) == 4) {
- p = (void*)0x1234567;
- } else {
- p = (void*)0x123456789ULL;
- }
- internal_snprintf(buf, 4, "%p", p); // NOLINT
- EXPECT_STREQ("0x0", buf);
- EXPECT_EQ(buf[3], 0);
- EXPECT_EQ(buf[4], '5');
- EXPECT_EQ(buf[5], '6');
- EXPECT_EQ(buf[6], '7');
- EXPECT_EQ(buf[7], '8');
- EXPECT_EQ(buf[8], '9');
- EXPECT_EQ(buf[9], 0);
-}
-
-#if defined(_WIN32)
-// Oh well, MSVS headers don't define snprintf.
-# define snprintf _snprintf
-#endif
-
-template<typename T>
-static void TestAgainstLibc(const char *fmt, T arg1, T arg2) {
- char buf[1024];
- uptr len = internal_snprintf(buf, sizeof(buf), fmt, arg1, arg2);
- char buf2[1024];
- snprintf(buf2, sizeof(buf2), fmt, arg1, arg2);
- EXPECT_EQ(len, strlen(buf));
- EXPECT_STREQ(buf2, buf);
-}
-
-TEST(Printf, MinMax) {
- TestAgainstLibc<int>("%d-%d", INT_MIN, INT_MAX); // NOLINT
- TestAgainstLibc<unsigned>("%u-%u", 0, UINT_MAX); // NOLINT
- TestAgainstLibc<unsigned>("%x-%x", 0, UINT_MAX); // NOLINT
-#if !defined(_WIN32)
- // %z* format doesn't seem to be supported by MSVS.
- TestAgainstLibc<long>("%zd-%zd", LONG_MIN, LONG_MAX); // NOLINT
- TestAgainstLibc<unsigned long>("%zu-%zu", 0, ULONG_MAX); // NOLINT
- TestAgainstLibc<unsigned long>("%zx-%zx", 0, ULONG_MAX); // NOLINT
-#endif
-}
-
-TEST(Printf, Padding) {
- TestAgainstLibc<int>("%3d - %3d", 1, 0);
- TestAgainstLibc<int>("%3d - %3d", -1, 123);
- TestAgainstLibc<int>("%3d - %3d", -1, -123);
- TestAgainstLibc<int>("%3d - %3d", 12, 1234);
- TestAgainstLibc<int>("%3d - %3d", -12, -1234);
- TestAgainstLibc<int>("%03d - %03d", 1, 0);
- TestAgainstLibc<int>("%03d - %03d", -1, 123);
- TestAgainstLibc<int>("%03d - %03d", -1, -123);
- TestAgainstLibc<int>("%03d - %03d", 12, 1234);
- TestAgainstLibc<int>("%03d - %03d", -12, -1234);
-}
-
-TEST(Printf, Precision) {
- char buf[1024];
- uptr len = internal_snprintf(buf, sizeof(buf), "%.*s", 3, "12345");
- EXPECT_EQ(3U, len);
- EXPECT_STREQ("123", buf);
- len = internal_snprintf(buf, sizeof(buf), "%.*s", 6, "12345");
- EXPECT_EQ(5U, len);
- EXPECT_STREQ("12345", buf);
- len = internal_snprintf(buf, sizeof(buf), "%-6s", "12345");
- EXPECT_EQ(6U, len);
- EXPECT_STREQ("12345 ", buf);
- // Check that width does not overflow the smaller buffer, although
- // 10 chars is requested, it stops at the buffer size, 8.
- len = internal_snprintf(buf, 8, "%-10s", "12345");
- EXPECT_EQ(10U, len); // The required size reported.
- EXPECT_STREQ("12345 ", buf);
-}
-
-} // namespace __sanitizer
diff --git a/lib/sanitizer_common/tests/sanitizer_procmaps_test.cc b/lib/sanitizer_common/tests/sanitizer_procmaps_test.cc
deleted file mode 100644
index 22052d9a4f592..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_procmaps_test.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-//===-- sanitizer_procmaps_test.cc ----------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
-//
-//===----------------------------------------------------------------------===//
-#if !defined(_WIN32) // There are no /proc/maps on Windows.
-
-#include "sanitizer_common/sanitizer_procmaps.h"
-#include "gtest/gtest.h"
-
-#include <stdlib.h>
-
-static void noop() {}
-extern const char *argv0;
-
-namespace __sanitizer {
-
-#if SANITIZER_LINUX && !SANITIZER_ANDROID
-TEST(MemoryMappingLayout, CodeRange) {
- uptr start, end;
- bool res = GetCodeRangeForFile("[vdso]", &start, &end);
- EXPECT_EQ(res, true);
- EXPECT_GT(start, 0U);
- EXPECT_LT(start, end);
-}
-#endif
-
-TEST(MemoryMappingLayout, DumpListOfModules) {
- const char *last_slash = strrchr(argv0, '/');
- const char *binary_name = last_slash ? last_slash + 1 : argv0;
- MemoryMappingLayout memory_mapping(false);
- const uptr kMaxModules = 100;
- InternalMmapVector<LoadedModule> modules;
- modules.reserve(kMaxModules);
- memory_mapping.DumpListOfModules(&modules);
- EXPECT_GT(modules.size(), 0U);
- bool found = false;
- for (uptr i = 0; i < modules.size(); ++i) {
- if (modules[i].containsAddress((uptr)&noop)) {
- // Verify that the module name is sane.
- if (strstr(modules[i].full_name(), binary_name) != 0)
- found = true;
- }
- modules[i].clear();
- }
- EXPECT_TRUE(found);
-}
-
-TEST(MemoryMapping, LoadedModuleArchAndUUID) {
- if (SANITIZER_MAC) {
- MemoryMappingLayout memory_mapping(false);
- const uptr kMaxModules = 100;
- InternalMmapVector<LoadedModule> modules;
- modules.reserve(kMaxModules);
- memory_mapping.DumpListOfModules(&modules);
- for (uptr i = 0; i < modules.size(); ++i) {
- ModuleArch arch = modules[i].arch();
- // Darwin unit tests are only run on i386/x86_64/x86_64h.
- if (SANITIZER_WORDSIZE == 32) {
- EXPECT_EQ(arch, kModuleArchI386);
- } else if (SANITIZER_WORDSIZE == 64) {
- EXPECT_TRUE(arch == kModuleArchX86_64 || arch == kModuleArchX86_64H);
- }
- const u8 *uuid = modules[i].uuid();
- u8 null_uuid[kModuleUUIDSize] = {0};
- EXPECT_NE(memcmp(null_uuid, uuid, kModuleUUIDSize), 0);
- }
- }
-}
-
-} // namespace __sanitizer
-#endif // !defined(_WIN32)
diff --git a/lib/sanitizer_common/tests/sanitizer_pthread_wrappers.h b/lib/sanitizer_common/tests/sanitizer_pthread_wrappers.h
deleted file mode 100644
index b7d784c2566df..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_pthread_wrappers.h
+++ /dev/null
@@ -1,68 +0,0 @@
-//===-- sanitizer_pthread_wrappers.h ----------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of *Sanitizer runtime.
-// It provides handy wrappers for thread manipulation, that:
-// a) assert on any failure rather than returning an error code
-// b) defines pthread-like interface on platforms where where <pthread.h>
-// is not supplied by default.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SANITIZER_PTHREAD_WRAPPERS_H
-#define SANITIZER_PTHREAD_WRAPPERS_H
-
-#include "sanitizer_test_utils.h"
-
-#if !defined(_WIN32)
-# include <pthread.h>
-// Simply forward the arguments and check that the pthread functions succeed.
-# define PTHREAD_CREATE(a, b, c, d) ASSERT_EQ(0, pthread_create(a, b, c, d))
-# define PTHREAD_JOIN(a, b) ASSERT_EQ(0, pthread_join(a, b))
-#else
-typedef HANDLE pthread_t;
-
-struct PthreadHelperCreateThreadInfo {
- void *(*start_routine)(void *);
- void *arg;
-};
-
-inline DWORD WINAPI PthreadHelperThreadProc(void *arg) {
- PthreadHelperCreateThreadInfo *start_data =
- reinterpret_cast<PthreadHelperCreateThreadInfo*>(arg);
- void *ret = (start_data->start_routine)(start_data->arg);
- delete start_data;
- return (DWORD)ret;
-}
-
-inline void PTHREAD_CREATE(pthread_t *thread, void *attr,
- void *(*start_routine)(void *), void *arg) {
- ASSERT_EQ(0, attr) << "Thread attributes are not supported yet.";
- PthreadHelperCreateThreadInfo *data = new PthreadHelperCreateThreadInfo;
- data->start_routine = start_routine;
- data->arg = arg;
- *thread = CreateThread(0, 0, PthreadHelperThreadProc, data, 0, 0);
- DWORD err = GetLastError();
- ASSERT_NE(nullptr, *thread) << "Failed to create a thread, got error 0x"
- << std::hex << err;
-}
-
-inline void PTHREAD_JOIN(pthread_t thread, void **value_ptr) {
- ASSERT_EQ(0, value_ptr) << "Nonzero value_ptr is not supported yet.";
- ASSERT_EQ(WAIT_OBJECT_0, WaitForSingleObject(thread, INFINITE));
- ASSERT_NE(0, CloseHandle(thread));
-}
-
-inline void pthread_exit(void *retval) {
- ASSERT_EQ(0, retval) << "Nonzero retval is not supported yet.";
- ExitThread((DWORD)retval);
-}
-#endif // _WIN32
-
-#endif // SANITIZER_PTHREAD_WRAPPERS_H
diff --git a/lib/sanitizer_common/tests/sanitizer_quarantine_test.cc b/lib/sanitizer_common/tests/sanitizer_quarantine_test.cc
deleted file mode 100644
index 23ed5f97ae27f..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_quarantine_test.cc
+++ /dev/null
@@ -1,180 +0,0 @@
-//===-- sanitizer_quarantine_test.cc --------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_quarantine.h"
-#include "gtest/gtest.h"
-
-#include <stdlib.h>
-
-namespace __sanitizer {
-
-struct QuarantineCallback {
- void Recycle(void *m) {}
- void *Allocate(uptr size) {
- return malloc(size);
- }
- void Deallocate(void *p) {
- free(p);
- }
-};
-
-typedef QuarantineCache<QuarantineCallback> Cache;
-
-static void* kFakePtr = reinterpret_cast<void*>(0xFA83FA83);
-static const size_t kBlockSize = 8;
-
-static QuarantineCallback cb;
-
-static void DeallocateCache(Cache *cache) {
- while (QuarantineBatch *batch = cache->DequeueBatch())
- cb.Deallocate(batch);
-}
-
-TEST(SanitizerCommon, QuarantineBatchMerge) {
- // Verify the trivial case.
- QuarantineBatch into;
- into.init(kFakePtr, 4UL);
- QuarantineBatch from;
- from.init(kFakePtr, 8UL);
-
- into.merge(&from);
-
- ASSERT_EQ(into.count, 2UL);
- ASSERT_EQ(into.batch[0], kFakePtr);
- ASSERT_EQ(into.batch[1], kFakePtr);
- ASSERT_EQ(into.size, 12UL + sizeof(QuarantineBatch));
- ASSERT_EQ(into.quarantined_size(), 12UL);
-
- ASSERT_EQ(from.count, 0UL);
- ASSERT_EQ(from.size, sizeof(QuarantineBatch));
- ASSERT_EQ(from.quarantined_size(), 0UL);
-
- // Merge the batch to the limit.
- for (uptr i = 2; i < QuarantineBatch::kSize; ++i)
- from.push_back(kFakePtr, 8UL);
- ASSERT_TRUE(into.count + from.count == QuarantineBatch::kSize);
- ASSERT_TRUE(into.can_merge(&from));
-
- into.merge(&from);
- ASSERT_TRUE(into.count == QuarantineBatch::kSize);
-
- // No more space, not even for one element.
- from.init(kFakePtr, 8UL);
-
- ASSERT_FALSE(into.can_merge(&from));
-}
-
-TEST(SanitizerCommon, QuarantineCacheMergeBatchesEmpty) {
- Cache cache;
- Cache to_deallocate;
- cache.MergeBatches(&to_deallocate);
-
- ASSERT_EQ(to_deallocate.Size(), 0UL);
- ASSERT_EQ(to_deallocate.DequeueBatch(), nullptr);
-}
-
-TEST(SanitizerCommon, QuarantineCacheMergeBatchesOneBatch) {
- Cache cache;
- cache.Enqueue(cb, kFakePtr, kBlockSize);
- ASSERT_EQ(kBlockSize + sizeof(QuarantineBatch), cache.Size());
-
- Cache to_deallocate;
- cache.MergeBatches(&to_deallocate);
-
- // Nothing to merge, nothing to deallocate.
- ASSERT_EQ(kBlockSize + sizeof(QuarantineBatch), cache.Size());
-
- ASSERT_EQ(to_deallocate.Size(), 0UL);
- ASSERT_EQ(to_deallocate.DequeueBatch(), nullptr);
-
- DeallocateCache(&cache);
-}
-
-TEST(SanitizerCommon, QuarantineCacheMergeBatchesSmallBatches) {
- // Make a cache with two batches small enough to merge.
- Cache from;
- from.Enqueue(cb, kFakePtr, kBlockSize);
- Cache cache;
- cache.Enqueue(cb, kFakePtr, kBlockSize);
-
- cache.Transfer(&from);
- ASSERT_EQ(kBlockSize * 2 + sizeof(QuarantineBatch) * 2, cache.Size());
-
- Cache to_deallocate;
- cache.MergeBatches(&to_deallocate);
-
- // Batches merged, one batch to deallocate.
- ASSERT_EQ(kBlockSize * 2 + sizeof(QuarantineBatch), cache.Size());
- ASSERT_EQ(to_deallocate.Size(), sizeof(QuarantineBatch));
-
- DeallocateCache(&cache);
- DeallocateCache(&to_deallocate);
-}
-
-TEST(SanitizerCommon, QuarantineCacheMergeBatchesTooBigToMerge) {
- const uptr kNumBlocks = QuarantineBatch::kSize - 1;
-
- // Make a cache with two batches small enough to merge.
- Cache from;
- Cache cache;
- for (uptr i = 0; i < kNumBlocks; ++i) {
- from.Enqueue(cb, kFakePtr, kBlockSize);
- cache.Enqueue(cb, kFakePtr, kBlockSize);
- }
- cache.Transfer(&from);
- ASSERT_EQ(kBlockSize * kNumBlocks * 2 +
- sizeof(QuarantineBatch) * 2, cache.Size());
-
- Cache to_deallocate;
- cache.MergeBatches(&to_deallocate);
-
- // Batches cannot be merged.
- ASSERT_EQ(kBlockSize * kNumBlocks * 2 +
- sizeof(QuarantineBatch) * 2, cache.Size());
- ASSERT_EQ(to_deallocate.Size(), 0UL);
-
- DeallocateCache(&cache);
-}
-
-TEST(SanitizerCommon, QuarantineCacheMergeBatchesALotOfBatches) {
- const uptr kNumBatchesAfterMerge = 3;
- const uptr kNumBlocks = QuarantineBatch::kSize * kNumBatchesAfterMerge;
- const uptr kNumBatchesBeforeMerge = kNumBlocks;
-
- // Make a cache with many small batches.
- Cache cache;
- for (uptr i = 0; i < kNumBlocks; ++i) {
- Cache from;
- from.Enqueue(cb, kFakePtr, kBlockSize);
- cache.Transfer(&from);
- }
-
- ASSERT_EQ(kBlockSize * kNumBlocks +
- sizeof(QuarantineBatch) * kNumBatchesBeforeMerge, cache.Size());
-
- Cache to_deallocate;
- cache.MergeBatches(&to_deallocate);
-
- // All blocks should fit into 3 batches.
- ASSERT_EQ(kBlockSize * kNumBlocks +
- sizeof(QuarantineBatch) * kNumBatchesAfterMerge, cache.Size());
-
- ASSERT_EQ(to_deallocate.Size(),
- sizeof(QuarantineBatch) *
- (kNumBatchesBeforeMerge - kNumBatchesAfterMerge));
-
- DeallocateCache(&cache);
- DeallocateCache(&to_deallocate);
-}
-
-} // namespace __sanitizer
diff --git a/lib/sanitizer_common/tests/sanitizer_ring_buffer_test.cc b/lib/sanitizer_common/tests/sanitizer_ring_buffer_test.cc
deleted file mode 100644
index 80aa57c5290eb..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_ring_buffer_test.cc
+++ /dev/null
@@ -1,99 +0,0 @@
-//===-- sanitizer_vector_test.cc ------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of *Sanitizer runtime.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_ring_buffer.h"
-#include "gtest/gtest.h"
-
-namespace __sanitizer {
-
-struct LargeStruct {
- int64_t v;
- int64_t extra[3];
-
- explicit LargeStruct(int64_t v) : v(v) {}
- operator int64_t() { return v; }
-};
-
-struct Struct10Bytes {
- short t[3];
-};
-
-TEST(RingBuffer, Construct) {
- RingBuffer<int64_t> *RBlong = RingBuffer<int64_t>::New(20);
- EXPECT_EQ(RBlong->size(), 20U);
- RBlong->Delete();
-}
-
-template <class T> void TestRB() {
- RingBuffer<T> *RB;
- const size_t Sizes[] = {1, 2, 3, 5, 8, 16, 20, 40, 10000};
- for (size_t Size : Sizes) {
- RB = RingBuffer<T>::New(Size);
- EXPECT_EQ(RB->size(), Size);
- RB->Delete();
- }
-
- RB = RingBuffer<T>::New(4);
- EXPECT_EQ(RB->size(), 4U);
-#define EXPECT_RING_BUFFER(a0, a1, a2, a3) \
- EXPECT_EQ((int64_t)(*RB)[0], (int64_t)a0); \
- EXPECT_EQ((int64_t)(*RB)[1], (int64_t)a1); \
- EXPECT_EQ((int64_t)(*RB)[2], (int64_t)a2); \
- EXPECT_EQ((int64_t)(*RB)[3], (int64_t)a3);
-
- RB->push(T(1)); EXPECT_RING_BUFFER(1, 0, 0, 0);
- RB->push(T(2)); EXPECT_RING_BUFFER(2, 1, 0, 0);
- RB->push(T(3)); EXPECT_RING_BUFFER(3, 2, 1, 0);
- RB->push(T(4)); EXPECT_RING_BUFFER(4, 3, 2, 1);
- RB->push(T(5)); EXPECT_RING_BUFFER(5, 4, 3, 2);
- RB->push(T(6)); EXPECT_RING_BUFFER(6, 5, 4, 3);
- RB->push(T(7)); EXPECT_RING_BUFFER(7, 6, 5, 4);
- RB->push(T(8)); EXPECT_RING_BUFFER(8, 7, 6, 5);
- RB->push(T(9)); EXPECT_RING_BUFFER(9, 8, 7, 6);
- RB->push(T(10)); EXPECT_RING_BUFFER(10, 9, 8, 7);
- RB->push(T(11)); EXPECT_RING_BUFFER(11, 10, 9, 8);
- RB->push(T(12)); EXPECT_RING_BUFFER(12, 11, 10, 9);
-
-#undef EXPECT_RING_BUFFER
-}
-
-#if SANITIZER_WORDSIZE == 64
-TEST(RingBuffer, int64) {
- TestRB<int64_t>();
-}
-
-TEST(RingBuffer, LargeStruct) {
- TestRB<LargeStruct>();
-}
-
-template<typename T>
-CompactRingBuffer<T> *AllocCompactRingBuffer(size_t count) {
- size_t sz = sizeof(T) * count;
- EXPECT_EQ(0ULL, sz % 4096);
- void *p = MmapAlignedOrDieOnFatalError(sz, sz * 2, "CompactRingBuffer");
- return new CompactRingBuffer<T>(p, sz);
-}
-
-TEST(CompactRingBuffer, int64) {
- const size_t page_sizes[] = {1, 2, 4, 128};
-
- for (size_t pages : page_sizes) {
- size_t count = 4096 * pages / sizeof(int64_t);
- auto R = AllocCompactRingBuffer<int64_t>(count);
- int64_t top = count * 3 + 13;
- for (int64_t i = 0; i < top; ++i) R->push(i);
- for (int64_t i = 0; i < (int64_t)count; ++i)
- EXPECT_EQ(top - i - 1, (*R)[i]);
- }
-}
-#endif
-} // namespace __sanitizer
diff --git a/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cc b/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cc
deleted file mode 100644
index 513432fac214a..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_stackdepot_test.cc
+++ /dev/null
@@ -1,93 +0,0 @@
-//===-- sanitizer_stackdepot_test.cc --------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_stackdepot.h"
-#include "sanitizer_common/sanitizer_internal_defs.h"
-#include "sanitizer_common/sanitizer_libc.h"
-#include "gtest/gtest.h"
-
-namespace __sanitizer {
-
-TEST(SanitizerCommon, StackDepotBasic) {
- uptr array[] = {1, 2, 3, 4, 5};
- StackTrace s1(array, ARRAY_SIZE(array));
- u32 i1 = StackDepotPut(s1);
- StackTrace stack = StackDepotGet(i1);
- EXPECT_NE(stack.trace, (uptr*)0);
- EXPECT_EQ(ARRAY_SIZE(array), stack.size);
- EXPECT_EQ(0, internal_memcmp(stack.trace, array, sizeof(array)));
-}
-
-TEST(SanitizerCommon, StackDepotAbsent) {
- StackTrace stack = StackDepotGet((1 << 30) - 1);
- EXPECT_EQ((uptr*)0, stack.trace);
-}
-
-TEST(SanitizerCommon, StackDepotEmptyStack) {
- u32 i1 = StackDepotPut(StackTrace());
- StackTrace stack = StackDepotGet(i1);
- EXPECT_EQ((uptr*)0, stack.trace);
-}
-
-TEST(SanitizerCommon, StackDepotZeroId) {
- StackTrace stack = StackDepotGet(0);
- EXPECT_EQ((uptr*)0, stack.trace);
-}
-
-TEST(SanitizerCommon, StackDepotSame) {
- uptr array[] = {1, 2, 3, 4, 6};
- StackTrace s1(array, ARRAY_SIZE(array));
- u32 i1 = StackDepotPut(s1);
- u32 i2 = StackDepotPut(s1);
- EXPECT_EQ(i1, i2);
- StackTrace stack = StackDepotGet(i1);
- EXPECT_NE(stack.trace, (uptr*)0);
- EXPECT_EQ(ARRAY_SIZE(array), stack.size);
- EXPECT_EQ(0, internal_memcmp(stack.trace, array, sizeof(array)));
-}
-
-TEST(SanitizerCommon, StackDepotSeveral) {
- uptr array1[] = {1, 2, 3, 4, 7};
- StackTrace s1(array1, ARRAY_SIZE(array1));
- u32 i1 = StackDepotPut(s1);
- uptr array2[] = {1, 2, 3, 4, 8, 9};
- StackTrace s2(array2, ARRAY_SIZE(array2));
- u32 i2 = StackDepotPut(s2);
- EXPECT_NE(i1, i2);
-}
-
-TEST(SanitizerCommon, StackDepotReverseMap) {
- uptr array1[] = {1, 2, 3, 4, 5};
- uptr array2[] = {7, 1, 3, 0};
- uptr array3[] = {10, 2, 5, 3};
- uptr array4[] = {1, 3, 2, 5};
- u32 ids[4] = {0};
- StackTrace s1(array1, ARRAY_SIZE(array1));
- StackTrace s2(array2, ARRAY_SIZE(array2));
- StackTrace s3(array3, ARRAY_SIZE(array3));
- StackTrace s4(array4, ARRAY_SIZE(array4));
- ids[0] = StackDepotPut(s1);
- ids[1] = StackDepotPut(s2);
- ids[2] = StackDepotPut(s3);
- ids[3] = StackDepotPut(s4);
-
- StackDepotReverseMap map;
-
- for (uptr i = 0; i < 4; i++) {
- StackTrace stack = StackDepotGet(ids[i]);
- StackTrace from_map = map.Get(ids[i]);
- EXPECT_EQ(stack.size, from_map.size);
- EXPECT_EQ(stack.trace, from_map.trace);
- }
-}
-
-} // namespace __sanitizer
diff --git a/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc b/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc
deleted file mode 100644
index 405f8d86ea3c1..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_stacktrace_printer_test.cc
+++ /dev/null
@@ -1,157 +0,0 @@
-//===-- sanitizer_common_printer_test.cc ----------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of sanitizer_common test suite.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_stacktrace_printer.h"
-
-#include "gtest/gtest.h"
-
-namespace __sanitizer {
-
-TEST(SanitizerStacktracePrinter, RenderSourceLocation) {
- InternalScopedString str(128);
- RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, "");
- EXPECT_STREQ("/dir/file.cc:10:5", str.data());
-
- str.clear();
- RenderSourceLocation(&str, "/dir/file.cc", 11, 0, false, "");
- EXPECT_STREQ("/dir/file.cc:11", str.data());
-
- str.clear();
- RenderSourceLocation(&str, "/dir/file.cc", 0, 0, false, "");
- EXPECT_STREQ("/dir/file.cc", str.data());
-
- str.clear();
- RenderSourceLocation(&str, "/dir/file.cc", 10, 5, false, "/dir/");
- EXPECT_STREQ("file.cc:10:5", str.data());
-
- str.clear();
- RenderSourceLocation(&str, "/dir/file.cc", 10, 5, true, "");
- EXPECT_STREQ("/dir/file.cc(10,5)", str.data());
-
- str.clear();
- RenderSourceLocation(&str, "/dir/file.cc", 11, 0, true, "");
- EXPECT_STREQ("/dir/file.cc(11)", str.data());
-
- str.clear();
- RenderSourceLocation(&str, "/dir/file.cc", 0, 0, true, "");
- EXPECT_STREQ("/dir/file.cc", str.data());
-
- str.clear();
- RenderSourceLocation(&str, "/dir/file.cc", 10, 5, true, "/dir/");
- EXPECT_STREQ("file.cc(10,5)", str.data());
-}
-
-TEST(SanitizerStacktracePrinter, RenderModuleLocation) {
- InternalScopedString str(128);
- RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchUnknown, "");
- EXPECT_STREQ("(/dir/exe+0x123)", str.data());
-
- // Check that we strip file prefix if necessary.
- str.clear();
- RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchUnknown, "/dir/");
- EXPECT_STREQ("(exe+0x123)", str.data());
-
- // Check that we render the arch.
- str.clear();
- RenderModuleLocation(&str, "/dir/exe", 0x123, kModuleArchX86_64H, "/dir/");
- EXPECT_STREQ("(exe:x86_64h+0x123)", str.data());
-}
-
-TEST(SanitizerStacktracePrinter, RenderFrame) {
- int frame_no = 42;
- AddressInfo info;
- info.address = 0x400000;
- info.module = internal_strdup("/path/to/my/module");
- info.module_offset = 0x200;
- info.function = internal_strdup("function_foo");
- info.function_offset = 0x100;
- info.file = internal_strdup("/path/to/my/source");
- info.line = 10;
- info.column = 5;
- InternalScopedString str(256);
-
- // Dump all the AddressInfo fields.
- RenderFrame(&str, "%% Frame:%n PC:%p Module:%m ModuleOffset:%o "
- "Function:%f FunctionOffset:%q Source:%s Line:%l "
- "Column:%c",
- frame_no, info, false, "/path/to/", "function_");
- EXPECT_STREQ("% Frame:42 PC:0x400000 Module:my/module ModuleOffset:0x200 "
- "Function:foo FunctionOffset:0x100 Source:my/source Line:10 "
- "Column:5",
- str.data());
- info.Clear();
- str.clear();
-
- // Test special format specifiers.
- info.address = 0x400000;
- RenderFrame(&str, "%M", frame_no, info, false);
- EXPECT_NE(nullptr, internal_strstr(str.data(), "400000"));
- str.clear();
-
- RenderFrame(&str, "%L", frame_no, info, false);
- EXPECT_STREQ("(<unknown module>)", str.data());
- str.clear();
-
- info.module = internal_strdup("/path/to/module");
- info.module_offset = 0x200;
- RenderFrame(&str, "%M", frame_no, info, false);
- EXPECT_NE(nullptr, internal_strstr(str.data(), "(module+0x"));
- EXPECT_NE(nullptr, internal_strstr(str.data(), "200"));
- str.clear();
-
- RenderFrame(&str, "%L", frame_no, info, false);
- EXPECT_STREQ("(/path/to/module+0x200)", str.data());
- str.clear();
-
- info.function = internal_strdup("my_function");
- RenderFrame(&str, "%F", frame_no, info, false);
- EXPECT_STREQ("in my_function", str.data());
- str.clear();
-
- info.function_offset = 0x100;
- RenderFrame(&str, "%F %S", frame_no, info, false);
- EXPECT_STREQ("in my_function+0x100 <null>", str.data());
- str.clear();
-
- info.file = internal_strdup("my_file");
- RenderFrame(&str, "%F %S", frame_no, info, false);
- EXPECT_STREQ("in my_function my_file", str.data());
- str.clear();
-
- info.line = 10;
- RenderFrame(&str, "%F %S", frame_no, info, false);
- EXPECT_STREQ("in my_function my_file:10", str.data());
- str.clear();
-
- info.column = 5;
- RenderFrame(&str, "%S %L", frame_no, info, false);
- EXPECT_STREQ("my_file:10:5 my_file:10:5", str.data());
- str.clear();
-
- RenderFrame(&str, "%S %L", frame_no, info, true);
- EXPECT_STREQ("my_file(10,5) my_file(10,5)", str.data());
- str.clear();
-
- info.column = 0;
- RenderFrame(&str, "%F %S", frame_no, info, true);
- EXPECT_STREQ("in my_function my_file(10)", str.data());
- str.clear();
-
- info.line = 0;
- RenderFrame(&str, "%F %S", frame_no, info, true);
- EXPECT_STREQ("in my_function my_file", str.data());
- str.clear();
-
- info.Clear();
-}
-
-} // namespace __sanitizer
diff --git a/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc b/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc
deleted file mode 100644
index ba9f4fd693265..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_stacktrace_test.cc
+++ /dev/null
@@ -1,167 +0,0 @@
-//===-- sanitizer_stacktrace_test.cc --------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
-//
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_stacktrace.h"
-#include "gtest/gtest.h"
-
-namespace __sanitizer {
-
-class FastUnwindTest : public ::testing::Test {
- protected:
- virtual void SetUp();
- virtual void TearDown();
- bool TryFastUnwind(uptr max_depth) {
- if (!StackTrace::WillUseFastUnwind(true))
- return false;
- trace.Unwind(max_depth, start_pc, (uptr)&fake_stack[0], 0, fake_top,
- fake_bottom, true);
- return true;
- }
-
- void *mapping;
- uhwptr *fake_stack;
- const uptr fake_stack_size = 10;
- uhwptr start_pc;
- uhwptr fake_top;
- uhwptr fake_bottom;
- BufferedStackTrace trace;
-};
-
-static uptr PC(uptr idx) {
- return (1<<20) + idx;
-}
-
-void FastUnwindTest::SetUp() {
- size_t ps = GetPageSize();
- mapping = MmapOrDie(2 * ps, "FastUnwindTest");
- MprotectNoAccess((uptr)mapping, ps);
-
- // Unwinder may peek 1 word down from the starting FP.
- fake_stack = (uhwptr *)((uptr)mapping + ps + sizeof(uhwptr));
-
- // Fill an array of pointers with fake fp+retaddr pairs. Frame pointers have
- // even indices.
- for (uptr i = 0; i + 1 < fake_stack_size; i += 2) {
- fake_stack[i] = (uptr)&fake_stack[i+2]; // fp
- fake_stack[i+1] = PC(i + 1); // retaddr
- }
- // Mark the last fp point back up to terminate the stack trace.
- fake_stack[RoundDownTo(fake_stack_size - 1, 2)] = (uhwptr)&fake_stack[0];
-
- // Top is two slots past the end because FastUnwindStack subtracts two.
- fake_top = (uhwptr)&fake_stack[fake_stack_size + 2];
- // Bottom is one slot before the start because FastUnwindStack uses >.
- fake_bottom = (uhwptr)mapping;
- start_pc = PC(0);
-}
-
-void FastUnwindTest::TearDown() {
- size_t ps = GetPageSize();
- UnmapOrDie(mapping, 2 * ps);
-}
-
-TEST_F(FastUnwindTest, Basic) {
- if (!TryFastUnwind(kStackTraceMax))
- return;
- // Should get all on-stack retaddrs and start_pc.
- EXPECT_EQ(6U, trace.size);
- EXPECT_EQ(start_pc, trace.trace[0]);
- for (uptr i = 1; i <= 5; i++) {
- EXPECT_EQ(PC(i*2 - 1), trace.trace[i]);
- }
-}
-
-// From: https://github.com/google/sanitizers/issues/162
-TEST_F(FastUnwindTest, FramePointerLoop) {
- // Make one fp point to itself.
- fake_stack[4] = (uhwptr)&fake_stack[4];
- if (!TryFastUnwind(kStackTraceMax))
- return;
- // Should get all on-stack retaddrs up to the 4th slot and start_pc.
- EXPECT_EQ(4U, trace.size);
- EXPECT_EQ(start_pc, trace.trace[0]);
- for (uptr i = 1; i <= 3; i++) {
- EXPECT_EQ(PC(i*2 - 1), trace.trace[i]);
- }
-}
-
-TEST_F(FastUnwindTest, MisalignedFramePointer) {
- // Make one fp misaligned.
- fake_stack[4] += 3;
- if (!TryFastUnwind(kStackTraceMax))
- return;
- // Should get all on-stack retaddrs up to the 4th slot and start_pc.
- EXPECT_EQ(4U, trace.size);
- EXPECT_EQ(start_pc, trace.trace[0]);
- for (uptr i = 1; i < 4U; i++) {
- EXPECT_EQ(PC(i*2 - 1), trace.trace[i]);
- }
-}
-
-TEST_F(FastUnwindTest, OneFrameStackTrace) {
- if (!TryFastUnwind(1))
- return;
- EXPECT_EQ(1U, trace.size);
- EXPECT_EQ(start_pc, trace.trace[0]);
- EXPECT_EQ((uhwptr)&fake_stack[0], trace.top_frame_bp);
-}
-
-TEST_F(FastUnwindTest, ZeroFramesStackTrace) {
- if (!TryFastUnwind(0))
- return;
- EXPECT_EQ(0U, trace.size);
- EXPECT_EQ(0U, trace.top_frame_bp);
-}
-
-TEST_F(FastUnwindTest, FPBelowPrevFP) {
- // The next FP points to unreadable memory inside the stack limits, but below
- // current FP.
- fake_stack[0] = (uhwptr)&fake_stack[-50];
- fake_stack[1] = PC(1);
- if (!TryFastUnwind(3))
- return;
- EXPECT_EQ(2U, trace.size);
- EXPECT_EQ(PC(0), trace.trace[0]);
- EXPECT_EQ(PC(1), trace.trace[1]);
-}
-
-TEST_F(FastUnwindTest, CloseToZeroFrame) {
- // Make one pc a NULL pointer.
- fake_stack[5] = 0x0;
- if (!TryFastUnwind(kStackTraceMax))
- return;
- // The stack should be truncated at the NULL pointer (and not include it).
- EXPECT_EQ(3U, trace.size);
- EXPECT_EQ(start_pc, trace.trace[0]);
- for (uptr i = 1; i < 3U; i++) {
- EXPECT_EQ(PC(i*2 - 1), trace.trace[i]);
- }
-}
-
-TEST(SlowUnwindTest, ShortStackTrace) {
- if (StackTrace::WillUseFastUnwind(false))
- return;
- BufferedStackTrace stack;
- uptr pc = StackTrace::GetCurrentPc();
- uptr bp = GET_CURRENT_FRAME();
- stack.Unwind(0, pc, bp, 0, 0, 0, false);
- EXPECT_EQ(0U, stack.size);
- EXPECT_EQ(0U, stack.top_frame_bp);
- stack.Unwind(1, pc, bp, 0, 0, 0, false);
- EXPECT_EQ(1U, stack.size);
- EXPECT_EQ(pc, stack.trace[0]);
- EXPECT_EQ(bp, stack.top_frame_bp);
-}
-
-} // namespace __sanitizer
diff --git a/lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cc b/lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cc
deleted file mode 100644
index 802af392c6096..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_stoptheworld_test.cc
+++ /dev/null
@@ -1,204 +0,0 @@
-//===-- sanitizer_stoptheworld_test.cc ------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Tests for sanitizer_stoptheworld.h
-//
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_LINUX && defined(__x86_64__)
-
-#include "sanitizer_common/sanitizer_stoptheworld.h"
-#include "gtest/gtest.h"
-
-#include "sanitizer_common/sanitizer_libc.h"
-#include "sanitizer_common/sanitizer_common.h"
-
-#include <pthread.h>
-#include <sched.h>
-
-namespace __sanitizer {
-
-static pthread_mutex_t incrementer_thread_exit_mutex;
-
-struct CallbackArgument {
- volatile int counter;
- volatile bool threads_stopped;
- volatile bool callback_executed;
- CallbackArgument()
- : counter(0),
- threads_stopped(false),
- callback_executed(false) {}
-};
-
-void *IncrementerThread(void *argument) {
- CallbackArgument *callback_argument = (CallbackArgument *)argument;
- while (true) {
- __sync_fetch_and_add(&callback_argument->counter, 1);
- if (pthread_mutex_trylock(&incrementer_thread_exit_mutex) == 0) {
- pthread_mutex_unlock(&incrementer_thread_exit_mutex);
- return NULL;
- } else {
- sched_yield();
- }
- }
-}
-
-// This callback checks that IncrementerThread is suspended at the time of its
-// execution.
-void Callback(const SuspendedThreadsList &suspended_threads_list,
- void *argument) {
- CallbackArgument *callback_argument = (CallbackArgument *)argument;
- callback_argument->callback_executed = true;
- int counter_at_init = __sync_fetch_and_add(&callback_argument->counter, 0);
- for (uptr i = 0; i < 1000; i++) {
- sched_yield();
- if (__sync_fetch_and_add(&callback_argument->counter, 0) !=
- counter_at_init) {
- callback_argument->threads_stopped = false;
- return;
- }
- }
- callback_argument->threads_stopped = true;
-}
-
-TEST(StopTheWorld, SuspendThreadsSimple) {
- pthread_mutex_init(&incrementer_thread_exit_mutex, NULL);
- CallbackArgument argument;
- pthread_t thread_id;
- int pthread_create_result;
- pthread_mutex_lock(&incrementer_thread_exit_mutex);
- pthread_create_result = pthread_create(&thread_id, NULL, IncrementerThread,
- &argument);
- ASSERT_EQ(0, pthread_create_result);
- StopTheWorld(&Callback, &argument);
- pthread_mutex_unlock(&incrementer_thread_exit_mutex);
- EXPECT_TRUE(argument.callback_executed);
- EXPECT_TRUE(argument.threads_stopped);
- // argument is on stack, so we have to wait for the incrementer thread to
- // terminate before we can return from this function.
- ASSERT_EQ(0, pthread_join(thread_id, NULL));
- pthread_mutex_destroy(&incrementer_thread_exit_mutex);
-}
-
-// A more comprehensive test where we spawn a bunch of threads while executing
-// StopTheWorld in parallel.
-static const uptr kThreadCount = 50;
-static const uptr kStopWorldAfter = 10; // let this many threads spawn first
-
-static pthread_mutex_t advanced_incrementer_thread_exit_mutex;
-
-struct AdvancedCallbackArgument {
- volatile uptr thread_index;
- volatile int counters[kThreadCount];
- pthread_t thread_ids[kThreadCount];
- volatile bool threads_stopped;
- volatile bool callback_executed;
- volatile bool fatal_error;
- AdvancedCallbackArgument()
- : thread_index(0),
- threads_stopped(false),
- callback_executed(false),
- fatal_error(false) {}
-};
-
-void *AdvancedIncrementerThread(void *argument) {
- AdvancedCallbackArgument *callback_argument =
- (AdvancedCallbackArgument *)argument;
- uptr this_thread_index = __sync_fetch_and_add(
- &callback_argument->thread_index, 1);
- // Spawn the next thread.
- int pthread_create_result;
- if (this_thread_index + 1 < kThreadCount) {
- pthread_create_result =
- pthread_create(&callback_argument->thread_ids[this_thread_index + 1],
- NULL, AdvancedIncrementerThread, argument);
- // Cannot use ASSERT_EQ in non-void-returning functions. If there's a
- // problem, defer failing to the main thread.
- if (pthread_create_result != 0) {
- callback_argument->fatal_error = true;
- __sync_fetch_and_add(&callback_argument->thread_index,
- kThreadCount - callback_argument->thread_index);
- }
- }
- // Do the actual work.
- while (true) {
- __sync_fetch_and_add(&callback_argument->counters[this_thread_index], 1);
- if (pthread_mutex_trylock(&advanced_incrementer_thread_exit_mutex) == 0) {
- pthread_mutex_unlock(&advanced_incrementer_thread_exit_mutex);
- return NULL;
- } else {
- sched_yield();
- }
- }
-}
-
-void AdvancedCallback(const SuspendedThreadsList &suspended_threads_list,
- void *argument) {
- AdvancedCallbackArgument *callback_argument =
- (AdvancedCallbackArgument *)argument;
- callback_argument->callback_executed = true;
-
- int counters_at_init[kThreadCount];
- for (uptr j = 0; j < kThreadCount; j++)
- counters_at_init[j] = __sync_fetch_and_add(&callback_argument->counters[j],
- 0);
- for (uptr i = 0; i < 10; i++) {
- sched_yield();
- for (uptr j = 0; j < kThreadCount; j++)
- if (__sync_fetch_and_add(&callback_argument->counters[j], 0) !=
- counters_at_init[j]) {
- callback_argument->threads_stopped = false;
- return;
- }
- }
- callback_argument->threads_stopped = true;
-}
-
-TEST(StopTheWorld, SuspendThreadsAdvanced) {
- pthread_mutex_init(&advanced_incrementer_thread_exit_mutex, NULL);
- AdvancedCallbackArgument argument;
-
- pthread_mutex_lock(&advanced_incrementer_thread_exit_mutex);
- int pthread_create_result;
- pthread_create_result = pthread_create(&argument.thread_ids[0], NULL,
- AdvancedIncrementerThread,
- &argument);
- ASSERT_EQ(0, pthread_create_result);
- // Wait for several threads to spawn before proceeding.
- while (__sync_fetch_and_add(&argument.thread_index, 0) < kStopWorldAfter)
- sched_yield();
- StopTheWorld(&AdvancedCallback, &argument);
- EXPECT_TRUE(argument.callback_executed);
- EXPECT_TRUE(argument.threads_stopped);
-
- // Wait for all threads to spawn before we start terminating them.
- while (__sync_fetch_and_add(&argument.thread_index, 0) < kThreadCount)
- sched_yield();
- ASSERT_FALSE(argument.fatal_error); // a pthread_create has failed
- // Signal the threads to terminate.
- pthread_mutex_unlock(&advanced_incrementer_thread_exit_mutex);
- for (uptr i = 0; i < kThreadCount; i++)
- ASSERT_EQ(0, pthread_join(argument.thread_ids[i], NULL));
- pthread_mutex_destroy(&advanced_incrementer_thread_exit_mutex);
-}
-
-static void SegvCallback(const SuspendedThreadsList &suspended_threads_list,
- void *argument) {
- *(volatile int*)0x1234 = 0;
-}
-
-TEST(StopTheWorld, SegvInCallback) {
- // Test that tracer thread catches SIGSEGV.
- StopTheWorld(&SegvCallback, NULL);
-}
-
-} // namespace __sanitizer
-
-#endif // SANITIZER_LINUX && defined(__x86_64__)
diff --git a/lib/sanitizer_common/tests/sanitizer_stoptheworld_testlib.cc b/lib/sanitizer_common/tests/sanitizer_stoptheworld_testlib.cc
deleted file mode 100644
index d8be2afb19e9c..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_stoptheworld_testlib.cc
+++ /dev/null
@@ -1,53 +0,0 @@
-//===-- sanitizer_stoptheworld_testlib.cc ---------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// Dynamic library to test StopTheWorld functionality.
-// When loaded with LD_PRELOAD, it will periodically suspend all threads.
-//===----------------------------------------------------------------------===//
-/* Usage:
-clang++ -fno-exceptions -g -fPIC -I. \
- sanitizer_common/tests/sanitizer_stoptheworld_testlib.cc \
- sanitizer_common/sanitizer_*.cc -shared -lpthread -o teststoptheworld.so
-LD_PRELOAD=`pwd`/teststoptheworld.so /your/app
-*/
-
-#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_LINUX
-
-#include <dlfcn.h>
-#include <stddef.h>
-#include <stdio.h>
-#include <pthread.h>
-#include <unistd.h>
-
-#include "sanitizer_common/sanitizer_stoptheworld.h"
-
-namespace {
-const uptr kSuspendDuration = 3;
-const uptr kRunDuration = 3;
-
-void Callback(const SuspendedThreadsList &suspended_threads_list,
- void *argument) {
- sleep(kSuspendDuration);
-}
-
-void *SuspenderThread(void *argument) {
- while (true) {
- sleep(kRunDuration);
- StopTheWorld(Callback, NULL);
- }
- return NULL;
-}
-
-__attribute__((constructor)) void StopTheWorldTestLibConstructor(void) {
- pthread_t thread_id;
- pthread_create(&thread_id, NULL, SuspenderThread, NULL);
-}
-} // namespace
-
-#endif // SANITIZER_LINUX
diff --git a/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc b/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc
deleted file mode 100644
index 224ab05383774..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_suppressions_test.cc
+++ /dev/null
@@ -1,135 +0,0 @@
-//===-- sanitizer_suppressions_test.cc ------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_suppressions.h"
-#include "gtest/gtest.h"
-
-#include <string.h>
-
-namespace __sanitizer {
-
-static bool MyMatch(const char *templ, const char *func) {
- char tmp[1024];
- strcpy(tmp, templ); // NOLINT
- return TemplateMatch(tmp, func);
-}
-
-TEST(Suppressions, Match) {
- EXPECT_TRUE(MyMatch("foobar$", "foobar"));
-
- EXPECT_TRUE(MyMatch("foobar", "foobar"));
- EXPECT_TRUE(MyMatch("*foobar*", "foobar"));
- EXPECT_TRUE(MyMatch("foobar", "prefix_foobar_postfix"));
- EXPECT_TRUE(MyMatch("*foobar*", "prefix_foobar_postfix"));
- EXPECT_TRUE(MyMatch("foo*bar", "foo_middle_bar"));
- EXPECT_TRUE(MyMatch("foo*bar", "foobar"));
- EXPECT_TRUE(MyMatch("foo*bar*baz", "foo_middle_bar_another_baz"));
- EXPECT_TRUE(MyMatch("foo*bar*baz", "foo_middle_barbaz"));
- EXPECT_TRUE(MyMatch("^foobar", "foobar"));
- EXPECT_TRUE(MyMatch("^foobar", "foobar_postfix"));
- EXPECT_TRUE(MyMatch("^*foobar", "foobar"));
- EXPECT_TRUE(MyMatch("^*foobar", "prefix_foobar"));
- EXPECT_TRUE(MyMatch("foobar$", "foobar"));
- EXPECT_TRUE(MyMatch("foobar$", "prefix_foobar"));
- EXPECT_TRUE(MyMatch("*foobar*$", "foobar"));
- EXPECT_TRUE(MyMatch("*foobar*$", "foobar_postfix"));
- EXPECT_TRUE(MyMatch("^foobar$", "foobar"));
-
- EXPECT_FALSE(MyMatch("foo", "baz"));
- EXPECT_FALSE(MyMatch("foobarbaz", "foobar"));
- EXPECT_FALSE(MyMatch("foobarbaz", "barbaz"));
- EXPECT_FALSE(MyMatch("foo*bar", "foobaz"));
- EXPECT_FALSE(MyMatch("foo*bar", "foo_baz"));
- EXPECT_FALSE(MyMatch("^foobar", "prefix_foobar"));
- EXPECT_FALSE(MyMatch("foobar$", "foobar_postfix"));
- EXPECT_FALSE(MyMatch("^foobar$", "prefix_foobar"));
- EXPECT_FALSE(MyMatch("^foobar$", "foobar_postfix"));
- EXPECT_FALSE(MyMatch("foo^bar", "foobar"));
- EXPECT_FALSE(MyMatch("foo$bar", "foobar"));
- EXPECT_FALSE(MyMatch("foo$^bar", "foobar"));
-}
-
-static const char *kTestSuppressionTypes[] = {"race", "thread", "mutex",
- "signal"};
-
-class SuppressionContextTest : public ::testing::Test {
- public:
- SuppressionContextTest()
- : ctx_(kTestSuppressionTypes, ARRAY_SIZE(kTestSuppressionTypes)) {}
-
- protected:
- SuppressionContext ctx_;
-
- void CheckSuppressions(unsigned count, std::vector<const char *> types,
- std::vector<const char *> templs) const {
- EXPECT_EQ(count, ctx_.SuppressionCount());
- for (unsigned i = 0; i < count; i++) {
- const Suppression *s = ctx_.SuppressionAt(i);
- EXPECT_STREQ(types[i], s->type);
- EXPECT_STREQ(templs[i], s->templ);
- }
- }
-};
-
-TEST_F(SuppressionContextTest, Parse) {
- ctx_.Parse("race:foo\n"
- " race:bar\n" // NOLINT
- "race:baz \n" // NOLINT
- "# a comment\n"
- "race:quz\n"); // NOLINT
- CheckSuppressions(4, {"race", "race", "race", "race"},
- {"foo", "bar", "baz", "quz"});
-}
-
-TEST_F(SuppressionContextTest, Parse2) {
- ctx_.Parse(
- " # first line comment\n" // NOLINT
- " race:bar \n" // NOLINT
- "race:baz* *baz\n"
- "# a comment\n"
- "# last line comment\n"
- ); // NOLINT
- CheckSuppressions(2, {"race", "race"}, {"bar", "baz* *baz"});
-}
-
-TEST_F(SuppressionContextTest, Parse3) {
- ctx_.Parse(
- "# last suppression w/o line-feed\n"
- "race:foo\n"
- "race:bar\r\n"
- "race:baz"
- ); // NOLINT
- CheckSuppressions(3, {"race", "race", "race"}, {"foo", "bar", "baz"});
-}
-
-TEST_F(SuppressionContextTest, ParseType) {
- ctx_.Parse(
- "race:foo\n"
- "thread:bar\n"
- "mutex:baz\n"
- "signal:quz\n"
- ); // NOLINT
- CheckSuppressions(4, {"race", "thread", "mutex", "signal"},
- {"foo", "bar", "baz", "quz"});
-}
-
-TEST_F(SuppressionContextTest, HasSuppressionType) {
- ctx_.Parse(
- "race:foo\n"
- "thread:bar\n");
- EXPECT_TRUE(ctx_.HasSuppressionType("race"));
- EXPECT_TRUE(ctx_.HasSuppressionType("thread"));
- EXPECT_FALSE(ctx_.HasSuppressionType("mutex"));
- EXPECT_FALSE(ctx_.HasSuppressionType("signal"));
-}
-
-} // namespace __sanitizer
diff --git a/lib/sanitizer_common/tests/sanitizer_symbolizer_test.cc b/lib/sanitizer_common/tests/sanitizer_symbolizer_test.cc
deleted file mode 100644
index 4c4d2a8c3fb20..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_symbolizer_test.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-//===-- sanitizer_symbolizer_test.cc --------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Tests for sanitizer_symbolizer.h and sanitizer_symbolizer_internal.h
-//
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_allocator_internal.h"
-#include "sanitizer_common/sanitizer_symbolizer_internal.h"
-#include "gtest/gtest.h"
-
-namespace __sanitizer {
-
-TEST(Symbolizer, ExtractToken) {
- char *token;
- const char *rest;
-
- rest = ExtractToken("a;b;c", ";", &token);
- EXPECT_STREQ("a", token);
- EXPECT_STREQ("b;c", rest);
- InternalFree(token);
-
- rest = ExtractToken("aaa-bbb.ccc", ";.-*", &token);
- EXPECT_STREQ("aaa", token);
- EXPECT_STREQ("bbb.ccc", rest);
- InternalFree(token);
-}
-
-TEST(Symbolizer, ExtractInt) {
- int token;
- const char *rest = ExtractInt("123,456;789", ";,", &token);
- EXPECT_EQ(123, token);
- EXPECT_STREQ("456;789", rest);
-}
-
-TEST(Symbolizer, ExtractUptr) {
- uptr token;
- const char *rest = ExtractUptr("123,456;789", ";,", &token);
- EXPECT_EQ(123U, token);
- EXPECT_STREQ("456;789", rest);
-}
-
-TEST(Symbolizer, ExtractTokenUpToDelimiter) {
- char *token;
- const char *rest =
- ExtractTokenUpToDelimiter("aaa-+-bbb-+-ccc", "-+-", &token);
- EXPECT_STREQ("aaa", token);
- EXPECT_STREQ("bbb-+-ccc", rest);
- InternalFree(token);
-}
-
-#if !SANITIZER_WINDOWS
-TEST(Symbolizer, DemangleSwiftAndCXX) {
- // Swift names are not demangled in default llvm build because Swift
- // runtime is not linked in.
- EXPECT_STREQ("_TtSd", DemangleSwiftAndCXX("_TtSd"));
- // Check that the rest demangles properly.
- EXPECT_STREQ("f1(char*, int)", DemangleSwiftAndCXX("_Z2f1Pci"));
-#if !SANITIZER_FREEBSD // QoI issue with libcxxrt on FreeBSD
- EXPECT_STREQ("foo", DemangleSwiftAndCXX("foo"));
-#endif
- EXPECT_STREQ("", DemangleSwiftAndCXX(""));
-}
-#endif
-
-} // namespace __sanitizer
diff --git a/lib/sanitizer_common/tests/sanitizer_test_config.h b/lib/sanitizer_common/tests/sanitizer_test_config.h
deleted file mode 100644
index bdf614606d6aa..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_test_config.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===-- sanitizer_test_config.h ---------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of *Sanitizer runtime.
-//
-//===----------------------------------------------------------------------===//
-#if !defined(INCLUDED_FROM_SANITIZER_TEST_UTILS_H)
-# error "This file should be included into sanitizer_test_utils.h only"
-#endif
-
-#ifndef SANITIZER_TEST_CONFIG_H
-#define SANITIZER_TEST_CONFIG_H
-
-#include <vector>
-#include <string>
-#include <map>
-
-#if SANITIZER_USE_DEJAGNU_GTEST
-# include "dejagnu-gtest.h"
-#else
-# include "gtest/gtest.h"
-#endif
-
-#endif // SANITIZER_TEST_CONFIG_H
diff --git a/lib/sanitizer_common/tests/sanitizer_test_main.cc b/lib/sanitizer_common/tests/sanitizer_test_main.cc
deleted file mode 100644
index 0da886120c31a..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_test_main.cc
+++ /dev/null
@@ -1,24 +0,0 @@
-//===-- sanitizer_test_main.cc --------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
-//
-//===----------------------------------------------------------------------===//
-#include "gtest/gtest.h"
-#include "sanitizer_common/sanitizer_flags.h"
-
-const char *argv0;
-
-int main(int argc, char **argv) {
- argv0 = argv[0];
- testing::GTEST_FLAG(death_test_style) = "threadsafe";
- testing::InitGoogleTest(&argc, argv);
- __sanitizer::SetCommonFlagsDefaults();
- return RUN_ALL_TESTS();
-}
diff --git a/lib/sanitizer_common/tests/sanitizer_test_utils.h b/lib/sanitizer_common/tests/sanitizer_test_utils.h
deleted file mode 100644
index 5c1f8ad488647..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_test_utils.h
+++ /dev/null
@@ -1,139 +0,0 @@
-//===-- sanitizer_test_utils.h ----------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of *Sanitizer runtime.
-// Common unit tests utilities.
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef SANITIZER_TEST_UTILS_H
-#define SANITIZER_TEST_UTILS_H
-
-#if defined(_WIN32)
-// <windows.h> should always be the first include on Windows.
-# include <windows.h>
-// MSVS headers define max/min as macros, so std::max/min gets crazy.
-# undef max
-# undef min
-#endif
-
-#if !defined(SANITIZER_EXTERNAL_TEST_CONFIG)
-# define INCLUDED_FROM_SANITIZER_TEST_UTILS_H
-# include "sanitizer_test_config.h"
-# undef INCLUDED_FROM_SANITIZER_TEST_UTILS_H
-#endif
-
-#include <stdint.h>
-
-#if defined(_MSC_VER)
-# define NOINLINE __declspec(noinline)
-#else // defined(_MSC_VER)
-# define NOINLINE __attribute__((noinline))
-#endif // defined(_MSC_VER)
-
-#if !defined(_MSC_VER) || defined(__clang__)
-# define UNUSED __attribute__((unused))
-# define USED __attribute__((used))
-#else
-# define UNUSED
-# define USED
-#endif
-
-#if !defined(__has_feature)
-#define __has_feature(x) 0
-#endif
-
-#ifndef ATTRIBUTE_NO_SANITIZE_ADDRESS
-# if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
-# define ATTRIBUTE_NO_SANITIZE_ADDRESS \
- __attribute__((no_sanitize_address))
-# else
-# define ATTRIBUTE_NO_SANITIZE_ADDRESS
-# endif
-#endif // ATTRIBUTE_NO_SANITIZE_ADDRESS
-
-#if __LP64__ || defined(_WIN64)
-# define SANITIZER_WORDSIZE 64
-#else
-# define SANITIZER_WORDSIZE 32
-#endif
-
-// Make the compiler thinks that something is going on there.
-inline void break_optimization(void *arg) {
-#if !defined(_WIN32) || defined(__clang__)
- __asm__ __volatile__("" : : "r" (arg) : "memory");
-#endif
-}
-
-// This function returns its parameter but in such a way that compiler
-// can not prove it.
-template<class T>
-NOINLINE
-static T Ident(T t) {
- T ret = t;
- break_optimization(&ret);
- return ret;
-}
-
-// Simple stand-alone pseudorandom number generator.
-// Current algorithm is ANSI C linear congruential PRNG.
-static inline uint32_t my_rand_r(uint32_t* state) {
- return (*state = *state * 1103515245 + 12345) >> 16;
-}
-
-static uint32_t global_seed = 0;
-
-static inline uint32_t my_rand() {
- return my_rand_r(&global_seed);
-}
-
-// Set availability of platform-specific functions.
-
-#if !defined(__APPLE__) && !defined(__ANDROID__) && !defined(_WIN32)
-# define SANITIZER_TEST_HAS_POSIX_MEMALIGN 1
-#else
-# define SANITIZER_TEST_HAS_POSIX_MEMALIGN 0
-#endif
-
-#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__ANDROID__) && \
- !defined(__NetBSD__) && !defined(_WIN32)
-# define SANITIZER_TEST_HAS_MEMALIGN 1
-#else
-# define SANITIZER_TEST_HAS_MEMALIGN 0
-#endif
-
-#if !defined(__APPLE__) && !defined(__FreeBSD__) && !defined(__ANDROID__) && \
- !defined(__NetBSD__) && !defined(_WIN32) && \
- !(defined(__sun__) && defined(__svr4__))
-# define SANITIZER_TEST_HAS_PVALLOC 1
-# define SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE 1
-#else
-# define SANITIZER_TEST_HAS_PVALLOC 0
-# define SANITIZER_TEST_HAS_MALLOC_USABLE_SIZE 0
-#endif
-
-#if !defined(__APPLE__)
-# define SANITIZER_TEST_HAS_STRNLEN 1
-#else
-# define SANITIZER_TEST_HAS_STRNLEN 0
-#endif
-
-#if defined(__FreeBSD__) || defined(__NetBSD__)
-# define SANITIZER_TEST_HAS_PRINTF_L 1
-#else
-# define SANITIZER_TEST_HAS_PRINTF_L 0
-#endif
-
-#if !defined(_MSC_VER)
-# define SANITIZER_TEST_HAS_STRNDUP 1
-#else
-# define SANITIZER_TEST_HAS_STRNDUP 0
-#endif
-
-#endif // SANITIZER_TEST_UTILS_H
diff --git a/lib/sanitizer_common/tests/sanitizer_thread_registry_test.cc b/lib/sanitizer_common/tests/sanitizer_thread_registry_test.cc
deleted file mode 100644
index f8b8c12d4ac34..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_thread_registry_test.cc
+++ /dev/null
@@ -1,236 +0,0 @@
-//===-- sanitizer_thread_registry_test.cc ---------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of shared sanitizer runtime.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_thread_registry.h"
-
-#include "sanitizer_pthread_wrappers.h"
-
-#include "gtest/gtest.h"
-
-#include <vector>
-
-namespace __sanitizer {
-
-static BlockingMutex tctx_allocator_lock(LINKER_INITIALIZED);
-static LowLevelAllocator tctx_allocator;
-
-template<typename TCTX>
-static ThreadContextBase *GetThreadContext(u32 tid) {
- BlockingMutexLock l(&tctx_allocator_lock);
- return new(tctx_allocator) TCTX(tid);
-}
-
-static const u32 kMaxRegistryThreads = 1000;
-static const u32 kRegistryQuarantine = 2;
-
-static void CheckThreadQuantity(ThreadRegistry *registry, uptr exp_total,
- uptr exp_running, uptr exp_alive) {
- uptr total, running, alive;
- registry->GetNumberOfThreads(&total, &running, &alive);
- EXPECT_EQ(exp_total, total);
- EXPECT_EQ(exp_running, running);
- EXPECT_EQ(exp_alive, alive);
-}
-
-static bool is_detached(u32 tid) {
- return (tid % 2 == 0);
-}
-
-static uptr get_uid(u32 tid) {
- return tid * 2;
-}
-
-static bool HasName(ThreadContextBase *tctx, void *arg) {
- char *name = (char*)arg;
- return (0 == internal_strcmp(tctx->name, name));
-}
-
-static bool HasUid(ThreadContextBase *tctx, void *arg) {
- uptr uid = (uptr)arg;
- return (tctx->user_id == uid);
-}
-
-static void MarkUidAsPresent(ThreadContextBase *tctx, void *arg) {
- bool *arr = (bool*)arg;
- arr[tctx->tid] = true;
-}
-
-static void TestRegistry(ThreadRegistry *registry, bool has_quarantine) {
- // Create and start a main thread.
- EXPECT_EQ(0U, registry->CreateThread(get_uid(0), true, -1, 0));
- registry->StartThread(0, 0, false, 0);
- // Create a bunch of threads.
- for (u32 i = 1; i <= 10; i++) {
- EXPECT_EQ(i, registry->CreateThread(get_uid(i), is_detached(i), 0, 0));
- }
- CheckThreadQuantity(registry, 11, 1, 11);
- // Start some of them.
- for (u32 i = 1; i <= 5; i++) {
- registry->StartThread(i, 0, false, 0);
- }
- CheckThreadQuantity(registry, 11, 6, 11);
- // Finish, create and start more threads.
- for (u32 i = 1; i <= 5; i++) {
- registry->FinishThread(i);
- if (!is_detached(i))
- registry->JoinThread(i, 0);
- }
- for (u32 i = 6; i <= 10; i++) {
- registry->StartThread(i, 0, false, 0);
- }
- std::vector<u32> new_tids;
- for (u32 i = 11; i <= 15; i++) {
- new_tids.push_back(
- registry->CreateThread(get_uid(i), is_detached(i), 0, 0));
- }
- ASSERT_LE(kRegistryQuarantine, 5U);
- u32 exp_total = 16 - (has_quarantine ? 5 - kRegistryQuarantine : 0);
- CheckThreadQuantity(registry, exp_total, 6, 11);
- // Test SetThreadName and FindThread.
- registry->SetThreadName(6, "six");
- registry->SetThreadName(7, "seven");
- EXPECT_EQ(7U, registry->FindThread(HasName, (void*)"seven"));
- EXPECT_EQ(ThreadRegistry::kUnknownTid,
- registry->FindThread(HasName, (void*)"none"));
- EXPECT_EQ(0U, registry->FindThread(HasUid, (void*)get_uid(0)));
- EXPECT_EQ(10U, registry->FindThread(HasUid, (void*)get_uid(10)));
- EXPECT_EQ(ThreadRegistry::kUnknownTid,
- registry->FindThread(HasUid, (void*)0x1234));
- // Detach and finish and join remaining threads.
- for (u32 i = 6; i <= 10; i++) {
- registry->DetachThread(i, 0);
- registry->FinishThread(i);
- }
- for (u32 i = 0; i < new_tids.size(); i++) {
- u32 tid = new_tids[i];
- registry->StartThread(tid, 0, false, 0);
- registry->DetachThread(tid, 0);
- registry->FinishThread(tid);
- }
- CheckThreadQuantity(registry, exp_total, 1, 1);
- // Test methods that require the caller to hold a ThreadRegistryLock.
- bool has_tid[16];
- internal_memset(&has_tid[0], 0, sizeof(has_tid));
- {
- ThreadRegistryLock l(registry);
- registry->RunCallbackForEachThreadLocked(MarkUidAsPresent, &has_tid[0]);
- }
- for (u32 i = 0; i < exp_total; i++) {
- EXPECT_TRUE(has_tid[i]);
- }
- {
- ThreadRegistryLock l(registry);
- registry->CheckLocked();
- ThreadContextBase *main_thread = registry->GetThreadLocked(0);
- EXPECT_EQ(main_thread, registry->FindThreadContextLocked(
- HasUid, (void*)get_uid(0)));
- }
- EXPECT_EQ(11U, registry->GetMaxAliveThreads());
-}
-
-TEST(SanitizerCommon, ThreadRegistryTest) {
- ThreadRegistry quarantine_registry(GetThreadContext<ThreadContextBase>,
- kMaxRegistryThreads,
- kRegistryQuarantine);
- TestRegistry(&quarantine_registry, true);
-
- ThreadRegistry no_quarantine_registry(GetThreadContext<ThreadContextBase>,
- kMaxRegistryThreads,
- kMaxRegistryThreads);
- TestRegistry(&no_quarantine_registry, false);
-}
-
-static const int kThreadsPerShard = 20;
-static const int kNumShards = 25;
-
-static int num_created[kNumShards + 1];
-static int num_started[kNumShards + 1];
-static int num_joined[kNumShards + 1];
-
-namespace {
-
-struct RunThreadArgs {
- ThreadRegistry *registry;
- uptr shard; // started from 1.
-};
-
-class TestThreadContext : public ThreadContextBase {
- public:
- explicit TestThreadContext(int tid) : ThreadContextBase(tid) {}
- void OnJoined(void *arg) {
- uptr shard = (uptr)arg;
- num_joined[shard]++;
- }
- void OnStarted(void *arg) {
- uptr shard = (uptr)arg;
- num_started[shard]++;
- }
- void OnCreated(void *arg) {
- uptr shard = (uptr)arg;
- num_created[shard]++;
- }
-};
-
-} // namespace
-
-void *RunThread(void *arg) {
- RunThreadArgs *args = static_cast<RunThreadArgs*>(arg);
- std::vector<int> tids;
- for (int i = 0; i < kThreadsPerShard; i++)
- tids.push_back(
- args->registry->CreateThread(0, false, 0, (void*)args->shard));
- for (int i = 0; i < kThreadsPerShard; i++)
- args->registry->StartThread(tids[i], 0, false, (void*)args->shard);
- for (int i = 0; i < kThreadsPerShard; i++)
- args->registry->FinishThread(tids[i]);
- for (int i = 0; i < kThreadsPerShard; i++)
- args->registry->JoinThread(tids[i], (void*)args->shard);
- return 0;
-}
-
-static void ThreadedTestRegistry(ThreadRegistry *registry) {
- // Create and start a main thread.
- EXPECT_EQ(0U, registry->CreateThread(0, true, -1, 0));
- registry->StartThread(0, 0, false, 0);
- pthread_t threads[kNumShards];
- RunThreadArgs args[kNumShards];
- for (int i = 0; i < kNumShards; i++) {
- args[i].registry = registry;
- args[i].shard = i + 1;
- PTHREAD_CREATE(&threads[i], 0, RunThread, &args[i]);
- }
- for (int i = 0; i < kNumShards; i++) {
- PTHREAD_JOIN(threads[i], 0);
- }
- // Check that each thread created/started/joined correct amount
- // of "threads" in thread_registry.
- EXPECT_EQ(1, num_created[0]);
- EXPECT_EQ(1, num_started[0]);
- EXPECT_EQ(0, num_joined[0]);
- for (int i = 1; i <= kNumShards; i++) {
- EXPECT_EQ(kThreadsPerShard, num_created[i]);
- EXPECT_EQ(kThreadsPerShard, num_started[i]);
- EXPECT_EQ(kThreadsPerShard, num_joined[i]);
- }
-}
-
-TEST(SanitizerCommon, ThreadRegistryThreadedTest) {
- memset(&num_created, 0, sizeof(num_created));
- memset(&num_started, 0, sizeof(num_created));
- memset(&num_joined, 0, sizeof(num_created));
-
- ThreadRegistry registry(GetThreadContext<TestThreadContext>,
- kThreadsPerShard * kNumShards + 1, 10);
- ThreadedTestRegistry(&registry);
-}
-
-} // namespace __sanitizer
diff --git a/lib/sanitizer_common/tests/sanitizer_type_traits_test.cc b/lib/sanitizer_common/tests/sanitizer_type_traits_test.cc
deleted file mode 100644
index 0dce02fac1700..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_type_traits_test.cc
+++ /dev/null
@@ -1,28 +0,0 @@
-//===-- sanitizer_type_traits_test.cc -------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer/AddressSanitizer runtime.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_type_traits.h"
-#include "gtest/gtest.h"
-#include "sanitizer_common/sanitizer_internal_defs.h"
-
-using namespace __sanitizer;
-
-TEST(SanitizerCommon, IsSame) {
- ASSERT_TRUE((is_same<unsigned, unsigned>::value));
- ASSERT_TRUE((is_same<uptr, uptr>::value));
- ASSERT_TRUE((is_same<sptr, sptr>::value));
- ASSERT_TRUE((is_same<const uptr, const uptr>::value));
-
- ASSERT_FALSE((is_same<unsigned, signed>::value));
- ASSERT_FALSE((is_same<uptr, sptr>::value));
- ASSERT_FALSE((is_same<uptr, const uptr>::value));
-}
diff --git a/lib/sanitizer_common/tests/sanitizer_vector_test.cc b/lib/sanitizer_common/tests/sanitizer_vector_test.cc
deleted file mode 100644
index 59fbf39685bdf..0000000000000
--- a/lib/sanitizer_common/tests/sanitizer_vector_test.cc
+++ /dev/null
@@ -1,51 +0,0 @@
-//===-- sanitizer_vector_test.cc ------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of *Sanitizer runtime.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_vector.h"
-#include "gtest/gtest.h"
-
-namespace __sanitizer {
-
-TEST(Vector, Basic) {
- Vector<int> v;
- EXPECT_EQ(v.Size(), 0u);
- v.PushBack(42);
- EXPECT_EQ(v.Size(), 1u);
- EXPECT_EQ(v[0], 42);
- v.PushBack(43);
- EXPECT_EQ(v.Size(), 2u);
- EXPECT_EQ(v[0], 42);
- EXPECT_EQ(v[1], 43);
-}
-
-TEST(Vector, Stride) {
- Vector<int> v;
- for (int i = 0; i < 1000; i++) {
- v.PushBack(i);
- EXPECT_EQ(v.Size(), i + 1u);
- EXPECT_EQ(v[i], i);
- }
- for (int i = 0; i < 1000; i++) {
- EXPECT_EQ(v[i], i);
- }
-}
-
-TEST(Vector, ResizeReduction) {
- Vector<int> v;
- v.PushBack(0);
- v.PushBack(0);
- EXPECT_EQ(v.Size(), 2u);
- v.Resize(1);
- EXPECT_EQ(v.Size(), 1u);
-}
-
-} // namespace __sanitizer
diff --git a/lib/sanitizer_common/tests/standalone_malloc_test.cc b/lib/sanitizer_common/tests/standalone_malloc_test.cc
deleted file mode 100644
index 9e6f7c93b04b2..0000000000000
--- a/lib/sanitizer_common/tests/standalone_malloc_test.cc
+++ /dev/null
@@ -1,87 +0,0 @@
-#include <stdio.h>
-#include <vector>
-#include <pthread.h>
-#include <malloc.h>
-#include <algorithm>
-
-using namespace std;
-
-const size_t kNumThreds = 16;
-const size_t kNumIters = 1 << 23;
-
-inline void break_optimization(void *arg) {
- __asm__ __volatile__("" : : "r" (arg) : "memory");
-}
-
-__attribute__((noinline))
-static void *MallocThread(void *t) {
- size_t total_malloced = 0, total_freed = 0;
- size_t max_in_use = 0;
- size_t tid = reinterpret_cast<size_t>(t);
- vector<pair<char *, size_t> > allocated;
- allocated.reserve(kNumIters);
- for (size_t i = 1; i < kNumIters; i++) {
- if ((i % (kNumIters / 4)) == 0 && tid == 0)
- fprintf(stderr, " T[%ld] iter %ld\n", tid, i);
- bool allocate = (i % 5) <= 2; // 60% malloc, 40% free
- if (i > kNumIters / 4)
- allocate = i % 2; // then switch to 50% malloc, 50% free
- if (allocate) {
- size_t size = 1 + (i % 200);
- if ((i % 10001) == 0)
- size *= 4096;
- total_malloced += size;
- char *x = new char[size];
- x[0] = x[size - 1] = x[size / 2] = 0;
- allocated.push_back(make_pair(x, size));
- max_in_use = max(max_in_use, total_malloced - total_freed);
- } else {
- if (allocated.empty()) continue;
- size_t slot = i % allocated.size();
- char *p = allocated[slot].first;
- p[0] = 0; // emulate last user touch of the block
- size_t size = allocated[slot].second;
- total_freed += size;
- swap(allocated[slot], allocated.back());
- allocated.pop_back();
- delete [] p;
- }
- }
- if (tid == 0)
- fprintf(stderr, " T[%ld] total_malloced: %ldM in use %ldM max %ldM\n",
- tid, total_malloced >> 20, (total_malloced - total_freed) >> 20,
- max_in_use >> 20);
- for (size_t i = 0; i < allocated.size(); i++)
- delete [] allocated[i].first;
- return 0;
-}
-
-template <int depth>
-struct DeepStack {
- __attribute__((noinline))
- static void *run(void *t) {
- break_optimization(0);
- DeepStack<depth - 1>::run(t);
- break_optimization(0);
- return 0;
- }
-};
-
-template<>
-struct DeepStack<0> {
- static void *run(void *t) {
- MallocThread(t);
- return 0;
- }
-};
-
-// Build with -Dstandalone_malloc_test=main to make it a separate program.
-int standalone_malloc_test() {
- pthread_t t[kNumThreds];
- for (size_t i = 0; i < kNumThreds; i++)
- pthread_create(&t[i], 0, DeepStack<200>::run, reinterpret_cast<void *>(i));
- for (size_t i = 0; i < kNumThreds; i++)
- pthread_join(t[i], 0);
- malloc_stats();
- return 0;
-}
diff --git a/lib/scudo/CMakeLists.txt b/lib/scudo/CMakeLists.txt
deleted file mode 100644
index 79f69e934f223..0000000000000
--- a/lib/scudo/CMakeLists.txt
+++ /dev/null
@@ -1,142 +0,0 @@
-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_MINIMAL_DYNAMIC_LIBS ${SANITIZER_COMMON_LINK_LIBS})
-append_list_if(COMPILER_RT_HAS_LIBDL dl SCUDO_MINIMAL_DYNAMIC_LIBS)
-append_list_if(COMPILER_RT_HAS_LIBRT rt SCUDO_MINIMAL_DYNAMIC_LIBS)
-append_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread SCUDO_MINIMAL_DYNAMIC_LIBS)
-append_list_if(COMPILER_RT_HAS_LIBLOG log SCUDO_MINIMAL_DYNAMIC_LIBS)
-
-set(SCUDO_DYNAMIC_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS})
-# Use gc-sections by default to avoid unused code being pulled in.
-list(APPEND SCUDO_DYNAMIC_LINK_FLAGS -Wl,--gc-sections)
-
-if(ANDROID)
-# Put most Sanitizer shared libraries in the global group. For more details, see
-# android-changes-for-ndk-developers.md#changes-to-library-search-order
- if (COMPILER_RT_HAS_Z_GLOBAL)
- list(APPEND SCUDO_DYNAMIC_LINK_FLAGS -Wl,-z,global)
- endif()
-endif()
-
-# The minimal Scudo runtime does not inlude the UBSan runtime.
-set(SCUDO_MINIMAL_OBJECT_LIBS
- RTSanitizerCommonNoTermination
- RTSanitizerCommonLibc
- RTInterception)
-set(SCUDO_OBJECT_LIBS ${SCUDO_MINIMAL_OBJECT_LIBS})
-set(SCUDO_DYNAMIC_LIBS ${SCUDO_MINIMAL_DYNAMIC_LIBS})
-
-if (FUCHSIA)
- list(APPEND SCUDO_CFLAGS -nostdinc++)
- list(APPEND SCUDO_DYNAMIC_LINK_FLAGS -nostdlib++)
-else()
- list(APPEND SCUDO_DYNAMIC_LIBS ${SANITIZER_CXX_ABI_LIBRARY})
- list(APPEND SCUDO_OBJECT_LIBS
- RTSanitizerCommonCoverage
- RTSanitizerCommonSymbolizer
- RTUbsan)
-endif()
-
-set(SCUDO_SOURCES
- scudo_allocator.cpp
- scudo_crc32.cpp
- scudo_errors.cpp
- scudo_flags.cpp
- scudo_malloc.cpp
- scudo_termination.cpp
- scudo_tsd_exclusive.cpp
- scudo_tsd_shared.cpp
- scudo_utils.cpp)
-
-set(SCUDO_CXX_SOURCES
- scudo_new_delete.cpp)
-
-set(SCUDO_HEADERS
- scudo_allocator.h
- scudo_allocator_combined.h
- scudo_allocator_secondary.h
- scudo_crc32.h
- scudo_errors.h
- scudo_flags.h
- scudo_flags.inc
- scudo_interface_internal.h
- scudo_platform.h
- scudo_tsd.h
- scudo_tsd_exclusive.inc
- scudo_tsd_shared.inc
- scudo_utils.h)
-
-# Enable the SSE 4.2 instruction set for scudo_crc32.cpp, if available.
-if (COMPILER_RT_HAS_MSSE4_2_FLAG)
- set_source_files_properties(scudo_crc32.cpp PROPERTIES COMPILE_FLAGS -msse4.2)
-endif()
-
-# Enable the AArch64 CRC32 feature for scudo_crc32.cpp, if available.
-# Note that it is enabled by default starting with armv8.1-a.
-if (COMPILER_RT_HAS_MCRC_FLAG)
- set_source_files_properties(scudo_crc32.cpp PROPERTIES COMPILE_FLAGS -mcrc)
-endif()
-
-if(COMPILER_RT_HAS_SCUDO)
- add_compiler_rt_runtime(clang_rt.scudo_minimal
- STATIC
- ARCHS ${SCUDO_SUPPORTED_ARCH}
- SOURCES ${SCUDO_SOURCES}
- ADDITIONAL_HEADERS ${SCUDO_HEADERS}
- OBJECT_LIBS ${SCUDO_MINIMAL_OBJECT_LIBS}
- CFLAGS ${SCUDO_CFLAGS}
- PARENT_TARGET scudo)
- add_compiler_rt_runtime(clang_rt.scudo_cxx_minimal
- STATIC
- ARCHS ${SCUDO_SUPPORTED_ARCH}
- SOURCES ${SCUDO_CXX_SOURCES}
- ADDITIONAL_HEADERS ${SCUDO_HEADERS}
- CFLAGS ${SCUDO_CFLAGS}
- PARENT_TARGET scudo)
-
- add_compiler_rt_runtime(clang_rt.scudo
- STATIC
- ARCHS ${SCUDO_SUPPORTED_ARCH}
- SOURCES ${SCUDO_SOURCES}
- ADDITIONAL_HEADERS ${SCUDO_HEADERS}
- OBJECT_LIBS ${SCUDO_OBJECT_LIBS}
- CFLAGS ${SCUDO_CFLAGS}
- PARENT_TARGET scudo)
- add_compiler_rt_runtime(clang_rt.scudo_cxx
- STATIC
- ARCHS ${SCUDO_SUPPORTED_ARCH}
- SOURCES ${SCUDO_CXX_SOURCES}
- ADDITIONAL_HEADERS ${SCUDO_HEADERS}
- OBJECT_LIBS RTUbsan_cxx
- CFLAGS ${SCUDO_CFLAGS}
- PARENT_TARGET scudo)
-
- add_compiler_rt_runtime(clang_rt.scudo_minimal
- SHARED
- ARCHS ${SCUDO_SUPPORTED_ARCH}
- SOURCES ${SCUDO_SOURCES} ${SCUDO_CXX_SOURCES}
- ADDITIONAL_HEADERS ${SCUDO_HEADERS}
- OBJECT_LIBS ${SCUDO_MINIMAL_OBJECT_LIBS}
- CFLAGS ${SCUDO_CFLAGS}
- LINK_FLAGS ${SCUDO_DYNAMIC_LINK_FLAGS}
- LINK_LIBS ${SCUDO_MINIMAL_DYNAMIC_LIBS}
- PARENT_TARGET scudo)
-
- add_compiler_rt_runtime(clang_rt.scudo
- SHARED
- ARCHS ${SCUDO_SUPPORTED_ARCH}
- SOURCES ${SCUDO_SOURCES} ${SCUDO_CXX_SOURCES}
- ADDITIONAL_HEADERS ${SCUDO_HEADERS}
- OBJECT_LIBS ${SCUDO_OBJECT_LIBS}
- CFLAGS ${SCUDO_CFLAGS}
- LINK_FLAGS ${SCUDO_DYNAMIC_LINK_FLAGS}
- LINK_LIBS ${SCUDO_DYNAMIC_LIBS}
- PARENT_TARGET scudo)
-endif()
diff --git a/lib/stats/CMakeLists.txt b/lib/stats/CMakeLists.txt
deleted file mode 100644
index 23c80843195d2..0000000000000
--- a/lib/stats/CMakeLists.txt
+++ /dev/null
@@ -1,45 +0,0 @@
-set(STATS_HEADERS
- stats.h)
-
-include_directories(..)
-
-add_custom_target(stats)
-set_target_properties(stats PROPERTIES FOLDER "Compiler-RT Misc")
-
-if(APPLE)
- set(STATS_LIB_FLAVOR SHARED)
-
- set(STATS_LINK_LIBS ${SANITIZER_COMMON_LINK_LIBS})
-
- 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_LINK_FLAGS)
-endif()
-
-add_compiler_rt_runtime(clang_rt.stats
- ${STATS_LIB_FLAVOR}
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- OS ${SANITIZER_COMMON_SUPPORTED_OS}
- SOURCES stats.cc
- ADDITIONAL_HEADERS ${STATS_HEADERS}
- OBJECT_LIBS RTSanitizerCommon
- RTSanitizerCommonLibc
- RTSanitizerCommonSymbolizer
- CFLAGS ${SANITIZER_COMMON_CFLAGS}
- LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS}
- LINK_LIBS ${STATS_LINK_LIBS}
- PARENT_TARGET stats)
-
-add_compiler_rt_runtime(clang_rt.stats_client
- STATIC
- ARCHS ${SANITIZER_COMMON_SUPPORTED_ARCH}
- OS ${SANITIZER_COMMON_SUPPORTED_OS}
- SOURCES stats_client.cc
- ADDITIONAL_HEADERS ${STATS_HEADERS}
- CFLAGS ${SANITIZER_COMMON_CFLAGS}
- LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
- PARENT_TARGET stats)
diff --git a/lib/tsan/.clang-format b/lib/tsan/.clang-format
deleted file mode 100644
index 560308c91deec..0000000000000
--- a/lib/tsan/.clang-format
+++ /dev/null
@@ -1,2 +0,0 @@
-BasedOnStyle: Google
-AllowShortIfStatementsOnASingleLine: false
diff --git a/lib/tsan/CMakeLists.txt b/lib/tsan/CMakeLists.txt
deleted file mode 100644
index e1da319ccc872..0000000000000
--- a/lib/tsan/CMakeLists.txt
+++ /dev/null
@@ -1,258 +0,0 @@
-# Build for the ThreadSanitizer runtime support library.
-
-include_directories(..)
-
-set(TSAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})
-# SANITIZER_COMMON_CFLAGS contains -fPIC, but it's performance-critical for
-# TSan runtime to be built with -fPIE to reduce the number of register spills.
-# On FreeBSD however it provokes linkage issue thus we disable it.
-if(NOT CMAKE_SYSTEM MATCHES "FreeBSD")
- append_list_if(COMPILER_RT_HAS_FPIE_FLAG -fPIE TSAN_CFLAGS)
-endif()
-append_rtti_flag(OFF TSAN_CFLAGS)
-
-if(COMPILER_RT_TSAN_DEBUG_OUTPUT)
- # Add extra debug information to TSan runtime. This configuration is rarely
- # used, but we need to support it so that debug output will not bitrot.
- list(APPEND TSAN_CFLAGS -DTSAN_COLLECT_STATS=1
- -DTSAN_DEBUG_OUTPUT=2)
-endif()
-
-set(TSAN_RTL_CFLAGS ${TSAN_CFLAGS})
-append_list_if(COMPILER_RT_HAS_MSSE3_FLAG -msse3 TSAN_RTL_CFLAGS)
-append_list_if(SANITIZER_LIMIT_FRAME_SIZE -Wframe-larger-than=530
- TSAN_RTL_CFLAGS)
-append_list_if(COMPILER_RT_HAS_WGLOBAL_CONSTRUCTORS_FLAG -Wglobal-constructors
- TSAN_RTL_CFLAGS)
-
-set(TSAN_SOURCES
- rtl/tsan_clock.cc
- rtl/tsan_debugging.cc
- rtl/tsan_external.cc
- rtl/tsan_fd.cc
- rtl/tsan_flags.cc
- rtl/tsan_ignoreset.cc
- rtl/tsan_interceptors.cc
- rtl/tsan_interface.cc
- rtl/tsan_interface_ann.cc
- rtl/tsan_interface_atomic.cc
- rtl/tsan_interface_java.cc
- rtl/tsan_malloc_mac.cc
- rtl/tsan_md5.cc
- rtl/tsan_mman.cc
- rtl/tsan_mutex.cc
- rtl/tsan_mutexset.cc
- rtl/tsan_preinit.cc
- rtl/tsan_report.cc
- rtl/tsan_rtl.cc
- rtl/tsan_rtl_mutex.cc
- rtl/tsan_rtl_proc.cc
- rtl/tsan_rtl_report.cc
- rtl/tsan_rtl_thread.cc
- rtl/tsan_stack_trace.cc
- rtl/tsan_stat.cc
- rtl/tsan_suppressions.cc
- rtl/tsan_symbolize.cc
- rtl/tsan_sync.cc)
-
-set(TSAN_CXX_SOURCES
- rtl/tsan_new_delete.cc)
-
-if(APPLE)
- list(APPEND TSAN_SOURCES
- rtl/tsan_interceptors_mac.cc
- rtl/tsan_libdispatch_mac.cc
- rtl/tsan_platform_mac.cc
- rtl/tsan_platform_posix.cc)
-elseif(UNIX)
- # Assume Linux
- list(APPEND TSAN_SOURCES
- rtl/tsan_platform_linux.cc
- rtl/tsan_platform_posix.cc)
-endif()
-
-set(TSAN_HEADERS
- rtl/tsan_clock.h
- rtl/tsan_defs.h
- rtl/tsan_dense_alloc.h
- rtl/tsan_fd.h
- rtl/tsan_flags.h
- rtl/tsan_flags.inc
- rtl/tsan_ignoreset.h
- rtl/tsan_interceptors.h
- rtl/tsan_interface.h
- rtl/tsan_interface_ann.h
- rtl/tsan_interface_inl.h
- rtl/tsan_interface_java.h
- rtl/tsan_mman.h
- rtl/tsan_mutex.h
- rtl/tsan_mutexset.h
- rtl/tsan_platform.h
- rtl/tsan_ppc_regs.h
- rtl/tsan_report.h
- rtl/tsan_rtl.h
- rtl/tsan_stack_trace.h
- rtl/tsan_stat.h
- rtl/tsan_suppressions.h
- rtl/tsan_symbolize.h
- rtl/tsan_sync.h
- rtl/tsan_trace.h
- rtl/tsan_update_shadow_word_inl.h)
-
-set(TSAN_RUNTIME_LIBRARIES)
-add_compiler_rt_component(tsan)
-
-if(APPLE)
- add_asm_sources(TSAN_ASM_SOURCES rtl/tsan_rtl_amd64.S rtl/tsan_rtl_aarch64.S)
-
- set(TSAN_LINK_LIBS ${SANITIZER_COMMON_LINK_LIBS})
-
- 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
- OS ${TSAN_SUPPORTED_OS}
- ARCHS ${TSAN_SUPPORTED_ARCH}
- SOURCES ${TSAN_SOURCES} ${TSAN_CXX_SOURCES} ${TSAN_ASM_SOURCES}
- ADDITIONAL_HEADERS ${TSAN_HEADERS}
- OBJECT_LIBS RTInterception
- RTSanitizerCommon
- RTSanitizerCommonLibc
- RTSanitizerCommonCoverage
- RTSanitizerCommonSymbolizer
- RTUbsan
- CFLAGS ${TSAN_RTL_CFLAGS}
- LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS}
- LINK_LIBS ${TSAN_LINK_LIBS} objc
- PARENT_TARGET tsan)
- add_compiler_rt_object_libraries(RTTsan_dynamic
- OS ${TSAN_SUPPORTED_OS}
- ARCHS ${TSAN_SUPPORTED_ARCH}
- SOURCES ${TSAN_SOURCES} ${TSAN_CXX_SOURCES} ${TSAN_ASM_SOURCES}
- ADDITIONAL_HEADERS ${TSAN_HEADERS}
- CFLAGS ${TSAN_RTL_CFLAGS})
-
- # Build and check Go runtime.
- set(BUILDGO_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/go/buildgo.sh)
- add_custom_target(GotsanRuntimeCheck
- COMMAND env "CC=${CMAKE_C_COMPILER} ${OSX_SYSROOT_FLAG}"
- IN_TMPDIR=1 SILENT=1 ${BUILDGO_SCRIPT}
- DEPENDS tsan ${BUILDGO_SCRIPT}
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/go
- COMMENT "Checking TSan Go runtime..."
- VERBATIM)
- set_target_properties(GotsanRuntimeCheck PROPERTIES FOLDER "Compiler-RT Misc")
-else()
- foreach(arch ${TSAN_SUPPORTED_ARCH})
- if(arch STREQUAL "x86_64")
- add_asm_sources(TSAN_ASM_SOURCES rtl/tsan_rtl_amd64.S)
- # Sanity check for Go runtime.
- set(BUILDGO_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/go/buildgo.sh)
- add_custom_target(GotsanRuntimeCheck
- COMMAND env "CC=${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}"
- IN_TMPDIR=1 SILENT=1 ${BUILDGO_SCRIPT}
- DEPENDS clang_rt.tsan-${arch} ${BUILDGO_SCRIPT}
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/go
- COMMENT "Checking TSan Go runtime..."
- VERBATIM)
- elseif(arch STREQUAL "aarch64")
- add_asm_sources(TSAN_ASM_SOURCES rtl/tsan_rtl_aarch64.S)
- # Sanity check for Go runtime.
- set(BUILDGO_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/go/buildgo.sh)
- add_custom_target(GotsanRuntimeCheck
- COMMAND env "CC=${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}"
- IN_TMPDIR=1 SILENT=1 ${BUILDGO_SCRIPT}
- DEPENDS clang_rt.tsan-${arch} ${BUILDGO_SCRIPT}
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/go
- COMMENT "Checking TSan Go runtime..."
- VERBATIM)
- elseif(arch MATCHES "powerpc64|powerpc64le")
- add_asm_sources(TSAN_ASM_SOURCES rtl/tsan_rtl_ppc64.S)
- # Sanity check for Go runtime.
- set(BUILDGO_SCRIPT ${CMAKE_CURRENT_SOURCE_DIR}/go/buildgo.sh)
- add_custom_target(GotsanRuntimeCheck
- COMMAND env "CC=${CMAKE_C_COMPILER} ${CMAKE_C_COMPILER_ARG1}"
- IN_TMPDIR=1 SILENT=1 ${BUILDGO_SCRIPT}
- DEPENDS clang_rt.tsan-${arch} ${BUILDGO_SCRIPT}
- WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}/go
- COMMENT "Checking TSan Go runtime..."
- VERBATIM)
- elseif(arch MATCHES "mips64|mips64le")
- add_asm_sources(TSAN_ASM_SOURCES rtl/tsan_rtl_mips64.S)
- else()
- set(TSAN_ASM_SOURCES)
- endif()
- add_compiler_rt_runtime(clang_rt.tsan
- STATIC
- ARCHS ${arch}
- SOURCES ${TSAN_SOURCES} ${TSAN_ASM_SOURCES}
- $<TARGET_OBJECTS:RTInterception.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonCoverage.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
- $<TARGET_OBJECTS:RTUbsan.${arch}>
- ADDITIONAL_HEADERS ${TSAN_HEADERS}
- CFLAGS ${TSAN_RTL_CFLAGS}
- PARENT_TARGET tsan)
- add_compiler_rt_runtime(clang_rt.tsan_cxx
- STATIC
- ARCHS ${arch}
- SOURCES ${TSAN_CXX_SOURCES}
- $<TARGET_OBJECTS:RTUbsan_cxx.${arch}>
- ADDITIONAL_HEADERS ${TSAN_HEADERS}
- CFLAGS ${TSAN_RTL_CFLAGS}
- PARENT_TARGET tsan)
- list(APPEND TSAN_RUNTIME_LIBRARIES clang_rt.tsan-${arch}
- clang_rt.tsan_cxx-${arch})
- add_sanitizer_rt_symbols(clang_rt.tsan
- ARCHS ${arch}
- EXTRA rtl/tsan.syms.extra)
- add_sanitizer_rt_symbols(clang_rt.tsan_cxx
- ARCHS ${arch}
- EXTRA rtl/tsan.syms.extra)
- add_dependencies(tsan clang_rt.tsan-${arch}
- clang_rt.tsan_cxx-${arch}
- clang_rt.tsan-${arch}-symbols
- clang_rt.tsan_cxx-${arch}-symbols)
- endforeach()
-endif()
-
-# Make sure that non-platform-specific files don't include any system headers.
-# FreeBSD/NetBSD do not install a number of Clang-provided headers for the
-# compiler in the base system due to incompatibilities between FreeBSD/NetBSD's
-# and Clang's versions. As a workaround do not use --sysroot=. on FreeBSD/NetBSD
-# until this is addressed.
-if(COMPILER_RT_HAS_SYSROOT_FLAG AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD"
- AND NOT CMAKE_SYSTEM_NAME MATCHES "NetBSD")
- file(GLOB _tsan_generic_sources rtl/tsan*)
- file(GLOB _tsan_platform_sources rtl/tsan*posix* rtl/tsan*mac*
- rtl/tsan*linux*)
- list(REMOVE_ITEM _tsan_generic_sources ${_tsan_platform_sources})
- set_source_files_properties(${_tsan_generic_sources}
- PROPERTIES COMPILE_FLAGS "--sysroot=.")
-endif()
-
-# Build libcxx instrumented with TSan.
-if(COMPILER_RT_LIBCXX_PATH AND
- COMPILER_RT_TEST_COMPILER_ID STREQUAL "Clang" AND
- NOT ANDROID)
- set(libcxx_tsan_deps)
- foreach(arch ${TSAN_SUPPORTED_ARCH})
- get_target_flags_for_arch(${arch} TARGET_CFLAGS)
- set(LIBCXX_PREFIX ${CMAKE_CURRENT_BINARY_DIR}/libcxx_tsan_${arch})
- add_custom_libcxx(libcxx_tsan_${arch} ${LIBCXX_PREFIX}
- DEPS ${TSAN_RUNTIME_LIBRARIES}
- CFLAGS ${TARGET_CFLAGS} -fsanitize=thread
- USE_TOOLCHAIN)
- list(APPEND libcxx_tsan_deps libcxx_tsan_${arch}-build)
- endforeach()
-
- add_custom_target(libcxx_tsan DEPENDS ${libcxx_tsan_deps})
- set_target_properties(libcxx_tsan PROPERTIES FOLDER "Compiler-RT Misc")
-endif()
-
-if(COMPILER_RT_INCLUDE_TESTS)
- add_subdirectory(tests)
-endif()
diff --git a/lib/tsan/analyze_libtsan.sh b/lib/tsan/analyze_libtsan.sh
deleted file mode 100755
index ae29f1b5b05a1..0000000000000
--- a/lib/tsan/analyze_libtsan.sh
+++ /dev/null
@@ -1,54 +0,0 @@
-#!/bin/bash
-#
-# Script that prints information about generated code in TSan runtime.
-
-set -e
-set -u
-
-if [[ "$#" != 1 ]]; then
- echo "Usage: $0 /path/to/binary/built/with/tsan"
- exit 1
-fi
-
-get_asm() {
- grep __tsan_$1.: -A 10000 ${OBJDUMP_CONTENTS} | \
- awk "/[^:]$/ {print;} />:/ {c++; if (c == 2) {exit}}"
-}
-
-list="write1 \
- write2 \
- write4 \
- write8 \
- read1 \
- read2 \
- read4 \
- read8 \
- func_entry \
- func_exit"
-
-BIN=$1
-OUTPUT_DIR=$(mktemp -t -d analyze_libtsan_out.XXXXXXXX)
-OBJDUMP_CONTENTS=${OUTPUT_DIR}/libtsan_objdump
-NM_CONTENTS=${OUTPUT_DIR}/libtsan_nm
-
-objdump -d $BIN > ${OBJDUMP_CONTENTS}
-nm -S $BIN | grep "__tsan_" > ${NM_CONTENTS}
-
-for f in $list; do
- file=${OUTPUT_DIR}/asm_$f.s
- get_asm $f > $file
- tot=$(wc -l < $file)
- size=$(grep __tsan_$f$ ${NM_CONTENTS} | awk --non-decimal-data '{print ("0x"$2)+0}')
- rsp=$(grep '(%rsp)' $file | wc -l)
- push=$(grep 'push' $file | wc -l)
- pop=$(grep 'pop' $file | wc -l)
- call=$(grep 'call' $file | wc -l)
- load=$(egrep 'mov .*\,.*\(.*\)|cmp .*\,.*\(.*\)' $file | wc -l)
- store=$(egrep 'mov .*\(.*\),' $file | wc -l)
- mov=$(grep 'mov' $file | wc -l)
- lea=$(grep 'lea' $file | wc -l)
- sh=$(grep 'shr\|shl' $file | wc -l)
- cmp=$(grep 'cmp\|test' $file | wc -l)
- printf "%10s tot %3d; size %4d; rsp %d; push %d; pop %d; call %d; load %2d; store %2d; sh %3d; mov %3d; lea %3d; cmp %3d\n" \
- $f $tot $size $rsp $push $pop $call $load $store $sh $mov $lea $cmp;
-done
diff --git a/lib/tsan/check_analyze.sh b/lib/tsan/check_analyze.sh
deleted file mode 100755
index 65c34d466da3f..0000000000000
--- a/lib/tsan/check_analyze.sh
+++ /dev/null
@@ -1,56 +0,0 @@
-#!/bin/bash
-#
-# Script that checks that critical functions in TSan runtime have correct number
-# of push/pop/rsp instructions to verify that runtime is efficient enough.
-#
-# This test can fail when backend code generation changes the output for various
-# tsan interceptors. When such a change happens, you can ensure that the
-# performance has not regressed by running the following benchmarks before and
-# after the breaking change to verify that the values in this file are safe to
-# update:
-# ./projects/compiler-rt/lib/tsan/tests/rtl/TsanRtlTest-x86_64-Test
-# --gtest_also_run_disabled_tests --gtest_filter=DISABLED_BENCH.Mop*
-
-set -u
-
-if [[ "$#" != 1 ]]; then
- echo "Usage: $0 /path/to/binary/built/with/tsan"
- exit 1
-fi
-
-SCRIPTDIR=$(dirname $0)
-RES=$(${SCRIPTDIR}/analyze_libtsan.sh $1)
-PrintRes() {
- printf "%s\n" "$RES"
-}
-
-PrintRes
-
-check() {
- res=$(PrintRes | egrep "$1 .* $2 $3; ")
- if [ "$res" == "" ]; then
- echo FAILED $1 must contain $2 $3
- exit 1
- fi
-}
-
-for f in write1 write2 write4 write8 read2 read4; do
- check $f rsp 1
- check $f push 1
- check $f pop 6
-done
-
-for f in read1 read8; do
- check $f rsp 1
- check $f push 2
- check $f pop 12
-done
-
-for f in func_entry func_exit; do
- check $f rsp 0
- check $f push 0
- check $f pop 0
- check $f call 1 # TraceSwitch()
-done
-
-echo LGTM
diff --git a/lib/tsan/check_cmake.sh b/lib/tsan/check_cmake.sh
deleted file mode 100755
index 7668c5b49e1a7..0000000000000
--- a/lib/tsan/check_cmake.sh
+++ /dev/null
@@ -1,18 +0,0 @@
-#!/bin/bash
-set -u
-set -e
-
-ROOT="$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )"
-if [ -d "$ROOT/llvm-build" ]; then
- cd $ROOT/llvm-build
-else
- mkdir -p $ROOT/llvm-build
- cd $ROOT/llvm-build
- CC=clang CXX=clang++ cmake -G Ninja -DLLVM_ENABLE_WERROR=ON -DCMAKE_BUILD_TYPE=Release -DLLVM_ENABLE_ASSERTIONS=ON $ROOT/../../../..
-fi
-ninja
-ninja check-sanitizer
-ninja check-tsan
-ninja check-asan
-ninja check-msan
-ninja check-lsan
diff --git a/lib/tsan/dd/CMakeLists.txt b/lib/tsan/dd/CMakeLists.txt
deleted file mode 100644
index f2b8a6d173a42..0000000000000
--- a/lib/tsan/dd/CMakeLists.txt
+++ /dev/null
@@ -1,52 +0,0 @@
-# Build for the experimental deadlock detector runtime library.
-
-include_directories(../..)
-
-set(DD_CFLAGS ${SANITIZER_COMMON_CFLAGS})
-append_rtti_flag(OFF DD_CFLAGS)
-
-set(DD_SOURCES
- dd_rtl.cc
- dd_interceptors.cc
-)
-
-set(DD_LINKLIBS ${SANITIZER_CXX_ABI_LIBRARY} ${SANITIZER_COMMON_LINK_LIBS})
-
-append_list_if(COMPILER_RT_HAS_LIBDL dl DD_LINKLIBS)
-append_list_if(COMPILER_RT_HAS_LIBRT rt DD_LINKLIBS)
-append_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread DD_LINKLIBS)
-
-add_custom_target(dd)
-set_target_properties(dd PROPERTIES FOLDER "Compiler-RT Misc")
-
-# Deadlock detector is currently supported on 64-bit Linux only.
-if(CAN_TARGET_x86_64 AND UNIX AND NOT APPLE AND NOT ANDROID)
- set(arch "x86_64")
- add_compiler_rt_runtime(clang_rt.dd
- STATIC
- ARCHS ${arch}
- SOURCES ${DD_SOURCES}
- $<TARGET_OBJECTS:RTInterception.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
- CFLAGS ${DD_CFLAGS}
- PARENT_TARGET dd)
-
- add_compiler_rt_object_libraries(RTDD
- ARCHS ${arch}
- SOURCES ${DD_SOURCES} CFLAGS ${DD_CFLAGS})
-
- add_compiler_rt_runtime(clang_rt.dyndd
- SHARED
- ARCHS ${arch}
- SOURCES $<TARGET_OBJECTS:RTDD.${arch}>
- $<TARGET_OBJECTS:RTInterception.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.${arch}>
- LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS}
- LINK_LIBS ${DD_LINKLIBS}
- PARENT_TARGET dd)
-endif()
-
-add_dependencies(compiler-rt dd)
diff --git a/lib/tsan/go/build.bat b/lib/tsan/go/build.bat
deleted file mode 100644
index 3a64a2413b979..0000000000000
--- a/lib/tsan/go/build.bat
+++ /dev/null
@@ -1,4 +0,0 @@
-type tsan_go.cc ..\rtl\tsan_interface_atomic.cc ..\rtl\tsan_clock.cc ..\rtl\tsan_flags.cc ..\rtl\tsan_md5.cc ..\rtl\tsan_mutex.cc ..\rtl\tsan_report.cc ..\rtl\tsan_rtl.cc ..\rtl\tsan_rtl_mutex.cc ..\rtl\tsan_rtl_report.cc ..\rtl\tsan_rtl_thread.cc ..\rtl\tsan_rtl_proc.cc ..\rtl\tsan_stat.cc ..\rtl\tsan_suppressions.cc ..\rtl\tsan_sync.cc ..\rtl\tsan_stack_trace.cc ..\..\sanitizer_common\sanitizer_allocator.cc ..\..\sanitizer_common\sanitizer_common.cc ..\..\sanitizer_common\sanitizer_flags.cc ..\..\sanitizer_common\sanitizer_stacktrace.cc ..\..\sanitizer_common\sanitizer_libc.cc ..\..\sanitizer_common\sanitizer_printf.cc ..\..\sanitizer_common\sanitizer_suppressions.cc ..\..\sanitizer_common\sanitizer_thread_registry.cc ..\rtl\tsan_platform_windows.cc ..\..\sanitizer_common\sanitizer_win.cc ..\..\sanitizer_common\sanitizer_deadlock_detector1.cc ..\..\sanitizer_common\sanitizer_stackdepot.cc ..\..\sanitizer_common\sanitizer_persistent_allocator.cc ..\..\sanitizer_common\sanitizer_flag_parser.cc ..\..\sanitizer_common\sanitizer_symbolizer.cc ..\..\sanitizer_common\sanitizer_termination.cc > gotsan.cc
-
-gcc -c -o race_windows_amd64.syso gotsan.cc -I..\rtl -I..\.. -I..\..\sanitizer_common -I..\..\..\include -m64 -Wall -fno-exceptions -fno-rtti -DSANITIZER_GO=1 -Wno-error=attributes -Wno-attributes -Wno-format -Wno-maybe-uninitialized -DSANITIZER_DEBUG=0 -O3 -fomit-frame-pointer -std=c++11
-
diff --git a/lib/tsan/go/buildgo.sh b/lib/tsan/go/buildgo.sh
deleted file mode 100755
index eec4cf15e5aac..0000000000000
--- a/lib/tsan/go/buildgo.sh
+++ /dev/null
@@ -1,173 +0,0 @@
-#!/bin/sh
-
-set -e
-
-SRCS="
- tsan_go.cc
- ../rtl/tsan_clock.cc
- ../rtl/tsan_external.cc
- ../rtl/tsan_flags.cc
- ../rtl/tsan_interface_atomic.cc
- ../rtl/tsan_md5.cc
- ../rtl/tsan_mutex.cc
- ../rtl/tsan_report.cc
- ../rtl/tsan_rtl.cc
- ../rtl/tsan_rtl_mutex.cc
- ../rtl/tsan_rtl_report.cc
- ../rtl/tsan_rtl_thread.cc
- ../rtl/tsan_rtl_proc.cc
- ../rtl/tsan_stack_trace.cc
- ../rtl/tsan_stat.cc
- ../rtl/tsan_suppressions.cc
- ../rtl/tsan_sync.cc
- ../../sanitizer_common/sanitizer_allocator.cc
- ../../sanitizer_common/sanitizer_common.cc
- ../../sanitizer_common/sanitizer_common_libcdep.cc
- ../../sanitizer_common/sanitizer_deadlock_detector2.cc
- ../../sanitizer_common/sanitizer_file.cc
- ../../sanitizer_common/sanitizer_flag_parser.cc
- ../../sanitizer_common/sanitizer_flags.cc
- ../../sanitizer_common/sanitizer_libc.cc
- ../../sanitizer_common/sanitizer_persistent_allocator.cc
- ../../sanitizer_common/sanitizer_printf.cc
- ../../sanitizer_common/sanitizer_suppressions.cc
- ../../sanitizer_common/sanitizer_thread_registry.cc
- ../../sanitizer_common/sanitizer_stackdepot.cc
- ../../sanitizer_common/sanitizer_stacktrace.cc
- ../../sanitizer_common/sanitizer_symbolizer.cc
- ../../sanitizer_common/sanitizer_symbolizer_report.cc
- ../../sanitizer_common/sanitizer_termination.cc
-"
-
-if [ "`uname -a | grep Linux`" != "" ]; then
- OSCFLAGS="-fPIC -Wno-maybe-uninitialized"
- OSLDFLAGS="-lpthread -fPIC -fpie"
- SRCS="
- $SRCS
- ../rtl/tsan_platform_linux.cc
- ../../sanitizer_common/sanitizer_posix.cc
- ../../sanitizer_common/sanitizer_posix_libcdep.cc
- ../../sanitizer_common/sanitizer_procmaps_common.cc
- ../../sanitizer_common/sanitizer_procmaps_linux.cc
- ../../sanitizer_common/sanitizer_linux.cc
- ../../sanitizer_common/sanitizer_linux_libcdep.cc
- ../../sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
- "
- if [ "`uname -a | grep ppc64le`" != "" ]; then
- SUFFIX="linux_ppc64le"
- ARCHCFLAGS="-m64"
- elif [ "`uname -a | grep x86_64`" != "" ]; then
- SUFFIX="linux_amd64"
- ARCHCFLAGS="-m64"
- OSCFLAGS="$OSCFLAGS -ffreestanding -Wno-unused-const-variable -Werror -Wno-unknown-warning-option"
- elif [ "`uname -a | grep aarch64`" != "" ]; then
- SUFFIX="linux_arm64"
- ARCHCFLAGS=""
- fi
-elif [ "`uname -a | grep FreeBSD`" != "" ]; then
- SUFFIX="freebsd_amd64"
- OSCFLAGS="-fno-strict-aliasing -fPIC -Werror"
- ARCHCFLAGS="-m64"
- OSLDFLAGS="-lpthread -fPIC -fpie"
- SRCS="
- $SRCS
- ../rtl/tsan_platform_linux.cc
- ../../sanitizer_common/sanitizer_posix.cc
- ../../sanitizer_common/sanitizer_posix_libcdep.cc
- ../../sanitizer_common/sanitizer_procmaps_bsd.cc
- ../../sanitizer_common/sanitizer_procmaps_common.cc
- ../../sanitizer_common/sanitizer_linux.cc
- ../../sanitizer_common/sanitizer_linux_libcdep.cc
- ../../sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
- "
-elif [ "`uname -a | grep NetBSD`" != "" ]; then
- SUFFIX="netbsd_amd64"
- OSCFLAGS="-fno-strict-aliasing -fPIC -Werror"
- ARCHCFLAGS="-m64"
- OSLDFLAGS="-lpthread -fPIC -fpie"
- SRCS="
- $SRCS
- ../rtl/tsan_platform_linux.cc
- ../../sanitizer_common/sanitizer_posix.cc
- ../../sanitizer_common/sanitizer_posix_libcdep.cc
- ../../sanitizer_common/sanitizer_procmaps_bsd.cc
- ../../sanitizer_common/sanitizer_procmaps_common.cc
- ../../sanitizer_common/sanitizer_linux.cc
- ../../sanitizer_common/sanitizer_linux_libcdep.cc
- ../../sanitizer_common/sanitizer_netbsd.cc
- ../../sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
- "
-elif [ "`uname -a | grep Darwin`" != "" ]; then
- SUFFIX="darwin_amd64"
- OSCFLAGS="-fPIC -Wno-unused-const-variable -Wno-unknown-warning-option -mmacosx-version-min=10.7"
- ARCHCFLAGS="-m64"
- OSLDFLAGS="-lpthread -fPIC -fpie -mmacosx-version-min=10.7"
- SRCS="
- $SRCS
- ../rtl/tsan_platform_mac.cc
- ../../sanitizer_common/sanitizer_mac.cc
- ../../sanitizer_common/sanitizer_posix.cc
- ../../sanitizer_common/sanitizer_posix_libcdep.cc
- ../../sanitizer_common/sanitizer_procmaps_mac.cc
- "
-elif [ "`uname -a | grep MINGW`" != "" ]; then
- SUFFIX="windows_amd64"
- OSCFLAGS="-Wno-error=attributes -Wno-attributes -Wno-unused-const-variable -Wno-unknown-warning-option"
- ARCHCFLAGS="-m64"
- OSLDFLAGS=""
- SRCS="
- $SRCS
- ../rtl/tsan_platform_windows.cc
- ../../sanitizer_common/sanitizer_win.cc
- "
-else
- echo Unknown platform
- exit 1
-fi
-
-CC=${CC:-gcc}
-IN_TMPDIR=${IN_TMPDIR:-0}
-SILENT=${SILENT:-0}
-
-if [ $IN_TMPDIR != "0" ]; then
- DIR=$(mktemp -qd /tmp/gotsan.XXXXXXXXXX)
- cleanup() {
- rm -rf $DIR
- }
- trap cleanup EXIT
-else
- DIR=.
-fi
-
-SRCS="$SRCS $ADD_SRCS"
-
-rm -f $DIR/gotsan.cc
-for F in $SRCS; do
- cat $F >> $DIR/gotsan.cc
-done
-
-FLAGS=" -I../rtl -I../.. -I../../sanitizer_common -I../../../include -std=c++11 -Wall -fno-exceptions -fno-rtti -DSANITIZER_GO=1 -DSANITIZER_DEADLOCK_DETECTOR_VERSION=2 $OSCFLAGS $ARCHCFLAGS"
-if [ "$DEBUG" = "" ]; then
- FLAGS="$FLAGS -DSANITIZER_DEBUG=0 -O3 -fomit-frame-pointer"
- if [ "$SUFFIX" = "linux_ppc64le" ]; then
- FLAGS="$FLAGS -mcpu=power8 -fno-function-sections"
- elif [ "$SUFFIX" = "linux_amd64" ]; then
- FLAGS="$FLAGS -msse3"
- fi
-else
- FLAGS="$FLAGS -DSANITIZER_DEBUG=1 -g"
-fi
-
-if [ "$SILENT" != "1" ]; then
- echo $CC gotsan.cc -c -o $DIR/race_$SUFFIX.syso $FLAGS $CFLAGS
-fi
-$CC $DIR/gotsan.cc -c -o $DIR/race_$SUFFIX.syso $FLAGS $CFLAGS
-
-$CC $OSCFLAGS $ARCHCFLAGS test.c $DIR/race_$SUFFIX.syso -g -o $DIR/test $OSLDFLAGS $LDFLAGS
-
-export GORACE="exitcode=0 atexit_sleep_ms=0"
-if [ "$SILENT" != "1" ]; then
- $DIR/test
-else
- $DIR/test 2>/dev/null
-fi
diff --git a/lib/tsan/tests/CMakeLists.txt b/lib/tsan/tests/CMakeLists.txt
deleted file mode 100644
index 352319f101092..0000000000000
--- a/lib/tsan/tests/CMakeLists.txt
+++ /dev/null
@@ -1,72 +0,0 @@
-include_directories(../rtl)
-
-add_custom_target(TsanUnitTests)
-set_target_properties(TsanUnitTests PROPERTIES
- FOLDER "Compiler-RT Tests")
-
-set(TSAN_UNITTEST_CFLAGS
- ${TSAN_CFLAGS}
- ${COMPILER_RT_UNITTEST_CFLAGS}
- ${COMPILER_RT_GTEST_CFLAGS}
- -I${COMPILER_RT_SOURCE_DIR}/include
- -I${COMPILER_RT_SOURCE_DIR}/lib
- -I${COMPILER_RT_SOURCE_DIR}/lib/tsan/rtl
- -DGTEST_HAS_RTTI=0)
-
-set(TSAN_TEST_ARCH ${TSAN_SUPPORTED_ARCH})
-if(APPLE)
-
- # Create a static library for test dependencies.
- set(TSAN_TEST_RUNTIME_OBJECTS
- $<TARGET_OBJECTS:RTTsan_dynamic.osx>
- $<TARGET_OBJECTS:RTInterception.osx>
- $<TARGET_OBJECTS:RTSanitizerCommon.osx>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.osx>
- $<TARGET_OBJECTS:RTSanitizerCommonCoverage.osx>
- $<TARGET_OBJECTS:RTSanitizerCommonSymbolizer.osx>
- $<TARGET_OBJECTS:RTUbsan.osx>)
- set(TSAN_TEST_RUNTIME RTTsanTest)
- add_library(${TSAN_TEST_RUNTIME} STATIC ${TSAN_TEST_RUNTIME_OBJECTS})
- set_target_properties(${TSAN_TEST_RUNTIME} PROPERTIES
- ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
-
- darwin_filter_host_archs(TSAN_SUPPORTED_ARCH TSAN_TEST_ARCH)
- list(APPEND TSAN_UNITTEST_CFLAGS ${DARWIN_osx_CFLAGS})
-
- set(LINK_FLAGS "-lc++")
- list(APPEND LINK_FLAGS ${DARWIN_osx_LINK_FLAGS})
- add_weak_symbols("ubsan" LINK_FLAGS)
- add_weak_symbols("sanitizer_common" LINK_FLAGS)
-else()
- set(LINK_FLAGS "-fsanitize=thread;-lstdc++;-lm")
-endif()
-
-set(TSAN_RTL_HEADERS)
-foreach (header ${TSAN_HEADERS})
- list(APPEND TSAN_RTL_HEADERS ${CMAKE_CURRENT_SOURCE_DIR}/../${header})
-endforeach()
-
-# add_tsan_unittest(<name>
-# SOURCES <sources list>
-# HEADERS <extra headers list>)
-macro(add_tsan_unittest testname)
- cmake_parse_arguments(TEST "" "" "SOURCES;HEADERS" ${ARGN})
- if(UNIX)
- foreach(arch ${TSAN_TEST_ARCH})
- set(TsanUnitTestsObjects)
- generate_compiler_rt_tests(TsanUnitTestsObjects TsanUnitTests
- "${testname}-${arch}-Test" ${arch}
- SOURCES ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE}
- RUNTIME ${TSAN_TEST_RUNTIME}
- COMPILE_DEPS ${TEST_HEADERS} ${TSAN_RTL_HEADERS}
- DEPS gtest tsan
- CFLAGS ${TSAN_UNITTEST_CFLAGS}
- LINK_FLAGS ${LINK_FLAGS})
- endforeach()
- endif()
-endmacro()
-
-if(COMPILER_RT_CAN_EXECUTE_TESTS AND NOT ANDROID)
- add_subdirectory(rtl)
- add_subdirectory(unit)
-endif()
diff --git a/lib/tsan/tests/rtl/CMakeLists.txt b/lib/tsan/tests/rtl/CMakeLists.txt
deleted file mode 100644
index a34f08ea965b8..0000000000000
--- a/lib/tsan/tests/rtl/CMakeLists.txt
+++ /dev/null
@@ -1,19 +0,0 @@
-set(TSAN_RTL_TEST_SOURCES
- tsan_bench.cc
- tsan_mop.cc
- tsan_mutex.cc
- tsan_posix.cc
- tsan_string.cc
- tsan_test.cc
- tsan_thread.cc)
-
-if(UNIX)
- list(APPEND TSAN_RTL_TEST_SOURCES tsan_test_util_posix.cc)
-endif()
-
-set(TSAN_RTL_TEST_HEADERS
- tsan_test_util.h)
-
-add_tsan_unittest(TsanRtlTest
- SOURCES ${TSAN_RTL_TEST_SOURCES}
- HEADERS ${TSAN_RTL_TEST_HEADERS})
diff --git a/lib/tsan/tests/rtl/tsan_bench.cc b/lib/tsan/tests/rtl/tsan_bench.cc
deleted file mode 100644
index a3cf22f2c6262..0000000000000
--- a/lib/tsan/tests/rtl/tsan_bench.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-//===-- tsan_bench.cc -----------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "tsan_test_util.h"
-#include "tsan_interface.h"
-#include "tsan_defs.h"
-#include "gtest/gtest.h"
-#include <stdint.h>
-
-const int kSize = 128;
-const int kRepeat = 2*1024*1024;
-
-void noinstr(void *p) {}
-
-template<typename T, void(*__tsan_mop)(void *p)>
-static void Benchmark() {
- volatile T data[kSize];
- for (int i = 0; i < kRepeat; i++) {
- for (int j = 0; j < kSize; j++) {
- __tsan_mop((void*)&data[j]);
- data[j]++;
- }
- }
-}
-
-TEST(DISABLED_BENCH, Mop1) {
- Benchmark<uint8_t, noinstr>();
-}
-
-TEST(DISABLED_BENCH, Mop1Read) {
- Benchmark<uint8_t, __tsan_read1>();
-}
-
-TEST(DISABLED_BENCH, Mop1Write) {
- Benchmark<uint8_t, __tsan_write1>();
-}
-
-TEST(DISABLED_BENCH, Mop2) {
- Benchmark<uint16_t, noinstr>();
-}
-
-TEST(DISABLED_BENCH, Mop2Read) {
- Benchmark<uint16_t, __tsan_read2>();
-}
-
-TEST(DISABLED_BENCH, Mop2Write) {
- Benchmark<uint16_t, __tsan_write2>();
-}
-
-TEST(DISABLED_BENCH, Mop4) {
- Benchmark<uint32_t, noinstr>();
-}
-
-TEST(DISABLED_BENCH, Mop4Read) {
- Benchmark<uint32_t, __tsan_read4>();
-}
-
-TEST(DISABLED_BENCH, Mop4Write) {
- Benchmark<uint32_t, __tsan_write4>();
-}
-
-TEST(DISABLED_BENCH, Mop8) {
- Benchmark<uint8_t, noinstr>();
-}
-
-TEST(DISABLED_BENCH, Mop8Read) {
- Benchmark<uint64_t, __tsan_read8>();
-}
-
-TEST(DISABLED_BENCH, Mop8Write) {
- Benchmark<uint64_t, __tsan_write8>();
-}
-
-TEST(DISABLED_BENCH, FuncCall) {
- for (int i = 0; i < kRepeat; i++) {
- for (int j = 0; j < kSize; j++)
- __tsan_func_entry((void*)(uintptr_t)j);
- for (int j = 0; j < kSize; j++)
- __tsan_func_exit();
- }
-}
-
-TEST(DISABLED_BENCH, MutexLocal) {
- Mutex m;
- ScopedThread().Create(m);
- for (int i = 0; i < 50; i++) {
- ScopedThread t;
- t.Lock(m);
- t.Unlock(m);
- }
- for (int i = 0; i < 16*1024*1024; i++) {
- m.Lock();
- m.Unlock();
- }
- ScopedThread().Destroy(m);
-}
diff --git a/lib/tsan/tests/rtl/tsan_mop.cc b/lib/tsan/tests/rtl/tsan_mop.cc
deleted file mode 100644
index f217428250509..0000000000000
--- a/lib/tsan/tests/rtl/tsan_mop.cc
+++ /dev/null
@@ -1,233 +0,0 @@
-//===-- tsan_mop.cc -------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "tsan_interface.h"
-#include "tsan_test_util.h"
-#include "gtest/gtest.h"
-#include <stddef.h>
-#include <stdint.h>
-
-TEST(ThreadSanitizer, SimpleWrite) {
- ScopedThread t;
- MemLoc l;
- t.Write1(l);
-}
-
-TEST(ThreadSanitizer, SimpleWriteWrite) {
- ScopedThread t1, t2;
- MemLoc l1, l2;
- t1.Write1(l1);
- t2.Write1(l2);
-}
-
-TEST(ThreadSanitizer, WriteWriteRace) {
- ScopedThread t1, t2;
- MemLoc l;
- t1.Write1(l);
- t2.Write1(l, true);
-}
-
-TEST(ThreadSanitizer, ReadWriteRace) {
- ScopedThread t1, t2;
- MemLoc l;
- t1.Read1(l);
- t2.Write1(l, true);
-}
-
-TEST(ThreadSanitizer, WriteReadRace) {
- ScopedThread t1, t2;
- MemLoc l;
- t1.Write1(l);
- t2.Read1(l, true);
-}
-
-TEST(ThreadSanitizer, ReadReadNoRace) {
- ScopedThread t1, t2;
- MemLoc l;
- t1.Read1(l);
- t2.Read1(l);
-}
-
-TEST(ThreadSanitizer, WriteThenRead) {
- MemLoc l;
- ScopedThread t1, t2;
- t1.Write1(l);
- t1.Read1(l);
- t2.Read1(l, true);
-}
-
-TEST(ThreadSanitizer, WriteThenLockedRead) {
- Mutex m(Mutex::RW);
- MainThread t0;
- t0.Create(m);
- MemLoc l;
- {
- ScopedThread t1, t2;
-
- t1.Write8(l);
-
- t1.Lock(m);
- t1.Read8(l);
- t1.Unlock(m);
-
- t2.Read8(l, true);
- }
- t0.Destroy(m);
-}
-
-TEST(ThreadSanitizer, LockedWriteThenRead) {
- Mutex m(Mutex::RW);
- MainThread t0;
- t0.Create(m);
- MemLoc l;
- {
- ScopedThread t1, t2;
-
- t1.Lock(m);
- t1.Write8(l);
- t1.Unlock(m);
-
- t1.Read8(l);
-
- t2.Read8(l, true);
- }
- t0.Destroy(m);
-}
-
-
-TEST(ThreadSanitizer, RaceWithOffset) {
- ScopedThread t1, t2;
- {
- MemLoc l;
- t1.Access(l.loc(), true, 8, false);
- t2.Access((char*)l.loc() + 4, true, 4, true);
- }
- {
- MemLoc l;
- t1.Access(l.loc(), true, 8, false);
- t2.Access((char*)l.loc() + 7, true, 1, true);
- }
- {
- MemLoc l;
- t1.Access((char*)l.loc() + 4, true, 4, false);
- t2.Access((char*)l.loc() + 4, true, 2, true);
- }
- {
- MemLoc l;
- t1.Access((char*)l.loc() + 4, true, 4, false);
- t2.Access((char*)l.loc() + 6, true, 2, true);
- }
- {
- MemLoc l;
- t1.Access((char*)l.loc() + 3, true, 2, false);
- t2.Access((char*)l.loc() + 4, true, 1, true);
- }
- {
- MemLoc l;
- t1.Access((char*)l.loc() + 1, true, 8, false);
- t2.Access((char*)l.loc() + 3, true, 1, true);
- }
-}
-
-TEST(ThreadSanitizer, RaceWithOffset2) {
- ScopedThread t1, t2;
- {
- MemLoc l;
- t1.Access((char*)l.loc(), true, 4, false);
- t2.Access((char*)l.loc() + 2, true, 1, true);
- }
- {
- MemLoc l;
- t1.Access((char*)l.loc() + 2, true, 1, false);
- t2.Access((char*)l.loc(), true, 4, true);
- }
-}
-
-TEST(ThreadSanitizer, NoRaceWithOffset) {
- ScopedThread t1, t2;
- {
- MemLoc l;
- t1.Access(l.loc(), true, 4, false);
- t2.Access((char*)l.loc() + 4, true, 4, false);
- }
- {
- MemLoc l;
- t1.Access((char*)l.loc() + 3, true, 2, false);
- t2.Access((char*)l.loc() + 1, true, 2, false);
- t2.Access((char*)l.loc() + 5, true, 2, false);
- }
-}
-
-TEST(ThreadSanitizer, RaceWithDeadThread) {
- MemLoc l;
- ScopedThread t;
- ScopedThread().Write1(l);
- t.Write1(l, true);
-}
-
-TEST(ThreadSanitizer, BenignRaceOnVptr) {
- void *vptr_storage;
- MemLoc vptr(&vptr_storage), val;
- vptr_storage = val.loc();
- ScopedThread t1, t2;
- t1.VptrUpdate(vptr, val);
- t2.Read8(vptr);
-}
-
-TEST(ThreadSanitizer, HarmfulRaceOnVptr) {
- void *vptr_storage;
- MemLoc vptr(&vptr_storage), val1, val2;
- vptr_storage = val1.loc();
- ScopedThread t1, t2;
- t1.VptrUpdate(vptr, val2);
- t2.Read8(vptr, true);
-}
-
-static void foo() {
- volatile int x = 42;
- int x2 = x;
- (void)x2;
-}
-
-static void bar() {
- volatile int x = 43;
- int x2 = x;
- (void)x2;
-}
-
-TEST(ThreadSanitizer, ReportDeadThread) {
- MemLoc l;
- ScopedThread t1;
- {
- ScopedThread t2;
- t2.Call(&foo);
- t2.Call(&bar);
- t2.Write1(l);
- }
- t1.Write1(l, true);
-}
-
-struct ClassWithStatic {
- static int Data[4];
-};
-
-int ClassWithStatic::Data[4];
-
-static void foobarbaz() {}
-
-TEST(ThreadSanitizer, ReportRace) {
- ScopedThread t1;
- MainThread().Access(&ClassWithStatic::Data, true, 4, false);
- t1.Call(&foobarbaz);
- t1.Access(&ClassWithStatic::Data, true, 2, true);
- t1.Return();
-}
diff --git a/lib/tsan/tests/rtl/tsan_mutex.cc b/lib/tsan/tests/rtl/tsan_mutex.cc
deleted file mode 100644
index 4d9c779618187..0000000000000
--- a/lib/tsan/tests/rtl/tsan_mutex.cc
+++ /dev/null
@@ -1,221 +0,0 @@
-//===-- tsan_mutex.cc -----------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_atomic.h"
-#include "tsan_interface.h"
-#include "tsan_interface_ann.h"
-#include "tsan_test_util.h"
-#include "gtest/gtest.h"
-#include <stdint.h>
-
-namespace __tsan {
-
-TEST(ThreadSanitizer, BasicMutex) {
- ScopedThread t;
- Mutex m;
- t.Create(m);
-
- t.Lock(m);
- t.Unlock(m);
-
- CHECK(t.TryLock(m));
- t.Unlock(m);
-
- t.Lock(m);
- CHECK(!t.TryLock(m));
- t.Unlock(m);
-
- t.Destroy(m);
-}
-
-TEST(ThreadSanitizer, BasicSpinMutex) {
- ScopedThread t;
- Mutex m(Mutex::Spin);
- t.Create(m);
-
- t.Lock(m);
- t.Unlock(m);
-
- CHECK(t.TryLock(m));
- t.Unlock(m);
-
- t.Lock(m);
- CHECK(!t.TryLock(m));
- t.Unlock(m);
-
- t.Destroy(m);
-}
-
-TEST(ThreadSanitizer, BasicRwMutex) {
- ScopedThread t;
- Mutex m(Mutex::RW);
- t.Create(m);
-
- t.Lock(m);
- t.Unlock(m);
-
- CHECK(t.TryLock(m));
- t.Unlock(m);
-
- t.Lock(m);
- CHECK(!t.TryLock(m));
- t.Unlock(m);
-
- t.ReadLock(m);
- t.ReadUnlock(m);
-
- CHECK(t.TryReadLock(m));
- t.ReadUnlock(m);
-
- t.Lock(m);
- CHECK(!t.TryReadLock(m));
- t.Unlock(m);
-
- t.ReadLock(m);
- CHECK(!t.TryLock(m));
- t.ReadUnlock(m);
-
- t.ReadLock(m);
- CHECK(t.TryReadLock(m));
- t.ReadUnlock(m);
- t.ReadUnlock(m);
-
- t.Destroy(m);
-}
-
-TEST(ThreadSanitizer, Mutex) {
- Mutex m;
- MainThread t0;
- t0.Create(m);
-
- ScopedThread t1, t2;
- MemLoc l;
- t1.Lock(m);
- t1.Write1(l);
- t1.Unlock(m);
- t2.Lock(m);
- t2.Write1(l);
- t2.Unlock(m);
- t2.Destroy(m);
-}
-
-TEST(ThreadSanitizer, SpinMutex) {
- Mutex m(Mutex::Spin);
- MainThread t0;
- t0.Create(m);
-
- ScopedThread t1, t2;
- MemLoc l;
- t1.Lock(m);
- t1.Write1(l);
- t1.Unlock(m);
- t2.Lock(m);
- t2.Write1(l);
- t2.Unlock(m);
- t2.Destroy(m);
-}
-
-TEST(ThreadSanitizer, RwMutex) {
- Mutex m(Mutex::RW);
- MainThread t0;
- t0.Create(m);
-
- ScopedThread t1, t2, t3;
- MemLoc l;
- t1.Lock(m);
- t1.Write1(l);
- t1.Unlock(m);
- t2.Lock(m);
- t2.Write1(l);
- t2.Unlock(m);
- t1.ReadLock(m);
- t3.ReadLock(m);
- t1.Read1(l);
- t3.Read1(l);
- t1.ReadUnlock(m);
- t3.ReadUnlock(m);
- t2.Lock(m);
- t2.Write1(l);
- t2.Unlock(m);
- t2.Destroy(m);
-}
-
-TEST(ThreadSanitizer, StaticMutex) {
- // Emulates statically initialized mutex.
- Mutex m;
- m.StaticInit();
- {
- ScopedThread t1, t2;
- t1.Lock(m);
- t1.Unlock(m);
- t2.Lock(m);
- t2.Unlock(m);
- }
- MainThread().Destroy(m);
-}
-
-static void *singleton_thread(void *param) {
- atomic_uintptr_t *singleton = (atomic_uintptr_t *)param;
- for (int i = 0; i < 4*1024*1024; i++) {
- int *val = (int *)atomic_load(singleton, memory_order_acquire);
- __tsan_acquire(singleton);
- __tsan_read4(val);
- CHECK_EQ(*val, 42);
- }
- return 0;
-}
-
-TEST(DISABLED_BENCH_ThreadSanitizer, Singleton) {
- const int kClockSize = 100;
- const int kThreadCount = 8;
-
- // Puff off thread's clock.
- for (int i = 0; i < kClockSize; i++) {
- ScopedThread t1;
- (void)t1;
- }
- // Create the singleton.
- int val = 42;
- __tsan_write4(&val);
- atomic_uintptr_t singleton;
- __tsan_release(&singleton);
- atomic_store(&singleton, (uintptr_t)&val, memory_order_release);
- // Create reader threads.
- pthread_t threads[kThreadCount];
- for (int t = 0; t < kThreadCount; t++)
- pthread_create(&threads[t], 0, singleton_thread, &singleton);
- for (int t = 0; t < kThreadCount; t++)
- pthread_join(threads[t], 0);
-}
-
-TEST(DISABLED_BENCH_ThreadSanitizer, StopFlag) {
- const int kClockSize = 100;
- const int kIters = 16*1024*1024;
-
- // Puff off thread's clock.
- for (int i = 0; i < kClockSize; i++) {
- ScopedThread t1;
- (void)t1;
- }
- // Create the stop flag.
- atomic_uintptr_t flag;
- __tsan_release(&flag);
- atomic_store(&flag, 0, memory_order_release);
- // Read it a lot.
- for (int i = 0; i < kIters; i++) {
- uptr v = atomic_load(&flag, memory_order_acquire);
- __tsan_acquire(&flag);
- CHECK_EQ(v, 0);
- }
-}
-
-} // namespace __tsan
diff --git a/lib/tsan/tests/rtl/tsan_posix.cc b/lib/tsan/tests/rtl/tsan_posix.cc
deleted file mode 100644
index e66dab609c620..0000000000000
--- a/lib/tsan/tests/rtl/tsan_posix.cc
+++ /dev/null
@@ -1,155 +0,0 @@
-//===-- tsan_posix.cc -----------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "tsan_interface.h"
-#include "tsan_posix_util.h"
-#include "tsan_test_util.h"
-#include "gtest/gtest.h"
-#include <pthread.h>
-
-struct thread_key {
- pthread_key_t key;
- pthread_mutex_t *mtx;
- int val;
- int *cnt;
- thread_key(pthread_key_t key, pthread_mutex_t *mtx, int val, int *cnt)
- : key(key)
- , mtx(mtx)
- , val(val)
- , cnt(cnt) {
- }
-};
-
-static void thread_secific_dtor(void *v) {
- thread_key *k = (thread_key *)v;
- EXPECT_EQ(__interceptor_pthread_mutex_lock(k->mtx), 0);
- (*k->cnt)++;
- __tsan_write4(&k->cnt);
- EXPECT_EQ(__interceptor_pthread_mutex_unlock(k->mtx), 0);
- if (k->val == 42) {
- // Okay.
- } else if (k->val == 43 || k->val == 44) {
- k->val--;
- EXPECT_EQ(pthread_setspecific(k->key, k), 0);
- } else {
- ASSERT_TRUE(false);
- }
-}
-
-static void *dtors_thread(void *p) {
- thread_key *k = (thread_key *)p;
- EXPECT_EQ(pthread_setspecific(k->key, k), 0);
- return 0;
-}
-
-TEST(Posix, ThreadSpecificDtors) {
- int cnt = 0;
- pthread_key_t key;
- EXPECT_EQ(pthread_key_create(&key, thread_secific_dtor), 0);
- pthread_mutex_t mtx;
- EXPECT_EQ(__interceptor_pthread_mutex_init(&mtx, 0), 0);
- pthread_t th[3];
- thread_key k1 = thread_key(key, &mtx, 42, &cnt);
- thread_key k2 = thread_key(key, &mtx, 43, &cnt);
- thread_key k3 = thread_key(key, &mtx, 44, &cnt);
- EXPECT_EQ(__interceptor_pthread_create(&th[0], 0, dtors_thread, &k1), 0);
- EXPECT_EQ(__interceptor_pthread_create(&th[1], 0, dtors_thread, &k2), 0);
- EXPECT_EQ(__interceptor_pthread_join(th[0], 0), 0);
- EXPECT_EQ(__interceptor_pthread_create(&th[2], 0, dtors_thread, &k3), 0);
- EXPECT_EQ(__interceptor_pthread_join(th[1], 0), 0);
- EXPECT_EQ(__interceptor_pthread_join(th[2], 0), 0);
- EXPECT_EQ(pthread_key_delete(key), 0);
- EXPECT_EQ(6, cnt);
-}
-
-#if !defined(__aarch64__) && !defined(__APPLE__)
-static __thread int local_var;
-
-static void *local_thread(void *p) {
- __tsan_write1(&local_var);
- __tsan_write1(&p);
- if (p == 0)
- return 0;
- const int kThreads = 4;
- pthread_t th[kThreads];
- for (int i = 0; i < kThreads; i++)
- EXPECT_EQ(__interceptor_pthread_create(&th[i], 0, local_thread,
- (void*)((long)p - 1)), 0); // NOLINT
- for (int i = 0; i < kThreads; i++)
- EXPECT_EQ(__interceptor_pthread_join(th[i], 0), 0);
- return 0;
-}
-#endif
-
-TEST(Posix, ThreadLocalAccesses) {
-// The test is failing with high thread count for aarch64.
-// FIXME: track down the issue and re-enable the test.
-// On Darwin, we're running unit tests without interceptors and __thread is
-// using malloc and free, which causes false data race reports. On rare
-// occasions on powerpc64le this test also fails.
-#if !defined(__aarch64__) && !defined(__APPLE__) && !defined(powerpc64le)
- local_thread((void*)2);
-#endif
-}
-
-struct CondContext {
- pthread_mutex_t m;
- pthread_cond_t c;
- int data;
-};
-
-static void *cond_thread(void *p) {
- CondContext &ctx = *static_cast<CondContext*>(p);
-
- EXPECT_EQ(__interceptor_pthread_mutex_lock(&ctx.m), 0);
- EXPECT_EQ(ctx.data, 0);
- ctx.data = 1;
- EXPECT_EQ(__interceptor_pthread_cond_signal(&ctx.c), 0);
- EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx.m), 0);
-
- EXPECT_EQ(__interceptor_pthread_mutex_lock(&ctx.m), 0);
- while (ctx.data != 2)
- EXPECT_EQ(__interceptor_pthread_cond_wait(&ctx.c, &ctx.m), 0);
- EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx.m), 0);
-
- EXPECT_EQ(__interceptor_pthread_mutex_lock(&ctx.m), 0);
- ctx.data = 3;
- EXPECT_EQ(pthread_cond_broadcast(&ctx.c), 0);
- EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx.m), 0);
-
- return 0;
-}
-
-TEST(Posix, CondBasic) {
- CondContext ctx;
- EXPECT_EQ(__interceptor_pthread_mutex_init(&ctx.m, 0), 0);
- EXPECT_EQ(__interceptor_pthread_cond_init(&ctx.c, 0), 0);
- ctx.data = 0;
- pthread_t th;
- EXPECT_EQ(__interceptor_pthread_create(&th, 0, cond_thread, &ctx), 0);
-
- EXPECT_EQ(__interceptor_pthread_mutex_lock(&ctx.m), 0);
- while (ctx.data != 1)
- EXPECT_EQ(__interceptor_pthread_cond_wait(&ctx.c, &ctx.m), 0);
- ctx.data = 2;
- EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx.m), 0);
- EXPECT_EQ(pthread_cond_broadcast(&ctx.c), 0);
-
- EXPECT_EQ(__interceptor_pthread_mutex_lock(&ctx.m), 0);
- while (ctx.data != 3)
- EXPECT_EQ(__interceptor_pthread_cond_wait(&ctx.c, &ctx.m), 0);
- EXPECT_EQ(__interceptor_pthread_mutex_unlock(&ctx.m), 0);
-
- EXPECT_EQ(__interceptor_pthread_join(th, 0), 0);
- EXPECT_EQ(__interceptor_pthread_cond_destroy(&ctx.c), 0);
- EXPECT_EQ(__interceptor_pthread_mutex_destroy(&ctx.m), 0);
-}
diff --git a/lib/tsan/tests/rtl/tsan_posix_util.h b/lib/tsan/tests/rtl/tsan_posix_util.h
deleted file mode 100644
index 340693ebb8a09..0000000000000
--- a/lib/tsan/tests/rtl/tsan_posix_util.h
+++ /dev/null
@@ -1,77 +0,0 @@
-//===-- tsan_posix_util.h ---------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-// Test POSIX utils.
-//===----------------------------------------------------------------------===//
-#ifndef TSAN_POSIX_UTIL_H
-#define TSAN_POSIX_UTIL_H
-
-#include <pthread.h>
-
-#ifdef __APPLE__
-#define __interceptor_memcpy wrap_memcpy
-#define __interceptor_memset wrap_memset
-#define __interceptor_pthread_create wrap_pthread_create
-#define __interceptor_pthread_join wrap_pthread_join
-#define __interceptor_pthread_detach wrap_pthread_detach
-#define __interceptor_pthread_mutex_init wrap_pthread_mutex_init
-#define __interceptor_pthread_mutex_lock wrap_pthread_mutex_lock
-#define __interceptor_pthread_mutex_unlock wrap_pthread_mutex_unlock
-#define __interceptor_pthread_mutex_destroy wrap_pthread_mutex_destroy
-#define __interceptor_pthread_mutex_trylock wrap_pthread_mutex_trylock
-#define __interceptor_pthread_rwlock_init wrap_pthread_rwlock_init
-#define __interceptor_pthread_rwlock_destroy wrap_pthread_rwlock_destroy
-#define __interceptor_pthread_rwlock_trywrlock wrap_pthread_rwlock_trywrlock
-#define __interceptor_pthread_rwlock_wrlock wrap_pthread_rwlock_wrlock
-#define __interceptor_pthread_rwlock_unlock wrap_pthread_rwlock_unlock
-#define __interceptor_pthread_rwlock_rdlock wrap_pthread_rwlock_rdlock
-#define __interceptor_pthread_rwlock_tryrdlock wrap_pthread_rwlock_tryrdlock
-#define __interceptor_pthread_cond_init wrap_pthread_cond_init
-#define __interceptor_pthread_cond_signal wrap_pthread_cond_signal
-#define __interceptor_pthread_cond_broadcast wrap_pthread_cond_broadcast
-#define __interceptor_pthread_cond_wait wrap_pthread_cond_wait
-#define __interceptor_pthread_cond_destroy wrap_pthread_cond_destroy
-#endif
-
-extern "C" void *__interceptor_memcpy(void *, const void *, uptr);
-extern "C" void *__interceptor_memset(void *, int, uptr);
-extern "C" int __interceptor_pthread_create(pthread_t *thread,
- const pthread_attr_t *attr,
- void *(*start_routine)(void *),
- void *arg);
-extern "C" int __interceptor_pthread_join(pthread_t thread, void **value_ptr);
-extern "C" int __interceptor_pthread_detach(pthread_t thread);
-
-extern "C" int __interceptor_pthread_mutex_init(
- pthread_mutex_t *mutex, const pthread_mutexattr_t *attr);
-extern "C" int __interceptor_pthread_mutex_lock(pthread_mutex_t *mutex);
-extern "C" int __interceptor_pthread_mutex_unlock(pthread_mutex_t *mutex);
-extern "C" int __interceptor_pthread_mutex_destroy(pthread_mutex_t *mutex);
-extern "C" int __interceptor_pthread_mutex_trylock(pthread_mutex_t *mutex);
-
-extern "C" int __interceptor_pthread_rwlock_init(
- pthread_rwlock_t *rwlock, const pthread_rwlockattr_t *attr);
-extern "C" int __interceptor_pthread_rwlock_destroy(pthread_rwlock_t *rwlock);
-extern "C" int __interceptor_pthread_rwlock_trywrlock(pthread_rwlock_t *rwlock);
-extern "C" int __interceptor_pthread_rwlock_wrlock(pthread_rwlock_t *rwlock);
-extern "C" int __interceptor_pthread_rwlock_unlock(pthread_rwlock_t *rwlock);
-extern "C" int __interceptor_pthread_rwlock_rdlock(pthread_rwlock_t *rwlock);
-extern "C" int __interceptor_pthread_rwlock_tryrdlock(pthread_rwlock_t *rwlock);
-
-extern "C" int __interceptor_pthread_cond_init(pthread_cond_t *cond,
- const pthread_condattr_t *attr);
-extern "C" int __interceptor_pthread_cond_signal(pthread_cond_t *cond);
-extern "C" int __interceptor_pthread_cond_broadcast(pthread_cond_t *cond);
-extern "C" int __interceptor_pthread_cond_wait(pthread_cond_t *cond,
- pthread_mutex_t *mutex);
-extern "C" int __interceptor_pthread_cond_destroy(pthread_cond_t *cond);
-
-#endif // #ifndef TSAN_POSIX_UTIL_H
diff --git a/lib/tsan/tests/rtl/tsan_string.cc b/lib/tsan/tests/rtl/tsan_string.cc
deleted file mode 100644
index 75adc6c85ee9c..0000000000000
--- a/lib/tsan/tests/rtl/tsan_string.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-//===-- tsan_string.cc ----------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "tsan_test_util.h"
-#include "gtest/gtest.h"
-#include <string.h>
-
-namespace __tsan {
-
-TEST(ThreadSanitizer, Memcpy) {
- char data0[7] = {1, 2, 3, 4, 5, 6, 7};
- char data[7] = {42, 42, 42, 42, 42, 42, 42};
- MainThread().Memcpy(data+1, data0+1, 5);
- EXPECT_EQ(data[0], 42);
- EXPECT_EQ(data[1], 2);
- EXPECT_EQ(data[2], 3);
- EXPECT_EQ(data[3], 4);
- EXPECT_EQ(data[4], 5);
- EXPECT_EQ(data[5], 6);
- EXPECT_EQ(data[6], 42);
- MainThread().Memset(data+1, 13, 5);
- EXPECT_EQ(data[0], 42);
- EXPECT_EQ(data[1], 13);
- EXPECT_EQ(data[2], 13);
- EXPECT_EQ(data[3], 13);
- EXPECT_EQ(data[4], 13);
- EXPECT_EQ(data[5], 13);
- EXPECT_EQ(data[6], 42);
-}
-
-TEST(ThreadSanitizer, MemcpyRace1) {
- char *data = new char[10];
- char *data1 = new char[10];
- char *data2 = new char[10];
- ScopedThread t1, t2;
- t1.Memcpy(data, data1, 10);
- t2.Memcpy(data, data2, 10, true);
-}
-
-TEST(ThreadSanitizer, MemcpyRace2) {
- char *data = new char[10];
- char *data1 = new char[10];
- char *data2 = new char[10];
- ScopedThread t1, t2;
- t1.Memcpy(data+5, data1, 1);
- t2.Memcpy(data+3, data2, 4, true);
-}
-
-TEST(ThreadSanitizer, MemcpyRace3) {
- char *data = new char[10];
- char *data1 = new char[10];
- char *data2 = new char[10];
- ScopedThread t1, t2;
- t1.Memcpy(data, data1, 10);
- t2.Memcpy(data1, data2, 10, true);
-}
-
-TEST(ThreadSanitizer, MemcpyStack) {
- char *data = new char[10];
- char *data1 = new char[10];
- ScopedThread t1, t2;
- t1.Memcpy(data, data1, 10);
- t2.Memcpy(data, data1, 10, true);
-}
-
-TEST(ThreadSanitizer, MemsetRace1) {
- char *data = new char[10];
- ScopedThread t1, t2;
- t1.Memset(data, 1, 10);
- t2.Memset(data, 2, 10, true);
-}
-
-} // namespace __tsan
diff --git a/lib/tsan/tests/rtl/tsan_test.cc b/lib/tsan/tests/rtl/tsan_test.cc
deleted file mode 100644
index 842b417500d83..0000000000000
--- a/lib/tsan/tests/rtl/tsan_test.cc
+++ /dev/null
@@ -1,66 +0,0 @@
-//===-- tsan_test.cc ------------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "tsan_interface.h"
-#include "tsan_test_util.h"
-#include "gtest/gtest.h"
-
-static void foo() {}
-static void bar() {}
-
-TEST(ThreadSanitizer, FuncCall) {
- ScopedThread t1, t2;
- MemLoc l;
- t1.Write1(l);
- t2.Call(foo);
- t2.Call(bar);
- t2.Write1(l, true);
- t2.Return();
- t2.Return();
-}
-
-// We use this function instead of main, as ISO C++ forbids taking the address
-// of main, which we need to pass inside __tsan_func_entry.
-int run_tests(int argc, char **argv) {
- TestMutexBeforeInit(); // Mutexes must be usable before __tsan_init();
- __tsan_init();
- __tsan_func_entry(__builtin_return_address(0));
- __tsan_func_entry((void*)((intptr_t)&run_tests + 1));
-
- testing::GTEST_FLAG(death_test_style) = "threadsafe";
- testing::InitGoogleTest(&argc, argv);
- int res = RUN_ALL_TESTS();
-
- __tsan_func_exit();
- __tsan_func_exit();
- return res;
-}
-
-const char *argv0;
-
-#ifdef __APPLE__
-// On Darwin, turns off symbolication and crash logs to make tests faster.
-extern "C" const char* __tsan_default_options() {
- return "symbolize=false:abort_on_error=0";
-}
-#endif
-
-namespace __sanitizer {
-bool ReexecDisabled() {
- return true;
-}
-}
-
-int main(int argc, char **argv) {
- argv0 = argv[0];
- return run_tests(argc, argv);
-}
diff --git a/lib/tsan/tests/rtl/tsan_test_util.h b/lib/tsan/tests/rtl/tsan_test_util.h
deleted file mode 100644
index 31b1b188f6247..0000000000000
--- a/lib/tsan/tests/rtl/tsan_test_util.h
+++ /dev/null
@@ -1,130 +0,0 @@
-//===-- tsan_test_util.h ----------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-// Test utils.
-//===----------------------------------------------------------------------===//
-#ifndef TSAN_TEST_UTIL_H
-#define TSAN_TEST_UTIL_H
-
-void TestMutexBeforeInit();
-
-// A location of memory on which a race may be detected.
-class MemLoc {
- public:
- explicit MemLoc(int offset_from_aligned = 0);
- explicit MemLoc(void *const real_addr) : loc_(real_addr) { }
- ~MemLoc();
- void *loc() const { return loc_; }
- private:
- void *const loc_;
- MemLoc(const MemLoc&);
- void operator = (const MemLoc&);
-};
-
-class Mutex {
- public:
- enum Type {
- Normal,
- RW,
-#ifndef __APPLE__
- Spin
-#else
- Spin = Normal
-#endif
- };
-
- explicit Mutex(Type type = Normal);
- ~Mutex();
-
- void Init();
- void StaticInit(); // Emulates static initialization (tsan invisible).
- void Destroy();
- void Lock();
- bool TryLock();
- void Unlock();
- void ReadLock();
- bool TryReadLock();
- void ReadUnlock();
-
- private:
- // Placeholder for pthread_mutex_t, CRITICAL_SECTION or whatever.
- void *mtx_[128];
- bool alive_;
- const Type type_;
-
- Mutex(const Mutex&);
- void operator = (const Mutex&);
-};
-
-// A thread is started in CTOR and joined in DTOR.
-class ScopedThread {
- public:
- explicit ScopedThread(bool detached = false, bool main = false);
- ~ScopedThread();
- void Detach();
-
- void Access(void *addr, bool is_write, int size, bool expect_race);
- void Read(const MemLoc &ml, int size, bool expect_race = false) {
- Access(ml.loc(), false, size, expect_race);
- }
- void Write(const MemLoc &ml, int size, bool expect_race = false) {
- Access(ml.loc(), true, size, expect_race);
- }
- void Read1(const MemLoc &ml, bool expect_race = false) {
- Read(ml, 1, expect_race); }
- void Read2(const MemLoc &ml, bool expect_race = false) {
- Read(ml, 2, expect_race); }
- void Read4(const MemLoc &ml, bool expect_race = false) {
- Read(ml, 4, expect_race); }
- void Read8(const MemLoc &ml, bool expect_race = false) {
- Read(ml, 8, expect_race); }
- void Write1(const MemLoc &ml, bool expect_race = false) {
- Write(ml, 1, expect_race); }
- void Write2(const MemLoc &ml, bool expect_race = false) {
- Write(ml, 2, expect_race); }
- void Write4(const MemLoc &ml, bool expect_race = false) {
- Write(ml, 4, expect_race); }
- void Write8(const MemLoc &ml, bool expect_race = false) {
- Write(ml, 8, expect_race); }
-
- void VptrUpdate(const MemLoc &vptr, const MemLoc &new_val,
- bool expect_race = false);
-
- void Call(void(*pc)());
- void Return();
-
- void Create(const Mutex &m);
- void Destroy(const Mutex &m);
- void Lock(const Mutex &m);
- bool TryLock(const Mutex &m);
- void Unlock(const Mutex &m);
- void ReadLock(const Mutex &m);
- bool TryReadLock(const Mutex &m);
- void ReadUnlock(const Mutex &m);
-
- void Memcpy(void *dst, const void *src, int size, bool expect_race = false);
- void Memset(void *dst, int val, int size, bool expect_race = false);
-
- private:
- struct Impl;
- Impl *impl_;
- ScopedThread(const ScopedThread&); // Not implemented.
- void operator = (const ScopedThread&); // Not implemented.
-};
-
-class MainThread : public ScopedThread {
- public:
- MainThread()
- : ScopedThread(false, true) {
- }
-};
-
-#endif // #ifndef TSAN_TEST_UTIL_H
diff --git a/lib/tsan/tests/rtl/tsan_test_util_posix.cc b/lib/tsan/tests/rtl/tsan_test_util_posix.cc
deleted file mode 100644
index d00e26dd5ca6b..0000000000000
--- a/lib/tsan/tests/rtl/tsan_test_util_posix.cc
+++ /dev/null
@@ -1,478 +0,0 @@
-//===-- tsan_test_util_posix.cc -------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-// Test utils, Linux, FreeBSD, NetBSD and Darwin implementation.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_atomic.h"
-#include "tsan_interface.h"
-#include "tsan_posix_util.h"
-#include "tsan_test_util.h"
-#include "tsan_report.h"
-
-#include "gtest/gtest.h"
-
-#include <assert.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <stdint.h>
-#include <string.h>
-#include <unistd.h>
-#include <errno.h>
-
-using namespace __tsan; // NOLINT
-
-static __thread bool expect_report;
-static __thread bool expect_report_reported;
-static __thread ReportType expect_report_type;
-
-static void *BeforeInitThread(void *param) {
- (void)param;
- return 0;
-}
-
-static void AtExit() {
-}
-
-void TestMutexBeforeInit() {
- // Mutexes must be usable before __tsan_init();
- pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
- __interceptor_pthread_mutex_lock(&mtx);
- __interceptor_pthread_mutex_unlock(&mtx);
- __interceptor_pthread_mutex_destroy(&mtx);
- pthread_t thr;
- __interceptor_pthread_create(&thr, 0, BeforeInitThread, 0);
- __interceptor_pthread_join(thr, 0);
- atexit(AtExit);
-}
-
-namespace __tsan {
-bool OnReport(const ReportDesc *rep, bool suppressed) {
- if (expect_report) {
- if (rep->typ != expect_report_type) {
- printf("Expected report of type %d, got type %d\n",
- (int)expect_report_type, (int)rep->typ);
- EXPECT_TRUE(false) << "Wrong report type";
- return false;
- }
- } else {
- EXPECT_TRUE(false) << "Unexpected report";
- return false;
- }
- expect_report_reported = true;
- return true;
-}
-} // namespace __tsan
-
-static void* allocate_addr(int size, int offset_from_aligned = 0) {
- static uintptr_t foo;
- static atomic_uintptr_t uniq = {(uintptr_t)&foo}; // Some real address.
- const int kAlign = 16;
- CHECK(offset_from_aligned < kAlign);
- size = (size + 2 * kAlign) & ~(kAlign - 1);
- uintptr_t addr = atomic_fetch_add(&uniq, size, memory_order_relaxed);
- return (void*)(addr + offset_from_aligned);
-}
-
-MemLoc::MemLoc(int offset_from_aligned)
- : loc_(allocate_addr(16, offset_from_aligned)) {
-}
-
-MemLoc::~MemLoc() {
-}
-
-Mutex::Mutex(Type type)
- : alive_()
- , type_(type) {
-}
-
-Mutex::~Mutex() {
- CHECK(!alive_);
-}
-
-void Mutex::Init() {
- CHECK(!alive_);
- alive_ = true;
- if (type_ == Normal)
- CHECK_EQ(__interceptor_pthread_mutex_init((pthread_mutex_t*)mtx_, 0), 0);
-#ifndef __APPLE__
- else if (type_ == Spin)
- CHECK_EQ(pthread_spin_init((pthread_spinlock_t*)mtx_, 0), 0);
-#endif
- else if (type_ == RW)
- CHECK_EQ(__interceptor_pthread_rwlock_init((pthread_rwlock_t*)mtx_, 0), 0);
- else
- CHECK(0);
-}
-
-void Mutex::StaticInit() {
- CHECK(!alive_);
- CHECK(type_ == Normal);
- alive_ = true;
- pthread_mutex_t tmp = PTHREAD_MUTEX_INITIALIZER;
- memcpy(mtx_, &tmp, sizeof(tmp));
-}
-
-void Mutex::Destroy() {
- CHECK(alive_);
- alive_ = false;
- if (type_ == Normal)
- CHECK_EQ(__interceptor_pthread_mutex_destroy((pthread_mutex_t*)mtx_), 0);
-#ifndef __APPLE__
- else if (type_ == Spin)
- CHECK_EQ(pthread_spin_destroy((pthread_spinlock_t*)mtx_), 0);
-#endif
- else if (type_ == RW)
- CHECK_EQ(__interceptor_pthread_rwlock_destroy((pthread_rwlock_t*)mtx_), 0);
-}
-
-void Mutex::Lock() {
- CHECK(alive_);
- if (type_ == Normal)
- CHECK_EQ(__interceptor_pthread_mutex_lock((pthread_mutex_t*)mtx_), 0);
-#ifndef __APPLE__
- else if (type_ == Spin)
- CHECK_EQ(pthread_spin_lock((pthread_spinlock_t*)mtx_), 0);
-#endif
- else if (type_ == RW)
- CHECK_EQ(__interceptor_pthread_rwlock_wrlock((pthread_rwlock_t*)mtx_), 0);
-}
-
-bool Mutex::TryLock() {
- CHECK(alive_);
- if (type_ == Normal)
- return __interceptor_pthread_mutex_trylock((pthread_mutex_t*)mtx_) == 0;
-#ifndef __APPLE__
- else if (type_ == Spin)
- return pthread_spin_trylock((pthread_spinlock_t*)mtx_) == 0;
-#endif
- else if (type_ == RW)
- return __interceptor_pthread_rwlock_trywrlock((pthread_rwlock_t*)mtx_) == 0;
- return false;
-}
-
-void Mutex::Unlock() {
- CHECK(alive_);
- if (type_ == Normal)
- CHECK_EQ(__interceptor_pthread_mutex_unlock((pthread_mutex_t*)mtx_), 0);
-#ifndef __APPLE__
- else if (type_ == Spin)
- CHECK_EQ(pthread_spin_unlock((pthread_spinlock_t*)mtx_), 0);
-#endif
- else if (type_ == RW)
- CHECK_EQ(__interceptor_pthread_rwlock_unlock((pthread_rwlock_t*)mtx_), 0);
-}
-
-void Mutex::ReadLock() {
- CHECK(alive_);
- CHECK(type_ == RW);
- CHECK_EQ(__interceptor_pthread_rwlock_rdlock((pthread_rwlock_t*)mtx_), 0);
-}
-
-bool Mutex::TryReadLock() {
- CHECK(alive_);
- CHECK(type_ == RW);
- return __interceptor_pthread_rwlock_tryrdlock((pthread_rwlock_t*)mtx_) == 0;
-}
-
-void Mutex::ReadUnlock() {
- CHECK(alive_);
- CHECK(type_ == RW);
- CHECK_EQ(__interceptor_pthread_rwlock_unlock((pthread_rwlock_t*)mtx_), 0);
-}
-
-struct Event {
- enum Type {
- SHUTDOWN,
- READ,
- WRITE,
- VPTR_UPDATE,
- CALL,
- RETURN,
- MUTEX_CREATE,
- MUTEX_DESTROY,
- MUTEX_LOCK,
- MUTEX_TRYLOCK,
- MUTEX_UNLOCK,
- MUTEX_READLOCK,
- MUTEX_TRYREADLOCK,
- MUTEX_READUNLOCK,
- MEMCPY,
- MEMSET
- };
- Type type;
- void *ptr;
- uptr arg;
- uptr arg2;
- bool res;
- bool expect_report;
- ReportType report_type;
-
- Event(Type type, const void *ptr = 0, uptr arg = 0, uptr arg2 = 0)
- : type(type)
- , ptr(const_cast<void*>(ptr))
- , arg(arg)
- , arg2(arg2)
- , res()
- , expect_report()
- , report_type() {
- }
-
- void ExpectReport(ReportType type) {
- expect_report = true;
- report_type = type;
- }
-};
-
-struct ScopedThread::Impl {
- pthread_t thread;
- bool main;
- bool detached;
- atomic_uintptr_t event; // Event*
-
- static void *ScopedThreadCallback(void *arg);
- void send(Event *ev);
- void HandleEvent(Event *ev);
-};
-
-void ScopedThread::Impl::HandleEvent(Event *ev) {
- CHECK_EQ(expect_report, false);
- expect_report = ev->expect_report;
- expect_report_reported = false;
- expect_report_type = ev->report_type;
- switch (ev->type) {
- case Event::READ:
- case Event::WRITE: {
- void (*tsan_mop)(void *addr) = 0;
- if (ev->type == Event::READ) {
- switch (ev->arg /*size*/) {
- case 1: tsan_mop = __tsan_read1; break;
- case 2: tsan_mop = __tsan_read2; break;
- case 4: tsan_mop = __tsan_read4; break;
- case 8: tsan_mop = __tsan_read8; break;
- case 16: tsan_mop = __tsan_read16; break;
- }
- } else {
- switch (ev->arg /*size*/) {
- case 1: tsan_mop = __tsan_write1; break;
- case 2: tsan_mop = __tsan_write2; break;
- case 4: tsan_mop = __tsan_write4; break;
- case 8: tsan_mop = __tsan_write8; break;
- case 16: tsan_mop = __tsan_write16; break;
- }
- }
- CHECK_NE(tsan_mop, 0);
-#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__NetBSD__)
- const int ErrCode = ESOCKTNOSUPPORT;
-#else
- const int ErrCode = ECHRNG;
-#endif
- errno = ErrCode;
- tsan_mop(ev->ptr);
- CHECK_EQ(ErrCode, errno); // In no case must errno be changed.
- break;
- }
- case Event::VPTR_UPDATE:
- __tsan_vptr_update((void**)ev->ptr, (void*)ev->arg);
- break;
- case Event::CALL:
- __tsan_func_entry((void*)((uptr)ev->ptr));
- break;
- case Event::RETURN:
- __tsan_func_exit();
- break;
- case Event::MUTEX_CREATE:
- static_cast<Mutex*>(ev->ptr)->Init();
- break;
- case Event::MUTEX_DESTROY:
- static_cast<Mutex*>(ev->ptr)->Destroy();
- break;
- case Event::MUTEX_LOCK:
- static_cast<Mutex*>(ev->ptr)->Lock();
- break;
- case Event::MUTEX_TRYLOCK:
- ev->res = static_cast<Mutex*>(ev->ptr)->TryLock();
- break;
- case Event::MUTEX_UNLOCK:
- static_cast<Mutex*>(ev->ptr)->Unlock();
- break;
- case Event::MUTEX_READLOCK:
- static_cast<Mutex*>(ev->ptr)->ReadLock();
- break;
- case Event::MUTEX_TRYREADLOCK:
- ev->res = static_cast<Mutex*>(ev->ptr)->TryReadLock();
- break;
- case Event::MUTEX_READUNLOCK:
- static_cast<Mutex*>(ev->ptr)->ReadUnlock();
- break;
- case Event::MEMCPY:
- __interceptor_memcpy(ev->ptr, (void*)ev->arg, ev->arg2);
- break;
- case Event::MEMSET:
- __interceptor_memset(ev->ptr, ev->arg, ev->arg2);
- break;
- default: CHECK(0);
- }
- if (expect_report && !expect_report_reported) {
- printf("Missed expected report of type %d\n", (int)ev->report_type);
- EXPECT_TRUE(false) << "Missed expected race";
- }
- expect_report = false;
-}
-
-void *ScopedThread::Impl::ScopedThreadCallback(void *arg) {
- __tsan_func_entry(__builtin_return_address(0));
- Impl *impl = (Impl*)arg;
- for (;;) {
- Event* ev = (Event*)atomic_load(&impl->event, memory_order_acquire);
- if (ev == 0) {
- sched_yield();
- continue;
- }
- if (ev->type == Event::SHUTDOWN) {
- atomic_store(&impl->event, 0, memory_order_release);
- break;
- }
- impl->HandleEvent(ev);
- atomic_store(&impl->event, 0, memory_order_release);
- }
- __tsan_func_exit();
- return 0;
-}
-
-void ScopedThread::Impl::send(Event *e) {
- if (main) {
- HandleEvent(e);
- } else {
- CHECK_EQ(atomic_load(&event, memory_order_relaxed), 0);
- atomic_store(&event, (uintptr_t)e, memory_order_release);
- while (atomic_load(&event, memory_order_acquire) != 0)
- sched_yield();
- }
-}
-
-ScopedThread::ScopedThread(bool detached, bool main) {
- impl_ = new Impl;
- impl_->main = main;
- impl_->detached = detached;
- atomic_store(&impl_->event, 0, memory_order_relaxed);
- if (!main) {
- pthread_attr_t attr;
- pthread_attr_init(&attr);
- pthread_attr_setdetachstate(
- &attr, detached ? PTHREAD_CREATE_DETACHED : PTHREAD_CREATE_JOINABLE);
- pthread_attr_setstacksize(&attr, 64*1024);
- __interceptor_pthread_create(&impl_->thread, &attr,
- ScopedThread::Impl::ScopedThreadCallback, impl_);
- }
-}
-
-ScopedThread::~ScopedThread() {
- if (!impl_->main) {
- Event event(Event::SHUTDOWN);
- impl_->send(&event);
- if (!impl_->detached)
- __interceptor_pthread_join(impl_->thread, 0);
- }
- delete impl_;
-}
-
-void ScopedThread::Detach() {
- CHECK(!impl_->main);
- CHECK(!impl_->detached);
- impl_->detached = true;
- __interceptor_pthread_detach(impl_->thread);
-}
-
-void ScopedThread::Access(void *addr, bool is_write,
- int size, bool expect_race) {
- Event event(is_write ? Event::WRITE : Event::READ, addr, size);
- if (expect_race)
- event.ExpectReport(ReportTypeRace);
- impl_->send(&event);
-}
-
-void ScopedThread::VptrUpdate(const MemLoc &vptr,
- const MemLoc &new_val,
- bool expect_race) {
- Event event(Event::VPTR_UPDATE, vptr.loc(), (uptr)new_val.loc());
- if (expect_race)
- event.ExpectReport(ReportTypeRace);
- impl_->send(&event);
-}
-
-void ScopedThread::Call(void(*pc)()) {
- Event event(Event::CALL, (void*)((uintptr_t)pc));
- impl_->send(&event);
-}
-
-void ScopedThread::Return() {
- Event event(Event::RETURN);
- impl_->send(&event);
-}
-
-void ScopedThread::Create(const Mutex &m) {
- Event event(Event::MUTEX_CREATE, &m);
- impl_->send(&event);
-}
-
-void ScopedThread::Destroy(const Mutex &m) {
- Event event(Event::MUTEX_DESTROY, &m);
- impl_->send(&event);
-}
-
-void ScopedThread::Lock(const Mutex &m) {
- Event event(Event::MUTEX_LOCK, &m);
- impl_->send(&event);
-}
-
-bool ScopedThread::TryLock(const Mutex &m) {
- Event event(Event::MUTEX_TRYLOCK, &m);
- impl_->send(&event);
- return event.res;
-}
-
-void ScopedThread::Unlock(const Mutex &m) {
- Event event(Event::MUTEX_UNLOCK, &m);
- impl_->send(&event);
-}
-
-void ScopedThread::ReadLock(const Mutex &m) {
- Event event(Event::MUTEX_READLOCK, &m);
- impl_->send(&event);
-}
-
-bool ScopedThread::TryReadLock(const Mutex &m) {
- Event event(Event::MUTEX_TRYREADLOCK, &m);
- impl_->send(&event);
- return event.res;
-}
-
-void ScopedThread::ReadUnlock(const Mutex &m) {
- Event event(Event::MUTEX_READUNLOCK, &m);
- impl_->send(&event);
-}
-
-void ScopedThread::Memcpy(void *dst, const void *src, int size,
- bool expect_race) {
- Event event(Event::MEMCPY, dst, (uptr)src, size);
- if (expect_race)
- event.ExpectReport(ReportTypeRace);
- impl_->send(&event);
-}
-
-void ScopedThread::Memset(void *dst, int val, int size,
- bool expect_race) {
- Event event(Event::MEMSET, dst, val, size);
- if (expect_race)
- event.ExpectReport(ReportTypeRace);
- impl_->send(&event);
-}
diff --git a/lib/tsan/tests/rtl/tsan_thread.cc b/lib/tsan/tests/rtl/tsan_thread.cc
deleted file mode 100644
index 5646415a79b87..0000000000000
--- a/lib/tsan/tests/rtl/tsan_thread.cc
+++ /dev/null
@@ -1,59 +0,0 @@
-//===-- tsan_thread.cc ----------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "tsan_test_util.h"
-#include "gtest/gtest.h"
-
-TEST(ThreadSanitizer, ThreadSync) {
- MainThread t0;
- MemLoc l;
- t0.Write1(l);
- {
- ScopedThread t1;
- t1.Write1(l);
- }
- t0.Write1(l);
-}
-
-TEST(ThreadSanitizer, ThreadDetach1) {
- ScopedThread t1(true);
- MemLoc l;
- t1.Write1(l);
-}
-
-TEST(ThreadSanitizer, ThreadDetach2) {
- ScopedThread t1;
- MemLoc l;
- t1.Write1(l);
- t1.Detach();
-}
-
-static void *thread_alot_func(void *arg) {
- (void)arg;
- int usleep(unsigned);
- usleep(50);
- return 0;
-}
-
-TEST(DISABLED_SLOW_ThreadSanitizer, ThreadALot) {
- const int kThreads = 70000;
- const int kAlive = 1000;
- pthread_t threads[kAlive] = {};
- for (int i = 0; i < kThreads; i++) {
- if (threads[i % kAlive])
- pthread_join(threads[i % kAlive], 0);
- pthread_create(&threads[i % kAlive], 0, thread_alot_func, 0);
- }
- for (int i = 0; i < kAlive; i++) {
- pthread_join(threads[i], 0);
- }
-}
diff --git a/lib/tsan/tests/unit/CMakeLists.txt b/lib/tsan/tests/unit/CMakeLists.txt
deleted file mode 100644
index c08508d507917..0000000000000
--- a/lib/tsan/tests/unit/CMakeLists.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-set(TSAN_UNIT_TEST_SOURCES
- tsan_clock_test.cc
- tsan_flags_test.cc
- tsan_mman_test.cc
- tsan_mutex_test.cc
- tsan_shadow_test.cc
- tsan_stack_test.cc
- tsan_sync_test.cc
- tsan_unit_test_main.cc)
-
-add_tsan_unittest(TsanUnitTest
- SOURCES ${TSAN_UNIT_TEST_SOURCES})
diff --git a/lib/tsan/tests/unit/tsan_clock_test.cc b/lib/tsan/tests/unit/tsan_clock_test.cc
deleted file mode 100644
index f6230e1be5656..0000000000000
--- a/lib/tsan/tests/unit/tsan_clock_test.cc
+++ /dev/null
@@ -1,494 +0,0 @@
-//===-- tsan_clock_test.cc ------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "tsan_clock.h"
-#include "tsan_rtl.h"
-#include "gtest/gtest.h"
-#include <sys/time.h>
-#include <time.h>
-
-namespace __tsan {
-
-ClockCache cache;
-
-TEST(Clock, VectorBasic) {
- ThreadClock clk(0);
- ASSERT_EQ(clk.size(), 1U);
- clk.tick();
- ASSERT_EQ(clk.size(), 1U);
- ASSERT_EQ(clk.get(0), 1U);
- clk.set(&cache, 3, clk.get(3) + 1);
- ASSERT_EQ(clk.size(), 4U);
- ASSERT_EQ(clk.get(0), 1U);
- ASSERT_EQ(clk.get(1), 0U);
- ASSERT_EQ(clk.get(2), 0U);
- ASSERT_EQ(clk.get(3), 1U);
- clk.set(&cache, 3, clk.get(3) + 1);
- ASSERT_EQ(clk.get(3), 2U);
-}
-
-TEST(Clock, ChunkedBasic) {
- ThreadClock vector(0);
- SyncClock chunked;
- ASSERT_EQ(vector.size(), 1U);
- ASSERT_EQ(chunked.size(), 0U);
- vector.acquire(&cache, &chunked);
- ASSERT_EQ(vector.size(), 1U);
- ASSERT_EQ(chunked.size(), 0U);
- vector.release(&cache, &chunked);
- ASSERT_EQ(vector.size(), 1U);
- ASSERT_EQ(chunked.size(), 1U);
- vector.acq_rel(&cache, &chunked);
- ASSERT_EQ(vector.size(), 1U);
- ASSERT_EQ(chunked.size(), 1U);
- chunked.Reset(&cache);
-}
-
-static const uptr interesting_sizes[] = {0, 1, 2, 30, 61, 62, 63, 64, 65, 66,
- 100, 124, 125, 126, 127, 128, 129, 130, 188, 189, 190, 191, 192, 193, 254,
- 255};
-
-TEST(Clock, Iter) {
- const uptr n = ARRAY_SIZE(interesting_sizes);
- for (uptr fi = 0; fi < n; fi++) {
- const uptr size = interesting_sizes[fi];
- SyncClock sync;
- ThreadClock vector(0);
- for (uptr i = 0; i < size; i++)
- vector.set(&cache, i, i + 1);
- if (size != 0)
- vector.release(&cache, &sync);
- uptr i = 0;
- for (ClockElem &ce : sync) {
- ASSERT_LT(i, size);
- ASSERT_EQ(sync.get_clean(i), ce.epoch);
- i++;
- }
- ASSERT_EQ(i, size);
- sync.Reset(&cache);
- }
-}
-
-TEST(Clock, AcquireRelease) {
- ThreadClock vector1(100);
- vector1.tick();
- SyncClock chunked;
- vector1.release(&cache, &chunked);
- ASSERT_EQ(chunked.size(), 101U);
- ThreadClock vector2(0);
- vector2.acquire(&cache, &chunked);
- ASSERT_EQ(vector2.size(), 101U);
- ASSERT_EQ(vector2.get(0), 0U);
- ASSERT_EQ(vector2.get(1), 0U);
- ASSERT_EQ(vector2.get(99), 0U);
- ASSERT_EQ(vector2.get(100), 1U);
- chunked.Reset(&cache);
-}
-
-TEST(Clock, RepeatedAcquire) {
- ThreadClock thr1(1);
- thr1.tick();
- ThreadClock thr2(2);
- thr2.tick();
-
- SyncClock sync;
- thr1.ReleaseStore(&cache, &sync);
-
- thr2.acquire(&cache, &sync);
- thr2.acquire(&cache, &sync);
-
- sync.Reset(&cache);
-}
-
-TEST(Clock, ManyThreads) {
- SyncClock chunked;
- for (unsigned i = 0; i < 200; i++) {
- ThreadClock vector(0);
- vector.tick();
- vector.set(&cache, i, i + 1);
- vector.release(&cache, &chunked);
- ASSERT_EQ(i + 1, chunked.size());
- vector.acquire(&cache, &chunked);
- ASSERT_EQ(i + 1, vector.size());
- }
-
- for (unsigned i = 0; i < 200; i++) {
- printf("i=%d\n", i);
- ASSERT_EQ(i + 1, chunked.get(i));
- }
-
- ThreadClock vector(1);
- vector.acquire(&cache, &chunked);
- ASSERT_EQ(200U, vector.size());
- for (unsigned i = 0; i < 200; i++)
- ASSERT_EQ(i + 1, vector.get(i));
-
- chunked.Reset(&cache);
-}
-
-TEST(Clock, DifferentSizes) {
- {
- ThreadClock vector1(10);
- vector1.tick();
- ThreadClock vector2(20);
- vector2.tick();
- {
- SyncClock chunked;
- vector1.release(&cache, &chunked);
- ASSERT_EQ(chunked.size(), 11U);
- vector2.release(&cache, &chunked);
- ASSERT_EQ(chunked.size(), 21U);
- chunked.Reset(&cache);
- }
- {
- SyncClock chunked;
- vector2.release(&cache, &chunked);
- ASSERT_EQ(chunked.size(), 21U);
- vector1.release(&cache, &chunked);
- ASSERT_EQ(chunked.size(), 21U);
- chunked.Reset(&cache);
- }
- {
- SyncClock chunked;
- vector1.release(&cache, &chunked);
- vector2.acquire(&cache, &chunked);
- ASSERT_EQ(vector2.size(), 21U);
- chunked.Reset(&cache);
- }
- {
- SyncClock chunked;
- vector2.release(&cache, &chunked);
- vector1.acquire(&cache, &chunked);
- ASSERT_EQ(vector1.size(), 21U);
- chunked.Reset(&cache);
- }
- }
-}
-
-TEST(Clock, Growth) {
- {
- ThreadClock vector(10);
- vector.tick();
- vector.set(&cache, 5, 42);
- SyncClock sync;
- vector.release(&cache, &sync);
- ASSERT_EQ(sync.size(), 11U);
- ASSERT_EQ(sync.get(0), 0ULL);
- ASSERT_EQ(sync.get(1), 0ULL);
- ASSERT_EQ(sync.get(5), 42ULL);
- ASSERT_EQ(sync.get(9), 0ULL);
- ASSERT_EQ(sync.get(10), 1ULL);
- sync.Reset(&cache);
- }
- {
- ThreadClock vector1(10);
- vector1.tick();
- ThreadClock vector2(20);
- vector2.tick();
- SyncClock sync;
- vector1.release(&cache, &sync);
- vector2.release(&cache, &sync);
- ASSERT_EQ(sync.size(), 21U);
- ASSERT_EQ(sync.get(0), 0ULL);
- ASSERT_EQ(sync.get(10), 1ULL);
- ASSERT_EQ(sync.get(19), 0ULL);
- ASSERT_EQ(sync.get(20), 1ULL);
- sync.Reset(&cache);
- }
- {
- ThreadClock vector(100);
- vector.tick();
- vector.set(&cache, 5, 42);
- vector.set(&cache, 90, 84);
- SyncClock sync;
- vector.release(&cache, &sync);
- ASSERT_EQ(sync.size(), 101U);
- ASSERT_EQ(sync.get(0), 0ULL);
- ASSERT_EQ(sync.get(1), 0ULL);
- ASSERT_EQ(sync.get(5), 42ULL);
- ASSERT_EQ(sync.get(60), 0ULL);
- ASSERT_EQ(sync.get(70), 0ULL);
- ASSERT_EQ(sync.get(90), 84ULL);
- ASSERT_EQ(sync.get(99), 0ULL);
- ASSERT_EQ(sync.get(100), 1ULL);
- sync.Reset(&cache);
- }
- {
- ThreadClock vector1(10);
- vector1.tick();
- ThreadClock vector2(100);
- vector2.tick();
- SyncClock sync;
- vector1.release(&cache, &sync);
- vector2.release(&cache, &sync);
- ASSERT_EQ(sync.size(), 101U);
- ASSERT_EQ(sync.get(0), 0ULL);
- ASSERT_EQ(sync.get(10), 1ULL);
- ASSERT_EQ(sync.get(99), 0ULL);
- ASSERT_EQ(sync.get(100), 1ULL);
- sync.Reset(&cache);
- }
-}
-
-TEST(Clock, Growth2) {
- // Test clock growth for every pair of sizes:
- const uptr n = ARRAY_SIZE(interesting_sizes);
- for (uptr fi = 0; fi < n; fi++) {
- for (uptr ti = fi + 1; ti < n; ti++) {
- const uptr from = interesting_sizes[fi];
- const uptr to = interesting_sizes[ti];
- SyncClock sync;
- ThreadClock vector(0);
- for (uptr i = 0; i < from; i++)
- vector.set(&cache, i, i + 1);
- if (from != 0)
- vector.release(&cache, &sync);
- ASSERT_EQ(sync.size(), from);
- for (uptr i = 0; i < from; i++)
- ASSERT_EQ(sync.get(i), i + 1);
- for (uptr i = 0; i < to; i++)
- vector.set(&cache, i, i + 1);
- vector.release(&cache, &sync);
- ASSERT_EQ(sync.size(), to);
- for (uptr i = 0; i < to; i++)
- ASSERT_EQ(sync.get(i), i + 1);
- vector.set(&cache, to + 1, to + 1);
- vector.release(&cache, &sync);
- ASSERT_EQ(sync.size(), to + 2);
- for (uptr i = 0; i < to; i++)
- ASSERT_EQ(sync.get(i), i + 1);
- ASSERT_EQ(sync.get(to), 0U);
- ASSERT_EQ(sync.get(to + 1), to + 1);
- sync.Reset(&cache);
- }
- }
-}
-
-const uptr kThreads = 4;
-const uptr kClocks = 4;
-
-// SimpleSyncClock and SimpleThreadClock implement the same thing as
-// SyncClock and ThreadClock, but in a very simple way.
-struct SimpleSyncClock {
- u64 clock[kThreads];
- uptr size;
-
- SimpleSyncClock() {
- Reset();
- }
-
- void Reset() {
- size = 0;
- for (uptr i = 0; i < kThreads; i++)
- clock[i] = 0;
- }
-
- bool verify(const SyncClock *other) const {
- for (uptr i = 0; i < min(size, other->size()); i++) {
- if (clock[i] != other->get(i))
- return false;
- }
- for (uptr i = min(size, other->size()); i < max(size, other->size()); i++) {
- if (i < size && clock[i] != 0)
- return false;
- if (i < other->size() && other->get(i) != 0)
- return false;
- }
- return true;
- }
-};
-
-struct SimpleThreadClock {
- u64 clock[kThreads];
- uptr size;
- unsigned tid;
-
- explicit SimpleThreadClock(unsigned tid) {
- this->tid = tid;
- size = tid + 1;
- for (uptr i = 0; i < kThreads; i++)
- clock[i] = 0;
- }
-
- void tick() {
- clock[tid]++;
- }
-
- void acquire(const SimpleSyncClock *src) {
- if (size < src->size)
- size = src->size;
- for (uptr i = 0; i < kThreads; i++)
- clock[i] = max(clock[i], src->clock[i]);
- }
-
- void release(SimpleSyncClock *dst) const {
- if (dst->size < size)
- dst->size = size;
- for (uptr i = 0; i < kThreads; i++)
- dst->clock[i] = max(dst->clock[i], clock[i]);
- }
-
- void acq_rel(SimpleSyncClock *dst) {
- acquire(dst);
- release(dst);
- }
-
- void ReleaseStore(SimpleSyncClock *dst) const {
- if (dst->size < size)
- dst->size = size;
- for (uptr i = 0; i < kThreads; i++)
- dst->clock[i] = clock[i];
- }
-
- bool verify(const ThreadClock *other) const {
- for (uptr i = 0; i < min(size, other->size()); i++) {
- if (clock[i] != other->get(i))
- return false;
- }
- for (uptr i = min(size, other->size()); i < max(size, other->size()); i++) {
- if (i < size && clock[i] != 0)
- return false;
- if (i < other->size() && other->get(i) != 0)
- return false;
- }
- return true;
- }
-};
-
-static bool ClockFuzzer(bool printing) {
- // Create kThreads thread clocks.
- SimpleThreadClock *thr0[kThreads];
- ThreadClock *thr1[kThreads];
- unsigned reused[kThreads];
- for (unsigned i = 0; i < kThreads; i++) {
- reused[i] = 0;
- thr0[i] = new SimpleThreadClock(i);
- thr1[i] = new ThreadClock(i, reused[i]);
- }
-
- // Create kClocks sync clocks.
- SimpleSyncClock *sync0[kClocks];
- SyncClock *sync1[kClocks];
- for (unsigned i = 0; i < kClocks; i++) {
- sync0[i] = new SimpleSyncClock();
- sync1[i] = new SyncClock();
- }
-
- // Do N random operations (acquire, release, etc) and compare results
- // for SimpleThread/SyncClock and real Thread/SyncClock.
- for (int i = 0; i < 10000; i++) {
- unsigned tid = rand() % kThreads;
- unsigned cid = rand() % kClocks;
- thr0[tid]->tick();
- thr1[tid]->tick();
-
- switch (rand() % 6) {
- case 0:
- if (printing)
- printf("acquire thr%d <- clk%d\n", tid, cid);
- thr0[tid]->acquire(sync0[cid]);
- thr1[tid]->acquire(&cache, sync1[cid]);
- break;
- case 1:
- if (printing)
- printf("release thr%d -> clk%d\n", tid, cid);
- thr0[tid]->release(sync0[cid]);
- thr1[tid]->release(&cache, sync1[cid]);
- break;
- case 2:
- if (printing)
- printf("acq_rel thr%d <> clk%d\n", tid, cid);
- thr0[tid]->acq_rel(sync0[cid]);
- thr1[tid]->acq_rel(&cache, sync1[cid]);
- break;
- case 3:
- if (printing)
- printf("rel_str thr%d >> clk%d\n", tid, cid);
- thr0[tid]->ReleaseStore(sync0[cid]);
- thr1[tid]->ReleaseStore(&cache, sync1[cid]);
- break;
- case 4:
- if (printing)
- printf("reset clk%d\n", cid);
- sync0[cid]->Reset();
- sync1[cid]->Reset(&cache);
- break;
- case 5:
- if (printing)
- printf("reset thr%d\n", tid);
- u64 epoch = thr0[tid]->clock[tid] + 1;
- reused[tid]++;
- delete thr0[tid];
- thr0[tid] = new SimpleThreadClock(tid);
- thr0[tid]->clock[tid] = epoch;
- delete thr1[tid];
- thr1[tid] = new ThreadClock(tid, reused[tid]);
- thr1[tid]->set(epoch);
- break;
- }
-
- if (printing) {
- for (unsigned i = 0; i < kThreads; i++) {
- printf("thr%d: ", i);
- thr1[i]->DebugDump(printf);
- printf("\n");
- }
- for (unsigned i = 0; i < kClocks; i++) {
- printf("clk%d: ", i);
- sync1[i]->DebugDump(printf);
- printf("\n");
- }
-
- printf("\n");
- }
-
- if (!thr0[tid]->verify(thr1[tid]) || !sync0[cid]->verify(sync1[cid])) {
- if (!printing)
- return false;
- printf("differs with model:\n");
- for (unsigned i = 0; i < kThreads; i++) {
- printf("thr%d: clock=[", i);
- for (uptr j = 0; j < thr0[i]->size; j++)
- printf("%s%llu", j == 0 ? "" : ",", thr0[i]->clock[j]);
- printf("]\n");
- }
- for (unsigned i = 0; i < kClocks; i++) {
- printf("clk%d: clock=[", i);
- for (uptr j = 0; j < sync0[i]->size; j++)
- printf("%s%llu", j == 0 ? "" : ",", sync0[i]->clock[j]);
- printf("]\n");
- }
- return false;
- }
- }
-
- for (unsigned i = 0; i < kClocks; i++) {
- sync1[i]->Reset(&cache);
- }
- return true;
-}
-
-TEST(Clock, Fuzzer) {
- struct timeval tv;
- gettimeofday(&tv, NULL);
- int seed = tv.tv_sec + tv.tv_usec;
- printf("seed=%d\n", seed);
- srand(seed);
- if (!ClockFuzzer(false)) {
- // Redo the test with the same seed, but logging operations.
- srand(seed);
- ClockFuzzer(true);
- ASSERT_TRUE(false);
- }
-}
-
-} // namespace __tsan
diff --git a/lib/tsan/tests/unit/tsan_dense_alloc_test.cc b/lib/tsan/tests/unit/tsan_dense_alloc_test.cc
deleted file mode 100644
index e848e48c6641d..0000000000000
--- a/lib/tsan/tests/unit/tsan_dense_alloc_test.cc
+++ /dev/null
@@ -1,55 +0,0 @@
-//===-- tsan_dense_alloc_test.cc ------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "tsan_dense_alloc.h"
-#include "tsan_rtl.h"
-#include "tsan_mman.h"
-#include "gtest/gtest.h"
-
-#include <stdlib.h>
-#include <stdint.h>
-#include <map>
-
-namespace __tsan {
-
-TEST(DenseSlabAlloc, Basic) {
- typedef DenseSlabAlloc<int, 128, 128> Alloc;
- typedef Alloc::Cache Cache;
- typedef Alloc::IndexT IndexT;
- const int N = 1000;
-
- Alloc alloc;
- Cache cache;
- alloc.InitCache(&cache);
-
- IndexT blocks[N];
- for (int ntry = 0; ntry < 3; ntry++) {
- for (int i = 0; i < N; i++) {
- IndexT idx = alloc.Alloc(&cache);
- blocks[i] = idx;
- EXPECT_NE(idx, 0U);
- int *v = alloc.Map(idx);
- *v = i;
- }
-
- for (int i = 0; i < N; i++) {
- IndexT idx = blocks[i];
- int *v = alloc.Map(idx);
- EXPECT_EQ(*v, i);
- alloc.Free(&cache, idx);
- }
-
- alloc.FlushCache(&cache);
- }
-}
-
-} // namespace __tsan
diff --git a/lib/tsan/tests/unit/tsan_flags_test.cc b/lib/tsan/tests/unit/tsan_flags_test.cc
deleted file mode 100644
index aa8a024f9dc5e..0000000000000
--- a/lib/tsan/tests/unit/tsan_flags_test.cc
+++ /dev/null
@@ -1,174 +0,0 @@
-//===-- tsan_flags_test.cc ------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "tsan_flags.h"
-#include "tsan_rtl.h"
-#include "gtest/gtest.h"
-#include <string>
-
-namespace __tsan {
-
-TEST(Flags, Basic) {
- // At least should not crash.
- Flags f;
- InitializeFlags(&f, 0);
- InitializeFlags(&f, "");
-}
-
-TEST(Flags, DefaultValues) {
- Flags f;
-
- f.enable_annotations = false;
- InitializeFlags(&f, "");
- EXPECT_EQ(true, f.enable_annotations);
-}
-
-static const char *options1 =
- " enable_annotations=0"
- " suppress_equal_stacks=0"
- " suppress_equal_addresses=0"
- " report_bugs=0"
- " report_thread_leaks=0"
- " report_destroy_locked=0"
- " report_mutex_bugs=0"
- " report_signal_unsafe=0"
- " report_atomic_races=0"
- " force_seq_cst_atomics=0"
- " print_benign=0"
- " halt_on_error=0"
- " atexit_sleep_ms=222"
- " profile_memory=qqq"
- " flush_memory_ms=444"
- " flush_symbolizer_ms=555"
- " memory_limit_mb=666"
- " stop_on_start=0"
- " running_on_valgrind=0"
- " history_size=5"
- " io_sync=1"
- " die_after_fork=true"
- "";
-
-static const char *options2 =
- " enable_annotations=true"
- " suppress_equal_stacks=true"
- " suppress_equal_addresses=true"
- " report_bugs=true"
- " report_thread_leaks=true"
- " report_destroy_locked=true"
- " report_mutex_bugs=true"
- " report_signal_unsafe=true"
- " report_atomic_races=true"
- " force_seq_cst_atomics=true"
- " print_benign=true"
- " halt_on_error=true"
- " atexit_sleep_ms=123"
- " profile_memory=bbbbb"
- " flush_memory_ms=234"
- " flush_symbolizer_ms=345"
- " memory_limit_mb=456"
- " stop_on_start=true"
- " running_on_valgrind=true"
- " history_size=6"
- " io_sync=2"
- " die_after_fork=false"
- "";
-
-void VerifyOptions1(Flags *f) {
- EXPECT_EQ(f->enable_annotations, 0);
- EXPECT_EQ(f->suppress_equal_stacks, 0);
- EXPECT_EQ(f->suppress_equal_addresses, 0);
- EXPECT_EQ(f->report_bugs, 0);
- EXPECT_EQ(f->report_thread_leaks, 0);
- EXPECT_EQ(f->report_destroy_locked, 0);
- EXPECT_EQ(f->report_mutex_bugs, 0);
- EXPECT_EQ(f->report_signal_unsafe, 0);
- EXPECT_EQ(f->report_atomic_races, 0);
- EXPECT_EQ(f->force_seq_cst_atomics, 0);
- EXPECT_EQ(f->print_benign, 0);
- EXPECT_EQ(f->halt_on_error, 0);
- EXPECT_EQ(f->atexit_sleep_ms, 222);
- EXPECT_EQ(f->profile_memory, std::string("qqq"));
- EXPECT_EQ(f->flush_memory_ms, 444);
- EXPECT_EQ(f->flush_symbolizer_ms, 555);
- EXPECT_EQ(f->memory_limit_mb, 666);
- EXPECT_EQ(f->stop_on_start, 0);
- EXPECT_EQ(f->running_on_valgrind, 0);
- EXPECT_EQ(f->history_size, 5);
- EXPECT_EQ(f->io_sync, 1);
- EXPECT_EQ(f->die_after_fork, true);
-}
-
-void VerifyOptions2(Flags *f) {
- EXPECT_EQ(f->enable_annotations, true);
- EXPECT_EQ(f->suppress_equal_stacks, true);
- EXPECT_EQ(f->suppress_equal_addresses, true);
- EXPECT_EQ(f->report_bugs, true);
- EXPECT_EQ(f->report_thread_leaks, true);
- EXPECT_EQ(f->report_destroy_locked, true);
- EXPECT_EQ(f->report_mutex_bugs, true);
- EXPECT_EQ(f->report_signal_unsafe, true);
- EXPECT_EQ(f->report_atomic_races, true);
- EXPECT_EQ(f->force_seq_cst_atomics, true);
- EXPECT_EQ(f->print_benign, true);
- EXPECT_EQ(f->halt_on_error, true);
- EXPECT_EQ(f->atexit_sleep_ms, 123);
- EXPECT_EQ(f->profile_memory, std::string("bbbbb"));
- EXPECT_EQ(f->flush_memory_ms, 234);
- EXPECT_EQ(f->flush_symbolizer_ms, 345);
- EXPECT_EQ(f->memory_limit_mb, 456);
- EXPECT_EQ(f->stop_on_start, true);
- EXPECT_EQ(f->running_on_valgrind, true);
- EXPECT_EQ(f->history_size, 6);
- EXPECT_EQ(f->io_sync, 2);
- EXPECT_EQ(f->die_after_fork, false);
-}
-
-static const char *test_default_options;
-extern "C" const char *__tsan_default_options() {
- return test_default_options;
-}
-
-TEST(Flags, ParseDefaultOptions) {
- Flags f;
-
- test_default_options = options1;
- InitializeFlags(&f, "");
- VerifyOptions1(&f);
-
- test_default_options = options2;
- InitializeFlags(&f, "");
- VerifyOptions2(&f);
-}
-
-TEST(Flags, ParseEnvOptions) {
- Flags f;
-
- InitializeFlags(&f, options1);
- VerifyOptions1(&f);
-
- InitializeFlags(&f, options2);
- VerifyOptions2(&f);
-}
-
-TEST(Flags, ParsePriority) {
- Flags f;
-
- test_default_options = options2;
- InitializeFlags(&f, options1);
- VerifyOptions1(&f);
-
- test_default_options = options1;
- InitializeFlags(&f, options2);
- VerifyOptions2(&f);
-}
-
-} // namespace __tsan
diff --git a/lib/tsan/tests/unit/tsan_mman_test.cc b/lib/tsan/tests/unit/tsan_mman_test.cc
deleted file mode 100644
index 26e13a55ce1c3..0000000000000
--- a/lib/tsan/tests/unit/tsan_mman_test.cc
+++ /dev/null
@@ -1,197 +0,0 @@
-//===-- tsan_mman_test.cc -------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include <limits>
-#include <sanitizer/allocator_interface.h>
-#include "tsan_mman.h"
-#include "tsan_rtl.h"
-#include "gtest/gtest.h"
-
-namespace __tsan {
-
-TEST(Mman, Internal) {
- char *p = (char*)internal_alloc(MBlockScopedBuf, 10);
- EXPECT_NE(p, (char*)0);
- char *p2 = (char*)internal_alloc(MBlockScopedBuf, 20);
- EXPECT_NE(p2, (char*)0);
- EXPECT_NE(p2, p);
- for (int i = 0; i < 10; i++) {
- p[i] = 42;
- }
- for (int i = 0; i < 20; i++) {
- ((char*)p2)[i] = 42;
- }
- internal_free(p);
- internal_free(p2);
-}
-
-TEST(Mman, User) {
- ThreadState *thr = cur_thread();
- uptr pc = 0;
- char *p = (char*)user_alloc(thr, pc, 10);
- EXPECT_NE(p, (char*)0);
- char *p2 = (char*)user_alloc(thr, pc, 20);
- EXPECT_NE(p2, (char*)0);
- EXPECT_NE(p2, p);
- EXPECT_EQ(10U, user_alloc_usable_size(p));
- EXPECT_EQ(20U, user_alloc_usable_size(p2));
- user_free(thr, pc, p);
- user_free(thr, pc, p2);
-}
-
-TEST(Mman, UserRealloc) {
- ThreadState *thr = cur_thread();
- uptr pc = 0;
- {
- void *p = user_realloc(thr, pc, 0, 0);
- // Realloc(NULL, N) is equivalent to malloc(N), thus must return
- // non-NULL pointer.
- EXPECT_NE(p, (void*)0);
- user_free(thr, pc, p);
- }
- {
- void *p = user_realloc(thr, pc, 0, 100);
- EXPECT_NE(p, (void*)0);
- memset(p, 0xde, 100);
- user_free(thr, pc, p);
- }
- {
- void *p = user_alloc(thr, pc, 100);
- EXPECT_NE(p, (void*)0);
- memset(p, 0xde, 100);
- // Realloc(P, 0) is equivalent to free(P) and returns NULL.
- void *p2 = user_realloc(thr, pc, p, 0);
- EXPECT_EQ(p2, (void*)0);
- }
- {
- void *p = user_realloc(thr, pc, 0, 100);
- EXPECT_NE(p, (void*)0);
- memset(p, 0xde, 100);
- void *p2 = user_realloc(thr, pc, p, 10000);
- EXPECT_NE(p2, (void*)0);
- for (int i = 0; i < 100; i++)
- EXPECT_EQ(((char*)p2)[i], (char)0xde);
- memset(p2, 0xde, 10000);
- user_free(thr, pc, p2);
- }
- {
- void *p = user_realloc(thr, pc, 0, 10000);
- EXPECT_NE(p, (void*)0);
- memset(p, 0xde, 10000);
- void *p2 = user_realloc(thr, pc, p, 10);
- EXPECT_NE(p2, (void*)0);
- for (int i = 0; i < 10; i++)
- EXPECT_EQ(((char*)p2)[i], (char)0xde);
- user_free(thr, pc, p2);
- }
-}
-
-TEST(Mman, UsableSize) {
- ThreadState *thr = cur_thread();
- uptr pc = 0;
- char *p = (char*)user_alloc(thr, pc, 10);
- char *p2 = (char*)user_alloc(thr, pc, 20);
- EXPECT_EQ(0U, user_alloc_usable_size(NULL));
- EXPECT_EQ(10U, user_alloc_usable_size(p));
- EXPECT_EQ(20U, user_alloc_usable_size(p2));
- user_free(thr, pc, p);
- user_free(thr, pc, p2);
- EXPECT_EQ(0U, user_alloc_usable_size((void*)0x4123));
-}
-
-TEST(Mman, Stats) {
- ThreadState *thr = cur_thread();
-
- uptr alloc0 = __sanitizer_get_current_allocated_bytes();
- uptr heap0 = __sanitizer_get_heap_size();
- uptr free0 = __sanitizer_get_free_bytes();
- uptr unmapped0 = __sanitizer_get_unmapped_bytes();
-
- EXPECT_EQ(10U, __sanitizer_get_estimated_allocated_size(10));
- EXPECT_EQ(20U, __sanitizer_get_estimated_allocated_size(20));
- EXPECT_EQ(100U, __sanitizer_get_estimated_allocated_size(100));
-
- char *p = (char*)user_alloc(thr, 0, 10);
- EXPECT_TRUE(__sanitizer_get_ownership(p));
- EXPECT_EQ(10U, __sanitizer_get_allocated_size(p));
-
- EXPECT_EQ(alloc0 + 16, __sanitizer_get_current_allocated_bytes());
- EXPECT_GE(__sanitizer_get_heap_size(), heap0);
- EXPECT_EQ(free0, __sanitizer_get_free_bytes());
- EXPECT_EQ(unmapped0, __sanitizer_get_unmapped_bytes());
-
- user_free(thr, 0, p);
-
- EXPECT_EQ(alloc0, __sanitizer_get_current_allocated_bytes());
- EXPECT_GE(__sanitizer_get_heap_size(), heap0);
- EXPECT_EQ(free0, __sanitizer_get_free_bytes());
- EXPECT_EQ(unmapped0, __sanitizer_get_unmapped_bytes());
-}
-
-TEST(Mman, Valloc) {
- ThreadState *thr = cur_thread();
- uptr page_size = GetPageSizeCached();
-
- void *p = user_valloc(thr, 0, 100);
- EXPECT_NE(p, (void*)0);
- user_free(thr, 0, p);
-
- p = user_pvalloc(thr, 0, 100);
- EXPECT_NE(p, (void*)0);
- user_free(thr, 0, p);
-
- p = user_pvalloc(thr, 0, 0);
- EXPECT_NE(p, (void*)0);
- EXPECT_EQ(page_size, __sanitizer_get_allocated_size(p));
- user_free(thr, 0, p);
-}
-
-#if !SANITIZER_DEBUG
-// EXPECT_DEATH clones a thread with 4K stack,
-// which is overflown by tsan memory accesses functions in debug mode.
-
-TEST(Mman, Memalign) {
- ThreadState *thr = cur_thread();
-
- void *p = user_memalign(thr, 0, 8, 100);
- EXPECT_NE(p, (void*)0);
- user_free(thr, 0, p);
-
- // TODO(alekseyshl): Remove this death test when memalign is verified by
- // tests in sanitizer_common.
- p = NULL;
- EXPECT_DEATH(p = user_memalign(thr, 0, 7, 100),
- "invalid-allocation-alignment");
- EXPECT_EQ(0L, p);
-}
-
-#endif
-
-TEST(Mman, PosixMemalign) {
- ThreadState *thr = cur_thread();
-
- void *p = NULL;
- int res = user_posix_memalign(thr, 0, &p, 8, 100);
- EXPECT_NE(p, (void*)0);
- EXPECT_EQ(res, 0);
- user_free(thr, 0, p);
-}
-
-TEST(Mman, AlignedAlloc) {
- ThreadState *thr = cur_thread();
-
- void *p = user_aligned_alloc(thr, 0, 8, 64);
- EXPECT_NE(p, (void*)0);
- user_free(thr, 0, p);
-}
-
-} // namespace __tsan
diff --git a/lib/tsan/tests/unit/tsan_mutex_test.cc b/lib/tsan/tests/unit/tsan_mutex_test.cc
deleted file mode 100644
index cce7f073b92fc..0000000000000
--- a/lib/tsan/tests/unit/tsan_mutex_test.cc
+++ /dev/null
@@ -1,126 +0,0 @@
-//===-- tsan_mutex_test.cc ------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "sanitizer_common/sanitizer_internal_defs.h"
-#include "sanitizer_common/sanitizer_atomic.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_mutex.h"
-#include "tsan_mutex.h"
-#include "gtest/gtest.h"
-
-namespace __tsan {
-
-template<typename MutexType>
-class TestData {
- public:
- explicit TestData(MutexType *mtx)
- : mtx_(mtx) {
- for (int i = 0; i < kSize; i++)
- data_[i] = 0;
- }
-
- void Write() {
- Lock l(mtx_);
- T v0 = data_[0];
- for (int i = 0; i < kSize; i++) {
- CHECK_EQ(data_[i], v0);
- data_[i]++;
- }
- }
-
- void Read() {
- ReadLock l(mtx_);
- T v0 = data_[0];
- for (int i = 0; i < kSize; i++) {
- CHECK_EQ(data_[i], v0);
- }
- }
-
- void Backoff() {
- volatile T data[kSize] = {};
- for (int i = 0; i < kSize; i++) {
- data[i]++;
- CHECK_EQ(data[i], 1);
- }
- }
-
- private:
- typedef GenericScopedLock<MutexType> Lock;
- static const int kSize = 64;
- typedef u64 T;
- MutexType *mtx_;
- char pad_[kCacheLineSize];
- T data_[kSize];
-};
-
-const int kThreads = 8;
-const int kWriteRate = 1024;
-#if SANITIZER_DEBUG
-const int kIters = 16*1024;
-#else
-const int kIters = 64*1024;
-#endif
-
-template<typename MutexType>
-static void *write_mutex_thread(void *param) {
- TestData<MutexType> *data = (TestData<MutexType>*)param;
- for (int i = 0; i < kIters; i++) {
- data->Write();
- data->Backoff();
- }
- return 0;
-}
-
-template<typename MutexType>
-static void *read_mutex_thread(void *param) {
- TestData<MutexType> *data = (TestData<MutexType>*)param;
- for (int i = 0; i < kIters; i++) {
- if ((i % kWriteRate) == 0)
- data->Write();
- else
- data->Read();
- data->Backoff();
- }
- return 0;
-}
-
-TEST(Mutex, Write) {
- Mutex mtx(MutexTypeAnnotations, StatMtxAnnotations);
- TestData<Mutex> data(&mtx);
- pthread_t threads[kThreads];
- for (int i = 0; i < kThreads; i++)
- pthread_create(&threads[i], 0, write_mutex_thread<Mutex>, &data);
- for (int i = 0; i < kThreads; i++)
- pthread_join(threads[i], 0);
-}
-
-TEST(Mutex, ReadWrite) {
- Mutex mtx(MutexTypeAnnotations, StatMtxAnnotations);
- TestData<Mutex> data(&mtx);
- pthread_t threads[kThreads];
- for (int i = 0; i < kThreads; i++)
- pthread_create(&threads[i], 0, read_mutex_thread<Mutex>, &data);
- for (int i = 0; i < kThreads; i++)
- pthread_join(threads[i], 0);
-}
-
-TEST(Mutex, SpinWrite) {
- SpinMutex mtx;
- TestData<SpinMutex> data(&mtx);
- pthread_t threads[kThreads];
- for (int i = 0; i < kThreads; i++)
- pthread_create(&threads[i], 0, write_mutex_thread<SpinMutex>, &data);
- for (int i = 0; i < kThreads; i++)
- pthread_join(threads[i], 0);
-}
-
-} // namespace __tsan
diff --git a/lib/tsan/tests/unit/tsan_mutexset_test.cc b/lib/tsan/tests/unit/tsan_mutexset_test.cc
deleted file mode 100644
index 335a7748cc1a9..0000000000000
--- a/lib/tsan/tests/unit/tsan_mutexset_test.cc
+++ /dev/null
@@ -1,127 +0,0 @@
-//===-- tsan_mutexset_test.cc ---------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "tsan_mutexset.h"
-#include "gtest/gtest.h"
-
-namespace __tsan {
-
-static void Expect(const MutexSet &mset, uptr i, u64 id, bool write, u64 epoch,
- int count) {
- MutexSet::Desc d = mset.Get(i);
- EXPECT_EQ(id, d.id);
- EXPECT_EQ(write, d.write);
- EXPECT_EQ(epoch, d.epoch);
- EXPECT_EQ(count, d.count);
-}
-
-TEST(MutexSet, Basic) {
- MutexSet mset;
- EXPECT_EQ(mset.Size(), (uptr)0);
-
- mset.Add(1, true, 2);
- EXPECT_EQ(mset.Size(), (uptr)1);
- Expect(mset, 0, 1, true, 2, 1);
- mset.Del(1, true);
- EXPECT_EQ(mset.Size(), (uptr)0);
-
- mset.Add(3, true, 4);
- mset.Add(5, false, 6);
- EXPECT_EQ(mset.Size(), (uptr)2);
- Expect(mset, 0, 3, true, 4, 1);
- Expect(mset, 1, 5, false, 6, 1);
- mset.Del(3, true);
- EXPECT_EQ(mset.Size(), (uptr)1);
- mset.Del(5, false);
- EXPECT_EQ(mset.Size(), (uptr)0);
-}
-
-TEST(MutexSet, DoubleAdd) {
- MutexSet mset;
- mset.Add(1, true, 2);
- EXPECT_EQ(mset.Size(), (uptr)1);
- Expect(mset, 0, 1, true, 2, 1);
-
- mset.Add(1, true, 2);
- EXPECT_EQ(mset.Size(), (uptr)1);
- Expect(mset, 0, 1, true, 2, 2);
-
- mset.Del(1, true);
- EXPECT_EQ(mset.Size(), (uptr)1);
- Expect(mset, 0, 1, true, 2, 1);
-
- mset.Del(1, true);
- EXPECT_EQ(mset.Size(), (uptr)0);
-}
-
-TEST(MutexSet, DoubleDel) {
- MutexSet mset;
- mset.Add(1, true, 2);
- EXPECT_EQ(mset.Size(), (uptr)1);
- mset.Del(1, true);
- EXPECT_EQ(mset.Size(), (uptr)0);
- mset.Del(1, true);
- EXPECT_EQ(mset.Size(), (uptr)0);
-}
-
-TEST(MutexSet, Remove) {
- MutexSet mset;
- mset.Add(1, true, 2);
- mset.Add(1, true, 2);
- mset.Add(3, true, 4);
- mset.Add(3, true, 4);
- EXPECT_EQ(mset.Size(), (uptr)2);
-
- mset.Remove(1);
- EXPECT_EQ(mset.Size(), (uptr)1);
- Expect(mset, 0, 3, true, 4, 2);
-}
-
-TEST(MutexSet, Full) {
- MutexSet mset;
- for (uptr i = 0; i < MutexSet::kMaxSize; i++) {
- mset.Add(i, true, i + 1);
- }
- EXPECT_EQ(mset.Size(), MutexSet::kMaxSize);
- for (uptr i = 0; i < MutexSet::kMaxSize; i++) {
- Expect(mset, i, i, true, i + 1, 1);
- }
-
- for (uptr i = 0; i < MutexSet::kMaxSize; i++) {
- mset.Add(i, true, i + 1);
- }
- EXPECT_EQ(mset.Size(), MutexSet::kMaxSize);
- for (uptr i = 0; i < MutexSet::kMaxSize; i++) {
- Expect(mset, i, i, true, i + 1, 2);
- }
-}
-
-TEST(MutexSet, Overflow) {
- MutexSet mset;
- for (uptr i = 0; i < MutexSet::kMaxSize; i++) {
- mset.Add(i, true, i + 1);
- mset.Add(i, true, i + 1);
- }
- mset.Add(100, true, 200);
- EXPECT_EQ(mset.Size(), MutexSet::kMaxSize);
- for (uptr i = 0; i < MutexSet::kMaxSize; i++) {
- if (i == 0)
- Expect(mset, i, MutexSet::kMaxSize - 1,
- true, MutexSet::kMaxSize, 2);
- else if (i == MutexSet::kMaxSize - 1)
- Expect(mset, i, 100, true, 200, 1);
- else
- Expect(mset, i, i, true, i + 1, 2);
- }
-}
-
-} // namespace __tsan
diff --git a/lib/tsan/tests/unit/tsan_shadow_test.cc b/lib/tsan/tests/unit/tsan_shadow_test.cc
deleted file mode 100644
index 17b17977bf86b..0000000000000
--- a/lib/tsan/tests/unit/tsan_shadow_test.cc
+++ /dev/null
@@ -1,78 +0,0 @@
-//===-- tsan_shadow_test.cc -----------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "tsan_platform.h"
-#include "tsan_rtl.h"
-#include "gtest/gtest.h"
-
-namespace __tsan {
-
-TEST(Shadow, FastState) {
- Shadow s(FastState(11, 22));
- EXPECT_EQ(s.tid(), (u64)11);
- EXPECT_EQ(s.epoch(), (u64)22);
- EXPECT_EQ(s.GetIgnoreBit(), false);
- EXPECT_EQ(s.GetFreedAndReset(), false);
- EXPECT_EQ(s.GetHistorySize(), 0);
- EXPECT_EQ(s.addr0(), (u64)0);
- EXPECT_EQ(s.size(), (u64)1);
- EXPECT_EQ(s.IsWrite(), true);
-
- s.IncrementEpoch();
- EXPECT_EQ(s.epoch(), (u64)23);
- s.IncrementEpoch();
- EXPECT_EQ(s.epoch(), (u64)24);
-
- s.SetIgnoreBit();
- EXPECT_EQ(s.GetIgnoreBit(), true);
- s.ClearIgnoreBit();
- EXPECT_EQ(s.GetIgnoreBit(), false);
-
- for (int i = 0; i < 8; i++) {
- s.SetHistorySize(i);
- EXPECT_EQ(s.GetHistorySize(), i);
- }
- s.SetHistorySize(2);
- s.ClearHistorySize();
- EXPECT_EQ(s.GetHistorySize(), 0);
-}
-
-TEST(Shadow, Mapping) {
- static int global;
- int stack;
- void *heap = malloc(0);
- free(heap);
-
- CHECK(IsAppMem((uptr)&global));
- CHECK(IsAppMem((uptr)&stack));
- CHECK(IsAppMem((uptr)heap));
-
- CHECK(IsShadowMem(MemToShadow((uptr)&global)));
- CHECK(IsShadowMem(MemToShadow((uptr)&stack)));
- CHECK(IsShadowMem(MemToShadow((uptr)heap)));
-}
-
-TEST(Shadow, Celling) {
- u64 aligned_data[4];
- char *data = (char*)aligned_data;
- CHECK_EQ((uptr)data % kShadowSize, 0);
- uptr s0 = MemToShadow((uptr)&data[0]);
- CHECK_EQ(s0 % kShadowSize, 0);
- for (unsigned i = 1; i < kShadowCell; i++)
- CHECK_EQ(s0, MemToShadow((uptr)&data[i]));
- for (unsigned i = kShadowCell; i < 2*kShadowCell; i++)
- CHECK_EQ(s0 + kShadowSize*kShadowCnt, MemToShadow((uptr)&data[i]));
- for (unsigned i = 2*kShadowCell; i < 3*kShadowCell; i++)
- CHECK_EQ(s0 + 2*kShadowSize*kShadowCnt, MemToShadow((uptr)&data[i]));
-}
-
-} // namespace __tsan
diff --git a/lib/tsan/tests/unit/tsan_stack_test.cc b/lib/tsan/tests/unit/tsan_stack_test.cc
deleted file mode 100644
index 92e035d8d0004..0000000000000
--- a/lib/tsan/tests/unit/tsan_stack_test.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-//===-- tsan_stack_test.cc ------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "tsan_sync.h"
-#include "tsan_rtl.h"
-#include "gtest/gtest.h"
-#include <string.h>
-
-namespace __tsan {
-
-template <typename StackTraceTy>
-static void TestStackTrace(StackTraceTy *trace) {
- ThreadState thr(0, 0, 0, 0, 0, 0, 0, 0, 0);
- uptr stack[128];
- thr.shadow_stack = &stack[0];
- thr.shadow_stack_pos = &stack[0];
- thr.shadow_stack_end = &stack[128];
-
- ObtainCurrentStack(&thr, 0, trace);
- EXPECT_EQ(0U, trace->size);
-
- ObtainCurrentStack(&thr, 42, trace);
- EXPECT_EQ(1U, trace->size);
- EXPECT_EQ(42U, trace->trace[0]);
-
- *thr.shadow_stack_pos++ = 100;
- *thr.shadow_stack_pos++ = 101;
- ObtainCurrentStack(&thr, 0, trace);
- EXPECT_EQ(2U, trace->size);
- EXPECT_EQ(100U, trace->trace[0]);
- EXPECT_EQ(101U, trace->trace[1]);
-
- ObtainCurrentStack(&thr, 42, trace);
- EXPECT_EQ(3U, trace->size);
- EXPECT_EQ(100U, trace->trace[0]);
- EXPECT_EQ(101U, trace->trace[1]);
- EXPECT_EQ(42U, trace->trace[2]);
-}
-
-template<typename StackTraceTy>
-static void TestTrim(StackTraceTy *trace) {
- ThreadState thr(0, 0, 0, 0, 0, 0, 0, 0, 0);
- const uptr kShadowStackSize = 2 * kStackTraceMax;
- uptr stack[kShadowStackSize];
- thr.shadow_stack = &stack[0];
- thr.shadow_stack_pos = &stack[0];
- thr.shadow_stack_end = &stack[kShadowStackSize];
-
- for (uptr i = 0; i < kShadowStackSize; ++i)
- *thr.shadow_stack_pos++ = 100 + i;
-
- ObtainCurrentStack(&thr, 0, trace);
- EXPECT_EQ(kStackTraceMax, trace->size);
- for (uptr i = 0; i < kStackTraceMax; i++) {
- EXPECT_EQ(100 + kStackTraceMax + i, trace->trace[i]);
- }
-
- ObtainCurrentStack(&thr, 42, trace);
- EXPECT_EQ(kStackTraceMax, trace->size);
- for (uptr i = 0; i < kStackTraceMax - 1; i++) {
- EXPECT_EQ(101 + kStackTraceMax + i, trace->trace[i]);
- }
- EXPECT_EQ(42U, trace->trace[kStackTraceMax - 1]);
-}
-
-TEST(StackTrace, BasicVarSize) {
- VarSizeStackTrace trace;
- TestStackTrace(&trace);
-}
-
-TEST(StackTrace, BasicBuffered) {
- BufferedStackTrace trace;
- TestStackTrace(&trace);
-}
-
-TEST(StackTrace, TrimVarSize) {
- VarSizeStackTrace trace;
- TestTrim(&trace);
-}
-
-TEST(StackTrace, TrimBuffered) {
- BufferedStackTrace trace;
- TestTrim(&trace);
-}
-
-} // namespace __tsan
diff --git a/lib/tsan/tests/unit/tsan_sync_test.cc b/lib/tsan/tests/unit/tsan_sync_test.cc
deleted file mode 100644
index 8016654787870..0000000000000
--- a/lib/tsan/tests/unit/tsan_sync_test.cc
+++ /dev/null
@@ -1,123 +0,0 @@
-//===-- tsan_sync_test.cc -------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "tsan_sync.h"
-#include "tsan_rtl.h"
-#include "gtest/gtest.h"
-
-namespace __tsan {
-
-TEST(MetaMap, Basic) {
- ThreadState *thr = cur_thread();
- MetaMap *m = &ctx->metamap;
- u64 block[1] = {}; // fake malloc block
- m->AllocBlock(thr, 0, (uptr)&block[0], 1 * sizeof(u64));
- MBlock *mb = m->GetBlock((uptr)&block[0]);
- EXPECT_NE(mb, (MBlock*)0);
- EXPECT_EQ(mb->siz, 1 * sizeof(u64));
- EXPECT_EQ(mb->tid, thr->tid);
- uptr sz = m->FreeBlock(thr->proc(), (uptr)&block[0]);
- EXPECT_EQ(sz, 1 * sizeof(u64));
- mb = m->GetBlock((uptr)&block[0]);
- EXPECT_EQ(mb, (MBlock*)0);
-}
-
-TEST(MetaMap, FreeRange) {
- ThreadState *thr = cur_thread();
- MetaMap *m = &ctx->metamap;
- u64 block[4] = {}; // fake malloc block
- m->AllocBlock(thr, 0, (uptr)&block[0], 1 * sizeof(u64));
- m->AllocBlock(thr, 0, (uptr)&block[1], 3 * sizeof(u64));
- MBlock *mb1 = m->GetBlock((uptr)&block[0]);
- EXPECT_EQ(mb1->siz, 1 * sizeof(u64));
- MBlock *mb2 = m->GetBlock((uptr)&block[1]);
- EXPECT_EQ(mb2->siz, 3 * sizeof(u64));
- m->FreeRange(thr->proc(), (uptr)&block[0], 4 * sizeof(u64));
- mb1 = m->GetBlock((uptr)&block[0]);
- EXPECT_EQ(mb1, (MBlock*)0);
- mb2 = m->GetBlock((uptr)&block[1]);
- EXPECT_EQ(mb2, (MBlock*)0);
-}
-
-TEST(MetaMap, Sync) {
- ThreadState *thr = cur_thread();
- MetaMap *m = &ctx->metamap;
- u64 block[4] = {}; // fake malloc block
- m->AllocBlock(thr, 0, (uptr)&block[0], 4 * sizeof(u64));
- SyncVar *s1 = m->GetIfExistsAndLock((uptr)&block[0], true);
- EXPECT_EQ(s1, (SyncVar*)0);
- s1 = m->GetOrCreateAndLock(thr, 0, (uptr)&block[0], true);
- EXPECT_NE(s1, (SyncVar*)0);
- EXPECT_EQ(s1->addr, (uptr)&block[0]);
- s1->mtx.Unlock();
- SyncVar *s2 = m->GetOrCreateAndLock(thr, 0, (uptr)&block[1], false);
- EXPECT_NE(s2, (SyncVar*)0);
- EXPECT_EQ(s2->addr, (uptr)&block[1]);
- s2->mtx.ReadUnlock();
- m->FreeBlock(thr->proc(), (uptr)&block[0]);
- s1 = m->GetIfExistsAndLock((uptr)&block[0], true);
- EXPECT_EQ(s1, (SyncVar*)0);
- s2 = m->GetIfExistsAndLock((uptr)&block[1], true);
- EXPECT_EQ(s2, (SyncVar*)0);
- m->OnProcIdle(thr->proc());
-}
-
-TEST(MetaMap, MoveMemory) {
- ThreadState *thr = cur_thread();
- MetaMap *m = &ctx->metamap;
- u64 block1[4] = {}; // fake malloc block
- u64 block2[4] = {}; // fake malloc block
- m->AllocBlock(thr, 0, (uptr)&block1[0], 3 * sizeof(u64));
- m->AllocBlock(thr, 0, (uptr)&block1[3], 1 * sizeof(u64));
- SyncVar *s1 = m->GetOrCreateAndLock(thr, 0, (uptr)&block1[0], true);
- s1->mtx.Unlock();
- SyncVar *s2 = m->GetOrCreateAndLock(thr, 0, (uptr)&block1[1], true);
- s2->mtx.Unlock();
- m->MoveMemory((uptr)&block1[0], (uptr)&block2[0], 4 * sizeof(u64));
- MBlock *mb1 = m->GetBlock((uptr)&block1[0]);
- EXPECT_EQ(mb1, (MBlock*)0);
- MBlock *mb2 = m->GetBlock((uptr)&block1[3]);
- EXPECT_EQ(mb2, (MBlock*)0);
- mb1 = m->GetBlock((uptr)&block2[0]);
- EXPECT_NE(mb1, (MBlock*)0);
- EXPECT_EQ(mb1->siz, 3 * sizeof(u64));
- mb2 = m->GetBlock((uptr)&block2[3]);
- EXPECT_NE(mb2, (MBlock*)0);
- EXPECT_EQ(mb2->siz, 1 * sizeof(u64));
- s1 = m->GetIfExistsAndLock((uptr)&block1[0], true);
- EXPECT_EQ(s1, (SyncVar*)0);
- s2 = m->GetIfExistsAndLock((uptr)&block1[1], true);
- EXPECT_EQ(s2, (SyncVar*)0);
- s1 = m->GetIfExistsAndLock((uptr)&block2[0], true);
- EXPECT_NE(s1, (SyncVar*)0);
- EXPECT_EQ(s1->addr, (uptr)&block2[0]);
- s1->mtx.Unlock();
- s2 = m->GetIfExistsAndLock((uptr)&block2[1], true);
- EXPECT_NE(s2, (SyncVar*)0);
- EXPECT_EQ(s2->addr, (uptr)&block2[1]);
- s2->mtx.Unlock();
- m->FreeRange(thr->proc(), (uptr)&block2[0], 4 * sizeof(u64));
-}
-
-TEST(MetaMap, ResetSync) {
- ThreadState *thr = cur_thread();
- MetaMap *m = &ctx->metamap;
- u64 block[1] = {}; // fake malloc block
- m->AllocBlock(thr, 0, (uptr)&block[0], 1 * sizeof(u64));
- SyncVar *s = m->GetOrCreateAndLock(thr, 0, (uptr)&block[0], true);
- s->Reset(thr->proc());
- s->mtx.Unlock();
- uptr sz = m->FreeBlock(thr->proc(), (uptr)&block[0]);
- EXPECT_EQ(sz, 1 * sizeof(u64));
-}
-
-} // namespace __tsan
diff --git a/lib/tsan/tests/unit/tsan_unit_test_main.cc b/lib/tsan/tests/unit/tsan_unit_test_main.cc
deleted file mode 100644
index 2d55747a0257f..0000000000000
--- a/lib/tsan/tests/unit/tsan_unit_test_main.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-//===-- tsan_unit_test_main.cc --------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of ThreadSanitizer (TSan), a race detector.
-//
-//===----------------------------------------------------------------------===//
-#include "gtest/gtest.h"
-
-namespace __sanitizer {
-bool ReexecDisabled() {
- return true;
-}
-}
-
-int main(int argc, char **argv) {
- testing::GTEST_FLAG(death_test_style) = "threadsafe";
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}
diff --git a/lib/ubsan/CMakeLists.txt b/lib/ubsan/CMakeLists.txt
deleted file mode 100644
index ab118ae4a5216..0000000000000
--- a/lib/ubsan/CMakeLists.txt
+++ /dev/null
@@ -1,227 +0,0 @@
-# Build for the undefined behavior sanitizer runtime support library.
-
-set(UBSAN_SOURCES
- ubsan_diag.cc
- ubsan_init.cc
- ubsan_flags.cc
- ubsan_handlers.cc
- ubsan_monitor.cc
- ubsan_value.cc)
-
-set(UBSAN_STANDALONE_SOURCES
- ubsan_diag_standalone.cc
- ubsan_init_standalone.cc
- ubsan_signals_standalone.cc)
-
-set(UBSAN_CXXABI_SOURCES
- ubsan_handlers_cxx.cc
- ubsan_type_hash.cc
- ubsan_type_hash_itanium.cc
- ubsan_type_hash_win.cc)
-
-set(UBSAN_HEADERS
- ubsan_checks.inc
- ubsan_diag.h
- ubsan_flags.h
- ubsan_flags.inc
- ubsan_handlers.h
- ubsan_handlers_cxx.h
- ubsan_init.h
- ubsan_interface.inc
- ubsan_monitor.h
- ubsan_platform.h
- ubsan_signals_standalone.h
- ubsan_type_hash.h
- ubsan_value.h
-)
-
-include_directories(..)
-
-set(UBSAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})
-append_rtti_flag(OFF UBSAN_CFLAGS)
-append_list_if(SANITIZER_CAN_USE_CXXABI -DUBSAN_CAN_USE_CXXABI UBSAN_CFLAGS)
-
-set(UBSAN_STANDALONE_CFLAGS ${SANITIZER_COMMON_CFLAGS})
-append_rtti_flag(OFF UBSAN_STANDALONE_CFLAGS)
-append_list_if(SANITIZER_CAN_USE_CXXABI -DUBSAN_CAN_USE_CXXABI UBSAN_STANDALONE_CFLAGS)
-
-set(UBSAN_CXXFLAGS ${SANITIZER_COMMON_CFLAGS})
-append_rtti_flag(ON UBSAN_CXXFLAGS)
-append_list_if(SANITIZER_CAN_USE_CXXABI -DUBSAN_CAN_USE_CXXABI UBSAN_CXXFLAGS)
-
-set(UBSAN_DYNAMIC_LIBS ${SANITIZER_CXX_ABI_LIBRARY} ${SANITIZER_COMMON_LINK_LIBS})
-
-append_list_if(COMPILER_RT_HAS_LIBDL dl UBSAN_DYNAMIC_LIBS)
-append_list_if(COMPILER_RT_HAS_LIBLOG log UBSAN_DYNAMIC_LIBS)
-append_list_if(COMPILER_RT_HAS_LIBRT rt UBSAN_DYNAMIC_LIBS)
-append_list_if(COMPILER_RT_HAS_LIBPTHREAD pthread UBSAN_DYNAMIC_LIBS)
-
-add_compiler_rt_component(ubsan)
-
-if(APPLE)
- set(UBSAN_COMMON_SOURCES ${UBSAN_SOURCES})
- if(SANITIZER_CAN_USE_CXXABI)
- list(APPEND UBSAN_COMMON_SOURCES ${UBSAN_CXXABI_SOURCES})
- endif()
-
- # Common parts of UBSan runtime.
- add_compiler_rt_object_libraries(RTUbsan
- OS ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${UBSAN_COMMON_SUPPORTED_ARCH}
- SOURCES ${UBSAN_COMMON_SOURCES}
- ADDITIONAL_HEADERS ${UBSAN_HEADERS}
- CFLAGS ${UBSAN_CXXFLAGS})
-
- if(COMPILER_RT_HAS_UBSAN)
- # Initializer of standalone UBSan runtime.
- add_compiler_rt_object_libraries(RTUbsan_standalone
- OS ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${UBSAN_SUPPORTED_ARCH}
- SOURCES ${UBSAN_STANDALONE_SOURCES}
- ADDITIONAL_HEADERS ${UBSAN_HEADERS}
- CFLAGS ${UBSAN_STANDALONE_CFLAGS})
-
- 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
- OS ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${UBSAN_SUPPORTED_ARCH}
- OBJECT_LIBS RTUbsan
- RTUbsan_standalone
- RTSanitizerCommon
- RTSanitizerCommonLibc
- RTSanitizerCommonCoverage
- RTSanitizerCommonSymbolizer
- RTInterception
- LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
- PARENT_TARGET ubsan)
-
- add_compiler_rt_runtime(clang_rt.ubsan
- STATIC
- OS ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${UBSAN_SUPPORTED_ARCH}
- OBJECT_LIBS RTUbsan
- RTUbsan_standalone
- RTSanitizerCommonNoHooks
- RTSanitizerCommonLibcNoHooks
- RTSanitizerCommonCoverage
- RTSanitizerCommonSymbolizerNoHooks
- RTInterception
- LINK_FLAGS ${WEAK_SYMBOL_LINK_FLAGS}
- PARENT_TARGET ubsan)
- endif()
-
-else()
- # Common parts of UBSan runtime.
- add_compiler_rt_object_libraries(RTUbsan
- ARCHS ${UBSAN_COMMON_SUPPORTED_ARCH}
- SOURCES ${UBSAN_SOURCES}
- ADDITIONAL_HEADERS ${UBSAN_HEADERS}
- CFLAGS ${UBSAN_CFLAGS})
-
- if(SANITIZER_CAN_USE_CXXABI)
- # C++-specific parts of UBSan runtime. Requires a C++ ABI library.
- set(UBSAN_CXX_SOURCES ${UBSAN_CXXABI_SOURCES})
- else()
- # Dummy target if we don't have C++ ABI library.
- file(WRITE ${CMAKE_CURRENT_BINARY_DIR}/cxx_dummy.cc "")
- set(UBSAN_CXX_SOURCES ${CMAKE_CURRENT_BINARY_DIR}/cxx_dummy.cc)
- endif()
-
- add_compiler_rt_object_libraries(RTUbsan_cxx
- ARCHS ${UBSAN_COMMON_SUPPORTED_ARCH}
- SOURCES ${UBSAN_CXX_SOURCES}
- ADDITIONAL_HEADERS ${UBSAN_HEADERS}
- CFLAGS ${UBSAN_CXXFLAGS})
-
- if (WIN32)
- add_compiler_rt_object_libraries(UbsanWeakInterception
- ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${UBSAN_SUPPORTED_ARCH}
- SOURCES ubsan_win_weak_interception.cc
- CFLAGS ${UBSAN_CFLAGS} -DSANITIZER_DYNAMIC
- DEFS ${UBSAN_COMMON_DEFINITIONS})
-
- add_compiler_rt_object_libraries(UbsanDllThunk
- ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${UBSAN_SUPPORTED_ARCH}
- SOURCES ubsan_win_dll_thunk.cc
- CFLAGS ${UBSAN_CFLAGS} -DSANITIZER_DLL_THUNK
- DEFS ${UBSAN_COMMON_DEFINITIONS})
-
- set(DYNAMIC_RUNTIME_THUNK_CFLAGS "-DSANITIZER_DYNAMIC_RUNTIME_THUNK")
- if(MSVC)
- list(APPEND DYNAMIC_RUNTIME_THUNK_CFLAGS "-Zl")
- elseif(CMAKE_C_COMPILER_ID MATCHES Clang)
- list(APPEND DYNAMIC_RUNTIME_THUNK_CFLAGS "-nodefaultlibs")
- endif()
- add_compiler_rt_object_libraries(UbsanDynamicRuntimeThunk
- ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${UBSAN_SUPPORTED_ARCH}
- SOURCES ubsan_win_dynamic_runtime_thunk.cc
- CFLAGS ${UBSAN_CFLAGS} ${DYNAMIC_RUNTIME_THUNK_CFLAGS}
- DEFS ${UBSAN_COMMON_DEFINITIONS})
- endif()
-
- if(COMPILER_RT_HAS_UBSAN)
- add_compiler_rt_object_libraries(RTUbsan_standalone
- ARCHS ${UBSAN_SUPPORTED_ARCH}
- SOURCES ${UBSAN_STANDALONE_SOURCES}
- ADDITIONAL_HEADERS ${UBSAN_HEADERS}
- CFLAGS ${UBSAN_STANDALONE_CFLAGS})
-
- # Standalone UBSan runtimes.
- add_compiler_rt_runtime(clang_rt.ubsan_standalone
- STATIC
- ARCHS ${UBSAN_SUPPORTED_ARCH}
- SOURCES ubsan_init_standalone_preinit.cc
- ADDITIONAL_HEADERS ${UBSAN_HEADERS}
- OBJECT_LIBS RTSanitizerCommon
- RTSanitizerCommonLibc
- RTSanitizerCommonCoverage
- RTSanitizerCommonSymbolizer
- RTUbsan
- RTUbsan_standalone
- RTInterception
- CFLAGS ${UBSAN_CFLAGS}
- PARENT_TARGET ubsan)
-
- add_compiler_rt_runtime(clang_rt.ubsan_standalone_cxx
- STATIC
- ARCHS ${UBSAN_SUPPORTED_ARCH}
- OBJECT_LIBS RTUbsan_cxx
- CFLAGS ${UBSAN_CXXFLAGS}
- PARENT_TARGET ubsan)
-
- if (FUCHSIA OR UNIX)
- add_compiler_rt_runtime(clang_rt.ubsan_standalone
- SHARED
- ARCHS ${UBSAN_SUPPORTED_ARCH}
- OBJECT_LIBS RTSanitizerCommon
- RTSanitizerCommonLibc
- RTSanitizerCommonCoverage
- RTSanitizerCommonSymbolizer
- RTUbsan
- RTUbsan_cxx
- RTUbsan_standalone
- RTInterception
- CFLAGS ${UBSAN_CFLAGS}
- LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS}
- LINK_LIBS ${UBSAN_DYNAMIC_LIBS}
- PARENT_TARGET ubsan)
-
- set(ARCHS_FOR_SYMBOLS ${UBSAN_SUPPORTED_ARCH})
- list(REMOVE_ITEM ARCHS_FOR_SYMBOLS i386)
- add_sanitizer_rt_symbols(clang_rt.ubsan_standalone
- ARCHS ${ARCHS_FOR_SYMBOLS}
- PARENT_TARGET ubsan
- EXTRA ubsan.syms.extra)
- add_sanitizer_rt_symbols(clang_rt.ubsan_standalone_cxx
- ARCHS ${ARCHS_FOR_SYMBOLS}
- PARENT_TARGET ubsan
- EXTRA ubsan.syms.extra)
- endif()
- endif()
-endif()
diff --git a/lib/ubsan_minimal/CMakeLists.txt b/lib/ubsan_minimal/CMakeLists.txt
deleted file mode 100644
index e0910e80f97e3..0000000000000
--- a/lib/ubsan_minimal/CMakeLists.txt
+++ /dev/null
@@ -1,53 +0,0 @@
-# Build for the minimal undefined behavior sanitizer runtime support library.
-
-set(UBSAN_MINIMAL_SOURCES
- ubsan_minimal_handlers.cc
- )
-
-include_directories(..)
-
-set(UBSAN_CFLAGS ${SANITIZER_COMMON_CFLAGS})
-append_rtti_flag(OFF UBSAN_CFLAGS)
-
-set(UBSAN_LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS})
-
-set(UBSAN_DYNAMIC_LIBS ${SANITIZER_COMMON_LINK_LIBS})
-
-add_compiler_rt_component(ubsan-minimal)
-
-# Common parts of minimal UBSan runtime.
-add_compiler_rt_object_libraries(RTUbsan_minimal
- OS ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${UBSAN_COMMON_SUPPORTED_ARCH}
- SOURCES ${UBSAN_MINIMAL_SOURCES} CFLAGS ${UBSAN_CFLAGS})
-
-
-if(COMPILER_RT_HAS_UBSAN_MINIMAL)
- # Standalone minimal UBSan runtimes.
- add_compiler_rt_runtime(clang_rt.ubsan_minimal
- STATIC
- OS ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${UBSAN_SUPPORTED_ARCH}
- OBJECT_LIBS RTUbsan_minimal
- CFLAGS ${UBSAN_CFLAGS}
- PARENT_TARGET ubsan-minimal)
-
- add_compiler_rt_runtime(clang_rt.ubsan_minimal
- SHARED
- OS ${SANITIZER_COMMON_SUPPORTED_OS}
- ARCHS ${UBSAN_SUPPORTED_ARCH}
- OBJECT_LIBS RTUbsan_minimal
- CFLAGS ${UBSAN_CFLAGS}
- LINK_FLAGS ${UBSAN_LINK_FLAGS}
- LINK_LIBS ${UBSAN_DYNAMIC_LIBS}
- PARENT_TARGET ubsan-minimal)
-
- if (SANITIZER_USE_SYMBOLS AND NOT APPLE)
- set(ARCHS_FOR_SYMBOLS ${UBSAN_SUPPORTED_ARCH})
- list(REMOVE_ITEM ARCHS_FOR_SYMBOLS i386 i686)
- add_sanitizer_rt_symbols(clang_rt.ubsan_minimal
- ARCHS ${ARCHS_FOR_SYMBOLS}
- PARENT_TARGET ubsan-minimal
- EXTRA ubsan.syms.extra)
- endif()
-endif()
diff --git a/lib/xray/CMakeLists.txt b/lib/xray/CMakeLists.txt
deleted file mode 100644
index 0a86c52e62089..0000000000000
--- a/lib/xray/CMakeLists.txt
+++ /dev/null
@@ -1,296 +0,0 @@
-# Build for all components of the XRay runtime support library.
-
-# XRay runtime library implementation files.
-set(XRAY_SOURCES
- xray_buffer_queue.cc
- xray_init.cc
- xray_flags.cc
- xray_interface.cc
- xray_log_interface.cc
- xray_utils.cc)
-
-# Implementation files for all XRay modes.
-set(XRAY_FDR_MODE_SOURCES
- xray_fdr_flags.cc
- xray_fdr_logging.cc)
-
-set(XRAY_BASIC_MODE_SOURCES
- xray_basic_flags.cc
- xray_basic_logging.cc)
-
-set(XRAY_PROFILING_MODE_SOURCES
- xray_profile_collector.cc
- xray_profiling.cc
- xray_profiling_flags.cc)
-
-# Implementation files for all XRay architectures.
-set(x86_64_SOURCES
- xray_x86_64.cc
- xray_trampoline_x86_64.S)
-
-set(arm_SOURCES
- xray_arm.cc
- xray_trampoline_arm.S)
-
-set(armhf_SOURCES
- ${arm_SOURCES})
-
-set(aarch64_SOURCES
- xray_AArch64.cc
- xray_trampoline_AArch64.S)
-
-set(mips_SOURCES
- xray_mips.cc
- xray_trampoline_mips.S)
-
-set(mipsel_SOURCES
- xray_mips.cc
- xray_trampoline_mips.S)
-
-set(mips64_SOURCES
- xray_mips64.cc
- xray_trampoline_mips64.S)
-
-set(mips64el_SOURCES
- xray_mips64.cc
- xray_trampoline_mips64.S)
-
-set(powerpc64le_SOURCES
- xray_powerpc64.cc
- xray_trampoline_powerpc64.cc
- xray_trampoline_powerpc64_asm.S)
-
-set(XRAY_IMPL_HEADERS
- xray_allocator.h
- xray_basic_flags.h
- xray_basic_flags.inc
- xray_basic_logging.h
- xray_buffer_queue.h
- xray_defs.h
- xray_fdr_controller.h
- xray_fdr_flags.h
- xray_fdr_flags.inc
- xray_fdr_log_records.h
- xray_fdr_log_writer.h
- xray_fdr_logging.h
- xray_flags.h
- xray_flags.inc
- xray_function_call_trie.h
- xray_interface_internal.h
- xray_powerpc64.inc
- xray_profile_collector.h
- xray_profiling_flags.h
- xray_profiling_flags.inc
- xray_recursion_guard.h
- xray_segmented_array.h
- xray_tsc.h
- xray_utils.h
- xray_x86_64.inc)
-
-# Create list of all source files for
-# consumption by tests.
-set(XRAY_ALL_SOURCE_FILES
- ${XRAY_SOURCES}
- ${XRAY_FDR_MODE_SOURCES}
- ${XRAY_BASIC_MODE_SOURCES}
- ${XRAY_PROFILING_MODE_SOURCES}
- ${x86_64_SOURCES}
- ${arm_SOURCES}
- ${armhf_SOURCES}
- ${mips_SOURCES}
- ${mipsel_SOURCES}
- ${mips64_SOURCES}
- ${mips64el_SOURCES}
- ${powerpc64le_SOURCES}
- ${XRAY_IMPL_HEADERS}
-)
-list(REMOVE_DUPLICATES XRAY_ALL_SOURCE_FILES)
-# Make list that uses absolute paths
-set(XRAY_ALL_SOURCE_FILES_ABS_PATHS "")
-foreach (src_file ${XRAY_ALL_SOURCE_FILES})
- list(APPEND
- XRAY_ALL_SOURCE_FILES_ABS_PATHS
- "${CMAKE_CURRENT_SOURCE_DIR}/${src_file}")
-endforeach()
-
-
-# Now put it all together...
-include_directories(..)
-include_directories(../../include)
-
-set(XRAY_CFLAGS ${SANITIZER_COMMON_CFLAGS})
-set(XRAY_COMMON_DEFINITIONS XRAY_HAS_EXCEPTIONS=1)
-
-# We don't need RTTI in XRay, so turn that off.
-append_rtti_flag(OFF XRAY_CFLAGS)
-
-append_list_if(
- COMPILER_RT_HAS_XRAY_COMPILER_FLAG XRAY_SUPPORTED=1 XRAY_COMMON_DEFINITIONS)
-append_list_if(
- COMPILER_RT_BUILD_XRAY_NO_PREINIT XRAY_NO_PREINIT XRAY_COMMON_DEFINITIONS)
-
-add_compiler_rt_component(xray)
-
-set(XRAY_COMMON_RUNTIME_OBJECT_LIBS
- RTSanitizerCommon
- RTSanitizerCommonLibc)
-
-if (TARGET cxx-headers OR HAVE_LIBCXX)
- set(XRAY_DEPS cxx-headers)
-endif()
-
-if (APPLE)
- set(XRAY_LINK_LIBS ${SANITIZER_COMMON_LINK_LIBS})
- add_asm_sources(XRAY_ASM_SOURCES xray_trampoline_x86_64.S)
-
- add_weak_symbols("sanitizer_common" WEAK_SYMBOL_LINK_FLAGS)
- add_weak_symbols("xray" WEAK_SYMBOL_LINK_FLAGS)
-
- add_compiler_rt_object_libraries(RTXray
- OS ${XRAY_SUPPORTED_OS}
- ARCHS ${XRAY_SUPPORTED_ARCH}
- SOURCES ${XRAY_SOURCES} ${x86_64_SOURCES}
- ADDITIONAL_HEADERS ${XRAY_IMPL_HEADERS}
- CFLAGS ${XRAY_CFLAGS}
- DEFS ${XRAY_COMMON_DEFINITIONS}
- DEPS ${XRAY_DEPS})
- add_compiler_rt_object_libraries(RTXrayFDR
- OS ${XRAY_SUPPORTED_OS}
- ARCHS ${XRAY_SUPPORTED_ARCH}
- SOURCES ${XRAY_FDR_MODE_SOURCES}
- ADDITIONAL_HEADERS ${XRAY_IMPL_HEADERS}
- CFLAGS ${XRAY_CFLAGS}
- DEFS ${XRAY_COMMON_DEFINITIONS}
- DEPS ${XRAY_DEPS})
- add_compiler_rt_object_libraries(RTXrayBASIC
- OS ${XRAY_SUPPORTED_OS}
- ARCHS ${XRAY_SUPPORTED_ARCH}
- SOURCES ${XRAY_BASIC_MODE_SOURCES}
- ADDITIONAL_HEADERS ${XRAY_IMPL_HEADERS}
- CFLAGS ${XRAY_CFLAGS}
- DEFS ${XRAY_COMMON_DEFINITIONS}
- DEPS ${XRAY_DEPS})
- add_compiler_rt_object_libraries(RTXrayPROFILING
- OS ${XRAY_SUPPORTED_OS}
- ARCHS ${XRAY_SUPPORTED_ARCH}
- SOURCES ${XRAY_PROFILING_MODE_SOURCES}
- ADDITIONAL_HEADERS ${XRAY_IMPL_HEADERS}
- CFLAGS ${XRAY_CFLAGS}
- DEFS ${XRAY_COMMON_DEFINITIONS}
- DEPS ${XRAY_DEPS})
-
- # We only support running on osx for now.
- add_compiler_rt_runtime(clang_rt.xray
- STATIC
- OS ${XRAY_SUPPORTED_OS}
- ARCHS ${XRAY_SUPPORTED_ARCH}
- OBJECT_LIBS RTXray
- RTSanitizerCommon
- RTSanitizerCommonLibc
- CFLAGS ${XRAY_CFLAGS}
- DEFS ${XRAY_COMMON_DEFINITIONS}
- LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS}
- LINK_LIBS ${XRAY_LINK_LIBS}
- PARENT_TARGET xray)
- add_compiler_rt_runtime(clang_rt.xray-fdr
- STATIC
- OS ${XRAY_SUPPORTED_OS}
- ARCHS ${XRAY_SUPPORTED_ARCH}
- OBJECT_LIBS RTXrayFDR
- CFLAGS ${XRAY_CFLAGS}
- DEFS ${XRAY_COMMON_DEFINITIONS}
- LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS}
- LINK_LIBS ${XRAY_LINK_LIBS}
- PARENT_TARGET xray)
- add_compiler_rt_runtime(clang_rt.xray-basic
- STATIC
- OS ${XRAY_SUPPORTED_OS}
- ARCHS ${XRAY_SUPPORTED_ARCH}
- OBJECT_LIBS RTXrayBASIC
- CFLAGS ${XRAY_CFLAGS}
- DEFS ${XRAY_COMMON_DEFINITIONS}
- LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS}
- LINK_LIBS ${XRAY_LINK_LIBS}
- PARENT_TARGET xray)
- add_compiler_rt_runtime(clang_rt.xray-profiling
- STATIC
- OS ${XRAY_SUPPORTED_OS}
- ARCHS ${XRAY_SUPPORTED_ARCH}
- OBJECT_LIBS RTXrayPROFILING
- CFLAGS ${XRAY_CFLAGS}
- DEFS ${XRAY_COMMON_DEFINITIONS}
- LINK_FLAGS ${SANITIZER_COMMON_LINK_FLAGS} ${WEAK_SYMBOL_LINK_FLAGS}
- LINK_LIBS ${XRAY_LINK_LIBS}
- PARENT_TARGET xray)
-else() # not Apple
- foreach(arch ${XRAY_SUPPORTED_ARCH})
- if(NOT CAN_TARGET_${arch})
- continue()
- endif()
- add_compiler_rt_object_libraries(RTXray
- ARCHS ${arch}
- SOURCES ${XRAY_SOURCES} ${${arch}_SOURCES}
- ADDITIONAL_HEADERS ${XRAY_IMPL_HEADERS}
- CFLAGS ${XRAY_CFLAGS}
- DEFS ${XRAY_COMMON_DEFINITIONS}
- DEPS ${XRAY_DEPS})
- add_compiler_rt_object_libraries(RTXrayFDR
- ARCHS ${arch}
- SOURCES ${XRAY_FDR_MODE_SOURCES}
- ADDITIONAL_HEADERS ${XRAY_IMPL_HEADERS}
- CFLAGS ${XRAY_CFLAGS}
- DEFS ${XRAY_COMMON_DEFINITIONS}
- DEPS ${XRAY_DEPS})
- add_compiler_rt_object_libraries(RTXrayBASIC
- ARCHS ${arch}
- SOURCES ${XRAY_BASIC_MODE_SOURCES}
- ADDITIONAL_HEADERS ${XRAY_IMPL_HEADERS}
- CFLAGS ${XRAY_CFLAGS}
- DEFS ${XRAY_COMMON_DEFINITIONS}
- DEPS ${XRAY_DEPS})
- add_compiler_rt_object_libraries(RTXrayPROFILING
- ARCHS ${arch}
- SOURCES ${XRAY_PROFILING_MODE_SOURCES}
- ADDITIONAL_HEADERS ${XRAY_IMPL_HEADERS}
- CFLAGS ${XRAY_CFLAGS}
- DEFS ${XRAY_COMMON_DEFINITIONS}
- DEPS ${XRAY_DEPS})
-
- # Common XRay archive for instrumented binaries.
- add_compiler_rt_runtime(clang_rt.xray
- STATIC
- ARCHS ${arch}
- CFLAGS ${XRAY_CFLAGS}
- DEFS ${XRAY_COMMON_DEFINITIONS}
- OBJECT_LIBS ${XRAY_COMMON_RUNTIME_OBJECT_LIBS} RTXray
- PARENT_TARGET xray)
- # FDR mode runtime archive (addon for clang_rt.xray)
- add_compiler_rt_runtime(clang_rt.xray-fdr
- STATIC
- ARCHS ${arch}
- CFLAGS ${XRAY_CFLAGS}
- DEFS ${XRAY_COMMON_DEFINITIONS}
- OBJECT_LIBS RTXrayFDR
- PARENT_TARGET xray)
- # Basic mode runtime archive (addon for clang_rt.xray)
- add_compiler_rt_runtime(clang_rt.xray-basic
- STATIC
- ARCHS ${arch}
- CFLAGS ${XRAY_CFLAGS}
- DEFS ${XRAY_COMMON_DEFINITIONS}
- OBJECT_LIBS RTXrayBASIC
- PARENT_TARGET xray)
- # Profiler Mode runtime
- add_compiler_rt_runtime(clang_rt.xray-profiling
- STATIC
- ARCHS ${arch}
- CFLAGS ${XRAY_CFLAGS}
- DEFS ${XRAY_COMMON_DEFINITIONS}
- OBJECT_LIBS RTXrayPROFILING
- PARENT_TARGET xray)
- endforeach()
-endif() # not Apple
-
-if(COMPILER_RT_INCLUDE_TESTS)
- add_subdirectory(tests)
-endif()
diff --git a/lib/xray/tests/CMakeLists.txt b/lib/xray/tests/CMakeLists.txt
deleted file mode 100644
index 89a2b3b01ed8a..0000000000000
--- a/lib/xray/tests/CMakeLists.txt
+++ /dev/null
@@ -1,132 +0,0 @@
-include_directories(..)
-
-add_custom_target(XRayUnitTests)
-set_target_properties(XRayUnitTests PROPERTIES FOLDER "XRay unittests")
-
-# Sanity check XRAY_ALL_SOURCE_FILES_ABS_PATHS
-list(LENGTH XRAY_ALL_SOURCE_FILES_ABS_PATHS XASFAP_LENGTH)
-if (${XASFAP_LENGTH} EQUAL 0)
- message(FATAL_ERROR "XRAY_ALL_SOURCE_FILES_ABS_PATHS cannot be empty")
-endif()
-unset(XASFAP_LENGTH)
-foreach (src_file ${XRAY_ALL_SOURCE_FILES_ABS_PATHS})
- if (NOT EXISTS "${src_file}")
- message(FATAL_ERROR "Source file \"${src_file}\" does not exist")
- endif()
-endforeach()
-
-set(XRAY_UNITTEST_CFLAGS
- ${XRAY_CFLAGS}
- ${COMPILER_RT_UNITTEST_CFLAGS}
- ${COMPILER_RT_GTEST_CFLAGS}
- ${COMPILER_RT_GMOCK_CFLAGS}
- -I${COMPILER_RT_SOURCE_DIR}/include
- -I${COMPILER_RT_SOURCE_DIR}/lib/xray
- -I${COMPILER_RT_SOURCE_DIR}/lib
- )
-
-# We add the include directories one at a time in our CFLAGS.
-foreach (DIR ${LLVM_INCLUDE_DIR} ${LLVM_MAIN_INCLUDE_DIR})
- list(APPEND XRAY_UNITTEST_CFLAGS -I${DIR})
-endforeach()
-
-function(add_xray_lib library)
- add_library(${library} STATIC ${ARGN})
- set_target_properties(${library} PROPERTIES
- ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR}
- FOLDER "Compiler-RT Runtime tests")
-endfunction()
-
-function(get_xray_lib_for_arch arch lib)
- if(APPLE)
- set(tgt_name "RTXRay.test.osx")
- else()
- set(tgt_name "RTXRay.test.${arch}")
- endif()
- set(${lib} "${tgt_name}" PARENT_SCOPE)
-endfunction()
-
-set(XRAY_TEST_ARCH ${XRAY_SUPPORTED_ARCH})
-set(XRAY_UNITTEST_LINK_FLAGS
- ${CMAKE_THREAD_LIBS_INIT}
- -l${SANITIZER_CXX_ABI_LIBRARY})
-
-if (NOT APPLE)
- # Needed by LLVMSupport.
- append_list_if(
- COMPILER_RT_HAS_TERMINFO
- -l${COMPILER_RT_TERMINFO_LIB} XRAY_UNITTEST_LINK_FLAGS)
-
- if (COMPILER_RT_STANDALONE_BUILD)
- append_list_if(COMPILER_RT_HAS_LLVMXRAY ${LLVM_XRAY_LDFLAGS} XRAY_UNITTEST_LINK_FLAGS)
- append_list_if(COMPILER_RT_HAS_LLVMXRAY ${LLVM_XRAY_LIBLIST} XRAY_UNITTEST_LINK_FLAGS)
- append_list_if(COMPILER_RT_HAS_LLVMTESTINGSUPPORT
- ${LLVM_TESTINGSUPPORT_LDFLAGS} XRAY_UNITTEST_LINK_FLAGS)
- append_list_if(COMPILER_RT_HAS_LLVMTESTINGSUPPORT
- ${LLVM_TESTINGSUPPORT_LIBLIST} XRAY_UNITTEST_LINK_FLAGS)
- else()
- # We add the library directories one at a time in our CFLAGS.
- foreach (DIR ${LLVM_LIBRARY_DIR})
- list(APPEND XRAY_UNITTEST_LINK_FLAGS -L${DIR})
- endforeach()
-
- # We also add the actual libraries to link as dependencies.
- list(APPEND XRAY_UNITTEST_LINK_FLAGS -lLLVMXRay -lLLVMSupport -lLLVMTestingSupport)
- endif()
-
- append_list_if(COMPILER_RT_HAS_LIBM -lm XRAY_UNITTEST_LINK_FLAGS)
- append_list_if(COMPILER_RT_HAS_LIBRT -lrt XRAY_UNITTEST_LINK_FLAGS)
- append_list_if(COMPILER_RT_HAS_LIBDL -ldl XRAY_UNITTEST_LINK_FLAGS)
- append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread XRAY_UNITTEST_LINK_FLAGS)
-endif()
-
-macro(add_xray_unittest testname)
- cmake_parse_arguments(TEST "" "" "SOURCES;HEADERS" ${ARGN})
- if(UNIX AND NOT APPLE)
- set(CMAKE_DL_LIBS_INIT "")
- foreach(arch ${XRAY_TEST_ARCH})
- set(TEST_OBJECTS)
- get_xray_lib_for_arch(${arch} XRAY_RUNTIME_LIBS)
- generate_compiler_rt_tests(TEST_OBJECTS
- XRayUnitTests "${testname}-${arch}-Test" "${arch}"
- SOURCES ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE}
- ${COMPILER_RT_GMOCK_SOURCE}
-
- # Note that any change in the implementations will cause all the unit
- # tests to be re-built. This is by design, but may be cumbersome during
- # the build/test cycle.
- COMPILE_DEPS ${TEST_SOURCES} ${COMPILER_RT_GTEST_SOURCE}
- ${XRAY_HEADERS} ${XRAY_ALL_SOURCE_FILES_ABS_PATHS}
- "test_helpers.h"
- RUNTIME "${XRAY_RUNTIME_LIBS}"
- DEPS gtest xray llvm-xray LLVMXRay LLVMTestingSupport
- CFLAGS ${XRAY_UNITTEST_CFLAGS}
- LINK_FLAGS ${TARGET_LINK_FLAGS} ${XRAY_UNITTEST_LINK_FLAGS}
- )
- set_target_properties(XRayUnitTests
- PROPERTIES
- RUNTIME_OUTPUT_DIRECTORY ${CMAKE_CURRENT_BINARY_DIR})
- endforeach()
- endif()
-endmacro()
-
-if(COMPILER_RT_CAN_EXECUTE_TESTS)
- if (APPLE)
- add_xray_lib("RTXRay.test.osx"
- $<TARGET_OBJECTS:RTXray.osx>
- $<TARGET_OBJECTS:RTXrayFDR.osx>
- $<TARGET_OBJECTS:RTXrayPROFILING.osx>
- $<TARGET_OBJECTS:RTSanitizerCommon.osx>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.osx>)
- else()
- foreach(arch ${XRAY_SUPPORTED_ARCH})
- add_xray_lib("RTXRay.test.${arch}"
- $<TARGET_OBJECTS:RTXray.${arch}>
- $<TARGET_OBJECTS:RTXrayFDR.${arch}>
- $<TARGET_OBJECTS:RTXrayPROFILING.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommon.${arch}>
- $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>)
- endforeach()
- endif()
- add_subdirectory(unit)
-endif()
diff --git a/lib/xray/tests/unit/CMakeLists.txt b/lib/xray/tests/unit/CMakeLists.txt
deleted file mode 100644
index d10524b8d030a..0000000000000
--- a/lib/xray/tests/unit/CMakeLists.txt
+++ /dev/null
@@ -1,16 +0,0 @@
-set(TEST_SOURCES
- allocator_test.cc
- buffer_queue_test.cc
- function_call_trie_test.cc
- profile_collector_test.cc
- segmented_array_test.cc
- test_helpers.cc
- xray_unit_test_main.cc)
-
-if (NOT COMPILER_RT_STANDALONE_BUILD OR COMPILER_RT_HAS_LLVMTESTINGSUPPORT)
- list(APPEND TEST_SOURCES
- fdr_controller_test.cc
- fdr_log_writer_test.cc)
-endif()
-
-add_xray_unittest(XRayTest SOURCES ${TEST_SOURCES})
diff --git a/lib/xray/tests/unit/allocator_test.cc b/lib/xray/tests/unit/allocator_test.cc
deleted file mode 100644
index 1170741623cbe..0000000000000
--- a/lib/xray/tests/unit/allocator_test.cc
+++ /dev/null
@@ -1,82 +0,0 @@
-//===-- allocator_test.cc -------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of XRay, a function call tracing system.
-//
-//===----------------------------------------------------------------------===//
-
-#include "xray_allocator.h"
-#include "xray_buffer_queue.h"
-#include "gtest/gtest.h"
-
-namespace __xray {
-namespace {
-
-struct TestData {
- s64 First;
- s64 Second;
-};
-
-TEST(AllocatorTest, Construction) { Allocator<sizeof(TestData)> A(2 << 11); }
-
-TEST(AllocatorTest, Allocate) {
- Allocator<sizeof(TestData)> A(2 << 11);
- auto B = A.Allocate();
- ASSERT_NE(B.Data, nullptr);
-}
-
-TEST(AllocatorTest, OverAllocate) {
- Allocator<sizeof(TestData)> A(sizeof(TestData));
- auto B1 = A.Allocate();
- ASSERT_NE(B1.Data, nullptr);
- auto B2 = A.Allocate();
- ASSERT_EQ(B2.Data, nullptr);
-}
-
-struct OddSizedData {
- s64 A;
- s32 B;
-};
-
-TEST(AllocatorTest, AllocateBoundaries) {
- Allocator<sizeof(OddSizedData)> A(GetPageSizeCached());
-
- // Keep allocating until we hit a nullptr block.
- unsigned C = 0;
- auto Expected =
- GetPageSizeCached() / RoundUpTo(sizeof(OddSizedData), kCacheLineSize);
- for (auto B = A.Allocate(); B.Data != nullptr; B = A.Allocate(), ++C)
- ;
-
- ASSERT_EQ(C, Expected);
-}
-
-TEST(AllocatorTest, AllocateFromNonOwned) {
- bool Success = false;
- BufferQueue BQ(GetPageSizeCached(), 10, Success);
- ASSERT_TRUE(Success);
- BufferQueue::Buffer B;
- ASSERT_EQ(BQ.getBuffer(B), BufferQueue::ErrorCode::Ok);
- {
- Allocator<sizeof(OddSizedData)> A(B.Data, B.Size);
-
- // Keep allocating until we hit a nullptr block.
- unsigned C = 0;
- auto Expected =
- GetPageSizeCached() / RoundUpTo(sizeof(OddSizedData), kCacheLineSize);
- for (auto B = A.Allocate(); B.Data != nullptr; B = A.Allocate(), ++C)
- ;
-
- ASSERT_EQ(C, Expected);
- }
- ASSERT_EQ(BQ.releaseBuffer(B), BufferQueue::ErrorCode::Ok);
-}
-
-} // namespace
-} // namespace __xray
diff --git a/lib/xray/tests/unit/buffer_queue_test.cc b/lib/xray/tests/unit/buffer_queue_test.cc
deleted file mode 100644
index a30343e188f28..0000000000000
--- a/lib/xray/tests/unit/buffer_queue_test.cc
+++ /dev/null
@@ -1,235 +0,0 @@
-//===-- buffer_queue_test.cc ----------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of XRay, a function call tracing system.
-//
-//===----------------------------------------------------------------------===//
-#include "xray_buffer_queue.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-#include <atomic>
-#include <future>
-#include <thread>
-#include <unistd.h>
-
-namespace __xray {
-namespace {
-
-static constexpr size_t kSize = 4096;
-
-using ::testing::Eq;
-
-TEST(BufferQueueTest, API) {
- bool Success = false;
- BufferQueue Buffers(kSize, 1, Success);
- ASSERT_TRUE(Success);
-}
-
-TEST(BufferQueueTest, GetAndRelease) {
- bool Success = false;
- BufferQueue Buffers(kSize, 1, Success);
- ASSERT_TRUE(Success);
- BufferQueue::Buffer Buf;
- ASSERT_EQ(Buffers.getBuffer(Buf), BufferQueue::ErrorCode::Ok);
- ASSERT_NE(nullptr, Buf.Data);
- ASSERT_EQ(Buffers.releaseBuffer(Buf), BufferQueue::ErrorCode::Ok);
- ASSERT_EQ(nullptr, Buf.Data);
-}
-
-TEST(BufferQueueTest, GetUntilFailed) {
- bool Success = false;
- BufferQueue Buffers(kSize, 1, Success);
- ASSERT_TRUE(Success);
- BufferQueue::Buffer Buf0;
- EXPECT_EQ(Buffers.getBuffer(Buf0), BufferQueue::ErrorCode::Ok);
- BufferQueue::Buffer Buf1;
- EXPECT_EQ(BufferQueue::ErrorCode::NotEnoughMemory, Buffers.getBuffer(Buf1));
- EXPECT_EQ(Buffers.releaseBuffer(Buf0), BufferQueue::ErrorCode::Ok);
-}
-
-TEST(BufferQueueTest, ReleaseUnknown) {
- bool Success = false;
- BufferQueue Buffers(kSize, 1, Success);
- ASSERT_TRUE(Success);
- BufferQueue::Buffer Buf;
- Buf.Data = reinterpret_cast<void *>(0xdeadbeef);
- Buf.Size = kSize;
- Buf.Generation = Buffers.generation();
-
- BufferQueue::Buffer Known;
- EXPECT_THAT(Buffers.getBuffer(Known), Eq(BufferQueue::ErrorCode::Ok));
- EXPECT_THAT(Buffers.releaseBuffer(Buf),
- Eq(BufferQueue::ErrorCode::UnrecognizedBuffer));
- EXPECT_THAT(Buffers.releaseBuffer(Known), Eq(BufferQueue::ErrorCode::Ok));
-}
-
-TEST(BufferQueueTest, ErrorsWhenFinalising) {
- bool Success = false;
- BufferQueue Buffers(kSize, 2, Success);
- ASSERT_TRUE(Success);
- BufferQueue::Buffer Buf;
- ASSERT_EQ(Buffers.getBuffer(Buf), BufferQueue::ErrorCode::Ok);
- ASSERT_NE(nullptr, Buf.Data);
- ASSERT_EQ(Buffers.finalize(), BufferQueue::ErrorCode::Ok);
- BufferQueue::Buffer OtherBuf;
- ASSERT_EQ(BufferQueue::ErrorCode::QueueFinalizing,
- Buffers.getBuffer(OtherBuf));
- ASSERT_EQ(BufferQueue::ErrorCode::QueueFinalizing, Buffers.finalize());
- ASSERT_EQ(Buffers.releaseBuffer(Buf), BufferQueue::ErrorCode::Ok);
-}
-
-TEST(BufferQueueTest, MultiThreaded) {
- bool Success = false;
- BufferQueue Buffers(kSize, 100, Success);
- ASSERT_TRUE(Success);
- auto F = [&] {
- BufferQueue::Buffer B;
- while (true) {
- auto EC = Buffers.getBuffer(B);
- if (EC != BufferQueue::ErrorCode::Ok)
- return;
- Buffers.releaseBuffer(B);
- }
- };
- auto T0 = std::async(std::launch::async, F);
- auto T1 = std::async(std::launch::async, F);
- auto T2 = std::async(std::launch::async, [&] {
- while (Buffers.finalize() != BufferQueue::ErrorCode::Ok)
- ;
- });
- F();
-}
-
-TEST(BufferQueueTest, Apply) {
- bool Success = false;
- BufferQueue Buffers(kSize, 10, Success);
- ASSERT_TRUE(Success);
- auto Count = 0;
- BufferQueue::Buffer B;
- for (int I = 0; I < 10; ++I) {
- ASSERT_EQ(Buffers.getBuffer(B), BufferQueue::ErrorCode::Ok);
- ASSERT_EQ(Buffers.releaseBuffer(B), BufferQueue::ErrorCode::Ok);
- }
- Buffers.apply([&](const BufferQueue::Buffer &B) { ++Count; });
- ASSERT_EQ(Count, 10);
-}
-
-TEST(BufferQueueTest, GenerationalSupport) {
- bool Success = false;
- BufferQueue Buffers(kSize, 10, Success);
- ASSERT_TRUE(Success);
- BufferQueue::Buffer B0;
- ASSERT_EQ(Buffers.getBuffer(B0), BufferQueue::ErrorCode::Ok);
- ASSERT_EQ(Buffers.finalize(),
- BufferQueue::ErrorCode::Ok); // No more new buffers.
-
- // Re-initialise the queue.
- ASSERT_EQ(Buffers.init(kSize, 10), BufferQueue::ErrorCode::Ok);
-
- BufferQueue::Buffer B1;
- ASSERT_EQ(Buffers.getBuffer(B1), BufferQueue::ErrorCode::Ok);
-
- // Validate that the buffers come from different generations.
- ASSERT_NE(B0.Generation, B1.Generation);
-
- // We stash the current generation, for use later.
- auto PrevGen = B1.Generation;
-
- // At this point, we want to ensure that we can return the buffer from the
- // first "generation" would still be accepted in the new generation...
- EXPECT_EQ(Buffers.releaseBuffer(B0), BufferQueue::ErrorCode::Ok);
-
- // ... and that the new buffer is also accepted.
- EXPECT_EQ(Buffers.releaseBuffer(B1), BufferQueue::ErrorCode::Ok);
-
- // A next round will do the same, ensure that we are able to do multiple
- // rounds in this case.
- ASSERT_EQ(Buffers.finalize(), BufferQueue::ErrorCode::Ok);
- ASSERT_EQ(Buffers.init(kSize, 10), BufferQueue::ErrorCode::Ok);
- EXPECT_EQ(Buffers.getBuffer(B0), BufferQueue::ErrorCode::Ok);
- EXPECT_EQ(Buffers.getBuffer(B1), BufferQueue::ErrorCode::Ok);
-
- // Here we ensure that the generation is different from the previous
- // generation.
- EXPECT_NE(B0.Generation, PrevGen);
- EXPECT_EQ(B1.Generation, B1.Generation);
- ASSERT_EQ(Buffers.finalize(), BufferQueue::ErrorCode::Ok);
- EXPECT_EQ(Buffers.releaseBuffer(B0), BufferQueue::ErrorCode::Ok);
- EXPECT_EQ(Buffers.releaseBuffer(B1), BufferQueue::ErrorCode::Ok);
-}
-
-TEST(BufferQueueTest, GenerationalSupportAcrossThreads) {
- bool Success = false;
- BufferQueue Buffers(kSize, 10, Success);
- ASSERT_TRUE(Success);
-
- std::atomic<int> Counter{0};
-
- // This function allows us to use thread-local storage to isolate the
- // instances of the buffers to be used. It also allows us signal the threads
- // of a new generation, and allow those to get new buffers. This is
- // representative of how we expect the buffer queue to be used by the XRay
- // runtime.
- auto Process = [&] {
- thread_local BufferQueue::Buffer B;
- ASSERT_EQ(Buffers.getBuffer(B), BufferQueue::ErrorCode::Ok);
- auto FirstGen = B.Generation;
-
- // Signal that we've gotten a buffer in the thread.
- Counter.fetch_add(1, std::memory_order_acq_rel);
- while (!Buffers.finalizing()) {
- Buffers.releaseBuffer(B);
- Buffers.getBuffer(B);
- }
-
- // Signal that we've exited the get/release buffer loop.
- Counter.fetch_sub(1, std::memory_order_acq_rel);
- if (B.Data != nullptr)
- Buffers.releaseBuffer(B);
-
- // Spin until we find that the Buffer Queue is no longer finalizing.
- while (Buffers.getBuffer(B) != BufferQueue::ErrorCode::Ok)
- ;
-
- // Signal that we've successfully gotten a buffer in the thread.
- Counter.fetch_add(1, std::memory_order_acq_rel);
-
- EXPECT_NE(FirstGen, B.Generation);
- EXPECT_EQ(Buffers.releaseBuffer(B), BufferQueue::ErrorCode::Ok);
-
- // Signal that we've successfully exited.
- Counter.fetch_sub(1, std::memory_order_acq_rel);
- };
-
- // Spawn two threads running Process.
- std::thread T0(Process), T1(Process);
-
- // Spin until we find the counter is up to 2.
- while (Counter.load(std::memory_order_acquire) != 2)
- ;
-
- // Then we finalize, then re-initialize immediately.
- Buffers.finalize();
-
- // Spin until we find the counter is down to 0.
- while (Counter.load(std::memory_order_acquire) != 0)
- ;
-
- // Then we re-initialize.
- EXPECT_EQ(Buffers.init(kSize, 10), BufferQueue::ErrorCode::Ok);
-
- T0.join();
- T1.join();
-
- ASSERT_EQ(Counter.load(std::memory_order_acquire), 0);
-}
-
-} // namespace
-} // namespace __xray
diff --git a/lib/xray/tests/unit/fdr_controller_test.cc b/lib/xray/tests/unit/fdr_controller_test.cc
deleted file mode 100644
index 8967c4919ae67..0000000000000
--- a/lib/xray/tests/unit/fdr_controller_test.cc
+++ /dev/null
@@ -1,424 +0,0 @@
-//===-- fdr_controller_test.cc --------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of XRay, a function call tracing system.
-//
-//===----------------------------------------------------------------------===//
-#include <algorithm>
-#include <memory>
-#include <time.h>
-
-#include "test_helpers.h"
-#include "xray/xray_records.h"
-#include "xray_buffer_queue.h"
-#include "xray_fdr_controller.h"
-#include "xray_fdr_log_writer.h"
-#include "llvm/Support/DataExtractor.h"
-#include "llvm/Testing/Support/Error.h"
-#include "llvm/XRay/Trace.h"
-#include "llvm/XRay/XRayRecord.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-namespace __xray {
-namespace {
-
-using ::llvm::HasValue;
-using ::llvm::xray::testing::FuncId;
-using ::llvm::xray::testing::HasArg;
-using ::llvm::xray::testing::RecordType;
-using ::llvm::xray::testing::TSCIs;
-using ::testing::AllOf;
-using ::testing::ElementsAre;
-using ::testing::Eq;
-using ::testing::Field;
-using ::testing::Gt;
-using ::testing::IsEmpty;
-using ::testing::SizeIs;
-
-class FunctionSequenceTest : public ::testing::Test {
-protected:
- BufferQueue::Buffer B{};
- std::unique_ptr<BufferQueue> BQ;
- std::unique_ptr<FDRLogWriter> W;
- std::unique_ptr<FDRController<>> C;
-
-public:
- void SetUp() override {
- bool Success;
- BQ = llvm::make_unique<BufferQueue>(4096, 1, Success);
- ASSERT_TRUE(Success);
- ASSERT_EQ(BQ->getBuffer(B), BufferQueue::ErrorCode::Ok);
- W = llvm::make_unique<FDRLogWriter>(B);
- C = llvm::make_unique<FDRController<>>(BQ.get(), B, *W, clock_gettime, 0);
- }
-};
-
-TEST_F(FunctionSequenceTest, DefaultInitFinalizeFlush) {
- ASSERT_TRUE(C->functionEnter(1, 2, 3));
- ASSERT_TRUE(C->functionExit(1, 2, 3));
- ASSERT_TRUE(C->flush());
- ASSERT_EQ(BQ->finalize(), BufferQueue::ErrorCode::Ok);
-
- // Serialize the buffers then test to see we find the expected records.
- std::string Serialized = serialize(*BQ, 3);
- llvm::DataExtractor DE(Serialized, true, 8);
- auto TraceOrErr = llvm::xray::loadTrace(DE);
- EXPECT_THAT_EXPECTED(
- TraceOrErr,
- HasValue(ElementsAre(
- AllOf(FuncId(1), RecordType(llvm::xray::RecordTypes::ENTER)),
- AllOf(FuncId(1), RecordType(llvm::xray::RecordTypes::EXIT)))));
-}
-
-TEST_F(FunctionSequenceTest, BoundaryFuncIdEncoding) {
- // We ensure that we can write function id's that are at the boundary of the
- // acceptable function ids.
- int32_t FId = (1 << 28) - 1;
- uint64_t TSC = 2;
- uint16_t CPU = 1;
- ASSERT_TRUE(C->functionEnter(FId, TSC++, CPU));
- ASSERT_TRUE(C->functionExit(FId, TSC++, CPU));
- ASSERT_TRUE(C->functionEnterArg(FId, TSC++, CPU, 1));
- ASSERT_TRUE(C->functionTailExit(FId, TSC++, CPU));
- ASSERT_TRUE(C->flush());
- ASSERT_EQ(BQ->finalize(), BufferQueue::ErrorCode::Ok);
-
- // Serialize the buffers then test to see we find the expected records.
- std::string Serialized = serialize(*BQ, 3);
- llvm::DataExtractor DE(Serialized, true, 8);
- auto TraceOrErr = llvm::xray::loadTrace(DE);
- EXPECT_THAT_EXPECTED(
- TraceOrErr,
- HasValue(ElementsAre(
- AllOf(FuncId(FId), RecordType(llvm::xray::RecordTypes::ENTER)),
- AllOf(FuncId(FId), RecordType(llvm::xray::RecordTypes::EXIT)),
- AllOf(FuncId(FId), RecordType(llvm::xray::RecordTypes::ENTER_ARG)),
- AllOf(FuncId(FId), RecordType(llvm::xray::RecordTypes::TAIL_EXIT)))));
-}
-
-TEST_F(FunctionSequenceTest, ThresholdsAreEnforced) {
- C = llvm::make_unique<FDRController<>>(BQ.get(), B, *W, clock_gettime, 1000);
- ASSERT_TRUE(C->functionEnter(1, 2, 3));
- ASSERT_TRUE(C->functionExit(1, 2, 3));
- ASSERT_TRUE(C->flush());
- ASSERT_EQ(BQ->finalize(), BufferQueue::ErrorCode::Ok);
-
- // Serialize the buffers then test to see we find the *no* records, because
- // the function entry-exit comes under the cycle threshold.
- std::string Serialized = serialize(*BQ, 3);
- llvm::DataExtractor DE(Serialized, true, 8);
- auto TraceOrErr = llvm::xray::loadTrace(DE);
- EXPECT_THAT_EXPECTED(TraceOrErr, HasValue(IsEmpty()));
-}
-
-TEST_F(FunctionSequenceTest, ArgsAreHandledAndKept) {
- C = llvm::make_unique<FDRController<>>(BQ.get(), B, *W, clock_gettime, 1000);
- ASSERT_TRUE(C->functionEnterArg(1, 2, 3, 4));
- ASSERT_TRUE(C->functionExit(1, 2, 3));
- ASSERT_TRUE(C->flush());
- ASSERT_EQ(BQ->finalize(), BufferQueue::ErrorCode::Ok);
-
- // Serialize the buffers then test to see we find the function enter arg
- // record with the specified argument.
- std::string Serialized = serialize(*BQ, 3);
- llvm::DataExtractor DE(Serialized, true, 8);
- auto TraceOrErr = llvm::xray::loadTrace(DE);
- EXPECT_THAT_EXPECTED(
- TraceOrErr,
- HasValue(ElementsAre(
- AllOf(FuncId(1), RecordType(llvm::xray::RecordTypes::ENTER_ARG),
- HasArg(4)),
- AllOf(FuncId(1), RecordType(llvm::xray::RecordTypes::EXIT)))));
-}
-
-TEST_F(FunctionSequenceTest, PreservedCallsHaveCorrectTSC) {
- C = llvm::make_unique<FDRController<>>(BQ.get(), B, *W, clock_gettime, 1000);
- uint64_t TSC = 1;
- uint16_t CPU = 0;
- ASSERT_TRUE(C->functionEnter(1, TSC++, CPU));
- ASSERT_TRUE(C->functionEnter(2, TSC++, CPU));
- ASSERT_TRUE(C->functionExit(2, TSC++, CPU));
- ASSERT_TRUE(C->functionExit(1, TSC += 1000, CPU));
- ASSERT_TRUE(C->flush());
- ASSERT_EQ(BQ->finalize(), BufferQueue::ErrorCode::Ok);
-
- // Serialize the buffers then test to see if we find the remaining records,
- // because the function entry-exit comes under the cycle threshold.
- std::string Serialized = serialize(*BQ, 3);
- llvm::DataExtractor DE(Serialized, true, 8);
- auto TraceOrErr = llvm::xray::loadTrace(DE);
- EXPECT_THAT_EXPECTED(
- TraceOrErr,
- HasValue(ElementsAre(
- AllOf(FuncId(1), RecordType(llvm::xray::RecordTypes::ENTER),
- TSCIs(Eq(1uL))),
- AllOf(FuncId(1), RecordType(llvm::xray::RecordTypes::EXIT),
- TSCIs(Gt(1000uL))))));
-}
-
-TEST_F(FunctionSequenceTest, PreservedCallsSupportLargeDeltas) {
- C = llvm::make_unique<FDRController<>>(BQ.get(), B, *W, clock_gettime, 1000);
- uint64_t TSC = 1;
- uint16_t CPU = 0;
- const auto LargeDelta = uint64_t{std::numeric_limits<int32_t>::max()};
- ASSERT_TRUE(C->functionEnter(1, TSC++, CPU));
- ASSERT_TRUE(C->functionExit(1, TSC += LargeDelta, CPU));
- ASSERT_TRUE(C->flush());
- ASSERT_EQ(BQ->finalize(), BufferQueue::ErrorCode::Ok);
-
- // Serialize the buffer then test to see if we find the right TSC with a large
- // delta.
- std::string Serialized = serialize(*BQ, 3);
- llvm::DataExtractor DE(Serialized, true, 8);
- auto TraceOrErr = llvm::xray::loadTrace(DE);
- EXPECT_THAT_EXPECTED(
- TraceOrErr,
- HasValue(ElementsAre(
- AllOf(FuncId(1), RecordType(llvm::xray::RecordTypes::ENTER),
- TSCIs(Eq(1uL))),
- AllOf(FuncId(1), RecordType(llvm::xray::RecordTypes::EXIT),
- TSCIs(Gt(LargeDelta))))));
-}
-
-TEST_F(FunctionSequenceTest, RewindingMultipleCalls) {
- C = llvm::make_unique<FDRController<>>(BQ.get(), B, *W, clock_gettime, 1000);
-
- // First we construct an arbitrarily deep function enter/call stack.
- // We also ensure that we are in the same CPU.
- uint64_t TSC = 1;
- uint16_t CPU = 1;
- ASSERT_TRUE(C->functionEnter(1, TSC++, CPU));
- ASSERT_TRUE(C->functionEnter(2, TSC++, CPU));
- ASSERT_TRUE(C->functionEnter(3, TSC++, CPU));
-
- // Then we exit them one at a time, in reverse order of entry.
- ASSERT_TRUE(C->functionExit(3, TSC++, CPU));
- ASSERT_TRUE(C->functionExit(2, TSC++, CPU));
- ASSERT_TRUE(C->functionExit(1, TSC++, CPU));
-
- ASSERT_TRUE(C->flush());
- ASSERT_EQ(BQ->finalize(), BufferQueue::ErrorCode::Ok);
-
- // Serialize the buffers then test to see we find that all the calls have been
- // unwound because all of them are under the cycle counter threshold.
- std::string Serialized = serialize(*BQ, 3);
- llvm::DataExtractor DE(Serialized, true, 8);
- auto TraceOrErr = llvm::xray::loadTrace(DE);
- EXPECT_THAT_EXPECTED(TraceOrErr, HasValue(IsEmpty()));
-}
-
-TEST_F(FunctionSequenceTest, RewindingIntermediaryTailExits) {
- C = llvm::make_unique<FDRController<>>(BQ.get(), B, *W, clock_gettime, 1000);
-
- // First we construct an arbitrarily deep function enter/call stack.
- // We also ensure that we are in the same CPU.
- uint64_t TSC = 1;
- uint16_t CPU = 1;
- ASSERT_TRUE(C->functionEnter(1, TSC++, CPU));
- ASSERT_TRUE(C->functionEnter(2, TSC++, CPU));
- ASSERT_TRUE(C->functionEnter(3, TSC++, CPU));
-
- // Next we tail-exit into a new function multiple times.
- ASSERT_TRUE(C->functionTailExit(3, TSC++, CPU));
- ASSERT_TRUE(C->functionEnter(4, TSC++, CPU));
- ASSERT_TRUE(C->functionTailExit(4, TSC++, CPU));
- ASSERT_TRUE(C->functionEnter(5, TSC++, CPU));
- ASSERT_TRUE(C->functionTailExit(5, TSC++, CPU));
- ASSERT_TRUE(C->functionEnter(6, TSC++, CPU));
-
- // Then we exit them one at a time, in reverse order of entry.
- ASSERT_TRUE(C->functionExit(6, TSC++, CPU));
- ASSERT_TRUE(C->functionExit(2, TSC++, CPU));
- ASSERT_TRUE(C->functionExit(1, TSC++, CPU));
- ASSERT_TRUE(C->flush());
- ASSERT_EQ(BQ->finalize(), BufferQueue::ErrorCode::Ok);
-
- // Serialize the buffers then test to see we find that all the calls have been
- // unwound because all of them are under the cycle counter threshold.
- std::string Serialized = serialize(*BQ, 3);
- llvm::DataExtractor DE(Serialized, true, 8);
- auto TraceOrErr = llvm::xray::loadTrace(DE);
- EXPECT_THAT_EXPECTED(TraceOrErr, HasValue(IsEmpty()));
-}
-
-TEST_F(FunctionSequenceTest, RewindingAfterMigration) {
- C = llvm::make_unique<FDRController<>>(BQ.get(), B, *W, clock_gettime, 1000);
-
- // First we construct an arbitrarily deep function enter/call stack.
- // We also ensure that we are in the same CPU.
- uint64_t TSC = 1;
- uint16_t CPU = 1;
- ASSERT_TRUE(C->functionEnter(1, TSC++, CPU));
- ASSERT_TRUE(C->functionEnter(2, TSC++, CPU));
- ASSERT_TRUE(C->functionEnter(3, TSC++, CPU));
-
- // Next we tail-exit into a new function multiple times.
- ASSERT_TRUE(C->functionTailExit(3, TSC++, CPU));
- ASSERT_TRUE(C->functionEnter(4, TSC++, CPU));
- ASSERT_TRUE(C->functionTailExit(4, TSC++, CPU));
-
- // But before we enter the next function, we migrate to a different CPU.
- CPU = 2;
- ASSERT_TRUE(C->functionEnter(5, TSC++, CPU));
- ASSERT_TRUE(C->functionTailExit(5, TSC++, CPU));
- ASSERT_TRUE(C->functionEnter(6, TSC++, CPU));
-
- // Then we exit them one at a time, in reverse order of entry.
- ASSERT_TRUE(C->functionExit(6, TSC++, CPU));
- ASSERT_TRUE(C->functionExit(2, TSC++, CPU));
- ASSERT_TRUE(C->functionExit(1, TSC++, CPU));
-
- ASSERT_TRUE(C->flush());
- ASSERT_EQ(BQ->finalize(), BufferQueue::ErrorCode::Ok);
-
- // Serialize buffers then test that we can find all the events that span the
- // CPU migration.
- std::string Serialized = serialize(*BQ, 3);
- llvm::DataExtractor DE(Serialized, true, 8);
- auto TraceOrErr = llvm::xray::loadTrace(DE);
- EXPECT_THAT_EXPECTED(
- TraceOrErr,
- HasValue(ElementsAre(
- AllOf(FuncId(1), RecordType(llvm::xray::RecordTypes::ENTER)),
- AllOf(FuncId(2), RecordType(llvm::xray::RecordTypes::ENTER)),
- AllOf(FuncId(2), RecordType(llvm::xray::RecordTypes::EXIT)),
- AllOf(FuncId(1), RecordType(llvm::xray::RecordTypes::EXIT)))));
-}
-
-class BufferManagementTest : public ::testing::Test {
-protected:
- BufferQueue::Buffer B{};
- std::unique_ptr<BufferQueue> BQ;
- std::unique_ptr<FDRLogWriter> W;
- std::unique_ptr<FDRController<>> C;
-
- static constexpr size_t kBuffers = 10;
-
-public:
- void SetUp() override {
- bool Success;
- BQ = llvm::make_unique<BufferQueue>(sizeof(MetadataRecord) * 5 +
- sizeof(FunctionRecord) * 2,
- kBuffers, Success);
- ASSERT_TRUE(Success);
- ASSERT_EQ(BQ->getBuffer(B), BufferQueue::ErrorCode::Ok);
- W = llvm::make_unique<FDRLogWriter>(B);
- C = llvm::make_unique<FDRController<>>(BQ.get(), B, *W, clock_gettime, 0);
- }
-};
-
-constexpr size_t BufferManagementTest::kBuffers;
-
-TEST_F(BufferManagementTest, HandlesOverflow) {
- uint64_t TSC = 1;
- uint16_t CPU = 1;
- for (size_t I = 0; I < kBuffers + 1; ++I) {
- ASSERT_TRUE(C->functionEnter(1, TSC++, CPU));
- ASSERT_TRUE(C->functionExit(1, TSC++, CPU));
- }
- ASSERT_TRUE(C->flush());
- ASSERT_THAT(BQ->finalize(), Eq(BufferQueue::ErrorCode::Ok));
-
- std::string Serialized = serialize(*BQ, 3);
- llvm::DataExtractor DE(Serialized, true, 8);
- auto TraceOrErr = llvm::xray::loadTrace(DE);
- EXPECT_THAT_EXPECTED(TraceOrErr, HasValue(SizeIs(kBuffers * 2)));
-}
-
-TEST_F(BufferManagementTest, HandlesOverflowWithArgs) {
- uint64_t TSC = 1;
- uint16_t CPU = 1;
- uint64_t ARG = 1;
- for (size_t I = 0; I < kBuffers + 1; ++I) {
- ASSERT_TRUE(C->functionEnterArg(1, TSC++, CPU, ARG++));
- ASSERT_TRUE(C->functionExit(1, TSC++, CPU));
- }
- ASSERT_TRUE(C->flush());
- ASSERT_THAT(BQ->finalize(), Eq(BufferQueue::ErrorCode::Ok));
-
- std::string Serialized = serialize(*BQ, 3);
- llvm::DataExtractor DE(Serialized, true, 8);
- auto TraceOrErr = llvm::xray::loadTrace(DE);
- EXPECT_THAT_EXPECTED(TraceOrErr, HasValue(SizeIs(kBuffers)));
-}
-
-TEST_F(BufferManagementTest, HandlesOverflowWithCustomEvents) {
- uint64_t TSC = 1;
- uint16_t CPU = 1;
- int32_t D = 0x9009;
- for (size_t I = 0; I < kBuffers; ++I) {
- ASSERT_TRUE(C->functionEnter(1, TSC++, CPU));
- ASSERT_TRUE(C->functionExit(1, TSC++, CPU));
- ASSERT_TRUE(C->customEvent(TSC++, CPU, &D, sizeof(D)));
- }
- ASSERT_TRUE(C->flush());
- ASSERT_THAT(BQ->finalize(), Eq(BufferQueue::ErrorCode::Ok));
-
- std::string Serialized = serialize(*BQ, 3);
- llvm::DataExtractor DE(Serialized, true, 8);
- auto TraceOrErr = llvm::xray::loadTrace(DE);
-
- // We expect to also now count the kBuffers/2 custom event records showing up
- // in the Trace.
- EXPECT_THAT_EXPECTED(TraceOrErr, HasValue(SizeIs(kBuffers + (kBuffers / 2))));
-}
-
-TEST_F(BufferManagementTest, HandlesFinalizedBufferQueue) {
- uint64_t TSC = 1;
- uint16_t CPU = 1;
-
- // First write one function entry.
- ASSERT_TRUE(C->functionEnter(1, TSC++, CPU));
-
- // Then we finalize the buffer queue, simulating the case where the logging
- // has been finalized.
- ASSERT_EQ(BQ->finalize(), BufferQueue::ErrorCode::Ok);
-
- // At this point further calls to the controller must fail.
- ASSERT_FALSE(C->functionExit(1, TSC++, CPU));
-
- // But flushing should succeed.
- ASSERT_TRUE(C->flush());
-
- // We expect that we'll only be able to find the function enter event, but not
- // the function exit event.
- std::string Serialized = serialize(*BQ, 3);
- llvm::DataExtractor DE(Serialized, true, 8);
- auto TraceOrErr = llvm::xray::loadTrace(DE);
- EXPECT_THAT_EXPECTED(
- TraceOrErr, HasValue(ElementsAre(AllOf(
- FuncId(1), RecordType(llvm::xray::RecordTypes::ENTER)))));
-}
-
-TEST_F(BufferManagementTest, HandlesGenerationalBufferQueue) {
- uint64_t TSC = 1;
- uint16_t CPU = 1;
-
- ASSERT_TRUE(C->functionEnter(1, TSC++, CPU));
- ASSERT_THAT(BQ->finalize(), Eq(BufferQueue::ErrorCode::Ok));
- ASSERT_THAT(BQ->init(sizeof(MetadataRecord) * 4 + sizeof(FunctionRecord) * 2,
- kBuffers),
- Eq(BufferQueue::ErrorCode::Ok));
- EXPECT_TRUE(C->functionExit(1, TSC++, CPU));
- ASSERT_TRUE(C->flush());
-
- // We expect that we will only be able to find the function exit event, but
- // not the function enter event, since we only have information about the new
- // generation of the buffers.
- std::string Serialized = serialize(*BQ, 3);
- llvm::DataExtractor DE(Serialized, true, 8);
- auto TraceOrErr = llvm::xray::loadTrace(DE);
- EXPECT_THAT_EXPECTED(
- TraceOrErr, HasValue(ElementsAre(AllOf(
- FuncId(1), RecordType(llvm::xray::RecordTypes::EXIT)))));
-}
-
-} // namespace
-} // namespace __xray
diff --git a/lib/xray/tests/unit/fdr_log_writer_test.cc b/lib/xray/tests/unit/fdr_log_writer_test.cc
deleted file mode 100644
index f2e7a5cba5d15..0000000000000
--- a/lib/xray/tests/unit/fdr_log_writer_test.cc
+++ /dev/null
@@ -1,162 +0,0 @@
-//===-- fdr_log_writer_test.cc --------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of XRay, a function call tracing system.
-//
-//===----------------------------------------------------------------------===//
-#include <time.h>
-
-#include "test_helpers.h"
-#include "xray/xray_records.h"
-#include "xray_fdr_log_writer.h"
-#include "llvm/Support/DataExtractor.h"
-#include "llvm/Testing/Support/Error.h"
-#include "llvm/XRay/Trace.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-
-namespace __xray {
-namespace {
-
-static constexpr size_t kSize = 4096;
-
-using ::llvm::HasValue;
-using ::llvm::xray::testing::FuncId;
-using ::llvm::xray::testing::RecordType;
-using ::testing::AllOf;
-using ::testing::ElementsAre;
-using ::testing::Eq;
-using ::testing::IsEmpty;
-using ::testing::IsNull;
-
-// Exercise the common code path where we initialize a buffer and are able to
-// write some records successfully.
-TEST(FdrLogWriterTest, WriteSomeRecords) {
- bool Success = false;
- BufferQueue Buffers(kSize, 1, Success);
- BufferQueue::Buffer B;
- ASSERT_EQ(Buffers.getBuffer(B), BufferQueue::ErrorCode::Ok);
-
- FDRLogWriter Writer(B);
- MetadataRecord Preamble[] = {
- createMetadataRecord<MetadataRecord::RecordKinds::NewBuffer>(int32_t{1}),
- createMetadataRecord<MetadataRecord::RecordKinds::WalltimeMarker>(
- int64_t{1}, int32_t{2}),
- createMetadataRecord<MetadataRecord::RecordKinds::Pid>(int32_t{1}),
- };
- ASSERT_THAT(Writer.writeMetadataRecords(Preamble),
- Eq(sizeof(MetadataRecord) * 3));
- ASSERT_TRUE(Writer.writeMetadata<MetadataRecord::RecordKinds::NewCPUId>(1));
- ASSERT_TRUE(
- Writer.writeFunction(FDRLogWriter::FunctionRecordKind::Enter, 1, 1));
- ASSERT_TRUE(
- Writer.writeFunction(FDRLogWriter::FunctionRecordKind::Exit, 1, 1));
- ASSERT_EQ(Buffers.releaseBuffer(B), BufferQueue::ErrorCode::Ok);
- ASSERT_EQ(B.Data, nullptr);
- ASSERT_EQ(Buffers.finalize(), BufferQueue::ErrorCode::Ok);
-
- // We then need to go through each element of the Buffers, and re-create a
- // flat buffer that we would see if they were laid out in a file. This also
- // means we need to write out the header manually.
- std::string Serialized = serialize(Buffers, 3);
- llvm::DataExtractor DE(Serialized, true, 8);
- auto TraceOrErr = llvm::xray::loadTrace(DE);
- EXPECT_THAT_EXPECTED(
- TraceOrErr,
- HasValue(ElementsAre(
- AllOf(FuncId(1), RecordType(llvm::xray::RecordTypes::ENTER)),
- AllOf(FuncId(1), RecordType(llvm::xray::RecordTypes::EXIT)))));
-}
-
-// Ensure that we can handle buffer re-use.
-TEST(FdrLogWriterTest, ReuseBuffers) {
- bool Success = false;
- BufferQueue Buffers(kSize, 1, Success);
- BufferQueue::Buffer B;
- ASSERT_EQ(Buffers.getBuffer(B), BufferQueue::ErrorCode::Ok);
-
- FDRLogWriter Writer(B);
- MetadataRecord Preamble[] = {
- createMetadataRecord<MetadataRecord::RecordKinds::NewBuffer>(int32_t{1}),
- createMetadataRecord<MetadataRecord::RecordKinds::WalltimeMarker>(
- int64_t{1}, int32_t{2}),
- createMetadataRecord<MetadataRecord::RecordKinds::Pid>(int32_t{1}),
- };
-
- // First we write the first set of records into the single buffer in the
- // queue which includes one enter and one exit record.
- ASSERT_THAT(Writer.writeMetadataRecords(Preamble),
- Eq(sizeof(MetadataRecord) * 3));
- ASSERT_TRUE(Writer.writeMetadata<MetadataRecord::RecordKinds::NewCPUId>(
- uint16_t{1}, uint64_t{1}));
- uint64_t TSC = 1;
- ASSERT_TRUE(
- Writer.writeFunction(FDRLogWriter::FunctionRecordKind::Enter, 1, TSC++));
- ASSERT_TRUE(
- Writer.writeFunction(FDRLogWriter::FunctionRecordKind::Exit, 1, TSC++));
- ASSERT_EQ(Buffers.releaseBuffer(B), BufferQueue::ErrorCode::Ok);
- ASSERT_THAT(B.Data, IsNull());
-
- // Then we re-use the buffer, but only write one record.
- ASSERT_EQ(Buffers.getBuffer(B), BufferQueue::ErrorCode::Ok);
- Writer.resetRecord();
- ASSERT_THAT(Writer.writeMetadataRecords(Preamble),
- Eq(sizeof(MetadataRecord) * 3));
- ASSERT_TRUE(Writer.writeMetadata<MetadataRecord::RecordKinds::NewCPUId>(
- uint16_t{1}, uint64_t{1}));
- ASSERT_TRUE(
- Writer.writeFunction(FDRLogWriter::FunctionRecordKind::Enter, 1, TSC++));
- ASSERT_EQ(Buffers.releaseBuffer(B), BufferQueue::ErrorCode::Ok);
- ASSERT_THAT(B.Data, IsNull());
- ASSERT_EQ(Buffers.finalize(), BufferQueue::ErrorCode::Ok);
-
- // Then we validate that we only see the single enter record.
- std::string Serialized = serialize(Buffers, 3);
- llvm::DataExtractor DE(Serialized, true, 8);
- auto TraceOrErr = llvm::xray::loadTrace(DE);
- EXPECT_THAT_EXPECTED(
- TraceOrErr, HasValue(ElementsAre(AllOf(
- FuncId(1), RecordType(llvm::xray::RecordTypes::ENTER)))));
-}
-
-TEST(FdrLogWriterTest, UnwriteRecords) {
- bool Success = false;
- BufferQueue Buffers(kSize, 1, Success);
- BufferQueue::Buffer B;
- ASSERT_EQ(Buffers.getBuffer(B), BufferQueue::ErrorCode::Ok);
-
- FDRLogWriter Writer(B);
- MetadataRecord Preamble[] = {
- createMetadataRecord<MetadataRecord::RecordKinds::NewBuffer>(int32_t{1}),
- createMetadataRecord<MetadataRecord::RecordKinds::WalltimeMarker>(
- int64_t{1}, int32_t{2}),
- createMetadataRecord<MetadataRecord::RecordKinds::Pid>(int32_t{1}),
- };
- ASSERT_THAT(Writer.writeMetadataRecords(Preamble),
- Eq(sizeof(MetadataRecord) * 3));
- ASSERT_TRUE(Writer.writeMetadata<MetadataRecord::RecordKinds::NewCPUId>(1));
- ASSERT_TRUE(
- Writer.writeFunction(FDRLogWriter::FunctionRecordKind::Enter, 1, 1));
- ASSERT_TRUE(
- Writer.writeFunction(FDRLogWriter::FunctionRecordKind::Exit, 1, 1));
- Writer.undoWrites(sizeof(FunctionRecord) * 2);
- ASSERT_EQ(Buffers.releaseBuffer(B), BufferQueue::ErrorCode::Ok);
- ASSERT_EQ(B.Data, nullptr);
- ASSERT_EQ(Buffers.finalize(), BufferQueue::ErrorCode::Ok);
-
- // We've un-done the two function records we've written, and now we expect
- // that we don't have any function records in the trace.
- std::string Serialized = serialize(Buffers, 3);
- llvm::DataExtractor DE(Serialized, true, 8);
- auto TraceOrErr = llvm::xray::loadTrace(DE);
- EXPECT_THAT_EXPECTED(TraceOrErr, HasValue(IsEmpty()));
-}
-
-} // namespace
-} // namespace __xray
diff --git a/lib/xray/tests/unit/function_call_trie_test.cc b/lib/xray/tests/unit/function_call_trie_test.cc
deleted file mode 100644
index 01be691228f2b..0000000000000
--- a/lib/xray/tests/unit/function_call_trie_test.cc
+++ /dev/null
@@ -1,344 +0,0 @@
-//===-- function_call_trie_test.cc ----------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of XRay, a function call tracing system.
-//
-//===----------------------------------------------------------------------===//
-#include "xray_function_call_trie.h"
-#include "gtest/gtest.h"
-#include <cstdint>
-
-namespace __xray {
-
-namespace {
-
-TEST(FunctionCallTrieTest, ConstructWithTLSAllocators) {
- profilingFlags()->setDefaults();
- FunctionCallTrie::Allocators Allocators = FunctionCallTrie::InitAllocators();
- FunctionCallTrie Trie(Allocators);
-}
-
-TEST(FunctionCallTrieTest, EnterAndExitFunction) {
- profilingFlags()->setDefaults();
- auto A = FunctionCallTrie::InitAllocators();
- FunctionCallTrie Trie(A);
-
- uint64_t TSC = 1;
- uint16_t CPU = 0;
- Trie.enterFunction(1, TSC++, CPU++);
- Trie.exitFunction(1, TSC++, CPU++);
- const auto &R = Trie.getRoots();
-
- ASSERT_EQ(R.size(), 1u);
- ASSERT_EQ(R.front()->FId, 1);
- ASSERT_EQ(R.front()->CallCount, 1u);
- ASSERT_EQ(R.front()->CumulativeLocalTime, 1u);
-}
-
-TEST(FunctionCallTrieTest, HandleTSCOverflow) {
- profilingFlags()->setDefaults();
- auto A = FunctionCallTrie::InitAllocators();
- FunctionCallTrie Trie(A);
-
- Trie.enterFunction(1, std::numeric_limits<uint64_t>::max(), 0);
- Trie.exitFunction(1, 1, 0);
- const auto &R = Trie.getRoots();
-
- ASSERT_EQ(R.size(), 1u);
- ASSERT_EQ(R.front()->FId, 1);
- ASSERT_EQ(R.front()->CallCount, 1u);
- ASSERT_EQ(R.front()->CumulativeLocalTime, 1u);
-}
-
-TEST(FunctionCallTrieTest, MaximalCumulativeTime) {
- profilingFlags()->setDefaults();
- auto A = FunctionCallTrie::InitAllocators();
- FunctionCallTrie Trie(A);
-
- Trie.enterFunction(1, 1, 0);
- Trie.exitFunction(1, 0, 0);
- const auto &R = Trie.getRoots();
-
- ASSERT_EQ(R.size(), 1u);
- ASSERT_EQ(R.front()->FId, 1);
- ASSERT_EQ(R.front()->CallCount, 1u);
- ASSERT_EQ(R.front()->CumulativeLocalTime,
- std::numeric_limits<uint64_t>::max() - 1);
-}
-
-TEST(FunctionCallTrieTest, MissingFunctionEntry) {
- profilingFlags()->setDefaults();
- auto A = FunctionCallTrie::InitAllocators();
- FunctionCallTrie Trie(A);
- Trie.exitFunction(1, 1, 0);
- const auto &R = Trie.getRoots();
-
- ASSERT_TRUE(R.empty());
-}
-
-TEST(FunctionCallTrieTest, NoMatchingEntersForExit) {
- profilingFlags()->setDefaults();
- auto A = FunctionCallTrie::InitAllocators();
- FunctionCallTrie Trie(A);
- Trie.enterFunction(2, 1, 0);
- Trie.enterFunction(3, 3, 0);
- Trie.exitFunction(1, 5, 0);
- const auto &R = Trie.getRoots();
-
- ASSERT_FALSE(R.empty());
- EXPECT_EQ(R.size(), size_t{1});
-}
-
-TEST(FunctionCallTrieTest, MissingFunctionExit) {
- profilingFlags()->setDefaults();
- auto A = FunctionCallTrie::InitAllocators();
- FunctionCallTrie Trie(A);
- Trie.enterFunction(1, 1, 0);
- const auto &R = Trie.getRoots();
-
- ASSERT_FALSE(R.empty());
- EXPECT_EQ(R.size(), size_t{1});
-}
-
-TEST(FunctionCallTrieTest, MultipleRoots) {
- profilingFlags()->setDefaults();
- auto A = FunctionCallTrie::InitAllocators();
- FunctionCallTrie Trie(A);
-
- // Enter and exit FId = 1.
- Trie.enterFunction(1, 1, 0);
- Trie.exitFunction(1, 2, 0);
-
- // Enter and exit FId = 2.
- Trie.enterFunction(2, 3, 0);
- Trie.exitFunction(2, 4, 0);
-
- const auto &R = Trie.getRoots();
- ASSERT_FALSE(R.empty());
- ASSERT_EQ(R.size(), 2u);
-
- // Make sure the roots have different IDs.
- const auto R0 = R[0];
- const auto R1 = R[1];
- ASSERT_NE(R0->FId, R1->FId);
-
- // Inspect the roots that they have the right data.
- ASSERT_NE(R0, nullptr);
- EXPECT_EQ(R0->CallCount, 1u);
- EXPECT_EQ(R0->CumulativeLocalTime, 1u);
-
- ASSERT_NE(R1, nullptr);
- EXPECT_EQ(R1->CallCount, 1u);
- EXPECT_EQ(R1->CumulativeLocalTime, 1u);
-}
-
-// While missing an intermediary entry may be rare in practice, we still enforce
-// that we can handle the case where we've missed the entry event somehow, in
-// between call entry/exits. To illustrate, imagine the following shadow call
-// stack:
-//
-// f0@t0 -> f1@t1 -> f2@t2
-//
-// If for whatever reason we see an exit for `f2` @ t3, followed by an exit for
-// `f0` @ t4 (i.e. no `f1` exit in between) then we need to handle the case of
-// accounting local time to `f2` from d = (t3 - t2), then local time to `f1`
-// as d' = (t3 - t1) - d, and then local time to `f0` as d'' = (t3 - t0) - d'.
-TEST(FunctionCallTrieTest, MissingIntermediaryExit) {
- profilingFlags()->setDefaults();
- auto A = FunctionCallTrie::InitAllocators();
- FunctionCallTrie Trie(A);
-
- Trie.enterFunction(1, 0, 0);
- Trie.enterFunction(2, 100, 0);
- Trie.enterFunction(3, 200, 0);
- Trie.exitFunction(3, 300, 0);
- Trie.exitFunction(1, 400, 0);
-
- // What we should see at this point is all the functions in the trie in a
- // specific order (1 -> 2 -> 3) with the appropriate count(s) and local
- // latencies.
- const auto &R = Trie.getRoots();
- ASSERT_FALSE(R.empty());
- ASSERT_EQ(R.size(), 1u);
-
- const auto &F1 = *R[0];
- ASSERT_EQ(F1.FId, 1);
- ASSERT_FALSE(F1.Callees.empty());
-
- const auto &F2 = *F1.Callees[0].NodePtr;
- ASSERT_EQ(F2.FId, 2);
- ASSERT_FALSE(F2.Callees.empty());
-
- const auto &F3 = *F2.Callees[0].NodePtr;
- ASSERT_EQ(F3.FId, 3);
- ASSERT_TRUE(F3.Callees.empty());
-
- // Now that we've established the preconditions, we check for specific aspects
- // of the nodes.
- EXPECT_EQ(F3.CallCount, 1u);
- EXPECT_EQ(F2.CallCount, 1u);
- EXPECT_EQ(F1.CallCount, 1u);
- EXPECT_EQ(F3.CumulativeLocalTime, 100u);
- EXPECT_EQ(F2.CumulativeLocalTime, 300u);
- EXPECT_EQ(F1.CumulativeLocalTime, 100u);
-}
-
-TEST(FunctionCallTrieTest, DeepCallStack) {
- // Simulate a relatively deep call stack (32 levels) and ensure that we can
- // properly pop all the way up the stack.
- profilingFlags()->setDefaults();
- auto A = FunctionCallTrie::InitAllocators();
- FunctionCallTrie Trie(A);
- for (int i = 0; i < 32; ++i)
- Trie.enterFunction(i + 1, i, 0);
- Trie.exitFunction(1, 33, 0);
-
- // Here, validate that we have a 32-level deep function call path from the
- // root (1) down to the leaf (33).
- const auto &R = Trie.getRoots();
- ASSERT_EQ(R.size(), 1u);
- auto F = R[0];
- for (int i = 0; i < 32; ++i) {
- EXPECT_EQ(F->FId, i + 1);
- EXPECT_EQ(F->CallCount, 1u);
- if (F->Callees.empty() && i != 31)
- FAIL() << "Empty callees for FId " << F->FId;
- if (i != 31)
- F = F->Callees[0].NodePtr;
- }
-}
-
-// TODO: Test that we can handle cross-CPU migrations, where TSCs are not
-// guaranteed to be synchronised.
-TEST(FunctionCallTrieTest, DeepCopy) {
- profilingFlags()->setDefaults();
- auto A = FunctionCallTrie::InitAllocators();
- FunctionCallTrie Trie(A);
-
- Trie.enterFunction(1, 0, 0);
- Trie.enterFunction(2, 1, 0);
- Trie.exitFunction(2, 2, 0);
- Trie.enterFunction(3, 3, 0);
- Trie.exitFunction(3, 4, 0);
- Trie.exitFunction(1, 5, 0);
-
- // We want to make a deep copy and compare notes.
- auto B = FunctionCallTrie::InitAllocators();
- FunctionCallTrie Copy(B);
- Trie.deepCopyInto(Copy);
-
- ASSERT_NE(Trie.getRoots().size(), 0u);
- ASSERT_EQ(Trie.getRoots().size(), Copy.getRoots().size());
- const auto &R0Orig = *Trie.getRoots()[0];
- const auto &R0Copy = *Copy.getRoots()[0];
- EXPECT_EQ(R0Orig.FId, 1);
- EXPECT_EQ(R0Orig.FId, R0Copy.FId);
-
- ASSERT_EQ(R0Orig.Callees.size(), 2u);
- ASSERT_EQ(R0Copy.Callees.size(), 2u);
-
- const auto &F1Orig =
- *R0Orig.Callees
- .find_element(
- [](const FunctionCallTrie::NodeIdPair &R) { return R.FId == 2; })
- ->NodePtr;
- const auto &F1Copy =
- *R0Copy.Callees
- .find_element(
- [](const FunctionCallTrie::NodeIdPair &R) { return R.FId == 2; })
- ->NodePtr;
- EXPECT_EQ(&R0Orig, F1Orig.Parent);
- EXPECT_EQ(&R0Copy, F1Copy.Parent);
-}
-
-TEST(FunctionCallTrieTest, MergeInto) {
- profilingFlags()->setDefaults();
- auto A = FunctionCallTrie::InitAllocators();
- FunctionCallTrie T0(A);
- FunctionCallTrie T1(A);
-
- // 1 -> 2 -> 3
- T0.enterFunction(1, 0, 0);
- T0.enterFunction(2, 1, 0);
- T0.enterFunction(3, 2, 0);
- T0.exitFunction(3, 3, 0);
- T0.exitFunction(2, 4, 0);
- T0.exitFunction(1, 5, 0);
-
- // 1 -> 2 -> 3
- T1.enterFunction(1, 0, 0);
- T1.enterFunction(2, 1, 0);
- T1.enterFunction(3, 2, 0);
- T1.exitFunction(3, 3, 0);
- T1.exitFunction(2, 4, 0);
- T1.exitFunction(1, 5, 0);
-
- // We use a different allocator here to make sure that we're able to transfer
- // data into a FunctionCallTrie which uses a different allocator. This
- // reflects the inteded usage scenario for when we're collecting profiles that
- // aggregate across threads.
- auto B = FunctionCallTrie::InitAllocators();
- FunctionCallTrie Merged(B);
-
- T0.mergeInto(Merged);
- T1.mergeInto(Merged);
-
- ASSERT_EQ(Merged.getRoots().size(), 1u);
- const auto &R0 = *Merged.getRoots()[0];
- EXPECT_EQ(R0.FId, 1);
- EXPECT_EQ(R0.CallCount, 2u);
- EXPECT_EQ(R0.CumulativeLocalTime, 10u);
- EXPECT_EQ(R0.Callees.size(), 1u);
-
- const auto &F1 = *R0.Callees[0].NodePtr;
- EXPECT_EQ(F1.FId, 2);
- EXPECT_EQ(F1.CallCount, 2u);
- EXPECT_EQ(F1.CumulativeLocalTime, 6u);
- EXPECT_EQ(F1.Callees.size(), 1u);
-
- const auto &F2 = *F1.Callees[0].NodePtr;
- EXPECT_EQ(F2.FId, 3);
- EXPECT_EQ(F2.CallCount, 2u);
- EXPECT_EQ(F2.CumulativeLocalTime, 2u);
- EXPECT_EQ(F2.Callees.size(), 0u);
-}
-
-TEST(FunctionCallTrieTest, PlacementNewOnAlignedStorage) {
- profilingFlags()->setDefaults();
- typename std::aligned_storage<sizeof(FunctionCallTrie::Allocators),
- alignof(FunctionCallTrie::Allocators)>::type
- AllocatorsStorage;
- new (&AllocatorsStorage)
- FunctionCallTrie::Allocators(FunctionCallTrie::InitAllocators());
- auto *A =
- reinterpret_cast<FunctionCallTrie::Allocators *>(&AllocatorsStorage);
-
- typename std::aligned_storage<sizeof(FunctionCallTrie),
- alignof(FunctionCallTrie)>::type FCTStorage;
- new (&FCTStorage) FunctionCallTrie(*A);
- auto *T = reinterpret_cast<FunctionCallTrie *>(&FCTStorage);
-
- // Put some data into it.
- T->enterFunction(1, 0, 0);
- T->exitFunction(1, 1, 0);
-
- // Re-initialize the objects in storage.
- T->~FunctionCallTrie();
- A->~Allocators();
- new (A) FunctionCallTrie::Allocators(FunctionCallTrie::InitAllocators());
- new (T) FunctionCallTrie(*A);
-
- // Then put some data into it again.
- T->enterFunction(1, 0, 0);
- T->exitFunction(1, 1, 0);
-}
-
-} // namespace
-
-} // namespace __xray
diff --git a/lib/xray/tests/unit/profile_collector_test.cc b/lib/xray/tests/unit/profile_collector_test.cc
deleted file mode 100644
index df786d46b9d46..0000000000000
--- a/lib/xray/tests/unit/profile_collector_test.cc
+++ /dev/null
@@ -1,236 +0,0 @@
-//===-- profile_collector_test.cc -----------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of XRay, a function call tracing system.
-//
-//===----------------------------------------------------------------------===//
-#include "gtest/gtest.h"
-
-#include "xray_profile_collector.h"
-#include "xray_profiling_flags.h"
-#include <cstdint>
-#include <cstring>
-#include <memory>
-#include <thread>
-#include <utility>
-#include <vector>
-
-namespace __xray {
-namespace {
-
-static constexpr auto kHeaderSize = 16u;
-
-constexpr uptr ExpectedProfilingVersion = 0x20180424;
-
-struct ExpectedProfilingFileHeader {
- const u64 MagicBytes = 0x7872617970726f66; // Identifier for XRay profiling
- // files 'xrayprof' in hex.
- const u64 Version = ExpectedProfilingVersion;
- u64 Timestamp = 0;
- u64 PID = 0;
-};
-
-void ValidateFileHeaderBlock(XRayBuffer B) {
- ASSERT_NE(static_cast<const void *>(B.Data), nullptr);
- ASSERT_EQ(B.Size, sizeof(ExpectedProfilingFileHeader));
- typename std::aligned_storage<sizeof(ExpectedProfilingFileHeader)>::type
- FileHeaderStorage;
- ExpectedProfilingFileHeader ExpectedHeader;
- std::memcpy(&FileHeaderStorage, B.Data, B.Size);
- auto &FileHeader =
- *reinterpret_cast<ExpectedProfilingFileHeader *>(&FileHeaderStorage);
- ASSERT_EQ(ExpectedHeader.MagicBytes, FileHeader.MagicBytes);
- ASSERT_EQ(ExpectedHeader.Version, FileHeader.Version);
-}
-
-void ValidateBlock(XRayBuffer B) {
- profilingFlags()->setDefaults();
- ASSERT_NE(static_cast<const void *>(B.Data), nullptr);
- ASSERT_NE(B.Size, 0u);
- ASSERT_GE(B.Size, kHeaderSize);
- // We look at the block size, the block number, and the thread ID to ensure
- // that none of them are zero (or that the header data is laid out as we
- // expect).
- char LocalBuffer[kHeaderSize] = {};
- internal_memcpy(LocalBuffer, B.Data, kHeaderSize);
- u32 BlockSize = 0;
- u32 BlockNumber = 0;
- u64 ThreadId = 0;
- internal_memcpy(&BlockSize, LocalBuffer, sizeof(u32));
- internal_memcpy(&BlockNumber, LocalBuffer + sizeof(u32), sizeof(u32));
- internal_memcpy(&ThreadId, LocalBuffer + (2 * sizeof(u32)), sizeof(u64));
- ASSERT_NE(BlockSize, 0u);
- ASSERT_GE(BlockNumber, 0u);
- ASSERT_NE(ThreadId, 0u);
-}
-
-std::tuple<u32, u32, u64> ParseBlockHeader(XRayBuffer B) {
- char LocalBuffer[kHeaderSize] = {};
- internal_memcpy(LocalBuffer, B.Data, kHeaderSize);
- u32 BlockSize = 0;
- u32 BlockNumber = 0;
- u64 ThreadId = 0;
- internal_memcpy(&BlockSize, LocalBuffer, sizeof(u32));
- internal_memcpy(&BlockNumber, LocalBuffer + sizeof(u32), sizeof(u32));
- internal_memcpy(&ThreadId, LocalBuffer + (2 * sizeof(u32)), sizeof(u64));
- return std::make_tuple(BlockSize, BlockNumber, ThreadId);
-}
-
-struct Profile {
- int64_t CallCount;
- int64_t CumulativeLocalTime;
- std::vector<int32_t> Path;
-};
-
-std::tuple<Profile, const char *> ParseProfile(const char *P) {
- Profile Result;
- // Read the path first, until we find a sentinel 0.
- int32_t F;
- do {
- internal_memcpy(&F, P, sizeof(int32_t));
- P += sizeof(int32_t);
- Result.Path.push_back(F);
- } while (F != 0);
-
- // Then read the CallCount.
- internal_memcpy(&Result.CallCount, P, sizeof(int64_t));
- P += sizeof(int64_t);
-
- // Then read the CumulativeLocalTime.
- internal_memcpy(&Result.CumulativeLocalTime, P, sizeof(int64_t));
- P += sizeof(int64_t);
- return std::make_tuple(std::move(Result), P);
-}
-
-TEST(profileCollectorServiceTest, PostSerializeCollect) {
- profilingFlags()->setDefaults();
- bool Success = false;
- BufferQueue BQ(profilingFlags()->per_thread_allocator_max,
- profilingFlags()->buffers_max, Success);
- ASSERT_EQ(Success, true);
- FunctionCallTrie::Allocators::Buffers Buffers;
- ASSERT_EQ(BQ.getBuffer(Buffers.NodeBuffer), BufferQueue::ErrorCode::Ok);
- ASSERT_EQ(BQ.getBuffer(Buffers.RootsBuffer), BufferQueue::ErrorCode::Ok);
- ASSERT_EQ(BQ.getBuffer(Buffers.ShadowStackBuffer),
- BufferQueue::ErrorCode::Ok);
- ASSERT_EQ(BQ.getBuffer(Buffers.NodeIdPairBuffer), BufferQueue::ErrorCode::Ok);
- auto Allocators = FunctionCallTrie::InitAllocatorsFromBuffers(Buffers);
- FunctionCallTrie T(Allocators);
-
- // Populate the trie with some data.
- T.enterFunction(1, 1, 0);
- T.enterFunction(2, 2, 0);
- T.exitFunction(2, 3, 0);
- T.exitFunction(1, 4, 0);
-
- // Reset the collector data structures.
- profileCollectorService::reset();
-
- // Then we post the data to the global profile collector service.
- profileCollectorService::post(&BQ, std::move(T), std::move(Allocators),
- std::move(Buffers), 1);
-
- // Then we serialize the data.
- profileCollectorService::serialize();
-
- // Then we go through two buffers to see whether we're getting the data we
- // expect. The first block must always be as large as a file header, which
- // will have a fixed size.
- auto B = profileCollectorService::nextBuffer({nullptr, 0});
- ValidateFileHeaderBlock(B);
-
- B = profileCollectorService::nextBuffer(B);
- ValidateBlock(B);
- u32 BlockSize;
- u32 BlockNum;
- u64 ThreadId;
- std::tie(BlockSize, BlockNum, ThreadId) = ParseBlockHeader(B);
-
- // We look at the serialized buffer to see whether the Trie we're expecting
- // to see is there.
- auto DStart = static_cast<const char *>(B.Data) + kHeaderSize;
- std::vector<char> D(DStart, DStart + BlockSize);
- B = profileCollectorService::nextBuffer(B);
- ASSERT_EQ(B.Data, nullptr);
- ASSERT_EQ(B.Size, 0u);
-
- Profile Profile1, Profile2;
- auto P = static_cast<const char *>(D.data());
- std::tie(Profile1, P) = ParseProfile(P);
- std::tie(Profile2, P) = ParseProfile(P);
-
- ASSERT_NE(Profile1.Path.size(), Profile2.Path.size());
- auto &P1 = Profile1.Path.size() < Profile2.Path.size() ? Profile2 : Profile1;
- auto &P2 = Profile1.Path.size() < Profile2.Path.size() ? Profile1 : Profile2;
- std::vector<int32_t> P1Expected = {2, 1, 0};
- std::vector<int32_t> P2Expected = {1, 0};
- ASSERT_EQ(P1.Path.size(), P1Expected.size());
- ASSERT_EQ(P2.Path.size(), P2Expected.size());
- ASSERT_EQ(P1.Path, P1Expected);
- ASSERT_EQ(P2.Path, P2Expected);
-}
-
-// We break out a function that will be run in multiple threads, one that will
-// use a thread local allocator, and will post the FunctionCallTrie to the
-// profileCollectorService. This simulates what the threads being profiled would
-// be doing anyway, but through the XRay logging implementation.
-void threadProcessing() {
- static bool Success = false;
- static BufferQueue BQ(profilingFlags()->per_thread_allocator_max,
- profilingFlags()->buffers_max, Success);
- thread_local FunctionCallTrie::Allocators::Buffers Buffers = [] {
- FunctionCallTrie::Allocators::Buffers B;
- BQ.getBuffer(B.NodeBuffer);
- BQ.getBuffer(B.RootsBuffer);
- BQ.getBuffer(B.ShadowStackBuffer);
- BQ.getBuffer(B.NodeIdPairBuffer);
- return B;
- }();
-
- thread_local auto Allocators =
- FunctionCallTrie::InitAllocatorsFromBuffers(Buffers);
-
- FunctionCallTrie T(Allocators);
-
- T.enterFunction(1, 1, 0);
- T.enterFunction(2, 2, 0);
- T.exitFunction(2, 3, 0);
- T.exitFunction(1, 4, 0);
-
- profileCollectorService::post(&BQ, std::move(T), std::move(Allocators),
- std::move(Buffers), GetTid());
-}
-
-TEST(profileCollectorServiceTest, PostSerializeCollectMultipleThread) {
- profilingFlags()->setDefaults();
-
- profileCollectorService::reset();
-
- std::thread t1(threadProcessing);
- std::thread t2(threadProcessing);
-
- t1.join();
- t2.join();
-
- // At this point, t1 and t2 are already done with what they were doing.
- profileCollectorService::serialize();
-
- // Ensure that we see two buffers.
- auto B = profileCollectorService::nextBuffer({nullptr, 0});
- ValidateFileHeaderBlock(B);
-
- B = profileCollectorService::nextBuffer(B);
- ValidateBlock(B);
-
- B = profileCollectorService::nextBuffer(B);
- ValidateBlock(B);
-}
-
-} // namespace
-} // namespace __xray
diff --git a/lib/xray/tests/unit/segmented_array_test.cc b/lib/xray/tests/unit/segmented_array_test.cc
deleted file mode 100644
index 46aeb88f71b4c..0000000000000
--- a/lib/xray/tests/unit/segmented_array_test.cc
+++ /dev/null
@@ -1,349 +0,0 @@
-#include "test_helpers.h"
-#include "xray_segmented_array.h"
-#include "gmock/gmock.h"
-#include "gtest/gtest.h"
-#include <algorithm>
-#include <numeric>
-#include <vector>
-
-namespace __xray {
-namespace {
-
-using ::testing::SizeIs;
-
-struct TestData {
- s64 First;
- s64 Second;
-
- // Need a constructor for emplace operations.
- TestData(s64 F, s64 S) : First(F), Second(S) {}
-};
-
-void PrintTo(const TestData &D, std::ostream *OS) {
- *OS << "{ " << D.First << ", " << D.Second << " }";
-}
-
-TEST(SegmentedArrayTest, ConstructWithAllocators) {
- using AllocatorType = typename Array<TestData>::AllocatorType;
- AllocatorType A(1 << 4);
- Array<TestData> Data(A);
- (void)Data;
-}
-
-TEST(SegmentedArrayTest, ConstructAndPopulate) {
- using AllocatorType = typename Array<TestData>::AllocatorType;
- AllocatorType A(1 << 4);
- Array<TestData> data(A);
- ASSERT_NE(data.Append(TestData{0, 0}), nullptr);
- ASSERT_NE(data.Append(TestData{1, 1}), nullptr);
- ASSERT_EQ(data.size(), 2u);
-}
-
-TEST(SegmentedArrayTest, ConstructPopulateAndLookup) {
- using AllocatorType = typename Array<TestData>::AllocatorType;
- AllocatorType A(1 << 4);
- Array<TestData> data(A);
- ASSERT_NE(data.Append(TestData{0, 1}), nullptr);
- ASSERT_EQ(data.size(), 1u);
- ASSERT_EQ(data[0].First, 0);
- ASSERT_EQ(data[0].Second, 1);
-}
-
-TEST(SegmentedArrayTest, PopulateWithMoreElements) {
- using AllocatorType = typename Array<TestData>::AllocatorType;
- AllocatorType A(1 << 24);
- Array<TestData> data(A);
- static const auto kMaxElements = 100u;
- for (auto I = 0u; I < kMaxElements; ++I) {
- ASSERT_NE(data.Append(TestData{I, I + 1}), nullptr);
- }
- ASSERT_EQ(data.size(), kMaxElements);
- for (auto I = 0u; I < kMaxElements; ++I) {
- ASSERT_EQ(data[I].First, I);
- ASSERT_EQ(data[I].Second, I + 1);
- }
-}
-
-TEST(SegmentedArrayTest, AppendEmplace) {
- using AllocatorType = typename Array<TestData>::AllocatorType;
- AllocatorType A(1 << 4);
- Array<TestData> data(A);
- ASSERT_NE(data.AppendEmplace(1, 1), nullptr);
- ASSERT_EQ(data[0].First, 1);
- ASSERT_EQ(data[0].Second, 1);
-}
-
-TEST(SegmentedArrayTest, AppendAndTrim) {
- using AllocatorType = typename Array<TestData>::AllocatorType;
- AllocatorType A(1 << 4);
- Array<TestData> data(A);
- ASSERT_NE(data.AppendEmplace(1, 1), nullptr);
- ASSERT_EQ(data.size(), 1u);
- data.trim(1);
- ASSERT_EQ(data.size(), 0u);
- ASSERT_TRUE(data.empty());
-}
-
-TEST(SegmentedArrayTest, IteratorAdvance) {
- using AllocatorType = typename Array<TestData>::AllocatorType;
- AllocatorType A(1 << 4);
- Array<TestData> data(A);
- ASSERT_TRUE(data.empty());
- ASSERT_EQ(data.begin(), data.end());
- auto I0 = data.begin();
- ASSERT_EQ(I0++, data.begin());
- ASSERT_NE(I0, data.begin());
- for (const auto &D : data) {
- (void)D;
- FAIL();
- }
- ASSERT_NE(data.AppendEmplace(1, 1), nullptr);
- ASSERT_EQ(data.size(), 1u);
- ASSERT_NE(data.begin(), data.end());
- auto &D0 = *data.begin();
- ASSERT_EQ(D0.First, 1);
- ASSERT_EQ(D0.Second, 1);
-}
-
-TEST(SegmentedArrayTest, IteratorRetreat) {
- using AllocatorType = typename Array<TestData>::AllocatorType;
- AllocatorType A(1 << 4);
- Array<TestData> data(A);
- ASSERT_TRUE(data.empty());
- ASSERT_EQ(data.begin(), data.end());
- ASSERT_NE(data.AppendEmplace(1, 1), nullptr);
- ASSERT_EQ(data.size(), 1u);
- ASSERT_NE(data.begin(), data.end());
- auto &D0 = *data.begin();
- ASSERT_EQ(D0.First, 1);
- ASSERT_EQ(D0.Second, 1);
-
- auto I0 = data.end();
- ASSERT_EQ(I0--, data.end());
- ASSERT_NE(I0, data.end());
- ASSERT_EQ(I0, data.begin());
- ASSERT_EQ(I0->First, 1);
- ASSERT_EQ(I0->Second, 1);
-}
-
-TEST(SegmentedArrayTest, IteratorTrimBehaviour) {
- using AllocatorType = typename Array<TestData>::AllocatorType;
- AllocatorType A(1 << 20);
- Array<TestData> Data(A);
- ASSERT_TRUE(Data.empty());
- auto I0Begin = Data.begin(), I0End = Data.end();
- // Add enough elements in Data to have more than one chunk.
- constexpr auto Segment = Array<TestData>::SegmentSize;
- constexpr auto SegmentX2 = Segment * 2;
- for (auto i = SegmentX2; i > 0u; --i) {
- Data.AppendEmplace(static_cast<s64>(i), static_cast<s64>(i));
- }
- ASSERT_EQ(Data.size(), SegmentX2);
- {
- auto &Back = Data.back();
- ASSERT_EQ(Back.First, 1);
- ASSERT_EQ(Back.Second, 1);
- }
-
- // Trim one chunk's elements worth.
- Data.trim(Segment);
- ASSERT_EQ(Data.size(), Segment);
-
- // Check that we are still able to access 'back' properly.
- {
- auto &Back = Data.back();
- ASSERT_EQ(Back.First, static_cast<s64>(Segment + 1));
- ASSERT_EQ(Back.Second, static_cast<s64>(Segment + 1));
- }
-
- // Then trim until it's empty.
- Data.trim(Segment);
- ASSERT_TRUE(Data.empty());
-
- // Here our iterators should be the same.
- auto I1Begin = Data.begin(), I1End = Data.end();
- EXPECT_EQ(I0Begin, I1Begin);
- EXPECT_EQ(I0End, I1End);
-
- // Then we ensure that adding elements back works just fine.
- for (auto i = SegmentX2; i > 0u; --i) {
- Data.AppendEmplace(static_cast<s64>(i), static_cast<s64>(i));
- }
- EXPECT_EQ(Data.size(), SegmentX2);
-}
-
-TEST(SegmentedArrayTest, HandleExhaustedAllocator) {
- using AllocatorType = typename Array<TestData>::AllocatorType;
- constexpr auto Segment = Array<TestData>::SegmentSize;
- constexpr auto MaxElements = Array<TestData>::ElementsPerSegment;
- AllocatorType A(Segment);
- Array<TestData> Data(A);
- for (auto i = MaxElements; i > 0u; --i)
- EXPECT_NE(Data.AppendEmplace(static_cast<s64>(i), static_cast<s64>(i)),
- nullptr);
- EXPECT_EQ(Data.AppendEmplace(0, 0), nullptr);
- EXPECT_THAT(Data, SizeIs(MaxElements));
-
- // Trimming more elements than there are in the container should be fine.
- Data.trim(MaxElements + 1);
- EXPECT_THAT(Data, SizeIs(0u));
-}
-
-struct ShadowStackEntry {
- uint64_t EntryTSC = 0;
- uint64_t *NodePtr = nullptr;
- ShadowStackEntry(uint64_t T, uint64_t *N) : EntryTSC(T), NodePtr(N) {}
-};
-
-TEST(SegmentedArrayTest, SimulateStackBehaviour) {
- using AllocatorType = typename Array<ShadowStackEntry>::AllocatorType;
- AllocatorType A(1 << 10);
- Array<ShadowStackEntry> Data(A);
- static uint64_t Dummy = 0;
- constexpr uint64_t Max = 9;
-
- for (uint64_t i = 0; i < Max; ++i) {
- auto P = Data.Append({i, &Dummy});
- ASSERT_NE(P, nullptr);
- ASSERT_EQ(P->NodePtr, &Dummy);
- auto &Back = Data.back();
- ASSERT_EQ(Back.NodePtr, &Dummy);
- ASSERT_EQ(Back.EntryTSC, i);
- }
-
- // Simulate a stack by checking the data from the end as we're trimming.
- auto Counter = Max;
- ASSERT_EQ(Data.size(), size_t(Max));
- while (!Data.empty()) {
- const auto &Top = Data.back();
- uint64_t *TopNode = Top.NodePtr;
- EXPECT_EQ(TopNode, &Dummy) << "Counter = " << Counter;
- Data.trim(1);
- --Counter;
- ASSERT_EQ(Data.size(), size_t(Counter));
- }
-}
-
-TEST(SegmentedArrayTest, PlacementNewOnAlignedStorage) {
- using AllocatorType = typename Array<ShadowStackEntry>::AllocatorType;
- typename std::aligned_storage<sizeof(AllocatorType),
- alignof(AllocatorType)>::type AllocatorStorage;
- new (&AllocatorStorage) AllocatorType(1 << 10);
- auto *A = reinterpret_cast<AllocatorType *>(&AllocatorStorage);
- typename std::aligned_storage<sizeof(Array<ShadowStackEntry>),
- alignof(Array<ShadowStackEntry>)>::type
- ArrayStorage;
- new (&ArrayStorage) Array<ShadowStackEntry>(*A);
- auto *Data = reinterpret_cast<Array<ShadowStackEntry> *>(&ArrayStorage);
-
- static uint64_t Dummy = 0;
- constexpr uint64_t Max = 9;
-
- for (uint64_t i = 0; i < Max; ++i) {
- auto P = Data->Append({i, &Dummy});
- ASSERT_NE(P, nullptr);
- ASSERT_EQ(P->NodePtr, &Dummy);
- auto &Back = Data->back();
- ASSERT_EQ(Back.NodePtr, &Dummy);
- ASSERT_EQ(Back.EntryTSC, i);
- }
-
- // Simulate a stack by checking the data from the end as we're trimming.
- auto Counter = Max;
- ASSERT_EQ(Data->size(), size_t(Max));
- while (!Data->empty()) {
- const auto &Top = Data->back();
- uint64_t *TopNode = Top.NodePtr;
- EXPECT_EQ(TopNode, &Dummy) << "Counter = " << Counter;
- Data->trim(1);
- --Counter;
- ASSERT_EQ(Data->size(), size_t(Counter));
- }
-
- // Once the stack is exhausted, we re-use the storage.
- for (uint64_t i = 0; i < Max; ++i) {
- auto P = Data->Append({i, &Dummy});
- ASSERT_NE(P, nullptr);
- ASSERT_EQ(P->NodePtr, &Dummy);
- auto &Back = Data->back();
- ASSERT_EQ(Back.NodePtr, &Dummy);
- ASSERT_EQ(Back.EntryTSC, i);
- }
-
- // We re-initialize the storage, by calling the destructor and
- // placement-new'ing again.
- Data->~Array();
- A->~AllocatorType();
- new (A) AllocatorType(1 << 10);
- new (Data) Array<ShadowStackEntry>(*A);
-
- // Then re-do the test.
- for (uint64_t i = 0; i < Max; ++i) {
- auto P = Data->Append({i, &Dummy});
- ASSERT_NE(P, nullptr);
- ASSERT_EQ(P->NodePtr, &Dummy);
- auto &Back = Data->back();
- ASSERT_EQ(Back.NodePtr, &Dummy);
- ASSERT_EQ(Back.EntryTSC, i);
- }
-
- // Simulate a stack by checking the data from the end as we're trimming.
- Counter = Max;
- ASSERT_EQ(Data->size(), size_t(Max));
- while (!Data->empty()) {
- const auto &Top = Data->back();
- uint64_t *TopNode = Top.NodePtr;
- EXPECT_EQ(TopNode, &Dummy) << "Counter = " << Counter;
- Data->trim(1);
- --Counter;
- ASSERT_EQ(Data->size(), size_t(Counter));
- }
-
- // Once the stack is exhausted, we re-use the storage.
- for (uint64_t i = 0; i < Max; ++i) {
- auto P = Data->Append({i, &Dummy});
- ASSERT_NE(P, nullptr);
- ASSERT_EQ(P->NodePtr, &Dummy);
- auto &Back = Data->back();
- ASSERT_EQ(Back.NodePtr, &Dummy);
- ASSERT_EQ(Back.EntryTSC, i);
- }
-}
-
-TEST(SegmentedArrayTest, ArrayOfPointersIteratorAccess) {
- using PtrArray = Array<int *>;
- PtrArray::AllocatorType Alloc(16384);
- Array<int *> A(Alloc);
- static constexpr size_t Count = 100;
- std::vector<int> Integers(Count);
- std::iota(Integers.begin(), Integers.end(), 0);
- for (auto &I : Integers)
- ASSERT_NE(A.Append(&I), nullptr);
- int V = 0;
- ASSERT_EQ(A.size(), Count);
- for (auto P : A) {
- ASSERT_NE(P, nullptr);
- ASSERT_EQ(*P, V++);
- }
-}
-
-TEST(SegmentedArrayTest, ArrayOfPointersIteratorAccessExhaustion) {
- using PtrArray = Array<int *>;
- PtrArray::AllocatorType Alloc(4096);
- Array<int *> A(Alloc);
- static constexpr size_t Count = 1000;
- std::vector<int> Integers(Count);
- std::iota(Integers.begin(), Integers.end(), 0);
- for (auto &I : Integers)
- if (A.Append(&I) == nullptr)
- break;
- int V = 0;
- ASSERT_LT(A.size(), Count);
- for (auto P : A) {
- ASSERT_NE(P, nullptr);
- ASSERT_EQ(*P, V++);
- }
-}
-
-} // namespace
-} // namespace __xray
diff --git a/lib/xray/tests/unit/test_helpers.cc b/lib/xray/tests/unit/test_helpers.cc
deleted file mode 100644
index 284492d1050b4..0000000000000
--- a/lib/xray/tests/unit/test_helpers.cc
+++ /dev/null
@@ -1,95 +0,0 @@
-//===-- test_helpers.cc ---------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of XRay, a function call tracing system.
-//
-//===----------------------------------------------------------------------===//
-#include "test_helpers.h"
-#include "xray/xray_records.h"
-#include "xray_buffer_queue.h"
-#include "xray_fdr_log_writer.h"
-#include <type_traits>
-
-// TODO: Move these to llvm/include/Testing/XRay/...
-namespace llvm {
-namespace xray {
-
-std::string RecordTypeAsString(RecordTypes T) {
- switch (T) {
- case RecordTypes::ENTER:
- return "llvm::xray::RecordTypes::ENTER";
- case RecordTypes::EXIT:
- return "llvm::xray::RecordTypes::EXIT";
- case RecordTypes::TAIL_EXIT:
- return "llvm::xray::RecordTypes::TAIL_EXIT";
- case RecordTypes::ENTER_ARG:
- return "llvm::xray::RecordTypes::ENTER_ARG";
- case RecordTypes::CUSTOM_EVENT:
- return "llvm::xray::RecordTypes::CUSTOM_EVENT";
- case RecordTypes::TYPED_EVENT:
- return "llvm::xray::RecordTypes::TYPED_EVENT";
- }
- return "<UNKNOWN>";
-}
-
-void PrintTo(RecordTypes T, std::ostream *OS) {
- *OS << RecordTypeAsString(T);
-}
-
-void PrintTo(const XRayRecord &R, std::ostream *OS) {
- *OS << "XRayRecord { CPU = " << R.CPU
- << "; Type = " << RecordTypeAsString(R.Type) << "; FuncId = " << R.FuncId
- << "; TSC = " << R.TSC << "; TId = " << R.TId << "; PId = " << R.PId
- << " Args = " << ::testing::PrintToString(R.CallArgs) << " }";
-}
-
-void PrintTo(const Trace &T, std::ostream *OS) {
- const auto &H = T.getFileHeader();
- *OS << "XRay Trace:\nHeader: { Version = " << H.Version
- << "; Type = " << H.Type
- << "; ConstantTSC = " << ::testing::PrintToString(H.ConstantTSC)
- << "; NonstopTSC = " << ::testing::PrintToString(H.NonstopTSC)
- << "; CycleFrequency = " << H.CycleFrequency << "; FreeFormData = '"
- << ::testing::PrintToString(H.FreeFormData) << "' }\n";
- for (const auto &R : T) {
- PrintTo(R, OS);
- *OS << "\n";
- }
-}
-
-} // namespace xray
-} // namespace llvm
-
-namespace __xray {
-
-std::string serialize(BufferQueue &Buffers, int32_t Version) {
- std::string Serialized;
- std::aligned_storage<sizeof(XRayFileHeader), alignof(XRayFileHeader)>::type
- HeaderStorage;
- auto *Header = reinterpret_cast<XRayFileHeader *>(&HeaderStorage);
- new (Header) XRayFileHeader();
- Header->Version = Version;
- Header->Type = FileTypes::FDR_LOG;
- Header->CycleFrequency = 3e9;
- Header->ConstantTSC = 1;
- Header->NonstopTSC = 1;
- Serialized.append(reinterpret_cast<const char *>(&HeaderStorage),
- sizeof(XRayFileHeader));
- Buffers.apply([&](const BufferQueue::Buffer &B) {
- auto Size = atomic_load_relaxed(B.Extents);
- auto Extents =
- createMetadataRecord<MetadataRecord::RecordKinds::BufferExtents>(Size);
- Serialized.append(reinterpret_cast<const char *>(&Extents),
- sizeof(Extents));
- Serialized.append(reinterpret_cast<const char *>(B.Data), Size);
- });
- return Serialized;
-}
-
-} // namespace __xray
diff --git a/lib/xray/tests/unit/test_helpers.h b/lib/xray/tests/unit/test_helpers.h
deleted file mode 100644
index ff0311e9bd30f..0000000000000
--- a/lib/xray/tests/unit/test_helpers.h
+++ /dev/null
@@ -1,78 +0,0 @@
-//===-- test_helpers.h ----------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of XRay, a function call tracing system.
-//
-//===----------------------------------------------------------------------===//
-#ifndef COMPILER_RT_LIB_XRAY_TESTS_TEST_HELPERS_H_
-#define COMPILER_RT_LIB_XRAY_TESTS_TEST_HELPERS_H_
-
-#include "xray_buffer_queue.h"
-#include "xray_segmented_array.h"
-#include "llvm/XRay/Trace.h"
-#include "llvm/XRay/XRayRecord.h"
-#include "gmock/gmock.h"
-
-// TODO: Move these to llvm/include/Testing/XRay/...
-namespace llvm {
-namespace xray {
-
-std::string RecordTypeAsString(RecordTypes T);
-void PrintTo(RecordTypes T, std::ostream *OS);
-void PrintTo(const XRayRecord &R, std::ostream *OS);
-void PrintTo(const Trace &T, std::ostream *OS);
-
-namespace testing {
-
-MATCHER_P(FuncId, F, "") {
- *result_listener << "where the function id is " << F;
- return arg.FuncId == F;
-}
-
-MATCHER_P(RecordType, T, "") {
- *result_listener << "where the record type is " << RecordTypeAsString(T);
- return arg.Type == T;
-}
-
-MATCHER_P(HasArg, A, "") {
- *result_listener << "where args contains " << A;
- return !arg.CallArgs.empty() &&
- std::any_of(arg.CallArgs.begin(), arg.CallArgs.end(),
- [this](decltype(A) V) { return V == A; });
-}
-
-MATCHER_P(TSCIs, M, std::string("TSC is ") + ::testing::PrintToString(M)) {
- return ::testing::Matcher<decltype(arg.TSC)>(M).MatchAndExplain(
- arg.TSC, result_listener);
-}
-
-} // namespace testing
-} // namespace xray
-} // namespace llvm
-
-namespace __xray {
-
-std::string serialize(BufferQueue &Buffers, int32_t Version);
-
-template <class T> void PrintTo(const Array<T> &A, std::ostream *OS) {
- *OS << "[";
- bool first = true;
- for (const auto &E : A) {
- if (!first) {
- *OS << ", ";
- }
- PrintTo(E, OS);
- first = false;
- }
- *OS << "]";
-}
-
-} // namespace __xray
-
-#endif // COMPILER_RT_LIB_XRAY_TESTS_TEST_HELPERS_H_
diff --git a/lib/xray/tests/unit/xray_unit_test_main.cc b/lib/xray/tests/unit/xray_unit_test_main.cc
deleted file mode 100644
index 27d17527dd5bc..0000000000000
--- a/lib/xray/tests/unit/xray_unit_test_main.cc
+++ /dev/null
@@ -1,18 +0,0 @@
-//===-- xray_unit_test_main.cc --------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// This file is a part of XRay, a function call tracing system.
-//
-//===----------------------------------------------------------------------===//
-#include "gtest/gtest.h"
-
-int main(int argc, char **argv) {
- testing::InitGoogleTest(&argc, argv);
- return RUN_ALL_TESTS();
-}