diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2014-11-06 22:49:13 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2014-11-06 22:49:13 +0000 |
commit | 8ef50bf3d1c287b5013c3168de77a462dfce3495 (patch) | |
tree | 3467f3372c1195b1546172d89af2205a50b1866d | |
parent | 11023dc647fd8f41418da90d59db138400d0f334 (diff) | |
download | src-8ef50bf3d1c287b5013c3168de77a462dfce3495.tar.gz src-8ef50bf3d1c287b5013c3168de77a462dfce3495.zip |
Import compiler-rt release_34 branch r197381.vendor/compiler-rt/compiler-rt-r197381
Notes
Notes:
svn path=/vendor/compiler-rt/dist/; revision=274201
svn path=/vendor/compiler-rt/compiler-rt-r197381/; revision=274202; tag=vendor/compiler-rt/compiler-rt-r197381
679 files changed, 36733 insertions, 7815 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index a57751ce6f61..a4424086c696 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -15,6 +15,9 @@ include(LLVMParseArguments) # runtime libraries. cmake_minimum_required(VERSION 2.8.8) +# Top level target used to build all compiler-rt libraries. +add_custom_target(compiler-rt) + # Compute the Clang version from the LLVM version. # FIXME: We should be able to reuse CLANG_VERSION variable calculated # in Clang cmake files, instead of copying the rules here. @@ -36,21 +39,24 @@ set(CMAKE_MODULE_PATH include(AddCompilerRT) set(COMPILER_RT_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) +set(COMPILER_RT_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) # Setup custom SDK sysroots. set(COMPILER_RT_DARWIN_SDK_SYSROOT ${COMPILER_RT_SOURCE_DIR}/SDKs/darwin) set(COMPILER_RT_LINUX_SDK_SYSROOT ${COMPILER_RT_SOURCE_DIR}/SDKs/linux) +include(SanitizerUtils) # Detect whether the current target platform is 32-bit or 64-bit, and setup # the correct commandline flags needed to attempt to target 32-bit and 64-bit. -if(CMAKE_SIZEOF_VOID_P EQUAL 4 OR LLVM_BUILD_32_BITS) +if (NOT CMAKE_SIZEOF_VOID_P EQUAL 4 AND + NOT CMAKE_SIZEOF_VOID_P EQUAL 8) + message(FATAL_ERROR "Please use architecture with 4 or 8 byte pointers.") +endif() +if (NOT MSVC) set(TARGET_64_BIT_CFLAGS "-m64") - set(TARGET_32_BIT_CFLAGS "") + set(TARGET_32_BIT_CFLAGS "-m32") else() - if(NOT CMAKE_SIZEOF_VOID_P EQUAL 8) - message(FATAL_ERROR "Please use a sane architecture with 4 or 8 byte pointers.") - endif() set(TARGET_64_BIT_CFLAGS "") - set(TARGET_32_BIT_CFLAGS "-m32") + set(TARGET_32_BIT_CFLAGS "") endif() # List of architectures we can target. @@ -86,13 +92,12 @@ macro(test_target_arch arch) endmacro() if("${LLVM_NATIVE_ARCH}" STREQUAL "X86") - test_target_arch(x86_64 ${TARGET_64_BIT_CFLAGS}) + if (NOT MSVC) + test_target_arch(x86_64 ${TARGET_64_BIT_CFLAGS}) + endif() test_target_arch(i386 ${TARGET_32_BIT_CFLAGS}) elseif("${LLVM_NATIVE_ARCH}" STREQUAL "PowerPC") - # Explicitly set -m flag on powerpc, because on ppc64 defaults for gcc and - # clang are different. - test_target_arch(powerpc64 "-m64") - test_target_arch(powerpc "-m32") + test_target_arch(powerpc64 ${TARGET_64_BIT_CFLAGS}) endif() # We only support running instrumented tests when we're not cross compiling @@ -119,26 +124,43 @@ function(filter_available_targets out_var) set(${out_var} ${archs} PARENT_SCOPE) endfunction() +option(COMPILER_RT_DEBUG "Build runtimes with full debug info" OFF) + +# COMPILER_RT_DEBUG_PYBOOL is used by lit.common.configured.in. +pythonize_bool(COMPILER_RT_DEBUG) + # Provide some common commmandline flags for Sanitizer runtimes. -set(SANITIZER_COMMON_CFLAGS - -fPIC - -fno-builtin - -fno-exceptions - -fomit-frame-pointer - -funwind-tables - -fno-stack-protector - -Wno-gnu # Variadic macros with 0 arguments for ... - -O3 - ) -if(NOT WIN32) - list(APPEND SANITIZER_COMMON_CFLAGS -fvisibility=hidden) -endif() -# Build sanitizer runtimes with debug info. -check_cxx_compiler_flag(-gline-tables-only SUPPORTS_GLINE_TABLES_ONLY_FLAG) -if(SUPPORTS_GLINE_TABLES_ONLY_FLAG) - list(APPEND SANITIZER_COMMON_CFLAGS -gline-tables-only) +if (NOT MSVC) + set(SANITIZER_COMMON_CFLAGS + -fPIC + -fno-builtin + -fno-exceptions + -fomit-frame-pointer + -funwind-tables + -fno-stack-protector + -Wno-gnu # Variadic macros with 0 arguments for ... + -fvisibility=hidden + ) + if (NOT COMPILER_RT_DEBUG) + list(APPEND SANITIZER_COMMON_CFLAGS -O3) + endif() else() - list(APPEND SANITIZER_COMMON_CFLAGS -g) + set(SANITIZER_COMMON_CFLAGS + /MT + /Zi + /Oy- + /GS- + /wd4722 + ) +endif() +# Build sanitizer runtimes with debug info. (MSVC gets /Zi above) +if (NOT MSVC) + check_cxx_compiler_flag(-gline-tables-only SUPPORTS_GLINE_TABLES_ONLY_FLAG) + if(SUPPORTS_GLINE_TABLES_ONLY_FLAG AND NOT COMPILER_RT_DEBUG) + list(APPEND SANITIZER_COMMON_CFLAGS -gline-tables-only) + else() + list(APPEND SANITIZER_COMMON_CFLAGS -g) + endif() endif() # Warnings suppressions. check_cxx_compiler_flag(-Wno-variadic-macros SUPPORTS_NO_VARIADIC_MACROS_FLAG) @@ -155,30 +177,50 @@ check_cxx_compiler_flag(-Wno-non-virtual-dtor SUPPORTS_NO_NON_VIRTUAL_DTOR_FLAG) if (SUPPORTS_NO_NON_VIRTUAL_DTOR_FLAG) list(APPEND SANITIZER_COMMON_CFLAGS -Wno-non-virtual-dtor) endif() +check_cxx_compiler_flag(-Wglobal-constructors SUPPORTS_GLOBAL_CONSTRUCTORS_FLAG) +# Not all sanitizers forbid global constructors. -# Setup min Mac OS X version. if(APPLE) + # Obtain the iOS Simulator SDK path from xcodebuild. + execute_process( + COMMAND xcodebuild -version -sdk iphonesimulator Path + OUTPUT_VARIABLE IOSSIM_SDK_DIR + OUTPUT_STRIP_TRAILING_WHITESPACE + ) + set(SANITIZER_COMMON_SUPPORTED_DARWIN_OS osx) + if (IOSSIM_SDK_DIR) + list(APPEND SANITIZER_COMMON_SUPPORTED_DARWIN_OS iossim) + endif() + if(COMPILER_RT_USES_LIBCXX) set(SANITIZER_MIN_OSX_VERSION 10.7) else() - set(SANITIZER_MIN_OSX_VERSION 10.5) + set(SANITIZER_MIN_OSX_VERSION 10.6) endif() - list(APPEND SANITIZER_COMMON_CFLAGS - -mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION}) + set(DARWIN_osx_CFLAGS -mmacosx-version-min=${SANITIZER_MIN_OSX_VERSION}) + set(DARWIN_iossim_CFLAGS + -mios-simulator-version-min=7.0 -isysroot ${IOSSIM_SDK_DIR}) + set(DARWIN_osx_LINKFLAGS) + set(DARWIN_iossim_LINKFLAGS + -Wl,-ios_simulator_version_min,7.0.0 + -mios-simulator-version-min=7.0 + -isysroot ${IOSSIM_SDK_DIR}) endif() # Architectures supported by Sanitizer runtimes. Specific sanitizers may # support only subset of these (e.g. TSan works on x86_64 only). filter_available_targets(SANITIZER_COMMON_SUPPORTED_ARCH - x86_64 i386 powerpc64 powerpc) + x86_64 i386 powerpc64) -# Add the public header's directory to the includes for all of compiler-rt. -include_directories(include) add_subdirectory(include) set(SANITIZER_COMMON_LIT_TEST_DEPS clang clang-headers FileCheck count not llvm-nm llvm-symbolizer compiler-rt-headers) +# Check code style when running lit tests for sanitizers. +if(UNIX) + list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS SanitizerLintCheck) +endif() add_subdirectory(lib) diff --git a/SDKs/darwin/usr/include/errno.h b/SDKs/darwin/usr/include/errno.h new file mode 100644 index 000000000000..f06e53713398 --- /dev/null +++ b/SDKs/darwin/usr/include/errno.h @@ -0,0 +1,17 @@ +/* ===-- errno.h - stub SDK header for compiler-rt --------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===-----------------------------------------------------------------------=== + * + * This is a stub SDK header file. This file is not part of the interface of + * this library nor an official version of the appropriate SDK header. It is + * intended only to stub the features of this header required by compiler-rt. + * + * ===-----------------------------------------------------------------------=== + */ + +#include <sys/errno.h> diff --git a/SDKs/darwin/usr/include/string.h b/SDKs/darwin/usr/include/string.h index c7da1f57ba57..c6ab5d8e5876 100644 --- a/SDKs/darwin/usr/include/string.h +++ b/SDKs/darwin/usr/include/string.h @@ -28,4 +28,25 @@ char *strdup(const char *); size_t strlen(const char *); char *strncpy(char *, const char *, size_t); +/* Determine the appropriate strerror() function. */ +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) +# if defined(__i386) +# define __STRERROR_NAME "_strerror$UNIX2003" +# elif defined(__x86_64__) || defined(__arm) +# define __STRERROR_NAME "_strerror" +# else +# error "unrecognized architecture for targetting OS X" +# endif +#elif defined(__ENVIRONMENT_IPHONE_OS_VERSION_MIN_REQUIRED__) +# if defined(__i386) || defined (__x86_64) || defined(__arm) +# define __STRERROR_NAME "_strerror" +# else +# error "unrecognized architecture for targetting iOS" +# endif +#else +# error "unrecognized architecture for targetting Darwin" +#endif + +char *strerror(int) __asm(__STRERROR_NAME); + #endif /* __STRING_H__ */ diff --git a/SDKs/darwin/usr/include/sys/errno.h b/SDKs/darwin/usr/include/sys/errno.h new file mode 100644 index 000000000000..4befe385535a --- /dev/null +++ b/SDKs/darwin/usr/include/sys/errno.h @@ -0,0 +1,31 @@ +/* ===-- errno.h - stub SDK header for compiler-rt --------------------------=== + * + * The LLVM Compiler Infrastructure + * + * This file is dual licensed under the MIT and the University of Illinois Open + * Source Licenses. See LICENSE.TXT for details. + * + * ===-----------------------------------------------------------------------=== + * + * This is a stub SDK header file. This file is not part of the interface of + * this library nor an official version of the appropriate SDK header. It is + * intended only to stub the features of this header required by compiler-rt. + * + * ===-----------------------------------------------------------------------=== + */ + +#ifndef _SYS_ERRNO_H_ +#define _SYS_ERRNO_H_ + +#if defined(__cplusplus) +extern "C" { +#endif + +extern int *__error(void); +#define errno (*__error()) + +#if defined(__cplusplus) +} +#endif + +#endif diff --git a/cmake/Modules/AddCompilerRT.cmake b/cmake/Modules/AddCompilerRT.cmake index bf114a401ef0..fd117ac522ca 100644 --- a/cmake/Modules/AddCompilerRT.cmake +++ b/cmake/Modules/AddCompilerRT.cmake @@ -6,29 +6,35 @@ include(CompilerRTUtils) # with name "<name>.<arch>" if architecture can be targeted. # add_compiler_rt_object_library(<name> <arch> # SOURCES <source files> -# CFLAGS <compile flags>) +# CFLAGS <compile flags> +# DEFS <compile definitions>) macro(add_compiler_rt_object_library name arch) if(CAN_TARGET_${arch}) - parse_arguments(LIB "SOURCES;CFLAGS" "" ${ARGN}) + parse_arguments(LIB "SOURCES;CFLAGS;DEFS" "" ${ARGN}) add_library(${name}.${arch} OBJECT ${LIB_SOURCES}) set_target_compile_flags(${name}.${arch} ${TARGET_${arch}_CFLAGS} ${LIB_CFLAGS}) + set_property(TARGET ${name}.${arch} APPEND PROPERTY + COMPILE_DEFINITIONS ${LIB_DEFS}) else() message(FATAL_ERROR "Archtecture ${arch} can't be targeted") endif() endmacro() -# Same as above, but adds universal osx library with name "<name>.osx" -# targeting multiple architectures. -# add_compiler_rt_osx_object_library(<name> ARCH <architectures> -# SOURCES <source files> -# CFLAGS <compile flags>) -macro(add_compiler_rt_osx_object_library name) - parse_arguments(LIB "ARCH;SOURCES;CFLAGS" "" ${ARGN}) - set(libname "${name}.osx") +# Same as above, but adds universal osx library for either OSX or iOS simulator +# with name "<name>.<os>" targeting multiple architectures. +# add_compiler_rt_darwin_object_library(<name> <os> ARCH <architectures> +# SOURCES <source files> +# CFLAGS <compile flags> +# DEFS <compile definitions>) +macro(add_compiler_rt_darwin_object_library name os) + parse_arguments(LIB "ARCH;SOURCES;CFLAGS;DEFS" "" ${ARGN}) + set(libname "${name}.${os}") add_library(${libname} OBJECT ${LIB_SOURCES}) - set_target_compile_flags(${libname} ${LIB_CFLAGS}) + set_target_compile_flags(${libname} ${LIB_CFLAGS} ${DARWIN_${os}_CFLAGS}) set_target_properties(${libname} PROPERTIES OSX_ARCHITECTURES "${LIB_ARCH}") + set_property(TARGET ${libname} APPEND PROPERTY + COMPILE_DEFINITIONS ${LIB_DEFS}) endmacro() # Adds static runtime for a given architecture and puts it in the proper @@ -36,11 +42,10 @@ endmacro() # add_compiler_rt_static_runtime(<name> <arch> # SOURCES <source files> # CFLAGS <compile flags> -# DEFS <compile definitions> -# SYMS <symbols file>) +# DEFS <compile definitions>) macro(add_compiler_rt_static_runtime name arch) if(CAN_TARGET_${arch}) - parse_arguments(LIB "SOURCES;CFLAGS;DEFS;SYMS" "" ${ARGN}) + parse_arguments(LIB "SOURCES;CFLAGS;DEFS" "" ${ARGN}) add_library(${name} STATIC ${LIB_SOURCES}) # Setup compile flags and definitions. set_target_compile_flags(${name} @@ -53,13 +58,7 @@ macro(add_compiler_rt_static_runtime name arch) # Add installation command. install(TARGETS ${name} ARCHIVE DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}) - # Generate the .syms file if possible. - if(LIB_SYMS) - get_target_property(libfile ${name} LOCATION) - configure_file(${LIB_SYMS} ${libfile}.syms) - install(FILES ${libfile}.syms - DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}) - endif(LIB_SYMS) + add_dependencies(compiler-rt ${name}) else() message(FATAL_ERROR "Archtecture ${arch} can't be targeted") endif() @@ -82,19 +81,22 @@ macro(add_compiler_rt_osx_static_runtime name) ARCHIVE_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR}) install(TARGETS ${name} ARCHIVE DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}) + add_dependencies(compiler-rt ${name}) endmacro() -# Adds dynamic runtime library on osx, which supports multiple architectures. -# add_compiler_rt_osx_dynamic_runtime(<name> ARCH <architectures> -# SOURCES <source files> -# CFLAGS <compile flags> -# DEFS <compile definitions> -# LINKFLAGS <link flags>) -macro(add_compiler_rt_osx_dynamic_runtime name) +# Adds dynamic runtime library on osx/iossim, which supports multiple +# architectures. +# add_compiler_rt_darwin_dynamic_runtime(<name> <os> +# ARCH <architectures> +# SOURCES <source files> +# CFLAGS <compile flags> +# DEFS <compile definitions> +# LINKFLAGS <link flags>) +macro(add_compiler_rt_darwin_dynamic_runtime name os) parse_arguments(LIB "ARCH;SOURCES;CFLAGS;DEFS;LINKFLAGS" "" ${ARGN}) add_library(${name} SHARED ${LIB_SOURCES}) - set_target_compile_flags(${name} ${LIB_CFLAGS}) - set_target_link_flags(${name} ${LIB_LINKFLAGS}) + set_target_compile_flags(${name} ${LIB_CFLAGS} ${DARWIN_${os}_CFLAGS}) + set_target_link_flags(${name} ${LIB_LINKFLAGS} ${DARWIN_${os}_LINKFLAGS}) set_property(TARGET ${name} APPEND PROPERTY COMPILE_DEFINITIONS ${LIB_DEFS}) set_target_properties(${name} PROPERTIES @@ -102,14 +104,16 @@ macro(add_compiler_rt_osx_dynamic_runtime name) LIBRARY_OUTPUT_DIRECTORY ${COMPILER_RT_LIBRARY_OUTPUT_DIR}) install(TARGETS ${name} LIBRARY DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}) + add_dependencies(compiler-rt ${name}) endmacro() # Unittests support. set(COMPILER_RT_GTEST_PATH ${LLVM_MAIN_SRC_DIR}/utils/unittest/googletest) -set(COMPILER_RT_GTEST_SOURCE ${COMPILER_RT_GTEST_PATH}/gtest-all.cc) +set(COMPILER_RT_GTEST_SOURCE ${COMPILER_RT_GTEST_PATH}/src/gtest-all.cc) set(COMPILER_RT_GTEST_INCLUDE_CFLAGS -DGTEST_NO_LLVM_RAW_OSTREAM=1 -I${COMPILER_RT_GTEST_PATH}/include + -I${COMPILER_RT_GTEST_PATH} ) # Use Clang to link objects into a single executable with just-built diff --git a/cmake/Modules/CompilerRTUtils.cmake b/cmake/Modules/CompilerRTUtils.cmake index f9760f40dbd5..fce37e3eb49a 100644 --- a/cmake/Modules/CompilerRTUtils.cmake +++ b/cmake/Modules/CompilerRTUtils.cmake @@ -26,3 +26,13 @@ function(find_flag_in_string flag_string flag out_var) set(${out_var} FALSE PARENT_SCOPE) endif() endfunction() + +# Set the variable var_PYBOOL to True if var holds a true-ish string, +# otherwise set it to False. +macro(pythonize_bool var) + if (${var}) + set(${var}_PYBOOL True) + else() + set(${var}_PYBOOL False) + endif() +endmacro() diff --git a/cmake/Modules/SanitizerUtils.cmake b/cmake/Modules/SanitizerUtils.cmake new file mode 100644 index 000000000000..0836edee2644 --- /dev/null +++ b/cmake/Modules/SanitizerUtils.cmake @@ -0,0 +1,42 @@ +include(LLVMParseArguments) + +set(SANITIZER_GEN_DYNAMIC_LIST + ${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/scripts/gen_dynamic_list.py) + +set(SANITIZER_LINT_SCRIPT + ${COMPILER_RT_SOURCE_DIR}/lib/sanitizer_common/scripts/check_lint.sh) + +# Create a target "<name>-symbols" that would generate the list of symbols +# that need to be exported from sanitizer runtime "<name>". Function +# interceptors are exported automatically, user can also provide files with +# symbol names that should be exported as well. +# add_sanitizer_rt_symbols(<name> <files with extra symbols to export>) +macro(add_sanitizer_rt_symbols name) + get_target_property(libfile ${name} LOCATION) + set(symsfile "${libfile}.syms") + add_custom_command(OUTPUT ${symsfile} + COMMAND ${PYTHON_EXECUTABLE} + ${SANITIZER_GEN_DYNAMIC_LIST} ${libfile} ${ARGN} + > ${symsfile} + DEPENDS ${name} ${SANITIZER_GEN_DYNAMIC_LIST} ${ARGN} + WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR} + COMMENT "Generating exported symbols for ${name}" + VERBATIM) + add_custom_target(${name}-symbols ALL + DEPENDS ${symsfile} + SOURCES ${SANITIZER_GEN_DYNAMIC_LIST} ${ARGN}) + install(FILES ${symsfile} DESTINATION ${COMPILER_RT_LIBRARY_INSTALL_DIR}) + add_dependencies(compiler-rt ${name}-symbols) +endmacro() + +# Add target to check code style for sanitizer runtimes. +if(UNIX) + add_custom_target(SanitizerLintCheck + COMMAND LLVM_CHECKOUT=${LLVM_MAIN_SRC_DIR} SILENT=1 TMPDIR= + PYTHON_EXECUTABLE=${PYTHON_EXECUTABLE} + ${SANITIZER_LINT_SCRIPT} + DEPENDS ${SANITIZER_LINT_SCRIPT} + COMMENT "Running lint check for sanitizer sources..." + VERBATIM) +endif() + diff --git a/include/CMakeLists.txt b/include/CMakeLists.txt index 700b5326b06c..d8a73872ba44 100644 --- a/include/CMakeLists.txt +++ b/include/CMakeLists.txt @@ -1,7 +1,9 @@ set(SANITIZER_HEADERS sanitizer/asan_interface.h sanitizer/common_interface_defs.h + sanitizer/dfsan_interface.h sanitizer/linux_syscall_hooks.h + sanitizer/lsan_interface.h sanitizer/msan_interface.h) set(output_dir ${LLVM_BINARY_DIR}/lib/clang/${CLANG_VERSION}/include) @@ -32,6 +34,7 @@ foreach( f ${SANITIZER_HEADERS} ) endforeach( f ) add_custom_target(compiler-rt-headers ALL DEPENDS ${out_files}) +add_dependencies(compiler-rt compiler-rt-headers) # Install sanitizer headers. install(FILES ${SANITIZER_HEADERS} diff --git a/include/sanitizer/common_interface_defs.h b/include/sanitizer/common_interface_defs.h index 31d0dea5484b..4cc2aeae23cb 100644 --- a/include/sanitizer/common_interface_defs.h +++ b/include/sanitizer/common_interface_defs.h @@ -27,10 +27,6 @@ extern "C" { // Tell the tools to write their reports to "path.<pid>" instead of stderr. void __sanitizer_set_report_path(const char *path); - // Tell the tools to write their reports to given file descriptor instead of - // stderr. - void __sanitizer_set_report_fd(int fd); - // Notify the tools that the sandbox is going to be turned on. The reserved // parameter will be used in the future to hold a structure with functions // that the tools may call to bypass the sandbox. @@ -51,6 +47,33 @@ extern "C" { void __sanitizer_unaligned_store32(void *p, uint32_t x); void __sanitizer_unaligned_store64(void *p, uint64_t x); + // Record and dump coverage info. + void __sanitizer_cov_dump(); + + // Annotate the current state of a contiguous container, such as + // std::vector, std::string or similar. + // A contiguous container is a container that keeps all of its elements + // in a contiguous region of memory. The container owns the region of memory + // [beg, end); the memory [beg, mid) is used to store the current elements + // and the memory [mid, end) is reserved for future elements; + // end <= mid <= end. For example, in "std::vector<> v" + // beg = &v[0]; + // end = beg + v.capacity() * sizeof(v[0]); + // mid = beg + v.size() * sizeof(v[0]); + // + // This annotation tells the Sanitizer tool about the current state of the + // container so that the tool can report errors when memory from [mid, end) + // is accessed. Insert this annotation into methods like push_back/pop_back. + // Supply the old and the new values of mid (old_mid/new_mid). + // In the initial state mid == end and so should be the final + // state when the container is destroyed or when it reallocates the storage. + // + // Use with caution and don't use for anything other than vector-like classes. + // + // For AddressSanitizer, 'beg' should be 8-aligned. + void __sanitizer_annotate_contiguous_container(void *beg, void *end, + void *old_mid, void *new_mid); + #ifdef __cplusplus } // extern "C" #endif diff --git a/include/sanitizer/dfsan_interface.h b/include/sanitizer/dfsan_interface.h new file mode 100644 index 000000000000..f14d45a2b2a1 --- /dev/null +++ b/include/sanitizer/dfsan_interface.h @@ -0,0 +1,87 @@ +//===-- dfsan_interface.h -------------------------------------------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of DataFlowSanitizer. +// +// Public interface header. +//===----------------------------------------------------------------------===// +#ifndef DFSAN_INTERFACE_H +#define DFSAN_INTERFACE_H + +#include <stddef.h> +#include <stdint.h> +#include <sanitizer/common_interface_defs.h> + +#ifdef __cplusplus +extern "C" { +#endif + +typedef uint16_t dfsan_label; + +/// Stores information associated with a specific label identifier. A label +/// may be a base label created using dfsan_create_label, with associated +/// text description and user data, or an automatically created union label, +/// which represents the union of two label identifiers (which may themselves +/// be base or union labels). +struct dfsan_label_info { + // Fields for union labels, set to 0 for base labels. + dfsan_label l1; + dfsan_label l2; + + // Fields for base labels. + const char *desc; + void *userdata; +}; + +/// Computes the union of \c l1 and \c l2, possibly creating a union label in +/// the process. +dfsan_label dfsan_union(dfsan_label l1, dfsan_label l2); + +/// Creates and returns a base label with the given description and user data. +dfsan_label dfsan_create_label(const char *desc, void *userdata); + +/// Sets the label for each address in [addr,addr+size) to \c label. +void dfsan_set_label(dfsan_label label, void *addr, size_t size); + +/// Sets the label for each address in [addr,addr+size) to the union of the +/// current label for that address and \c label. +void dfsan_add_label(dfsan_label label, void *addr, size_t size); + +/// Retrieves the label associated with the given data. +/// +/// The type of 'data' is arbitrary. The function accepts a value of any type, +/// which can be truncated or extended (implicitly or explicitly) as necessary. +/// The truncation/extension operations will preserve the label of the original +/// value. +dfsan_label dfsan_get_label(long data); + +/// Retrieves the label associated with the data at the given address. +dfsan_label dfsan_read_label(const void *addr, size_t size); + +/// Retrieves a pointer to the dfsan_label_info struct for the given label. +const struct dfsan_label_info *dfsan_get_label_info(dfsan_label label); + +/// Returns whether the given label label contains the label elem. +int dfsan_has_label(dfsan_label label, dfsan_label elem); + +/// If the given label label contains a label with the description desc, returns +/// that label, else returns 0. +dfsan_label dfsan_has_label_with_desc(dfsan_label label, const char *desc); + +#ifdef __cplusplus +} // extern "C" + +template <typename T> +void dfsan_set_label(dfsan_label label, T &data) { // NOLINT + dfsan_set_label(label, (void *)&data, sizeof(T)); +} + +#endif + +#endif // DFSAN_INTERFACE_H diff --git a/include/sanitizer/linux_syscall_hooks.h b/include/sanitizer/linux_syscall_hooks.h index 894d5c2bebff..89867c15190a 100644 --- a/include/sanitizer/linux_syscall_hooks.h +++ b/include/sanitizer/linux_syscall_hooks.h @@ -15,788 +15,3056 @@ // actions for the active sanitizer. // Usage: // __sanitizer_syscall_pre_getfoo(...args...); -// int res = syscall(__NR_getfoo, ...args...); +// long res = syscall(__NR_getfoo, ...args...); // __sanitizer_syscall_post_getfoo(res, ...args...); //===----------------------------------------------------------------------===// #ifndef SANITIZER_LINUX_SYSCALL_HOOKS_H #define SANITIZER_LINUX_SYSCALL_HOOKS_H -#ifdef __cplusplus -extern "C" { -#endif +#define __sanitizer_syscall_pre_time(tloc) \ + __sanitizer_syscall_pre_impl_time((long)(tloc)) +#define __sanitizer_syscall_post_time(res, tloc) \ + __sanitizer_syscall_post_impl_time(res, (long)(tloc)) +#define __sanitizer_syscall_pre_stime(tptr) \ + __sanitizer_syscall_pre_impl_stime((long)(tptr)) +#define __sanitizer_syscall_post_stime(res, tptr) \ + __sanitizer_syscall_post_impl_stime(res, (long)(tptr)) +#define __sanitizer_syscall_pre_gettimeofday(tv, tz) \ + __sanitizer_syscall_pre_impl_gettimeofday((long)(tv), (long)(tz)) +#define __sanitizer_syscall_post_gettimeofday(res, tv, tz) \ + __sanitizer_syscall_post_impl_gettimeofday(res, (long)(tv), (long)(tz)) +#define __sanitizer_syscall_pre_settimeofday(tv, tz) \ + __sanitizer_syscall_pre_impl_settimeofday((long)(tv), (long)(tz)) +#define __sanitizer_syscall_post_settimeofday(res, tv, tz) \ + __sanitizer_syscall_post_impl_settimeofday(res, (long)(tv), (long)(tz)) +#define __sanitizer_syscall_pre_adjtimex(txc_p) \ + __sanitizer_syscall_pre_impl_adjtimex((long)(txc_p)) +#define __sanitizer_syscall_post_adjtimex(res, txc_p) \ + __sanitizer_syscall_post_impl_adjtimex(res, (long)(txc_p)) +#define __sanitizer_syscall_pre_times(tbuf) \ + __sanitizer_syscall_pre_impl_times((long)(tbuf)) +#define __sanitizer_syscall_post_times(res, tbuf) \ + __sanitizer_syscall_post_impl_times(res, (long)(tbuf)) +#define __sanitizer_syscall_pre_gettid() __sanitizer_syscall_pre_impl_gettid() +#define __sanitizer_syscall_post_gettid(res) \ + __sanitizer_syscall_post_impl_gettid(res) +#define __sanitizer_syscall_pre_nanosleep(rqtp, rmtp) \ + __sanitizer_syscall_pre_impl_nanosleep((long)(rqtp), (long)(rmtp)) +#define __sanitizer_syscall_post_nanosleep(res, rqtp, rmtp) \ + __sanitizer_syscall_post_impl_nanosleep(res, (long)(rqtp), (long)(rmtp)) +#define __sanitizer_syscall_pre_alarm(seconds) \ + __sanitizer_syscall_pre_impl_alarm((long)(seconds)) +#define __sanitizer_syscall_post_alarm(res, seconds) \ + __sanitizer_syscall_post_impl_alarm(res, (long)(seconds)) +#define __sanitizer_syscall_pre_getpid() __sanitizer_syscall_pre_impl_getpid() +#define __sanitizer_syscall_post_getpid(res) \ + __sanitizer_syscall_post_impl_getpid(res) +#define __sanitizer_syscall_pre_getppid() __sanitizer_syscall_pre_impl_getppid() +#define __sanitizer_syscall_post_getppid(res) \ + __sanitizer_syscall_post_impl_getppid(res) +#define __sanitizer_syscall_pre_getuid() __sanitizer_syscall_pre_impl_getuid() +#define __sanitizer_syscall_post_getuid(res) \ + __sanitizer_syscall_post_impl_getuid(res) +#define __sanitizer_syscall_pre_geteuid() __sanitizer_syscall_pre_impl_geteuid() +#define __sanitizer_syscall_post_geteuid(res) \ + __sanitizer_syscall_post_impl_geteuid(res) +#define __sanitizer_syscall_pre_getgid() __sanitizer_syscall_pre_impl_getgid() +#define __sanitizer_syscall_post_getgid(res) \ + __sanitizer_syscall_post_impl_getgid(res) +#define __sanitizer_syscall_pre_getegid() __sanitizer_syscall_pre_impl_getegid() +#define __sanitizer_syscall_post_getegid(res) \ + __sanitizer_syscall_post_impl_getegid(res) +#define __sanitizer_syscall_pre_getresuid(ruid, euid, suid) \ + __sanitizer_syscall_pre_impl_getresuid((long)(ruid), (long)(euid), \ + (long)(suid)) +#define __sanitizer_syscall_post_getresuid(res, ruid, euid, suid) \ + __sanitizer_syscall_post_impl_getresuid(res, (long)(ruid), (long)(euid), \ + (long)(suid)) +#define __sanitizer_syscall_pre_getresgid(rgid, egid, sgid) \ + __sanitizer_syscall_pre_impl_getresgid((long)(rgid), (long)(egid), \ + (long)(sgid)) +#define __sanitizer_syscall_post_getresgid(res, rgid, egid, sgid) \ + __sanitizer_syscall_post_impl_getresgid(res, (long)(rgid), (long)(egid), \ + (long)(sgid)) +#define __sanitizer_syscall_pre_getpgid(pid) \ + __sanitizer_syscall_pre_impl_getpgid((long)(pid)) +#define __sanitizer_syscall_post_getpgid(res, pid) \ + __sanitizer_syscall_post_impl_getpgid(res, (long)(pid)) +#define __sanitizer_syscall_pre_getpgrp() __sanitizer_syscall_pre_impl_getpgrp() +#define __sanitizer_syscall_post_getpgrp(res) \ + __sanitizer_syscall_post_impl_getpgrp(res) +#define __sanitizer_syscall_pre_getsid(pid) \ + __sanitizer_syscall_pre_impl_getsid((long)(pid)) +#define __sanitizer_syscall_post_getsid(res, pid) \ + __sanitizer_syscall_post_impl_getsid(res, (long)(pid)) +#define __sanitizer_syscall_pre_getgroups(gidsetsize, grouplist) \ + __sanitizer_syscall_pre_impl_getgroups((long)(gidsetsize), (long)(grouplist)) +#define __sanitizer_syscall_post_getgroups(res, gidsetsize, grouplist) \ + __sanitizer_syscall_post_impl_getgroups(res, (long)(gidsetsize), \ + (long)(grouplist)) +#define __sanitizer_syscall_pre_setregid(rgid, egid) \ + __sanitizer_syscall_pre_impl_setregid((long)(rgid), (long)(egid)) +#define __sanitizer_syscall_post_setregid(res, rgid, egid) \ + __sanitizer_syscall_post_impl_setregid(res, (long)(rgid), (long)(egid)) +#define __sanitizer_syscall_pre_setgid(gid) \ + __sanitizer_syscall_pre_impl_setgid((long)(gid)) +#define __sanitizer_syscall_post_setgid(res, gid) \ + __sanitizer_syscall_post_impl_setgid(res, (long)(gid)) +#define __sanitizer_syscall_pre_setreuid(ruid, euid) \ + __sanitizer_syscall_pre_impl_setreuid((long)(ruid), (long)(euid)) +#define __sanitizer_syscall_post_setreuid(res, ruid, euid) \ + __sanitizer_syscall_post_impl_setreuid(res, (long)(ruid), (long)(euid)) +#define __sanitizer_syscall_pre_setuid(uid) \ + __sanitizer_syscall_pre_impl_setuid((long)(uid)) +#define __sanitizer_syscall_post_setuid(res, uid) \ + __sanitizer_syscall_post_impl_setuid(res, (long)(uid)) +#define __sanitizer_syscall_pre_setresuid(ruid, euid, suid) \ + __sanitizer_syscall_pre_impl_setresuid((long)(ruid), (long)(euid), \ + (long)(suid)) +#define __sanitizer_syscall_post_setresuid(res, ruid, euid, suid) \ + __sanitizer_syscall_post_impl_setresuid(res, (long)(ruid), (long)(euid), \ + (long)(suid)) +#define __sanitizer_syscall_pre_setresgid(rgid, egid, sgid) \ + __sanitizer_syscall_pre_impl_setresgid((long)(rgid), (long)(egid), \ + (long)(sgid)) +#define __sanitizer_syscall_post_setresgid(res, rgid, egid, sgid) \ + __sanitizer_syscall_post_impl_setresgid(res, (long)(rgid), (long)(egid), \ + (long)(sgid)) +#define __sanitizer_syscall_pre_setfsuid(uid) \ + __sanitizer_syscall_pre_impl_setfsuid((long)(uid)) +#define __sanitizer_syscall_post_setfsuid(res, uid) \ + __sanitizer_syscall_post_impl_setfsuid(res, (long)(uid)) +#define __sanitizer_syscall_pre_setfsgid(gid) \ + __sanitizer_syscall_pre_impl_setfsgid((long)(gid)) +#define __sanitizer_syscall_post_setfsgid(res, gid) \ + __sanitizer_syscall_post_impl_setfsgid(res, (long)(gid)) +#define __sanitizer_syscall_pre_setpgid(pid, pgid) \ + __sanitizer_syscall_pre_impl_setpgid((long)(pid), (long)(pgid)) +#define __sanitizer_syscall_post_setpgid(res, pid, pgid) \ + __sanitizer_syscall_post_impl_setpgid(res, (long)(pid), (long)(pgid)) +#define __sanitizer_syscall_pre_setsid() __sanitizer_syscall_pre_impl_setsid() +#define __sanitizer_syscall_post_setsid(res) \ + __sanitizer_syscall_post_impl_setsid(res) +#define __sanitizer_syscall_pre_setgroups(gidsetsize, grouplist) \ + __sanitizer_syscall_pre_impl_setgroups((long)(gidsetsize), (long)(grouplist)) +#define __sanitizer_syscall_post_setgroups(res, gidsetsize, grouplist) \ + __sanitizer_syscall_post_impl_setgroups(res, (long)(gidsetsize), \ + (long)(grouplist)) +#define __sanitizer_syscall_pre_acct(name) \ + __sanitizer_syscall_pre_impl_acct((long)(name)) +#define __sanitizer_syscall_post_acct(res, name) \ + __sanitizer_syscall_post_impl_acct(res, (long)(name)) +#define __sanitizer_syscall_pre_capget(header, dataptr) \ + __sanitizer_syscall_pre_impl_capget((long)(header), (long)(dataptr)) +#define __sanitizer_syscall_post_capget(res, header, dataptr) \ + __sanitizer_syscall_post_impl_capget(res, (long)(header), (long)(dataptr)) +#define __sanitizer_syscall_pre_capset(header, data) \ + __sanitizer_syscall_pre_impl_capset((long)(header), (long)(data)) +#define __sanitizer_syscall_post_capset(res, header, data) \ + __sanitizer_syscall_post_impl_capset(res, (long)(header), (long)(data)) +#define __sanitizer_syscall_pre_personality(personality) \ + __sanitizer_syscall_pre_impl_personality((long)(personality)) +#define __sanitizer_syscall_post_personality(res, personality) \ + __sanitizer_syscall_post_impl_personality(res, (long)(personality)) +#define __sanitizer_syscall_pre_sigpending(set) \ + __sanitizer_syscall_pre_impl_sigpending((long)(set)) +#define __sanitizer_syscall_post_sigpending(res, set) \ + __sanitizer_syscall_post_impl_sigpending(res, (long)(set)) +#define __sanitizer_syscall_pre_sigprocmask(how, set, oset) \ + __sanitizer_syscall_pre_impl_sigprocmask((long)(how), (long)(set), \ + (long)(oset)) +#define __sanitizer_syscall_post_sigprocmask(res, how, set, oset) \ + __sanitizer_syscall_post_impl_sigprocmask(res, (long)(how), (long)(set), \ + (long)(oset)) +#define __sanitizer_syscall_pre_getitimer(which, value) \ + __sanitizer_syscall_pre_impl_getitimer((long)(which), (long)(value)) +#define __sanitizer_syscall_post_getitimer(res, which, value) \ + __sanitizer_syscall_post_impl_getitimer(res, (long)(which), (long)(value)) +#define __sanitizer_syscall_pre_setitimer(which, value, ovalue) \ + __sanitizer_syscall_pre_impl_setitimer((long)(which), (long)(value), \ + (long)(ovalue)) +#define __sanitizer_syscall_post_setitimer(res, which, value, ovalue) \ + __sanitizer_syscall_post_impl_setitimer(res, (long)(which), (long)(value), \ + (long)(ovalue)) +#define __sanitizer_syscall_pre_timer_create(which_clock, timer_event_spec, \ + created_timer_id) \ + __sanitizer_syscall_pre_impl_timer_create( \ + (long)(which_clock), (long)(timer_event_spec), (long)(created_timer_id)) +#define __sanitizer_syscall_post_timer_create( \ + res, which_clock, timer_event_spec, created_timer_id) \ + __sanitizer_syscall_post_impl_timer_create(res, (long)(which_clock), \ + (long)(timer_event_spec), \ + (long)(created_timer_id)) +#define __sanitizer_syscall_pre_timer_gettime(timer_id, setting) \ + __sanitizer_syscall_pre_impl_timer_gettime((long)(timer_id), (long)(setting)) +#define __sanitizer_syscall_post_timer_gettime(res, timer_id, setting) \ + __sanitizer_syscall_post_impl_timer_gettime(res, (long)(timer_id), \ + (long)(setting)) +#define __sanitizer_syscall_pre_timer_getoverrun(timer_id) \ + __sanitizer_syscall_pre_impl_timer_getoverrun((long)(timer_id)) +#define __sanitizer_syscall_post_timer_getoverrun(res, timer_id) \ + __sanitizer_syscall_post_impl_timer_getoverrun(res, (long)(timer_id)) +#define __sanitizer_syscall_pre_timer_settime(timer_id, flags, new_setting, \ + old_setting) \ + __sanitizer_syscall_pre_impl_timer_settime((long)(timer_id), (long)(flags), \ + (long)(new_setting), \ + (long)(old_setting)) +#define __sanitizer_syscall_post_timer_settime(res, timer_id, flags, \ + new_setting, old_setting) \ + __sanitizer_syscall_post_impl_timer_settime( \ + res, (long)(timer_id), (long)(flags), (long)(new_setting), \ + (long)(old_setting)) +#define __sanitizer_syscall_pre_timer_delete(timer_id) \ + __sanitizer_syscall_pre_impl_timer_delete((long)(timer_id)) +#define __sanitizer_syscall_post_timer_delete(res, timer_id) \ + __sanitizer_syscall_post_impl_timer_delete(res, (long)(timer_id)) +#define __sanitizer_syscall_pre_clock_settime(which_clock, tp) \ + __sanitizer_syscall_pre_impl_clock_settime((long)(which_clock), (long)(tp)) +#define __sanitizer_syscall_post_clock_settime(res, which_clock, tp) \ + __sanitizer_syscall_post_impl_clock_settime(res, (long)(which_clock), \ + (long)(tp)) +#define __sanitizer_syscall_pre_clock_gettime(which_clock, tp) \ + __sanitizer_syscall_pre_impl_clock_gettime((long)(which_clock), (long)(tp)) +#define __sanitizer_syscall_post_clock_gettime(res, which_clock, tp) \ + __sanitizer_syscall_post_impl_clock_gettime(res, (long)(which_clock), \ + (long)(tp)) +#define __sanitizer_syscall_pre_clock_adjtime(which_clock, tx) \ + __sanitizer_syscall_pre_impl_clock_adjtime((long)(which_clock), (long)(tx)) +#define __sanitizer_syscall_post_clock_adjtime(res, which_clock, tx) \ + __sanitizer_syscall_post_impl_clock_adjtime(res, (long)(which_clock), \ + (long)(tx)) +#define __sanitizer_syscall_pre_clock_getres(which_clock, tp) \ + __sanitizer_syscall_pre_impl_clock_getres((long)(which_clock), (long)(tp)) +#define __sanitizer_syscall_post_clock_getres(res, which_clock, tp) \ + __sanitizer_syscall_post_impl_clock_getres(res, (long)(which_clock), \ + (long)(tp)) +#define __sanitizer_syscall_pre_clock_nanosleep(which_clock, flags, rqtp, \ + rmtp) \ + __sanitizer_syscall_pre_impl_clock_nanosleep( \ + (long)(which_clock), (long)(flags), (long)(rqtp), (long)(rmtp)) +#define __sanitizer_syscall_post_clock_nanosleep(res, which_clock, flags, \ + rqtp, rmtp) \ + __sanitizer_syscall_post_impl_clock_nanosleep( \ + res, (long)(which_clock), (long)(flags), (long)(rqtp), (long)(rmtp)) +#define __sanitizer_syscall_pre_nice(increment) \ + __sanitizer_syscall_pre_impl_nice((long)(increment)) +#define __sanitizer_syscall_post_nice(res, increment) \ + __sanitizer_syscall_post_impl_nice(res, (long)(increment)) +#define __sanitizer_syscall_pre_sched_setscheduler(pid, policy, param) \ + __sanitizer_syscall_pre_impl_sched_setscheduler((long)(pid), (long)(policy), \ + (long)(param)) +#define __sanitizer_syscall_post_sched_setscheduler(res, pid, policy, param) \ + __sanitizer_syscall_post_impl_sched_setscheduler( \ + res, (long)(pid), (long)(policy), (long)(param)) +#define __sanitizer_syscall_pre_sched_setparam(pid, param) \ + __sanitizer_syscall_pre_impl_sched_setparam((long)(pid), (long)(param)) +#define __sanitizer_syscall_post_sched_setparam(res, pid, param) \ + __sanitizer_syscall_post_impl_sched_setparam(res, (long)(pid), (long)(param)) +#define __sanitizer_syscall_pre_sched_getscheduler(pid) \ + __sanitizer_syscall_pre_impl_sched_getscheduler((long)(pid)) +#define __sanitizer_syscall_post_sched_getscheduler(res, pid) \ + __sanitizer_syscall_post_impl_sched_getscheduler(res, (long)(pid)) +#define __sanitizer_syscall_pre_sched_getparam(pid, param) \ + __sanitizer_syscall_pre_impl_sched_getparam((long)(pid), (long)(param)) +#define __sanitizer_syscall_post_sched_getparam(res, pid, param) \ + __sanitizer_syscall_post_impl_sched_getparam(res, (long)(pid), (long)(param)) +#define __sanitizer_syscall_pre_sched_setaffinity(pid, len, user_mask_ptr) \ + __sanitizer_syscall_pre_impl_sched_setaffinity((long)(pid), (long)(len), \ + (long)(user_mask_ptr)) +#define __sanitizer_syscall_post_sched_setaffinity(res, pid, len, \ + user_mask_ptr) \ + __sanitizer_syscall_post_impl_sched_setaffinity( \ + res, (long)(pid), (long)(len), (long)(user_mask_ptr)) +#define __sanitizer_syscall_pre_sched_getaffinity(pid, len, user_mask_ptr) \ + __sanitizer_syscall_pre_impl_sched_getaffinity((long)(pid), (long)(len), \ + (long)(user_mask_ptr)) +#define __sanitizer_syscall_post_sched_getaffinity(res, pid, len, \ + user_mask_ptr) \ + __sanitizer_syscall_post_impl_sched_getaffinity( \ + res, (long)(pid), (long)(len), (long)(user_mask_ptr)) +#define __sanitizer_syscall_pre_sched_yield() \ + __sanitizer_syscall_pre_impl_sched_yield() +#define __sanitizer_syscall_post_sched_yield(res) \ + __sanitizer_syscall_post_impl_sched_yield(res) +#define __sanitizer_syscall_pre_sched_get_priority_max(policy) \ + __sanitizer_syscall_pre_impl_sched_get_priority_max((long)(policy)) +#define __sanitizer_syscall_post_sched_get_priority_max(res, policy) \ + __sanitizer_syscall_post_impl_sched_get_priority_max(res, (long)(policy)) +#define __sanitizer_syscall_pre_sched_get_priority_min(policy) \ + __sanitizer_syscall_pre_impl_sched_get_priority_min((long)(policy)) +#define __sanitizer_syscall_post_sched_get_priority_min(res, policy) \ + __sanitizer_syscall_post_impl_sched_get_priority_min(res, (long)(policy)) +#define __sanitizer_syscall_pre_sched_rr_get_interval(pid, interval) \ + __sanitizer_syscall_pre_impl_sched_rr_get_interval((long)(pid), \ + (long)(interval)) +#define __sanitizer_syscall_post_sched_rr_get_interval(res, pid, interval) \ + __sanitizer_syscall_post_impl_sched_rr_get_interval(res, (long)(pid), \ + (long)(interval)) +#define __sanitizer_syscall_pre_setpriority(which, who, niceval) \ + __sanitizer_syscall_pre_impl_setpriority((long)(which), (long)(who), \ + (long)(niceval)) +#define __sanitizer_syscall_post_setpriority(res, which, who, niceval) \ + __sanitizer_syscall_post_impl_setpriority(res, (long)(which), (long)(who), \ + (long)(niceval)) +#define __sanitizer_syscall_pre_getpriority(which, who) \ + __sanitizer_syscall_pre_impl_getpriority((long)(which), (long)(who)) +#define __sanitizer_syscall_post_getpriority(res, which, who) \ + __sanitizer_syscall_post_impl_getpriority(res, (long)(which), (long)(who)) +#define __sanitizer_syscall_pre_shutdown(arg0, arg1) \ + __sanitizer_syscall_pre_impl_shutdown((long)(arg0), (long)(arg1)) +#define __sanitizer_syscall_post_shutdown(res, arg0, arg1) \ + __sanitizer_syscall_post_impl_shutdown(res, (long)(arg0), (long)(arg1)) +#define __sanitizer_syscall_pre_reboot(magic1, magic2, cmd, arg) \ + __sanitizer_syscall_pre_impl_reboot((long)(magic1), (long)(magic2), \ + (long)(cmd), (long)(arg)) +#define __sanitizer_syscall_post_reboot(res, magic1, magic2, cmd, arg) \ + __sanitizer_syscall_post_impl_reboot(res, (long)(magic1), (long)(magic2), \ + (long)(cmd), (long)(arg)) +#define __sanitizer_syscall_pre_restart_syscall() \ + __sanitizer_syscall_pre_impl_restart_syscall() +#define __sanitizer_syscall_post_restart_syscall(res) \ + __sanitizer_syscall_post_impl_restart_syscall(res) +#define __sanitizer_syscall_pre_kexec_load(entry, nr_segments, segments, \ + flags) \ + __sanitizer_syscall_pre_impl_kexec_load((long)(entry), (long)(nr_segments), \ + (long)(segments), (long)(flags)) +#define __sanitizer_syscall_post_kexec_load(res, entry, nr_segments, segments, \ + flags) \ + __sanitizer_syscall_post_impl_kexec_load(res, (long)(entry), \ + (long)(nr_segments), \ + (long)(segments), (long)(flags)) +#define __sanitizer_syscall_pre_exit(error_code) \ + __sanitizer_syscall_pre_impl_exit((long)(error_code)) +#define __sanitizer_syscall_post_exit(res, error_code) \ + __sanitizer_syscall_post_impl_exit(res, (long)(error_code)) +#define __sanitizer_syscall_pre_exit_group(error_code) \ + __sanitizer_syscall_pre_impl_exit_group((long)(error_code)) +#define __sanitizer_syscall_post_exit_group(res, error_code) \ + __sanitizer_syscall_post_impl_exit_group(res, (long)(error_code)) +#define __sanitizer_syscall_pre_wait4(pid, stat_addr, options, ru) \ + __sanitizer_syscall_pre_impl_wait4((long)(pid), (long)(stat_addr), \ + (long)(options), (long)(ru)) +#define __sanitizer_syscall_post_wait4(res, pid, stat_addr, options, ru) \ + __sanitizer_syscall_post_impl_wait4(res, (long)(pid), (long)(stat_addr), \ + (long)(options), (long)(ru)) +#define __sanitizer_syscall_pre_waitid(which, pid, infop, options, ru) \ + __sanitizer_syscall_pre_impl_waitid( \ + (long)(which), (long)(pid), (long)(infop), (long)(options), (long)(ru)) +#define __sanitizer_syscall_post_waitid(res, which, pid, infop, options, ru) \ + __sanitizer_syscall_post_impl_waitid(res, (long)(which), (long)(pid), \ + (long)(infop), (long)(options), \ + (long)(ru)) +#define __sanitizer_syscall_pre_waitpid(pid, stat_addr, options) \ + __sanitizer_syscall_pre_impl_waitpid((long)(pid), (long)(stat_addr), \ + (long)(options)) +#define __sanitizer_syscall_post_waitpid(res, pid, stat_addr, options) \ + __sanitizer_syscall_post_impl_waitpid(res, (long)(pid), (long)(stat_addr), \ + (long)(options)) +#define __sanitizer_syscall_pre_set_tid_address(tidptr) \ + __sanitizer_syscall_pre_impl_set_tid_address((long)(tidptr)) +#define __sanitizer_syscall_post_set_tid_address(res, tidptr) \ + __sanitizer_syscall_post_impl_set_tid_address(res, (long)(tidptr)) +#define __sanitizer_syscall_pre_init_module(umod, len, uargs) \ + __sanitizer_syscall_pre_impl_init_module((long)(umod), (long)(len), \ + (long)(uargs)) +#define __sanitizer_syscall_post_init_module(res, umod, len, uargs) \ + __sanitizer_syscall_post_impl_init_module(res, (long)(umod), (long)(len), \ + (long)(uargs)) +#define __sanitizer_syscall_pre_delete_module(name_user, flags) \ + __sanitizer_syscall_pre_impl_delete_module((long)(name_user), (long)(flags)) +#define __sanitizer_syscall_post_delete_module(res, name_user, flags) \ + __sanitizer_syscall_post_impl_delete_module(res, (long)(name_user), \ + (long)(flags)) +#define __sanitizer_syscall_pre_rt_sigprocmask(how, set, oset, sigsetsize) \ + __sanitizer_syscall_pre_impl_rt_sigprocmask( \ + (long)(how), (long)(set), (long)(oset), (long)(sigsetsize)) +#define __sanitizer_syscall_post_rt_sigprocmask(res, how, set, oset, \ + sigsetsize) \ + __sanitizer_syscall_post_impl_rt_sigprocmask( \ + res, (long)(how), (long)(set), (long)(oset), (long)(sigsetsize)) +#define __sanitizer_syscall_pre_rt_sigpending(set, sigsetsize) \ + __sanitizer_syscall_pre_impl_rt_sigpending((long)(set), (long)(sigsetsize)) +#define __sanitizer_syscall_post_rt_sigpending(res, set, sigsetsize) \ + __sanitizer_syscall_post_impl_rt_sigpending(res, (long)(set), \ + (long)(sigsetsize)) +#define __sanitizer_syscall_pre_rt_sigtimedwait(uthese, uinfo, uts, \ + sigsetsize) \ + __sanitizer_syscall_pre_impl_rt_sigtimedwait( \ + (long)(uthese), (long)(uinfo), (long)(uts), (long)(sigsetsize)) +#define __sanitizer_syscall_post_rt_sigtimedwait(res, uthese, uinfo, uts, \ + sigsetsize) \ + __sanitizer_syscall_post_impl_rt_sigtimedwait( \ + res, (long)(uthese), (long)(uinfo), (long)(uts), (long)(sigsetsize)) +#define __sanitizer_syscall_pre_rt_tgsigqueueinfo(tgid, pid, sig, uinfo) \ + __sanitizer_syscall_pre_impl_rt_tgsigqueueinfo((long)(tgid), (long)(pid), \ + (long)(sig), (long)(uinfo)) +#define __sanitizer_syscall_post_rt_tgsigqueueinfo(res, tgid, pid, sig, uinfo) \ + __sanitizer_syscall_post_impl_rt_tgsigqueueinfo( \ + res, (long)(tgid), (long)(pid), (long)(sig), (long)(uinfo)) +#define __sanitizer_syscall_pre_kill(pid, sig) \ + __sanitizer_syscall_pre_impl_kill((long)(pid), (long)(sig)) +#define __sanitizer_syscall_post_kill(res, pid, sig) \ + __sanitizer_syscall_post_impl_kill(res, (long)(pid), (long)(sig)) +#define __sanitizer_syscall_pre_tgkill(tgid, pid, sig) \ + __sanitizer_syscall_pre_impl_tgkill((long)(tgid), (long)(pid), (long)(sig)) +#define __sanitizer_syscall_post_tgkill(res, tgid, pid, sig) \ + __sanitizer_syscall_post_impl_tgkill(res, (long)(tgid), (long)(pid), \ + (long)(sig)) +#define __sanitizer_syscall_pre_tkill(pid, sig) \ + __sanitizer_syscall_pre_impl_tkill((long)(pid), (long)(sig)) +#define __sanitizer_syscall_post_tkill(res, pid, sig) \ + __sanitizer_syscall_post_impl_tkill(res, (long)(pid), (long)(sig)) +#define __sanitizer_syscall_pre_rt_sigqueueinfo(pid, sig, uinfo) \ + __sanitizer_syscall_pre_impl_rt_sigqueueinfo((long)(pid), (long)(sig), \ + (long)(uinfo)) +#define __sanitizer_syscall_post_rt_sigqueueinfo(res, pid, sig, uinfo) \ + __sanitizer_syscall_post_impl_rt_sigqueueinfo(res, (long)(pid), (long)(sig), \ + (long)(uinfo)) +#define __sanitizer_syscall_pre_sgetmask() \ + __sanitizer_syscall_pre_impl_sgetmask() +#define __sanitizer_syscall_post_sgetmask(res) \ + __sanitizer_syscall_post_impl_sgetmask(res) +#define __sanitizer_syscall_pre_ssetmask(newmask) \ + __sanitizer_syscall_pre_impl_ssetmask((long)(newmask)) +#define __sanitizer_syscall_post_ssetmask(res, newmask) \ + __sanitizer_syscall_post_impl_ssetmask(res, (long)(newmask)) +#define __sanitizer_syscall_pre_signal(sig, handler) \ + __sanitizer_syscall_pre_impl_signal((long)(sig), (long)(handler)) +#define __sanitizer_syscall_post_signal(res, sig, handler) \ + __sanitizer_syscall_post_impl_signal(res, (long)(sig), (long)(handler)) +#define __sanitizer_syscall_pre_pause() __sanitizer_syscall_pre_impl_pause() +#define __sanitizer_syscall_post_pause(res) \ + __sanitizer_syscall_post_impl_pause(res) +#define __sanitizer_syscall_pre_sync() __sanitizer_syscall_pre_impl_sync() +#define __sanitizer_syscall_post_sync(res) \ + __sanitizer_syscall_post_impl_sync(res) +#define __sanitizer_syscall_pre_fsync(fd) \ + __sanitizer_syscall_pre_impl_fsync((long)(fd)) +#define __sanitizer_syscall_post_fsync(res, fd) \ + __sanitizer_syscall_post_impl_fsync(res, (long)(fd)) +#define __sanitizer_syscall_pre_fdatasync(fd) \ + __sanitizer_syscall_pre_impl_fdatasync((long)(fd)) +#define __sanitizer_syscall_post_fdatasync(res, fd) \ + __sanitizer_syscall_post_impl_fdatasync(res, (long)(fd)) +#define __sanitizer_syscall_pre_bdflush(func, data) \ + __sanitizer_syscall_pre_impl_bdflush((long)(func), (long)(data)) +#define __sanitizer_syscall_post_bdflush(res, func, data) \ + __sanitizer_syscall_post_impl_bdflush(res, (long)(func), (long)(data)) +#define __sanitizer_syscall_pre_mount(dev_name, dir_name, type, flags, data) \ + __sanitizer_syscall_pre_impl_mount((long)(dev_name), (long)(dir_name), \ + (long)(type), (long)(flags), \ + (long)(data)) +#define __sanitizer_syscall_post_mount(res, dev_name, dir_name, type, flags, \ + data) \ + __sanitizer_syscall_post_impl_mount(res, (long)(dev_name), (long)(dir_name), \ + (long)(type), (long)(flags), \ + (long)(data)) +#define __sanitizer_syscall_pre_umount(name, flags) \ + __sanitizer_syscall_pre_impl_umount((long)(name), (long)(flags)) +#define __sanitizer_syscall_post_umount(res, name, flags) \ + __sanitizer_syscall_post_impl_umount(res, (long)(name), (long)(flags)) +#define __sanitizer_syscall_pre_oldumount(name) \ + __sanitizer_syscall_pre_impl_oldumount((long)(name)) +#define __sanitizer_syscall_post_oldumount(res, name) \ + __sanitizer_syscall_post_impl_oldumount(res, (long)(name)) +#define __sanitizer_syscall_pre_truncate(path, length) \ + __sanitizer_syscall_pre_impl_truncate((long)(path), (long)(length)) +#define __sanitizer_syscall_post_truncate(res, path, length) \ + __sanitizer_syscall_post_impl_truncate(res, (long)(path), (long)(length)) +#define __sanitizer_syscall_pre_ftruncate(fd, length) \ + __sanitizer_syscall_pre_impl_ftruncate((long)(fd), (long)(length)) +#define __sanitizer_syscall_post_ftruncate(res, fd, length) \ + __sanitizer_syscall_post_impl_ftruncate(res, (long)(fd), (long)(length)) +#define __sanitizer_syscall_pre_stat(filename, statbuf) \ + __sanitizer_syscall_pre_impl_stat((long)(filename), (long)(statbuf)) +#define __sanitizer_syscall_post_stat(res, filename, statbuf) \ + __sanitizer_syscall_post_impl_stat(res, (long)(filename), (long)(statbuf)) +#define __sanitizer_syscall_pre_statfs(path, buf) \ + __sanitizer_syscall_pre_impl_statfs((long)(path), (long)(buf)) +#define __sanitizer_syscall_post_statfs(res, path, buf) \ + __sanitizer_syscall_post_impl_statfs(res, (long)(path), (long)(buf)) +#define __sanitizer_syscall_pre_statfs64(path, sz, buf) \ + __sanitizer_syscall_pre_impl_statfs64((long)(path), (long)(sz), (long)(buf)) +#define __sanitizer_syscall_post_statfs64(res, path, sz, buf) \ + __sanitizer_syscall_post_impl_statfs64(res, (long)(path), (long)(sz), \ + (long)(buf)) +#define __sanitizer_syscall_pre_fstatfs(fd, buf) \ + __sanitizer_syscall_pre_impl_fstatfs((long)(fd), (long)(buf)) +#define __sanitizer_syscall_post_fstatfs(res, fd, buf) \ + __sanitizer_syscall_post_impl_fstatfs(res, (long)(fd), (long)(buf)) +#define __sanitizer_syscall_pre_fstatfs64(fd, sz, buf) \ + __sanitizer_syscall_pre_impl_fstatfs64((long)(fd), (long)(sz), (long)(buf)) +#define __sanitizer_syscall_post_fstatfs64(res, fd, sz, buf) \ + __sanitizer_syscall_post_impl_fstatfs64(res, (long)(fd), (long)(sz), \ + (long)(buf)) +#define __sanitizer_syscall_pre_lstat(filename, statbuf) \ + __sanitizer_syscall_pre_impl_lstat((long)(filename), (long)(statbuf)) +#define __sanitizer_syscall_post_lstat(res, filename, statbuf) \ + __sanitizer_syscall_post_impl_lstat(res, (long)(filename), (long)(statbuf)) +#define __sanitizer_syscall_pre_fstat(fd, statbuf) \ + __sanitizer_syscall_pre_impl_fstat((long)(fd), (long)(statbuf)) +#define __sanitizer_syscall_post_fstat(res, fd, statbuf) \ + __sanitizer_syscall_post_impl_fstat(res, (long)(fd), (long)(statbuf)) +#define __sanitizer_syscall_pre_newstat(filename, statbuf) \ + __sanitizer_syscall_pre_impl_newstat((long)(filename), (long)(statbuf)) +#define __sanitizer_syscall_post_newstat(res, filename, statbuf) \ + __sanitizer_syscall_post_impl_newstat(res, (long)(filename), (long)(statbuf)) +#define __sanitizer_syscall_pre_newlstat(filename, statbuf) \ + __sanitizer_syscall_pre_impl_newlstat((long)(filename), (long)(statbuf)) +#define __sanitizer_syscall_post_newlstat(res, filename, statbuf) \ + __sanitizer_syscall_post_impl_newlstat(res, (long)(filename), (long)(statbuf)) +#define __sanitizer_syscall_pre_newfstat(fd, statbuf) \ + __sanitizer_syscall_pre_impl_newfstat((long)(fd), (long)(statbuf)) +#define __sanitizer_syscall_post_newfstat(res, fd, statbuf) \ + __sanitizer_syscall_post_impl_newfstat(res, (long)(fd), (long)(statbuf)) +#define __sanitizer_syscall_pre_ustat(dev, ubuf) \ + __sanitizer_syscall_pre_impl_ustat((long)(dev), (long)(ubuf)) +#define __sanitizer_syscall_post_ustat(res, dev, ubuf) \ + __sanitizer_syscall_post_impl_ustat(res, (long)(dev), (long)(ubuf)) +#define __sanitizer_syscall_pre_stat64(filename, statbuf) \ + __sanitizer_syscall_pre_impl_stat64((long)(filename), (long)(statbuf)) +#define __sanitizer_syscall_post_stat64(res, filename, statbuf) \ + __sanitizer_syscall_post_impl_stat64(res, (long)(filename), (long)(statbuf)) +#define __sanitizer_syscall_pre_fstat64(fd, statbuf) \ + __sanitizer_syscall_pre_impl_fstat64((long)(fd), (long)(statbuf)) +#define __sanitizer_syscall_post_fstat64(res, fd, statbuf) \ + __sanitizer_syscall_post_impl_fstat64(res, (long)(fd), (long)(statbuf)) +#define __sanitizer_syscall_pre_lstat64(filename, statbuf) \ + __sanitizer_syscall_pre_impl_lstat64((long)(filename), (long)(statbuf)) +#define __sanitizer_syscall_post_lstat64(res, filename, statbuf) \ + __sanitizer_syscall_post_impl_lstat64(res, (long)(filename), (long)(statbuf)) +#define __sanitizer_syscall_pre_setxattr(path, name, value, size, flags) \ + __sanitizer_syscall_pre_impl_setxattr( \ + (long)(path), (long)(name), (long)(value), (long)(size), (long)(flags)) +#define __sanitizer_syscall_post_setxattr(res, path, name, value, size, flags) \ + __sanitizer_syscall_post_impl_setxattr(res, (long)(path), (long)(name), \ + (long)(value), (long)(size), \ + (long)(flags)) +#define __sanitizer_syscall_pre_lsetxattr(path, name, value, size, flags) \ + __sanitizer_syscall_pre_impl_lsetxattr( \ + (long)(path), (long)(name), (long)(value), (long)(size), (long)(flags)) +#define __sanitizer_syscall_post_lsetxattr(res, path, name, value, size, \ + flags) \ + __sanitizer_syscall_post_impl_lsetxattr(res, (long)(path), (long)(name), \ + (long)(value), (long)(size), \ + (long)(flags)) +#define __sanitizer_syscall_pre_fsetxattr(fd, name, value, size, flags) \ + __sanitizer_syscall_pre_impl_fsetxattr( \ + (long)(fd), (long)(name), (long)(value), (long)(size), (long)(flags)) +#define __sanitizer_syscall_post_fsetxattr(res, fd, name, value, size, flags) \ + __sanitizer_syscall_post_impl_fsetxattr(res, (long)(fd), (long)(name), \ + (long)(value), (long)(size), \ + (long)(flags)) +#define __sanitizer_syscall_pre_getxattr(path, name, value, size) \ + __sanitizer_syscall_pre_impl_getxattr((long)(path), (long)(name), \ + (long)(value), (long)(size)) +#define __sanitizer_syscall_post_getxattr(res, path, name, value, size) \ + __sanitizer_syscall_post_impl_getxattr(res, (long)(path), (long)(name), \ + (long)(value), (long)(size)) +#define __sanitizer_syscall_pre_lgetxattr(path, name, value, size) \ + __sanitizer_syscall_pre_impl_lgetxattr((long)(path), (long)(name), \ + (long)(value), (long)(size)) +#define __sanitizer_syscall_post_lgetxattr(res, path, name, value, size) \ + __sanitizer_syscall_post_impl_lgetxattr(res, (long)(path), (long)(name), \ + (long)(value), (long)(size)) +#define __sanitizer_syscall_pre_fgetxattr(fd, name, value, size) \ + __sanitizer_syscall_pre_impl_fgetxattr((long)(fd), (long)(name), \ + (long)(value), (long)(size)) +#define __sanitizer_syscall_post_fgetxattr(res, fd, name, value, size) \ + __sanitizer_syscall_post_impl_fgetxattr(res, (long)(fd), (long)(name), \ + (long)(value), (long)(size)) +#define __sanitizer_syscall_pre_listxattr(path, list, size) \ + __sanitizer_syscall_pre_impl_listxattr((long)(path), (long)(list), \ + (long)(size)) +#define __sanitizer_syscall_post_listxattr(res, path, list, size) \ + __sanitizer_syscall_post_impl_listxattr(res, (long)(path), (long)(list), \ + (long)(size)) +#define __sanitizer_syscall_pre_llistxattr(path, list, size) \ + __sanitizer_syscall_pre_impl_llistxattr((long)(path), (long)(list), \ + (long)(size)) +#define __sanitizer_syscall_post_llistxattr(res, path, list, size) \ + __sanitizer_syscall_post_impl_llistxattr(res, (long)(path), (long)(list), \ + (long)(size)) +#define __sanitizer_syscall_pre_flistxattr(fd, list, size) \ + __sanitizer_syscall_pre_impl_flistxattr((long)(fd), (long)(list), \ + (long)(size)) +#define __sanitizer_syscall_post_flistxattr(res, fd, list, size) \ + __sanitizer_syscall_post_impl_flistxattr(res, (long)(fd), (long)(list), \ + (long)(size)) +#define __sanitizer_syscall_pre_removexattr(path, name) \ + __sanitizer_syscall_pre_impl_removexattr((long)(path), (long)(name)) +#define __sanitizer_syscall_post_removexattr(res, path, name) \ + __sanitizer_syscall_post_impl_removexattr(res, (long)(path), (long)(name)) +#define __sanitizer_syscall_pre_lremovexattr(path, name) \ + __sanitizer_syscall_pre_impl_lremovexattr((long)(path), (long)(name)) +#define __sanitizer_syscall_post_lremovexattr(res, path, name) \ + __sanitizer_syscall_post_impl_lremovexattr(res, (long)(path), (long)(name)) +#define __sanitizer_syscall_pre_fremovexattr(fd, name) \ + __sanitizer_syscall_pre_impl_fremovexattr((long)(fd), (long)(name)) +#define __sanitizer_syscall_post_fremovexattr(res, fd, name) \ + __sanitizer_syscall_post_impl_fremovexattr(res, (long)(fd), (long)(name)) +#define __sanitizer_syscall_pre_brk(brk) \ + __sanitizer_syscall_pre_impl_brk((long)(brk)) +#define __sanitizer_syscall_post_brk(res, brk) \ + __sanitizer_syscall_post_impl_brk(res, (long)(brk)) +#define __sanitizer_syscall_pre_mprotect(start, len, prot) \ + __sanitizer_syscall_pre_impl_mprotect((long)(start), (long)(len), \ + (long)(prot)) +#define __sanitizer_syscall_post_mprotect(res, start, len, prot) \ + __sanitizer_syscall_post_impl_mprotect(res, (long)(start), (long)(len), \ + (long)(prot)) +#define __sanitizer_syscall_pre_mremap(addr, old_len, new_len, flags, \ + new_addr) \ + __sanitizer_syscall_pre_impl_mremap((long)(addr), (long)(old_len), \ + (long)(new_len), (long)(flags), \ + (long)(new_addr)) +#define __sanitizer_syscall_post_mremap(res, addr, old_len, new_len, flags, \ + new_addr) \ + __sanitizer_syscall_post_impl_mremap(res, (long)(addr), (long)(old_len), \ + (long)(new_len), (long)(flags), \ + (long)(new_addr)) +#define __sanitizer_syscall_pre_remap_file_pages(start, size, prot, pgoff, \ + flags) \ + __sanitizer_syscall_pre_impl_remap_file_pages( \ + (long)(start), (long)(size), (long)(prot), (long)(pgoff), (long)(flags)) +#define __sanitizer_syscall_post_remap_file_pages(res, start, size, prot, \ + pgoff, flags) \ + __sanitizer_syscall_post_impl_remap_file_pages(res, (long)(start), \ + (long)(size), (long)(prot), \ + (long)(pgoff), (long)(flags)) +#define __sanitizer_syscall_pre_msync(start, len, flags) \ + __sanitizer_syscall_pre_impl_msync((long)(start), (long)(len), (long)(flags)) +#define __sanitizer_syscall_post_msync(res, start, len, flags) \ + __sanitizer_syscall_post_impl_msync(res, (long)(start), (long)(len), \ + (long)(flags)) +#define __sanitizer_syscall_pre_munmap(addr, len) \ + __sanitizer_syscall_pre_impl_munmap((long)(addr), (long)(len)) +#define __sanitizer_syscall_post_munmap(res, addr, len) \ + __sanitizer_syscall_post_impl_munmap(res, (long)(addr), (long)(len)) +#define __sanitizer_syscall_pre_mlock(start, len) \ + __sanitizer_syscall_pre_impl_mlock((long)(start), (long)(len)) +#define __sanitizer_syscall_post_mlock(res, start, len) \ + __sanitizer_syscall_post_impl_mlock(res, (long)(start), (long)(len)) +#define __sanitizer_syscall_pre_munlock(start, len) \ + __sanitizer_syscall_pre_impl_munlock((long)(start), (long)(len)) +#define __sanitizer_syscall_post_munlock(res, start, len) \ + __sanitizer_syscall_post_impl_munlock(res, (long)(start), (long)(len)) +#define __sanitizer_syscall_pre_mlockall(flags) \ + __sanitizer_syscall_pre_impl_mlockall((long)(flags)) +#define __sanitizer_syscall_post_mlockall(res, flags) \ + __sanitizer_syscall_post_impl_mlockall(res, (long)(flags)) +#define __sanitizer_syscall_pre_munlockall() \ + __sanitizer_syscall_pre_impl_munlockall() +#define __sanitizer_syscall_post_munlockall(res) \ + __sanitizer_syscall_post_impl_munlockall(res) +#define __sanitizer_syscall_pre_madvise(start, len, behavior) \ + __sanitizer_syscall_pre_impl_madvise((long)(start), (long)(len), \ + (long)(behavior)) +#define __sanitizer_syscall_post_madvise(res, start, len, behavior) \ + __sanitizer_syscall_post_impl_madvise(res, (long)(start), (long)(len), \ + (long)(behavior)) +#define __sanitizer_syscall_pre_mincore(start, len, vec) \ + __sanitizer_syscall_pre_impl_mincore((long)(start), (long)(len), (long)(vec)) +#define __sanitizer_syscall_post_mincore(res, start, len, vec) \ + __sanitizer_syscall_post_impl_mincore(res, (long)(start), (long)(len), \ + (long)(vec)) +#define __sanitizer_syscall_pre_pivot_root(new_root, put_old) \ + __sanitizer_syscall_pre_impl_pivot_root((long)(new_root), (long)(put_old)) +#define __sanitizer_syscall_post_pivot_root(res, new_root, put_old) \ + __sanitizer_syscall_post_impl_pivot_root(res, (long)(new_root), \ + (long)(put_old)) +#define __sanitizer_syscall_pre_chroot(filename) \ + __sanitizer_syscall_pre_impl_chroot((long)(filename)) +#define __sanitizer_syscall_post_chroot(res, filename) \ + __sanitizer_syscall_post_impl_chroot(res, (long)(filename)) +#define __sanitizer_syscall_pre_mknod(filename, mode, dev) \ + __sanitizer_syscall_pre_impl_mknod((long)(filename), (long)(mode), \ + (long)(dev)) +#define __sanitizer_syscall_post_mknod(res, filename, mode, dev) \ + __sanitizer_syscall_post_impl_mknod(res, (long)(filename), (long)(mode), \ + (long)(dev)) +#define __sanitizer_syscall_pre_link(oldname, newname) \ + __sanitizer_syscall_pre_impl_link((long)(oldname), (long)(newname)) +#define __sanitizer_syscall_post_link(res, oldname, newname) \ + __sanitizer_syscall_post_impl_link(res, (long)(oldname), (long)(newname)) +#define __sanitizer_syscall_pre_symlink(old, new_) \ + __sanitizer_syscall_pre_impl_symlink((long)(old), (long)(new_)) +#define __sanitizer_syscall_post_symlink(res, old, new_) \ + __sanitizer_syscall_post_impl_symlink(res, (long)(old), (long)(new_)) +#define __sanitizer_syscall_pre_unlink(pathname) \ + __sanitizer_syscall_pre_impl_unlink((long)(pathname)) +#define __sanitizer_syscall_post_unlink(res, pathname) \ + __sanitizer_syscall_post_impl_unlink(res, (long)(pathname)) +#define __sanitizer_syscall_pre_rename(oldname, newname) \ + __sanitizer_syscall_pre_impl_rename((long)(oldname), (long)(newname)) +#define __sanitizer_syscall_post_rename(res, oldname, newname) \ + __sanitizer_syscall_post_impl_rename(res, (long)(oldname), (long)(newname)) +#define __sanitizer_syscall_pre_chmod(filename, mode) \ + __sanitizer_syscall_pre_impl_chmod((long)(filename), (long)(mode)) +#define __sanitizer_syscall_post_chmod(res, filename, mode) \ + __sanitizer_syscall_post_impl_chmod(res, (long)(filename), (long)(mode)) +#define __sanitizer_syscall_pre_fchmod(fd, mode) \ + __sanitizer_syscall_pre_impl_fchmod((long)(fd), (long)(mode)) +#define __sanitizer_syscall_post_fchmod(res, fd, mode) \ + __sanitizer_syscall_post_impl_fchmod(res, (long)(fd), (long)(mode)) +#define __sanitizer_syscall_pre_fcntl(fd, cmd, arg) \ + __sanitizer_syscall_pre_impl_fcntl((long)(fd), (long)(cmd), (long)(arg)) +#define __sanitizer_syscall_post_fcntl(res, fd, cmd, arg) \ + __sanitizer_syscall_post_impl_fcntl(res, (long)(fd), (long)(cmd), (long)(arg)) +#define __sanitizer_syscall_pre_fcntl64(fd, cmd, arg) \ + __sanitizer_syscall_pre_impl_fcntl64((long)(fd), (long)(cmd), (long)(arg)) +#define __sanitizer_syscall_post_fcntl64(res, fd, cmd, arg) \ + __sanitizer_syscall_post_impl_fcntl64(res, (long)(fd), (long)(cmd), \ + (long)(arg)) +#define __sanitizer_syscall_pre_pipe(fildes) \ + __sanitizer_syscall_pre_impl_pipe((long)(fildes)) +#define __sanitizer_syscall_post_pipe(res, fildes) \ + __sanitizer_syscall_post_impl_pipe(res, (long)(fildes)) +#define __sanitizer_syscall_pre_pipe2(fildes, flags) \ + __sanitizer_syscall_pre_impl_pipe2((long)(fildes), (long)(flags)) +#define __sanitizer_syscall_post_pipe2(res, fildes, flags) \ + __sanitizer_syscall_post_impl_pipe2(res, (long)(fildes), (long)(flags)) +#define __sanitizer_syscall_pre_dup(fildes) \ + __sanitizer_syscall_pre_impl_dup((long)(fildes)) +#define __sanitizer_syscall_post_dup(res, fildes) \ + __sanitizer_syscall_post_impl_dup(res, (long)(fildes)) +#define __sanitizer_syscall_pre_dup2(oldfd, newfd) \ + __sanitizer_syscall_pre_impl_dup2((long)(oldfd), (long)(newfd)) +#define __sanitizer_syscall_post_dup2(res, oldfd, newfd) \ + __sanitizer_syscall_post_impl_dup2(res, (long)(oldfd), (long)(newfd)) +#define __sanitizer_syscall_pre_dup3(oldfd, newfd, flags) \ + __sanitizer_syscall_pre_impl_dup3((long)(oldfd), (long)(newfd), (long)(flags)) +#define __sanitizer_syscall_post_dup3(res, oldfd, newfd, flags) \ + __sanitizer_syscall_post_impl_dup3(res, (long)(oldfd), (long)(newfd), \ + (long)(flags)) +#define __sanitizer_syscall_pre_ioperm(from, num, on) \ + __sanitizer_syscall_pre_impl_ioperm((long)(from), (long)(num), (long)(on)) +#define __sanitizer_syscall_post_ioperm(res, from, num, on) \ + __sanitizer_syscall_post_impl_ioperm(res, (long)(from), (long)(num), \ + (long)(on)) +#define __sanitizer_syscall_pre_ioctl(fd, cmd, arg) \ + __sanitizer_syscall_pre_impl_ioctl((long)(fd), (long)(cmd), (long)(arg)) +#define __sanitizer_syscall_post_ioctl(res, fd, cmd, arg) \ + __sanitizer_syscall_post_impl_ioctl(res, (long)(fd), (long)(cmd), (long)(arg)) +#define __sanitizer_syscall_pre_flock(fd, cmd) \ + __sanitizer_syscall_pre_impl_flock((long)(fd), (long)(cmd)) +#define __sanitizer_syscall_post_flock(res, fd, cmd) \ + __sanitizer_syscall_post_impl_flock(res, (long)(fd), (long)(cmd)) +#define __sanitizer_syscall_pre_io_setup(nr_reqs, ctx) \ + __sanitizer_syscall_pre_impl_io_setup((long)(nr_reqs), (long)(ctx)) +#define __sanitizer_syscall_post_io_setup(res, nr_reqs, ctx) \ + __sanitizer_syscall_post_impl_io_setup(res, (long)(nr_reqs), (long)(ctx)) +#define __sanitizer_syscall_pre_io_destroy(ctx) \ + __sanitizer_syscall_pre_impl_io_destroy((long)(ctx)) +#define __sanitizer_syscall_post_io_destroy(res, ctx) \ + __sanitizer_syscall_post_impl_io_destroy(res, (long)(ctx)) +#define __sanitizer_syscall_pre_io_getevents(ctx_id, min_nr, nr, events, \ + timeout) \ + __sanitizer_syscall_pre_impl_io_getevents((long)(ctx_id), (long)(min_nr), \ + (long)(nr), (long)(events), \ + (long)(timeout)) +#define __sanitizer_syscall_post_io_getevents(res, ctx_id, min_nr, nr, events, \ + timeout) \ + __sanitizer_syscall_post_impl_io_getevents(res, (long)(ctx_id), \ + (long)(min_nr), (long)(nr), \ + (long)(events), (long)(timeout)) +#define __sanitizer_syscall_pre_io_submit(ctx_id, arg1, arg2) \ + __sanitizer_syscall_pre_impl_io_submit((long)(ctx_id), (long)(arg1), \ + (long)(arg2)) +#define __sanitizer_syscall_post_io_submit(res, ctx_id, arg1, arg2) \ + __sanitizer_syscall_post_impl_io_submit(res, (long)(ctx_id), (long)(arg1), \ + (long)(arg2)) +#define __sanitizer_syscall_pre_io_cancel(ctx_id, iocb, result) \ + __sanitizer_syscall_pre_impl_io_cancel((long)(ctx_id), (long)(iocb), \ + (long)(result)) +#define __sanitizer_syscall_post_io_cancel(res, ctx_id, iocb, result) \ + __sanitizer_syscall_post_impl_io_cancel(res, (long)(ctx_id), (long)(iocb), \ + (long)(result)) +#define __sanitizer_syscall_pre_sendfile(out_fd, in_fd, offset, count) \ + __sanitizer_syscall_pre_impl_sendfile((long)(out_fd), (long)(in_fd), \ + (long)(offset), (long)(count)) +#define __sanitizer_syscall_post_sendfile(res, out_fd, in_fd, offset, count) \ + __sanitizer_syscall_post_impl_sendfile(res, (long)(out_fd), (long)(in_fd), \ + (long)(offset), (long)(count)) +#define __sanitizer_syscall_pre_sendfile64(out_fd, in_fd, offset, count) \ + __sanitizer_syscall_pre_impl_sendfile64((long)(out_fd), (long)(in_fd), \ + (long)(offset), (long)(count)) +#define __sanitizer_syscall_post_sendfile64(res, out_fd, in_fd, offset, count) \ + __sanitizer_syscall_post_impl_sendfile64(res, (long)(out_fd), (long)(in_fd), \ + (long)(offset), (long)(count)) +#define __sanitizer_syscall_pre_readlink(path, buf, bufsiz) \ + __sanitizer_syscall_pre_impl_readlink((long)(path), (long)(buf), \ + (long)(bufsiz)) +#define __sanitizer_syscall_post_readlink(res, path, buf, bufsiz) \ + __sanitizer_syscall_post_impl_readlink(res, (long)(path), (long)(buf), \ + (long)(bufsiz)) +#define __sanitizer_syscall_pre_creat(pathname, mode) \ + __sanitizer_syscall_pre_impl_creat((long)(pathname), (long)(mode)) +#define __sanitizer_syscall_post_creat(res, pathname, mode) \ + __sanitizer_syscall_post_impl_creat(res, (long)(pathname), (long)(mode)) +#define __sanitizer_syscall_pre_open(filename, flags, mode) \ + __sanitizer_syscall_pre_impl_open((long)(filename), (long)(flags), \ + (long)(mode)) +#define __sanitizer_syscall_post_open(res, filename, flags, mode) \ + __sanitizer_syscall_post_impl_open(res, (long)(filename), (long)(flags), \ + (long)(mode)) +#define __sanitizer_syscall_pre_close(fd) \ + __sanitizer_syscall_pre_impl_close((long)(fd)) +#define __sanitizer_syscall_post_close(res, fd) \ + __sanitizer_syscall_post_impl_close(res, (long)(fd)) +#define __sanitizer_syscall_pre_access(filename, mode) \ + __sanitizer_syscall_pre_impl_access((long)(filename), (long)(mode)) +#define __sanitizer_syscall_post_access(res, filename, mode) \ + __sanitizer_syscall_post_impl_access(res, (long)(filename), (long)(mode)) +#define __sanitizer_syscall_pre_vhangup() __sanitizer_syscall_pre_impl_vhangup() +#define __sanitizer_syscall_post_vhangup(res) \ + __sanitizer_syscall_post_impl_vhangup(res) +#define __sanitizer_syscall_pre_chown(filename, user, group) \ + __sanitizer_syscall_pre_impl_chown((long)(filename), (long)(user), \ + (long)(group)) +#define __sanitizer_syscall_post_chown(res, filename, user, group) \ + __sanitizer_syscall_post_impl_chown(res, (long)(filename), (long)(user), \ + (long)(group)) +#define __sanitizer_syscall_pre_lchown(filename, user, group) \ + __sanitizer_syscall_pre_impl_lchown((long)(filename), (long)(user), \ + (long)(group)) +#define __sanitizer_syscall_post_lchown(res, filename, user, group) \ + __sanitizer_syscall_post_impl_lchown(res, (long)(filename), (long)(user), \ + (long)(group)) +#define __sanitizer_syscall_pre_fchown(fd, user, group) \ + __sanitizer_syscall_pre_impl_fchown((long)(fd), (long)(user), (long)(group)) +#define __sanitizer_syscall_post_fchown(res, fd, user, group) \ + __sanitizer_syscall_post_impl_fchown(res, (long)(fd), (long)(user), \ + (long)(group)) +#define __sanitizer_syscall_pre_chown16(filename, user, group) \ + __sanitizer_syscall_pre_impl_chown16((long)(filename), (long)user, \ + (long)group) +#define __sanitizer_syscall_post_chown16(res, filename, user, group) \ + __sanitizer_syscall_post_impl_chown16(res, (long)(filename), (long)user, \ + (long)group) +#define __sanitizer_syscall_pre_lchown16(filename, user, group) \ + __sanitizer_syscall_pre_impl_lchown16((long)(filename), (long)user, \ + (long)group) +#define __sanitizer_syscall_post_lchown16(res, filename, user, group) \ + __sanitizer_syscall_post_impl_lchown16(res, (long)(filename), (long)user, \ + (long)group) +#define __sanitizer_syscall_pre_fchown16(fd, user, group) \ + __sanitizer_syscall_pre_impl_fchown16((long)(fd), (long)user, (long)group) +#define __sanitizer_syscall_post_fchown16(res, fd, user, group) \ + __sanitizer_syscall_post_impl_fchown16(res, (long)(fd), (long)user, \ + (long)group) +#define __sanitizer_syscall_pre_setregid16(rgid, egid) \ + __sanitizer_syscall_pre_impl_setregid16((long)rgid, (long)egid) +#define __sanitizer_syscall_post_setregid16(res, rgid, egid) \ + __sanitizer_syscall_post_impl_setregid16(res, (long)rgid, (long)egid) +#define __sanitizer_syscall_pre_setgid16(gid) \ + __sanitizer_syscall_pre_impl_setgid16((long)gid) +#define __sanitizer_syscall_post_setgid16(res, gid) \ + __sanitizer_syscall_post_impl_setgid16(res, (long)gid) +#define __sanitizer_syscall_pre_setreuid16(ruid, euid) \ + __sanitizer_syscall_pre_impl_setreuid16((long)ruid, (long)euid) +#define __sanitizer_syscall_post_setreuid16(res, ruid, euid) \ + __sanitizer_syscall_post_impl_setreuid16(res, (long)ruid, (long)euid) +#define __sanitizer_syscall_pre_setuid16(uid) \ + __sanitizer_syscall_pre_impl_setuid16((long)uid) +#define __sanitizer_syscall_post_setuid16(res, uid) \ + __sanitizer_syscall_post_impl_setuid16(res, (long)uid) +#define __sanitizer_syscall_pre_setresuid16(ruid, euid, suid) \ + __sanitizer_syscall_pre_impl_setresuid16((long)ruid, (long)euid, (long)suid) +#define __sanitizer_syscall_post_setresuid16(res, ruid, euid, suid) \ + __sanitizer_syscall_post_impl_setresuid16(res, (long)ruid, (long)euid, \ + (long)suid) +#define __sanitizer_syscall_pre_getresuid16(ruid, euid, suid) \ + __sanitizer_syscall_pre_impl_getresuid16((long)(ruid), (long)(euid), \ + (long)(suid)) +#define __sanitizer_syscall_post_getresuid16(res, ruid, euid, suid) \ + __sanitizer_syscall_post_impl_getresuid16(res, (long)(ruid), (long)(euid), \ + (long)(suid)) +#define __sanitizer_syscall_pre_setresgid16(rgid, egid, sgid) \ + __sanitizer_syscall_pre_impl_setresgid16((long)rgid, (long)egid, (long)sgid) +#define __sanitizer_syscall_post_setresgid16(res, rgid, egid, sgid) \ + __sanitizer_syscall_post_impl_setresgid16(res, (long)rgid, (long)egid, \ + (long)sgid) +#define __sanitizer_syscall_pre_getresgid16(rgid, egid, sgid) \ + __sanitizer_syscall_pre_impl_getresgid16((long)(rgid), (long)(egid), \ + (long)(sgid)) +#define __sanitizer_syscall_post_getresgid16(res, rgid, egid, sgid) \ + __sanitizer_syscall_post_impl_getresgid16(res, (long)(rgid), (long)(egid), \ + (long)(sgid)) +#define __sanitizer_syscall_pre_setfsuid16(uid) \ + __sanitizer_syscall_pre_impl_setfsuid16((long)uid) +#define __sanitizer_syscall_post_setfsuid16(res, uid) \ + __sanitizer_syscall_post_impl_setfsuid16(res, (long)uid) +#define __sanitizer_syscall_pre_setfsgid16(gid) \ + __sanitizer_syscall_pre_impl_setfsgid16((long)gid) +#define __sanitizer_syscall_post_setfsgid16(res, gid) \ + __sanitizer_syscall_post_impl_setfsgid16(res, (long)gid) +#define __sanitizer_syscall_pre_getgroups16(gidsetsize, grouplist) \ + __sanitizer_syscall_pre_impl_getgroups16((long)(gidsetsize), \ + (long)(grouplist)) +#define __sanitizer_syscall_post_getgroups16(res, gidsetsize, grouplist) \ + __sanitizer_syscall_post_impl_getgroups16(res, (long)(gidsetsize), \ + (long)(grouplist)) +#define __sanitizer_syscall_pre_setgroups16(gidsetsize, grouplist) \ + __sanitizer_syscall_pre_impl_setgroups16((long)(gidsetsize), \ + (long)(grouplist)) +#define __sanitizer_syscall_post_setgroups16(res, gidsetsize, grouplist) \ + __sanitizer_syscall_post_impl_setgroups16(res, (long)(gidsetsize), \ + (long)(grouplist)) +#define __sanitizer_syscall_pre_getuid16() \ + __sanitizer_syscall_pre_impl_getuid16() +#define __sanitizer_syscall_post_getuid16(res) \ + __sanitizer_syscall_post_impl_getuid16(res) +#define __sanitizer_syscall_pre_geteuid16() \ + __sanitizer_syscall_pre_impl_geteuid16() +#define __sanitizer_syscall_post_geteuid16(res) \ + __sanitizer_syscall_post_impl_geteuid16(res) +#define __sanitizer_syscall_pre_getgid16() \ + __sanitizer_syscall_pre_impl_getgid16() +#define __sanitizer_syscall_post_getgid16(res) \ + __sanitizer_syscall_post_impl_getgid16(res) +#define __sanitizer_syscall_pre_getegid16() \ + __sanitizer_syscall_pre_impl_getegid16() +#define __sanitizer_syscall_post_getegid16(res) \ + __sanitizer_syscall_post_impl_getegid16(res) +#define __sanitizer_syscall_pre_utime(filename, times) \ + __sanitizer_syscall_pre_impl_utime((long)(filename), (long)(times)) +#define __sanitizer_syscall_post_utime(res, filename, times) \ + __sanitizer_syscall_post_impl_utime(res, (long)(filename), (long)(times)) +#define __sanitizer_syscall_pre_utimes(filename, utimes) \ + __sanitizer_syscall_pre_impl_utimes((long)(filename), (long)(utimes)) +#define __sanitizer_syscall_post_utimes(res, filename, utimes) \ + __sanitizer_syscall_post_impl_utimes(res, (long)(filename), (long)(utimes)) +#define __sanitizer_syscall_pre_lseek(fd, offset, origin) \ + __sanitizer_syscall_pre_impl_lseek((long)(fd), (long)(offset), (long)(origin)) +#define __sanitizer_syscall_post_lseek(res, fd, offset, origin) \ + __sanitizer_syscall_post_impl_lseek(res, (long)(fd), (long)(offset), \ + (long)(origin)) +#define __sanitizer_syscall_pre_llseek(fd, offset_high, offset_low, result, \ + origin) \ + __sanitizer_syscall_pre_impl_llseek((long)(fd), (long)(offset_high), \ + (long)(offset_low), (long)(result), \ + (long)(origin)) +#define __sanitizer_syscall_post_llseek(res, fd, offset_high, offset_low, \ + result, origin) \ + __sanitizer_syscall_post_impl_llseek(res, (long)(fd), (long)(offset_high), \ + (long)(offset_low), (long)(result), \ + (long)(origin)) +#define __sanitizer_syscall_pre_read(fd, buf, count) \ + __sanitizer_syscall_pre_impl_read((long)(fd), (long)(buf), (long)(count)) +#define __sanitizer_syscall_post_read(res, fd, buf, count) \ + __sanitizer_syscall_post_impl_read(res, (long)(fd), (long)(buf), \ + (long)(count)) +#define __sanitizer_syscall_pre_readv(fd, vec, vlen) \ + __sanitizer_syscall_pre_impl_readv((long)(fd), (long)(vec), (long)(vlen)) +#define __sanitizer_syscall_post_readv(res, fd, vec, vlen) \ + __sanitizer_syscall_post_impl_readv(res, (long)(fd), (long)(vec), \ + (long)(vlen)) +#define __sanitizer_syscall_pre_write(fd, buf, count) \ + __sanitizer_syscall_pre_impl_write((long)(fd), (long)(buf), (long)(count)) +#define __sanitizer_syscall_post_write(res, fd, buf, count) \ + __sanitizer_syscall_post_impl_write(res, (long)(fd), (long)(buf), \ + (long)(count)) +#define __sanitizer_syscall_pre_writev(fd, vec, vlen) \ + __sanitizer_syscall_pre_impl_writev((long)(fd), (long)(vec), (long)(vlen)) +#define __sanitizer_syscall_post_writev(res, fd, vec, vlen) \ + __sanitizer_syscall_post_impl_writev(res, (long)(fd), (long)(vec), \ + (long)(vlen)) -void __sanitizer_syscall_pre_rt_sigpending(void *p, size_t s); -void __sanitizer_syscall_pre_getdents(int fd, void *dirp, int count); -void __sanitizer_syscall_pre_getdents64(int fd, void *dirp, int count); -void __sanitizer_syscall_pre_recvmsg(int sockfd, void *msg, int flags); -void __sanitizer_syscall_pre_wait4(int pid, int *status, int options, void *r); -void __sanitizer_syscall_pre_waitpid(int pid, int *status, int options); +#ifdef _LP64 +#define __sanitizer_syscall_pre_pread64(fd, buf, count, pos) \ + __sanitizer_syscall_pre_impl_pread64((long)(fd), (long)(buf), (long)(count), \ + (long)(pos)) +#define __sanitizer_syscall_post_pread64(res, fd, buf, count, pos) \ + __sanitizer_syscall_post_impl_pread64(res, (long)(fd), (long)(buf), \ + (long)(count), (long)(pos)) +#define __sanitizer_syscall_pre_pwrite64(fd, buf, count, pos) \ + __sanitizer_syscall_pre_impl_pwrite64((long)(fd), (long)(buf), \ + (long)(count), (long)(pos)) +#define __sanitizer_syscall_post_pwrite64(res, fd, buf, count, pos) \ + __sanitizer_syscall_post_impl_pwrite64(res, (long)(fd), (long)(buf), \ + (long)(count), (long)(pos)) +#else +#define __sanitizer_syscall_pre_pread64(fd, buf, count, pos0, pos1) \ + __sanitizer_syscall_pre_impl_pread64((long)(fd), (long)(buf), (long)(count), \ + (long)(pos0), (long)(pos1)) +#define __sanitizer_syscall_post_pread64(res, fd, buf, count, pos0, pos1) \ + __sanitizer_syscall_post_impl_pread64(res, (long)(fd), (long)(buf), \ + (long)(count), (long)(pos0), \ + (long)(pos1)) +#define __sanitizer_syscall_pre_pwrite64(fd, buf, count, pos0, pos1) \ + __sanitizer_syscall_pre_impl_pwrite64( \ + (long)(fd), (long)(buf), (long)(count), (long)(pos0), (long)(pos1)) +#define __sanitizer_syscall_post_pwrite64(res, fd, buf, count, pos0, pos1) \ + __sanitizer_syscall_post_impl_pwrite64( \ + res, (long)(fd), (long)(buf), (long)(count), (long)(pos0), (long)(pos1)) +#endif -void __sanitizer_syscall_post_rt_sigpending(long res, void *p, size_t s); -void __sanitizer_syscall_post_getdents(long res, int fd, void *dirp, int count); -void __sanitizer_syscall_post_getdents64(long res, int fd, void *dirp, - int count); -void __sanitizer_syscall_post_recvmsg(long res, int sockfd, void *msg, - int flags); -void __sanitizer_syscall_post_wait4(long res, int pid, int *status, int options, - void *r); -void __sanitizer_syscall_post_waitpid(long res, int pid, int *status, - int options); +#define __sanitizer_syscall_pre_preadv(fd, vec, vlen, pos_l, pos_h) \ + __sanitizer_syscall_pre_impl_preadv((long)(fd), (long)(vec), (long)(vlen), \ + (long)(pos_l), (long)(pos_h)) +#define __sanitizer_syscall_post_preadv(res, fd, vec, vlen, pos_l, pos_h) \ + __sanitizer_syscall_post_impl_preadv(res, (long)(fd), (long)(vec), \ + (long)(vlen), (long)(pos_l), \ + (long)(pos_h)) +#define __sanitizer_syscall_pre_pwritev(fd, vec, vlen, pos_l, pos_h) \ + __sanitizer_syscall_pre_impl_pwritev((long)(fd), (long)(vec), (long)(vlen), \ + (long)(pos_l), (long)(pos_h)) +#define __sanitizer_syscall_post_pwritev(res, fd, vec, vlen, pos_l, pos_h) \ + __sanitizer_syscall_post_impl_pwritev(res, (long)(fd), (long)(vec), \ + (long)(vlen), (long)(pos_l), \ + (long)(pos_h)) +#define __sanitizer_syscall_pre_getcwd(buf, size) \ + __sanitizer_syscall_pre_impl_getcwd((long)(buf), (long)(size)) +#define __sanitizer_syscall_post_getcwd(res, buf, size) \ + __sanitizer_syscall_post_impl_getcwd(res, (long)(buf), (long)(size)) +#define __sanitizer_syscall_pre_mkdir(pathname, mode) \ + __sanitizer_syscall_pre_impl_mkdir((long)(pathname), (long)(mode)) +#define __sanitizer_syscall_post_mkdir(res, pathname, mode) \ + __sanitizer_syscall_post_impl_mkdir(res, (long)(pathname), (long)(mode)) +#define __sanitizer_syscall_pre_chdir(filename) \ + __sanitizer_syscall_pre_impl_chdir((long)(filename)) +#define __sanitizer_syscall_post_chdir(res, filename) \ + __sanitizer_syscall_post_impl_chdir(res, (long)(filename)) +#define __sanitizer_syscall_pre_fchdir(fd) \ + __sanitizer_syscall_pre_impl_fchdir((long)(fd)) +#define __sanitizer_syscall_post_fchdir(res, fd) \ + __sanitizer_syscall_post_impl_fchdir(res, (long)(fd)) +#define __sanitizer_syscall_pre_rmdir(pathname) \ + __sanitizer_syscall_pre_impl_rmdir((long)(pathname)) +#define __sanitizer_syscall_post_rmdir(res, pathname) \ + __sanitizer_syscall_post_impl_rmdir(res, (long)(pathname)) +#define __sanitizer_syscall_pre_lookup_dcookie(cookie64, buf, len) \ + __sanitizer_syscall_pre_impl_lookup_dcookie((long)(cookie64), (long)(buf), \ + (long)(len)) +#define __sanitizer_syscall_post_lookup_dcookie(res, cookie64, buf, len) \ + __sanitizer_syscall_post_impl_lookup_dcookie(res, (long)(cookie64), \ + (long)(buf), (long)(len)) +#define __sanitizer_syscall_pre_quotactl(cmd, special, id, addr) \ + __sanitizer_syscall_pre_impl_quotactl((long)(cmd), (long)(special), \ + (long)(id), (long)(addr)) +#define __sanitizer_syscall_post_quotactl(res, cmd, special, id, addr) \ + __sanitizer_syscall_post_impl_quotactl(res, (long)(cmd), (long)(special), \ + (long)(id), (long)(addr)) +#define __sanitizer_syscall_pre_getdents(fd, dirent, count) \ + __sanitizer_syscall_pre_impl_getdents((long)(fd), (long)(dirent), \ + (long)(count)) +#define __sanitizer_syscall_post_getdents(res, fd, dirent, count) \ + __sanitizer_syscall_post_impl_getdents(res, (long)(fd), (long)(dirent), \ + (long)(count)) +#define __sanitizer_syscall_pre_getdents64(fd, dirent, count) \ + __sanitizer_syscall_pre_impl_getdents64((long)(fd), (long)(dirent), \ + (long)(count)) +#define __sanitizer_syscall_post_getdents64(res, fd, dirent, count) \ + __sanitizer_syscall_post_impl_getdents64(res, (long)(fd), (long)(dirent), \ + (long)(count)) +#define __sanitizer_syscall_pre_setsockopt(fd, level, optname, optval, optlen) \ + __sanitizer_syscall_pre_impl_setsockopt((long)(fd), (long)(level), \ + (long)(optname), (long)(optval), \ + (long)(optlen)) +#define __sanitizer_syscall_post_setsockopt(res, fd, level, optname, optval, \ + optlen) \ + __sanitizer_syscall_post_impl_setsockopt(res, (long)(fd), (long)(level), \ + (long)(optname), (long)(optval), \ + (long)(optlen)) +#define __sanitizer_syscall_pre_getsockopt(fd, level, optname, optval, optlen) \ + __sanitizer_syscall_pre_impl_getsockopt((long)(fd), (long)(level), \ + (long)(optname), (long)(optval), \ + (long)(optlen)) +#define __sanitizer_syscall_post_getsockopt(res, fd, level, optname, optval, \ + optlen) \ + __sanitizer_syscall_post_impl_getsockopt(res, (long)(fd), (long)(level), \ + (long)(optname), (long)(optval), \ + (long)(optlen)) +#define __sanitizer_syscall_pre_bind(arg0, arg1, arg2) \ + __sanitizer_syscall_pre_impl_bind((long)(arg0), (long)(arg1), (long)(arg2)) +#define __sanitizer_syscall_post_bind(res, arg0, arg1, arg2) \ + __sanitizer_syscall_post_impl_bind(res, (long)(arg0), (long)(arg1), \ + (long)(arg2)) +#define __sanitizer_syscall_pre_connect(arg0, arg1, arg2) \ + __sanitizer_syscall_pre_impl_connect((long)(arg0), (long)(arg1), (long)(arg2)) +#define __sanitizer_syscall_post_connect(res, arg0, arg1, arg2) \ + __sanitizer_syscall_post_impl_connect(res, (long)(arg0), (long)(arg1), \ + (long)(arg2)) +#define __sanitizer_syscall_pre_accept(arg0, arg1, arg2) \ + __sanitizer_syscall_pre_impl_accept((long)(arg0), (long)(arg1), (long)(arg2)) +#define __sanitizer_syscall_post_accept(res, arg0, arg1, arg2) \ + __sanitizer_syscall_post_impl_accept(res, (long)(arg0), (long)(arg1), \ + (long)(arg2)) +#define __sanitizer_syscall_pre_accept4(arg0, arg1, arg2, arg3) \ + __sanitizer_syscall_pre_impl_accept4((long)(arg0), (long)(arg1), \ + (long)(arg2), (long)(arg3)) +#define __sanitizer_syscall_post_accept4(res, arg0, arg1, arg2, arg3) \ + __sanitizer_syscall_post_impl_accept4(res, (long)(arg0), (long)(arg1), \ + (long)(arg2), (long)(arg3)) +#define __sanitizer_syscall_pre_getsockname(arg0, arg1, arg2) \ + __sanitizer_syscall_pre_impl_getsockname((long)(arg0), (long)(arg1), \ + (long)(arg2)) +#define __sanitizer_syscall_post_getsockname(res, arg0, arg1, arg2) \ + __sanitizer_syscall_post_impl_getsockname(res, (long)(arg0), (long)(arg1), \ + (long)(arg2)) +#define __sanitizer_syscall_pre_getpeername(arg0, arg1, arg2) \ + __sanitizer_syscall_pre_impl_getpeername((long)(arg0), (long)(arg1), \ + (long)(arg2)) +#define __sanitizer_syscall_post_getpeername(res, arg0, arg1, arg2) \ + __sanitizer_syscall_post_impl_getpeername(res, (long)(arg0), (long)(arg1), \ + (long)(arg2)) +#define __sanitizer_syscall_pre_send(arg0, arg1, arg2, arg3) \ + __sanitizer_syscall_pre_impl_send((long)(arg0), (long)(arg1), (long)(arg2), \ + (long)(arg3)) +#define __sanitizer_syscall_post_send(res, arg0, arg1, arg2, arg3) \ + __sanitizer_syscall_post_impl_send(res, (long)(arg0), (long)(arg1), \ + (long)(arg2), (long)(arg3)) +#define __sanitizer_syscall_pre_sendto(arg0, arg1, arg2, arg3, arg4, arg5) \ + __sanitizer_syscall_pre_impl_sendto((long)(arg0), (long)(arg1), \ + (long)(arg2), (long)(arg3), \ + (long)(arg4), (long)(arg5)) +#define __sanitizer_syscall_post_sendto(res, arg0, arg1, arg2, arg3, arg4, \ + arg5) \ + __sanitizer_syscall_post_impl_sendto(res, (long)(arg0), (long)(arg1), \ + (long)(arg2), (long)(arg3), \ + (long)(arg4), (long)(arg5)) +#define __sanitizer_syscall_pre_sendmsg(fd, msg, flags) \ + __sanitizer_syscall_pre_impl_sendmsg((long)(fd), (long)(msg), (long)(flags)) +#define __sanitizer_syscall_post_sendmsg(res, fd, msg, flags) \ + __sanitizer_syscall_post_impl_sendmsg(res, (long)(fd), (long)(msg), \ + (long)(flags)) +#define __sanitizer_syscall_pre_sendmmsg(fd, msg, vlen, flags) \ + __sanitizer_syscall_pre_impl_sendmmsg((long)(fd), (long)(msg), (long)(vlen), \ + (long)(flags)) +#define __sanitizer_syscall_post_sendmmsg(res, fd, msg, vlen, flags) \ + __sanitizer_syscall_post_impl_sendmmsg(res, (long)(fd), (long)(msg), \ + (long)(vlen), (long)(flags)) +#define __sanitizer_syscall_pre_recv(arg0, arg1, arg2, arg3) \ + __sanitizer_syscall_pre_impl_recv((long)(arg0), (long)(arg1), (long)(arg2), \ + (long)(arg3)) +#define __sanitizer_syscall_post_recv(res, arg0, arg1, arg2, arg3) \ + __sanitizer_syscall_post_impl_recv(res, (long)(arg0), (long)(arg1), \ + (long)(arg2), (long)(arg3)) +#define __sanitizer_syscall_pre_recvfrom(arg0, arg1, arg2, arg3, arg4, arg5) \ + __sanitizer_syscall_pre_impl_recvfrom((long)(arg0), (long)(arg1), \ + (long)(arg2), (long)(arg3), \ + (long)(arg4), (long)(arg5)) +#define __sanitizer_syscall_post_recvfrom(res, arg0, arg1, arg2, arg3, arg4, \ + arg5) \ + __sanitizer_syscall_post_impl_recvfrom(res, (long)(arg0), (long)(arg1), \ + (long)(arg2), (long)(arg3), \ + (long)(arg4), (long)(arg5)) +#define __sanitizer_syscall_pre_recvmsg(fd, msg, flags) \ + __sanitizer_syscall_pre_impl_recvmsg((long)(fd), (long)(msg), (long)(flags)) +#define __sanitizer_syscall_post_recvmsg(res, fd, msg, flags) \ + __sanitizer_syscall_post_impl_recvmsg(res, (long)(fd), (long)(msg), \ + (long)(flags)) +#define __sanitizer_syscall_pre_recvmmsg(fd, msg, vlen, flags, timeout) \ + __sanitizer_syscall_pre_impl_recvmmsg((long)(fd), (long)(msg), (long)(vlen), \ + (long)(flags), (long)(timeout)) +#define __sanitizer_syscall_post_recvmmsg(res, fd, msg, vlen, flags, timeout) \ + __sanitizer_syscall_post_impl_recvmmsg(res, (long)(fd), (long)(msg), \ + (long)(vlen), (long)(flags), \ + (long)(timeout)) +#define __sanitizer_syscall_pre_socket(arg0, arg1, arg2) \ + __sanitizer_syscall_pre_impl_socket((long)(arg0), (long)(arg1), (long)(arg2)) +#define __sanitizer_syscall_post_socket(res, arg0, arg1, arg2) \ + __sanitizer_syscall_post_impl_socket(res, (long)(arg0), (long)(arg1), \ + (long)(arg2)) +#define __sanitizer_syscall_pre_socketpair(arg0, arg1, arg2, arg3) \ + __sanitizer_syscall_pre_impl_socketpair((long)(arg0), (long)(arg1), \ + (long)(arg2), (long)(arg3)) +#define __sanitizer_syscall_post_socketpair(res, arg0, arg1, arg2, arg3) \ + __sanitizer_syscall_post_impl_socketpair(res, (long)(arg0), (long)(arg1), \ + (long)(arg2), (long)(arg3)) +#define __sanitizer_syscall_pre_socketcall(call, args) \ + __sanitizer_syscall_pre_impl_socketcall((long)(call), (long)(args)) +#define __sanitizer_syscall_post_socketcall(res, call, args) \ + __sanitizer_syscall_post_impl_socketcall(res, (long)(call), (long)(args)) +#define __sanitizer_syscall_pre_listen(arg0, arg1) \ + __sanitizer_syscall_pre_impl_listen((long)(arg0), (long)(arg1)) +#define __sanitizer_syscall_post_listen(res, arg0, arg1) \ + __sanitizer_syscall_post_impl_listen(res, (long)(arg0), (long)(arg1)) +#define __sanitizer_syscall_pre_poll(ufds, nfds, timeout) \ + __sanitizer_syscall_pre_impl_poll((long)(ufds), (long)(nfds), (long)(timeout)) +#define __sanitizer_syscall_post_poll(res, ufds, nfds, timeout) \ + __sanitizer_syscall_post_impl_poll(res, (long)(ufds), (long)(nfds), \ + (long)(timeout)) +#define __sanitizer_syscall_pre_select(n, inp, outp, exp, tvp) \ + __sanitizer_syscall_pre_impl_select((long)(n), (long)(inp), (long)(outp), \ + (long)(exp), (long)(tvp)) +#define __sanitizer_syscall_post_select(res, n, inp, outp, exp, tvp) \ + __sanitizer_syscall_post_impl_select(res, (long)(n), (long)(inp), \ + (long)(outp), (long)(exp), (long)(tvp)) +#define __sanitizer_syscall_pre_old_select(arg) \ + __sanitizer_syscall_pre_impl_old_select((long)(arg)) +#define __sanitizer_syscall_post_old_select(res, arg) \ + __sanitizer_syscall_post_impl_old_select(res, (long)(arg)) +#define __sanitizer_syscall_pre_epoll_create(size) \ + __sanitizer_syscall_pre_impl_epoll_create((long)(size)) +#define __sanitizer_syscall_post_epoll_create(res, size) \ + __sanitizer_syscall_post_impl_epoll_create(res, (long)(size)) +#define __sanitizer_syscall_pre_epoll_create1(flags) \ + __sanitizer_syscall_pre_impl_epoll_create1((long)(flags)) +#define __sanitizer_syscall_post_epoll_create1(res, flags) \ + __sanitizer_syscall_post_impl_epoll_create1(res, (long)(flags)) +#define __sanitizer_syscall_pre_epoll_ctl(epfd, op, fd, event) \ + __sanitizer_syscall_pre_impl_epoll_ctl((long)(epfd), (long)(op), (long)(fd), \ + (long)(event)) +#define __sanitizer_syscall_post_epoll_ctl(res, epfd, op, fd, event) \ + __sanitizer_syscall_post_impl_epoll_ctl(res, (long)(epfd), (long)(op), \ + (long)(fd), (long)(event)) +#define __sanitizer_syscall_pre_epoll_wait(epfd, events, maxevents, timeout) \ + __sanitizer_syscall_pre_impl_epoll_wait((long)(epfd), (long)(events), \ + (long)(maxevents), (long)(timeout)) +#define __sanitizer_syscall_post_epoll_wait(res, epfd, events, maxevents, \ + timeout) \ + __sanitizer_syscall_post_impl_epoll_wait(res, (long)(epfd), (long)(events), \ + (long)(maxevents), (long)(timeout)) +#define __sanitizer_syscall_pre_epoll_pwait(epfd, events, maxevents, timeout, \ + sigmask, sigsetsize) \ + __sanitizer_syscall_pre_impl_epoll_pwait( \ + (long)(epfd), (long)(events), (long)(maxevents), (long)(timeout), \ + (long)(sigmask), (long)(sigsetsize)) +#define __sanitizer_syscall_post_epoll_pwait(res, epfd, events, maxevents, \ + timeout, sigmask, sigsetsize) \ + __sanitizer_syscall_post_impl_epoll_pwait( \ + res, (long)(epfd), (long)(events), (long)(maxevents), (long)(timeout), \ + (long)(sigmask), (long)(sigsetsize)) +#define __sanitizer_syscall_pre_gethostname(name, len) \ + __sanitizer_syscall_pre_impl_gethostname((long)(name), (long)(len)) +#define __sanitizer_syscall_post_gethostname(res, name, len) \ + __sanitizer_syscall_post_impl_gethostname(res, (long)(name), (long)(len)) +#define __sanitizer_syscall_pre_sethostname(name, len) \ + __sanitizer_syscall_pre_impl_sethostname((long)(name), (long)(len)) +#define __sanitizer_syscall_post_sethostname(res, name, len) \ + __sanitizer_syscall_post_impl_sethostname(res, (long)(name), (long)(len)) +#define __sanitizer_syscall_pre_setdomainname(name, len) \ + __sanitizer_syscall_pre_impl_setdomainname((long)(name), (long)(len)) +#define __sanitizer_syscall_post_setdomainname(res, name, len) \ + __sanitizer_syscall_post_impl_setdomainname(res, (long)(name), (long)(len)) +#define __sanitizer_syscall_pre_newuname(name) \ + __sanitizer_syscall_pre_impl_newuname((long)(name)) +#define __sanitizer_syscall_post_newuname(res, name) \ + __sanitizer_syscall_post_impl_newuname(res, (long)(name)) +#define __sanitizer_syscall_pre_uname(arg0) \ + __sanitizer_syscall_pre_impl_uname((long)(arg0)) +#define __sanitizer_syscall_post_uname(res, arg0) \ + __sanitizer_syscall_post_impl_uname(res, (long)(arg0)) +#define __sanitizer_syscall_pre_olduname(arg0) \ + __sanitizer_syscall_pre_impl_olduname((long)(arg0)) +#define __sanitizer_syscall_post_olduname(res, arg0) \ + __sanitizer_syscall_post_impl_olduname(res, (long)(arg0)) +#define __sanitizer_syscall_pre_getrlimit(resource, rlim) \ + __sanitizer_syscall_pre_impl_getrlimit((long)(resource), (long)(rlim)) +#define __sanitizer_syscall_post_getrlimit(res, resource, rlim) \ + __sanitizer_syscall_post_impl_getrlimit(res, (long)(resource), (long)(rlim)) +#define __sanitizer_syscall_pre_old_getrlimit(resource, rlim) \ + __sanitizer_syscall_pre_impl_old_getrlimit((long)(resource), (long)(rlim)) +#define __sanitizer_syscall_post_old_getrlimit(res, resource, rlim) \ + __sanitizer_syscall_post_impl_old_getrlimit(res, (long)(resource), \ + (long)(rlim)) +#define __sanitizer_syscall_pre_setrlimit(resource, rlim) \ + __sanitizer_syscall_pre_impl_setrlimit((long)(resource), (long)(rlim)) +#define __sanitizer_syscall_post_setrlimit(res, resource, rlim) \ + __sanitizer_syscall_post_impl_setrlimit(res, (long)(resource), (long)(rlim)) +#define __sanitizer_syscall_pre_prlimit64(pid, resource, new_rlim, old_rlim) \ + __sanitizer_syscall_pre_impl_prlimit64((long)(pid), (long)(resource), \ + (long)(new_rlim), (long)(old_rlim)) +#define __sanitizer_syscall_post_prlimit64(res, pid, resource, new_rlim, \ + old_rlim) \ + __sanitizer_syscall_post_impl_prlimit64(res, (long)(pid), (long)(resource), \ + (long)(new_rlim), (long)(old_rlim)) +#define __sanitizer_syscall_pre_getrusage(who, ru) \ + __sanitizer_syscall_pre_impl_getrusage((long)(who), (long)(ru)) +#define __sanitizer_syscall_post_getrusage(res, who, ru) \ + __sanitizer_syscall_post_impl_getrusage(res, (long)(who), (long)(ru)) +#define __sanitizer_syscall_pre_umask(mask) \ + __sanitizer_syscall_pre_impl_umask((long)(mask)) +#define __sanitizer_syscall_post_umask(res, mask) \ + __sanitizer_syscall_post_impl_umask(res, (long)(mask)) +#define __sanitizer_syscall_pre_msgget(key, msgflg) \ + __sanitizer_syscall_pre_impl_msgget((long)(key), (long)(msgflg)) +#define __sanitizer_syscall_post_msgget(res, key, msgflg) \ + __sanitizer_syscall_post_impl_msgget(res, (long)(key), (long)(msgflg)) +#define __sanitizer_syscall_pre_msgsnd(msqid, msgp, msgsz, msgflg) \ + __sanitizer_syscall_pre_impl_msgsnd((long)(msqid), (long)(msgp), \ + (long)(msgsz), (long)(msgflg)) +#define __sanitizer_syscall_post_msgsnd(res, msqid, msgp, msgsz, msgflg) \ + __sanitizer_syscall_post_impl_msgsnd(res, (long)(msqid), (long)(msgp), \ + (long)(msgsz), (long)(msgflg)) +#define __sanitizer_syscall_pre_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg) \ + __sanitizer_syscall_pre_impl_msgrcv((long)(msqid), (long)(msgp), \ + (long)(msgsz), (long)(msgtyp), \ + (long)(msgflg)) +#define __sanitizer_syscall_post_msgrcv(res, msqid, msgp, msgsz, msgtyp, \ + msgflg) \ + __sanitizer_syscall_post_impl_msgrcv(res, (long)(msqid), (long)(msgp), \ + (long)(msgsz), (long)(msgtyp), \ + (long)(msgflg)) +#define __sanitizer_syscall_pre_msgctl(msqid, cmd, buf) \ + __sanitizer_syscall_pre_impl_msgctl((long)(msqid), (long)(cmd), (long)(buf)) +#define __sanitizer_syscall_post_msgctl(res, msqid, cmd, buf) \ + __sanitizer_syscall_post_impl_msgctl(res, (long)(msqid), (long)(cmd), \ + (long)(buf)) +#define __sanitizer_syscall_pre_semget(key, nsems, semflg) \ + __sanitizer_syscall_pre_impl_semget((long)(key), (long)(nsems), \ + (long)(semflg)) +#define __sanitizer_syscall_post_semget(res, key, nsems, semflg) \ + __sanitizer_syscall_post_impl_semget(res, (long)(key), (long)(nsems), \ + (long)(semflg)) +#define __sanitizer_syscall_pre_semop(semid, sops, nsops) \ + __sanitizer_syscall_pre_impl_semop((long)(semid), (long)(sops), (long)(nsops)) +#define __sanitizer_syscall_post_semop(res, semid, sops, nsops) \ + __sanitizer_syscall_post_impl_semop(res, (long)(semid), (long)(sops), \ + (long)(nsops)) +#define __sanitizer_syscall_pre_semctl(semid, semnum, cmd, arg) \ + __sanitizer_syscall_pre_impl_semctl((long)(semid), (long)(semnum), \ + (long)(cmd), (long)(arg)) +#define __sanitizer_syscall_post_semctl(res, semid, semnum, cmd, arg) \ + __sanitizer_syscall_post_impl_semctl(res, (long)(semid), (long)(semnum), \ + (long)(cmd), (long)(arg)) +#define __sanitizer_syscall_pre_semtimedop(semid, sops, nsops, timeout) \ + __sanitizer_syscall_pre_impl_semtimedop((long)(semid), (long)(sops), \ + (long)(nsops), (long)(timeout)) +#define __sanitizer_syscall_post_semtimedop(res, semid, sops, nsops, timeout) \ + __sanitizer_syscall_post_impl_semtimedop(res, (long)(semid), (long)(sops), \ + (long)(nsops), (long)(timeout)) +#define __sanitizer_syscall_pre_shmat(shmid, shmaddr, shmflg) \ + __sanitizer_syscall_pre_impl_shmat((long)(shmid), (long)(shmaddr), \ + (long)(shmflg)) +#define __sanitizer_syscall_post_shmat(res, shmid, shmaddr, shmflg) \ + __sanitizer_syscall_post_impl_shmat(res, (long)(shmid), (long)(shmaddr), \ + (long)(shmflg)) +#define __sanitizer_syscall_pre_shmget(key, size, flag) \ + __sanitizer_syscall_pre_impl_shmget((long)(key), (long)(size), (long)(flag)) +#define __sanitizer_syscall_post_shmget(res, key, size, flag) \ + __sanitizer_syscall_post_impl_shmget(res, (long)(key), (long)(size), \ + (long)(flag)) +#define __sanitizer_syscall_pre_shmdt(shmaddr) \ + __sanitizer_syscall_pre_impl_shmdt((long)(shmaddr)) +#define __sanitizer_syscall_post_shmdt(res, shmaddr) \ + __sanitizer_syscall_post_impl_shmdt(res, (long)(shmaddr)) +#define __sanitizer_syscall_pre_shmctl(shmid, cmd, buf) \ + __sanitizer_syscall_pre_impl_shmctl((long)(shmid), (long)(cmd), (long)(buf)) +#define __sanitizer_syscall_post_shmctl(res, shmid, cmd, buf) \ + __sanitizer_syscall_post_impl_shmctl(res, (long)(shmid), (long)(cmd), \ + (long)(buf)) +#define __sanitizer_syscall_pre_ipc(call, first, second, third, ptr, fifth) \ + __sanitizer_syscall_pre_impl_ipc((long)(call), (long)(first), \ + (long)(second), (long)(third), (long)(ptr), \ + (long)(fifth)) +#define __sanitizer_syscall_post_ipc(res, call, first, second, third, ptr, \ + fifth) \ + __sanitizer_syscall_post_impl_ipc(res, (long)(call), (long)(first), \ + (long)(second), (long)(third), \ + (long)(ptr), (long)(fifth)) +#define __sanitizer_syscall_pre_mq_open(name, oflag, mode, attr) \ + __sanitizer_syscall_pre_impl_mq_open((long)(name), (long)(oflag), \ + (long)(mode), (long)(attr)) +#define __sanitizer_syscall_post_mq_open(res, name, oflag, mode, attr) \ + __sanitizer_syscall_post_impl_mq_open(res, (long)(name), (long)(oflag), \ + (long)(mode), (long)(attr)) +#define __sanitizer_syscall_pre_mq_unlink(name) \ + __sanitizer_syscall_pre_impl_mq_unlink((long)(name)) +#define __sanitizer_syscall_post_mq_unlink(res, name) \ + __sanitizer_syscall_post_impl_mq_unlink(res, (long)(name)) +#define __sanitizer_syscall_pre_mq_timedsend(mqdes, msg_ptr, msg_len, \ + msg_prio, abs_timeout) \ + __sanitizer_syscall_pre_impl_mq_timedsend((long)(mqdes), (long)(msg_ptr), \ + (long)(msg_len), (long)(msg_prio), \ + (long)(abs_timeout)) +#define __sanitizer_syscall_post_mq_timedsend(res, mqdes, msg_ptr, msg_len, \ + msg_prio, abs_timeout) \ + __sanitizer_syscall_post_impl_mq_timedsend( \ + res, (long)(mqdes), (long)(msg_ptr), (long)(msg_len), (long)(msg_prio), \ + (long)(abs_timeout)) +#define __sanitizer_syscall_pre_mq_timedreceive(mqdes, msg_ptr, msg_len, \ + msg_prio, abs_timeout) \ + __sanitizer_syscall_pre_impl_mq_timedreceive( \ + (long)(mqdes), (long)(msg_ptr), (long)(msg_len), (long)(msg_prio), \ + (long)(abs_timeout)) +#define __sanitizer_syscall_post_mq_timedreceive(res, mqdes, msg_ptr, msg_len, \ + msg_prio, abs_timeout) \ + __sanitizer_syscall_post_impl_mq_timedreceive( \ + res, (long)(mqdes), (long)(msg_ptr), (long)(msg_len), (long)(msg_prio), \ + (long)(abs_timeout)) +#define __sanitizer_syscall_pre_mq_notify(mqdes, notification) \ + __sanitizer_syscall_pre_impl_mq_notify((long)(mqdes), (long)(notification)) +#define __sanitizer_syscall_post_mq_notify(res, mqdes, notification) \ + __sanitizer_syscall_post_impl_mq_notify(res, (long)(mqdes), \ + (long)(notification)) +#define __sanitizer_syscall_pre_mq_getsetattr(mqdes, mqstat, omqstat) \ + __sanitizer_syscall_pre_impl_mq_getsetattr((long)(mqdes), (long)(mqstat), \ + (long)(omqstat)) +#define __sanitizer_syscall_post_mq_getsetattr(res, mqdes, mqstat, omqstat) \ + __sanitizer_syscall_post_impl_mq_getsetattr(res, (long)(mqdes), \ + (long)(mqstat), (long)(omqstat)) +#define __sanitizer_syscall_pre_pciconfig_iobase(which, bus, devfn) \ + __sanitizer_syscall_pre_impl_pciconfig_iobase((long)(which), (long)(bus), \ + (long)(devfn)) +#define __sanitizer_syscall_post_pciconfig_iobase(res, which, bus, devfn) \ + __sanitizer_syscall_post_impl_pciconfig_iobase(res, (long)(which), \ + (long)(bus), (long)(devfn)) +#define __sanitizer_syscall_pre_pciconfig_read(bus, dfn, off, len, buf) \ + __sanitizer_syscall_pre_impl_pciconfig_read( \ + (long)(bus), (long)(dfn), (long)(off), (long)(len), (long)(buf)) +#define __sanitizer_syscall_post_pciconfig_read(res, bus, dfn, off, len, buf) \ + __sanitizer_syscall_post_impl_pciconfig_read( \ + res, (long)(bus), (long)(dfn), (long)(off), (long)(len), (long)(buf)) +#define __sanitizer_syscall_pre_pciconfig_write(bus, dfn, off, len, buf) \ + __sanitizer_syscall_pre_impl_pciconfig_write( \ + (long)(bus), (long)(dfn), (long)(off), (long)(len), (long)(buf)) +#define __sanitizer_syscall_post_pciconfig_write(res, bus, dfn, off, len, buf) \ + __sanitizer_syscall_post_impl_pciconfig_write( \ + res, (long)(bus), (long)(dfn), (long)(off), (long)(len), (long)(buf)) +#define __sanitizer_syscall_pre_swapon(specialfile, swap_flags) \ + __sanitizer_syscall_pre_impl_swapon((long)(specialfile), (long)(swap_flags)) +#define __sanitizer_syscall_post_swapon(res, specialfile, swap_flags) \ + __sanitizer_syscall_post_impl_swapon(res, (long)(specialfile), \ + (long)(swap_flags)) +#define __sanitizer_syscall_pre_swapoff(specialfile) \ + __sanitizer_syscall_pre_impl_swapoff((long)(specialfile)) +#define __sanitizer_syscall_post_swapoff(res, specialfile) \ + __sanitizer_syscall_post_impl_swapoff(res, (long)(specialfile)) +#define __sanitizer_syscall_pre_sysctl(args) \ + __sanitizer_syscall_pre_impl_sysctl((long)(args)) +#define __sanitizer_syscall_post_sysctl(res, args) \ + __sanitizer_syscall_post_impl_sysctl(res, (long)(args)) +#define __sanitizer_syscall_pre_sysinfo(info) \ + __sanitizer_syscall_pre_impl_sysinfo((long)(info)) +#define __sanitizer_syscall_post_sysinfo(res, info) \ + __sanitizer_syscall_post_impl_sysinfo(res, (long)(info)) +#define __sanitizer_syscall_pre_sysfs(option, arg1, arg2) \ + __sanitizer_syscall_pre_impl_sysfs((long)(option), (long)(arg1), (long)(arg2)) +#define __sanitizer_syscall_post_sysfs(res, option, arg1, arg2) \ + __sanitizer_syscall_post_impl_sysfs(res, (long)(option), (long)(arg1), \ + (long)(arg2)) +#define __sanitizer_syscall_pre_syslog(type, buf, len) \ + __sanitizer_syscall_pre_impl_syslog((long)(type), (long)(buf), (long)(len)) +#define __sanitizer_syscall_post_syslog(res, type, buf, len) \ + __sanitizer_syscall_post_impl_syslog(res, (long)(type), (long)(buf), \ + (long)(len)) +#define __sanitizer_syscall_pre_uselib(library) \ + __sanitizer_syscall_pre_impl_uselib((long)(library)) +#define __sanitizer_syscall_post_uselib(res, library) \ + __sanitizer_syscall_post_impl_uselib(res, (long)(library)) +#define __sanitizer_syscall_pre_ni_syscall() \ + __sanitizer_syscall_pre_impl_ni_syscall() +#define __sanitizer_syscall_post_ni_syscall(res) \ + __sanitizer_syscall_post_impl_ni_syscall(res) +#define __sanitizer_syscall_pre_ptrace(request, pid, addr, data) \ + __sanitizer_syscall_pre_impl_ptrace((long)(request), (long)(pid), \ + (long)(addr), (long)(data)) +#define __sanitizer_syscall_post_ptrace(res, request, pid, addr, data) \ + __sanitizer_syscall_post_impl_ptrace(res, (long)(request), (long)(pid), \ + (long)(addr), (long)(data)) +#define __sanitizer_syscall_pre_add_key(_type, _description, _payload, plen, \ + destringid) \ + __sanitizer_syscall_pre_impl_add_key((long)(_type), (long)(_description), \ + (long)(_payload), (long)(plen), \ + (long)(destringid)) +#define __sanitizer_syscall_post_add_key(res, _type, _description, _payload, \ + plen, destringid) \ + __sanitizer_syscall_post_impl_add_key( \ + res, (long)(_type), (long)(_description), (long)(_payload), \ + (long)(plen), (long)(destringid)) +#define __sanitizer_syscall_pre_request_key(_type, _description, \ + _callout_info, destringid) \ + __sanitizer_syscall_pre_impl_request_key( \ + (long)(_type), (long)(_description), (long)(_callout_info), \ + (long)(destringid)) +#define __sanitizer_syscall_post_request_key(res, _type, _description, \ + _callout_info, destringid) \ + __sanitizer_syscall_post_impl_request_key( \ + res, (long)(_type), (long)(_description), (long)(_callout_info), \ + (long)(destringid)) +#define __sanitizer_syscall_pre_keyctl(cmd, arg2, arg3, arg4, arg5) \ + __sanitizer_syscall_pre_impl_keyctl((long)(cmd), (long)(arg2), (long)(arg3), \ + (long)(arg4), (long)(arg5)) +#define __sanitizer_syscall_post_keyctl(res, cmd, arg2, arg3, arg4, arg5) \ + __sanitizer_syscall_post_impl_keyctl(res, (long)(cmd), (long)(arg2), \ + (long)(arg3), (long)(arg4), \ + (long)(arg5)) +#define __sanitizer_syscall_pre_ioprio_set(which, who, ioprio) \ + __sanitizer_syscall_pre_impl_ioprio_set((long)(which), (long)(who), \ + (long)(ioprio)) +#define __sanitizer_syscall_post_ioprio_set(res, which, who, ioprio) \ + __sanitizer_syscall_post_impl_ioprio_set(res, (long)(which), (long)(who), \ + (long)(ioprio)) +#define __sanitizer_syscall_pre_ioprio_get(which, who) \ + __sanitizer_syscall_pre_impl_ioprio_get((long)(which), (long)(who)) +#define __sanitizer_syscall_post_ioprio_get(res, which, who) \ + __sanitizer_syscall_post_impl_ioprio_get(res, (long)(which), (long)(who)) +#define __sanitizer_syscall_pre_set_mempolicy(mode, nmask, maxnode) \ + __sanitizer_syscall_pre_impl_set_mempolicy((long)(mode), (long)(nmask), \ + (long)(maxnode)) +#define __sanitizer_syscall_post_set_mempolicy(res, mode, nmask, maxnode) \ + __sanitizer_syscall_post_impl_set_mempolicy(res, (long)(mode), \ + (long)(nmask), (long)(maxnode)) +#define __sanitizer_syscall_pre_migrate_pages(pid, maxnode, from, to) \ + __sanitizer_syscall_pre_impl_migrate_pages((long)(pid), (long)(maxnode), \ + (long)(from), (long)(to)) +#define __sanitizer_syscall_post_migrate_pages(res, pid, maxnode, from, to) \ + __sanitizer_syscall_post_impl_migrate_pages( \ + res, (long)(pid), (long)(maxnode), (long)(from), (long)(to)) +#define __sanitizer_syscall_pre_move_pages(pid, nr_pages, pages, nodes, \ + status, flags) \ + __sanitizer_syscall_pre_impl_move_pages((long)(pid), (long)(nr_pages), \ + (long)(pages), (long)(nodes), \ + (long)(status), (long)(flags)) +#define __sanitizer_syscall_post_move_pages(res, pid, nr_pages, pages, nodes, \ + status, flags) \ + __sanitizer_syscall_post_impl_move_pages(res, (long)(pid), (long)(nr_pages), \ + (long)(pages), (long)(nodes), \ + (long)(status), (long)(flags)) +#define __sanitizer_syscall_pre_mbind(start, len, mode, nmask, maxnode, flags) \ + __sanitizer_syscall_pre_impl_mbind((long)(start), (long)(len), (long)(mode), \ + (long)(nmask), (long)(maxnode), \ + (long)(flags)) +#define __sanitizer_syscall_post_mbind(res, start, len, mode, nmask, maxnode, \ + flags) \ + __sanitizer_syscall_post_impl_mbind(res, (long)(start), (long)(len), \ + (long)(mode), (long)(nmask), \ + (long)(maxnode), (long)(flags)) +#define __sanitizer_syscall_pre_get_mempolicy(policy, nmask, maxnode, addr, \ + flags) \ + __sanitizer_syscall_pre_impl_get_mempolicy((long)(policy), (long)(nmask), \ + (long)(maxnode), (long)(addr), \ + (long)(flags)) +#define __sanitizer_syscall_post_get_mempolicy(res, policy, nmask, maxnode, \ + addr, flags) \ + __sanitizer_syscall_post_impl_get_mempolicy(res, (long)(policy), \ + (long)(nmask), (long)(maxnode), \ + (long)(addr), (long)(flags)) +#define __sanitizer_syscall_pre_inotify_init() \ + __sanitizer_syscall_pre_impl_inotify_init() +#define __sanitizer_syscall_post_inotify_init(res) \ + __sanitizer_syscall_post_impl_inotify_init(res) +#define __sanitizer_syscall_pre_inotify_init1(flags) \ + __sanitizer_syscall_pre_impl_inotify_init1((long)(flags)) +#define __sanitizer_syscall_post_inotify_init1(res, flags) \ + __sanitizer_syscall_post_impl_inotify_init1(res, (long)(flags)) +#define __sanitizer_syscall_pre_inotify_add_watch(fd, path, mask) \ + __sanitizer_syscall_pre_impl_inotify_add_watch((long)(fd), (long)(path), \ + (long)(mask)) +#define __sanitizer_syscall_post_inotify_add_watch(res, fd, path, mask) \ + __sanitizer_syscall_post_impl_inotify_add_watch(res, (long)(fd), \ + (long)(path), (long)(mask)) +#define __sanitizer_syscall_pre_inotify_rm_watch(fd, wd) \ + __sanitizer_syscall_pre_impl_inotify_rm_watch((long)(fd), (long)(wd)) +#define __sanitizer_syscall_post_inotify_rm_watch(res, fd, wd) \ + __sanitizer_syscall_post_impl_inotify_rm_watch(res, (long)(fd), (long)(wd)) +#define __sanitizer_syscall_pre_spu_run(fd, unpc, ustatus) \ + __sanitizer_syscall_pre_impl_spu_run((long)(fd), (long)(unpc), \ + (long)(ustatus)) +#define __sanitizer_syscall_post_spu_run(res, fd, unpc, ustatus) \ + __sanitizer_syscall_post_impl_spu_run(res, (long)(fd), (long)(unpc), \ + (long)(ustatus)) +#define __sanitizer_syscall_pre_spu_create(name, flags, mode, fd) \ + __sanitizer_syscall_pre_impl_spu_create((long)(name), (long)(flags), \ + (long)(mode), (long)(fd)) +#define __sanitizer_syscall_post_spu_create(res, name, flags, mode, fd) \ + __sanitizer_syscall_post_impl_spu_create(res, (long)(name), (long)(flags), \ + (long)(mode), (long)(fd)) +#define __sanitizer_syscall_pre_mknodat(dfd, filename, mode, dev) \ + __sanitizer_syscall_pre_impl_mknodat((long)(dfd), (long)(filename), \ + (long)(mode), (long)(dev)) +#define __sanitizer_syscall_post_mknodat(res, dfd, filename, mode, dev) \ + __sanitizer_syscall_post_impl_mknodat(res, (long)(dfd), (long)(filename), \ + (long)(mode), (long)(dev)) +#define __sanitizer_syscall_pre_mkdirat(dfd, pathname, mode) \ + __sanitizer_syscall_pre_impl_mkdirat((long)(dfd), (long)(pathname), \ + (long)(mode)) +#define __sanitizer_syscall_post_mkdirat(res, dfd, pathname, mode) \ + __sanitizer_syscall_post_impl_mkdirat(res, (long)(dfd), (long)(pathname), \ + (long)(mode)) +#define __sanitizer_syscall_pre_unlinkat(dfd, pathname, flag) \ + __sanitizer_syscall_pre_impl_unlinkat((long)(dfd), (long)(pathname), \ + (long)(flag)) +#define __sanitizer_syscall_post_unlinkat(res, dfd, pathname, flag) \ + __sanitizer_syscall_post_impl_unlinkat(res, (long)(dfd), (long)(pathname), \ + (long)(flag)) +#define __sanitizer_syscall_pre_symlinkat(oldname, newdfd, newname) \ + __sanitizer_syscall_pre_impl_symlinkat((long)(oldname), (long)(newdfd), \ + (long)(newname)) +#define __sanitizer_syscall_post_symlinkat(res, oldname, newdfd, newname) \ + __sanitizer_syscall_post_impl_symlinkat(res, (long)(oldname), \ + (long)(newdfd), (long)(newname)) +#define __sanitizer_syscall_pre_linkat(olddfd, oldname, newdfd, newname, \ + flags) \ + __sanitizer_syscall_pre_impl_linkat((long)(olddfd), (long)(oldname), \ + (long)(newdfd), (long)(newname), \ + (long)(flags)) +#define __sanitizer_syscall_post_linkat(res, olddfd, oldname, newdfd, newname, \ + flags) \ + __sanitizer_syscall_post_impl_linkat(res, (long)(olddfd), (long)(oldname), \ + (long)(newdfd), (long)(newname), \ + (long)(flags)) +#define __sanitizer_syscall_pre_renameat(olddfd, oldname, newdfd, newname) \ + __sanitizer_syscall_pre_impl_renameat((long)(olddfd), (long)(oldname), \ + (long)(newdfd), (long)(newname)) +#define __sanitizer_syscall_post_renameat(res, olddfd, oldname, newdfd, \ + newname) \ + __sanitizer_syscall_post_impl_renameat(res, (long)(olddfd), (long)(oldname), \ + (long)(newdfd), (long)(newname)) +#define __sanitizer_syscall_pre_futimesat(dfd, filename, utimes) \ + __sanitizer_syscall_pre_impl_futimesat((long)(dfd), (long)(filename), \ + (long)(utimes)) +#define __sanitizer_syscall_post_futimesat(res, dfd, filename, utimes) \ + __sanitizer_syscall_post_impl_futimesat(res, (long)(dfd), (long)(filename), \ + (long)(utimes)) +#define __sanitizer_syscall_pre_faccessat(dfd, filename, mode) \ + __sanitizer_syscall_pre_impl_faccessat((long)(dfd), (long)(filename), \ + (long)(mode)) +#define __sanitizer_syscall_post_faccessat(res, dfd, filename, mode) \ + __sanitizer_syscall_post_impl_faccessat(res, (long)(dfd), (long)(filename), \ + (long)(mode)) +#define __sanitizer_syscall_pre_fchmodat(dfd, filename, mode) \ + __sanitizer_syscall_pre_impl_fchmodat((long)(dfd), (long)(filename), \ + (long)(mode)) +#define __sanitizer_syscall_post_fchmodat(res, dfd, filename, mode) \ + __sanitizer_syscall_post_impl_fchmodat(res, (long)(dfd), (long)(filename), \ + (long)(mode)) +#define __sanitizer_syscall_pre_fchownat(dfd, filename, user, group, flag) \ + __sanitizer_syscall_pre_impl_fchownat((long)(dfd), (long)(filename), \ + (long)(user), (long)(group), \ + (long)(flag)) +#define __sanitizer_syscall_post_fchownat(res, dfd, filename, user, group, \ + flag) \ + __sanitizer_syscall_post_impl_fchownat(res, (long)(dfd), (long)(filename), \ + (long)(user), (long)(group), \ + (long)(flag)) +#define __sanitizer_syscall_pre_openat(dfd, filename, flags, mode) \ + __sanitizer_syscall_pre_impl_openat((long)(dfd), (long)(filename), \ + (long)(flags), (long)(mode)) +#define __sanitizer_syscall_post_openat(res, dfd, filename, flags, mode) \ + __sanitizer_syscall_post_impl_openat(res, (long)(dfd), (long)(filename), \ + (long)(flags), (long)(mode)) +#define __sanitizer_syscall_pre_newfstatat(dfd, filename, statbuf, flag) \ + __sanitizer_syscall_pre_impl_newfstatat((long)(dfd), (long)(filename), \ + (long)(statbuf), (long)(flag)) +#define __sanitizer_syscall_post_newfstatat(res, dfd, filename, statbuf, flag) \ + __sanitizer_syscall_post_impl_newfstatat(res, (long)(dfd), (long)(filename), \ + (long)(statbuf), (long)(flag)) +#define __sanitizer_syscall_pre_fstatat64(dfd, filename, statbuf, flag) \ + __sanitizer_syscall_pre_impl_fstatat64((long)(dfd), (long)(filename), \ + (long)(statbuf), (long)(flag)) +#define __sanitizer_syscall_post_fstatat64(res, dfd, filename, statbuf, flag) \ + __sanitizer_syscall_post_impl_fstatat64(res, (long)(dfd), (long)(filename), \ + (long)(statbuf), (long)(flag)) +#define __sanitizer_syscall_pre_readlinkat(dfd, path, buf, bufsiz) \ + __sanitizer_syscall_pre_impl_readlinkat((long)(dfd), (long)(path), \ + (long)(buf), (long)(bufsiz)) +#define __sanitizer_syscall_post_readlinkat(res, dfd, path, buf, bufsiz) \ + __sanitizer_syscall_post_impl_readlinkat(res, (long)(dfd), (long)(path), \ + (long)(buf), (long)(bufsiz)) +#define __sanitizer_syscall_pre_utimensat(dfd, filename, utimes, flags) \ + __sanitizer_syscall_pre_impl_utimensat((long)(dfd), (long)(filename), \ + (long)(utimes), (long)(flags)) +#define __sanitizer_syscall_post_utimensat(res, dfd, filename, utimes, flags) \ + __sanitizer_syscall_post_impl_utimensat(res, (long)(dfd), (long)(filename), \ + (long)(utimes), (long)(flags)) +#define __sanitizer_syscall_pre_unshare(unshare_flags) \ + __sanitizer_syscall_pre_impl_unshare((long)(unshare_flags)) +#define __sanitizer_syscall_post_unshare(res, unshare_flags) \ + __sanitizer_syscall_post_impl_unshare(res, (long)(unshare_flags)) +#define __sanitizer_syscall_pre_splice(fd_in, off_in, fd_out, off_out, len, \ + flags) \ + __sanitizer_syscall_pre_impl_splice((long)(fd_in), (long)(off_in), \ + (long)(fd_out), (long)(off_out), \ + (long)(len), (long)(flags)) +#define __sanitizer_syscall_post_splice(res, fd_in, off_in, fd_out, off_out, \ + len, flags) \ + __sanitizer_syscall_post_impl_splice(res, (long)(fd_in), (long)(off_in), \ + (long)(fd_out), (long)(off_out), \ + (long)(len), (long)(flags)) +#define __sanitizer_syscall_pre_vmsplice(fd, iov, nr_segs, flags) \ + __sanitizer_syscall_pre_impl_vmsplice((long)(fd), (long)(iov), \ + (long)(nr_segs), (long)(flags)) +#define __sanitizer_syscall_post_vmsplice(res, fd, iov, nr_segs, flags) \ + __sanitizer_syscall_post_impl_vmsplice(res, (long)(fd), (long)(iov), \ + (long)(nr_segs), (long)(flags)) +#define __sanitizer_syscall_pre_tee(fdin, fdout, len, flags) \ + __sanitizer_syscall_pre_impl_tee((long)(fdin), (long)(fdout), (long)(len), \ + (long)(flags)) +#define __sanitizer_syscall_post_tee(res, fdin, fdout, len, flags) \ + __sanitizer_syscall_post_impl_tee(res, (long)(fdin), (long)(fdout), \ + (long)(len), (long)(flags)) +#define __sanitizer_syscall_pre_get_robust_list(pid, head_ptr, len_ptr) \ + __sanitizer_syscall_pre_impl_get_robust_list((long)(pid), (long)(head_ptr), \ + (long)(len_ptr)) +#define __sanitizer_syscall_post_get_robust_list(res, pid, head_ptr, len_ptr) \ + __sanitizer_syscall_post_impl_get_robust_list( \ + res, (long)(pid), (long)(head_ptr), (long)(len_ptr)) +#define __sanitizer_syscall_pre_set_robust_list(head, len) \ + __sanitizer_syscall_pre_impl_set_robust_list((long)(head), (long)(len)) +#define __sanitizer_syscall_post_set_robust_list(res, head, len) \ + __sanitizer_syscall_post_impl_set_robust_list(res, (long)(head), (long)(len)) +#define __sanitizer_syscall_pre_getcpu(cpu, node, cache) \ + __sanitizer_syscall_pre_impl_getcpu((long)(cpu), (long)(node), (long)(cache)) +#define __sanitizer_syscall_post_getcpu(res, cpu, node, cache) \ + __sanitizer_syscall_post_impl_getcpu(res, (long)(cpu), (long)(node), \ + (long)(cache)) +#define __sanitizer_syscall_pre_signalfd(ufd, user_mask, sizemask) \ + __sanitizer_syscall_pre_impl_signalfd((long)(ufd), (long)(user_mask), \ + (long)(sizemask)) +#define __sanitizer_syscall_post_signalfd(res, ufd, user_mask, sizemask) \ + __sanitizer_syscall_post_impl_signalfd(res, (long)(ufd), (long)(user_mask), \ + (long)(sizemask)) +#define __sanitizer_syscall_pre_signalfd4(ufd, user_mask, sizemask, flags) \ + __sanitizer_syscall_pre_impl_signalfd4((long)(ufd), (long)(user_mask), \ + (long)(sizemask), (long)(flags)) +#define __sanitizer_syscall_post_signalfd4(res, ufd, user_mask, sizemask, \ + flags) \ + __sanitizer_syscall_post_impl_signalfd4(res, (long)(ufd), (long)(user_mask), \ + (long)(sizemask), (long)(flags)) +#define __sanitizer_syscall_pre_timerfd_create(clockid, flags) \ + __sanitizer_syscall_pre_impl_timerfd_create((long)(clockid), (long)(flags)) +#define __sanitizer_syscall_post_timerfd_create(res, clockid, flags) \ + __sanitizer_syscall_post_impl_timerfd_create(res, (long)(clockid), \ + (long)(flags)) +#define __sanitizer_syscall_pre_timerfd_settime(ufd, flags, utmr, otmr) \ + __sanitizer_syscall_pre_impl_timerfd_settime((long)(ufd), (long)(flags), \ + (long)(utmr), (long)(otmr)) +#define __sanitizer_syscall_post_timerfd_settime(res, ufd, flags, utmr, otmr) \ + __sanitizer_syscall_post_impl_timerfd_settime( \ + res, (long)(ufd), (long)(flags), (long)(utmr), (long)(otmr)) +#define __sanitizer_syscall_pre_timerfd_gettime(ufd, otmr) \ + __sanitizer_syscall_pre_impl_timerfd_gettime((long)(ufd), (long)(otmr)) +#define __sanitizer_syscall_post_timerfd_gettime(res, ufd, otmr) \ + __sanitizer_syscall_post_impl_timerfd_gettime(res, (long)(ufd), (long)(otmr)) +#define __sanitizer_syscall_pre_eventfd(count) \ + __sanitizer_syscall_pre_impl_eventfd((long)(count)) +#define __sanitizer_syscall_post_eventfd(res, count) \ + __sanitizer_syscall_post_impl_eventfd(res, (long)(count)) +#define __sanitizer_syscall_pre_eventfd2(count, flags) \ + __sanitizer_syscall_pre_impl_eventfd2((long)(count), (long)(flags)) +#define __sanitizer_syscall_post_eventfd2(res, count, flags) \ + __sanitizer_syscall_post_impl_eventfd2(res, (long)(count), (long)(flags)) +#define __sanitizer_syscall_pre_old_readdir(arg0, arg1, arg2) \ + __sanitizer_syscall_pre_impl_old_readdir((long)(arg0), (long)(arg1), \ + (long)(arg2)) +#define __sanitizer_syscall_post_old_readdir(res, arg0, arg1, arg2) \ + __sanitizer_syscall_post_impl_old_readdir(res, (long)(arg0), (long)(arg1), \ + (long)(arg2)) +#define __sanitizer_syscall_pre_pselect6(arg0, arg1, arg2, arg3, arg4, arg5) \ + __sanitizer_syscall_pre_impl_pselect6((long)(arg0), (long)(arg1), \ + (long)(arg2), (long)(arg3), \ + (long)(arg4), (long)(arg5)) +#define __sanitizer_syscall_post_pselect6(res, arg0, arg1, arg2, arg3, arg4, \ + arg5) \ + __sanitizer_syscall_post_impl_pselect6(res, (long)(arg0), (long)(arg1), \ + (long)(arg2), (long)(arg3), \ + (long)(arg4), (long)(arg5)) +#define __sanitizer_syscall_pre_ppoll(arg0, arg1, arg2, arg3, arg4) \ + __sanitizer_syscall_pre_impl_ppoll((long)(arg0), (long)(arg1), (long)(arg2), \ + (long)(arg3), (long)(arg4)) +#define __sanitizer_syscall_post_ppoll(res, arg0, arg1, arg2, arg3, arg4) \ + __sanitizer_syscall_post_impl_ppoll(res, (long)(arg0), (long)(arg1), \ + (long)(arg2), (long)(arg3), \ + (long)(arg4)) +#define __sanitizer_syscall_pre_syncfs(fd) \ + __sanitizer_syscall_pre_impl_syncfs((long)(fd)) +#define __sanitizer_syscall_post_syncfs(res, fd) \ + __sanitizer_syscall_post_impl_syncfs(res, (long)(fd)) +#define __sanitizer_syscall_pre_perf_event_open(attr_uptr, pid, cpu, group_fd, \ + flags) \ + __sanitizer_syscall_pre_impl_perf_event_open((long)(attr_uptr), (long)(pid), \ + (long)(cpu), (long)(group_fd), \ + (long)(flags)) +#define __sanitizer_syscall_post_perf_event_open(res, attr_uptr, pid, cpu, \ + group_fd, flags) \ + __sanitizer_syscall_post_impl_perf_event_open( \ + res, (long)(attr_uptr), (long)(pid), (long)(cpu), (long)(group_fd), \ + (long)(flags)) +#define __sanitizer_syscall_pre_mmap_pgoff(addr, len, prot, flags, fd, pgoff) \ + __sanitizer_syscall_pre_impl_mmap_pgoff((long)(addr), (long)(len), \ + (long)(prot), (long)(flags), \ + (long)(fd), (long)(pgoff)) +#define __sanitizer_syscall_post_mmap_pgoff(res, addr, len, prot, flags, fd, \ + pgoff) \ + __sanitizer_syscall_post_impl_mmap_pgoff(res, (long)(addr), (long)(len), \ + (long)(prot), (long)(flags), \ + (long)(fd), (long)(pgoff)) +#define __sanitizer_syscall_pre_old_mmap(arg) \ + __sanitizer_syscall_pre_impl_old_mmap((long)(arg)) +#define __sanitizer_syscall_post_old_mmap(res, arg) \ + __sanitizer_syscall_post_impl_old_mmap(res, (long)(arg)) +#define __sanitizer_syscall_pre_name_to_handle_at(dfd, name, handle, mnt_id, \ + flag) \ + __sanitizer_syscall_pre_impl_name_to_handle_at( \ + (long)(dfd), (long)(name), (long)(handle), (long)(mnt_id), (long)(flag)) +#define __sanitizer_syscall_post_name_to_handle_at(res, dfd, name, handle, \ + mnt_id, flag) \ + __sanitizer_syscall_post_impl_name_to_handle_at( \ + res, (long)(dfd), (long)(name), (long)(handle), (long)(mnt_id), \ + (long)(flag)) +#define __sanitizer_syscall_pre_open_by_handle_at(mountdirfd, handle, flags) \ + __sanitizer_syscall_pre_impl_open_by_handle_at( \ + (long)(mountdirfd), (long)(handle), (long)(flags)) +#define __sanitizer_syscall_post_open_by_handle_at(res, mountdirfd, handle, \ + flags) \ + __sanitizer_syscall_post_impl_open_by_handle_at( \ + res, (long)(mountdirfd), (long)(handle), (long)(flags)) +#define __sanitizer_syscall_pre_setns(fd, nstype) \ + __sanitizer_syscall_pre_impl_setns((long)(fd), (long)(nstype)) +#define __sanitizer_syscall_post_setns(res, fd, nstype) \ + __sanitizer_syscall_post_impl_setns(res, (long)(fd), (long)(nstype)) +#define __sanitizer_syscall_pre_process_vm_readv(pid, lvec, liovcnt, rvec, \ + riovcnt, flags) \ + __sanitizer_syscall_pre_impl_process_vm_readv( \ + (long)(pid), (long)(lvec), (long)(liovcnt), (long)(rvec), \ + (long)(riovcnt), (long)(flags)) +#define __sanitizer_syscall_post_process_vm_readv(res, pid, lvec, liovcnt, \ + rvec, riovcnt, flags) \ + __sanitizer_syscall_post_impl_process_vm_readv( \ + res, (long)(pid), (long)(lvec), (long)(liovcnt), (long)(rvec), \ + (long)(riovcnt), (long)(flags)) +#define __sanitizer_syscall_pre_process_vm_writev(pid, lvec, liovcnt, rvec, \ + riovcnt, flags) \ + __sanitizer_syscall_pre_impl_process_vm_writev( \ + (long)(pid), (long)(lvec), (long)(liovcnt), (long)(rvec), \ + (long)(riovcnt), (long)(flags)) +#define __sanitizer_syscall_post_process_vm_writev(res, pid, lvec, liovcnt, \ + rvec, riovcnt, flags) \ + __sanitizer_syscall_post_impl_process_vm_writev( \ + res, (long)(pid), (long)(lvec), (long)(liovcnt), (long)(rvec), \ + (long)(riovcnt), (long)(flags)) +#define __sanitizer_syscall_pre_fork() \ + __sanitizer_syscall_pre_impl_fork() +#define __sanitizer_syscall_post_fork(res) \ + __sanitizer_syscall_post_impl_fork(res) +#define __sanitizer_syscall_pre_vfork() \ + __sanitizer_syscall_pre_impl_vfork() +#define __sanitizer_syscall_post_vfork(res) \ + __sanitizer_syscall_post_impl_vfork(res) // And now a few syscalls we don't handle yet. - -#define __sanitizer_syscall_pre_accept(...) -#define __sanitizer_syscall_pre_accept4(...) -#define __sanitizer_syscall_pre_access(...) -#define __sanitizer_syscall_pre_acct(...) -#define __sanitizer_syscall_pre_add_key(...) -#define __sanitizer_syscall_pre_adjtimex(...) #define __sanitizer_syscall_pre_afs_syscall(...) -#define __sanitizer_syscall_pre_alarm(...) #define __sanitizer_syscall_pre_arch_prctl(...) -#define __sanitizer_syscall_pre_bdflush(...) -#define __sanitizer_syscall_pre_bind(...) #define __sanitizer_syscall_pre_break(...) -#define __sanitizer_syscall_pre_brk(...) -#define __sanitizer_syscall_pre_capget(...) -#define __sanitizer_syscall_pre_capset(...) -#define __sanitizer_syscall_pre_chdir(...) -#define __sanitizer_syscall_pre_chmod(...) -#define __sanitizer_syscall_pre_chown(...) #define __sanitizer_syscall_pre_chown32(...) -#define __sanitizer_syscall_pre_chroot(...) -#define __sanitizer_syscall_pre_clock_adjtime(...) -#define __sanitizer_syscall_pre_clock_getres(...) -#define __sanitizer_syscall_pre_clock_gettime(...) -#define __sanitizer_syscall_pre_clock_nanosleep(...) -#define __sanitizer_syscall_pre_clock_settime(...) #define __sanitizer_syscall_pre_clone(...) -#define __sanitizer_syscall_pre_close(...) -#define __sanitizer_syscall_pre_connect(...) -#define __sanitizer_syscall_pre_creat(...) #define __sanitizer_syscall_pre_create_module(...) -#define __sanitizer_syscall_pre_delete_module(...) -#define __sanitizer_syscall_pre_dup(...) -#define __sanitizer_syscall_pre_dup2(...) -#define __sanitizer_syscall_pre_dup3(...) -#define __sanitizer_syscall_pre_epoll_create(...) -#define __sanitizer_syscall_pre_epoll_create1(...) -#define __sanitizer_syscall_pre_epoll_ctl(...) #define __sanitizer_syscall_pre_epoll_ctl_old(...) -#define __sanitizer_syscall_pre_epoll_pwait(...) -#define __sanitizer_syscall_pre_epoll_wait(...) #define __sanitizer_syscall_pre_epoll_wait_old(...) -#define __sanitizer_syscall_pre_eventfd(...) -#define __sanitizer_syscall_pre_eventfd2(...) #define __sanitizer_syscall_pre_execve(...) -#define __sanitizer_syscall_pre_exit(...) -#define __sanitizer_syscall_pre_exit_group(...) -#define __sanitizer_syscall_pre_faccessat(...) #define __sanitizer_syscall_pre_fadvise64(...) #define __sanitizer_syscall_pre_fadvise64_64(...) #define __sanitizer_syscall_pre_fallocate(...) #define __sanitizer_syscall_pre_fanotify_init(...) #define __sanitizer_syscall_pre_fanotify_mark(...) -#define __sanitizer_syscall_pre_fchdir(...) -#define __sanitizer_syscall_pre_fchmod(...) -#define __sanitizer_syscall_pre_fchmodat(...) -#define __sanitizer_syscall_pre_fchown(...) #define __sanitizer_syscall_pre_fchown32(...) -#define __sanitizer_syscall_pre_fchownat(...) -#define __sanitizer_syscall_pre_fcntl(...) -#define __sanitizer_syscall_pre_fcntl64(...) -#define __sanitizer_syscall_pre_fdatasync(...) -#define __sanitizer_syscall_pre_fgetxattr(...) -#define __sanitizer_syscall_pre_flistxattr(...) -#define __sanitizer_syscall_pre_flock(...) -#define __sanitizer_syscall_pre_fork(...) -#define __sanitizer_syscall_pre_fremovexattr(...) -#define __sanitizer_syscall_pre_fsetxattr(...) -#define __sanitizer_syscall_pre_fstat(...) -#define __sanitizer_syscall_pre_fstat64(...) -#define __sanitizer_syscall_pre_fstatat64(...) -#define __sanitizer_syscall_pre_fstatfs(...) -#define __sanitizer_syscall_pre_fstatfs64(...) -#define __sanitizer_syscall_pre_fsync(...) #define __sanitizer_syscall_pre_ftime(...) -#define __sanitizer_syscall_pre_ftruncate(...) #define __sanitizer_syscall_pre_ftruncate64(...) #define __sanitizer_syscall_pre_futex(...) -#define __sanitizer_syscall_pre_futimesat(...) -#define __sanitizer_syscall_pre_getcpu(...) -#define __sanitizer_syscall_pre_getcwd(...) -#define __sanitizer_syscall_pre_getegid(...) #define __sanitizer_syscall_pre_getegid32(...) -#define __sanitizer_syscall_pre_geteuid(...) #define __sanitizer_syscall_pre_geteuid32(...) -#define __sanitizer_syscall_pre_getgid(...) #define __sanitizer_syscall_pre_getgid32(...) -#define __sanitizer_syscall_pre_getgroups(...) #define __sanitizer_syscall_pre_getgroups32(...) -#define __sanitizer_syscall_pre_getitimer(...) #define __sanitizer_syscall_pre_get_kernel_syms(...) -#define __sanitizer_syscall_pre_get_mempolicy(...) -#define __sanitizer_syscall_pre_getpeername(...) -#define __sanitizer_syscall_pre_getpgid(...) -#define __sanitizer_syscall_pre_getpgrp(...) -#define __sanitizer_syscall_pre_getpid(...) #define __sanitizer_syscall_pre_getpmsg(...) -#define __sanitizer_syscall_pre_getppid(...) -#define __sanitizer_syscall_pre_getpriority(...) -#define __sanitizer_syscall_pre_getresgid(...) #define __sanitizer_syscall_pre_getresgid32(...) -#define __sanitizer_syscall_pre_getresuid(...) #define __sanitizer_syscall_pre_getresuid32(...) -#define __sanitizer_syscall_pre_getrlimit(...) -#define __sanitizer_syscall_pre_get_robust_list(...) -#define __sanitizer_syscall_pre_getrusage(...) -#define __sanitizer_syscall_pre_getsid(...) -#define __sanitizer_syscall_pre_getsockname(...) -#define __sanitizer_syscall_pre_getsockopt(...) #define __sanitizer_syscall_pre_get_thread_area(...) -#define __sanitizer_syscall_pre_gettid(...) -#define __sanitizer_syscall_pre_gettimeofday(...) -#define __sanitizer_syscall_pre_getuid(...) #define __sanitizer_syscall_pre_getuid32(...) -#define __sanitizer_syscall_pre_getxattr(...) #define __sanitizer_syscall_pre_gtty(...) #define __sanitizer_syscall_pre_idle(...) -#define __sanitizer_syscall_pre_init_module(...) -#define __sanitizer_syscall_pre_inotify_add_watch(...) -#define __sanitizer_syscall_pre_inotify_init(...) -#define __sanitizer_syscall_pre_inotify_init1(...) -#define __sanitizer_syscall_pre_inotify_rm_watch(...) -#define __sanitizer_syscall_pre_io_cancel(...) -#define __sanitizer_syscall_pre_ioctl(...) -#define __sanitizer_syscall_pre_io_destroy(...) -#define __sanitizer_syscall_pre_io_getevents(...) -#define __sanitizer_syscall_pre_ioperm(...) #define __sanitizer_syscall_pre_iopl(...) -#define __sanitizer_syscall_pre_ioprio_get(...) -#define __sanitizer_syscall_pre_ioprio_set(...) -#define __sanitizer_syscall_pre_io_setup(...) -#define __sanitizer_syscall_pre_io_submit(...) -#define __sanitizer_syscall_pre_ipc(...) -#define __sanitizer_syscall_pre_kexec_load(...) -#define __sanitizer_syscall_pre_keyctl(...) -#define __sanitizer_syscall_pre_kill(...) -#define __sanitizer_syscall_pre_lchown(...) #define __sanitizer_syscall_pre_lchown32(...) -#define __sanitizer_syscall_pre_lgetxattr(...) -#define __sanitizer_syscall_pre_link(...) -#define __sanitizer_syscall_pre_linkat(...) -#define __sanitizer_syscall_pre_listen(...) -#define __sanitizer_syscall_pre_listxattr(...) -#define __sanitizer_syscall_pre_llistxattr(...) #define __sanitizer_syscall_pre__llseek(...) #define __sanitizer_syscall_pre_lock(...) -#define __sanitizer_syscall_pre_lookup_dcookie(...) -#define __sanitizer_syscall_pre_lremovexattr(...) -#define __sanitizer_syscall_pre_lseek(...) -#define __sanitizer_syscall_pre_lsetxattr(...) -#define __sanitizer_syscall_pre_lstat(...) -#define __sanitizer_syscall_pre_lstat64(...) -#define __sanitizer_syscall_pre_madvise(...) #define __sanitizer_syscall_pre_madvise1(...) -#define __sanitizer_syscall_pre_mbind(...) -#define __sanitizer_syscall_pre_migrate_pages(...) -#define __sanitizer_syscall_pre_mincore(...) -#define __sanitizer_syscall_pre_mkdir(...) -#define __sanitizer_syscall_pre_mkdirat(...) -#define __sanitizer_syscall_pre_mknod(...) -#define __sanitizer_syscall_pre_mknodat(...) -#define __sanitizer_syscall_pre_mlock(...) -#define __sanitizer_syscall_pre_mlockall(...) #define __sanitizer_syscall_pre_mmap(...) #define __sanitizer_syscall_pre_mmap2(...) #define __sanitizer_syscall_pre_modify_ldt(...) -#define __sanitizer_syscall_pre_mount(...) -#define __sanitizer_syscall_pre_move_pages(...) -#define __sanitizer_syscall_pre_mprotect(...) #define __sanitizer_syscall_pre_mpx(...) -#define __sanitizer_syscall_pre_mq_getsetattr(...) -#define __sanitizer_syscall_pre_mq_notify(...) -#define __sanitizer_syscall_pre_mq_open(...) -#define __sanitizer_syscall_pre_mq_timedreceive(...) -#define __sanitizer_syscall_pre_mq_timedsend(...) -#define __sanitizer_syscall_pre_mq_unlink(...) -#define __sanitizer_syscall_pre_mremap(...) -#define __sanitizer_syscall_pre_msgctl(...) -#define __sanitizer_syscall_pre_msgget(...) -#define __sanitizer_syscall_pre_msgrcv(...) -#define __sanitizer_syscall_pre_msgsnd(...) -#define __sanitizer_syscall_pre_msync(...) -#define __sanitizer_syscall_pre_munlock(...) -#define __sanitizer_syscall_pre_munlockall(...) -#define __sanitizer_syscall_pre_munmap(...) -#define __sanitizer_syscall_pre_name_to_handle_at(...) -#define __sanitizer_syscall_pre_nanosleep(...) -#define __sanitizer_syscall_pre_newfstatat(...) #define __sanitizer_syscall_pre__newselect(...) #define __sanitizer_syscall_pre_nfsservctl(...) -#define __sanitizer_syscall_pre_nice(...) #define __sanitizer_syscall_pre_oldfstat(...) #define __sanitizer_syscall_pre_oldlstat(...) #define __sanitizer_syscall_pre_oldolduname(...) #define __sanitizer_syscall_pre_oldstat(...) -#define __sanitizer_syscall_pre_olduname(...) -#define __sanitizer_syscall_pre_open(...) -#define __sanitizer_syscall_pre_openat(...) -#define __sanitizer_syscall_pre_open_by_handle_at(...) -#define __sanitizer_syscall_pre_pause(...) -#define __sanitizer_syscall_pre_perf_event_open(...) -#define __sanitizer_syscall_pre_personality(...) -#define __sanitizer_syscall_pre_pipe(...) -#define __sanitizer_syscall_pre_pipe2(...) -#define __sanitizer_syscall_pre_pivot_root(...) -#define __sanitizer_syscall_pre_poll(...) -#define __sanitizer_syscall_pre_ppoll(...) #define __sanitizer_syscall_pre_prctl(...) -#define __sanitizer_syscall_pre_pread64(...) -#define __sanitizer_syscall_pre_preadv(...) -#define __sanitizer_syscall_pre_prlimit64(...) -#define __sanitizer_syscall_pre_process_vm_readv(...) -#define __sanitizer_syscall_pre_process_vm_writev(...) #define __sanitizer_syscall_pre_prof(...) #define __sanitizer_syscall_pre_profil(...) -#define __sanitizer_syscall_pre_pselect6(...) -#define __sanitizer_syscall_pre_ptrace(...) #define __sanitizer_syscall_pre_putpmsg(...) -#define __sanitizer_syscall_pre_pwrite64(...) -#define __sanitizer_syscall_pre_pwritev(...) #define __sanitizer_syscall_pre_query_module(...) -#define __sanitizer_syscall_pre_quotactl(...) -#define __sanitizer_syscall_pre_read(...) #define __sanitizer_syscall_pre_readahead(...) #define __sanitizer_syscall_pre_readdir(...) -#define __sanitizer_syscall_pre_readlink(...) -#define __sanitizer_syscall_pre_readlinkat(...) -#define __sanitizer_syscall_pre_readv(...) -#define __sanitizer_syscall_pre_reboot(...) -#define __sanitizer_syscall_pre_recvfrom(...) -#define __sanitizer_syscall_pre_recvmmsg(...) -#define __sanitizer_syscall_pre_remap_file_pages(...) -#define __sanitizer_syscall_pre_removexattr(...) -#define __sanitizer_syscall_pre_rename(...) -#define __sanitizer_syscall_pre_renameat(...) -#define __sanitizer_syscall_pre_request_key(...) -#define __sanitizer_syscall_pre_restart_syscall(...) -#define __sanitizer_syscall_pre_rmdir(...) #define __sanitizer_syscall_pre_rt_sigaction(...) -#define __sanitizer_syscall_pre_rt_sigprocmask(...) -#define __sanitizer_syscall_pre_rt_sigqueueinfo(...) #define __sanitizer_syscall_pre_rt_sigreturn(...) #define __sanitizer_syscall_pre_rt_sigsuspend(...) -#define __sanitizer_syscall_pre_rt_sigtimedwait(...) -#define __sanitizer_syscall_pre_rt_tgsigqueueinfo(...) -#define __sanitizer_syscall_pre_sched_getaffinity(...) -#define __sanitizer_syscall_pre_sched_getparam(...) -#define __sanitizer_syscall_pre_sched_get_priority_max(...) -#define __sanitizer_syscall_pre_sched_get_priority_min(...) -#define __sanitizer_syscall_pre_sched_getscheduler(...) -#define __sanitizer_syscall_pre_sched_rr_get_interval(...) -#define __sanitizer_syscall_pre_sched_setaffinity(...) -#define __sanitizer_syscall_pre_sched_setparam(...) -#define __sanitizer_syscall_pre_sched_setscheduler(...) -#define __sanitizer_syscall_pre_sched_yield(...) #define __sanitizer_syscall_pre_security(...) -#define __sanitizer_syscall_pre_select(...) -#define __sanitizer_syscall_pre_semctl(...) -#define __sanitizer_syscall_pre_semget(...) -#define __sanitizer_syscall_pre_semop(...) -#define __sanitizer_syscall_pre_semtimedop(...) -#define __sanitizer_syscall_pre_sendfile(...) -#define __sanitizer_syscall_pre_sendfile64(...) -#define __sanitizer_syscall_pre_sendmmsg(...) -#define __sanitizer_syscall_pre_sendmsg(...) -#define __sanitizer_syscall_pre_sendto(...) -#define __sanitizer_syscall_pre_setdomainname(...) -#define __sanitizer_syscall_pre_setfsgid(...) #define __sanitizer_syscall_pre_setfsgid32(...) -#define __sanitizer_syscall_pre_setfsuid(...) #define __sanitizer_syscall_pre_setfsuid32(...) -#define __sanitizer_syscall_pre_setgid(...) #define __sanitizer_syscall_pre_setgid32(...) -#define __sanitizer_syscall_pre_setgroups(...) #define __sanitizer_syscall_pre_setgroups32(...) -#define __sanitizer_syscall_pre_sethostname(...) -#define __sanitizer_syscall_pre_setitimer(...) -#define __sanitizer_syscall_pre_set_mempolicy(...) -#define __sanitizer_syscall_pre_setns(...) -#define __sanitizer_syscall_pre_setpgid(...) -#define __sanitizer_syscall_pre_setpriority(...) -#define __sanitizer_syscall_pre_setregid(...) #define __sanitizer_syscall_pre_setregid32(...) -#define __sanitizer_syscall_pre_setresgid(...) #define __sanitizer_syscall_pre_setresgid32(...) -#define __sanitizer_syscall_pre_setresuid(...) #define __sanitizer_syscall_pre_setresuid32(...) -#define __sanitizer_syscall_pre_setreuid(...) #define __sanitizer_syscall_pre_setreuid32(...) -#define __sanitizer_syscall_pre_setrlimit(...) -#define __sanitizer_syscall_pre_set_robust_list(...) -#define __sanitizer_syscall_pre_setsid(...) -#define __sanitizer_syscall_pre_setsockopt(...) #define __sanitizer_syscall_pre_set_thread_area(...) -#define __sanitizer_syscall_pre_set_tid_address(...) -#define __sanitizer_syscall_pre_settimeofday(...) -#define __sanitizer_syscall_pre_setuid(...) #define __sanitizer_syscall_pre_setuid32(...) -#define __sanitizer_syscall_pre_setxattr(...) -#define __sanitizer_syscall_pre_sgetmask(...) -#define __sanitizer_syscall_pre_shmat(...) -#define __sanitizer_syscall_pre_shmctl(...) -#define __sanitizer_syscall_pre_shmdt(...) -#define __sanitizer_syscall_pre_shmget(...) -#define __sanitizer_syscall_pre_shutdown(...) #define __sanitizer_syscall_pre_sigaction(...) #define __sanitizer_syscall_pre_sigaltstack(...) -#define __sanitizer_syscall_pre_signal(...) -#define __sanitizer_syscall_pre_signalfd(...) -#define __sanitizer_syscall_pre_signalfd4(...) -#define __sanitizer_syscall_pre_sigpending(...) -#define __sanitizer_syscall_pre_sigprocmask(...) #define __sanitizer_syscall_pre_sigreturn(...) #define __sanitizer_syscall_pre_sigsuspend(...) -#define __sanitizer_syscall_pre_socket(...) -#define __sanitizer_syscall_pre_socketcall(...) -#define __sanitizer_syscall_pre_socketpair(...) -#define __sanitizer_syscall_pre_splice(...) -#define __sanitizer_syscall_pre_ssetmask(...) -#define __sanitizer_syscall_pre_stat(...) -#define __sanitizer_syscall_pre_stat64(...) -#define __sanitizer_syscall_pre_statfs(...) -#define __sanitizer_syscall_pre_statfs64(...) -#define __sanitizer_syscall_pre_stime(...) #define __sanitizer_syscall_pre_stty(...) -#define __sanitizer_syscall_pre_swapoff(...) -#define __sanitizer_syscall_pre_swapon(...) -#define __sanitizer_syscall_pre_symlink(...) -#define __sanitizer_syscall_pre_symlinkat(...) -#define __sanitizer_syscall_pre_sync(...) #define __sanitizer_syscall_pre_sync_file_range(...) -#define __sanitizer_syscall_pre_syncfs(...) #define __sanitizer_syscall_pre__sysctl(...) -#define __sanitizer_syscall_pre_sysfs(...) -#define __sanitizer_syscall_pre_sysinfo(...) -#define __sanitizer_syscall_pre_syslog(...) -#define __sanitizer_syscall_pre_tee(...) -#define __sanitizer_syscall_pre_tgkill(...) -#define __sanitizer_syscall_pre_time(...) -#define __sanitizer_syscall_pre_timer_create(...) -#define __sanitizer_syscall_pre_timer_delete(...) -#define __sanitizer_syscall_pre_timerfd_create(...) -#define __sanitizer_syscall_pre_timerfd_gettime(...) -#define __sanitizer_syscall_pre_timerfd_settime(...) -#define __sanitizer_syscall_pre_timer_getoverrun(...) -#define __sanitizer_syscall_pre_timer_gettime(...) -#define __sanitizer_syscall_pre_timer_settime(...) -#define __sanitizer_syscall_pre_times(...) -#define __sanitizer_syscall_pre_tkill(...) -#define __sanitizer_syscall_pre_truncate(...) #define __sanitizer_syscall_pre_truncate64(...) #define __sanitizer_syscall_pre_tuxcall(...) #define __sanitizer_syscall_pre_ugetrlimit(...) #define __sanitizer_syscall_pre_ulimit(...) -#define __sanitizer_syscall_pre_umask(...) -#define __sanitizer_syscall_pre_umount(...) #define __sanitizer_syscall_pre_umount2(...) -#define __sanitizer_syscall_pre_uname(...) -#define __sanitizer_syscall_pre_unlink(...) -#define __sanitizer_syscall_pre_unlinkat(...) -#define __sanitizer_syscall_pre_unshare(...) -#define __sanitizer_syscall_pre_uselib(...) -#define __sanitizer_syscall_pre_ustat(...) -#define __sanitizer_syscall_pre_utime(...) -#define __sanitizer_syscall_pre_utimensat(...) -#define __sanitizer_syscall_pre_utimes(...) -#define __sanitizer_syscall_pre_vfork(...) -#define __sanitizer_syscall_pre_vhangup(...) #define __sanitizer_syscall_pre_vm86(...) #define __sanitizer_syscall_pre_vm86old(...) -#define __sanitizer_syscall_pre_vmsplice(...) #define __sanitizer_syscall_pre_vserver(...) -#define __sanitizer_syscall_pre_waitid(...) -#define __sanitizer_syscall_pre_write(...) -#define __sanitizer_syscall_pre_writev(...) -#define __sanitizer_syscall_post_accept4(res, ...) -#define __sanitizer_syscall_post_accept(res, ...) -#define __sanitizer_syscall_post_access(res, ...) -#define __sanitizer_syscall_post_acct(res, ...) -#define __sanitizer_syscall_post_add_key(res, ...) -#define __sanitizer_syscall_post_adjtimex(res, ...) #define __sanitizer_syscall_post_afs_syscall(res, ...) -#define __sanitizer_syscall_post_alarm(res, ...) #define __sanitizer_syscall_post_arch_prctl(res, ...) -#define __sanitizer_syscall_post_bdflush(res, ...) -#define __sanitizer_syscall_post_bind(res, ...) #define __sanitizer_syscall_post_break(res, ...) -#define __sanitizer_syscall_post_brk(res, ...) -#define __sanitizer_syscall_post_capget(res, ...) -#define __sanitizer_syscall_post_capset(res, ...) -#define __sanitizer_syscall_post_chdir(res, ...) -#define __sanitizer_syscall_post_chmod(res, ...) #define __sanitizer_syscall_post_chown32(res, ...) -#define __sanitizer_syscall_post_chown(res, ...) -#define __sanitizer_syscall_post_chroot(res, ...) -#define __sanitizer_syscall_post_clock_adjtime(res, ...) -#define __sanitizer_syscall_post_clock_getres(res, ...) -#define __sanitizer_syscall_post_clock_gettime(res, ...) -#define __sanitizer_syscall_post_clock_nanosleep(res, ...) -#define __sanitizer_syscall_post_clock_settime(res, ...) #define __sanitizer_syscall_post_clone(res, ...) -#define __sanitizer_syscall_post_close(res, ...) -#define __sanitizer_syscall_post_connect(res, ...) #define __sanitizer_syscall_post_create_module(res, ...) -#define __sanitizer_syscall_post_creat(res, ...) -#define __sanitizer_syscall_post_delete_module(res, ...) -#define __sanitizer_syscall_post_dup2(res, ...) -#define __sanitizer_syscall_post_dup3(res, ...) -#define __sanitizer_syscall_post_dup(res, ...) -#define __sanitizer_syscall_post_epoll_create1(res, ...) -#define __sanitizer_syscall_post_epoll_create(res, ...) #define __sanitizer_syscall_post_epoll_ctl_old(res, ...) -#define __sanitizer_syscall_post_epoll_ctl(res, ...) -#define __sanitizer_syscall_post_epoll_pwait(res, ...) #define __sanitizer_syscall_post_epoll_wait_old(res, ...) -#define __sanitizer_syscall_post_epoll_wait(res, ...) -#define __sanitizer_syscall_post_eventfd2(res, ...) -#define __sanitizer_syscall_post_eventfd(res, ...) #define __sanitizer_syscall_post_execve(res, ...) -#define __sanitizer_syscall_post_exit_group(res, ...) -#define __sanitizer_syscall_post_exit(res, ...) -#define __sanitizer_syscall_post_faccessat(res, ...) -#define __sanitizer_syscall_post_fadvise64_64(res, ...) #define __sanitizer_syscall_post_fadvise64(res, ...) +#define __sanitizer_syscall_post_fadvise64_64(res, ...) #define __sanitizer_syscall_post_fallocate(res, ...) #define __sanitizer_syscall_post_fanotify_init(res, ...) #define __sanitizer_syscall_post_fanotify_mark(res, ...) -#define __sanitizer_syscall_post_fchdir(res, ...) -#define __sanitizer_syscall_post_fchmodat(res, ...) -#define __sanitizer_syscall_post_fchmod(res, ...) #define __sanitizer_syscall_post_fchown32(res, ...) -#define __sanitizer_syscall_post_fchownat(res, ...) -#define __sanitizer_syscall_post_fchown(res, ...) -#define __sanitizer_syscall_post_fcntl64(res, ...) -#define __sanitizer_syscall_post_fcntl(res, ...) -#define __sanitizer_syscall_post_fdatasync(res, ...) -#define __sanitizer_syscall_post_fgetxattr(res, ...) -#define __sanitizer_syscall_post_flistxattr(res, ...) -#define __sanitizer_syscall_post_flock(res, ...) -#define __sanitizer_syscall_post_fork(res, ...) -#define __sanitizer_syscall_post_fremovexattr(res, ...) -#define __sanitizer_syscall_post_fsetxattr(res, ...) -#define __sanitizer_syscall_post_fstat64(res, ...) -#define __sanitizer_syscall_post_fstatat64(res, ...) -#define __sanitizer_syscall_post_fstatfs64(res, ...) -#define __sanitizer_syscall_post_fstatfs(res, ...) -#define __sanitizer_syscall_post_fstat(res, ...) -#define __sanitizer_syscall_post_fsync(res, ...) #define __sanitizer_syscall_post_ftime(res, ...) #define __sanitizer_syscall_post_ftruncate64(res, ...) -#define __sanitizer_syscall_post_ftruncate(res, ...) #define __sanitizer_syscall_post_futex(res, ...) -#define __sanitizer_syscall_post_futimesat(res, ...) -#define __sanitizer_syscall_post_getcpu(res, ...) -#define __sanitizer_syscall_post_getcwd(res, ...) #define __sanitizer_syscall_post_getegid32(res, ...) -#define __sanitizer_syscall_post_getegid(res, ...) #define __sanitizer_syscall_post_geteuid32(res, ...) -#define __sanitizer_syscall_post_geteuid(res, ...) #define __sanitizer_syscall_post_getgid32(res, ...) -#define __sanitizer_syscall_post_getgid(res, ...) #define __sanitizer_syscall_post_getgroups32(res, ...) -#define __sanitizer_syscall_post_getgroups(res, ...) -#define __sanitizer_syscall_post_getitimer(res, ...) #define __sanitizer_syscall_post_get_kernel_syms(res, ...) -#define __sanitizer_syscall_post_get_mempolicy(res, ...) -#define __sanitizer_syscall_post_getpeername(res, ...) -#define __sanitizer_syscall_post_getpgid(res, ...) -#define __sanitizer_syscall_post_getpgrp(res, ...) -#define __sanitizer_syscall_post_getpid(res, ...) #define __sanitizer_syscall_post_getpmsg(res, ...) -#define __sanitizer_syscall_post_getppid(res, ...) -#define __sanitizer_syscall_post_getpriority(res, ...) #define __sanitizer_syscall_post_getresgid32(res, ...) -#define __sanitizer_syscall_post_getresgid(res, ...) #define __sanitizer_syscall_post_getresuid32(res, ...) -#define __sanitizer_syscall_post_getresuid(res, ...) -#define __sanitizer_syscall_post_getrlimit(res, ...) -#define __sanitizer_syscall_post_get_robust_list(res, ...) -#define __sanitizer_syscall_post_getrusage(res, ...) -#define __sanitizer_syscall_post_getsid(res, ...) -#define __sanitizer_syscall_post_getsockname(res, ...) -#define __sanitizer_syscall_post_getsockopt(res, ...) #define __sanitizer_syscall_post_get_thread_area(res, ...) -#define __sanitizer_syscall_post_gettid(res, ...) -#define __sanitizer_syscall_post_gettimeofday(res, ...) #define __sanitizer_syscall_post_getuid32(res, ...) -#define __sanitizer_syscall_post_getuid(res, ...) -#define __sanitizer_syscall_post_getxattr(res, ...) #define __sanitizer_syscall_post_gtty(res, ...) #define __sanitizer_syscall_post_idle(res, ...) -#define __sanitizer_syscall_post_init_module(res, ...) -#define __sanitizer_syscall_post_inotify_add_watch(res, ...) -#define __sanitizer_syscall_post_inotify_init1(res, ...) -#define __sanitizer_syscall_post_inotify_init(res, ...) -#define __sanitizer_syscall_post_inotify_rm_watch(res, ...) -#define __sanitizer_syscall_post_io_cancel(res, ...) -#define __sanitizer_syscall_post_ioctl(res, ...) -#define __sanitizer_syscall_post_io_destroy(res, ...) -#define __sanitizer_syscall_post_io_getevents(res, ...) -#define __sanitizer_syscall_post_ioperm(res, ...) #define __sanitizer_syscall_post_iopl(res, ...) -#define __sanitizer_syscall_post_ioprio_get(res, ...) -#define __sanitizer_syscall_post_ioprio_set(res, ...) -#define __sanitizer_syscall_post_io_setup(res, ...) -#define __sanitizer_syscall_post_io_submit(res, ...) -#define __sanitizer_syscall_post_ipc(res, ...) -#define __sanitizer_syscall_post_kexec_load(res, ...) -#define __sanitizer_syscall_post_keyctl(res, ...) -#define __sanitizer_syscall_post_kill(res, ...) #define __sanitizer_syscall_post_lchown32(res, ...) -#define __sanitizer_syscall_post_lchown(res, ...) -#define __sanitizer_syscall_post_lgetxattr(res, ...) -#define __sanitizer_syscall_post_linkat(res, ...) -#define __sanitizer_syscall_post_link(res, ...) -#define __sanitizer_syscall_post_listen(res, ...) -#define __sanitizer_syscall_post_listxattr(res, ...) -#define __sanitizer_syscall_post_llistxattr(res, ...) #define __sanitizer_syscall_post__llseek(res, ...) #define __sanitizer_syscall_post_lock(res, ...) -#define __sanitizer_syscall_post_lookup_dcookie(res, ...) -#define __sanitizer_syscall_post_lremovexattr(res, ...) -#define __sanitizer_syscall_post_lseek(res, ...) -#define __sanitizer_syscall_post_lsetxattr(res, ...) -#define __sanitizer_syscall_post_lstat64(res, ...) -#define __sanitizer_syscall_post_lstat(res, ...) #define __sanitizer_syscall_post_madvise1(res, ...) -#define __sanitizer_syscall_post_madvise(res, ...) -#define __sanitizer_syscall_post_mbind(res, ...) -#define __sanitizer_syscall_post_migrate_pages(res, ...) -#define __sanitizer_syscall_post_mincore(res, ...) -#define __sanitizer_syscall_post_mkdirat(res, ...) -#define __sanitizer_syscall_post_mkdir(res, ...) -#define __sanitizer_syscall_post_mknodat(res, ...) -#define __sanitizer_syscall_post_mknod(res, ...) -#define __sanitizer_syscall_post_mlockall(res, ...) -#define __sanitizer_syscall_post_mlock(res, ...) #define __sanitizer_syscall_post_mmap2(res, ...) #define __sanitizer_syscall_post_mmap(res, ...) #define __sanitizer_syscall_post_modify_ldt(res, ...) -#define __sanitizer_syscall_post_mount(res, ...) -#define __sanitizer_syscall_post_move_pages(res, ...) -#define __sanitizer_syscall_post_mprotect(res, ...) #define __sanitizer_syscall_post_mpx(res, ...) -#define __sanitizer_syscall_post_mq_getsetattr(res, ...) -#define __sanitizer_syscall_post_mq_notify(res, ...) -#define __sanitizer_syscall_post_mq_open(res, ...) -#define __sanitizer_syscall_post_mq_timedreceive(res, ...) -#define __sanitizer_syscall_post_mq_timedsend(res, ...) -#define __sanitizer_syscall_post_mq_unlink(res, ...) -#define __sanitizer_syscall_post_mremap(res, ...) -#define __sanitizer_syscall_post_msgctl(res, ...) -#define __sanitizer_syscall_post_msgget(res, ...) -#define __sanitizer_syscall_post_msgrcv(res, ...) -#define __sanitizer_syscall_post_msgsnd(res, ...) -#define __sanitizer_syscall_post_msync(res, ...) -#define __sanitizer_syscall_post_munlockall(res, ...) -#define __sanitizer_syscall_post_munlock(res, ...) -#define __sanitizer_syscall_post_munmap(res, ...) -#define __sanitizer_syscall_post_name_to_handle_at(res, ...) -#define __sanitizer_syscall_post_nanosleep(res, ...) -#define __sanitizer_syscall_post_newfstatat(res, ...) #define __sanitizer_syscall_post__newselect(res, ...) #define __sanitizer_syscall_post_nfsservctl(res, ...) -#define __sanitizer_syscall_post_nice(res, ...) #define __sanitizer_syscall_post_oldfstat(res, ...) #define __sanitizer_syscall_post_oldlstat(res, ...) #define __sanitizer_syscall_post_oldolduname(res, ...) #define __sanitizer_syscall_post_oldstat(res, ...) -#define __sanitizer_syscall_post_olduname(res, ...) -#define __sanitizer_syscall_post_openat(res, ...) -#define __sanitizer_syscall_post_open_by_handle_at(res, ...) -#define __sanitizer_syscall_post_open(res, ...) -#define __sanitizer_syscall_post_pause(res, ...) -#define __sanitizer_syscall_post_perf_event_open(res, ...) -#define __sanitizer_syscall_post_personality(res, ...) -#define __sanitizer_syscall_post_pipe2(res, ...) -#define __sanitizer_syscall_post_pipe(res, ...) -#define __sanitizer_syscall_post_pivot_root(res, ...) -#define __sanitizer_syscall_post_poll(res, ...) -#define __sanitizer_syscall_post_ppoll(res, ...) #define __sanitizer_syscall_post_prctl(res, ...) -#define __sanitizer_syscall_post_pread64(res, ...) -#define __sanitizer_syscall_post_preadv(res, ...) -#define __sanitizer_syscall_post_prlimit64(res, ...) -#define __sanitizer_syscall_post_process_vm_readv(res, ...) -#define __sanitizer_syscall_post_process_vm_writev(res, ...) #define __sanitizer_syscall_post_profil(res, ...) #define __sanitizer_syscall_post_prof(res, ...) -#define __sanitizer_syscall_post_pselect6(res, ...) -#define __sanitizer_syscall_post_ptrace(res, ...) #define __sanitizer_syscall_post_putpmsg(res, ...) -#define __sanitizer_syscall_post_pwrite64(res, ...) -#define __sanitizer_syscall_post_pwritev(res, ...) #define __sanitizer_syscall_post_query_module(res, ...) -#define __sanitizer_syscall_post_quotactl(res, ...) #define __sanitizer_syscall_post_readahead(res, ...) #define __sanitizer_syscall_post_readdir(res, ...) -#define __sanitizer_syscall_post_readlinkat(res, ...) -#define __sanitizer_syscall_post_readlink(res, ...) -#define __sanitizer_syscall_post_read(res, ...) -#define __sanitizer_syscall_post_readv(res, ...) -#define __sanitizer_syscall_post_reboot(res, ...) -#define __sanitizer_syscall_post_recvfrom(res, ...) -#define __sanitizer_syscall_post_recvmmsg(res, ...) -#define __sanitizer_syscall_post_remap_file_pages(res, ...) -#define __sanitizer_syscall_post_removexattr(res, ...) -#define __sanitizer_syscall_post_renameat(res, ...) -#define __sanitizer_syscall_post_rename(res, ...) -#define __sanitizer_syscall_post_request_key(res, ...) -#define __sanitizer_syscall_post_restart_syscall(res, ...) -#define __sanitizer_syscall_post_rmdir(res, ...) #define __sanitizer_syscall_post_rt_sigaction(res, ...) -#define __sanitizer_syscall_post_rt_sigprocmask(res, ...) -#define __sanitizer_syscall_post_rt_sigqueueinfo(res, ...) #define __sanitizer_syscall_post_rt_sigreturn(res, ...) #define __sanitizer_syscall_post_rt_sigsuspend(res, ...) -#define __sanitizer_syscall_post_rt_sigtimedwait(res, ...) -#define __sanitizer_syscall_post_rt_tgsigqueueinfo(res, ...) -#define __sanitizer_syscall_post_sched_getaffinity(res, ...) -#define __sanitizer_syscall_post_sched_getparam(res, ...) -#define __sanitizer_syscall_post_sched_get_priority_max(res, ...) -#define __sanitizer_syscall_post_sched_get_priority_min(res, ...) -#define __sanitizer_syscall_post_sched_getscheduler(res, ...) -#define __sanitizer_syscall_post_sched_rr_get_interval(res, ...) -#define __sanitizer_syscall_post_sched_setaffinity(res, ...) -#define __sanitizer_syscall_post_sched_setparam(res, ...) -#define __sanitizer_syscall_post_sched_setscheduler(res, ...) -#define __sanitizer_syscall_post_sched_yield(res, ...) #define __sanitizer_syscall_post_security(res, ...) -#define __sanitizer_syscall_post_select(res, ...) -#define __sanitizer_syscall_post_semctl(res, ...) -#define __sanitizer_syscall_post_semget(res, ...) -#define __sanitizer_syscall_post_semop(res, ...) -#define __sanitizer_syscall_post_semtimedop(res, ...) -#define __sanitizer_syscall_post_sendfile64(res, ...) -#define __sanitizer_syscall_post_sendfile(res, ...) -#define __sanitizer_syscall_post_sendmmsg(res, ...) -#define __sanitizer_syscall_post_sendmsg(res, ...) -#define __sanitizer_syscall_post_sendto(res, ...) -#define __sanitizer_syscall_post_setdomainname(res, ...) #define __sanitizer_syscall_post_setfsgid32(res, ...) -#define __sanitizer_syscall_post_setfsgid(res, ...) #define __sanitizer_syscall_post_setfsuid32(res, ...) -#define __sanitizer_syscall_post_setfsuid(res, ...) #define __sanitizer_syscall_post_setgid32(res, ...) -#define __sanitizer_syscall_post_setgid(res, ...) #define __sanitizer_syscall_post_setgroups32(res, ...) -#define __sanitizer_syscall_post_setgroups(res, ...) -#define __sanitizer_syscall_post_sethostname(res, ...) -#define __sanitizer_syscall_post_setitimer(res, ...) -#define __sanitizer_syscall_post_set_mempolicy(res, ...) -#define __sanitizer_syscall_post_setns(res, ...) -#define __sanitizer_syscall_post_setpgid(res, ...) -#define __sanitizer_syscall_post_setpriority(res, ...) #define __sanitizer_syscall_post_setregid32(res, ...) -#define __sanitizer_syscall_post_setregid(res, ...) #define __sanitizer_syscall_post_setresgid32(res, ...) -#define __sanitizer_syscall_post_setresgid(res, ...) #define __sanitizer_syscall_post_setresuid32(res, ...) -#define __sanitizer_syscall_post_setresuid(res, ...) #define __sanitizer_syscall_post_setreuid32(res, ...) -#define __sanitizer_syscall_post_setreuid(res, ...) -#define __sanitizer_syscall_post_setrlimit(res, ...) -#define __sanitizer_syscall_post_set_robust_list(res, ...) -#define __sanitizer_syscall_post_setsid(res, ...) -#define __sanitizer_syscall_post_setsockopt(res, ...) #define __sanitizer_syscall_post_set_thread_area(res, ...) -#define __sanitizer_syscall_post_set_tid_address(res, ...) -#define __sanitizer_syscall_post_settimeofday(res, ...) #define __sanitizer_syscall_post_setuid32(res, ...) -#define __sanitizer_syscall_post_setuid(res, ...) -#define __sanitizer_syscall_post_setxattr(res, ...) -#define __sanitizer_syscall_post_sgetmask(res, ...) -#define __sanitizer_syscall_post_shmat(res, ...) -#define __sanitizer_syscall_post_shmctl(res, ...) -#define __sanitizer_syscall_post_shmdt(res, ...) -#define __sanitizer_syscall_post_shmget(res, ...) -#define __sanitizer_syscall_post_shutdown(res, ...) #define __sanitizer_syscall_post_sigaction(res, ...) #define __sanitizer_syscall_post_sigaltstack(res, ...) -#define __sanitizer_syscall_post_signalfd4(res, ...) -#define __sanitizer_syscall_post_signalfd(res, ...) -#define __sanitizer_syscall_post_signal(res, ...) -#define __sanitizer_syscall_post_sigpending(res, ...) -#define __sanitizer_syscall_post_sigprocmask(res, ...) #define __sanitizer_syscall_post_sigreturn(res, ...) #define __sanitizer_syscall_post_sigsuspend(res, ...) -#define __sanitizer_syscall_post_socketcall(res, ...) -#define __sanitizer_syscall_post_socketpair(res, ...) -#define __sanitizer_syscall_post_socket(res, ...) -#define __sanitizer_syscall_post_splice(res, ...) -#define __sanitizer_syscall_post_ssetmask(res, ...) -#define __sanitizer_syscall_post_stat64(res, ...) -#define __sanitizer_syscall_post_statfs64(res, ...) -#define __sanitizer_syscall_post_statfs(res, ...) -#define __sanitizer_syscall_post_stat(res, ...) -#define __sanitizer_syscall_post_stime(res, ...) #define __sanitizer_syscall_post_stty(res, ...) -#define __sanitizer_syscall_post_swapoff(res, ...) -#define __sanitizer_syscall_post_swapon(res, ...) -#define __sanitizer_syscall_post_symlinkat(res, ...) -#define __sanitizer_syscall_post_symlink(res, ...) #define __sanitizer_syscall_post_sync_file_range(res, ...) -#define __sanitizer_syscall_post_syncfs(res, ...) -#define __sanitizer_syscall_post_sync(res, ...) #define __sanitizer_syscall_post__sysctl(res, ...) -#define __sanitizer_syscall_post_sysfs(res, ...) -#define __sanitizer_syscall_post_sysinfo(res, ...) -#define __sanitizer_syscall_post_syslog(res, ...) -#define __sanitizer_syscall_post_tee(res, ...) -#define __sanitizer_syscall_post_tgkill(res, ...) -#define __sanitizer_syscall_post_timer_create(res, ...) -#define __sanitizer_syscall_post_timer_delete(res, ...) -#define __sanitizer_syscall_post_time(res, ...) -#define __sanitizer_syscall_post_timerfd_create(res, ...) -#define __sanitizer_syscall_post_timerfd_gettime(res, ...) -#define __sanitizer_syscall_post_timerfd_settime(res, ...) -#define __sanitizer_syscall_post_timer_getoverrun(res, ...) -#define __sanitizer_syscall_post_timer_gettime(res, ...) -#define __sanitizer_syscall_post_timer_settime(res, ...) -#define __sanitizer_syscall_post_times(res, ...) -#define __sanitizer_syscall_post_tkill(res, ...) #define __sanitizer_syscall_post_truncate64(res, ...) -#define __sanitizer_syscall_post_truncate(res, ...) #define __sanitizer_syscall_post_tuxcall(res, ...) #define __sanitizer_syscall_post_ugetrlimit(res, ...) #define __sanitizer_syscall_post_ulimit(res, ...) -#define __sanitizer_syscall_post_umask(res, ...) #define __sanitizer_syscall_post_umount2(res, ...) -#define __sanitizer_syscall_post_umount(res, ...) -#define __sanitizer_syscall_post_uname(res, ...) -#define __sanitizer_syscall_post_unlinkat(res, ...) -#define __sanitizer_syscall_post_unlink(res, ...) -#define __sanitizer_syscall_post_unshare(res, ...) -#define __sanitizer_syscall_post_uselib(res, ...) -#define __sanitizer_syscall_post_ustat(res, ...) -#define __sanitizer_syscall_post_utimensat(res, ...) -#define __sanitizer_syscall_post_utime(res, ...) -#define __sanitizer_syscall_post_utimes(res, ...) -#define __sanitizer_syscall_post_vfork(res, ...) -#define __sanitizer_syscall_post_vhangup(res, ...) #define __sanitizer_syscall_post_vm86old(res, ...) #define __sanitizer_syscall_post_vm86(res, ...) -#define __sanitizer_syscall_post_vmsplice(res, ...) #define __sanitizer_syscall_post_vserver(res, ...) -#define __sanitizer_syscall_post_waitid(res, ...) -#define __sanitizer_syscall_post_write(res, ...) -#define __sanitizer_syscall_post_writev(res, ...) #ifdef __cplusplus -} // extern "C" +extern "C" { +#endif + +// Private declarations. Do not call directly from user code. Use macros above. +void __sanitizer_syscall_pre_impl_time(long tloc); +void __sanitizer_syscall_post_impl_time(long res, long tloc); +void __sanitizer_syscall_pre_impl_stime(long tptr); +void __sanitizer_syscall_post_impl_stime(long res, long tptr); +void __sanitizer_syscall_pre_impl_gettimeofday(long tv, long tz); +void __sanitizer_syscall_post_impl_gettimeofday(long res, long tv, long tz); +void __sanitizer_syscall_pre_impl_settimeofday(long tv, long tz); +void __sanitizer_syscall_post_impl_settimeofday(long res, long tv, long tz); +void __sanitizer_syscall_pre_impl_adjtimex(long txc_p); +void __sanitizer_syscall_post_impl_adjtimex(long res, long txc_p); +void __sanitizer_syscall_pre_impl_times(long tbuf); +void __sanitizer_syscall_post_impl_times(long res, long tbuf); +void __sanitizer_syscall_pre_impl_gettid(); +void __sanitizer_syscall_post_impl_gettid(long res); +void __sanitizer_syscall_pre_impl_nanosleep(long rqtp, long rmtp); +void __sanitizer_syscall_post_impl_nanosleep(long res, long rqtp, long rmtp); +void __sanitizer_syscall_pre_impl_alarm(long seconds); +void __sanitizer_syscall_post_impl_alarm(long res, long seconds); +void __sanitizer_syscall_pre_impl_getpid(); +void __sanitizer_syscall_post_impl_getpid(long res); +void __sanitizer_syscall_pre_impl_getppid(); +void __sanitizer_syscall_post_impl_getppid(long res); +void __sanitizer_syscall_pre_impl_getuid(); +void __sanitizer_syscall_post_impl_getuid(long res); +void __sanitizer_syscall_pre_impl_geteuid(); +void __sanitizer_syscall_post_impl_geteuid(long res); +void __sanitizer_syscall_pre_impl_getgid(); +void __sanitizer_syscall_post_impl_getgid(long res); +void __sanitizer_syscall_pre_impl_getegid(); +void __sanitizer_syscall_post_impl_getegid(long res); +void __sanitizer_syscall_pre_impl_getresuid(long ruid, long euid, long suid); +void __sanitizer_syscall_post_impl_getresuid(long res, long ruid, long euid, + long suid); +void __sanitizer_syscall_pre_impl_getresgid(long rgid, long egid, long sgid); +void __sanitizer_syscall_post_impl_getresgid(long res, long rgid, long egid, + long sgid); +void __sanitizer_syscall_pre_impl_getpgid(long pid); +void __sanitizer_syscall_post_impl_getpgid(long res, long pid); +void __sanitizer_syscall_pre_impl_getpgrp(); +void __sanitizer_syscall_post_impl_getpgrp(long res); +void __sanitizer_syscall_pre_impl_getsid(long pid); +void __sanitizer_syscall_post_impl_getsid(long res, long pid); +void __sanitizer_syscall_pre_impl_getgroups(long gidsetsize, long grouplist); +void __sanitizer_syscall_post_impl_getgroups(long res, long gidsetsize, + long grouplist); +void __sanitizer_syscall_pre_impl_setregid(long rgid, long egid); +void __sanitizer_syscall_post_impl_setregid(long res, long rgid, long egid); +void __sanitizer_syscall_pre_impl_setgid(long gid); +void __sanitizer_syscall_post_impl_setgid(long res, long gid); +void __sanitizer_syscall_pre_impl_setreuid(long ruid, long euid); +void __sanitizer_syscall_post_impl_setreuid(long res, long ruid, long euid); +void __sanitizer_syscall_pre_impl_setuid(long uid); +void __sanitizer_syscall_post_impl_setuid(long res, long uid); +void __sanitizer_syscall_pre_impl_setresuid(long ruid, long euid, long suid); +void __sanitizer_syscall_post_impl_setresuid(long res, long ruid, long euid, + long suid); +void __sanitizer_syscall_pre_impl_setresgid(long rgid, long egid, long sgid); +void __sanitizer_syscall_post_impl_setresgid(long res, long rgid, long egid, + long sgid); +void __sanitizer_syscall_pre_impl_setfsuid(long uid); +void __sanitizer_syscall_post_impl_setfsuid(long res, long uid); +void __sanitizer_syscall_pre_impl_setfsgid(long gid); +void __sanitizer_syscall_post_impl_setfsgid(long res, long gid); +void __sanitizer_syscall_pre_impl_setpgid(long pid, long pgid); +void __sanitizer_syscall_post_impl_setpgid(long res, long pid, long pgid); +void __sanitizer_syscall_pre_impl_setsid(); +void __sanitizer_syscall_post_impl_setsid(long res); +void __sanitizer_syscall_pre_impl_setgroups(long gidsetsize, long grouplist); +void __sanitizer_syscall_post_impl_setgroups(long res, long gidsetsize, + long grouplist); +void __sanitizer_syscall_pre_impl_acct(long name); +void __sanitizer_syscall_post_impl_acct(long res, long name); +void __sanitizer_syscall_pre_impl_capget(long header, long dataptr); +void __sanitizer_syscall_post_impl_capget(long res, long header, long dataptr); +void __sanitizer_syscall_pre_impl_capset(long header, long data); +void __sanitizer_syscall_post_impl_capset(long res, long header, long data); +void __sanitizer_syscall_pre_impl_personality(long personality); +void __sanitizer_syscall_post_impl_personality(long res, long personality); +void __sanitizer_syscall_pre_impl_sigpending(long set); +void __sanitizer_syscall_post_impl_sigpending(long res, long set); +void __sanitizer_syscall_pre_impl_sigprocmask(long how, long set, long oset); +void __sanitizer_syscall_post_impl_sigprocmask(long res, long how, long set, + long oset); +void __sanitizer_syscall_pre_impl_getitimer(long which, long value); +void __sanitizer_syscall_post_impl_getitimer(long res, long which, long value); +void __sanitizer_syscall_pre_impl_setitimer(long which, long value, + long ovalue); +void __sanitizer_syscall_post_impl_setitimer(long res, long which, long value, + long ovalue); +void __sanitizer_syscall_pre_impl_timer_create(long which_clock, + long timer_event_spec, + long created_timer_id); +void __sanitizer_syscall_post_impl_timer_create(long res, long which_clock, + long timer_event_spec, + long created_timer_id); +void __sanitizer_syscall_pre_impl_timer_gettime(long timer_id, long setting); +void __sanitizer_syscall_post_impl_timer_gettime(long res, long timer_id, + long setting); +void __sanitizer_syscall_pre_impl_timer_getoverrun(long timer_id); +void __sanitizer_syscall_post_impl_timer_getoverrun(long res, long timer_id); +void __sanitizer_syscall_pre_impl_timer_settime(long timer_id, long flags, + long new_setting, + long old_setting); +void __sanitizer_syscall_post_impl_timer_settime(long res, long timer_id, + long flags, long new_setting, + long old_setting); +void __sanitizer_syscall_pre_impl_timer_delete(long timer_id); +void __sanitizer_syscall_post_impl_timer_delete(long res, long timer_id); +void __sanitizer_syscall_pre_impl_clock_settime(long which_clock, long tp); +void __sanitizer_syscall_post_impl_clock_settime(long res, long which_clock, + long tp); +void __sanitizer_syscall_pre_impl_clock_gettime(long which_clock, long tp); +void __sanitizer_syscall_post_impl_clock_gettime(long res, long which_clock, + long tp); +void __sanitizer_syscall_pre_impl_clock_adjtime(long which_clock, long tx); +void __sanitizer_syscall_post_impl_clock_adjtime(long res, long which_clock, + long tx); +void __sanitizer_syscall_pre_impl_clock_getres(long which_clock, long tp); +void __sanitizer_syscall_post_impl_clock_getres(long res, long which_clock, + long tp); +void __sanitizer_syscall_pre_impl_clock_nanosleep(long which_clock, long flags, + long rqtp, long rmtp); +void __sanitizer_syscall_post_impl_clock_nanosleep(long res, long which_clock, + long flags, long rqtp, + long rmtp); +void __sanitizer_syscall_pre_impl_nice(long increment); +void __sanitizer_syscall_post_impl_nice(long res, long increment); +void __sanitizer_syscall_pre_impl_sched_setscheduler(long pid, long policy, + long param); +void __sanitizer_syscall_post_impl_sched_setscheduler(long res, long pid, + long policy, long param); +void __sanitizer_syscall_pre_impl_sched_setparam(long pid, long param); +void __sanitizer_syscall_post_impl_sched_setparam(long res, long pid, + long param); +void __sanitizer_syscall_pre_impl_sched_getscheduler(long pid); +void __sanitizer_syscall_post_impl_sched_getscheduler(long res, long pid); +void __sanitizer_syscall_pre_impl_sched_getparam(long pid, long param); +void __sanitizer_syscall_post_impl_sched_getparam(long res, long pid, + long param); +void __sanitizer_syscall_pre_impl_sched_setaffinity(long pid, long len, + long user_mask_ptr); +void __sanitizer_syscall_post_impl_sched_setaffinity(long res, long pid, + long len, + long user_mask_ptr); +void __sanitizer_syscall_pre_impl_sched_getaffinity(long pid, long len, + long user_mask_ptr); +void __sanitizer_syscall_post_impl_sched_getaffinity(long res, long pid, + long len, + long user_mask_ptr); +void __sanitizer_syscall_pre_impl_sched_yield(); +void __sanitizer_syscall_post_impl_sched_yield(long res); +void __sanitizer_syscall_pre_impl_sched_get_priority_max(long policy); +void __sanitizer_syscall_post_impl_sched_get_priority_max(long res, + long policy); +void __sanitizer_syscall_pre_impl_sched_get_priority_min(long policy); +void __sanitizer_syscall_post_impl_sched_get_priority_min(long res, + long policy); +void __sanitizer_syscall_pre_impl_sched_rr_get_interval(long pid, + long interval); +void __sanitizer_syscall_post_impl_sched_rr_get_interval(long res, long pid, + long interval); +void __sanitizer_syscall_pre_impl_setpriority(long which, long who, + long niceval); +void __sanitizer_syscall_post_impl_setpriority(long res, long which, long who, + long niceval); +void __sanitizer_syscall_pre_impl_getpriority(long which, long who); +void __sanitizer_syscall_post_impl_getpriority(long res, long which, long who); +void __sanitizer_syscall_pre_impl_shutdown(long arg0, long arg1); +void __sanitizer_syscall_post_impl_shutdown(long res, long arg0, long arg1); +void __sanitizer_syscall_pre_impl_reboot(long magic1, long magic2, long cmd, + long arg); +void __sanitizer_syscall_post_impl_reboot(long res, long magic1, long magic2, + long cmd, long arg); +void __sanitizer_syscall_pre_impl_restart_syscall(); +void __sanitizer_syscall_post_impl_restart_syscall(long res); +void __sanitizer_syscall_pre_impl_kexec_load(long entry, long nr_segments, + long segments, long flags); +void __sanitizer_syscall_post_impl_kexec_load(long res, long entry, + long nr_segments, long segments, + long flags); +void __sanitizer_syscall_pre_impl_exit(long error_code); +void __sanitizer_syscall_post_impl_exit(long res, long error_code); +void __sanitizer_syscall_pre_impl_exit_group(long error_code); +void __sanitizer_syscall_post_impl_exit_group(long res, long error_code); +void __sanitizer_syscall_pre_impl_wait4(long pid, long stat_addr, long options, + long ru); +void __sanitizer_syscall_post_impl_wait4(long res, long pid, long stat_addr, + long options, long ru); +void __sanitizer_syscall_pre_impl_waitid(long which, long pid, long infop, + long options, long ru); +void __sanitizer_syscall_post_impl_waitid(long res, long which, long pid, + long infop, long options, long ru); +void __sanitizer_syscall_pre_impl_waitpid(long pid, long stat_addr, + long options); +void __sanitizer_syscall_post_impl_waitpid(long res, long pid, long stat_addr, + long options); +void __sanitizer_syscall_pre_impl_set_tid_address(long tidptr); +void __sanitizer_syscall_post_impl_set_tid_address(long res, long tidptr); +void __sanitizer_syscall_pre_impl_init_module(long umod, long len, long uargs); +void __sanitizer_syscall_post_impl_init_module(long res, long umod, long len, + long uargs); +void __sanitizer_syscall_pre_impl_delete_module(long name_user, long flags); +void __sanitizer_syscall_post_impl_delete_module(long res, long name_user, + long flags); +void __sanitizer_syscall_pre_impl_rt_sigprocmask(long how, long set, long oset, + long sigsetsize); +void __sanitizer_syscall_post_impl_rt_sigprocmask(long res, long how, long set, + long oset, long sigsetsize); +void __sanitizer_syscall_pre_impl_rt_sigpending(long set, long sigsetsize); +void __sanitizer_syscall_post_impl_rt_sigpending(long res, long set, + long sigsetsize); +void __sanitizer_syscall_pre_impl_rt_sigtimedwait(long uthese, long uinfo, + long uts, long sigsetsize); +void __sanitizer_syscall_post_impl_rt_sigtimedwait(long res, long uthese, + long uinfo, long uts, + long sigsetsize); +void __sanitizer_syscall_pre_impl_rt_tgsigqueueinfo(long tgid, long pid, + long sig, long uinfo); +void __sanitizer_syscall_post_impl_rt_tgsigqueueinfo(long res, long tgid, + long pid, long sig, + long uinfo); +void __sanitizer_syscall_pre_impl_kill(long pid, long sig); +void __sanitizer_syscall_post_impl_kill(long res, long pid, long sig); +void __sanitizer_syscall_pre_impl_tgkill(long tgid, long pid, long sig); +void __sanitizer_syscall_post_impl_tgkill(long res, long tgid, long pid, + long sig); +void __sanitizer_syscall_pre_impl_tkill(long pid, long sig); +void __sanitizer_syscall_post_impl_tkill(long res, long pid, long sig); +void __sanitizer_syscall_pre_impl_rt_sigqueueinfo(long pid, long sig, + long uinfo); +void __sanitizer_syscall_post_impl_rt_sigqueueinfo(long res, long pid, long sig, + long uinfo); +void __sanitizer_syscall_pre_impl_sgetmask(); +void __sanitizer_syscall_post_impl_sgetmask(long res); +void __sanitizer_syscall_pre_impl_ssetmask(long newmask); +void __sanitizer_syscall_post_impl_ssetmask(long res, long newmask); +void __sanitizer_syscall_pre_impl_signal(long sig, long handler); +void __sanitizer_syscall_post_impl_signal(long res, long sig, long handler); +void __sanitizer_syscall_pre_impl_pause(); +void __sanitizer_syscall_post_impl_pause(long res); +void __sanitizer_syscall_pre_impl_sync(); +void __sanitizer_syscall_post_impl_sync(long res); +void __sanitizer_syscall_pre_impl_fsync(long fd); +void __sanitizer_syscall_post_impl_fsync(long res, long fd); +void __sanitizer_syscall_pre_impl_fdatasync(long fd); +void __sanitizer_syscall_post_impl_fdatasync(long res, long fd); +void __sanitizer_syscall_pre_impl_bdflush(long func, long data); +void __sanitizer_syscall_post_impl_bdflush(long res, long func, long data); +void __sanitizer_syscall_pre_impl_mount(long dev_name, long dir_name, long type, + long flags, long data); +void __sanitizer_syscall_post_impl_mount(long res, long dev_name, long dir_name, + long type, long flags, long data); +void __sanitizer_syscall_pre_impl_umount(long name, long flags); +void __sanitizer_syscall_post_impl_umount(long res, long name, long flags); +void __sanitizer_syscall_pre_impl_oldumount(long name); +void __sanitizer_syscall_post_impl_oldumount(long res, long name); +void __sanitizer_syscall_pre_impl_truncate(long path, long length); +void __sanitizer_syscall_post_impl_truncate(long res, long path, long length); +void __sanitizer_syscall_pre_impl_ftruncate(long fd, long length); +void __sanitizer_syscall_post_impl_ftruncate(long res, long fd, long length); +void __sanitizer_syscall_pre_impl_stat(long filename, long statbuf); +void __sanitizer_syscall_post_impl_stat(long res, long filename, long statbuf); +void __sanitizer_syscall_pre_impl_statfs(long path, long buf); +void __sanitizer_syscall_post_impl_statfs(long res, long path, long buf); +void __sanitizer_syscall_pre_impl_statfs64(long path, long sz, long buf); +void __sanitizer_syscall_post_impl_statfs64(long res, long path, long sz, + long buf); +void __sanitizer_syscall_pre_impl_fstatfs(long fd, long buf); +void __sanitizer_syscall_post_impl_fstatfs(long res, long fd, long buf); +void __sanitizer_syscall_pre_impl_fstatfs64(long fd, long sz, long buf); +void __sanitizer_syscall_post_impl_fstatfs64(long res, long fd, long sz, + long buf); +void __sanitizer_syscall_pre_impl_lstat(long filename, long statbuf); +void __sanitizer_syscall_post_impl_lstat(long res, long filename, long statbuf); +void __sanitizer_syscall_pre_impl_fstat(long fd, long statbuf); +void __sanitizer_syscall_post_impl_fstat(long res, long fd, long statbuf); +void __sanitizer_syscall_pre_impl_newstat(long filename, long statbuf); +void __sanitizer_syscall_post_impl_newstat(long res, long filename, + long statbuf); +void __sanitizer_syscall_pre_impl_newlstat(long filename, long statbuf); +void __sanitizer_syscall_post_impl_newlstat(long res, long filename, + long statbuf); +void __sanitizer_syscall_pre_impl_newfstat(long fd, long statbuf); +void __sanitizer_syscall_post_impl_newfstat(long res, long fd, long statbuf); +void __sanitizer_syscall_pre_impl_ustat(long dev, long ubuf); +void __sanitizer_syscall_post_impl_ustat(long res, long dev, long ubuf); +void __sanitizer_syscall_pre_impl_stat64(long filename, long statbuf); +void __sanitizer_syscall_post_impl_stat64(long res, long filename, + long statbuf); +void __sanitizer_syscall_pre_impl_fstat64(long fd, long statbuf); +void __sanitizer_syscall_post_impl_fstat64(long res, long fd, long statbuf); +void __sanitizer_syscall_pre_impl_lstat64(long filename, long statbuf); +void __sanitizer_syscall_post_impl_lstat64(long res, long filename, + long statbuf); +void __sanitizer_syscall_pre_impl_setxattr(long path, long name, long value, + long size, long flags); +void __sanitizer_syscall_post_impl_setxattr(long res, long path, long name, + long value, long size, long flags); +void __sanitizer_syscall_pre_impl_lsetxattr(long path, long name, long value, + long size, long flags); +void __sanitizer_syscall_post_impl_lsetxattr(long res, long path, long name, + long value, long size, long flags); +void __sanitizer_syscall_pre_impl_fsetxattr(long fd, long name, long value, + long size, long flags); +void __sanitizer_syscall_post_impl_fsetxattr(long res, long fd, long name, + long value, long size, long flags); +void __sanitizer_syscall_pre_impl_getxattr(long path, long name, long value, + long size); +void __sanitizer_syscall_post_impl_getxattr(long res, long path, long name, + long value, long size); +void __sanitizer_syscall_pre_impl_lgetxattr(long path, long name, long value, + long size); +void __sanitizer_syscall_post_impl_lgetxattr(long res, long path, long name, + long value, long size); +void __sanitizer_syscall_pre_impl_fgetxattr(long fd, long name, long value, + long size); +void __sanitizer_syscall_post_impl_fgetxattr(long res, long fd, long name, + long value, long size); +void __sanitizer_syscall_pre_impl_listxattr(long path, long list, long size); +void __sanitizer_syscall_post_impl_listxattr(long res, long path, long list, + long size); +void __sanitizer_syscall_pre_impl_llistxattr(long path, long list, long size); +void __sanitizer_syscall_post_impl_llistxattr(long res, long path, long list, + long size); +void __sanitizer_syscall_pre_impl_flistxattr(long fd, long list, long size); +void __sanitizer_syscall_post_impl_flistxattr(long res, long fd, long list, + long size); +void __sanitizer_syscall_pre_impl_removexattr(long path, long name); +void __sanitizer_syscall_post_impl_removexattr(long res, long path, long name); +void __sanitizer_syscall_pre_impl_lremovexattr(long path, long name); +void __sanitizer_syscall_post_impl_lremovexattr(long res, long path, long name); +void __sanitizer_syscall_pre_impl_fremovexattr(long fd, long name); +void __sanitizer_syscall_post_impl_fremovexattr(long res, long fd, long name); +void __sanitizer_syscall_pre_impl_brk(long brk); +void __sanitizer_syscall_post_impl_brk(long res, long brk); +void __sanitizer_syscall_pre_impl_mprotect(long start, long len, long prot); +void __sanitizer_syscall_post_impl_mprotect(long res, long start, long len, + long prot); +void __sanitizer_syscall_pre_impl_mremap(long addr, long old_len, long new_len, + long flags, long new_addr); +void __sanitizer_syscall_post_impl_mremap(long res, long addr, long old_len, + long new_len, long flags, + long new_addr); +void __sanitizer_syscall_pre_impl_remap_file_pages(long start, long size, + long prot, long pgoff, + long flags); +void __sanitizer_syscall_post_impl_remap_file_pages(long res, long start, + long size, long prot, + long pgoff, long flags); +void __sanitizer_syscall_pre_impl_msync(long start, long len, long flags); +void __sanitizer_syscall_post_impl_msync(long res, long start, long len, + long flags); +void __sanitizer_syscall_pre_impl_munmap(long addr, long len); +void __sanitizer_syscall_post_impl_munmap(long res, long addr, long len); +void __sanitizer_syscall_pre_impl_mlock(long start, long len); +void __sanitizer_syscall_post_impl_mlock(long res, long start, long len); +void __sanitizer_syscall_pre_impl_munlock(long start, long len); +void __sanitizer_syscall_post_impl_munlock(long res, long start, long len); +void __sanitizer_syscall_pre_impl_mlockall(long flags); +void __sanitizer_syscall_post_impl_mlockall(long res, long flags); +void __sanitizer_syscall_pre_impl_munlockall(); +void __sanitizer_syscall_post_impl_munlockall(long res); +void __sanitizer_syscall_pre_impl_madvise(long start, long len, long behavior); +void __sanitizer_syscall_post_impl_madvise(long res, long start, long len, + long behavior); +void __sanitizer_syscall_pre_impl_mincore(long start, long len, long vec); +void __sanitizer_syscall_post_impl_mincore(long res, long start, long len, + long vec); +void __sanitizer_syscall_pre_impl_pivot_root(long new_root, long put_old); +void __sanitizer_syscall_post_impl_pivot_root(long res, long new_root, + long put_old); +void __sanitizer_syscall_pre_impl_chroot(long filename); +void __sanitizer_syscall_post_impl_chroot(long res, long filename); +void __sanitizer_syscall_pre_impl_mknod(long filename, long mode, long dev); +void __sanitizer_syscall_post_impl_mknod(long res, long filename, long mode, + long dev); +void __sanitizer_syscall_pre_impl_link(long oldname, long newname); +void __sanitizer_syscall_post_impl_link(long res, long oldname, long newname); +void __sanitizer_syscall_pre_impl_symlink(long old, long new_); +void __sanitizer_syscall_post_impl_symlink(long res, long old, long new_); +void __sanitizer_syscall_pre_impl_unlink(long pathname); +void __sanitizer_syscall_post_impl_unlink(long res, long pathname); +void __sanitizer_syscall_pre_impl_rename(long oldname, long newname); +void __sanitizer_syscall_post_impl_rename(long res, long oldname, long newname); +void __sanitizer_syscall_pre_impl_chmod(long filename, long mode); +void __sanitizer_syscall_post_impl_chmod(long res, long filename, long mode); +void __sanitizer_syscall_pre_impl_fchmod(long fd, long mode); +void __sanitizer_syscall_post_impl_fchmod(long res, long fd, long mode); +void __sanitizer_syscall_pre_impl_fcntl(long fd, long cmd, long arg); +void __sanitizer_syscall_post_impl_fcntl(long res, long fd, long cmd, long arg); +void __sanitizer_syscall_pre_impl_fcntl64(long fd, long cmd, long arg); +void __sanitizer_syscall_post_impl_fcntl64(long res, long fd, long cmd, + long arg); +void __sanitizer_syscall_pre_impl_pipe(long fildes); +void __sanitizer_syscall_post_impl_pipe(long res, long fildes); +void __sanitizer_syscall_pre_impl_pipe2(long fildes, long flags); +void __sanitizer_syscall_post_impl_pipe2(long res, long fildes, long flags); +void __sanitizer_syscall_pre_impl_dup(long fildes); +void __sanitizer_syscall_post_impl_dup(long res, long fildes); +void __sanitizer_syscall_pre_impl_dup2(long oldfd, long newfd); +void __sanitizer_syscall_post_impl_dup2(long res, long oldfd, long newfd); +void __sanitizer_syscall_pre_impl_dup3(long oldfd, long newfd, long flags); +void __sanitizer_syscall_post_impl_dup3(long res, long oldfd, long newfd, + long flags); +void __sanitizer_syscall_pre_impl_ioperm(long from, long num, long on); +void __sanitizer_syscall_post_impl_ioperm(long res, long from, long num, + long on); +void __sanitizer_syscall_pre_impl_ioctl(long fd, long cmd, long arg); +void __sanitizer_syscall_post_impl_ioctl(long res, long fd, long cmd, long arg); +void __sanitizer_syscall_pre_impl_flock(long fd, long cmd); +void __sanitizer_syscall_post_impl_flock(long res, long fd, long cmd); +void __sanitizer_syscall_pre_impl_io_setup(long nr_reqs, long ctx); +void __sanitizer_syscall_post_impl_io_setup(long res, long nr_reqs, long ctx); +void __sanitizer_syscall_pre_impl_io_destroy(long ctx); +void __sanitizer_syscall_post_impl_io_destroy(long res, long ctx); +void __sanitizer_syscall_pre_impl_io_getevents(long ctx_id, long min_nr, + long nr, long events, + long timeout); +void __sanitizer_syscall_post_impl_io_getevents(long res, long ctx_id, + long min_nr, long nr, + long events, long timeout); +void __sanitizer_syscall_pre_impl_io_submit(long ctx_id, long arg1, long arg2); +void __sanitizer_syscall_post_impl_io_submit(long res, long ctx_id, long arg1, + long arg2); +void __sanitizer_syscall_pre_impl_io_cancel(long ctx_id, long iocb, + long result); +void __sanitizer_syscall_post_impl_io_cancel(long res, long ctx_id, long iocb, + long result); +void __sanitizer_syscall_pre_impl_sendfile(long out_fd, long in_fd, long offset, + long count); +void __sanitizer_syscall_post_impl_sendfile(long res, long out_fd, long in_fd, + long offset, long count); +void __sanitizer_syscall_pre_impl_sendfile64(long out_fd, long in_fd, + long offset, long count); +void __sanitizer_syscall_post_impl_sendfile64(long res, long out_fd, long in_fd, + long offset, long count); +void __sanitizer_syscall_pre_impl_readlink(long path, long buf, long bufsiz); +void __sanitizer_syscall_post_impl_readlink(long res, long path, long buf, + long bufsiz); +void __sanitizer_syscall_pre_impl_creat(long pathname, long mode); +void __sanitizer_syscall_post_impl_creat(long res, long pathname, long mode); +void __sanitizer_syscall_pre_impl_open(long filename, long flags, long mode); +void __sanitizer_syscall_post_impl_open(long res, long filename, long flags, + long mode); +void __sanitizer_syscall_pre_impl_close(long fd); +void __sanitizer_syscall_post_impl_close(long res, long fd); +void __sanitizer_syscall_pre_impl_access(long filename, long mode); +void __sanitizer_syscall_post_impl_access(long res, long filename, long mode); +void __sanitizer_syscall_pre_impl_vhangup(); +void __sanitizer_syscall_post_impl_vhangup(long res); +void __sanitizer_syscall_pre_impl_chown(long filename, long user, long group); +void __sanitizer_syscall_post_impl_chown(long res, long filename, long user, + long group); +void __sanitizer_syscall_pre_impl_lchown(long filename, long user, long group); +void __sanitizer_syscall_post_impl_lchown(long res, long filename, long user, + long group); +void __sanitizer_syscall_pre_impl_fchown(long fd, long user, long group); +void __sanitizer_syscall_post_impl_fchown(long res, long fd, long user, + long group); +void __sanitizer_syscall_pre_impl_chown16(long filename, long user, long group); +void __sanitizer_syscall_post_impl_chown16(long res, long filename, long user, + long group); +void __sanitizer_syscall_pre_impl_lchown16(long filename, long user, + long group); +void __sanitizer_syscall_post_impl_lchown16(long res, long filename, long user, + long group); +void __sanitizer_syscall_pre_impl_fchown16(long fd, long user, long group); +void __sanitizer_syscall_post_impl_fchown16(long res, long fd, long user, + long group); +void __sanitizer_syscall_pre_impl_setregid16(long rgid, long egid); +void __sanitizer_syscall_post_impl_setregid16(long res, long rgid, long egid); +void __sanitizer_syscall_pre_impl_setgid16(long gid); +void __sanitizer_syscall_post_impl_setgid16(long res, long gid); +void __sanitizer_syscall_pre_impl_setreuid16(long ruid, long euid); +void __sanitizer_syscall_post_impl_setreuid16(long res, long ruid, long euid); +void __sanitizer_syscall_pre_impl_setuid16(long uid); +void __sanitizer_syscall_post_impl_setuid16(long res, long uid); +void __sanitizer_syscall_pre_impl_setresuid16(long ruid, long euid, long suid); +void __sanitizer_syscall_post_impl_setresuid16(long res, long ruid, long euid, + long suid); +void __sanitizer_syscall_pre_impl_getresuid16(long ruid, long euid, long suid); +void __sanitizer_syscall_post_impl_getresuid16(long res, long ruid, long euid, + long suid); +void __sanitizer_syscall_pre_impl_setresgid16(long rgid, long egid, long sgid); +void __sanitizer_syscall_post_impl_setresgid16(long res, long rgid, long egid, + long sgid); +void __sanitizer_syscall_pre_impl_getresgid16(long rgid, long egid, long sgid); +void __sanitizer_syscall_post_impl_getresgid16(long res, long rgid, long egid, + long sgid); +void __sanitizer_syscall_pre_impl_setfsuid16(long uid); +void __sanitizer_syscall_post_impl_setfsuid16(long res, long uid); +void __sanitizer_syscall_pre_impl_setfsgid16(long gid); +void __sanitizer_syscall_post_impl_setfsgid16(long res, long gid); +void __sanitizer_syscall_pre_impl_getgroups16(long gidsetsize, long grouplist); +void __sanitizer_syscall_post_impl_getgroups16(long res, long gidsetsize, + long grouplist); +void __sanitizer_syscall_pre_impl_setgroups16(long gidsetsize, long grouplist); +void __sanitizer_syscall_post_impl_setgroups16(long res, long gidsetsize, + long grouplist); +void __sanitizer_syscall_pre_impl_getuid16(); +void __sanitizer_syscall_post_impl_getuid16(long res); +void __sanitizer_syscall_pre_impl_geteuid16(); +void __sanitizer_syscall_post_impl_geteuid16(long res); +void __sanitizer_syscall_pre_impl_getgid16(); +void __sanitizer_syscall_post_impl_getgid16(long res); +void __sanitizer_syscall_pre_impl_getegid16(); +void __sanitizer_syscall_post_impl_getegid16(long res); +void __sanitizer_syscall_pre_impl_utime(long filename, long times); +void __sanitizer_syscall_post_impl_utime(long res, long filename, long times); +void __sanitizer_syscall_pre_impl_utimes(long filename, long utimes); +void __sanitizer_syscall_post_impl_utimes(long res, long filename, long utimes); +void __sanitizer_syscall_pre_impl_lseek(long fd, long offset, long origin); +void __sanitizer_syscall_post_impl_lseek(long res, long fd, long offset, + long origin); +void __sanitizer_syscall_pre_impl_llseek(long fd, long offset_high, + long offset_low, long result, + long origin); +void __sanitizer_syscall_post_impl_llseek(long res, long fd, long offset_high, + long offset_low, long result, + long origin); +void __sanitizer_syscall_pre_impl_read(long fd, long buf, long count); +void __sanitizer_syscall_post_impl_read(long res, long fd, long buf, + long count); +void __sanitizer_syscall_pre_impl_readv(long fd, long vec, long vlen); +void __sanitizer_syscall_post_impl_readv(long res, long fd, long vec, + long vlen); +void __sanitizer_syscall_pre_impl_write(long fd, long buf, long count); +void __sanitizer_syscall_post_impl_write(long res, long fd, long buf, + long count); +void __sanitizer_syscall_pre_impl_writev(long fd, long vec, long vlen); +void __sanitizer_syscall_post_impl_writev(long res, long fd, long vec, + long vlen); + +#ifdef _LP64 +void __sanitizer_syscall_pre_impl_pread64(long fd, long buf, long count, + long pos); +void __sanitizer_syscall_post_impl_pread64(long res, long fd, long buf, + long count, long pos); +void __sanitizer_syscall_pre_impl_pwrite64(long fd, long buf, long count, + long pos); +void __sanitizer_syscall_post_impl_pwrite64(long res, long fd, long buf, + long count, long pos); +#else +void __sanitizer_syscall_pre_impl_pread64(long fd, long buf, long count, + long pos0, long pos1); +void __sanitizer_syscall_post_impl_pread64(long res, long fd, long buf, + long count, long pos0, long pos1); +void __sanitizer_syscall_pre_impl_pwrite64(long fd, long buf, long count, + long pos0, long pos1); +void __sanitizer_syscall_post_impl_pwrite64(long res, long fd, long buf, + long count, long pos0, long pos1); +#endif + +void __sanitizer_syscall_pre_impl_preadv(long fd, long vec, long vlen, + long pos_l, long pos_h); +void __sanitizer_syscall_post_impl_preadv(long res, long fd, long vec, + long vlen, long pos_l, long pos_h); +void __sanitizer_syscall_pre_impl_pwritev(long fd, long vec, long vlen, + long pos_l, long pos_h); +void __sanitizer_syscall_post_impl_pwritev(long res, long fd, long vec, + long vlen, long pos_l, long pos_h); +void __sanitizer_syscall_pre_impl_getcwd(long buf, long size); +void __sanitizer_syscall_post_impl_getcwd(long res, long buf, long size); +void __sanitizer_syscall_pre_impl_mkdir(long pathname, long mode); +void __sanitizer_syscall_post_impl_mkdir(long res, long pathname, long mode); +void __sanitizer_syscall_pre_impl_chdir(long filename); +void __sanitizer_syscall_post_impl_chdir(long res, long filename); +void __sanitizer_syscall_pre_impl_fchdir(long fd); +void __sanitizer_syscall_post_impl_fchdir(long res, long fd); +void __sanitizer_syscall_pre_impl_rmdir(long pathname); +void __sanitizer_syscall_post_impl_rmdir(long res, long pathname); +void __sanitizer_syscall_pre_impl_lookup_dcookie(long cookie64, long buf, + long len); +void __sanitizer_syscall_post_impl_lookup_dcookie(long res, long cookie64, + long buf, long len); +void __sanitizer_syscall_pre_impl_quotactl(long cmd, long special, long id, + long addr); +void __sanitizer_syscall_post_impl_quotactl(long res, long cmd, long special, + long id, long addr); +void __sanitizer_syscall_pre_impl_getdents(long fd, long dirent, long count); +void __sanitizer_syscall_post_impl_getdents(long res, long fd, long dirent, + long count); +void __sanitizer_syscall_pre_impl_getdents64(long fd, long dirent, long count); +void __sanitizer_syscall_post_impl_getdents64(long res, long fd, long dirent, + long count); +void __sanitizer_syscall_pre_impl_setsockopt(long fd, long level, long optname, + long optval, long optlen); +void __sanitizer_syscall_post_impl_setsockopt(long res, long fd, long level, + long optname, long optval, + long optlen); +void __sanitizer_syscall_pre_impl_getsockopt(long fd, long level, long optname, + long optval, long optlen); +void __sanitizer_syscall_post_impl_getsockopt(long res, long fd, long level, + long optname, long optval, + long optlen); +void __sanitizer_syscall_pre_impl_bind(long arg0, long arg1, long arg2); +void __sanitizer_syscall_post_impl_bind(long res, long arg0, long arg1, + long arg2); +void __sanitizer_syscall_pre_impl_connect(long arg0, long arg1, long arg2); +void __sanitizer_syscall_post_impl_connect(long res, long arg0, long arg1, + long arg2); +void __sanitizer_syscall_pre_impl_accept(long arg0, long arg1, long arg2); +void __sanitizer_syscall_post_impl_accept(long res, long arg0, long arg1, + long arg2); +void __sanitizer_syscall_pre_impl_accept4(long arg0, long arg1, long arg2, + long arg3); +void __sanitizer_syscall_post_impl_accept4(long res, long arg0, long arg1, + long arg2, long arg3); +void __sanitizer_syscall_pre_impl_getsockname(long arg0, long arg1, long arg2); +void __sanitizer_syscall_post_impl_getsockname(long res, long arg0, long arg1, + long arg2); +void __sanitizer_syscall_pre_impl_getpeername(long arg0, long arg1, long arg2); +void __sanitizer_syscall_post_impl_getpeername(long res, long arg0, long arg1, + long arg2); +void __sanitizer_syscall_pre_impl_send(long arg0, long arg1, long arg2, + long arg3); +void __sanitizer_syscall_post_impl_send(long res, long arg0, long arg1, + long arg2, long arg3); +void __sanitizer_syscall_pre_impl_sendto(long arg0, long arg1, long arg2, + long arg3, long arg4, long arg5); +void __sanitizer_syscall_post_impl_sendto(long res, long arg0, long arg1, + long arg2, long arg3, long arg4, + long arg5); +void __sanitizer_syscall_pre_impl_sendmsg(long fd, long msg, long flags); +void __sanitizer_syscall_post_impl_sendmsg(long res, long fd, long msg, + long flags); +void __sanitizer_syscall_pre_impl_sendmmsg(long fd, long msg, long vlen, + long flags); +void __sanitizer_syscall_post_impl_sendmmsg(long res, long fd, long msg, + long vlen, long flags); +void __sanitizer_syscall_pre_impl_recv(long arg0, long arg1, long arg2, + long arg3); +void __sanitizer_syscall_post_impl_recv(long res, long arg0, long arg1, + long arg2, long arg3); +void __sanitizer_syscall_pre_impl_recvfrom(long arg0, long arg1, long arg2, + long arg3, long arg4, long arg5); +void __sanitizer_syscall_post_impl_recvfrom(long res, long arg0, long arg1, + long arg2, long arg3, long arg4, + long arg5); +void __sanitizer_syscall_pre_impl_recvmsg(long fd, long msg, long flags); +void __sanitizer_syscall_post_impl_recvmsg(long res, long fd, long msg, + long flags); +void __sanitizer_syscall_pre_impl_recvmmsg(long fd, long msg, long vlen, + long flags, long timeout); +void __sanitizer_syscall_post_impl_recvmmsg(long res, long fd, long msg, + long vlen, long flags, + long timeout); +void __sanitizer_syscall_pre_impl_socket(long arg0, long arg1, long arg2); +void __sanitizer_syscall_post_impl_socket(long res, long arg0, long arg1, + long arg2); +void __sanitizer_syscall_pre_impl_socketpair(long arg0, long arg1, long arg2, + long arg3); +void __sanitizer_syscall_post_impl_socketpair(long res, long arg0, long arg1, + long arg2, long arg3); +void __sanitizer_syscall_pre_impl_socketcall(long call, long args); +void __sanitizer_syscall_post_impl_socketcall(long res, long call, long args); +void __sanitizer_syscall_pre_impl_listen(long arg0, long arg1); +void __sanitizer_syscall_post_impl_listen(long res, long arg0, long arg1); +void __sanitizer_syscall_pre_impl_poll(long ufds, long nfds, long timeout); +void __sanitizer_syscall_post_impl_poll(long res, long ufds, long nfds, + long timeout); +void __sanitizer_syscall_pre_impl_select(long n, long inp, long outp, long exp, + long tvp); +void __sanitizer_syscall_post_impl_select(long res, long n, long inp, long outp, + long exp, long tvp); +void __sanitizer_syscall_pre_impl_old_select(long arg); +void __sanitizer_syscall_post_impl_old_select(long res, long arg); +void __sanitizer_syscall_pre_impl_epoll_create(long size); +void __sanitizer_syscall_post_impl_epoll_create(long res, long size); +void __sanitizer_syscall_pre_impl_epoll_create1(long flags); +void __sanitizer_syscall_post_impl_epoll_create1(long res, long flags); +void __sanitizer_syscall_pre_impl_epoll_ctl(long epfd, long op, long fd, + long event); +void __sanitizer_syscall_post_impl_epoll_ctl(long res, long epfd, long op, + long fd, long event); +void __sanitizer_syscall_pre_impl_epoll_wait(long epfd, long events, + long maxevents, long timeout); +void __sanitizer_syscall_post_impl_epoll_wait(long res, long epfd, long events, + long maxevents, long timeout); +void __sanitizer_syscall_pre_impl_epoll_pwait(long epfd, long events, + long maxevents, long timeout, + long sigmask, long sigsetsize); +void __sanitizer_syscall_post_impl_epoll_pwait(long res, long epfd, long events, + long maxevents, long timeout, + long sigmask, long sigsetsize); +void __sanitizer_syscall_pre_impl_gethostname(long name, long len); +void __sanitizer_syscall_post_impl_gethostname(long res, long name, long len); +void __sanitizer_syscall_pre_impl_sethostname(long name, long len); +void __sanitizer_syscall_post_impl_sethostname(long res, long name, long len); +void __sanitizer_syscall_pre_impl_setdomainname(long name, long len); +void __sanitizer_syscall_post_impl_setdomainname(long res, long name, long len); +void __sanitizer_syscall_pre_impl_newuname(long name); +void __sanitizer_syscall_post_impl_newuname(long res, long name); +void __sanitizer_syscall_pre_impl_uname(long arg0); +void __sanitizer_syscall_post_impl_uname(long res, long arg0); +void __sanitizer_syscall_pre_impl_olduname(long arg0); +void __sanitizer_syscall_post_impl_olduname(long res, long arg0); +void __sanitizer_syscall_pre_impl_getrlimit(long resource, long rlim); +void __sanitizer_syscall_post_impl_getrlimit(long res, long resource, + long rlim); +void __sanitizer_syscall_pre_impl_old_getrlimit(long resource, long rlim); +void __sanitizer_syscall_post_impl_old_getrlimit(long res, long resource, + long rlim); +void __sanitizer_syscall_pre_impl_setrlimit(long resource, long rlim); +void __sanitizer_syscall_post_impl_setrlimit(long res, long resource, + long rlim); +void __sanitizer_syscall_pre_impl_prlimit64(long pid, long resource, + long new_rlim, long old_rlim); +void __sanitizer_syscall_post_impl_prlimit64(long res, long pid, long resource, + long new_rlim, long old_rlim); +void __sanitizer_syscall_pre_impl_getrusage(long who, long ru); +void __sanitizer_syscall_post_impl_getrusage(long res, long who, long ru); +void __sanitizer_syscall_pre_impl_umask(long mask); +void __sanitizer_syscall_post_impl_umask(long res, long mask); +void __sanitizer_syscall_pre_impl_msgget(long key, long msgflg); +void __sanitizer_syscall_post_impl_msgget(long res, long key, long msgflg); +void __sanitizer_syscall_pre_impl_msgsnd(long msqid, long msgp, long msgsz, + long msgflg); +void __sanitizer_syscall_post_impl_msgsnd(long res, long msqid, long msgp, + long msgsz, long msgflg); +void __sanitizer_syscall_pre_impl_msgrcv(long msqid, long msgp, long msgsz, + long msgtyp, long msgflg); +void __sanitizer_syscall_post_impl_msgrcv(long res, long msqid, long msgp, + long msgsz, long msgtyp, long msgflg); +void __sanitizer_syscall_pre_impl_msgctl(long msqid, long cmd, long buf); +void __sanitizer_syscall_post_impl_msgctl(long res, long msqid, long cmd, + long buf); +void __sanitizer_syscall_pre_impl_semget(long key, long nsems, long semflg); +void __sanitizer_syscall_post_impl_semget(long res, long key, long nsems, + long semflg); +void __sanitizer_syscall_pre_impl_semop(long semid, long sops, long nsops); +void __sanitizer_syscall_post_impl_semop(long res, long semid, long sops, + long nsops); +void __sanitizer_syscall_pre_impl_semctl(long semid, long semnum, long cmd, + long arg); +void __sanitizer_syscall_post_impl_semctl(long res, long semid, long semnum, + long cmd, long arg); +void __sanitizer_syscall_pre_impl_semtimedop(long semid, long sops, long nsops, + long timeout); +void __sanitizer_syscall_post_impl_semtimedop(long res, long semid, long sops, + long nsops, long timeout); +void __sanitizer_syscall_pre_impl_shmat(long shmid, long shmaddr, long shmflg); +void __sanitizer_syscall_post_impl_shmat(long res, long shmid, long shmaddr, + long shmflg); +void __sanitizer_syscall_pre_impl_shmget(long key, long size, long flag); +void __sanitizer_syscall_post_impl_shmget(long res, long key, long size, + long flag); +void __sanitizer_syscall_pre_impl_shmdt(long shmaddr); +void __sanitizer_syscall_post_impl_shmdt(long res, long shmaddr); +void __sanitizer_syscall_pre_impl_shmctl(long shmid, long cmd, long buf); +void __sanitizer_syscall_post_impl_shmctl(long res, long shmid, long cmd, + long buf); +void __sanitizer_syscall_pre_impl_ipc(long call, long first, long second, + long third, long ptr, long fifth); +void __sanitizer_syscall_post_impl_ipc(long res, long call, long first, + long second, long third, long ptr, + long fifth); +void __sanitizer_syscall_pre_impl_mq_open(long name, long oflag, long mode, + long attr); +void __sanitizer_syscall_post_impl_mq_open(long res, long name, long oflag, + long mode, long attr); +void __sanitizer_syscall_pre_impl_mq_unlink(long name); +void __sanitizer_syscall_post_impl_mq_unlink(long res, long name); +void __sanitizer_syscall_pre_impl_mq_timedsend(long mqdes, long msg_ptr, + long msg_len, long msg_prio, + long abs_timeout); +void __sanitizer_syscall_post_impl_mq_timedsend(long res, long mqdes, + long msg_ptr, long msg_len, + long msg_prio, + long abs_timeout); +void __sanitizer_syscall_pre_impl_mq_timedreceive(long mqdes, long msg_ptr, + long msg_len, long msg_prio, + long abs_timeout); +void __sanitizer_syscall_post_impl_mq_timedreceive(long res, long mqdes, + long msg_ptr, long msg_len, + long msg_prio, + long abs_timeout); +void __sanitizer_syscall_pre_impl_mq_notify(long mqdes, long notification); +void __sanitizer_syscall_post_impl_mq_notify(long res, long mqdes, + long notification); +void __sanitizer_syscall_pre_impl_mq_getsetattr(long mqdes, long mqstat, + long omqstat); +void __sanitizer_syscall_post_impl_mq_getsetattr(long res, long mqdes, + long mqstat, long omqstat); +void __sanitizer_syscall_pre_impl_pciconfig_iobase(long which, long bus, + long devfn); +void __sanitizer_syscall_post_impl_pciconfig_iobase(long res, long which, + long bus, long devfn); +void __sanitizer_syscall_pre_impl_pciconfig_read(long bus, long dfn, long off, + long len, long buf); +void __sanitizer_syscall_post_impl_pciconfig_read(long res, long bus, long dfn, + long off, long len, long buf); +void __sanitizer_syscall_pre_impl_pciconfig_write(long bus, long dfn, long off, + long len, long buf); +void __sanitizer_syscall_post_impl_pciconfig_write(long res, long bus, long dfn, + long off, long len, + long buf); +void __sanitizer_syscall_pre_impl_swapon(long specialfile, long swap_flags); +void __sanitizer_syscall_post_impl_swapon(long res, long specialfile, + long swap_flags); +void __sanitizer_syscall_pre_impl_swapoff(long specialfile); +void __sanitizer_syscall_post_impl_swapoff(long res, long specialfile); +void __sanitizer_syscall_pre_impl_sysctl(long args); +void __sanitizer_syscall_post_impl_sysctl(long res, long args); +void __sanitizer_syscall_pre_impl_sysinfo(long info); +void __sanitizer_syscall_post_impl_sysinfo(long res, long info); +void __sanitizer_syscall_pre_impl_sysfs(long option, long arg1, long arg2); +void __sanitizer_syscall_post_impl_sysfs(long res, long option, long arg1, + long arg2); +void __sanitizer_syscall_pre_impl_syslog(long type, long buf, long len); +void __sanitizer_syscall_post_impl_syslog(long res, long type, long buf, + long len); +void __sanitizer_syscall_pre_impl_uselib(long library); +void __sanitizer_syscall_post_impl_uselib(long res, long library); +void __sanitizer_syscall_pre_impl_ni_syscall(); +void __sanitizer_syscall_post_impl_ni_syscall(long res); +void __sanitizer_syscall_pre_impl_ptrace(long request, long pid, long addr, + long data); +void __sanitizer_syscall_post_impl_ptrace(long res, long request, long pid, + long addr, long data); +void __sanitizer_syscall_pre_impl_add_key(long _type, long _description, + long _payload, long plen, + long destringid); +void __sanitizer_syscall_post_impl_add_key(long res, long _type, + long _description, long _payload, + long plen, long destringid); +void __sanitizer_syscall_pre_impl_request_key(long _type, long _description, + long _callout_info, + long destringid); +void __sanitizer_syscall_post_impl_request_key(long res, long _type, + long _description, + long _callout_info, + long destringid); +void __sanitizer_syscall_pre_impl_keyctl(long cmd, long arg2, long arg3, + long arg4, long arg5); +void __sanitizer_syscall_post_impl_keyctl(long res, long cmd, long arg2, + long arg3, long arg4, long arg5); +void __sanitizer_syscall_pre_impl_ioprio_set(long which, long who, long ioprio); +void __sanitizer_syscall_post_impl_ioprio_set(long res, long which, long who, + long ioprio); +void __sanitizer_syscall_pre_impl_ioprio_get(long which, long who); +void __sanitizer_syscall_post_impl_ioprio_get(long res, long which, long who); +void __sanitizer_syscall_pre_impl_set_mempolicy(long mode, long nmask, + long maxnode); +void __sanitizer_syscall_post_impl_set_mempolicy(long res, long mode, + long nmask, long maxnode); +void __sanitizer_syscall_pre_impl_migrate_pages(long pid, long maxnode, + long from, long to); +void __sanitizer_syscall_post_impl_migrate_pages(long res, long pid, + long maxnode, long from, + long to); +void __sanitizer_syscall_pre_impl_move_pages(long pid, long nr_pages, + long pages, long nodes, + long status, long flags); +void __sanitizer_syscall_post_impl_move_pages(long res, long pid, long nr_pages, + long pages, long nodes, + long status, long flags); +void __sanitizer_syscall_pre_impl_mbind(long start, long len, long mode, + long nmask, long maxnode, long flags); +void __sanitizer_syscall_post_impl_mbind(long res, long start, long len, + long mode, long nmask, long maxnode, + long flags); +void __sanitizer_syscall_pre_impl_get_mempolicy(long policy, long nmask, + long maxnode, long addr, + long flags); +void __sanitizer_syscall_post_impl_get_mempolicy(long res, long policy, + long nmask, long maxnode, + long addr, long flags); +void __sanitizer_syscall_pre_impl_inotify_init(); +void __sanitizer_syscall_post_impl_inotify_init(long res); +void __sanitizer_syscall_pre_impl_inotify_init1(long flags); +void __sanitizer_syscall_post_impl_inotify_init1(long res, long flags); +void __sanitizer_syscall_pre_impl_inotify_add_watch(long fd, long path, + long mask); +void __sanitizer_syscall_post_impl_inotify_add_watch(long res, long fd, + long path, long mask); +void __sanitizer_syscall_pre_impl_inotify_rm_watch(long fd, long wd); +void __sanitizer_syscall_post_impl_inotify_rm_watch(long res, long fd, long wd); +void __sanitizer_syscall_pre_impl_spu_run(long fd, long unpc, long ustatus); +void __sanitizer_syscall_post_impl_spu_run(long res, long fd, long unpc, + long ustatus); +void __sanitizer_syscall_pre_impl_spu_create(long name, long flags, long mode, + long fd); +void __sanitizer_syscall_post_impl_spu_create(long res, long name, long flags, + long mode, long fd); +void __sanitizer_syscall_pre_impl_mknodat(long dfd, long filename, long mode, + long dev); +void __sanitizer_syscall_post_impl_mknodat(long res, long dfd, long filename, + long mode, long dev); +void __sanitizer_syscall_pre_impl_mkdirat(long dfd, long pathname, long mode); +void __sanitizer_syscall_post_impl_mkdirat(long res, long dfd, long pathname, + long mode); +void __sanitizer_syscall_pre_impl_unlinkat(long dfd, long pathname, long flag); +void __sanitizer_syscall_post_impl_unlinkat(long res, long dfd, long pathname, + long flag); +void __sanitizer_syscall_pre_impl_symlinkat(long oldname, long newdfd, + long newname); +void __sanitizer_syscall_post_impl_symlinkat(long res, long oldname, + long newdfd, long newname); +void __sanitizer_syscall_pre_impl_linkat(long olddfd, long oldname, long newdfd, + long newname, long flags); +void __sanitizer_syscall_post_impl_linkat(long res, long olddfd, long oldname, + long newdfd, long newname, + long flags); +void __sanitizer_syscall_pre_impl_renameat(long olddfd, long oldname, + long newdfd, long newname); +void __sanitizer_syscall_post_impl_renameat(long res, long olddfd, long oldname, + long newdfd, long newname); +void __sanitizer_syscall_pre_impl_futimesat(long dfd, long filename, + long utimes); +void __sanitizer_syscall_post_impl_futimesat(long res, long dfd, long filename, + long utimes); +void __sanitizer_syscall_pre_impl_faccessat(long dfd, long filename, long mode); +void __sanitizer_syscall_post_impl_faccessat(long res, long dfd, long filename, + long mode); +void __sanitizer_syscall_pre_impl_fchmodat(long dfd, long filename, long mode); +void __sanitizer_syscall_post_impl_fchmodat(long res, long dfd, long filename, + long mode); +void __sanitizer_syscall_pre_impl_fchownat(long dfd, long filename, long user, + long group, long flag); +void __sanitizer_syscall_post_impl_fchownat(long res, long dfd, long filename, + long user, long group, long flag); +void __sanitizer_syscall_pre_impl_openat(long dfd, long filename, long flags, + long mode); +void __sanitizer_syscall_post_impl_openat(long res, long dfd, long filename, + long flags, long mode); +void __sanitizer_syscall_pre_impl_newfstatat(long dfd, long filename, + long statbuf, long flag); +void __sanitizer_syscall_post_impl_newfstatat(long res, long dfd, long filename, + long statbuf, long flag); +void __sanitizer_syscall_pre_impl_fstatat64(long dfd, long filename, + long statbuf, long flag); +void __sanitizer_syscall_post_impl_fstatat64(long res, long dfd, long filename, + long statbuf, long flag); +void __sanitizer_syscall_pre_impl_readlinkat(long dfd, long path, long buf, + long bufsiz); +void __sanitizer_syscall_post_impl_readlinkat(long res, long dfd, long path, + long buf, long bufsiz); +void __sanitizer_syscall_pre_impl_utimensat(long dfd, long filename, + long utimes, long flags); +void __sanitizer_syscall_post_impl_utimensat(long res, long dfd, long filename, + long utimes, long flags); +void __sanitizer_syscall_pre_impl_unshare(long unshare_flags); +void __sanitizer_syscall_post_impl_unshare(long res, long unshare_flags); +void __sanitizer_syscall_pre_impl_splice(long fd_in, long off_in, long fd_out, + long off_out, long len, long flags); +void __sanitizer_syscall_post_impl_splice(long res, long fd_in, long off_in, + long fd_out, long off_out, long len, + long flags); +void __sanitizer_syscall_pre_impl_vmsplice(long fd, long iov, long nr_segs, + long flags); +void __sanitizer_syscall_post_impl_vmsplice(long res, long fd, long iov, + long nr_segs, long flags); +void __sanitizer_syscall_pre_impl_tee(long fdin, long fdout, long len, + long flags); +void __sanitizer_syscall_post_impl_tee(long res, long fdin, long fdout, + long len, long flags); +void __sanitizer_syscall_pre_impl_get_robust_list(long pid, long head_ptr, + long len_ptr); +void __sanitizer_syscall_post_impl_get_robust_list(long res, long pid, + long head_ptr, long len_ptr); +void __sanitizer_syscall_pre_impl_set_robust_list(long head, long len); +void __sanitizer_syscall_post_impl_set_robust_list(long res, long head, + long len); +void __sanitizer_syscall_pre_impl_getcpu(long cpu, long node, long cache); +void __sanitizer_syscall_post_impl_getcpu(long res, long cpu, long node, + long cache); +void __sanitizer_syscall_pre_impl_signalfd(long ufd, long user_mask, + long sizemask); +void __sanitizer_syscall_post_impl_signalfd(long res, long ufd, long user_mask, + long sizemask); +void __sanitizer_syscall_pre_impl_signalfd4(long ufd, long user_mask, + long sizemask, long flags); +void __sanitizer_syscall_post_impl_signalfd4(long res, long ufd, long user_mask, + long sizemask, long flags); +void __sanitizer_syscall_pre_impl_timerfd_create(long clockid, long flags); +void __sanitizer_syscall_post_impl_timerfd_create(long res, long clockid, + long flags); +void __sanitizer_syscall_pre_impl_timerfd_settime(long ufd, long flags, + long utmr, long otmr); +void __sanitizer_syscall_post_impl_timerfd_settime(long res, long ufd, + long flags, long utmr, + long otmr); +void __sanitizer_syscall_pre_impl_timerfd_gettime(long ufd, long otmr); +void __sanitizer_syscall_post_impl_timerfd_gettime(long res, long ufd, + long otmr); +void __sanitizer_syscall_pre_impl_eventfd(long count); +void __sanitizer_syscall_post_impl_eventfd(long res, long count); +void __sanitizer_syscall_pre_impl_eventfd2(long count, long flags); +void __sanitizer_syscall_post_impl_eventfd2(long res, long count, long flags); +void __sanitizer_syscall_pre_impl_old_readdir(long arg0, long arg1, long arg2); +void __sanitizer_syscall_post_impl_old_readdir(long res, long arg0, long arg1, + long arg2); +void __sanitizer_syscall_pre_impl_pselect6(long arg0, long arg1, long arg2, + long arg3, long arg4, long arg5); +void __sanitizer_syscall_post_impl_pselect6(long res, long arg0, long arg1, + long arg2, long arg3, long arg4, + long arg5); +void __sanitizer_syscall_pre_impl_ppoll(long arg0, long arg1, long arg2, + long arg3, long arg4); +void __sanitizer_syscall_post_impl_ppoll(long res, long arg0, long arg1, + long arg2, long arg3, long arg4); +void __sanitizer_syscall_pre_impl_fanotify_init(long flags, long event_f_flags); +void __sanitizer_syscall_post_impl_fanotify_init(long res, long flags, + long event_f_flags); +void __sanitizer_syscall_pre_impl_fanotify_mark(long fanotify_fd, long flags, + long mask, long fd, + long pathname); +void __sanitizer_syscall_post_impl_fanotify_mark(long res, long fanotify_fd, + long flags, long mask, long fd, + long pathname); +void __sanitizer_syscall_pre_impl_syncfs(long fd); +void __sanitizer_syscall_post_impl_syncfs(long res, long fd); +void __sanitizer_syscall_pre_impl_perf_event_open(long attr_uptr, long pid, + long cpu, long group_fd, + long flags); +void __sanitizer_syscall_post_impl_perf_event_open(long res, long attr_uptr, + long pid, long cpu, + long group_fd, long flags); +void __sanitizer_syscall_pre_impl_mmap_pgoff(long addr, long len, long prot, + long flags, long fd, long pgoff); +void __sanitizer_syscall_post_impl_mmap_pgoff(long res, long addr, long len, + long prot, long flags, long fd, + long pgoff); +void __sanitizer_syscall_pre_impl_old_mmap(long arg); +void __sanitizer_syscall_post_impl_old_mmap(long res, long arg); +void __sanitizer_syscall_pre_impl_name_to_handle_at(long dfd, long name, + long handle, long mnt_id, + long flag); +void __sanitizer_syscall_post_impl_name_to_handle_at(long res, long dfd, + long name, long handle, + long mnt_id, long flag); +void __sanitizer_syscall_pre_impl_open_by_handle_at(long mountdirfd, + long handle, long flags); +void __sanitizer_syscall_post_impl_open_by_handle_at(long res, long mountdirfd, + long handle, long flags); +void __sanitizer_syscall_pre_impl_setns(long fd, long nstype); +void __sanitizer_syscall_post_impl_setns(long res, long fd, long nstype); +void __sanitizer_syscall_pre_impl_process_vm_readv(long pid, long lvec, + long liovcnt, long rvec, + long riovcnt, long flags); +void __sanitizer_syscall_post_impl_process_vm_readv(long res, long pid, + long lvec, long liovcnt, + long rvec, long riovcnt, + long flags); +void __sanitizer_syscall_pre_impl_process_vm_writev(long pid, long lvec, + long liovcnt, long rvec, + long riovcnt, long flags); +void __sanitizer_syscall_post_impl_process_vm_writev(long res, long pid, + long lvec, long liovcnt, + long rvec, long riovcnt, + long flags); +void __sanitizer_syscall_pre_impl_fork(); +void __sanitizer_syscall_post_impl_fork(long res); +void __sanitizer_syscall_pre_impl_vfork(); +void __sanitizer_syscall_post_impl_vfork(long res); + +#ifdef __cplusplus +} // extern "C" #endif -#endif // SANITIZER_LINUX_SYSCALL_HOOKS_H +#endif // SANITIZER_LINUX_SYSCALL_HOOKS_H diff --git a/include/sanitizer/lsan_interface.h b/include/sanitizer/lsan_interface.h new file mode 100644 index 000000000000..df256c0e5384 --- /dev/null +++ b/include/sanitizer/lsan_interface.h @@ -0,0 +1,52 @@ +//===-- sanitizer/lsan_interface.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 LeakSanitizer. +// +// Public interface header. +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_LSAN_INTERFACE_H +#define SANITIZER_LSAN_INTERFACE_H + +#include <sanitizer/common_interface_defs.h> + +#ifdef __cplusplus +extern "C" { +#endif + // Allocations made between calls to __lsan_disable() and __lsan_enable() will + // be treated as non-leaks. Disable/enable pairs may be nested. + void __lsan_disable(); + void __lsan_enable(); + // The heap object into which p points will be treated as a non-leak. + void __lsan_ignore_object(const void *p); + // The user may optionally provide this function to disallow leak checking + // for the program it is linked into (if the return value is non-zero). This + // function must be defined as returning a constant value; any behavior beyond + // that is unsupported. + int __lsan_is_turned_off(); + // Calling this function makes LSan enter the leak checking phase immediately. + // Use this if normal end-of-process leak checking happens too late (e.g. if + // you have intentional memory leaks in your shutdown code). Calling this + // function overrides end-of-process leak checking; it must be called at + // most once per process. This function will terminate the process if there + // are memory leaks and the exit_code flag is non-zero. + void __lsan_do_leak_check(); +#ifdef __cplusplus +} // extern "C" + +namespace __lsan { +class ScopedDisabler { + public: + ScopedDisabler() { __lsan_disable(); } + ~ScopedDisabler() { __lsan_enable(); } +}; +} // namespace __lsan +#endif + +#endif // SANITIZER_LSAN_INTERFACE_H diff --git a/include/sanitizer/msan_interface.h b/include/sanitizer/msan_interface.h index 9eff7b597b69..63af84fc3ff1 100644 --- a/include/sanitizer/msan_interface.h +++ b/include/sanitizer/msan_interface.h @@ -27,10 +27,10 @@ extern "C" { /* Set raw origin for the memory range. */ - void __msan_set_origin(const void *a, size_t size, uint32_t origin); + void __msan_set_origin(const volatile void *a, size_t size, uint32_t origin); /* Get raw origin for an address. */ - uint32_t __msan_get_origin(const void *a); + uint32_t __msan_get_origin(const volatile void *a); /* Returns non-zero if tracking origins. */ int __msan_get_track_origins(); @@ -39,18 +39,19 @@ extern "C" { uint32_t __msan_get_umr_origin(); /* Make memory region fully initialized (without changing its contents). */ - void __msan_unpoison(const void *a, size_t size); + void __msan_unpoison(const volatile void *a, size_t size); /* Make memory region fully uninitialized (without changing its contents). */ - void __msan_poison(const void *a, size_t size); + void __msan_poison(const volatile void *a, size_t size); /* Make memory region partially uninitialized (without changing its contents). */ - void __msan_partial_poison(const void* data, void* shadow, size_t size); + void __msan_partial_poison(const volatile void *data, void *shadow, + size_t size); /* Returns the offset of the first (at least partially) poisoned byte in the memory range, or -1 if the whole range is good. */ - intptr_t __msan_test_shadow(const void *x, size_t size); + intptr_t __msan_test_shadow(const volatile void *x, size_t size); /* Set exit code when error(s) were detected. Value of 0 means don't change the program exit code. */ @@ -63,9 +64,14 @@ extern "C" { The last line will verify that a UMR happened. */ void __msan_set_expect_umr(int expect_umr); + /* Change the value of keep_going flag. Non-zero value means don't terminate + program execution when an error is detected. This will not affect error in + modules that were compiled without the corresponding compiler flag. */ + void __msan_set_keep_going(int keep_going); + /* Print shadow and origin for the memory range to stdout in a human-readable format. */ - void __msan_print_shadow(const void *x, size_t size); + void __msan_print_shadow(const volatile void *x, size_t size); /* Print current function arguments shadow and origin to stdout in a human-readable format. */ @@ -76,7 +82,58 @@ extern "C" { /* Tell MSan about newly allocated memory (ex.: custom allocator). Memory will be marked uninitialized, with origin at the call site. */ - void __msan_allocated_memory(const void* data, size_t size); + void __msan_allocated_memory(const volatile void* data, size_t size); + + /* This function may be optionally provided by user and should return + a string containing Msan runtime options. See msan_flags.h for details. */ + const char* __msan_default_options(); + + + /***********************************/ + /* Allocator statistics interface. */ + + /* Returns the estimated number of bytes that will be reserved by allocator + for request of "size" bytes. If Msan allocator can't allocate that much + memory, returns the maximal possible allocation size, otherwise returns + "size". */ + size_t __msan_get_estimated_allocated_size(size_t size); + + /* Returns true if p was returned by the Msan allocator and + is not yet freed. */ + int __msan_get_ownership(const volatile void *p); + + /* Returns the number of bytes reserved for the pointer p. + Requires (get_ownership(p) == true) or (p == 0). */ + size_t __msan_get_allocated_size(const volatile void *p); + + /* Number of bytes, allocated and not yet freed by the application. */ + size_t __msan_get_current_allocated_bytes(); + + /* Number of bytes, mmaped by msan allocator to fulfill allocation requests. + Generally, for request of X bytes, allocator can reserve and add to free + lists a large number of chunks of size X to use them for future requests. + All these chunks count toward the heap size. Currently, allocator never + releases memory to OS (instead, it just puts freed chunks to free + lists). */ + size_t __msan_get_heap_size(); + + /* Number of bytes, mmaped by msan allocator, which can be used to fulfill + allocation requests. When a user program frees memory chunk, it can first + fall into quarantine and will count toward __msan_get_free_bytes() + later. */ + size_t __msan_get_free_bytes(); + + /* Number of bytes in unmapped pages, that are released to OS. Currently, + always returns 0. */ + size_t __msan_get_unmapped_bytes(); + + /* Malloc hooks that may be optionally provided by user. + __msan_malloc_hook(ptr, size) is called immediately after + allocation of "size" bytes, which returned "ptr". + __msan_free_hook(ptr) is called immediately before + deallocation of "ptr". */ + void __msan_malloc_hook(const volatile void *ptr, size_t size); + void __msan_free_hook(const volatile void *ptr); #else // __has_feature(memory_sanitizer) diff --git a/lib/CMakeLists.txt b/lib/CMakeLists.txt index f07ab1e1872b..b620828beb2b 100644 --- a/lib/CMakeLists.txt +++ b/lib/CMakeLists.txt @@ -1,22 +1,36 @@ # First, add the subdirectories which contain feature-based runtime libraries # and several convenience helper libraries. -if(CMAKE_SYSTEM_NAME MATCHES "Darwin|Linux") + +# Don't build sanitizers in the bootstrap build. +if(LLVM_USE_SANITIZER STREQUAL "") # AddressSanitizer is supported on Linux and Mac OS X. - # Windows support is work in progress. - add_subdirectory(asan) - add_subdirectory(interception) - add_subdirectory(sanitizer_common) - if(NOT ANDROID) + # 32-bit Windows support is experimental. + if(CMAKE_SYSTEM_NAME MATCHES "Darwin|Linux") + set(SUPPORTS_BUILDING_ASAN TRUE) + elseif(CMAKE_SYSTEM_NAME MATCHES "Windows" + AND MSVC AND CMAKE_SIZEOF_VOID_P EQUAL 4) + set(SUPPORTS_BUILDING_ASAN TRUE) + else() + set(SUPPORTS_BUILDING_ASAN FALSE) + endif() + if(SUPPORTS_BUILDING_ASAN) + add_subdirectory(asan) + add_subdirectory(interception) + add_subdirectory(sanitizer_common) + endif() + if(CMAKE_SYSTEM_NAME MATCHES "Darwin|Linux" AND NOT ANDROID) + # LSan, UBsan and profile can be built on Mac OS and Linux. + add_subdirectory(lsan) add_subdirectory(profile) add_subdirectory(ubsan) endif() -endif() -if("${CMAKE_SYSTEM_NAME}" STREQUAL "Linux" AND NOT ANDROID) - # ThreadSanitizer and MemorySanitizer are supported on Linux only. - add_subdirectory(tsan) - add_subdirectory(msan) - add_subdirectory(msandr) - add_subdirectory(lsan) + if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT ANDROID) + # ThreadSanitizer and MemorySanitizer are supported on Linux only. + add_subdirectory(tsan) + add_subdirectory(msan) + add_subdirectory(msandr) + add_subdirectory(dfsan) + endif() endif() # The top-level lib directory contains a large amount of C code which provides @@ -181,10 +195,22 @@ set(i386_SOURCES i386/umoddi3.S ${GENERIC_SOURCES}) -foreach(arch x86_64 i386) - if(CAN_TARGET_${arch}) - add_compiler_rt_static_runtime(clang_rt.${arch} ${arch} - SOURCES ${${arch}_SOURCES} - CFLAGS "-std=c99") - endif() -endforeach() +if (NOT WIN32) + foreach(arch x86_64 i386) + if(CAN_TARGET_${arch}) + add_compiler_rt_static_runtime(clang_rt.${arch} ${arch} + SOURCES ${${arch}_SOURCES} + CFLAGS "-std=c99") + endif() + endforeach() +endif() + +# Generate configs for running lit and unit tests. +configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.common.configured.in + ${CMAKE_CURRENT_BINARY_DIR}/lit.common.configured) + +configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/lit.common.unit.configured.in + ${CMAKE_CURRENT_BINARY_DIR}/lit.common.unit.configured) + diff --git a/lib/Makefile.mk b/lib/Makefile.mk index 8054c35aa362..f9d7800cc4c4 100644 --- a/lib/Makefile.mk +++ b/lib/Makefile.mk @@ -22,6 +22,7 @@ SubDirs += tsan SubDirs += msan SubDirs += ubsan SubDirs += lsan +SubDirs += dfsan # Define the variables for this specific directory. Sources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file))) diff --git a/lib/apple_versioning.c b/lib/apple_versioning.c index 09f149f14cf7..3797a1ab02da 100644 --- a/lib/apple_versioning.c +++ b/lib/apple_versioning.c @@ -9,19 +9,20 @@ */ - #if __APPLE__ - #if __arm__ + #include <Availability.h> + + #if __IPHONE_OS_VERSION_MIN_REQUIRED #define NOT_HERE_BEFORE_10_6(sym) - #define NOT_HERE_IN_10_8_AND_EARLIER(sym) - #elif __ppc__ - #define NOT_HERE_BEFORE_10_6(sym) \ - extern const char sym##_tmp3 __asm("$ld$hide$os10.3$_" #sym ); \ - __attribute__((visibility("default"))) const char sym##_tmp3 = 0; \ - extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \ - __attribute__((visibility("default"))) const char sym##_tmp4 = 0; \ - extern const char sym##_tmp5 __asm("$ld$hide$os10.5$_" #sym ); \ - __attribute__((visibility("default"))) const char sym##_tmp5 = 0; + #define NOT_HERE_IN_10_8_AND_EARLIER(sym) \ + extern const char sym##_tmp61 __asm("$ld$hide$os6.1$_" #sym ); \ + __attribute__((visibility("default"))) const char sym##_tmp61 = 0; \ + extern const char sym##_tmp60 __asm("$ld$hide$os6.0$_" #sym ); \ + __attribute__((visibility("default"))) const char sym##_tmp60 = 0; \ + extern const char sym##_tmp51 __asm("$ld$hide$os5.1$_" #sym ); \ + __attribute__((visibility("default"))) const char sym##_tmp51 = 0; \ + extern const char sym##_tmp50 __asm("$ld$hide$os5.0$_" #sym ); \ + __attribute__((visibility("default"))) const char sym##_tmp50 = 0; #else #define NOT_HERE_BEFORE_10_6(sym) \ extern const char sym##_tmp4 __asm("$ld$hide$os10.4$_" #sym ); \ @@ -35,7 +36,7 @@ __attribute__((visibility("default"))) const char sym##_tmp7 = 0; \ extern const char sym##_tmp6 __asm("$ld$hide$os10.6$_" #sym ); \ __attribute__((visibility("default"))) const char sym##_tmp6 = 0; - #endif /* __ppc__ */ + #endif /* Symbols in libSystem.dylib in 10.6 and later, diff --git a/lib/arm/Makefile.mk b/lib/arm/Makefile.mk index 04dec88a9714..a2df115f926f 100644 --- a/lib/arm/Makefile.mk +++ b/lib/arm/Makefile.mk @@ -9,7 +9,7 @@ ModuleName := builtins SubDirs := -OnlyArchs := armv5 armv6 armv7 armv7f armv7k armv7s +OnlyArchs := armv5 armv6 armv7 armv7f armv7k armv7m armv7em armv7s AsmSources := $(foreach file,$(wildcard $(Dir)/*.S),$(notdir $(file))) Sources := $(foreach file,$(wildcard $(Dir)/*.c),$(notdir $(file))) diff --git a/lib/arm/comparesf2.S b/lib/arm/comparesf2.S index ee18203392dc..ce6f4b9efd00 100644 --- a/lib/arm/comparesf2.S +++ b/lib/arm/comparesf2.S @@ -59,12 +59,14 @@ DEFINE_COMPILERRT_FUNCTION(__nesf2) // Next, we check if a and b have the same or different signs. If they have // opposite signs, this eor will set the N flag. + it ne eorsne r12, r0, r1 // If a and b are equal (either both zeros or bit identical; again, we're // ignoring NaNs for now), this subtract will zero out r0. If they have the // same sign, the flags are updated as they would be for a comparison of the // absolute values of a and b. + it pl subspl r0, r2, r3 // If a is smaller in magnitude than b and both have the same sign, place @@ -77,23 +79,27 @@ DEFINE_COMPILERRT_FUNCTION(__nesf2) // still clear from the shift argument in orrs; if a is positive and b // negative, this places 0 in r0; if a is negative and b positive, -1 is // placed in r0. + it lo mvnlo r0, r1, asr #31 // If a is greater in magnitude than b and both have the same sign, place // the sign of b in r0. Thus, if both are negative and a < b, -1 is placed // in r0, which is the desired result. Conversely, if both are positive // and a > b, zero is placed in r0. + it hi movhi r0, r1, asr #31 // If you've been keeping track, at this point r0 contains -1 if a < b and // 0 if a >= b. All that remains to be done is to set it to 1 if a > b. // If a == b, then the Z flag is set, so we can get the correct final value // into r0 by simply or'ing with 1 if Z is clear. - orrne r0, r0, #1 + it ne + orrne r0, r0, #1 // Finally, we need to deal with NaNs. If either argument is NaN, replace // the value in r0 with 1. cmp r2, #0xff000000 + ite ls cmpls r3, #0xff000000 movhi r0, #1 bx lr @@ -108,12 +114,18 @@ DEFINE_COMPILERRT_FUNCTION(__gtsf2) mov r2, r0, lsl #1 mov r3, r1, lsl #1 orrs r12, r2, r3, lsr #1 + it ne eorsne r12, r0, r1 + it pl subspl r0, r2, r3 + it lo mvnlo r0, r1, asr #31 + it hi movhi r0, r1, asr #31 - orrne r0, r0, #1 + it ne + orrne r0, r0, #1 cmp r2, #0xff000000 + ite ls cmpls r3, #0xff000000 movhi r0, #-1 bx lr @@ -125,6 +137,7 @@ DEFINE_COMPILERRT_FUNCTION(__unordsf2) mov r3, r1, lsl #1 mov r0, #0 cmp r2, #0xff000000 + ite ls cmpls r3, #0xff000000 movhi r0, #1 bx lr diff --git a/lib/arm/divmodsi4.S b/lib/arm/divmodsi4.S index d31e510c8f38..6495a8b4cc3a 100644 --- a/lib/arm/divmodsi4.S +++ b/lib/arm/divmodsi4.S @@ -24,7 +24,7 @@ .syntax unified .align 3 DEFINE_COMPILERRT_FUNCTION(__divmodsi4) -#if __ARM_ARCH_7S__ +#if __ARM_ARCH_EXT_IDIV__ tst r1, r1 beq LOCAL_LABEL(divzero) mov r3, r0 diff --git a/lib/arm/divsi3.S b/lib/arm/divsi3.S index e76fe31bb782..b631db292b8a 100644 --- a/lib/arm/divsi3.S +++ b/lib/arm/divsi3.S @@ -25,7 +25,7 @@ // Ok, APCS and AAPCS agree on 32 bit args, so it's safe to use the same routine. DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_idiv, __divsi3) DEFINE_COMPILERRT_FUNCTION(__divsi3) -#if __ARM_ARCH_7S__ +#if __ARM_ARCH_EXT_IDIV__ tst r1,r1 beq LOCAL_LABEL(divzero) sdiv r0, r0, r1 diff --git a/lib/arm/modsi3.S b/lib/arm/modsi3.S index 04595011d0ec..fe75b41b1331 100644 --- a/lib/arm/modsi3.S +++ b/lib/arm/modsi3.S @@ -23,7 +23,7 @@ .syntax unified .align 3 DEFINE_COMPILERRT_FUNCTION(__modsi3) -#if __ARM_ARCH_7S__ +#if __ARM_ARCH_EXT_IDIV__ tst r1, r1 beq LOCAL_LABEL(divzero) sdiv r2, r0, r1 diff --git a/lib/arm/switch16.S b/lib/arm/switch16.S index e8f08c49c5df..9c3f0cf9915f 100644 --- a/lib/arm/switch16.S +++ b/lib/arm/switch16.S @@ -34,8 +34,9 @@ DEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch16) ldrh ip, [lr, #-1] // get first 16-bit word in table cmp r0, ip // compare with index add r0, lr, r0, lsl #1 // compute address of element in table - ldrshcc r0, [r0, #1] // load 16-bit element if r0 is in range add ip, lr, ip, lsl #1 // compute address of last element in table + ite lo + ldrshlo r0, [r0, #1] // load 16-bit element if r0 is in range ldrshhs r0, [ip, #1] // load 16-bit element if r0 out of range add ip, lr, r0, lsl #1 // compute label = lr + element*2 bx ip // jump to computed label diff --git a/lib/arm/switch32.S b/lib/arm/switch32.S index 7008fccb18ee..3152dfa1d0be 100644 --- a/lib/arm/switch32.S +++ b/lib/arm/switch32.S @@ -34,9 +34,10 @@ DEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch32) ldr ip, [lr, #-1] // get first 32-bit word in table cmp r0, ip // compare with index add r0, lr, r0, lsl #2 // compute address of element in table - ldrcc r0, [r0, #3] // load 32-bit element if r0 is in range add ip, lr, ip, lsl #2 // compute address of last element in table - ldrcs r0, [ip, #3] // load 32-bit element if r0 out of range + ite lo + ldrlo r0, [r0, #3] // load 32-bit element if r0 is in range + ldrhs r0, [ip, #3] // load 32-bit element if r0 out of range add ip, lr, r0 // compute label = lr + element bx ip // jump to computed label diff --git a/lib/arm/switch8.S b/lib/arm/switch8.S index e784b4082e1f..15729ebc3165 100644 --- a/lib/arm/switch8.S +++ b/lib/arm/switch8.S @@ -33,7 +33,8 @@ DEFINE_COMPILERRT_PRIVATE_FUNCTION(__switch8) ldrb ip, [lr, #-1] // get first byte in table cmp r0, ip // signed compare with index - ldrsbcc r0, [lr, r0] // get indexed byte out of table + ite lo + ldrsblo r0, [lr, r0] // get indexed byte out of table ldrsbhs r0, [lr, ip] // if out of range, use last entry in table add ip, lr, r0, lsl #1 // compute label = lr + element*2 bx ip // jump to computed label diff --git a/lib/arm/switchu8.S b/lib/arm/switchu8.S index 19bed2f664d7..0a4efac88abe 100644 --- a/lib/arm/switchu8.S +++ b/lib/arm/switchu8.S @@ -33,7 +33,8 @@ DEFINE_COMPILERRT_PRIVATE_FUNCTION(__switchu8) ldrb ip, [lr, #-1] // get first byte in table cmp r0, ip // compare with index - ldrbcc r0, [lr, r0] // get indexed byte out of table + ite lo + ldrblo r0, [lr, r0] // get indexed byte out of table ldrbhs r0, [lr, ip] // if out of range, use last entry in table add ip, lr, r0, lsl #1 // compute label = lr + element*2 bx ip // jump to computed label diff --git a/lib/arm/udivmodsi4.S b/lib/arm/udivmodsi4.S index 9956cd48442f..aee2776671f7 100644 --- a/lib/arm/udivmodsi4.S +++ b/lib/arm/udivmodsi4.S @@ -31,7 +31,7 @@ .syntax unified .align 3 DEFINE_COMPILERRT_FUNCTION(__udivmodsi4) -#if __ARM_ARCH_7S__ +#if __ARM_ARCH_EXT_IDIV__ tst r1, r1 beq LOCAL_LABEL(divzero) mov r3, r0 @@ -74,14 +74,17 @@ LOCAL_LABEL(mainLoop): // this way, we can merge the two branches which is a substantial win for // such a tight loop on current ARM architectures. subs r, a, b, lsl i + itt hs orrhs q, q,one, lsl i movhs a, r + it ne subsne i, i, #1 bhi LOCAL_LABEL(mainLoop) // Do the final test subtraction and update of quotient (i == 0), as it is // not performed in the main loop. subs r, a, b + itt hs orrhs q, #1 movhs a, r diff --git a/lib/arm/udivsi3.S b/lib/arm/udivsi3.S index 28979fee4bdc..2bb14123ca31 100644 --- a/lib/arm/udivsi3.S +++ b/lib/arm/udivsi3.S @@ -33,7 +33,7 @@ // Ok, APCS and AAPCS agree on 32 bit args, so it's safe to use the same routine. DEFINE_AEABI_FUNCTION_ALIAS(__aeabi_uidiv, __udivsi3) DEFINE_COMPILERRT_FUNCTION(__udivsi3) -#if __ARM_ARCH_7S__ +#if __ARM_ARCH_EXT_IDIV__ tst r1,r1 beq LOCAL_LABEL(divzero) udiv r0, r0, r1 @@ -73,14 +73,17 @@ LOCAL_LABEL(mainLoop): // this way, we can merge the two branches which is a substantial win for // such a tight loop on current ARM architectures. subs r, a, b, lsl i + itt hs orrhs q, q,one, lsl i movhs a, r + it ne subsne i, i, #1 bhi LOCAL_LABEL(mainLoop) // Do the final test subtraction and update of quotient (i == 0), as it is // not performed in the main loop. subs r, a, b + it hs orrhs q, #1 LOCAL_LABEL(return): diff --git a/lib/arm/umodsi3.S b/lib/arm/umodsi3.S index 328e7054b857..092a4f1a2062 100644 --- a/lib/arm/umodsi3.S +++ b/lib/arm/umodsi3.S @@ -23,7 +23,7 @@ .syntax unified .align 3 DEFINE_COMPILERRT_FUNCTION(__umodsi3) -#if __ARM_ARCH_7S__ +#if __ARM_ARCH_EXT_IDIV__ tst r1, r1 beq LOCAL_LABEL(divzero) udiv r2, r0, r1 @@ -57,13 +57,16 @@ LOCAL_LABEL(mainLoop): // this way, we can merge the two branches which is a substantial win for // such a tight loop on current ARM architectures. subs r, a, b, lsl i + it hs movhs a, r + it ne subsne i, i, #1 bhi LOCAL_LABEL(mainLoop) // Do the final test subtraction and update of remainder (i == 0), as it is // not performed in the main loop. subs r, a, b + it hs movhs a, r bx lr #endif diff --git a/lib/asan/CMakeLists.txt b/lib/asan/CMakeLists.txt index a567a4d3e970..ad3f05488ebf 100644 --- a/lib/asan/CMakeLists.txt +++ b/lib/asan/CMakeLists.txt @@ -19,18 +19,19 @@ set(ASAN_SOURCES asan_stack.cc asan_stats.cc asan_thread.cc - asan_win.cc - ) - -set(ASAN_DYLIB_SOURCES - ${ASAN_SOURCES} - ) + asan_win.cc) include_directories(..) -set(ASAN_CFLAGS - ${SANITIZER_COMMON_CFLAGS} - -fno-rtti) +if (NOT MSVC) + set(ASAN_CFLAGS + ${SANITIZER_COMMON_CFLAGS} + -fno-rtti) +else() + set(ASAN_CFLAGS + ${SANITIZER_COMMON_CFLAGS} + /GR-) +endif() set(ASAN_COMMON_DEFINITIONS ASAN_HAS_EXCEPTIONS=1) @@ -40,6 +41,10 @@ if(ANDROID) ASAN_FLEXIBLE_MAPPING_AND_OFFSET=0 ASAN_NEEDS_SEGV=0 ASAN_LOW_MEMORY=1) +elseif(MSVC) + list(APPEND ASAN_COMMON_DEFINITIONS + ASAN_FLEXIBLE_MAPPING_AND_OFFSET=0 + ASAN_NEEDS_SEGV=0) else() list(APPEND ASAN_COMMON_DEFINITIONS ASAN_FLEXIBLE_MAPPING_AND_OFFSET=1 @@ -48,29 +53,55 @@ endif() # Architectures supported by ASan. filter_available_targets(ASAN_SUPPORTED_ARCH - x86_64 i386 powerpc64 powerpc) + x86_64 i386 powerpc64) +# Compile ASan sources into an object library. +if(APPLE) + foreach(os ${SANITIZER_COMMON_SUPPORTED_DARWIN_OS}) + add_compiler_rt_darwin_object_library(RTAsan ${os} + ARCH ${ASAN_SUPPORTED_ARCH} + SOURCES ${ASAN_SOURCES} + CFLAGS ${ASAN_CFLAGS} + DEFS ${ASAN_COMMON_DEFINITIONS}) + endforeach() +elseif(ANDROID) + add_library(RTAsan.arm.android OBJECT ${ASAN_SOURCES}) + set_target_compile_flags(RTAsan.arm.android ${ASAN_CFLAGS}) + set_property(TARGET RTAsan.arm.android APPEND PROPERTY + COMPILE_DEFINITIONS ${ASAN_COMMON_DEFINITIONS}) +else() + foreach(arch ${ASAN_SUPPORTED_ARCH}) + add_compiler_rt_object_library(RTAsan ${arch} + SOURCES ${ASAN_SOURCES} CFLAGS ${ASAN_CFLAGS} + DEFS ${ASAN_COMMON_DEFINITIONS}) + endforeach() +endif() + +# Build ASan runtimes shipped with Clang. set(ASAN_RUNTIME_LIBRARIES) if(APPLE) - # Build universal binary on APPLE. - add_compiler_rt_osx_dynamic_runtime(clang_rt.asan_osx_dynamic - ARCH ${ASAN_SUPPORTED_ARCH} - SOURCES ${ASAN_DYLIB_SOURCES} - $<TARGET_OBJECTS:RTInterception.osx> - $<TARGET_OBJECTS:RTSanitizerCommon.osx> - CFLAGS ${ASAN_CFLAGS} - DEFS ${ASAN_COMMON_DEFINITIONS} + foreach (os ${SANITIZER_COMMON_SUPPORTED_DARWIN_OS}) # Dynamic lookup is needed because shadow scale and offset are # provided by the instrumented modules. - LINKFLAGS "-framework Foundation" - "-undefined dynamic_lookup") - list(APPEND ASAN_RUNTIME_LIBRARIES clang_rt.asan_osx_dynamic) + set(ASAN_RUNTIME_LDFLAGS + "-undefined dynamic_lookup") + add_compiler_rt_darwin_dynamic_runtime(clang_rt.asan_${os}_dynamic ${os} + ARCH ${ASAN_SUPPORTED_ARCH} + SOURCES $<TARGET_OBJECTS:RTAsan.${os}> + $<TARGET_OBJECTS:RTInterception.${os}> + $<TARGET_OBJECTS:RTSanitizerCommon.${os}> + $<TARGET_OBJECTS:RTLSanCommon.${os}> + CFLAGS ${ASAN_CFLAGS} + DEFS ${ASAN_COMMON_DEFINITIONS} + LINKFLAGS ${ASAN_RUNTIME_LDFLAGS}) + list(APPEND ASAN_RUNTIME_LIBRARIES clang_rt.asan_${os}_dynamic) + endforeach() + elseif(ANDROID) add_library(clang_rt.asan-arm-android SHARED - ${ASAN_SOURCES} + $<TARGET_OBJECTS:RTAsan.arm.android> $<TARGET_OBJECTS:RTInterception.arm.android> - $<TARGET_OBJECTS:RTSanitizerCommon.arm.android> - ) + $<TARGET_OBJECTS:RTSanitizerCommon.arm.android>) set_target_compile_flags(clang_rt.asan-arm-android ${ASAN_CFLAGS}) set_property(TARGET clang_rt.asan-arm-android APPEND PROPERTY @@ -78,23 +109,44 @@ elseif(ANDROID) target_link_libraries(clang_rt.asan-arm-android dl) list(APPEND ASAN_RUNTIME_LIBRARIES clang_rt.asan-arm-android) else() - # Otherwise, build separate libraries for each target. + # Build separate libraries for each target. foreach(arch ${ASAN_SUPPORTED_ARCH}) + set(ASAN_RUNTIME_OBJECTS + $<TARGET_OBJECTS:RTAsan.${arch}> + $<TARGET_OBJECTS:RTInterception.${arch}> + $<TARGET_OBJECTS:RTSanitizerCommon.${arch}> + $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}>) + if (NOT WIN32) + # We can't build Leak Sanitizer on Windows yet. + list(APPEND ASAN_RUNTIME_OBJECTS $<TARGET_OBJECTS:RTLSanCommon.${arch}>) + endif() + add_compiler_rt_static_runtime(clang_rt.asan-${arch} ${arch} - SOURCES ${ASAN_SOURCES} - $<TARGET_OBJECTS:RTInterception.${arch}> - $<TARGET_OBJECTS:RTSanitizerCommon.${arch}> - $<TARGET_OBJECTS:RTSanitizerCommonLibc.${arch}> - $<TARGET_OBJECTS:RTLSanCommon.${arch}> + SOURCES ${ASAN_RUNTIME_OBJECTS} CFLAGS ${ASAN_CFLAGS} - DEFS ${ASAN_COMMON_DEFINITIONS} - SYMS asan.syms) + DEFS ${ASAN_COMMON_DEFINITIONS}) list(APPEND ASAN_RUNTIME_LIBRARIES clang_rt.asan-${arch}) + if (UNIX AND NOT ${arch} STREQUAL "i386") + add_sanitizer_rt_symbols(clang_rt.asan-${arch} asan.syms.extra) + list(APPEND ASAN_RUNTIME_LIBRARIES clang_rt.asan-${arch}-symbols) + endif() + + if (WIN32) + add_compiler_rt_static_runtime(clang_rt.asan_dll_thunk-${arch} ${arch} + SOURCES asan_dll_thunk.cc + CFLAGS ${ASAN_CFLAGS} -DASAN_DLL_THUNK + DEFS ${ASAN_COMMON_DEFINITIONS}) + list(APPEND ASAN_RUNTIME_LIBRARIES clang_rt.asan_dll_thunk-${arch}) + endif() endforeach() endif() add_compiler_rt_resource_file(asan_blacklist asan_blacklist.txt) +# All ASan runtime dependencies. +add_custom_target(asan_runtime_libraries + DEPENDS asan_blacklist ${ASAN_RUNTIME_LIBRARIES}) + if(LLVM_INCLUDE_TESTS) add_subdirectory(tests) endif() diff --git a/lib/asan/asan.syms b/lib/asan/asan.syms deleted file mode 100644 index fce367314093..000000000000 --- a/lib/asan/asan.syms +++ /dev/null @@ -1,5 +0,0 @@ -{ - __asan_*; - __sanitizer_syscall_pre_*; - __sanitizer_syscall_post_*; -}; diff --git a/lib/asan/asan.syms.extra b/lib/asan/asan.syms.extra new file mode 100644 index 000000000000..007aafe380a8 --- /dev/null +++ b/lib/asan/asan.syms.extra @@ -0,0 +1,3 @@ +__asan_* +__lsan_* +__ubsan_* diff --git a/lib/asan/asan_allocator.h b/lib/asan/asan_allocator.h index f817ce352ee2..c5fcbbb5d64b 100644 --- a/lib/asan/asan_allocator.h +++ b/lib/asan/asan_allocator.h @@ -35,10 +35,11 @@ void InitializeAllocator(); class AsanChunkView { public: explicit AsanChunkView(AsanChunk *chunk) : chunk_(chunk) {} - bool IsValid() { return chunk_ != 0; } - uptr Beg(); // first byte of user memory. - uptr End(); // last byte of user memory. - uptr UsedSize(); // size requested by the user. + bool IsValid(); // Checks if AsanChunkView points to a valid allocated + // or quarantined chunk. + uptr Beg(); // First byte of user memory. + uptr End(); // Last byte of user memory. + uptr UsedSize(); // Size requested by the user. uptr AllocTid(); uptr FreeTid(); void GetAllocStack(StackTrace *stack); @@ -114,7 +115,7 @@ void *asan_pvalloc(uptr size, StackTrace *stack); int asan_posix_memalign(void **memptr, uptr alignment, uptr size, StackTrace *stack); -uptr asan_malloc_usable_size(void *ptr, StackTrace *stack); +uptr asan_malloc_usable_size(void *ptr, uptr pc, uptr bp); uptr asan_mz_size(const void *ptr); void asan_mz_force_lock(); diff --git a/lib/asan/asan_allocator2.cc b/lib/asan/asan_allocator2.cc index d74aa553a288..7a29975d711e 100644 --- a/lib/asan/asan_allocator2.cc +++ b/lib/asan/asan_allocator2.cc @@ -94,7 +94,7 @@ AllocatorCache *GetAllocatorCache(AsanThreadLocalMallocStorage *ms) { static Allocator allocator; static const uptr kMaxAllowedMallocSize = - FIRST_32_SECOND_64(3UL << 30, 8UL << 30); + FIRST_32_SECOND_64(3UL << 30, 64UL << 30); static const uptr kMaxThreadLocalQuarantine = FIRST_32_SECOND_64(1 << 18, 1 << 20); @@ -146,14 +146,15 @@ static uptr ComputeRZLog(uptr user_requested_size) { // ChunkBase consists of ChunkHeader and other bytes that overlap with user // memory. -// If a memory chunk is allocated by memalign and we had to increase the -// allocation size to achieve the proper alignment, then we store this magic +// 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 H H U U U U U U -// M -- magic value kMemalignMagic +// 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 kMemalignMagic = 0xCC6E96B9; +static const uptr kAllocBegMagic = 0xCC6E96B9; struct ChunkHeader { // 1-st 8 bytes. @@ -185,14 +186,19 @@ COMPILER_CHECK(kChunkHeader2Size <= 16); struct AsanChunk: ChunkBase { uptr Beg() { return reinterpret_cast<uptr>(this) + kChunkHeaderSize; } - uptr UsedSize() { + uptr UsedSize(bool locked_version = false) { if (user_requested_size != SizeClassMap::kMaxSize) return user_requested_size; - return *reinterpret_cast<uptr *>(allocator.GetMetaData(AllocBeg())); - } - void *AllocBeg() { - if (from_memalign) + return *reinterpret_cast<uptr *>( + allocator.GetMetaData(AllocBeg(locked_version))); + } + void *AllocBeg(bool locked_version = false) { + if (from_memalign) { + if (locked_version) + return allocator.GetBlockBeginFastLocked( + reinterpret_cast<void *>(this)); return allocator.GetBlockBegin(reinterpret_cast<void *>(this)); + } return reinterpret_cast<void*>(Beg() - RZLog2Size(rz_log)); } // If we don't use stack depot, we store the alloc/free stack traces @@ -212,11 +218,14 @@ struct AsanChunk: ChunkBase { uptr available = RoundUpTo(user_requested_size, SHADOW_GRANULARITY); return (available - kChunkHeader2Size) / sizeof(u32); } - bool AddrIsInside(uptr addr) { - return (addr >= Beg()) && (addr < Beg() + UsedSize()); + bool AddrIsInside(uptr addr, bool locked_version = false) { + return (addr >= Beg()) && (addr < Beg() + UsedSize(locked_version)); } }; +bool AsanChunkView::IsValid() { + return chunk_ != 0 && chunk_->chunk_state != CHUNK_AVAILABLE; +} uptr AsanChunkView::Beg() { return chunk_->Beg(); } uptr AsanChunkView::End() { return Beg() + UsedSize(); } uptr AsanChunkView::UsedSize() { return chunk_->UsedSize(); } @@ -227,25 +236,16 @@ static void GetStackTraceFromId(u32 id, StackTrace *stack) { CHECK(id); uptr size = 0; const uptr *trace = StackDepotGet(id, &size); - CHECK_LT(size, kStackTraceMax); - internal_memcpy(stack->trace, trace, sizeof(uptr) * size); - stack->size = size; + CHECK(trace); + stack->CopyFrom(trace, size); } void AsanChunkView::GetAllocStack(StackTrace *stack) { - if (flags()->use_stack_depot) - GetStackTraceFromId(chunk_->alloc_context_id, stack); - else - StackTrace::UncompressStack(stack, chunk_->AllocStackBeg(), - chunk_->AllocStackSize()); + GetStackTraceFromId(chunk_->alloc_context_id, stack); } void AsanChunkView::GetFreeStack(StackTrace *stack) { - if (flags()->use_stack_depot) - GetStackTraceFromId(chunk_->free_context_id, stack); - else - StackTrace::UncompressStack(stack, chunk_->FreeStackBeg(), - chunk_->FreeStackSize()); + GetStackTraceFromId(chunk_->free_context_id, stack); } struct QuarantineCallback; @@ -276,10 +276,13 @@ struct QuarantineCallback { RoundUpTo(m->UsedSize(), SHADOW_GRANULARITY), kAsanHeapLeftRedzoneMagic); void *p = reinterpret_cast<void *>(m->AllocBeg()); - if (m->from_memalign) { - uptr *memalign_magic = reinterpret_cast<uptr *>(p); - CHECK_EQ(memalign_magic[0], kMemalignMagic); - CHECK_EQ(memalign_magic[1], reinterpret_cast<uptr>(m)); + 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. @@ -341,7 +344,7 @@ static void *Allocate(uptr size, uptr alignment, StackTrace *stack, if (size > kMaxAllowedMallocSize || needed_size > kMaxAllowedMallocSize) { Report("WARNING: AddressSanitizer failed to allocate %p bytes\n", (void*)size); - return 0; + return AllocatorReturnNull(); } AsanThread *t = GetCurrentThread(); @@ -355,8 +358,6 @@ static void *Allocate(uptr size, uptr alignment, StackTrace *stack, allocated = allocator.Allocate(cache, needed_size, 8, false); } uptr alloc_beg = reinterpret_cast<uptr>(allocated); - // Clear the first allocated word (an old kMemalignMagic may still be there). - reinterpret_cast<uptr *>(alloc_beg)[0] = 0; uptr alloc_end = alloc_beg + needed_size; uptr beg_plus_redzone = alloc_beg + rz_size; uptr user_beg = beg_plus_redzone; @@ -373,11 +374,10 @@ static void *Allocate(uptr size, uptr alignment, StackTrace *stack, 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 (m->from_memalign) { - CHECK_LE(beg_plus_redzone + 2 * sizeof(uptr), user_beg); - uptr *memalign_magic = reinterpret_cast<uptr *>(alloc_beg); - memalign_magic[0] = kMemalignMagic; - memalign_magic[1] = chunk_beg; + 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); @@ -391,12 +391,7 @@ static void *Allocate(uptr size, uptr alignment, StackTrace *stack, meta[1] = chunk_beg; } - if (fl.use_stack_depot) { - m->alloc_context_id = StackDepotPut(stack->trace, stack->size); - } else { - m->alloc_context_id = 0; - StackTrace::CompressStack(stack, m->AllocStackBeg(), m->AllocStackSize()); - } + m->alloc_context_id = StackDepotPut(stack->trace, stack->size); uptr size_rounded_down_to_granularity = RoundDownTo(size, SHADOW_GRANULARITY); // Unpoison the bulk of the memory region. @@ -405,7 +400,7 @@ static void *Allocate(uptr size, uptr alignment, StackTrace *stack, // Deal with the end of the region if size is not aligned to granularity. if (size != size_rounded_down_to_granularity && fl.poison_heap) { u8 *shadow = (u8*)MemToShadow(user_beg + size_rounded_down_to_granularity); - *shadow = size & (SHADOW_GRANULARITY - 1); + *shadow = fl.poison_partial ? (size & (SHADOW_GRANULARITY - 1)) : 0; } AsanStats &thread_stats = GetCurrentThreadStats(); @@ -422,23 +417,30 @@ static void *Allocate(uptr size, uptr alignment, StackTrace *stack, 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; } +static void ReportInvalidFree(void *ptr, u8 chunk_state, StackTrace *stack) { + if (chunk_state == CHUNK_QUARANTINE) + ReportDoubleFree((uptr)ptr, stack); + else + ReportFreeNotMalloced((uptr)ptr, stack); +} + static void AtomicallySetQuarantineFlag(AsanChunk *m, void *ptr, StackTrace *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)) { - if (old_chunk_state == CHUNK_QUARANTINE) - ReportDoubleFree((uptr)ptr, stack); - else - ReportFreeNotMalloced((uptr)ptr, stack); - } + CHUNK_QUARANTINE, memory_order_acquire)) + ReportInvalidFree(ptr, old_chunk_state, stack); CHECK_EQ(CHUNK_ALLOCATED, old_chunk_state); } @@ -448,12 +450,6 @@ static void QuarantineChunk(AsanChunk *m, void *ptr, StackTrace *stack, AllocType alloc_type) { CHECK_EQ(m->chunk_state, CHUNK_QUARANTINE); - // FIXME: if the free hook produces an ASan report (e.g. due to a bug), - // printing the report may crash as the AsanChunk free-related fields have not - // been updated yet. We might need to introduce yet another chunk state to - // handle this correctly, but don't want to yet. - ASAN_FREE_HOOK(ptr); - if (m->alloc_type != alloc_type && flags()->alloc_dealloc_mismatch) ReportAllocTypeMismatch((uptr)ptr, stack, (AllocType)m->alloc_type, (AllocType)alloc_type); @@ -463,12 +459,7 @@ static void QuarantineChunk(AsanChunk *m, void *ptr, CHECK_EQ(m->free_tid, kInvalidTid); AsanThread *t = GetCurrentThread(); m->free_tid = t ? t->tid() : 0; - if (flags()->use_stack_depot) { - m->free_context_id = StackDepotPut(stack->trace, stack->size); - } else { - m->free_context_id = 0; - StackTrace::CompressStack(stack, m->FreeStackBeg(), m->FreeStackSize()); - } + m->free_context_id = StackDepotPut(stack->trace, stack->size); // Poison the region. PoisonShadow(m->Beg(), RoundUpTo(m->UsedSize(), SHADOW_GRANULARITY), @@ -498,6 +489,7 @@ static void Deallocate(void *ptr, StackTrace *stack, AllocType alloc_type) { uptr chunk_beg = p - kChunkHeaderSize; AsanChunk *m = reinterpret_cast<AsanChunk *>(chunk_beg); + ASAN_FREE_HOOK(ptr); // Must mark the chunk as quarantined before any changes to its metadata. AtomicallySetQuarantineFlag(m, ptr, stack); QuarantineChunk(m, ptr, stack, alloc_type); @@ -513,50 +505,45 @@ static void *Reallocate(void *old_ptr, uptr new_size, StackTrace *stack) { thread_stats.reallocs++; thread_stats.realloced += new_size; - // Must mark the chunk as quarantined before any changes to its metadata. - // This also ensures that other threads can't deallocate it in the meantime. - AtomicallySetQuarantineFlag(m, old_ptr, stack); - - uptr old_size = m->UsedSize(); - uptr memcpy_size = Min(new_size, old_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), (void*)0); + 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); - QuarantineChunk(m, old_ptr, stack, FROM_MALLOC); + Deallocate(old_ptr, stack, FROM_MALLOC); } return new_ptr; } -static AsanChunk *GetAsanChunkByAddr(uptr p) { - void *ptr = reinterpret_cast<void *>(p); - uptr alloc_beg = reinterpret_cast<uptr>(allocator.GetBlockBegin(ptr)); +// Assumes alloc_beg == allocator.GetBlockBegin(alloc_beg). +static AsanChunk *GetAsanChunk(void *alloc_beg) { if (!alloc_beg) return 0; - uptr *memalign_magic = reinterpret_cast<uptr *>(alloc_beg); - if (memalign_magic[0] == kMemalignMagic) { - AsanChunk *m = reinterpret_cast<AsanChunk *>(memalign_magic[1]); - CHECK(m->from_memalign); - return m; - } - if (!allocator.FromPrimary(ptr)) { - uptr *meta = reinterpret_cast<uptr *>( - allocator.GetMetaData(reinterpret_cast<void *>(alloc_beg))); + if (!allocator.FromPrimary(alloc_beg)) { + uptr *meta = reinterpret_cast<uptr *>(allocator.GetMetaData(alloc_beg)); AsanChunk *m = reinterpret_cast<AsanChunk *>(meta[1]); return m; } - uptr actual_size = allocator.GetActuallyAllocatedSize(ptr); - CHECK_LE(actual_size, SizeClassMap::kMaxSize); - // We know the actually allocted size, but we don't know the redzone size. - // Just try all possible redzone sizes. - for (u32 rz_log = 0; rz_log < 8; rz_log++) { - u32 rz_size = RZLog2Size(rz_log); - uptr max_possible_size = actual_size - rz_size; - if (ComputeRZLog(max_possible_size) != rz_log) - continue; - return reinterpret_cast<AsanChunk *>( - alloc_beg + rz_size - kChunkHeaderSize); - } - return 0; + 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); +} + +static 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. +static AsanChunk *GetAsanChunkByAddrFastLocked(uptr p) { + void *alloc_beg = + allocator.GetBlockBeginFastLocked(reinterpret_cast<void *>(p)); + return GetAsanChunk(alloc_beg); } static uptr AllocationSize(uptr p) { @@ -621,24 +608,22 @@ void PrintInternalAllocatorStats() { allocator.PrintStats(); } -SANITIZER_INTERFACE_ATTRIBUTE void *asan_memalign(uptr alignment, uptr size, StackTrace *stack, AllocType alloc_type) { return Allocate(size, alignment, stack, alloc_type, true); } -SANITIZER_INTERFACE_ATTRIBUTE void asan_free(void *ptr, StackTrace *stack, AllocType alloc_type) { Deallocate(ptr, stack, alloc_type); } -SANITIZER_INTERFACE_ATTRIBUTE void *asan_malloc(uptr size, StackTrace *stack) { return Allocate(size, 8, stack, FROM_MALLOC, true); } void *asan_calloc(uptr nmemb, uptr size, StackTrace *stack) { - if (CallocShouldReturnNullDueToOverflow(size, nmemb)) return 0; + if (CallocShouldReturnNullDueToOverflow(size, nmemb)) + return AllocatorReturnNull(); 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. @@ -679,12 +664,13 @@ int asan_posix_memalign(void **memptr, uptr alignment, uptr size, return 0; } -uptr asan_malloc_usable_size(void *ptr, StackTrace *stack) { - CHECK(stack); +uptr asan_malloc_usable_size(void *ptr, uptr pc, uptr bp) { if (ptr == 0) return 0; uptr usable_size = AllocationSize(reinterpret_cast<uptr>(ptr)); - if (flags()->check_malloc_usable_size && (usable_size == 0)) - ReportMallocUsableSizeNotOwned((uptr)ptr, stack); + if (flags()->check_malloc_usable_size && (usable_size == 0)) { + GET_STACK_TRACE_FATAL(pc, bp); + ReportMallocUsableSizeNotOwned((uptr)ptr, &stack); + } return usable_size; } @@ -719,25 +705,26 @@ void GetAllocatorGlobalRange(uptr *begin, uptr *end) { *end = *begin + sizeof(__asan::allocator); } -void *PointsIntoChunk(void* p) { +uptr PointsIntoChunk(void* p) { uptr addr = reinterpret_cast<uptr>(p); - __asan::AsanChunk *m = __asan::GetAsanChunkByAddr(addr); + __asan::AsanChunk *m = __asan::GetAsanChunkByAddrFastLocked(addr); if (!m) return 0; uptr chunk = m->Beg(); - if ((m->chunk_state == __asan::CHUNK_ALLOCATED) && m->AddrIsInside(addr)) - return reinterpret_cast<void *>(chunk); + if ((m->chunk_state == __asan::CHUNK_ALLOCATED) && + m->AddrIsInside(addr, /*locked_version=*/true)) + return chunk; return 0; } -void *GetUserBegin(void *p) { - __asan::AsanChunk *m = __asan::GetAsanChunkByAddr(reinterpret_cast<uptr>(p)); +uptr GetUserBegin(uptr chunk) { + __asan::AsanChunk *m = + __asan::GetAsanChunkByAddrFastLocked(chunk); CHECK(m); - return reinterpret_cast<void *>(m->Beg()); + return m->Beg(); } -LsanMetadata::LsanMetadata(void *chunk) { - uptr addr = reinterpret_cast<uptr>(chunk); - metadata_ = reinterpret_cast<void *>(addr - __asan::kChunkHeaderSize); +LsanMetadata::LsanMetadata(uptr chunk) { + metadata_ = reinterpret_cast<void *>(chunk - __asan::kChunkHeaderSize); } bool LsanMetadata::allocated() const { @@ -757,7 +744,7 @@ void LsanMetadata::set_tag(ChunkTag value) { uptr LsanMetadata::requested_size() const { __asan::AsanChunk *m = reinterpret_cast<__asan::AsanChunk *>(metadata_); - return m->UsedSize(); + return m->UsedSize(/*locked_version=*/true); } u32 LsanMetadata::stack_trace_id() const { @@ -765,18 +752,23 @@ u32 LsanMetadata::stack_trace_id() const { return m->alloc_context_id; } -template <typename Callable> void ForEachChunk(Callable const &callback) { - __asan::allocator.ForEachChunk(callback); +void ForEachChunk(ForEachChunkCallback callback, void *arg) { + __asan::allocator.ForEachChunk(callback, arg); +} + +IgnoreObjectResult IgnoreObjectLocked(const void *p) { + uptr addr = reinterpret_cast<uptr>(p); + __asan::AsanChunk *m = __asan::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; + } } -#if CAN_SANITIZE_LEAKS -template void ForEachChunk<ProcessPlatformSpecificAllocationsCb>( - ProcessPlatformSpecificAllocationsCb const &callback); -template void ForEachChunk<PrintLeakedCb>(PrintLeakedCb const &callback); -template void ForEachChunk<CollectLeaksCb>(CollectLeaksCb const &callback); -template void ForEachChunk<MarkIndirectlyLeakedCb>( - MarkIndirectlyLeakedCb const &callback); -template void ForEachChunk<ClearTagCb>(ClearTagCb const &callback); -#endif // CAN_SANITIZE_LEAKS } // namespace __lsan // ---------------------- Interface ---------------- {{{1 @@ -808,12 +800,12 @@ uptr __asan_get_allocated_size(const void *p) { #if !SANITIZER_SUPPORTS_WEAK_HOOKS // Provide default (no-op) implementation of malloc hooks. extern "C" { -SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void __asan_malloc_hook(void *ptr, uptr size) { (void)ptr; (void)size; } -SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void __asan_free_hook(void *ptr) { (void)ptr; } diff --git a/lib/asan/asan_blacklist.txt b/lib/asan/asan_blacklist.txt index 03da08598d23..63b3c315b26b 100644 --- a/lib/asan/asan_blacklist.txt +++ b/lib/asan/asan_blacklist.txt @@ -6,5 +6,5 @@ # fun:*bad_function_name* # src:file_with_tricky_code.cc # global:*global_with_bad_access_or_initialization* -# global-init:*global_with_initialization_issues* -# global-init-type:*Namespace::ClassName* +# global:*global_with_initialization_issues*=init +# type:*Namespace::ClassName*=init diff --git a/lib/asan/asan_dll_thunk.cc b/lib/asan/asan_dll_thunk.cc new file mode 100644 index 000000000000..cedd60d342f6 --- /dev/null +++ b/lib/asan/asan_dll_thunk.cc @@ -0,0 +1,196 @@ +//===-- asan_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://code.google.com/p/address-sanitizer/issues/detail?id=209 for the +// details. +//===----------------------------------------------------------------------===// + +// Only compile this code when buidling asan_dll_thunk.lib +// Using #ifdef rather than relying on Makefiles etc. +// simplifies the build procedure. +#ifdef ASAN_DLL_THUNK + +// ----------------- Helper functions and macros --------------------- {{{1 +extern "C" { +void *__stdcall GetModuleHandleA(const char *module_name); +void *__stdcall GetProcAddress(void *module, const char *proc_name); +void abort(); +} + +static void *getRealProcAddressOrDie(const char *name) { + void *ret = GetProcAddress(GetModuleHandleA(0), name); + if (!ret) + abort(); + return ret; +} + +#define WRAP_V_V(name) \ + extern "C" void name() { \ + typedef void (*fntype)(); \ + static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ + fn(); \ + } + +#define WRAP_V_W(name) \ + extern "C" void name(void *arg) { \ + typedef void (*fntype)(void *arg); \ + static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ + fn(arg); \ + } + +#define WRAP_V_WW(name) \ + extern "C" void name(void *arg1, void *arg2) { \ + typedef void (*fntype)(void *, void *); \ + static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ + fn(arg1, arg2); \ + } + +#define WRAP_V_WWW(name) \ + extern "C" void name(void *arg1, void *arg2, void *arg3) { \ + typedef void *(*fntype)(void *, void *, void *); \ + static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ + fn(arg1, arg2, arg3); \ + } + +#define WRAP_W_V(name) \ + extern "C" void *name() { \ + typedef void *(*fntype)(); \ + static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ + return fn(); \ + } + +#define WRAP_W_W(name) \ + extern "C" void *name(void *arg) { \ + typedef void *(*fntype)(void *arg); \ + static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ + return fn(arg); \ + } + +#define WRAP_W_WW(name) \ + extern "C" void *name(void *arg1, void *arg2) { \ + typedef void *(*fntype)(void *, void *); \ + static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ + return fn(arg1, arg2); \ + } + +#define WRAP_W_WWW(name) \ + extern "C" void *name(void *arg1, void *arg2, void *arg3) { \ + typedef void *(*fntype)(void *, void *, void *); \ + static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ + return fn(arg1, arg2, arg3); \ + } + +#define WRAP_W_WWWW(name) \ + extern "C" void *name(void *arg1, void *arg2, void *arg3, void *arg4) { \ + typedef void *(*fntype)(void *, void *, void *, void *); \ + static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ + return fn(arg1, arg2, arg3, arg4); \ + } + +#define WRAP_W_WWWWW(name) \ + extern "C" void *name(void *arg1, void *arg2, void *arg3, void *arg4, \ + void *arg5) { \ + typedef void *(*fntype)(void *, void *, void *, void *, void *); \ + static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ + return fn(arg1, arg2, arg3, arg4, arg5); \ + } + +#define WRAP_W_WWWWWW(name) \ + extern "C" void *name(void *arg1, void *arg2, void *arg3, void *arg4, \ + void *arg5, void *arg6) { \ + typedef void *(*fntype)(void *, void *, void *, void *, void *, void *); \ + static fntype fn = (fntype)getRealProcAddressOrDie(#name); \ + return fn(arg1, arg2, arg3, arg4, arg5, arg6); \ + } +// }}} + +// ----------------- ASan own interface functions -------------------- +WRAP_W_V(__asan_should_detect_stack_use_after_return) + +extern "C" { + int __asan_option_detect_stack_use_after_return; + + // Manually wrap __asan_init as we need to initialize + // __asan_option_detect_stack_use_after_return afterwards. + void __asan_init_v3() { + typedef void (*fntype)(); + static fntype fn = (fntype)getRealProcAddressOrDie("__asan_init_v3"); + fn(); + __asan_option_detect_stack_use_after_return = + (__asan_should_detect_stack_use_after_return() != 0); + } +} + +WRAP_V_W(__asan_report_store1) +WRAP_V_W(__asan_report_store2) +WRAP_V_W(__asan_report_store4) +WRAP_V_W(__asan_report_store8) +WRAP_V_W(__asan_report_store16) +WRAP_V_WW(__asan_report_store_n) + +WRAP_V_W(__asan_report_load1) +WRAP_V_W(__asan_report_load2) +WRAP_V_W(__asan_report_load4) +WRAP_V_W(__asan_report_load8) +WRAP_V_W(__asan_report_load16) +WRAP_V_WW(__asan_report_load_n) + +WRAP_V_WW(__asan_register_globals) +WRAP_V_WW(__asan_unregister_globals) + +WRAP_W_WW(__asan_stack_malloc_0) +WRAP_W_WW(__asan_stack_malloc_1) +WRAP_W_WW(__asan_stack_malloc_2) +WRAP_W_WW(__asan_stack_malloc_3) +WRAP_W_WW(__asan_stack_malloc_4) +WRAP_W_WW(__asan_stack_malloc_5) +WRAP_W_WW(__asan_stack_malloc_6) +WRAP_W_WW(__asan_stack_malloc_7) +WRAP_W_WW(__asan_stack_malloc_8) +WRAP_W_WW(__asan_stack_malloc_9) +WRAP_W_WW(__asan_stack_malloc_10) + +WRAP_V_WWW(__asan_stack_free_0) +WRAP_V_WWW(__asan_stack_free_1) +WRAP_V_WWW(__asan_stack_free_2) +WRAP_V_WWW(__asan_stack_free_4) +WRAP_V_WWW(__asan_stack_free_5) +WRAP_V_WWW(__asan_stack_free_6) +WRAP_V_WWW(__asan_stack_free_7) +WRAP_V_WWW(__asan_stack_free_8) +WRAP_V_WWW(__asan_stack_free_9) +WRAP_V_WWW(__asan_stack_free_10) + +// TODO(timurrrr): Add more interface functions on the as-needed basis. + +// ----------------- Memory allocation functions --------------------- +WRAP_V_W(free) +WRAP_V_WW(_free_dbg) + +WRAP_W_W(malloc) +WRAP_W_WWWW(_malloc_dbg) + +WRAP_W_WW(calloc) +WRAP_W_WWWWW(_calloc_dbg) +WRAP_W_WWW(_calloc_impl) + +WRAP_W_WW(realloc) +WRAP_W_WWW(_realloc_dbg) +WRAP_W_WWW(_recalloc) + +WRAP_W_W(_msize) + +// TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cc). + +#endif // ASAN_DLL_THUNK diff --git a/lib/asan/asan_fake_stack.cc b/lib/asan/asan_fake_stack.cc index 23eebe64e612..d3e55bff1e6e 100644 --- a/lib/asan/asan_fake_stack.cc +++ b/lib/asan/asan_fake_stack.cc @@ -17,167 +17,204 @@ namespace __asan { -FakeStack::FakeStack() { - CHECK(REAL(memset)); - REAL(memset)(this, 0, sizeof(*this)); +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; + +// For small size classes inline PoisonShadow for better performance. +ALWAYS_INLINE void SetShadow(uptr ptr, uptr size, uptr class_id, u64 magic) { + CHECK_EQ(SHADOW_SCALE, 3); // This code expects SHADOW_SCALE=3. + u64 *shadow = reinterpret_cast<u64*>(MemToShadow(ptr)); + if (class_id <= 6) { + for (uptr i = 0; i < (1U << class_id); i++) + shadow[i] = magic; + } else { + // The size class is too big, it's cheaper to poison only size bytes. + PoisonShadow(ptr, size, static_cast<u8>(magic)); + } } -bool FakeStack::AddrIsInSizeClass(uptr addr, uptr size_class) { - uptr mem = allocated_size_classes_[size_class]; - uptr size = ClassMmapSize(size_class); - bool res = mem && addr >= mem && addr < mem + size; +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; + FakeStack *res = reinterpret_cast<FakeStack *>( + MmapOrDie(RequiredSize(stack_size_log), "FakeStack")); + res->stack_size_log_ = stack_size_log; + if (common_flags()->verbosity) { + u8 *p = reinterpret_cast<u8 *>(res); + Report("T%d: FakeStack created: %p -- %p stack_size_log: %zd \n", + GetCurrentTidOrInvalid(), p, + p + FakeStack::RequiredSize(stack_size_log), stack_size_log); + } return res; } -uptr FakeStack::AddrIsInFakeStack(uptr addr) { - for (uptr size_class = 0; size_class < kNumberOfSizeClasses; size_class++) { - if (!AddrIsInSizeClass(addr, size_class)) continue; - uptr size_class_first_ptr = allocated_size_classes_[size_class]; - uptr size = ClassSize(size_class); - CHECK_LE(size_class_first_ptr, addr); - CHECK_GT(size_class_first_ptr + ClassMmapSize(size_class), addr); - return size_class_first_ptr + ((addr - size_class_first_ptr) / size) * size; - } - return 0; +void FakeStack::Destroy() { + PoisonAll(0); + UnmapOrDie(this, RequiredSize(stack_size_log_)); } -// We may want to compute this during compilation. -ALWAYS_INLINE uptr FakeStack::ComputeSizeClass(uptr alloc_size) { - uptr rounded_size = RoundUpToPowerOfTwo(alloc_size); - uptr log = Log2(rounded_size); - CHECK_LE(alloc_size, (1UL << log)); - CHECK_GT(alloc_size, (1UL << (log-1))); - uptr res = log < kMinStackFrameSizeLog ? 0 : log - kMinStackFrameSizeLog; - CHECK_LT(res, kNumberOfSizeClasses); - CHECK_GE(ClassSize(res), rounded_size); - return res; +void FakeStack::PoisonAll(u8 magic) { + PoisonShadow(reinterpret_cast<uptr>(this), RequiredSize(stack_size_log()), + magic); } -void FakeFrameFifo::FifoPush(FakeFrame *node) { - CHECK(node); - node->next = 0; - if (first_ == 0 && last_ == 0) { - first_ = last_ = node; - } else { - CHECK(first_); - CHECK(last_); - last_->next = node; - last_ = node; +ALWAYS_INLINE USED +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-atimic 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 0; // We are out of fake stack. } -FakeFrame *FakeFrameFifo::FifoPop() { - CHECK(first_ && last_ && "Exhausted fake stack"); - FakeFrame *res = 0; - if (first_ == last_) { - res = first_; - first_ = last_ = 0; - } else { - res = first_; - first_ = first_->next; - } - return res; +uptr FakeStack::AddrIsInFakeStack(uptr ptr) { + 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 + (1UL << stack_size_log)); + uptr pos = (ptr - base) >> (kMinStackFrameSizeLog + class_id); + return base + pos * BytesInSizeClass(class_id); } -void FakeStack::Init(uptr stack_size) { - stack_size_ = stack_size; - alive_ = true; +void FakeStack::HandleNoReturn() { + needs_gc_ = true; } -void FakeStack::Cleanup() { - alive_ = false; - for (uptr i = 0; i < kNumberOfSizeClasses; i++) { - uptr mem = allocated_size_classes_[i]; - if (mem) { - PoisonShadow(mem, ClassMmapSize(i), 0); - allocated_size_classes_[i] = 0; - UnmapOrDie((void*)mem, ClassMmapSize(i)); +// 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; } -uptr FakeStack::ClassMmapSize(uptr size_class) { - return RoundUpToPowerOfTwo(stack_size_); +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); + } + } } -void FakeStack::AllocateOneSizeClass(uptr size_class) { - CHECK(ClassMmapSize(size_class) >= GetPageSizeCached()); - uptr new_mem = (uptr)MmapOrDie( - ClassMmapSize(size_class), __FUNCTION__); - // Printf("T%d new_mem[%zu]: %p-%p mmap %zu\n", - // GetCurrentThread()->tid(), - // size_class, new_mem, new_mem + ClassMmapSize(size_class), - // ClassMmapSize(size_class)); - uptr i; - for (i = 0; i < ClassMmapSize(size_class); - i += ClassSize(size_class)) { - size_classes_[size_class].FifoPush((FakeFrame*)(new_mem + i)); - } - CHECK(i == ClassMmapSize(size_class)); - allocated_size_classes_[size_class] = new_mem; +#if SANITIZER_LINUX && !SANITIZER_ANDROID +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 -ALWAYS_INLINE uptr FakeStack::AllocateStack(uptr size, uptr real_stack) { - if (!alive_) return real_stack; - CHECK(size <= kMaxStackMallocSize && size > 1); - uptr size_class = ComputeSizeClass(size); - if (!allocated_size_classes_[size_class]) { - AllocateOneSizeClass(size_class); - } - FakeFrame *fake_frame = size_classes_[size_class].FifoPop(); - CHECK(fake_frame); - fake_frame->size_minus_one = size - 1; - fake_frame->real_stack = real_stack; - while (FakeFrame *top = call_stack_.top()) { - if (top->real_stack > real_stack) break; - call_stack_.LifoPop(); - DeallocateFrame(top); - } - call_stack_.LifoPush(fake_frame); - uptr ptr = (uptr)fake_frame; - PoisonShadow(ptr, size, 0); - return ptr; +static FakeStack *GetFakeStack() { + AsanThread *t = GetCurrentThread(); + if (!t) return 0; + return t->fake_stack(); } -ALWAYS_INLINE void FakeStack::DeallocateFrame(FakeFrame *fake_frame) { - CHECK(alive_); - uptr size = fake_frame->size_minus_one + 1; - uptr size_class = ComputeSizeClass(size); - CHECK(allocated_size_classes_[size_class]); - uptr ptr = (uptr)fake_frame; - CHECK(AddrIsInSizeClass(ptr, size_class)); - CHECK(AddrIsInSizeClass(ptr + size - 1, size_class)); - size_classes_[size_class].FifoPush(fake_frame); +static FakeStack *GetFakeStackFast() { + if (FakeStack *fs = GetTLSFakeStack()) + return fs; + if (!__asan_option_detect_stack_use_after_return) + return 0; + return GetFakeStack(); +} + +ALWAYS_INLINE uptr OnMalloc(uptr class_id, uptr size, uptr real_stack) { + FakeStack *fs = GetFakeStackFast(); + if (!fs) return real_stack; + FakeFrame *ff = fs->Allocate(fs->stack_size_log(), class_id, real_stack); + if (!ff) + return real_stack; // Out of fake stack, return the real one. + uptr ptr = reinterpret_cast<uptr>(ff); + SetShadow(ptr, size, class_id, 0); + return ptr; } -ALWAYS_INLINE void FakeStack::OnFree(uptr ptr, uptr size, uptr real_stack) { - FakeFrame *fake_frame = (FakeFrame*)ptr; - CHECK_EQ(fake_frame->magic, kRetiredStackFrameMagic); - CHECK_NE(fake_frame->descr, 0); - CHECK_EQ(fake_frame->size_minus_one, size - 1); - PoisonShadow(ptr, size, kAsanStackAfterReturnMagic); +ALWAYS_INLINE void OnFree(uptr ptr, uptr class_id, uptr size, uptr real_stack) { + if (ptr == real_stack) + return; + FakeStack::Deallocate(ptr, class_id); + SetShadow(ptr, size, class_id, kMagic8); } } // namespace __asan // ---------------------- Interface ---------------- {{{1 -using namespace __asan; // NOLINT - -uptr __asan_stack_malloc(uptr size, uptr real_stack) { - if (!flags()->use_fake_stack) return real_stack; - AsanThread *t = GetCurrentThread(); - if (!t) { - // TSD is gone, use the real stack. - return real_stack; +#define DEFINE_STACK_MALLOC_FREE_WITH_CLASS_ID(class_id) \ + extern "C" SANITIZER_INTERFACE_ATTRIBUTE uptr \ + __asan_stack_malloc_##class_id(uptr size, uptr real_stack) { \ + return __asan::OnMalloc(class_id, size, real_stack); \ + } \ + extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __asan_stack_free_##class_id( \ + uptr ptr, uptr size, uptr real_stack) { \ + __asan::OnFree(ptr, class_id, size, real_stack); \ } - uptr ptr = t->fake_stack().AllocateStack(size, real_stack); - // Printf("__asan_stack_malloc %p %zu %p\n", ptr, size, real_stack); - return ptr; -} -void __asan_stack_free(uptr ptr, uptr size, uptr real_stack) { - if (!flags()->use_fake_stack) return; - if (ptr != real_stack) { - FakeStack::OnFree(ptr, size, real_stack); - } -} +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) diff --git a/lib/asan/asan_fake_stack.h b/lib/asan/asan_fake_stack.h index 308b4c571832..f17ee0268917 100644 --- a/lib/asan/asan_fake_stack.h +++ b/lib/asan/asan_fake_stack.h @@ -9,12 +9,14 @@ // // This file is a part of AddressSanitizer, an address sanity checker. // -// ASan-private header for asan_fake_stack.cc +// 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. @@ -22,96 +24,148 @@ struct FakeFrame { uptr magic; // Modified by the instrumented code. uptr descr; // Modified by the instrumented code. uptr pc; // Modified by the instrumented code. - u64 real_stack : 48; - u64 size_minus_one : 16; - // End of the first 32 bytes. - // The rest should not be used when the frame is active. - FakeFrame *next; -}; - -struct FakeFrameFifo { - public: - void FifoPush(FakeFrame *node); - FakeFrame *FifoPop(); - private: - FakeFrame *first_, *last_; -}; - -template<uptr kMaxNumberOfFrames> -class FakeFrameLifo { - public: - explicit FakeFrameLifo(LinkerInitialized) {} - FakeFrameLifo() : n_frames_(0) {} - void LifoPush(FakeFrame *node) { - CHECK_LT(n_frames_, kMaxNumberOfFrames); - frames_[n_frames_++] = node; - } - void LifoPop() { - CHECK(n_frames_); - n_frames_--; - } - FakeFrame *top() { - if (n_frames_ == 0) - return 0; - return frames_[n_frames_ - 1]; - } - private: - uptr n_frames_; - FakeFrame *frames_[kMaxNumberOfFrames]; + 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 poped but remains there for quite some time until gets used again. +// 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. -// We can not rely on __asan_stack_free being called on every function exit, -// so we maintain a lifo list of all current fake frames and update it on every -// call to __asan_stack_malloc. +// +// 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 fasion to maximize the delay between a deallocation +// and the next allocation. class FakeStack { - public: - FakeStack(); - explicit FakeStack(LinkerInitialized x) : call_stack_(x) {} - void Init(uptr stack_size); - void StopUsingFakeStack() { alive_ = false; } - void Cleanup(); - uptr AllocateStack(uptr size, uptr real_stack); - static void OnFree(uptr ptr, uptr size, uptr real_stack); - // Return the bottom of the maped region. - uptr AddrIsInFakeStack(uptr addr); - bool StackSize() { return stack_size_; } - - private: - static const uptr kMinStackFrameSizeLog = 9; // Min frame is 512B. + static const uptr kMinStackFrameSizeLog = 6; // Min frame is 64B. static const uptr kMaxStackFrameSizeLog = 16; // Max stack frame is 64K. - static const uptr kMaxStackMallocSize = 1 << kMaxStackFrameSizeLog; + + public: static const uptr kNumberOfSizeClasses = - kMaxStackFrameSizeLog - kMinStackFrameSizeLog + 1; - static const uptr kMaxRecursionDepth = 1023; + kMaxStackFrameSizeLog - kMinStackFrameSizeLog + 1; + + // CTOR: create the FakeStack as a single mmap-ed object. + static FakeStack *Create(uptr stack_size_log); + + void Destroy(); + + // stack_size_log is at least 15 (stack_size >= 32K). + static uptr SizeRequiredForFlags(uptr stack_size_log) { + return 1UL << (stack_size_log + 1 - kMinStackFrameSizeLog); + } - bool AddrIsInSizeClass(uptr addr, uptr size_class); + // Each size class occupies stack_size bytes. + static uptr SizeRequiredForFrames(uptr stack_size_log) { + return (1ULL << 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 = (1 << (kNumberOfSizeClasses - 1)) - 1; + return ((all_ones >> t) << t) << (stack_size_log - 15); + } + + static uptr NumberOfFrames(uptr stack_size_log, uptr class_id) { + return 1UL << (stack_size_log - kMinStackFrameSizeLog - class_id); + } + + // Divide n by the numbe 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 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) + + (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); - // Each size class should be large enough to hold all frames. - uptr ClassMmapSize(uptr size_class); + // Number of bytes in a fake frame of this size class. + static uptr BytesInSizeClass(uptr class_id) { + return 1UL << (class_id + kMinStackFrameSizeLog); + } - uptr ClassSize(uptr size_class) { - return 1UL << (size_class + 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)); } - void DeallocateFrame(FakeFrame *fake_frame); + uptr stack_size_log() const { return stack_size_log_; } + + void HandleNoReturn(); + void GC(uptr real_stack); - uptr ComputeSizeClass(uptr alloc_size); - void AllocateOneSizeClass(uptr size_class); + void ForEachFakeFrame(RangeIteratorCallback callback, void *arg); - uptr stack_size_; - bool alive_; + 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 = 1 << kMaxStackFrameSizeLog; - uptr allocated_size_classes_[kNumberOfSizeClasses]; - FakeFrameFifo size_classes_[kNumberOfSizeClasses]; - FakeFrameLifo<kMaxRecursionDepth> call_stack_; + 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.h b/lib/asan/asan_flags.h index 2f3bc9051ae1..89662f28b29c 100644 --- a/lib/asan/asan_flags.h +++ b/lib/asan/asan_flags.h @@ -32,8 +32,6 @@ struct Flags { // Lower value may reduce memory usage but increase the chance of // false negatives. int quarantine_size; - // Verbosity level (0 - silent, 1 - a bit of output, 2+ - more output). - int verbosity; // Size (in bytes) of redzones around heap objects. // Requirement: redzone >= 32, is a power of two. int redzone; @@ -52,8 +50,10 @@ struct Flags { bool replace_intrin; // Used on Mac only. bool mac_ignore_invalid_free; - // ASan allocator flag. - bool use_fake_stack; + // Enables stack-use-after-return checking at run-time. + bool detect_stack_use_after_return; + // The minimal fake stack size log. + int uar_stack_size_log; // ASan allocator flag. max_malloc_fill_size is the maximal amount of bytes // that will be filled with malloc_fill_byte on malloc. int max_malloc_fill_size, malloc_fill_byte; @@ -83,6 +83,9 @@ struct Flags { bool print_legend; // If set, prints ASan exit stats even after program terminates successfully. bool atexit; + // If set, coverage information will be dumped at shutdown time if the + // appropriate instrumentation was enabled. + bool coverage; // By default, disable core dumper on 64-bit - it makes little sense // to dump 16T+ core. bool disable_core; @@ -93,23 +96,20 @@ struct Flags { // but also thread creation stacks for threads that created those threads, // etc. up to main thread. bool print_full_thread_history; - // ASan will write logs to "log_path.pid" instead of stderr. - const char *log_path; // Poison (or not) the heap memory on [de]allocation. Zero value is useful // for benchmarking the allocator or instrumentator. bool poison_heap; + // If true, poison partially addressable 8-byte aligned words (default=true). + // This flag affects heap and global buffers, but not stack buffers. + bool poison_partial; // Report errors on malloc/delete, new/free, new/delete[], etc. bool alloc_dealloc_mismatch; - // Use stack depot instead of storing stacks in the redzones. - bool use_stack_depot; // If true, assume that memcmp(p1, p2, n) always reads n bytes before // comparing p1 and p2. bool strict_memcmp; // If true, assume that dynamic initializers can never access globals from // other modules, even if the latter are already initialized. bool strict_init_order; - // Invoke LeakSanitizer at process exit. - bool detect_leaks; }; extern Flags asan_flags_dont_use_directly; diff --git a/lib/asan/asan_globals.cc b/lib/asan/asan_globals.cc index 301ea44f2ca5..81699676b574 100644 --- a/lib/asan/asan_globals.cc +++ b/lib/asan/asan_globals.cc @@ -41,7 +41,7 @@ struct DynInitGlobal { Global g; bool initialized; }; -typedef InternalVector<DynInitGlobal> VectorOfGlobals; +typedef InternalMmapVector<DynInitGlobal> VectorOfGlobals; // Lazy-initialized and never deleted. static VectorOfGlobals *dynamic_init_globals; @@ -94,15 +94,13 @@ static void RegisterGlobal(const Global *g) { CHECK(AddrIsAlignedByGranularity(g->size_with_redzone)); if (flags()->poison_heap) PoisonRedZones(*g); - ListOfGlobals *l = - (ListOfGlobals*)allocator_for_globals.Allocate(sizeof(ListOfGlobals)); + 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 == 0) { - void *mem = allocator_for_globals.Allocate(sizeof(VectorOfGlobals)); - dynamic_init_globals = new(mem) + dynamic_init_globals = new(allocator_for_globals) VectorOfGlobals(kDynamicInitGlobalsInitialCapacity); } DynInitGlobal dyn_global = { *g, false }; diff --git a/lib/asan/asan_intercepted_functions.h b/lib/asan/asan_intercepted_functions.h index 842781cdb17f..de42cd6d5ca6 100644 --- a/lib/asan/asan_intercepted_functions.h +++ b/lib/asan/asan_intercepted_functions.h @@ -14,15 +14,8 @@ #ifndef ASAN_INTERCEPTED_FUNCTIONS_H #define ASAN_INTERCEPTED_FUNCTIONS_H -#include "asan_internal.h" -#include "interception/interception.h" #include "sanitizer_common/sanitizer_platform_interceptors.h" -#include <stdarg.h> -#include <stddef.h> - -using __sanitizer::uptr; - // Use macro to describe if specific function should be // intercepted on a given platform. #if !SANITIZER_WINDOWS @@ -83,32 +76,4 @@ using __sanitizer::uptr; # define ASAN_INTERCEPT___CXA_ATEXIT 0 #endif -# if SANITIZER_WINDOWS -extern "C" { -// Windows threads. -__declspec(dllimport) -void* __stdcall CreateThread(void *sec, uptr st, void* start, - void *arg, DWORD fl, DWORD *id); - -int memcmp(const void *a1, const void *a2, uptr size); -void memmove(void *to, const void *from, uptr size); -void* memset(void *block, int c, uptr size); -void* memcpy(void *to, const void *from, uptr size); -char* strcat(char *to, const char* from); // NOLINT -char* strchr(const char *str, int c); -int strcmp(const char *s1, const char* s2); -char* strcpy(char *to, const char* from); // NOLINT -uptr strlen(const char *s); -char* strncat(char *to, const char* from, uptr size); -int strncmp(const char *s1, const char* s2, uptr size); -char* strncpy(char *to, const char* from, uptr size); -uptr strnlen(const char *s, uptr maxlen); -int atoi(const char *nptr); -long atol(const char *nptr); // NOLINT -long strtol(const char *nptr, char **endptr, int base); // NOLINT -void longjmp(void *env, int value); -double frexp(double x, int *expptr); -} -# endif - #endif // ASAN_INTERCEPTED_FUNCTIONS_H diff --git a/lib/asan/asan_interceptors.cc b/lib/asan/asan_interceptors.cc index 7e7deea29634..a25827b6b9ae 100644 --- a/lib/asan/asan_interceptors.cc +++ b/lib/asan/asan_interceptors.cc @@ -53,7 +53,7 @@ static inline bool QuickCheckForUnpoisonedRegion(uptr beg, uptr size) { } while (0) #define ASAN_READ_RANGE(offset, size) ACCESS_MEMORY_RANGE(offset, size, false) -#define ASAN_WRITE_RANGE(offset, size) ACCESS_MEMORY_RANGE(offset, size, true); +#define ASAN_WRITE_RANGE(offset, size) ACCESS_MEMORY_RANGE(offset, size, true) // Behavior of functions like "memcpy" or "strcpy" is undefined // if memory intervals overlap. We report error in this case. @@ -94,9 +94,9 @@ void SetThreadName(const char *name) { asanThreadRegistry().SetThreadName(t->tid(), name); } -static void DisableStrictInitOrderChecker() { - if (flags()->strict_init_order) - flags()->check_initialization_order = false; +int OnExit() { + // FIXME: ask frontend whether we need to return failure. + return 0; } } // namespace __asan @@ -104,26 +104,69 @@ static void DisableStrictInitOrderChecker() { // ---------------------- Wrappers ---------------- {{{1 using namespace __asan; // NOLINT +DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr) +DECLARE_REAL_AND_INTERCEPTOR(void, free, void *) + +#if !SANITIZER_MAC +#define ASAN_INTERCEPT_FUNC(name) \ + do { \ + if ((!INTERCEPT_FUNCTION(name) || !REAL(name)) && \ + common_flags()->verbosity > 0) \ + Report("AddressSanitizer: failed to intercept '" #name "'\n"); \ + } while (0) +#else +// OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION. +#define ASAN_INTERCEPT_FUNC(name) +#endif // SANITIZER_MAC + +#define COMMON_INTERCEPT_FUNCTION(name) ASAN_INTERCEPT_FUNC(name) +#define COMMON_INTERCEPTOR_UNPOISON_PARAM(ctx, count) \ + do { \ + } while (false) #define COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ptr, size) \ ASAN_WRITE_RANGE(ptr, size) #define COMMON_INTERCEPTOR_READ_RANGE(ctx, ptr, size) ASAN_READ_RANGE(ptr, size) -#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \ - do { \ - if (asan_init_is_running) \ - return REAL(func)(__VA_ARGS__); \ - ctx = 0; \ - (void)ctx; \ - ENSURE_ASAN_INITED(); \ +#define COMMON_INTERCEPTOR_ENTER(ctx, func, ...) \ + do { \ + if (asan_init_is_running) return REAL(func)(__VA_ARGS__); \ + ctx = 0; \ + (void) ctx; \ + if (SANITIZER_MAC && !asan_inited) return REAL(func)(__VA_ARGS__); \ + ENSURE_ASAN_INITED(); \ + } 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_FD_ACQUIRE(ctx, fd) do { } while (false) -#define COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd) 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) +#define COMMON_INTERCEPTOR_ON_EXIT(ctx) OnExit() #include "sanitizer_common/sanitizer_common_interceptors.inc" #define COMMON_SYSCALL_PRE_READ_RANGE(p, s) ASAN_READ_RANGE(p, s) #define COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) ASAN_WRITE_RANGE(p, s) -#define COMMON_SYSCALL_POST_READ_RANGE(p, s) -#define COMMON_SYSCALL_POST_WRITE_RANGE(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" static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) { @@ -133,16 +176,16 @@ static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) { } #if ASAN_INTERCEPT_PTHREAD_CREATE -extern "C" int pthread_attr_getdetachstate(void *attr, int *v); - INTERCEPTOR(int, pthread_create, void *thread, void *attr, void *(*start_routine)(void*), void *arg) { + EnsureMainThreadIDIsCorrect(); // Strict init-order checking in thread-hostile. - DisableStrictInitOrderChecker(); + if (flags()->strict_init_order) + StopInitOrderChecking(); GET_STACK_TRACE_THREAD; int detached = 0; if (attr != 0) - pthread_attr_getdetachstate(attr, &detached); + REAL(pthread_attr_getdetachstate)(attr, &detached); u32 current_tid = GetCurrentTidOrInvalid(); AsanThread *t = AsanThread::Create(start_routine, arg); @@ -170,7 +213,7 @@ INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act, #elif SANITIZER_POSIX // We need to have defined REAL(sigaction) on posix systems. DEFINE_REAL(int, sigaction, int signum, const struct sigaction *act, - struct sigaction *oldact); + struct sigaction *oldact) #endif // ASAN_INTERCEPT_SIGNAL_AND_SIGACTION #if ASAN_INTERCEPT_SWAPCONTEXT @@ -240,13 +283,15 @@ INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) { // Since asan maps 16T of RAM, mlock is completely unfriendly to asan. // All functions return 0 (success). static void MlockIsUnsupported() { - static bool printed = 0; + static bool printed = false; if (printed) return; printed = true; - Printf("INFO: AddressSanitizer ignores mlock/mlockall/munlock/munlockall\n"); + if (common_flags()->verbosity > 0) { + Printf("INFO: AddressSanitizer ignores " + "mlock/mlockall/munlock/munlockall\n"); + } } -extern "C" { INTERCEPTOR(int, mlock, const void *addr, uptr len) { MlockIsUnsupported(); return 0; @@ -266,7 +311,6 @@ INTERCEPTOR(int, munlockall, void) { MlockIsUnsupported(); return 0; } -} // extern "C" static inline int CharCmp(unsigned char c1, unsigned char c2) { return (c1 == c2) ? 0 : (c1 < c2) ? -1 : 1; @@ -300,7 +344,23 @@ INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) { return REAL(memcmp(a1, a2, size)); } +#define MEMMOVE_BODY { \ + if (!asan_inited) return internal_memmove(to, from, size); \ + if (asan_init_is_running) { \ + return REAL(memmove)(to, from, size); \ + } \ + ENSURE_ASAN_INITED(); \ + if (flags()->replace_intrin) { \ + ASAN_READ_RANGE(from, size); \ + ASAN_WRITE_RANGE(to, size); \ + } \ + return internal_memmove(to, from, size); \ +} + +INTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) MEMMOVE_BODY + INTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) { +#if !SANITIZER_MAC if (!asan_inited) return internal_memcpy(to, from, size); // memcpy is called during __asan_init() from the internals // of printf(...). @@ -317,24 +377,19 @@ INTERCEPTOR(void*, memcpy, void *to, const void *from, uptr size) { ASAN_READ_RANGE(from, size); ASAN_WRITE_RANGE(to, size); } - // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8. + // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8, so + // calling REAL(memcpy) here leads to infinite recursion. // See also http://code.google.com/p/address-sanitizer/issues/detail?id=116. return internal_memcpy(to, from, size); -} - -INTERCEPTOR(void*, memmove, void *to, const void *from, uptr size) { - if (!asan_inited) return internal_memmove(to, from, size); - if (asan_init_is_running) { - return REAL(memmove)(to, from, size); - } - ENSURE_ASAN_INITED(); - if (flags()->replace_intrin) { - ASAN_READ_RANGE(from, size); - ASAN_WRITE_RANGE(to, size); - } - // Interposing of resolver functions is broken on Mac OS 10.7 and 10.8. - // See also http://code.google.com/p/address-sanitizer/issues/detail?id=116. - return internal_memmove(to, from, size); +#else + // At least on 10.7 and 10.8 both memcpy() and memmove() are being replaced + // with WRAP(memcpy). As a result, false positives are reported for memmove() + // calls. If we just disable error reporting with + // ASAN_OPTIONS=replace_intrin=0, memmove() is still replaced with + // internal_memcpy(), which may lead to crashes, see + // http://llvm.org/bugs/show_bug.cgi?id=16362. + MEMMOVE_BODY +#endif // !SANITIZER_MAC } INTERCEPTOR(void*, memset, void *block, int c, uptr size) { @@ -375,7 +430,7 @@ INTERCEPTOR(char*, index, const char *string, int c) DECLARE_REAL(char*, index, const char *string, int c) OVERRIDE_FUNCTION(index, strchr); # else -DEFINE_REAL(char*, index, const char *string, int c); +DEFINE_REAL(char*, index, const char *string, int c) # endif # endif #endif // ASAN_INTERCEPT_INDEX @@ -418,24 +473,6 @@ INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) { return REAL(strncat)(to, from, size); } -INTERCEPTOR(int, strcmp, const char *s1, const char *s2) { - if (!asan_inited) return internal_strcmp(s1, s2); - if (asan_init_is_running) { - return REAL(strcmp)(s1, s2); - } - ENSURE_ASAN_INITED(); - unsigned char c1, c2; - uptr i; - for (i = 0; ; i++) { - c1 = (unsigned char)s1[i]; - c2 = (unsigned char)s2[i]; - if (c1 != c2 || c1 == '\0') break; - } - ASAN_READ_RANGE(s1, i + 1); - ASAN_READ_RANGE(s2, i + 1); - return CharCmp(c1, c2); -} - INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT #if SANITIZER_MAC if (!asan_inited) return REAL(strcpy)(to, from); // NOLINT @@ -457,21 +494,16 @@ INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT #if ASAN_INTERCEPT_STRDUP INTERCEPTOR(char*, strdup, const char *s) { -#if SANITIZER_MAC - // FIXME: because internal_strdup() uses InternalAlloc(), which currently - // just calls malloc() on Mac, we can't use internal_strdup() with the - // dynamic runtime. We can remove the call to REAL(strdup) once InternalAlloc - // starts using mmap() instead. - // See also http://code.google.com/p/address-sanitizer/issues/detail?id=123. - if (!asan_inited) return REAL(strdup)(s); -#endif if (!asan_inited) return internal_strdup(s); ENSURE_ASAN_INITED(); + uptr length = REAL(strlen)(s); if (flags()->replace_str) { - uptr length = REAL(strlen)(s); ASAN_READ_RANGE(s, length + 1); } - return REAL(strdup)(s); + 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 @@ -490,24 +522,13 @@ INTERCEPTOR(uptr, strlen, const char *s) { return length; } -INTERCEPTOR(int, strncmp, const char *s1, const char *s2, uptr size) { - if (!asan_inited) return internal_strncmp(s1, s2, size); - // strncmp is called from malloc_default_purgeable_zone() - // in __asan::ReplaceSystemAlloc() on Mac. - if (asan_init_is_running) { - return REAL(strncmp)(s1, s2, size); +INTERCEPTOR(uptr, wcslen, const wchar_t *s) { + uptr length = REAL(wcslen)(s); + if (!asan_init_is_running) { + ENSURE_ASAN_INITED(); + ASAN_READ_RANGE(s, (length + 1) * sizeof(wchar_t)); } - ENSURE_ASAN_INITED(); - unsigned char c1 = 0, c2 = 0; - uptr i; - for (i = 0; i < size; i++) { - c1 = (unsigned char)s1[i]; - c2 = (unsigned char)s2[i]; - if (c1 != c2 || c1 == '\0') break; - } - ASAN_READ_RANGE(s1, Min(i + 1, size)); - ASAN_READ_RANGE(s2, Min(i + 1, size)); - return CharCmp(c1, c2); + return length; } INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) { @@ -644,6 +665,9 @@ static void AtCxaAtexit(void *unused) { #if ASAN_INTERCEPT___CXA_ATEXIT INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg, void *dso_handle) { +#if SANITIZER_MAC + if (!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, 0, 0); @@ -651,26 +675,22 @@ INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg, } #endif // ASAN_INTERCEPT___CXA_ATEXIT -#define ASAN_INTERCEPT_FUNC(name) do { \ - if (!INTERCEPT_FUNCTION(name) && flags()->verbosity > 0) \ - Report("AddressSanitizer: failed to intercept '" #name "'\n"); \ - } while (0) - #if SANITIZER_WINDOWS INTERCEPTOR_WINAPI(DWORD, CreateThread, void* security, uptr stack_size, DWORD (__stdcall *start_routine)(void*), void* arg, - DWORD flags, void* tid) { + DWORD thr_flags, void* tid) { // Strict init-order checking in thread-hostile. - DisableStrictInitOrderChecker(); + if (flags()->strict_init_order) + StopInitOrderChecking(); GET_STACK_TRACE_THREAD; u32 current_tid = GetCurrentTidOrInvalid(); AsanThread *t = AsanThread::Create(start_routine, arg); CreateThreadContextArgs args = { t, &stack }; - int detached = 0; // FIXME: how can we determine it on Windows? + bool detached = false; // FIXME: how can we determine it on Windows? asanThreadRegistry().CreateThread(*(uptr*)t, detached, current_tid, &args); return REAL(CreateThread)(security, stack_size, - asan_thread_start, t, flags, tid); + asan_thread_start, t, thr_flags, tid); } namespace __asan { @@ -687,9 +707,6 @@ void InitializeAsanInterceptors() { static bool was_called_once; CHECK(was_called_once == false); was_called_once = true; -#if SANITIZER_MAC - return; -#else SANITIZER_COMMON_INTERCEPTORS_INIT; // Intercept mem* functions. @@ -703,11 +720,10 @@ void InitializeAsanInterceptors() { // Intercept str* functions. ASAN_INTERCEPT_FUNC(strcat); // NOLINT ASAN_INTERCEPT_FUNC(strchr); - ASAN_INTERCEPT_FUNC(strcmp); ASAN_INTERCEPT_FUNC(strcpy); // NOLINT ASAN_INTERCEPT_FUNC(strlen); + ASAN_INTERCEPT_FUNC(wcslen); ASAN_INTERCEPT_FUNC(strncat); - ASAN_INTERCEPT_FUNC(strncmp); ASAN_INTERCEPT_FUNC(strncpy); #if ASAN_INTERCEPT_STRDUP ASAN_INTERCEPT_FUNC(strdup); @@ -771,10 +787,9 @@ void InitializeAsanInterceptors() { InitializeWindowsInterceptors(); #endif - if (flags()->verbosity > 0) { + if (common_flags()->verbosity > 0) { Report("AddressSanitizer: libc interceptors initialized\n"); } -#endif // SANITIZER_MAC } } // namespace __asan diff --git a/lib/asan/asan_interface_internal.h b/lib/asan/asan_interface_internal.h index 24f76253bccd..5c1d025296fb 100644 --- a/lib/asan/asan_interface_internal.h +++ b/lib/asan/asan_interface_internal.h @@ -30,7 +30,7 @@ extern "C" { // v2=>v3: stack frame description (created by the compiler) // contains the function PC as the 3-rd field (see // DescribeAddressIfStack). - void __asan_init_v3() SANITIZER_INTERFACE_ATTRIBUTE; + SANITIZER_INTERFACE_ATTRIBUTE void __asan_init_v3(); #define __asan_init __asan_init_v3 // This structure describes an instrumented global variable. @@ -46,96 +46,85 @@ extern "C" { // These two functions should be called by the instrumented code. // 'globals' is an array of structures describing 'n' globals. - void __asan_register_globals(__asan_global *globals, uptr n) - SANITIZER_INTERFACE_ATTRIBUTE; - void __asan_unregister_globals(__asan_global *globals, uptr n) - SANITIZER_INTERFACE_ATTRIBUTE; + 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. - void __asan_before_dynamic_init(const char *module_name) - SANITIZER_INTERFACE_ATTRIBUTE; - void __asan_after_dynamic_init() - SANITIZER_INTERFACE_ATTRIBUTE; - - // These two functions are used by the instrumented code in the - // use-after-return mode. __asan_stack_malloc allocates size bytes of - // fake stack and __asan_stack_free poisons it. real_stack is a pointer to - // the real stack region. - uptr __asan_stack_malloc(uptr size, uptr real_stack) - SANITIZER_INTERFACE_ATTRIBUTE; - void __asan_stack_free(uptr ptr, uptr size, uptr real_stack) - SANITIZER_INTERFACE_ATTRIBUTE; + SANITIZER_INTERFACE_ATTRIBUTE + void __asan_before_dynamic_init(const char *module_name); + SANITIZER_INTERFACE_ATTRIBUTE + void __asan_after_dynamic_init(); // 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. - void __asan_poison_stack_memory(uptr addr, uptr size) - SANITIZER_INTERFACE_ATTRIBUTE; - void __asan_unpoison_stack_memory(uptr addr, uptr size) - SANITIZER_INTERFACE_ATTRIBUTE; + 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. - void __asan_handle_no_return() SANITIZER_INTERFACE_ATTRIBUTE; + SANITIZER_INTERFACE_ATTRIBUTE void __asan_handle_no_return(); - 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; + 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); - bool __asan_address_is_poisoned(void const volatile *addr) - SANITIZER_INTERFACE_ATTRIBUTE; + SANITIZER_INTERFACE_ATTRIBUTE + bool __asan_address_is_poisoned(void const volatile *addr); - uptr __asan_region_is_poisoned(uptr beg, uptr size) - SANITIZER_INTERFACE_ATTRIBUTE; + SANITIZER_INTERFACE_ATTRIBUTE + uptr __asan_region_is_poisoned(uptr beg, uptr size); - void __asan_describe_address(uptr addr) - SANITIZER_INTERFACE_ATTRIBUTE; + SANITIZER_INTERFACE_ATTRIBUTE + void __asan_describe_address(uptr addr); + SANITIZER_INTERFACE_ATTRIBUTE void __asan_report_error(uptr pc, uptr bp, uptr sp, - uptr addr, bool is_write, uptr access_size) - SANITIZER_INTERFACE_ATTRIBUTE; + uptr addr, bool is_write, uptr access_size); - int __asan_set_error_exit_code(int exit_code) - 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_INTERFACE_ATTRIBUTE + int __asan_set_error_exit_code(int exit_code); + SANITIZER_INTERFACE_ATTRIBUTE + void __asan_set_death_callback(void (*callback)(void)); + SANITIZER_INTERFACE_ATTRIBUTE + void __asan_set_error_report_callback(void (*callback)(const char*)); - /* OPTIONAL */ void __asan_on_error() - SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE; + SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE + /* OPTIONAL */ void __asan_on_error(); + SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE /* OPTIONAL */ bool __asan_symbolize(const void *pc, char *out_buffer, - int out_size) - SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE; - - uptr __asan_get_estimated_allocated_size(uptr size) - SANITIZER_INTERFACE_ATTRIBUTE; - bool __asan_get_ownership(const void *p) - SANITIZER_INTERFACE_ATTRIBUTE; - uptr __asan_get_allocated_size(const void *p) - SANITIZER_INTERFACE_ATTRIBUTE; - uptr __asan_get_current_allocated_bytes() - SANITIZER_INTERFACE_ATTRIBUTE; - uptr __asan_get_heap_size() - SANITIZER_INTERFACE_ATTRIBUTE; - uptr __asan_get_free_bytes() - SANITIZER_INTERFACE_ATTRIBUTE; - uptr __asan_get_unmapped_bytes() - SANITIZER_INTERFACE_ATTRIBUTE; - void __asan_print_accumulated_stats() - SANITIZER_INTERFACE_ATTRIBUTE; - - /* OPTIONAL */ const char* __asan_default_options() - SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE; - - /* OPTIONAL */ void __asan_malloc_hook(void *ptr, uptr size) - SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE; - /* OPTIONAL */ void __asan_free_hook(void *ptr) - SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE; + int out_size); + + SANITIZER_INTERFACE_ATTRIBUTE + uptr __asan_get_estimated_allocated_size(uptr size); + + SANITIZER_INTERFACE_ATTRIBUTE bool __asan_get_ownership(const void *p); + SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_get_allocated_size(const void *p); + SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_get_current_allocated_bytes(); + SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_get_heap_size(); + SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_get_free_bytes(); + SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_get_unmapped_bytes(); + SANITIZER_INTERFACE_ATTRIBUTE void __asan_print_accumulated_stats(); + + SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE + /* OPTIONAL */ const char* __asan_default_options(); + + SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE + /* OPTIONAL */ void __asan_malloc_hook(void *ptr, uptr size); + SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE + /* OPTIONAL */ void __asan_free_hook(void *ptr); + + // Global flag, copy of ASAN_OPTIONS=detect_stack_use_after_return + SANITIZER_INTERFACE_ATTRIBUTE + extern int __asan_option_detect_stack_use_after_return; } // extern "C" #endif // ASAN_INTERFACE_INTERNAL_H diff --git a/lib/asan/asan_internal.h b/lib/asan/asan_internal.h index 7a4d74472bcd..70e55ea0afef 100644 --- a/lib/asan/asan_internal.h +++ b/lib/asan/asan_internal.h @@ -98,6 +98,7 @@ void StopInitOrderChecking(); void AsanTSDInit(void (*destructor)(void *tsd)); void *AsanTSDGet(); void AsanTSDSet(void *tsd); +void PlatformTSDDtor(void *tsd); void AppendToErrorMessageBuffer(const char *buffer); diff --git a/lib/asan/asan_linux.cc b/lib/asan/asan_linux.cc index 17bb4ca5f01c..39eec3bfd301 100644 --- a/lib/asan/asan_linux.cc +++ b/lib/asan/asan_linux.cc @@ -58,6 +58,12 @@ void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { *pc = ucontext->uc_mcontext.arm_pc; *bp = ucontext->uc_mcontext.arm_fp; *sp = ucontext->uc_mcontext.arm_sp; +# elif defined(__hppa__) + ucontext_t *ucontext = (ucontext_t*)context; + *pc = ucontext->uc_mcontext.sc_iaoq[0]; + /* GCC uses %r3 whenever a frame pointer is needed. */ + *bp = ucontext->uc_mcontext.sc_gr[3]; + *sp = ucontext->uc_mcontext.sc_gr[30]; # elif defined(__x86_64__) ucontext_t *ucontext = (ucontext_t*)context; *pc = ucontext->uc_mcontext.gregs[REG_RIP]; @@ -89,6 +95,11 @@ void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { stk_ptr = (uptr *) *sp; *bp = stk_ptr[15]; # endif +# elif defined(__mips__) + ucontext_t *ucontext = (ucontext_t*)context; + *pc = ucontext->uc_mcontext.gregs[31]; + *bp = ucontext->uc_mcontext.gregs[30]; + *sp = ucontext->uc_mcontext.gregs[29]; #else # error "Unsupported arch" #endif diff --git a/lib/asan/asan_mac.cc b/lib/asan/asan_mac.cc index 4313534008e7..e27d70adb81e 100644 --- a/lib/asan/asan_mac.cc +++ b/lib/asan/asan_mac.cc @@ -21,6 +21,7 @@ #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 <crt_externs.h> // for _NSGetArgv @@ -52,7 +53,9 @@ void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { # endif // SANITIZER_WORDSIZE } -int GetMacosVersion() { +MacosVersion cached_macos_version = MACOS_VERSION_UNINITIALIZED; + +MacosVersion GetMacosVersionInternal() { int mib[2] = { CTL_KERN, KERN_OSRELEASE }; char version[100]; uptr len = 0, maxlen = sizeof(version) / sizeof(version[0]); @@ -68,6 +71,7 @@ int GetMacosVersion() { case '0': return MACOS_VERSION_SNOW_LEOPARD; case '1': return MACOS_VERSION_LION; case '2': return MACOS_VERSION_MOUNTAIN_LION; + case '3': return MACOS_VERSION_MAVERICKS; default: return MACOS_VERSION_UNKNOWN; } } @@ -75,6 +79,18 @@ int GetMacosVersion() { } } +MacosVersion GetMacosVersion() { + atomic_uint32_t *cache = + reinterpret_cast<atomic_uint32_t*>(&cached_macos_version); + MacosVersion result = + static_cast<MacosVersion>(atomic_load(cache, memory_order_acquire)); + if (result == MACOS_VERSION_UNINITIALIZED) { + result = GetMacosVersionInternal(); + atomic_store(cache, result, memory_order_release); + } + return result; +} + bool PlatformHasDifferentMemcpyAndMemmove() { // On OS X 10.7 memcpy() and memmove() are both resolved // into memmove$VARIANT$sse42. @@ -158,7 +174,7 @@ void MaybeReexec() { // Set DYLD_INSERT_LIBRARIES equal to the runtime dylib name. setenv(kDyldInsertLibraries, info.dli_fname, /*overwrite*/0); } - if (flags()->verbosity >= 1) { + if (common_flags()->verbosity >= 1) { Report("exec()-ing the program with\n"); Report("%s=%s\n", kDyldInsertLibraries, new_env); Report("to enable ASan wrappers.\n"); @@ -295,7 +311,7 @@ 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; - if (flags()->verbosity >= 2) { + if (common_flags()->verbosity >= 2) { Report("asan_dispatch_call_block_and_release(): " "context: %p, pthread_self: %p\n", block, pthread_self()); @@ -330,7 +346,7 @@ asan_block_context_t *alloc_asan_context(void *ctxt, dispatch_function_t func, dispatch_function_t func) { \ GET_STACK_TRACE_THREAD; \ asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); \ - if (flags()->verbosity >= 2) { \ + if (common_flags()->verbosity >= 2) { \ Report(#dispatch_x_f "(): context: %p, pthread_self: %p\n", \ asan_ctxt, pthread_self()); \ PRINT_CURRENT_STACK(); \ @@ -348,7 +364,7 @@ INTERCEPTOR(void, dispatch_after_f, dispatch_time_t when, dispatch_function_t func) { GET_STACK_TRACE_THREAD; asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); - if (flags()->verbosity >= 2) { + if (common_flags()->verbosity >= 2) { Report("dispatch_after_f: %p\n", asan_ctxt); PRINT_CURRENT_STACK(); } @@ -361,7 +377,7 @@ INTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group, dispatch_function_t func) { GET_STACK_TRACE_THREAD; asan_block_context_t *asan_ctxt = alloc_asan_context(ctxt, func, &stack); - if (flags()->verbosity >= 2) { + if (common_flags()->verbosity >= 2) { Report("dispatch_group_async_f(): context: %p, pthread_self: %p\n", asan_ctxt, pthread_self()); PRINT_CURRENT_STACK(); diff --git a/lib/asan/asan_mac.h b/lib/asan/asan_mac.h index b1a1966dbc6e..827b8b001699 100644 --- a/lib/asan/asan_mac.h +++ b/lib/asan/asan_mac.h @@ -12,7 +12,7 @@ // Mac-specific ASan definitions. //===----------------------------------------------------------------------===// #ifndef ASAN_MAC_H -#define ASAN__MAC_H +#define ASAN_MAC_H // CF_RC_BITS, the layout of CFRuntimeBase and __CFStrIsConstant are internal // and subject to change in further CoreFoundation versions. Apple does not @@ -36,12 +36,14 @@ typedef struct __CFRuntimeBase { #endif } CFRuntimeBase; -enum { - MACOS_VERSION_UNKNOWN = 0, +enum MacosVersion { + MACOS_VERSION_UNINITIALIZED = 0, + MACOS_VERSION_UNKNOWN, MACOS_VERSION_LEOPARD, MACOS_VERSION_SNOW_LEOPARD, MACOS_VERSION_LION, - MACOS_VERSION_MOUNTAIN_LION + MACOS_VERSION_MOUNTAIN_LION, + MACOS_VERSION_MAVERICKS }; // Used by asan_malloc_mac.cc and asan_mac.cc @@ -49,7 +51,7 @@ extern "C" void __CFInitialize(); namespace __asan { -int GetMacosVersion(); +MacosVersion GetMacosVersion(); void MaybeReplaceCFAllocator(); } // namespace __asan diff --git a/lib/asan/asan_malloc_linux.cc b/lib/asan/asan_malloc_linux.cc index 20e636b9b3c0..24b7f6977927 100644 --- a/lib/asan/asan_malloc_linux.cc +++ b/lib/asan/asan_malloc_linux.cc @@ -105,8 +105,9 @@ INTERCEPTOR(void*, __libc_memalign, uptr align, uptr s) ALIAS("memalign"); INTERCEPTOR(uptr, malloc_usable_size, void *ptr) { - GET_STACK_TRACE_MALLOC; - return asan_malloc_usable_size(ptr, &stack); + GET_CURRENT_PC_BP_SP; + (void)sp; + return asan_malloc_usable_size(ptr, pc, bp); } // We avoid including malloc.h for portability reasons. diff --git a/lib/asan/asan_malloc_mac.cc b/lib/asan/asan_malloc_mac.cc index 4f353cb99ca7..f9f08f0201c2 100644 --- a/lib/asan/asan_malloc_mac.cc +++ b/lib/asan/asan_malloc_mac.cc @@ -19,6 +19,7 @@ #include <CoreFoundation/CFBase.h> #include <dlfcn.h> #include <malloc/malloc.h> +#include <sys/mman.h> #include "asan_allocator.h" #include "asan_interceptors.h" @@ -42,10 +43,19 @@ INTERCEPTOR(malloc_zone_t *, malloc_create_zone, vm_size_t start_size, unsigned zone_flags) { if (!asan_inited) __asan_init(); GET_STACK_TRACE_MALLOC; + uptr page_size = GetPageSizeCached(); + uptr allocated_size = RoundUpTo(sizeof(asan_zone), page_size); malloc_zone_t *new_zone = - (malloc_zone_t*)asan_malloc(sizeof(asan_zone), &stack); + (malloc_zone_t*)asan_memalign(page_size, allocated_size, + &stack, FROM_MALLOC); internal_memcpy(new_zone, &asan_zone, sizeof(asan_zone)); new_zone->zone_name = NULL; // The name will be changed anyway. + if (GetMacosVersion() >= MACOS_VERSION_LION) { + // Prevent the client app from overwriting the zone contents. + // Library functions that need to modify the zone will set PROT_WRITE on it. + // This matches the behavior of malloc_create_zone() on OSX 10.7 and higher. + mprotect(new_zone, allocated_size, PROT_READ); + } return new_zone; } diff --git a/lib/asan/asan_malloc_win.cc b/lib/asan/asan_malloc_win.cc index 31fb777c7045..73e4c825092c 100644 --- a/lib/asan/asan_malloc_win.cc +++ b/lib/asan/asan_malloc_win.cc @@ -32,11 +32,13 @@ using namespace __asan; // NOLINT // revisited in the future. extern "C" { +SANITIZER_INTERFACE_ATTRIBUTE void free(void *ptr) { GET_STACK_TRACE_FREE; return asan_free(ptr, &stack, FROM_MALLOC); } +SANITIZER_INTERFACE_ATTRIBUTE void _free_dbg(void* ptr, int) { free(ptr); } @@ -45,38 +47,46 @@ void cfree(void *ptr) { CHECK(!"cfree() should not be used on Windows?"); } +SANITIZER_INTERFACE_ATTRIBUTE void *malloc(size_t size) { GET_STACK_TRACE_MALLOC; return asan_malloc(size, &stack); } +SANITIZER_INTERFACE_ATTRIBUTE void* _malloc_dbg(size_t size, int , const char*, int) { return malloc(size); } +SANITIZER_INTERFACE_ATTRIBUTE void *calloc(size_t nmemb, size_t size) { GET_STACK_TRACE_MALLOC; return asan_calloc(nmemb, size, &stack); } +SANITIZER_INTERFACE_ATTRIBUTE void* _calloc_dbg(size_t n, size_t size, int, const char*, int) { return calloc(n, size); } +SANITIZER_INTERFACE_ATTRIBUTE void *_calloc_impl(size_t nmemb, size_t size, int *errno_tmp) { return calloc(nmemb, size); } +SANITIZER_INTERFACE_ATTRIBUTE void *realloc(void *ptr, size_t size) { GET_STACK_TRACE_MALLOC; return asan_realloc(ptr, size, &stack); } +SANITIZER_INTERFACE_ATTRIBUTE void *_realloc_dbg(void *ptr, size_t size, int) { CHECK(!"_realloc_dbg should not exist!"); return 0; } +SANITIZER_INTERFACE_ATTRIBUTE void* _recalloc(void* p, size_t n, size_t elem_size) { if (!p) return calloc(n, elem_size); @@ -86,9 +96,11 @@ void* _recalloc(void* p, size_t n, size_t elem_size) { return realloc(p, size); } +SANITIZER_INTERFACE_ATTRIBUTE size_t _msize(void *ptr) { - GET_STACK_TRACE_MALLOC; - return asan_malloc_usable_size(ptr, &stack); + GET_CURRENT_PC_BP_SP; + (void)sp; + return asan_malloc_usable_size(ptr, pc, bp); } int _CrtDbgReport(int, const char*, int, diff --git a/lib/asan/asan_mapping.h b/lib/asan/asan_mapping.h index f04629222419..1fecaeb35e1e 100644 --- a/lib/asan/asan_mapping.h +++ b/lib/asan/asan_mapping.h @@ -49,6 +49,20 @@ // || `[0x24000000, 0x27ffffff]` || ShadowGap || // || `[0x20000000, 0x23ffffff]` || LowShadow || // || `[0x00000000, 0x1fffffff]` || LowMem || +// +// Default Linux/MIPS mapping: +// || `[0x2aaa8000, 0xffffffff]` || HighMem || +// || `[0x0fffd000, 0x2aaa7fff]` || HighShadow || +// || `[0x0bffd000, 0x0fffcfff]` || ShadowGap || +// || `[0x0aaa8000, 0x0bffcfff]` || LowShadow || +// || `[0x00000000, 0x0aaa7fff]` || LowMem || + +static const u64 kDefaultShadowScale = 3; +static const u64 kDefaultShadowOffset32 = 1ULL << 29; +static const u64 kDefaultShadowOffset64 = 1ULL << 44; +static const u64 kDefaultShort64bitShadowOffset = 0x7FFF8000; // < 2G. +static const u64 kPPC64_ShadowOffset64 = 1ULL << 41; +static const u64 kMIPS32_ShadowOffset32 = 0x0aaa8000; #if ASAN_FLEXIBLE_MAPPING_AND_OFFSET == 1 extern SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_scale; @@ -56,22 +70,23 @@ extern SANITIZER_INTERFACE_ATTRIBUTE uptr __asan_mapping_offset; # define SHADOW_SCALE (__asan_mapping_scale) # define SHADOW_OFFSET (__asan_mapping_offset) #else +# define SHADOW_SCALE kDefaultShadowScale # if SANITIZER_ANDROID -# define SHADOW_SCALE (3) # define SHADOW_OFFSET (0) # else -# define SHADOW_SCALE (3) # if SANITIZER_WORDSIZE == 32 -# define SHADOW_OFFSET (1 << 29) +# if defined(__mips__) +# define SHADOW_OFFSET kMIPS32_ShadowOffset32 +# else +# define SHADOW_OFFSET kDefaultShadowOffset32 +# endif # else # if defined(__powerpc64__) -# define SHADOW_OFFSET (1ULL << 41) +# define SHADOW_OFFSET kPPC64_ShadowOffset64 +# elif SANITIZER_MAC +# define SHADOW_OFFSET kDefaultShadowOffset64 # else -# if SANITIZER_MAC -# define SHADOW_OFFSET (1ULL << 44) -# else -# define SHADOW_OFFSET 0x7fff8000ULL -# endif +# define SHADOW_OFFSET kDefaultShort64bitShadowOffset # endif # endif # endif @@ -133,7 +148,6 @@ static uptr kHighMemEnd = 0x7fffffffffffULL; static uptr kMidMemBeg = 0x3000000000ULL; static uptr kMidMemEnd = 0x4fffffffffULL; #else -SANITIZER_INTERFACE_ATTRIBUTE extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init. #endif diff --git a/lib/asan/asan_poisoning.cc b/lib/asan/asan_poisoning.cc index 772b5e64b027..280aaeb909a3 100644 --- a/lib/asan/asan_poisoning.cc +++ b/lib/asan/asan_poisoning.cc @@ -14,6 +14,7 @@ #include "asan_poisoning.h" #include "sanitizer_common/sanitizer_libc.h" +#include "sanitizer_common/sanitizer_flags.h" namespace __asan { @@ -68,7 +69,7 @@ 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; - if (flags()->verbosity >= 1) { + if (common_flags()->verbosity >= 1) { Printf("Trying to poison memory region [%p, %p)\n", (void*)beg_addr, (void*)end_addr); } @@ -110,7 +111,7 @@ 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; - if (flags()->verbosity >= 1) { + if (common_flags()->verbosity >= 1) { Printf("Trying to unpoison memory region [%p, %p)\n", (void*)beg_addr, (void*)end_addr); } @@ -183,37 +184,37 @@ uptr __asan_region_is_poisoned(uptr beg, uptr size) { extern "C" SANITIZER_INTERFACE_ATTRIBUTE -u16 __sanitizer_unaligned_load16(const u16 *p) { +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 u32 *p) { +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 u64 *p) { +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(u16 *p, u16 x) { +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(u32 *p, u32 x) { +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(u64 *p, u64 x) { +void __sanitizer_unaligned_store64(uu64 *p, u64 x) { CHECK_SMALL_REGION(p, sizeof(*p), true); *p = x; } @@ -244,13 +245,55 @@ static void PoisonAlignedStackMemory(uptr addr, uptr size, bool do_poison) { } void __asan_poison_stack_memory(uptr addr, uptr size) { - if (flags()->verbosity > 0) + if (common_flags()->verbosity > 0) Report("poisoning: %p %zx\n", (void*)addr, size); PoisonAlignedStackMemory(addr, size, true); } void __asan_unpoison_stack_memory(uptr addr, uptr size) { - if (flags()->verbosity > 0) + if (common_flags()->verbosity > 0) Report("unpoisoning: %p %zx\n", (void*)addr, size); PoisonAlignedStackMemory(addr, size, false); } + +void __sanitizer_annotate_contiguous_container(void *beg_p, void *end_p, + void *old_mid_p, + void *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; + CHECK(beg <= end && beg <= old_mid && beg <= new_mid && old_mid <= end && + new_mid <= end && IsAligned(beg, granularity)); + CHECK_LE(end - beg, + FIRST_32_SECOND_64(1UL << 30, 1UL << 34)); // Sanity check. + + uptr a = RoundDownTo(Min(old_mid, new_mid), granularity); + uptr c = RoundUpTo(Max(old_mid, new_mid), granularity); + uptr b = new_mid; + uptr b1 = RoundDownTo(b, granularity); + uptr b2 = RoundUpTo(b, granularity); + uptr d = old_mid; + uptr d1 = RoundDownTo(d, granularity); + uptr d2 = RoundUpTo(d, 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. + if (d1 != d2) + CHECK_EQ(*(u8*)MemToShadow(d1), d - d1); + if (a + granularity <= d1) + CHECK_EQ(*(u8*)MemToShadow(a), 0); + if (d2 + granularity <= c && c <= end) + CHECK_EQ(*(u8 *)MemToShadow(c - granularity), kAsanUserPoisonedMemoryMagic); + + // New state: + // [a, b1) is good, [b2, c) is bad, [b1, b2) is partially good. + // FIXME: we may want to have a separate poison magic value. + PoisonShadow(a, b1 - a, 0); + PoisonShadow(b2, c - b2, kAsanUserPoisonedMemoryMagic); + if (b1 != b2) { + CHECK_EQ(b2 - b1, granularity); + *(u8*)MemToShadow(b1) = static_cast<u8>(b - b1); + } +} diff --git a/lib/asan/asan_poisoning.h b/lib/asan/asan_poisoning.h index 86f81e5d0ae5..fbac21196b8f 100644 --- a/lib/asan/asan_poisoning.h +++ b/lib/asan/asan_poisoning.h @@ -43,6 +43,7 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size, ALWAYS_INLINE void FastPoisonShadowPartialRightRedzone( uptr aligned_addr, uptr size, uptr redzone_size, u8 value) { DCHECK(flags()->poison_heap); + 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) { @@ -50,7 +51,8 @@ ALWAYS_INLINE void FastPoisonShadowPartialRightRedzone( } else if (i >= size) { *shadow = (SHADOW_GRANULARITY == 128) ? 0xff : value; // unaddressable } else { - *shadow = size - i; // first size-i bytes are addressable + // first size-i bytes are addressable + *shadow = poison_partial ? static_cast<u8>(size - i) : 0; } } } diff --git a/lib/asan/asan_posix.cc b/lib/asan/asan_posix.cc index 5126a756d1c8..bcc6b381a785 100644 --- a/lib/asan/asan_posix.cc +++ b/lib/asan/asan_posix.cc @@ -1,4 +1,4 @@ -//===-- asan_linux.cc -----------------------------------------------------===// +//===-- asan_posix.cc -----------------------------------------------------===// // // The LLVM Compiler Infrastructure // @@ -44,7 +44,7 @@ static void MaybeInstallSigaction(int signum, sigact.sa_flags = SA_SIGINFO; if (flags()->use_sigaltstack) sigact.sa_flags |= SA_ONSTACK; CHECK_EQ(0, REAL(sigaction)(signum, &sigact, 0)); - if (flags()->verbosity >= 1) { + if (common_flags()->verbosity >= 1) { Report("Installed the sigaction for signal %d\n", signum); } } @@ -71,7 +71,7 @@ void SetAlternateSignalStack() { altstack.ss_flags = 0; altstack.ss_size = kAltStackSize; CHECK_EQ(0, sigaltstack(&altstack, 0)); - if (flags()->verbosity > 0) { + if (common_flags()->verbosity > 0) { Report("Alternative stack for T%d set: [%p,%p)\n", GetCurrentTidOrInvalid(), altstack.ss_sp, (char*)altstack.ss_sp + altstack.ss_size); @@ -116,6 +116,15 @@ void AsanTSDSet(void *tsd) { 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_LINUX || SANITIZER_MAC diff --git a/lib/asan/asan_report.cc b/lib/asan/asan_report.cc index aeeebf452ca8..ed4e433c7a54 100644 --- a/lib/asan/asan_report.cc +++ b/lib/asan/asan_report.cc @@ -20,6 +20,7 @@ #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 { @@ -44,15 +45,6 @@ void AppendToErrorMessageBuffer(const char *buffer) { } // ---------------------- Decorator ------------------------------ {{{1 -bool PrintsToTtyCached() { - static int cached = 0; - static bool prints_to_tty; - if (!cached) { // Ok wrt threads since we are printing only from one thread. - prints_to_tty = PrintsToTty(); - cached = 1; - } - return prints_to_tty; -} class Decorator: private __sanitizer::AnsiColorDecorator { public: Decorator() : __sanitizer::AnsiColorDecorator(PrintsToTtyCached()) { } @@ -113,7 +105,7 @@ static void PrintShadowBytes(const char *before, u8 *bytes, for (uptr i = 0; i < n; i++) { u8 *p = bytes + i; const char *before = p == guilty ? "[" : - p - 1 == guilty ? "" : " "; + (p - 1 == guilty && i != 0) ? "" : " "; const char *after = p == guilty ? "]" : ""; PrintShadowByte(before, *p, after); } @@ -125,7 +117,7 @@ static void PrintLegend() { "application bytes):\n", (int)SHADOW_GRANULARITY); PrintShadowByte(" Addressable: ", 0); Printf(" Partially addressable: "); - for (uptr i = 1; i < SHADOW_GRANULARITY; i++) + for (u8 i = 1; i < SHADOW_GRANULARITY; i++) PrintShadowByte("", i, " "); Printf("\n"); PrintShadowByte(" Heap left redzone: ", kAsanHeapLeftRedzoneMagic); @@ -175,6 +167,11 @@ static void PrintZoneForPointer(uptr ptr, uptr zone_ptr, } } +static void DescribeThread(AsanThread *t) { + if (t) + DescribeThread(t->context()); +} + // ---------------------- Address Descriptions ------------------- {{{1 static bool IsASCII(unsigned char c) { @@ -184,7 +181,9 @@ static bool IsASCII(unsigned char c) { static 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. - return (name[0] == '_' && name[1] == 'Z') ? Demangle(name) : name; + return (name[0] == '_' && name[1] == 'Z') + ? Symbolizer::Get()->Demangle(name) + : name; } // Check if the global is a zero-terminated ASCII string. If so, print it. @@ -264,10 +263,53 @@ const char *ThreadNameWithParenthesis(u32 tid, char buff[], return ThreadNameWithParenthesis(t, buff, buff_len); } +void PrintAccessAndVarIntersection(const char *var_name, + uptr var_beg, uptr var_size, + 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 = 0; + // 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"; + } + Printf(" [%zd, %zd) '%s'", var_beg, var_beg + var_size, var_name); + 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. + Printf("%s <== Memory access at offset %zd %s this variable%s\n", + d.Location(), addr, pos_descr, d.EndLocation()); + } else { + Printf("\n"); + } +} + +struct StackVarDescr { + uptr beg; + uptr size; + const char *name_pos; + uptr name_len; +}; + bool DescribeAddressIfStack(uptr addr, uptr access_size) { AsanThread *t = FindThreadByStackAddress(addr); if (!t) return false; - const sptr kBufSize = 4095; + const uptr kBufSize = 4095; char buf[kBufSize]; uptr offset = 0; uptr frame_pc = 0; @@ -306,31 +348,44 @@ bool DescribeAddressIfStack(uptr addr, uptr access_size) { PrintStack(&alloca_stack); // Report the number of stack objects. char *p; - uptr n_objects = internal_simple_strtoll(frame_descr, &p, 10); + uptr n_objects = (uptr)internal_simple_strtoll(frame_descr, &p, 10); CHECK_GT(n_objects, 0); Printf(" This frame has %zu object(s):\n", n_objects); + // Report all objects in this frame. + InternalScopedBuffer<StackVarDescr> vars(n_objects); for (uptr i = 0; i < n_objects; i++) { uptr beg, size; - sptr len; - beg = internal_simple_strtoll(p, &p, 10); - size = internal_simple_strtoll(p, &p, 10); - len = internal_simple_strtoll(p, &p, 10); - if (beg <= 0 || size <= 0 || len < 0 || *p != ' ') { + uptr len; + beg = (uptr)internal_simple_strtoll(p, &p, 10); + size = (uptr)internal_simple_strtoll(p, &p, 10); + len = (uptr)internal_simple_strtoll(p, &p, 10); + if (beg == 0 || size == 0 || *p != ' ') { Printf("AddressSanitizer can't parse the stack frame " "descriptor: |%s|\n", frame_descr); break; } p++; - buf[0] = 0; - internal_strncat(buf, p, Min(kBufSize, len)); + vars[i].beg = beg; + vars[i].size = size; + vars[i].name_pos = p; + vars[i].name_len = len; p += len; - Printf(" [%zu, %zu) '%s'\n", beg, beg + size, buf); + } + for (uptr i = 0; i < n_objects; i++) { + buf[0] = 0; + internal_strncat(buf, vars[i].name_pos, + static_cast<uptr>(Min(kBufSize, vars[i].name_len))); + 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(buf, vars[i].beg, vars[i].size, + 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 or swapcontext\n" " (longjmp and C++ exceptions *are* supported)\n"); - DescribeThread(t->context()); + DescribeThread(t); return true; } @@ -360,7 +415,11 @@ static void DescribeAccessToHeapChunk(AsanChunkView chunk, uptr addr, void DescribeHeapAddress(uptr addr, uptr access_size) { AsanChunkView chunk = FindHeapChunkByAddress(addr); - if (!chunk.IsValid()) return; + if (!chunk.IsValid()) { + Printf("AddressSanitizer can not describe address in more detail " + "(wild memory access suspected).\n"); + return; + } DescribeAccessToHeapChunk(chunk, addr, access_size); CHECK(chunk.AllocTid() != kInvalidTid); asanThreadRegistry().CheckLocked(); @@ -368,13 +427,11 @@ void DescribeHeapAddress(uptr addr, uptr access_size) { GetThreadContextByTidLocked(chunk.AllocTid()); StackTrace alloc_stack; chunk.GetAllocStack(&alloc_stack); - AsanThread *t = GetCurrentThread(); - CHECK(t); char tname[128]; Decorator d; + AsanThreadContext *free_thread = 0; if (chunk.FreeTid() != kInvalidTid) { - AsanThreadContext *free_thread = - GetThreadContextByTidLocked(chunk.FreeTid()); + free_thread = GetThreadContextByTidLocked(chunk.FreeTid()); Printf("%sfreed by thread T%d%s here:%s\n", d.Allocation(), free_thread->tid, ThreadNameWithParenthesis(free_thread, tname, sizeof(tname)), @@ -386,19 +443,17 @@ void DescribeHeapAddress(uptr addr, uptr access_size) { d.Allocation(), alloc_thread->tid, ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)), d.EndAllocation()); - PrintStack(&alloc_stack); - DescribeThread(t->context()); - DescribeThread(free_thread); - DescribeThread(alloc_thread); } else { Printf("%sallocated by thread T%d%s here:%s\n", d.Allocation(), alloc_thread->tid, ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)), d.EndAllocation()); - PrintStack(&alloc_stack); - DescribeThread(t->context()); - DescribeThread(alloc_thread); } + PrintStack(&alloc_stack); + DescribeThread(GetCurrentThread()); + if (free_thread) + DescribeThread(free_thread); + DescribeThread(alloc_thread); } void DescribeAddress(uptr addr, uptr access_size) { @@ -431,7 +486,9 @@ void DescribeThread(AsanThreadContext *context) { context->parent_tid, ThreadNameWithParenthesis(context->parent_tid, tname, sizeof(tname))); - PrintStack(&context->stack); + uptr stack_size; + const uptr *stack_trace = StackDepotGet(context->stack_id, &stack_size); + PrintStack(stack_trace, stack_size); // Recursively described parent thread if needed. if (flags()->print_full_thread_history) { AsanThreadContext *parent_context = @@ -476,21 +533,11 @@ class ScopedInErrorReport { reporting_thread_tid = GetCurrentTidOrInvalid(); Printf("====================================================" "=============\n"); - if (reporting_thread_tid != kInvalidTid) { - // We started reporting an error message. Stop using the fake stack - // in case we call an instrumented function from a symbolizer. - AsanThread *curr_thread = GetCurrentThread(); - CHECK(curr_thread); - curr_thread->fake_stack().StopUsingFakeStack(); - } } // Destructor is NORETURN, as functions that report errors are. NORETURN ~ScopedInErrorReport() { // Make sure the current thread is announced. - AsanThread *curr_thread = GetCurrentThread(); - if (curr_thread) { - DescribeThread(curr_thread->context()); - } + DescribeThread(GetCurrentThread()); // Print memory stats. if (flags()->print_stats) __asan_print_accumulated_stats(); @@ -502,22 +549,6 @@ class ScopedInErrorReport { } }; -static void ReportSummary(const char *error_type, StackTrace *stack) { - if (!stack->size) return; - if (IsSymbolizerAvailable()) { - AddressInfo ai; - // Currently, we include the first stack frame into the report summary. - // Maybe sometimes we need to choose another frame (e.g. skip memcpy/etc). - uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]); - SymbolizeCode(pc, &ai, 1); - ReportErrorSummary(error_type, - StripPathPrefix(ai.file, - common_flags()->strip_path_prefix), - ai.line, ai.function); - } - // FIXME: do we need to print anything at all if there is no symbolizer? -} - void ReportSIGSEGV(uptr pc, uptr sp, uptr bp, uptr addr) { ScopedInErrorReport in_report; Decorator d; @@ -527,13 +558,13 @@ void ReportSIGSEGV(uptr pc, uptr sp, uptr bp, uptr addr) { (void*)addr, (void*)pc, (void*)sp, (void*)bp, GetCurrentTidOrInvalid()); Printf("%s", d.EndWarning()); - Printf("AddressSanitizer can not provide additional info.\n"); GET_STACK_TRACE_FATAL(pc, bp); PrintStack(&stack); - ReportSummary("SEGV", &stack); + Printf("AddressSanitizer can not provide additional info.\n"); + ReportErrorSummary("SEGV", &stack); } -void ReportDoubleFree(uptr addr, StackTrace *stack) { +void ReportDoubleFree(uptr addr, StackTrace *free_stack) { ScopedInErrorReport in_report; Decorator d; Printf("%s", d.Warning()); @@ -543,14 +574,15 @@ void ReportDoubleFree(uptr addr, StackTrace *stack) { "thread T%d%s:\n", addr, curr_tid, ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname))); - Printf("%s", d.EndWarning()); - PrintStack(stack); + CHECK_GT(free_stack->size, 0); + GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp); + PrintStack(&stack); DescribeHeapAddress(addr, 1); - ReportSummary("double-free", stack); + ReportErrorSummary("double-free", &stack); } -void ReportFreeNotMalloced(uptr addr, StackTrace *stack) { +void ReportFreeNotMalloced(uptr addr, StackTrace *free_stack) { ScopedInErrorReport in_report; Decorator d; Printf("%s", d.Warning()); @@ -560,12 +592,14 @@ void ReportFreeNotMalloced(uptr addr, StackTrace *stack) { "which was not malloc()-ed: %p in thread T%d%s\n", addr, curr_tid, ThreadNameWithParenthesis(curr_tid, tname, sizeof(tname))); Printf("%s", d.EndWarning()); - PrintStack(stack); + CHECK_GT(free_stack->size, 0); + GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp); + PrintStack(&stack); DescribeHeapAddress(addr, 1); - ReportSummary("bad-free", stack); + ReportErrorSummary("bad-free", &stack); } -void ReportAllocTypeMismatch(uptr addr, StackTrace *stack, +void ReportAllocTypeMismatch(uptr addr, StackTrace *free_stack, AllocType alloc_type, AllocType dealloc_type) { static const char *alloc_names[] = @@ -579,9 +613,11 @@ void ReportAllocTypeMismatch(uptr addr, StackTrace *stack, Report("ERROR: AddressSanitizer: alloc-dealloc-mismatch (%s vs %s) on %p\n", alloc_names[alloc_type], dealloc_names[dealloc_type], addr); Printf("%s", d.EndWarning()); - PrintStack(stack); + CHECK_GT(free_stack->size, 0); + GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp); + PrintStack(&stack); DescribeHeapAddress(addr, 1); - ReportSummary("alloc-dealloc-mismatch", stack); + ReportErrorSummary("alloc-dealloc-mismatch", &stack); Report("HINT: if you don't care about these warnings you may set " "ASAN_OPTIONS=alloc_dealloc_mismatch=0\n"); } @@ -596,7 +632,7 @@ void ReportMallocUsableSizeNotOwned(uptr addr, StackTrace *stack) { Printf("%s", d.EndWarning()); PrintStack(stack); DescribeHeapAddress(addr, 1); - ReportSummary("bad-malloc_usable_size", stack); + ReportErrorSummary("bad-malloc_usable_size", stack); } void ReportAsanGetAllocatedSizeNotOwned(uptr addr, StackTrace *stack) { @@ -609,7 +645,7 @@ void ReportAsanGetAllocatedSizeNotOwned(uptr addr, StackTrace *stack) { Printf("%s", d.EndWarning()); PrintStack(stack); DescribeHeapAddress(addr, 1); - ReportSummary("bad-__asan_get_allocated_size", stack); + ReportErrorSummary("bad-__asan_get_allocated_size", stack); } void ReportStringFunctionMemoryRangesOverlap( @@ -627,7 +663,7 @@ void ReportStringFunctionMemoryRangesOverlap( PrintStack(stack); DescribeAddress((uptr)offset1, length1); DescribeAddress((uptr)offset2, length2); - ReportSummary(bug_type, stack); + ReportErrorSummary(bug_type, stack); } // ----------------------- Mac-specific reports ----------------- {{{1 @@ -737,7 +773,7 @@ void __asan_report_error(uptr pc, uptr bp, uptr sp, PrintStack(&stack); DescribeAddress(addr, access_size); - ReportSummary(bug_descr, &stack); + ReportErrorSummary(bug_descr, &stack); PrintShadowMemoryForAddress(addr); } @@ -758,6 +794,6 @@ void __asan_describe_address(uptr addr) { #if !SANITIZER_SUPPORTS_WEAK_HOOKS // Provide default implementation of __asan_on_error that does nothing // and may be overriden by user. -SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE NOINLINE +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE NOINLINE void __asan_on_error() {} #endif diff --git a/lib/asan/asan_report.h b/lib/asan/asan_report.h index db271fc10e97..f55b57bd4d9f 100644 --- a/lib/asan/asan_report.h +++ b/lib/asan/asan_report.h @@ -33,9 +33,9 @@ void DescribeThread(AsanThreadContext *context); // Different kinds of error reports. void NORETURN ReportSIGSEGV(uptr pc, uptr sp, uptr bp, uptr addr); -void NORETURN ReportDoubleFree(uptr addr, StackTrace *stack); -void NORETURN ReportFreeNotMalloced(uptr addr, StackTrace *stack); -void NORETURN ReportAllocTypeMismatch(uptr addr, StackTrace *stack, +void NORETURN ReportDoubleFree(uptr addr, StackTrace *free_stack); +void NORETURN ReportFreeNotMalloced(uptr addr, StackTrace *free_stack); +void NORETURN ReportAllocTypeMismatch(uptr addr, StackTrace *free_stack, AllocType alloc_type, AllocType dealloc_type); void NORETURN ReportMallocUsableSizeNotOwned(uptr addr, diff --git a/lib/asan/asan_rtl.cc b/lib/asan/asan_rtl.cc index f989c5c0d2a5..11f05954d31e 100644 --- a/lib/asan/asan_rtl.cc +++ b/lib/asan/asan_rtl.cc @@ -13,6 +13,7 @@ //===----------------------------------------------------------------------===// #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" @@ -26,6 +27,8 @@ #include "sanitizer_common/sanitizer_symbolizer.h" #include "lsan/lsan_common.h" +int __asan_option_detect_stack_use_after_return; // Global interface symbol. + namespace __asan { uptr AsanMappingProfile[kAsanMappingProfileSize]; @@ -89,7 +92,6 @@ static void ParseFlagsFromString(Flags *f, const char *str) { CHECK((uptr)common_flags()->malloc_context_size <= kStackTraceMax); ParseFlag(str, &f->quarantine_size, "quarantine_size"); - ParseFlag(str, &f->verbosity, "verbosity"); ParseFlag(str, &f->redzone, "redzone"); CHECK_GE(f->redzone, 16); CHECK(IsPowerOfTwo(f->redzone)); @@ -101,7 +103,9 @@ static void ParseFlagsFromString(Flags *f, const char *str) { ParseFlag(str, &f->replace_str, "replace_str"); ParseFlag(str, &f->replace_intrin, "replace_intrin"); ParseFlag(str, &f->mac_ignore_invalid_free, "mac_ignore_invalid_free"); - ParseFlag(str, &f->use_fake_stack, "use_fake_stack"); + ParseFlag(str, &f->detect_stack_use_after_return, + "detect_stack_use_after_return"); + ParseFlag(str, &f->uar_stack_size_log, "uar_stack_size_log"); ParseFlag(str, &f->max_malloc_fill_size, "max_malloc_fill_size"); ParseFlag(str, &f->malloc_fill_byte, "malloc_fill_byte"); ParseFlag(str, &f->exitcode, "exitcode"); @@ -116,30 +120,25 @@ static void ParseFlagsFromString(Flags *f, const char *str) { ParseFlag(str, &f->print_stats, "print_stats"); ParseFlag(str, &f->print_legend, "print_legend"); ParseFlag(str, &f->atexit, "atexit"); + ParseFlag(str, &f->coverage, "coverage"); ParseFlag(str, &f->disable_core, "disable_core"); ParseFlag(str, &f->allow_reexec, "allow_reexec"); ParseFlag(str, &f->print_full_thread_history, "print_full_thread_history"); - ParseFlag(str, &f->log_path, "log_path"); ParseFlag(str, &f->poison_heap, "poison_heap"); + ParseFlag(str, &f->poison_partial, "poison_partial"); ParseFlag(str, &f->alloc_dealloc_mismatch, "alloc_dealloc_mismatch"); - ParseFlag(str, &f->use_stack_depot, "use_stack_depot"); ParseFlag(str, &f->strict_memcmp, "strict_memcmp"); ParseFlag(str, &f->strict_init_order, "strict_init_order"); - ParseFlag(str, &f->detect_leaks, "detect_leaks"); } void InitializeFlags(Flags *f, const char *env) { CommonFlags *cf = common_flags(); + SetCommonFlagDefaults(); cf->external_symbolizer_path = GetEnv("ASAN_SYMBOLIZER_PATH"); - cf->symbolize = true; cf->malloc_context_size = kDefaultMallocContextSize; - cf->fast_unwind_on_fatal = false; - cf->fast_unwind_on_malloc = true; - cf->strip_path_prefix = ""; internal_memset(f, 0, sizeof(*f)); f->quarantine_size = (ASAN_LOW_MEMORY) ? 1UL << 26 : 1UL << 28; - f->verbosity = 0; f->redzone = 16; f->debug = false; f->report_globals = 1; @@ -147,7 +146,8 @@ void InitializeFlags(Flags *f, const char *env) { f->replace_str = true; f->replace_intrin = true; f->mac_ignore_invalid_free = false; - f->use_fake_stack = true; + f->detect_stack_use_after_return = false; // Also needs the compiler flag. + f->uar_stack_size_log = 0; f->max_malloc_fill_size = 0x1000; // By default, fill only the first 4K. f->malloc_fill_byte = 0xbe; f->exitcode = ASAN_DEFAULT_FAILURE_EXITCODE; @@ -162,25 +162,24 @@ void InitializeFlags(Flags *f, const char *env) { f->print_stats = false; f->print_legend = true; f->atexit = false; + f->coverage = false; f->disable_core = (SANITIZER_WORDSIZE == 64); f->allow_reexec = true; f->print_full_thread_history = true; - f->log_path = 0; f->poison_heap = true; - // Turn off alloc/dealloc mismatch checker on Mac for now. - // TODO(glider): Fix known issues and enable this back. - f->alloc_dealloc_mismatch = (SANITIZER_MAC == 0);; - f->use_stack_depot = true; + f->poison_partial = true; + // Turn off alloc/dealloc mismatch checker on Mac and Windows for now. + // TODO(glider,timurrrr): Fix known issues and enable this back. + f->alloc_dealloc_mismatch = (SANITIZER_MAC == 0) && (SANITIZER_WINDOWS == 0); f->strict_memcmp = true; f->strict_init_order = false; - f->detect_leaks = false; // Override from compile definition. ParseFlagsFromString(f, MaybeUseAsanDefaultOptionsCompileDefiniton()); // Override from user-specified string. ParseFlagsFromString(f, MaybeCallAsanDefaultOptions()); - if (flags()->verbosity) { + if (common_flags()->verbosity) { Report("Using the defaults from __asan_default_options: %s\n", MaybeCallAsanDefaultOptions()); } @@ -189,17 +188,17 @@ void InitializeFlags(Flags *f, const char *env) { ParseFlagsFromString(f, env); #if !CAN_SANITIZE_LEAKS - if (f->detect_leaks) { + if (cf->detect_leaks) { Report("%s: detect_leaks is not supported on this platform.\n", SanitizerToolName); - f->detect_leaks = false; + cf->detect_leaks = false; } #endif - if (f->detect_leaks && !f->use_stack_depot) { - Report("%s: detect_leaks is ignored (requires use_stack_depot).\n", - SanitizerToolName); - f->detect_leaks = false; + // 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; } } @@ -305,8 +304,6 @@ static NOINLINE void force_interface_symbols() { case 25: __asan_poison_memory_region(0, 0); break; case 26: __asan_unpoison_memory_region(0, 0); break; case 27: __asan_set_error_exit_code(0); break; - case 28: __asan_stack_free(0, 0, 0); break; - case 29: __asan_stack_malloc(0, 0); break; case 30: __asan_before_dynamic_init(0); break; case 31: __asan_after_dynamic_init(); break; case 32: __asan_poison_stack_memory(0, 0); break; @@ -328,22 +325,12 @@ static void asan_atexit() { static void InitializeHighMemEnd() { #if !ASAN_FIXED_MAPPING -#if SANITIZER_WORDSIZE == 64 -# if defined(__powerpc64__) - // FIXME: - // On PowerPC64 we have two different address space layouts: 44- and 46-bit. - // We somehow need to figure our which one we are using now and choose - // one of 0x00000fffffffffffUL and 0x00003fffffffffffUL. - // Note that with 'ulimit -s unlimited' the stack is moved away from the top - // of the address space, so simply checking the stack address is not enough. - kHighMemEnd = (1ULL << 44) - 1; // 0x00000fffffffffffUL -# else - kHighMemEnd = (1ULL << 47) - 1; // 0x00007fffffffffffUL; -# endif -#else // SANITIZER_WORDSIZE == 32 - kHighMemEnd = (1ULL << 32) - 1; // 0xffffffff; -#endif // SANITIZER_WORDSIZE + kHighMemEnd = GetMaxVirtualAddress(); + // Increase kHighMemEnd to make sure it's properly + // aligned together with kHighMemBeg: + kHighMemEnd |= SHADOW_GRANULARITY * GetPageSizeCached() - 1; #endif // !ASAN_FIXED_MAPPING + CHECK_EQ((kHighMemBeg % GetPageSizeCached()), 0); } static void ProtectGap(uptr a, uptr size) { @@ -385,6 +372,7 @@ static void PrintAddressSpaceLayout() { } Printf("\n"); Printf("red_zone=%zu\n", (uptr)flags()->redzone); + Printf("quarantine_size=%zuM\n", (uptr)flags()->quarantine_size >> 20); Printf("malloc_context_size=%zu\n", (uptr)common_flags()->malloc_context_size); @@ -405,7 +393,7 @@ using namespace __asan; // NOLINT #if !SANITIZER_SUPPORTS_WEAK_HOOKS extern "C" { -SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE const char* __asan_default_options() { return ""; } } // extern "C" #endif @@ -438,6 +426,8 @@ void NOINLINE __asan_handle_no_return() { return; } PoisonShadow(bottom, top - bottom, 0); + if (curr_thread->has_fake_stack()) + curr_thread->fake_stack()->HandleNoReturn(); } void NOINLINE __asan_set_death_callback(void (*callback)(void)) { @@ -463,9 +453,11 @@ void __asan_init() { // initialization steps look at flags(). const char *options = GetEnv("ASAN_OPTIONS"); InitializeFlags(flags(), options); - __sanitizer_set_report_path(flags()->log_path); + __sanitizer_set_report_path(common_flags()->log_path); + __asan_option_detect_stack_use_after_return = + flags()->detect_stack_use_after_return; - if (flags()->verbosity && options) { + if (common_flags()->verbosity && options) { Report("Parsed ASAN_OPTIONS: %s\n", options); } @@ -475,21 +467,16 @@ void __asan_init() { // Setup internal allocator callback. SetLowLevelAllocateCallback(OnLowLevelAllocate); - if (flags()->atexit) { - Atexit(asan_atexit); - } - - // interceptors InitializeAsanInterceptors(); ReplaceSystemMalloc(); ReplaceOperatorsNewAndDelete(); uptr shadow_start = kLowShadowBeg; - if (kLowShadowBeg) shadow_start -= GetMmapGranularity(); - uptr shadow_end = kHighShadowEnd; + if (kLowShadowBeg) + shadow_start -= GetMmapGranularity(); bool full_shadow_is_available = - MemoryRangeIsAvailable(shadow_start, shadow_end); + MemoryRangeIsAvailable(shadow_start, kHighShadowEnd); #if SANITIZER_LINUX && defined(__x86_64__) && !ASAN_FIXED_MAPPING if (!full_shadow_is_available) { @@ -498,7 +485,7 @@ void __asan_init() { } #endif - if (flags()->verbosity) + if (common_flags()->verbosity) PrintAddressSpaceLayout(); if (flags()->disable_core) { @@ -515,7 +502,7 @@ void __asan_init() { ProtectGap(kShadowGapBeg, kShadowGapEnd - kShadowGapBeg + 1); } else if (kMidMemBeg && MemoryRangeIsAvailable(shadow_start, kMidMemBeg - 1) && - MemoryRangeIsAvailable(kMidMemEnd + 1, shadow_end)) { + MemoryRangeIsAvailable(kMidMemEnd + 1, kHighShadowEnd)) { CHECK(kLowShadowBeg != kLowShadowEnd); // mmap the low shadow plus at least one page at the left. ReserveShadowMemoryRange(shadow_start, kLowShadowEnd); @@ -534,12 +521,18 @@ void __asan_init() { Die(); } + AsanTSDInit(PlatformTSDDtor); InstallSignalHandlers(); + + // Allocator should be initialized before starting external symbolizer, as + // fork() on Mac locks the allocator. + InitializeAllocator(); + // Start symbolizer process if necessary. - const char* external_symbolizer = common_flags()->external_symbolizer_path; - if (common_flags()->symbolize && external_symbolizer && - external_symbolizer[0]) { - InitializeExternalSymbolizer(external_symbolizer); + if (common_flags()->symbolize) { + Symbolizer::Init(common_flags()->external_symbolizer_path); + } else { + Symbolizer::Disable(); } // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited @@ -547,8 +540,16 @@ void __asan_init() { asan_inited = 1; asan_init_is_running = false; + if (flags()->atexit) + Atexit(asan_atexit); + + if (flags()->coverage) + Atexit(__sanitizer_cov_dump); + + // interceptors + InitTlsSize(); + // Create main thread. - AsanTSDInit(AsanThread::TSDDtor); AsanThread *main_thread = AsanThread::Create(0, 0); CreateThreadContextArgs create_main_args = { main_thread, 0 }; u32 main_tid = asanThreadRegistry().CreateThread( @@ -558,16 +559,14 @@ void __asan_init() { main_thread->ThreadStart(internal_getpid()); force_interface_symbols(); // no-op. - InitializeAllocator(); - #if CAN_SANITIZE_LEAKS __lsan::InitCommonLsan(); - if (flags()->detect_leaks) { + if (common_flags()->detect_leaks && common_flags()->leak_check_at_exit) { Atexit(__lsan::DoLeakCheck); } #endif // CAN_SANITIZE_LEAKS - if (flags()->verbosity) { + if (common_flags()->verbosity) { Report("AddressSanitizer Init done\n"); } } diff --git a/lib/asan/asan_stack.cc b/lib/asan/asan_stack.cc index 21dae7df096a..0bc5a5f2d036 100644 --- a/lib/asan/asan_stack.cc +++ b/lib/asan/asan_stack.cc @@ -24,9 +24,12 @@ static bool MaybeCallAsanSymbolize(const void *pc, char *out_buffer, : false; } +void PrintStack(const uptr *trace, uptr size) { + StackTrace::PrintStack(trace, size, MaybeCallAsanSymbolize); +} + void PrintStack(StackTrace *stack) { - stack->PrintStack(stack->trace, stack->size, common_flags()->symbolize, - common_flags()->strip_path_prefix, MaybeCallAsanSymbolize); + PrintStack(stack->trace, stack->size); } } // namespace __asan @@ -37,7 +40,7 @@ void PrintStack(StackTrace *stack) { // and may be overriden by user if he wants to use his own symbolization. // ASan on Windows has its own implementation of this. #if !SANITIZER_WINDOWS && !SANITIZER_SUPPORTS_WEAK_HOOKS -SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE NOINLINE +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE NOINLINE bool __asan_symbolize(const void *pc, char *out_buffer, int out_size) { return false; } diff --git a/lib/asan/asan_stack.h b/lib/asan/asan_stack.h index 176aa183c93b..7f5fd661eec8 100644 --- a/lib/asan/asan_stack.h +++ b/lib/asan/asan_stack.h @@ -22,6 +22,7 @@ namespace __asan { void PrintStack(StackTrace *stack); +void PrintStack(const uptr *trace, uptr size); } // namespace __asan @@ -29,21 +30,21 @@ void PrintStack(StackTrace *stack); // 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. #if SANITIZER_WINDOWS -#define GET_STACK_TRACE_WITH_PC_AND_BP(max_s, pc, bp, fast) \ - StackTrace stack; \ - GetStackTrace(&stack, max_s, pc, bp, 0, 0, fast) +#define GET_STACK_TRACE_WITH_PC_AND_BP(max_s, pc, bp, fast) \ + StackTrace stack; \ + stack.Unwind(max_s, pc, bp, 0, 0, fast) #else -#define GET_STACK_TRACE_WITH_PC_AND_BP(max_s, pc, bp, fast) \ - StackTrace stack; \ - { \ - uptr stack_top = 0, stack_bottom = 0; \ - AsanThread *t; \ - if (asan_inited && (t = GetCurrentThread())) { \ - stack_top = t->stack_top(); \ - stack_bottom = t->stack_bottom(); \ - } \ - GetStackTrace(&stack, max_s, pc, bp, \ - stack_top, stack_bottom, fast); \ +#define GET_STACK_TRACE_WITH_PC_AND_BP(max_s, pc, bp, fast) \ + StackTrace stack; \ + { \ + AsanThread *t; \ + stack.size = 0; \ + if (asan_inited && (t = GetCurrentThread()) && !t->isUnwinding()) { \ + uptr stack_top = t->stack_top(); \ + uptr stack_bottom = t->stack_bottom(); \ + ScopedUnwinding unwind_scope(t); \ + stack.Unwind(max_s, pc, bp, stack_top, stack_bottom, fast); \ + } \ } #endif // SANITIZER_WINDOWS diff --git a/lib/asan/asan_stats.cc b/lib/asan/asan_stats.cc index ba7c1ab6e91a..73dc3c5ac44f 100644 --- a/lib/asan/asan_stats.cc +++ b/lib/asan/asan_stats.cc @@ -21,6 +21,10 @@ namespace __asan { AsanStats::AsanStats() { + Clear(); +} + +void AsanStats::Clear() { CHECK(REAL(memset)); REAL(memset)(this, 0, sizeof(AsanStats)); } @@ -54,77 +58,63 @@ void AsanStats::Print() { malloc_large, malloc_small_slow); } -static BlockingMutex print_lock(LINKER_INITIALIZED); - -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 mapped\n", - stack_depot_stats->n_uniq_ids, stack_depot_stats->mapped >> 20); - PrintInternalAllocatorStats(); +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 accumulated_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 BlockingMutex acc_stats_lock(LINKER_INITIALIZED); - -static void FlushToAccumulatedStatsUnlocked(AsanStats *stats) { - acc_stats_lock.CheckLocked(); - uptr *dst = (uptr*)&accumulated_stats; - uptr *src = (uptr*)stats; - uptr num_fields = sizeof(*stats) / sizeof(uptr); - for (uptr i = 0; i < num_fields; i++) { - dst[i] += src[i]; - src[i] = 0; - } -} -static void FlushThreadStats(ThreadContextBase *tctx_base, void *arg) { +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) - FlushToAccumulatedStatsUnlocked(&t->stats()); + accumulated_stats->MergeFrom(&t->stats()); } -static void UpdateAccumulatedStatsUnlocked() { - acc_stats_lock.CheckLocked(); +static void GetAccumulatedStats(AsanStats *stats) { + stats->Clear(); { ThreadRegistryLock l(&asanThreadRegistry()); - asanThreadRegistry().RunCallbackForEachThreadLocked(FlushThreadStats, 0); + asanThreadRegistry() + .RunCallbackForEachThreadLocked(MergeThreadStats, stats); + } + stats->MergeFrom(&unknown_thread_stats); + { + BlockingMutexLock lock(&dead_threads_stats_lock); + stats->MergeFrom(&dead_threads_stats); } - FlushToAccumulatedStatsUnlocked(&unknown_thread_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 < accumulated_stats.malloced) { - max_malloced_memory = accumulated_stats.malloced; + if (max_malloced_memory < stats->malloced) { + max_malloced_memory = stats->malloced; } } -void FlushToAccumulatedStats(AsanStats *stats) { - BlockingMutexLock lock(&acc_stats_lock); - FlushToAccumulatedStatsUnlocked(stats); -} - -void GetAccumulatedStats(AsanStats *stats) { - BlockingMutexLock lock(&acc_stats_lock); - UpdateAccumulatedStatsUnlocked(); - internal_memcpy(stats, &accumulated_stats, sizeof(accumulated_stats)); +void FlushToDeadThreadStats(AsanStats *stats) { + BlockingMutexLock lock(&dead_threads_stats_lock); + dead_threads_stats.MergeFrom(stats); + stats->Clear(); } void FillMallocStatistics(AsanMallocStats *malloc_stats) { - BlockingMutexLock lock(&acc_stats_lock); - UpdateAccumulatedStatsUnlocked(); - malloc_stats->blocks_in_use = accumulated_stats.mallocs; - malloc_stats->size_in_use = accumulated_stats.malloced; + 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 = accumulated_stats.mmaped; + malloc_stats->size_allocated = stats.mmaped; } AsanStats &GetCurrentThreadStats() { @@ -132,36 +122,48 @@ AsanStats &GetCurrentThreadStats() { 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 mapped\n", + stack_depot_stats->n_uniq_ids, stack_depot_stats->mapped >> 20); + PrintInternalAllocatorStats(); +} + } // namespace __asan // ---------------------- Interface ---------------- {{{1 using namespace __asan; // NOLINT uptr __asan_get_current_allocated_bytes() { - BlockingMutexLock lock(&acc_stats_lock); - UpdateAccumulatedStatsUnlocked(); - uptr malloced = accumulated_stats.malloced; - uptr freed = accumulated_stats.freed; + 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 __asan_get_heap_size() { - BlockingMutexLock lock(&acc_stats_lock); - UpdateAccumulatedStatsUnlocked(); - return accumulated_stats.mmaped - accumulated_stats.munmaped; + AsanStats stats; + GetAccumulatedStats(&stats); + return stats.mmaped - stats.munmaped; } uptr __asan_get_free_bytes() { - BlockingMutexLock lock(&acc_stats_lock); - UpdateAccumulatedStatsUnlocked(); - uptr total_free = accumulated_stats.mmaped - - accumulated_stats.munmaped - + accumulated_stats.really_freed - + accumulated_stats.really_freed_redzones; - uptr total_used = accumulated_stats.malloced - + accumulated_stats.malloced_redzones; + AsanStats stats; + GetAccumulatedStats(&stats); + uptr total_free = stats.mmaped + - stats.munmaped + + stats.really_freed + + stats.really_freed_redzones; + 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; diff --git a/lib/asan/asan_stats.h b/lib/asan/asan_stats.h index 68495fb33f95..e3030e88fdc2 100644 --- a/lib/asan/asan_stats.h +++ b/lib/asan/asan_stats.h @@ -52,18 +52,16 @@ struct AsanStats { // Default ctor for thread-local stats. AsanStats(); - // Prints formatted stats to stderr. - void Print(); + 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 all thread-local stats to accumulated stats, and makes -// a copy of accumulated stats. -void GetAccumulatedStats(AsanStats *stats); -// Flushes a given stats into accumulated stats. -void FlushToAccumulatedStats(AsanStats *stats); +// 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 { diff --git a/lib/asan/asan_thread.cc b/lib/asan/asan_thread.cc index da28381031a5..328ac2fcd398 100644 --- a/lib/asan/asan_thread.cc +++ b/lib/asan/asan_thread.cc @@ -19,6 +19,7 @@ #include "asan_mapping.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_placement_new.h" +#include "sanitizer_common/sanitizer_stackdepot.h" #include "lsan/lsan_common.h" namespace __asan { @@ -27,9 +28,8 @@ namespace __asan { void AsanThreadContext::OnCreated(void *arg) { CreateThreadContextArgs *args = static_cast<CreateThreadContextArgs*>(arg); - if (args->stack) { - internal_memcpy(&stack, args->stack, sizeof(stack)); - } + if (args->stack) + stack_id = StackDepotPut(args->stack->trace, args->stack->size); thread = args->thread; thread->set_context(this); } @@ -39,12 +39,16 @@ void AsanThreadContext::OnFinished() { thread = 0; } -static char thread_registry_placeholder[sizeof(ThreadRegistry)]; +// 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) { - void *mem = MmapOrDie(sizeof(AsanThreadContext), "AsanThreadContext"); - return new(mem) AsanThreadContext(tid); + BlockingMutexLock lock(&mu_for_thread_context); + return new(allocator_for_thread_context) AsanThreadContext(tid); } ThreadRegistry &asanThreadRegistry() { @@ -84,40 +88,68 @@ AsanThread *AsanThread::Create(thread_callback_t start_routine, void AsanThread::TSDDtor(void *tsd) { AsanThreadContext *context = (AsanThreadContext*)tsd; - if (flags()->verbosity >= 1) + if (common_flags()->verbosity >= 1) Report("T%d TSDDtor\n", context->tid); if (context->thread) context->thread->Destroy(); } void AsanThread::Destroy() { - if (flags()->verbosity >= 1) { + if (common_flags()->verbosity >= 1) { Report("T%d exited\n", tid()); } + malloc_storage().CommitBack(); + if (flags()->use_sigaltstack) UnsetAlternateSignalStack(); asanThreadRegistry().FinishThread(tid()); - FlushToAccumulatedStats(&stats_); + 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. - ClearShadowForThreadStack(); - fake_stack().Cleanup(); + ClearShadowForThreadStackAndTLS(); + DeleteFakeStack(); uptr size = RoundUpTo(sizeof(AsanThread), GetPageSizeCached()); UnmapOrDie(this, size); } +// 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 0; + 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 successfull, it initilizes 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)); + if (flags()->uar_stack_size_log) + stack_size_log = static_cast<uptr>(flags()->uar_stack_size_log); + fake_stack_ = FakeStack::Create(stack_size_log); + SetTLSFakeStack(fake_stack_); + return fake_stack_; + } + return 0; +} + void AsanThread::Init() { - SetThreadStackTopAndBottom(); + SetThreadStackAndTls(); CHECK(AddrIsInMem(stack_bottom_)); CHECK(AddrIsInMem(stack_top_ - 1)); - ClearShadowForThreadStack(); - if (flags()->verbosity >= 1) { + ClearShadowForThreadStackAndTLS(); + if (common_flags()->verbosity >= 1) { int local = 0; Report("T%d: stack [%p,%p) size 0x%zx; local=%p\n", tid(), (void*)stack_bottom_, (void*)stack_top_, stack_top_ - stack_bottom_, &local); } - fake_stack_.Init(stack_size()); + fake_stack_ = 0; // Will be initialized lazily if needed. AsanPlatformThreadInit(); } @@ -135,22 +167,33 @@ thread_return_t AsanThread::ThreadStart(uptr os_id) { } thread_return_t res = start_routine_(arg_); - malloc_storage().CommitBack(); - if (flags()->use_sigaltstack) UnsetAlternateSignalStack(); - this->Destroy(); + // 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; } -void AsanThread::SetThreadStackTopAndBottom() { - GetThreadStackTopAndBottom(tid() == 0, &stack_top_, &stack_bottom_); +void AsanThread::SetThreadStackAndTls() { + uptr tls_size = 0; + GetThreadStackAndTls(tid() == 0, &stack_bottom_, &stack_size_, &tls_begin_, + &tls_size); + stack_top_ = stack_bottom_ + stack_size_; + tls_end_ = tls_begin_ + tls_size; + int local; CHECK(AddrIsInStack((uptr)&local)); } -void AsanThread::ClearShadowForThreadStack() { +void AsanThread::ClearShadowForThreadStackAndTLS() { PoisonShadow(stack_bottom_, stack_top_ - stack_bottom_, 0); + if (tls_begin_ != tls_end_) + PoisonShadow(tls_begin_, tls_end_ - tls_begin_, 0); } const char *AsanThread::GetFrameNameByAddr(uptr addr, uptr *offset, @@ -158,8 +201,8 @@ const char *AsanThread::GetFrameNameByAddr(uptr addr, uptr *offset, uptr bottom = 0; if (AddrIsInStack(addr)) { bottom = stack_bottom(); - } else { - bottom = fake_stack().AddrIsInFakeStack(addr); + } else if (has_fake_stack()) { + bottom = fake_stack()->AddrIsInFakeStack(addr); CHECK(bottom); *offset = addr - bottom; *frame_pc = ((uptr*)bottom)[2]; @@ -195,13 +238,16 @@ static bool ThreadStackContainsAddress(ThreadContextBase *tctx_base, void *addr) { AsanThreadContext *tctx = static_cast<AsanThreadContext*>(tctx_base); AsanThread *t = tctx->thread; - return (t && t->fake_stack().StackSize() && - (t->fake_stack().AddrIsInFakeStack((uptr)addr) || - t->AddrIsInStack((uptr)addr))); + 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() { - AsanThreadContext *context = (AsanThreadContext*)AsanTSDGet(); + AsanThreadContext *context = + reinterpret_cast<AsanThreadContext *>(AsanTSDGet()); if (!context) { if (SANITIZER_ANDROID) { // On Android, libc constructor is called _after_ asan_init, and cleans up @@ -222,7 +268,7 @@ AsanThread *GetCurrentThread() { void SetCurrentThread(AsanThread *t) { CHECK(t->context()); - if (flags()->verbosity >= 2) { + if (common_flags()->verbosity >= 2) { Report("SetCurrentThread: %p for thread %p\n", t->context(), (void*)GetThreadSelf()); } @@ -244,6 +290,20 @@ AsanThread *FindThreadByStackAddress(uptr addr) { (void *)addr)); return tctx ? tctx->thread : 0; } + +void EnsureMainThreadIDIsCorrect() { + AsanThreadContext *context = + reinterpret_cast<AsanThreadContext *>(AsanTSDGet()); + if (context && (context->tid == 0)) + context->os_id = GetTid(); +} + +__asan::AsanThread *GetAsanThreadByOsIDLocked(uptr os_id) { + __asan::AsanThreadContext *context = static_cast<__asan::AsanThreadContext *>( + __asan::asanThreadRegistry().FindThreadContextByOsIDLocked(os_id)); + if (!context) return 0; + return context->thread; +} } // namespace __asan // --- Implementation of LSan-specific functions --- {{{1 @@ -251,8 +311,23 @@ namespace __lsan { bool GetThreadRangesLocked(uptr os_id, uptr *stack_begin, uptr *stack_end, uptr *tls_begin, uptr *tls_end, uptr *cache_begin, uptr *cache_end) { - // FIXME: Stub. - return false; + __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; + return true; +} + +void ForEachExtraStackRange(uptr 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() { @@ -262,4 +337,8 @@ void LockThreadRegistry() { void UnlockThreadRegistry() { __asan::asanThreadRegistry().Unlock(); } + +void EnsureMainThreadIDIsCorrect() { + __asan::EnsureMainThreadIDIsCorrect(); +} } // namespace __lsan diff --git a/lib/asan/asan_thread.h b/lib/asan/asan_thread.h index 14062b62f751..11771ecd09f0 100644 --- a/lib/asan/asan_thread.h +++ b/lib/asan/asan_thread.h @@ -19,6 +19,7 @@ #include "asan_fake_stack.h" #include "asan_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" @@ -36,11 +37,13 @@ class AsanThreadContext : public ThreadContextBase { explicit AsanThreadContext(int tid) : ThreadContextBase(tid), announced(false), + destructor_iterations(kPthreadDestructorIterations), + stack_id(0), thread(0) { - internal_memset(&stack, 0, sizeof(stack)); } bool announced; - StackTrace stack; + u8 destructor_iterations; + u32 stack_id; AsanThread *thread; void OnCreated(void *arg); @@ -48,7 +51,7 @@ class AsanThreadContext : public ThreadContextBase { }; // AsanThreadContext objects are never freed, so we need many of them. -COMPILER_CHECK(sizeof(AsanThreadContext) <= 4096); +COMPILER_CHECK(sizeof(AsanThreadContext) <= 256); // AsanThread are stored in TSD and destroyed when the thread dies. class AsanThread { @@ -62,7 +65,9 @@ class AsanThread { uptr stack_top() { return stack_top_; } uptr stack_bottom() { return stack_bottom_; } - uptr stack_size() { return stack_top_ - stack_bottom_; } + uptr stack_size() { return stack_size_; } + uptr tls_begin() { return tls_begin_; } + uptr tls_end() { return tls_end_; } u32 tid() { return context_->tid; } AsanThreadContext *context() { return context_; } void set_context(AsanThreadContext *context) { context_ = context; } @@ -73,23 +78,68 @@ class AsanThread { return addr >= stack_bottom_ && addr < stack_top_; } - FakeStack &fake_stack() { return fake_stack_; } + void DeleteFakeStack() { + if (!fake_stack_) return; + FakeStack *t = fake_stack_; + fake_stack_ = 0; + SetTLSFakeStack(0); + t->Destroy(); + } + + bool has_fake_stack() { + return (reinterpret_cast<uptr>(fake_stack_) > 1); + } + + FakeStack *fake_stack() { + if (!__asan_option_detect_stack_use_after_return) + return 0; + 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: - AsanThread() {} - void SetThreadStackTopAndBottom(); - void ClearShadowForThreadStack(); + AsanThread() : unwinding(false) {} + void SetThreadStackAndTls(); + void ClearShadowForThreadStackAndTLS(); + FakeStack *AsyncSignalSafeLazyInitFakeStack(); + AsanThreadContext *context_; thread_callback_t start_routine_; void *arg_; uptr stack_top_; uptr stack_bottom_; + // stack_size_ == stack_top_ - stack_bottom_; + // It needs to be set in a async-signal-safe manner. + uptr stack_size_; + uptr tls_begin_; + uptr tls_end_; - FakeStack fake_stack_; + 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; }; struct CreateThreadContextArgs { @@ -109,6 +159,8 @@ 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 index f74de7227ed2..9e66b3417a1e 100644 --- a/lib/asan/asan_win.cc +++ b/lib/asan/asan_win.cc @@ -25,6 +25,14 @@ #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_mutex.h" +extern "C" { + SANITIZER_INTERFACE_ATTRIBUTE + int __asan_should_detect_stack_use_after_return() { + __asan_init(); + return __asan_option_detect_stack_use_after_return; + } +} + namespace __asan { // ---------------------- Stacktraces, symbols, etc. ---------------- {{{1 @@ -52,6 +60,9 @@ void AsanTSDSet(void *tsd) { fake_tsd = tsd; } +void PlatformTSDDtor(void *tsd) { + AsanThread::TSDDtor(tsd); +} // ---------------------- Various stuff ---------------- {{{1 void MaybeReexec() { // No need to re-exec on Windows. diff --git a/lib/asan/lit_tests/32bitConfig/lit.site.cfg.in b/lib/asan/lit_tests/32bitConfig/lit.site.cfg.in new file mode 100644 index 000000000000..faef4e8c9b17 --- /dev/null +++ b/lib/asan/lit_tests/32bitConfig/lit.site.cfg.in @@ -0,0 +1,13 @@ +## Autogenerated by LLVM/Clang configuration. +# Do not edit! + +# Load common config for all compiler-rt lit tests. +lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/lib/lit.common.configured") + +# Tool-specific config options. +config.asan_source_dir = "@ASAN_SOURCE_DIR@" +config.bits = "32" + +# Load tool-specific config that would do the real work. +lit_config.load_config(config, "@ASAN_SOURCE_DIR@/lit_tests/lit.cfg") + diff --git a/lib/asan/lit_tests/64bitConfig/lit.site.cfg.in b/lib/asan/lit_tests/64bitConfig/lit.site.cfg.in new file mode 100644 index 000000000000..a35994484d5f --- /dev/null +++ b/lib/asan/lit_tests/64bitConfig/lit.site.cfg.in @@ -0,0 +1,12 @@ +## Autogenerated by LLVM/Clang configuration. +# Do not edit! + +# Load common config for all compiler-rt lit tests. +lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/lib/lit.common.configured") + +# Tool-specific config options. +config.asan_source_dir = "@ASAN_SOURCE_DIR@" +config.bits = "64" + +# Load tool-specific config that would do the real work. +lit_config.load_config(config, "@ASAN_SOURCE_DIR@/lit_tests/lit.cfg") diff --git a/lib/asan/lit_tests/CMakeLists.txt b/lib/asan/lit_tests/CMakeLists.txt index d2420b50da83..72a3f5439b70 100644 --- a/lib/asan/lit_tests/CMakeLists.txt +++ b/lib/asan/lit_tests/CMakeLists.txt @@ -2,8 +2,13 @@ set(ASAN_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}/..) set(ASAN_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/..) configure_lit_site_cfg( - ${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in - ${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg + ${CMAKE_CURRENT_SOURCE_DIR}/64bitConfig/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/64bitConfig/lit.site.cfg + ) + +configure_lit_site_cfg( + ${CMAKE_CURRENT_SOURCE_DIR}/32bitConfig/lit.site.cfg.in + ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig/lit.site.cfg ) configure_lit_site_cfg( @@ -12,21 +17,26 @@ configure_lit_site_cfg( ) if(COMPILER_RT_CAN_EXECUTE_TESTS) + set(ASAN_TESTSUITES) + if(CAN_TARGET_i386) + list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/32bitConfig) + endif() + if(CAN_TARGET_x86_64 OR CAN_TARGET_powerpc64) + list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/64bitConfig) + endif() # Run ASan tests only if we're sure we may produce working binaries. set(ASAN_TEST_DEPS ${SANITIZER_COMMON_LIT_TEST_DEPS} - ${ASAN_RUNTIME_LIBRARIES} - asan_blacklist) + asan_runtime_libraries) set(ASAN_TEST_PARAMS - asan_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg - ) + asan_site_config=${CMAKE_CURRENT_BINARY_DIR}/lit.site.cfg) if(LLVM_INCLUDE_TESTS) list(APPEND ASAN_TEST_DEPS AsanUnitTests) + list(APPEND ASAN_TESTSUITES ${CMAKE_CURRENT_BINARY_DIR}/Unit) endif() add_lit_testsuite(check-asan "Running the AddressSanitizer tests" - ${CMAKE_CURRENT_BINARY_DIR} + ${ASAN_TESTSUITES} PARAMS ${ASAN_TEST_PARAMS} - DEPENDS ${ASAN_TEST_DEPS} - ) + DEPENDS ${ASAN_TEST_DEPS}) set_target_properties(check-asan PROPERTIES FOLDER "ASan tests") endif() diff --git a/lib/asan/lit_tests/Darwin/unset-insert-libraries-on-exec.cc b/lib/asan/lit_tests/Darwin/unset-insert-libraries-on-exec.cc deleted file mode 100644 index cf89949cf942..000000000000 --- a/lib/asan/lit_tests/Darwin/unset-insert-libraries-on-exec.cc +++ /dev/null @@ -1,20 +0,0 @@ -// Make sure ASan removes the runtime library from DYLD_INSERT_LIBRARIES before -// executing other programs. - -// RUN: %clangxx_asan -m64 %s -o %t -// RUN: %clangxx -m64 %p/../SharedLibs/darwin-dummy-shared-lib-so.cc \ -// RUN: -dynamiclib -o darwin-dummy-shared-lib-so.dylib - -// Make sure DYLD_INSERT_LIBRARIES doesn't contain the runtime library before -// execl(). - -// RUN: %t >/dev/null 2>&1 -// RUN: DYLD_INSERT_LIBRARIES=darwin-dummy-shared-lib-so.dylib \ -// RUN: %t 2>&1 | FileCheck %s || exit 1 -#include <unistd.h> -int main() { - execl("/bin/bash", "/bin/bash", "-c", - "echo DYLD_INSERT_LIBRARIES=$DYLD_INSERT_LIBRARIES", NULL); - // CHECK: {{DYLD_INSERT_LIBRARIES=.*darwin-dummy-shared-lib-so.dylib.*}} - return 0; -} diff --git a/lib/asan/lit_tests/Helpers/initialization-blacklist.txt b/lib/asan/lit_tests/Helpers/initialization-blacklist.txt deleted file mode 100644 index fa4a83667f4b..000000000000 --- a/lib/asan/lit_tests/Helpers/initialization-blacklist.txt +++ /dev/null @@ -1,3 +0,0 @@ -global-init:*badGlobal* -global-init-type:*badNamespace::BadClass* -global-init-src:*initialization-blacklist-extra2.cc diff --git a/lib/asan/lit_tests/Linux/interception_failure_test.cc b/lib/asan/lit_tests/Linux/interception_failure_test.cc deleted file mode 100644 index dfad909f528c..000000000000 --- a/lib/asan/lit_tests/Linux/interception_failure_test.cc +++ /dev/null @@ -1,26 +0,0 @@ -// If user provides his own libc functions, ASan doesn't -// intercept these functions. - -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | FileCheck %s -#include <stdlib.h> -#include <stdio.h> - -extern "C" long strtol(const char *nptr, char **endptr, int base) { - fprintf(stderr, "my_strtol_interceptor\n"); - return 0; -} - -int main() { - char *x = (char*)malloc(10 * sizeof(char)); - free(x); - return (int)strtol(x, 0, 10); - // CHECK: my_strtol_interceptor - // CHECK-NOT: heap-use-after-free -} diff --git a/lib/asan/lit_tests/Linux/interception_malloc_test.cc b/lib/asan/lit_tests/Linux/interception_malloc_test.cc deleted file mode 100644 index 8f66788e9a82..000000000000 --- a/lib/asan/lit_tests/Linux/interception_malloc_test.cc +++ /dev/null @@ -1,27 +0,0 @@ -// ASan interceptor can be accessed with __interceptor_ prefix. - -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | FileCheck %s -#include <stdlib.h> -#include <stdio.h> -#include <unistd.h> - -extern "C" void *__interceptor_malloc(size_t size); -extern "C" void *malloc(size_t size) { - write(2, "malloc call\n", sizeof("malloc call\n") - 1); - return __interceptor_malloc(size); -} - -int main() { - char *x = (char*)malloc(10 * sizeof(char)); - free(x); - return (int)strtol(x, 0, 10); - // CHECK: malloc call - // CHECK: heap-use-after-free -} diff --git a/lib/asan/lit_tests/Linux/interception_test.cc b/lib/asan/lit_tests/Linux/interception_test.cc deleted file mode 100644 index 94fb499f2f87..000000000000 --- a/lib/asan/lit_tests/Linux/interception_test.cc +++ /dev/null @@ -1,26 +0,0 @@ -// ASan interceptor can be accessed with __interceptor_ prefix. - -// RUN: %clangxx_asan -m64 -O0 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O1 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O2 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m64 -O3 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O0 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O1 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O2 %s -o %t && %t 2>&1 | FileCheck %s -// RUN: %clangxx_asan -m32 -O3 %s -o %t && %t 2>&1 | FileCheck %s -#include <stdlib.h> -#include <stdio.h> - -extern "C" long __interceptor_strtol(const char *nptr, char **endptr, int base); -extern "C" long strtol(const char *nptr, char **endptr, int base) { - fprintf(stderr, "my_strtol_interceptor\n"); - return __interceptor_strtol(nptr, endptr, base); -} - -int main() { - char *x = (char*)malloc(10 * sizeof(char)); - free(x); - return (int)strtol(x, 0, 10); - // CHECK: my_strtol_interceptor - // CHECK: heap-use-after-free -} diff --git a/lib/asan/lit_tests/Linux/zero-base-shadow.cc b/lib/asan/lit_tests/Linux/zero-base-shadow.cc deleted file mode 100644 index 682e7e8d7e59..000000000000 --- a/lib/asan/lit_tests/Linux/zero-base-shadow.cc +++ /dev/null @@ -1,31 +0,0 @@ -// RUN: %clangxx_asan -m64 -O0 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-64 < %t.out -// RUN: %clangxx_asan -m64 -O1 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-64 < %t.out -// RUN: %clangxx_asan -m64 -O2 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-64 < %t.out -// RUN: %clangxx_asan -m32 -O0 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-32 < %t.out -// RUN: %clangxx_asan -m32 -O1 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-32 < %t.out -// RUN: %clangxx_asan -m32 -O2 -fsanitize-address-zero-base-shadow -fPIE -pie %s -o %t && %t 2>&1 | %symbolize > %t.out -// RUN: FileCheck %s < %t.out && FileCheck %s --check-prefix=CHECK-32 < %t.out - -// Zero-base shadow only works on x86_64 and i386. -// REQUIRES: x86_64-supported-target,i386-supported-target - -#include <string.h> -int main(int argc, char **argv) { - char x[10]; - memset(x, 0, 10); - int res = x[argc * 10]; // BOOOM - // CHECK: {{READ of size 1 at 0x.* thread T0}} - // CHECK: {{ #0 0x.* in _?main .*zero-base-shadow.cc:}}[[@LINE-2]] - // CHECK: {{Address 0x.* is .* frame}} - // CHECK: main - - // Check that shadow for stack memory occupies lower part of address space. - // CHECK-64: =>0x0f - // CHECK-32: =>0x1 - return res; -} diff --git a/lib/asan/lit_tests/Darwin/interface_symbols_darwin.c b/lib/asan/lit_tests/TestCases/Darwin/interface_symbols_darwin.c index 3fca6e915324..b453b64cafd2 100644 --- a/lib/asan/lit_tests/Darwin/interface_symbols_darwin.c +++ b/lib/asan/lit_tests/TestCases/Darwin/interface_symbols_darwin.c @@ -2,7 +2,7 @@ // If you're changing this file, please also change // ../Linux/interface_symbols.c -// RUN: %clang -fsanitize=address -dead_strip -O2 %s -o %t.exe +// RUN: %clang_asan -dead_strip -O2 %s -o %t.exe // RUN: rm -f %t.symbols %t.interface // RUN: nm -g `otool -L %t.exe | grep "asan_osx_dynamic.dylib" | \ @@ -16,7 +16,7 @@ // RUN: | grep -v "__asan_default_options" \ // RUN: | grep -v "__asan_on_error" > %t.symbols -// RUN: cat %p/../../asan_interface_internal.h \ +// RUN: cat %p/../../../asan_interface_internal.h \ // RUN: | sed "s/\/\/.*//" | sed "s/typedef.*//" \ // RUN: | grep -v "OPTIONAL" \ // RUN: | grep "__asan_.*(" | sed "s/.* __asan_/__asan_/;s/(.*//" \ @@ -33,6 +33,8 @@ // RUN: echo __asan_report_store16 >> %t.interface // RUN: echo __asan_report_load_n >> %t.interface // RUN: echo __asan_report_store_n >> %t.interface +// RUN: for i in `jot - 0 10`; do echo __asan_stack_malloc_$i >> %t.interface; done +// RUN: for i in `jot - 0 10`; do echo __asan_stack_free_$i >> %t.interface; done // RUN: cat %t.interface | sort -u | diff %t.symbols - diff --git a/lib/asan/lit_tests/Darwin/lit.local.cfg b/lib/asan/lit_tests/TestCases/Darwin/lit.local.cfg index a85dfcd24c08..a85dfcd24c08 100644 --- a/lib/asan/lit_tests/Darwin/lit.local.cfg +++ b/lib/asan/lit_tests/TestCases/Darwin/lit.local.cfg diff --git a/lib/asan/lit_tests/TestCases/Darwin/malloc_set_zone_name-mprotect.cc b/lib/asan/lit_tests/TestCases/Darwin/malloc_set_zone_name-mprotect.cc new file mode 100644 index 000000000000..807a8283e788 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Darwin/malloc_set_zone_name-mprotect.cc @@ -0,0 +1,51 @@ +// Regression test for a bug in malloc_create_zone() +// (https://code.google.com/p/address-sanitizer/issues/detail?id=203) +// The old implementation of malloc_create_zone() didn't always return a +// page-aligned address, so we can only test on a best-effort basis. + +// RUN: %clangxx_asan %s -o %t +// RUN: %t 2>&1 + +#include <malloc/malloc.h> +#include <stdlib.h> +#include <string.h> +#include <stdio.h> + +const int kNumIter = 4096; +const int kNumZones = 100; +int main() { + char *mem[kNumIter * 2]; + // Allocate memory chunks from different size classes up to 1 page. + // (For the case malloc() returns memory chunks in descending order) + for (int i = 0; i < kNumIter; i++) { + mem[i] = (char*)malloc(8 * i); + } + // Try to allocate a page-aligned malloc zone. Otherwise the mprotect() call + // in malloc_set_zone_name() will silently fail. + malloc_zone_t *zone = NULL; + bool aligned = false; + for (int i = 0; i < kNumZones; i++) { + zone = malloc_create_zone(0, 0); + if (((uintptr_t)zone & (~0xfff)) == (uintptr_t)zone) { + aligned = true; + break; + } + } + if (!aligned) { + printf("Warning: couldn't allocate a page-aligned zone."); + return 0; + } + // malloc_set_zone_name() calls mprotect(zone, 4096, PROT_READ | PROT_WRITE), + // modifies the zone contents and then calls mprotect(zone, 4096, PROT_READ). + malloc_set_zone_name(zone, "foobar"); + // Allocate memory chunks from different size classes again. + for (int i = 0; i < kNumIter; i++) { + mem[i + kNumIter] = (char*)malloc(8 * i); + } + // Access the allocated memory chunks and free them. + for (int i = 0; i < kNumIter * 2; i++) { + memset(mem[i], 'a', 8 * (i % kNumIter)); + free(mem[i]); + } + return 0; +} diff --git a/lib/asan/lit_tests/TestCases/Darwin/malloc_zone-protected.cc b/lib/asan/lit_tests/TestCases/Darwin/malloc_zone-protected.cc new file mode 100644 index 000000000000..d5f6c7c12e67 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Darwin/malloc_zone-protected.cc @@ -0,0 +1,20 @@ +// Make sure the zones created by malloc_create_zone() are write-protected. +#include <malloc/malloc.h> +#include <stdio.h> + +// RUN: %clangxx_asan %s -o %t +// RUN: not %t 2>&1 | FileCheck %s + + +void *pwn(malloc_zone_t *unused_zone, size_t unused_size) { + printf("PWNED\n"); + return NULL; +} + +int main() { + malloc_zone_t *zone = malloc_create_zone(0, 0); + zone->malloc = pwn; + void *v = malloc_zone_malloc(zone, 1); + // CHECK-NOT: PWNED + return 0; +} diff --git a/lib/asan/lit_tests/Darwin/reexec-insert-libraries-env.cc b/lib/asan/lit_tests/TestCases/Darwin/reexec-insert-libraries-env.cc index 40a459fd84db..208fe43ac7e4 100644 --- a/lib/asan/lit_tests/Darwin/reexec-insert-libraries-env.cc +++ b/lib/asan/lit_tests/TestCases/Darwin/reexec-insert-libraries-env.cc @@ -2,8 +2,8 @@ // This is a regression test for // https://code.google.com/p/address-sanitizer/issues/detail?id=159 -// RUN: %clangxx_asan -m64 %s -o %t -// RUN: %clangxx -m64 %p/../SharedLibs/darwin-dummy-shared-lib-so.cc \ +// RUN: %clangxx_asan %s -o %t +// RUN: %clangxx %p/../SharedLibs/darwin-dummy-shared-lib-so.cc \ // RUN: -dynamiclib -o darwin-dummy-shared-lib-so.dylib // FIXME: the following command line may hang in the case of a regression. diff --git a/lib/asan/lit_tests/TestCases/Darwin/unset-insert-libraries-on-exec.cc b/lib/asan/lit_tests/TestCases/Darwin/unset-insert-libraries-on-exec.cc new file mode 100644 index 000000000000..fa0dd4f9df88 --- /dev/null +++ b/lib/asan/lit_tests/TestCases/Darwin/unset-insert-libraries-on-exec.cc @@ -0,0 +1,20 @@ +// Make sure ASan removes the runtime library from DYLD_INSERT_LIBRARIES before +// executing other programs. + +// RUN: %clangxx_asan %s -o %t +// RUN: %clangxx %p/../Helpers/echo-env.cc -o %T/echo-env +// RUN: %clangxx %p/../SharedLibs/darwin-dummy-shared-lib-so.cc \ +// RUN: -dynamiclib -o %t-darwin-dummy-shared-lib-so.dylib + +// Make sure DYLD_INSERT_LIBRARIES doesn't contain the runtime library before +// execl(). + +// RUN: %t %T/echo-env >/dev/null 2>&1 +// RUN: DYLD_INSERT_LIBRARIES=%t-darwin-dummy-shared-lib-so.dylib \ +// RUN: %t %T/echo-env 2>&1 | FileCheck %s || exit 1 +#include <unistd.h> +int main(int argc, char *argv[]) { + execl(argv[1], argv[1], "DYLD_INSERT_LIBRARIES", NULL); + // CHECK: {{DYLD_INSERT_LIBRARIES = .*darwin-dummy-shared-lib-so.dylib.*}} + return 0; +} |