summaryrefslogtreecommitdiff
path: root/lib/asan
diff options
context:
space:
mode:
Diffstat (limited to 'lib/asan')
-rw-r--r--lib/asan/.clang-format2
-rw-r--r--lib/asan/CMakeLists.txt316
-rw-r--r--lib/asan/README.txt26
-rw-r--r--lib/asan/asan.syms.extra4
-rw-r--r--lib/asan/asan_activation.cc144
-rw-r--r--lib/asan/asan_activation.h23
-rw-r--r--lib/asan/asan_activation_flags.inc37
-rw-r--r--lib/asan/asan_allocator.cc1109
-rw-r--r--lib/asan/asan_allocator.h224
-rw-r--r--lib/asan/asan_blacklist.txt13
-rw-r--r--lib/asan/asan_debugging.cc147
-rw-r--r--lib/asan/asan_descriptions.cc502
-rw-r--r--lib/asan/asan_descriptions.h263
-rw-r--r--lib/asan/asan_errors.cc586
-rw-r--r--lib/asan/asan_errors.h439
-rw-r--r--lib/asan/asan_fake_stack.cc283
-rw-r--r--lib/asan/asan_fake_stack.h176
-rw-r--r--lib/asan/asan_flags.cc215
-rw-r--r--lib/asan/asan_flags.h49
-rw-r--r--lib/asan/asan_flags.inc163
-rw-r--r--lib/asan/asan_fuchsia.cc218
-rw-r--r--lib/asan/asan_globals.cc462
-rw-r--r--lib/asan/asan_globals_win.cc62
-rw-r--r--lib/asan/asan_init_version.h45
-rw-r--r--lib/asan/asan_interceptors.cc667
-rw-r--r--lib/asan/asan_interceptors.h135
-rw-r--r--lib/asan/asan_interceptors_memintrinsics.cc44
-rw-r--r--lib/asan/asan_interceptors_memintrinsics.h155
-rw-r--r--lib/asan/asan_interface.inc169
-rw-r--r--lib/asan/asan_interface_internal.h255
-rw-r--r--lib/asan/asan_internal.h159
-rw-r--r--lib/asan/asan_linux.cc254
-rw-r--r--lib/asan/asan_lock.h0
-rw-r--r--lib/asan/asan_mac.cc332
-rw-r--r--lib/asan/asan_malloc_linux.cc300
-rw-r--r--lib/asan/asan_malloc_local.h44
-rw-r--r--lib/asan/asan_malloc_mac.cc64
-rw-r--r--lib/asan/asan_malloc_win.cc252
-rw-r--r--lib/asan/asan_mapping.h401
-rw-r--r--lib/asan/asan_mapping_myriad.h86
-rw-r--r--lib/asan/asan_memory_profile.cc130
-rw-r--r--lib/asan/asan_new_delete.cc211
-rw-r--r--lib/asan/asan_poisoning.cc461
-rw-r--r--lib/asan/asan_poisoning.h99
-rw-r--r--lib/asan/asan_posix.cc72
-rw-r--r--lib/asan/asan_preinit.cc25
-rw-r--r--lib/asan/asan_premap_shadow.cc79
-rw-r--r--lib/asan/asan_premap_shadow.h30
-rw-r--r--lib/asan/asan_report.cc552
-rw-r--r--lib/asan/asan_report.h94
-rw-r--r--lib/asan/asan_rtems.cc253
-rw-r--r--lib/asan/asan_rtl.cc589
-rw-r--r--lib/asan/asan_scariness_score.h74
-rw-r--r--lib/asan/asan_shadow_setup.cc165
-rw-r--r--lib/asan/asan_stack.cc40
-rw-r--r--lib/asan/asan_stack.h114
-rw-r--r--lib/asan/asan_stats.cc174
-rw-r--r--lib/asan/asan_stats.h72
-rw-r--r--lib/asan/asan_suppressions.cc105
-rw-r--r--lib/asan/asan_suppressions.h30
-rw-r--r--lib/asan/asan_thread.cc529
-rw-r--r--lib/asan/asan_thread.h199
-rw-r--r--lib/asan/asan_win.cc348
-rw-r--r--lib/asan/asan_win_dll_thunk.cc152
-rw-r--r--lib/asan/asan_win_dynamic_runtime_thunk.cc131
-rw-r--r--lib/asan/asan_win_weak_interception.cc23
-rw-r--r--lib/asan/scripts/CMakeLists.txt4
-rwxr-xr-xlib/asan/scripts/asan_device_setup467
-rwxr-xr-xlib/asan/scripts/asan_symbolize.py519
-rw-r--r--lib/asan/tests/CMakeLists.txt314
-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.cc420
-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.cc271
-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.cc1361
-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/asan/weak_symbols.txt12
91 files changed, 0 insertions, 19315 deletions
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 2ae5c85ecefba..0000000000000
--- a/lib/asan/CMakeLists.txt
+++ /dev/null
@@ -1,316 +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})
-
-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)
-
-# 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})
-
-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})
- 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})
- 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})
-
- 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})
-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_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 (MSVC)
- 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})
- 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})
-
- 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})
-
- 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/README.txt b/lib/asan/README.txt
deleted file mode 100644
index bb6ff42c5cde4..0000000000000
--- a/lib/asan/README.txt
+++ /dev/null
@@ -1,26 +0,0 @@
-AddressSanitizer RT
-================================
-This directory contains sources of the AddressSanitizer (ASan) runtime library.
-
-Directory structure:
-README.txt : This file.
-Makefile.mk : File for make-based build.
-CMakeLists.txt : File for cmake-based build.
-asan_*.{cc,h} : Sources of the asan runtime library.
-scripts/* : Helper scripts.
-tests/* : ASan unit tests.
-
-Also ASan runtime needs the following libraries:
-lib/interception/ : Machinery used to intercept function calls.
-lib/sanitizer_common/ : Code shared between various sanitizers.
-
-ASan runtime currently also embeds part of LeakSanitizer runtime for
-leak detection (lib/lsan/lsan_common.{cc,h}).
-
-ASan runtime can only be built by CMake. You can run ASan tests
-from the root of your CMake build tree:
-
-make check-asan
-
-For more instructions see:
-https://github.com/google/sanitizers/wiki/AddressSanitizerHowToBuild
diff --git a/lib/asan/asan.syms.extra b/lib/asan/asan.syms.extra
deleted file mode 100644
index f8e9b3aedcc3b..0000000000000
--- a/lib/asan/asan.syms.extra
+++ /dev/null
@@ -1,4 +0,0 @@
-__asan_*
-__lsan_*
-__ubsan_*
-__sancov_*
diff --git a/lib/asan/asan_activation.cc b/lib/asan/asan_activation.cc
deleted file mode 100644
index d642be93488dc..0000000000000
--- a/lib/asan/asan_activation.cc
+++ /dev/null
@@ -1,144 +0,0 @@
-//===-- asan_activation.cc --------------------------------------*- 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.
-//
-// ASan activation/deactivation logic.
-//===----------------------------------------------------------------------===//
-
-#include "asan_activation.h"
-#include "asan_allocator.h"
-#include "asan_flags.h"
-#include "asan_internal.h"
-#include "asan_mapping.h"
-#include "asan_poisoning.h"
-#include "asan_stack.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_flags.h"
-
-namespace __asan {
-
-static struct AsanDeactivatedFlags {
- AllocatorOptions allocator_options;
- int malloc_context_size;
- bool poison_heap;
- bool coverage;
- const char *coverage_dir;
-
- void RegisterActivationFlags(FlagParser *parser, Flags *f, CommonFlags *cf) {
-#define ASAN_ACTIVATION_FLAG(Type, Name) \
- RegisterFlag(parser, #Name, "", &f->Name);
-#define COMMON_ACTIVATION_FLAG(Type, Name) \
- RegisterFlag(parser, #Name, "", &cf->Name);
-#include "asan_activation_flags.inc"
-#undef ASAN_ACTIVATION_FLAG
-#undef COMMON_ACTIVATION_FLAG
-
- RegisterIncludeFlags(parser, cf);
- }
-
- void OverrideFromActivationFlags() {
- Flags f;
- CommonFlags cf;
- FlagParser parser;
- RegisterActivationFlags(&parser, &f, &cf);
-
- cf.SetDefaults();
- // Copy the current activation flags.
- allocator_options.CopyTo(&f, &cf);
- cf.malloc_context_size = malloc_context_size;
- f.poison_heap = poison_heap;
- cf.coverage = coverage;
- cf.coverage_dir = coverage_dir;
- cf.verbosity = Verbosity();
- cf.help = false; // this is activation-specific help
-
- // Check if activation flags need to be overriden.
- if (const char *env = GetEnv("ASAN_ACTIVATION_OPTIONS")) {
- parser.ParseString(env);
- }
-
- InitializeCommonFlags(&cf);
-
- if (Verbosity()) ReportUnrecognizedFlags();
-
- if (cf.help) parser.PrintFlagDescriptions();
-
- allocator_options.SetFrom(&f, &cf);
- malloc_context_size = cf.malloc_context_size;
- poison_heap = f.poison_heap;
- coverage = cf.coverage;
- coverage_dir = cf.coverage_dir;
- }
-
- void Print() {
- Report(
- "quarantine_size_mb %d, thread_local_quarantine_size_kb %d, "
- "max_redzone %d, poison_heap %d, malloc_context_size %d, "
- "alloc_dealloc_mismatch %d, allocator_may_return_null %d, coverage %d, "
- "coverage_dir %s, allocator_release_to_os_interval_ms %d\n",
- allocator_options.quarantine_size_mb,
- allocator_options.thread_local_quarantine_size_kb,
- allocator_options.max_redzone, poison_heap, malloc_context_size,
- allocator_options.alloc_dealloc_mismatch,
- allocator_options.may_return_null, coverage, coverage_dir,
- allocator_options.release_to_os_interval_ms);
- }
-} asan_deactivated_flags;
-
-static bool asan_is_deactivated;
-
-void AsanDeactivate() {
- CHECK(!asan_is_deactivated);
- VReport(1, "Deactivating ASan\n");
-
- // Stash runtime state.
- GetAllocatorOptions(&asan_deactivated_flags.allocator_options);
- asan_deactivated_flags.malloc_context_size = GetMallocContextSize();
- asan_deactivated_flags.poison_heap = CanPoisonMemory();
- asan_deactivated_flags.coverage = common_flags()->coverage;
- asan_deactivated_flags.coverage_dir = common_flags()->coverage_dir;
-
- // Deactivate the runtime.
- SetCanPoisonMemory(false);
- SetMallocContextSize(1);
-
- AllocatorOptions disabled = asan_deactivated_flags.allocator_options;
- disabled.quarantine_size_mb = 0;
- disabled.thread_local_quarantine_size_kb = 0;
- // Redzone must be at least Max(16, granularity) bytes long.
- disabled.min_redzone = Max(16, (int)SHADOW_GRANULARITY);
- disabled.max_redzone = disabled.min_redzone;
- disabled.alloc_dealloc_mismatch = false;
- disabled.may_return_null = true;
- ReInitializeAllocator(disabled);
-
- asan_is_deactivated = true;
-}
-
-void AsanActivate() {
- if (!asan_is_deactivated) return;
- VReport(1, "Activating ASan\n");
-
- UpdateProcessName();
-
- asan_deactivated_flags.OverrideFromActivationFlags();
-
- SetCanPoisonMemory(asan_deactivated_flags.poison_heap);
- SetMallocContextSize(asan_deactivated_flags.malloc_context_size);
- ReInitializeAllocator(asan_deactivated_flags.allocator_options);
-
- asan_is_deactivated = false;
- if (Verbosity()) {
- Report("Activated with flags:\n");
- asan_deactivated_flags.Print();
- }
-}
-
-} // namespace __asan
diff --git a/lib/asan/asan_activation.h b/lib/asan/asan_activation.h
deleted file mode 100644
index d5e1ce4330011..0000000000000
--- a/lib/asan/asan_activation.h
+++ /dev/null
@@ -1,23 +0,0 @@
-//===-- asan_activation.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.
-//
-// ASan activation/deactivation logic.
-//===----------------------------------------------------------------------===//
-
-#ifndef ASAN_ACTIVATION_H
-#define ASAN_ACTIVATION_H
-
-namespace __asan {
-void AsanDeactivate();
-void AsanActivate();
-} // namespace __asan
-
-#endif // ASAN_ACTIVATION_H
diff --git a/lib/asan/asan_activation_flags.inc b/lib/asan/asan_activation_flags.inc
deleted file mode 100644
index 1c66e5bb53a52..0000000000000
--- a/lib/asan/asan_activation_flags.inc
+++ /dev/null
@@ -1,37 +0,0 @@
-//===-- asan_activation_flags.inc -------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// A subset of ASan (and common) runtime flags supported at activation time.
-//
-//===----------------------------------------------------------------------===//
-#ifndef ASAN_ACTIVATION_FLAG
-# error "Define ASAN_ACTIVATION_FLAG prior to including this file!"
-#endif
-
-#ifndef COMMON_ACTIVATION_FLAG
-# error "Define COMMON_ACTIVATION_FLAG prior to including this file!"
-#endif
-
-// ASAN_ACTIVATION_FLAG(Type, Name)
-// See COMMON_FLAG in sanitizer_flags.inc for more details.
-
-ASAN_ACTIVATION_FLAG(int, redzone)
-ASAN_ACTIVATION_FLAG(int, max_redzone)
-ASAN_ACTIVATION_FLAG(int, quarantine_size_mb)
-ASAN_ACTIVATION_FLAG(int, thread_local_quarantine_size_kb)
-ASAN_ACTIVATION_FLAG(bool, alloc_dealloc_mismatch)
-ASAN_ACTIVATION_FLAG(bool, poison_heap)
-
-COMMON_ACTIVATION_FLAG(bool, allocator_may_return_null)
-COMMON_ACTIVATION_FLAG(int, malloc_context_size)
-COMMON_ACTIVATION_FLAG(bool, coverage)
-COMMON_ACTIVATION_FLAG(const char *, coverage_dir)
-COMMON_ACTIVATION_FLAG(int, verbosity)
-COMMON_ACTIVATION_FLAG(bool, help)
-COMMON_ACTIVATION_FLAG(s32, allocator_release_to_os_interval_ms)
diff --git a/lib/asan/asan_allocator.cc b/lib/asan/asan_allocator.cc
deleted file mode 100644
index c0fad4fa042b8..0000000000000
--- a/lib/asan/asan_allocator.cc
+++ /dev/null
@@ -1,1109 +0,0 @@
-//===-- asan_allocator.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.
-//
-// Implementation of ASan's memory allocator, 2-nd version.
-// This variant uses the allocator from sanitizer_common, i.e. the one shared
-// with ThreadSanitizer and MemorySanitizer.
-//
-//===----------------------------------------------------------------------===//
-
-#include "asan_allocator.h"
-#include "asan_mapping.h"
-#include "asan_poisoning.h"
-#include "asan_report.h"
-#include "asan_stack.h"
-#include "asan_thread.h"
-#include "sanitizer_common/sanitizer_allocator_checks.h"
-#include "sanitizer_common/sanitizer_allocator_interface.h"
-#include "sanitizer_common/sanitizer_errno.h"
-#include "sanitizer_common/sanitizer_flags.h"
-#include "sanitizer_common/sanitizer_internal_defs.h"
-#include "sanitizer_common/sanitizer_list.h"
-#include "sanitizer_common/sanitizer_stackdepot.h"
-#include "sanitizer_common/sanitizer_quarantine.h"
-#include "lsan/lsan_common.h"
-
-namespace __asan {
-
-// Valid redzone sizes are 16, 32, 64, ... 2048, so we encode them in 3 bits.
-// We use adaptive redzones: for larger allocation larger redzones are used.
-static u32 RZLog2Size(u32 rz_log) {
- CHECK_LT(rz_log, 8);
- return 16 << rz_log;
-}
-
-static u32 RZSize2Log(u32 rz_size) {
- CHECK_GE(rz_size, 16);
- CHECK_LE(rz_size, 2048);
- CHECK(IsPowerOfTwo(rz_size));
- u32 res = Log2(rz_size) - 4;
- CHECK_EQ(rz_size, RZLog2Size(res));
- return res;
-}
-
-static AsanAllocator &get_allocator();
-
-// The memory chunk allocated from the underlying allocator looks like this:
-// L L L L L L H H U U U U U U R R
-// L -- left redzone words (0 or more bytes)
-// H -- ChunkHeader (16 bytes), which is also a part of the left redzone.
-// U -- user memory.
-// R -- right redzone (0 or more bytes)
-// ChunkBase consists of ChunkHeader and other bytes that overlap with user
-// memory.
-
-// If the left redzone is greater than the ChunkHeader size we store a magic
-// value in the first uptr word of the memory block and store the address of
-// ChunkBase in the next uptr.
-// M B L L L L L L L L L H H U U U U U U
-// | ^
-// ---------------------|
-// M -- magic value kAllocBegMagic
-// B -- address of ChunkHeader pointing to the first 'H'
-static const uptr kAllocBegMagic = 0xCC6E96B9;
-
-struct ChunkHeader {
- // 1-st 8 bytes.
- u32 chunk_state : 8; // Must be first.
- u32 alloc_tid : 24;
-
- u32 free_tid : 24;
- u32 from_memalign : 1;
- u32 alloc_type : 2;
- u32 rz_log : 3;
- u32 lsan_tag : 2;
- // 2-nd 8 bytes
- // This field is used for small sizes. For large sizes it is equal to
- // SizeClassMap::kMaxSize and the actual size is stored in the
- // SecondaryAllocator's metadata.
- u32 user_requested_size : 29;
- // align < 8 -> 0
- // else -> log2(min(align, 512)) - 2
- u32 user_requested_alignment_log : 3;
- u32 alloc_context_id;
-};
-
-struct ChunkBase : ChunkHeader {
- // Header2, intersects with user memory.
- u32 free_context_id;
-};
-
-static const uptr kChunkHeaderSize = sizeof(ChunkHeader);
-static const uptr kChunkHeader2Size = sizeof(ChunkBase) - kChunkHeaderSize;
-COMPILER_CHECK(kChunkHeaderSize == 16);
-COMPILER_CHECK(kChunkHeader2Size <= 16);
-
-// Every chunk of memory allocated by this allocator can be in one of 3 states:
-// CHUNK_AVAILABLE: the chunk is in the free list and ready to be allocated.
-// CHUNK_ALLOCATED: the chunk is allocated and not yet freed.
-// CHUNK_QUARANTINE: the chunk was freed and put into quarantine zone.
-enum {
- CHUNK_AVAILABLE = 0, // 0 is the default value even if we didn't set it.
- CHUNK_ALLOCATED = 2,
- CHUNK_QUARANTINE = 3
-};
-
-struct AsanChunk: ChunkBase {
- uptr Beg() { return reinterpret_cast<uptr>(this) + kChunkHeaderSize; }
- uptr UsedSize(bool locked_version = false) {
- if (user_requested_size != SizeClassMap::kMaxSize)
- return user_requested_size;
- return *reinterpret_cast<uptr *>(
- get_allocator().GetMetaData(AllocBeg(locked_version)));
- }
- void *AllocBeg(bool locked_version = false) {
- if (from_memalign) {
- if (locked_version)
- return get_allocator().GetBlockBeginFastLocked(
- reinterpret_cast<void *>(this));
- return get_allocator().GetBlockBegin(reinterpret_cast<void *>(this));
- }
- return reinterpret_cast<void*>(Beg() - RZLog2Size(rz_log));
- }
- bool AddrIsInside(uptr addr, bool locked_version = false) {
- return (addr >= Beg()) && (addr < Beg() + UsedSize(locked_version));
- }
-};
-
-struct QuarantineCallback {
- QuarantineCallback(AllocatorCache *cache, BufferedStackTrace *stack)
- : cache_(cache),
- stack_(stack) {
- }
-
- void Recycle(AsanChunk *m) {
- CHECK_EQ(m->chunk_state, CHUNK_QUARANTINE);
- atomic_store((atomic_uint8_t*)m, CHUNK_AVAILABLE, memory_order_relaxed);
- CHECK_NE(m->alloc_tid, kInvalidTid);
- CHECK_NE(m->free_tid, kInvalidTid);
- PoisonShadow(m->Beg(),
- RoundUpTo(m->UsedSize(), SHADOW_GRANULARITY),
- kAsanHeapLeftRedzoneMagic);
- void *p = reinterpret_cast<void *>(m->AllocBeg());
- if (p != m) {
- uptr *alloc_magic = reinterpret_cast<uptr *>(p);
- CHECK_EQ(alloc_magic[0], kAllocBegMagic);
- // Clear the magic value, as allocator internals may overwrite the
- // contents of deallocated chunk, confusing GetAsanChunk lookup.
- alloc_magic[0] = 0;
- CHECK_EQ(alloc_magic[1], reinterpret_cast<uptr>(m));
- }
-
- // Statistics.
- AsanStats &thread_stats = GetCurrentThreadStats();
- thread_stats.real_frees++;
- thread_stats.really_freed += m->UsedSize();
-
- get_allocator().Deallocate(cache_, p);
- }
-
- void *Allocate(uptr size) {
- void *res = get_allocator().Allocate(cache_, size, 1);
- // TODO(alekseys): Consider making quarantine OOM-friendly.
- if (UNLIKELY(!res))
- ReportOutOfMemory(size, stack_);
- return res;
- }
-
- void Deallocate(void *p) {
- get_allocator().Deallocate(cache_, p);
- }
-
- private:
- AllocatorCache* const cache_;
- BufferedStackTrace* const stack_;
-};
-
-typedef Quarantine<QuarantineCallback, AsanChunk> AsanQuarantine;
-typedef AsanQuarantine::Cache QuarantineCache;
-
-void AsanMapUnmapCallback::OnMap(uptr p, uptr size) const {
- PoisonShadow(p, size, kAsanHeapLeftRedzoneMagic);
- // Statistics.
- AsanStats &thread_stats = GetCurrentThreadStats();
- thread_stats.mmaps++;
- thread_stats.mmaped += size;
-}
-void AsanMapUnmapCallback::OnUnmap(uptr p, uptr size) const {
- PoisonShadow(p, size, 0);
- // We are about to unmap a chunk of user memory.
- // Mark the corresponding shadow memory as not needed.
- FlushUnneededASanShadowMemory(p, size);
- // Statistics.
- AsanStats &thread_stats = GetCurrentThreadStats();
- thread_stats.munmaps++;
- thread_stats.munmaped += size;
-}
-
-// We can not use THREADLOCAL because it is not supported on some of the
-// platforms we care about (OSX 10.6, Android).
-// static THREADLOCAL AllocatorCache cache;
-AllocatorCache *GetAllocatorCache(AsanThreadLocalMallocStorage *ms) {
- CHECK(ms);
- return &ms->allocator_cache;
-}
-
-QuarantineCache *GetQuarantineCache(AsanThreadLocalMallocStorage *ms) {
- CHECK(ms);
- CHECK_LE(sizeof(QuarantineCache), sizeof(ms->quarantine_cache));
- return reinterpret_cast<QuarantineCache *>(ms->quarantine_cache);
-}
-
-void AllocatorOptions::SetFrom(const Flags *f, const CommonFlags *cf) {
- quarantine_size_mb = f->quarantine_size_mb;
- thread_local_quarantine_size_kb = f->thread_local_quarantine_size_kb;
- min_redzone = f->redzone;
- max_redzone = f->max_redzone;
- may_return_null = cf->allocator_may_return_null;
- alloc_dealloc_mismatch = f->alloc_dealloc_mismatch;
- release_to_os_interval_ms = cf->allocator_release_to_os_interval_ms;
-}
-
-void AllocatorOptions::CopyTo(Flags *f, CommonFlags *cf) {
- f->quarantine_size_mb = quarantine_size_mb;
- f->thread_local_quarantine_size_kb = thread_local_quarantine_size_kb;
- f->redzone = min_redzone;
- f->max_redzone = max_redzone;
- cf->allocator_may_return_null = may_return_null;
- f->alloc_dealloc_mismatch = alloc_dealloc_mismatch;
- cf->allocator_release_to_os_interval_ms = release_to_os_interval_ms;
-}
-
-struct Allocator {
- static const uptr kMaxAllowedMallocSize =
- FIRST_32_SECOND_64(3UL << 30, 1ULL << 40);
-
- AsanAllocator allocator;
- AsanQuarantine quarantine;
- StaticSpinMutex fallback_mutex;
- AllocatorCache fallback_allocator_cache;
- QuarantineCache fallback_quarantine_cache;
-
- atomic_uint8_t rss_limit_exceeded;
-
- // ------------------- Options --------------------------
- atomic_uint16_t min_redzone;
- atomic_uint16_t max_redzone;
- atomic_uint8_t alloc_dealloc_mismatch;
-
- // ------------------- Initialization ------------------------
- explicit Allocator(LinkerInitialized)
- : quarantine(LINKER_INITIALIZED),
- fallback_quarantine_cache(LINKER_INITIALIZED) {}
-
- void CheckOptions(const AllocatorOptions &options) const {
- CHECK_GE(options.min_redzone, 16);
- CHECK_GE(options.max_redzone, options.min_redzone);
- CHECK_LE(options.max_redzone, 2048);
- CHECK(IsPowerOfTwo(options.min_redzone));
- CHECK(IsPowerOfTwo(options.max_redzone));
- }
-
- void SharedInitCode(const AllocatorOptions &options) {
- CheckOptions(options);
- quarantine.Init((uptr)options.quarantine_size_mb << 20,
- (uptr)options.thread_local_quarantine_size_kb << 10);
- atomic_store(&alloc_dealloc_mismatch, options.alloc_dealloc_mismatch,
- memory_order_release);
- atomic_store(&min_redzone, options.min_redzone, memory_order_release);
- atomic_store(&max_redzone, options.max_redzone, memory_order_release);
- }
-
- void InitLinkerInitialized(const AllocatorOptions &options) {
- SetAllocatorMayReturnNull(options.may_return_null);
- allocator.InitLinkerInitialized(options.release_to_os_interval_ms);
- SharedInitCode(options);
- }
-
- bool RssLimitExceeded() {
- return atomic_load(&rss_limit_exceeded, memory_order_relaxed);
- }
-
- void SetRssLimitExceeded(bool limit_exceeded) {
- atomic_store(&rss_limit_exceeded, limit_exceeded, memory_order_relaxed);
- }
-
- void RePoisonChunk(uptr chunk) {
- // This could be a user-facing chunk (with redzones), or some internal
- // housekeeping chunk, like TransferBatch. Start by assuming the former.
- AsanChunk *ac = GetAsanChunk((void *)chunk);
- uptr allocated_size = allocator.GetActuallyAllocatedSize((void *)ac);
- uptr beg = ac->Beg();
- uptr end = ac->Beg() + ac->UsedSize(true);
- uptr chunk_end = chunk + allocated_size;
- if (chunk < beg && beg < end && end <= chunk_end &&
- ac->chunk_state == CHUNK_ALLOCATED) {
- // Looks like a valid AsanChunk in use, poison redzones only.
- PoisonShadow(chunk, beg - chunk, kAsanHeapLeftRedzoneMagic);
- uptr end_aligned_down = RoundDownTo(end, SHADOW_GRANULARITY);
- FastPoisonShadowPartialRightRedzone(
- end_aligned_down, end - end_aligned_down,
- chunk_end - end_aligned_down, kAsanHeapLeftRedzoneMagic);
- } else {
- // This is either not an AsanChunk or freed or quarantined AsanChunk.
- // In either case, poison everything.
- PoisonShadow(chunk, allocated_size, kAsanHeapLeftRedzoneMagic);
- }
- }
-
- void ReInitialize(const AllocatorOptions &options) {
- SetAllocatorMayReturnNull(options.may_return_null);
- allocator.SetReleaseToOSIntervalMs(options.release_to_os_interval_ms);
- SharedInitCode(options);
-
- // Poison all existing allocation's redzones.
- if (CanPoisonMemory()) {
- allocator.ForceLock();
- allocator.ForEachChunk(
- [](uptr chunk, void *alloc) {
- ((Allocator *)alloc)->RePoisonChunk(chunk);
- },
- this);
- allocator.ForceUnlock();
- }
- }
-
- void GetOptions(AllocatorOptions *options) const {
- options->quarantine_size_mb = quarantine.GetSize() >> 20;
- options->thread_local_quarantine_size_kb = quarantine.GetCacheSize() >> 10;
- options->min_redzone = atomic_load(&min_redzone, memory_order_acquire);
- options->max_redzone = atomic_load(&max_redzone, memory_order_acquire);
- options->may_return_null = AllocatorMayReturnNull();
- options->alloc_dealloc_mismatch =
- atomic_load(&alloc_dealloc_mismatch, memory_order_acquire);
- options->release_to_os_interval_ms = allocator.ReleaseToOSIntervalMs();
- }
-
- // -------------------- Helper methods. -------------------------
- uptr ComputeRZLog(uptr user_requested_size) {
- u32 rz_log =
- user_requested_size <= 64 - 16 ? 0 :
- user_requested_size <= 128 - 32 ? 1 :
- user_requested_size <= 512 - 64 ? 2 :
- user_requested_size <= 4096 - 128 ? 3 :
- user_requested_size <= (1 << 14) - 256 ? 4 :
- user_requested_size <= (1 << 15) - 512 ? 5 :
- user_requested_size <= (1 << 16) - 1024 ? 6 : 7;
- u32 min_rz = atomic_load(&min_redzone, memory_order_acquire);
- u32 max_rz = atomic_load(&max_redzone, memory_order_acquire);
- return Min(Max(rz_log, RZSize2Log(min_rz)), RZSize2Log(max_rz));
- }
-
- static uptr ComputeUserRequestedAlignmentLog(uptr user_requested_alignment) {
- if (user_requested_alignment < 8)
- return 0;
- if (user_requested_alignment > 512)
- user_requested_alignment = 512;
- return Log2(user_requested_alignment) - 2;
- }
-
- static uptr ComputeUserAlignment(uptr user_requested_alignment_log) {
- if (user_requested_alignment_log == 0)
- return 0;
- return 1LL << (user_requested_alignment_log + 2);
- }
-
- // We have an address between two chunks, and we want to report just one.
- AsanChunk *ChooseChunk(uptr addr, AsanChunk *left_chunk,
- AsanChunk *right_chunk) {
- // Prefer an allocated chunk over freed chunk and freed chunk
- // over available chunk.
- if (left_chunk->chunk_state != right_chunk->chunk_state) {
- if (left_chunk->chunk_state == CHUNK_ALLOCATED)
- return left_chunk;
- if (right_chunk->chunk_state == CHUNK_ALLOCATED)
- return right_chunk;
- if (left_chunk->chunk_state == CHUNK_QUARANTINE)
- return left_chunk;
- if (right_chunk->chunk_state == CHUNK_QUARANTINE)
- return right_chunk;
- }
- // Same chunk_state: choose based on offset.
- sptr l_offset = 0, r_offset = 0;
- CHECK(AsanChunkView(left_chunk).AddrIsAtRight(addr, 1, &l_offset));
- CHECK(AsanChunkView(right_chunk).AddrIsAtLeft(addr, 1, &r_offset));
- if (l_offset < r_offset)
- return left_chunk;
- return right_chunk;
- }
-
- // -------------------- Allocation/Deallocation routines ---------------
- void *Allocate(uptr size, uptr alignment, BufferedStackTrace *stack,
- AllocType alloc_type, bool can_fill) {
- if (UNLIKELY(!asan_inited))
- AsanInitFromRtl();
- if (RssLimitExceeded()) {
- if (AllocatorMayReturnNull())
- return nullptr;
- ReportRssLimitExceeded(stack);
- }
- Flags &fl = *flags();
- CHECK(stack);
- const uptr min_alignment = SHADOW_GRANULARITY;
- const uptr user_requested_alignment_log =
- ComputeUserRequestedAlignmentLog(alignment);
- if (alignment < min_alignment)
- alignment = min_alignment;
- if (size == 0) {
- // We'd be happy to avoid allocating memory for zero-size requests, but
- // some programs/tests depend on this behavior and assume that malloc
- // would not return NULL even for zero-size allocations. Moreover, it
- // looks like operator new should never return NULL, and results of
- // consecutive "new" calls must be different even if the allocated size
- // is zero.
- size = 1;
- }
- CHECK(IsPowerOfTwo(alignment));
- uptr rz_log = ComputeRZLog(size);
- uptr rz_size = RZLog2Size(rz_log);
- uptr rounded_size = RoundUpTo(Max(size, kChunkHeader2Size), alignment);
- uptr needed_size = rounded_size + rz_size;
- if (alignment > min_alignment)
- needed_size += alignment;
- bool using_primary_allocator = true;
- // If we are allocating from the secondary allocator, there will be no
- // automatic right redzone, so add the right redzone manually.
- if (!PrimaryAllocator::CanAllocate(needed_size, alignment)) {
- needed_size += rz_size;
- using_primary_allocator = false;
- }
- CHECK(IsAligned(needed_size, min_alignment));
- if (size > kMaxAllowedMallocSize || needed_size > kMaxAllowedMallocSize) {
- if (AllocatorMayReturnNull()) {
- Report("WARNING: AddressSanitizer failed to allocate 0x%zx bytes\n",
- (void*)size);
- return nullptr;
- }
- ReportAllocationSizeTooBig(size, needed_size, kMaxAllowedMallocSize,
- stack);
- }
-
- AsanThread *t = GetCurrentThread();
- void *allocated;
- if (t) {
- AllocatorCache *cache = GetAllocatorCache(&t->malloc_storage());
- allocated = allocator.Allocate(cache, needed_size, 8);
- } else {
- SpinMutexLock l(&fallback_mutex);
- AllocatorCache *cache = &fallback_allocator_cache;
- allocated = allocator.Allocate(cache, needed_size, 8);
- }
- if (UNLIKELY(!allocated)) {
- SetAllocatorOutOfMemory();
- if (AllocatorMayReturnNull())
- return nullptr;
- ReportOutOfMemory(size, stack);
- }
-
- if (*(u8 *)MEM_TO_SHADOW((uptr)allocated) == 0 && CanPoisonMemory()) {
- // Heap poisoning is enabled, but the allocator provides an unpoisoned
- // chunk. This is possible if CanPoisonMemory() was false for some
- // time, for example, due to flags()->start_disabled.
- // Anyway, poison the block before using it for anything else.
- uptr allocated_size = allocator.GetActuallyAllocatedSize(allocated);
- PoisonShadow((uptr)allocated, allocated_size, kAsanHeapLeftRedzoneMagic);
- }
-
- uptr alloc_beg = reinterpret_cast<uptr>(allocated);
- uptr alloc_end = alloc_beg + needed_size;
- uptr beg_plus_redzone = alloc_beg + rz_size;
- uptr user_beg = beg_plus_redzone;
- if (!IsAligned(user_beg, alignment))
- user_beg = RoundUpTo(user_beg, alignment);
- uptr user_end = user_beg + size;
- CHECK_LE(user_end, alloc_end);
- uptr chunk_beg = user_beg - kChunkHeaderSize;
- AsanChunk *m = reinterpret_cast<AsanChunk *>(chunk_beg);
- m->alloc_type = alloc_type;
- m->rz_log = rz_log;
- u32 alloc_tid = t ? t->tid() : 0;
- m->alloc_tid = alloc_tid;
- CHECK_EQ(alloc_tid, m->alloc_tid); // Does alloc_tid fit into the bitfield?
- m->free_tid = kInvalidTid;
- m->from_memalign = user_beg != beg_plus_redzone;
- if (alloc_beg != chunk_beg) {
- CHECK_LE(alloc_beg+ 2 * sizeof(uptr), chunk_beg);
- reinterpret_cast<uptr *>(alloc_beg)[0] = kAllocBegMagic;
- reinterpret_cast<uptr *>(alloc_beg)[1] = chunk_beg;
- }
- if (using_primary_allocator) {
- CHECK(size);
- m->user_requested_size = size;
- CHECK(allocator.FromPrimary(allocated));
- } else {
- CHECK(!allocator.FromPrimary(allocated));
- m->user_requested_size = SizeClassMap::kMaxSize;
- uptr *meta = reinterpret_cast<uptr *>(allocator.GetMetaData(allocated));
- meta[0] = size;
- meta[1] = chunk_beg;
- }
- m->user_requested_alignment_log = user_requested_alignment_log;
-
- m->alloc_context_id = StackDepotPut(*stack);
-
- uptr size_rounded_down_to_granularity =
- RoundDownTo(size, SHADOW_GRANULARITY);
- // Unpoison the bulk of the memory region.
- if (size_rounded_down_to_granularity)
- PoisonShadow(user_beg, size_rounded_down_to_granularity, 0);
- // Deal with the end of the region if size is not aligned to granularity.
- if (size != size_rounded_down_to_granularity && CanPoisonMemory()) {
- u8 *shadow =
- (u8 *)MemToShadow(user_beg + size_rounded_down_to_granularity);
- *shadow = fl.poison_partial ? (size & (SHADOW_GRANULARITY - 1)) : 0;
- }
-
- AsanStats &thread_stats = GetCurrentThreadStats();
- thread_stats.mallocs++;
- thread_stats.malloced += size;
- thread_stats.malloced_redzones += needed_size - size;
- if (needed_size > SizeClassMap::kMaxSize)
- thread_stats.malloc_large++;
- else
- thread_stats.malloced_by_size[SizeClassMap::ClassID(needed_size)]++;
-
- void *res = reinterpret_cast<void *>(user_beg);
- if (can_fill && fl.max_malloc_fill_size) {
- uptr fill_size = Min(size, (uptr)fl.max_malloc_fill_size);
- REAL(memset)(res, fl.malloc_fill_byte, fill_size);
- }
-#if CAN_SANITIZE_LEAKS
- m->lsan_tag = __lsan::DisabledInThisThread() ? __lsan::kIgnored
- : __lsan::kDirectlyLeaked;
-#endif
- // Must be the last mutation of metadata in this function.
- atomic_store((atomic_uint8_t *)m, CHUNK_ALLOCATED, memory_order_release);
- ASAN_MALLOC_HOOK(res, size);
- return res;
- }
-
- // Set quarantine flag if chunk is allocated, issue ASan error report on
- // available and quarantined chunks. Return true on success, false otherwise.
- bool AtomicallySetQuarantineFlagIfAllocated(AsanChunk *m, void *ptr,
- BufferedStackTrace *stack) {
- u8 old_chunk_state = CHUNK_ALLOCATED;
- // Flip the chunk_state atomically to avoid race on double-free.
- if (!atomic_compare_exchange_strong((atomic_uint8_t *)m, &old_chunk_state,
- CHUNK_QUARANTINE,
- memory_order_acquire)) {
- ReportInvalidFree(ptr, old_chunk_state, stack);
- // It's not safe to push a chunk in quarantine on invalid free.
- return false;
- }
- CHECK_EQ(CHUNK_ALLOCATED, old_chunk_state);
- return true;
- }
-
- // Expects the chunk to already be marked as quarantined by using
- // AtomicallySetQuarantineFlagIfAllocated.
- void QuarantineChunk(AsanChunk *m, void *ptr, BufferedStackTrace *stack) {
- CHECK_EQ(m->chunk_state, CHUNK_QUARANTINE);
- CHECK_GE(m->alloc_tid, 0);
- if (SANITIZER_WORDSIZE == 64) // On 32-bits this resides in user area.
- CHECK_EQ(m->free_tid, kInvalidTid);
- AsanThread *t = GetCurrentThread();
- m->free_tid = t ? t->tid() : 0;
- m->free_context_id = StackDepotPut(*stack);
-
- Flags &fl = *flags();
- if (fl.max_free_fill_size > 0) {
- // We have to skip the chunk header, it contains free_context_id.
- uptr scribble_start = (uptr)m + kChunkHeaderSize + kChunkHeader2Size;
- if (m->UsedSize() >= kChunkHeader2Size) { // Skip Header2 in user area.
- uptr size_to_fill = m->UsedSize() - kChunkHeader2Size;
- size_to_fill = Min(size_to_fill, (uptr)fl.max_free_fill_size);
- REAL(memset)((void *)scribble_start, fl.free_fill_byte, size_to_fill);
- }
- }
-
- // Poison the region.
- PoisonShadow(m->Beg(),
- RoundUpTo(m->UsedSize(), SHADOW_GRANULARITY),
- kAsanHeapFreeMagic);
-
- AsanStats &thread_stats = GetCurrentThreadStats();
- thread_stats.frees++;
- thread_stats.freed += m->UsedSize();
-
- // Push into quarantine.
- if (t) {
- AsanThreadLocalMallocStorage *ms = &t->malloc_storage();
- AllocatorCache *ac = GetAllocatorCache(ms);
- quarantine.Put(GetQuarantineCache(ms), QuarantineCallback(ac, stack), m,
- m->UsedSize());
- } else {
- SpinMutexLock l(&fallback_mutex);
- AllocatorCache *ac = &fallback_allocator_cache;
- quarantine.Put(&fallback_quarantine_cache, QuarantineCallback(ac, stack),
- m, m->UsedSize());
- }
- }
-
- void Deallocate(void *ptr, uptr delete_size, uptr delete_alignment,
- BufferedStackTrace *stack, AllocType alloc_type) {
- uptr p = reinterpret_cast<uptr>(ptr);
- if (p == 0) return;
-
- uptr chunk_beg = p - kChunkHeaderSize;
- AsanChunk *m = reinterpret_cast<AsanChunk *>(chunk_beg);
-
- // On Windows, uninstrumented DLLs may allocate memory before ASan hooks
- // malloc. Don't report an invalid free in this case.
- if (SANITIZER_WINDOWS &&
- !get_allocator().PointerIsMine(ptr)) {
- if (!IsSystemHeapAddress(p))
- ReportFreeNotMalloced(p, stack);
- return;
- }
-
- ASAN_FREE_HOOK(ptr);
-
- // Must mark the chunk as quarantined before any changes to its metadata.
- // Do not quarantine given chunk if we failed to set CHUNK_QUARANTINE flag.
- if (!AtomicallySetQuarantineFlagIfAllocated(m, ptr, stack)) return;
-
- if (m->alloc_type != alloc_type) {
- if (atomic_load(&alloc_dealloc_mismatch, memory_order_acquire)) {
- ReportAllocTypeMismatch((uptr)ptr, stack, (AllocType)m->alloc_type,
- (AllocType)alloc_type);
- }
- } else {
- if (flags()->new_delete_type_mismatch &&
- (alloc_type == FROM_NEW || alloc_type == FROM_NEW_BR) &&
- ((delete_size && delete_size != m->UsedSize()) ||
- ComputeUserRequestedAlignmentLog(delete_alignment) !=
- m->user_requested_alignment_log)) {
- ReportNewDeleteTypeMismatch(p, delete_size, delete_alignment, stack);
- }
- }
-
- QuarantineChunk(m, ptr, stack);
- }
-
- void *Reallocate(void *old_ptr, uptr new_size, BufferedStackTrace *stack) {
- CHECK(old_ptr && new_size);
- uptr p = reinterpret_cast<uptr>(old_ptr);
- uptr chunk_beg = p - kChunkHeaderSize;
- AsanChunk *m = reinterpret_cast<AsanChunk *>(chunk_beg);
-
- AsanStats &thread_stats = GetCurrentThreadStats();
- thread_stats.reallocs++;
- thread_stats.realloced += new_size;
-
- void *new_ptr = Allocate(new_size, 8, stack, FROM_MALLOC, true);
- if (new_ptr) {
- u8 chunk_state = m->chunk_state;
- if (chunk_state != CHUNK_ALLOCATED)
- ReportInvalidFree(old_ptr, chunk_state, stack);
- CHECK_NE(REAL(memcpy), nullptr);
- uptr memcpy_size = Min(new_size, m->UsedSize());
- // If realloc() races with free(), we may start copying freed memory.
- // However, we will report racy double-free later anyway.
- REAL(memcpy)(new_ptr, old_ptr, memcpy_size);
- Deallocate(old_ptr, 0, 0, stack, FROM_MALLOC);
- }
- return new_ptr;
- }
-
- void *Calloc(uptr nmemb, uptr size, BufferedStackTrace *stack) {
- if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
- if (AllocatorMayReturnNull())
- return nullptr;
- ReportCallocOverflow(nmemb, size, stack);
- }
- void *ptr = Allocate(nmemb * size, 8, stack, FROM_MALLOC, false);
- // If the memory comes from the secondary allocator no need to clear it
- // as it comes directly from mmap.
- if (ptr && allocator.FromPrimary(ptr))
- REAL(memset)(ptr, 0, nmemb * size);
- return ptr;
- }
-
- void ReportInvalidFree(void *ptr, u8 chunk_state, BufferedStackTrace *stack) {
- if (chunk_state == CHUNK_QUARANTINE)
- ReportDoubleFree((uptr)ptr, stack);
- else
- ReportFreeNotMalloced((uptr)ptr, stack);
- }
-
- void CommitBack(AsanThreadLocalMallocStorage *ms, BufferedStackTrace *stack) {
- AllocatorCache *ac = GetAllocatorCache(ms);
- quarantine.Drain(GetQuarantineCache(ms), QuarantineCallback(ac, stack));
- allocator.SwallowCache(ac);
- }
-
- // -------------------------- Chunk lookup ----------------------
-
- // Assumes alloc_beg == allocator.GetBlockBegin(alloc_beg).
- AsanChunk *GetAsanChunk(void *alloc_beg) {
- if (!alloc_beg) return nullptr;
- if (!allocator.FromPrimary(alloc_beg)) {
- uptr *meta = reinterpret_cast<uptr *>(allocator.GetMetaData(alloc_beg));
- AsanChunk *m = reinterpret_cast<AsanChunk *>(meta[1]);
- return m;
- }
- uptr *alloc_magic = reinterpret_cast<uptr *>(alloc_beg);
- if (alloc_magic[0] == kAllocBegMagic)
- return reinterpret_cast<AsanChunk *>(alloc_magic[1]);
- return reinterpret_cast<AsanChunk *>(alloc_beg);
- }
-
- AsanChunk *GetAsanChunkByAddr(uptr p) {
- void *alloc_beg = allocator.GetBlockBegin(reinterpret_cast<void *>(p));
- return GetAsanChunk(alloc_beg);
- }
-
- // Allocator must be locked when this function is called.
- AsanChunk *GetAsanChunkByAddrFastLocked(uptr p) {
- void *alloc_beg =
- allocator.GetBlockBeginFastLocked(reinterpret_cast<void *>(p));
- return GetAsanChunk(alloc_beg);
- }
-
- uptr AllocationSize(uptr p) {
- AsanChunk *m = GetAsanChunkByAddr(p);
- if (!m) return 0;
- if (m->chunk_state != CHUNK_ALLOCATED) return 0;
- if (m->Beg() != p) return 0;
- return m->UsedSize();
- }
-
- AsanChunkView FindHeapChunkByAddress(uptr addr) {
- AsanChunk *m1 = GetAsanChunkByAddr(addr);
- if (!m1) return AsanChunkView(m1);
- sptr offset = 0;
- if (AsanChunkView(m1).AddrIsAtLeft(addr, 1, &offset)) {
- // The address is in the chunk's left redzone, so maybe it is actually
- // a right buffer overflow from the other chunk to the left.
- // Search a bit to the left to see if there is another chunk.
- AsanChunk *m2 = nullptr;
- for (uptr l = 1; l < GetPageSizeCached(); l++) {
- m2 = GetAsanChunkByAddr(addr - l);
- if (m2 == m1) continue; // Still the same chunk.
- break;
- }
- if (m2 && AsanChunkView(m2).AddrIsAtRight(addr, 1, &offset))
- m1 = ChooseChunk(addr, m2, m1);
- }
- return AsanChunkView(m1);
- }
-
- void Purge(BufferedStackTrace *stack) {
- AsanThread *t = GetCurrentThread();
- if (t) {
- AsanThreadLocalMallocStorage *ms = &t->malloc_storage();
- quarantine.DrainAndRecycle(GetQuarantineCache(ms),
- QuarantineCallback(GetAllocatorCache(ms),
- stack));
- }
- {
- SpinMutexLock l(&fallback_mutex);
- quarantine.DrainAndRecycle(&fallback_quarantine_cache,
- QuarantineCallback(&fallback_allocator_cache,
- stack));
- }
-
- allocator.ForceReleaseToOS();
- }
-
- void PrintStats() {
- allocator.PrintStats();
- quarantine.PrintStats();
- }
-
- void ForceLock() {
- allocator.ForceLock();
- fallback_mutex.Lock();
- }
-
- void ForceUnlock() {
- fallback_mutex.Unlock();
- allocator.ForceUnlock();
- }
-};
-
-static Allocator instance(LINKER_INITIALIZED);
-
-static AsanAllocator &get_allocator() {
- return instance.allocator;
-}
-
-bool AsanChunkView::IsValid() const {
- return chunk_ && chunk_->chunk_state != CHUNK_AVAILABLE;
-}
-bool AsanChunkView::IsAllocated() const {
- return chunk_ && chunk_->chunk_state == CHUNK_ALLOCATED;
-}
-bool AsanChunkView::IsQuarantined() const {
- return chunk_ && chunk_->chunk_state == CHUNK_QUARANTINE;
-}
-uptr AsanChunkView::Beg() const { return chunk_->Beg(); }
-uptr AsanChunkView::End() const { return Beg() + UsedSize(); }
-uptr AsanChunkView::UsedSize() const { return chunk_->UsedSize(); }
-u32 AsanChunkView::UserRequestedAlignment() const {
- return Allocator::ComputeUserAlignment(chunk_->user_requested_alignment_log);
-}
-uptr AsanChunkView::AllocTid() const { return chunk_->alloc_tid; }
-uptr AsanChunkView::FreeTid() const { return chunk_->free_tid; }
-AllocType AsanChunkView::GetAllocType() const {
- return (AllocType)chunk_->alloc_type;
-}
-
-static StackTrace GetStackTraceFromId(u32 id) {
- CHECK(id);
- StackTrace res = StackDepotGet(id);
- CHECK(res.trace);
- return res;
-}
-
-u32 AsanChunkView::GetAllocStackId() const { return chunk_->alloc_context_id; }
-u32 AsanChunkView::GetFreeStackId() const { return chunk_->free_context_id; }
-
-StackTrace AsanChunkView::GetAllocStack() const {
- return GetStackTraceFromId(GetAllocStackId());
-}
-
-StackTrace AsanChunkView::GetFreeStack() const {
- return GetStackTraceFromId(GetFreeStackId());
-}
-
-void InitializeAllocator(const AllocatorOptions &options) {
- instance.InitLinkerInitialized(options);
-}
-
-void ReInitializeAllocator(const AllocatorOptions &options) {
- instance.ReInitialize(options);
-}
-
-void GetAllocatorOptions(AllocatorOptions *options) {
- instance.GetOptions(options);
-}
-
-AsanChunkView FindHeapChunkByAddress(uptr addr) {
- return instance.FindHeapChunkByAddress(addr);
-}
-AsanChunkView FindHeapChunkByAllocBeg(uptr addr) {
- return AsanChunkView(instance.GetAsanChunk(reinterpret_cast<void*>(addr)));
-}
-
-void AsanThreadLocalMallocStorage::CommitBack() {
- GET_STACK_TRACE_MALLOC;
- instance.CommitBack(this, &stack);
-}
-
-void PrintInternalAllocatorStats() {
- instance.PrintStats();
-}
-
-void asan_free(void *ptr, BufferedStackTrace *stack, AllocType alloc_type) {
- instance.Deallocate(ptr, 0, 0, stack, alloc_type);
-}
-
-void asan_delete(void *ptr, uptr size, uptr alignment,
- BufferedStackTrace *stack, AllocType alloc_type) {
- instance.Deallocate(ptr, size, alignment, stack, alloc_type);
-}
-
-void *asan_malloc(uptr size, BufferedStackTrace *stack) {
- return SetErrnoOnNull(instance.Allocate(size, 8, stack, FROM_MALLOC, true));
-}
-
-void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack) {
- return SetErrnoOnNull(instance.Calloc(nmemb, size, stack));
-}
-
-void *asan_realloc(void *p, uptr size, BufferedStackTrace *stack) {
- if (!p)
- return SetErrnoOnNull(instance.Allocate(size, 8, stack, FROM_MALLOC, true));
- if (size == 0) {
- if (flags()->allocator_frees_and_returns_null_on_realloc_zero) {
- instance.Deallocate(p, 0, 0, stack, FROM_MALLOC);
- return nullptr;
- }
- // Allocate a size of 1 if we shouldn't free() on Realloc to 0
- size = 1;
- }
- return SetErrnoOnNull(instance.Reallocate(p, size, stack));
-}
-
-void *asan_valloc(uptr size, BufferedStackTrace *stack) {
- return SetErrnoOnNull(
- instance.Allocate(size, GetPageSizeCached(), stack, FROM_MALLOC, true));
-}
-
-void *asan_pvalloc(uptr size, BufferedStackTrace *stack) {
- uptr PageSize = GetPageSizeCached();
- if (UNLIKELY(CheckForPvallocOverflow(size, PageSize))) {
- errno = errno_ENOMEM;
- if (AllocatorMayReturnNull())
- return nullptr;
- ReportPvallocOverflow(size, stack);
- }
- // pvalloc(0) should allocate one page.
- size = size ? RoundUpTo(size, PageSize) : PageSize;
- return SetErrnoOnNull(
- instance.Allocate(size, PageSize, stack, FROM_MALLOC, true));
-}
-
-void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack,
- AllocType alloc_type) {
- if (UNLIKELY(!IsPowerOfTwo(alignment))) {
- errno = errno_EINVAL;
- if (AllocatorMayReturnNull())
- return nullptr;
- ReportInvalidAllocationAlignment(alignment, stack);
- }
- return SetErrnoOnNull(
- instance.Allocate(size, alignment, stack, alloc_type, true));
-}
-
-void *asan_aligned_alloc(uptr alignment, uptr size, BufferedStackTrace *stack) {
- if (UNLIKELY(!CheckAlignedAllocAlignmentAndSize(alignment, size))) {
- errno = errno_EINVAL;
- if (AllocatorMayReturnNull())
- return nullptr;
- ReportInvalidAlignedAllocAlignment(size, alignment, stack);
- }
- return SetErrnoOnNull(
- instance.Allocate(size, alignment, stack, FROM_MALLOC, true));
-}
-
-int asan_posix_memalign(void **memptr, uptr alignment, uptr size,
- BufferedStackTrace *stack) {
- if (UNLIKELY(!CheckPosixMemalignAlignment(alignment))) {
- if (AllocatorMayReturnNull())
- return errno_EINVAL;
- ReportInvalidPosixMemalignAlignment(alignment, stack);
- }
- void *ptr = instance.Allocate(size, alignment, stack, FROM_MALLOC, true);
- if (UNLIKELY(!ptr))
- // OOM error is already taken care of by Allocate.
- return errno_ENOMEM;
- CHECK(IsAligned((uptr)ptr, alignment));
- *memptr = ptr;
- return 0;
-}
-
-uptr asan_malloc_usable_size(const void *ptr, uptr pc, uptr bp) {
- if (!ptr) return 0;
- uptr usable_size = instance.AllocationSize(reinterpret_cast<uptr>(ptr));
- if (flags()->check_malloc_usable_size && (usable_size == 0)) {
- GET_STACK_TRACE_FATAL(pc, bp);
- ReportMallocUsableSizeNotOwned((uptr)ptr, &stack);
- }
- return usable_size;
-}
-
-uptr asan_mz_size(const void *ptr) {
- return instance.AllocationSize(reinterpret_cast<uptr>(ptr));
-}
-
-void asan_mz_force_lock() {
- instance.ForceLock();
-}
-
-void asan_mz_force_unlock() {
- instance.ForceUnlock();
-}
-
-void AsanSoftRssLimitExceededCallback(bool limit_exceeded) {
- instance.SetRssLimitExceeded(limit_exceeded);
-}
-
-} // namespace __asan
-
-// --- Implementation of LSan-specific functions --- {{{1
-namespace __lsan {
-void LockAllocator() {
- __asan::get_allocator().ForceLock();
-}
-
-void UnlockAllocator() {
- __asan::get_allocator().ForceUnlock();
-}
-
-void GetAllocatorGlobalRange(uptr *begin, uptr *end) {
- *begin = (uptr)&__asan::get_allocator();
- *end = *begin + sizeof(__asan::get_allocator());
-}
-
-uptr PointsIntoChunk(void* p) {
- uptr addr = reinterpret_cast<uptr>(p);
- __asan::AsanChunk *m = __asan::instance.GetAsanChunkByAddrFastLocked(addr);
- if (!m) return 0;
- uptr chunk = m->Beg();
- if (m->chunk_state != __asan::CHUNK_ALLOCATED)
- return 0;
- if (m->AddrIsInside(addr, /*locked_version=*/true))
- return chunk;
- if (IsSpecialCaseOfOperatorNew0(chunk, m->UsedSize(/*locked_version*/ true),
- addr))
- return chunk;
- return 0;
-}
-
-uptr GetUserBegin(uptr chunk) {
- __asan::AsanChunk *m = __asan::instance.GetAsanChunkByAddrFastLocked(chunk);
- CHECK(m);
- return m->Beg();
-}
-
-LsanMetadata::LsanMetadata(uptr chunk) {
- metadata_ = reinterpret_cast<void *>(chunk - __asan::kChunkHeaderSize);
-}
-
-bool LsanMetadata::allocated() const {
- __asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);
- return m->chunk_state == __asan::CHUNK_ALLOCATED;
-}
-
-ChunkTag LsanMetadata::tag() const {
- __asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);
- return static_cast<ChunkTag>(m->lsan_tag);
-}
-
-void LsanMetadata::set_tag(ChunkTag value) {
- __asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);
- m->lsan_tag = value;
-}
-
-uptr LsanMetadata::requested_size() const {
- __asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);
- return m->UsedSize(/*locked_version=*/true);
-}
-
-u32 LsanMetadata::stack_trace_id() const {
- __asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_);
- return m->alloc_context_id;
-}
-
-void ForEachChunk(ForEachChunkCallback callback, void *arg) {
- __asan::get_allocator().ForEachChunk(callback, arg);
-}
-
-IgnoreObjectResult IgnoreObjectLocked(const void *p) {
- uptr addr = reinterpret_cast<uptr>(p);
- __asan::AsanChunk *m = __asan::instance.GetAsanChunkByAddr(addr);
- if (!m) return kIgnoreObjectInvalid;
- if ((m->chunk_state == __asan::CHUNK_ALLOCATED) && m->AddrIsInside(addr)) {
- if (m->lsan_tag == kIgnored)
- return kIgnoreObjectAlreadyIgnored;
- m->lsan_tag = __lsan::kIgnored;
- return kIgnoreObjectSuccess;
- } else {
- return kIgnoreObjectInvalid;
- }
-}
-} // namespace __lsan
-
-// ---------------------- Interface ---------------- {{{1
-using namespace __asan; // NOLINT
-
-// ASan allocator doesn't reserve extra bytes, so normally we would
-// just return "size". We don't want to expose our redzone sizes, etc here.
-uptr __sanitizer_get_estimated_allocated_size(uptr size) {
- return size;
-}
-
-int __sanitizer_get_ownership(const void *p) {
- uptr ptr = reinterpret_cast<uptr>(p);
- return instance.AllocationSize(ptr) > 0;
-}
-
-uptr __sanitizer_get_allocated_size(const void *p) {
- if (!p) return 0;
- uptr ptr = reinterpret_cast<uptr>(p);
- uptr allocated_size = instance.AllocationSize(ptr);
- // Die if p is not malloced or if it is already freed.
- if (allocated_size == 0) {
- GET_STACK_TRACE_FATAL_HERE;
- ReportSanitizerGetAllocatedSizeNotOwned(ptr, &stack);
- }
- return allocated_size;
-}
-
-void __sanitizer_purge_allocator() {
- GET_STACK_TRACE_MALLOC;
- instance.Purge(&stack);
-}
-
-#if !SANITIZER_SUPPORTS_WEAK_HOOKS
-// Provide default (no-op) implementation of malloc hooks.
-SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_malloc_hook,
- void *ptr, uptr size) {
- (void)ptr;
- (void)size;
-}
-
-SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_free_hook, void *ptr) {
- (void)ptr;
-}
-#endif
diff --git a/lib/asan/asan_allocator.h b/lib/asan/asan_allocator.h
deleted file mode 100644
index 93d6f29c5bf55..0000000000000
--- a/lib/asan/asan_allocator.h
+++ /dev/null
@@ -1,224 +0,0 @@
-//===-- asan_allocator.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.
-//
-// ASan-private header for asan_allocator.cc.
-//===----------------------------------------------------------------------===//
-
-#ifndef ASAN_ALLOCATOR_H
-#define ASAN_ALLOCATOR_H
-
-#include "asan_flags.h"
-#include "asan_internal.h"
-#include "asan_interceptors.h"
-#include "sanitizer_common/sanitizer_allocator.h"
-#include "sanitizer_common/sanitizer_list.h"
-
-namespace __asan {
-
-enum AllocType {
- FROM_MALLOC = 1, // Memory block came from malloc, calloc, realloc, etc.
- FROM_NEW = 2, // Memory block came from operator new.
- FROM_NEW_BR = 3 // Memory block came from operator new [ ]
-};
-
-struct AsanChunk;
-
-struct AllocatorOptions {
- u32 quarantine_size_mb;
- u32 thread_local_quarantine_size_kb;
- u16 min_redzone;
- u16 max_redzone;
- u8 may_return_null;
- u8 alloc_dealloc_mismatch;
- s32 release_to_os_interval_ms;
-
- void SetFrom(const Flags *f, const CommonFlags *cf);
- void CopyTo(Flags *f, CommonFlags *cf);
-};
-
-void InitializeAllocator(const AllocatorOptions &options);
-void ReInitializeAllocator(const AllocatorOptions &options);
-void GetAllocatorOptions(AllocatorOptions *options);
-
-class AsanChunkView {
- public:
- explicit AsanChunkView(AsanChunk *chunk) : chunk_(chunk) {}
- bool IsValid() const; // Checks if AsanChunkView points to a valid
- // allocated or quarantined chunk.
- bool IsAllocated() const; // Checks if the memory is currently allocated.
- bool IsQuarantined() const; // Checks if the memory is currently quarantined.
- uptr Beg() const; // First byte of user memory.
- uptr End() const; // Last byte of user memory.
- uptr UsedSize() const; // Size requested by the user.
- u32 UserRequestedAlignment() const; // Originally requested alignment.
- uptr AllocTid() const;
- uptr FreeTid() const;
- bool Eq(const AsanChunkView &c) const { return chunk_ == c.chunk_; }
- u32 GetAllocStackId() const;
- u32 GetFreeStackId() const;
- StackTrace GetAllocStack() const;
- StackTrace GetFreeStack() const;
- AllocType GetAllocType() const;
- bool AddrIsInside(uptr addr, uptr access_size, sptr *offset) const {
- if (addr >= Beg() && (addr + access_size) <= End()) {
- *offset = addr - Beg();
- return true;
- }
- return false;
- }
- bool AddrIsAtLeft(uptr addr, uptr access_size, sptr *offset) const {
- (void)access_size;
- if (addr < Beg()) {
- *offset = Beg() - addr;
- return true;
- }
- return false;
- }
- bool AddrIsAtRight(uptr addr, uptr access_size, sptr *offset) const {
- if (addr + access_size > End()) {
- *offset = addr - End();
- return true;
- }
- return false;
- }
-
- private:
- AsanChunk *const chunk_;
-};
-
-AsanChunkView FindHeapChunkByAddress(uptr address);
-AsanChunkView FindHeapChunkByAllocBeg(uptr address);
-
-// List of AsanChunks with total size.
-class AsanChunkFifoList: public IntrusiveList<AsanChunk> {
- public:
- explicit AsanChunkFifoList(LinkerInitialized) { }
- AsanChunkFifoList() { clear(); }
- void Push(AsanChunk *n);
- void PushList(AsanChunkFifoList *q);
- AsanChunk *Pop();
- uptr size() { return size_; }
- void clear() {
- IntrusiveList<AsanChunk>::clear();
- size_ = 0;
- }
- private:
- uptr size_;
-};
-
-struct AsanMapUnmapCallback {
- void OnMap(uptr p, uptr size) const;
- void OnUnmap(uptr p, uptr size) const;
-};
-
-#if SANITIZER_CAN_USE_ALLOCATOR64
-# if SANITIZER_FUCHSIA
-const uptr kAllocatorSpace = ~(uptr)0;
-const uptr kAllocatorSize = 0x40000000000ULL; // 4T.
-typedef DefaultSizeClassMap SizeClassMap;
-# elif defined(__powerpc64__)
-const uptr kAllocatorSpace = ~(uptr)0;
-const uptr kAllocatorSize = 0x20000000000ULL; // 2T.
-typedef DefaultSizeClassMap SizeClassMap;
-# elif defined(__aarch64__) && SANITIZER_ANDROID
-// Android needs to support 39, 42 and 48 bit VMA.
-const uptr kAllocatorSpace = ~(uptr)0;
-const uptr kAllocatorSize = 0x2000000000ULL; // 128G.
-typedef VeryCompactSizeClassMap SizeClassMap;
-# elif defined(__aarch64__)
-// AArch64/SANITIZER_CAN_USER_ALLOCATOR64 is only for 42-bit VMA
-// so no need to different values for different VMA.
-const uptr kAllocatorSpace = 0x10000000000ULL;
-const uptr kAllocatorSize = 0x10000000000ULL; // 3T.
-typedef DefaultSizeClassMap SizeClassMap;
-# elif SANITIZER_WINDOWS
-const uptr kAllocatorSpace = ~(uptr)0;
-const uptr kAllocatorSize = 0x8000000000ULL; // 500G
-typedef DefaultSizeClassMap SizeClassMap;
-# else
-const uptr kAllocatorSpace = 0x600000000000ULL;
-const uptr kAllocatorSize = 0x40000000000ULL; // 4T.
-typedef DefaultSizeClassMap SizeClassMap;
-# endif
-struct AP64 { // Allocator64 parameters. Deliberately using a short name.
- static const uptr kSpaceBeg = kAllocatorSpace;
- static const uptr kSpaceSize = kAllocatorSize;
- static const uptr kMetadataSize = 0;
- typedef __asan::SizeClassMap SizeClassMap;
- typedef AsanMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags = 0;
-};
-
-typedef SizeClassAllocator64<AP64> PrimaryAllocator;
-#else // Fallback to SizeClassAllocator32.
-static const uptr kRegionSizeLog = 20;
-static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
-# if SANITIZER_WORDSIZE == 32
-typedef FlatByteMap<kNumRegions> ByteMap;
-# elif SANITIZER_WORDSIZE == 64
-typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
-# endif
-typedef CompactSizeClassMap SizeClassMap;
-struct AP32 {
- static const uptr kSpaceBeg = 0;
- static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
- static const uptr kMetadataSize = 16;
- typedef __asan::SizeClassMap SizeClassMap;
- static const uptr kRegionSizeLog = __asan::kRegionSizeLog;
- typedef __asan::ByteMap ByteMap;
- typedef AsanMapUnmapCallback MapUnmapCallback;
- static const uptr kFlags = 0;
-};
-typedef SizeClassAllocator32<AP32> PrimaryAllocator;
-#endif // SANITIZER_CAN_USE_ALLOCATOR64
-
-static const uptr kNumberOfSizeClasses = SizeClassMap::kNumClasses;
-typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
-typedef LargeMmapAllocator<AsanMapUnmapCallback> SecondaryAllocator;
-typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
- SecondaryAllocator> AsanAllocator;
-
-
-struct AsanThreadLocalMallocStorage {
- uptr quarantine_cache[16];
- AllocatorCache allocator_cache;
- void CommitBack();
- private:
- // These objects are allocated via mmap() and are zero-initialized.
- AsanThreadLocalMallocStorage() {}
-};
-
-void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack,
- AllocType alloc_type);
-void asan_free(void *ptr, BufferedStackTrace *stack, AllocType alloc_type);
-void asan_delete(void *ptr, uptr size, uptr alignment,
- BufferedStackTrace *stack, AllocType alloc_type);
-
-void *asan_malloc(uptr size, BufferedStackTrace *stack);
-void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack);
-void *asan_realloc(void *p, uptr size, BufferedStackTrace *stack);
-void *asan_valloc(uptr size, BufferedStackTrace *stack);
-void *asan_pvalloc(uptr size, BufferedStackTrace *stack);
-
-void *asan_aligned_alloc(uptr alignment, uptr size, BufferedStackTrace *stack);
-int asan_posix_memalign(void **memptr, uptr alignment, uptr size,
- BufferedStackTrace *stack);
-uptr asan_malloc_usable_size(const void *ptr, uptr pc, uptr bp);
-
-uptr asan_mz_size(const void *ptr);
-void asan_mz_force_lock();
-void asan_mz_force_unlock();
-
-void PrintInternalAllocatorStats();
-void AsanSoftRssLimitExceededCallback(bool exceeded);
-
-} // namespace __asan
-#endif // ASAN_ALLOCATOR_H
diff --git a/lib/asan/asan_blacklist.txt b/lib/asan/asan_blacklist.txt
deleted file mode 100644
index c25921fd5fe70..0000000000000
--- a/lib/asan/asan_blacklist.txt
+++ /dev/null
@@ -1,13 +0,0 @@
-# Blacklist for AddressSanitizer. Turns off instrumentation of particular
-# functions or sources. Use with care. You may set location of blacklist
-# at compile-time using -fsanitize-blacklist=<path> flag.
-
-# Example usage:
-# fun:*bad_function_name*
-# src:file_with_tricky_code.cc
-# global:*global_with_bad_access_or_initialization*
-# global:*global_with_initialization_issues*=init
-# type:*Namespace::ClassName*=init
-
-# Stack buffer overflow in VC/INCLUDE/xlocnum, see http://goo.gl/L4qqUG
-fun:*_Find_elem@*@std*
diff --git a/lib/asan/asan_debugging.cc b/lib/asan/asan_debugging.cc
deleted file mode 100644
index 7c877ded30cf4..0000000000000
--- a/lib/asan/asan_debugging.cc
+++ /dev/null
@@ -1,147 +0,0 @@
-//===-- asan_debugging.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 file contains various functions that are generally useful to call when
-// using a debugger (LLDB, GDB).
-//===----------------------------------------------------------------------===//
-
-#include "asan_allocator.h"
-#include "asan_descriptions.h"
-#include "asan_flags.h"
-#include "asan_internal.h"
-#include "asan_mapping.h"
-#include "asan_report.h"
-#include "asan_thread.h"
-
-namespace {
-using namespace __asan;
-
-static void FindInfoForStackVar(uptr addr, const char *frame_descr, uptr offset,
- char *name, uptr name_size,
- uptr &region_address, uptr &region_size) {
- InternalMmapVector<StackVarDescr> vars;
- vars.reserve(16);
- if (!ParseFrameDescription(frame_descr, &vars)) {
- return;
- }
-
- for (uptr i = 0; i < vars.size(); i++) {
- if (offset <= vars[i].beg + vars[i].size) {
- // We use name_len + 1 because strlcpy will guarantee a \0 at the end, so
- // if we're limiting the copy due to name_len, we add 1 to ensure we copy
- // the whole name and then terminate with '\0'.
- internal_strlcpy(name, vars[i].name_pos,
- Min(name_size, vars[i].name_len + 1));
- region_address = addr - (offset - vars[i].beg);
- region_size = vars[i].size;
- return;
- }
- }
-}
-
-uptr AsanGetStack(uptr addr, uptr *trace, u32 size, u32 *thread_id,
- bool alloc_stack) {
- AsanChunkView chunk = FindHeapChunkByAddress(addr);
- if (!chunk.IsValid()) return 0;
-
- StackTrace stack(nullptr, 0);
- if (alloc_stack) {
- if (chunk.AllocTid() == kInvalidTid) return 0;
- stack = chunk.GetAllocStack();
- if (thread_id) *thread_id = chunk.AllocTid();
- } else {
- if (chunk.FreeTid() == kInvalidTid) return 0;
- stack = chunk.GetFreeStack();
- if (thread_id) *thread_id = chunk.FreeTid();
- }
-
- if (trace && size) {
- size = Min(size, Min(stack.size, kStackTraceMax));
- for (uptr i = 0; i < size; i++)
- trace[i] = StackTrace::GetPreviousInstructionPc(stack.trace[i]);
-
- return size;
- }
-
- return 0;
-}
-
-} // namespace
-
-SANITIZER_INTERFACE_ATTRIBUTE
-const char *__asan_locate_address(uptr addr, char *name, uptr name_size,
- uptr *region_address_ptr,
- uptr *region_size_ptr) {
- AddressDescription descr(addr);
- uptr region_address = 0;
- uptr region_size = 0;
- const char *region_kind = nullptr;
- if (name && name_size > 0) name[0] = 0;
-
- if (auto shadow = descr.AsShadow()) {
- // region_{address,size} are already 0
- switch (shadow->kind) {
- case kShadowKindLow:
- region_kind = "low shadow";
- break;
- case kShadowKindGap:
- region_kind = "shadow gap";
- break;
- case kShadowKindHigh:
- region_kind = "high shadow";
- break;
- }
- } else if (auto heap = descr.AsHeap()) {
- region_kind = "heap";
- region_address = heap->chunk_access.chunk_begin;
- region_size = heap->chunk_access.chunk_size;
- } else if (auto stack = descr.AsStack()) {
- region_kind = "stack";
- if (!stack->frame_descr) {
- // region_{address,size} are already 0
- } else {
- FindInfoForStackVar(addr, stack->frame_descr, stack->offset, name,
- name_size, region_address, region_size);
- }
- } else if (auto global = descr.AsGlobal()) {
- region_kind = "global";
- auto &g = global->globals[0];
- internal_strlcpy(name, g.name, name_size);
- region_address = g.beg;
- region_size = g.size;
- } else {
- // region_{address,size} are already 0
- region_kind = "heap-invalid";
- }
-
- CHECK(region_kind);
- if (region_address_ptr) *region_address_ptr = region_address;
- if (region_size_ptr) *region_size_ptr = region_size;
- return region_kind;
-}
-
-SANITIZER_INTERFACE_ATTRIBUTE
-uptr __asan_get_alloc_stack(uptr addr, uptr *trace, uptr size, u32 *thread_id) {
- return AsanGetStack(addr, trace, size, thread_id, /* alloc_stack */ true);
-}
-
-SANITIZER_INTERFACE_ATTRIBUTE
-uptr __asan_get_free_stack(uptr addr, uptr *trace, uptr size, u32 *thread_id) {
- return AsanGetStack(addr, trace, size, thread_id, /* alloc_stack */ false);
-}
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void __asan_get_shadow_mapping(uptr *shadow_scale, uptr *shadow_offset) {
- if (shadow_scale)
- *shadow_scale = SHADOW_SCALE;
- if (shadow_offset)
- *shadow_offset = SHADOW_OFFSET;
-}
diff --git a/lib/asan/asan_descriptions.cc b/lib/asan/asan_descriptions.cc
deleted file mode 100644
index cdb562d975ff2..0000000000000
--- a/lib/asan/asan_descriptions.cc
+++ /dev/null
@@ -1,502 +0,0 @@
-//===-- asan_descriptions.cc ------------------------------------*- 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.
-//
-// ASan functions for getting information about an address and/or printing it.
-//===----------------------------------------------------------------------===//
-
-#include "asan_descriptions.h"
-#include "asan_mapping.h"
-#include "asan_report.h"
-#include "asan_stack.h"
-#include "sanitizer_common/sanitizer_stackdepot.h"
-
-namespace __asan {
-
-AsanThreadIdAndName::AsanThreadIdAndName(AsanThreadContext *t) {
- Init(t->tid, t->name);
-}
-
-AsanThreadIdAndName::AsanThreadIdAndName(u32 tid) {
- if (tid == kInvalidTid) {
- Init(tid, "");
- } else {
- asanThreadRegistry().CheckLocked();
- AsanThreadContext *t = GetThreadContextByTidLocked(tid);
- Init(tid, t->name);
- }
-}
-
-void AsanThreadIdAndName::Init(u32 tid, const char *tname) {
- int len = internal_snprintf(name, sizeof(name), "T%d", tid);
- CHECK(((unsigned int)len) < sizeof(name));
- if (tname[0] != '\0')
- internal_snprintf(&name[len], sizeof(name) - len, " (%s)", tname);
-}
-
-void DescribeThread(AsanThreadContext *context) {
- CHECK(context);
- asanThreadRegistry().CheckLocked();
- // No need to announce the main thread.
- if (context->tid == 0 || context->announced) {
- return;
- }
- context->announced = true;
- InternalScopedString str(1024);
- str.append("Thread %s", AsanThreadIdAndName(context).c_str());
- if (context->parent_tid == kInvalidTid) {
- str.append(" created by unknown thread\n");
- Printf("%s", str.data());
- return;
- }
- str.append(" created by %s here:\n",
- AsanThreadIdAndName(context->parent_tid).c_str());
- Printf("%s", str.data());
- StackDepotGet(context->stack_id).Print();
- // Recursively described parent thread if needed.
- if (flags()->print_full_thread_history) {
- AsanThreadContext *parent_context =
- GetThreadContextByTidLocked(context->parent_tid);
- DescribeThread(parent_context);
- }
-}
-
-// Shadow descriptions
-static bool GetShadowKind(uptr addr, ShadowKind *shadow_kind) {
- CHECK(!AddrIsInMem(addr));
- if (AddrIsInShadowGap(addr)) {
- *shadow_kind = kShadowKindGap;
- } else if (AddrIsInHighShadow(addr)) {
- *shadow_kind = kShadowKindHigh;
- } else if (AddrIsInLowShadow(addr)) {
- *shadow_kind = kShadowKindLow;
- } else {
- CHECK(0 && "Address is not in memory and not in shadow?");
- return false;
- }
- return true;
-}
-
-bool DescribeAddressIfShadow(uptr addr) {
- ShadowAddressDescription descr;
- if (!GetShadowAddressInformation(addr, &descr)) return false;
- descr.Print();
- return true;
-}
-
-bool GetShadowAddressInformation(uptr addr, ShadowAddressDescription *descr) {
- if (AddrIsInMem(addr)) return false;
- ShadowKind shadow_kind;
- if (!GetShadowKind(addr, &shadow_kind)) return false;
- if (shadow_kind != kShadowKindGap) descr->shadow_byte = *(u8 *)addr;
- descr->addr = addr;
- descr->kind = shadow_kind;
- return true;
-}
-
-// Heap descriptions
-static void GetAccessToHeapChunkInformation(ChunkAccess *descr,
- AsanChunkView chunk, uptr addr,
- uptr access_size) {
- descr->bad_addr = addr;
- if (chunk.AddrIsAtLeft(addr, access_size, &descr->offset)) {
- descr->access_type = kAccessTypeLeft;
- } else if (chunk.AddrIsAtRight(addr, access_size, &descr->offset)) {
- descr->access_type = kAccessTypeRight;
- if (descr->offset < 0) {
- descr->bad_addr -= descr->offset;
- descr->offset = 0;
- }
- } else if (chunk.AddrIsInside(addr, access_size, &descr->offset)) {
- descr->access_type = kAccessTypeInside;
- } else {
- descr->access_type = kAccessTypeUnknown;
- }
- descr->chunk_begin = chunk.Beg();
- descr->chunk_size = chunk.UsedSize();
- descr->user_requested_alignment = chunk.UserRequestedAlignment();
- descr->alloc_type = chunk.GetAllocType();
-}
-
-static void PrintHeapChunkAccess(uptr addr, const ChunkAccess &descr) {
- Decorator d;
- InternalScopedString str(4096);
- str.append("%s", d.Location());
- switch (descr.access_type) {
- case kAccessTypeLeft:
- str.append("%p is located %zd bytes to the left of",
- (void *)descr.bad_addr, descr.offset);
- break;
- case kAccessTypeRight:
- str.append("%p is located %zd bytes to the right of",
- (void *)descr.bad_addr, descr.offset);
- break;
- case kAccessTypeInside:
- str.append("%p is located %zd bytes inside of", (void *)descr.bad_addr,
- descr.offset);
- break;
- case kAccessTypeUnknown:
- str.append(
- "%p is located somewhere around (this is AddressSanitizer bug!)",
- (void *)descr.bad_addr);
- }
- str.append(" %zu-byte region [%p,%p)\n", descr.chunk_size,
- (void *)descr.chunk_begin,
- (void *)(descr.chunk_begin + descr.chunk_size));
- str.append("%s", d.Default());
- Printf("%s", str.data());
-}
-
-bool GetHeapAddressInformation(uptr addr, uptr access_size,
- HeapAddressDescription *descr) {
- AsanChunkView chunk = FindHeapChunkByAddress(addr);
- if (!chunk.IsValid()) {
- return false;
- }
- descr->addr = addr;
- GetAccessToHeapChunkInformation(&descr->chunk_access, chunk, addr,
- access_size);
- CHECK_NE(chunk.AllocTid(), kInvalidTid);
- descr->alloc_tid = chunk.AllocTid();
- descr->alloc_stack_id = chunk.GetAllocStackId();
- descr->free_tid = chunk.FreeTid();
- if (descr->free_tid != kInvalidTid)
- descr->free_stack_id = chunk.GetFreeStackId();
- return true;
-}
-
-static StackTrace GetStackTraceFromId(u32 id) {
- CHECK(id);
- StackTrace res = StackDepotGet(id);
- CHECK(res.trace);
- return res;
-}
-
-bool DescribeAddressIfHeap(uptr addr, uptr access_size) {
- HeapAddressDescription descr;
- if (!GetHeapAddressInformation(addr, access_size, &descr)) {
- Printf(
- "AddressSanitizer can not describe address in more detail "
- "(wild memory access suspected).\n");
- return false;
- }
- descr.Print();
- return true;
-}
-
-// Stack descriptions
-bool GetStackAddressInformation(uptr addr, uptr access_size,
- StackAddressDescription *descr) {
- AsanThread *t = FindThreadByStackAddress(addr);
- if (!t) return false;
-
- descr->addr = addr;
- descr->tid = t->tid();
- // Try to fetch precise stack frame for this access.
- AsanThread::StackFrameAccess access;
- if (!t->GetStackFrameAccessByAddr(addr, &access)) {
- descr->frame_descr = nullptr;
- return true;
- }
-
- descr->offset = access.offset;
- descr->access_size = access_size;
- descr->frame_pc = access.frame_pc;
- descr->frame_descr = access.frame_descr;
-
-#if SANITIZER_PPC64V1
- // On PowerPC64 ELFv1, the address of a function actually points to a
- // three-doubleword data structure with the first field containing
- // the address of the function's code.
- descr->frame_pc = *reinterpret_cast<uptr *>(descr->frame_pc);
-#endif
- descr->frame_pc += 16;
-
- return true;
-}
-
-static void PrintAccessAndVarIntersection(const StackVarDescr &var, uptr addr,
- uptr access_size, uptr prev_var_end,
- uptr next_var_beg) {
- uptr var_end = var.beg + var.size;
- uptr addr_end = addr + access_size;
- const char *pos_descr = nullptr;
- // If the variable [var.beg, var_end) is the nearest variable to the
- // current memory access, indicate it in the log.
- if (addr >= var.beg) {
- if (addr_end <= var_end)
- pos_descr = "is inside"; // May happen if this is a use-after-return.
- else if (addr < var_end)
- pos_descr = "partially overflows";
- else if (addr_end <= next_var_beg &&
- next_var_beg - addr_end >= addr - var_end)
- pos_descr = "overflows";
- } else {
- if (addr_end > var.beg)
- pos_descr = "partially underflows";
- else if (addr >= prev_var_end && addr - prev_var_end >= var.beg - addr_end)
- pos_descr = "underflows";
- }
- InternalScopedString str(1024);
- str.append(" [%zd, %zd)", var.beg, var_end);
- // Render variable name.
- str.append(" '");
- for (uptr i = 0; i < var.name_len; ++i) {
- str.append("%c", var.name_pos[i]);
- }
- str.append("'");
- if (var.line > 0) {
- str.append(" (line %d)", var.line);
- }
- if (pos_descr) {
- Decorator d;
- // FIXME: we may want to also print the size of the access here,
- // but in case of accesses generated by memset it may be confusing.
- str.append("%s <== Memory access at offset %zd %s this variable%s\n",
- d.Location(), addr, pos_descr, d.Default());
- } else {
- str.append("\n");
- }
- Printf("%s", str.data());
-}
-
-bool DescribeAddressIfStack(uptr addr, uptr access_size) {
- StackAddressDescription descr;
- if (!GetStackAddressInformation(addr, access_size, &descr)) return false;
- descr.Print();
- return true;
-}
-
-// Global descriptions
-static void DescribeAddressRelativeToGlobal(uptr addr, uptr access_size,
- const __asan_global &g) {
- InternalScopedString str(4096);
- Decorator d;
- str.append("%s", d.Location());
- if (addr < g.beg) {
- str.append("%p is located %zd bytes to the left", (void *)addr,
- g.beg - addr);
- } else if (addr + access_size > g.beg + g.size) {
- if (addr < g.beg + g.size) addr = g.beg + g.size;
- str.append("%p is located %zd bytes to the right", (void *)addr,
- addr - (g.beg + g.size));
- } else {
- // Can it happen?
- str.append("%p is located %zd bytes inside", (void *)addr, addr - g.beg);
- }
- str.append(" of global variable '%s' defined in '",
- MaybeDemangleGlobalName(g.name));
- PrintGlobalLocation(&str, g);
- str.append("' (0x%zx) of size %zu\n", g.beg, g.size);
- str.append("%s", d.Default());
- PrintGlobalNameIfASCII(&str, g);
- Printf("%s", str.data());
-}
-
-bool GetGlobalAddressInformation(uptr addr, uptr access_size,
- GlobalAddressDescription *descr) {
- descr->addr = addr;
- int globals_num = GetGlobalsForAddress(addr, descr->globals, descr->reg_sites,
- ARRAY_SIZE(descr->globals));
- descr->size = globals_num;
- descr->access_size = access_size;
- return globals_num != 0;
-}
-
-bool DescribeAddressIfGlobal(uptr addr, uptr access_size,
- const char *bug_type) {
- GlobalAddressDescription descr;
- if (!GetGlobalAddressInformation(addr, access_size, &descr)) return false;
-
- descr.Print(bug_type);
- return true;
-}
-
-void ShadowAddressDescription::Print() const {
- Printf("Address %p is located in the %s area.\n", addr, ShadowNames[kind]);
-}
-
-void GlobalAddressDescription::Print(const char *bug_type) const {
- for (int i = 0; i < size; i++) {
- DescribeAddressRelativeToGlobal(addr, access_size, globals[i]);
- if (bug_type &&
- 0 == internal_strcmp(bug_type, "initialization-order-fiasco") &&
- reg_sites[i]) {
- Printf(" registered at:\n");
- StackDepotGet(reg_sites[i]).Print();
- }
- }
-}
-
-bool GlobalAddressDescription::PointsInsideTheSameVariable(
- const GlobalAddressDescription &other) const {
- if (size == 0 || other.size == 0) return false;
-
- for (uptr i = 0; i < size; i++) {
- const __asan_global &a = globals[i];
- for (uptr j = 0; j < other.size; j++) {
- const __asan_global &b = other.globals[j];
- if (a.beg == b.beg &&
- a.beg <= addr &&
- b.beg <= other.addr &&
- (addr + access_size) < (a.beg + a.size) &&
- (other.addr + other.access_size) < (b.beg + b.size))
- return true;
- }
- }
-
- return false;
-}
-
-void StackAddressDescription::Print() const {
- Decorator d;
- Printf("%s", d.Location());
- Printf("Address %p is located in stack of thread %s", addr,
- AsanThreadIdAndName(tid).c_str());
-
- if (!frame_descr) {
- Printf("%s\n", d.Default());
- return;
- }
- Printf(" at offset %zu in frame%s\n", offset, d.Default());
-
- // Now we print the frame where the alloca has happened.
- // We print this frame as a stack trace with one element.
- // The symbolizer may print more than one frame if inlining was involved.
- // The frame numbers may be different than those in the stack trace printed
- // previously. That's unfortunate, but I have no better solution,
- // especially given that the alloca may be from entirely different place
- // (e.g. use-after-scope, or different thread's stack).
- Printf("%s", d.Default());
- StackTrace alloca_stack(&frame_pc, 1);
- alloca_stack.Print();
-
- InternalMmapVector<StackVarDescr> vars;
- vars.reserve(16);
- if (!ParseFrameDescription(frame_descr, &vars)) {
- Printf(
- "AddressSanitizer can't parse the stack frame "
- "descriptor: |%s|\n",
- frame_descr);
- // 'addr' is a stack address, so return true even if we can't parse frame
- return;
- }
- uptr n_objects = vars.size();
- // Report the number of stack objects.
- Printf(" This frame has %zu object(s):\n", n_objects);
-
- // Report all objects in this frame.
- for (uptr i = 0; i < n_objects; i++) {
- uptr prev_var_end = i ? vars[i - 1].beg + vars[i - 1].size : 0;
- uptr next_var_beg = i + 1 < n_objects ? vars[i + 1].beg : ~(0UL);
- PrintAccessAndVarIntersection(vars[i], offset, access_size, prev_var_end,
- next_var_beg);
- }
- Printf(
- "HINT: this may be a false positive if your program uses "
- "some custom stack unwind mechanism, swapcontext or vfork\n");
- if (SANITIZER_WINDOWS)
- Printf(" (longjmp, SEH and C++ exceptions *are* supported)\n");
- else
- Printf(" (longjmp and C++ exceptions *are* supported)\n");
-
- DescribeThread(GetThreadContextByTidLocked(tid));
-}
-
-void HeapAddressDescription::Print() const {
- PrintHeapChunkAccess(addr, chunk_access);
-
- asanThreadRegistry().CheckLocked();
- AsanThreadContext *alloc_thread = GetThreadContextByTidLocked(alloc_tid);
- StackTrace alloc_stack = GetStackTraceFromId(alloc_stack_id);
-
- Decorator d;
- AsanThreadContext *free_thread = nullptr;
- if (free_tid != kInvalidTid) {
- free_thread = GetThreadContextByTidLocked(free_tid);
- Printf("%sfreed by thread %s here:%s\n", d.Allocation(),
- AsanThreadIdAndName(free_thread).c_str(), d.Default());
- StackTrace free_stack = GetStackTraceFromId(free_stack_id);
- free_stack.Print();
- Printf("%spreviously allocated by thread %s here:%s\n", d.Allocation(),
- AsanThreadIdAndName(alloc_thread).c_str(), d.Default());
- } else {
- Printf("%sallocated by thread %s here:%s\n", d.Allocation(),
- AsanThreadIdAndName(alloc_thread).c_str(), d.Default());
- }
- alloc_stack.Print();
- DescribeThread(GetCurrentThread());
- if (free_thread) DescribeThread(free_thread);
- DescribeThread(alloc_thread);
-}
-
-AddressDescription::AddressDescription(uptr addr, uptr access_size,
- bool shouldLockThreadRegistry) {
- if (GetShadowAddressInformation(addr, &data.shadow)) {
- data.kind = kAddressKindShadow;
- return;
- }
- if (GetHeapAddressInformation(addr, access_size, &data.heap)) {
- data.kind = kAddressKindHeap;
- return;
- }
-
- bool isStackMemory = false;
- if (shouldLockThreadRegistry) {
- ThreadRegistryLock l(&asanThreadRegistry());
- isStackMemory = GetStackAddressInformation(addr, access_size, &data.stack);
- } else {
- isStackMemory = GetStackAddressInformation(addr, access_size, &data.stack);
- }
- if (isStackMemory) {
- data.kind = kAddressKindStack;
- return;
- }
-
- if (GetGlobalAddressInformation(addr, access_size, &data.global)) {
- data.kind = kAddressKindGlobal;
- return;
- }
- data.kind = kAddressKindWild;
- addr = 0;
-}
-
-void PrintAddressDescription(uptr addr, uptr access_size,
- const char *bug_type) {
- ShadowAddressDescription shadow_descr;
- if (GetShadowAddressInformation(addr, &shadow_descr)) {
- shadow_descr.Print();
- return;
- }
-
- GlobalAddressDescription global_descr;
- if (GetGlobalAddressInformation(addr, access_size, &global_descr)) {
- global_descr.Print(bug_type);
- return;
- }
-
- StackAddressDescription stack_descr;
- if (GetStackAddressInformation(addr, access_size, &stack_descr)) {
- stack_descr.Print();
- return;
- }
-
- HeapAddressDescription heap_descr;
- if (GetHeapAddressInformation(addr, access_size, &heap_descr)) {
- heap_descr.Print();
- return;
- }
-
- // We exhausted our possibilities. Bail out.
- Printf(
- "AddressSanitizer can not describe address in more detail "
- "(wild memory access suspected).\n");
-}
-} // namespace __asan
diff --git a/lib/asan/asan_descriptions.h b/lib/asan/asan_descriptions.h
deleted file mode 100644
index 5c2d7662a35aa..0000000000000
--- a/lib/asan/asan_descriptions.h
+++ /dev/null
@@ -1,263 +0,0 @@
-//===-- asan_descriptions.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.
-//
-// ASan-private header for asan_descriptions.cc.
-// TODO(filcab): Most struct definitions should move to the interface headers.
-//===----------------------------------------------------------------------===//
-#ifndef ASAN_DESCRIPTIONS_H
-#define ASAN_DESCRIPTIONS_H
-
-#include "asan_allocator.h"
-#include "asan_thread.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_report_decorator.h"
-
-namespace __asan {
-
-void DescribeThread(AsanThreadContext *context);
-static inline void DescribeThread(AsanThread *t) {
- if (t) DescribeThread(t->context());
-}
-
-class AsanThreadIdAndName {
- public:
- explicit AsanThreadIdAndName(AsanThreadContext *t);
- explicit AsanThreadIdAndName(u32 tid);
-
- // Contains "T%tid (%name)" or "T%tid" if the name is empty.
- const char *c_str() const { return &name[0]; }
-
- private:
- void Init(u32 tid, const char *tname);
-
- char name[128];
-};
-
-class Decorator : public __sanitizer::SanitizerCommonDecorator {
- public:
- Decorator() : SanitizerCommonDecorator() {}
- const char *Access() { return Blue(); }
- const char *Location() { return Green(); }
- const char *Allocation() { return Magenta(); }
-
- const char *ShadowByte(u8 byte) {
- switch (byte) {
- case kAsanHeapLeftRedzoneMagic:
- case kAsanArrayCookieMagic:
- return Red();
- case kAsanHeapFreeMagic:
- return Magenta();
- case kAsanStackLeftRedzoneMagic:
- case kAsanStackMidRedzoneMagic:
- case kAsanStackRightRedzoneMagic:
- return Red();
- case kAsanStackAfterReturnMagic:
- return Magenta();
- case kAsanInitializationOrderMagic:
- return Cyan();
- case kAsanUserPoisonedMemoryMagic:
- case kAsanContiguousContainerOOBMagic:
- case kAsanAllocaLeftMagic:
- case kAsanAllocaRightMagic:
- return Blue();
- case kAsanStackUseAfterScopeMagic:
- return Magenta();
- case kAsanGlobalRedzoneMagic:
- return Red();
- case kAsanInternalHeapMagic:
- return Yellow();
- case kAsanIntraObjectRedzone:
- return Yellow();
- default:
- return Default();
- }
- }
-};
-
-enum ShadowKind : u8 {
- kShadowKindLow,
- kShadowKindGap,
- kShadowKindHigh,
-};
-static const char *const ShadowNames[] = {"low shadow", "shadow gap",
- "high shadow"};
-
-struct ShadowAddressDescription {
- uptr addr;
- ShadowKind kind;
- u8 shadow_byte;
-
- void Print() const;
-};
-
-bool GetShadowAddressInformation(uptr addr, ShadowAddressDescription *descr);
-bool DescribeAddressIfShadow(uptr addr);
-
-enum AccessType {
- kAccessTypeLeft,
- kAccessTypeRight,
- kAccessTypeInside,
- kAccessTypeUnknown, // This means we have an AddressSanitizer bug!
-};
-
-struct ChunkAccess {
- uptr bad_addr;
- sptr offset;
- uptr chunk_begin;
- uptr chunk_size;
- u32 user_requested_alignment : 12;
- u32 access_type : 2;
- u32 alloc_type : 2;
-};
-
-struct HeapAddressDescription {
- uptr addr;
- uptr alloc_tid;
- uptr free_tid;
- u32 alloc_stack_id;
- u32 free_stack_id;
- ChunkAccess chunk_access;
-
- void Print() const;
-};
-
-bool GetHeapAddressInformation(uptr addr, uptr access_size,
- HeapAddressDescription *descr);
-bool DescribeAddressIfHeap(uptr addr, uptr access_size = 1);
-
-struct StackAddressDescription {
- uptr addr;
- uptr tid;
- uptr offset;
- uptr frame_pc;
- uptr access_size;
- const char *frame_descr;
-
- void Print() const;
-};
-
-bool GetStackAddressInformation(uptr addr, uptr access_size,
- StackAddressDescription *descr);
-
-struct GlobalAddressDescription {
- uptr addr;
- // Assume address is close to at most four globals.
- static const int kMaxGlobals = 4;
- __asan_global globals[kMaxGlobals];
- u32 reg_sites[kMaxGlobals];
- uptr access_size;
- u8 size;
-
- void Print(const char *bug_type = "") const;
-
- // Returns true when this descriptions points inside the same global variable
- // as other. Descriptions can have different address within the variable
- bool PointsInsideTheSameVariable(const GlobalAddressDescription &other) const;
-};
-
-bool GetGlobalAddressInformation(uptr addr, uptr access_size,
- GlobalAddressDescription *descr);
-bool DescribeAddressIfGlobal(uptr addr, uptr access_size, const char *bug_type);
-
-// General function to describe an address. Will try to describe the address as
-// a shadow, global (variable), stack, or heap address.
-// bug_type is optional and is used for checking if we're reporting an
-// initialization-order-fiasco
-// The proper access_size should be passed for stack, global, and heap
-// addresses. Defaults to 1.
-// Each of the *AddressDescription functions has its own Print() member, which
-// may take access_size and bug_type parameters if needed.
-void PrintAddressDescription(uptr addr, uptr access_size = 1,
- const char *bug_type = "");
-
-enum AddressKind {
- kAddressKindWild,
- kAddressKindShadow,
- kAddressKindHeap,
- kAddressKindStack,
- kAddressKindGlobal,
-};
-
-class AddressDescription {
- struct AddressDescriptionData {
- AddressKind kind;
- union {
- ShadowAddressDescription shadow;
- HeapAddressDescription heap;
- StackAddressDescription stack;
- GlobalAddressDescription global;
- uptr addr;
- };
- };
-
- AddressDescriptionData data;
-
- public:
- AddressDescription() = default;
- // shouldLockThreadRegistry allows us to skip locking if we're sure we already
- // have done it.
- AddressDescription(uptr addr, bool shouldLockThreadRegistry = true)
- : AddressDescription(addr, 1, shouldLockThreadRegistry) {}
- AddressDescription(uptr addr, uptr access_size,
- bool shouldLockThreadRegistry = true);
-
- uptr Address() const {
- switch (data.kind) {
- case kAddressKindWild:
- return data.addr;
- case kAddressKindShadow:
- return data.shadow.addr;
- case kAddressKindHeap:
- return data.heap.addr;
- case kAddressKindStack:
- return data.stack.addr;
- case kAddressKindGlobal:
- return data.global.addr;
- }
- UNREACHABLE("AddressInformation kind is invalid");
- }
- void Print(const char *bug_descr = nullptr) const {
- switch (data.kind) {
- case kAddressKindWild:
- Printf("Address %p is a wild pointer.\n", data.addr);
- return;
- case kAddressKindShadow:
- return data.shadow.Print();
- case kAddressKindHeap:
- return data.heap.Print();
- case kAddressKindStack:
- return data.stack.Print();
- case kAddressKindGlobal:
- // initialization-order-fiasco has a special Print()
- return data.global.Print(bug_descr);
- }
- UNREACHABLE("AddressInformation kind is invalid");
- }
-
- void StoreTo(AddressDescriptionData *dst) const { *dst = data; }
-
- const ShadowAddressDescription *AsShadow() const {
- return data.kind == kAddressKindShadow ? &data.shadow : nullptr;
- }
- const HeapAddressDescription *AsHeap() const {
- return data.kind == kAddressKindHeap ? &data.heap : nullptr;
- }
- const StackAddressDescription *AsStack() const {
- return data.kind == kAddressKindStack ? &data.stack : nullptr;
- }
- const GlobalAddressDescription *AsGlobal() const {
- return data.kind == kAddressKindGlobal ? &data.global : nullptr;
- }
-};
-
-} // namespace __asan
-
-#endif // ASAN_DESCRIPTIONS_H
diff --git a/lib/asan/asan_errors.cc b/lib/asan/asan_errors.cc
deleted file mode 100644
index 33d0613f79f47..0000000000000
--- a/lib/asan/asan_errors.cc
+++ /dev/null
@@ -1,586 +0,0 @@
-//===-- asan_errors.cc ------------------------------------------*- 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.
-//
-// ASan implementation for error structures.
-//===----------------------------------------------------------------------===//
-
-#include "asan_errors.h"
-#include "asan_descriptions.h"
-#include "asan_mapping.h"
-#include "asan_report.h"
-#include "asan_stack.h"
-#include "sanitizer_common/sanitizer_stackdepot.h"
-
-namespace __asan {
-
-static void OnStackUnwind(const SignalContext &sig,
- const void *callback_context,
- BufferedStackTrace *stack) {
- bool fast = common_flags()->fast_unwind_on_fatal;
-#if SANITIZER_FREEBSD || SANITIZER_NETBSD
- // On FreeBSD the slow unwinding that leverages _Unwind_Backtrace()
- // yields the call stack of the signal's handler and not of the code
- // that raised the signal (as it does on Linux).
- fast = true;
-#endif
- // Tests and maybe some users expect that scariness is going to be printed
- // just before the stack. As only asan has scariness score we have no
- // corresponding code in the sanitizer_common and we use this callback to
- // print it.
- static_cast<const ScarinessScoreBase *>(callback_context)->Print();
- GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context, fast);
-}
-
-void ErrorDeadlySignal::Print() {
- ReportDeadlySignal(signal, tid, &OnStackUnwind, &scariness);
-}
-
-void ErrorDoubleFree::Print() {
- Decorator d;
- Printf("%s", d.Error());
- Report(
- "ERROR: AddressSanitizer: attempting %s on %p in thread %s:\n",
- scariness.GetDescription(), addr_description.addr,
- AsanThreadIdAndName(tid).c_str());
- Printf("%s", d.Default());
- scariness.Print();
- GET_STACK_TRACE_FATAL(second_free_stack->trace[0],
- second_free_stack->top_frame_bp);
- stack.Print();
- addr_description.Print();
- ReportErrorSummary(scariness.GetDescription(), &stack);
-}
-
-void ErrorNewDeleteTypeMismatch::Print() {
- Decorator d;
- Printf("%s", d.Error());
- Report(
- "ERROR: AddressSanitizer: %s on %p in thread %s:\n",
- scariness.GetDescription(), addr_description.addr,
- AsanThreadIdAndName(tid).c_str());
- Printf("%s object passed to delete has wrong type:\n", d.Default());
- if (delete_size != 0) {
- Printf(
- " size of the allocated type: %zd bytes;\n"
- " size of the deallocated type: %zd bytes.\n",
- addr_description.chunk_access.chunk_size, delete_size);
- }
- const uptr user_alignment =
- addr_description.chunk_access.user_requested_alignment;
- if (delete_alignment != user_alignment) {
- char user_alignment_str[32];
- char delete_alignment_str[32];
- internal_snprintf(user_alignment_str, sizeof(user_alignment_str),
- "%zd bytes", user_alignment);
- internal_snprintf(delete_alignment_str, sizeof(delete_alignment_str),
- "%zd bytes", delete_alignment);
- static const char *kDefaultAlignment = "default-aligned";
- Printf(
- " alignment of the allocated type: %s;\n"
- " alignment of the deallocated type: %s.\n",
- user_alignment > 0 ? user_alignment_str : kDefaultAlignment,
- delete_alignment > 0 ? delete_alignment_str : kDefaultAlignment);
- }
- CHECK_GT(free_stack->size, 0);
- scariness.Print();
- GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
- stack.Print();
- addr_description.Print();
- ReportErrorSummary(scariness.GetDescription(), &stack);
- Report(
- "HINT: if you don't care about these errors you may set "
- "ASAN_OPTIONS=new_delete_type_mismatch=0\n");
-}
-
-void ErrorFreeNotMalloced::Print() {
- Decorator d;
- Printf("%s", d.Error());
- Report(
- "ERROR: AddressSanitizer: attempting free on address "
- "which was not malloc()-ed: %p in thread %s\n",
- addr_description.Address(), AsanThreadIdAndName(tid).c_str());
- Printf("%s", d.Default());
- CHECK_GT(free_stack->size, 0);
- scariness.Print();
- GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp);
- stack.Print();
- addr_description.Print();
- ReportErrorSummary(scariness.GetDescription(), &stack);
-}
-
-void ErrorAllocTypeMismatch::Print() {
- static const char *alloc_names[] = {"INVALID", "malloc", "operator new",
- "operator new []"};
- static const char *dealloc_names[] = {"INVALID", "free", "operator delete",
- "operator delete []"};
- CHECK_NE(alloc_type, dealloc_type);
- Decorator d;
- Printf("%s", d.Error());
- Report("ERROR: AddressSanitizer: %s (%s vs %s) on %p\n",
- scariness.GetDescription(),
- alloc_names[alloc_type], dealloc_names[dealloc_type],
- addr_description.addr);
- Printf("%s", d.Default());
- CHECK_GT(dealloc_stack->size, 0);
- scariness.Print();
- GET_STACK_TRACE_FATAL(dealloc_stack->trace[0], dealloc_stack->top_frame_bp);
- stack.Print();
- addr_description.Print();
- ReportErrorSummary(scariness.GetDescription(), &stack);
- Report(
- "HINT: if you don't care about these errors you may set "
- "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n");
-}
-
-void ErrorMallocUsableSizeNotOwned::Print() {
- Decorator d;
- Printf("%s", d.Error());
- Report(
- "ERROR: AddressSanitizer: attempting to call malloc_usable_size() for "
- "pointer which is not owned: %p\n",
- addr_description.Address());
- Printf("%s", d.Default());
- stack->Print();
- addr_description.Print();
- ReportErrorSummary(scariness.GetDescription(), stack);
-}
-
-void ErrorSanitizerGetAllocatedSizeNotOwned::Print() {
- Decorator d;
- Printf("%s", d.Error());
- Report(
- "ERROR: AddressSanitizer: attempting to call "
- "__sanitizer_get_allocated_size() for pointer which is not owned: %p\n",
- addr_description.Address());
- Printf("%s", d.Default());
- stack->Print();
- addr_description.Print();
- ReportErrorSummary(scariness.GetDescription(), stack);
-}
-
-void ErrorCallocOverflow::Print() {
- Decorator d;
- Printf("%s", d.Error());
- Report(
- "ERROR: AddressSanitizer: calloc parameters overflow: count * size "
- "(%zd * %zd) cannot be represented in type size_t (thread %s)\n",
- count, size, AsanThreadIdAndName(tid).c_str());
- Printf("%s", d.Default());
- stack->Print();
- PrintHintAllocatorCannotReturnNull();
- ReportErrorSummary(scariness.GetDescription(), stack);
-}
-
-void ErrorPvallocOverflow::Print() {
- Decorator d;
- Printf("%s", d.Error());
- Report(
- "ERROR: AddressSanitizer: pvalloc parameters overflow: size 0x%zx "
- "rounded up to system page size 0x%zx cannot be represented in type "
- "size_t (thread %s)\n",
- size, GetPageSizeCached(), AsanThreadIdAndName(tid).c_str());
- Printf("%s", d.Default());
- stack->Print();
- PrintHintAllocatorCannotReturnNull();
- ReportErrorSummary(scariness.GetDescription(), stack);
-}
-
-void ErrorInvalidAllocationAlignment::Print() {
- Decorator d;
- Printf("%s", d.Error());
- Report(
- "ERROR: AddressSanitizer: invalid allocation alignment: %zd, "
- "alignment must be a power of two (thread %s)\n",
- alignment, AsanThreadIdAndName(tid).c_str());
- Printf("%s", d.Default());
- stack->Print();
- PrintHintAllocatorCannotReturnNull();
- ReportErrorSummary(scariness.GetDescription(), stack);
-}
-
-void ErrorInvalidAlignedAllocAlignment::Print() {
- Decorator d;
- Printf("%s", d.Error());
-#if SANITIZER_POSIX
- Report("ERROR: AddressSanitizer: invalid alignment requested in "
- "aligned_alloc: %zd, alignment must be a power of two and the "
- "requested size 0x%zx must be a multiple of alignment "
- "(thread %s)\n", alignment, size, AsanThreadIdAndName(tid).c_str());
-#else
- Report("ERROR: AddressSanitizer: invalid alignment requested in "
- "aligned_alloc: %zd, the requested size 0x%zx must be a multiple of "
- "alignment (thread %s)\n", alignment, size,
- AsanThreadIdAndName(tid).c_str());
-#endif
- Printf("%s", d.Default());
- stack->Print();
- PrintHintAllocatorCannotReturnNull();
- ReportErrorSummary(scariness.GetDescription(), stack);
-}
-
-void ErrorInvalidPosixMemalignAlignment::Print() {
- Decorator d;
- Printf("%s", d.Error());
- Report(
- "ERROR: AddressSanitizer: invalid alignment requested in posix_memalign: "
- "%zd, alignment must be a power of two and a multiple of sizeof(void*) "
- "== %zd (thread %s)\n",
- alignment, sizeof(void*), AsanThreadIdAndName(tid).c_str()); // NOLINT
- Printf("%s", d.Default());
- stack->Print();
- PrintHintAllocatorCannotReturnNull();
- ReportErrorSummary(scariness.GetDescription(), stack);
-}
-
-void ErrorAllocationSizeTooBig::Print() {
- Decorator d;
- Printf("%s", d.Error());
- Report(
- "ERROR: AddressSanitizer: requested allocation size 0x%zx (0x%zx after "
- "adjustments for alignment, red zones etc.) exceeds maximum supported "
- "size of 0x%zx (thread %s)\n",
- user_size, total_size, max_size, AsanThreadIdAndName(tid).c_str());
- Printf("%s", d.Default());
- stack->Print();
- PrintHintAllocatorCannotReturnNull();
- ReportErrorSummary(scariness.GetDescription(), stack);
-}
-
-void ErrorRssLimitExceeded::Print() {
- Decorator d;
- Printf("%s", d.Error());
- Report(
- "ERROR: AddressSanitizer: specified RSS limit exceeded, currently set to "
- "soft_rss_limit_mb=%zd\n", common_flags()->soft_rss_limit_mb);
- Printf("%s", d.Default());
- stack->Print();
- PrintHintAllocatorCannotReturnNull();
- ReportErrorSummary(scariness.GetDescription(), stack);
-}
-
-void ErrorOutOfMemory::Print() {
- Decorator d;
- Printf("%s", d.Error());
- Report(
- "ERROR: AddressSanitizer: allocator is out of memory trying to allocate "
- "0x%zx bytes\n", requested_size);
- Printf("%s", d.Default());
- stack->Print();
- PrintHintAllocatorCannotReturnNull();
- ReportErrorSummary(scariness.GetDescription(), stack);
-}
-
-void ErrorStringFunctionMemoryRangesOverlap::Print() {
- Decorator d;
- char bug_type[100];
- internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);
- Printf("%s", d.Error());
- Report(
- "ERROR: AddressSanitizer: %s: memory ranges [%p,%p) and [%p, %p) "
- "overlap\n",
- bug_type, addr1_description.Address(),
- addr1_description.Address() + length1, addr2_description.Address(),
- addr2_description.Address() + length2);
- Printf("%s", d.Default());
- scariness.Print();
- stack->Print();
- addr1_description.Print();
- addr2_description.Print();
- ReportErrorSummary(bug_type, stack);
-}
-
-void ErrorStringFunctionSizeOverflow::Print() {
- Decorator d;
- Printf("%s", d.Error());
- Report("ERROR: AddressSanitizer: %s: (size=%zd)\n",
- scariness.GetDescription(), size);
- Printf("%s", d.Default());
- scariness.Print();
- stack->Print();
- addr_description.Print();
- ReportErrorSummary(scariness.GetDescription(), stack);
-}
-
-void ErrorBadParamsToAnnotateContiguousContainer::Print() {
- Report(
- "ERROR: AddressSanitizer: bad parameters to "
- "__sanitizer_annotate_contiguous_container:\n"
- " beg : %p\n"
- " end : %p\n"
- " old_mid : %p\n"
- " new_mid : %p\n",
- beg, end, old_mid, new_mid);
- uptr granularity = SHADOW_GRANULARITY;
- if (!IsAligned(beg, granularity))
- Report("ERROR: beg is not aligned by %d\n", granularity);
- stack->Print();
- ReportErrorSummary(scariness.GetDescription(), stack);
-}
-
-void ErrorODRViolation::Print() {
- Decorator d;
- Printf("%s", d.Error());
- Report("ERROR: AddressSanitizer: %s (%p):\n", scariness.GetDescription(),
- global1.beg);
- Printf("%s", d.Default());
- InternalScopedString g1_loc(256), g2_loc(256);
- PrintGlobalLocation(&g1_loc, global1);
- PrintGlobalLocation(&g2_loc, global2);
- Printf(" [1] size=%zd '%s' %s\n", global1.size,
- MaybeDemangleGlobalName(global1.name), g1_loc.data());
- Printf(" [2] size=%zd '%s' %s\n", global2.size,
- MaybeDemangleGlobalName(global2.name), g2_loc.data());
- if (stack_id1 && stack_id2) {
- Printf("These globals were registered at these points:\n");
- Printf(" [1]:\n");
- StackDepotGet(stack_id1).Print();
- Printf(" [2]:\n");
- StackDepotGet(stack_id2).Print();
- }
- Report(
- "HINT: if you don't care about these errors you may set "
- "ASAN_OPTIONS=detect_odr_violation=0\n");
- InternalScopedString error_msg(256);
- error_msg.append("%s: global '%s' at %s", scariness.GetDescription(),
- MaybeDemangleGlobalName(global1.name), g1_loc.data());
- ReportErrorSummary(error_msg.data());
-}
-
-void ErrorInvalidPointerPair::Print() {
- Decorator d;
- Printf("%s", d.Error());
- Report("ERROR: AddressSanitizer: %s: %p %p\n", scariness.GetDescription(),
- addr1_description.Address(), addr2_description.Address());
- Printf("%s", d.Default());
- GET_STACK_TRACE_FATAL(pc, bp);
- stack.Print();
- addr1_description.Print();
- addr2_description.Print();
- ReportErrorSummary(scariness.GetDescription(), &stack);
-}
-
-static bool AdjacentShadowValuesAreFullyPoisoned(u8 *s) {
- return s[-1] > 127 && s[1] > 127;
-}
-
-ErrorGeneric::ErrorGeneric(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr addr,
- bool is_write_, uptr access_size_)
- : ErrorBase(tid),
- addr_description(addr, access_size_, /*shouldLockThreadRegistry=*/false),
- pc(pc_),
- bp(bp_),
- sp(sp_),
- access_size(access_size_),
- is_write(is_write_),
- shadow_val(0) {
- scariness.Clear();
- if (access_size) {
- if (access_size <= 9) {
- char desr[] = "?-byte";
- desr[0] = '0' + access_size;
- scariness.Scare(access_size + access_size / 2, desr);
- } else if (access_size >= 10) {
- scariness.Scare(15, "multi-byte");
- }
- is_write ? scariness.Scare(20, "write") : scariness.Scare(1, "read");
-
- // Determine the error type.
- bug_descr = "unknown-crash";
- if (AddrIsInMem(addr)) {
- u8 *shadow_addr = (u8 *)MemToShadow(addr);
- // If we are accessing 16 bytes, look at the second shadow byte.
- if (*shadow_addr == 0 && access_size > SHADOW_GRANULARITY) shadow_addr++;
- // If we are in the partial right redzone, look at the next shadow byte.
- if (*shadow_addr > 0 && *shadow_addr < 128) shadow_addr++;
- bool far_from_bounds = false;
- shadow_val = *shadow_addr;
- int bug_type_score = 0;
- // For use-after-frees reads are almost as bad as writes.
- int read_after_free_bonus = 0;
- switch (shadow_val) {
- case kAsanHeapLeftRedzoneMagic:
- case kAsanArrayCookieMagic:
- bug_descr = "heap-buffer-overflow";
- bug_type_score = 10;
- far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
- break;
- case kAsanHeapFreeMagic:
- bug_descr = "heap-use-after-free";
- bug_type_score = 20;
- if (!is_write) read_after_free_bonus = 18;
- break;
- case kAsanStackLeftRedzoneMagic:
- bug_descr = "stack-buffer-underflow";
- bug_type_score = 25;
- far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
- break;
- case kAsanInitializationOrderMagic:
- bug_descr = "initialization-order-fiasco";
- bug_type_score = 1;
- break;
- case kAsanStackMidRedzoneMagic:
- case kAsanStackRightRedzoneMagic:
- bug_descr = "stack-buffer-overflow";
- bug_type_score = 25;
- far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
- break;
- case kAsanStackAfterReturnMagic:
- bug_descr = "stack-use-after-return";
- bug_type_score = 30;
- if (!is_write) read_after_free_bonus = 18;
- break;
- case kAsanUserPoisonedMemoryMagic:
- bug_descr = "use-after-poison";
- bug_type_score = 20;
- break;
- case kAsanContiguousContainerOOBMagic:
- bug_descr = "container-overflow";
- bug_type_score = 10;
- break;
- case kAsanStackUseAfterScopeMagic:
- bug_descr = "stack-use-after-scope";
- bug_type_score = 10;
- break;
- case kAsanGlobalRedzoneMagic:
- bug_descr = "global-buffer-overflow";
- bug_type_score = 10;
- far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
- break;
- case kAsanIntraObjectRedzone:
- bug_descr = "intra-object-overflow";
- bug_type_score = 10;
- break;
- case kAsanAllocaLeftMagic:
- case kAsanAllocaRightMagic:
- bug_descr = "dynamic-stack-buffer-overflow";
- bug_type_score = 25;
- far_from_bounds = AdjacentShadowValuesAreFullyPoisoned(shadow_addr);
- break;
- }
- scariness.Scare(bug_type_score + read_after_free_bonus, bug_descr);
- if (far_from_bounds) scariness.Scare(10, "far-from-bounds");
- }
- }
-}
-
-static void PrintContainerOverflowHint() {
- Printf("HINT: if you don't care about these errors you may set "
- "ASAN_OPTIONS=detect_container_overflow=0.\n"
- "If you suspect a false positive see also: "
- "https://github.com/google/sanitizers/wiki/"
- "AddressSanitizerContainerOverflow.\n");
-}
-
-static void PrintShadowByte(InternalScopedString *str, const char *before,
- u8 byte, const char *after = "\n") {
- PrintMemoryByte(str, before, byte, /*in_shadow*/true, after);
-}
-
-static void PrintLegend(InternalScopedString *str) {
- str->append(
- "Shadow byte legend (one shadow byte represents %d "
- "application bytes):\n",
- (int)SHADOW_GRANULARITY);
- PrintShadowByte(str, " Addressable: ", 0);
- str->append(" Partially addressable: ");
- for (u8 i = 1; i < SHADOW_GRANULARITY; i++) PrintShadowByte(str, "", i, " ");
- str->append("\n");
- PrintShadowByte(str, " Heap left redzone: ",
- kAsanHeapLeftRedzoneMagic);
- PrintShadowByte(str, " Freed heap region: ", kAsanHeapFreeMagic);
- PrintShadowByte(str, " Stack left redzone: ",
- kAsanStackLeftRedzoneMagic);
- PrintShadowByte(str, " Stack mid redzone: ",
- kAsanStackMidRedzoneMagic);
- PrintShadowByte(str, " Stack right redzone: ",
- kAsanStackRightRedzoneMagic);
- PrintShadowByte(str, " Stack after return: ",
- kAsanStackAfterReturnMagic);
- PrintShadowByte(str, " Stack use after scope: ",
- kAsanStackUseAfterScopeMagic);
- PrintShadowByte(str, " Global redzone: ", kAsanGlobalRedzoneMagic);
- PrintShadowByte(str, " Global init order: ",
- kAsanInitializationOrderMagic);
- PrintShadowByte(str, " Poisoned by user: ",
- kAsanUserPoisonedMemoryMagic);
- PrintShadowByte(str, " Container overflow: ",
- kAsanContiguousContainerOOBMagic);
- PrintShadowByte(str, " Array cookie: ",
- kAsanArrayCookieMagic);
- PrintShadowByte(str, " Intra object redzone: ",
- kAsanIntraObjectRedzone);
- PrintShadowByte(str, " ASan internal: ", kAsanInternalHeapMagic);
- PrintShadowByte(str, " Left alloca redzone: ", kAsanAllocaLeftMagic);
- PrintShadowByte(str, " Right alloca redzone: ", kAsanAllocaRightMagic);
- PrintShadowByte(str, " Shadow gap: ", kAsanShadowGap);
-}
-
-static void PrintShadowBytes(InternalScopedString *str, const char *before,
- u8 *bytes, u8 *guilty, uptr n) {
- Decorator d;
- if (before) str->append("%s%p:", before, bytes);
- for (uptr i = 0; i < n; i++) {
- u8 *p = bytes + i;
- const char *before =
- p == guilty ? "[" : (p - 1 == guilty && i != 0) ? "" : " ";
- const char *after = p == guilty ? "]" : "";
- PrintShadowByte(str, before, *p, after);
- }
- str->append("\n");
-}
-
-static void PrintShadowMemoryForAddress(uptr addr) {
- if (!AddrIsInMem(addr)) return;
- uptr shadow_addr = MemToShadow(addr);
- const uptr n_bytes_per_row = 16;
- uptr aligned_shadow = shadow_addr & ~(n_bytes_per_row - 1);
- InternalScopedString str(4096 * 8);
- str.append("Shadow bytes around the buggy address:\n");
- for (int i = -5; i <= 5; i++) {
- uptr row_shadow_addr = aligned_shadow + i * n_bytes_per_row;
- // Skip rows that would be outside the shadow range. This can happen when
- // the user address is near the bottom, top, or shadow gap of the address
- // space.
- if (!AddrIsInShadow(row_shadow_addr)) continue;
- const char *prefix = (i == 0) ? "=>" : " ";
- PrintShadowBytes(&str, prefix, (u8 *)row_shadow_addr, (u8 *)shadow_addr,
- n_bytes_per_row);
- }
- if (flags()->print_legend) PrintLegend(&str);
- Printf("%s", str.data());
-}
-
-void ErrorGeneric::Print() {
- Decorator d;
- Printf("%s", d.Error());
- uptr addr = addr_description.Address();
- Report("ERROR: AddressSanitizer: %s on address %p at pc %p bp %p sp %p\n",
- bug_descr, (void *)addr, pc, bp, sp);
- Printf("%s", d.Default());
-
- Printf("%s%s of size %zu at %p thread %s%s\n", d.Access(),
- access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", access_size,
- (void *)addr, AsanThreadIdAndName(tid).c_str(), d.Default());
-
- scariness.Print();
- GET_STACK_TRACE_FATAL(pc, bp);
- stack.Print();
-
- // Pass bug_descr because we have a special case for
- // initialization-order-fiasco
- addr_description.Print(bug_descr);
- if (shadow_val == kAsanContiguousContainerOOBMagic)
- PrintContainerOverflowHint();
- ReportErrorSummary(bug_descr, &stack);
- PrintShadowMemoryForAddress(addr);
-}
-
-} // namespace __asan
diff --git a/lib/asan/asan_errors.h b/lib/asan/asan_errors.h
deleted file mode 100644
index 574197ebff868..0000000000000
--- a/lib/asan/asan_errors.h
+++ /dev/null
@@ -1,439 +0,0 @@
-//===-- asan_errors.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.
-//
-// ASan-private header for error structures.
-//===----------------------------------------------------------------------===//
-#ifndef ASAN_ERRORS_H
-#define ASAN_ERRORS_H
-
-#include "asan_descriptions.h"
-#include "asan_scariness_score.h"
-#include "sanitizer_common/sanitizer_common.h"
-
-namespace __asan {
-
-// (*) VS2013 does not implement unrestricted unions, so we need a trivial
-// default constructor explicitly defined for each particular error.
-
-// None of the error classes own the stack traces mentioned in them.
-
-struct ErrorBase {
- ScarinessScoreBase scariness;
- u32 tid;
-
- ErrorBase() = default; // (*)
- explicit ErrorBase(u32 tid_) : tid(tid_) {}
- ErrorBase(u32 tid_, int initial_score, const char *reason) : tid(tid_) {
- scariness.Clear();
- scariness.Scare(initial_score, reason);
- }
-};
-
-struct ErrorDeadlySignal : ErrorBase {
- SignalContext signal;
-
- ErrorDeadlySignal() = default; // (*)
- ErrorDeadlySignal(u32 tid, const SignalContext &sig)
- : ErrorBase(tid),
- signal(sig) {
- scariness.Clear();
- if (signal.IsStackOverflow()) {
- scariness.Scare(10, "stack-overflow");
- } else if (!signal.is_memory_access) {
- scariness.Scare(10, "signal");
- } else if (signal.addr < GetPageSizeCached()) {
- scariness.Scare(10, "null-deref");
- } else if (signal.addr == signal.pc) {
- scariness.Scare(60, "wild-jump");
- } else if (signal.write_flag == SignalContext::WRITE) {
- scariness.Scare(30, "wild-addr-write");
- } else if (signal.write_flag == SignalContext::READ) {
- scariness.Scare(20, "wild-addr-read");
- } else {
- scariness.Scare(25, "wild-addr");
- }
- }
- void Print();
-};
-
-struct ErrorDoubleFree : ErrorBase {
- const BufferedStackTrace *second_free_stack;
- HeapAddressDescription addr_description;
-
- ErrorDoubleFree() = default; // (*)
- ErrorDoubleFree(u32 tid, BufferedStackTrace *stack, uptr addr)
- : ErrorBase(tid, 42, "double-free"),
- second_free_stack(stack) {
- CHECK_GT(second_free_stack->size, 0);
- GetHeapAddressInformation(addr, 1, &addr_description);
- }
- void Print();
-};
-
-struct ErrorNewDeleteTypeMismatch : ErrorBase {
- const BufferedStackTrace *free_stack;
- HeapAddressDescription addr_description;
- uptr delete_size;
- uptr delete_alignment;
-
- ErrorNewDeleteTypeMismatch() = default; // (*)
- ErrorNewDeleteTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr,
- uptr delete_size_, uptr delete_alignment_)
- : ErrorBase(tid, 10, "new-delete-type-mismatch"),
- free_stack(stack),
- delete_size(delete_size_),
- delete_alignment(delete_alignment_) {
- GetHeapAddressInformation(addr, 1, &addr_description);
- }
- void Print();
-};
-
-struct ErrorFreeNotMalloced : ErrorBase {
- const BufferedStackTrace *free_stack;
- AddressDescription addr_description;
-
- ErrorFreeNotMalloced() = default; // (*)
- ErrorFreeNotMalloced(u32 tid, BufferedStackTrace *stack, uptr addr)
- : ErrorBase(tid, 40, "bad-free"),
- free_stack(stack),
- addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
- void Print();
-};
-
-struct ErrorAllocTypeMismatch : ErrorBase {
- const BufferedStackTrace *dealloc_stack;
- HeapAddressDescription addr_description;
- AllocType alloc_type, dealloc_type;
-
- ErrorAllocTypeMismatch() = default; // (*)
- ErrorAllocTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr,
- AllocType alloc_type_, AllocType dealloc_type_)
- : ErrorBase(tid, 10, "alloc-dealloc-mismatch"),
- dealloc_stack(stack),
- alloc_type(alloc_type_),
- dealloc_type(dealloc_type_) {
- GetHeapAddressInformation(addr, 1, &addr_description);
- };
- void Print();
-};
-
-struct ErrorMallocUsableSizeNotOwned : ErrorBase {
- const BufferedStackTrace *stack;
- AddressDescription addr_description;
-
- ErrorMallocUsableSizeNotOwned() = default; // (*)
- ErrorMallocUsableSizeNotOwned(u32 tid, BufferedStackTrace *stack_, uptr addr)
- : ErrorBase(tid, 10, "bad-malloc_usable_size"),
- stack(stack_),
- addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
- void Print();
-};
-
-struct ErrorSanitizerGetAllocatedSizeNotOwned : ErrorBase {
- const BufferedStackTrace *stack;
- AddressDescription addr_description;
-
- ErrorSanitizerGetAllocatedSizeNotOwned() = default; // (*)
- ErrorSanitizerGetAllocatedSizeNotOwned(u32 tid, BufferedStackTrace *stack_,
- uptr addr)
- : ErrorBase(tid, 10, "bad-__sanitizer_get_allocated_size"),
- stack(stack_),
- addr_description(addr, /*shouldLockThreadRegistry=*/false) {}
- void Print();
-};
-
-struct ErrorCallocOverflow : ErrorBase {
- const BufferedStackTrace *stack;
- uptr count;
- uptr size;
-
- ErrorCallocOverflow() = default; // (*)
- ErrorCallocOverflow(u32 tid, BufferedStackTrace *stack_, uptr count_,
- uptr size_)
- : ErrorBase(tid, 10, "calloc-overflow"),
- stack(stack_),
- count(count_),
- size(size_) {}
- void Print();
-};
-
-struct ErrorPvallocOverflow : ErrorBase {
- const BufferedStackTrace *stack;
- uptr size;
-
- ErrorPvallocOverflow() = default; // (*)
- ErrorPvallocOverflow(u32 tid, BufferedStackTrace *stack_, uptr size_)
- : ErrorBase(tid, 10, "pvalloc-overflow"),
- stack(stack_),
- size(size_) {}
- void Print();
-};
-
-struct ErrorInvalidAllocationAlignment : ErrorBase {
- const BufferedStackTrace *stack;
- uptr alignment;
-
- ErrorInvalidAllocationAlignment() = default; // (*)
- ErrorInvalidAllocationAlignment(u32 tid, BufferedStackTrace *stack_,
- uptr alignment_)
- : ErrorBase(tid, 10, "invalid-allocation-alignment"),
- stack(stack_),
- alignment(alignment_) {}
- void Print();
-};
-
-struct ErrorInvalidAlignedAllocAlignment : ErrorBase {
- const BufferedStackTrace *stack;
- uptr size;
- uptr alignment;
-
- ErrorInvalidAlignedAllocAlignment() = default; // (*)
- ErrorInvalidAlignedAllocAlignment(u32 tid, BufferedStackTrace *stack_,
- uptr size_, uptr alignment_)
- : ErrorBase(tid, 10, "invalid-aligned-alloc-alignment"),
- stack(stack_),
- size(size_),
- alignment(alignment_) {}
- void Print();
-};
-
-struct ErrorInvalidPosixMemalignAlignment : ErrorBase {
- const BufferedStackTrace *stack;
- uptr alignment;
-
- ErrorInvalidPosixMemalignAlignment() = default; // (*)
- ErrorInvalidPosixMemalignAlignment(u32 tid, BufferedStackTrace *stack_,
- uptr alignment_)
- : ErrorBase(tid, 10, "invalid-posix-memalign-alignment"),
- stack(stack_),
- alignment(alignment_) {}
- void Print();
-};
-
-struct ErrorAllocationSizeTooBig : ErrorBase {
- const BufferedStackTrace *stack;
- uptr user_size;
- uptr total_size;
- uptr max_size;
-
- ErrorAllocationSizeTooBig() = default; // (*)
- ErrorAllocationSizeTooBig(u32 tid, BufferedStackTrace *stack_,
- uptr user_size_, uptr total_size_, uptr max_size_)
- : ErrorBase(tid, 10, "allocation-size-too-big"),
- stack(stack_),
- user_size(user_size_),
- total_size(total_size_),
- max_size(max_size_) {}
- void Print();
-};
-
-struct ErrorRssLimitExceeded : ErrorBase {
- const BufferedStackTrace *stack;
-
- ErrorRssLimitExceeded() = default; // (*)
- ErrorRssLimitExceeded(u32 tid, BufferedStackTrace *stack_)
- : ErrorBase(tid, 10, "rss-limit-exceeded"),
- stack(stack_) {}
- void Print();
-};
-
-struct ErrorOutOfMemory : ErrorBase {
- const BufferedStackTrace *stack;
- uptr requested_size;
-
- ErrorOutOfMemory() = default; // (*)
- ErrorOutOfMemory(u32 tid, BufferedStackTrace *stack_, uptr requested_size_)
- : ErrorBase(tid, 10, "out-of-memory"),
- stack(stack_),
- requested_size(requested_size_) {}
- void Print();
-};
-
-struct ErrorStringFunctionMemoryRangesOverlap : ErrorBase {
- const BufferedStackTrace *stack;
- uptr length1, length2;
- AddressDescription addr1_description;
- AddressDescription addr2_description;
- const char *function;
-
- ErrorStringFunctionMemoryRangesOverlap() = default; // (*)
- ErrorStringFunctionMemoryRangesOverlap(u32 tid, BufferedStackTrace *stack_,
- uptr addr1, uptr length1_, uptr addr2,
- uptr length2_, const char *function_)
- : ErrorBase(tid),
- stack(stack_),
- length1(length1_),
- length2(length2_),
- addr1_description(addr1, length1, /*shouldLockThreadRegistry=*/false),
- addr2_description(addr2, length2, /*shouldLockThreadRegistry=*/false),
- function(function_) {
- char bug_type[100];
- internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function);
- scariness.Clear();
- scariness.Scare(10, bug_type);
- }
- void Print();
-};
-
-struct ErrorStringFunctionSizeOverflow : ErrorBase {
- const BufferedStackTrace *stack;
- AddressDescription addr_description;
- uptr size;
-
- ErrorStringFunctionSizeOverflow() = default; // (*)
- ErrorStringFunctionSizeOverflow(u32 tid, BufferedStackTrace *stack_,
- uptr addr, uptr size_)
- : ErrorBase(tid, 10, "negative-size-param"),
- stack(stack_),
- addr_description(addr, /*shouldLockThreadRegistry=*/false),
- size(size_) {}
- void Print();
-};
-
-struct ErrorBadParamsToAnnotateContiguousContainer : ErrorBase {
- const BufferedStackTrace *stack;
- uptr beg, end, old_mid, new_mid;
-
- ErrorBadParamsToAnnotateContiguousContainer() = default; // (*)
- // PS4: Do we want an AddressDescription for beg?
- ErrorBadParamsToAnnotateContiguousContainer(u32 tid,
- BufferedStackTrace *stack_,
- uptr beg_, uptr end_,
- uptr old_mid_, uptr new_mid_)
- : ErrorBase(tid, 10, "bad-__sanitizer_annotate_contiguous_container"),
- stack(stack_),
- beg(beg_),
- end(end_),
- old_mid(old_mid_),
- new_mid(new_mid_) {}
- void Print();
-};
-
-struct ErrorODRViolation : ErrorBase {
- __asan_global global1, global2;
- u32 stack_id1, stack_id2;
-
- ErrorODRViolation() = default; // (*)
- ErrorODRViolation(u32 tid, const __asan_global *g1, u32 stack_id1_,
- const __asan_global *g2, u32 stack_id2_)
- : ErrorBase(tid, 10, "odr-violation"),
- global1(*g1),
- global2(*g2),
- stack_id1(stack_id1_),
- stack_id2(stack_id2_) {}
- void Print();
-};
-
-struct ErrorInvalidPointerPair : ErrorBase {
- uptr pc, bp, sp;
- AddressDescription addr1_description;
- AddressDescription addr2_description;
-
- ErrorInvalidPointerPair() = default; // (*)
- ErrorInvalidPointerPair(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr p1,
- uptr p2)
- : ErrorBase(tid, 10, "invalid-pointer-pair"),
- pc(pc_),
- bp(bp_),
- sp(sp_),
- addr1_description(p1, 1, /*shouldLockThreadRegistry=*/false),
- addr2_description(p2, 1, /*shouldLockThreadRegistry=*/false) {}
- void Print();
-};
-
-struct ErrorGeneric : ErrorBase {
- AddressDescription addr_description;
- uptr pc, bp, sp;
- uptr access_size;
- const char *bug_descr;
- bool is_write;
- u8 shadow_val;
-
- ErrorGeneric() = default; // (*)
- ErrorGeneric(u32 tid, uptr addr, uptr pc_, uptr bp_, uptr sp_, bool is_write_,
- uptr access_size_);
- void Print();
-};
-
-// clang-format off
-#define ASAN_FOR_EACH_ERROR_KIND(macro) \
- macro(DeadlySignal) \
- macro(DoubleFree) \
- macro(NewDeleteTypeMismatch) \
- macro(FreeNotMalloced) \
- macro(AllocTypeMismatch) \
- macro(MallocUsableSizeNotOwned) \
- macro(SanitizerGetAllocatedSizeNotOwned) \
- macro(CallocOverflow) \
- macro(PvallocOverflow) \
- macro(InvalidAllocationAlignment) \
- macro(InvalidAlignedAllocAlignment) \
- macro(InvalidPosixMemalignAlignment) \
- macro(AllocationSizeTooBig) \
- macro(RssLimitExceeded) \
- macro(OutOfMemory) \
- macro(StringFunctionMemoryRangesOverlap) \
- macro(StringFunctionSizeOverflow) \
- macro(BadParamsToAnnotateContiguousContainer) \
- macro(ODRViolation) \
- macro(InvalidPointerPair) \
- macro(Generic)
-// clang-format on
-
-#define ASAN_DEFINE_ERROR_KIND(name) kErrorKind##name,
-#define ASAN_ERROR_DESCRIPTION_MEMBER(name) Error##name name;
-#define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \
- ErrorDescription(Error##name const &e) : kind(kErrorKind##name), name(e) {}
-#define ASAN_ERROR_DESCRIPTION_PRINT(name) \
- case kErrorKind##name: \
- return name.Print();
-
-enum ErrorKind {
- kErrorKindInvalid = 0,
- ASAN_FOR_EACH_ERROR_KIND(ASAN_DEFINE_ERROR_KIND)
-};
-
-struct ErrorDescription {
- ErrorKind kind;
- // We're using a tagged union because it allows us to have a trivially
- // copiable type and use the same structures as the public interface.
- //
- // We can add a wrapper around it to make it "more c++-like", but that would
- // add a lot of code and the benefit wouldn't be that big.
- union {
- ErrorBase Base;
- ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_MEMBER)
- };
-
- ErrorDescription() { internal_memset(this, 0, sizeof(*this)); }
- explicit ErrorDescription(LinkerInitialized) {}
- ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_CONSTRUCTOR)
-
- bool IsValid() { return kind != kErrorKindInvalid; }
- void Print() {
- switch (kind) {
- ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_PRINT)
- case kErrorKindInvalid:
- CHECK(0);
- }
- CHECK(0);
- }
-};
-
-#undef ASAN_FOR_EACH_ERROR_KIND
-#undef ASAN_DEFINE_ERROR_KIND
-#undef ASAN_ERROR_DESCRIPTION_MEMBER
-#undef ASAN_ERROR_DESCRIPTION_CONSTRUCTOR
-#undef ASAN_ERROR_DESCRIPTION_PRINT
-
-} // namespace __asan
-
-#endif // ASAN_ERRORS_H
diff --git a/lib/asan/asan_fake_stack.cc b/lib/asan/asan_fake_stack.cc
deleted file mode 100644
index 1c6184e3c7fc9..0000000000000
--- a/lib/asan/asan_fake_stack.cc
+++ /dev/null
@@ -1,283 +0,0 @@
-//===-- asan_fake_stack.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.
-//
-// FakeStack is used to detect use-after-return bugs.
-//===----------------------------------------------------------------------===//
-
-#include "asan_allocator.h"
-#include "asan_poisoning.h"
-#include "asan_thread.h"
-
-namespace __asan {
-
-static const u64 kMagic1 = kAsanStackAfterReturnMagic;
-static const u64 kMagic2 = (kMagic1 << 8) | kMagic1;
-static const u64 kMagic4 = (kMagic2 << 16) | kMagic2;
-static const u64 kMagic8 = (kMagic4 << 32) | kMagic4;
-
-static const u64 kAllocaRedzoneSize = 32UL;
-static const u64 kAllocaRedzoneMask = 31UL;
-
-// For small size classes inline PoisonShadow for better performance.
-ALWAYS_INLINE void SetShadow(uptr ptr, uptr size, uptr class_id, u64 magic) {
- u64 *shadow = reinterpret_cast<u64*>(MemToShadow(ptr));
- if (SHADOW_SCALE == 3 && class_id <= 6) {
- // This code expects SHADOW_SCALE=3.
- for (uptr i = 0; i < (((uptr)1) << class_id); i++) {
- shadow[i] = magic;
- // Make sure this does not become memset.
- SanitizerBreakOptimization(nullptr);
- }
- } else {
- // The size class is too big, it's cheaper to poison only size bytes.
- PoisonShadow(ptr, size, static_cast<u8>(magic));
- }
-}
-
-FakeStack *FakeStack::Create(uptr stack_size_log) {
- static uptr kMinStackSizeLog = 16;
- static uptr kMaxStackSizeLog = FIRST_32_SECOND_64(24, 28);
- if (stack_size_log < kMinStackSizeLog)
- stack_size_log = kMinStackSizeLog;
- if (stack_size_log > kMaxStackSizeLog)
- stack_size_log = kMaxStackSizeLog;
- uptr size = RequiredSize(stack_size_log);
- FakeStack *res = reinterpret_cast<FakeStack *>(
- flags()->uar_noreserve ? MmapNoReserveOrDie(size, "FakeStack")
- : MmapOrDie(size, "FakeStack"));
- res->stack_size_log_ = stack_size_log;
- u8 *p = reinterpret_cast<u8 *>(res);
- VReport(1, "T%d: FakeStack created: %p -- %p stack_size_log: %zd; "
- "mmapped %zdK, noreserve=%d \n",
- GetCurrentTidOrInvalid(), p,
- p + FakeStack::RequiredSize(stack_size_log), stack_size_log,
- size >> 10, flags()->uar_noreserve);
- return res;
-}
-
-void FakeStack::Destroy(int tid) {
- PoisonAll(0);
- if (Verbosity() >= 2) {
- InternalScopedString str(kNumberOfSizeClasses * 50);
- for (uptr class_id = 0; class_id < kNumberOfSizeClasses; class_id++)
- str.append("%zd: %zd/%zd; ", class_id, hint_position_[class_id],
- NumberOfFrames(stack_size_log(), class_id));
- Report("T%d: FakeStack destroyed: %s\n", tid, str.data());
- }
- uptr size = RequiredSize(stack_size_log_);
- FlushUnneededASanShadowMemory(reinterpret_cast<uptr>(this), size);
- UnmapOrDie(this, size);
-}
-
-void FakeStack::PoisonAll(u8 magic) {
- PoisonShadow(reinterpret_cast<uptr>(this), RequiredSize(stack_size_log()),
- magic);
-}
-
-#if !defined(_MSC_VER) || defined(__clang__)
-ALWAYS_INLINE USED
-#endif
-FakeFrame *FakeStack::Allocate(uptr stack_size_log, uptr class_id,
- uptr real_stack) {
- CHECK_LT(class_id, kNumberOfSizeClasses);
- if (needs_gc_)
- GC(real_stack);
- uptr &hint_position = hint_position_[class_id];
- const int num_iter = NumberOfFrames(stack_size_log, class_id);
- u8 *flags = GetFlags(stack_size_log, class_id);
- for (int i = 0; i < num_iter; i++) {
- uptr pos = ModuloNumberOfFrames(stack_size_log, class_id, hint_position++);
- // This part is tricky. On one hand, checking and setting flags[pos]
- // should be atomic to ensure async-signal safety. But on the other hand,
- // if the signal arrives between checking and setting flags[pos], the
- // signal handler's fake stack will start from a different hint_position
- // and so will not touch this particular byte. So, it is safe to do this
- // with regular non-atomic load and store (at least I was not able to make
- // this code crash).
- if (flags[pos]) continue;
- flags[pos] = 1;
- FakeFrame *res = reinterpret_cast<FakeFrame *>(
- GetFrame(stack_size_log, class_id, pos));
- res->real_stack = real_stack;
- *SavedFlagPtr(reinterpret_cast<uptr>(res), class_id) = &flags[pos];
- return res;
- }
- return nullptr; // We are out of fake stack.
-}
-
-uptr FakeStack::AddrIsInFakeStack(uptr ptr, uptr *frame_beg, uptr *frame_end) {
- uptr stack_size_log = this->stack_size_log();
- uptr beg = reinterpret_cast<uptr>(GetFrame(stack_size_log, 0, 0));
- uptr end = reinterpret_cast<uptr>(this) + RequiredSize(stack_size_log);
- if (ptr < beg || ptr >= end) return 0;
- uptr class_id = (ptr - beg) >> stack_size_log;
- uptr base = beg + (class_id << stack_size_log);
- CHECK_LE(base, ptr);
- CHECK_LT(ptr, base + (((uptr)1) << stack_size_log));
- uptr pos = (ptr - base) >> (kMinStackFrameSizeLog + class_id);
- uptr res = base + pos * BytesInSizeClass(class_id);
- *frame_end = res + BytesInSizeClass(class_id);
- *frame_beg = res + sizeof(FakeFrame);
- return res;
-}
-
-void FakeStack::HandleNoReturn() {
- needs_gc_ = true;
-}
-
-// When throw, longjmp or some such happens we don't call OnFree() and
-// as the result may leak one or more fake frames, but the good news is that
-// we are notified about all such events by HandleNoReturn().
-// If we recently had such no-return event we need to collect garbage frames.
-// We do it based on their 'real_stack' values -- everything that is lower
-// than the current real_stack is garbage.
-NOINLINE void FakeStack::GC(uptr real_stack) {
- uptr collected = 0;
- for (uptr class_id = 0; class_id < kNumberOfSizeClasses; class_id++) {
- u8 *flags = GetFlags(stack_size_log(), class_id);
- for (uptr i = 0, n = NumberOfFrames(stack_size_log(), class_id); i < n;
- i++) {
- if (flags[i] == 0) continue; // not allocated.
- FakeFrame *ff = reinterpret_cast<FakeFrame *>(
- GetFrame(stack_size_log(), class_id, i));
- if (ff->real_stack < real_stack) {
- flags[i] = 0;
- collected++;
- }
- }
- }
- needs_gc_ = false;
-}
-
-void FakeStack::ForEachFakeFrame(RangeIteratorCallback callback, void *arg) {
- for (uptr class_id = 0; class_id < kNumberOfSizeClasses; class_id++) {
- u8 *flags = GetFlags(stack_size_log(), class_id);
- for (uptr i = 0, n = NumberOfFrames(stack_size_log(), class_id); i < n;
- i++) {
- if (flags[i] == 0) continue; // not allocated.
- FakeFrame *ff = reinterpret_cast<FakeFrame *>(
- GetFrame(stack_size_log(), class_id, i));
- uptr begin = reinterpret_cast<uptr>(ff);
- callback(begin, begin + FakeStack::BytesInSizeClass(class_id), arg);
- }
- }
-}
-
-#if (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_FUCHSIA
-static THREADLOCAL FakeStack *fake_stack_tls;
-
-FakeStack *GetTLSFakeStack() {
- return fake_stack_tls;
-}
-void SetTLSFakeStack(FakeStack *fs) {
- fake_stack_tls = fs;
-}
-#else
-FakeStack *GetTLSFakeStack() { return 0; }
-void SetTLSFakeStack(FakeStack *fs) { }
-#endif // (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_FUCHSIA
-
-static FakeStack *GetFakeStack() {
- AsanThread *t = GetCurrentThread();
- if (!t) return nullptr;
- return t->fake_stack();
-}
-
-static FakeStack *GetFakeStackFast() {
- if (FakeStack *fs = GetTLSFakeStack())
- return fs;
- if (!__asan_option_detect_stack_use_after_return)
- return nullptr;
- return GetFakeStack();
-}
-
-ALWAYS_INLINE uptr OnMalloc(uptr class_id, uptr size) {
- FakeStack *fs = GetFakeStackFast();
- if (!fs) return 0;
- uptr local_stack;
- uptr real_stack = reinterpret_cast<uptr>(&local_stack);
- FakeFrame *ff = fs->Allocate(fs->stack_size_log(), class_id, real_stack);
- if (!ff) return 0; // Out of fake stack.
- uptr ptr = reinterpret_cast<uptr>(ff);
- SetShadow(ptr, size, class_id, 0);
- return ptr;
-}
-
-ALWAYS_INLINE void OnFree(uptr ptr, uptr class_id, uptr size) {
- FakeStack::Deallocate(ptr, class_id);
- SetShadow(ptr, size, class_id, kMagic8);
-}
-
-} // namespace __asan
-
-// ---------------------- Interface ---------------- {{{1
-using namespace __asan;
-#define DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(class_id) \
- extern "C" SANITIZER_INTERFACE_ATTRIBUTE uptr \
- __asan_stack_malloc_##class_id(uptr size) { \
- return OnMalloc(class_id, size); \
- } \
- extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __asan_stack_free_##class_id( \
- uptr ptr, uptr size) { \
- OnFree(ptr, class_id, size); \
- }
-
-DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(0)
-DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(1)
-DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(2)
-DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(3)
-DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(4)
-DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(5)
-DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(6)
-DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(7)
-DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(8)
-DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(9)
-DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(10)
-extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE
-void *__asan_get_current_fake_stack() { return GetFakeStackFast(); }
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,
- void **end) {
- FakeStack *fs = reinterpret_cast<FakeStack*>(fake_stack);
- if (!fs) return nullptr;
- uptr frame_beg, frame_end;
- FakeFrame *frame = reinterpret_cast<FakeFrame *>(fs->AddrIsInFakeStack(
- reinterpret_cast<uptr>(addr), &frame_beg, &frame_end));
- if (!frame) return nullptr;
- if (frame->magic != kCurrentStackFrameMagic)
- return nullptr;
- if (beg) *beg = reinterpret_cast<void*>(frame_beg);
- if (end) *end = reinterpret_cast<void*>(frame_end);
- return reinterpret_cast<void*>(frame->real_stack);
-}
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void __asan_alloca_poison(uptr addr, uptr size) {
- uptr LeftRedzoneAddr = addr - kAllocaRedzoneSize;
- uptr PartialRzAddr = addr + size;
- uptr RightRzAddr = (PartialRzAddr + kAllocaRedzoneMask) & ~kAllocaRedzoneMask;
- uptr PartialRzAligned = PartialRzAddr & ~(SHADOW_GRANULARITY - 1);
- FastPoisonShadow(LeftRedzoneAddr, kAllocaRedzoneSize, kAsanAllocaLeftMagic);
- FastPoisonShadowPartialRightRedzone(
- PartialRzAligned, PartialRzAddr % SHADOW_GRANULARITY,
- RightRzAddr - PartialRzAligned, kAsanAllocaRightMagic);
- FastPoisonShadow(RightRzAddr, kAllocaRedzoneSize, kAsanAllocaRightMagic);
-}
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void __asan_allocas_unpoison(uptr top, uptr bottom) {
- if ((!top) || (top > bottom)) return;
- REAL(memset)(reinterpret_cast<void*>(MemToShadow(top)), 0,
- (bottom - top) / SHADOW_GRANULARITY);
-}
-} // extern "C"
diff --git a/lib/asan/asan_fake_stack.h b/lib/asan/asan_fake_stack.h
deleted file mode 100644
index da9a91c23025f..0000000000000
--- a/lib/asan/asan_fake_stack.h
+++ /dev/null
@@ -1,176 +0,0 @@
-//===-- asan_fake_stack.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.
-//
-// ASan-private header for asan_fake_stack.cc, implements FakeStack.
-//===----------------------------------------------------------------------===//
-
-#ifndef ASAN_FAKE_STACK_H
-#define ASAN_FAKE_STACK_H
-
-#include "sanitizer_common/sanitizer_common.h"
-
-namespace __asan {
-
-// Fake stack frame contains local variables of one function.
-struct FakeFrame {
- uptr magic; // Modified by the instrumented code.
- uptr descr; // Modified by the instrumented code.
- uptr pc; // Modified by the instrumented code.
- uptr real_stack;
-};
-
-// For each thread we create a fake stack and place stack objects on this fake
-// stack instead of the real stack. The fake stack is not really a stack but
-// a fast malloc-like allocator so that when a function exits the fake stack
-// is not popped but remains there for quite some time until gets used again.
-// So, we poison the objects on the fake stack when function returns.
-// It helps us find use-after-return bugs.
-//
-// The FakeStack objects is allocated by a single mmap call and has no other
-// pointers. The size of the fake stack depends on the actual thread stack size
-// and thus can not be a constant.
-// stack_size is a power of two greater or equal to the thread's stack size;
-// we store it as its logarithm (stack_size_log).
-// FakeStack has kNumberOfSizeClasses (11) size classes, each size class
-// is a power of two, starting from 64 bytes. Each size class occupies
-// stack_size bytes and thus can allocate
-// NumberOfFrames=(stack_size/BytesInSizeClass) fake frames (also a power of 2).
-// For each size class we have NumberOfFrames allocation flags,
-// each flag indicates whether the given frame is currently allocated.
-// All flags for size classes 0 .. 10 are stored in a single contiguous region
-// followed by another contiguous region which contains the actual memory for
-// size classes. The addresses are computed by GetFlags and GetFrame without
-// any memory accesses solely based on 'this' and stack_size_log.
-// Allocate() flips the appropriate allocation flag atomically, thus achieving
-// async-signal safety.
-// This allocator does not have quarantine per se, but it tries to allocate the
-// frames in round robin fashion to maximize the delay between a deallocation
-// and the next allocation.
-class FakeStack {
- static const uptr kMinStackFrameSizeLog = 6; // Min frame is 64B.
- static const uptr kMaxStackFrameSizeLog = 16; // Max stack frame is 64K.
-
- public:
- static const uptr kNumberOfSizeClasses =
- kMaxStackFrameSizeLog - kMinStackFrameSizeLog + 1;
-
- // CTOR: create the FakeStack as a single mmap-ed object.
- static FakeStack *Create(uptr stack_size_log);
-
- void Destroy(int tid);
-
- // stack_size_log is at least 15 (stack_size >= 32K).
- static uptr SizeRequiredForFlags(uptr stack_size_log) {
- return ((uptr)1) << (stack_size_log + 1 - kMinStackFrameSizeLog);
- }
-
- // Each size class occupies stack_size bytes.
- static uptr SizeRequiredForFrames(uptr stack_size_log) {
- return (((uptr)1) << stack_size_log) * kNumberOfSizeClasses;
- }
-
- // Number of bytes requires for the whole object.
- static uptr RequiredSize(uptr stack_size_log) {
- return kFlagsOffset + SizeRequiredForFlags(stack_size_log) +
- SizeRequiredForFrames(stack_size_log);
- }
-
- // Offset of the given flag from the first flag.
- // The flags for class 0 begin at offset 000000000
- // The flags for class 1 begin at offset 100000000
- // ....................2................ 110000000
- // ....................3................ 111000000
- // and so on.
- static uptr FlagsOffset(uptr stack_size_log, uptr class_id) {
- uptr t = kNumberOfSizeClasses - 1 - class_id;
- const uptr all_ones = (((uptr)1) << (kNumberOfSizeClasses - 1)) - 1;
- return ((all_ones >> t) << t) << (stack_size_log - 15);
- }
-
- static uptr NumberOfFrames(uptr stack_size_log, uptr class_id) {
- return ((uptr)1) << (stack_size_log - kMinStackFrameSizeLog - class_id);
- }
-
- // Divide n by the number of frames in size class.
- static uptr ModuloNumberOfFrames(uptr stack_size_log, uptr class_id, uptr n) {
- return n & (NumberOfFrames(stack_size_log, class_id) - 1);
- }
-
- // The pointer to the flags of the given class_id.
- u8 *GetFlags(uptr stack_size_log, uptr class_id) {
- return reinterpret_cast<u8 *>(this) + kFlagsOffset +
- FlagsOffset(stack_size_log, class_id);
- }
-
- // Get frame by class_id and pos.
- u8 *GetFrame(uptr stack_size_log, uptr class_id, uptr pos) {
- return reinterpret_cast<u8 *>(this) + kFlagsOffset +
- SizeRequiredForFlags(stack_size_log) +
- (((uptr)1) << stack_size_log) * class_id +
- BytesInSizeClass(class_id) * pos;
- }
-
- // Allocate the fake frame.
- FakeFrame *Allocate(uptr stack_size_log, uptr class_id, uptr real_stack);
-
- // Deallocate the fake frame: read the saved flag address and write 0 there.
- static void Deallocate(uptr x, uptr class_id) {
- **SavedFlagPtr(x, class_id) = 0;
- }
-
- // Poison the entire FakeStack's shadow with the magic value.
- void PoisonAll(u8 magic);
-
- // Return the beginning of the FakeFrame or 0 if the address is not ours.
- uptr AddrIsInFakeStack(uptr addr, uptr *frame_beg, uptr *frame_end);
- USED uptr AddrIsInFakeStack(uptr addr) {
- uptr t1, t2;
- return AddrIsInFakeStack(addr, &t1, &t2);
- }
-
- // Number of bytes in a fake frame of this size class.
- static uptr BytesInSizeClass(uptr class_id) {
- return ((uptr)1) << (class_id + kMinStackFrameSizeLog);
- }
-
- // The fake frame is guaranteed to have a right redzone.
- // We use the last word of that redzone to store the address of the flag
- // that corresponds to the current frame to make faster deallocation.
- static u8 **SavedFlagPtr(uptr x, uptr class_id) {
- return reinterpret_cast<u8 **>(x + BytesInSizeClass(class_id) - sizeof(x));
- }
-
- uptr stack_size_log() const { return stack_size_log_; }
-
- void HandleNoReturn();
- void GC(uptr real_stack);
-
- void ForEachFakeFrame(RangeIteratorCallback callback, void *arg);
-
- private:
- FakeStack() { }
- static const uptr kFlagsOffset = 4096; // This is were the flags begin.
- // Must match the number of uses of DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID
- COMPILER_CHECK(kNumberOfSizeClasses == 11);
- static const uptr kMaxStackMallocSize = ((uptr)1) << kMaxStackFrameSizeLog;
-
- uptr hint_position_[kNumberOfSizeClasses];
- uptr stack_size_log_;
- // a bit is set if something was allocated from the corresponding size class.
- bool needs_gc_;
-};
-
-FakeStack *GetTLSFakeStack();
-void SetTLSFakeStack(FakeStack *fs);
-
-} // namespace __asan
-
-#endif // ASAN_FAKE_STACK_H
diff --git a/lib/asan/asan_flags.cc b/lib/asan/asan_flags.cc
deleted file mode 100644
index 5682ab4eb4769..0000000000000
--- a/lib/asan/asan_flags.cc
+++ /dev/null
@@ -1,215 +0,0 @@
-//===-- asan_flags.cc -------------------------------------------*- 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.
-//
-// ASan flag parsing logic.
-//===----------------------------------------------------------------------===//
-
-#include "asan_activation.h"
-#include "asan_flags.h"
-#include "asan_interface_internal.h"
-#include "asan_stack.h"
-#include "lsan/lsan_common.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_flags.h"
-#include "sanitizer_common/sanitizer_flag_parser.h"
-#include "ubsan/ubsan_flags.h"
-#include "ubsan/ubsan_platform.h"
-
-namespace __asan {
-
-Flags asan_flags_dont_use_directly; // use via flags().
-
-static const char *MaybeCallAsanDefaultOptions() {
- return (&__asan_default_options) ? __asan_default_options() : "";
-}
-
-static const char *MaybeUseAsanDefaultOptionsCompileDefinition() {
-#ifdef ASAN_DEFAULT_OPTIONS
- return SANITIZER_STRINGIFY(ASAN_DEFAULT_OPTIONS);
-#else
- return "";
-#endif
-}
-
-void Flags::SetDefaults() {
-#define ASAN_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue;
-#include "asan_flags.inc"
-#undef ASAN_FLAG
-}
-
-static void RegisterAsanFlags(FlagParser *parser, Flags *f) {
-#define ASAN_FLAG(Type, Name, DefaultValue, Description) \
- RegisterFlag(parser, #Name, Description, &f->Name);
-#include "asan_flags.inc"
-#undef ASAN_FLAG
-}
-
-void InitializeFlags() {
- // Set the default values and prepare for parsing ASan and common flags.
- SetCommonFlagsDefaults();
- {
- CommonFlags cf;
- cf.CopyFrom(*common_flags());
- cf.detect_leaks = cf.detect_leaks && CAN_SANITIZE_LEAKS;
- cf.external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH");
- cf.malloc_context_size = kDefaultMallocContextSize;
- cf.intercept_tls_get_addr = true;
- cf.exitcode = 1;
- OverrideCommonFlags(cf);
- }
- Flags *f = flags();
- f->SetDefaults();
-
- FlagParser asan_parser;
- RegisterAsanFlags(&asan_parser, f);
- RegisterCommonFlags(&asan_parser);
-
- // Set the default values and prepare for parsing LSan and UBSan flags
- // (which can also overwrite common flags).
-#if CAN_SANITIZE_LEAKS
- __lsan::Flags *lf = __lsan::flags();
- lf->SetDefaults();
-
- FlagParser lsan_parser;
- __lsan::RegisterLsanFlags(&lsan_parser, lf);
- RegisterCommonFlags(&lsan_parser);
-#endif
-
-#if CAN_SANITIZE_UB
- __ubsan::Flags *uf = __ubsan::flags();
- uf->SetDefaults();
-
- FlagParser ubsan_parser;
- __ubsan::RegisterUbsanFlags(&ubsan_parser, uf);
- RegisterCommonFlags(&ubsan_parser);
-#endif
-
- if (SANITIZER_MAC) {
- // Support macOS MallocScribble and MallocPreScribble:
- // <https://developer.apple.com/library/content/documentation/Performance/
- // Conceptual/ManagingMemory/Articles/MallocDebug.html>
- if (GetEnv("MallocScribble")) {
- f->max_free_fill_size = 0x1000;
- }
- if (GetEnv("MallocPreScribble")) {
- f->malloc_fill_byte = 0xaa;
- }
- }
-
- // Override from ASan compile definition.
- const char *asan_compile_def = MaybeUseAsanDefaultOptionsCompileDefinition();
- asan_parser.ParseString(asan_compile_def);
-
- // Override from user-specified string.
- const char *asan_default_options = MaybeCallAsanDefaultOptions();
- asan_parser.ParseString(asan_default_options);
-#if CAN_SANITIZE_UB
- const char *ubsan_default_options = __ubsan::MaybeCallUbsanDefaultOptions();
- ubsan_parser.ParseString(ubsan_default_options);
-#endif
-#if CAN_SANITIZE_LEAKS
- const char *lsan_default_options = __lsan::MaybeCallLsanDefaultOptions();
- lsan_parser.ParseString(lsan_default_options);
-#endif
-
- // Override from command line.
- asan_parser.ParseString(GetEnv("ASAN_OPTIONS"));
-#if CAN_SANITIZE_LEAKS
- lsan_parser.ParseString(GetEnv("LSAN_OPTIONS"));
-#endif
-#if CAN_SANITIZE_UB
- ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS"));
-#endif
-
- InitializeCommonFlags();
-
- // TODO(eugenis): dump all flags at verbosity>=2?
- if (Verbosity()) ReportUnrecognizedFlags();
-
- if (common_flags()->help) {
- // TODO(samsonov): print all of the flags (ASan, LSan, common).
- asan_parser.PrintFlagDescriptions();
- }
-
- // Flag validation:
- if (!CAN_SANITIZE_LEAKS && common_flags()->detect_leaks) {
- Report("%s: detect_leaks is not supported on this platform.\n",
- SanitizerToolName);
- Die();
- }
- // Ensure that redzone is at least SHADOW_GRANULARITY.
- if (f->redzone < (int)SHADOW_GRANULARITY)
- f->redzone = SHADOW_GRANULARITY;
- // Make "strict_init_order" imply "check_initialization_order".
- // TODO(samsonov): Use a single runtime flag for an init-order checker.
- if (f->strict_init_order) {
- f->check_initialization_order = true;
- }
- CHECK_LE((uptr)common_flags()->malloc_context_size, kStackTraceMax);
- CHECK_LE(f->min_uar_stack_size_log, f->max_uar_stack_size_log);
- CHECK_GE(f->redzone, 16);
- CHECK_GE(f->max_redzone, f->redzone);
- CHECK_LE(f->max_redzone, 2048);
- CHECK(IsPowerOfTwo(f->redzone));
- CHECK(IsPowerOfTwo(f->max_redzone));
- if (SANITIZER_RTEMS) {
- CHECK(!f->unmap_shadow_on_exit);
- CHECK(!f->protect_shadow_gap);
- }
-
- // quarantine_size is deprecated but we still honor it.
- // quarantine_size can not be used together with quarantine_size_mb.
- if (f->quarantine_size >= 0 && f->quarantine_size_mb >= 0) {
- Report("%s: please use either 'quarantine_size' (deprecated) or "
- "quarantine_size_mb, but not both\n", SanitizerToolName);
- Die();
- }
- if (f->quarantine_size >= 0)
- f->quarantine_size_mb = f->quarantine_size >> 20;
- if (f->quarantine_size_mb < 0) {
- const int kDefaultQuarantineSizeMb =
- (ASAN_LOW_MEMORY) ? 1UL << 4 : 1UL << 8;
- f->quarantine_size_mb = kDefaultQuarantineSizeMb;
- }
- if (f->thread_local_quarantine_size_kb < 0) {
- const u32 kDefaultThreadLocalQuarantineSizeKb =
- // It is not advised to go lower than 64Kb, otherwise quarantine batches
- // pushed from thread local quarantine to global one will create too
- // much overhead. One quarantine batch size is 8Kb and it holds up to
- // 1021 chunk, which amounts to 1/8 memory overhead per batch when
- // thread local quarantine is set to 64Kb.
- (ASAN_LOW_MEMORY) ? 1 << 6 : FIRST_32_SECOND_64(1 << 8, 1 << 10);
- f->thread_local_quarantine_size_kb = kDefaultThreadLocalQuarantineSizeKb;
- }
- if (f->thread_local_quarantine_size_kb == 0 && f->quarantine_size_mb > 0) {
- Report("%s: thread_local_quarantine_size_kb can be set to 0 only when "
- "quarantine_size_mb is set to 0\n", SanitizerToolName);
- Die();
- }
- if (!f->replace_str && common_flags()->intercept_strlen) {
- Report("WARNING: strlen interceptor is enabled even though replace_str=0. "
- "Use intercept_strlen=0 to disable it.");
- }
- if (!f->replace_str && common_flags()->intercept_strchr) {
- Report("WARNING: strchr* interceptors are enabled even though "
- "replace_str=0. Use intercept_strchr=0 to disable them.");
- }
- if (!f->replace_str && common_flags()->intercept_strndup) {
- Report("WARNING: strndup* interceptors are enabled even though "
- "replace_str=0. Use intercept_strndup=0 to disable them.");
- }
-}
-
-} // namespace __asan
-
-SANITIZER_INTERFACE_WEAK_DEF(const char*, __asan_default_options, void) {
- return "";
-}
diff --git a/lib/asan/asan_flags.h b/lib/asan/asan_flags.h
deleted file mode 100644
index 4935161c30f1e..0000000000000
--- a/lib/asan/asan_flags.h
+++ /dev/null
@@ -1,49 +0,0 @@
-//===-- asan_flags.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.
-//
-// ASan runtime flags.
-//===----------------------------------------------------------------------===//
-
-#ifndef ASAN_FLAGS_H
-#define ASAN_FLAGS_H
-
-#include "sanitizer_common/sanitizer_internal_defs.h"
-#include "sanitizer_common/sanitizer_flag_parser.h"
-
-// ASan flag values can be defined in four ways:
-// 1) initialized with default values at startup.
-// 2) overriden during compilation of ASan runtime by providing
-// compile definition ASAN_DEFAULT_OPTIONS.
-// 3) overriden from string returned by user-specified function
-// __asan_default_options().
-// 4) overriden from env variable ASAN_OPTIONS.
-// 5) overriden during ASan activation (for now used on Android only).
-
-namespace __asan {
-
-struct Flags {
-#define ASAN_FLAG(Type, Name, DefaultValue, Description) Type Name;
-#include "asan_flags.inc"
-#undef ASAN_FLAG
-
- void SetDefaults();
-};
-
-extern Flags asan_flags_dont_use_directly;
-inline Flags *flags() {
- return &asan_flags_dont_use_directly;
-}
-
-void InitializeFlags();
-
-} // namespace __asan
-
-#endif // ASAN_FLAGS_H
diff --git a/lib/asan/asan_flags.inc b/lib/asan/asan_flags.inc
deleted file mode 100644
index 4af94c56fca0b..0000000000000
--- a/lib/asan/asan_flags.inc
+++ /dev/null
@@ -1,163 +0,0 @@
-//===-- asan_flags.inc ------------------------------------------*- C++ -*-===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// ASan runtime flags.
-//
-//===----------------------------------------------------------------------===//
-#ifndef ASAN_FLAG
-# error "Define ASAN_FLAG prior to including this file!"
-#endif
-
-// ASAN_FLAG(Type, Name, DefaultValue, Description)
-// See COMMON_FLAG in sanitizer_flags.inc for more details.
-
-ASAN_FLAG(int, quarantine_size, -1,
- "Deprecated, please use quarantine_size_mb.")
-ASAN_FLAG(int, quarantine_size_mb, -1,
- "Size (in Mb) of quarantine used to detect use-after-free "
- "errors. Lower value may reduce memory usage but increase the "
- "chance of false negatives.")
-ASAN_FLAG(int, thread_local_quarantine_size_kb, -1,
- "Size (in Kb) of thread local quarantine used to detect "
- "use-after-free errors. Lower value may reduce memory usage but "
- "increase the chance of false negatives. It is not advised to go "
- "lower than 64Kb, otherwise frequent transfers to global quarantine "
- "might affect performance.")
-ASAN_FLAG(int, redzone, 16,
- "Minimal size (in bytes) of redzones around heap objects. "
- "Requirement: redzone >= 16, is a power of two.")
-ASAN_FLAG(int, max_redzone, 2048,
- "Maximal size (in bytes) of redzones around heap objects.")
-ASAN_FLAG(
- bool, debug, false,
- "If set, prints some debugging information and does additional checks.")
-ASAN_FLAG(
- int, report_globals, 1,
- "Controls the way to handle globals (0 - don't detect buffer overflow on "
- "globals, 1 - detect buffer overflow, 2 - print data about registered "
- "globals).")
-ASAN_FLAG(bool, check_initialization_order, false,
- "If set, attempts to catch initialization order issues.")
-ASAN_FLAG(
- bool, replace_str, true,
- "If set, uses custom wrappers and replacements for libc string functions "
- "to find more errors.")
-ASAN_FLAG(bool, replace_intrin, true,
- "If set, uses custom wrappers for memset/memcpy/memmove intrinsics.")
-ASAN_FLAG(bool, detect_stack_use_after_return, false,
- "Enables stack-use-after-return checking at run-time.")
-ASAN_FLAG(int, min_uar_stack_size_log, 16, // We can't do smaller anyway.
- "Minimum fake stack size log.")
-ASAN_FLAG(int, max_uar_stack_size_log,
- 20, // 1Mb per size class, i.e. ~11Mb per thread
- "Maximum fake stack size log.")
-ASAN_FLAG(bool, uar_noreserve, false,
- "Use mmap with 'noreserve' flag to allocate fake stack.")
-ASAN_FLAG(
- int, max_malloc_fill_size, 0x1000, // By default, fill only the first 4K.
- "ASan allocator flag. max_malloc_fill_size is the maximal amount of "
- "bytes that will be filled with malloc_fill_byte on malloc.")
-ASAN_FLAG(
- int, max_free_fill_size, 0,
- "ASan allocator flag. max_free_fill_size is the maximal amount of "
- "bytes that will be filled with free_fill_byte during free.")
-ASAN_FLAG(int, malloc_fill_byte, 0xbe,
- "Value used to fill the newly allocated memory.")
-ASAN_FLAG(int, free_fill_byte, 0x55,
- "Value used to fill deallocated memory.")
-ASAN_FLAG(bool, allow_user_poisoning, true,
- "If set, user may manually mark memory regions as poisoned or "
- "unpoisoned.")
-ASAN_FLAG(
- int, sleep_before_dying, 0,
- "Number of seconds to sleep between printing an error report and "
- "terminating the program. Useful for debugging purposes (e.g. when one "
- "needs to attach gdb).")
-ASAN_FLAG(
- int, sleep_after_init, 0,
- "Number of seconds to sleep after AddressSanitizer is initialized. "
- "Useful for debugging purposes (e.g. when one needs to attach gdb).")
-ASAN_FLAG(bool, check_malloc_usable_size, true,
- "Allows the users to work around the bug in Nvidia drivers prior to "
- "295.*.")
-ASAN_FLAG(bool, unmap_shadow_on_exit, false,
- "If set, explicitly unmaps the (huge) shadow at exit.")
-ASAN_FLAG(bool, protect_shadow_gap, !SANITIZER_RTEMS,
- "If set, mprotect the shadow gap")
-ASAN_FLAG(bool, print_stats, false,
- "Print various statistics after printing an error message or if "
- "atexit=1.")
-ASAN_FLAG(bool, print_legend, true, "Print the legend for the shadow bytes.")
-ASAN_FLAG(bool, print_scariness, false,
- "Print the scariness score. Experimental.")
-ASAN_FLAG(bool, atexit, false,
- "If set, prints ASan exit stats even after program terminates "
- "successfully.")
-ASAN_FLAG(
- bool, print_full_thread_history, true,
- "If set, prints thread creation stacks for the threads involved in the "
- "report and their ancestors up to the main thread.")
-ASAN_FLAG(
- bool, poison_heap, true,
- "Poison (or not) the heap memory on [de]allocation. Zero value is useful "
- "for benchmarking the allocator or instrumentator.")
-ASAN_FLAG(bool, poison_partial, true,
- "If true, poison partially addressable 8-byte aligned words "
- "(default=true). This flag affects heap and global buffers, but not "
- "stack buffers.")
-ASAN_FLAG(bool, poison_array_cookie, true,
- "Poison (or not) the array cookie after operator new[].")
-
-// Turn off alloc/dealloc mismatch checker on Mac and Windows for now.
-// https://github.com/google/sanitizers/issues/131
-// https://github.com/google/sanitizers/issues/309
-// TODO(glider,timurrrr): Fix known issues and enable this back.
-ASAN_FLAG(bool, alloc_dealloc_mismatch,
- !SANITIZER_MAC && !SANITIZER_WINDOWS && !SANITIZER_ANDROID,
- "Report errors on malloc/delete, new/free, new/delete[], etc.")
-
-ASAN_FLAG(bool, new_delete_type_mismatch, true,
- "Report errors on mismatch between size of new and delete.")
-ASAN_FLAG(
- bool, strict_init_order, false,
- "If true, assume that dynamic initializers can never access globals from "
- "other modules, even if the latter are already initialized.")
-ASAN_FLAG(
- bool, start_deactivated, false,
- "If true, ASan tweaks a bunch of other flags (quarantine, redzone, heap "
- "poisoning) to reduce memory consumption as much as possible, and "
- "restores them to original values when the first instrumented module is "
- "loaded into the process. This is mainly intended to be used on "
- "Android. ")
-ASAN_FLAG(
- int, detect_invalid_pointer_pairs, 0,
- "If >= 2, detect operations like <, <=, >, >= and - on invalid pointer "
- "pairs (e.g. when pointers belong to different objects); "
- "If == 1, detect invalid operations only when both pointers are non-null.")
-ASAN_FLAG(
- bool, detect_container_overflow, true,
- "If true, honor the container overflow annotations. See "
- "https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow")
-ASAN_FLAG(int, detect_odr_violation, 2,
- "If >=2, detect violation of One-Definition-Rule (ODR); "
- "If ==1, detect ODR-violation only if the two variables "
- "have different sizes")
-ASAN_FLAG(const char *, suppressions, "", "Suppressions file name.")
-ASAN_FLAG(bool, halt_on_error, true,
- "Crash the program after printing the first error report "
- "(WARNING: USE AT YOUR OWN RISK!)")
-ASAN_FLAG(bool, use_odr_indicator, false,
- "Use special ODR indicator symbol for ODR violation detection")
-ASAN_FLAG(bool, allocator_frees_and_returns_null_on_realloc_zero, true,
- "realloc(p, 0) is equivalent to free(p) by default (Same as the "
- "POSIX standard). If set to false, realloc(p, 0) will return a "
- "pointer to an allocated space which can not be used.")
-ASAN_FLAG(bool, verify_asan_link_order, true,
- "Check position of ASan runtime in library list (needs to be disabled"
- " when other library has to be preloaded system-wide)")
diff --git a/lib/asan/asan_fuchsia.cc b/lib/asan/asan_fuchsia.cc
deleted file mode 100644
index 0b5bff4f565ec..0000000000000
--- a/lib/asan/asan_fuchsia.cc
+++ /dev/null
@@ -1,218 +0,0 @@
-//===-- asan_fuchsia.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.
-//
-// Fuchsia-specific details.
-//===---------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_fuchsia.h"
-#if SANITIZER_FUCHSIA
-
-#include "asan_interceptors.h"
-#include "asan_internal.h"
-#include "asan_stack.h"
-#include "asan_thread.h"
-
-#include <limits.h>
-#include <zircon/sanitizer.h>
-#include <zircon/syscalls.h>
-#include <zircon/threads.h>
-
-namespace __asan {
-
-// The system already set up the shadow memory for us.
-// __sanitizer::GetMaxUserVirtualAddress has already been called by
-// AsanInitInternal->InitializeHighMemEnd (asan_rtl.cc).
-// Just do some additional sanity checks here.
-void InitializeShadowMemory() {
- if (Verbosity()) PrintAddressSpaceLayout();
-
- // Make sure SHADOW_OFFSET doesn't use __asan_shadow_memory_dynamic_address.
- __asan_shadow_memory_dynamic_address = kDefaultShadowSentinel;
- DCHECK(kLowShadowBeg != kDefaultShadowSentinel);
- __asan_shadow_memory_dynamic_address = kLowShadowBeg;
-
- CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 1);
- CHECK_EQ(kHighMemEnd, __sanitizer::ShadowBounds.memory_limit - 1);
- CHECK_EQ(kHighMemBeg, __sanitizer::ShadowBounds.shadow_limit);
- CHECK_EQ(kHighShadowBeg, __sanitizer::ShadowBounds.shadow_base);
- CHECK_EQ(kShadowGapEnd, __sanitizer::ShadowBounds.shadow_base - 1);
- CHECK_EQ(kLowShadowEnd, 0);
- CHECK_EQ(kLowShadowBeg, 0);
-}
-
-void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {
- UNIMPLEMENTED();
-}
-
-void AsanCheckDynamicRTPrereqs() {}
-void AsanCheckIncompatibleRT() {}
-void InitializeAsanInterceptors() {}
-
-void *AsanDoesNotSupportStaticLinkage() { return nullptr; }
-
-void InitializePlatformExceptionHandlers() {}
-void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
- UNIMPLEMENTED();
-}
-
-// We can use a plain thread_local variable for TSD.
-static thread_local void *per_thread;
-
-void *AsanTSDGet() { return per_thread; }
-
-void AsanTSDSet(void *tsd) { per_thread = tsd; }
-
-// There's no initialization needed, and the passed-in destructor
-// will never be called. Instead, our own thread destruction hook
-// (below) will call AsanThread::TSDDtor directly.
-void AsanTSDInit(void (*destructor)(void *tsd)) {
- DCHECK(destructor == &PlatformTSDDtor);
-}
-
-void PlatformTSDDtor(void *tsd) { UNREACHABLE(__func__); }
-
-static inline size_t AsanThreadMmapSize() {
- return RoundUpTo(sizeof(AsanThread), PAGE_SIZE);
-}
-
-struct AsanThread::InitOptions {
- uptr stack_bottom, stack_size;
-};
-
-// Shared setup between thread creation and startup for the initial thread.
-static AsanThread *CreateAsanThread(StackTrace *stack, u32 parent_tid,
- uptr user_id, bool detached,
- const char *name, uptr stack_bottom,
- uptr stack_size) {
- // In lieu of AsanThread::Create.
- AsanThread *thread = (AsanThread *)MmapOrDie(AsanThreadMmapSize(), __func__);
-
- AsanThreadContext::CreateThreadContextArgs args = {thread, stack};
- u32 tid =
- asanThreadRegistry().CreateThread(user_id, detached, parent_tid, &args);
- asanThreadRegistry().SetThreadName(tid, name);
-
- // On other systems, AsanThread::Init() is called from the new
- // thread itself. But on Fuchsia we already know the stack address
- // range beforehand, so we can do most of the setup right now.
- const AsanThread::InitOptions options = {stack_bottom, stack_size};
- thread->Init(&options);
-
- return thread;
-}
-
-// This gets the same arguments passed to Init by CreateAsanThread, above.
-// We're in the creator thread before the new thread is actually started,
-// but its stack address range is already known. We don't bother tracking
-// the static TLS address range because the system itself already uses an
-// ASan-aware allocator for that.
-void AsanThread::SetThreadStackAndTls(const AsanThread::InitOptions *options) {
- DCHECK_NE(GetCurrentThread(), this);
- DCHECK_NE(GetCurrentThread(), nullptr);
- CHECK_NE(options->stack_bottom, 0);
- CHECK_NE(options->stack_size, 0);
- stack_bottom_ = options->stack_bottom;
- stack_top_ = options->stack_bottom + options->stack_size;
-}
-
-// Called by __asan::AsanInitInternal (asan_rtl.c).
-AsanThread *CreateMainThread() {
- thrd_t self = thrd_current();
- char name[ZX_MAX_NAME_LEN];
- CHECK_NE(__sanitizer::MainThreadStackBase, 0);
- CHECK_GT(__sanitizer::MainThreadStackSize, 0);
- AsanThread *t = CreateAsanThread(
- nullptr, 0, reinterpret_cast<uptr>(self), true,
- _zx_object_get_property(thrd_get_zx_handle(self), ZX_PROP_NAME, name,
- sizeof(name)) == ZX_OK
- ? name
- : nullptr,
- __sanitizer::MainThreadStackBase, __sanitizer::MainThreadStackSize);
- SetCurrentThread(t);
- return t;
-}
-
-// This is called before each thread creation is attempted. So, in
-// its first call, the calling thread is the initial and sole thread.
-static void *BeforeThreadCreateHook(uptr user_id, bool detached,
- const char *name, uptr stack_bottom,
- uptr stack_size) {
- EnsureMainThreadIDIsCorrect();
- // Strict init-order checking is thread-hostile.
- if (flags()->strict_init_order) StopInitOrderChecking();
-
- GET_STACK_TRACE_THREAD;
- u32 parent_tid = GetCurrentTidOrInvalid();
-
- return CreateAsanThread(&stack, parent_tid, user_id, detached, name,
- stack_bottom, stack_size);
-}
-
-// This is called after creating a new thread (in the creating thread),
-// with the pointer returned by BeforeThreadCreateHook (above).
-static void ThreadCreateHook(void *hook, bool aborted) {
- AsanThread *thread = static_cast<AsanThread *>(hook);
- if (!aborted) {
- // The thread was created successfully.
- // ThreadStartHook is already running in the new thread.
- } else {
- // The thread wasn't created after all.
- // Clean up everything we set up in BeforeThreadCreateHook.
- asanThreadRegistry().FinishThread(thread->tid());
- UnmapOrDie(thread, AsanThreadMmapSize());
- }
-}
-
-// This is called in the newly-created thread before it runs anything else,
-// with the pointer returned by BeforeThreadCreateHook (above).
-// cf. asan_interceptors.cc:asan_thread_start
-static void ThreadStartHook(void *hook, uptr os_id) {
- AsanThread *thread = static_cast<AsanThread *>(hook);
- SetCurrentThread(thread);
-
- // In lieu of AsanThread::ThreadStart.
- asanThreadRegistry().StartThread(thread->tid(), os_id, /*workerthread*/ false,
- nullptr);
-}
-
-// Each thread runs this just before it exits,
-// with the pointer returned by BeforeThreadCreateHook (above).
-// All per-thread destructors have already been called.
-static void ThreadExitHook(void *hook, uptr os_id) {
- AsanThread::TSDDtor(per_thread);
-}
-
-} // namespace __asan
-
-// These are declared (in extern "C") by <zircon/sanitizer.h>.
-// The system runtime will call our definitions directly.
-
-void *__sanitizer_before_thread_create_hook(thrd_t thread, bool detached,
- const char *name, void *stack_base,
- size_t stack_size) {
- return __asan::BeforeThreadCreateHook(
- reinterpret_cast<uptr>(thread), detached, name,
- reinterpret_cast<uptr>(stack_base), stack_size);
-}
-
-void __sanitizer_thread_create_hook(void *hook, thrd_t thread, int error) {
- __asan::ThreadCreateHook(hook, error != thrd_success);
-}
-
-void __sanitizer_thread_start_hook(void *hook, thrd_t self) {
- __asan::ThreadStartHook(hook, reinterpret_cast<uptr>(self));
-}
-
-void __sanitizer_thread_exit_hook(void *hook, thrd_t self) {
- __asan::ThreadExitHook(hook, reinterpret_cast<uptr>(self));
-}
-
-#endif // SANITIZER_FUCHSIA
diff --git a/lib/asan/asan_globals.cc b/lib/asan/asan_globals.cc
deleted file mode 100644
index 898f7f40d31bd..0000000000000
--- a/lib/asan/asan_globals.cc
+++ /dev/null
@@ -1,462 +0,0 @@
-//===-- asan_globals.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.
-//
-// Handle globals.
-//===----------------------------------------------------------------------===//
-
-#include "asan_interceptors.h"
-#include "asan_internal.h"
-#include "asan_mapping.h"
-#include "asan_poisoning.h"
-#include "asan_report.h"
-#include "asan_stack.h"
-#include "asan_stats.h"
-#include "asan_suppressions.h"
-#include "asan_thread.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_mutex.h"
-#include "sanitizer_common/sanitizer_placement_new.h"
-#include "sanitizer_common/sanitizer_stackdepot.h"
-#include "sanitizer_common/sanitizer_symbolizer.h"
-
-namespace __asan {
-
-typedef __asan_global Global;
-
-struct ListOfGlobals {
- const Global *g;
- ListOfGlobals *next;
-};
-
-static BlockingMutex mu_for_globals(LINKER_INITIALIZED);
-static LowLevelAllocator allocator_for_globals;
-static ListOfGlobals *list_of_all_globals;
-
-static const int kDynamicInitGlobalsInitialCapacity = 512;
-struct DynInitGlobal {
- Global g;
- bool initialized;
-};
-typedef InternalMmapVector<DynInitGlobal> VectorOfGlobals;
-// Lazy-initialized and never deleted.
-static VectorOfGlobals *dynamic_init_globals;
-
-// We want to remember where a certain range of globals was registered.
-struct GlobalRegistrationSite {
- u32 stack_id;
- Global *g_first, *g_last;
-};
-typedef InternalMmapVector<GlobalRegistrationSite> GlobalRegistrationSiteVector;
-static GlobalRegistrationSiteVector *global_registration_site_vector;
-
-ALWAYS_INLINE void PoisonShadowForGlobal(const Global *g, u8 value) {
- FastPoisonShadow(g->beg, g->size_with_redzone, value);
-}
-
-ALWAYS_INLINE void PoisonRedZones(const Global &g) {
- uptr aligned_size = RoundUpTo(g.size, SHADOW_GRANULARITY);
- FastPoisonShadow(g.beg + aligned_size, g.size_with_redzone - aligned_size,
- kAsanGlobalRedzoneMagic);
- if (g.size != aligned_size) {
- FastPoisonShadowPartialRightRedzone(
- g.beg + RoundDownTo(g.size, SHADOW_GRANULARITY),
- g.size % SHADOW_GRANULARITY,
- SHADOW_GRANULARITY,
- kAsanGlobalRedzoneMagic);
- }
-}
-
-const uptr kMinimalDistanceFromAnotherGlobal = 64;
-
-static bool IsAddressNearGlobal(uptr addr, const __asan_global &g) {
- if (addr <= g.beg - kMinimalDistanceFromAnotherGlobal) return false;
- if (addr >= g.beg + g.size_with_redzone) return false;
- return true;
-}
-
-static void ReportGlobal(const Global &g, const char *prefix) {
- Report("%s Global[%p]: beg=%p size=%zu/%zu name=%s module=%s dyn_init=%zu\n",
- prefix, &g, (void *)g.beg, g.size, g.size_with_redzone, g.name,
- g.module_name, g.has_dynamic_init);
- if (g.location) {
- Report(" location (%p): name=%s[%p], %d %d\n", g.location,
- g.location->filename, g.location->filename, g.location->line_no,
- g.location->column_no);
- }
-}
-
-static u32 FindRegistrationSite(const Global *g) {
- mu_for_globals.CheckLocked();
- CHECK(global_registration_site_vector);
- for (uptr i = 0, n = global_registration_site_vector->size(); i < n; i++) {
- GlobalRegistrationSite &grs = (*global_registration_site_vector)[i];
- if (g >= grs.g_first && g <= grs.g_last)
- return grs.stack_id;
- }
- return 0;
-}
-
-int GetGlobalsForAddress(uptr addr, Global *globals, u32 *reg_sites,
- int max_globals) {
- if (!flags()->report_globals) return 0;
- BlockingMutexLock lock(&mu_for_globals);
- int res = 0;
- for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
- const Global &g = *l->g;
- if (flags()->report_globals >= 2)
- ReportGlobal(g, "Search");
- if (IsAddressNearGlobal(addr, g)) {
- globals[res] = g;
- if (reg_sites)
- reg_sites[res] = FindRegistrationSite(&g);
- res++;
- if (res == max_globals) break;
- }
- }
- return res;
-}
-
-enum GlobalSymbolState {
- UNREGISTERED = 0,
- REGISTERED = 1
-};
-
-// Check ODR violation for given global G via special ODR indicator. We use
-// this method in case compiler instruments global variables through their
-// local aliases.
-static void CheckODRViolationViaIndicator(const Global *g) {
- u8 *odr_indicator = reinterpret_cast<u8 *>(g->odr_indicator);
- if (*odr_indicator == UNREGISTERED) {
- *odr_indicator = REGISTERED;
- return;
- }
- // If *odr_indicator is DEFINED, some module have already registered
- // externally visible symbol with the same name. This is an ODR violation.
- for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
- if (g->odr_indicator == l->g->odr_indicator &&
- (flags()->detect_odr_violation >= 2 || g->size != l->g->size) &&
- !IsODRViolationSuppressed(g->name))
- ReportODRViolation(g, FindRegistrationSite(g),
- l->g, FindRegistrationSite(l->g));
- }
-}
-
-// Check ODR violation for given global G by checking if it's already poisoned.
-// We use this method in case compiler doesn't use private aliases for global
-// variables.
-static void CheckODRViolationViaPoisoning(const Global *g) {
- if (__asan_region_is_poisoned(g->beg, g->size_with_redzone)) {
- // This check may not be enough: if the first global is much larger
- // the entire redzone of the second global may be within the first global.
- for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) {
- if (g->beg == l->g->beg &&
- (flags()->detect_odr_violation >= 2 || g->size != l->g->size) &&
- !IsODRViolationSuppressed(g->name))
- ReportODRViolation(g, FindRegistrationSite(g),
- l->g, FindRegistrationSite(l->g));
- }
- }
-}
-
-// Clang provides two different ways for global variables protection:
-// it can poison the global itself or its private alias. In former
-// case we may poison same symbol multiple times, that can help us to
-// cheaply detect ODR violation: if we try to poison an already poisoned
-// global, we have ODR violation error.
-// In latter case, we poison each symbol exactly once, so we use special
-// indicator symbol to perform similar check.
-// In either case, compiler provides a special odr_indicator field to Global
-// structure, that can contain two kinds of values:
-// 1) Non-zero value. In this case, odr_indicator is an address of
-// corresponding indicator variable for given global.
-// 2) Zero. This means that we don't use private aliases for global variables
-// and can freely check ODR violation with the first method.
-//
-// This routine chooses between two different methods of ODR violation
-// detection.
-static inline bool UseODRIndicator(const Global *g) {
- // Use ODR indicator method iff use_odr_indicator flag is set and
- // indicator symbol address is not 0.
- return flags()->use_odr_indicator && g->odr_indicator > 0;
-}
-
-// Register a global variable.
-// This function may be called more than once for every global
-// so we store the globals in a map.
-static void RegisterGlobal(const Global *g) {
- CHECK(asan_inited);
- if (flags()->report_globals >= 2)
- ReportGlobal(*g, "Added");
- CHECK(flags()->report_globals);
- CHECK(AddrIsInMem(g->beg));
- if (!AddrIsAlignedByGranularity(g->beg)) {
- Report("The following global variable is not properly aligned.\n");
- Report("This may happen if another global with the same name\n");
- Report("resides in another non-instrumented module.\n");
- Report("Or the global comes from a C file built w/o -fno-common.\n");
- Report("In either case this is likely an ODR violation bug,\n");
- Report("but AddressSanitizer can not provide more details.\n");
- ReportODRViolation(g, FindRegistrationSite(g), g, FindRegistrationSite(g));
- CHECK(AddrIsAlignedByGranularity(g->beg));
- }
- CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));
- if (flags()->detect_odr_violation) {
- // Try detecting ODR (One Definition Rule) violation, i.e. the situation
- // where two globals with the same name are defined in different modules.
- if (UseODRIndicator(g))
- CheckODRViolationViaIndicator(g);
- else
- CheckODRViolationViaPoisoning(g);
- }
- if (CanPoisonMemory())
- PoisonRedZones(*g);
- ListOfGlobals *l = new(allocator_for_globals) ListOfGlobals;
- l->g = g;
- l->next = list_of_all_globals;
- list_of_all_globals = l;
- if (g->has_dynamic_init) {
- if (!dynamic_init_globals) {
- dynamic_init_globals =
- new (allocator_for_globals) VectorOfGlobals; // NOLINT
- dynamic_init_globals->reserve(kDynamicInitGlobalsInitialCapacity);
- }
- DynInitGlobal dyn_global = { *g, false };
- dynamic_init_globals->push_back(dyn_global);
- }
-}
-
-static void UnregisterGlobal(const Global *g) {
- CHECK(asan_inited);
- if (flags()->report_globals >= 2)
- ReportGlobal(*g, "Removed");
- CHECK(flags()->report_globals);
- CHECK(AddrIsInMem(g->beg));
- CHECK(AddrIsAlignedByGranularity(g->beg));
- CHECK(AddrIsAlignedByGranularity(g->size_with_redzone));
- if (CanPoisonMemory())
- PoisonShadowForGlobal(g, 0);
- // We unpoison the shadow memory for the global but we do not remove it from
- // the list because that would require O(n^2) time with the current list
- // implementation. It might not be worth doing anyway.
-
- // Release ODR indicator.
- if (UseODRIndicator(g)) {
- u8 *odr_indicator = reinterpret_cast<u8 *>(g->odr_indicator);
- *odr_indicator = UNREGISTERED;
- }
-}
-
-void StopInitOrderChecking() {
- BlockingMutexLock lock(&mu_for_globals);
- if (!flags()->check_initialization_order || !dynamic_init_globals)
- return;
- flags()->check_initialization_order = false;
- for (uptr i = 0, n = dynamic_init_globals->size(); i < n; ++i) {
- DynInitGlobal &dyn_g = (*dynamic_init_globals)[i];
- const Global *g = &dyn_g.g;
- // Unpoison the whole global.
- PoisonShadowForGlobal(g, 0);
- // Poison redzones back.
- PoisonRedZones(*g);
- }
-}
-
-static bool IsASCII(unsigned char c) { return /*0x00 <= c &&*/ c <= 0x7F; }
-
-const char *MaybeDemangleGlobalName(const char *name) {
- // We can spoil names of globals with C linkage, so use an heuristic
- // approach to check if the name should be demangled.
- bool should_demangle = false;
- if (name[0] == '_' && name[1] == 'Z')
- should_demangle = true;
- else if (SANITIZER_WINDOWS && name[0] == '\01' && name[1] == '?')
- should_demangle = true;
-
- return should_demangle ? Symbolizer::GetOrInit()->Demangle(name) : name;
-}
-
-// Check if the global is a zero-terminated ASCII string. If so, print it.
-void PrintGlobalNameIfASCII(InternalScopedString *str, const __asan_global &g) {
- for (uptr p = g.beg; p < g.beg + g.size - 1; p++) {
- unsigned char c = *(unsigned char *)p;
- if (c == '\0' || !IsASCII(c)) return;
- }
- if (*(char *)(g.beg + g.size - 1) != '\0') return;
- str->append(" '%s' is ascii string '%s'\n", MaybeDemangleGlobalName(g.name),
- (char *)g.beg);
-}
-
-static const char *GlobalFilename(const __asan_global &g) {
- const char *res = g.module_name;
- // Prefer the filename from source location, if is available.
- if (g.location) res = g.location->filename;
- CHECK(res);
- return res;
-}
-
-void PrintGlobalLocation(InternalScopedString *str, const __asan_global &g) {
- str->append("%s", GlobalFilename(g));
- if (!g.location) return;
- if (g.location->line_no) str->append(":%d", g.location->line_no);
- if (g.location->column_no) str->append(":%d", g.location->column_no);
-}
-
-} // namespace __asan
-
-// ---------------------- Interface ---------------- {{{1
-using namespace __asan; // NOLINT
-
-
-// Apply __asan_register_globals to all globals found in the same loaded
-// executable or shared library as `flag'. The flag tracks whether globals have
-// already been registered or not for this image.
-void __asan_register_image_globals(uptr *flag) {
- if (*flag)
- return;
- AsanApplyToGlobals(__asan_register_globals, flag);
- *flag = 1;
-}
-
-// This mirrors __asan_register_image_globals.
-void __asan_unregister_image_globals(uptr *flag) {
- if (!*flag)
- return;
- AsanApplyToGlobals(__asan_unregister_globals, flag);
- *flag = 0;
-}
-
-void __asan_register_elf_globals(uptr *flag, void *start, void *stop) {
- if (*flag) return;
- if (!start) return;
- CHECK_EQ(0, ((uptr)stop - (uptr)start) % sizeof(__asan_global));
- __asan_global *globals_start = (__asan_global*)start;
- __asan_global *globals_stop = (__asan_global*)stop;
- __asan_register_globals(globals_start, globals_stop - globals_start);
- *flag = 1;
-}
-
-void __asan_unregister_elf_globals(uptr *flag, void *start, void *stop) {
- if (!*flag) return;
- if (!start) return;
- CHECK_EQ(0, ((uptr)stop - (uptr)start) % sizeof(__asan_global));
- __asan_global *globals_start = (__asan_global*)start;
- __asan_global *globals_stop = (__asan_global*)stop;
- __asan_unregister_globals(globals_start, globals_stop - globals_start);
- *flag = 0;
-}
-
-// Register an array of globals.
-void __asan_register_globals(__asan_global *globals, uptr n) {
- if (!flags()->report_globals) return;
- GET_STACK_TRACE_MALLOC;
- u32 stack_id = StackDepotPut(stack);
- BlockingMutexLock lock(&mu_for_globals);
- if (!global_registration_site_vector) {
- global_registration_site_vector =
- new (allocator_for_globals) GlobalRegistrationSiteVector; // NOLINT
- global_registration_site_vector->reserve(128);
- }
- GlobalRegistrationSite site = {stack_id, &globals[0], &globals[n - 1]};
- global_registration_site_vector->push_back(site);
- if (flags()->report_globals >= 2) {
- PRINT_CURRENT_STACK();
- Printf("=== ID %d; %p %p\n", stack_id, &globals[0], &globals[n - 1]);
- }
- for (uptr i = 0; i < n; i++) {
- if (SANITIZER_WINDOWS && globals[i].beg == 0) {
- // The MSVC incremental linker may pad globals out to 256 bytes. As long
- // as __asan_global is less than 256 bytes large and its size is a power
- // of two, we can skip over the padding.
- static_assert(
- sizeof(__asan_global) < 256 &&
- (sizeof(__asan_global) & (sizeof(__asan_global) - 1)) == 0,
- "sizeof(__asan_global) incompatible with incremental linker padding");
- // If these are padding bytes, the rest of the global should be zero.
- CHECK(globals[i].size == 0 && globals[i].size_with_redzone == 0 &&
- globals[i].name == nullptr && globals[i].module_name == nullptr &&
- globals[i].odr_indicator == 0);
- continue;
- }
- RegisterGlobal(&globals[i]);
- }
-
- // Poison the metadata. It should not be accessible to user code.
- PoisonShadow(reinterpret_cast<uptr>(globals), n * sizeof(__asan_global),
- kAsanGlobalRedzoneMagic);
-}
-
-// Unregister an array of globals.
-// We must do this when a shared objects gets dlclosed.
-void __asan_unregister_globals(__asan_global *globals, uptr n) {
- if (!flags()->report_globals) return;
- BlockingMutexLock lock(&mu_for_globals);
- for (uptr i = 0; i < n; i++) {
- if (SANITIZER_WINDOWS && globals[i].beg == 0) {
- // Skip globals that look like padding from the MSVC incremental linker.
- // See comment in __asan_register_globals.
- continue;
- }
- UnregisterGlobal(&globals[i]);
- }
-
- // Unpoison the metadata.
- PoisonShadow(reinterpret_cast<uptr>(globals), n * sizeof(__asan_global), 0);
-}
-
-// This method runs immediately prior to dynamic initialization in each TU,
-// when all dynamically initialized globals are unpoisoned. This method
-// poisons all global variables not defined in this TU, so that a dynamic
-// initializer can only touch global variables in the same TU.
-void __asan_before_dynamic_init(const char *module_name) {
- if (!flags()->check_initialization_order ||
- !CanPoisonMemory() ||
- !dynamic_init_globals)
- return;
- bool strict_init_order = flags()->strict_init_order;
- CHECK(module_name);
- CHECK(asan_inited);
- BlockingMutexLock lock(&mu_for_globals);
- if (flags()->report_globals >= 3)
- Printf("DynInitPoison module: %s\n", module_name);
- for (uptr i = 0, n = dynamic_init_globals->size(); i < n; ++i) {
- DynInitGlobal &dyn_g = (*dynamic_init_globals)[i];
- const Global *g = &dyn_g.g;
- if (dyn_g.initialized)
- continue;
- if (g->module_name != module_name)
- PoisonShadowForGlobal(g, kAsanInitializationOrderMagic);
- else if (!strict_init_order)
- dyn_g.initialized = true;
- }
-}
-
-// This method runs immediately after dynamic initialization in each TU, when
-// all dynamically initialized globals except for those defined in the current
-// TU are poisoned. It simply unpoisons all dynamically initialized globals.
-void __asan_after_dynamic_init() {
- if (!flags()->check_initialization_order ||
- !CanPoisonMemory() ||
- !dynamic_init_globals)
- return;
- CHECK(asan_inited);
- BlockingMutexLock lock(&mu_for_globals);
- // FIXME: Optionally report that we're unpoisoning globals from a module.
- for (uptr i = 0, n = dynamic_init_globals->size(); i < n; ++i) {
- DynInitGlobal &dyn_g = (*dynamic_init_globals)[i];
- const Global *g = &dyn_g.g;
- if (!dyn_g.initialized) {
- // Unpoison the whole global.
- PoisonShadowForGlobal(g, 0);
- // Poison redzones back.
- PoisonRedZones(*g);
- }
- }
-}
diff --git a/lib/asan/asan_globals_win.cc b/lib/asan/asan_globals_win.cc
deleted file mode 100644
index 29ab5ebf16d4c..0000000000000
--- a/lib/asan/asan_globals_win.cc
+++ /dev/null
@@ -1,62 +0,0 @@
-//===-- asan_globals_win.cc -----------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-//
-// Global registration code that is linked into every Windows DLL and EXE.
-//
-//===----------------------------------------------------------------------===//
-
-#include "asan_interface_internal.h"
-#if SANITIZER_WINDOWS
-
-namespace __asan {
-
-#pragma section(".ASAN$GA", read, write) // NOLINT
-#pragma section(".ASAN$GZ", read, write) // NOLINT
-extern "C" __declspec(allocate(".ASAN$GA"))
- ALIGNED(sizeof(__asan_global)) __asan_global __asan_globals_start = {};
-extern "C" __declspec(allocate(".ASAN$GZ"))
- ALIGNED(sizeof(__asan_global)) __asan_global __asan_globals_end = {};
-#pragma comment(linker, "/merge:.ASAN=.data")
-
-static void call_on_globals(void (*hook)(__asan_global *, uptr)) {
- __asan_global *start = &__asan_globals_start + 1;
- __asan_global *end = &__asan_globals_end;
- uptr bytediff = (uptr)end - (uptr)start;
- if (bytediff % sizeof(__asan_global) != 0) {
-#ifdef SANITIZER_DLL_THUNK
- __debugbreak();
-#else
- CHECK("corrupt asan global array");
-#endif
- }
- // We know end >= start because the linker sorts the portion after the dollar
- // sign alphabetically.
- uptr n = end - start;
- hook(start, n);
-}
-
-static void register_dso_globals() {
- call_on_globals(&__asan_register_globals);
-}
-
-static void unregister_dso_globals() {
- call_on_globals(&__asan_unregister_globals);
-}
-
-// Register globals
-#pragma section(".CRT$XCU", long, read) // NOLINT
-#pragma section(".CRT$XTX", long, read) // NOLINT
-extern "C" __declspec(allocate(".CRT$XCU"))
-void (*const __asan_dso_reg_hook)() = &register_dso_globals;
-extern "C" __declspec(allocate(".CRT$XTX"))
-void (*const __asan_dso_unreg_hook)() = &unregister_dso_globals;
-
-} // namespace __asan
-
-#endif // SANITIZER_WINDOWS
diff --git a/lib/asan/asan_init_version.h b/lib/asan/asan_init_version.h
deleted file mode 100644
index c49fcd7402487..0000000000000
--- a/lib/asan/asan_init_version.h
+++ /dev/null
@@ -1,45 +0,0 @@
-//===-- asan_init_version.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.
-//
-// This header defines a versioned __asan_init function to be called at the
-// startup of the instrumented program.
-//===----------------------------------------------------------------------===//
-#ifndef ASAN_INIT_VERSION_H
-#define ASAN_INIT_VERSION_H
-
-#include "sanitizer_common/sanitizer_platform.h"
-
-extern "C" {
- // Every time the ASan ABI changes we also change the version number in the
- // __asan_init function name. Objects built with incompatible ASan ABI
- // versions will not link with run-time.
- //
- // Changes between ABI versions:
- // v1=>v2: added 'module_name' to __asan_global
- // v2=>v3: stack frame description (created by the compiler)
- // contains the function PC as the 3rd field (see
- // DescribeAddressIfStack)
- // v3=>v4: added '__asan_global_source_location' to __asan_global
- // v4=>v5: changed the semantics and format of __asan_stack_malloc_ and
- // __asan_stack_free_ functions
- // v5=>v6: changed the name of the version check symbol
- // v6=>v7: added 'odr_indicator' to __asan_global
- // v7=>v8: added '__asan_(un)register_image_globals' functions for dead
- // stripping support on Mach-O platforms
-#if SANITIZER_WORDSIZE == 32 && SANITIZER_ANDROID
- // v8=>v9: 32-bit Android switched to dynamic shadow
- #define __asan_version_mismatch_check __asan_version_mismatch_check_v9
-#else
- #define __asan_version_mismatch_check __asan_version_mismatch_check_v8
-#endif
-}
-
-#endif // ASAN_INIT_VERSION_H
diff --git a/lib/asan/asan_interceptors.cc b/lib/asan/asan_interceptors.cc
deleted file mode 100644
index aac2bb8a6bbf4..0000000000000
--- a/lib/asan/asan_interceptors.cc
+++ /dev/null
@@ -1,667 +0,0 @@
-//===-- asan_interceptors.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.
-//
-// Intercept various libc functions.
-//===----------------------------------------------------------------------===//
-
-#include "asan_interceptors.h"
-#include "asan_allocator.h"
-#include "asan_internal.h"
-#include "asan_mapping.h"
-#include "asan_poisoning.h"
-#include "asan_report.h"
-#include "asan_stack.h"
-#include "asan_stats.h"
-#include "asan_suppressions.h"
-#include "lsan/lsan_common.h"
-#include "sanitizer_common/sanitizer_libc.h"
-
-// There is no general interception at all on Fuchsia and RTEMS.
-// Only the functions in asan_interceptors_memintrinsics.cc are
-// really defined to replace libc functions.
-#if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS
-
-#if SANITIZER_POSIX
-#include "sanitizer_common/sanitizer_posix.h"
-#endif
-
-#if ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION || \
- ASAN_INTERCEPT__SJLJ_UNWIND_RAISEEXCEPTION
-#include <unwind.h>
-#endif
-
-#if defined(__i386) && SANITIZER_LINUX
-#define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.1"
-#elif defined(__mips__) && SANITIZER_LINUX
-#define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.2"
-#endif
-
-namespace __asan {
-
-#define ASAN_READ_STRING_OF_LEN(ctx, s, len, n) \
- ASAN_READ_RANGE((ctx), (s), \
- common_flags()->strict_string_checks ? (len) + 1 : (n))
-
-#define ASAN_READ_STRING(ctx, s, n) \
- ASAN_READ_STRING_OF_LEN((ctx), (s), REAL(strlen)(s), (n))
-
-static inline uptr MaybeRealStrnlen(const char *s, uptr maxlen) {
-#if SANITIZER_INTERCEPT_STRNLEN
- if (REAL(strnlen)) {
- return REAL(strnlen)(s, maxlen);
- }
-#endif
- return internal_strnlen(s, maxlen);
-}
-
-void SetThreadName(const char *name) {
- AsanThread *t = GetCurrentThread();
- if (t)
- asanThreadRegistry().SetThreadName(t->tid(), name);
-}
-
-int OnExit() {
- if (CAN_SANITIZE_LEAKS && common_flags()->detect_leaks &&
- __lsan::HasReportedLeaks()) {
- return common_flags()->exitcode;
- }
- // FIXME: ask frontend whether we need to return failure.
- return 0;
-}
-
-} // namespace __asan
-
-// ---------------------- Wrappers ---------------- {{{1
-using namespace __asan; // NOLINT
-
-DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr)
-DECLARE_REAL_AND_INTERCEPTOR(void, free, void *)
-
-#define ASAN_INTERCEPTOR_ENTER(ctx, func) \
- AsanInterceptorContext _ctx = {#func}; \
- ctx = (void *)&_ctx; \
- (void) ctx; \
-
-#define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name)
-#define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \
- ASAN_INTERCEPT_FUNC_VER(name, ver)
-#define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \
- ASAN_WRITE_RANGE(ctx, ptr, size)
-#define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) \
- ASAN_READ_RANGE(ctx, ptr, size)
-#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \
- ASAN_INTERCEPTOR_ENTER(ctx, func); \
- do { \
- if (asan_init_is_running) \
- return REAL(func)(__VA_ARGS__); \
- if (SANITIZER_MAC && UNLIKELY(!asan_inited)) \
- return REAL(func)(__VA_ARGS__); \
- ENSURE_ASAN_INITED(); \
- } while (false)
-#define COMMON_INTERCEPTOR_DIR_ACQUIRE(ctx, path) \
- do { \
- } while (false)
-#define COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd) \
- do { \
- } while (false)
-#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) \
- do { \
- } while (false)
-#define COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, newfd) \
- do { \
- } while (false)
-#define COMMON_INTERCEPTOR_SET_THREAD_NAME(ctx, name) SetThreadName(name)
-// Should be asanThreadRegistry().SetThreadNameByUserId(thread, name)
-// But asan does not remember UserId's for threads (pthread_t);
-// and remembers all ever existed threads, so the linear search by UserId
-// can be slow.
-#define COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, name) \
- do { \
- } while (false)
-#define COMMON_INTERCEPTOR_BLOCK_REAL(name) REAL(name)
-// Strict init-order checking is dlopen-hostile:
-// https://github.com/google/sanitizers/issues/178
-#define COMMON_INTERCEPTOR_ON_DLOPEN(filename, flag) \
- do { \
- if (flags()->strict_init_order) \
- StopInitOrderChecking(); \
- CheckNoDeepBind(filename, flag); \
- } while (false)
-#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit()
-#define COMMON_INTERCEPTOR_LIBRARY_LOADED(filename, handle)
-#define COMMON_INTERCEPTOR_LIBRARY_UNLOADED()
-#define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED (!asan_inited)
-#define COMMON_INTERCEPTOR_GET_TLS_RANGE(begin, end) \
- if (AsanThread *t = GetCurrentThread()) { \
- *begin = t->tls_begin(); \
- *end = t->tls_end(); \
- } else { \
- *begin = *end = 0; \
- }
-
-#define COMMON_INTERCEPTOR_MEMMOVE_IMPL(ctx, to, from, size) \
- do { \
- ASAN_INTERCEPTOR_ENTER(ctx, memmove); \
- ASAN_MEMMOVE_IMPL(ctx, to, from, size); \
- } while (false)
-
-#define COMMON_INTERCEPTOR_MEMCPY_IMPL(ctx, to, from, size) \
- do { \
- ASAN_INTERCEPTOR_ENTER(ctx, memcpy); \
- ASAN_MEMCPY_IMPL(ctx, to, from, size); \
- } while (false)
-
-#define COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, c, size) \
- do { \
- ASAN_INTERCEPTOR_ENTER(ctx, memset); \
- ASAN_MEMSET_IMPL(ctx, block, c, size); \
- } while (false)
-
-#include "sanitizer_common/sanitizer_common_interceptors.inc"
-#include "sanitizer_common/sanitizer_signal_interceptors.inc"
-
-// Syscall interceptors don't have contexts, we don't support suppressions
-// for them.
-#define COMMON_SYSCALL_PRE_READ_RANGE(p, s) ASAN_READ_RANGE(nullptr, p, s)
-#define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) ASAN_WRITE_RANGE(nullptr, p, s)
-#define COMMON_SYSCALL_POST_READ_RANGE(p, s) \
- do { \
- (void)(p); \
- (void)(s); \
- } while (false)
-#define COMMON_SYSCALL_POST_WRITE_RANGE(p, s) \
- do { \
- (void)(p); \
- (void)(s); \
- } while (false)
-#include "sanitizer_common/sanitizer_common_syscalls.inc"
-#include "sanitizer_common/sanitizer_syscalls_netbsd.inc"
-
-struct ThreadStartParam {
- atomic_uintptr_t t;
- atomic_uintptr_t is_registered;
-};
-
-#if ASAN_INTERCEPT_PTHREAD_CREATE
-static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
- ThreadStartParam *param = reinterpret_cast<ThreadStartParam *>(arg);
- AsanThread *t = nullptr;
- while ((t = reinterpret_cast<AsanThread *>(
- atomic_load(&param->t, memory_order_acquire))) == nullptr)
- internal_sched_yield();
- SetCurrentThread(t);
- return t->ThreadStart(GetTid(), &param->is_registered);
-}
-
-INTERCEPTOR(int, pthread_create, void *thread,
- void *attr, void *(*start_routine)(void*), void *arg) {
- EnsureMainThreadIDIsCorrect();
- // Strict init-order checking is thread-hostile.
- if (flags()->strict_init_order)
- StopInitOrderChecking();
- GET_STACK_TRACE_THREAD;
- int detached = 0;
- if (attr)
- REAL(pthread_attr_getdetachstate)(attr, &detached);
- ThreadStartParam param;
- atomic_store(&param.t, 0, memory_order_relaxed);
- atomic_store(&param.is_registered, 0, memory_order_relaxed);
- int result;
- {
- // Ignore all allocations made by pthread_create: thread stack/TLS may be
- // stored by pthread for future reuse even after thread destruction, and
- // the linked list it's stored in doesn't even hold valid pointers to the
- // objects, the latter are calculated by obscure pointer arithmetic.
-#if CAN_SANITIZE_LEAKS
- __lsan::ScopedInterceptorDisabler disabler;
-#endif
- result = REAL(pthread_create)(thread, attr, asan_thread_start, &param);
- }
- if (result == 0) {
- u32 current_tid = GetCurrentTidOrInvalid();
- AsanThread *t =
- AsanThread::Create(start_routine, arg, current_tid, &stack, detached);
- atomic_store(&param.t, reinterpret_cast<uptr>(t), memory_order_release);
- // Wait until the AsanThread object is initialized and the ThreadRegistry
- // entry is in "started" state. One reason for this is that after this
- // interceptor exits, the child thread's stack may be the only thing holding
- // the |arg| pointer. This may cause LSan to report a leak if leak checking
- // happens at a point when the interceptor has already exited, but the stack
- // range for the child thread is not yet known.
- while (atomic_load(&param.is_registered, memory_order_acquire) == 0)
- internal_sched_yield();
- }
- return result;
-}
-
-INTERCEPTOR(int, pthread_join, void *t, void **arg) {
- return real_pthread_join(t, arg);
-}
-
-DEFINE_REAL_PTHREAD_FUNCTIONS
-#endif // ASAN_INTERCEPT_PTHREAD_CREATE
-
-#if ASAN_INTERCEPT_SWAPCONTEXT
-static void ClearShadowMemoryForContextStack(uptr stack, uptr ssize) {
- // Align to page size.
- uptr PageSize = GetPageSizeCached();
- uptr bottom = stack & ~(PageSize - 1);
- ssize += stack - bottom;
- ssize = RoundUpTo(ssize, PageSize);
- static const uptr kMaxSaneContextStackSize = 1 << 22; // 4 Mb
- if (AddrIsInMem(bottom) && ssize && ssize <= kMaxSaneContextStackSize) {
- PoisonShadow(bottom, ssize, 0);
- }
-}
-
-INTERCEPTOR(int, swapcontext, struct ucontext_t *oucp,
- struct ucontext_t *ucp) {
- static bool reported_warning = false;
- if (!reported_warning) {
- Report("WARNING: ASan doesn't fully support makecontext/swapcontext "
- "functions and may produce false positives in some cases!\n");
- reported_warning = true;
- }
- // Clear shadow memory for new context (it may share stack
- // with current context).
- uptr stack, ssize;
- ReadContextStack(ucp, &stack, &ssize);
- ClearShadowMemoryForContextStack(stack, ssize);
-#if __has_attribute(__indirect_return__) && \
- (defined(__x86_64__) || defined(__i386__))
- int (*real_swapcontext)(struct ucontext_t *, struct ucontext_t *)
- __attribute__((__indirect_return__))
- = REAL(swapcontext);
- int res = real_swapcontext(oucp, ucp);
-#else
- int res = REAL(swapcontext)(oucp, ucp);
-#endif
- // swapcontext technically does not return, but program may swap context to
- // "oucp" later, that would look as if swapcontext() returned 0.
- // We need to clear shadow for ucp once again, as it may be in arbitrary
- // state.
- ClearShadowMemoryForContextStack(stack, ssize);
- return res;
-}
-#endif // ASAN_INTERCEPT_SWAPCONTEXT
-
-#if SANITIZER_NETBSD
-#define longjmp __longjmp14
-#define siglongjmp __siglongjmp14
-#endif
-
-INTERCEPTOR(void, longjmp, void *env, int val) {
- __asan_handle_no_return();
- REAL(longjmp)(env, val);
-}
-
-#if ASAN_INTERCEPT__LONGJMP
-INTERCEPTOR(void, _longjmp, void *env, int val) {
- __asan_handle_no_return();
- REAL(_longjmp)(env, val);
-}
-#endif
-
-#if ASAN_INTERCEPT___LONGJMP_CHK
-INTERCEPTOR(void, __longjmp_chk, void *env, int val) {
- __asan_handle_no_return();
- REAL(__longjmp_chk)(env, val);
-}
-#endif
-
-#if ASAN_INTERCEPT_SIGLONGJMP
-INTERCEPTOR(void, siglongjmp, void *env, int val) {
- __asan_handle_no_return();
- REAL(siglongjmp)(env, val);
-}
-#endif
-
-#if ASAN_INTERCEPT___CXA_THROW
-INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) {
- CHECK(REAL(__cxa_throw));
- __asan_handle_no_return();
- REAL(__cxa_throw)(a, b, c);
-}
-#endif
-
-#if ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION
-INTERCEPTOR(void, __cxa_rethrow_primary_exception, void *a) {
- CHECK(REAL(__cxa_rethrow_primary_exception));
- __asan_handle_no_return();
- REAL(__cxa_rethrow_primary_exception)(a);
-}
-#endif
-
-#if ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION
-INTERCEPTOR(_Unwind_Reason_Code, _Unwind_RaiseException,
- _Unwind_Exception *object) {
- CHECK(REAL(_Unwind_RaiseException));
- __asan_handle_no_return();
- return REAL(_Unwind_RaiseException)(object);
-}
-#endif
-
-#if ASAN_INTERCEPT__SJLJ_UNWIND_RAISEEXCEPTION
-INTERCEPTOR(_Unwind_Reason_Code, _Unwind_SjLj_RaiseException,
- _Unwind_Exception *object) {
- CHECK(REAL(_Unwind_SjLj_RaiseException));
- __asan_handle_no_return();
- return REAL(_Unwind_SjLj_RaiseException)(object);
-}
-#endif
-
-#if ASAN_INTERCEPT_INDEX
-# if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX
-INTERCEPTOR(char*, index, const char *string, int c)
- ALIAS(WRAPPER_NAME(strchr));
-# else
-# if SANITIZER_MAC
-DECLARE_REAL(char*, index, const char *string, int c)
-OVERRIDE_FUNCTION(index, strchr);
-# else
-DEFINE_REAL(char*, index, const char *string, int c)
-# endif
-# endif
-#endif // ASAN_INTERCEPT_INDEX
-
-// For both strcat() and strncat() we need to check the validity of |to|
-// argument irrespective of the |from| length.
-INTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT
- void *ctx;
- ASAN_INTERCEPTOR_ENTER(ctx, strcat); // NOLINT
- ENSURE_ASAN_INITED();
- if (flags()->replace_str) {
- uptr from_length = REAL(strlen)(from);
- ASAN_READ_RANGE(ctx, from, from_length + 1);
- uptr to_length = REAL(strlen)(to);
- ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length);
- ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
- // If the copying actually happens, the |from| string should not overlap
- // with the resulting string starting at |to|, which has a length of
- // to_length + from_length + 1.
- if (from_length > 0) {
- CHECK_RANGES_OVERLAP("strcat", to, from_length + to_length + 1,
- from, from_length + 1);
- }
- }
- return REAL(strcat)(to, from); // NOLINT
-}
-
-INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) {
- void *ctx;
- ASAN_INTERCEPTOR_ENTER(ctx, strncat);
- ENSURE_ASAN_INITED();
- if (flags()->replace_str) {
- uptr from_length = MaybeRealStrnlen(from, size);
- uptr copy_length = Min(size, from_length + 1);
- ASAN_READ_RANGE(ctx, from, copy_length);
- uptr to_length = REAL(strlen)(to);
- ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length);
- ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1);
- if (from_length > 0) {
- CHECK_RANGES_OVERLAP("strncat", to, to_length + copy_length + 1,
- from, copy_length);
- }
- }
- return REAL(strncat)(to, from, size);
-}
-
-INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT
- void *ctx;
- ASAN_INTERCEPTOR_ENTER(ctx, strcpy); // NOLINT
-#if SANITIZER_MAC
- if (UNLIKELY(!asan_inited)) return REAL(strcpy)(to, from); // NOLINT
-#endif
- // strcpy is called from malloc_default_purgeable_zone()
- // in __asan::ReplaceSystemAlloc() on Mac.
- if (asan_init_is_running) {
- return REAL(strcpy)(to, from); // NOLINT
- }
- ENSURE_ASAN_INITED();
- if (flags()->replace_str) {
- uptr from_size = REAL(strlen)(from) + 1;
- CHECK_RANGES_OVERLAP("strcpy", to, from_size, from, from_size);
- ASAN_READ_RANGE(ctx, from, from_size);
- ASAN_WRITE_RANGE(ctx, to, from_size);
- }
- return REAL(strcpy)(to, from); // NOLINT
-}
-
-INTERCEPTOR(char*, strdup, const char *s) {
- void *ctx;
- ASAN_INTERCEPTOR_ENTER(ctx, strdup);
- if (UNLIKELY(!asan_inited)) return internal_strdup(s);
- ENSURE_ASAN_INITED();
- uptr length = REAL(strlen)(s);
- if (flags()->replace_str) {
- ASAN_READ_RANGE(ctx, s, length + 1);
- }
- GET_STACK_TRACE_MALLOC;
- void *new_mem = asan_malloc(length + 1, &stack);
- REAL(memcpy)(new_mem, s, length + 1);
- return reinterpret_cast<char*>(new_mem);
-}
-
-#if ASAN_INTERCEPT___STRDUP
-INTERCEPTOR(char*, __strdup, const char *s) {
- void *ctx;
- ASAN_INTERCEPTOR_ENTER(ctx, strdup);
- if (UNLIKELY(!asan_inited)) return internal_strdup(s);
- ENSURE_ASAN_INITED();
- uptr length = REAL(strlen)(s);
- if (flags()->replace_str) {
- ASAN_READ_RANGE(ctx, s, length + 1);
- }
- GET_STACK_TRACE_MALLOC;
- void *new_mem = asan_malloc(length + 1, &stack);
- REAL(memcpy)(new_mem, s, length + 1);
- return reinterpret_cast<char*>(new_mem);
-}
-#endif // ASAN_INTERCEPT___STRDUP
-
-INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) {
- void *ctx;
- ASAN_INTERCEPTOR_ENTER(ctx, strncpy);
- ENSURE_ASAN_INITED();
- if (flags()->replace_str) {
- uptr from_size = Min(size, MaybeRealStrnlen(from, size) + 1);
- CHECK_RANGES_OVERLAP("strncpy", to, from_size, from, from_size);
- ASAN_READ_RANGE(ctx, from, from_size);
- ASAN_WRITE_RANGE(ctx, to, size);
- }
- return REAL(strncpy)(to, from, size);
-}
-
-INTERCEPTOR(long, strtol, const char *nptr, // NOLINT
- char **endptr, int base) {
- void *ctx;
- ASAN_INTERCEPTOR_ENTER(ctx, strtol);
- ENSURE_ASAN_INITED();
- if (!flags()->replace_str) {
- return REAL(strtol)(nptr, endptr, base);
- }
- char *real_endptr;
- long result = REAL(strtol)(nptr, &real_endptr, base); // NOLINT
- StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
- return result;
-}
-
-INTERCEPTOR(int, atoi, const char *nptr) {
- void *ctx;
- ASAN_INTERCEPTOR_ENTER(ctx, atoi);
-#if SANITIZER_MAC
- if (UNLIKELY(!asan_inited)) return REAL(atoi)(nptr);
-#endif
- ENSURE_ASAN_INITED();
- if (!flags()->replace_str) {
- return REAL(atoi)(nptr);
- }
- char *real_endptr;
- // "man atoi" tells that behavior of atoi(nptr) is the same as
- // strtol(nptr, 0, 10), i.e. it sets errno to ERANGE if the
- // parsed integer can't be stored in *long* type (even if it's
- // different from int). So, we just imitate this behavior.
- int result = REAL(strtol)(nptr, &real_endptr, 10);
- FixRealStrtolEndptr(nptr, &real_endptr);
- ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);
- return result;
-}
-
-INTERCEPTOR(long, atol, const char *nptr) { // NOLINT
- void *ctx;
- ASAN_INTERCEPTOR_ENTER(ctx, atol);
-#if SANITIZER_MAC
- if (UNLIKELY(!asan_inited)) return REAL(atol)(nptr);
-#endif
- ENSURE_ASAN_INITED();
- if (!flags()->replace_str) {
- return REAL(atol)(nptr);
- }
- char *real_endptr;
- long result = REAL(strtol)(nptr, &real_endptr, 10); // NOLINT
- FixRealStrtolEndptr(nptr, &real_endptr);
- ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);
- return result;
-}
-
-#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
-INTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT
- char **endptr, int base) {
- void *ctx;
- ASAN_INTERCEPTOR_ENTER(ctx, strtoll);
- ENSURE_ASAN_INITED();
- if (!flags()->replace_str) {
- return REAL(strtoll)(nptr, endptr, base);
- }
- char *real_endptr;
- long long result = REAL(strtoll)(nptr, &real_endptr, base); // NOLINT
- StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base);
- return result;
-}
-
-INTERCEPTOR(long long, atoll, const char *nptr) { // NOLINT
- void *ctx;
- ASAN_INTERCEPTOR_ENTER(ctx, atoll);
- ENSURE_ASAN_INITED();
- if (!flags()->replace_str) {
- return REAL(atoll)(nptr);
- }
- char *real_endptr;
- long long result = REAL(strtoll)(nptr, &real_endptr, 10); // NOLINT
- FixRealStrtolEndptr(nptr, &real_endptr);
- ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1);
- return result;
-}
-#endif // ASAN_INTERCEPT_ATOLL_AND_STRTOLL
-
-#if ASAN_INTERCEPT___CXA_ATEXIT
-static void AtCxaAtexit(void *unused) {
- (void)unused;
- StopInitOrderChecking();
-}
-
-INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg,
- void *dso_handle) {
-#if SANITIZER_MAC
- if (UNLIKELY(!asan_inited)) return REAL(__cxa_atexit)(func, arg, dso_handle);
-#endif
- ENSURE_ASAN_INITED();
- int res = REAL(__cxa_atexit)(func, arg, dso_handle);
- REAL(__cxa_atexit)(AtCxaAtexit, nullptr, nullptr);
- return res;
-}
-#endif // ASAN_INTERCEPT___CXA_ATEXIT
-
-// ---------------------- InitializeAsanInterceptors ---------------- {{{1
-namespace __asan {
-void InitializeAsanInterceptors() {
- static bool was_called_once;
- CHECK(!was_called_once);
- was_called_once = true;
- InitializeCommonInterceptors();
- InitializeSignalInterceptors();
-
- // Intercept str* functions.
- ASAN_INTERCEPT_FUNC(strcat); // NOLINT
- ASAN_INTERCEPT_FUNC(strcpy); // NOLINT
- ASAN_INTERCEPT_FUNC(strncat);
- ASAN_INTERCEPT_FUNC(strncpy);
- ASAN_INTERCEPT_FUNC(strdup);
-#if ASAN_INTERCEPT___STRDUP
- ASAN_INTERCEPT_FUNC(__strdup);
-#endif
-#if ASAN_INTERCEPT_INDEX && ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX
- ASAN_INTERCEPT_FUNC(index);
-#endif
-
- ASAN_INTERCEPT_FUNC(atoi);
- ASAN_INTERCEPT_FUNC(atol);
- ASAN_INTERCEPT_FUNC(strtol);
-#if ASAN_INTERCEPT_ATOLL_AND_STRTOLL
- ASAN_INTERCEPT_FUNC(atoll);
- ASAN_INTERCEPT_FUNC(strtoll);
-#endif
-
- // Intecept jump-related functions.
- ASAN_INTERCEPT_FUNC(longjmp);
-
-#if ASAN_INTERCEPT_SWAPCONTEXT
- ASAN_INTERCEPT_FUNC(swapcontext);
-#endif
-#if ASAN_INTERCEPT__LONGJMP
- ASAN_INTERCEPT_FUNC(_longjmp);
-#endif
-#if ASAN_INTERCEPT___LONGJMP_CHK
- ASAN_INTERCEPT_FUNC(__longjmp_chk);
-#endif
-#if ASAN_INTERCEPT_SIGLONGJMP
- ASAN_INTERCEPT_FUNC(siglongjmp);
-#endif
-
- // Intercept exception handling functions.
-#if ASAN_INTERCEPT___CXA_THROW
- ASAN_INTERCEPT_FUNC(__cxa_throw);
-#endif
-#if ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION
- ASAN_INTERCEPT_FUNC(__cxa_rethrow_primary_exception);
-#endif
- // Indirectly intercept std::rethrow_exception.
-#if ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION
- INTERCEPT_FUNCTION(_Unwind_RaiseException);
-#endif
- // Indirectly intercept std::rethrow_exception.
-#if ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION
- INTERCEPT_FUNCTION(_Unwind_SjLj_RaiseException);
-#endif
-
- // Intercept threading-related functions
-#if ASAN_INTERCEPT_PTHREAD_CREATE
-#if defined(ASAN_PTHREAD_CREATE_VERSION)
- ASAN_INTERCEPT_FUNC_VER(pthread_create, ASAN_PTHREAD_CREATE_VERSION);
-#else
- ASAN_INTERCEPT_FUNC(pthread_create);
-#endif
- ASAN_INTERCEPT_FUNC(pthread_join);
-#endif
-
- // Intercept atexit function.
-#if ASAN_INTERCEPT___CXA_ATEXIT
- ASAN_INTERCEPT_FUNC(__cxa_atexit);
-#endif
-
- InitializePlatformInterceptors();
-
- VReport(1, "AddressSanitizer: libc interceptors initialized\n");
-}
-
-} // namespace __asan
-
-#endif // !SANITIZER_FUCHSIA
diff --git a/lib/asan/asan_interceptors.h b/lib/asan/asan_interceptors.h
deleted file mode 100644
index 50895b1679901..0000000000000
--- a/lib/asan/asan_interceptors.h
+++ /dev/null
@@ -1,135 +0,0 @@
-//===-- asan_interceptors.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.
-//
-// ASan-private header for asan_interceptors.cc
-//===----------------------------------------------------------------------===//
-#ifndef ASAN_INTERCEPTORS_H
-#define ASAN_INTERCEPTORS_H
-
-#include "asan_internal.h"
-#include "asan_interceptors_memintrinsics.h"
-#include "interception/interception.h"
-#include "sanitizer_common/sanitizer_platform_interceptors.h"
-
-namespace __asan {
-
-void InitializeAsanInterceptors();
-void InitializePlatformInterceptors();
-
-#define ENSURE_ASAN_INITED() \
- do { \
- CHECK(!asan_init_is_running); \
- if (UNLIKELY(!asan_inited)) { \
- AsanInitFromRtl(); \
- } \
- } while (0)
-
-} // namespace __asan
-
-// There is no general interception at all on Fuchsia and RTEMS.
-// Only the functions in asan_interceptors_memintrinsics.h are
-// really defined to replace libc functions.
-#if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS
-
-// Use macro to describe if specific function should be
-// intercepted on a given platform.
-#if !SANITIZER_WINDOWS
-# define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 1
-# define ASAN_INTERCEPT__LONGJMP 1
-# define ASAN_INTERCEPT_INDEX 1
-# define ASAN_INTERCEPT_PTHREAD_CREATE 1
-#else
-# define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 0
-# define ASAN_INTERCEPT__LONGJMP 0
-# define ASAN_INTERCEPT_INDEX 0
-# define ASAN_INTERCEPT_PTHREAD_CREATE 0
-#endif
-
-#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
- SANITIZER_SOLARIS
-# define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 1
-#else
-# define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 0
-#endif
-
-#if (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_SOLARIS
-# define ASAN_INTERCEPT_SWAPCONTEXT 1
-#else
-# define ASAN_INTERCEPT_SWAPCONTEXT 0
-#endif
-
-#if !SANITIZER_WINDOWS
-# define ASAN_INTERCEPT_SIGLONGJMP 1
-#else
-# define ASAN_INTERCEPT_SIGLONGJMP 0
-#endif
-
-#if SANITIZER_LINUX && !SANITIZER_ANDROID
-# define ASAN_INTERCEPT___LONGJMP_CHK 1
-#else
-# define ASAN_INTERCEPT___LONGJMP_CHK 0
-#endif
-
-#if ASAN_HAS_EXCEPTIONS && !SANITIZER_WINDOWS && !SANITIZER_SOLARIS && \
- !SANITIZER_NETBSD
-# define ASAN_INTERCEPT___CXA_THROW 1
-# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1
-# if defined(_GLIBCXX_SJLJ_EXCEPTIONS) || (SANITIZER_IOS && defined(__arm__))
-# define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 1
-# else
-# define ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION 1
-# endif
-#else
-# define ASAN_INTERCEPT___CXA_THROW 0
-# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 0
-# define ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION 0
-# define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 0
-#endif
-
-#if !SANITIZER_WINDOWS
-# define ASAN_INTERCEPT___CXA_ATEXIT 1
-#else
-# define ASAN_INTERCEPT___CXA_ATEXIT 0
-#endif
-
-#if SANITIZER_LINUX && !SANITIZER_ANDROID
-# define ASAN_INTERCEPT___STRDUP 1
-#else
-# define ASAN_INTERCEPT___STRDUP 0
-#endif
-
-DECLARE_REAL(int, memcmp, const void *a1, const void *a2, uptr size)
-DECLARE_REAL(char*, strchr, const char *str, int c)
-DECLARE_REAL(SIZE_T, strlen, const char *s)
-DECLARE_REAL(char*, strncpy, char *to, const char *from, uptr size)
-DECLARE_REAL(uptr, strnlen, const char *s, uptr maxlen)
-DECLARE_REAL(char*, strstr, const char *s1, const char *s2)
-
-#if !SANITIZER_MAC
-#define ASAN_INTERCEPT_FUNC(name) \
- do { \
- if ((!INTERCEPT_FUNCTION(name) || !REAL(name))) \
- VReport(1, "AddressSanitizer: failed to intercept '" #name "'\n"); \
- } while (0)
-#define ASAN_INTERCEPT_FUNC_VER(name, ver) \
- do { \
- if ((!INTERCEPT_FUNCTION_VER(name, ver) || !REAL(name))) \
- VReport( \
- 1, "AddressSanitizer: failed to intercept '" #name "@@" #ver "'\n"); \
- } while (0)
-#else
-// OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION.
-#define ASAN_INTERCEPT_FUNC(name)
-#endif // SANITIZER_MAC
-
-#endif // !SANITIZER_FUCHSIA
-
-#endif // ASAN_INTERCEPTORS_H
diff --git a/lib/asan/asan_interceptors_memintrinsics.cc b/lib/asan/asan_interceptors_memintrinsics.cc
deleted file mode 100644
index 39e32cdad12ed..0000000000000
--- a/lib/asan/asan_interceptors_memintrinsics.cc
+++ /dev/null
@@ -1,44 +0,0 @@
-//===-- asan_interceptors_memintrinsics.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.
-//
-// ASan versions of memcpy, memmove, and memset.
-//===---------------------------------------------------------------------===//
-
-#include "asan_interceptors_memintrinsics.h"
-#include "asan_report.h"
-#include "asan_stack.h"
-#include "asan_suppressions.h"
-
-using namespace __asan; // NOLINT
-
-void *__asan_memcpy(void *to, const void *from, uptr size) {
- ASAN_MEMCPY_IMPL(nullptr, to, from, size);
-}
-
-void *__asan_memset(void *block, int c, uptr size) {
- ASAN_MEMSET_IMPL(nullptr, block, c, size);
-}
-
-void *__asan_memmove(void *to, const void *from, uptr size) {
- ASAN_MEMMOVE_IMPL(nullptr, to, from, size);
-}
-
-#if SANITIZER_FUCHSIA || SANITIZER_RTEMS
-
-// Fuchsia and RTEMS don't use sanitizer_common_interceptors.inc, but
-// the only things there it wants are these three. Just define them
-// as aliases here rather than repeating the contents.
-
-extern "C" decltype(__asan_memcpy) memcpy[[gnu::alias("__asan_memcpy")]];
-extern "C" decltype(__asan_memmove) memmove[[gnu::alias("__asan_memmove")]];
-extern "C" decltype(__asan_memset) memset[[gnu::alias("__asan_memset")]];
-
-#endif // SANITIZER_FUCHSIA || SANITIZER_RTEMS
diff --git a/lib/asan/asan_interceptors_memintrinsics.h b/lib/asan/asan_interceptors_memintrinsics.h
deleted file mode 100644
index a071e8f684a02..0000000000000
--- a/lib/asan/asan_interceptors_memintrinsics.h
+++ /dev/null
@@ -1,155 +0,0 @@
-//===-- asan_interceptors_memintrinsics.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.
-//
-// ASan-private header for asan_memintrin.cc
-//===---------------------------------------------------------------------===//
-#ifndef ASAN_MEMINTRIN_H
-#define ASAN_MEMINTRIN_H
-
-#include "asan_interface_internal.h"
-#include "asan_internal.h"
-#include "asan_mapping.h"
-#include "interception/interception.h"
-
-DECLARE_REAL(void*, memcpy, void *to, const void *from, uptr size)
-DECLARE_REAL(void*, memset, void *block, int c, uptr size)
-
-namespace __asan {
-
-// Return true if we can quickly decide that the region is unpoisoned.
-// We assume that a redzone is at least 16 bytes.
-static inline bool QuickCheckForUnpoisonedRegion(uptr beg, uptr size) {
- if (size == 0) return true;
- if (size <= 32)
- return !AddressIsPoisoned(beg) &&
- !AddressIsPoisoned(beg + size - 1) &&
- !AddressIsPoisoned(beg + size / 2);
- if (size <= 64)
- return !AddressIsPoisoned(beg) &&
- !AddressIsPoisoned(beg + size / 4) &&
- !AddressIsPoisoned(beg + size - 1) &&
- !AddressIsPoisoned(beg + 3 * size / 4) &&
- !AddressIsPoisoned(beg + size / 2);
- return false;
-}
-
-struct AsanInterceptorContext {
- const char *interceptor_name;
-};
-
-// We implement ACCESS_MEMORY_RANGE, ASAN_READ_RANGE,
-// and ASAN_WRITE_RANGE as macro instead of function so
-// that no extra frames are created, and stack trace contains
-// relevant information only.
-// We check all shadow bytes.
-#define ACCESS_MEMORY_RANGE(ctx, offset, size, isWrite) do { \
- uptr __offset = (uptr)(offset); \
- uptr __size = (uptr)(size); \
- uptr __bad = 0; \
- if (__offset > __offset + __size) { \
- GET_STACK_TRACE_FATAL_HERE; \
- ReportStringFunctionSizeOverflow(__offset, __size, &stack); \
- } \
- if (!QuickCheckForUnpoisonedRegion(__offset, __size) && \
- (__bad = __asan_region_is_poisoned(__offset, __size))) { \
- AsanInterceptorContext *_ctx = (AsanInterceptorContext *)ctx; \
- bool suppressed = false; \
- if (_ctx) { \
- suppressed = IsInterceptorSuppressed(_ctx->interceptor_name); \
- if (!suppressed && HaveStackTraceBasedSuppressions()) { \
- GET_STACK_TRACE_FATAL_HERE; \
- suppressed = IsStackTraceSuppressed(&stack); \
- } \
- } \
- if (!suppressed) { \
- GET_CURRENT_PC_BP_SP; \
- ReportGenericError(pc, bp, sp, __bad, isWrite, __size, 0, false);\
- } \
- } \
- } while (0)
-
-// memcpy is called during __asan_init() from the internals of printf(...).
-// We do not treat memcpy with to==from as a bug.
-// See http://llvm.org/bugs/show_bug.cgi?id=11763.
-#define ASAN_MEMCPY_IMPL(ctx, to, from, size) \
- do { \
- if (UNLIKELY(!asan_inited)) return internal_memcpy(to, from, size); \
- if (asan_init_is_running) { \
- return REAL(memcpy)(to, from, size); \
- } \
- ENSURE_ASAN_INITED(); \
- if (flags()->replace_intrin) { \
- if (to != from) { \
- CHECK_RANGES_OVERLAP("memcpy", to, size, from, size); \
- } \
- ASAN_READ_RANGE(ctx, from, size); \
- ASAN_WRITE_RANGE(ctx, to, size); \
- } \
- return REAL(memcpy)(to, from, size); \
- } while (0)
-
-// memset is called inside Printf.
-#define ASAN_MEMSET_IMPL(ctx, block, c, size) \
- do { \
- if (UNLIKELY(!asan_inited)) return internal_memset(block, c, size); \
- if (asan_init_is_running) { \
- return REAL(memset)(block, c, size); \
- } \
- ENSURE_ASAN_INITED(); \
- if (flags()->replace_intrin) { \
- ASAN_WRITE_RANGE(ctx, block, size); \
- } \
- return REAL(memset)(block, c, size); \
- } while (0)
-
-#define ASAN_MEMMOVE_IMPL(ctx, to, from, size) \
- do { \
- if (UNLIKELY(!asan_inited)) return internal_memmove(to, from, size); \
- ENSURE_ASAN_INITED(); \
- if (flags()->replace_intrin) { \
- ASAN_READ_RANGE(ctx, from, size); \
- ASAN_WRITE_RANGE(ctx, to, size); \
- } \
- return internal_memmove(to, from, size); \
- } while (0)
-
-#define ASAN_READ_RANGE(ctx, offset, size) \
- ACCESS_MEMORY_RANGE(ctx, offset, size, false)
-#define ASAN_WRITE_RANGE(ctx, offset, size) \
- ACCESS_MEMORY_RANGE(ctx, offset, size, true)
-
-// Behavior of functions like "memcpy" or "strcpy" is undefined
-// if memory intervals overlap. We report error in this case.
-// Macro is used to avoid creation of new frames.
-static inline bool RangesOverlap(const char *offset1, uptr length1,
- const char *offset2, uptr length2) {
- return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1));
-}
-#define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) \
- do { \
- const char *offset1 = (const char *)_offset1; \
- const char *offset2 = (const char *)_offset2; \
- if (RangesOverlap(offset1, length1, offset2, length2)) { \
- GET_STACK_TRACE_FATAL_HERE; \
- bool suppressed = IsInterceptorSuppressed(name); \
- if (!suppressed && HaveStackTraceBasedSuppressions()) { \
- suppressed = IsStackTraceSuppressed(&stack); \
- } \
- if (!suppressed) { \
- ReportStringFunctionMemoryRangesOverlap(name, offset1, length1, \
- offset2, length2, &stack); \
- } \
- } \
- } while (0)
-
-} // namespace __asan
-
-#endif // ASAN_MEMINTRIN_H
diff --git a/lib/asan/asan_interface.inc b/lib/asan/asan_interface.inc
deleted file mode 100644
index e65f61722b103..0000000000000
--- a/lib/asan/asan_interface.inc
+++ /dev/null
@@ -1,169 +0,0 @@
-//===-- asan_interface.inc ------------------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// Asan interface list.
-//===----------------------------------------------------------------------===//
-INTERFACE_FUNCTION(__asan_addr_is_in_fake_stack)
-INTERFACE_FUNCTION(__asan_address_is_poisoned)
-INTERFACE_FUNCTION(__asan_after_dynamic_init)
-INTERFACE_FUNCTION(__asan_alloca_poison)
-INTERFACE_FUNCTION(__asan_allocas_unpoison)
-INTERFACE_FUNCTION(__asan_before_dynamic_init)
-INTERFACE_FUNCTION(__asan_describe_address)
-INTERFACE_FUNCTION(__asan_exp_load1)
-INTERFACE_FUNCTION(__asan_exp_load2)
-INTERFACE_FUNCTION(__asan_exp_load4)
-INTERFACE_FUNCTION(__asan_exp_load8)
-INTERFACE_FUNCTION(__asan_exp_load16)
-INTERFACE_FUNCTION(__asan_exp_loadN)
-INTERFACE_FUNCTION(__asan_exp_store1)
-INTERFACE_FUNCTION(__asan_exp_store2)
-INTERFACE_FUNCTION(__asan_exp_store4)
-INTERFACE_FUNCTION(__asan_exp_store8)
-INTERFACE_FUNCTION(__asan_exp_store16)
-INTERFACE_FUNCTION(__asan_exp_storeN)
-INTERFACE_FUNCTION(__asan_get_alloc_stack)
-INTERFACE_FUNCTION(__asan_get_current_fake_stack)
-INTERFACE_FUNCTION(__asan_get_free_stack)
-INTERFACE_FUNCTION(__asan_get_report_access_size)
-INTERFACE_FUNCTION(__asan_get_report_access_type)
-INTERFACE_FUNCTION(__asan_get_report_address)
-INTERFACE_FUNCTION(__asan_get_report_bp)
-INTERFACE_FUNCTION(__asan_get_report_description)
-INTERFACE_FUNCTION(__asan_get_report_pc)
-INTERFACE_FUNCTION(__asan_get_report_sp)
-INTERFACE_FUNCTION(__asan_get_shadow_mapping)
-INTERFACE_FUNCTION(__asan_handle_no_return)
-INTERFACE_FUNCTION(__asan_init)
-INTERFACE_FUNCTION(__asan_load_cxx_array_cookie)
-INTERFACE_FUNCTION(__asan_load1)
-INTERFACE_FUNCTION(__asan_load2)
-INTERFACE_FUNCTION(__asan_load4)
-INTERFACE_FUNCTION(__asan_load8)
-INTERFACE_FUNCTION(__asan_load16)
-INTERFACE_FUNCTION(__asan_loadN)
-INTERFACE_FUNCTION(__asan_load1_noabort)
-INTERFACE_FUNCTION(__asan_load2_noabort)
-INTERFACE_FUNCTION(__asan_load4_noabort)
-INTERFACE_FUNCTION(__asan_load8_noabort)
-INTERFACE_FUNCTION(__asan_load16_noabort)
-INTERFACE_FUNCTION(__asan_loadN_noabort)
-INTERFACE_FUNCTION(__asan_locate_address)
-INTERFACE_FUNCTION(__asan_memcpy)
-INTERFACE_FUNCTION(__asan_memmove)
-INTERFACE_FUNCTION(__asan_memset)
-INTERFACE_FUNCTION(__asan_poison_cxx_array_cookie)
-INTERFACE_FUNCTION(__asan_poison_intra_object_redzone)
-INTERFACE_FUNCTION(__asan_poison_memory_region)
-INTERFACE_FUNCTION(__asan_poison_stack_memory)
-INTERFACE_FUNCTION(__asan_print_accumulated_stats)
-INTERFACE_FUNCTION(__asan_region_is_poisoned)
-INTERFACE_FUNCTION(__asan_register_globals)
-INTERFACE_FUNCTION(__asan_register_elf_globals)
-INTERFACE_FUNCTION(__asan_register_image_globals)
-INTERFACE_FUNCTION(__asan_report_error)
-INTERFACE_FUNCTION(__asan_report_exp_load1)
-INTERFACE_FUNCTION(__asan_report_exp_load2)
-INTERFACE_FUNCTION(__asan_report_exp_load4)
-INTERFACE_FUNCTION(__asan_report_exp_load8)
-INTERFACE_FUNCTION(__asan_report_exp_load16)
-INTERFACE_FUNCTION(__asan_report_exp_load_n)
-INTERFACE_FUNCTION(__asan_report_exp_store1)
-INTERFACE_FUNCTION(__asan_report_exp_store2)
-INTERFACE_FUNCTION(__asan_report_exp_store4)
-INTERFACE_FUNCTION(__asan_report_exp_store8)
-INTERFACE_FUNCTION(__asan_report_exp_store16)
-INTERFACE_FUNCTION(__asan_report_exp_store_n)
-INTERFACE_FUNCTION(__asan_report_load1)
-INTERFACE_FUNCTION(__asan_report_load2)
-INTERFACE_FUNCTION(__asan_report_load4)
-INTERFACE_FUNCTION(__asan_report_load8)
-INTERFACE_FUNCTION(__asan_report_load16)
-INTERFACE_FUNCTION(__asan_report_load_n)
-INTERFACE_FUNCTION(__asan_report_load1_noabort)
-INTERFACE_FUNCTION(__asan_report_load2_noabort)
-INTERFACE_FUNCTION(__asan_report_load4_noabort)
-INTERFACE_FUNCTION(__asan_report_load8_noabort)
-INTERFACE_FUNCTION(__asan_report_load16_noabort)
-INTERFACE_FUNCTION(__asan_report_load_n_noabort)
-INTERFACE_FUNCTION(__asan_report_present)
-INTERFACE_FUNCTION(__asan_report_store1)
-INTERFACE_FUNCTION(__asan_report_store2)
-INTERFACE_FUNCTION(__asan_report_store4)
-INTERFACE_FUNCTION(__asan_report_store8)
-INTERFACE_FUNCTION(__asan_report_store16)
-INTERFACE_FUNCTION(__asan_report_store_n)
-INTERFACE_FUNCTION(__asan_report_store1_noabort)
-INTERFACE_FUNCTION(__asan_report_store2_noabort)
-INTERFACE_FUNCTION(__asan_report_store4_noabort)
-INTERFACE_FUNCTION(__asan_report_store8_noabort)
-INTERFACE_FUNCTION(__asan_report_store16_noabort)
-INTERFACE_FUNCTION(__asan_report_store_n_noabort)
-INTERFACE_FUNCTION(__asan_set_death_callback)
-INTERFACE_FUNCTION(__asan_set_error_report_callback)
-INTERFACE_FUNCTION(__asan_set_shadow_00)
-INTERFACE_FUNCTION(__asan_set_shadow_f1)
-INTERFACE_FUNCTION(__asan_set_shadow_f2)
-INTERFACE_FUNCTION(__asan_set_shadow_f3)
-INTERFACE_FUNCTION(__asan_set_shadow_f5)
-INTERFACE_FUNCTION(__asan_set_shadow_f8)
-INTERFACE_FUNCTION(__asan_stack_free_0)
-INTERFACE_FUNCTION(__asan_stack_free_1)
-INTERFACE_FUNCTION(__asan_stack_free_2)
-INTERFACE_FUNCTION(__asan_stack_free_3)
-INTERFACE_FUNCTION(__asan_stack_free_4)
-INTERFACE_FUNCTION(__asan_stack_free_5)
-INTERFACE_FUNCTION(__asan_stack_free_6)
-INTERFACE_FUNCTION(__asan_stack_free_7)
-INTERFACE_FUNCTION(__asan_stack_free_8)
-INTERFACE_FUNCTION(__asan_stack_free_9)
-INTERFACE_FUNCTION(__asan_stack_free_10)
-INTERFACE_FUNCTION(__asan_stack_malloc_0)
-INTERFACE_FUNCTION(__asan_stack_malloc_1)
-INTERFACE_FUNCTION(__asan_stack_malloc_2)
-INTERFACE_FUNCTION(__asan_stack_malloc_3)
-INTERFACE_FUNCTION(__asan_stack_malloc_4)
-INTERFACE_FUNCTION(__asan_stack_malloc_5)
-INTERFACE_FUNCTION(__asan_stack_malloc_6)
-INTERFACE_FUNCTION(__asan_stack_malloc_7)
-INTERFACE_FUNCTION(__asan_stack_malloc_8)
-INTERFACE_FUNCTION(__asan_stack_malloc_9)
-INTERFACE_FUNCTION(__asan_stack_malloc_10)
-INTERFACE_FUNCTION(__asan_store1)
-INTERFACE_FUNCTION(__asan_store2)
-INTERFACE_FUNCTION(__asan_store4)
-INTERFACE_FUNCTION(__asan_store8)
-INTERFACE_FUNCTION(__asan_store16)
-INTERFACE_FUNCTION(__asan_storeN)
-INTERFACE_FUNCTION(__asan_store1_noabort)
-INTERFACE_FUNCTION(__asan_store2_noabort)
-INTERFACE_FUNCTION(__asan_store4_noabort)
-INTERFACE_FUNCTION(__asan_store8_noabort)
-INTERFACE_FUNCTION(__asan_store16_noabort)
-INTERFACE_FUNCTION(__asan_storeN_noabort)
-INTERFACE_FUNCTION(__asan_unpoison_intra_object_redzone)
-INTERFACE_FUNCTION(__asan_unpoison_memory_region)
-INTERFACE_FUNCTION(__asan_unpoison_stack_memory)
-INTERFACE_FUNCTION(__asan_unregister_globals)
-INTERFACE_FUNCTION(__asan_unregister_elf_globals)
-INTERFACE_FUNCTION(__asan_unregister_image_globals)
-INTERFACE_FUNCTION(__asan_version_mismatch_check_v8)
-INTERFACE_FUNCTION(__sanitizer_finish_switch_fiber)
-INTERFACE_FUNCTION(__sanitizer_print_stack_trace)
-INTERFACE_FUNCTION(__sanitizer_ptr_cmp)
-INTERFACE_FUNCTION(__sanitizer_ptr_sub)
-INTERFACE_FUNCTION(__sanitizer_start_switch_fiber)
-INTERFACE_FUNCTION(__sanitizer_unaligned_load16)
-INTERFACE_FUNCTION(__sanitizer_unaligned_load32)
-INTERFACE_FUNCTION(__sanitizer_unaligned_load64)
-INTERFACE_FUNCTION(__sanitizer_unaligned_store16)
-INTERFACE_FUNCTION(__sanitizer_unaligned_store32)
-INTERFACE_FUNCTION(__sanitizer_unaligned_store64)
-INTERFACE_WEAK_FUNCTION(__asan_default_options)
-INTERFACE_WEAK_FUNCTION(__asan_default_suppressions)
-INTERFACE_WEAK_FUNCTION(__asan_on_error)
diff --git a/lib/asan/asan_interface_internal.h b/lib/asan/asan_interface_internal.h
deleted file mode 100644
index b974c0cc4b430..0000000000000
--- a/lib/asan/asan_interface_internal.h
+++ /dev/null
@@ -1,255 +0,0 @@
-//===-- asan_interface_internal.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.
-//
-// This header declares the AddressSanitizer runtime interface functions.
-// The runtime library has to define these functions so the instrumented program
-// could call them.
-//
-// See also include/sanitizer/asan_interface.h
-//===----------------------------------------------------------------------===//
-#ifndef ASAN_INTERFACE_INTERNAL_H
-#define ASAN_INTERFACE_INTERNAL_H
-
-#include "sanitizer_common/sanitizer_internal_defs.h"
-
-#include "asan_init_version.h"
-
-using __sanitizer::uptr;
-using __sanitizer::u64;
-using __sanitizer::u32;
-
-extern "C" {
- // This function should be called at the very beginning of the process,
- // before any instrumented code is executed and before any call to malloc.
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_init();
-
- // This function exists purely to get a linker/loader error when using
- // incompatible versions of instrumentation and runtime library. Please note
- // that __asan_version_mismatch_check is a macro that is replaced with
- // __asan_version_mismatch_check_vXXX at compile-time.
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_version_mismatch_check();
-
- // This structure is used to describe the source location of a place where
- // global was defined.
- struct __asan_global_source_location {
- const char *filename;
- int line_no;
- int column_no;
- };
-
- // This structure describes an instrumented global variable.
- struct __asan_global {
- uptr beg; // The address of the global.
- uptr size; // The original size of the global.
- uptr size_with_redzone; // The size with the redzone.
- const char *name; // Name as a C string.
- const char *module_name; // Module name as a C string. This pointer is a
- // unique identifier of a module.
- uptr has_dynamic_init; // Non-zero if the global has dynamic initializer.
- __asan_global_source_location *location; // Source location of a global,
- // or NULL if it is unknown.
- uptr odr_indicator; // The address of the ODR indicator symbol.
- };
-
- // These functions can be called on some platforms to find globals in the same
- // loaded image as `flag' and apply __asan_(un)register_globals to them,
- // filtering out redundant calls.
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_register_image_globals(uptr *flag);
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_unregister_image_globals(uptr *flag);
-
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_register_elf_globals(uptr *flag, void *start, void *stop);
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_unregister_elf_globals(uptr *flag, void *start, void *stop);
-
- // These two functions should be called by the instrumented code.
- // 'globals' is an array of structures describing 'n' globals.
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_register_globals(__asan_global *globals, uptr n);
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_unregister_globals(__asan_global *globals, uptr n);
-
- // These two functions should be called before and after dynamic initializers
- // of a single module run, respectively.
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_before_dynamic_init(const char *module_name);
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_after_dynamic_init();
-
- // Sets bytes of the given range of the shadow memory into specific value.
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_set_shadow_00(uptr addr, uptr size);
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_set_shadow_f1(uptr addr, uptr size);
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_set_shadow_f2(uptr addr, uptr size);
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_set_shadow_f3(uptr addr, uptr size);
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_set_shadow_f5(uptr addr, uptr size);
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_set_shadow_f8(uptr addr, uptr size);
-
- // These two functions are used by instrumented code in the
- // use-after-scope mode. They mark memory for local variables as
- // unaddressable when they leave scope and addressable before the
- // function exits.
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_poison_stack_memory(uptr addr, uptr size);
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_unpoison_stack_memory(uptr addr, uptr size);
-
- // Performs cleanup before a NoReturn function. Must be called before things
- // like _exit and execl to avoid false positives on stack.
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_handle_no_return();
-
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_poison_memory_region(void const volatile *addr, uptr size);
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_unpoison_memory_region(void const volatile *addr, uptr size);
-
- SANITIZER_INTERFACE_ATTRIBUTE
- int __asan_address_is_poisoned(void const volatile *addr);
-
- SANITIZER_INTERFACE_ATTRIBUTE
- uptr __asan_region_is_poisoned(uptr beg, uptr size);
-
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_describe_address(uptr addr);
-
- SANITIZER_INTERFACE_ATTRIBUTE
- int __asan_report_present();
-
- SANITIZER_INTERFACE_ATTRIBUTE
- uptr __asan_get_report_pc();
- SANITIZER_INTERFACE_ATTRIBUTE
- uptr __asan_get_report_bp();
- SANITIZER_INTERFACE_ATTRIBUTE
- uptr __asan_get_report_sp();
- SANITIZER_INTERFACE_ATTRIBUTE
- uptr __asan_get_report_address();
- SANITIZER_INTERFACE_ATTRIBUTE
- int __asan_get_report_access_type();
- SANITIZER_INTERFACE_ATTRIBUTE
- uptr __asan_get_report_access_size();
- SANITIZER_INTERFACE_ATTRIBUTE
- const char * __asan_get_report_description();
-
- SANITIZER_INTERFACE_ATTRIBUTE
- const char * __asan_locate_address(uptr addr, char *name, uptr name_size,
- uptr *region_address, uptr *region_size);
-
- SANITIZER_INTERFACE_ATTRIBUTE
- uptr __asan_get_alloc_stack(uptr addr, uptr *trace, uptr size,
- u32 *thread_id);
-
- SANITIZER_INTERFACE_ATTRIBUTE
- uptr __asan_get_free_stack(uptr addr, uptr *trace, uptr size,
- u32 *thread_id);
-
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_get_shadow_mapping(uptr *shadow_scale, uptr *shadow_offset);
-
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_report_error(uptr pc, uptr bp, uptr sp,
- uptr addr, int is_write, uptr access_size, u32 exp);
-
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_set_death_callback(void (*callback)(void));
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_set_error_report_callback(void (*callback)(const char*));
-
- SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
- void __asan_on_error();
-
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_print_accumulated_stats();
-
- SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
- const char* __asan_default_options();
-
- SANITIZER_INTERFACE_ATTRIBUTE
- extern uptr __asan_shadow_memory_dynamic_address;
-
- // Global flag, copy of ASAN_OPTIONS=detect_stack_use_after_return
- SANITIZER_INTERFACE_ATTRIBUTE
- extern int __asan_option_detect_stack_use_after_return;
-
- SANITIZER_INTERFACE_ATTRIBUTE
- extern uptr *__asan_test_only_reported_buggy_pointer;
-
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_load1(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_load2(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_load4(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_load8(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_load16(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_store1(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_store2(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_store4(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_store8(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_store16(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_loadN(uptr p, uptr size);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_storeN(uptr p, uptr size);
-
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_load1_noabort(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_load2_noabort(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_load4_noabort(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_load8_noabort(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_load16_noabort(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_store1_noabort(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_store2_noabort(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_store4_noabort(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_store8_noabort(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_store16_noabort(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_loadN_noabort(uptr p, uptr size);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_storeN_noabort(uptr p, uptr size);
-
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load1(uptr p, u32 exp);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load2(uptr p, u32 exp);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load4(uptr p, u32 exp);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load8(uptr p, u32 exp);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_load16(uptr p, u32 exp);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_store1(uptr p, u32 exp);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_store2(uptr p, u32 exp);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_store4(uptr p, u32 exp);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_store8(uptr p, u32 exp);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_store16(uptr p, u32 exp);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_loadN(uptr p, uptr size,
- u32 exp);
- SANITIZER_INTERFACE_ATTRIBUTE void __asan_exp_storeN(uptr p, uptr size,
- u32 exp);
-
- SANITIZER_INTERFACE_ATTRIBUTE
- void* __asan_memcpy(void *dst, const void *src, uptr size);
- SANITIZER_INTERFACE_ATTRIBUTE
- void* __asan_memset(void *s, int c, uptr n);
- SANITIZER_INTERFACE_ATTRIBUTE
- void* __asan_memmove(void* dest, const void* src, uptr n);
-
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_poison_cxx_array_cookie(uptr p);
- SANITIZER_INTERFACE_ATTRIBUTE
- uptr __asan_load_cxx_array_cookie(uptr *p);
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_poison_intra_object_redzone(uptr p, uptr size);
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_unpoison_intra_object_redzone(uptr p, uptr size);
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_alloca_poison(uptr addr, uptr size);
- SANITIZER_INTERFACE_ATTRIBUTE
- void __asan_allocas_unpoison(uptr top, uptr bottom);
-
- SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE
- const char* __asan_default_suppressions();
-} // extern "C"
-
-#endif // ASAN_INTERFACE_INTERNAL_H
diff --git a/lib/asan/asan_internal.h b/lib/asan/asan_internal.h
deleted file mode 100644
index 654878cd15f0b..0000000000000
--- a/lib/asan/asan_internal.h
+++ /dev/null
@@ -1,159 +0,0 @@
-//===-- asan_internal.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.
-//
-// ASan-private header which defines various general utilities.
-//===----------------------------------------------------------------------===//
-#ifndef ASAN_INTERNAL_H
-#define ASAN_INTERNAL_H
-
-#include "asan_flags.h"
-#include "asan_interface_internal.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_internal_defs.h"
-#include "sanitizer_common/sanitizer_stacktrace.h"
-#include "sanitizer_common/sanitizer_libc.h"
-
-#if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__)
-# error "The AddressSanitizer run-time should not be"
- " instrumented by AddressSanitizer"
-#endif
-
-// Build-time configuration options.
-
-// If set, asan will intercept C++ exception api call(s).
-#ifndef ASAN_HAS_EXCEPTIONS
-# define ASAN_HAS_EXCEPTIONS 1
-#endif
-
-// If set, values like allocator chunk size, as well as defaults for some flags
-// will be changed towards less memory overhead.
-#ifndef ASAN_LOW_MEMORY
-# if SANITIZER_IOS || SANITIZER_ANDROID || SANITIZER_RTEMS
-# define ASAN_LOW_MEMORY 1
-# else
-# define ASAN_LOW_MEMORY 0
-# endif
-#endif
-
-#ifndef ASAN_DYNAMIC
-# ifdef PIC
-# define ASAN_DYNAMIC 1
-# else
-# define ASAN_DYNAMIC 0
-# endif
-#endif
-
-// All internal functions in asan reside inside the __asan namespace
-// to avoid namespace collisions with the user programs.
-// Separate namespace also makes it simpler to distinguish the asan run-time
-// functions from the instrumented user code in a profile.
-namespace __asan {
-
-class AsanThread;
-using __sanitizer::StackTrace;
-
-void AsanInitFromRtl();
-
-// asan_win.cc
-void InitializePlatformExceptionHandlers();
-// Returns whether an address is a valid allocated system heap block.
-// 'addr' must point to the beginning of the block.
-bool IsSystemHeapAddress(uptr addr);
-
-// asan_rtl.cc
-void PrintAddressSpaceLayout();
-void NORETURN ShowStatsAndAbort();
-
-// asan_shadow_setup.cc
-void InitializeShadowMemory();
-
-// asan_malloc_linux.cc / asan_malloc_mac.cc
-void ReplaceSystemMalloc();
-
-// asan_linux.cc / asan_mac.cc / asan_rtems.cc / asan_win.cc
-uptr FindDynamicShadowStart();
-void *AsanDoesNotSupportStaticLinkage();
-void AsanCheckDynamicRTPrereqs();
-void AsanCheckIncompatibleRT();
-
-// asan_thread.cc
-AsanThread *CreateMainThread();
-
-// Support function for __asan_(un)register_image_globals. Searches for the
-// loaded image containing `needle' and then enumerates all global metadata
-// structures declared in that image, applying `op' (e.g.,
-// __asan_(un)register_globals) to them.
-typedef void (*globals_op_fptr)(__asan_global *, uptr);
-void AsanApplyToGlobals(globals_op_fptr op, const void *needle);
-
-void AsanOnDeadlySignal(int, void *siginfo, void *context);
-
-void ReadContextStack(void *context, uptr *stack, uptr *ssize);
-void StopInitOrderChecking();
-
-// Wrapper for TLS/TSD.
-void AsanTSDInit(void (*destructor)(void *tsd));
-void *AsanTSDGet();
-void AsanTSDSet(void *tsd);
-void PlatformTSDDtor(void *tsd);
-
-void AppendToErrorMessageBuffer(const char *buffer);
-
-void *AsanDlSymNext(const char *sym);
-
-void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name);
-
-// Add convenient macro for interface functions that may be represented as
-// weak hooks.
-#define ASAN_MALLOC_HOOK(ptr, size) \
- do { \
- if (&__sanitizer_malloc_hook) __sanitizer_malloc_hook(ptr, size); \
- RunMallocHooks(ptr, size); \
- } while (false)
-#define ASAN_FREE_HOOK(ptr) \
- do { \
- if (&__sanitizer_free_hook) __sanitizer_free_hook(ptr); \
- RunFreeHooks(ptr); \
- } while (false)
-#define ASAN_ON_ERROR() \
- if (&__asan_on_error) __asan_on_error()
-
-extern int asan_inited;
-// Used to avoid infinite recursion in __asan_init().
-extern bool asan_init_is_running;
-extern void (*death_callback)(void);
-// These magic values are written to shadow for better error reporting.
-const int kAsanHeapLeftRedzoneMagic = 0xfa;
-const int kAsanHeapFreeMagic = 0xfd;
-const int kAsanStackLeftRedzoneMagic = 0xf1;
-const int kAsanStackMidRedzoneMagic = 0xf2;
-const int kAsanStackRightRedzoneMagic = 0xf3;
-const int kAsanStackAfterReturnMagic = 0xf5;
-const int kAsanInitializationOrderMagic = 0xf6;
-const int kAsanUserPoisonedMemoryMagic = 0xf7;
-const int kAsanContiguousContainerOOBMagic = 0xfc;
-const int kAsanStackUseAfterScopeMagic = 0xf8;
-const int kAsanGlobalRedzoneMagic = 0xf9;
-const int kAsanInternalHeapMagic = 0xfe;
-const int kAsanArrayCookieMagic = 0xac;
-const int kAsanIntraObjectRedzone = 0xbb;
-const int kAsanAllocaLeftMagic = 0xca;
-const int kAsanAllocaRightMagic = 0xcb;
-// Used to populate the shadow gap for systems without memory
-// protection there (i.e. Myriad).
-const int kAsanShadowGap = 0xcc;
-
-static const uptr kCurrentStackFrameMagic = 0x41B58AB3;
-static const uptr kRetiredStackFrameMagic = 0x45E0360E;
-
-} // namespace __asan
-
-#endif // ASAN_INTERNAL_H
diff --git a/lib/asan/asan_linux.cc b/lib/asan/asan_linux.cc
deleted file mode 100644
index 625f32d408dfa..0000000000000
--- a/lib/asan/asan_linux.cc
+++ /dev/null
@@ -1,254 +0,0 @@
-//===-- asan_linux.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.
-//
-// Linux-specific details.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
- SANITIZER_SOLARIS
-
-#include "asan_interceptors.h"
-#include "asan_internal.h"
-#include "asan_premap_shadow.h"
-#include "asan_thread.h"
-#include "sanitizer_common/sanitizer_flags.h"
-#include "sanitizer_common/sanitizer_freebsd.h"
-#include "sanitizer_common/sanitizer_libc.h"
-#include "sanitizer_common/sanitizer_procmaps.h"
-
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <sys/mman.h>
-#include <sys/syscall.h>
-#include <sys/types.h>
-#include <dlfcn.h>
-#include <fcntl.h>
-#include <limits.h>
-#include <pthread.h>
-#include <stdio.h>
-#include <unistd.h>
-#include <unwind.h>
-
-#if SANITIZER_FREEBSD
-#include <sys/link_elf.h>
-#endif
-
-#if SANITIZER_SOLARIS
-#include <link.h>
-#endif
-
-#if SANITIZER_ANDROID || SANITIZER_FREEBSD || SANITIZER_SOLARIS
-#include <ucontext.h>
-extern "C" void* _DYNAMIC;
-#elif SANITIZER_NETBSD
-#include <link_elf.h>
-#include <ucontext.h>
-extern Elf_Dyn _DYNAMIC;
-#else
-#include <sys/ucontext.h>
-#include <link.h>
-#endif
-
-// x86-64 FreeBSD 9.2 and older define 'ucontext_t' incorrectly in
-// 32-bit mode.
-#if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32) && \
- __FreeBSD_version <= 902001 // v9.2
-#define ucontext_t xucontext_t
-#endif
-
-typedef enum {
- ASAN_RT_VERSION_UNDEFINED = 0,
- ASAN_RT_VERSION_DYNAMIC,
- ASAN_RT_VERSION_STATIC,
-} asan_rt_version_t;
-
-// FIXME: perhaps also store abi version here?
-extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE
-asan_rt_version_t __asan_rt_version;
-}
-
-namespace __asan {
-
-void InitializePlatformInterceptors() {}
-void InitializePlatformExceptionHandlers() {}
-bool IsSystemHeapAddress (uptr addr) { return false; }
-
-void *AsanDoesNotSupportStaticLinkage() {
- // This will fail to link with -static.
- return &_DYNAMIC; // defined in link.h
-}
-
-static void UnmapFromTo(uptr from, uptr to) {
- CHECK(to >= from);
- if (to == from) return;
- uptr res = internal_munmap(reinterpret_cast<void *>(from), to - from);
- if (UNLIKELY(internal_iserror(res))) {
- Report(
- "ERROR: AddresSanitizer failed to unmap 0x%zx (%zd) bytes at address "
- "%p\n",
- to - from, to - from, from);
- CHECK("unable to unmap" && 0);
- }
-}
-
-#if ASAN_PREMAP_SHADOW
-uptr FindPremappedShadowStart() {
- uptr granularity = GetMmapGranularity();
- uptr shadow_start = reinterpret_cast<uptr>(&__asan_shadow);
- uptr premap_shadow_size = PremapShadowSize();
- uptr shadow_size = RoundUpTo(kHighShadowEnd, granularity);
- // We may have mapped too much. Release extra memory.
- UnmapFromTo(shadow_start + shadow_size, shadow_start + premap_shadow_size);
- return shadow_start;
-}
-#endif
-
-uptr FindDynamicShadowStart() {
-#if ASAN_PREMAP_SHADOW
- if (!PremapShadowFailed())
- return FindPremappedShadowStart();
-#endif
-
- uptr granularity = GetMmapGranularity();
- uptr alignment = granularity * 8;
- uptr left_padding = granularity;
- uptr shadow_size = RoundUpTo(kHighShadowEnd, granularity);
- uptr map_size = shadow_size + left_padding + alignment;
-
- uptr map_start = (uptr)MmapNoAccess(map_size);
- CHECK_NE(map_start, ~(uptr)0);
-
- uptr shadow_start = RoundUpTo(map_start + left_padding, alignment);
- UnmapFromTo(map_start, shadow_start - left_padding);
- UnmapFromTo(shadow_start + shadow_size, map_start + map_size);
-
- return shadow_start;
-}
-
-void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {
- UNIMPLEMENTED();
-}
-
-#if SANITIZER_ANDROID
-// FIXME: should we do anything for Android?
-void AsanCheckDynamicRTPrereqs() {}
-void AsanCheckIncompatibleRT() {}
-#else
-static int FindFirstDSOCallback(struct dl_phdr_info *info, size_t size,
- void *data) {
- VReport(2, "info->dlpi_name = %s\tinfo->dlpi_addr = %p\n",
- info->dlpi_name, info->dlpi_addr);
-
- // Continue until the first dynamic library is found
- if (!info->dlpi_name || info->dlpi_name[0] == 0)
- return 0;
-
- // Ignore vDSO
- if (internal_strncmp(info->dlpi_name, "linux-", sizeof("linux-") - 1) == 0)
- return 0;
-
-#if SANITIZER_FREEBSD || SANITIZER_NETBSD
- // Ignore first entry (the main program)
- char **p = (char **)data;
- if (!(*p)) {
- *p = (char *)-1;
- return 0;
- }
-#endif
-
-#if SANITIZER_SOLARIS
- // Ignore executable on Solaris
- if (info->dlpi_addr == 0)
- return 0;
-#endif
-
- *(const char **)data = info->dlpi_name;
- return 1;
-}
-
-static bool IsDynamicRTName(const char *libname) {
- return internal_strstr(libname, "libclang_rt.asan") ||
- internal_strstr(libname, "libasan.so");
-}
-
-static void ReportIncompatibleRT() {
- Report("Your application is linked against incompatible ASan runtimes.\n");
- Die();
-}
-
-void AsanCheckDynamicRTPrereqs() {
- if (!ASAN_DYNAMIC || !flags()->verify_asan_link_order)
- return;
-
- // Ensure that dynamic RT is the first DSO in the list
- const char *first_dso_name = nullptr;
- dl_iterate_phdr(FindFirstDSOCallback, &first_dso_name);
- if (first_dso_name && !IsDynamicRTName(first_dso_name)) {
- Report("ASan runtime does not come first in initial library list; "
- "you should either link runtime to your application or "
- "manually preload it with LD_PRELOAD.\n");
- Die();
- }
-}
-
-void AsanCheckIncompatibleRT() {
- if (ASAN_DYNAMIC) {
- if (__asan_rt_version == ASAN_RT_VERSION_UNDEFINED) {
- __asan_rt_version = ASAN_RT_VERSION_DYNAMIC;
- } else if (__asan_rt_version != ASAN_RT_VERSION_DYNAMIC) {
- ReportIncompatibleRT();
- }
- } else {
- if (__asan_rt_version == ASAN_RT_VERSION_UNDEFINED) {
- // Ensure that dynamic runtime is not present. We should detect it
- // as early as possible, otherwise ASan interceptors could bind to
- // the functions in dynamic ASan runtime instead of the functions in
- // system libraries, causing crashes later in ASan initialization.
- MemoryMappingLayout proc_maps(/*cache_enabled*/true);
- char filename[PATH_MAX];
- MemoryMappedSegment segment(filename, sizeof(filename));
- while (proc_maps.Next(&segment)) {
- if (IsDynamicRTName(segment.filename)) {
- Report("Your application is linked against "
- "incompatible ASan runtimes.\n");
- Die();
- }
- }
- __asan_rt_version = ASAN_RT_VERSION_STATIC;
- } else if (__asan_rt_version != ASAN_RT_VERSION_STATIC) {
- ReportIncompatibleRT();
- }
- }
-}
-#endif // SANITIZER_ANDROID
-
-#if !SANITIZER_ANDROID
-void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
- ucontext_t *ucp = (ucontext_t*)context;
- *stack = (uptr)ucp->uc_stack.ss_sp;
- *ssize = ucp->uc_stack.ss_size;
-}
-#else
-void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
- UNIMPLEMENTED();
-}
-#endif
-
-void *AsanDlSymNext(const char *sym) {
- return dlsym(RTLD_NEXT, sym);
-}
-
-} // namespace __asan
-
-#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD ||
- // SANITIZER_SOLARIS
diff --git a/lib/asan/asan_lock.h b/lib/asan/asan_lock.h
deleted file mode 100644
index e69de29bb2d1d..0000000000000
--- a/lib/asan/asan_lock.h
+++ /dev/null
diff --git a/lib/asan/asan_mac.cc b/lib/asan/asan_mac.cc
deleted file mode 100644
index 17a0ec57701d9..0000000000000
--- a/lib/asan/asan_mac.cc
+++ /dev/null
@@ -1,332 +0,0 @@
-//===-- asan_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.
-//
-// Mac-specific details.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_MAC
-
-#include "asan_interceptors.h"
-#include "asan_internal.h"
-#include "asan_mapping.h"
-#include "asan_stack.h"
-#include "asan_thread.h"
-#include "sanitizer_common/sanitizer_atomic.h"
-#include "sanitizer_common/sanitizer_libc.h"
-#include "sanitizer_common/sanitizer_mac.h"
-
-#include <dlfcn.h>
-#include <fcntl.h>
-#include <libkern/OSAtomic.h>
-#include <mach-o/dyld.h>
-#include <mach-o/getsect.h>
-#include <mach-o/loader.h>
-#include <pthread.h>
-#include <stdlib.h> // for free()
-#include <sys/mman.h>
-#include <sys/resource.h>
-#include <sys/sysctl.h>
-#include <sys/ucontext.h>
-#include <unistd.h>
-
-// from <crt_externs.h>, but we don't have that file on iOS
-extern "C" {
- extern char ***_NSGetArgv(void);
- extern char ***_NSGetEnviron(void);
-}
-
-namespace __asan {
-
-void InitializePlatformInterceptors() {}
-void InitializePlatformExceptionHandlers() {}
-bool IsSystemHeapAddress (uptr addr) { return false; }
-
-// No-op. Mac does not support static linkage anyway.
-void *AsanDoesNotSupportStaticLinkage() {
- return 0;
-}
-
-uptr FindDynamicShadowStart() {
- uptr granularity = GetMmapGranularity();
- uptr alignment = 8 * granularity;
- uptr left_padding = granularity;
- uptr space_size = kHighShadowEnd + left_padding;
-
- uptr largest_gap_found = 0;
- uptr max_occupied_addr = 0;
- VReport(2, "FindDynamicShadowStart, space_size = %p\n", space_size);
- uptr shadow_start =
- FindAvailableMemoryRange(space_size, alignment, granularity,
- &largest_gap_found, &max_occupied_addr);
- // If the shadow doesn't fit, restrict the address space to make it fit.
- if (shadow_start == 0) {
- VReport(
- 2,
- "Shadow doesn't fit, largest_gap_found = %p, max_occupied_addr = %p\n",
- largest_gap_found, max_occupied_addr);
- uptr new_max_vm = RoundDownTo(largest_gap_found << SHADOW_SCALE, alignment);
- if (new_max_vm < max_occupied_addr) {
- Report("Unable to find a memory range for dynamic shadow.\n");
- Report(
- "space_size = %p, largest_gap_found = %p, max_occupied_addr = %p, "
- "new_max_vm = %p\n",
- space_size, largest_gap_found, max_occupied_addr, new_max_vm);
- CHECK(0 && "cannot place shadow");
- }
- RestrictMemoryToMaxAddress(new_max_vm);
- kHighMemEnd = new_max_vm - 1;
- space_size = kHighShadowEnd + left_padding;
- VReport(2, "FindDynamicShadowStart, space_size = %p\n", space_size);
- shadow_start = FindAvailableMemoryRange(space_size, alignment, granularity,
- nullptr, nullptr);
- if (shadow_start == 0) {
- Report("Unable to find a memory range after restricting VM.\n");
- CHECK(0 && "cannot place shadow after restricting vm");
- }
- }
- CHECK_NE((uptr)0, shadow_start);
- CHECK(IsAligned(shadow_start, alignment));
- return shadow_start;
-}
-
-// No-op. Mac does not support static linkage anyway.
-void AsanCheckDynamicRTPrereqs() {}
-
-// No-op. Mac does not support static linkage anyway.
-void AsanCheckIncompatibleRT() {}
-
-void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {
- // Find the Mach-O header for the image containing the needle
- Dl_info info;
- int err = dladdr(needle, &info);
- if (err == 0) return;
-
-#if __LP64__
- const struct mach_header_64 *mh = (struct mach_header_64 *)info.dli_fbase;
-#else
- const struct mach_header *mh = (struct mach_header *)info.dli_fbase;
-#endif
-
- // Look up the __asan_globals section in that image and register its globals
- unsigned long size = 0;
- __asan_global *globals = (__asan_global *)getsectiondata(
- mh,
- "__DATA", "__asan_globals",
- &size);
-
- if (!globals) return;
- if (size % sizeof(__asan_global) != 0) return;
- op(globals, size / sizeof(__asan_global));
-}
-
-void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
- UNIMPLEMENTED();
-}
-
-// Support for the following functions from libdispatch on Mac OS:
-// dispatch_async_f()
-// dispatch_async()
-// dispatch_sync_f()
-// dispatch_sync()
-// dispatch_after_f()
-// dispatch_after()
-// dispatch_group_async_f()
-// dispatch_group_async()
-// TODO(glider): libdispatch API contains other functions that we don't support
-// yet.
-//
-// dispatch_sync() and dispatch_sync_f() are synchronous, although chances are
-// they can cause jobs to run on a thread different from the current one.
-// TODO(glider): if so, we need a test for this (otherwise we should remove
-// them).
-//
-// The following functions use dispatch_barrier_async_f() (which isn't a library
-// function but is exported) and are thus supported:
-// dispatch_source_set_cancel_handler_f()
-// dispatch_source_set_cancel_handler()
-// dispatch_source_set_event_handler_f()
-// dispatch_source_set_event_handler()
-//
-// The reference manual for Grand Central Dispatch is available at
-// http://developer.apple.com/library/mac/#documentation/Performance/Reference/GCD_libdispatch_Ref/Reference/reference.html
-// The implementation details are at
-// http://libdispatch.macosforge.org/trac/browser/trunk/src/queue.c
-
-typedef void* dispatch_group_t;
-typedef void* dispatch_queue_t;
-typedef void* dispatch_source_t;
-typedef u64 dispatch_time_t;
-typedef void (*dispatch_function_t)(void *block);
-typedef void* (*worker_t)(void *block);
-
-// A wrapper for the ObjC blocks used to support libdispatch.
-typedef struct {
- void *block;
- dispatch_function_t func;
- u32 parent_tid;
-} asan_block_context_t;
-
-ALWAYS_INLINE
-void asan_register_worker_thread(int parent_tid, StackTrace *stack) {
- AsanThread *t = GetCurrentThread();
- if (!t) {
- t = AsanThread::Create(/* start_routine */ nullptr, /* arg */ nullptr,
- parent_tid, stack, /* detached */ true);
- t->Init();
- asanThreadRegistry().StartThread(t->tid(), GetTid(),
- /* workerthread */ true, 0);
- SetCurrentThread(t);
- }
-}
-
-// For use by only those functions that allocated the context via
-// alloc_asan_context().
-extern "C"
-void asan_dispatch_call_block_and_release(void *block) {
- GET_STACK_TRACE_THREAD;
- asan_block_context_t *context = (asan_block_context_t*)block;
- VReport(2,
- "asan_dispatch_call_block_and_release(): "
- "context: %p, pthread_self: %p\n",
- block, pthread_self());
- asan_register_worker_thread(context->parent_tid, &stack);
- // Call the original dispatcher for the block.
- context->func(context->block);
- asan_free(context, &stack, FROM_MALLOC);
-}
-
-} // namespace __asan
-
-using namespace __asan; // NOLINT
-
-// Wrap |ctxt| and |func| into an asan_block_context_t.
-// The caller retains control of the allocated context.
-extern "C"
-asan_block_context_t *alloc_asan_context(void *ctxt, dispatch_function_t func,
- BufferedStackTrace *stack) {
- asan_block_context_t *asan_ctxt =
- (asan_block_context_t*) asan_malloc(sizeof(asan_block_context_t), stack);
- asan_ctxt->block = ctxt;
- asan_ctxt->func = func;
- asan_ctxt->parent_tid = GetCurrentTidOrInvalid();
- return asan_ctxt;
-}
-
-// Define interceptor for dispatch_*_f function with the three most common
-// parameters: dispatch_queue_t, context, dispatch_function_t.
-#define INTERCEPT_DISPATCH_X_F_3(dispatch_x_f) \
- INTERCEPTOR(void, dispatch_x_f, dispatch_queue_t dq, void *ctxt, \
- dispatch_function_t func) { \
- GET_STACK_TRACE_THREAD; \
- asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); \
- if (Verbosity() >= 2) { \
- Report(#dispatch_x_f "(): context: %p, pthread_self: %p\n", \
- asan_ctxt, pthread_self()); \
- PRINT_CURRENT_STACK(); \
- } \
- return REAL(dispatch_x_f)(dq, (void*)asan_ctxt, \
- asan_dispatch_call_block_and_release); \
- }
-
-INTERCEPT_DISPATCH_X_F_3(dispatch_async_f)
-INTERCEPT_DISPATCH_X_F_3(dispatch_sync_f)
-INTERCEPT_DISPATCH_X_F_3(dispatch_barrier_async_f)
-
-INTERCEPTOR(void, dispatch_after_f, dispatch_time_t when,
- dispatch_queue_t dq, void *ctxt,
- dispatch_function_t func) {
- GET_STACK_TRACE_THREAD;
- asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack);
- if (Verbosity() >= 2) {
- Report("dispatch_after_f: %p\n", asan_ctxt);
- PRINT_CURRENT_STACK();
- }
- return REAL(dispatch_after_f)(when, dq, (void*)asan_ctxt,
- asan_dispatch_call_block_and_release);
-}
-
-INTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group,
- dispatch_queue_t dq, void *ctxt,
- dispatch_function_t func) {
- GET_STACK_TRACE_THREAD;
- asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack);
- if (Verbosity() >= 2) {
- Report("dispatch_group_async_f(): context: %p, pthread_self: %p\n",
- asan_ctxt, pthread_self());
- PRINT_CURRENT_STACK();
- }
- REAL(dispatch_group_async_f)(group, dq, (void*)asan_ctxt,
- asan_dispatch_call_block_and_release);
-}
-
-#if !defined(MISSING_BLOCKS_SUPPORT)
-extern "C" {
-void dispatch_async(dispatch_queue_t dq, void(^work)(void));
-void dispatch_group_async(dispatch_group_t dg, dispatch_queue_t dq,
- void(^work)(void));
-void dispatch_after(dispatch_time_t when, dispatch_queue_t queue,
- void(^work)(void));
-void dispatch_source_set_cancel_handler(dispatch_source_t ds,
- void(^work)(void));
-void dispatch_source_set_event_handler(dispatch_source_t ds, void(^work)(void));
-}
-
-#define GET_ASAN_BLOCK(work) \
- void (^asan_block)(void); \
- int parent_tid = GetCurrentTidOrInvalid(); \
- asan_block = ^(void) { \
- GET_STACK_TRACE_THREAD; \
- asan_register_worker_thread(parent_tid, &stack); \
- work(); \
- }
-
-INTERCEPTOR(void, dispatch_async,
- dispatch_queue_t dq, void(^work)(void)) {
- ENABLE_FRAME_POINTER;
- GET_ASAN_BLOCK(work);
- REAL(dispatch_async)(dq, asan_block);
-}
-
-INTERCEPTOR(void, dispatch_group_async,
- dispatch_group_t dg, dispatch_queue_t dq, void(^work)(void)) {
- ENABLE_FRAME_POINTER;
- GET_ASAN_BLOCK(work);
- REAL(dispatch_group_async)(dg, dq, asan_block);
-}
-
-INTERCEPTOR(void, dispatch_after,
- dispatch_time_t when, dispatch_queue_t queue, void(^work)(void)) {
- ENABLE_FRAME_POINTER;
- GET_ASAN_BLOCK(work);
- REAL(dispatch_after)(when, queue, asan_block);
-}
-
-INTERCEPTOR(void, dispatch_source_set_cancel_handler,
- dispatch_source_t ds, void(^work)(void)) {
- if (!work) {
- REAL(dispatch_source_set_cancel_handler)(ds, work);
- return;
- }
- ENABLE_FRAME_POINTER;
- GET_ASAN_BLOCK(work);
- REAL(dispatch_source_set_cancel_handler)(ds, asan_block);
-}
-
-INTERCEPTOR(void, dispatch_source_set_event_handler,
- dispatch_source_t ds, void(^work)(void)) {
- ENABLE_FRAME_POINTER;
- GET_ASAN_BLOCK(work);
- REAL(dispatch_source_set_event_handler)(ds, asan_block);
-}
-#endif
-
-#endif // SANITIZER_MAC
diff --git a/lib/asan/asan_malloc_linux.cc b/lib/asan/asan_malloc_linux.cc
deleted file mode 100644
index 76bdff999d624..0000000000000
--- a/lib/asan/asan_malloc_linux.cc
+++ /dev/null
@@ -1,300 +0,0 @@
-//===-- asan_malloc_linux.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.
-//
-// Linux-specific malloc interception.
-// We simply define functions like malloc, free, realloc, etc.
-// They will replace the corresponding libc functions automagically.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX || \
- SANITIZER_NETBSD || SANITIZER_RTEMS || SANITIZER_SOLARIS
-
-#include "sanitizer_common/sanitizer_allocator_checks.h"
-#include "sanitizer_common/sanitizer_errno.h"
-#include "sanitizer_common/sanitizer_tls_get_addr.h"
-#include "asan_allocator.h"
-#include "asan_interceptors.h"
-#include "asan_internal.h"
-#include "asan_malloc_local.h"
-#include "asan_stack.h"
-
-// ---------------------- Replacement functions ---------------- {{{1
-using namespace __asan; // NOLINT
-
-static uptr allocated_for_dlsym;
-static uptr last_dlsym_alloc_size_in_words;
-static const uptr kDlsymAllocPoolSize = SANITIZER_RTEMS ? 4096 : 1024;
-static uptr alloc_memory_for_dlsym[kDlsymAllocPoolSize];
-
-static INLINE bool IsInDlsymAllocPool(const void *ptr) {
- uptr off = (uptr)ptr - (uptr)alloc_memory_for_dlsym;
- return off < allocated_for_dlsym * sizeof(alloc_memory_for_dlsym[0]);
-}
-
-static void *AllocateFromLocalPool(uptr size_in_bytes) {
- uptr size_in_words = RoundUpTo(size_in_bytes, kWordSize) / kWordSize;
- void *mem = (void*)&alloc_memory_for_dlsym[allocated_for_dlsym];
- last_dlsym_alloc_size_in_words = size_in_words;
- allocated_for_dlsym += size_in_words;
- CHECK_LT(allocated_for_dlsym, kDlsymAllocPoolSize);
- return mem;
-}
-
-static void DeallocateFromLocalPool(const void *ptr) {
- // Hack: since glibc 2.27 dlsym no longer uses stack-allocated memory to store
- // error messages and instead uses malloc followed by free. To avoid pool
- // exhaustion due to long object filenames, handle that special case here.
- uptr prev_offset = allocated_for_dlsym - last_dlsym_alloc_size_in_words;
- void *prev_mem = (void*)&alloc_memory_for_dlsym[prev_offset];
- if (prev_mem == ptr) {
- REAL(memset)(prev_mem, 0, last_dlsym_alloc_size_in_words * kWordSize);
- allocated_for_dlsym = prev_offset;
- last_dlsym_alloc_size_in_words = 0;
- }
-}
-
-static int PosixMemalignFromLocalPool(void **memptr, uptr alignment,
- uptr size_in_bytes) {
- if (UNLIKELY(!CheckPosixMemalignAlignment(alignment)))
- return errno_EINVAL;
-
- CHECK(alignment >= kWordSize);
-
- uptr addr = (uptr)&alloc_memory_for_dlsym[allocated_for_dlsym];
- uptr aligned_addr = RoundUpTo(addr, alignment);
- uptr aligned_size = RoundUpTo(size_in_bytes, kWordSize);
-
- uptr *end_mem = (uptr*)(aligned_addr + aligned_size);
- uptr allocated = end_mem - alloc_memory_for_dlsym;
- if (allocated >= kDlsymAllocPoolSize)
- return errno_ENOMEM;
-
- allocated_for_dlsym = allocated;
- *memptr = (void*)aligned_addr;
- return 0;
-}
-
-#if SANITIZER_RTEMS
-void* MemalignFromLocalPool(uptr alignment, uptr size) {
- void *ptr = nullptr;
- alignment = Max(alignment, kWordSize);
- PosixMemalignFromLocalPool(&ptr, alignment, size);
- return ptr;
-}
-
-bool IsFromLocalPool(const void *ptr) {
- return IsInDlsymAllocPool(ptr);
-}
-#endif
-
-static INLINE bool MaybeInDlsym() {
- // Fuchsia doesn't use dlsym-based interceptors.
- return !SANITIZER_FUCHSIA && asan_init_is_running;
-}
-
-static INLINE bool UseLocalPool() {
- return EarlyMalloc() || MaybeInDlsym();
-}
-
-static void *ReallocFromLocalPool(void *ptr, uptr size) {
- const uptr offset = (uptr)ptr - (uptr)alloc_memory_for_dlsym;
- const uptr copy_size = Min(size, kDlsymAllocPoolSize - offset);
- void *new_ptr;
- if (UNLIKELY(UseLocalPool())) {
- new_ptr = AllocateFromLocalPool(size);
- } else {
- ENSURE_ASAN_INITED();
- GET_STACK_TRACE_MALLOC;
- new_ptr = asan_malloc(size, &stack);
- }
- internal_memcpy(new_ptr, ptr, copy_size);
- return new_ptr;
-}
-
-INTERCEPTOR(void, free, void *ptr) {
- GET_STACK_TRACE_FREE;
- if (UNLIKELY(IsInDlsymAllocPool(ptr))) {
- DeallocateFromLocalPool(ptr);
- return;
- }
- asan_free(ptr, &stack, FROM_MALLOC);
-}
-
-#if SANITIZER_INTERCEPT_CFREE
-INTERCEPTOR(void, cfree, void *ptr) {
- GET_STACK_TRACE_FREE;
- if (UNLIKELY(IsInDlsymAllocPool(ptr)))
- return;
- asan_free(ptr, &stack, FROM_MALLOC);
-}
-#endif // SANITIZER_INTERCEPT_CFREE
-
-INTERCEPTOR(void*, malloc, uptr size) {
- if (UNLIKELY(UseLocalPool()))
- // Hack: dlsym calls malloc before REAL(malloc) is retrieved from dlsym.
- return AllocateFromLocalPool(size);
- ENSURE_ASAN_INITED();
- GET_STACK_TRACE_MALLOC;
- return asan_malloc(size, &stack);
-}
-
-INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) {
- if (UNLIKELY(UseLocalPool()))
- // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym.
- return AllocateFromLocalPool(nmemb * size);
- ENSURE_ASAN_INITED();
- GET_STACK_TRACE_MALLOC;
- return asan_calloc(nmemb, size, &stack);
-}
-
-INTERCEPTOR(void*, realloc, void *ptr, uptr size) {
- if (UNLIKELY(IsInDlsymAllocPool(ptr)))
- return ReallocFromLocalPool(ptr, size);
- if (UNLIKELY(UseLocalPool()))
- return AllocateFromLocalPool(size);
- ENSURE_ASAN_INITED();
- GET_STACK_TRACE_MALLOC;
- return asan_realloc(ptr, size, &stack);
-}
-
-#if SANITIZER_INTERCEPT_MEMALIGN
-INTERCEPTOR(void*, memalign, uptr boundary, uptr size) {
- GET_STACK_TRACE_MALLOC;
- return asan_memalign(boundary, size, &stack, FROM_MALLOC);
-}
-
-INTERCEPTOR(void*, __libc_memalign, uptr boundary, uptr size) {
- GET_STACK_TRACE_MALLOC;
- void *res = asan_memalign(boundary, size, &stack, FROM_MALLOC);
- DTLS_on_libc_memalign(res, size);
- return res;
-}
-#endif // SANITIZER_INTERCEPT_MEMALIGN
-
-#if SANITIZER_INTERCEPT_ALIGNED_ALLOC
-INTERCEPTOR(void*, aligned_alloc, uptr boundary, uptr size) {
- GET_STACK_TRACE_MALLOC;
- return asan_aligned_alloc(boundary, size, &stack);
-}
-#endif // SANITIZER_INTERCEPT_ALIGNED_ALLOC
-
-INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
- GET_CURRENT_PC_BP_SP;
- (void)sp;
- return asan_malloc_usable_size(ptr, pc, bp);
-}
-
-#if SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
-// We avoid including malloc.h for portability reasons.
-// man mallinfo says the fields are "long", but the implementation uses int.
-// It doesn't matter much -- we just need to make sure that the libc's mallinfo
-// is not called.
-struct fake_mallinfo {
- int x[10];
-};
-
-INTERCEPTOR(struct fake_mallinfo, mallinfo, void) {
- struct fake_mallinfo res;
- REAL(memset)(&res, 0, sizeof(res));
- return res;
-}
-
-INTERCEPTOR(int, mallopt, int cmd, int value) {
- return -1;
-}
-#endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO
-
-INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) {
- if (UNLIKELY(UseLocalPool()))
- return PosixMemalignFromLocalPool(memptr, alignment, size);
- GET_STACK_TRACE_MALLOC;
- return asan_posix_memalign(memptr, alignment, size, &stack);
-}
-
-INTERCEPTOR(void*, valloc, uptr size) {
- GET_STACK_TRACE_MALLOC;
- return asan_valloc(size, &stack);
-}
-
-#if SANITIZER_INTERCEPT_PVALLOC
-INTERCEPTOR(void*, pvalloc, uptr size) {
- GET_STACK_TRACE_MALLOC;
- return asan_pvalloc(size, &stack);
-}
-#endif // SANITIZER_INTERCEPT_PVALLOC
-
-INTERCEPTOR(void, malloc_stats, void) {
- __asan_print_accumulated_stats();
-}
-
-#if SANITIZER_ANDROID
-// Format of __libc_malloc_dispatch has changed in Android L.
-// While we are moving towards a solution that does not depend on bionic
-// internals, here is something to support both K* and L releases.
-struct MallocDebugK {
- void *(*malloc)(uptr bytes);
- void (*free)(void *mem);
- void *(*calloc)(uptr n_elements, uptr elem_size);
- void *(*realloc)(void *oldMem, uptr bytes);
- void *(*memalign)(uptr alignment, uptr bytes);
- uptr (*malloc_usable_size)(void *mem);
-};
-
-struct MallocDebugL {
- void *(*calloc)(uptr n_elements, uptr elem_size);
- void (*free)(void *mem);
- fake_mallinfo (*mallinfo)(void);
- void *(*malloc)(uptr bytes);
- uptr (*malloc_usable_size)(void *mem);
- void *(*memalign)(uptr alignment, uptr bytes);
- int (*posix_memalign)(void **memptr, uptr alignment, uptr size);
- void* (*pvalloc)(uptr size);
- void *(*realloc)(void *oldMem, uptr bytes);
- void* (*valloc)(uptr size);
-};
-
-ALIGNED(32) const MallocDebugK asan_malloc_dispatch_k = {
- WRAP(malloc), WRAP(free), WRAP(calloc),
- WRAP(realloc), WRAP(memalign), WRAP(malloc_usable_size)};
-
-ALIGNED(32) const MallocDebugL asan_malloc_dispatch_l = {
- WRAP(calloc), WRAP(free), WRAP(mallinfo),
- WRAP(malloc), WRAP(malloc_usable_size), WRAP(memalign),
- WRAP(posix_memalign), WRAP(pvalloc), WRAP(realloc),
- WRAP(valloc)};
-
-namespace __asan {
-void ReplaceSystemMalloc() {
- void **__libc_malloc_dispatch_p =
- (void **)AsanDlSymNext("__libc_malloc_dispatch");
- if (__libc_malloc_dispatch_p) {
- // Decide on K vs L dispatch format by the presence of
- // __libc_malloc_default_dispatch export in libc.
- void *default_dispatch_p = AsanDlSymNext("__libc_malloc_default_dispatch");
- if (default_dispatch_p)
- *__libc_malloc_dispatch_p = (void *)&asan_malloc_dispatch_k;
- else
- *__libc_malloc_dispatch_p = (void *)&asan_malloc_dispatch_l;
- }
-}
-} // namespace __asan
-
-#else // SANITIZER_ANDROID
-
-namespace __asan {
-void ReplaceSystemMalloc() {
-}
-} // namespace __asan
-#endif // SANITIZER_ANDROID
-
-#endif // SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX ||
- // SANITIZER_NETBSD || SANITIZER_SOLARIS
diff --git a/lib/asan/asan_malloc_local.h b/lib/asan/asan_malloc_local.h
deleted file mode 100644
index 0e8de207d98d3..0000000000000
--- a/lib/asan/asan_malloc_local.h
+++ /dev/null
@@ -1,44 +0,0 @@
-//===-- asan_malloc_local.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.
-//
-// Provide interfaces to check for and handle local pool memory allocation.
-//===----------------------------------------------------------------------===//
-
-#ifndef ASAN_MALLOC_LOCAL_H
-#define ASAN_MALLOC_LOCAL_H
-
-#include "sanitizer_common/sanitizer_platform.h"
-#include "asan_internal.h"
-
-// On RTEMS, we use the local pool to handle memory allocation when the ASan
-// run-time is not up.
-static INLINE bool EarlyMalloc() {
- return SANITIZER_RTEMS && (!__asan::asan_inited ||
- __asan::asan_init_is_running);
-}
-
-void* MemalignFromLocalPool(uptr alignment, uptr size);
-
-#if SANITIZER_RTEMS
-
-bool IsFromLocalPool(const void *ptr);
-
-#define ALLOCATE_FROM_LOCAL_POOL UNLIKELY(EarlyMalloc())
-#define IS_FROM_LOCAL_POOL(ptr) UNLIKELY(IsFromLocalPool(ptr))
-
-#else // SANITIZER_RTEMS
-
-#define ALLOCATE_FROM_LOCAL_POOL 0
-#define IS_FROM_LOCAL_POOL(ptr) 0
-
-#endif // SANITIZER_RTEMS
-
-#endif // ASAN_MALLOC_LOCAL_H
diff --git a/lib/asan/asan_malloc_mac.cc b/lib/asan/asan_malloc_mac.cc
deleted file mode 100644
index 733ba2d86e13b..0000000000000
--- a/lib/asan/asan_malloc_mac.cc
+++ /dev/null
@@ -1,64 +0,0 @@
-//===-- asan_malloc_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.
-//
-// Mac-specific malloc interception.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_MAC
-
-#include "asan_interceptors.h"
-#include "asan_report.h"
-#include "asan_stack.h"
-#include "asan_stats.h"
-
-using namespace __asan;
-#define COMMON_MALLOC_ZONE_NAME "asan"
-#define COMMON_MALLOC_ENTER() ENSURE_ASAN_INITED()
-#define COMMON_MALLOC_SANITIZER_INITIALIZED asan_inited
-#define COMMON_MALLOC_FORCE_LOCK() asan_mz_force_lock()
-#define COMMON_MALLOC_FORCE_UNLOCK() asan_mz_force_unlock()
-#define COMMON_MALLOC_MEMALIGN(alignment, size) \
- GET_STACK_TRACE_MALLOC; \
- void *p = asan_memalign(alignment, size, &stack, FROM_MALLOC)
-#define COMMON_MALLOC_MALLOC(size) \
- GET_STACK_TRACE_MALLOC; \
- void *p = asan_malloc(size, &stack)
-#define COMMON_MALLOC_REALLOC(ptr, size) \
- GET_STACK_TRACE_MALLOC; \
- void *p = asan_realloc(ptr, size, &stack);
-#define COMMON_MALLOC_CALLOC(count, size) \
- GET_STACK_TRACE_MALLOC; \
- void *p = asan_calloc(count, size, &stack);
-#define COMMON_MALLOC_POSIX_MEMALIGN(memptr, alignment, size) \
- GET_STACK_TRACE_MALLOC; \
- int res = asan_posix_memalign(memptr, alignment, size, &stack);
-#define COMMON_MALLOC_VALLOC(size) \
- GET_STACK_TRACE_MALLOC; \
- void *p = asan_memalign(GetPageSizeCached(), size, &stack, FROM_MALLOC);
-#define COMMON_MALLOC_FREE(ptr) \
- GET_STACK_TRACE_FREE; \
- asan_free(ptr, &stack, FROM_MALLOC);
-#define COMMON_MALLOC_SIZE(ptr) \
- uptr size = asan_mz_size(ptr);
-#define COMMON_MALLOC_FILL_STATS(zone, stats) \
- AsanMallocStats malloc_stats; \
- FillMallocStatistics(&malloc_stats); \
- CHECK(sizeof(malloc_statistics_t) == sizeof(AsanMallocStats)); \
- internal_memcpy(stats, &malloc_stats, sizeof(malloc_statistics_t));
-#define COMMON_MALLOC_REPORT_UNKNOWN_REALLOC(ptr, zone_ptr, zone_name) \
- GET_STACK_TRACE_FREE; \
- ReportMacMzReallocUnknown((uptr)ptr, (uptr)zone_ptr, zone_name, &stack);
-#define COMMON_MALLOC_NAMESPACE __asan
-
-#include "sanitizer_common/sanitizer_malloc_mac.inc"
-
-#endif
diff --git a/lib/asan/asan_malloc_win.cc b/lib/asan/asan_malloc_win.cc
deleted file mode 100644
index efa0582439793..0000000000000
--- a/lib/asan/asan_malloc_win.cc
+++ /dev/null
@@ -1,252 +0,0 @@
-//===-- asan_malloc_win.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.
-//
-// Windows-specific malloc interception.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_WINDOWS
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-#include "asan_allocator.h"
-#include "asan_interceptors.h"
-#include "asan_internal.h"
-#include "asan_stack.h"
-#include "interception/interception.h"
-
-#include <stddef.h>
-
-using namespace __asan; // NOLINT
-
-// MT: Simply defining functions with the same signature in *.obj
-// files overrides the standard functions in the CRT.
-// MD: Memory allocation functions are defined in the CRT .dll,
-// so we have to intercept them before they are called for the first time.
-
-#if ASAN_DYNAMIC
-# define ALLOCATION_FUNCTION_ATTRIBUTE
-#else
-# define ALLOCATION_FUNCTION_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE
-#endif
-
-extern "C" {
-ALLOCATION_FUNCTION_ATTRIBUTE
-void free(void *ptr) {
- GET_STACK_TRACE_FREE;
- return asan_free(ptr, &stack, FROM_MALLOC);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void _free_dbg(void *ptr, int) {
- free(ptr);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void _free_base(void *ptr) {
- free(ptr);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *malloc(size_t size) {
- GET_STACK_TRACE_MALLOC;
- return asan_malloc(size, &stack);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_malloc_base(size_t size) {
- return malloc(size);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_malloc_dbg(size_t size, int, const char *, int) {
- return malloc(size);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *calloc(size_t nmemb, size_t size) {
- GET_STACK_TRACE_MALLOC;
- return asan_calloc(nmemb, size, &stack);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_calloc_base(size_t nmemb, size_t size) {
- return calloc(nmemb, size);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_calloc_dbg(size_t nmemb, size_t size, int, const char *, int) {
- return calloc(nmemb, size);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_calloc_impl(size_t nmemb, size_t size, int *errno_tmp) {
- return calloc(nmemb, size);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *realloc(void *ptr, size_t size) {
- GET_STACK_TRACE_MALLOC;
- return asan_realloc(ptr, size, &stack);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_realloc_dbg(void *ptr, size_t size, int) {
- UNREACHABLE("_realloc_dbg should not exist!");
- return 0;
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_realloc_base(void *ptr, size_t size) {
- return realloc(ptr, size);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_recalloc(void *p, size_t n, size_t elem_size) {
- if (!p)
- return calloc(n, elem_size);
- const size_t size = n * elem_size;
- if (elem_size != 0 && size / elem_size != n)
- return 0;
- return realloc(p, size);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_recalloc_base(void *p, size_t n, size_t elem_size) {
- return _recalloc(p, n, elem_size);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-size_t _msize(const void *ptr) {
- GET_CURRENT_PC_BP_SP;
- (void)sp;
- return asan_malloc_usable_size(ptr, pc, bp);
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_expand(void *memblock, size_t size) {
- // _expand is used in realloc-like functions to resize the buffer if possible.
- // We don't want memory to stand still while resizing buffers, so return 0.
- return 0;
-}
-
-ALLOCATION_FUNCTION_ATTRIBUTE
-void *_expand_dbg(void *memblock, size_t size) {
- return _expand(memblock, size);
-}
-
-// TODO(timurrrr): Might want to add support for _aligned_* allocation
-// functions to detect a bit more bugs. Those functions seem to wrap malloc().
-
-int _CrtDbgReport(int, const char*, int,
- const char*, const char*, ...) {
- ShowStatsAndAbort();
-}
-
-int _CrtDbgReportW(int reportType, const wchar_t*, int,
- const wchar_t*, const wchar_t*, ...) {
- ShowStatsAndAbort();
-}
-
-int _CrtSetReportMode(int, int) {
- return 0;
-}
-} // extern "C"
-
-INTERCEPTOR_WINAPI(LPVOID, HeapAlloc, HANDLE hHeap, DWORD dwFlags,
- SIZE_T dwBytes) {
- GET_STACK_TRACE_MALLOC;
- void *p = asan_malloc(dwBytes, &stack);
- // Reading MSDN suggests that the *entire* usable allocation is zeroed out.
- // Otherwise it is difficult to HeapReAlloc with HEAP_ZERO_MEMORY.
- // https://blogs.msdn.microsoft.com/oldnewthing/20120316-00/?p=8083
- if (dwFlags == HEAP_ZERO_MEMORY)
- internal_memset(p, 0, asan_mz_size(p));
- else
- CHECK(dwFlags == 0 && "unsupported heap flags");
- return p;
-}
-
-INTERCEPTOR_WINAPI(BOOL, HeapFree, HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) {
- CHECK(dwFlags == 0 && "unsupported heap flags");
- GET_STACK_TRACE_FREE;
- asan_free(lpMem, &stack, FROM_MALLOC);
- return true;
-}
-
-INTERCEPTOR_WINAPI(LPVOID, HeapReAlloc, HANDLE hHeap, DWORD dwFlags,
- LPVOID lpMem, SIZE_T dwBytes) {
- GET_STACK_TRACE_MALLOC;
- // Realloc should never reallocate in place.
- if (dwFlags & HEAP_REALLOC_IN_PLACE_ONLY)
- return nullptr;
- CHECK(dwFlags == 0 && "unsupported heap flags");
- return asan_realloc(lpMem, dwBytes, &stack);
-}
-
-INTERCEPTOR_WINAPI(SIZE_T, HeapSize, HANDLE hHeap, DWORD dwFlags,
- LPCVOID lpMem) {
- CHECK(dwFlags == 0 && "unsupported heap flags");
- GET_CURRENT_PC_BP_SP;
- (void)sp;
- return asan_malloc_usable_size(lpMem, pc, bp);
-}
-
-namespace __asan {
-
-static void TryToOverrideFunction(const char *fname, uptr new_func) {
- // Failure here is not fatal. The CRT may not be present, and different CRT
- // versions use different symbols.
- if (!__interception::OverrideFunction(fname, new_func))
- VPrintf(2, "Failed to override function %s\n", fname);
-}
-
-void ReplaceSystemMalloc() {
-#if defined(ASAN_DYNAMIC)
- TryToOverrideFunction("free", (uptr)free);
- TryToOverrideFunction("_free_base", (uptr)free);
- TryToOverrideFunction("malloc", (uptr)malloc);
- TryToOverrideFunction("_malloc_base", (uptr)malloc);
- TryToOverrideFunction("_malloc_crt", (uptr)malloc);
- TryToOverrideFunction("calloc", (uptr)calloc);
- TryToOverrideFunction("_calloc_base", (uptr)calloc);
- TryToOverrideFunction("_calloc_crt", (uptr)calloc);
- TryToOverrideFunction("realloc", (uptr)realloc);
- TryToOverrideFunction("_realloc_base", (uptr)realloc);
- TryToOverrideFunction("_realloc_crt", (uptr)realloc);
- TryToOverrideFunction("_recalloc", (uptr)_recalloc);
- TryToOverrideFunction("_recalloc_base", (uptr)_recalloc);
- TryToOverrideFunction("_recalloc_crt", (uptr)_recalloc);
- TryToOverrideFunction("_msize", (uptr)_msize);
- TryToOverrideFunction("_expand", (uptr)_expand);
- TryToOverrideFunction("_expand_base", (uptr)_expand);
-
- // Recent versions of ucrtbase.dll appear to be built with PGO and LTCG, which
- // enable cross-module inlining. This means our _malloc_base hook won't catch
- // all CRT allocations. This code here patches the import table of
- // ucrtbase.dll so that all attempts to use the lower-level win32 heap
- // allocation API will be directed to ASan's heap. We don't currently
- // intercept all calls to HeapAlloc. If we did, we would have to check on
- // HeapFree whether the pointer came from ASan of from the system.
-#define INTERCEPT_UCRT_FUNCTION(func) \
- if (!INTERCEPT_FUNCTION_DLLIMPORT("ucrtbase.dll", \
- "api-ms-win-core-heap-l1-1-0.dll", func)) \
- VPrintf(2, "Failed to intercept ucrtbase.dll import %s\n", #func);
- INTERCEPT_UCRT_FUNCTION(HeapAlloc);
- INTERCEPT_UCRT_FUNCTION(HeapFree);
- INTERCEPT_UCRT_FUNCTION(HeapReAlloc);
- INTERCEPT_UCRT_FUNCTION(HeapSize);
-#undef INTERCEPT_UCRT_FUNCTION
-#endif
-}
-} // namespace __asan
-
-#endif // _WIN32
diff --git a/lib/asan/asan_mapping.h b/lib/asan/asan_mapping.h
deleted file mode 100644
index f3696da62b30a..0000000000000
--- a/lib/asan/asan_mapping.h
+++ /dev/null
@@ -1,401 +0,0 @@
-//===-- asan_mapping.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.
-//
-// Defines ASan memory mapping.
-//===----------------------------------------------------------------------===//
-#ifndef ASAN_MAPPING_H
-#define ASAN_MAPPING_H
-
-#include "asan_internal.h"
-
-// The full explanation of the memory mapping could be found here:
-// https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm
-//
-// Typical shadow mapping on Linux/x86_64 with SHADOW_OFFSET == 0x00007fff8000:
-// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem ||
-// || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
-// || `[0x00008fff7000, 0x02008fff6fff]` || ShadowGap ||
-// || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow ||
-// || `[0x000000000000, 0x00007fff7fff]` || LowMem ||
-//
-// When SHADOW_OFFSET is zero (-pie):
-// || `[0x100000000000, 0x7fffffffffff]` || HighMem ||
-// || `[0x020000000000, 0x0fffffffffff]` || HighShadow ||
-// || `[0x000000040000, 0x01ffffffffff]` || ShadowGap ||
-//
-// Special case when something is already mapped between
-// 0x003000000000 and 0x005000000000 (e.g. when prelink is installed):
-// || `[0x10007fff8000, 0x7fffffffffff]` || HighMem ||
-// || `[0x02008fff7000, 0x10007fff7fff]` || HighShadow ||
-// || `[0x005000000000, 0x02008fff6fff]` || ShadowGap3 ||
-// || `[0x003000000000, 0x004fffffffff]` || MidMem ||
-// || `[0x000a7fff8000, 0x002fffffffff]` || ShadowGap2 ||
-// || `[0x00067fff8000, 0x000a7fff7fff]` || MidShadow ||
-// || `[0x00008fff7000, 0x00067fff7fff]` || ShadowGap ||
-// || `[0x00007fff8000, 0x00008fff6fff]` || LowShadow ||
-// || `[0x000000000000, 0x00007fff7fff]` || LowMem ||
-//
-// Default Linux/i386 mapping on x86_64 machine:
-// || `[0x40000000, 0xffffffff]` || HighMem ||
-// || `[0x28000000, 0x3fffffff]` || HighShadow ||
-// || `[0x24000000, 0x27ffffff]` || ShadowGap ||
-// || `[0x20000000, 0x23ffffff]` || LowShadow ||
-// || `[0x00000000, 0x1fffffff]` || LowMem ||
-//
-// Default Linux/i386 mapping on i386 machine
-// (addresses starting with 0xc0000000 are reserved
-// for kernel and thus not sanitized):
-// || `[0x38000000, 0xbfffffff]` || HighMem ||
-// || `[0x27000000, 0x37ffffff]` || HighShadow ||
-// || `[0x24000000, 0x26ffffff]` || ShadowGap ||
-// || `[0x20000000, 0x23ffffff]` || LowShadow ||
-// || `[0x00000000, 0x1fffffff]` || LowMem ||
-//
-// Default Linux/MIPS32 mapping:
-// || `[0x2aaa0000, 0xffffffff]` || HighMem ||
-// || `[0x0fff4000, 0x2aa9ffff]` || HighShadow ||
-// || `[0x0bff4000, 0x0fff3fff]` || ShadowGap ||
-// || `[0x0aaa0000, 0x0bff3fff]` || LowShadow ||
-// || `[0x00000000, 0x0aa9ffff]` || LowMem ||
-//
-// Default Linux/MIPS64 mapping:
-// || `[0x4000000000, 0xffffffffff]` || HighMem ||
-// || `[0x2800000000, 0x3fffffffff]` || HighShadow ||
-// || `[0x2400000000, 0x27ffffffff]` || ShadowGap ||
-// || `[0x2000000000, 0x23ffffffff]` || LowShadow ||
-// || `[0x0000000000, 0x1fffffffff]` || LowMem ||
-//
-// Default Linux/AArch64 (39-bit VMA) mapping:
-// || `[0x2000000000, 0x7fffffffff]` || highmem ||
-// || `[0x1400000000, 0x1fffffffff]` || highshadow ||
-// || `[0x1200000000, 0x13ffffffff]` || shadowgap ||
-// || `[0x1000000000, 0x11ffffffff]` || lowshadow ||
-// || `[0x0000000000, 0x0fffffffff]` || lowmem ||
-//
-// Default Linux/AArch64 (42-bit VMA) mapping:
-// || `[0x10000000000, 0x3ffffffffff]` || highmem ||
-// || `[0x0a000000000, 0x0ffffffffff]` || highshadow ||
-// || `[0x09000000000, 0x09fffffffff]` || shadowgap ||
-// || `[0x08000000000, 0x08fffffffff]` || lowshadow ||
-// || `[0x00000000000, 0x07fffffffff]` || lowmem ||
-//
-// Default Linux/S390 mapping:
-// || `[0x30000000, 0x7fffffff]` || HighMem ||
-// || `[0x26000000, 0x2fffffff]` || HighShadow ||
-// || `[0x24000000, 0x25ffffff]` || ShadowGap ||
-// || `[0x20000000, 0x23ffffff]` || LowShadow ||
-// || `[0x00000000, 0x1fffffff]` || LowMem ||
-//
-// Default Linux/SystemZ mapping:
-// || `[0x14000000000000, 0x1fffffffffffff]` || HighMem ||
-// || `[0x12800000000000, 0x13ffffffffffff]` || HighShadow ||
-// || `[0x12000000000000, 0x127fffffffffff]` || ShadowGap ||
-// || `[0x10000000000000, 0x11ffffffffffff]` || LowShadow ||
-// || `[0x00000000000000, 0x0fffffffffffff]` || LowMem ||
-//
-// Shadow mapping on FreeBSD/x86-64 with SHADOW_OFFSET == 0x400000000000:
-// || `[0x500000000000, 0x7fffffffffff]` || HighMem ||
-// || `[0x4a0000000000, 0x4fffffffffff]` || HighShadow ||
-// || `[0x480000000000, 0x49ffffffffff]` || ShadowGap ||
-// || `[0x400000000000, 0x47ffffffffff]` || LowShadow ||
-// || `[0x000000000000, 0x3fffffffffff]` || LowMem ||
-//
-// Shadow mapping on FreeBSD/i386 with SHADOW_OFFSET == 0x40000000:
-// || `[0x60000000, 0xffffffff]` || HighMem ||
-// || `[0x4c000000, 0x5fffffff]` || HighShadow ||
-// || `[0x48000000, 0x4bffffff]` || ShadowGap ||
-// || `[0x40000000, 0x47ffffff]` || LowShadow ||
-// || `[0x00000000, 0x3fffffff]` || LowMem ||
-//
-// Shadow mapping on NetBSD/x86-64 with SHADOW_OFFSET == 0x400000000000:
-// || `[0x4feffffffe01, 0x7f7ffffff000]` || HighMem ||
-// || `[0x49fdffffffc0, 0x4feffffffe00]` || HighShadow ||
-// || `[0x480000000000, 0x49fdffffffbf]` || ShadowGap ||
-// || `[0x400000000000, 0x47ffffffffff]` || LowShadow ||
-// || `[0x000000000000, 0x3fffffffffff]` || LowMem ||
-//
-// Shadow mapping on NetBSD/i386 with SHADOW_OFFSET == 0x40000000:
-// || `[0x60000000, 0xfffff000]` || HighMem ||
-// || `[0x4c000000, 0x5fffffff]` || HighShadow ||
-// || `[0x48000000, 0x4bffffff]` || ShadowGap ||
-// || `[0x40000000, 0x47ffffff]` || LowShadow ||
-// || `[0x00000000, 0x3fffffff]` || LowMem ||
-//
-// Default Windows/i386 mapping:
-// (the exact location of HighShadow/HighMem may vary depending
-// on WoW64, /LARGEADDRESSAWARE, etc).
-// || `[0x50000000, 0xffffffff]` || HighMem ||
-// || `[0x3a000000, 0x4fffffff]` || HighShadow ||
-// || `[0x36000000, 0x39ffffff]` || ShadowGap ||
-// || `[0x30000000, 0x35ffffff]` || LowShadow ||
-// || `[0x00000000, 0x2fffffff]` || LowMem ||
-//
-// Shadow mapping on Myriad2 (for shadow scale 5):
-// || `[0x9ff80000, 0x9fffffff]` || ShadowGap ||
-// || `[0x9f000000, 0x9ff7ffff]` || LowShadow ||
-// || `[0x80000000, 0x9effffff]` || LowMem ||
-// || `[0x00000000, 0x7fffffff]` || Ignored ||
-
-#if defined(ASAN_SHADOW_SCALE)
-static const u64 kDefaultShadowScale = ASAN_SHADOW_SCALE;
-#else
-static const u64 kDefaultShadowScale = SANITIZER_MYRIAD2 ? 5 : 3;
-#endif
-static const u64 kDefaultShadowSentinel = ~(uptr)0;
-static const u64 kDefaultShadowOffset32 = 1ULL << 29; // 0x20000000
-static const u64 kDefaultShadowOffset64 = 1ULL << 44;
-static const u64 kDefaultShort64bitShadowOffset =
- 0x7FFFFFFF & (~0xFFFULL << kDefaultShadowScale); // < 2G.
-static const u64 kIosShadowOffset32 = 1ULL << 30; // 0x40000000
-static const u64 kIosShadowOffset64 = 0x120200000;
-static const u64 kIosSimShadowOffset32 = 1ULL << 30;
-static const u64 kIosSimShadowOffset64 = kDefaultShadowOffset64;
-static const u64 kAArch64_ShadowOffset64 = 1ULL << 36;
-static const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000;
-static const u64 kMIPS64_ShadowOffset64 = 1ULL << 37;
-static const u64 kPPC64_ShadowOffset64 = 1ULL << 44;
-static const u64 kSystemZ_ShadowOffset64 = 1ULL << 52;
-static const u64 kFreeBSD_ShadowOffset32 = 1ULL << 30; // 0x40000000
-static const u64 kFreeBSD_ShadowOffset64 = 1ULL << 46; // 0x400000000000
-static const u64 kNetBSD_ShadowOffset32 = 1ULL << 30; // 0x40000000
-static const u64 kNetBSD_ShadowOffset64 = 1ULL << 46; // 0x400000000000
-static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000
-
-static const u64 kMyriadMemoryOffset32 = 0x80000000ULL;
-static const u64 kMyriadMemorySize32 = 0x20000000ULL;
-static const u64 kMyriadMemoryEnd32 =
- kMyriadMemoryOffset32 + kMyriadMemorySize32 - 1;
-static const u64 kMyriadShadowOffset32 =
- (kMyriadMemoryOffset32 + kMyriadMemorySize32 -
- (kMyriadMemorySize32 >> kDefaultShadowScale));
-static const u64 kMyriadCacheBitMask32 = 0x40000000ULL;
-
-#define SHADOW_SCALE kDefaultShadowScale
-
-#if SANITIZER_FUCHSIA
-# define SHADOW_OFFSET (0)
-#elif SANITIZER_WORDSIZE == 32
-# if SANITIZER_ANDROID
-# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
-# elif defined(__mips__)
-# define SHADOW_OFFSET kMIPS32_ShadowOffset32
-# elif SANITIZER_FREEBSD
-# define SHADOW_OFFSET kFreeBSD_ShadowOffset32
-# elif SANITIZER_NETBSD
-# define SHADOW_OFFSET kNetBSD_ShadowOffset32
-# elif SANITIZER_WINDOWS
-# define SHADOW_OFFSET kWindowsShadowOffset32
-# elif SANITIZER_IOS
-# if SANITIZER_IOSSIM
-# define SHADOW_OFFSET kIosSimShadowOffset32
-# else
-# define SHADOW_OFFSET kIosShadowOffset32
-# endif
-# elif SANITIZER_MYRIAD2
-# define SHADOW_OFFSET kMyriadShadowOffset32
-# else
-# define SHADOW_OFFSET kDefaultShadowOffset32
-# endif
-#else
-# if SANITIZER_IOS
-# if SANITIZER_IOSSIM
-# define SHADOW_OFFSET kIosSimShadowOffset64
-# else
-# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
-# endif
-# elif defined(__aarch64__)
-# define SHADOW_OFFSET kAArch64_ShadowOffset64
-# elif defined(__powerpc64__)
-# define SHADOW_OFFSET kPPC64_ShadowOffset64
-# elif defined(__s390x__)
-# define SHADOW_OFFSET kSystemZ_ShadowOffset64
-# elif SANITIZER_FREEBSD
-# define SHADOW_OFFSET kFreeBSD_ShadowOffset64
-# elif SANITIZER_NETBSD
-# define SHADOW_OFFSET kNetBSD_ShadowOffset64
-# elif SANITIZER_MAC
-# define SHADOW_OFFSET kDefaultShadowOffset64
-# elif defined(__mips64)
-# define SHADOW_OFFSET kMIPS64_ShadowOffset64
-# elif SANITIZER_WINDOWS64
-# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address
-# else
-# define SHADOW_OFFSET kDefaultShort64bitShadowOffset
-# endif
-#endif
-
-#if SANITIZER_ANDROID && defined(__arm__)
-# define ASAN_PREMAP_SHADOW 1
-#else
-# define ASAN_PREMAP_SHADOW 0
-#endif
-
-#define SHADOW_GRANULARITY (1ULL << SHADOW_SCALE)
-
-#define DO_ASAN_MAPPING_PROFILE 0 // Set to 1 to profile the functions below.
-
-#if DO_ASAN_MAPPING_PROFILE
-# define PROFILE_ASAN_MAPPING() AsanMappingProfile[__LINE__]++;
-#else
-# define PROFILE_ASAN_MAPPING()
-#endif
-
-// If 1, all shadow boundaries are constants.
-// Don't set to 1 other than for testing.
-#define ASAN_FIXED_MAPPING 0
-
-namespace __asan {
-
-extern uptr AsanMappingProfile[];
-
-#if ASAN_FIXED_MAPPING
-// Fixed mapping for 64-bit Linux. Mostly used for performance comparison
-// with non-fixed mapping. As of r175253 (Feb 2013) the performance
-// difference between fixed and non-fixed mapping is below the noise level.
-static uptr kHighMemEnd = 0x7fffffffffffULL;
-static uptr kMidMemBeg = 0x3000000000ULL;
-static uptr kMidMemEnd = 0x4fffffffffULL;
-#else
-extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init.
-#endif
-
-} // namespace __asan
-
-#if SANITIZER_MYRIAD2
-#include "asan_mapping_myriad.h"
-#else
-#define MEM_TO_SHADOW(mem) (((mem) >> SHADOW_SCALE) + (SHADOW_OFFSET))
-
-#define kLowMemBeg 0
-#define kLowMemEnd (SHADOW_OFFSET ? SHADOW_OFFSET - 1 : 0)
-
-#define kLowShadowBeg SHADOW_OFFSET
-#define kLowShadowEnd MEM_TO_SHADOW(kLowMemEnd)
-
-#define kHighMemBeg (MEM_TO_SHADOW(kHighMemEnd) + 1)
-
-#define kHighShadowBeg MEM_TO_SHADOW(kHighMemBeg)
-#define kHighShadowEnd MEM_TO_SHADOW(kHighMemEnd)
-
-# define kMidShadowBeg MEM_TO_SHADOW(kMidMemBeg)
-# define kMidShadowEnd MEM_TO_SHADOW(kMidMemEnd)
-
-// With the zero shadow base we can not actually map pages starting from 0.
-// This constant is somewhat arbitrary.
-#define kZeroBaseShadowStart 0
-#define kZeroBaseMaxShadowStart (1 << 18)
-
-#define kShadowGapBeg (kLowShadowEnd ? kLowShadowEnd + 1 \
- : kZeroBaseShadowStart)
-#define kShadowGapEnd ((kMidMemBeg ? kMidShadowBeg : kHighShadowBeg) - 1)
-
-#define kShadowGap2Beg (kMidMemBeg ? kMidShadowEnd + 1 : 0)
-#define kShadowGap2End (kMidMemBeg ? kMidMemBeg - 1 : 0)
-
-#define kShadowGap3Beg (kMidMemBeg ? kMidMemEnd + 1 : 0)
-#define kShadowGap3End (kMidMemBeg ? kHighShadowBeg - 1 : 0)
-
-namespace __asan {
-
-static inline bool AddrIsInLowMem(uptr a) {
- PROFILE_ASAN_MAPPING();
- return a <= kLowMemEnd;
-}
-
-static inline bool AddrIsInLowShadow(uptr a) {
- PROFILE_ASAN_MAPPING();
- return a >= kLowShadowBeg && a <= kLowShadowEnd;
-}
-
-static inline bool AddrIsInMidMem(uptr a) {
- PROFILE_ASAN_MAPPING();
- return kMidMemBeg && a >= kMidMemBeg && a <= kMidMemEnd;
-}
-
-static inline bool AddrIsInMidShadow(uptr a) {
- PROFILE_ASAN_MAPPING();
- return kMidMemBeg && a >= kMidShadowBeg && a <= kMidShadowEnd;
-}
-
-static inline bool AddrIsInHighMem(uptr a) {
- PROFILE_ASAN_MAPPING();
- return kHighMemBeg && a >= kHighMemBeg && a <= kHighMemEnd;
-}
-
-static inline bool AddrIsInHighShadow(uptr a) {
- PROFILE_ASAN_MAPPING();
- return kHighMemBeg && a >= kHighShadowBeg && a <= kHighShadowEnd;
-}
-
-static inline bool AddrIsInShadowGap(uptr a) {
- PROFILE_ASAN_MAPPING();
- if (kMidMemBeg) {
- if (a <= kShadowGapEnd)
- return SHADOW_OFFSET == 0 || a >= kShadowGapBeg;
- return (a >= kShadowGap2Beg && a <= kShadowGap2End) ||
- (a >= kShadowGap3Beg && a <= kShadowGap3End);
- }
- // In zero-based shadow mode we treat addresses near zero as addresses
- // in shadow gap as well.
- if (SHADOW_OFFSET == 0)
- return a <= kShadowGapEnd;
- return a >= kShadowGapBeg && a <= kShadowGapEnd;
-}
-
-} // namespace __asan
-
-#endif // SANITIZER_MYRIAD2
-
-namespace __asan {
-
-static inline bool AddrIsInMem(uptr a) {
- PROFILE_ASAN_MAPPING();
- return AddrIsInLowMem(a) || AddrIsInMidMem(a) || AddrIsInHighMem(a) ||
- (flags()->protect_shadow_gap == 0 && AddrIsInShadowGap(a));
-}
-
-static inline uptr MemToShadow(uptr p) {
- PROFILE_ASAN_MAPPING();
- CHECK(AddrIsInMem(p));
- return MEM_TO_SHADOW(p);
-}
-
-static inline bool AddrIsInShadow(uptr a) {
- PROFILE_ASAN_MAPPING();
- return AddrIsInLowShadow(a) || AddrIsInMidShadow(a) || AddrIsInHighShadow(a);
-}
-
-static inline bool AddrIsAlignedByGranularity(uptr a) {
- PROFILE_ASAN_MAPPING();
- return (a & (SHADOW_GRANULARITY - 1)) == 0;
-}
-
-static inline bool AddressIsPoisoned(uptr a) {
- PROFILE_ASAN_MAPPING();
- if (SANITIZER_MYRIAD2 && !AddrIsInMem(a) && !AddrIsInShadow(a))
- return false;
- const uptr kAccessSize = 1;
- u8 *shadow_address = (u8*)MEM_TO_SHADOW(a);
- s8 shadow_value = *shadow_address;
- if (shadow_value) {
- u8 last_accessed_byte = (a & (SHADOW_GRANULARITY - 1))
- + kAccessSize - 1;
- return (last_accessed_byte >= shadow_value);
- }
- return false;
-}
-
-// Must be after all calls to PROFILE_ASAN_MAPPING().
-static const uptr kAsanMappingProfileSize = __LINE__;
-
-} // namespace __asan
-
-#endif // ASAN_MAPPING_H
diff --git a/lib/asan/asan_mapping_myriad.h b/lib/asan/asan_mapping_myriad.h
deleted file mode 100644
index baa3247bd1901..0000000000000
--- a/lib/asan/asan_mapping_myriad.h
+++ /dev/null
@@ -1,86 +0,0 @@
-//===-- asan_mapping_myriad.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.
-//
-// Myriad-specific definitions for ASan memory mapping.
-//===----------------------------------------------------------------------===//
-#ifndef ASAN_MAPPING_MYRIAD_H
-#define ASAN_MAPPING_MYRIAD_H
-
-#define RAW_ADDR(mem) ((mem) & ~kMyriadCacheBitMask32)
-#define MEM_TO_SHADOW(mem) \
- (((RAW_ADDR(mem) - kLowMemBeg) >> SHADOW_SCALE) + (SHADOW_OFFSET))
-
-#define kLowMemBeg kMyriadMemoryOffset32
-#define kLowMemEnd (SHADOW_OFFSET - 1)
-
-#define kLowShadowBeg SHADOW_OFFSET
-#define kLowShadowEnd MEM_TO_SHADOW(kLowMemEnd)
-
-#define kHighMemBeg 0
-
-#define kHighShadowBeg 0
-#define kHighShadowEnd 0
-
-#define kMidShadowBeg 0
-#define kMidShadowEnd 0
-
-#define kShadowGapBeg (kLowShadowEnd + 1)
-#define kShadowGapEnd kMyriadMemoryEnd32
-
-#define kShadowGap2Beg 0
-#define kShadowGap2End 0
-
-#define kShadowGap3Beg 0
-#define kShadowGap3End 0
-
-namespace __asan {
-
-static inline bool AddrIsInLowMem(uptr a) {
- PROFILE_ASAN_MAPPING();
- a = RAW_ADDR(a);
- return a >= kLowMemBeg && a <= kLowMemEnd;
-}
-
-static inline bool AddrIsInLowShadow(uptr a) {
- PROFILE_ASAN_MAPPING();
- a = RAW_ADDR(a);
- return a >= kLowShadowBeg && a <= kLowShadowEnd;
-}
-
-static inline bool AddrIsInMidMem(uptr a) {
- PROFILE_ASAN_MAPPING();
- return false;
-}
-
-static inline bool AddrIsInMidShadow(uptr a) {
- PROFILE_ASAN_MAPPING();
- return false;
-}
-
-static inline bool AddrIsInHighMem(uptr a) {
- PROFILE_ASAN_MAPPING();
- return false;
-}
-
-static inline bool AddrIsInHighShadow(uptr a) {
- PROFILE_ASAN_MAPPING();
- return false;
-}
-
-static inline bool AddrIsInShadowGap(uptr a) {
- PROFILE_ASAN_MAPPING();
- a = RAW_ADDR(a);
- return a >= kShadowGapBeg && a <= kShadowGapEnd;
-}
-
-} // namespace __asan
-
-#endif // ASAN_MAPPING_MYRIAD_H
diff --git a/lib/asan/asan_memory_profile.cc b/lib/asan/asan_memory_profile.cc
deleted file mode 100644
index 8c86d9fe49f2b..0000000000000
--- a/lib/asan/asan_memory_profile.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-//===-- asan_memory_profile.cc.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 file implements __sanitizer_print_memory_profile.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_stackdepot.h"
-#include "sanitizer_common/sanitizer_stacktrace.h"
-#include "sanitizer_common/sanitizer_stoptheworld.h"
-#include "lsan/lsan_common.h"
-#include "asan/asan_allocator.h"
-
-#if CAN_SANITIZE_LEAKS
-
-namespace __asan {
-
-struct AllocationSite {
- u32 id;
- uptr total_size;
- uptr count;
-};
-
-class HeapProfile {
- public:
- HeapProfile() { allocations_.reserve(1024); }
-
- void ProcessChunk(const AsanChunkView &cv) {
- if (cv.IsAllocated()) {
- total_allocated_user_size_ += cv.UsedSize();
- total_allocated_count_++;
- u32 id = cv.GetAllocStackId();
- if (id)
- Insert(id, cv.UsedSize());
- } else if (cv.IsQuarantined()) {
- total_quarantined_user_size_ += cv.UsedSize();
- total_quarantined_count_++;
- } else {
- total_other_count_++;
- }
- }
-
- void Print(uptr top_percent, uptr max_number_of_contexts) {
- Sort(allocations_.data(), allocations_.size(),
- [](const AllocationSite &a, const AllocationSite &b) {
- return a.total_size > b.total_size;
- });
- CHECK(total_allocated_user_size_);
- uptr total_shown = 0;
- Printf("Live Heap Allocations: %zd bytes in %zd chunks; quarantined: "
- "%zd bytes in %zd chunks; %zd other chunks; total chunks: %zd; "
- "showing top %zd%% (at most %zd unique contexts)\n",
- total_allocated_user_size_, total_allocated_count_,
- total_quarantined_user_size_, total_quarantined_count_,
- total_other_count_, total_allocated_count_ +
- total_quarantined_count_ + total_other_count_, top_percent,
- max_number_of_contexts);
- for (uptr i = 0; i < Min(allocations_.size(), max_number_of_contexts);
- i++) {
- auto &a = allocations_[i];
- Printf("%zd byte(s) (%zd%%) in %zd allocation(s)\n", a.total_size,
- a.total_size * 100 / total_allocated_user_size_, a.count);
- StackDepotGet(a.id).Print();
- total_shown += a.total_size;
- if (total_shown * 100 / total_allocated_user_size_ > top_percent)
- break;
- }
- }
-
- private:
- uptr total_allocated_user_size_ = 0;
- uptr total_allocated_count_ = 0;
- uptr total_quarantined_user_size_ = 0;
- uptr total_quarantined_count_ = 0;
- uptr total_other_count_ = 0;
- InternalMmapVector<AllocationSite> allocations_;
-
- void Insert(u32 id, uptr size) {
- // Linear lookup will be good enough for most cases (although not all).
- for (uptr i = 0; i < allocations_.size(); i++) {
- if (allocations_[i].id == id) {
- allocations_[i].total_size += size;
- allocations_[i].count++;
- return;
- }
- }
- allocations_.push_back({id, size, 1});
- }
-};
-
-static void ChunkCallback(uptr chunk, void *arg) {
- reinterpret_cast<HeapProfile*>(arg)->ProcessChunk(
- FindHeapChunkByAllocBeg(chunk));
-}
-
-static void MemoryProfileCB(const SuspendedThreadsList &suspended_threads_list,
- void *argument) {
- HeapProfile hp;
- __lsan::ForEachChunk(ChunkCallback, &hp);
- uptr *Arg = reinterpret_cast<uptr*>(argument);
- hp.Print(Arg[0], Arg[1]);
-
- if (Verbosity())
- __asan_print_accumulated_stats();
-}
-
-} // namespace __asan
-
-#endif // CAN_SANITIZE_LEAKS
-
-extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE
-void __sanitizer_print_memory_profile(uptr top_percent,
- uptr max_number_of_contexts) {
-#if CAN_SANITIZE_LEAKS
- uptr Arg[2];
- Arg[0] = top_percent;
- Arg[1] = max_number_of_contexts;
- __sanitizer::StopTheWorld(__asan::MemoryProfileCB, Arg);
-#endif // CAN_SANITIZE_LEAKS
-}
-} // extern "C"
diff --git a/lib/asan/asan_new_delete.cc b/lib/asan/asan_new_delete.cc
deleted file mode 100644
index 30efd61a9680f..0000000000000
--- a/lib/asan/asan_new_delete.cc
+++ /dev/null
@@ -1,211 +0,0 @@
-//===-- asan_interceptors.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.
-//
-// Interceptors for operators new and delete.
-//===----------------------------------------------------------------------===//
-
-#include "asan_allocator.h"
-#include "asan_internal.h"
-#include "asan_malloc_local.h"
-#include "asan_report.h"
-#include "asan_stack.h"
-
-#include "interception/interception.h"
-
-#include <stddef.h>
-
-// C++ operators can't have dllexport attributes on Windows. We export them
-// anyway by passing extra -export flags to the linker, which is exactly that
-// dllexport would normally do. We need to export them in order to make the
-// VS2015 dynamic CRT (MD) work.
-#if SANITIZER_WINDOWS
-#define CXX_OPERATOR_ATTRIBUTE
-#define COMMENT_EXPORT(sym) __pragma(comment(linker, "/export:" sym))
-#ifdef _WIN64
-COMMENT_EXPORT("??2@YAPEAX_K@Z") // operator new
-COMMENT_EXPORT("??2@YAPEAX_KAEBUnothrow_t@std@@@Z") // operator new nothrow
-COMMENT_EXPORT("??3@YAXPEAX@Z") // operator delete
-COMMENT_EXPORT("??3@YAXPEAX_K@Z") // sized operator delete
-COMMENT_EXPORT("??_U@YAPEAX_K@Z") // operator new[]
-COMMENT_EXPORT("??_V@YAXPEAX@Z") // operator delete[]
-#else
-COMMENT_EXPORT("??2@YAPAXI@Z") // operator new
-COMMENT_EXPORT("??2@YAPAXIABUnothrow_t@std@@@Z") // operator new nothrow
-COMMENT_EXPORT("??3@YAXPAX@Z") // operator delete
-COMMENT_EXPORT("??3@YAXPAXI@Z") // sized operator delete
-COMMENT_EXPORT("??_U@YAPAXI@Z") // operator new[]
-COMMENT_EXPORT("??_V@YAXPAX@Z") // operator delete[]
-#endif
-#undef COMMENT_EXPORT
-#else
-#define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE
-#endif
-
-using namespace __asan; // NOLINT
-
-// FreeBSD prior v9.2 have wrong definition of 'size_t'.
-// http://svnweb.freebsd.org/base?view=revision&revision=232261
-#if SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 32
-#include <sys/param.h>
-#if __FreeBSD_version <= 902001 // v9.2
-#define size_t unsigned
-#endif // __FreeBSD_version
-#endif // SANITIZER_FREEBSD && SANITIZER_WORDSIZE == 32
-
-// This code has issues on OSX.
-// See https://github.com/google/sanitizers/issues/131.
-
-// Fake std::nothrow_t and std::align_val_t to avoid including <new>.
-namespace std {
-struct nothrow_t {};
-enum class align_val_t: size_t {};
-} // namespace std
-
-// TODO(alekseyshl): throw std::bad_alloc instead of dying on OOM.
-// For local pool allocation, align to SHADOW_GRANULARITY to match asan
-// allocator behavior.
-#define OPERATOR_NEW_BODY(type, nothrow) \
- if (ALLOCATE_FROM_LOCAL_POOL) {\
- void *res = MemalignFromLocalPool(SHADOW_GRANULARITY, size);\
- if (!nothrow) CHECK(res);\
- return res;\
- }\
- GET_STACK_TRACE_MALLOC;\
- void *res = asan_memalign(0, size, &stack, type);\
- if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\
- return res;
-#define OPERATOR_NEW_BODY_ALIGN(type, nothrow) \
- if (ALLOCATE_FROM_LOCAL_POOL) {\
- void *res = MemalignFromLocalPool((uptr)align, size);\
- if (!nothrow) CHECK(res);\
- return res;\
- }\
- GET_STACK_TRACE_MALLOC;\
- void *res = asan_memalign((uptr)align, size, &stack, type);\
- if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\
- return res;
-
-// On OS X it's not enough to just provide our own 'operator new' and
-// 'operator delete' implementations, because they're going to be in the
-// runtime dylib, and the main executable will depend on both the runtime
-// dylib and libstdc++, each of those'll have its implementation of new and
-// delete.
-// To make sure that C++ allocation/deallocation operators are overridden on
-// OS X we need to intercept them using their mangled names.
-#if !SANITIZER_MAC
-CXX_OPERATOR_ATTRIBUTE
-void *operator new(size_t size)
-{ OPERATOR_NEW_BODY(FROM_NEW, false /*nothrow*/); }
-CXX_OPERATOR_ATTRIBUTE
-void *operator new[](size_t size)
-{ OPERATOR_NEW_BODY(FROM_NEW_BR, false /*nothrow*/); }
-CXX_OPERATOR_ATTRIBUTE
-void *operator new(size_t size, std::nothrow_t const&)
-{ OPERATOR_NEW_BODY(FROM_NEW, true /*nothrow*/); }
-CXX_OPERATOR_ATTRIBUTE
-void *operator new[](size_t size, std::nothrow_t const&)
-{ OPERATOR_NEW_BODY(FROM_NEW_BR, true /*nothrow*/); }
-CXX_OPERATOR_ATTRIBUTE
-void *operator new(size_t size, std::align_val_t align)
-{ OPERATOR_NEW_BODY_ALIGN(FROM_NEW, false /*nothrow*/); }
-CXX_OPERATOR_ATTRIBUTE
-void *operator new[](size_t size, std::align_val_t align)
-{ OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR, false /*nothrow*/); }
-CXX_OPERATOR_ATTRIBUTE
-void *operator new(size_t size, std::align_val_t align, std::nothrow_t const&)
-{ OPERATOR_NEW_BODY_ALIGN(FROM_NEW, true /*nothrow*/); }
-CXX_OPERATOR_ATTRIBUTE
-void *operator new[](size_t size, std::align_val_t align, std::nothrow_t const&)
-{ OPERATOR_NEW_BODY_ALIGN(FROM_NEW_BR, true /*nothrow*/); }
-
-#else // SANITIZER_MAC
-INTERCEPTOR(void *, _Znwm, size_t size) {
- OPERATOR_NEW_BODY(FROM_NEW, false /*nothrow*/);
-}
-INTERCEPTOR(void *, _Znam, size_t size) {
- OPERATOR_NEW_BODY(FROM_NEW_BR, false /*nothrow*/);
-}
-INTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&) {
- OPERATOR_NEW_BODY(FROM_NEW, true /*nothrow*/);
-}
-INTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&) {
- OPERATOR_NEW_BODY(FROM_NEW_BR, true /*nothrow*/);
-}
-#endif // !SANITIZER_MAC
-
-#define OPERATOR_DELETE_BODY(type) \
- if (IS_FROM_LOCAL_POOL(ptr)) return;\
- GET_STACK_TRACE_FREE;\
- asan_delete(ptr, 0, 0, &stack, type);
-
-#define OPERATOR_DELETE_BODY_SIZE(type) \
- if (IS_FROM_LOCAL_POOL(ptr)) return;\
- GET_STACK_TRACE_FREE;\
- asan_delete(ptr, size, 0, &stack, type);
-
-#define OPERATOR_DELETE_BODY_ALIGN(type) \
- if (IS_FROM_LOCAL_POOL(ptr)) return;\
- GET_STACK_TRACE_FREE;\
- asan_delete(ptr, 0, static_cast<uptr>(align), &stack, type);
-
-#define OPERATOR_DELETE_BODY_SIZE_ALIGN(type) \
- if (IS_FROM_LOCAL_POOL(ptr)) return;\
- GET_STACK_TRACE_FREE;\
- asan_delete(ptr, size, static_cast<uptr>(align), &stack, type);
-
-#if !SANITIZER_MAC
-CXX_OPERATOR_ATTRIBUTE
-void operator delete(void *ptr) NOEXCEPT
-{ OPERATOR_DELETE_BODY(FROM_NEW); }
-CXX_OPERATOR_ATTRIBUTE
-void operator delete[](void *ptr) NOEXCEPT
-{ OPERATOR_DELETE_BODY(FROM_NEW_BR); }
-CXX_OPERATOR_ATTRIBUTE
-void operator delete(void *ptr, std::nothrow_t const&)
-{ OPERATOR_DELETE_BODY(FROM_NEW); }
-CXX_OPERATOR_ATTRIBUTE
-void operator delete[](void *ptr, std::nothrow_t const&)
-{ OPERATOR_DELETE_BODY(FROM_NEW_BR); }
-CXX_OPERATOR_ATTRIBUTE
-void operator delete(void *ptr, size_t size) NOEXCEPT
-{ OPERATOR_DELETE_BODY_SIZE(FROM_NEW); }
-CXX_OPERATOR_ATTRIBUTE
-void operator delete[](void *ptr, size_t size) NOEXCEPT
-{ OPERATOR_DELETE_BODY_SIZE(FROM_NEW_BR); }
-CXX_OPERATOR_ATTRIBUTE
-void operator delete(void *ptr, std::align_val_t align) NOEXCEPT
-{ OPERATOR_DELETE_BODY_ALIGN(FROM_NEW); }
-CXX_OPERATOR_ATTRIBUTE
-void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT
-{ OPERATOR_DELETE_BODY_ALIGN(FROM_NEW_BR); }
-CXX_OPERATOR_ATTRIBUTE
-void operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&)
-{ OPERATOR_DELETE_BODY_ALIGN(FROM_NEW); }
-CXX_OPERATOR_ATTRIBUTE
-void operator delete[](void *ptr, std::align_val_t align, std::nothrow_t const&)
-{ OPERATOR_DELETE_BODY_ALIGN(FROM_NEW_BR); }
-CXX_OPERATOR_ATTRIBUTE
-void operator delete(void *ptr, size_t size, std::align_val_t align) NOEXCEPT
-{ OPERATOR_DELETE_BODY_SIZE_ALIGN(FROM_NEW); }
-CXX_OPERATOR_ATTRIBUTE
-void operator delete[](void *ptr, size_t size, std::align_val_t align) NOEXCEPT
-{ OPERATOR_DELETE_BODY_SIZE_ALIGN(FROM_NEW_BR); }
-
-#else // SANITIZER_MAC
-INTERCEPTOR(void, _ZdlPv, void *ptr)
-{ OPERATOR_DELETE_BODY(FROM_NEW); }
-INTERCEPTOR(void, _ZdaPv, void *ptr)
-{ OPERATOR_DELETE_BODY(FROM_NEW_BR); }
-INTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&)
-{ OPERATOR_DELETE_BODY(FROM_NEW); }
-INTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&)
-{ OPERATOR_DELETE_BODY(FROM_NEW_BR); }
-#endif // !SANITIZER_MAC
diff --git a/lib/asan/asan_poisoning.cc b/lib/asan/asan_poisoning.cc
deleted file mode 100644
index 1e9c37a13a169..0000000000000
--- a/lib/asan/asan_poisoning.cc
+++ /dev/null
@@ -1,461 +0,0 @@
-//===-- asan_poisoning.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.
-//
-// Shadow memory poisoning by ASan RTL and by user application.
-//===----------------------------------------------------------------------===//
-
-#include "asan_poisoning.h"
-#include "asan_report.h"
-#include "asan_stack.h"
-#include "sanitizer_common/sanitizer_atomic.h"
-#include "sanitizer_common/sanitizer_libc.h"
-#include "sanitizer_common/sanitizer_flags.h"
-
-namespace __asan {
-
-static atomic_uint8_t can_poison_memory;
-
-void SetCanPoisonMemory(bool value) {
- atomic_store(&can_poison_memory, value, memory_order_release);
-}
-
-bool CanPoisonMemory() {
- return atomic_load(&can_poison_memory, memory_order_acquire);
-}
-
-void PoisonShadow(uptr addr, uptr size, u8 value) {
- if (value && !CanPoisonMemory()) return;
- CHECK(AddrIsAlignedByGranularity(addr));
- CHECK(AddrIsInMem(addr));
- CHECK(AddrIsAlignedByGranularity(addr + size));
- CHECK(AddrIsInMem(addr + size - SHADOW_GRANULARITY));
- CHECK(REAL(memset));
- FastPoisonShadow(addr, size, value);
-}
-
-void PoisonShadowPartialRightRedzone(uptr addr,
- uptr size,
- uptr redzone_size,
- u8 value) {
- if (!CanPoisonMemory()) return;
- CHECK(AddrIsAlignedByGranularity(addr));
- CHECK(AddrIsInMem(addr));
- FastPoisonShadowPartialRightRedzone(addr, size, redzone_size, value);
-}
-
-struct ShadowSegmentEndpoint {
- u8 *chunk;
- s8 offset; // in [0, SHADOW_GRANULARITY)
- s8 value; // = *chunk;
-
- explicit ShadowSegmentEndpoint(uptr address) {
- chunk = (u8*)MemToShadow(address);
- offset = address & (SHADOW_GRANULARITY - 1);
- value = *chunk;
- }
-};
-
-void FlushUnneededASanShadowMemory(uptr p, uptr size) {
- // Since asan's mapping is compacting, the shadow chunk may be
- // not page-aligned, so we only flush the page-aligned portion.
- ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size));
-}
-
-void AsanPoisonOrUnpoisonIntraObjectRedzone(uptr ptr, uptr size, bool poison) {
- uptr end = ptr + size;
- if (Verbosity()) {
- Printf("__asan_%spoison_intra_object_redzone [%p,%p) %zd\n",
- poison ? "" : "un", ptr, end, size);
- if (Verbosity() >= 2)
- PRINT_CURRENT_STACK();
- }
- CHECK(size);
- CHECK_LE(size, 4096);
- CHECK(IsAligned(end, SHADOW_GRANULARITY));
- if (!IsAligned(ptr, SHADOW_GRANULARITY)) {
- *(u8 *)MemToShadow(ptr) =
- poison ? static_cast<u8>(ptr % SHADOW_GRANULARITY) : 0;
- ptr |= SHADOW_GRANULARITY - 1;
- ptr++;
- }
- for (; ptr < end; ptr += SHADOW_GRANULARITY)
- *(u8*)MemToShadow(ptr) = poison ? kAsanIntraObjectRedzone : 0;
-}
-
-} // namespace __asan
-
-// ---------------------- Interface ---------------- {{{1
-using namespace __asan; // NOLINT
-
-// Current implementation of __asan_(un)poison_memory_region doesn't check
-// that user program (un)poisons the memory it owns. It poisons memory
-// conservatively, and unpoisons progressively to make sure asan shadow
-// mapping invariant is preserved (see detailed mapping description here:
-// https://github.com/google/sanitizers/wiki/AddressSanitizerAlgorithm).
-//
-// * if user asks to poison region [left, right), the program poisons
-// at least [left, AlignDown(right)).
-// * if user asks to unpoison region [left, right), the program unpoisons
-// at most [AlignDown(left), right).
-void __asan_poison_memory_region(void const volatile *addr, uptr size) {
- if (!flags()->allow_user_poisoning || size == 0) return;
- uptr beg_addr = (uptr)addr;
- uptr end_addr = beg_addr + size;
- VPrintf(3, "Trying to poison memory region [%p, %p)\n", (void *)beg_addr,
- (void *)end_addr);
- ShadowSegmentEndpoint beg(beg_addr);
- ShadowSegmentEndpoint end(end_addr);
- if (beg.chunk == end.chunk) {
- CHECK_LT(beg.offset, end.offset);
- s8 value = beg.value;
- CHECK_EQ(value, end.value);
- // We can only poison memory if the byte in end.offset is unaddressable.
- // No need to re-poison memory if it is poisoned already.
- if (value > 0 && value <= end.offset) {
- if (beg.offset > 0) {
- *beg.chunk = Min(value, beg.offset);
- } else {
- *beg.chunk = kAsanUserPoisonedMemoryMagic;
- }
- }
- return;
- }
- CHECK_LT(beg.chunk, end.chunk);
- if (beg.offset > 0) {
- // Mark bytes from beg.offset as unaddressable.
- if (beg.value == 0) {
- *beg.chunk = beg.offset;
- } else {
- *beg.chunk = Min(beg.value, beg.offset);
- }
- beg.chunk++;
- }
- REAL(memset)(beg.chunk, kAsanUserPoisonedMemoryMagic, end.chunk - beg.chunk);
- // Poison if byte in end.offset is unaddressable.
- if (end.value > 0 && end.value <= end.offset) {
- *end.chunk = kAsanUserPoisonedMemoryMagic;
- }
-}
-
-void __asan_unpoison_memory_region(void const volatile *addr, uptr size) {
- if (!flags()->allow_user_poisoning || size == 0) return;
- uptr beg_addr = (uptr)addr;
- uptr end_addr = beg_addr + size;
- VPrintf(3, "Trying to unpoison memory region [%p, %p)\n", (void *)beg_addr,
- (void *)end_addr);
- ShadowSegmentEndpoint beg(beg_addr);
- ShadowSegmentEndpoint end(end_addr);
- if (beg.chunk == end.chunk) {
- CHECK_LT(beg.offset, end.offset);
- s8 value = beg.value;
- CHECK_EQ(value, end.value);
- // We unpoison memory bytes up to enbytes up to end.offset if it is not
- // unpoisoned already.
- if (value != 0) {
- *beg.chunk = Max(value, end.offset);
- }
- return;
- }
- CHECK_LT(beg.chunk, end.chunk);
- if (beg.offset > 0) {
- *beg.chunk = 0;
- beg.chunk++;
- }
- REAL(memset)(beg.chunk, 0, end.chunk - beg.chunk);
- if (end.offset > 0 && end.value != 0) {
- *end.chunk = Max(end.value, end.offset);
- }
-}
-
-int __asan_address_is_poisoned(void const volatile *addr) {
- return __asan::AddressIsPoisoned((uptr)addr);
-}
-
-uptr __asan_region_is_poisoned(uptr beg, uptr size) {
- if (!size) return 0;
- uptr end = beg + size;
- if (SANITIZER_MYRIAD2) {
- // On Myriad, address not in DRAM range need to be treated as
- // unpoisoned.
- if (!AddrIsInMem(beg) && !AddrIsInShadow(beg)) return 0;
- if (!AddrIsInMem(end) && !AddrIsInShadow(end)) return 0;
- } else {
- if (!AddrIsInMem(beg)) return beg;
- if (!AddrIsInMem(end)) return end;
- }
- CHECK_LT(beg, end);
- uptr aligned_b = RoundUpTo(beg, SHADOW_GRANULARITY);
- uptr aligned_e = RoundDownTo(end, SHADOW_GRANULARITY);
- uptr shadow_beg = MemToShadow(aligned_b);
- uptr shadow_end = MemToShadow(aligned_e);
- // First check the first and the last application bytes,
- // then check the SHADOW_GRANULARITY-aligned region by calling
- // mem_is_zero on the corresponding shadow.
- if (!__asan::AddressIsPoisoned(beg) &&
- !__asan::AddressIsPoisoned(end - 1) &&
- (shadow_end <= shadow_beg ||
- __sanitizer::mem_is_zero((const char *)shadow_beg,
- shadow_end - shadow_beg)))
- return 0;
- // The fast check failed, so we have a poisoned byte somewhere.
- // Find it slowly.
- for (; beg < end; beg++)
- if (__asan::AddressIsPoisoned(beg))
- return beg;
- UNREACHABLE("mem_is_zero returned false, but poisoned byte was not found");
- return 0;
-}
-
-#define CHECK_SMALL_REGION(p, size, isWrite) \
- do { \
- uptr __p = reinterpret_cast<uptr>(p); \
- uptr __size = size; \
- if (UNLIKELY(__asan::AddressIsPoisoned(__p) || \
- __asan::AddressIsPoisoned(__p + __size - 1))) { \
- GET_CURRENT_PC_BP_SP; \
- uptr __bad = __asan_region_is_poisoned(__p, __size); \
- __asan_report_error(pc, bp, sp, __bad, isWrite, __size, 0);\
- } \
- } while (false)
-
-
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-u16 __sanitizer_unaligned_load16(const uu16 *p) {
- CHECK_SMALL_REGION(p, sizeof(*p), false);
- return *p;
-}
-
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-u32 __sanitizer_unaligned_load32(const uu32 *p) {
- CHECK_SMALL_REGION(p, sizeof(*p), false);
- return *p;
-}
-
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-u64 __sanitizer_unaligned_load64(const uu64 *p) {
- CHECK_SMALL_REGION(p, sizeof(*p), false);
- return *p;
-}
-
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-void __sanitizer_unaligned_store16(uu16 *p, u16 x) {
- CHECK_SMALL_REGION(p, sizeof(*p), true);
- *p = x;
-}
-
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-void __sanitizer_unaligned_store32(uu32 *p, u32 x) {
- CHECK_SMALL_REGION(p, sizeof(*p), true);
- *p = x;
-}
-
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-void __sanitizer_unaligned_store64(uu64 *p, u64 x) {
- CHECK_SMALL_REGION(p, sizeof(*p), true);
- *p = x;
-}
-
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-void __asan_poison_cxx_array_cookie(uptr p) {
- if (SANITIZER_WORDSIZE != 64) return;
- if (!flags()->poison_array_cookie) return;
- uptr s = MEM_TO_SHADOW(p);
- *reinterpret_cast<u8*>(s) = kAsanArrayCookieMagic;
-}
-
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-uptr __asan_load_cxx_array_cookie(uptr *p) {
- if (SANITIZER_WORDSIZE != 64) return *p;
- if (!flags()->poison_array_cookie) return *p;
- uptr s = MEM_TO_SHADOW(reinterpret_cast<uptr>(p));
- u8 sval = *reinterpret_cast<u8*>(s);
- if (sval == kAsanArrayCookieMagic) return *p;
- // If sval is not kAsanArrayCookieMagic it can only be freed memory,
- // which means that we are going to get double-free. So, return 0 to avoid
- // infinite loop of destructors. We don't want to report a double-free here
- // though, so print a warning just in case.
- // CHECK_EQ(sval, kAsanHeapFreeMagic);
- if (sval == kAsanHeapFreeMagic) {
- Report("AddressSanitizer: loaded array cookie from free-d memory; "
- "expect a double-free report\n");
- return 0;
- }
- // The cookie may remain unpoisoned if e.g. it comes from a custom
- // operator new defined inside a class.
- return *p;
-}
-
-// This is a simplified version of __asan_(un)poison_memory_region, which
-// assumes that left border of region to be poisoned is properly aligned.
-static void PoisonAlignedStackMemory(uptr addr, uptr size, bool do_poison) {
- if (size == 0) return;
- uptr aligned_size = size & ~(SHADOW_GRANULARITY - 1);
- PoisonShadow(addr, aligned_size,
- do_poison ? kAsanStackUseAfterScopeMagic : 0);
- if (size == aligned_size)
- return;
- s8 end_offset = (s8)(size - aligned_size);
- s8* shadow_end = (s8*)MemToShadow(addr + aligned_size);
- s8 end_value = *shadow_end;
- if (do_poison) {
- // If possible, mark all the bytes mapping to last shadow byte as
- // unaddressable.
- if (end_value > 0 && end_value <= end_offset)
- *shadow_end = (s8)kAsanStackUseAfterScopeMagic;
- } else {
- // If necessary, mark few first bytes mapping to last shadow byte
- // as addressable
- if (end_value != 0)
- *shadow_end = Max(end_value, end_offset);
- }
-}
-
-void __asan_set_shadow_00(uptr addr, uptr size) {
- REAL(memset)((void *)addr, 0, size);
-}
-
-void __asan_set_shadow_f1(uptr addr, uptr size) {
- REAL(memset)((void *)addr, 0xf1, size);
-}
-
-void __asan_set_shadow_f2(uptr addr, uptr size) {
- REAL(memset)((void *)addr, 0xf2, size);
-}
-
-void __asan_set_shadow_f3(uptr addr, uptr size) {
- REAL(memset)((void *)addr, 0xf3, size);
-}
-
-void __asan_set_shadow_f5(uptr addr, uptr size) {
- REAL(memset)((void *)addr, 0xf5, size);
-}
-
-void __asan_set_shadow_f8(uptr addr, uptr size) {
- REAL(memset)((void *)addr, 0xf8, size);
-}
-
-void __asan_poison_stack_memory(uptr addr, uptr size) {
- VReport(1, "poisoning: %p %zx\n", (void *)addr, size);
- PoisonAlignedStackMemory(addr, size, true);
-}
-
-void __asan_unpoison_stack_memory(uptr addr, uptr size) {
- VReport(1, "unpoisoning: %p %zx\n", (void *)addr, size);
- PoisonAlignedStackMemory(addr, size, false);
-}
-
-void __sanitizer_annotate_contiguous_container(const void *beg_p,
- const void *end_p,
- const void *old_mid_p,
- const void *new_mid_p) {
- if (!flags()->detect_container_overflow) return;
- VPrintf(2, "contiguous_container: %p %p %p %p\n", beg_p, end_p, old_mid_p,
- new_mid_p);
- uptr beg = reinterpret_cast<uptr>(beg_p);
- uptr end = reinterpret_cast<uptr>(end_p);
- uptr old_mid = reinterpret_cast<uptr>(old_mid_p);
- uptr new_mid = reinterpret_cast<uptr>(new_mid_p);
- uptr granularity = SHADOW_GRANULARITY;
- if (!(beg <= old_mid && beg <= new_mid && old_mid <= end && new_mid <= end &&
- IsAligned(beg, granularity))) {
- GET_STACK_TRACE_FATAL_HERE;
- ReportBadParamsToAnnotateContiguousContainer(beg, end, old_mid, new_mid,
- &stack);
- }
- CHECK_LE(end - beg,
- FIRST_32_SECOND_64(1UL << 30, 1ULL << 34)); // Sanity check.
-
- uptr a = RoundDownTo(Min(old_mid, new_mid), granularity);
- uptr c = RoundUpTo(Max(old_mid, new_mid), granularity);
- uptr d1 = RoundDownTo(old_mid, granularity);
- // uptr d2 = RoundUpTo(old_mid, granularity);
- // Currently we should be in this state:
- // [a, d1) is good, [d2, c) is bad, [d1, d2) is partially good.
- // Make a quick sanity check that we are indeed in this state.
- //
- // FIXME: Two of these three checks are disabled until we fix
- // https://github.com/google/sanitizers/issues/258.
- // if (d1 != d2)
- // CHECK_EQ(*(u8*)MemToShadow(d1), old_mid - d1);
- if (a + granularity <= d1)
- CHECK_EQ(*(u8*)MemToShadow(a), 0);
- // if (d2 + granularity <= c && c <= end)
- // CHECK_EQ(*(u8 *)MemToShadow(c - granularity),
- // kAsanContiguousContainerOOBMagic);
-
- uptr b1 = RoundDownTo(new_mid, granularity);
- uptr b2 = RoundUpTo(new_mid, granularity);
- // New state:
- // [a, b1) is good, [b2, c) is bad, [b1, b2) is partially good.
- PoisonShadow(a, b1 - a, 0);
- PoisonShadow(b2, c - b2, kAsanContiguousContainerOOBMagic);
- if (b1 != b2) {
- CHECK_EQ(b2 - b1, granularity);
- *(u8*)MemToShadow(b1) = static_cast<u8>(new_mid - b1);
- }
-}
-
-const void *__sanitizer_contiguous_container_find_bad_address(
- const void *beg_p, const void *mid_p, const void *end_p) {
- if (!flags()->detect_container_overflow)
- return nullptr;
- uptr beg = reinterpret_cast<uptr>(beg_p);
- uptr end = reinterpret_cast<uptr>(end_p);
- uptr mid = reinterpret_cast<uptr>(mid_p);
- CHECK_LE(beg, mid);
- CHECK_LE(mid, end);
- // Check some bytes starting from beg, some bytes around mid, and some bytes
- // ending with end.
- uptr kMaxRangeToCheck = 32;
- uptr r1_beg = beg;
- uptr r1_end = Min(beg + kMaxRangeToCheck, mid);
- uptr r2_beg = Max(beg, mid - kMaxRangeToCheck);
- uptr r2_end = Min(end, mid + kMaxRangeToCheck);
- uptr r3_beg = Max(end - kMaxRangeToCheck, mid);
- uptr r3_end = end;
- for (uptr i = r1_beg; i < r1_end; i++)
- if (AddressIsPoisoned(i))
- return reinterpret_cast<const void *>(i);
- for (uptr i = r2_beg; i < mid; i++)
- if (AddressIsPoisoned(i))
- return reinterpret_cast<const void *>(i);
- for (uptr i = mid; i < r2_end; i++)
- if (!AddressIsPoisoned(i))
- return reinterpret_cast<const void *>(i);
- for (uptr i = r3_beg; i < r3_end; i++)
- if (!AddressIsPoisoned(i))
- return reinterpret_cast<const void *>(i);
- return nullptr;
-}
-
-int __sanitizer_verify_contiguous_container(const void *beg_p,
- const void *mid_p,
- const void *end_p) {
- return __sanitizer_contiguous_container_find_bad_address(beg_p, mid_p,
- end_p) == nullptr;
-}
-
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-void __asan_poison_intra_object_redzone(uptr ptr, uptr size) {
- AsanPoisonOrUnpoisonIntraObjectRedzone(ptr, size, true);
-}
-
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-void __asan_unpoison_intra_object_redzone(uptr ptr, uptr size) {
- AsanPoisonOrUnpoisonIntraObjectRedzone(ptr, size, false);
-}
-
-// --- Implementation of LSan-specific functions --- {{{1
-namespace __lsan {
-bool WordIsPoisoned(uptr addr) {
- return (__asan_region_is_poisoned(addr, sizeof(uptr)) != 0);
-}
-}
diff --git a/lib/asan/asan_poisoning.h b/lib/asan/asan_poisoning.h
deleted file mode 100644
index c94794cead890..0000000000000
--- a/lib/asan/asan_poisoning.h
+++ /dev/null
@@ -1,99 +0,0 @@
-//===-- asan_poisoning.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.
-//
-// Shadow memory poisoning by ASan RTL and by user application.
-//===----------------------------------------------------------------------===//
-
-#include "asan_interceptors.h"
-#include "asan_internal.h"
-#include "asan_mapping.h"
-#include "sanitizer_common/sanitizer_flags.h"
-
-namespace __asan {
-
-// Enable/disable memory poisoning.
-void SetCanPoisonMemory(bool value);
-bool CanPoisonMemory();
-
-// Poisons the shadow memory for "size" bytes starting from "addr".
-void PoisonShadow(uptr addr, uptr size, u8 value);
-
-// Poisons the shadow memory for "redzone_size" bytes starting from
-// "addr + size".
-void PoisonShadowPartialRightRedzone(uptr addr,
- uptr size,
- uptr redzone_size,
- u8 value);
-
-// Fast versions of PoisonShadow and PoisonShadowPartialRightRedzone that
-// assume that memory addresses are properly aligned. Use in
-// performance-critical code with care.
-ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size,
- u8 value) {
- DCHECK(!value || CanPoisonMemory());
- uptr shadow_beg = MEM_TO_SHADOW(aligned_beg);
- uptr shadow_end = MEM_TO_SHADOW(
- aligned_beg + aligned_size - SHADOW_GRANULARITY) + 1;
- // FIXME: Page states are different on Windows, so using the same interface
- // for mapping shadow and zeroing out pages doesn't "just work", so we should
- // probably provide higher-level interface for these operations.
- // For now, just memset on Windows.
- if (value || SANITIZER_WINDOWS == 1 ||
- // TODO(mcgrathr): Fuchsia doesn't allow the shadow mapping to be
- // changed at all. It doesn't currently have an efficient means
- // to zero a bunch of pages, but maybe we should add one.
- SANITIZER_FUCHSIA == 1 ||
- // RTEMS doesn't have have pages, let alone a fast way to zero
- // them, so default to memset.
- SANITIZER_RTEMS == 1 ||
- shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) {
- REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg);
- } else {
- uptr page_size = GetPageSizeCached();
- uptr page_beg = RoundUpTo(shadow_beg, page_size);
- uptr page_end = RoundDownTo(shadow_end, page_size);
-
- if (page_beg >= page_end) {
- REAL(memset)((void *)shadow_beg, 0, shadow_end - shadow_beg);
- } else {
- if (page_beg != shadow_beg) {
- REAL(memset)((void *)shadow_beg, 0, page_beg - shadow_beg);
- }
- if (page_end != shadow_end) {
- REAL(memset)((void *)page_end, 0, shadow_end - page_end);
- }
- ReserveShadowMemoryRange(page_beg, page_end - 1, nullptr);
- }
- }
-}
-
-ALWAYS_INLINE void FastPoisonShadowPartialRightRedzone(
- uptr aligned_addr, uptr size, uptr redzone_size, u8 value) {
- DCHECK(CanPoisonMemory());
- bool poison_partial = flags()->poison_partial;
- u8 *shadow = (u8*)MEM_TO_SHADOW(aligned_addr);
- for (uptr i = 0; i < redzone_size; i += SHADOW_GRANULARITY, shadow++) {
- if (i + SHADOW_GRANULARITY <= size) {
- *shadow = 0; // fully addressable
- } else if (i >= size) {
- *shadow = (SHADOW_GRANULARITY == 128) ? 0xff : value; // unaddressable
- } else {
- // first size-i bytes are addressable
- *shadow = poison_partial ? static_cast<u8>(size - i) : 0;
- }
- }
-}
-
-// Calls __sanitizer::ReleaseMemoryPagesToOS() on
-// [MemToShadow(p), MemToShadow(p+size)].
-void FlushUnneededASanShadowMemory(uptr p, uptr size);
-
-} // namespace __asan
diff --git a/lib/asan/asan_posix.cc b/lib/asan/asan_posix.cc
deleted file mode 100644
index 17c28b0aea2a2..0000000000000
--- a/lib/asan/asan_posix.cc
+++ /dev/null
@@ -1,72 +0,0 @@
-//===-- asan_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 AddressSanitizer, an address sanity checker.
-//
-// Posix-specific details.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_POSIX
-
-#include "asan_internal.h"
-#include "asan_interceptors.h"
-#include "asan_mapping.h"
-#include "asan_report.h"
-#include "asan_stack.h"
-#include "sanitizer_common/sanitizer_libc.h"
-#include "sanitizer_common/sanitizer_posix.h"
-#include "sanitizer_common/sanitizer_procmaps.h"
-
-#include <pthread.h>
-#include <stdlib.h>
-#include <sys/time.h>
-#include <sys/resource.h>
-#include <unistd.h>
-
-namespace __asan {
-
-void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
- StartReportDeadlySignal();
- SignalContext sig(siginfo, context);
- ReportDeadlySignal(sig);
-}
-
-// ---------------------- TSD ---------------- {{{1
-
-static pthread_key_t tsd_key;
-static bool tsd_key_inited = false;
-void AsanTSDInit(void (*destructor)(void *tsd)) {
- CHECK(!tsd_key_inited);
- tsd_key_inited = true;
- CHECK_EQ(0, pthread_key_create(&tsd_key, destructor));
-}
-
-void *AsanTSDGet() {
- CHECK(tsd_key_inited);
- return pthread_getspecific(tsd_key);
-}
-
-void AsanTSDSet(void *tsd) {
- CHECK(tsd_key_inited);
- pthread_setspecific(tsd_key, tsd);
-}
-
-void PlatformTSDDtor(void *tsd) {
- AsanThreadContext *context = (AsanThreadContext*)tsd;
- if (context->destructor_iterations > 1) {
- context->destructor_iterations--;
- CHECK_EQ(0, pthread_setspecific(tsd_key, tsd));
- return;
- }
- AsanThread::TSDDtor(tsd);
-}
-} // namespace __asan
-
-#endif // SANITIZER_POSIX
diff --git a/lib/asan/asan_preinit.cc b/lib/asan/asan_preinit.cc
deleted file mode 100644
index a3986d24f9c3b..0000000000000
--- a/lib/asan/asan_preinit.cc
+++ /dev/null
@@ -1,25 +0,0 @@
-//===-- asan_preinit.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.
-//
-// Call __asan_init at the very early stage of process startup.
-//===----------------------------------------------------------------------===//
-#include "asan_internal.h"
-
-using namespace __asan;
-
-#if SANITIZER_CAN_USE_PREINIT_ARRAY
- // The symbol is called __local_asan_preinit, because it's not intended to be
- // exported.
- // This code linked into the main executable when -fsanitize=address is in
- // the link flags. It can only use exported interface functions.
- __attribute__((section(".preinit_array"), used))
- void (*__local_asan_preinit)(void) = __asan_init;
-#endif
diff --git a/lib/asan/asan_premap_shadow.cc b/lib/asan/asan_premap_shadow.cc
deleted file mode 100644
index 229eba99fe0eb..0000000000000
--- a/lib/asan/asan_premap_shadow.cc
+++ /dev/null
@@ -1,79 +0,0 @@
-//===-- asan_premap_shadow.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.
-//
-// Reserve shadow memory with an ifunc resolver.
-//===----------------------------------------------------------------------===//
-
-#include "asan_mapping.h"
-
-#if ASAN_PREMAP_SHADOW
-
-#include "asan_premap_shadow.h"
-#include "sanitizer_common/sanitizer_posix.h"
-
-namespace __asan {
-
-// The code in this file needs to run in an unrelocated binary. It may not
-// access any external symbol, including its own non-hidden globals.
-
-// Conservative upper limit.
-uptr PremapShadowSize() {
- uptr granularity = GetMmapGranularity();
- return RoundUpTo(GetMaxVirtualAddress() >> SHADOW_SCALE, granularity);
-}
-
-// Returns an address aligned to 8 pages, such that one page on the left and
-// PremapShadowSize() bytes on the right of it are mapped r/o.
-uptr PremapShadow() {
- uptr granularity = GetMmapGranularity();
- uptr alignment = granularity * 8;
- uptr left_padding = granularity;
- uptr shadow_size = PremapShadowSize();
- uptr map_size = shadow_size + left_padding + alignment;
-
- uptr map_start = (uptr)MmapNoAccess(map_size);
- CHECK_NE(map_start, ~(uptr)0);
-
- uptr shadow_start = RoundUpTo(map_start + left_padding, alignment);
- uptr shadow_end = shadow_start + shadow_size;
- internal_munmap(reinterpret_cast<void *>(map_start),
- shadow_start - left_padding - map_start);
- internal_munmap(reinterpret_cast<void *>(shadow_end),
- map_start + map_size - shadow_end);
- return shadow_start;
-}
-
-bool PremapShadowFailed() {
- uptr shadow = reinterpret_cast<uptr>(&__asan_shadow);
- uptr resolver = reinterpret_cast<uptr>(&__asan_premap_shadow);
- // shadow == resolver is how Android KitKat and older handles ifunc.
- // shadow == 0 just in case.
- if (shadow == 0 || shadow == resolver)
- return true;
- return false;
-}
-} // namespace __asan
-
-extern "C" {
-decltype(__asan_shadow)* __asan_premap_shadow() {
- // The resolver may be called multiple times. Map the shadow just once.
- static uptr premapped_shadow = 0;
- if (!premapped_shadow) premapped_shadow = __asan::PremapShadow();
- return reinterpret_cast<decltype(__asan_shadow)*>(premapped_shadow);
-}
-
-// __asan_shadow is a "function" that has the same address as the first byte of
-// the shadow mapping.
-INTERFACE_ATTRIBUTE __attribute__((ifunc("__asan_premap_shadow"))) void
-__asan_shadow();
-}
-
-#endif // ASAN_PREMAP_SHADOW
diff --git a/lib/asan/asan_premap_shadow.h b/lib/asan/asan_premap_shadow.h
deleted file mode 100644
index 41acbdbbb69f6..0000000000000
--- a/lib/asan/asan_premap_shadow.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===-- asan_mapping.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.
-//
-// Premap shadow range with an ifunc resolver.
-//===----------------------------------------------------------------------===//
-
-
-#ifndef ASAN_PREMAP_SHADOW_H
-#define ASAN_PREMAP_SHADOW_H
-
-#if ASAN_PREMAP_SHADOW
-namespace __asan {
-// Conservative upper limit.
-uptr PremapShadowSize();
-bool PremapShadowFailed();
-}
-#endif
-
-extern "C" INTERFACE_ATTRIBUTE void __asan_shadow();
-extern "C" decltype(__asan_shadow)* __asan_premap_shadow();
-
-#endif // ASAN_PREMAP_SHADOW_H
diff --git a/lib/asan/asan_report.cc b/lib/asan/asan_report.cc
deleted file mode 100644
index 439712350e46e..0000000000000
--- a/lib/asan/asan_report.cc
+++ /dev/null
@@ -1,552 +0,0 @@
-//===-- asan_report.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 file contains error reporting code.
-//===----------------------------------------------------------------------===//
-
-#include "asan_errors.h"
-#include "asan_flags.h"
-#include "asan_descriptions.h"
-#include "asan_internal.h"
-#include "asan_mapping.h"
-#include "asan_report.h"
-#include "asan_scariness_score.h"
-#include "asan_stack.h"
-#include "asan_thread.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_flags.h"
-#include "sanitizer_common/sanitizer_report_decorator.h"
-#include "sanitizer_common/sanitizer_stackdepot.h"
-#include "sanitizer_common/sanitizer_symbolizer.h"
-
-namespace __asan {
-
-// -------------------- User-specified callbacks ----------------- {{{1
-static void (*error_report_callback)(const char*);
-static char *error_message_buffer = nullptr;
-static uptr error_message_buffer_pos = 0;
-static BlockingMutex error_message_buf_mutex(LINKER_INITIALIZED);
-static const unsigned kAsanBuggyPcPoolSize = 25;
-static __sanitizer::atomic_uintptr_t AsanBuggyPcPool[kAsanBuggyPcPoolSize];
-
-void AppendToErrorMessageBuffer(const char *buffer) {
- BlockingMutexLock l(&error_message_buf_mutex);
- if (!error_message_buffer) {
- error_message_buffer =
- (char*)MmapOrDieQuietly(kErrorMessageBufferSize, __func__);
- error_message_buffer_pos = 0;
- }
- uptr length = internal_strlen(buffer);
- RAW_CHECK(kErrorMessageBufferSize >= error_message_buffer_pos);
- uptr remaining = kErrorMessageBufferSize - error_message_buffer_pos;
- internal_strncpy(error_message_buffer + error_message_buffer_pos,
- buffer, remaining);
- error_message_buffer[kErrorMessageBufferSize - 1] = '\0';
- // FIXME: reallocate the buffer instead of truncating the message.
- error_message_buffer_pos += Min(remaining, length);
-}
-
-// ---------------------- Helper functions ----------------------- {{{1
-
-void PrintMemoryByte(InternalScopedString *str, const char *before, u8 byte,
- bool in_shadow, const char *after) {
- Decorator d;
- str->append("%s%s%x%x%s%s", before,
- in_shadow ? d.ShadowByte(byte) : d.MemoryByte(), byte >> 4,
- byte & 15, d.Default(), after);
-}
-
-static void PrintZoneForPointer(uptr ptr, uptr zone_ptr,
- const char *zone_name) {
- if (zone_ptr) {
- if (zone_name) {
- Printf("malloc_zone_from_ptr(%p) = %p, which is %s\n",
- ptr, zone_ptr, zone_name);
- } else {
- Printf("malloc_zone_from_ptr(%p) = %p, which doesn't have a name\n",
- ptr, zone_ptr);
- }
- } else {
- Printf("malloc_zone_from_ptr(%p) = 0\n", ptr);
- }
-}
-
-// ---------------------- Address Descriptions ------------------- {{{1
-
-bool ParseFrameDescription(const char *frame_descr,
- InternalMmapVector<StackVarDescr> *vars) {
- CHECK(frame_descr);
- const char *p;
- // This string is created by the compiler and has the following form:
- // "n alloc_1 alloc_2 ... alloc_n"
- // where alloc_i looks like "offset size len ObjectName"
- // or "offset size len ObjectName:line".
- uptr n_objects = (uptr)internal_simple_strtoll(frame_descr, &p, 10);
- if (n_objects == 0)
- return false;
-
- for (uptr i = 0; i < n_objects; i++) {
- uptr beg = (uptr)internal_simple_strtoll(p, &p, 10);
- uptr size = (uptr)internal_simple_strtoll(p, &p, 10);
- uptr len = (uptr)internal_simple_strtoll(p, &p, 10);
- if (beg == 0 || size == 0 || *p != ' ') {
- return false;
- }
- p++;
- char *colon_pos = internal_strchr(p, ':');
- uptr line = 0;
- uptr name_len = len;
- if (colon_pos != nullptr && colon_pos < p + len) {
- name_len = colon_pos - p;
- line = (uptr)internal_simple_strtoll(colon_pos + 1, nullptr, 10);
- }
- StackVarDescr var = {beg, size, p, name_len, line};
- vars->push_back(var);
- p += len;
- }
-
- return true;
-}
-
-// -------------------- Different kinds of reports ----------------- {{{1
-
-// Use ScopedInErrorReport to run common actions just before and
-// immediately after printing error report.
-class ScopedInErrorReport {
- public:
- explicit ScopedInErrorReport(bool fatal = false)
- : halt_on_error_(fatal || flags()->halt_on_error) {
- // Make sure the registry and sanitizer report mutexes are locked while
- // we're printing an error report.
- // We can lock them only here to avoid self-deadlock in case of
- // recursive reports.
- asanThreadRegistry().Lock();
- Printf(
- "=================================================================\n");
- }
-
- ~ScopedInErrorReport() {
- if (halt_on_error_ && !__sanitizer_acquire_crash_state()) {
- asanThreadRegistry().Unlock();
- return;
- }
- ASAN_ON_ERROR();
- if (current_error_.IsValid()) current_error_.Print();
-
- // Make sure the current thread is announced.
- DescribeThread(GetCurrentThread());
- // We may want to grab this lock again when printing stats.
- asanThreadRegistry().Unlock();
- // Print memory stats.
- if (flags()->print_stats)
- __asan_print_accumulated_stats();
-
- if (common_flags()->print_cmdline)
- PrintCmdline();
-
- if (common_flags()->print_module_map == 2) PrintModuleMap();
-
- // Copy the message buffer so that we could start logging without holding a
- // lock that gets aquired during printing.
- InternalMmapVector<char> buffer_copy(kErrorMessageBufferSize);
- {
- BlockingMutexLock l(&error_message_buf_mutex);
- internal_memcpy(buffer_copy.data(),
- error_message_buffer, kErrorMessageBufferSize);
- }
-
- LogFullErrorReport(buffer_copy.data());
-
- if (error_report_callback) {
- error_report_callback(buffer_copy.data());
- }
-
- if (halt_on_error_ && common_flags()->abort_on_error) {
- // On Android the message is truncated to 512 characters.
- // FIXME: implement "compact" error format, possibly without, or with
- // highly compressed stack traces?
- // FIXME: or just use the summary line as abort message?
- SetAbortMessage(buffer_copy.data());
- }
-
- // In halt_on_error = false mode, reset the current error object (before
- // unlocking).
- if (!halt_on_error_)
- internal_memset(&current_error_, 0, sizeof(current_error_));
-
- if (halt_on_error_) {
- Report("ABORTING\n");
- Die();
- }
- }
-
- void ReportError(const ErrorDescription &description) {
- // Can only report one error per ScopedInErrorReport.
- CHECK_EQ(current_error_.kind, kErrorKindInvalid);
- current_error_ = description;
- }
-
- static ErrorDescription &CurrentError() {
- return current_error_;
- }
-
- private:
- ScopedErrorReportLock error_report_lock_;
- // Error currently being reported. This enables the destructor to interact
- // with the debugger and point it to an error description.
- static ErrorDescription current_error_;
- bool halt_on_error_;
-};
-
-ErrorDescription ScopedInErrorReport::current_error_(LINKER_INITIALIZED);
-
-void ReportDeadlySignal(const SignalContext &sig) {
- ScopedInErrorReport in_report(/*fatal*/ true);
- ErrorDeadlySignal error(GetCurrentTidOrInvalid(), sig);
- in_report.ReportError(error);
-}
-
-void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack) {
- ScopedInErrorReport in_report;
- ErrorDoubleFree error(GetCurrentTidOrInvalid(), free_stack, addr);
- in_report.ReportError(error);
-}
-
-void ReportNewDeleteTypeMismatch(uptr addr, uptr delete_size,
- uptr delete_alignment,
- BufferedStackTrace *free_stack) {
- ScopedInErrorReport in_report;
- ErrorNewDeleteTypeMismatch error(GetCurrentTidOrInvalid(), free_stack, addr,
- delete_size, delete_alignment);
- in_report.ReportError(error);
-}
-
-void ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack) {
- ScopedInErrorReport in_report;
- ErrorFreeNotMalloced error(GetCurrentTidOrInvalid(), free_stack, addr);
- in_report.ReportError(error);
-}
-
-void ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack,
- AllocType alloc_type,
- AllocType dealloc_type) {
- ScopedInErrorReport in_report;
- ErrorAllocTypeMismatch error(GetCurrentTidOrInvalid(), free_stack, addr,
- alloc_type, dealloc_type);
- in_report.ReportError(error);
-}
-
-void ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack) {
- ScopedInErrorReport in_report;
- ErrorMallocUsableSizeNotOwned error(GetCurrentTidOrInvalid(), stack, addr);
- in_report.ReportError(error);
-}
-
-void ReportSanitizerGetAllocatedSizeNotOwned(uptr addr,
- BufferedStackTrace *stack) {
- ScopedInErrorReport in_report;
- ErrorSanitizerGetAllocatedSizeNotOwned error(GetCurrentTidOrInvalid(), stack,
- addr);
- in_report.ReportError(error);
-}
-
-void ReportCallocOverflow(uptr count, uptr size, BufferedStackTrace *stack) {
- ScopedInErrorReport in_report(/*fatal*/ true);
- ErrorCallocOverflow error(GetCurrentTidOrInvalid(), stack, count, size);
- in_report.ReportError(error);
-}
-
-void ReportPvallocOverflow(uptr size, BufferedStackTrace *stack) {
- ScopedInErrorReport in_report(/*fatal*/ true);
- ErrorPvallocOverflow error(GetCurrentTidOrInvalid(), stack, size);
- in_report.ReportError(error);
-}
-
-void ReportInvalidAllocationAlignment(uptr alignment,
- BufferedStackTrace *stack) {
- ScopedInErrorReport in_report(/*fatal*/ true);
- ErrorInvalidAllocationAlignment error(GetCurrentTidOrInvalid(), stack,
- alignment);
- in_report.ReportError(error);
-}
-
-void ReportInvalidAlignedAllocAlignment(uptr size, uptr alignment,
- BufferedStackTrace *stack) {
- ScopedInErrorReport in_report(/*fatal*/ true);
- ErrorInvalidAlignedAllocAlignment error(GetCurrentTidOrInvalid(), stack,
- size, alignment);
- in_report.ReportError(error);
-}
-
-void ReportInvalidPosixMemalignAlignment(uptr alignment,
- BufferedStackTrace *stack) {
- ScopedInErrorReport in_report(/*fatal*/ true);
- ErrorInvalidPosixMemalignAlignment error(GetCurrentTidOrInvalid(), stack,
- alignment);
- in_report.ReportError(error);
-}
-
-void ReportAllocationSizeTooBig(uptr user_size, uptr total_size, uptr max_size,
- BufferedStackTrace *stack) {
- ScopedInErrorReport in_report(/*fatal*/ true);
- ErrorAllocationSizeTooBig error(GetCurrentTidOrInvalid(), stack, user_size,
- total_size, max_size);
- in_report.ReportError(error);
-}
-
-void ReportRssLimitExceeded(BufferedStackTrace *stack) {
- ScopedInErrorReport in_report(/*fatal*/ true);
- ErrorRssLimitExceeded error(GetCurrentTidOrInvalid(), stack);
- in_report.ReportError(error);
-}
-
-void ReportOutOfMemory(uptr requested_size, BufferedStackTrace *stack) {
- ScopedInErrorReport in_report(/*fatal*/ true);
- ErrorOutOfMemory error(GetCurrentTidOrInvalid(), stack, requested_size);
- in_report.ReportError(error);
-}
-
-void ReportStringFunctionMemoryRangesOverlap(const char *function,
- const char *offset1, uptr length1,
- const char *offset2, uptr length2,
- BufferedStackTrace *stack) {
- ScopedInErrorReport in_report;
- ErrorStringFunctionMemoryRangesOverlap error(
- GetCurrentTidOrInvalid(), stack, (uptr)offset1, length1, (uptr)offset2,
- length2, function);
- in_report.ReportError(error);
-}
-
-void ReportStringFunctionSizeOverflow(uptr offset, uptr size,
- BufferedStackTrace *stack) {
- ScopedInErrorReport in_report;
- ErrorStringFunctionSizeOverflow error(GetCurrentTidOrInvalid(), stack, offset,
- size);
- in_report.ReportError(error);
-}
-
-void ReportBadParamsToAnnotateContiguousContainer(uptr beg, uptr end,
- uptr old_mid, uptr new_mid,
- BufferedStackTrace *stack) {
- ScopedInErrorReport in_report;
- ErrorBadParamsToAnnotateContiguousContainer error(
- GetCurrentTidOrInvalid(), stack, beg, end, old_mid, new_mid);
- in_report.ReportError(error);
-}
-
-void ReportODRViolation(const __asan_global *g1, u32 stack_id1,
- const __asan_global *g2, u32 stack_id2) {
- ScopedInErrorReport in_report;
- ErrorODRViolation error(GetCurrentTidOrInvalid(), g1, stack_id1, g2,
- stack_id2);
- in_report.ReportError(error);
-}
-
-// ----------------------- CheckForInvalidPointerPair ----------- {{{1
-static NOINLINE void ReportInvalidPointerPair(uptr pc, uptr bp, uptr sp,
- uptr a1, uptr a2) {
- ScopedInErrorReport in_report;
- ErrorInvalidPointerPair error(GetCurrentTidOrInvalid(), pc, bp, sp, a1, a2);
- in_report.ReportError(error);
-}
-
-static bool IsInvalidPointerPair(uptr a1, uptr a2) {
- if (a1 == a2)
- return false;
-
- // 256B in shadow memory can be iterated quite fast
- static const uptr kMaxOffset = 2048;
-
- uptr left = a1 < a2 ? a1 : a2;
- uptr right = a1 < a2 ? a2 : a1;
- uptr offset = right - left;
- if (offset <= kMaxOffset)
- return __asan_region_is_poisoned(left, offset);
-
- AsanThread *t = GetCurrentThread();
-
- // check whether left is a stack memory pointer
- if (uptr shadow_offset1 = t->GetStackVariableShadowStart(left)) {
- uptr shadow_offset2 = t->GetStackVariableShadowStart(right);
- return shadow_offset2 == 0 || shadow_offset1 != shadow_offset2;
- }
-
- // check whether left is a heap memory address
- HeapAddressDescription hdesc1, hdesc2;
- if (GetHeapAddressInformation(left, 0, &hdesc1) &&
- hdesc1.chunk_access.access_type == kAccessTypeInside)
- return !GetHeapAddressInformation(right, 0, &hdesc2) ||
- hdesc2.chunk_access.access_type != kAccessTypeInside ||
- hdesc1.chunk_access.chunk_begin != hdesc2.chunk_access.chunk_begin;
-
- // check whether left is an address of a global variable
- GlobalAddressDescription gdesc1, gdesc2;
- if (GetGlobalAddressInformation(left, 0, &gdesc1))
- return !GetGlobalAddressInformation(right - 1, 0, &gdesc2) ||
- !gdesc1.PointsInsideTheSameVariable(gdesc2);
-
- if (t->GetStackVariableShadowStart(right) ||
- GetHeapAddressInformation(right, 0, &hdesc2) ||
- GetGlobalAddressInformation(right - 1, 0, &gdesc2))
- return true;
-
- // At this point we know nothing about both a1 and a2 addresses.
- return false;
-}
-
-static INLINE void CheckForInvalidPointerPair(void *p1, void *p2) {
- switch (flags()->detect_invalid_pointer_pairs) {
- case 0 : return;
- case 1 : if (p1 == nullptr || p2 == nullptr) return; break;
- }
-
- uptr a1 = reinterpret_cast<uptr>(p1);
- uptr a2 = reinterpret_cast<uptr>(p2);
-
- if (IsInvalidPointerPair(a1, a2)) {
- GET_CALLER_PC_BP_SP;
- ReportInvalidPointerPair(pc, bp, sp, a1, a2);
- }
-}
-// ----------------------- Mac-specific reports ----------------- {{{1
-
-void ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr, const char *zone_name,
- BufferedStackTrace *stack) {
- ScopedInErrorReport in_report;
- Printf("mz_realloc(%p) -- attempting to realloc unallocated memory.\n"
- "This is an unrecoverable problem, exiting now.\n",
- addr);
- PrintZoneForPointer(addr, zone_ptr, zone_name);
- stack->Print();
- DescribeAddressIfHeap(addr);
-}
-
-// -------------- SuppressErrorReport -------------- {{{1
-// Avoid error reports duplicating for ASan recover mode.
-static bool SuppressErrorReport(uptr pc) {
- if (!common_flags()->suppress_equal_pcs) return false;
- for (unsigned i = 0; i < kAsanBuggyPcPoolSize; i++) {
- uptr cmp = atomic_load_relaxed(&AsanBuggyPcPool[i]);
- if (cmp == 0 && atomic_compare_exchange_strong(&AsanBuggyPcPool[i], &cmp,
- pc, memory_order_relaxed))
- return false;
- if (cmp == pc) return true;
- }
- Die();
-}
-
-void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write,
- uptr access_size, u32 exp, bool fatal) {
- if (!fatal && SuppressErrorReport(pc)) return;
- ENABLE_FRAME_POINTER;
-
- // Optimization experiments.
- // The experiments can be used to evaluate potential optimizations that remove
- // instrumentation (assess false negatives). Instead of completely removing
- // some instrumentation, compiler can emit special calls into runtime
- // (e.g. __asan_report_exp_load1 instead of __asan_report_load1) and pass
- // mask of experiments (exp).
- // The reaction to a non-zero value of exp is to be defined.
- (void)exp;
-
- ScopedInErrorReport in_report(fatal);
- ErrorGeneric error(GetCurrentTidOrInvalid(), pc, bp, sp, addr, is_write,
- access_size);
- in_report.ReportError(error);
-}
-
-} // namespace __asan
-
-// --------------------------- Interface --------------------- {{{1
-using namespace __asan; // NOLINT
-
-void __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write,
- uptr access_size, u32 exp) {
- ENABLE_FRAME_POINTER;
- bool fatal = flags()->halt_on_error;
- ReportGenericError(pc, bp, sp, addr, is_write, access_size, exp, fatal);
-}
-
-void NOINLINE __asan_set_error_report_callback(void (*callback)(const char*)) {
- BlockingMutexLock l(&error_message_buf_mutex);
- error_report_callback = callback;
-}
-
-void __asan_describe_address(uptr addr) {
- // Thread registry must be locked while we're describing an address.
- asanThreadRegistry().Lock();
- PrintAddressDescription(addr, 1, "");
- asanThreadRegistry().Unlock();
-}
-
-int __asan_report_present() {
- return ScopedInErrorReport::CurrentError().kind != kErrorKindInvalid;
-}
-
-uptr __asan_get_report_pc() {
- if (ScopedInErrorReport::CurrentError().kind == kErrorKindGeneric)
- return ScopedInErrorReport::CurrentError().Generic.pc;
- return 0;
-}
-
-uptr __asan_get_report_bp() {
- if (ScopedInErrorReport::CurrentError().kind == kErrorKindGeneric)
- return ScopedInErrorReport::CurrentError().Generic.bp;
- return 0;
-}
-
-uptr __asan_get_report_sp() {
- if (ScopedInErrorReport::CurrentError().kind == kErrorKindGeneric)
- return ScopedInErrorReport::CurrentError().Generic.sp;
- return 0;
-}
-
-uptr __asan_get_report_address() {
- ErrorDescription &err = ScopedInErrorReport::CurrentError();
- if (err.kind == kErrorKindGeneric)
- return err.Generic.addr_description.Address();
- else if (err.kind == kErrorKindDoubleFree)
- return err.DoubleFree.addr_description.addr;
- return 0;
-}
-
-int __asan_get_report_access_type() {
- if (ScopedInErrorReport::CurrentError().kind == kErrorKindGeneric)
- return ScopedInErrorReport::CurrentError().Generic.is_write;
- return 0;
-}
-
-uptr __asan_get_report_access_size() {
- if (ScopedInErrorReport::CurrentError().kind == kErrorKindGeneric)
- return ScopedInErrorReport::CurrentError().Generic.access_size;
- return 0;
-}
-
-const char *__asan_get_report_description() {
- if (ScopedInErrorReport::CurrentError().kind == kErrorKindGeneric)
- return ScopedInErrorReport::CurrentError().Generic.bug_descr;
- return ScopedInErrorReport::CurrentError().Base.scariness.GetDescription();
-}
-
-extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE
-void __sanitizer_ptr_sub(void *a, void *b) {
- CheckForInvalidPointerPair(a, b);
-}
-SANITIZER_INTERFACE_ATTRIBUTE
-void __sanitizer_ptr_cmp(void *a, void *b) {
- CheckForInvalidPointerPair(a, b);
-}
-} // extern "C"
-
-// Provide default implementation of __asan_on_error that does nothing
-// and may be overriden by user.
-SANITIZER_INTERFACE_WEAK_DEF(void, __asan_on_error, void) {}
diff --git a/lib/asan/asan_report.h b/lib/asan/asan_report.h
deleted file mode 100644
index f7153d4810d06..0000000000000
--- a/lib/asan/asan_report.h
+++ /dev/null
@@ -1,94 +0,0 @@
-//===-- asan_report.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.
-//
-// ASan-private header for error reporting functions.
-//===----------------------------------------------------------------------===//
-
-#include "asan_allocator.h"
-#include "asan_internal.h"
-#include "asan_thread.h"
-
-namespace __asan {
-
-struct StackVarDescr {
- uptr beg;
- uptr size;
- const char *name_pos;
- uptr name_len;
- uptr line;
-};
-
-// Returns the number of globals close to the provided address and copies
-// them to "globals" array.
-int GetGlobalsForAddress(uptr addr, __asan_global *globals, u32 *reg_sites,
- int max_globals);
-
-const char *MaybeDemangleGlobalName(const char *name);
-void PrintGlobalNameIfASCII(InternalScopedString *str, const __asan_global &g);
-void PrintGlobalLocation(InternalScopedString *str, const __asan_global &g);
-
-void PrintMemoryByte(InternalScopedString *str, const char *before, u8 byte,
- bool in_shadow, const char *after = "\n");
-
-// The following functions prints address description depending
-// on the memory type (shadow/heap/stack/global).
-bool ParseFrameDescription(const char *frame_descr,
- InternalMmapVector<StackVarDescr> *vars);
-
-// Different kinds of error reports.
-void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write,
- uptr access_size, u32 exp, bool fatal);
-void ReportDeadlySignal(const SignalContext &sig);
-void ReportNewDeleteTypeMismatch(uptr addr, uptr delete_size,
- uptr delete_alignment,
- BufferedStackTrace *free_stack);
-void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack);
-void ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack);
-void ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack,
- AllocType alloc_type,
- AllocType dealloc_type);
-void ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack);
-void ReportSanitizerGetAllocatedSizeNotOwned(uptr addr,
- BufferedStackTrace *stack);
-void ReportCallocOverflow(uptr count, uptr size, BufferedStackTrace *stack);
-void ReportPvallocOverflow(uptr size, BufferedStackTrace *stack);
-void ReportInvalidAllocationAlignment(uptr alignment,
- BufferedStackTrace *stack);
-void ReportInvalidAlignedAllocAlignment(uptr size, uptr alignment,
- BufferedStackTrace *stack);
-void ReportInvalidPosixMemalignAlignment(uptr alignment,
- BufferedStackTrace *stack);
-void ReportAllocationSizeTooBig(uptr user_size, uptr total_size, uptr max_size,
- BufferedStackTrace *stack);
-void ReportRssLimitExceeded(BufferedStackTrace *stack);
-void ReportOutOfMemory(uptr requested_size, BufferedStackTrace *stack);
-void ReportStringFunctionMemoryRangesOverlap(const char *function,
- const char *offset1, uptr length1,
- const char *offset2, uptr length2,
- BufferedStackTrace *stack);
-void ReportStringFunctionSizeOverflow(uptr offset, uptr size,
- BufferedStackTrace *stack);
-void ReportBadParamsToAnnotateContiguousContainer(uptr beg, uptr end,
- uptr old_mid, uptr new_mid,
- BufferedStackTrace *stack);
-
-void ReportODRViolation(const __asan_global *g1, u32 stack_id1,
- const __asan_global *g2, u32 stack_id2);
-
-// Mac-specific errors and warnings.
-void ReportMacMzReallocUnknown(uptr addr, uptr zone_ptr,
- const char *zone_name,
- BufferedStackTrace *stack);
-void ReportMacCfReallocUnknown(uptr addr, uptr zone_ptr,
- const char *zone_name,
- BufferedStackTrace *stack);
-
-} // namespace __asan
diff --git a/lib/asan/asan_rtems.cc b/lib/asan/asan_rtems.cc
deleted file mode 100644
index a4af940057eb8..0000000000000
--- a/lib/asan/asan_rtems.cc
+++ /dev/null
@@ -1,253 +0,0 @@
-//===-- asan_rtems.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.
-//
-// RTEMS-specific details.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_rtems.h"
-#if SANITIZER_RTEMS
-
-#include "asan_internal.h"
-#include "asan_interceptors.h"
-#include "asan_mapping.h"
-#include "asan_poisoning.h"
-#include "asan_report.h"
-#include "asan_stack.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_libc.h"
-
-#include <pthread.h>
-#include <stdlib.h>
-
-namespace __asan {
-
-static void ResetShadowMemory() {
- uptr shadow_start = SHADOW_OFFSET;
- uptr shadow_end = MEM_TO_SHADOW(kMyriadMemoryEnd32);
- uptr gap_start = MEM_TO_SHADOW(shadow_start);
- uptr gap_end = MEM_TO_SHADOW(shadow_end);
-
- REAL(memset)((void *)shadow_start, 0, shadow_end - shadow_start);
- REAL(memset)((void *)gap_start, kAsanShadowGap, gap_end - gap_start);
-}
-
-void InitializeShadowMemory() {
- kHighMemEnd = 0;
- kMidMemBeg = 0;
- kMidMemEnd = 0;
-
- ResetShadowMemory();
-}
-
-void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {
- UNIMPLEMENTED();
-}
-
-void AsanCheckDynamicRTPrereqs() {}
-void AsanCheckIncompatibleRT() {}
-void InitializeAsanInterceptors() {}
-void InitializePlatformInterceptors() {}
-void InitializePlatformExceptionHandlers() {}
-
-// RTEMS only support static linking; it sufficies to return with no
-// error.
-void *AsanDoesNotSupportStaticLinkage() { return nullptr; }
-
-void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
- UNIMPLEMENTED();
-}
-
-void EarlyInit() {
- // Provide early initialization of shadow memory so that
- // instrumented code running before full initialzation will not
- // report spurious errors.
- ResetShadowMemory();
-}
-
-// We can use a plain thread_local variable for TSD.
-static thread_local void *per_thread;
-
-void *AsanTSDGet() { return per_thread; }
-
-void AsanTSDSet(void *tsd) { per_thread = tsd; }
-
-// There's no initialization needed, and the passed-in destructor
-// will never be called. Instead, our own thread destruction hook
-// (below) will call AsanThread::TSDDtor directly.
-void AsanTSDInit(void (*destructor)(void *tsd)) {
- DCHECK(destructor == &PlatformTSDDtor);
-}
-
-void PlatformTSDDtor(void *tsd) { UNREACHABLE(__func__); }
-
-//
-// Thread registration. We provide an API similar to the Fushia port.
-//
-
-struct AsanThread::InitOptions {
- uptr stack_bottom, stack_size, tls_bottom, tls_size;
-};
-
-// Shared setup between thread creation and startup for the initial thread.
-static AsanThread *CreateAsanThread(StackTrace *stack, u32 parent_tid,
- uptr user_id, bool detached,
- uptr stack_bottom, uptr stack_size,
- uptr tls_bottom, uptr tls_size) {
- // In lieu of AsanThread::Create.
- AsanThread *thread = (AsanThread *)MmapOrDie(sizeof(AsanThread), __func__);
- AsanThreadContext::CreateThreadContextArgs args = {thread, stack};
- asanThreadRegistry().CreateThread(user_id, detached, parent_tid, &args);
-
- // On other systems, AsanThread::Init() is called from the new
- // thread itself. But on RTEMS we already know the stack address
- // range beforehand, so we can do most of the setup right now.
- const AsanThread::InitOptions options = {stack_bottom, stack_size,
- tls_bottom, tls_size};
- thread->Init(&options);
- return thread;
-}
-
-// This gets the same arguments passed to Init by CreateAsanThread, above.
-// We're in the creator thread before the new thread is actually started, but
-// its stack and tls address range are already known.
-void AsanThread::SetThreadStackAndTls(const AsanThread::InitOptions *options) {
- DCHECK_NE(GetCurrentThread(), this);
- DCHECK_NE(GetCurrentThread(), nullptr);
- CHECK_NE(options->stack_bottom, 0);
- CHECK_NE(options->stack_size, 0);
- stack_bottom_ = options->stack_bottom;
- stack_top_ = options->stack_bottom + options->stack_size;
- tls_begin_ = options->tls_bottom;
- tls_end_ = options->tls_bottom + options->tls_size;
-}
-
-// Called by __asan::AsanInitInternal (asan_rtl.c). Unlike other ports, the
-// main thread on RTEMS does not require special treatment; its AsanThread is
-// already created by the provided hooks. This function simply looks up and
-// returns the created thread.
-AsanThread *CreateMainThread() {
- return GetThreadContextByTidLocked(0)->thread;
-}
-
-// This is called before each thread creation is attempted. So, in
-// its first call, the calling thread is the initial and sole thread.
-static void *BeforeThreadCreateHook(uptr user_id, bool detached,
- uptr stack_bottom, uptr stack_size,
- uptr tls_bottom, uptr tls_size) {
- EnsureMainThreadIDIsCorrect();
- // Strict init-order checking is thread-hostile.
- if (flags()->strict_init_order) StopInitOrderChecking();
-
- GET_STACK_TRACE_THREAD;
- u32 parent_tid = GetCurrentTidOrInvalid();
-
- return CreateAsanThread(&stack, parent_tid, user_id, detached,
- stack_bottom, stack_size, tls_bottom, tls_size);
-}
-
-// This is called after creating a new thread (in the creating thread),
-// with the pointer returned by BeforeThreadCreateHook (above).
-static void ThreadCreateHook(void *hook, bool aborted) {
- AsanThread *thread = static_cast<AsanThread *>(hook);
- if (!aborted) {
- // The thread was created successfully.
- // ThreadStartHook is already running in the new thread.
- } else {
- // The thread wasn't created after all.
- // Clean up everything we set up in BeforeThreadCreateHook.
- asanThreadRegistry().FinishThread(thread->tid());
- UnmapOrDie(thread, sizeof(AsanThread));
- }
-}
-
-// This is called (1) in the newly-created thread before it runs anything else,
-// with the pointer returned by BeforeThreadCreateHook (above). (2) before a
-// thread restart.
-static void ThreadStartHook(void *hook, uptr os_id) {
- if (!hook)
- return;
-
- AsanThread *thread = static_cast<AsanThread *>(hook);
- SetCurrentThread(thread);
-
- ThreadStatus status =
- asanThreadRegistry().GetThreadLocked(thread->tid())->status;
- DCHECK(status == ThreadStatusCreated || status == ThreadStatusRunning);
- // Determine whether we are starting or restarting the thread.
- if (status == ThreadStatusCreated)
- // In lieu of AsanThread::ThreadStart.
- asanThreadRegistry().StartThread(thread->tid(), os_id,
- /*workerthread*/ false, nullptr);
- else {
- // In a thread restart, a thread may resume execution at an
- // arbitrary function entry point, with its stack and TLS state
- // reset. We unpoison the stack in that case.
- PoisonShadow(thread->stack_bottom(), thread->stack_size(), 0);
- }
-}
-
-// Each thread runs this just before it exits,
-// with the pointer returned by BeforeThreadCreateHook (above).
-// All per-thread destructors have already been called.
-static void ThreadExitHook(void *hook, uptr os_id) {
- AsanThread *thread = static_cast<AsanThread *>(hook);
- if (thread)
- AsanThread::TSDDtor(thread->context());
-}
-
-static void HandleExit() {
- // Disable ASan by setting it to uninitialized. Also reset the
- // shadow memory to avoid reporting errors after the run-time has
- // been desroyed.
- if (asan_inited) {
- asan_inited = false;
- ResetShadowMemory();
- }
-}
-
-} // namespace __asan
-
-// These are declared (in extern "C") by <some_path/sanitizer.h>.
-// The system runtime will call our definitions directly.
-
-extern "C" {
-void __sanitizer_early_init() {
- __asan::EarlyInit();
-}
-
-void *__sanitizer_before_thread_create_hook(uptr thread, bool detached,
- const char *name,
- void *stack_base, size_t stack_size,
- void *tls_base, size_t tls_size) {
- return __asan::BeforeThreadCreateHook(
- thread, detached,
- reinterpret_cast<uptr>(stack_base), stack_size,
- reinterpret_cast<uptr>(tls_base), tls_size);
-}
-
-void __sanitizer_thread_create_hook(void *handle, uptr thread, int status) {
- __asan::ThreadCreateHook(handle, status != 0);
-}
-
-void __sanitizer_thread_start_hook(void *handle, uptr self) {
- __asan::ThreadStartHook(handle, self);
-}
-
-void __sanitizer_thread_exit_hook(void *handle, uptr self) {
- __asan::ThreadExitHook(handle, self);
-}
-
-void __sanitizer_exit() {
- __asan::HandleExit();
-}
-} // "C"
-
-#endif // SANITIZER_RTEMS
diff --git a/lib/asan/asan_rtl.cc b/lib/asan/asan_rtl.cc
deleted file mode 100644
index 4cff736f213a6..0000000000000
--- a/lib/asan/asan_rtl.cc
+++ /dev/null
@@ -1,589 +0,0 @@
-//===-- asan_rtl.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.
-//
-// Main file of the ASan run-time library.
-//===----------------------------------------------------------------------===//
-
-#include "asan_activation.h"
-#include "asan_allocator.h"
-#include "asan_interceptors.h"
-#include "asan_interface_internal.h"
-#include "asan_internal.h"
-#include "asan_mapping.h"
-#include "asan_poisoning.h"
-#include "asan_report.h"
-#include "asan_stack.h"
-#include "asan_stats.h"
-#include "asan_suppressions.h"
-#include "asan_thread.h"
-#include "sanitizer_common/sanitizer_atomic.h"
-#include "sanitizer_common/sanitizer_flags.h"
-#include "sanitizer_common/sanitizer_libc.h"
-#include "sanitizer_common/sanitizer_symbolizer.h"
-#include "lsan/lsan_common.h"
-#include "ubsan/ubsan_init.h"
-#include "ubsan/ubsan_platform.h"
-
-uptr __asan_shadow_memory_dynamic_address; // Global interface symbol.
-int __asan_option_detect_stack_use_after_return; // Global interface symbol.
-uptr *__asan_test_only_reported_buggy_pointer; // Used only for testing asan.
-
-namespace __asan {
-
-uptr AsanMappingProfile[kAsanMappingProfileSize];
-
-static void AsanDie() {
- static atomic_uint32_t num_calls;
- if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) != 0) {
- // Don't die twice - run a busy loop.
- while (1) { }
- }
- if (common_flags()->print_module_map >= 1) PrintModuleMap();
- if (flags()->sleep_before_dying) {
- Report("Sleeping for %d second(s)\n", flags()->sleep_before_dying);
- SleepForSeconds(flags()->sleep_before_dying);
- }
- if (flags()->unmap_shadow_on_exit) {
- if (kMidMemBeg) {
- UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg);
- UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd);
- } else {
- if (kHighShadowEnd)
- UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg);
- }
- }
-}
-
-static void AsanCheckFailed(const char *file, int line, const char *cond,
- u64 v1, u64 v2) {
- Report("AddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n", file,
- line, cond, (uptr)v1, (uptr)v2);
-
- // Print a stack trace the first time we come here. Otherwise, we probably
- // failed a CHECK during symbolization.
- static atomic_uint32_t num_calls;
- if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) == 0) {
- PRINT_CURRENT_STACK_CHECK();
- }
-
- Die();
-}
-
-// -------------------------- Globals --------------------- {{{1
-int asan_inited;
-bool asan_init_is_running;
-
-#if !ASAN_FIXED_MAPPING
-uptr kHighMemEnd, kMidMemBeg, kMidMemEnd;
-#endif
-
-// -------------------------- Misc ---------------- {{{1
-void ShowStatsAndAbort() {
- __asan_print_accumulated_stats();
- Die();
-}
-
-// --------------- LowLevelAllocateCallbac ---------- {{{1
-static void OnLowLevelAllocate(uptr ptr, uptr size) {
- PoisonShadow(ptr, size, kAsanInternalHeapMagic);
-}
-
-// -------------------------- Run-time entry ------------------- {{{1
-// exported functions
-#define ASAN_REPORT_ERROR(type, is_write, size) \
-extern "C" NOINLINE INTERFACE_ATTRIBUTE \
-void __asan_report_ ## type ## size(uptr addr) { \
- GET_CALLER_PC_BP_SP; \
- ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true); \
-} \
-extern "C" NOINLINE INTERFACE_ATTRIBUTE \
-void __asan_report_exp_ ## type ## size(uptr addr, u32 exp) { \
- GET_CALLER_PC_BP_SP; \
- ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true); \
-} \
-extern "C" NOINLINE INTERFACE_ATTRIBUTE \
-void __asan_report_ ## type ## size ## _noabort(uptr addr) { \
- GET_CALLER_PC_BP_SP; \
- ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false); \
-} \
-
-ASAN_REPORT_ERROR(load, false, 1)
-ASAN_REPORT_ERROR(load, false, 2)
-ASAN_REPORT_ERROR(load, false, 4)
-ASAN_REPORT_ERROR(load, false, 8)
-ASAN_REPORT_ERROR(load, false, 16)
-ASAN_REPORT_ERROR(store, true, 1)
-ASAN_REPORT_ERROR(store, true, 2)
-ASAN_REPORT_ERROR(store, true, 4)
-ASAN_REPORT_ERROR(store, true, 8)
-ASAN_REPORT_ERROR(store, true, 16)
-
-#define ASAN_REPORT_ERROR_N(type, is_write) \
-extern "C" NOINLINE INTERFACE_ATTRIBUTE \
-void __asan_report_ ## type ## _n(uptr addr, uptr size) { \
- GET_CALLER_PC_BP_SP; \
- ReportGenericError(pc, bp, sp, addr, is_write, size, 0, true); \
-} \
-extern "C" NOINLINE INTERFACE_ATTRIBUTE \
-void __asan_report_exp_ ## type ## _n(uptr addr, uptr size, u32 exp) { \
- GET_CALLER_PC_BP_SP; \
- ReportGenericError(pc, bp, sp, addr, is_write, size, exp, true); \
-} \
-extern "C" NOINLINE INTERFACE_ATTRIBUTE \
-void __asan_report_ ## type ## _n_noabort(uptr addr, uptr size) { \
- GET_CALLER_PC_BP_SP; \
- ReportGenericError(pc, bp, sp, addr, is_write, size, 0, false); \
-} \
-
-ASAN_REPORT_ERROR_N(load, false)
-ASAN_REPORT_ERROR_N(store, true)
-
-#define ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp_arg, fatal) \
- if (SANITIZER_MYRIAD2 && !AddrIsInMem(addr) && !AddrIsInShadow(addr)) \
- return; \
- uptr sp = MEM_TO_SHADOW(addr); \
- uptr s = size <= SHADOW_GRANULARITY ? *reinterpret_cast<u8 *>(sp) \
- : *reinterpret_cast<u16 *>(sp); \
- if (UNLIKELY(s)) { \
- if (UNLIKELY(size >= SHADOW_GRANULARITY || \
- ((s8)((addr & (SHADOW_GRANULARITY - 1)) + size - 1)) >= \
- (s8)s)) { \
- if (__asan_test_only_reported_buggy_pointer) { \
- *__asan_test_only_reported_buggy_pointer = addr; \
- } else { \
- GET_CALLER_PC_BP_SP; \
- ReportGenericError(pc, bp, sp, addr, is_write, size, exp_arg, \
- fatal); \
- } \
- } \
- }
-
-#define ASAN_MEMORY_ACCESS_CALLBACK(type, is_write, size) \
- extern "C" NOINLINE INTERFACE_ATTRIBUTE \
- void __asan_##type##size(uptr addr) { \
- ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, true) \
- } \
- extern "C" NOINLINE INTERFACE_ATTRIBUTE \
- void __asan_exp_##type##size(uptr addr, u32 exp) { \
- ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp, true) \
- } \
- extern "C" NOINLINE INTERFACE_ATTRIBUTE \
- void __asan_##type##size ## _noabort(uptr addr) { \
- ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, 0, false) \
- } \
-
-ASAN_MEMORY_ACCESS_CALLBACK(load, false, 1)
-ASAN_MEMORY_ACCESS_CALLBACK(load, false, 2)
-ASAN_MEMORY_ACCESS_CALLBACK(load, false, 4)
-ASAN_MEMORY_ACCESS_CALLBACK(load, false, 8)
-ASAN_MEMORY_ACCESS_CALLBACK(load, false, 16)
-ASAN_MEMORY_ACCESS_CALLBACK(store, true, 1)
-ASAN_MEMORY_ACCESS_CALLBACK(store, true, 2)
-ASAN_MEMORY_ACCESS_CALLBACK(store, true, 4)
-ASAN_MEMORY_ACCESS_CALLBACK(store, true, 8)
-ASAN_MEMORY_ACCESS_CALLBACK(store, true, 16)
-
-extern "C"
-NOINLINE INTERFACE_ATTRIBUTE
-void __asan_loadN(uptr addr, uptr size) {
- if (__asan_region_is_poisoned(addr, size)) {
- GET_CALLER_PC_BP_SP;
- ReportGenericError(pc, bp, sp, addr, false, size, 0, true);
- }
-}
-
-extern "C"
-NOINLINE INTERFACE_ATTRIBUTE
-void __asan_exp_loadN(uptr addr, uptr size, u32 exp) {
- if (__asan_region_is_poisoned(addr, size)) {
- GET_CALLER_PC_BP_SP;
- ReportGenericError(pc, bp, sp, addr, false, size, exp, true);
- }
-}
-
-extern "C"
-NOINLINE INTERFACE_ATTRIBUTE
-void __asan_loadN_noabort(uptr addr, uptr size) {
- if (__asan_region_is_poisoned(addr, size)) {
- GET_CALLER_PC_BP_SP;
- ReportGenericError(pc, bp, sp, addr, false, size, 0, false);
- }
-}
-
-extern "C"
-NOINLINE INTERFACE_ATTRIBUTE
-void __asan_storeN(uptr addr, uptr size) {
- if (__asan_region_is_poisoned(addr, size)) {
- GET_CALLER_PC_BP_SP;
- ReportGenericError(pc, bp, sp, addr, true, size, 0, true);
- }
-}
-
-extern "C"
-NOINLINE INTERFACE_ATTRIBUTE
-void __asan_exp_storeN(uptr addr, uptr size, u32 exp) {
- if (__asan_region_is_poisoned(addr, size)) {
- GET_CALLER_PC_BP_SP;
- ReportGenericError(pc, bp, sp, addr, true, size, exp, true);
- }
-}
-
-extern "C"
-NOINLINE INTERFACE_ATTRIBUTE
-void __asan_storeN_noabort(uptr addr, uptr size) {
- if (__asan_region_is_poisoned(addr, size)) {
- GET_CALLER_PC_BP_SP;
- ReportGenericError(pc, bp, sp, addr, true, size, 0, false);
- }
-}
-
-// Force the linker to keep the symbols for various ASan interface functions.
-// We want to keep those in the executable in order to let the instrumented
-// dynamic libraries access the symbol even if it is not used by the executable
-// itself. This should help if the build system is removing dead code at link
-// time.
-static NOINLINE void force_interface_symbols() {
- volatile int fake_condition = 0; // prevent dead condition elimination.
- // __asan_report_* functions are noreturn, so we need a switch to prevent
- // the compiler from removing any of them.
- // clang-format off
- switch (fake_condition) {
- case 1: __asan_report_load1(0); break;
- case 2: __asan_report_load2(0); break;
- case 3: __asan_report_load4(0); break;
- case 4: __asan_report_load8(0); break;
- case 5: __asan_report_load16(0); break;
- case 6: __asan_report_load_n(0, 0); break;
- case 7: __asan_report_store1(0); break;
- case 8: __asan_report_store2(0); break;
- case 9: __asan_report_store4(0); break;
- case 10: __asan_report_store8(0); break;
- case 11: __asan_report_store16(0); break;
- case 12: __asan_report_store_n(0, 0); break;
- case 13: __asan_report_exp_load1(0, 0); break;
- case 14: __asan_report_exp_load2(0, 0); break;
- case 15: __asan_report_exp_load4(0, 0); break;
- case 16: __asan_report_exp_load8(0, 0); break;
- case 17: __asan_report_exp_load16(0, 0); break;
- case 18: __asan_report_exp_load_n(0, 0, 0); break;
- case 19: __asan_report_exp_store1(0, 0); break;
- case 20: __asan_report_exp_store2(0, 0); break;
- case 21: __asan_report_exp_store4(0, 0); break;
- case 22: __asan_report_exp_store8(0, 0); break;
- case 23: __asan_report_exp_store16(0, 0); break;
- case 24: __asan_report_exp_store_n(0, 0, 0); break;
- case 25: __asan_register_globals(nullptr, 0); break;
- case 26: __asan_unregister_globals(nullptr, 0); break;
- case 27: __asan_set_death_callback(nullptr); break;
- case 28: __asan_set_error_report_callback(nullptr); break;
- case 29: __asan_handle_no_return(); break;
- case 30: __asan_address_is_poisoned(nullptr); break;
- case 31: __asan_poison_memory_region(nullptr, 0); break;
- case 32: __asan_unpoison_memory_region(nullptr, 0); break;
- case 34: __asan_before_dynamic_init(nullptr); break;
- case 35: __asan_after_dynamic_init(); break;
- case 36: __asan_poison_stack_memory(0, 0); break;
- case 37: __asan_unpoison_stack_memory(0, 0); break;
- case 38: __asan_region_is_poisoned(0, 0); break;
- case 39: __asan_describe_address(0); break;
- case 40: __asan_set_shadow_00(0, 0); break;
- case 41: __asan_set_shadow_f1(0, 0); break;
- case 42: __asan_set_shadow_f2(0, 0); break;
- case 43: __asan_set_shadow_f3(0, 0); break;
- case 44: __asan_set_shadow_f5(0, 0); break;
- case 45: __asan_set_shadow_f8(0, 0); break;
- }
- // clang-format on
-}
-
-static void asan_atexit() {
- Printf("AddressSanitizer exit stats:\n");
- __asan_print_accumulated_stats();
- // Print AsanMappingProfile.
- for (uptr i = 0; i < kAsanMappingProfileSize; i++) {
- if (AsanMappingProfile[i] == 0) continue;
- Printf("asan_mapping.h:%zd -- %zd\n", i, AsanMappingProfile[i]);
- }
-}
-
-static void InitializeHighMemEnd() {
-#if !SANITIZER_MYRIAD2
-#if !ASAN_FIXED_MAPPING
- kHighMemEnd = GetMaxUserVirtualAddress();
- // Increase kHighMemEnd to make sure it's properly
- // aligned together with kHighMemBeg:
- kHighMemEnd |= SHADOW_GRANULARITY * GetMmapGranularity() - 1;
-#endif // !ASAN_FIXED_MAPPING
- CHECK_EQ((kHighMemBeg % GetMmapGranularity()), 0);
-#endif // !SANITIZER_MYRIAD2
-}
-
-void PrintAddressSpaceLayout() {
- if (kHighMemBeg) {
- Printf("|| `[%p, %p]` || HighMem ||\n",
- (void*)kHighMemBeg, (void*)kHighMemEnd);
- Printf("|| `[%p, %p]` || HighShadow ||\n",
- (void*)kHighShadowBeg, (void*)kHighShadowEnd);
- }
- if (kMidMemBeg) {
- Printf("|| `[%p, %p]` || ShadowGap3 ||\n",
- (void*)kShadowGap3Beg, (void*)kShadowGap3End);
- Printf("|| `[%p, %p]` || MidMem ||\n",
- (void*)kMidMemBeg, (void*)kMidMemEnd);
- Printf("|| `[%p, %p]` || ShadowGap2 ||\n",
- (void*)kShadowGap2Beg, (void*)kShadowGap2End);
- Printf("|| `[%p, %p]` || MidShadow ||\n",
- (void*)kMidShadowBeg, (void*)kMidShadowEnd);
- }
- Printf("|| `[%p, %p]` || ShadowGap ||\n",
- (void*)kShadowGapBeg, (void*)kShadowGapEnd);
- if (kLowShadowBeg) {
- Printf("|| `[%p, %p]` || LowShadow ||\n",
- (void*)kLowShadowBeg, (void*)kLowShadowEnd);
- Printf("|| `[%p, %p]` || LowMem ||\n",
- (void*)kLowMemBeg, (void*)kLowMemEnd);
- }
- Printf("MemToShadow(shadow): %p %p",
- (void*)MEM_TO_SHADOW(kLowShadowBeg),
- (void*)MEM_TO_SHADOW(kLowShadowEnd));
- if (kHighMemBeg) {
- Printf(" %p %p",
- (void*)MEM_TO_SHADOW(kHighShadowBeg),
- (void*)MEM_TO_SHADOW(kHighShadowEnd));
- }
- if (kMidMemBeg) {
- Printf(" %p %p",
- (void*)MEM_TO_SHADOW(kMidShadowBeg),
- (void*)MEM_TO_SHADOW(kMidShadowEnd));
- }
- Printf("\n");
- Printf("redzone=%zu\n", (uptr)flags()->redzone);
- Printf("max_redzone=%zu\n", (uptr)flags()->max_redzone);
- Printf("quarantine_size_mb=%zuM\n", (uptr)flags()->quarantine_size_mb);
- Printf("thread_local_quarantine_size_kb=%zuK\n",
- (uptr)flags()->thread_local_quarantine_size_kb);
- Printf("malloc_context_size=%zu\n",
- (uptr)common_flags()->malloc_context_size);
-
- Printf("SHADOW_SCALE: %d\n", (int)SHADOW_SCALE);
- Printf("SHADOW_GRANULARITY: %d\n", (int)SHADOW_GRANULARITY);
- Printf("SHADOW_OFFSET: 0x%zx\n", (uptr)SHADOW_OFFSET);
- CHECK(SHADOW_SCALE >= 3 && SHADOW_SCALE <= 7);
- if (kMidMemBeg)
- CHECK(kMidShadowBeg > kLowShadowEnd &&
- kMidMemBeg > kMidShadowEnd &&
- kHighShadowBeg > kMidMemEnd);
-}
-
-static void AsanInitInternal() {
- if (LIKELY(asan_inited)) return;
- SanitizerToolName = "AddressSanitizer";
- CHECK(!asan_init_is_running && "ASan init calls itself!");
- asan_init_is_running = true;
-
- CacheBinaryName();
- CheckASLR();
-
- // Initialize flags. This must be done early, because most of the
- // initialization steps look at flags().
- InitializeFlags();
-
- AsanCheckIncompatibleRT();
- AsanCheckDynamicRTPrereqs();
- AvoidCVE_2016_2143();
-
- SetCanPoisonMemory(flags()->poison_heap);
- SetMallocContextSize(common_flags()->malloc_context_size);
-
- InitializePlatformExceptionHandlers();
-
- InitializeHighMemEnd();
-
- // Make sure we are not statically linked.
- AsanDoesNotSupportStaticLinkage();
-
- // Install tool-specific callbacks in sanitizer_common.
- AddDieCallback(AsanDie);
- SetCheckFailedCallback(AsanCheckFailed);
- SetPrintfAndReportCallback(AppendToErrorMessageBuffer);
-
- __sanitizer_set_report_path(common_flags()->log_path);
-
- __asan_option_detect_stack_use_after_return =
- flags()->detect_stack_use_after_return;
-
- // Re-exec ourselves if we need to set additional env or command line args.
- MaybeReexec();
-
- // Setup internal allocator callback.
- SetLowLevelAllocateMinAlignment(SHADOW_GRANULARITY);
- SetLowLevelAllocateCallback(OnLowLevelAllocate);
-
- InitializeAsanInterceptors();
-
- // Enable system log ("adb logcat") on Android.
- // Doing this before interceptors are initialized crashes in:
- // AsanInitInternal -> android_log_write -> __interceptor_strcmp
- AndroidLogInit();
-
- ReplaceSystemMalloc();
-
- DisableCoreDumperIfNecessary();
-
- InitializeShadowMemory();
-
- AsanTSDInit(PlatformTSDDtor);
- InstallDeadlySignalHandlers(AsanOnDeadlySignal);
-
- AllocatorOptions allocator_options;
- allocator_options.SetFrom(flags(), common_flags());
- InitializeAllocator(allocator_options);
-
- MaybeStartBackgroudThread();
- SetSoftRssLimitExceededCallback(AsanSoftRssLimitExceededCallback);
-
- // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited
- // should be set to 1 prior to initializing the threads.
- asan_inited = 1;
- asan_init_is_running = false;
-
- if (flags()->atexit)
- Atexit(asan_atexit);
-
- InitializeCoverage(common_flags()->coverage, common_flags()->coverage_dir);
-
- // Now that ASan runtime is (mostly) initialized, deactivate it if
- // necessary, so that it can be re-activated when requested.
- if (flags()->start_deactivated)
- AsanDeactivate();
-
- // interceptors
- InitTlsSize();
-
- // Create main thread.
- AsanThread *main_thread = CreateMainThread();
- CHECK_EQ(0, main_thread->tid());
- force_interface_symbols(); // no-op.
- SanitizerInitializeUnwinder();
-
- if (CAN_SANITIZE_LEAKS) {
- __lsan::InitCommonLsan();
- if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) {
- if (flags()->halt_on_error)
- Atexit(__lsan::DoLeakCheck);
- else
- Atexit(__lsan::DoRecoverableLeakCheckVoid);
- }
- }
-
-#if CAN_SANITIZE_UB
- __ubsan::InitAsPlugin();
-#endif
-
- InitializeSuppressions();
-
- if (CAN_SANITIZE_LEAKS) {
- // LateInitialize() calls dlsym, which can allocate an error string buffer
- // in the TLS. Let's ignore the allocation to avoid reporting a leak.
- __lsan::ScopedInterceptorDisabler disabler;
- Symbolizer::LateInitialize();
- } else {
- Symbolizer::LateInitialize();
- }
-
- VReport(1, "AddressSanitizer Init done\n");
-
- if (flags()->sleep_after_init) {
- Report("Sleeping for %d second(s)\n", flags()->sleep_after_init);
- SleepForSeconds(flags()->sleep_after_init);
- }
-}
-
-// Initialize as requested from some part of ASan runtime library (interceptors,
-// allocator, etc).
-void AsanInitFromRtl() {
- AsanInitInternal();
-}
-
-#if ASAN_DYNAMIC
-// Initialize runtime in case it's LD_PRELOAD-ed into unsanitized executable
-// (and thus normal initializers from .preinit_array or modules haven't run).
-
-class AsanInitializer {
-public: // NOLINT
- AsanInitializer() {
- AsanInitFromRtl();
- }
-};
-
-static AsanInitializer asan_initializer;
-#endif // ASAN_DYNAMIC
-
-} // namespace __asan
-
-// ---------------------- Interface ---------------- {{{1
-using namespace __asan; // NOLINT
-
-void NOINLINE __asan_handle_no_return() {
- if (asan_init_is_running)
- return;
-
- int local_stack;
- AsanThread *curr_thread = GetCurrentThread();
- uptr PageSize = GetPageSizeCached();
- uptr top, bottom;
- if (curr_thread) {
- top = curr_thread->stack_top();
- bottom = ((uptr)&local_stack - PageSize) & ~(PageSize - 1);
- } else if (SANITIZER_RTEMS) {
- // Give up On RTEMS.
- return;
- } else {
- CHECK(!SANITIZER_FUCHSIA);
- // If we haven't seen this thread, try asking the OS for stack bounds.
- uptr tls_addr, tls_size, stack_size;
- GetThreadStackAndTls(/*main=*/false, &bottom, &stack_size, &tls_addr,
- &tls_size);
- top = bottom + stack_size;
- }
- static const uptr kMaxExpectedCleanupSize = 64 << 20; // 64M
- if (top - bottom > kMaxExpectedCleanupSize) {
- static bool reported_warning = false;
- if (reported_warning)
- return;
- reported_warning = true;
- Report("WARNING: ASan is ignoring requested __asan_handle_no_return: "
- "stack top: %p; bottom %p; size: %p (%zd)\n"
- "False positive error reports may follow\n"
- "For details see "
- "https://github.com/google/sanitizers/issues/189\n",
- top, bottom, top - bottom, top - bottom);
- return;
- }
- PoisonShadow(bottom, top - bottom, 0);
- if (curr_thread && curr_thread->has_fake_stack())
- curr_thread->fake_stack()->HandleNoReturn();
-}
-
-void NOINLINE __asan_set_death_callback(void (*callback)(void)) {
- SetUserDieCallback(callback);
-}
-
-// Initialize as requested from instrumented application code.
-// We use this call as a trigger to wake up ASan from deactivated state.
-void __asan_init() {
- AsanActivate();
- AsanInitInternal();
-}
-
-void __asan_version_mismatch_check() {
- // Do nothing.
-}
diff --git a/lib/asan/asan_scariness_score.h b/lib/asan/asan_scariness_score.h
deleted file mode 100644
index 7f095dd29f293..0000000000000
--- a/lib/asan/asan_scariness_score.h
+++ /dev/null
@@ -1,74 +0,0 @@
-//===-- asan_scariness_score.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.
-//
-// Compute the level of scariness of the error message.
-// Don't expect any deep science here, just a set of heuristics that suggest
-// that e.g. 1-byte-read-global-buffer-overflow is less scary than
-// 8-byte-write-stack-use-after-return.
-//
-// Every error report has one or more features, such as memory access size,
-// type (read or write), type of accessed memory (e.g. free-d heap, or a global
-// redzone), etc. Every such feature has an int score and a string description.
-// The overall score is the sum of all feature scores and the description
-// is a concatenation of feature descriptions.
-// Examples:
-// 17 (4-byte-read-heap-buffer-overflow)
-// 65 (multi-byte-write-stack-use-after-return)
-// 10 (null-deref)
-//
-//===----------------------------------------------------------------------===//
-
-#ifndef ASAN_SCARINESS_SCORE_H
-#define ASAN_SCARINESS_SCORE_H
-
-#include "asan_flags.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_libc.h"
-
-namespace __asan {
-struct ScarinessScoreBase {
- void Clear() {
- descr[0] = 0;
- score = 0;
- }
- void Scare(int add_to_score, const char *reason) {
- if (descr[0])
- internal_strlcat(descr, "-", sizeof(descr));
- internal_strlcat(descr, reason, sizeof(descr));
- score += add_to_score;
- };
- int GetScore() const { return score; }
- const char *GetDescription() const { return descr; }
- void Print() const {
- if (score && flags()->print_scariness)
- Printf("SCARINESS: %d (%s)\n", score, descr);
- }
- static void PrintSimple(int score, const char *descr) {
- ScarinessScoreBase SSB;
- SSB.Clear();
- SSB.Scare(score, descr);
- SSB.Print();
- }
-
- private:
- int score;
- char descr[1024];
-};
-
-struct ScarinessScore : ScarinessScoreBase {
- ScarinessScore() {
- Clear();
- }
-};
-
-} // namespace __asan
-
-#endif // ASAN_SCARINESS_SCORE_H
diff --git a/lib/asan/asan_shadow_setup.cc b/lib/asan/asan_shadow_setup.cc
deleted file mode 100644
index 083926e70aa2d..0000000000000
--- a/lib/asan/asan_shadow_setup.cc
+++ /dev/null
@@ -1,165 +0,0 @@
-//===-- asan_shadow_setup.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.
-//
-// Set up the shadow memory.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_platform.h"
-
-// asan_fuchsia.cc and asan_rtems.cc have their own
-// InitializeShadowMemory implementation.
-#if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS
-
-#include "asan_internal.h"
-#include "asan_mapping.h"
-
-namespace __asan {
-
-// ---------------------- mmap -------------------- {{{1
-// Reserve memory range [beg, end].
-// We need to use inclusive range because end+1 may not be representable.
-void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name) {
- CHECK_EQ((beg % GetMmapGranularity()), 0);
- CHECK_EQ(((end + 1) % GetMmapGranularity()), 0);
- uptr size = end - beg + 1;
- DecreaseTotalMmap(size); // Don't count the shadow against mmap_limit_mb.
- if (!MmapFixedNoReserve(beg, size, name)) {
- Report(
- "ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. "
- "Perhaps you're using ulimit -v\n",
- size);
- Abort();
- }
- if (common_flags()->no_huge_pages_for_shadow) NoHugePagesInRegion(beg, size);
- if (common_flags()->use_madv_dontdump) DontDumpShadowMemory(beg, size);
-}
-
-static void ProtectGap(uptr addr, uptr size) {
- if (!flags()->protect_shadow_gap) {
- // The shadow gap is unprotected, so there is a chance that someone
- // is actually using this memory. Which means it needs a shadow...
- uptr GapShadowBeg = RoundDownTo(MEM_TO_SHADOW(addr), GetPageSizeCached());
- uptr GapShadowEnd =
- RoundUpTo(MEM_TO_SHADOW(addr + size), GetPageSizeCached()) - 1;
- if (Verbosity())
- Printf(
- "protect_shadow_gap=0:"
- " not protecting shadow gap, allocating gap's shadow\n"
- "|| `[%p, %p]` || ShadowGap's shadow ||\n",
- GapShadowBeg, GapShadowEnd);
- ReserveShadowMemoryRange(GapShadowBeg, GapShadowEnd,
- "unprotected gap shadow");
- return;
- }
- void *res = MmapFixedNoAccess(addr, size, "shadow gap");
- if (addr == (uptr)res) return;
- // A few pages at the start of the address space can not be protected.
- // But we really want to protect as much as possible, to prevent this memory
- // being returned as a result of a non-FIXED mmap().
- if (addr == kZeroBaseShadowStart) {
- uptr step = GetMmapGranularity();
- while (size > step && addr < kZeroBaseMaxShadowStart) {
- addr += step;
- size -= step;
- void *res = MmapFixedNoAccess(addr, size, "shadow gap");
- if (addr == (uptr)res) return;
- }
- }
-
- Report(
- "ERROR: Failed to protect the shadow gap. "
- "ASan cannot proceed correctly. ABORTING.\n");
- DumpProcessMap();
- Die();
-}
-
-static void MaybeReportLinuxPIEBug() {
-#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__aarch64__))
- Report("This might be related to ELF_ET_DYN_BASE change in Linux 4.12.\n");
- Report(
- "See https://github.com/google/sanitizers/issues/856 for possible "
- "workarounds.\n");
-#endif
-}
-
-void InitializeShadowMemory() {
- // Set the shadow memory address to uninitialized.
- __asan_shadow_memory_dynamic_address = kDefaultShadowSentinel;
-
- uptr shadow_start = kLowShadowBeg;
- // Detect if a dynamic shadow address must used and find a available location
- // when necessary. When dynamic address is used, the macro |kLowShadowBeg|
- // expands to |__asan_shadow_memory_dynamic_address| which is
- // |kDefaultShadowSentinel|.
- bool full_shadow_is_available = false;
- if (shadow_start == kDefaultShadowSentinel) {
- __asan_shadow_memory_dynamic_address = 0;
- CHECK_EQ(0, kLowShadowBeg);
- shadow_start = FindDynamicShadowStart();
- if (SANITIZER_LINUX) full_shadow_is_available = true;
- }
- // Update the shadow memory address (potentially) used by instrumentation.
- __asan_shadow_memory_dynamic_address = shadow_start;
-
- if (kLowShadowBeg) shadow_start -= GetMmapGranularity();
-
- if (!full_shadow_is_available)
- full_shadow_is_available =
- MemoryRangeIsAvailable(shadow_start, kHighShadowEnd);
-
-#if SANITIZER_LINUX && defined(__x86_64__) && defined(_LP64) && \
- !ASAN_FIXED_MAPPING
- if (!full_shadow_is_available) {
- kMidMemBeg = kLowMemEnd < 0x3000000000ULL ? 0x3000000000ULL : 0;
- kMidMemEnd = kLowMemEnd < 0x3000000000ULL ? 0x4fffffffffULL : 0;
- }
-#endif
-
- if (Verbosity()) PrintAddressSpaceLayout();
-
- if (full_shadow_is_available) {
- // mmap the low shadow plus at least one page at the left.
- if (kLowShadowBeg)
- ReserveShadowMemoryRange(shadow_start, kLowShadowEnd, "low shadow");
- // mmap the high shadow.
- ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd, "high shadow");
- // protect the gap.
- ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
- CHECK_EQ(kShadowGapEnd, kHighShadowBeg - 1);
- } else if (kMidMemBeg &&
- MemoryRangeIsAvailable(shadow_start, kMidMemBeg - 1) &&
- MemoryRangeIsAvailable(kMidMemEnd + 1, kHighShadowEnd)) {
- CHECK(kLowShadowBeg != kLowShadowEnd);
- // mmap the low shadow plus at least one page at the left.
- ReserveShadowMemoryRange(shadow_start, kLowShadowEnd, "low shadow");
- // mmap the mid shadow.
- ReserveShadowMemoryRange(kMidShadowBeg, kMidShadowEnd, "mid shadow");
- // mmap the high shadow.
- ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowEnd, "high shadow");
- // protect the gaps.
- ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1);
- ProtectGap(kShadowGap2Beg, kShadowGap2End - kShadowGap2Beg + 1);
- ProtectGap(kShadowGap3Beg, kShadowGap3End - kShadowGap3Beg + 1);
- } else {
- Report(
- "Shadow memory range interleaves with an existing memory mapping. "
- "ASan cannot proceed correctly. ABORTING.\n");
- Report("ASan shadow was supposed to be located in the [%p-%p] range.\n",
- shadow_start, kHighShadowEnd);
- MaybeReportLinuxPIEBug();
- DumpProcessMap();
- Die();
- }
-}
-
-} // namespace __asan
-
-#endif // !SANITIZER_FUCHSIA && !SANITIZER_RTEMS
diff --git a/lib/asan/asan_stack.cc b/lib/asan/asan_stack.cc
deleted file mode 100644
index cf7a587fa65ae..0000000000000
--- a/lib/asan/asan_stack.cc
+++ /dev/null
@@ -1,40 +0,0 @@
-//===-- asan_stack.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.
-//
-// Code for ASan stack trace.
-//===----------------------------------------------------------------------===//
-#include "asan_internal.h"
-#include "asan_stack.h"
-#include "sanitizer_common/sanitizer_atomic.h"
-
-namespace __asan {
-
-static atomic_uint32_t malloc_context_size;
-
-void SetMallocContextSize(u32 size) {
- atomic_store(&malloc_context_size, size, memory_order_release);
-}
-
-u32 GetMallocContextSize() {
- return atomic_load(&malloc_context_size, memory_order_acquire);
-}
-
-} // namespace __asan
-
-// ------------------ Interface -------------- {{{1
-
-extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE
-void __sanitizer_print_stack_trace() {
- using namespace __asan;
- PRINT_CURRENT_STACK();
-}
-} // extern "C"
diff --git a/lib/asan/asan_stack.h b/lib/asan/asan_stack.h
deleted file mode 100644
index 8e9df888d798e..0000000000000
--- a/lib/asan/asan_stack.h
+++ /dev/null
@@ -1,114 +0,0 @@
-//===-- asan_stack.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.
-//
-// ASan-private header for asan_stack.cc.
-//===----------------------------------------------------------------------===//
-
-#ifndef ASAN_STACK_H
-#define ASAN_STACK_H
-
-#include "asan_flags.h"
-#include "asan_thread.h"
-#include "sanitizer_common/sanitizer_flags.h"
-#include "sanitizer_common/sanitizer_stacktrace.h"
-
-namespace __asan {
-
-static const u32 kDefaultMallocContextSize = 30;
-
-void SetMallocContextSize(u32 size);
-u32 GetMallocContextSize();
-
-// Get the stack trace with the given pc and bp.
-// The pc will be in the position 0 of the resulting stack trace.
-// The bp may refer to the current frame or to the caller's frame.
-ALWAYS_INLINE
-void GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, uptr bp,
- void *context, bool fast) {
-#if SANITIZER_WINDOWS
- stack->Unwind(max_depth, pc, bp, context, 0, 0, fast);
-#else
- AsanThread *t;
- stack->size = 0;
- if (LIKELY(asan_inited)) {
- if ((t = GetCurrentThread()) && !t->isUnwinding()) {
- uptr stack_top = t->stack_top();
- uptr stack_bottom = t->stack_bottom();
- ScopedUnwinding unwind_scope(t);
- if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) {
- stack->Unwind(max_depth, pc, bp, context, stack_top, stack_bottom,
- fast);
- }
- } else if (!t && !fast) {
- /* If GetCurrentThread() has failed, try to do slow unwind anyways. */
- stack->Unwind(max_depth, pc, bp, context, 0, 0, false);
- }
- }
-#endif // SANITIZER_WINDOWS
-}
-
-} // namespace __asan
-
-// NOTE: A Rule of thumb is to retrieve stack trace in the interceptors
-// as early as possible (in functions exposed to the user), as we generally
-// don't want stack trace to contain functions from ASan internals.
-
-#define GET_STACK_TRACE(max_size, fast) \
- BufferedStackTrace stack; \
- if (max_size <= 2) { \
- stack.size = max_size; \
- if (max_size > 0) { \
- stack.top_frame_bp = GET_CURRENT_FRAME(); \
- stack.trace_buffer[0] = StackTrace::GetCurrentPc(); \
- if (max_size > 1) stack.trace_buffer[1] = GET_CALLER_PC(); \
- } \
- } else { \
- GetStackTrace(&stack, max_size, StackTrace::GetCurrentPc(), \
- GET_CURRENT_FRAME(), 0, fast); \
- }
-
-#define GET_STACK_TRACE_FATAL(pc, bp) \
- BufferedStackTrace stack; \
- GetStackTrace(&stack, kStackTraceMax, pc, bp, 0, \
- common_flags()->fast_unwind_on_fatal)
-
-#define GET_STACK_TRACE_SIGNAL(sig) \
- BufferedStackTrace stack; \
- GetStackTrace(&stack, kStackTraceMax, (sig).pc, (sig).bp, (sig).context, \
- common_flags()->fast_unwind_on_fatal)
-
-#define GET_STACK_TRACE_FATAL_HERE \
- GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_fatal)
-
-#define GET_STACK_TRACE_CHECK_HERE \
- GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_check)
-
-#define GET_STACK_TRACE_THREAD \
- GET_STACK_TRACE(kStackTraceMax, true)
-
-#define GET_STACK_TRACE_MALLOC \
- GET_STACK_TRACE(GetMallocContextSize(), common_flags()->fast_unwind_on_malloc)
-
-#define GET_STACK_TRACE_FREE GET_STACK_TRACE_MALLOC
-
-#define PRINT_CURRENT_STACK() \
- { \
- GET_STACK_TRACE_FATAL_HERE; \
- stack.Print(); \
- }
-
-#define PRINT_CURRENT_STACK_CHECK() \
- { \
- GET_STACK_TRACE_CHECK_HERE; \
- stack.Print(); \
- }
-
-#endif // ASAN_STACK_H
diff --git a/lib/asan/asan_stats.cc b/lib/asan/asan_stats.cc
deleted file mode 100644
index b8c68c32dfbfa..0000000000000
--- a/lib/asan/asan_stats.cc
+++ /dev/null
@@ -1,174 +0,0 @@
-//===-- asan_stats.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.
-//
-// Code related to statistics collected by AddressSanitizer.
-//===----------------------------------------------------------------------===//
-#include "asan_interceptors.h"
-#include "asan_internal.h"
-#include "asan_stats.h"
-#include "asan_thread.h"
-#include "sanitizer_common/sanitizer_allocator_interface.h"
-#include "sanitizer_common/sanitizer_mutex.h"
-#include "sanitizer_common/sanitizer_stackdepot.h"
-
-namespace __asan {
-
-AsanStats::AsanStats() {
- Clear();
-}
-
-void AsanStats::Clear() {
- CHECK(REAL(memset));
- REAL(memset)(this, 0, sizeof(AsanStats));
-}
-
-static void PrintMallocStatsArray(const char *prefix,
- uptr (&array)[kNumberOfSizeClasses]) {
- Printf("%s", prefix);
- for (uptr i = 0; i < kNumberOfSizeClasses; i++) {
- if (!array[i]) continue;
- Printf("%zu:%zu; ", i, array[i]);
- }
- Printf("\n");
-}
-
-void AsanStats::Print() {
- Printf("Stats: %zuM malloced (%zuM for red zones) by %zu calls\n",
- malloced>>20, malloced_redzones>>20, mallocs);
- Printf("Stats: %zuM realloced by %zu calls\n", realloced>>20, reallocs);
- Printf("Stats: %zuM freed by %zu calls\n", freed>>20, frees);
- Printf("Stats: %zuM really freed by %zu calls\n",
- really_freed>>20, real_frees);
- Printf("Stats: %zuM (%zuM-%zuM) mmaped; %zu maps, %zu unmaps\n",
- (mmaped-munmaped)>>20, mmaped>>20, munmaped>>20,
- mmaps, munmaps);
-
- PrintMallocStatsArray(" mallocs by size class: ", malloced_by_size);
- Printf("Stats: malloc large: %zu\n", malloc_large);
-}
-
-void AsanStats::MergeFrom(const AsanStats *stats) {
- uptr *dst_ptr = reinterpret_cast<uptr*>(this);
- const uptr *src_ptr = reinterpret_cast<const uptr*>(stats);
- uptr num_fields = sizeof(*this) / sizeof(uptr);
- for (uptr i = 0; i < num_fields; i++)
- dst_ptr[i] += src_ptr[i];
-}
-
-static BlockingMutex print_lock(LINKER_INITIALIZED);
-
-static AsanStats unknown_thread_stats(LINKER_INITIALIZED);
-static AsanStats dead_threads_stats(LINKER_INITIALIZED);
-static BlockingMutex dead_threads_stats_lock(LINKER_INITIALIZED);
-// Required for malloc_zone_statistics() on OS X. This can't be stored in
-// per-thread AsanStats.
-static uptr max_malloced_memory;
-
-static void MergeThreadStats(ThreadContextBase *tctx_base, void *arg) {
- AsanStats *accumulated_stats = reinterpret_cast<AsanStats*>(arg);
- AsanThreadContext *tctx = static_cast<AsanThreadContext*>(tctx_base);
- if (AsanThread *t = tctx->thread)
- accumulated_stats->MergeFrom(&t->stats());
-}
-
-static void GetAccumulatedStats(AsanStats *stats) {
- stats->Clear();
- {
- ThreadRegistryLock l(&asanThreadRegistry());
- asanThreadRegistry()
- .RunCallbackForEachThreadLocked(MergeThreadStats, stats);
- }
- stats->MergeFrom(&unknown_thread_stats);
- {
- BlockingMutexLock lock(&dead_threads_stats_lock);
- stats->MergeFrom(&dead_threads_stats);
- }
- // This is not very accurate: we may miss allocation peaks that happen
- // between two updates of accumulated_stats_. For more accurate bookkeeping
- // the maximum should be updated on every malloc(), which is unacceptable.
- if (max_malloced_memory < stats->malloced) {
- max_malloced_memory = stats->malloced;
- }
-}
-
-void FlushToDeadThreadStats(AsanStats *stats) {
- BlockingMutexLock lock(&dead_threads_stats_lock);
- dead_threads_stats.MergeFrom(stats);
- stats->Clear();
-}
-
-void FillMallocStatistics(AsanMallocStats *malloc_stats) {
- AsanStats stats;
- GetAccumulatedStats(&stats);
- malloc_stats->blocks_in_use = stats.mallocs;
- malloc_stats->size_in_use = stats.malloced;
- malloc_stats->max_size_in_use = max_malloced_memory;
- malloc_stats->size_allocated = stats.mmaped;
-}
-
-AsanStats &GetCurrentThreadStats() {
- AsanThread *t = GetCurrentThread();
- return (t) ? t->stats() : unknown_thread_stats;
-}
-
-static void PrintAccumulatedStats() {
- AsanStats stats;
- GetAccumulatedStats(&stats);
- // Use lock to keep reports from mixing up.
- BlockingMutexLock lock(&print_lock);
- stats.Print();
- StackDepotStats *stack_depot_stats = StackDepotGetStats();
- Printf("Stats: StackDepot: %zd ids; %zdM allocated\n",
- stack_depot_stats->n_uniq_ids, stack_depot_stats->allocated >> 20);
- PrintInternalAllocatorStats();
-}
-
-} // namespace __asan
-
-// ---------------------- Interface ---------------- {{{1
-using namespace __asan; // NOLINT
-
-uptr __sanitizer_get_current_allocated_bytes() {
- AsanStats stats;
- GetAccumulatedStats(&stats);
- uptr malloced = stats.malloced;
- uptr freed = stats.freed;
- // Return sane value if malloced < freed due to racy
- // way we update accumulated stats.
- return (malloced > freed) ? malloced - freed : 1;
-}
-
-uptr __sanitizer_get_heap_size() {
- AsanStats stats;
- GetAccumulatedStats(&stats);
- return stats.mmaped - stats.munmaped;
-}
-
-uptr __sanitizer_get_free_bytes() {
- AsanStats stats;
- GetAccumulatedStats(&stats);
- uptr total_free = stats.mmaped
- - stats.munmaped
- + stats.really_freed;
- uptr total_used = stats.malloced
- + stats.malloced_redzones;
- // Return sane value if total_free < total_used due to racy
- // way we update accumulated stats.
- return (total_free > total_used) ? total_free - total_used : 1;
-}
-
-uptr __sanitizer_get_unmapped_bytes() {
- return 0;
-}
-
-void __asan_print_accumulated_stats() {
- PrintAccumulatedStats();
-}
diff --git a/lib/asan/asan_stats.h b/lib/asan/asan_stats.h
deleted file mode 100644
index 4605135e166f5..0000000000000
--- a/lib/asan/asan_stats.h
+++ /dev/null
@@ -1,72 +0,0 @@
-//===-- asan_stats.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.
-//
-// ASan-private header for statistics.
-//===----------------------------------------------------------------------===//
-#ifndef ASAN_STATS_H
-#define ASAN_STATS_H
-
-#include "asan_allocator.h"
-#include "asan_internal.h"
-
-namespace __asan {
-
-// AsanStats struct is NOT thread-safe.
-// Each AsanThread has its own AsanStats, which are sometimes flushed
-// to the accumulated AsanStats.
-struct AsanStats {
- // AsanStats must be a struct consisting of uptr fields only.
- // When merging two AsanStats structs, we treat them as arrays of uptr.
- uptr mallocs;
- uptr malloced;
- uptr malloced_redzones;
- uptr frees;
- uptr freed;
- uptr real_frees;
- uptr really_freed;
- uptr reallocs;
- uptr realloced;
- uptr mmaps;
- uptr mmaped;
- uptr munmaps;
- uptr munmaped;
- uptr malloc_large;
- uptr malloced_by_size[kNumberOfSizeClasses];
-
- // Ctor for global AsanStats (accumulated stats for dead threads).
- explicit AsanStats(LinkerInitialized) { }
- // Creates empty stats.
- AsanStats();
-
- void Print(); // Prints formatted stats to stderr.
- void Clear();
- void MergeFrom(const AsanStats *stats);
-};
-
-// Returns stats for GetCurrentThread(), or stats for fake "unknown thread"
-// if GetCurrentThread() returns 0.
-AsanStats &GetCurrentThreadStats();
-// Flushes a given stats into accumulated stats of dead threads.
-void FlushToDeadThreadStats(AsanStats *stats);
-
-// A cross-platform equivalent of malloc_statistics_t on Mac OS.
-struct AsanMallocStats {
- uptr blocks_in_use;
- uptr size_in_use;
- uptr max_size_in_use;
- uptr size_allocated;
-};
-
-void FillMallocStatistics(AsanMallocStats *malloc_stats);
-
-} // namespace __asan
-
-#endif // ASAN_STATS_H
diff --git a/lib/asan/asan_suppressions.cc b/lib/asan/asan_suppressions.cc
deleted file mode 100644
index ac8aa023f6ba4..0000000000000
--- a/lib/asan/asan_suppressions.cc
+++ /dev/null
@@ -1,105 +0,0 @@
-//===-- asan_suppressions.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.
-//
-// Issue suppression and suppression-related functions.
-//===----------------------------------------------------------------------===//
-
-#include "asan_suppressions.h"
-
-#include "asan_stack.h"
-#include "sanitizer_common/sanitizer_placement_new.h"
-#include "sanitizer_common/sanitizer_suppressions.h"
-#include "sanitizer_common/sanitizer_symbolizer.h"
-
-namespace __asan {
-
-ALIGNED(64) static char suppression_placeholder[sizeof(SuppressionContext)];
-static SuppressionContext *suppression_ctx = nullptr;
-static const char kInterceptorName[] = "interceptor_name";
-static const char kInterceptorViaFunction[] = "interceptor_via_fun";
-static const char kInterceptorViaLibrary[] = "interceptor_via_lib";
-static const char kODRViolation[] = "odr_violation";
-static const char *kSuppressionTypes[] = {
- kInterceptorName, kInterceptorViaFunction, kInterceptorViaLibrary,
- kODRViolation};
-
-SANITIZER_INTERFACE_WEAK_DEF(const char *, __asan_default_suppressions, void) {
- return "";
-}
-
-void InitializeSuppressions() {
- CHECK_EQ(nullptr, suppression_ctx);
- suppression_ctx = new (suppression_placeholder) // NOLINT
- SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes));
- suppression_ctx->ParseFromFile(flags()->suppressions);
- if (&__asan_default_suppressions)
- suppression_ctx->Parse(__asan_default_suppressions());
-}
-
-bool IsInterceptorSuppressed(const char *interceptor_name) {
- CHECK(suppression_ctx);
- Suppression *s;
- // Match "interceptor_name" suppressions.
- return suppression_ctx->Match(interceptor_name, kInterceptorName, &s);
-}
-
-bool HaveStackTraceBasedSuppressions() {
- CHECK(suppression_ctx);
- return suppression_ctx->HasSuppressionType(kInterceptorViaFunction) ||
- suppression_ctx->HasSuppressionType(kInterceptorViaLibrary);
-}
-
-bool IsODRViolationSuppressed(const char *global_var_name) {
- CHECK(suppression_ctx);
- Suppression *s;
- // Match "odr_violation" suppressions.
- return suppression_ctx->Match(global_var_name, kODRViolation, &s);
-}
-
-bool IsStackTraceSuppressed(const StackTrace *stack) {
- if (!HaveStackTraceBasedSuppressions())
- return false;
-
- CHECK(suppression_ctx);
- Symbolizer *symbolizer = Symbolizer::GetOrInit();
- Suppression *s;
- for (uptr i = 0; i < stack->size && stack->trace[i]; i++) {
- uptr addr = stack->trace[i];
-
- if (suppression_ctx->HasSuppressionType(kInterceptorViaLibrary)) {
- // Match "interceptor_via_lib" suppressions.
- if (const char *module_name = symbolizer->GetModuleNameForPc(addr))
- if (suppression_ctx->Match(module_name, kInterceptorViaLibrary, &s))
- return true;
- }
-
- if (suppression_ctx->HasSuppressionType(kInterceptorViaFunction)) {
- SymbolizedStack *frames = symbolizer->SymbolizePC(addr);
- CHECK(frames);
- for (SymbolizedStack *cur = frames; cur; cur = cur->next) {
- const char *function_name = cur->info.function;
- if (!function_name) {
- continue;
- }
- // Match "interceptor_via_fun" suppressions.
- if (suppression_ctx->Match(function_name, kInterceptorViaFunction,
- &s)) {
- frames->ClearAll();
- return true;
- }
- }
- frames->ClearAll();
- }
- }
- return false;
-}
-
-} // namespace __asan
diff --git a/lib/asan/asan_suppressions.h b/lib/asan/asan_suppressions.h
deleted file mode 100644
index 5246b4b30334f..0000000000000
--- a/lib/asan/asan_suppressions.h
+++ /dev/null
@@ -1,30 +0,0 @@
-//===-- asan_suppressions.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.
-//
-// ASan-private header for asan_suppressions.cc.
-//===----------------------------------------------------------------------===//
-#ifndef ASAN_SUPPRESSIONS_H
-#define ASAN_SUPPRESSIONS_H
-
-#include "asan_internal.h"
-#include "sanitizer_common/sanitizer_stacktrace.h"
-
-namespace __asan {
-
-void InitializeSuppressions();
-bool IsInterceptorSuppressed(const char *interceptor_name);
-bool HaveStackTraceBasedSuppressions();
-bool IsStackTraceSuppressed(const StackTrace *stack);
-bool IsODRViolationSuppressed(const char *global_var_name);
-
-} // namespace __asan
-
-#endif // ASAN_SUPPRESSIONS_H
diff --git a/lib/asan/asan_thread.cc b/lib/asan/asan_thread.cc
deleted file mode 100644
index faf423d305b7d..0000000000000
--- a/lib/asan/asan_thread.cc
+++ /dev/null
@@ -1,529 +0,0 @@
-//===-- asan_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 AddressSanitizer, an address sanity checker.
-//
-// Thread-related code.
-//===----------------------------------------------------------------------===//
-#include "asan_allocator.h"
-#include "asan_interceptors.h"
-#include "asan_poisoning.h"
-#include "asan_stack.h"
-#include "asan_thread.h"
-#include "asan_mapping.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_placement_new.h"
-#include "sanitizer_common/sanitizer_stackdepot.h"
-#include "sanitizer_common/sanitizer_tls_get_addr.h"
-#include "lsan/lsan_common.h"
-
-namespace __asan {
-
-// AsanThreadContext implementation.
-
-void AsanThreadContext::OnCreated(void *arg) {
- CreateThreadContextArgs *args = static_cast<CreateThreadContextArgs*>(arg);
- if (args->stack)
- stack_id = StackDepotPut(*args->stack);
- thread = args->thread;
- thread->set_context(this);
-}
-
-void AsanThreadContext::OnFinished() {
- // Drop the link to the AsanThread object.
- thread = nullptr;
-}
-
-// MIPS requires aligned address
-static ALIGNED(16) char thread_registry_placeholder[sizeof(ThreadRegistry)];
-static ThreadRegistry *asan_thread_registry;
-
-static BlockingMutex mu_for_thread_context(LINKER_INITIALIZED);
-static LowLevelAllocator allocator_for_thread_context;
-
-static ThreadContextBase *GetAsanThreadContext(u32 tid) {
- BlockingMutexLock lock(&mu_for_thread_context);
- return new(allocator_for_thread_context) AsanThreadContext(tid);
-}
-
-ThreadRegistry &asanThreadRegistry() {
- static bool initialized;
- // Don't worry about thread_safety - this should be called when there is
- // a single thread.
- if (!initialized) {
- // Never reuse ASan threads: we store pointer to AsanThreadContext
- // in TSD and can't reliably tell when no more TSD destructors will
- // be called. It would be wrong to reuse AsanThreadContext for another
- // thread before all TSD destructors will be called for it.
- asan_thread_registry = new(thread_registry_placeholder) ThreadRegistry(
- GetAsanThreadContext, kMaxNumberOfThreads, kMaxNumberOfThreads);
- initialized = true;
- }
- return *asan_thread_registry;
-}
-
-AsanThreadContext *GetThreadContextByTidLocked(u32 tid) {
- return static_cast<AsanThreadContext *>(
- asanThreadRegistry().GetThreadLocked(tid));
-}
-
-// AsanThread implementation.
-
-AsanThread *AsanThread::Create(thread_callback_t start_routine, void *arg,
- u32 parent_tid, StackTrace *stack,
- bool detached) {
- uptr PageSize = GetPageSizeCached();
- uptr size = RoundUpTo(sizeof(AsanThread), PageSize);
- AsanThread *thread = (AsanThread*)MmapOrDie(size, __func__);
- thread->start_routine_ = start_routine;
- thread->arg_ = arg;
- AsanThreadContext::CreateThreadContextArgs args = {thread, stack};
- asanThreadRegistry().CreateThread(*reinterpret_cast<uptr *>(thread), detached,
- parent_tid, &args);
-
- return thread;
-}
-
-void AsanThread::TSDDtor(void *tsd) {
- AsanThreadContext *context = (AsanThreadContext*)tsd;
- VReport(1, "T%d TSDDtor\n", context->tid);
- if (context->thread)
- context->thread->Destroy();
-}
-
-void AsanThread::Destroy() {
- int tid = this->tid();
- VReport(1, "T%d exited\n", tid);
-
- malloc_storage().CommitBack();
- if (common_flags()->use_sigaltstack) UnsetAlternateSignalStack();
- asanThreadRegistry().FinishThread(tid);
- FlushToDeadThreadStats(&stats_);
- // We also clear the shadow on thread destruction because
- // some code may still be executing in later TSD destructors
- // and we don't want it to have any poisoned stack.
- ClearShadowForThreadStackAndTLS();
- DeleteFakeStack(tid);
- uptr size = RoundUpTo(sizeof(AsanThread), GetPageSizeCached());
- UnmapOrDie(this, size);
- DTLS_Destroy();
-}
-
-void AsanThread::StartSwitchFiber(FakeStack **fake_stack_save, uptr bottom,
- uptr size) {
- if (atomic_load(&stack_switching_, memory_order_relaxed)) {
- Report("ERROR: starting fiber switch while in fiber switch\n");
- Die();
- }
-
- next_stack_bottom_ = bottom;
- next_stack_top_ = bottom + size;
- atomic_store(&stack_switching_, 1, memory_order_release);
-
- FakeStack *current_fake_stack = fake_stack_;
- if (fake_stack_save)
- *fake_stack_save = fake_stack_;
- fake_stack_ = nullptr;
- SetTLSFakeStack(nullptr);
- // if fake_stack_save is null, the fiber will die, delete the fakestack
- if (!fake_stack_save && current_fake_stack)
- current_fake_stack->Destroy(this->tid());
-}
-
-void AsanThread::FinishSwitchFiber(FakeStack *fake_stack_save,
- uptr *bottom_old,
- uptr *size_old) {
- if (!atomic_load(&stack_switching_, memory_order_relaxed)) {
- Report("ERROR: finishing a fiber switch that has not started\n");
- Die();
- }
-
- if (fake_stack_save) {
- SetTLSFakeStack(fake_stack_save);
- fake_stack_ = fake_stack_save;
- }
-
- if (bottom_old)
- *bottom_old = stack_bottom_;
- if (size_old)
- *size_old = stack_top_ - stack_bottom_;
- stack_bottom_ = next_stack_bottom_;
- stack_top_ = next_stack_top_;
- atomic_store(&stack_switching_, 0, memory_order_release);
- next_stack_top_ = 0;
- next_stack_bottom_ = 0;
-}
-
-inline AsanThread::StackBounds AsanThread::GetStackBounds() const {
- if (!atomic_load(&stack_switching_, memory_order_acquire)) {
- // Make sure the stack bounds are fully initialized.
- if (stack_bottom_ >= stack_top_) return {0, 0};
- return {stack_bottom_, stack_top_};
- }
- char local;
- const uptr cur_stack = (uptr)&local;
- // Note: need to check next stack first, because FinishSwitchFiber
- // may be in process of overwriting stack_top_/bottom_. But in such case
- // we are already on the next stack.
- if (cur_stack >= next_stack_bottom_ && cur_stack < next_stack_top_)
- return {next_stack_bottom_, next_stack_top_};
- return {stack_bottom_, stack_top_};
-}
-
-uptr AsanThread::stack_top() {
- return GetStackBounds().top;
-}
-
-uptr AsanThread::stack_bottom() {
- return GetStackBounds().bottom;
-}
-
-uptr AsanThread::stack_size() {
- const auto bounds = GetStackBounds();
- return bounds.top - bounds.bottom;
-}
-
-// We want to create the FakeStack lazyly on the first use, but not eralier
-// than the stack size is known and the procedure has to be async-signal safe.
-FakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() {
- uptr stack_size = this->stack_size();
- if (stack_size == 0) // stack_size is not yet available, don't use FakeStack.
- return nullptr;
- uptr old_val = 0;
- // fake_stack_ has 3 states:
- // 0 -- not initialized
- // 1 -- being initialized
- // ptr -- initialized
- // This CAS checks if the state was 0 and if so changes it to state 1,
- // if that was successful, it initializes the pointer.
- if (atomic_compare_exchange_strong(
- reinterpret_cast<atomic_uintptr_t *>(&fake_stack_), &old_val, 1UL,
- memory_order_relaxed)) {
- uptr stack_size_log = Log2(RoundUpToPowerOfTwo(stack_size));
- CHECK_LE(flags()->min_uar_stack_size_log, flags()->max_uar_stack_size_log);
- stack_size_log =
- Min(stack_size_log, static_cast<uptr>(flags()->max_uar_stack_size_log));
- stack_size_log =
- Max(stack_size_log, static_cast<uptr>(flags()->min_uar_stack_size_log));
- fake_stack_ = FakeStack::Create(stack_size_log);
- SetTLSFakeStack(fake_stack_);
- return fake_stack_;
- }
- return nullptr;
-}
-
-void AsanThread::Init(const InitOptions *options) {
- next_stack_top_ = next_stack_bottom_ = 0;
- atomic_store(&stack_switching_, false, memory_order_release);
- CHECK_EQ(this->stack_size(), 0U);
- SetThreadStackAndTls(options);
- CHECK_GT(this->stack_size(), 0U);
- CHECK(AddrIsInMem(stack_bottom_));
- CHECK(AddrIsInMem(stack_top_ - 1));
- ClearShadowForThreadStackAndTLS();
- fake_stack_ = nullptr;
- if (__asan_option_detect_stack_use_after_return)
- AsyncSignalSafeLazyInitFakeStack();
- int local = 0;
- VReport(1, "T%d: stack [%p,%p) size 0x%zx; local=%p\n", tid(),
- (void *)stack_bottom_, (void *)stack_top_, stack_top_ - stack_bottom_,
- &local);
-}
-
-// Fuchsia and RTEMS don't use ThreadStart.
-// asan_fuchsia.c/asan_rtems.c define CreateMainThread and
-// SetThreadStackAndTls.
-#if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS
-
-thread_return_t AsanThread::ThreadStart(
- tid_t os_id, atomic_uintptr_t *signal_thread_is_registered) {
- Init();
- asanThreadRegistry().StartThread(tid(), os_id, /*workerthread*/ false,
- nullptr);
- if (signal_thread_is_registered)
- atomic_store(signal_thread_is_registered, 1, memory_order_release);
-
- if (common_flags()->use_sigaltstack) SetAlternateSignalStack();
-
- if (!start_routine_) {
- // start_routine_ == 0 if we're on the main thread or on one of the
- // OS X libdispatch worker threads. But nobody is supposed to call
- // ThreadStart() for the worker threads.
- CHECK_EQ(tid(), 0);
- return 0;
- }
-
- thread_return_t res = start_routine_(arg_);
-
- // On POSIX systems we defer this to the TSD destructor. LSan will consider
- // the thread's memory as non-live from the moment we call Destroy(), even
- // though that memory might contain pointers to heap objects which will be
- // cleaned up by a user-defined TSD destructor. Thus, calling Destroy() before
- // the TSD destructors have run might cause false positives in LSan.
- if (!SANITIZER_POSIX)
- this->Destroy();
-
- return res;
-}
-
-AsanThread *CreateMainThread() {
- AsanThread *main_thread = AsanThread::Create(
- /* start_routine */ nullptr, /* arg */ nullptr, /* parent_tid */ 0,
- /* stack */ nullptr, /* detached */ true);
- SetCurrentThread(main_thread);
- main_thread->ThreadStart(internal_getpid(),
- /* signal_thread_is_registered */ nullptr);
- return main_thread;
-}
-
-// This implementation doesn't use the argument, which is just passed down
-// from the caller of Init (which see, above). It's only there to support
-// OS-specific implementations that need more information passed through.
-void AsanThread::SetThreadStackAndTls(const InitOptions *options) {
- DCHECK_EQ(options, nullptr);
- uptr tls_size = 0;
- uptr stack_size = 0;
- GetThreadStackAndTls(tid() == 0, const_cast<uptr *>(&stack_bottom_),
- const_cast<uptr *>(&stack_size), &tls_begin_, &tls_size);
- stack_top_ = stack_bottom_ + stack_size;
- tls_end_ = tls_begin_ + tls_size;
- dtls_ = DTLS_Get();
-
- int local;
- CHECK(AddrIsInStack((uptr)&local));
-}
-
-#endif // !SANITIZER_FUCHSIA && !SANITIZER_RTEMS
-
-void AsanThread::ClearShadowForThreadStackAndTLS() {
- PoisonShadow(stack_bottom_, stack_top_ - stack_bottom_, 0);
- if (tls_begin_ != tls_end_) {
- uptr tls_begin_aligned = RoundDownTo(tls_begin_, SHADOW_GRANULARITY);
- uptr tls_end_aligned = RoundUpTo(tls_end_, SHADOW_GRANULARITY);
- FastPoisonShadowPartialRightRedzone(tls_begin_aligned,
- tls_end_ - tls_begin_aligned,
- tls_end_aligned - tls_end_, 0);
- }
-}
-
-bool AsanThread::GetStackFrameAccessByAddr(uptr addr,
- StackFrameAccess *access) {
- uptr bottom = 0;
- if (AddrIsInStack(addr)) {
- bottom = stack_bottom();
- } else if (has_fake_stack()) {
- bottom = fake_stack()->AddrIsInFakeStack(addr);
- CHECK(bottom);
- access->offset = addr - bottom;
- access->frame_pc = ((uptr*)bottom)[2];
- access->frame_descr = (const char *)((uptr*)bottom)[1];
- return true;
- }
- uptr aligned_addr = RoundDownTo(addr, SANITIZER_WORDSIZE / 8); // align addr.
- uptr mem_ptr = RoundDownTo(aligned_addr, SHADOW_GRANULARITY);
- u8 *shadow_ptr = (u8*)MemToShadow(aligned_addr);
- u8 *shadow_bottom = (u8*)MemToShadow(bottom);
-
- while (shadow_ptr >= shadow_bottom &&
- *shadow_ptr != kAsanStackLeftRedzoneMagic) {
- shadow_ptr--;
- mem_ptr -= SHADOW_GRANULARITY;
- }
-
- while (shadow_ptr >= shadow_bottom &&
- *shadow_ptr == kAsanStackLeftRedzoneMagic) {
- shadow_ptr--;
- mem_ptr -= SHADOW_GRANULARITY;
- }
-
- if (shadow_ptr < shadow_bottom) {
- return false;
- }
-
- uptr* ptr = (uptr*)(mem_ptr + SHADOW_GRANULARITY);
- CHECK(ptr[0] == kCurrentStackFrameMagic);
- access->offset = addr - (uptr)ptr;
- access->frame_pc = ptr[2];
- access->frame_descr = (const char*)ptr[1];
- return true;
-}
-
-uptr AsanThread::GetStackVariableShadowStart(uptr addr) {
- uptr bottom = 0;
- if (AddrIsInStack(addr)) {
- bottom = stack_bottom();
- } else if (has_fake_stack()) {
- bottom = fake_stack()->AddrIsInFakeStack(addr);
- CHECK(bottom);
- } else
- return 0;
-
- uptr aligned_addr = RoundDownTo(addr, SANITIZER_WORDSIZE / 8); // align addr.
- u8 *shadow_ptr = (u8*)MemToShadow(aligned_addr);
- u8 *shadow_bottom = (u8*)MemToShadow(bottom);
-
- while (shadow_ptr >= shadow_bottom &&
- (*shadow_ptr != kAsanStackLeftRedzoneMagic &&
- *shadow_ptr != kAsanStackMidRedzoneMagic &&
- *shadow_ptr != kAsanStackRightRedzoneMagic))
- shadow_ptr--;
-
- return (uptr)shadow_ptr + 1;
-}
-
-bool AsanThread::AddrIsInStack(uptr addr) {
- const auto bounds = GetStackBounds();
- return addr >= bounds.bottom && addr < bounds.top;
-}
-
-static bool ThreadStackContainsAddress(ThreadContextBase *tctx_base,
- void *addr) {
- AsanThreadContext *tctx = static_cast<AsanThreadContext*>(tctx_base);
- AsanThread *t = tctx->thread;
- if (!t) return false;
- if (t->AddrIsInStack((uptr)addr)) return true;
- if (t->has_fake_stack() && t->fake_stack()->AddrIsInFakeStack((uptr)addr))
- return true;
- return false;
-}
-
-AsanThread *GetCurrentThread() {
- if (SANITIZER_RTEMS && !asan_inited)
- return nullptr;
-
- AsanThreadContext *context =
- reinterpret_cast<AsanThreadContext *>(AsanTSDGet());
- if (!context) {
- if (SANITIZER_ANDROID) {
- // On Android, libc constructor is called _after_ asan_init, and cleans up
- // TSD. Try to figure out if this is still the main thread by the stack
- // address. We are not entirely sure that we have correct main thread
- // limits, so only do this magic on Android, and only if the found thread
- // is the main thread.
- AsanThreadContext *tctx = GetThreadContextByTidLocked(0);
- if (tctx && ThreadStackContainsAddress(tctx, &context)) {
- SetCurrentThread(tctx->thread);
- return tctx->thread;
- }
- }
- return nullptr;
- }
- return context->thread;
-}
-
-void SetCurrentThread(AsanThread *t) {
- CHECK(t->context());
- VReport(2, "SetCurrentThread: %p for thread %p\n", t->context(),
- (void *)GetThreadSelf());
- // Make sure we do not reset the current AsanThread.
- CHECK_EQ(0, AsanTSDGet());
- AsanTSDSet(t->context());
- CHECK_EQ(t->context(), AsanTSDGet());
-}
-
-u32 GetCurrentTidOrInvalid() {
- AsanThread *t = GetCurrentThread();
- return t ? t->tid() : kInvalidTid;
-}
-
-AsanThread *FindThreadByStackAddress(uptr addr) {
- asanThreadRegistry().CheckLocked();
- AsanThreadContext *tctx = static_cast<AsanThreadContext *>(
- asanThreadRegistry().FindThreadContextLocked(ThreadStackContainsAddress,
- (void *)addr));
- return tctx ? tctx->thread : nullptr;
-}
-
-void EnsureMainThreadIDIsCorrect() {
- AsanThreadContext *context =
- reinterpret_cast<AsanThreadContext *>(AsanTSDGet());
- if (context && (context->tid == 0))
- context->os_id = GetTid();
-}
-
-__asan::AsanThread *GetAsanThreadByOsIDLocked(tid_t os_id) {
- __asan::AsanThreadContext *context = static_cast<__asan::AsanThreadContext *>(
- __asan::asanThreadRegistry().FindThreadContextByOsIDLocked(os_id));
- if (!context) return nullptr;
- return context->thread;
-}
-} // namespace __asan
-
-// --- Implementation of LSan-specific functions --- {{{1
-namespace __lsan {
-bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end,
- uptr *tls_begin, uptr *tls_end, uptr *cache_begin,
- uptr *cache_end, DTLS **dtls) {
- __asan::AsanThread *t = __asan::GetAsanThreadByOsIDLocked(os_id);
- if (!t) return false;
- *stack_begin = t->stack_bottom();
- *stack_end = t->stack_top();
- *tls_begin = t->tls_begin();
- *tls_end = t->tls_end();
- // ASan doesn't keep allocator caches in TLS, so these are unused.
- *cache_begin = 0;
- *cache_end = 0;
- *dtls = t->dtls();
- return true;
-}
-
-void ForEachExtraStackRange(tid_t os_id, RangeIteratorCallback callback,
- void *arg) {
- __asan::AsanThread *t = __asan::GetAsanThreadByOsIDLocked(os_id);
- if (t && t->has_fake_stack())
- t->fake_stack()->ForEachFakeFrame(callback, arg);
-}
-
-void LockThreadRegistry() {
- __asan::asanThreadRegistry().Lock();
-}
-
-void UnlockThreadRegistry() {
- __asan::asanThreadRegistry().Unlock();
-}
-
-ThreadRegistry *GetThreadRegistryLocked() {
- __asan::asanThreadRegistry().CheckLocked();
- return &__asan::asanThreadRegistry();
-}
-
-void EnsureMainThreadIDIsCorrect() {
- __asan::EnsureMainThreadIDIsCorrect();
-}
-} // namespace __lsan
-
-// ---------------------- Interface ---------------- {{{1
-using namespace __asan; // NOLINT
-
-extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE
-void __sanitizer_start_switch_fiber(void **fakestacksave, const void *bottom,
- uptr size) {
- AsanThread *t = GetCurrentThread();
- if (!t) {
- VReport(1, "__asan_start_switch_fiber called from unknown thread\n");
- return;
- }
- t->StartSwitchFiber((FakeStack**)fakestacksave, (uptr)bottom, size);
-}
-
-SANITIZER_INTERFACE_ATTRIBUTE
-void __sanitizer_finish_switch_fiber(void* fakestack,
- const void **bottom_old,
- uptr *size_old) {
- AsanThread *t = GetCurrentThread();
- if (!t) {
- VReport(1, "__asan_finish_switch_fiber called from unknown thread\n");
- return;
- }
- t->FinishSwitchFiber((FakeStack*)fakestack,
- (uptr*)bottom_old,
- (uptr*)size_old);
-}
-}
diff --git a/lib/asan/asan_thread.h b/lib/asan/asan_thread.h
deleted file mode 100644
index 66091921101fb..0000000000000
--- a/lib/asan/asan_thread.h
+++ /dev/null
@@ -1,199 +0,0 @@
-//===-- asan_thread.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.
-//
-// ASan-private header for asan_thread.cc.
-//===----------------------------------------------------------------------===//
-
-#ifndef ASAN_THREAD_H
-#define ASAN_THREAD_H
-
-#include "asan_allocator.h"
-#include "asan_internal.h"
-#include "asan_fake_stack.h"
-#include "asan_stats.h"
-#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_libc.h"
-#include "sanitizer_common/sanitizer_thread_registry.h"
-
-namespace __sanitizer {
-struct DTLS;
-} // namespace __sanitizer
-
-namespace __asan {
-
-const u32 kInvalidTid = 0xffffff; // Must fit into 24 bits.
-const u32 kMaxNumberOfThreads = (1 << 22); // 4M
-
-class AsanThread;
-
-// These objects are created for every thread and are never deleted,
-// so we can find them by tid even if the thread is long dead.
-class AsanThreadContext : public ThreadContextBase {
- public:
- explicit AsanThreadContext(int tid)
- : ThreadContextBase(tid), announced(false),
- destructor_iterations(GetPthreadDestructorIterations()), stack_id(0),
- thread(nullptr) {}
- bool announced;
- u8 destructor_iterations;
- u32 stack_id;
- AsanThread *thread;
-
- void OnCreated(void *arg) override;
- void OnFinished() override;
-
- struct CreateThreadContextArgs {
- AsanThread *thread;
- StackTrace *stack;
- };
-};
-
-// AsanThreadContext objects are never freed, so we need many of them.
-COMPILER_CHECK(sizeof(AsanThreadContext) <= 256);
-
-// AsanThread are stored in TSD and destroyed when the thread dies.
-class AsanThread {
- public:
- static AsanThread *Create(thread_callback_t start_routine, void *arg,
- u32 parent_tid, StackTrace *stack, bool detached);
- static void TSDDtor(void *tsd);
- void Destroy();
-
- struct InitOptions;
- void Init(const InitOptions *options = nullptr);
-
- thread_return_t ThreadStart(tid_t os_id,
- atomic_uintptr_t *signal_thread_is_registered);
-
- uptr stack_top();
- uptr stack_bottom();
- uptr stack_size();
- uptr tls_begin() { return tls_begin_; }
- uptr tls_end() { return tls_end_; }
- DTLS *dtls() { return dtls_; }
- u32 tid() { return context_->tid; }
- AsanThreadContext *context() { return context_; }
- void set_context(AsanThreadContext *context) { context_ = context; }
-
- struct StackFrameAccess {
- uptr offset;
- uptr frame_pc;
- const char *frame_descr;
- };
- bool GetStackFrameAccessByAddr(uptr addr, StackFrameAccess *access);
-
- // Returns a pointer to the start of the stack variable's shadow memory.
- uptr GetStackVariableShadowStart(uptr addr);
-
- bool AddrIsInStack(uptr addr);
-
- void DeleteFakeStack(int tid) {
- if (!fake_stack_) return;
- FakeStack *t = fake_stack_;
- fake_stack_ = nullptr;
- SetTLSFakeStack(nullptr);
- t->Destroy(tid);
- }
-
- void StartSwitchFiber(FakeStack **fake_stack_save, uptr bottom, uptr size);
- void FinishSwitchFiber(FakeStack *fake_stack_save, uptr *bottom_old,
- uptr *size_old);
-
- bool has_fake_stack() {
- return !atomic_load(&stack_switching_, memory_order_relaxed) &&
- (reinterpret_cast<uptr>(fake_stack_) > 1);
- }
-
- FakeStack *fake_stack() {
- if (!__asan_option_detect_stack_use_after_return)
- return nullptr;
- if (atomic_load(&stack_switching_, memory_order_relaxed))
- return nullptr;
- if (!has_fake_stack())
- return AsyncSignalSafeLazyInitFakeStack();
- return fake_stack_;
- }
-
- // True is this thread is currently unwinding stack (i.e. collecting a stack
- // trace). Used to prevent deadlocks on platforms where libc unwinder calls
- // malloc internally. See PR17116 for more details.
- bool isUnwinding() const { return unwinding_; }
- void setUnwinding(bool b) { unwinding_ = b; }
-
- AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; }
- AsanStats &stats() { return stats_; }
-
- private:
- // NOTE: There is no AsanThread constructor. It is allocated
- // via mmap() and *must* be valid in zero-initialized state.
-
- void SetThreadStackAndTls(const InitOptions *options);
-
- void ClearShadowForThreadStackAndTLS();
- FakeStack *AsyncSignalSafeLazyInitFakeStack();
-
- struct StackBounds {
- uptr bottom;
- uptr top;
- };
- StackBounds GetStackBounds() const;
-
- AsanThreadContext *context_;
- thread_callback_t start_routine_;
- void *arg_;
-
- uptr stack_top_;
- uptr stack_bottom_;
- // these variables are used when the thread is about to switch stack
- uptr next_stack_top_;
- uptr next_stack_bottom_;
- // true if switching is in progress
- atomic_uint8_t stack_switching_;
-
- uptr tls_begin_;
- uptr tls_end_;
- DTLS *dtls_;
-
- FakeStack *fake_stack_;
- AsanThreadLocalMallocStorage malloc_storage_;
- AsanStats stats_;
- bool unwinding_;
-};
-
-// ScopedUnwinding is a scope for stacktracing member of a context
-class ScopedUnwinding {
- public:
- explicit ScopedUnwinding(AsanThread *t) : thread(t) {
- t->setUnwinding(true);
- }
- ~ScopedUnwinding() { thread->setUnwinding(false); }
-
- private:
- AsanThread *thread;
-};
-
-// Returns a single instance of registry.
-ThreadRegistry &asanThreadRegistry();
-
-// Must be called under ThreadRegistryLock.
-AsanThreadContext *GetThreadContextByTidLocked(u32 tid);
-
-// Get the current thread. May return 0.
-AsanThread *GetCurrentThread();
-void SetCurrentThread(AsanThread *t);
-u32 GetCurrentTidOrInvalid();
-AsanThread *FindThreadByStackAddress(uptr addr);
-
-// Used to handle fork().
-void EnsureMainThreadIDIsCorrect();
-} // namespace __asan
-
-#endif // ASAN_THREAD_H
diff --git a/lib/asan/asan_win.cc b/lib/asan/asan_win.cc
deleted file mode 100644
index 67125d38ad4a3..0000000000000
--- a/lib/asan/asan_win.cc
+++ /dev/null
@@ -1,348 +0,0 @@
-//===-- asan_win.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.
-//
-// Windows-specific details.
-//===----------------------------------------------------------------------===//
-
-#include "sanitizer_common/sanitizer_platform.h"
-#if SANITIZER_WINDOWS
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-#include <stdlib.h>
-
-#include "asan_interceptors.h"
-#include "asan_internal.h"
-#include "asan_report.h"
-#include "asan_stack.h"
-#include "asan_thread.h"
-#include "asan_mapping.h"
-#include "sanitizer_common/sanitizer_libc.h"
-#include "sanitizer_common/sanitizer_mutex.h"
-#include "sanitizer_common/sanitizer_win.h"
-#include "sanitizer_common/sanitizer_win_defs.h"
-
-using namespace __asan; // NOLINT
-
-extern "C" {
-SANITIZER_INTERFACE_ATTRIBUTE
-int __asan_should_detect_stack_use_after_return() {
- __asan_init();
- return __asan_option_detect_stack_use_after_return;
-}
-
-SANITIZER_INTERFACE_ATTRIBUTE
-uptr __asan_get_shadow_memory_dynamic_address() {
- __asan_init();
- return __asan_shadow_memory_dynamic_address;
-}
-} // extern "C"
-
-// ---------------------- Windows-specific interceptors ---------------- {{{
-static LPTOP_LEVEL_EXCEPTION_FILTER default_seh_handler;
-static LPTOP_LEVEL_EXCEPTION_FILTER user_seh_handler;
-
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-long __asan_unhandled_exception_filter(EXCEPTION_POINTERS *info) {
- EXCEPTION_RECORD *exception_record = info->ExceptionRecord;
- CONTEXT *context = info->ContextRecord;
-
- // FIXME: Handle EXCEPTION_STACK_OVERFLOW here.
-
- SignalContext sig(exception_record, context);
- ReportDeadlySignal(sig);
- UNREACHABLE("returned from reporting deadly signal");
-}
-
-// Wrapper SEH Handler. If the exception should be handled by asan, we call
-// __asan_unhandled_exception_filter, otherwise, we execute the user provided
-// exception handler or the default.
-static long WINAPI SEHHandler(EXCEPTION_POINTERS *info) {
- DWORD exception_code = info->ExceptionRecord->ExceptionCode;
- if (__sanitizer::IsHandledDeadlyException(exception_code))
- return __asan_unhandled_exception_filter(info);
- if (user_seh_handler)
- return user_seh_handler(info);
- // Bubble out to the default exception filter.
- if (default_seh_handler)
- return default_seh_handler(info);
- return EXCEPTION_CONTINUE_SEARCH;
-}
-
-INTERCEPTOR_WINAPI(LPTOP_LEVEL_EXCEPTION_FILTER, SetUnhandledExceptionFilter,
- LPTOP_LEVEL_EXCEPTION_FILTER ExceptionFilter) {
- CHECK(REAL(SetUnhandledExceptionFilter));
- if (ExceptionFilter == &SEHHandler)
- return REAL(SetUnhandledExceptionFilter)(ExceptionFilter);
- // We record the user provided exception handler to be called for all the
- // exceptions unhandled by asan.
- Swap(ExceptionFilter, user_seh_handler);
- return ExceptionFilter;
-}
-
-INTERCEPTOR_WINAPI(void, RtlRaiseException, EXCEPTION_RECORD *ExceptionRecord) {
- CHECK(REAL(RtlRaiseException));
- // This is a noreturn function, unless it's one of the exceptions raised to
- // communicate with the debugger, such as the one from OutputDebugString.
- if (ExceptionRecord->ExceptionCode != DBG_PRINTEXCEPTION_C)
- __asan_handle_no_return();
- REAL(RtlRaiseException)(ExceptionRecord);
-}
-
-INTERCEPTOR_WINAPI(void, RaiseException, void *a, void *b, void *c, void *d) {
- CHECK(REAL(RaiseException));
- __asan_handle_no_return();
- REAL(RaiseException)(a, b, c, d);
-}
-
-#ifdef _WIN64
-
-INTERCEPTOR_WINAPI(int, __C_specific_handler, void *a, void *b, void *c, void *d) { // NOLINT
- CHECK(REAL(__C_specific_handler));
- __asan_handle_no_return();
- return REAL(__C_specific_handler)(a, b, c, d);
-}
-
-#else
-
-INTERCEPTOR(int, _except_handler3, void *a, void *b, void *c, void *d) {
- CHECK(REAL(_except_handler3));
- __asan_handle_no_return();
- return REAL(_except_handler3)(a, b, c, d);
-}
-
-#if ASAN_DYNAMIC
-// This handler is named differently in -MT and -MD CRTs.
-#define _except_handler4 _except_handler4_common
-#endif
-INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {
- CHECK(REAL(_except_handler4));
- __asan_handle_no_return();
- return REAL(_except_handler4)(a, b, c, d);
-}
-#endif
-
-static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) {
- AsanThread *t = (AsanThread*)arg;
- SetCurrentThread(t);
- return t->ThreadStart(GetTid(), /* signal_thread_is_registered */ nullptr);
-}
-
-INTERCEPTOR_WINAPI(DWORD, CreateThread,
- void* security, uptr stack_size,
- DWORD (__stdcall *start_routine)(void*), void* arg,
- DWORD thr_flags, void* tid) {
- // Strict init-order checking is thread-hostile.
- if (flags()->strict_init_order)
- StopInitOrderChecking();
- GET_STACK_TRACE_THREAD;
- // FIXME: The CreateThread interceptor is not the same as a pthread_create
- // one. This is a bandaid fix for PR22025.
- bool detached = false; // FIXME: how can we determine it on Windows?
- u32 current_tid = GetCurrentTidOrInvalid();
- AsanThread *t =
- AsanThread::Create(start_routine, arg, current_tid, &stack, detached);
- return REAL(CreateThread)(security, stack_size,
- asan_thread_start, t, thr_flags, tid);
-}
-
-// }}}
-
-namespace __asan {
-
-void InitializePlatformInterceptors() {
- ASAN_INTERCEPT_FUNC(CreateThread);
- ASAN_INTERCEPT_FUNC(SetUnhandledExceptionFilter);
-
-#ifdef _WIN64
- ASAN_INTERCEPT_FUNC(__C_specific_handler);
-#else
- ASAN_INTERCEPT_FUNC(_except_handler3);
- ASAN_INTERCEPT_FUNC(_except_handler4);
-#endif
-
- // Try to intercept kernel32!RaiseException, and if that fails, intercept
- // ntdll!RtlRaiseException instead.
- if (!::__interception::OverrideFunction("RaiseException",
- (uptr)WRAP(RaiseException),
- (uptr *)&REAL(RaiseException))) {
- CHECK(::__interception::OverrideFunction("RtlRaiseException",
- (uptr)WRAP(RtlRaiseException),
- (uptr *)&REAL(RtlRaiseException)));
- }
-}
-
-void AsanApplyToGlobals(globals_op_fptr op, const void *needle) {
- UNIMPLEMENTED();
-}
-
-// ---------------------- TSD ---------------- {{{
-static bool tsd_key_inited = false;
-
-static __declspec(thread) void *fake_tsd = 0;
-
-void AsanTSDInit(void (*destructor)(void *tsd)) {
- // FIXME: we're ignoring the destructor for now.
- tsd_key_inited = true;
-}
-
-void *AsanTSDGet() {
- CHECK(tsd_key_inited);
- return fake_tsd;
-}
-
-void AsanTSDSet(void *tsd) {
- CHECK(tsd_key_inited);
- fake_tsd = tsd;
-}
-
-void PlatformTSDDtor(void *tsd) {
- AsanThread::TSDDtor(tsd);
-}
-// }}}
-
-// ---------------------- Various stuff ---------------- {{{
-void *AsanDoesNotSupportStaticLinkage() {
-#if defined(_DEBUG)
-#error Please build the runtime with a non-debug CRT: /MD or /MT
-#endif
- return 0;
-}
-
-uptr FindDynamicShadowStart() {
- uptr granularity = GetMmapGranularity();
- uptr alignment = 8 * granularity;
- uptr left_padding = granularity;
- uptr space_size = kHighShadowEnd + left_padding;
- uptr shadow_start = FindAvailableMemoryRange(space_size, alignment,
- granularity, nullptr, nullptr);
- CHECK_NE((uptr)0, shadow_start);
- CHECK(IsAligned(shadow_start, alignment));
- return shadow_start;
-}
-
-void AsanCheckDynamicRTPrereqs() {}
-
-void AsanCheckIncompatibleRT() {}
-
-void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
- UNIMPLEMENTED();
-}
-
-void AsanOnDeadlySignal(int, void *siginfo, void *context) {
- UNIMPLEMENTED();
-}
-
-#if SANITIZER_WINDOWS64
-// Exception handler for dealing with shadow memory.
-static LONG CALLBACK
-ShadowExceptionHandler(PEXCEPTION_POINTERS exception_pointers) {
- uptr page_size = GetPageSizeCached();
- // Only handle access violations.
- if (exception_pointers->ExceptionRecord->ExceptionCode !=
- EXCEPTION_ACCESS_VIOLATION) {
- return EXCEPTION_CONTINUE_SEARCH;
- }
-
- // Only handle access violations that land within the shadow memory.
- uptr addr =
- (uptr)(exception_pointers->ExceptionRecord->ExceptionInformation[1]);
-
- // Check valid shadow range.
- if (!AddrIsInShadow(addr)) return EXCEPTION_CONTINUE_SEARCH;
-
- // This is an access violation while trying to read from the shadow. Commit
- // the relevant page and let execution continue.
-
- // Determine the address of the page that is being accessed.
- uptr page = RoundDownTo(addr, page_size);
-
- // Commit the page.
- uptr result =
- (uptr)::VirtualAlloc((LPVOID)page, page_size, MEM_COMMIT, PAGE_READWRITE);
- if (result != page) return EXCEPTION_CONTINUE_SEARCH;
-
- // The page mapping succeeded, so continue execution as usual.
- return EXCEPTION_CONTINUE_EXECUTION;
-}
-
-#endif
-
-void InitializePlatformExceptionHandlers() {
-#if SANITIZER_WINDOWS64
- // On Win64, we map memory on demand with access violation handler.
- // Install our exception handler.
- CHECK(AddVectoredExceptionHandler(TRUE, &ShadowExceptionHandler));
-#endif
-}
-
-bool IsSystemHeapAddress(uptr addr) {
- return ::HeapValidate(GetProcessHeap(), 0, (void*)addr) != FALSE;
-}
-
-// We want to install our own exception handler (EH) to print helpful reports
-// on access violations and whatnot. Unfortunately, the CRT initializers assume
-// they are run before any user code and drop any previously-installed EHs on
-// the floor, so we can't install our handler inside __asan_init.
-// (See crt0dat.c in the CRT sources for the details)
-//
-// Things get even more complicated with the dynamic runtime, as it finishes its
-// initialization before the .exe module CRT begins to initialize.
-//
-// For the static runtime (-MT), it's enough to put a callback to
-// __asan_set_seh_filter in the last section for C initializers.
-//
-// For the dynamic runtime (-MD), we want link the same
-// asan_dynamic_runtime_thunk.lib to all the modules, thus __asan_set_seh_filter
-// will be called for each instrumented module. This ensures that at least one
-// __asan_set_seh_filter call happens after the .exe module CRT is initialized.
-extern "C" SANITIZER_INTERFACE_ATTRIBUTE
-int __asan_set_seh_filter() {
- // We should only store the previous handler if it's not our own handler in
- // order to avoid loops in the EH chain.
- auto prev_seh_handler = SetUnhandledExceptionFilter(SEHHandler);
- if (prev_seh_handler != &SEHHandler)
- default_seh_handler = prev_seh_handler;
- return 0;
-}
-
-#if !ASAN_DYNAMIC
-// The CRT runs initializers in this order:
-// - C initializers, from XIA to XIZ
-// - C++ initializers, from XCA to XCZ
-// Prior to 2015, the CRT set the unhandled exception filter at priority XIY,
-// near the end of C initialization. Starting in 2015, it was moved to the
-// beginning of C++ initialization. We set our priority to XCAB to run
-// immediately after the CRT runs. This way, our exception filter is called
-// first and we can delegate to their filter if appropriate.
-#pragma section(".CRT$XCAB", long, read) // NOLINT
-__declspec(allocate(".CRT$XCAB")) int (*__intercept_seh)() =
- __asan_set_seh_filter;
-
-// Piggyback on the TLS initialization callback directory to initialize asan as
-// early as possible. Initializers in .CRT$XL* are called directly by ntdll,
-// which run before the CRT. Users also add code to .CRT$XLC, so it's important
-// to run our initializers first.
-static void NTAPI asan_thread_init(void *module, DWORD reason, void *reserved) {
- if (reason == DLL_PROCESS_ATTACH) __asan_init();
-}
-
-#pragma section(".CRT$XLAB", long, read) // NOLINT
-__declspec(allocate(".CRT$XLAB")) void (NTAPI *__asan_tls_init)(void *,
- unsigned long, void *) = asan_thread_init;
-#endif
-
-WIN_FORCE_LINK(__asan_dso_reg_hook)
-
-// }}}
-} // namespace __asan
-
-#endif // SANITIZER_WINDOWS
diff --git a/lib/asan/asan_win_dll_thunk.cc b/lib/asan/asan_win_dll_thunk.cc
deleted file mode 100644
index c6a313d24026e..0000000000000
--- a/lib/asan/asan_win_dll_thunk.cc
+++ /dev/null
@@ -1,152 +0,0 @@
-//===-- asan_win_dll_thunk.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 file defines a family of thunks that should be statically linked into
-// the DLLs that have ASan instrumentation in order to delegate the calls to the
-// shared runtime that lives in the main binary.
-// See https://github.com/google/sanitizers/issues/209 for the details.
-//===----------------------------------------------------------------------===//
-
-#ifdef SANITIZER_DLL_THUNK
-#include "asan_init_version.h"
-#include "interception/interception.h"
-#include "sanitizer_common/sanitizer_win_defs.h"
-#include "sanitizer_common/sanitizer_win_dll_thunk.h"
-#include "sanitizer_common/sanitizer_platform_interceptors.h"
-
-// ASan own interface functions.
-#define INTERFACE_FUNCTION(Name) INTERCEPT_SANITIZER_FUNCTION(Name)
-#define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name)
-#include "asan_interface.inc"
-
-// Memory allocation functions.
-INTERCEPT_WRAP_V_W(free)
-INTERCEPT_WRAP_V_W(_free_base)
-INTERCEPT_WRAP_V_WW(_free_dbg)
-
-INTERCEPT_WRAP_W_W(malloc)
-INTERCEPT_WRAP_W_W(_malloc_base)
-INTERCEPT_WRAP_W_WWWW(_malloc_dbg)
-
-INTERCEPT_WRAP_W_WW(calloc)
-INTERCEPT_WRAP_W_WW(_calloc_base)
-INTERCEPT_WRAP_W_WWWWW(_calloc_dbg)
-INTERCEPT_WRAP_W_WWW(_calloc_impl)
-
-INTERCEPT_WRAP_W_WW(realloc)
-INTERCEPT_WRAP_W_WW(_realloc_base)
-INTERCEPT_WRAP_W_WWW(_realloc_dbg)
-INTERCEPT_WRAP_W_WWW(_recalloc)
-INTERCEPT_WRAP_W_WWW(_recalloc_base)
-
-INTERCEPT_WRAP_W_W(_msize)
-INTERCEPT_WRAP_W_W(_expand)
-INTERCEPT_WRAP_W_W(_expand_dbg)
-
-// TODO(timurrrr): Might want to add support for _aligned_* allocation
-// functions to detect a bit more bugs. Those functions seem to wrap malloc().
-
-// TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cc).
-
-INTERCEPT_LIBRARY_FUNCTION(atoi);
-INTERCEPT_LIBRARY_FUNCTION(atol);
-INTERCEPT_LIBRARY_FUNCTION(frexp);
-INTERCEPT_LIBRARY_FUNCTION(longjmp);
-#if SANITIZER_INTERCEPT_MEMCHR
-INTERCEPT_LIBRARY_FUNCTION(memchr);
-#endif
-INTERCEPT_LIBRARY_FUNCTION(memcmp);
-INTERCEPT_LIBRARY_FUNCTION(memcpy);
-INTERCEPT_LIBRARY_FUNCTION(memmove);
-INTERCEPT_LIBRARY_FUNCTION(memset);
-INTERCEPT_LIBRARY_FUNCTION(strcat); // NOLINT
-INTERCEPT_LIBRARY_FUNCTION(strchr);
-INTERCEPT_LIBRARY_FUNCTION(strcmp);
-INTERCEPT_LIBRARY_FUNCTION(strcpy); // NOLINT
-INTERCEPT_LIBRARY_FUNCTION(strcspn);
-INTERCEPT_LIBRARY_FUNCTION(strdup);
-INTERCEPT_LIBRARY_FUNCTION(strlen);
-INTERCEPT_LIBRARY_FUNCTION(strncat);
-INTERCEPT_LIBRARY_FUNCTION(strncmp);
-INTERCEPT_LIBRARY_FUNCTION(strncpy);
-INTERCEPT_LIBRARY_FUNCTION(strnlen);
-INTERCEPT_LIBRARY_FUNCTION(strpbrk);
-INTERCEPT_LIBRARY_FUNCTION(strrchr);
-INTERCEPT_LIBRARY_FUNCTION(strspn);
-INTERCEPT_LIBRARY_FUNCTION(strstr);
-INTERCEPT_LIBRARY_FUNCTION(strtok);
-INTERCEPT_LIBRARY_FUNCTION(strtol);
-INTERCEPT_LIBRARY_FUNCTION(wcslen);
-INTERCEPT_LIBRARY_FUNCTION(wcsnlen);
-
-#ifdef _WIN64
-INTERCEPT_LIBRARY_FUNCTION(__C_specific_handler);
-#else
-INTERCEPT_LIBRARY_FUNCTION(_except_handler3);
-// _except_handler4 checks -GS cookie which is different for each module, so we
-// can't use INTERCEPT_LIBRARY_FUNCTION(_except_handler4).
-INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) {
- __asan_handle_no_return();
- return REAL(_except_handler4)(a, b, c, d);
-}
-#endif
-
-// Windows specific functions not included in asan_interface.inc.
-INTERCEPT_WRAP_W_V(__asan_should_detect_stack_use_after_return)
-INTERCEPT_WRAP_W_V(__asan_get_shadow_memory_dynamic_address)
-INTERCEPT_WRAP_W_W(__asan_unhandled_exception_filter)
-
-using namespace __sanitizer;
-
-extern "C" {
-int __asan_option_detect_stack_use_after_return;
-uptr __asan_shadow_memory_dynamic_address;
-} // extern "C"
-
-static int asan_dll_thunk_init() {
- typedef void (*fntype)();
- static fntype fn = 0;
- // asan_dll_thunk_init is expected to be called by only one thread.
- if (fn) return 0;
-
- // Ensure all interception was executed.
- __dll_thunk_init();
-
- fn = (fntype) dllThunkGetRealAddrOrDie("__asan_init");
- fn();
- __asan_option_detect_stack_use_after_return =
- (__asan_should_detect_stack_use_after_return() != 0);
- __asan_shadow_memory_dynamic_address =
- (uptr)__asan_get_shadow_memory_dynamic_address();
-
-#ifndef _WIN64
- INTERCEPT_FUNCTION(_except_handler4);
-#endif
- // In DLLs, the callbacks are expected to return 0,
- // otherwise CRT initialization fails.
- return 0;
-}
-
-#pragma section(".CRT$XIB", long, read) // NOLINT
-__declspec(allocate(".CRT$XIB")) int (*__asan_preinit)() = asan_dll_thunk_init;
-
-static void WINAPI asan_thread_init(void *mod, unsigned long reason,
- void *reserved) {
- if (reason == /*DLL_PROCESS_ATTACH=*/1) asan_dll_thunk_init();
-}
-
-#pragma section(".CRT$XLAB", long, read) // NOLINT
-__declspec(allocate(".CRT$XLAB")) void (WINAPI *__asan_tls_init)(void *,
- unsigned long, void *) = asan_thread_init;
-
-WIN_FORCE_LINK(__asan_dso_reg_hook)
-
-#endif // SANITIZER_DLL_THUNK
diff --git a/lib/asan/asan_win_dynamic_runtime_thunk.cc b/lib/asan/asan_win_dynamic_runtime_thunk.cc
deleted file mode 100644
index 416c73b236299..0000000000000
--- a/lib/asan/asan_win_dynamic_runtime_thunk.cc
+++ /dev/null
@@ -1,131 +0,0 @@
-//===-- asan_win_dynamic_runtime_thunk.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 file defines things that need to be present in the application modules
-// to interact with the ASan DLL runtime correctly and can't be implemented
-// using the default "import library" generated when linking the DLL RTL.
-//
-// This includes:
-// - creating weak aliases to default implementation imported from asan dll.
-// - forwarding the detect_stack_use_after_return runtime option
-// - working around deficiencies of the MD runtime
-// - installing a custom SEH handler
-//
-//===----------------------------------------------------------------------===//
-
-#ifdef SANITIZER_DYNAMIC_RUNTIME_THUNK
-#define SANITIZER_IMPORT_INTERFACE 1
-#include "sanitizer_common/sanitizer_win_defs.h"
-#define WIN32_LEAN_AND_MEAN
-#include <windows.h>
-
-// Define weak alias for all weak functions imported from asan dll.
-#define INTERFACE_FUNCTION(Name)
-#define INTERFACE_WEAK_FUNCTION(Name) WIN_WEAK_IMPORT_DEF(Name)
-#include "asan_interface.inc"
-
-// First, declare CRT sections we'll be using in this file
-#pragma section(".CRT$XIB", long, read) // NOLINT
-#pragma section(".CRT$XID", long, read) // NOLINT
-#pragma section(".CRT$XCAB", long, read) // NOLINT
-#pragma section(".CRT$XTW", long, read) // NOLINT
-#pragma section(".CRT$XTY", long, read) // NOLINT
-#pragma section(".CRT$XLAB", long, read) // NOLINT
-
-////////////////////////////////////////////////////////////////////////////////
-// Define a copy of __asan_option_detect_stack_use_after_return that should be
-// used when linking an MD runtime with a set of object files on Windows.
-//
-// The ASan MD runtime dllexports '__asan_option_detect_stack_use_after_return',
-// so normally we would just dllimport it. Unfortunately, the dllimport
-// attribute adds __imp_ prefix to the symbol name of a variable.
-// Since in general we don't know if a given TU is going to be used
-// with a MT or MD runtime and we don't want to use ugly __imp_ names on Windows
-// just to work around this issue, let's clone the variable that is constant
-// after initialization anyways.
-extern "C" {
-__declspec(dllimport) int __asan_should_detect_stack_use_after_return();
-int __asan_option_detect_stack_use_after_return;
-
-__declspec(dllimport) void* __asan_get_shadow_memory_dynamic_address();
-void* __asan_shadow_memory_dynamic_address;
-}
-
-static int InitializeClonedVariables() {
- __asan_option_detect_stack_use_after_return =
- __asan_should_detect_stack_use_after_return();
- __asan_shadow_memory_dynamic_address =
- __asan_get_shadow_memory_dynamic_address();
- return 0;
-}
-
-static void NTAPI asan_thread_init(void *mod, unsigned long reason,
- void *reserved) {
- if (reason == DLL_PROCESS_ATTACH) InitializeClonedVariables();
-}
-
-// Our cloned variables must be initialized before C/C++ constructors. If TLS
-// is used, our .CRT$XLAB initializer will run first. If not, our .CRT$XIB
-// initializer is needed as a backup.
-__declspec(allocate(".CRT$XIB")) int (*__asan_initialize_cloned_variables)() =
- InitializeClonedVariables;
-__declspec(allocate(".CRT$XLAB")) void (NTAPI *__asan_tls_init)(void *,
- unsigned long, void *) = asan_thread_init;
-
-////////////////////////////////////////////////////////////////////////////////
-// For some reason, the MD CRT doesn't call the C/C++ terminators during on DLL
-// unload or on exit. ASan relies on LLVM global_dtors to call
-// __asan_unregister_globals on these events, which unfortunately doesn't work
-// with the MD runtime, see PR22545 for the details.
-// To work around this, for each DLL we schedule a call to UnregisterGlobals
-// using atexit() that calls a small subset of C terminators
-// where LLVM global_dtors is placed. Fingers crossed, no other C terminators
-// are there.
-extern "C" int __cdecl atexit(void (__cdecl *f)(void));
-extern "C" void __cdecl _initterm(void *a, void *b);
-
-namespace {
-__declspec(allocate(".CRT$XTW")) void* before_global_dtors = 0;
-__declspec(allocate(".CRT$XTY")) void* after_global_dtors = 0;
-
-void UnregisterGlobals() {
- _initterm(&before_global_dtors, &after_global_dtors);
-}
-
-int ScheduleUnregisterGlobals() {
- return atexit(UnregisterGlobals);
-}
-} // namespace
-
-// We need to call 'atexit(UnregisterGlobals);' as early as possible, but after
-// atexit() is initialized (.CRT$XIC). As this is executed before C++
-// initializers (think ctors for globals), UnregisterGlobals gets executed after
-// dtors for C++ globals.
-__declspec(allocate(".CRT$XID"))
-int (*__asan_schedule_unregister_globals)() = ScheduleUnregisterGlobals;
-
-////////////////////////////////////////////////////////////////////////////////
-// ASan SEH handling.
-// We need to set the ASan-specific SEH handler at the end of CRT initialization
-// of each module (see also asan_win.cc).
-extern "C" {
-__declspec(dllimport) int __asan_set_seh_filter();
-static int SetSEHFilter() { return __asan_set_seh_filter(); }
-
-// Unfortunately, putting a pointer to __asan_set_seh_filter into
-// __asan_intercept_seh gets optimized out, so we have to use an extra function.
-__declspec(allocate(".CRT$XCAB")) int (*__asan_seh_interceptor)() =
- SetSEHFilter;
-}
-
-WIN_FORCE_LINK(__asan_dso_reg_hook)
-
-#endif // SANITIZER_DYNAMIC_RUNTIME_THUNK
diff --git a/lib/asan/asan_win_weak_interception.cc b/lib/asan/asan_win_weak_interception.cc
deleted file mode 100644
index ca26f914cf5f6..0000000000000
--- a/lib/asan/asan_win_weak_interception.cc
+++ /dev/null
@@ -1,23 +0,0 @@
-//===-- asan_win_weak_interception.cc -------------------------------------===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// This module should be included in Address Sanitizer when it is implemented as
-// a shared library on Windows (dll), in order to delegate the calls of weak
-// functions to the implementation in the main executable when a strong
-// definition is provided.
-//===----------------------------------------------------------------------===//
-#ifdef SANITIZER_DYNAMIC
-#include "sanitizer_common/sanitizer_win_weak_interception.h"
-#include "asan_interface_internal.h"
-// Check if strong definitions for weak functions are present in the main
-// executable. If that is the case, override dll functions to point to strong
-// implementations.
-#define INTERFACE_FUNCTION(Name)
-#define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name)
-#include "asan_interface.inc"
-#endif // SANITIZER_DYNAMIC
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 68b6f093b533f..0000000000000
--- a/lib/asan/scripts/asan_symbolize.py
+++ /dev/null
@@ -1,519 +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
- 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, 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 1b70605915301..0000000000000
--- a/lib/asan/tests/CMakeLists.txt
+++ /dev/null
@@ -1,314 +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()
-
-if(MSVC)
- # Disable exceptions on Windows until they work reliably.
- list(APPEND ASAN_UNITTEST_COMMON_CFLAGS -fno-exceptions -DGTEST_HAS_SEH=0)
-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 69c8fe6f4818c..0000000000000
--- a/lib/asan/tests/asan_interface_test.cc
+++ /dev/null
@@ -1,420 +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());
- }
-}
-
-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));
-}
-
-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 65acb2839ba1b..0000000000000
--- a/lib/asan/tests/asan_noinst_test.cc
+++ /dev/null
@@ -1,271 +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);
-}
-
-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));
- }
-}
-
-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 25d6a20834503..0000000000000
--- a/lib/asan/tests/asan_test.cc
+++ /dev/null
@@ -1,1361 +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);
- }
-}
-
-// 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);
-}
-
-
-// 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/asan/weak_symbols.txt b/lib/asan/weak_symbols.txt
deleted file mode 100644
index fe680f8a9a4f6..0000000000000
--- a/lib/asan/weak_symbols.txt
+++ /dev/null
@@ -1,12 +0,0 @@
-___asan_default_options
-___asan_default_suppressions
-___asan_on_error
-___asan_set_shadow_00
-___asan_set_shadow_f1
-___asan_set_shadow_f2
-___asan_set_shadow_f3
-___asan_set_shadow_f4
-___asan_set_shadow_f5
-___asan_set_shadow_f6
-___asan_set_shadow_f7
-___asan_set_shadow_f8