summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJordan Rupprecht <rupprecht@google.com>2019-01-18 19:46:00 +0000
committerJordan Rupprecht <rupprecht@google.com>2019-01-18 19:46:00 +0000
commit05342ccc9cff16425c0a831fddd510879544a0bf (patch)
treed86b2dfee6aa9d3a54d6d21aabb6bd7462b6669b
parent6fc0ad0a5de45f80140620e2dd606f65d547362a (diff)
parentb15181368831966c0ec1824617a4c95853fd1b92 (diff)
downloadcompiler-rt-05342ccc9cff16425c0a831fddd510879544a0bf.tar.gz
Creating branches/google/stable and tags/google/stable/2019-01-18 from r351319
git-svn-id: https://llvm.org/svn/llvm-project/compiler-rt/branches/google/stable@351578 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--CMakeLists.txt24
-rw-r--r--LICENSE.TXT2
-rw-r--r--cmake/Modules/CompilerRTUtils.cmake30
-rw-r--r--cmake/Modules/SanitizerUtils.cmake4
-rw-r--r--cmake/base-config-ix.cmake6
-rw-r--r--cmake/config-ix.cmake2
-rw-r--r--lib/asan/asan_allocator.h24
-rw-r--r--lib/asan/asan_errors.cc5
-rw-r--r--lib/asan/asan_errors.h7
-rw-r--r--lib/asan/asan_posix.cc46
-rw-r--r--lib/asan/asan_rtl.cc15
-rw-r--r--lib/asan/asan_thread.cc24
-rw-r--r--lib/builtins/CMakeLists.txt2
-rw-r--r--lib/builtins/ppc/fixunstfti.c106
-rw-r--r--lib/builtins/ppc/floattitf.c48
-rw-r--r--lib/fuzzer/CMakeLists.txt4
-rw-r--r--lib/fuzzer/FuzzerBuiltins.h36
-rw-r--r--lib/fuzzer/FuzzerBuiltinsMsvc.h59
-rw-r--r--lib/fuzzer/FuzzerCorpus.h6
-rw-r--r--lib/fuzzer/FuzzerDefs.h12
-rw-r--r--lib/fuzzer/FuzzerDriver.cpp4
-rw-r--r--lib/fuzzer/FuzzerExtFunctionsWeakAlias.cpp56
-rw-r--r--lib/fuzzer/FuzzerExtFunctionsWindows.cpp83
-rw-r--r--lib/fuzzer/FuzzerFlags.def11
-rw-r--r--lib/fuzzer/FuzzerInternal.h1
-rw-r--r--lib/fuzzer/FuzzerLoop.cpp38
-rw-r--r--lib/fuzzer/FuzzerOptions.h2
-rw-r--r--lib/fuzzer/FuzzerTracePC.cpp124
-rw-r--r--lib/fuzzer/FuzzerTracePC.h20
-rw-r--r--lib/fuzzer/FuzzerUtil.h6
-rw-r--r--lib/hwasan/CMakeLists.txt1
-rw-r--r--lib/hwasan/hwasan.cc67
-rw-r--r--lib/hwasan/hwasan.h2
-rw-r--r--lib/hwasan/hwasan_allocator.cc41
-rw-r--r--lib/hwasan/hwasan_allocator.h22
-rw-r--r--lib/hwasan/hwasan_checks.h80
-rw-r--r--lib/hwasan/hwasan_interceptors.cc42
-rw-r--r--lib/hwasan/hwasan_interface_internal.h7
-rw-r--r--lib/hwasan/hwasan_linux.cc8
-rw-r--r--lib/hwasan/hwasan_memintrinsics.cc45
-rw-r--r--lib/hwasan/hwasan_new_delete.cc2
-rw-r--r--lib/hwasan/hwasan_report.cc2
-rw-r--r--lib/hwasan/hwasan_thread.cc25
-rw-r--r--lib/lsan/lsan_allocator.cc3
-rw-r--r--lib/lsan/lsan_allocator.h24
-rw-r--r--lib/msan/msan_allocator.cc2
-rw-r--r--lib/msan/msan_linux.cc46
-rw-r--r--lib/profile/InstrProfData.inc20
-rw-r--r--lib/profile/InstrProfilingPlatformLinux.c2
-rw-r--r--lib/profile/InstrProfilingPlatformOther.c2
-rw-r--r--lib/sanitizer_common/CMakeLists.txt8
-rw-r--r--lib/sanitizer_common/sanitizer_allocator_combined.h16
-rw-r--r--lib/sanitizer_common/sanitizer_allocator_primary32.h7
-rw-r--r--lib/sanitizer_common/sanitizer_allocator_primary64.h5
-rw-r--r--lib/sanitizer_common/sanitizer_allocator_secondary.h13
-rw-r--r--lib/sanitizer_common/sanitizer_allocator_size_class_map.h3
-rw-r--r--lib/sanitizer_common/sanitizer_common.h11
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc541
-rw-r--r--lib/sanitizer_common/sanitizer_common_libcdep.cc4
-rw-r--r--lib/sanitizer_common/sanitizer_flags.inc5
-rw-r--r--lib/sanitizer_common/sanitizer_fuchsia.cc9
-rw-r--r--lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc20
-rw-r--r--lib/sanitizer_common/sanitizer_linux.cc39
-rw-r--r--lib/sanitizer_common/sanitizer_linux.h10
-rw-r--r--lib/sanitizer_common/sanitizer_linux_libcdep.cc4
-rw-r--r--lib/sanitizer_common/sanitizer_local_address_space_view.h42
-rw-r--r--lib/sanitizer_common/sanitizer_mac.cc10
-rw-r--r--lib/sanitizer_common/sanitizer_netbsd.cc7
-rw-r--r--lib/sanitizer_common/sanitizer_platform.h6
-rw-r--r--lib/sanitizer_common/sanitizer_platform_interceptors.h21
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_freebsd.cc15
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_freebsd.h9
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc45
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_netbsd.h52
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_posix.cc10
-rw-r--r--lib/sanitizer_common/sanitizer_platform_limits_posix.h3
-rw-r--r--lib/sanitizer_common/sanitizer_posix.cc35
-rw-r--r--lib/sanitizer_common/sanitizer_posix.h6
-rw-r--r--lib/sanitizer_common/sanitizer_procmaps.h1
-rw-r--r--lib/sanitizer_common/sanitizer_procmaps_bsd.cc1
-rw-r--r--lib/sanitizer_common/sanitizer_procmaps_common.cc6
-rw-r--r--lib/sanitizer_common/sanitizer_procmaps_linux.cc1
-rw-r--r--lib/sanitizer_common/sanitizer_procmaps_mac.cc4
-rw-r--r--lib/sanitizer_common/sanitizer_procmaps_solaris.cc9
-rw-r--r--lib/sanitizer_common/sanitizer_rtems.cc1
-rw-r--r--lib/sanitizer_common/sanitizer_solaris.cc4
-rw-r--r--lib/sanitizer_common/sanitizer_stackdepot.cc2
-rw-r--r--lib/sanitizer_common/sanitizer_stackdepot.h2
-rw-r--r--lib/sanitizer_common/sanitizer_type_traits.cc21
-rw-r--r--lib/sanitizer_common/sanitizer_type_traits.h2
-rw-r--r--lib/sanitizer_common/sanitizer_win.cc4
-rwxr-xr-xlib/sanitizer_common/scripts/gen_dynamic_list.py23
-rw-r--r--lib/sanitizer_common/tests/sanitizer_allocator_test.cc46
-rw-r--r--lib/scudo/scudo_allocator.h1
-rw-r--r--lib/tsan/CMakeLists.txt11
-rw-r--r--lib/tsan/rtl/tsan_debugging.cc50
-rw-r--r--lib/tsan/rtl/tsan_flags.cc3
-rw-r--r--lib/tsan/rtl/tsan_flags.inc2
-rw-r--r--lib/tsan/rtl/tsan_interceptors.cc22
-rw-r--r--lib/tsan/rtl/tsan_interceptors_mac.cc63
-rw-r--r--lib/tsan/rtl/tsan_report.cc67
-rw-r--r--lib/tsan/rtl/tsan_rtl.h1
-rw-r--r--lib/tsan/rtl/tsan_suppressions.cc56
-rw-r--r--lib/ubsan/ubsan_checks.inc1
-rw-r--r--lib/ubsan/ubsan_handlers.cc56
-rw-r--r--lib/ubsan/ubsan_handlers.h11
-rw-r--r--lib/ubsan/ubsan_interface.inc2
-rw-r--r--lib/ubsan_minimal/ubsan_minimal_handlers.cc1
-rw-r--r--lib/xray/tests/CMakeLists.txt4
-rw-r--r--lib/xray/tests/unit/CMakeLists.txt12
-rw-r--r--lib/xray/xray_basic_logging.cc2
-rw-r--r--lib/xray/xray_defs.h10
-rw-r--r--lib/xray/xray_fdr_log_writer.h2
-rw-r--r--lib/xray/xray_fdr_logging.cc4
-rw-r--r--lib/xray/xray_init.cc3
-rw-r--r--lib/xray/xray_trampoline_x86_64.S2
-rw-r--r--test/CMakeLists.txt2
-rw-r--r--test/asan/TestCases/Linux/asan_rt_confict_test-2.cc4
-rw-r--r--test/asan/TestCases/Linux/local_alias.cc9
-rw-r--r--test/asan/TestCases/Linux/new_delete_mismatch.cc1
-rw-r--r--test/asan/TestCases/Linux/new_delete_mismatch_global.cc16
-rw-r--r--test/asan/TestCases/Linux/new_delete_mismatch_stack.cc17
-rw-r--r--test/asan/TestCases/Linux/odr-violation.cc20
-rw-r--r--test/asan/TestCases/Linux/odr-vtable.cc26
-rw-r--r--test/asan/TestCases/Linux/odr_c_test.c8
-rw-r--r--test/asan/TestCases/Linux/preinit_test.cc7
-rw-r--r--test/asan/TestCases/Posix/no-fd.cc43
-rw-r--r--test/asan/TestCases/Posix/tsd_dtor_leak.cc2
-rw-r--r--test/asan/TestCases/asan_and_llvm_coverage_test.cc2
-rw-r--r--test/asan/TestCases/printf-3.c4
-rw-r--r--test/builtins/Unit/ppc/fixtfdi_test.c6
-rw-r--r--test/builtins/Unit/ppc/fixunstfti_test.c52
-rw-r--r--test/builtins/Unit/ppc/fixunstfti_test.h706
-rw-r--r--test/builtins/Unit/ppc/floatditf_test.c5
-rw-r--r--test/builtins/Unit/ppc/floattitf_test.c59
-rw-r--r--test/builtins/Unit/ppc/floattitf_test.h197
-rw-r--r--test/builtins/Unit/ppc/floatunditf_test.c5
-rw-r--r--test/builtins/Unit/ppc/qadd_test.c4
-rw-r--r--test/builtins/Unit/ppc/qdiv_test.c4
-rw-r--r--test/builtins/Unit/ppc/qmul_test.c4
-rw-r--r--test/builtins/Unit/ppc/qsub_test.c4
-rw-r--r--test/fuzzer/AlignmentAssumptionTest.cpp27
-rw-r--r--test/fuzzer/PrintUnstableStatsTest.cpp69
-rw-r--r--test/fuzzer/fuzzer-alignment-assumption.test7
-rw-r--r--test/fuzzer/handle-unstable.test43
-rw-r--r--test/fuzzer/print_unstable_stats.test24
-rw-r--r--test/hwasan/CMakeLists.txt3
-rw-r--r--test/hwasan/TestCases/Posix/system-allocator-fallback.cc54
-rw-r--r--test/hwasan/TestCases/deep-recursion.c10
-rw-r--r--test/hwasan/TestCases/heap-buffer-overflow.c1
-rw-r--r--test/hwasan/TestCases/mem-intrinsics-zero-size.c10
-rw-r--r--test/hwasan/TestCases/mem-intrinsics.c37
-rw-r--r--test/hwasan/TestCases/stack-history-length.c4
-rw-r--r--test/hwasan/TestCases/stack-uar.c2
-rw-r--r--test/hwasan/TestCases/use-after-free.c2
-rw-r--r--test/hwasan/lit.cfg6
-rw-r--r--test/hwasan/lit.site.cfg.in1
-rw-r--r--test/lit.common.cfg40
-rw-r--r--test/lit.common.configured.in3
-rw-r--r--test/lsan/TestCases/Linux/use_tls_dynamic.cc5
-rw-r--r--test/msan/Linux/sunrpc.cc2
-rw-r--r--test/msan/Linux/sunrpc_bytes.cc2
-rw-r--r--test/msan/Linux/sunrpc_string.cc2
-rw-r--r--test/msan/dtls_test.c5
-rw-r--r--test/msan/pthread_getname_np.cc6
-rw-r--r--test/profile/instrprof-dlopen-dlclose-gcov.test3
-rw-r--r--test/profile/lit.cfg2
-rw-r--r--test/sanitizer_common/CMakeLists.txt7
-rw-r--r--test/sanitizer_common/TestCases/FreeBSD/capsicum.cc6
-rw-r--r--test/sanitizer_common/TestCases/FreeBSD/fdevname.cc44
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/funopen2.cc110
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/md2.cc8
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/md4.cc8
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/md5.cc4
-rw-r--r--test/sanitizer_common/TestCases/NetBSD/sha2.cc24
-rw-r--r--test/sanitizer_common/TestCases/Posix/arc4random.cc71
-rw-r--r--test/sanitizer_common/TestCases/Posix/devname.cc8
-rw-r--r--test/sanitizer_common/TestCases/Posix/devname_r.cc10
-rw-r--r--test/sanitizer_common/TestCases/Posix/feof_fileno_ferror.cc41
-rw-r--r--test/sanitizer_common/TestCases/Posix/fgetc_ungetc_getc.cc19
-rw-r--r--test/sanitizer_common/TestCases/Posix/fgetln.cc16
-rw-r--r--test/sanitizer_common/TestCases/Posix/fgets.cc18
-rw-r--r--test/sanitizer_common/TestCases/Posix/fputc_putc_putchar.cc13
-rw-r--r--test/sanitizer_common/TestCases/Posix/fputs_puts.cc12
-rw-r--r--test/sanitizer_common/TestCases/Posix/fts.cc (renamed from test/sanitizer_common/TestCases/NetBSD/fts.cc)2
-rw-r--r--test/sanitizer_common/TestCases/Posix/funopen.cc91
-rw-r--r--test/sanitizer_common/TestCases/Posix/getc_unlocked.cc20
-rw-r--r--test/sanitizer_common/TestCases/Posix/getfsent.cc36
-rw-r--r--test/sanitizer_common/TestCases/Posix/getusershell.cc23
-rw-r--r--test/sanitizer_common/TestCases/Posix/lstat.cc8
-rw-r--r--test/sanitizer_common/TestCases/Posix/popen.cc23
-rw-r--r--test/sanitizer_common/TestCases/Posix/putc_putchar_unlocked.cc12
-rw-r--r--test/sanitizer_common/TestCases/Posix/regex.cc (renamed from test/sanitizer_common/TestCases/NetBSD/regex.cc)42
-rw-r--r--test/sanitizer_common/TestCases/Posix/sl_add.cc26
-rw-r--r--test/sanitizer_common/TestCases/Posix/strtonum.cc (renamed from test/sanitizer_common/TestCases/NetBSD/strtonum.cc)2
-rw-r--r--test/sanitizer_common/TestCases/Posix/vis.cc (renamed from test/sanitizer_common/TestCases/NetBSD/vis.cc)2
-rw-r--r--test/sanitizer_common/TestCases/hard_rss_limit_mb_test.cc (renamed from test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc)3
-rw-r--r--test/tsan/Darwin/ignore-noninstrumented.mm5
-rw-r--r--test/tsan/Darwin/ignored-interceptors.mm55
-rw-r--r--test/tsan/Darwin/objc-synchronize-cycle-tagged.mm42
-rw-r--r--test/tsan/Darwin/objc-synchronize-cycle.mm31
-rw-r--r--test/tsan/Darwin/objc-synchronize-nested-recursive.mm35
-rw-r--r--test/tsan/deadlock_detector_stress_test.cc10
-rw-r--r--test/tsan/ignored-interceptors-mmap.cc61
-rw-r--r--test/tsan/mutex_cycle2.c2
-rw-r--r--test/tsan/sunrpc.cc2
-rw-r--r--test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-lvalue.cpp36
-rw-r--r--test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-paramvar.cpp30
-rw-r--r--test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function-variable.cpp33
-rw-r--r--test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function.cpp29
-rw-r--r--test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp28
-rw-r--r--test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function.cpp28
-rw-r--r--test/ubsan/TestCases/Pointer/alignment-assumption-blacklist.cpp20
-rw-r--r--test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params-variable.cpp27
-rw-r--r--test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params.cpp23
-rw-r--r--test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-two-params.cpp23
-rw-r--r--test/ubsan/TestCases/Pointer/alignment-assumption-openmp.cpp28
-rw-r--r--test/ubsan/TestCases/Pointer/alignment-assumption-summary.cpp17
-rw-r--r--test/ubsan_minimal/TestCases/alignment-assumption.c17
219 files changed, 4515 insertions, 1072 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index 4697dba62..aa360a3ef 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -200,7 +200,7 @@ set(CXXABIS none default libstdc++ libc++)
set_property(CACHE SANITIZER_CXX_ABI PROPERTY STRINGS ;${CXXABIS})
if (SANITIZER_CXX_ABI STREQUAL "default")
- if (APPLE)
+ if (APPLE OR CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
set(SANITIZER_CXX_ABI_LIBNAME "libc++")
set(SANITIZER_CXX_ABI_SYSTEM 1)
elseif (FUCHSIA)
@@ -428,15 +428,19 @@ endif()
add_subdirectory(include)
-foreach(path IN ITEMS ${LLVM_MAIN_SRC_DIR}/projects/libcxx
- ${LLVM_MAIN_SRC_DIR}/runtimes/libcxx
- ${LLVM_MAIN_SRC_DIR}/../libcxx
- ${LLVM_EXTERNAL_LIBCXX_SOURCE_DIR})
- if(IS_DIRECTORY ${path})
- set(COMPILER_RT_LIBCXX_PATH ${path})
- break()
- endif()
-endforeach()
+option(COMPILER_RT_USE_LIBCXX
+ "Enable compiler-rt to use libc++ from the source tree" ON)
+if(COMPILER_RT_USE_LIBCXX)
+ foreach(path IN ITEMS ${LLVM_MAIN_SRC_DIR}/projects/libcxx
+ ${LLVM_MAIN_SRC_DIR}/runtimes/libcxx
+ ${LLVM_MAIN_SRC_DIR}/../libcxx
+ ${LLVM_EXTERNAL_LIBCXX_SOURCE_DIR})
+ if(IS_DIRECTORY ${path})
+ set(COMPILER_RT_LIBCXX_PATH ${path})
+ break()
+ endif()
+ endforeach()
+endif()
set(COMPILER_RT_LLD_PATH ${LLVM_MAIN_SRC_DIR}/tools/lld)
if(EXISTS ${COMPILER_RT_LLD_PATH}/ AND LLVM_TOOL_LLD_BUILD)
diff --git a/LICENSE.TXT b/LICENSE.TXT
index 0134694e4..1c94ad5d8 100644
--- a/LICENSE.TXT
+++ b/LICENSE.TXT
@@ -14,7 +14,7 @@ Full text of the relevant licenses is included below.
University of Illinois/NCSA
Open Source License
-Copyright (c) 2009-2018 by the contributors listed in CREDITS.TXT
+Copyright (c) 2009-2019 by the contributors listed in CREDITS.TXT
All rights reserved.
diff --git a/cmake/Modules/CompilerRTUtils.cmake b/cmake/Modules/CompilerRTUtils.cmake
index c4500328e..5348f2064 100644
--- a/cmake/Modules/CompilerRTUtils.cmake
+++ b/cmake/Modules/CompilerRTUtils.cmake
@@ -58,14 +58,6 @@ macro(append_rtti_flag polarity list)
endif()
endmacro()
-macro(append_have_file_definition filename varname list)
- check_include_file("${filename}" "${varname}")
- if (NOT ${varname})
- set("${varname}" 0)
- endif()
- list(APPEND ${list} "${varname}=${${varname}}")
-endmacro()
-
macro(list_intersect output input1 input2)
set(${output})
foreach(it ${${input1}})
@@ -239,7 +231,7 @@ macro(load_llvm_config)
# Detect if we have the LLVMXRay and TestingSupport library installed and
# available from llvm-config.
execute_process(
- COMMAND ${LLVM_CONFIG_PATH} "--ldflags" "--libs" "xray" "testingsupport"
+ COMMAND ${LLVM_CONFIG_PATH} "--ldflags" "--libs" "xray"
RESULT_VARIABLE HAD_ERROR
OUTPUT_VARIABLE CONFIG_OUTPUT)
if (HAD_ERROR)
@@ -254,6 +246,26 @@ macro(load_llvm_config)
set(COMPILER_RT_HAS_LLVMXRAY TRUE)
endif()
+ set(COMPILER_RT_HAS_LLVMTESTINGSUPPORT FALSE)
+ execute_process(
+ COMMAND ${LLVM_CONFIG_PATH} "--ldflags" "--libs" "testingsupport"
+ RESULT_VARIABLE HAD_ERROR
+ OUTPUT_VARIABLE CONFIG_OUTPUT)
+ if (HAD_ERROR)
+ message(WARNING "llvm-config finding testingsupport failed with status ${HAD_ERROR}")
+ else()
+ string(REGEX REPLACE "[ \t]*[\r\n]+[ \t]*" ";" CONFIG_OUTPUT ${CONFIG_OUTPUT})
+ list(GET CONFIG_OUTPUT 0 LDFLAGS)
+ list(GET CONFIG_OUTPUT 1 LIBLIST)
+ if (LIBLIST STREQUAL "")
+ message(WARNING "testingsupport library not installed, some tests will be skipped")
+ else()
+ set(LLVM_TESTINGSUPPORT_LDFLAGS ${LDFLAGS} CACHE STRING "Linker flags for LLVMTestingSupport library")
+ set(LLVM_TESTINGSUPPORT_LIBLIST ${LIBLIST} CACHE STRING "Library list for LLVMTestingSupport")
+ set(COMPILER_RT_HAS_LLVMTESTINGSUPPORT TRUE)
+ endif()
+ endif()
+
# Make use of LLVM CMake modules.
# --cmakedir is supported since llvm r291218 (4.0 release)
execute_process(
diff --git a/cmake/Modules/SanitizerUtils.cmake b/cmake/Modules/SanitizerUtils.cmake
index 8fe4baae4..64d3ed92c 100644
--- a/cmake/Modules/SanitizerUtils.cmake
+++ b/cmake/Modules/SanitizerUtils.cmake
@@ -30,7 +30,7 @@ macro(add_sanitizer_rt_symbols name)
add_custom_command(OUTPUT ${stamp}
COMMAND ${PYTHON_EXECUTABLE}
${SANITIZER_GEN_DYNAMIC_LIST} ${extra_args} $<TARGET_FILE:${target_name}>
- > $<TARGET_FILE:${target_name}>.syms
+ -o $<TARGET_FILE:${target_name}>.syms
COMMAND ${CMAKE_COMMAND} -E touch ${stamp}
DEPENDS ${target_name} ${SANITIZER_GEN_DYNAMIC_LIST} ${ARG_EXTRA}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
@@ -80,7 +80,7 @@ macro(add_sanitizer_rt_version_list name)
add_custom_command(OUTPUT ${vers}
COMMAND ${PYTHON_EXECUTABLE}
${SANITIZER_GEN_DYNAMIC_LIST} --version-list ${args}
- > ${vers}
+ -o ${vers}
DEPENDS ${SANITIZER_GEN_DYNAMIC_LIST} ${ARG_EXTRA} ${ARG_LIBS}
WORKING_DIRECTORY ${CMAKE_CURRENT_SOURCE_DIR}
COMMENT "Generating version list for ${name}"
diff --git a/cmake/base-config-ix.cmake b/cmake/base-config-ix.cmake
index 2a44d830b..6684d7371 100644
--- a/cmake/base-config-ix.cmake
+++ b/cmake/base-config-ix.cmake
@@ -8,6 +8,12 @@ include(CheckCXXSourceCompiles)
check_include_file(unwind.h HAVE_UNWIND_H)
+# Used by sanitizer_common and tests.
+check_include_file(rpc/xdr.h HAVE_RPC_XDR_H)
+if (NOT HAVE_RPC_XDR_H)
+ set(HAVE_RPC_XDR_H 0)
+endif()
+
# Top level target used to build all compiler-rt libraries.
add_custom_target(compiler-rt ALL)
add_custom_target(install-compiler-rt)
diff --git a/cmake/config-ix.cmake b/cmake/config-ix.cmake
index 7e9ad6355..db5c4645d 100644
--- a/cmake/config-ix.cmake
+++ b/cmake/config-ix.cmake
@@ -586,7 +586,7 @@ else()
endif()
if (PROFILE_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND
- OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS")
+ OS_NAME MATCHES "Darwin|Linux|FreeBSD|Windows|Android|Fuchsia|SunOS|NetBSD")
set(COMPILER_RT_HAS_PROFILE TRUE)
else()
set(COMPILER_RT_HAS_PROFILE FALSE)
diff --git a/lib/asan/asan_allocator.h b/lib/asan/asan_allocator.h
index 51fba254a..c9b37dc7a 100644
--- a/lib/asan/asan_allocator.h
+++ b/lib/asan/asan_allocator.h
@@ -148,6 +148,7 @@ const uptr kAllocatorSpace = 0x600000000000ULL;
const uptr kAllocatorSize = 0x40000000000ULL; // 4T.
typedef DefaultSizeClassMap SizeClassMap;
# endif
+template <typename AddressSpaceViewTy>
struct AP64 { // Allocator64 parameters. Deliberately using a short name.
static const uptr kSpaceBeg = kAllocatorSpace;
static const uptr kSpaceSize = kAllocatorSize;
@@ -155,9 +156,12 @@ struct AP64 { // Allocator64 parameters. Deliberately using a short name.
typedef __asan::SizeClassMap SizeClassMap;
typedef AsanMapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
+ using AddressSpaceView = AddressSpaceViewTy;
};
-typedef SizeClassAllocator64<AP64> PrimaryAllocator;
+template <typename AddressSpaceView>
+using PrimaryAllocatorASVT = SizeClassAllocator64<AP64<AddressSpaceView>>;
+using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>;
#else // Fallback to SizeClassAllocator32.
static const uptr kRegionSizeLog = 20;
static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
@@ -188,11 +192,21 @@ using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>;
#endif // SANITIZER_CAN_USE_ALLOCATOR64
static const uptr kNumberOfSizeClasses = SizeClassMap::kNumClasses;
-typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
-typedef LargeMmapAllocator<AsanMapUnmapCallback> SecondaryAllocator;
-typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
- SecondaryAllocator> AsanAllocator;
+template <typename AddressSpaceView>
+using AllocatorCacheASVT =
+ SizeClassAllocatorLocalCache<PrimaryAllocatorASVT<AddressSpaceView>>;
+using AllocatorCache = AllocatorCacheASVT<LocalAddressSpaceView>;
+template <typename AddressSpaceView>
+using SecondaryAllocatorASVT =
+ LargeMmapAllocator<AsanMapUnmapCallback, DefaultLargeMmapAllocatorPtrArray,
+ AddressSpaceView>;
+template <typename AddressSpaceView>
+using AsanAllocatorASVT =
+ CombinedAllocator<PrimaryAllocatorASVT<AddressSpaceView>,
+ AllocatorCacheASVT<AddressSpaceView>,
+ SecondaryAllocatorASVT<AddressSpaceView>>;
+using AsanAllocator = AsanAllocatorASVT<LocalAddressSpaceView>;
struct AsanThreadLocalMallocStorage {
uptr quarantine_cache[16];
diff --git a/lib/asan/asan_errors.cc b/lib/asan/asan_errors.cc
index 33d0613f7..0ecd30dca 100644
--- a/lib/asan/asan_errors.cc
+++ b/lib/asan/asan_errors.cc
@@ -125,9 +125,8 @@ void ErrorAllocTypeMismatch::Print() {
Decorator d;
Printf("%s", d.Error());
Report("ERROR: AddressSanitizer: %s (%s vs %s) on %p\n",
- scariness.GetDescription(),
- alloc_names[alloc_type], dealloc_names[dealloc_type],
- addr_description.addr);
+ scariness.GetDescription(), alloc_names[alloc_type],
+ dealloc_names[dealloc_type], addr_description.Address());
Printf("%s", d.Default());
CHECK_GT(dealloc_stack->size, 0);
scariness.Print();
diff --git a/lib/asan/asan_errors.h b/lib/asan/asan_errors.h
index 574197ebf..7ddd7e94e 100644
--- a/lib/asan/asan_errors.h
+++ b/lib/asan/asan_errors.h
@@ -110,8 +110,8 @@ struct ErrorFreeNotMalloced : ErrorBase {
struct ErrorAllocTypeMismatch : ErrorBase {
const BufferedStackTrace *dealloc_stack;
- HeapAddressDescription addr_description;
AllocType alloc_type, dealloc_type;
+ AddressDescription addr_description;
ErrorAllocTypeMismatch() = default; // (*)
ErrorAllocTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr,
@@ -119,9 +119,8 @@ struct ErrorAllocTypeMismatch : ErrorBase {
: ErrorBase(tid, 10, "alloc-dealloc-mismatch"),
dealloc_stack(stack),
alloc_type(alloc_type_),
- dealloc_type(dealloc_type_) {
- GetHeapAddressInformation(addr, 1, &addr_description);
- };
+ dealloc_type(dealloc_type_),
+ addr_description(addr, 1, false) {}
void Print();
};
diff --git a/lib/asan/asan_posix.cc b/lib/asan/asan_posix.cc
index 17c28b0ae..ca99c04b3 100644
--- a/lib/asan/asan_posix.cc
+++ b/lib/asan/asan_posix.cc
@@ -40,6 +40,51 @@ void AsanOnDeadlySignal(int signo, void *siginfo, void *context) {
// ---------------------- TSD ---------------- {{{1
+#if SANITIZER_NETBSD || SANITIZER_FREEBSD
+// Thread Static Data cannot be used in early init on NetBSD and FreeBSD.
+// Reuse the Asan TSD API for compatibility with existing code
+// with an alternative implementation.
+
+static void (*tsd_destructor)(void *tsd) = nullptr;
+
+struct tsd_key {
+ tsd_key() : key(nullptr) {}
+ ~tsd_key() {
+ CHECK(tsd_destructor);
+ if (key)
+ (*tsd_destructor)(key);
+ }
+ void *key;
+};
+
+static thread_local struct tsd_key key;
+
+void AsanTSDInit(void (*destructor)(void *tsd)) {
+ CHECK(!tsd_destructor);
+ tsd_destructor = destructor;
+}
+
+void *AsanTSDGet() {
+ CHECK(tsd_destructor);
+ return key.key;
+}
+
+void AsanTSDSet(void *tsd) {
+ CHECK(tsd_destructor);
+ CHECK(tsd);
+ CHECK(!key.key);
+ key.key = tsd;
+}
+
+void PlatformTSDDtor(void *tsd) {
+ CHECK(tsd_destructor);
+ CHECK_EQ(key.key, tsd);
+ key.key = nullptr;
+ // Make sure that signal handler can not see a stale current thread pointer.
+ atomic_signal_fence(memory_order_seq_cst);
+ AsanThread::TSDDtor(tsd);
+}
+#else
static pthread_key_t tsd_key;
static bool tsd_key_inited = false;
void AsanTSDInit(void (*destructor)(void *tsd)) {
@@ -67,6 +112,7 @@ void PlatformTSDDtor(void *tsd) {
}
AsanThread::TSDDtor(tsd);
}
+#endif
} // namespace __asan
#endif // SANITIZER_POSIX
diff --git a/lib/asan/asan_rtl.cc b/lib/asan/asan_rtl.cc
index 0ecbcd594..13344f3b8 100644
--- a/lib/asan/asan_rtl.cc
+++ b/lib/asan/asan_rtl.cc
@@ -383,6 +383,19 @@ void PrintAddressSpaceLayout() {
kHighShadowBeg > kMidMemEnd);
}
+#if defined(__thumb__) && defined(__linux__)
+#define START_BACKGROUND_THREAD_IN_ASAN_INTERNAL
+#endif
+
+#ifndef START_BACKGROUND_THREAD_IN_ASAN_INTERNAL
+static bool UNUSED __local_asan_dyninit = [] {
+ MaybeStartBackgroudThread();
+ SetSoftRssLimitExceededCallback(AsanSoftRssLimitExceededCallback);
+
+ return false;
+}();
+#endif
+
static void AsanInitInternal() {
if (LIKELY(asan_inited)) return;
SanitizerToolName = "AddressSanitizer";
@@ -457,8 +470,10 @@ static void AsanInitInternal() {
allocator_options.SetFrom(flags(), common_flags());
InitializeAllocator(allocator_options);
+#ifdef START_BACKGROUND_THREAD_IN_ASAN_INTERNAL
MaybeStartBackgroudThread();
SetSoftRssLimitExceededCallback(AsanSoftRssLimitExceededCallback);
+#endif
// On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited
// should be set to 1 prior to initializing the threads.
diff --git a/lib/asan/asan_thread.cc b/lib/asan/asan_thread.cc
index faf423d30..0895e4ce0 100644
--- a/lib/asan/asan_thread.cc
+++ b/lib/asan/asan_thread.cc
@@ -223,9 +223,11 @@ void AsanThread::Init(const InitOptions *options) {
atomic_store(&stack_switching_, false, memory_order_release);
CHECK_EQ(this->stack_size(), 0U);
SetThreadStackAndTls(options);
- CHECK_GT(this->stack_size(), 0U);
- CHECK(AddrIsInMem(stack_bottom_));
- CHECK(AddrIsInMem(stack_top_ - 1));
+ if (stack_top_ != stack_bottom_) {
+ CHECK_GT(this->stack_size(), 0U);
+ CHECK(AddrIsInMem(stack_bottom_));
+ CHECK(AddrIsInMem(stack_top_ - 1));
+ }
ClearShadowForThreadStackAndTLS();
fake_stack_ = nullptr;
if (__asan_option_detect_stack_use_after_return)
@@ -289,20 +291,23 @@ void AsanThread::SetThreadStackAndTls(const InitOptions *options) {
DCHECK_EQ(options, nullptr);
uptr tls_size = 0;
uptr stack_size = 0;
- GetThreadStackAndTls(tid() == 0, const_cast<uptr *>(&stack_bottom_),
- const_cast<uptr *>(&stack_size), &tls_begin_, &tls_size);
+ GetThreadStackAndTls(tid() == 0, &stack_bottom_, &stack_size, &tls_begin_,
+ &tls_size);
stack_top_ = stack_bottom_ + stack_size;
tls_end_ = tls_begin_ + tls_size;
dtls_ = DTLS_Get();
- int local;
- CHECK(AddrIsInStack((uptr)&local));
+ if (stack_top_ != stack_bottom_) {
+ int local;
+ CHECK(AddrIsInStack((uptr)&local));
+ }
}
#endif // !SANITIZER_FUCHSIA && !SANITIZER_RTEMS
void AsanThread::ClearShadowForThreadStackAndTLS() {
- PoisonShadow(stack_bottom_, stack_top_ - stack_bottom_, 0);
+ if (stack_top_ != stack_bottom_)
+ PoisonShadow(stack_bottom_, stack_top_ - stack_bottom_, 0);
if (tls_begin_ != tls_end_) {
uptr tls_begin_aligned = RoundDownTo(tls_begin_, SHADOW_GRANULARITY);
uptr tls_end_aligned = RoundUpTo(tls_end_, SHADOW_GRANULARITY);
@@ -314,6 +319,9 @@ void AsanThread::ClearShadowForThreadStackAndTLS() {
bool AsanThread::GetStackFrameAccessByAddr(uptr addr,
StackFrameAccess *access) {
+ if (stack_top_ == stack_bottom_)
+ return false;
+
uptr bottom = 0;
if (AddrIsInStack(addr)) {
bottom = stack_bottom();
diff --git a/lib/builtins/CMakeLists.txt b/lib/builtins/CMakeLists.txt
index 82332967b..77947417b 100644
--- a/lib/builtins/CMakeLists.txt
+++ b/lib/builtins/CMakeLists.txt
@@ -505,7 +505,9 @@ set(mips64el_SOURCES ${GENERIC_TF_SOURCES}
set(powerpc64_SOURCES
ppc/divtc3.c
ppc/fixtfdi.c
+ ppc/fixunstfti.c
ppc/fixunstfdi.c
+ ppc/floattitf.c
ppc/floatditf.c
ppc/floatunditf.c
ppc/gcc_qadd.c
diff --git a/lib/builtins/ppc/fixunstfti.c b/lib/builtins/ppc/fixunstfti.c
new file mode 100644
index 000000000..fa21084cb
--- /dev/null
+++ b/lib/builtins/ppc/fixunstfti.c
@@ -0,0 +1,106 @@
+//===-- lib/builtins/ppc/fixunstfti.c - Convert long double->int128 *-C -*-===//
+//
+// 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 file implements converting the 128bit IBM/PowerPC long double (double-
+// double) data type to an unsigned 128 bit integer.
+//
+//===----------------------------------------------------------------------===//
+
+#include "../int_math.h"
+#define BIAS 1023
+
+/* Convert long double into an unsigned 128-bit integer. */
+__uint128_t __fixunstfti(long double input) {
+
+ /* If we are trying to convert a NaN, return the NaN bit pattern. */
+ if (crt_isnan(input)) {
+ return ((__uint128_t)0x7FF8000000000000ll) << 64 |
+ (__uint128_t)0x0000000000000000ll;
+ }
+
+ __uint128_t result, hiResult, loResult;
+ int hiExponent, loExponent, shift;
+ /* The long double representation, with the high and low portions of
+ * the long double, and the corresponding bit patterns of each double. */
+ union {
+ long double ld;
+ double d[2]; /* [0] is the high double, [1] is the low double. */
+ unsigned long long ull[2]; /* High and low doubles as 64-bit integers. */
+ } ldUnion;
+
+ /* If the long double is less than 1.0 or negative,
+ * return 0.0. */
+ if (input < 1.0)
+ return 0.0;
+
+ /* Retrieve the 64-bit patterns of high and low doubles.
+ * Compute the unbiased exponent of both high and low doubles by
+ * removing the signs, isolating the exponent, and subtracting
+ * the bias from it. */
+ ldUnion.ld = input;
+ hiExponent = ((ldUnion.ull[0] & 0x7FFFFFFFFFFFFFFFll) >> 52) - BIAS;
+ loExponent = ((ldUnion.ull[1] & 0x7FFFFFFFFFFFFFFFll) >> 52) - BIAS;
+
+ /* Convert each double into int64; they will be added to the int128 result.
+ * CASE 1: High or low double fits in int64
+ * - Convert the each double normally into int64.
+ *
+ * CASE 2: High or low double does not fit in int64
+ * - Scale the double to fit within a 64-bit integer
+ * - Calculate the shift (amount to scale the double by in the int128)
+ * - Clear all the bits of the exponent (with 0x800FFFFFFFFFFFFF)
+ * - Add BIAS+53 (0x4350000000000000) to exponent to correct the value
+ * - Scale (move) the double to the correct place in the int128
+ * (Move it by 2^53 places)
+ *
+ * Note: If the high double is assumed to be positive, an unsigned conversion
+ * from long double to 64-bit integer is needed. The low double can be either
+ * positive or negative, so a signed conversion is needed to retain the result
+ * of the low double and to ensure it does not simply get converted to 0. */
+
+ /* CASE 1 - High double fits in int64. */
+ if (hiExponent < 63) {
+ hiResult = (unsigned long long)ldUnion.d[0];
+ } else if (hiExponent < 128) {
+ /* CASE 2 - High double does not fit in int64, scale and convert it. */
+ shift = hiExponent - 54;
+ ldUnion.ull[0] &= 0x800FFFFFFFFFFFFFll;
+ ldUnion.ull[0] |= 0x4350000000000000ll;
+ hiResult = (unsigned long long)ldUnion.d[0];
+ hiResult <<= shift;
+ } else {
+ /* Detect cases for overflow. When the exponent of the high
+ * double is greater than 128 bits and when the long double
+ * input is positive, return the max 128-bit integer.
+ * For negative inputs with exponents > 128, return 1, like gcc. */
+ if (ldUnion.d[0] > 0) {
+ return ((__uint128_t)0xFFFFFFFFFFFFFFFFll) << 64 |
+ (__uint128_t)0xFFFFFFFFFFFFFFFFll;
+ } else {
+ return ((__uint128_t)0x0000000000000000ll) << 64 |
+ (__uint128_t)0x0000000000000001ll;
+ }
+ }
+
+ /* CASE 1 - Low double fits in int64. */
+ if (loExponent < 63) {
+ loResult = (long long)ldUnion.d[1];
+ } else {
+ /* CASE 2 - Low double does not fit in int64, scale and convert it. */
+ shift = loExponent - 54;
+ ldUnion.ull[1] &= 0x800FFFFFFFFFFFFFll;
+ ldUnion.ull[1] |= 0x4350000000000000ll;
+ loResult = (long long)ldUnion.d[1];
+ loResult <<= shift;
+ }
+
+ /* Add the high and low doublewords together to form a 128 bit integer. */
+ result = loResult + hiResult;
+ return result;
+}
diff --git a/lib/builtins/ppc/floattitf.c b/lib/builtins/ppc/floattitf.c
new file mode 100644
index 000000000..b8e297b6b
--- /dev/null
+++ b/lib/builtins/ppc/floattitf.c
@@ -0,0 +1,48 @@
+//===-- lib/builtins/ppc/floattitf.c - Convert int128->long double -*-C -*-===//
+//
+// 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 file implements converting a signed 128 bit integer to a 128bit IBM /
+// PowerPC long double (double-double) value.
+//
+//===----------------------------------------------------------------------===//
+
+#include <stdint.h>
+
+/* Conversions from signed and unsigned 64-bit int to long double. */
+long double __floatditf(int64_t);
+long double __floatunditf(uint64_t);
+
+/* Convert a signed 128-bit integer to long double.
+ * This uses the following property: Let hi and lo be 64-bits each,
+ * and let signed_val_k() and unsigned_val_k() be the value of the
+ * argument interpreted as a signed or unsigned k-bit integer. Then,
+ *
+ * signed_val_128(hi,lo) = signed_val_64(hi) * 2^64 + unsigned_val_64(lo)
+ * = (long double)hi * 2^64 + (long double)lo,
+ *
+ * where (long double)hi and (long double)lo are signed and
+ * unsigned 64-bit integer to long double conversions, respectively.
+ */
+long double __floattitf(__int128_t arg) {
+ /* Split the int128 argument into 64-bit high and low int64 parts. */
+ int64_t ArgHiPart = (int64_t)(arg >> 64);
+ uint64_t ArgLoPart = (uint64_t)arg;
+
+ /* Convert each 64-bit part into long double. The high part
+ * must be a signed conversion and the low part an unsigned conversion
+ * to ensure the correct result. */
+ long double ConvertedHiPart = __floatditf(ArgHiPart);
+ long double ConvertedLoPart = __floatunditf(ArgLoPart);
+
+ /* The low bit of ArgHiPart corresponds to the 2^64 bit in arg.
+ * Multiply the high part by 2^64 to undo the right shift by 64-bits
+ * done in the splitting. Then, add to the low part to obtain the
+ * final result. */
+ return ((ConvertedHiPart * 0x1.0p64) + ConvertedLoPart);
+}
diff --git a/lib/fuzzer/CMakeLists.txt b/lib/fuzzer/CMakeLists.txt
index 8ba3f8a5a..caea9734f 100644
--- a/lib/fuzzer/CMakeLists.txt
+++ b/lib/fuzzer/CMakeLists.txt
@@ -3,8 +3,8 @@ set(LIBFUZZER_SOURCES
FuzzerDataFlowTrace.cpp
FuzzerDriver.cpp
FuzzerExtFunctionsDlsym.cpp
- FuzzerExtFunctionsWeakAlias.cpp
FuzzerExtFunctionsWeak.cpp
+ FuzzerExtFunctionsWindows.cpp
FuzzerExtraCounters.cpp
FuzzerIO.cpp
FuzzerIOPosix.cpp
@@ -25,6 +25,8 @@ set(LIBFUZZER_SOURCES
FuzzerUtilWindows.cpp)
set(LIBFUZZER_HEADERS
+ FuzzerBuiltins.h
+ FuzzerBuiltinsMsvc.h
FuzzerCommand.h
FuzzerCorpus.h
FuzzerDataFlowTrace.h
diff --git a/lib/fuzzer/FuzzerBuiltins.h b/lib/fuzzer/FuzzerBuiltins.h
new file mode 100644
index 000000000..a80938d9a
--- /dev/null
+++ b/lib/fuzzer/FuzzerBuiltins.h
@@ -0,0 +1,36 @@
+//===- FuzzerBuiltins.h - Internal header for builtins ----------*- C++ -* ===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Wrapper functions and marcos around builtin functions.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FUZZER_BUILTINS_H
+#define LLVM_FUZZER_BUILTINS_H
+
+#include "FuzzerDefs.h"
+
+#if !LIBFUZZER_MSVC
+#include <cstdint>
+
+#define GET_CALLER_PC() __builtin_return_address(0)
+
+namespace fuzzer {
+
+inline uint8_t Bswap(uint8_t x) { return x; }
+inline uint16_t Bswap(uint16_t x) { return __builtin_bswap16(x); }
+inline uint32_t Bswap(uint32_t x) { return __builtin_bswap32(x); }
+inline uint64_t Bswap(uint64_t x) { return __builtin_bswap64(x); }
+
+inline uint32_t Clzll(unsigned long long X) { return __builtin_clzll(X); }
+inline uint32_t Clz(unsigned long long X) { return __builtin_clz(X); }
+inline int Popcountll(unsigned long long X) { return __builtin_popcountll(X); }
+
+} // namespace fuzzer
+
+#endif // !LIBFUZZER_MSVC
+#endif // LLVM_FUZZER_BUILTINS_H
diff --git a/lib/fuzzer/FuzzerBuiltinsMsvc.h b/lib/fuzzer/FuzzerBuiltinsMsvc.h
new file mode 100644
index 000000000..67dd57ff9
--- /dev/null
+++ b/lib/fuzzer/FuzzerBuiltinsMsvc.h
@@ -0,0 +1,59 @@
+//===- FuzzerBuiltinsMSVC.h - Internal header for builtins ------*- C++ -* ===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Wrapper functions and marcos that use intrinsics instead of builtin functions
+// which cannot be compiled by MSVC.
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_FUZZER_BUILTINS_MSVC_H
+#define LLVM_FUZZER_BUILTINS_MSVC_H
+
+#include "FuzzerDefs.h"
+
+#if LIBFUZZER_MSVC
+#if !defined(_M_ARM) && !defined(_M_X64)
+#error "_BitScanReverse64 unavailable on this platform so MSVC is unsupported."
+#endif
+#include <intrin.h>
+#include <cstdint>
+#include <cstdlib>
+
+// __builtin_return_address() cannot be compiled with MSVC. Use the equivalent
+// from <intrin.h>
+#define GET_CALLER_PC() reinterpret_cast<uintptr_t>(_ReturnAddress())
+
+namespace fuzzer {
+
+inline uint8_t Bswap(uint8_t x) { return x; }
+// Use alternatives to __builtin functions from <stdlib.h> and <intrin.h> on
+// Windows since the builtins are not supported by MSVC.
+inline uint16_t Bswap(uint16_t x) { return _byteswap_ushort(x); }
+inline uint32_t Bswap(uint32_t x) { return _byteswap_ulong(x); }
+inline uint64_t Bswap(uint64_t x) { return _byteswap_uint64(x); }
+
+// The functions below were mostly copied from
+// compiler-rt/lib/builtins/int_lib.h which defines the __builtin functions used
+// outside of Windows.
+inline uint32_t Clzll(uint64_t X) {
+ unsigned long LeadZeroIdx = 0;
+ if (_BitScanReverse64(&LeadZeroIdx, X)) return 63 - LeadZeroIdx;
+ return 64;
+}
+
+inline uint32_t Clz(uint32_t X) {
+ unsigned long LeadZeroIdx = 0;
+ if (_BitScanReverse(&LeadZeroIdx, X)) return 31 - LeadZeroIdx;
+ return 32;
+}
+
+inline int Popcountll(unsigned long long X) { return __popcnt64(X); }
+
+} // namespace fuzzer
+
+#endif // LIBFUZER_MSVC
+#endif // LLVM_FUZZER_BUILTINS_MSVC_H
diff --git a/lib/fuzzer/FuzzerCorpus.h b/lib/fuzzer/FuzzerCorpus.h
index 8ad14656c..f844c07c7 100644
--- a/lib/fuzzer/FuzzerCorpus.h
+++ b/lib/fuzzer/FuzzerCorpus.h
@@ -238,12 +238,6 @@ class InputCorpus {
return false;
}
- bool IsFeatureNew(size_t Idx, uint32_t NewSize, bool Shrink) {
- assert(NewSize);
- uint32_t OldSize = GetFeature(Idx % kFeatureSetSize);
- return OldSize == 0 || (Shrink && OldSize > NewSize);
- }
-
size_t NumFeatures() const { return NumAddedFeatures; }
size_t NumFeatureUpdates() const { return NumUpdatedFeatures; }
diff --git a/lib/fuzzer/FuzzerDefs.h b/lib/fuzzer/FuzzerDefs.h
index 31655d562..c3dccbcd8 100644
--- a/lib/fuzzer/FuzzerDefs.h
+++ b/lib/fuzzer/FuzzerDefs.h
@@ -82,6 +82,13 @@
#error "Support for your platform has not been implemented"
#endif
+#if defined(_MSC_VER) && !defined(__clang__)
+// MSVC compiler is being used.
+#define LIBFUZZER_MSVC 1
+#else
+#define LIBFUZZER_MSVC 0
+#endif
+
#ifndef __has_attribute
# define __has_attribute(x) 0
#endif
@@ -183,11 +190,6 @@ typedef int (*UserCallback)(const uint8_t *Data, size_t Size);
int FuzzerDriver(int *argc, char ***argv, UserCallback Callback);
-inline uint8_t Bswap(uint8_t x) { return x; }
-inline uint16_t Bswap(uint16_t x) { return __builtin_bswap16(x); }
-inline uint32_t Bswap(uint32_t x) { return __builtin_bswap32(x); }
-inline uint64_t Bswap(uint64_t x) { return __builtin_bswap64(x); }
-
uint8_t *ExtraCountersBegin();
uint8_t *ExtraCountersEnd();
void ClearExtraCounters();
diff --git a/lib/fuzzer/FuzzerDriver.cpp b/lib/fuzzer/FuzzerDriver.cpp
index 918a972ff..ff2a639ac 100644
--- a/lib/fuzzer/FuzzerDriver.cpp
+++ b/lib/fuzzer/FuzzerDriver.cpp
@@ -617,10 +617,6 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) {
Options.PrintFinalStats = Flags.print_final_stats;
Options.PrintCorpusStats = Flags.print_corpus_stats;
Options.PrintCoverage = Flags.print_coverage;
- Options.PrintUnstableStats = Flags.print_unstable_stats;
- if (Flags.handle_unstable == TracePC::MinUnstable ||
- Flags.handle_unstable == TracePC::ZeroUnstable)
- Options.HandleUnstable = Flags.handle_unstable;
Options.DumpCoverage = Flags.dump_coverage;
if (Flags.exit_on_src_pos)
Options.ExitOnSrcPos = Flags.exit_on_src_pos;
diff --git a/lib/fuzzer/FuzzerExtFunctionsWeakAlias.cpp b/lib/fuzzer/FuzzerExtFunctionsWeakAlias.cpp
deleted file mode 100644
index e10f7b4dc..000000000
--- a/lib/fuzzer/FuzzerExtFunctionsWeakAlias.cpp
+++ /dev/null
@@ -1,56 +0,0 @@
-//===- FuzzerExtFunctionsWeakAlias.cpp - Interface to external functions --===//
-//
-// The LLVM Compiler Infrastructure
-//
-// This file is distributed under the University of Illinois Open Source
-// License. See LICENSE.TXT for details.
-//
-//===----------------------------------------------------------------------===//
-// Implementation using weak aliases. Works for Windows.
-//===----------------------------------------------------------------------===//
-#include "FuzzerDefs.h"
-#if LIBFUZZER_WINDOWS
-
-#include "FuzzerExtFunctions.h"
-#include "FuzzerIO.h"
-
-using namespace fuzzer;
-
-extern "C" {
-// Declare these symbols as weak to allow them to be optionally defined.
-#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
- RETURN_TYPE NAME##Def FUNC_SIG { \
- Printf("ERROR: Function \"%s\" not defined.\n", #NAME); \
- exit(1); \
- } \
- RETURN_TYPE NAME FUNC_SIG __attribute__((weak, alias(#NAME "Def")));
-
-#include "FuzzerExtFunctions.def"
-
-#undef EXT_FUNC
-}
-
-template <typename T>
-static T *GetFnPtr(T *Fun, T *FunDef, const char *FnName, bool WarnIfMissing) {
- if (Fun == FunDef) {
- if (WarnIfMissing)
- Printf("WARNING: Failed to find function \"%s\".\n", FnName);
- return nullptr;
- }
- return Fun;
-}
-
-namespace fuzzer {
-
-ExternalFunctions::ExternalFunctions() {
-#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
- this->NAME = GetFnPtr<decltype(::NAME)>(::NAME, ::NAME##Def, #NAME, WARN);
-
-#include "FuzzerExtFunctions.def"
-
-#undef EXT_FUNC
-}
-
-} // namespace fuzzer
-
-#endif // LIBFUZZER_WINDOWS
diff --git a/lib/fuzzer/FuzzerExtFunctionsWindows.cpp b/lib/fuzzer/FuzzerExtFunctionsWindows.cpp
new file mode 100644
index 000000000..b01871439
--- /dev/null
+++ b/lib/fuzzer/FuzzerExtFunctionsWindows.cpp
@@ -0,0 +1,83 @@
+//=== FuzzerExtWindows.cpp - Interface to external functions --------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+// Implementation of FuzzerExtFunctions for Windows. Uses alternatename when
+// compiled with MSVC. Uses weak aliases when compiled with clang. Unfortunately
+// the method each compiler supports is not supported by the other.
+//===----------------------------------------------------------------------===//
+#include "FuzzerDefs.h"
+#if LIBFUZZER_WINDOWS
+
+#include "FuzzerExtFunctions.h"
+#include "FuzzerIO.h"
+
+using namespace fuzzer;
+
+// Intermediate macro to ensure the parameter is expanded before stringified.
+#define STRINGIFY_(A) #A
+#define STRINGIFY(A) STRINGIFY_(A)
+
+#if LIBFUZZER_MSVC
+// Copied from compiler-rt/lib/sanitizer_common/sanitizer_win_defs.h
+#if defined(_M_IX86) || defined(__i386__)
+#define WIN_SYM_PREFIX "_"
+#else
+#define WIN_SYM_PREFIX
+#endif
+
+// Declare external functions as having alternativenames, so that we can
+// determine if they are not defined.
+#define EXTERNAL_FUNC(Name, Default) \
+ __pragma(comment(linker, "/alternatename:" WIN_SYM_PREFIX STRINGIFY( \
+ Name) "=" WIN_SYM_PREFIX STRINGIFY(Default)))
+#else
+// Declare external functions as weak to allow them to default to a specified
+// function if not defined explicitly. We must use weak symbols because clang's
+// support for alternatename is not 100%, see
+// https://bugs.llvm.org/show_bug.cgi?id=40218 for more details.
+#define EXTERNAL_FUNC(Name, Default) \
+ __attribute__((weak, alias(STRINGIFY(Default))))
+#endif // LIBFUZZER_MSVC
+
+extern "C" {
+#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
+ RETURN_TYPE NAME##Def FUNC_SIG { \
+ Printf("ERROR: Function \"%s\" not defined.\n", #NAME); \
+ exit(1); \
+ } \
+ EXTERNAL_FUNC(NAME, NAME##Def) RETURN_TYPE NAME FUNC_SIG;
+
+#include "FuzzerExtFunctions.def"
+
+#undef EXT_FUNC
+}
+
+template <typename T>
+static T *GetFnPtr(T *Fun, T *FunDef, const char *FnName, bool WarnIfMissing) {
+ if (Fun == FunDef) {
+ if (WarnIfMissing)
+ Printf("WARNING: Failed to find function \"%s\".\n", FnName);
+ return nullptr;
+ }
+ return Fun;
+}
+
+namespace fuzzer {
+
+ExternalFunctions::ExternalFunctions() {
+#define EXT_FUNC(NAME, RETURN_TYPE, FUNC_SIG, WARN) \
+ this->NAME = GetFnPtr<decltype(::NAME)>(::NAME, ::NAME##Def, #NAME, WARN);
+
+#include "FuzzerExtFunctions.def"
+
+#undef EXT_FUNC
+}
+
+} // namespace fuzzer
+
+#endif // LIBFUZZER_WINDOWS
diff --git a/lib/fuzzer/FuzzerFlags.def b/lib/fuzzer/FuzzerFlags.def
index 0417dda5b..91281c979 100644
--- a/lib/fuzzer/FuzzerFlags.def
+++ b/lib/fuzzer/FuzzerFlags.def
@@ -17,7 +17,7 @@ FUZZER_FLAG_INT(runs, -1,
FUZZER_FLAG_INT(max_len, 0, "Maximum length of the test input. "
"If 0, libFuzzer tries to guess a good value based on the corpus "
"and reports it. ")
-FUZZER_FLAG_INT(len_control, 1000, "Try generating small inputs first, "
+FUZZER_FLAG_INT(len_control, 100, "Try generating small inputs first, "
"then try larger inputs over time. Specifies the rate at which the length "
"limit is increased (smaller == faster). If 0, immediately try inputs with "
"size up to max_len.")
@@ -110,15 +110,6 @@ FUZZER_FLAG_INT(print_coverage, 0, "If 1, print coverage information as text"
FUZZER_FLAG_INT(dump_coverage, 0, "Deprecated."
" If 1, dump coverage information as a"
" .sancov file at exit.")
-FUZZER_FLAG_INT(handle_unstable, 0, "Experimental."
- " Executes every input 3 times in total if a unique feature"
- " is found during the first execution."
- " If 1, we only use the minimum hit count from the 3 runs"
- " to determine whether an input is interesting."
- " If 2, we disregard edges that are found unstable for"
- " feature collection.")
-FUZZER_FLAG_INT(print_unstable_stats, 0, "Experimental."
- " If 1, print unstable statistics at exit.")
FUZZER_FLAG_INT(handle_segv, 1, "If 1, try to intercept SIGSEGV.")
FUZZER_FLAG_INT(handle_bus, 1, "If 1, try to intercept SIGBUS.")
FUZZER_FLAG_INT(handle_abrt, 1, "If 1, try to intercept SIGABRT.")
diff --git a/lib/fuzzer/FuzzerInternal.h b/lib/fuzzer/FuzzerInternal.h
index bfc898248..a7fdc89cb 100644
--- a/lib/fuzzer/FuzzerInternal.h
+++ b/lib/fuzzer/FuzzerInternal.h
@@ -67,7 +67,6 @@ public:
static void StaticGracefulExitCallback();
void ExecuteCallback(const uint8_t *Data, size_t Size);
- void CheckForUnstableCounters(const uint8_t *Data, size_t Size);
bool RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile = false,
InputInfo *II = nullptr, bool *FoundUniqFeatures = nullptr);
diff --git a/lib/fuzzer/FuzzerLoop.cpp b/lib/fuzzer/FuzzerLoop.cpp
index 09c57c3f6..a32a30723 100644
--- a/lib/fuzzer/FuzzerLoop.cpp
+++ b/lib/fuzzer/FuzzerLoop.cpp
@@ -355,8 +355,6 @@ void Fuzzer::PrintStats(const char *Where, const char *End, size_t Units) {
void Fuzzer::PrintFinalStats() {
if (Options.PrintCoverage)
TPC.PrintCoverage();
- if (Options.PrintUnstableStats)
- TPC.PrintUnstableStats();
if (Options.DumpCoverage)
TPC.DumpCoverage();
if (Options.PrintCorpusStats)
@@ -449,29 +447,6 @@ void Fuzzer::PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size) {
}
}
-void Fuzzer::CheckForUnstableCounters(const uint8_t *Data, size_t Size) {
- auto CBSetupAndRun = [&]() {
- ScopedEnableMsanInterceptorChecks S;
- UnitStartTime = system_clock::now();
- TPC.ResetMaps();
- RunningUserCallback = true;
- CB(Data, Size);
- RunningUserCallback = false;
- UnitStopTime = system_clock::now();
- };
-
- // Copy original run counters into our unstable counters
- TPC.InitializeUnstableCounters();
-
- // First Rerun
- CBSetupAndRun();
- if (TPC.UpdateUnstableCounters(Options.HandleUnstable)) {
- // Second Rerun
- CBSetupAndRun();
- TPC.UpdateAndApplyUnstableCounters(Options.HandleUnstable);
- }
-}
-
bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile,
InputInfo *II, bool *FoundUniqFeatures) {
if (!Size)
@@ -482,17 +457,6 @@ bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile,
UniqFeatureSetTmp.clear();
size_t FoundUniqFeaturesOfII = 0;
size_t NumUpdatesBefore = Corpus.NumFeatureUpdates();
- bool NewFeaturesUnstable = false;
-
- if (Options.HandleUnstable || Options.PrintUnstableStats) {
- TPC.CollectFeatures([&](size_t Feature) {
- if (Corpus.IsFeatureNew(Feature, Size, Options.Shrink))
- NewFeaturesUnstable = true;
- });
- if (NewFeaturesUnstable)
- CheckForUnstableCounters(Data, Size);
- }
-
TPC.CollectFeatures([&](size_t Feature) {
if (Corpus.AddFeature(Feature, Size, Options.Shrink))
UniqFeatureSetTmp.push_back(Feature);
@@ -501,12 +465,10 @@ bool Fuzzer::RunOne(const uint8_t *Data, size_t Size, bool MayDeleteFile,
II->UniqFeatureSet.end(), Feature))
FoundUniqFeaturesOfII++;
});
-
if (FoundUniqFeatures)
*FoundUniqFeatures = FoundUniqFeaturesOfII;
PrintPulseAndReportSlowInput(Data, Size);
size_t NumNewFeatures = Corpus.NumFeatureUpdates() - NumUpdatesBefore;
-
if (NumNewFeatures) {
TPC.UpdateObservedPCs();
Corpus.AddToCorpus({Data, Data + Size}, NumNewFeatures, MayDeleteFile,
diff --git a/lib/fuzzer/FuzzerOptions.h b/lib/fuzzer/FuzzerOptions.h
index bb642f1e2..ab90df82a 100644
--- a/lib/fuzzer/FuzzerOptions.h
+++ b/lib/fuzzer/FuzzerOptions.h
@@ -54,8 +54,6 @@ struct FuzzingOptions {
bool PrintFinalStats = false;
bool PrintCorpusStats = false;
bool PrintCoverage = false;
- bool PrintUnstableStats = false;
- int HandleUnstable = 0;
bool DumpCoverage = false;
bool DetectLeaks = true;
int PurgeAllocatorIntervalSec = 1;
diff --git a/lib/fuzzer/FuzzerTracePC.cpp b/lib/fuzzer/FuzzerTracePC.cpp
index 7ba75c7b2..80b33105b 100644
--- a/lib/fuzzer/FuzzerTracePC.cpp
+++ b/lib/fuzzer/FuzzerTracePC.cpp
@@ -13,6 +13,8 @@
//===----------------------------------------------------------------------===//
#include "FuzzerTracePC.h"
+#include "FuzzerBuiltins.h"
+#include "FuzzerBuiltinsMsvc.h"
#include "FuzzerCorpus.h"
#include "FuzzerDefs.h"
#include "FuzzerDictionary.h"
@@ -56,59 +58,6 @@ size_t TracePC::GetTotalPCCoverage() {
return Res;
}
-template<class CallBack>
-void TracePC::IterateInline8bitCounters(CallBack CB) const {
- if (NumInline8bitCounters && NumInline8bitCounters == NumPCsInPCTables) {
- size_t CounterIdx = 0;
- for (size_t i = 0; i < NumModulesWithInline8bitCounters; i++) {
- uint8_t *Beg = ModuleCounters[i].Start;
- size_t Size = ModuleCounters[i].Stop - Beg;
- assert(Size == (size_t)(ModulePCTable[i].Stop - ModulePCTable[i].Start));
- for (size_t j = 0; j < Size; j++, CounterIdx++)
- CB(i, j, CounterIdx);
- }
- }
-}
-
-// Initializes unstable counters by copying Inline8bitCounters to unstable
-// counters.
-void TracePC::InitializeUnstableCounters() {
- IterateInline8bitCounters([&](int i, int j, int UnstableIdx) {
- UnstableCounters[UnstableIdx].Counter = ModuleCounters[i].Start[j];
- });
-}
-
-// Compares the current counters with counters from previous runs
-// and records differences as unstable edges.
-bool TracePC::UpdateUnstableCounters(int UnstableMode) {
- bool Updated = false;
- IterateInline8bitCounters([&](int i, int j, int UnstableIdx) {
- if (ModuleCounters[i].Start[j] != UnstableCounters[UnstableIdx].Counter) {
- Updated = true;
- UnstableCounters[UnstableIdx].IsUnstable = true;
- if (UnstableMode == ZeroUnstable)
- UnstableCounters[UnstableIdx].Counter = 0;
- else if (UnstableMode == MinUnstable)
- UnstableCounters[UnstableIdx].Counter = std::min(
- ModuleCounters[i].Start[j], UnstableCounters[UnstableIdx].Counter);
- }
- });
- return Updated;
-}
-
-// Updates and applies unstable counters to ModuleCounters in single iteration
-void TracePC::UpdateAndApplyUnstableCounters(int UnstableMode) {
- IterateInline8bitCounters([&](int i, int j, int UnstableIdx) {
- if (ModuleCounters[i].Start[j] != UnstableCounters[UnstableIdx].Counter) {
- UnstableCounters[UnstableIdx].IsUnstable = true;
- if (UnstableMode == ZeroUnstable)
- ModuleCounters[i].Start[j] = 0;
- else if (UnstableMode == MinUnstable)
- ModuleCounters[i].Start[j] = std::min(
- ModuleCounters[i].Start[j], UnstableCounters[UnstableIdx].Counter);
- }
- });
-}
void TracePC::HandleInline8bitCountersInit(uint8_t *Start, uint8_t *Stop) {
if (Start == Stop) return;
@@ -243,10 +192,15 @@ void TracePC::UpdateObservedPCs() {
if (NumPCsInPCTables) {
if (NumInline8bitCounters == NumPCsInPCTables) {
- IterateInline8bitCounters([&](int i, int j, int CounterIdx) {
- if (ModuleCounters[i].Start[j])
- Observe(ModulePCTable[i].Start[j]);
- });
+ for (size_t i = 0; i < NumModulesWithInline8bitCounters; i++) {
+ uint8_t *Beg = ModuleCounters[i].Start;
+ size_t Size = ModuleCounters[i].Stop - Beg;
+ assert(Size ==
+ (size_t)(ModulePCTable[i].Stop - ModulePCTable[i].Start));
+ for (size_t j = 0; j < Size; j++)
+ if (Beg[j])
+ Observe(ModulePCTable[i].Start[j]);
+ }
} else if (NumGuards == NumPCsInPCTables) {
size_t GuardIdx = 1;
for (size_t i = 0; i < NumModules; i++) {
@@ -378,27 +332,6 @@ void TracePC::DumpCoverage() {
}
}
-void TracePC::PrintUnstableStats() {
- size_t count = 0;
- Printf("UNSTABLE_FUNCTIONS:\n");
- IterateInline8bitCounters([&](int i, int j, int UnstableIdx) {
- const PCTableEntry &TE = ModulePCTable[i].Start[j];
- if (UnstableCounters[UnstableIdx].IsUnstable) {
- count++;
- if (ObservedFuncs.count(TE.PC)) {
- auto VisualizePC = GetNextInstructionPc(TE.PC);
- std::string FunctionStr = DescribePC("%F", VisualizePC);
- if (FunctionStr.find("in ") == 0)
- FunctionStr = FunctionStr.substr(3);
- Printf("%s\n", FunctionStr.c_str());
- }
- }
- });
-
- Printf("stat::stability_rate: %.2f\n",
- 100 - static_cast<float>(count * 100) / NumInline8bitCounters);
-}
-
// Value profile.
// We keep track of various values that affect control flow.
// These values are inserted into a bit-set-based hash map.
@@ -446,9 +379,8 @@ void TracePC::HandleCmp(uintptr_t PC, T Arg1, T Arg2) {
TORC4.Insert(ArgXor, Arg1, Arg2);
else if (sizeof(T) == 8)
TORC8.Insert(ArgXor, Arg1, Arg2);
- uint64_t HammingDistance = __builtin_popcountll(ArgXor); // [0,64]
- uint64_t AbsoluteDistance =
- (Arg1 == Arg2 ? 0 : __builtin_clzll(Arg1 - Arg2) + 1);
+ uint64_t HammingDistance = Popcountll(ArgXor); // [0,64]
+ uint64_t AbsoluteDistance = (Arg1 == Arg2 ? 0 : Clzll(Arg1 - Arg2) + 1);
ValueProfileMap.AddValue(PC * 128 + HammingDistance);
ValueProfileMap.AddValue(PC * 128 + 64 + AbsoluteDistance);
}
@@ -491,7 +423,7 @@ extern "C" {
ATTRIBUTE_INTERFACE
ATTRIBUTE_NO_SANITIZE_ALL
void __sanitizer_cov_trace_pc_guard(uint32_t *Guard) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+ uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
uint32_t Idx = *Guard;
__sancov_trace_pc_pcs[Idx] = PC;
__sancov_trace_pc_guard_8bit_counters[Idx]++;
@@ -502,7 +434,7 @@ void __sanitizer_cov_trace_pc_guard(uint32_t *Guard) {
ATTRIBUTE_INTERFACE
ATTRIBUTE_NO_SANITIZE_ALL
void __sanitizer_cov_trace_pc() {
- uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+ uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
uintptr_t Idx = PC & (((uintptr_t)1 << fuzzer::TracePC::kTracePcBits) - 1);
__sancov_trace_pc_pcs[Idx] = PC;
__sancov_trace_pc_guard_8bit_counters[Idx]++;
@@ -527,7 +459,7 @@ void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
ATTRIBUTE_INTERFACE
ATTRIBUTE_NO_SANITIZE_ALL
void __sanitizer_cov_trace_pc_indir(uintptr_t Callee) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+ uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
fuzzer::TPC.HandleCallerCallee(PC, Callee);
}
@@ -535,7 +467,7 @@ ATTRIBUTE_INTERFACE
ATTRIBUTE_NO_SANITIZE_ALL
ATTRIBUTE_TARGET_POPCNT
void __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t Arg2) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+ uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
}
@@ -546,7 +478,7 @@ ATTRIBUTE_TARGET_POPCNT
// the behaviour of __sanitizer_cov_trace_cmp[1248] ones. This, however,
// should be changed later to make full use of instrumentation.
void __sanitizer_cov_trace_const_cmp8(uint64_t Arg1, uint64_t Arg2) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+ uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
}
@@ -554,7 +486,7 @@ ATTRIBUTE_INTERFACE
ATTRIBUTE_NO_SANITIZE_ALL
ATTRIBUTE_TARGET_POPCNT
void __sanitizer_cov_trace_cmp4(uint32_t Arg1, uint32_t Arg2) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+ uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
}
@@ -562,7 +494,7 @@ ATTRIBUTE_INTERFACE
ATTRIBUTE_NO_SANITIZE_ALL
ATTRIBUTE_TARGET_POPCNT
void __sanitizer_cov_trace_const_cmp4(uint32_t Arg1, uint32_t Arg2) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+ uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
}
@@ -570,7 +502,7 @@ ATTRIBUTE_INTERFACE
ATTRIBUTE_NO_SANITIZE_ALL
ATTRIBUTE_TARGET_POPCNT
void __sanitizer_cov_trace_cmp2(uint16_t Arg1, uint16_t Arg2) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+ uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
}
@@ -578,7 +510,7 @@ ATTRIBUTE_INTERFACE
ATTRIBUTE_NO_SANITIZE_ALL
ATTRIBUTE_TARGET_POPCNT
void __sanitizer_cov_trace_const_cmp2(uint16_t Arg1, uint16_t Arg2) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+ uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
}
@@ -586,7 +518,7 @@ ATTRIBUTE_INTERFACE
ATTRIBUTE_NO_SANITIZE_ALL
ATTRIBUTE_TARGET_POPCNT
void __sanitizer_cov_trace_cmp1(uint8_t Arg1, uint8_t Arg2) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+ uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
}
@@ -594,7 +526,7 @@ ATTRIBUTE_INTERFACE
ATTRIBUTE_NO_SANITIZE_ALL
ATTRIBUTE_TARGET_POPCNT
void __sanitizer_cov_trace_const_cmp1(uint8_t Arg1, uint8_t Arg2) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+ uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
fuzzer::TPC.HandleCmp(PC, Arg1, Arg2);
}
@@ -608,7 +540,7 @@ void __sanitizer_cov_trace_switch(uint64_t Val, uint64_t *Cases) {
// Skip the most common and the most boring case.
if (Vals[N - 1] < 256 && Val < 256)
return;
- uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+ uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
size_t i;
uint64_t Token = 0;
for (i = 0; i < N; i++) {
@@ -629,7 +561,7 @@ ATTRIBUTE_INTERFACE
ATTRIBUTE_NO_SANITIZE_ALL
ATTRIBUTE_TARGET_POPCNT
void __sanitizer_cov_trace_div4(uint32_t Val) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+ uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
fuzzer::TPC.HandleCmp(PC, Val, (uint32_t)0);
}
@@ -637,7 +569,7 @@ ATTRIBUTE_INTERFACE
ATTRIBUTE_NO_SANITIZE_ALL
ATTRIBUTE_TARGET_POPCNT
void __sanitizer_cov_trace_div8(uint64_t Val) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+ uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
fuzzer::TPC.HandleCmp(PC, Val, (uint64_t)0);
}
@@ -645,7 +577,7 @@ ATTRIBUTE_INTERFACE
ATTRIBUTE_NO_SANITIZE_ALL
ATTRIBUTE_TARGET_POPCNT
void __sanitizer_cov_trace_gep(uintptr_t Idx) {
- uintptr_t PC = reinterpret_cast<uintptr_t>(__builtin_return_address(0));
+ uintptr_t PC = reinterpret_cast<uintptr_t>(GET_CALLER_PC());
fuzzer::TPC.HandleCmp(PC, Idx, (uintptr_t)0);
}
diff --git a/lib/fuzzer/FuzzerTracePC.h b/lib/fuzzer/FuzzerTracePC.h
index 39f97acdb..46d6c2488 100644
--- a/lib/fuzzer/FuzzerTracePC.h
+++ b/lib/fuzzer/FuzzerTracePC.h
@@ -74,11 +74,6 @@ class TracePC {
// How many bits of PC are used from __sanitizer_cov_trace_pc.
static const size_t kTracePcBits = 18;
- enum HandleUnstableOptions {
- MinUnstable = 1,
- ZeroUnstable = 2,
- };
-
void HandleInit(uint32_t *Start, uint32_t *Stop);
void HandleInline8bitCountersInit(uint8_t *Start, uint8_t *Stop);
void HandlePCsInit(const uintptr_t *Start, const uintptr_t *Stop);
@@ -109,7 +104,6 @@ class TracePC {
void PrintCoverage();
void DumpCoverage();
- void PrintUnstableStats();
template<class CallBack>
void IterateCoveredFunctions(CallBack CB);
@@ -142,18 +136,7 @@ class TracePC {
void SetFocusFunction(const std::string &FuncName);
bool ObservedFocusFunction();
- void InitializeUnstableCounters();
- bool UpdateUnstableCounters(int UnstableMode);
- void UpdateAndApplyUnstableCounters(int UnstableMode);
-
private:
- struct UnstableEdge {
- uint8_t Counter;
- bool IsUnstable;
- };
-
- UnstableEdge UnstableCounters[kNumPCs];
-
bool UseCounters = false;
uint32_t UseValueProfileMask = false;
bool DoPrintNewPCs = false;
@@ -185,9 +168,6 @@ private:
Set<uintptr_t> ObservedPCs;
std::unordered_map<uintptr_t, uintptr_t> ObservedFuncs; // PC => Counter.
- template <class Callback>
- void IterateInline8bitCounters(Callback CB) const;
-
std::pair<size_t, size_t> FocusFunction = {-1, -1}; // Module and PC IDs.
ValueBitMap ValueProfileMap;
diff --git a/lib/fuzzer/FuzzerUtil.h b/lib/fuzzer/FuzzerUtil.h
index 8c5c57c3a..d2f1d5de4 100644
--- a/lib/fuzzer/FuzzerUtil.h
+++ b/lib/fuzzer/FuzzerUtil.h
@@ -12,8 +12,10 @@
#ifndef LLVM_FUZZER_UTIL_H
#define LLVM_FUZZER_UTIL_H
-#include "FuzzerDefs.h"
+#include "FuzzerBuiltins.h"
+#include "FuzzerBuiltinsMsvc.h"
#include "FuzzerCommand.h"
+#include "FuzzerDefs.h"
namespace fuzzer {
@@ -84,7 +86,7 @@ std::string SearchRegexCmd(const std::string &Regex);
size_t SimpleFastHash(const uint8_t *Data, size_t Size);
-inline uint32_t Log(uint32_t X) { return 32 - __builtin_clz(X) - 1; }
+inline uint32_t Log(uint32_t X) { return 32 - Clz(X) - 1; }
} // namespace fuzzer
diff --git a/lib/hwasan/CMakeLists.txt b/lib/hwasan/CMakeLists.txt
index ca257dfe1..20ab94dc0 100644
--- a/lib/hwasan/CMakeLists.txt
+++ b/lib/hwasan/CMakeLists.txt
@@ -7,6 +7,7 @@ set(HWASAN_RTL_SOURCES
hwasan_dynamic_shadow.cc
hwasan_interceptors.cc
hwasan_linux.cc
+ hwasan_memintrinsics.cc
hwasan_poisoning.cc
hwasan_report.cc
hwasan_thread.cc
diff --git a/lib/hwasan/hwasan.cc b/lib/hwasan/hwasan.cc
index da95891d8..e2bfea5e4 100644
--- a/lib/hwasan/hwasan.cc
+++ b/lib/hwasan/hwasan.cc
@@ -13,20 +13,20 @@
//===----------------------------------------------------------------------===//
#include "hwasan.h"
-#include "hwasan_mapping.h"
+#include "hwasan_checks.h"
#include "hwasan_poisoning.h"
#include "hwasan_report.h"
#include "hwasan_thread.h"
#include "hwasan_thread_list.h"
#include "sanitizer_common/sanitizer_atomic.h"
#include "sanitizer_common/sanitizer_common.h"
-#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_flag_parser.h"
+#include "sanitizer_common/sanitizer_flags.h"
#include "sanitizer_common/sanitizer_libc.h"
#include "sanitizer_common/sanitizer_procmaps.h"
+#include "sanitizer_common/sanitizer_stackdepot.h"
#include "sanitizer_common/sanitizer_stacktrace.h"
#include "sanitizer_common/sanitizer_symbolizer.h"
-#include "sanitizer_common/sanitizer_stackdepot.h"
#include "ubsan/ubsan_flags.h"
#include "ubsan/ubsan_init.h"
@@ -229,8 +229,8 @@ static InternalMmapVectorNoCtor<FrameDescriptionArray> AllFrames;
void InitFrameDescriptors(uptr b, uptr e) {
FrameDescription *beg = reinterpret_cast<FrameDescription *>(b);
FrameDescription *end = reinterpret_cast<FrameDescription *>(e);
- // Must have at least one entry, which we can use for a linked list.
- CHECK_GE(end - beg, 1U);
+ if (beg == end)
+ return;
AllFrames.push_back({beg, end});
if (Verbosity())
for (FrameDescription *frame_descr = beg; frame_descr < end; frame_descr++)
@@ -365,63 +365,6 @@ void __sanitizer_unaligned_store64(uu64 *p, u64 x) {
*p = x;
}
-template<unsigned X>
-__attribute__((always_inline))
-static void SigTrap(uptr p) {
-#if defined(__aarch64__)
- (void)p;
- // 0x900 is added to do not interfere with the kernel use of lower values of
- // brk immediate.
- // FIXME: Add a constraint to put the pointer into x0, the same as x86 branch.
- asm("brk %0\n\t" ::"n"(0x900 + X));
-#elif defined(__x86_64__)
- // INT3 + NOP DWORD ptr [EAX + X] to pass X to our signal handler, 5 bytes
- // total. The pointer is passed via rdi.
- // 0x40 is added as a safeguard, to help distinguish our trap from others and
- // to avoid 0 offsets in the command (otherwise it'll be reduced to a
- // different nop command, the three bytes one).
- asm volatile(
- "int3\n"
- "nopl %c0(%%rax)\n"
- :: "n"(0x40 + X), "D"(p));
-#else
- // FIXME: not always sigill.
- __builtin_trap();
-#endif
- // __builtin_unreachable();
-}
-
-enum class ErrorAction { Abort, Recover };
-enum class AccessType { Load, Store };
-
-template <ErrorAction EA, AccessType AT, unsigned LogSize>
-__attribute__((always_inline, nodebug)) static void CheckAddress(uptr p) {
- tag_t ptr_tag = GetTagFromPointer(p);
- uptr ptr_raw = p & ~kAddressTagMask;
- tag_t mem_tag = *(tag_t *)MemToShadow(ptr_raw);
- if (UNLIKELY(ptr_tag != mem_tag)) {
- SigTrap<0x20 * (EA == ErrorAction::Recover) +
- 0x10 * (AT == AccessType::Store) + LogSize>(p);
- if (EA == ErrorAction::Abort) __builtin_unreachable();
- }
-}
-
-template <ErrorAction EA, AccessType AT>
-__attribute__((always_inline, nodebug)) static void CheckAddressSized(uptr p,
- uptr sz) {
- CHECK_NE(0, sz);
- tag_t ptr_tag = GetTagFromPointer(p);
- uptr ptr_raw = p & ~kAddressTagMask;
- tag_t *shadow_first = (tag_t *)MemToShadow(ptr_raw);
- tag_t *shadow_last = (tag_t *)MemToShadow(ptr_raw + sz - 1);
- for (tag_t *t = shadow_first; t <= shadow_last; ++t)
- if (UNLIKELY(ptr_tag != *t)) {
- SigTrap<0x20 * (EA == ErrorAction::Recover) +
- 0x10 * (AT == AccessType::Store) + 0xf>(p);
- if (EA == ErrorAction::Abort) __builtin_unreachable();
- }
-}
-
void __hwasan_loadN(uptr p, uptr sz) {
CheckAddressSized<ErrorAction::Abort, AccessType::Load>(p, sz);
}
diff --git a/lib/hwasan/hwasan.h b/lib/hwasan/hwasan.h
index 64b1f1a3d..ce9e904c5 100644
--- a/lib/hwasan/hwasan.h
+++ b/lib/hwasan/hwasan.h
@@ -77,7 +77,6 @@ void InitializeInterceptors();
void HwasanAllocatorInit();
void HwasanAllocatorThreadFinish();
-void HwasanDeallocate(StackTrace *stack, void *ptr);
void *hwasan_malloc(uptr size, StackTrace *stack);
void *hwasan_calloc(uptr nmemb, uptr size, StackTrace *stack);
@@ -88,6 +87,7 @@ void *hwasan_aligned_alloc(uptr alignment, uptr size, StackTrace *stack);
void *hwasan_memalign(uptr alignment, uptr size, StackTrace *stack);
int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size,
StackTrace *stack);
+void hwasan_free(void *ptr, StackTrace *stack);
void InstallTrapHandler();
void InstallAtExitHandler();
diff --git a/lib/hwasan/hwasan_allocator.cc b/lib/hwasan/hwasan_allocator.cc
index 8fd2349d9..8487ed7e1 100644
--- a/lib/hwasan/hwasan_allocator.cc
+++ b/lib/hwasan/hwasan_allocator.cc
@@ -21,6 +21,11 @@
#include "hwasan_thread.h"
#include "hwasan_report.h"
+#if HWASAN_WITH_INTERCEPTORS
+DEFINE_REAL(void *, realloc, void *ptr, uptr size)
+DEFINE_REAL(void, free, void *ptr)
+#endif
+
namespace __hwasan {
static Allocator allocator;
@@ -199,7 +204,7 @@ static bool PointerAndMemoryTagsMatch(void *tagged_ptr) {
return ptr_tag == mem_tag;
}
-void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) {
+static void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) {
CHECK(tagged_ptr);
HWASAN_FREE_HOOK(tagged_ptr);
@@ -253,8 +258,8 @@ void HwasanDeallocate(StackTrace *stack, void *tagged_ptr) {
}
}
-void *HwasanReallocate(StackTrace *stack, void *tagged_ptr_old, uptr new_size,
- uptr alignment) {
+static void *HwasanReallocate(StackTrace *stack, void *tagged_ptr_old,
+ uptr new_size, uptr alignment) {
if (!PointerAndMemoryTagsMatch(tagged_ptr_old))
ReportInvalidFree(stack, reinterpret_cast<uptr>(tagged_ptr_old));
@@ -271,7 +276,7 @@ void *HwasanReallocate(StackTrace *stack, void *tagged_ptr_old, uptr new_size,
return tagged_ptr_new;
}
-void *HwasanCalloc(StackTrace *stack, uptr nmemb, uptr size) {
+static void *HwasanCalloc(StackTrace *stack, uptr nmemb, uptr size) {
if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) {
if (AllocatorMayReturnNull())
return nullptr;
@@ -315,6 +320,14 @@ void *hwasan_calloc(uptr nmemb, uptr size, StackTrace *stack) {
void *hwasan_realloc(void *ptr, uptr size, StackTrace *stack) {
if (!ptr)
return SetErrnoOnNull(HwasanAllocate(stack, size, sizeof(u64), false));
+
+#if HWASAN_WITH_INTERCEPTORS
+ // A tag of 0 means that this is a system allocator allocation, so we must use
+ // the system allocator to realloc it.
+ if (!flags()->disable_allocator_tagging && GetTagFromPointer((uptr)ptr) == 0)
+ return REAL(realloc)(ptr, size);
+#endif
+
if (size == 0) {
HwasanDeallocate(stack, ptr);
return nullptr;
@@ -376,6 +389,17 @@ int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size,
return 0;
}
+void hwasan_free(void *ptr, StackTrace *stack) {
+#if HWASAN_WITH_INTERCEPTORS
+ // A tag of 0 means that this is a system allocator allocation, so we must use
+ // the system allocator to free it.
+ if (!flags()->disable_allocator_tagging && GetTagFromPointer((uptr)ptr) == 0)
+ return REAL(free)(ptr);
+#endif
+
+ return HwasanDeallocate(stack, ptr);
+}
+
} // namespace __hwasan
using namespace __hwasan;
@@ -385,6 +409,15 @@ void __hwasan_enable_allocator_tagging() {
}
void __hwasan_disable_allocator_tagging() {
+#if HWASAN_WITH_INTERCEPTORS
+ // Allocator tagging must be enabled for the system allocator fallback to work
+ // correctly. This means that we can't disable it at runtime if it was enabled
+ // at startup since that might result in our deallocations going to the system
+ // allocator. If tagging was disabled at startup we avoid this problem by
+ // disabling the fallback altogether.
+ CHECK(flags()->disable_allocator_tagging);
+#endif
+
atomic_store_relaxed(&hwasan_allocator_tagging_enabled, 0);
}
diff --git a/lib/hwasan/hwasan_allocator.h b/lib/hwasan/hwasan_allocator.h
index b3f2d6c84..6ab722fa6 100644
--- a/lib/hwasan/hwasan_allocator.h
+++ b/lib/hwasan/hwasan_allocator.h
@@ -14,6 +14,7 @@
#ifndef HWASAN_ALLOCATOR_H
#define HWASAN_ALLOCATOR_H
+#include "interception/interception.h"
#include "sanitizer_common/sanitizer_allocator.h"
#include "sanitizer_common/sanitizer_allocator_checks.h"
#include "sanitizer_common/sanitizer_allocator_interface.h"
@@ -26,6 +27,11 @@
#error Unsupported platform
#endif
+#if HWASAN_WITH_INTERCEPTORS
+DECLARE_REAL(void *, realloc, void *ptr, uptr size)
+DECLARE_REAL(void, free, void *ptr)
+#endif
+
namespace __hwasan {
struct Metadata {
@@ -45,28 +51,22 @@ struct HwasanMapUnmapCallback {
};
static const uptr kMaxAllowedMallocSize = 2UL << 30; // 2G
-static const uptr kRegionSizeLog = 20;
-static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog;
-typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap;
-struct AP32 {
- static const uptr kSpaceBeg = 0;
- static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE;
+struct AP64 {
+ static const uptr kSpaceBeg = ~0ULL;
+ static const uptr kSpaceSize = 0x2000000000ULL;
static const uptr kMetadataSize = sizeof(Metadata);
- typedef __sanitizer::CompactSizeClassMap SizeClassMap;
- static const uptr kRegionSizeLog = __hwasan::kRegionSizeLog;
+ typedef __sanitizer::VeryDenseSizeClassMap SizeClassMap;
using AddressSpaceView = LocalAddressSpaceView;
- using ByteMap = __hwasan::ByteMap;
typedef HwasanMapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
};
-typedef SizeClassAllocator32<AP32> PrimaryAllocator;
+typedef SizeClassAllocator64<AP64> PrimaryAllocator;
typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
typedef LargeMmapAllocator<HwasanMapUnmapCallback> SecondaryAllocator;
typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
SecondaryAllocator> Allocator;
-
void AllocatorSwallowThreadLocalCache(AllocatorCache *cache);
class HwasanChunkView {
diff --git a/lib/hwasan/hwasan_checks.h b/lib/hwasan/hwasan_checks.h
new file mode 100644
index 000000000..688b5e2be
--- /dev/null
+++ b/lib/hwasan/hwasan_checks.h
@@ -0,0 +1,80 @@
+//===-- hwasan_checks.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 HWAddressSanitizer.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef HWASAN_CHECKS_H
+#define HWASAN_CHECKS_H
+
+#include "hwasan_mapping.h"
+
+namespace __hwasan {
+template <unsigned X>
+__attribute__((always_inline)) static void SigTrap(uptr p) {
+#if defined(__aarch64__)
+ (void)p;
+ // 0x900 is added to do not interfere with the kernel use of lower values of
+ // brk immediate.
+ // FIXME: Add a constraint to put the pointer into x0, the same as x86 branch.
+ asm("brk %0\n\t" ::"n"(0x900 + X));
+#elif defined(__x86_64__)
+ // INT3 + NOP DWORD ptr [EAX + X] to pass X to our signal handler, 5 bytes
+ // total. The pointer is passed via rdi.
+ // 0x40 is added as a safeguard, to help distinguish our trap from others and
+ // to avoid 0 offsets in the command (otherwise it'll be reduced to a
+ // different nop command, the three bytes one).
+ asm volatile(
+ "int3\n"
+ "nopl %c0(%%rax)\n" ::"n"(0x40 + X),
+ "D"(p));
+#else
+ // FIXME: not always sigill.
+ __builtin_trap();
+#endif
+ // __builtin_unreachable();
+}
+
+enum class ErrorAction { Abort, Recover };
+enum class AccessType { Load, Store };
+
+template <ErrorAction EA, AccessType AT, unsigned LogSize>
+__attribute__((always_inline, nodebug)) static void CheckAddress(uptr p) {
+ tag_t ptr_tag = GetTagFromPointer(p);
+ uptr ptr_raw = p & ~kAddressTagMask;
+ tag_t mem_tag = *(tag_t *)MemToShadow(ptr_raw);
+ if (UNLIKELY(ptr_tag != mem_tag)) {
+ SigTrap<0x20 * (EA == ErrorAction::Recover) +
+ 0x10 * (AT == AccessType::Store) + LogSize>(p);
+ if (EA == ErrorAction::Abort)
+ __builtin_unreachable();
+ }
+}
+
+template <ErrorAction EA, AccessType AT>
+__attribute__((always_inline, nodebug)) static void CheckAddressSized(uptr p,
+ uptr sz) {
+ if (sz == 0)
+ return;
+ tag_t ptr_tag = GetTagFromPointer(p);
+ uptr ptr_raw = p & ~kAddressTagMask;
+ tag_t *shadow_first = (tag_t *)MemToShadow(ptr_raw);
+ tag_t *shadow_last = (tag_t *)MemToShadow(ptr_raw + sz - 1);
+ for (tag_t *t = shadow_first; t <= shadow_last; ++t)
+ if (UNLIKELY(ptr_tag != *t)) {
+ SigTrap<0x20 * (EA == ErrorAction::Recover) +
+ 0x10 * (AT == AccessType::Store) + 0xf>(p);
+ if (EA == ErrorAction::Abort)
+ __builtin_unreachable();
+ }
+}
+} // end namespace __hwasan
+
+#endif // HWASAN_CHECKS_H
diff --git a/lib/hwasan/hwasan_interceptors.cc b/lib/hwasan/hwasan_interceptors.cc
index d20bdd95a..fb0dcb890 100644
--- a/lib/hwasan/hwasan_interceptors.cc
+++ b/lib/hwasan/hwasan_interceptors.cc
@@ -17,6 +17,7 @@
#include "interception/interception.h"
#include "hwasan.h"
+#include "hwasan_allocator.h"
#include "hwasan_mapping.h"
#include "hwasan_thread.h"
#include "hwasan_poisoning.h"
@@ -44,11 +45,6 @@ using __sanitizer::atomic_load;
using __sanitizer::atomic_store;
using __sanitizer::atomic_uintptr_t;
-DECLARE_REAL(SIZE_T, strlen, const char *s)
-DECLARE_REAL(SIZE_T, strnlen, const char *s, SIZE_T maxlen)
-DECLARE_REAL(void *, memcpy, void *dest, const void *src, uptr n)
-DECLARE_REAL(void *, memset, void *dest, int c, uptr n)
-
bool IsInInterceptorScope() {
Thread *t = GetCurrentThread();
return t && t->InInterceptorScope();
@@ -130,13 +126,13 @@ void * __sanitizer_pvalloc(uptr size) {
void __sanitizer_free(void *ptr) {
GET_MALLOC_STACK_TRACE;
if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr))) return;
- HwasanDeallocate(&stack, ptr);
+ hwasan_free(ptr, &stack);
}
void __sanitizer_cfree(void *ptr) {
GET_MALLOC_STACK_TRACE;
if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr))) return;
- HwasanDeallocate(&stack, ptr);
+ hwasan_free(ptr, &stack);
}
uptr __sanitizer_malloc_usable_size(const void *ptr) {
@@ -222,33 +218,15 @@ INTERCEPTOR_ALIAS(void, malloc_stats, void);
#endif // HWASAN_WITH_INTERCEPTORS
-#if HWASAN_WITH_INTERCEPTORS
-extern "C" int pthread_attr_init(void *attr);
-extern "C" int pthread_attr_destroy(void *attr);
-
-struct ThreadStartArg {
- thread_callback_t callback;
- void *param;
-};
-
-static void *HwasanThreadStartFunc(void *arg) {
- __hwasan_thread_enter();
- ThreadStartArg A = *reinterpret_cast<ThreadStartArg*>(arg);
- UnmapOrDie(arg, GetPageSizeCached());
- return A.callback(A.param);
-}
-
-INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*),
- void * param) {
+#if HWASAN_WITH_INTERCEPTORS && !defined(__aarch64__)
+INTERCEPTOR(int, pthread_create, void *th, void *attr,
+ void *(*callback)(void *), void *param) {
ScopedTaggingDisabler disabler;
- ThreadStartArg *A = reinterpret_cast<ThreadStartArg *> (MmapOrDie(
- GetPageSizeCached(), "pthread_create"));
- *A = {callback, param};
int res = REAL(pthread_create)(UntagPtr(th), UntagPtr(attr),
- &HwasanThreadStartFunc, A);
+ callback, param);
return res;
}
-#endif // HWASAN_WITH_INTERCEPTORS
+#endif
static void BeforeFork() {
StackDepotLockAll();
@@ -289,8 +267,12 @@ void InitializeInterceptors() {
INTERCEPT_FUNCTION(fork);
#if HWASAN_WITH_INTERCEPTORS
+#if !defined(__aarch64__)
INTERCEPT_FUNCTION(pthread_create);
#endif
+ INTERCEPT_FUNCTION(realloc);
+ INTERCEPT_FUNCTION(free);
+#endif
inited = 1;
}
diff --git a/lib/hwasan/hwasan_interface_internal.h b/lib/hwasan/hwasan_interface_internal.h
index 0e49a3fc2..d3b2087d0 100644
--- a/lib/hwasan/hwasan_interface_internal.h
+++ b/lib/hwasan/hwasan_interface_internal.h
@@ -194,6 +194,13 @@ void * __sanitizer_realloc(void *ptr, uptr size);
SANITIZER_INTERFACE_ATTRIBUTE
void * __sanitizer_malloc(uptr size);
+
+SANITIZER_INTERFACE_ATTRIBUTE
+void *__hwasan_memcpy(void *dst, const void *src, uptr size);
+SANITIZER_INTERFACE_ATTRIBUTE
+void *__hwasan_memset(void *s, int c, uptr n);
+SANITIZER_INTERFACE_ATTRIBUTE
+void *__hwasan_memmove(void *dest, const void *src, uptr n);
} // extern "C"
#endif // HWASAN_INTERFACE_INTERNAL_H
diff --git a/lib/hwasan/hwasan_linux.cc b/lib/hwasan/hwasan_linux.cc
index af9378c31..5b0a8b4ac 100644
--- a/lib/hwasan/hwasan_linux.cc
+++ b/lib/hwasan/hwasan_linux.cc
@@ -40,6 +40,7 @@
#include "sanitizer_common/sanitizer_procmaps.h"
#if HWASAN_WITH_INTERCEPTORS && !SANITIZER_ANDROID
+SANITIZER_INTERFACE_ATTRIBUTE
THREADLOCAL uptr __hwasan_tls;
#endif
@@ -301,7 +302,12 @@ void AndroidTestTlsSlot() {}
#endif
Thread *GetCurrentThread() {
- auto *R = (StackAllocationsRingBuffer*)GetCurrentThreadLongPtr();
+ uptr *ThreadLong = GetCurrentThreadLongPtr();
+#if HWASAN_WITH_INTERCEPTORS
+ if (!*ThreadLong)
+ __hwasan_thread_enter();
+#endif
+ auto *R = (StackAllocationsRingBuffer *)ThreadLong;
return hwasanThreadList().GetThreadByBufferAddress((uptr)(R->Next()));
}
diff --git a/lib/hwasan/hwasan_memintrinsics.cc b/lib/hwasan/hwasan_memintrinsics.cc
new file mode 100644
index 000000000..9cb844e45
--- /dev/null
+++ b/lib/hwasan/hwasan_memintrinsics.cc
@@ -0,0 +1,45 @@
+//===-- hwasan_memintrinsics.cc ---------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// This file is a part of HWAddressSanitizer and contains HWASAN versions of
+/// memset, memcpy and memmove
+///
+//===----------------------------------------------------------------------===//
+
+#include <string.h>
+#include "hwasan.h"
+#include "hwasan_checks.h"
+#include "hwasan_flags.h"
+#include "hwasan_interface_internal.h"
+#include "sanitizer_common/sanitizer_libc.h"
+
+using namespace __hwasan;
+
+void *__hwasan_memset(void *block, int c, uptr size) {
+ CheckAddressSized<ErrorAction::Recover, AccessType::Store>(
+ reinterpret_cast<uptr>(block), size);
+ return memset(UntagPtr(block), c, size);
+}
+
+void *__hwasan_memcpy(void *to, const void *from, uptr size) {
+ CheckAddressSized<ErrorAction::Recover, AccessType::Store>(
+ reinterpret_cast<uptr>(to), size);
+ CheckAddressSized<ErrorAction::Recover, AccessType::Load>(
+ reinterpret_cast<uptr>(from), size);
+ return memcpy(UntagPtr(to), UntagPtr(from), size);
+}
+
+void *__hwasan_memmove(void *to, const void *from, uptr size) {
+ CheckAddressSized<ErrorAction::Recover, AccessType::Store>(
+ reinterpret_cast<uptr>(to), size);
+ CheckAddressSized<ErrorAction::Recover, AccessType::Load>(
+ reinterpret_cast<uptr>(from), size);
+ return memmove(UntagPtr(to), UntagPtr(from), size);
+}
diff --git a/lib/hwasan/hwasan_new_delete.cc b/lib/hwasan/hwasan_new_delete.cc
index 63ca74edd..f2e8faf5d 100644
--- a/lib/hwasan/hwasan_new_delete.cc
+++ b/lib/hwasan/hwasan_new_delete.cc
@@ -51,7 +51,7 @@ void *operator new[](size_t size, std::nothrow_t const&) {
#define OPERATOR_DELETE_BODY \
GET_MALLOC_STACK_TRACE; \
- if (ptr) HwasanDeallocate(&stack, ptr)
+ if (ptr) hwasan_free(ptr, &stack)
INTERCEPTOR_ATTRIBUTE
void operator delete(void *ptr) NOEXCEPT { OPERATOR_DELETE_BODY; }
diff --git a/lib/hwasan/hwasan_report.cc b/lib/hwasan/hwasan_report.cc
index b5d310a34..ea3e4096d 100644
--- a/lib/hwasan/hwasan_report.cc
+++ b/lib/hwasan/hwasan_report.cc
@@ -233,7 +233,7 @@ void PrintAddressDescription(
t->Announce();
// Temporary report section, needs to be improved.
- Printf("Previosly allocated frames:\n");
+ Printf("Previously allocated frames:\n");
auto *sa = (t == GetCurrentThread() && current_stack_allocations)
? current_stack_allocations
: t->stack_allocations();
diff --git a/lib/hwasan/hwasan_thread.cc b/lib/hwasan/hwasan_thread.cc
index 0d15c7e46..631c2813e 100644
--- a/lib/hwasan/hwasan_thread.cc
+++ b/lib/hwasan/hwasan_thread.cc
@@ -43,27 +43,18 @@ void Thread::Init(uptr stack_buffer_start, uptr stack_buffer_size) {
// ScopedTaggingDisable needs GetCurrentThread to be set up.
ScopedTaggingDisabler disabler;
- // If this process is "init" (pid 1), /proc may not be mounted yet.
- if (IsMainThread() && !FileExists("/proc/self/maps")) {
- stack_top_ = stack_bottom_ = 0;
- tls_begin_ = tls_end_ = 0;
- } else {
- uptr tls_size;
- uptr stack_size;
- GetThreadStackAndTls(IsMainThread(), &stack_bottom_, &stack_size,
- &tls_begin_, &tls_size);
- stack_top_ = stack_bottom_ + stack_size;
- tls_end_ = tls_begin_ + tls_size;
-
+ uptr tls_size;
+ uptr stack_size;
+ GetThreadStackAndTls(IsMainThread(), &stack_bottom_, &stack_size, &tls_begin_,
+ &tls_size);
+ stack_top_ = stack_bottom_ + stack_size;
+ tls_end_ = tls_begin_ + tls_size;
+
+ if (stack_bottom_) {
int local;
CHECK(AddrIsInStack((uptr)&local));
CHECK(MemIsApp(stack_bottom_));
CHECK(MemIsApp(stack_top_ - 1));
-
- if (stack_bottom_) {
- CHECK(MemIsApp(stack_bottom_));
- CHECK(MemIsApp(stack_top_ - 1));
- }
}
if (flags()->verbose_threads) {
diff --git a/lib/lsan/lsan_allocator.cc b/lib/lsan/lsan_allocator.cc
index c58c35480..1b338bd59 100644
--- a/lib/lsan/lsan_allocator.cc
+++ b/lib/lsan/lsan_allocator.cc
@@ -34,9 +34,6 @@ static const uptr kMaxAllowedMallocSize = 4UL << 30;
#else
static const uptr kMaxAllowedMallocSize = 8UL << 30;
#endif
-typedef LargeMmapAllocator<> SecondaryAllocator;
-typedef CombinedAllocator<PrimaryAllocator, AllocatorCache,
- SecondaryAllocator> Allocator;
static Allocator allocator;
diff --git a/lib/lsan/lsan_allocator.h b/lib/lsan/lsan_allocator.h
index 23ebc11f6..4c4e02fc0 100644
--- a/lib/lsan/lsan_allocator.h
+++ b/lib/lsan/lsan_allocator.h
@@ -81,6 +81,7 @@ const uptr kAllocatorSize = 0x20000000000ULL; // 2T.
const uptr kAllocatorSpace = 0x600000000000ULL;
const uptr kAllocatorSize = 0x40000000000ULL; // 4T.
# endif
+template <typename AddressSpaceViewTy>
struct AP64 { // Allocator64 parameters. Deliberately using a short name.
static const uptr kSpaceBeg = kAllocatorSpace;
static const uptr kSpaceSize = kAllocatorSize;
@@ -88,11 +89,30 @@ struct AP64 { // Allocator64 parameters. Deliberately using a short name.
typedef DefaultSizeClassMap SizeClassMap;
typedef NoOpMapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
+ using AddressSpaceView = AddressSpaceViewTy;
};
-typedef SizeClassAllocator64<AP64> PrimaryAllocator;
+template <typename AddressSpaceView>
+using PrimaryAllocatorASVT = SizeClassAllocator64<AP64<AddressSpaceView>>;
+using PrimaryAllocator = PrimaryAllocatorASVT<LocalAddressSpaceView>;
#endif
-typedef SizeClassAllocatorLocalCache<PrimaryAllocator> AllocatorCache;
+
+template <typename AddressSpaceView>
+using AllocatorCacheASVT =
+ SizeClassAllocatorLocalCache<PrimaryAllocatorASVT<AddressSpaceView>>;
+using AllocatorCache = AllocatorCacheASVT<LocalAddressSpaceView>;
+
+template <typename AddressSpaceView>
+using SecondaryAllocatorASVT =
+ LargeMmapAllocator<NoOpMapUnmapCallback, DefaultLargeMmapAllocatorPtrArray,
+ AddressSpaceView>;
+
+template <typename AddressSpaceView>
+using AllocatorASVT =
+ CombinedAllocator<PrimaryAllocatorASVT<AddressSpaceView>,
+ AllocatorCacheASVT<AddressSpaceView>,
+ SecondaryAllocatorASVT<AddressSpaceView>>;
+using Allocator = AllocatorASVT<LocalAddressSpaceView>;
AllocatorCache *GetAllocatorCache();
diff --git a/lib/msan/msan_allocator.cc b/lib/msan/msan_allocator.cc
index 8b9fa6506..053ab0280 100644
--- a/lib/msan/msan_allocator.cc
+++ b/lib/msan/msan_allocator.cc
@@ -79,6 +79,7 @@ struct MsanMapUnmapCallback {
typedef DefaultSizeClassMap SizeClassMap;
typedef MsanMapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
+ using AddressSpaceView = LocalAddressSpaceView;
};
typedef SizeClassAllocator64<AP64> PrimaryAllocator;
@@ -93,6 +94,7 @@ struct MsanMapUnmapCallback {
typedef DefaultSizeClassMap SizeClassMap;
typedef MsanMapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
+ using AddressSpaceView = LocalAddressSpaceView;
};
typedef SizeClassAllocator64<AP64> PrimaryAllocator;
diff --git a/lib/msan/msan_linux.cc b/lib/msan/msan_linux.cc
index 385a650c4..0b0208884 100644
--- a/lib/msan/msan_linux.cc
+++ b/lib/msan/msan_linux.cc
@@ -175,6 +175,51 @@ void InstallAtExitHandler() {
// ---------------------- TSD ---------------- {{{1
+#if SANITIZER_NETBSD || SANITIZER_FREEBSD
+// Thread Static Data cannot be used in early init on NetBSD and FreeBSD.
+// Reuse the MSan TSD API for compatibility with existing code
+// with an alternative implementation.
+
+static void (*tsd_destructor)(void *tsd) = nullptr;
+
+struct tsd_key {
+ tsd_key() : key(nullptr) {}
+ ~tsd_key() {
+ CHECK(tsd_destructor);
+ if (key)
+ (*tsd_destructor)(key);
+ }
+ MsanThread *key;
+};
+
+static thread_local struct tsd_key key;
+
+void MsanTSDInit(void (*destructor)(void *tsd)) {
+ CHECK(!tsd_destructor);
+ tsd_destructor = destructor;
+}
+
+MsanThread *GetCurrentThread() {
+ CHECK(tsd_destructor);
+ return key.key;
+}
+
+void SetCurrentThread(MsanThread *tsd) {
+ CHECK(tsd_destructor);
+ CHECK(tsd);
+ CHECK(!key.key);
+ key.key = tsd;
+}
+
+void MsanTSDDtor(void *tsd) {
+ CHECK(tsd_destructor);
+ CHECK_EQ(key.key, tsd);
+ key.key = nullptr;
+ // Make sure that signal handler can not see a stale current thread pointer.
+ atomic_signal_fence(memory_order_seq_cst);
+ MsanThread::TSDDtor(tsd);
+}
+#else
static pthread_key_t tsd_key;
static bool tsd_key_inited = false;
@@ -211,6 +256,7 @@ void MsanTSDDtor(void *tsd) {
atomic_signal_fence(memory_order_seq_cst);
MsanThread::TSDDtor(tsd);
}
+#endif
} // namespace __msan
diff --git a/lib/profile/InstrProfData.inc b/lib/profile/InstrProfData.inc
index eb4a792ce..454620ed9 100644
--- a/lib/profile/InstrProfData.inc
+++ b/lib/profile/InstrProfData.inc
@@ -308,14 +308,14 @@ typedef struct ValueProfRecord {
#ifdef __cplusplus
/*!
- * \brief Return the number of value sites.
+ * Return the number of value sites.
*/
uint32_t getNumValueSites() const { return NumValueSites; }
/*!
- * \brief Read data from this record and save it to Record.
+ * Read data from this record and save it to Record.
*/
void deserializeTo(InstrProfRecord &Record,
- InstrProfRecord::ValueMapType *VMap);
+ InstrProfSymtab *SymTab);
/*
* In-place byte swap:
* Do byte swap for this instance. \c Old is the original order before
@@ -393,7 +393,7 @@ typedef struct ValueProfData {
* Read data from this data and save it to \c Record.
*/
void deserializeTo(InstrProfRecord &Record,
- InstrProfRecord::ValueMapType *VMap);
+ InstrProfSymtab *SymTab);
void operator delete(void *ptr) { ::operator delete(ptr); }
#endif
} ValueProfData;
@@ -458,7 +458,7 @@ getValueProfRecordHeaderSize(uint32_t NumValueSites);
#endif
/*!
- * \brief Return the \c ValueProfRecord header size including the
+ * Return the \c ValueProfRecord header size including the
* padding bytes.
*/
INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
@@ -471,7 +471,7 @@ uint32_t getValueProfRecordHeaderSize(uint32_t NumValueSites) {
}
/*!
- * \brief Return the total size of the value profile record including the
+ * Return the total size of the value profile record including the
* header and the value data.
*/
INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
@@ -482,7 +482,7 @@ uint32_t getValueProfRecordSize(uint32_t NumValueSites,
}
/*!
- * \brief Return the pointer to the start of value data array.
+ * Return the pointer to the start of value data array.
*/
INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
InstrProfValueData *getValueProfRecordValueData(ValueProfRecord *This) {
@@ -491,7 +491,7 @@ InstrProfValueData *getValueProfRecordValueData(ValueProfRecord *This) {
}
/*!
- * \brief Return the total number of value data for \c This record.
+ * Return the total number of value data for \c This record.
*/
INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
uint32_t getValueProfRecordNumValueData(ValueProfRecord *This) {
@@ -503,7 +503,7 @@ uint32_t getValueProfRecordNumValueData(ValueProfRecord *This) {
}
/*!
- * \brief Use this method to advance to the next \c This \c ValueProfRecord.
+ * Use this method to advance to the next \c This \c ValueProfRecord.
*/
INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
ValueProfRecord *getValueProfRecordNext(ValueProfRecord *This) {
@@ -514,7 +514,7 @@ ValueProfRecord *getValueProfRecordNext(ValueProfRecord *This) {
}
/*!
- * \brief Return the first \c ValueProfRecord instance.
+ * Return the first \c ValueProfRecord instance.
*/
INSTR_PROF_VISIBILITY INSTR_PROF_INLINE
ValueProfRecord *getFirstValueProfRecord(ValueProfData *This) {
diff --git a/lib/profile/InstrProfilingPlatformLinux.c b/lib/profile/InstrProfilingPlatformLinux.c
index a517821a2..3764df1d8 100644
--- a/lib/profile/InstrProfilingPlatformLinux.c
+++ b/lib/profile/InstrProfilingPlatformLinux.c
@@ -8,7 +8,7 @@
\*===----------------------------------------------------------------------===*/
#if defined(__linux__) || defined(__FreeBSD__) || defined(__Fuchsia__) || \
- (defined(__sun__) && defined(__svr4__))
+ (defined(__sun__) && defined(__svr4__)) || defined(__NetBSD__)
#include <stdlib.h>
diff --git a/lib/profile/InstrProfilingPlatformOther.c b/lib/profile/InstrProfilingPlatformOther.c
index a339abc7f..7c2f14cfc 100644
--- a/lib/profile/InstrProfilingPlatformOther.c
+++ b/lib/profile/InstrProfilingPlatformOther.c
@@ -8,7 +8,7 @@
\*===----------------------------------------------------------------------===*/
#if !defined(__APPLE__) && !defined(__linux__) && !defined(__FreeBSD__) && \
- !(defined(__sun__) && defined(__svr4__))
+ !(defined(__sun__) && defined(__svr4__)) && !defined(__NetBSD__)
#include <stdlib.h>
diff --git a/lib/sanitizer_common/CMakeLists.txt b/lib/sanitizer_common/CMakeLists.txt
index a8bd56933..f7bf4b009 100644
--- a/lib/sanitizer_common/CMakeLists.txt
+++ b/lib/sanitizer_common/CMakeLists.txt
@@ -38,6 +38,7 @@ set(SANITIZER_SOURCES_NOTERMINATION
sanitizer_suppressions.cc
sanitizer_tls_get_addr.cc
sanitizer_thread_registry.cc
+ sanitizer_type_traits.cc
sanitizer_win.cc)
if(UNIX AND NOT APPLE AND NOT OS_NAME MATCHES "SunOS")
@@ -191,11 +192,8 @@ set(SANITIZER_IMPL_HEADERS
include_directories(..)
-set(SANITIZER_COMMON_DEFINITIONS)
-
-include(CheckIncludeFile)
-append_have_file_definition(rpc/xdr.h HAVE_RPC_XDR_H SANITIZER_COMMON_DEFINITIONS)
-append_have_file_definition(tirpc/rpc/xdr.h HAVE_TIRPC_RPC_XDR_H SANITIZER_COMMON_DEFINITIONS)
+set(SANITIZER_COMMON_DEFINITIONS
+ HAVE_RPC_XDR_H=${HAVE_RPC_XDR_H})
set(SANITIZER_CFLAGS ${SANITIZER_COMMON_CFLAGS})
append_rtti_flag(OFF SANITIZER_CFLAGS)
diff --git a/lib/sanitizer_common/sanitizer_allocator_combined.h b/lib/sanitizer_common/sanitizer_allocator_combined.h
index 1f874d60b..fcc4469c9 100644
--- a/lib/sanitizer_common/sanitizer_allocator_combined.h
+++ b/lib/sanitizer_common/sanitizer_allocator_combined.h
@@ -21,19 +21,28 @@
// PrimaryAllocator is used via a local AllocatorCache.
// SecondaryAllocator can allocate anything, but is not efficient.
template <class PrimaryAllocator, class AllocatorCache,
- class SecondaryAllocator> // NOLINT
+ class SecondaryAllocator,
+ typename AddressSpaceViewTy = LocalAddressSpaceView> // NOLINT
class CombinedAllocator {
public:
+ using AddressSpaceView = AddressSpaceViewTy;
+ static_assert(is_same<AddressSpaceView,
+ typename PrimaryAllocator::AddressSpaceView>::value,
+ "PrimaryAllocator is using wrong AddressSpaceView");
+ static_assert(is_same<AddressSpaceView,
+ typename SecondaryAllocator::AddressSpaceView>::value,
+ "SecondaryAllocator is using wrong AddressSpaceView");
+
void InitLinkerInitialized(s32 release_to_os_interval_ms) {
+ stats_.InitLinkerInitialized();
primary_.Init(release_to_os_interval_ms);
secondary_.InitLinkerInitialized();
- stats_.InitLinkerInitialized();
}
void Init(s32 release_to_os_interval_ms) {
+ stats_.Init();
primary_.Init(release_to_os_interval_ms);
secondary_.Init();
- stats_.Init();
}
void *Allocate(AllocatorCache *cache, uptr size, uptr alignment) {
@@ -194,4 +203,3 @@ class CombinedAllocator {
SecondaryAllocator secondary_;
AllocatorGlobalStats stats_;
};
-
diff --git a/lib/sanitizer_common/sanitizer_allocator_primary32.h b/lib/sanitizer_common/sanitizer_allocator_primary32.h
index e5d637665..abaac3d1a 100644
--- a/lib/sanitizer_common/sanitizer_allocator_primary32.h
+++ b/lib/sanitizer_common/sanitizer_allocator_primary32.h
@@ -57,6 +57,10 @@ class SizeClassAllocator32 {
typedef typename Params::ByteMap ByteMap;
typedef typename Params::MapUnmapCallback MapUnmapCallback;
+ static_assert(
+ is_same<typename ByteMap::AddressSpaceView, AddressSpaceView>::value,
+ "AddressSpaceView type mismatch");
+
static const bool kRandomShuffleChunks = Params::kFlags &
SizeClassAllocator32FlagMasks::kRandomShuffleChunks;
static const bool kUseSeparateSizeClassForBatch = Params::kFlags &
@@ -109,9 +113,6 @@ class SizeClassAllocator32 {
typedef SizeClassAllocator32LocalCache<ThisT> AllocatorCache;
void Init(s32 release_to_os_interval_ms) {
- static_assert(
- is_same<typename ByteMap::AddressSpaceView, AddressSpaceView>::value,
- "AddressSpaceView type mismatch");
possible_regions.Init();
internal_memset(size_class_info_array, 0, sizeof(size_class_info_array));
}
diff --git a/lib/sanitizer_common/sanitizer_allocator_primary64.h b/lib/sanitizer_common/sanitizer_allocator_primary64.h
index 6acb4f8bc..b063bf0d3 100644
--- a/lib/sanitizer_common/sanitizer_allocator_primary64.h
+++ b/lib/sanitizer_common/sanitizer_allocator_primary64.h
@@ -46,6 +46,7 @@ struct SizeClassAllocator64FlagMasks { // Bit masks.
template <class Params>
class SizeClassAllocator64 {
public:
+ using AddressSpaceView = typename Params::AddressSpaceView;
static const uptr kSpaceBeg = Params::kSpaceBeg;
static const uptr kSpaceSize = Params::kSpaceSize;
static const uptr kMetadataSize = Params::kMetadataSize;
@@ -294,8 +295,10 @@ class SizeClassAllocator64 {
RegionInfo *region = GetRegionInfo(class_id);
uptr chunk_size = ClassIdToSize(class_id);
uptr region_beg = SpaceBeg() + class_id * kRegionSize;
+ uptr region_allocated_user_size =
+ AddressSpaceView::Load(region)->allocated_user;
for (uptr chunk = region_beg;
- chunk < region_beg + region->allocated_user;
+ chunk < region_beg + region_allocated_user_size;
chunk += chunk_size) {
// Too slow: CHECK_EQ((void *)chunk, GetBlockBegin((void *)chunk));
callback(chunk, arg);
diff --git a/lib/sanitizer_common/sanitizer_allocator_secondary.h b/lib/sanitizer_common/sanitizer_allocator_secondary.h
index 455fcf3b4..0c8505c34 100644
--- a/lib/sanitizer_common/sanitizer_allocator_secondary.h
+++ b/lib/sanitizer_common/sanitizer_allocator_secondary.h
@@ -69,9 +69,10 @@ typedef LargeMmapAllocatorPtrArrayDynamic DefaultLargeMmapAllocatorPtrArray;
// sizes not covered by more efficient allocators (e.g. SizeClassAllocator64).
template <class MapUnmapCallback = NoOpMapUnmapCallback,
class PtrArrayT = DefaultLargeMmapAllocatorPtrArray,
- class AddressSpaceView = LocalAddressSpaceView>
+ class AddressSpaceViewTy = LocalAddressSpaceView>
class LargeMmapAllocator {
public:
+ using AddressSpaceView = AddressSpaceViewTy;
void InitLinkerInitialized() {
page_size_ = GetPageSizeCached();
chunks_ = reinterpret_cast<Header**>(ptr_array_.Init());
@@ -203,10 +204,10 @@ class LargeMmapAllocator {
void EnsureSortedChunks() {
if (chunks_sorted_) return;
- Header **chunks = AddressSpaceView::Load(chunks_, n_chunks_);
+ Header **chunks = AddressSpaceView::LoadWritable(chunks_, n_chunks_);
Sort(reinterpret_cast<uptr *>(chunks), n_chunks_);
for (uptr i = 0; i < n_chunks_; i++)
- AddressSpaceView::Load(chunks[i])->chunk_idx = i;
+ AddressSpaceView::LoadWritable(chunks[i])->chunk_idx = i;
chunks_sorted_ = true;
}
@@ -274,9 +275,9 @@ class LargeMmapAllocator {
// The allocator must be locked when calling this function.
void ForEachChunk(ForEachChunkCallback callback, void *arg) {
EnsureSortedChunks(); // Avoid doing the sort while iterating.
- Header **chunks = AddressSpaceView::Load(chunks_, n_chunks_);
+ const Header *const *chunks = AddressSpaceView::Load(chunks_, n_chunks_);
for (uptr i = 0; i < n_chunks_; i++) {
- Header *t = chunks[i];
+ const Header *t = chunks[i];
callback(reinterpret_cast<uptr>(GetUser(t)), arg);
// Consistency check: verify that the array did not change.
CHECK_EQ(chunks[i], t);
@@ -300,7 +301,7 @@ class LargeMmapAllocator {
return GetHeader(reinterpret_cast<uptr>(p));
}
- void *GetUser(Header *h) {
+ void *GetUser(const Header *h) {
CHECK(IsAligned((uptr)h, page_size_));
return reinterpret_cast<void*>(reinterpret_cast<uptr>(h) + page_size_);
}
diff --git a/lib/sanitizer_common/sanitizer_allocator_size_class_map.h b/lib/sanitizer_common/sanitizer_allocator_size_class_map.h
index 07958424c..1c05fb8ff 100644
--- a/lib/sanitizer_common/sanitizer_allocator_size_class_map.h
+++ b/lib/sanitizer_common/sanitizer_allocator_size_class_map.h
@@ -237,3 +237,6 @@ typedef SizeClassMap<2, 5, 9, 16, 64, 14> VeryCompactSizeClassMap;
// allowing for denser per-class arrays, smaller memory footprint and usually
// better performances in threaded environments.
typedef SizeClassMap<3, 4, 8, 17, 8, 10> DenseSizeClassMap;
+// Similar to VeryCompact map above, this one has a small number of different
+// size classes, and also reduced thread-local caches.
+typedef SizeClassMap<2, 5, 9, 16, 8, 10> VeryDenseSizeClassMap;
diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h
index a0615fa87..d0aebd994 100644
--- a/lib/sanitizer_common/sanitizer_common.h
+++ b/lib/sanitizer_common/sanitizer_common.h
@@ -61,6 +61,15 @@ INLINE int Verbosity() {
return atomic_load(&current_verbosity, memory_order_relaxed);
}
+#if SANITIZER_ANDROID
+INLINE uptr GetPageSize() {
+// Android post-M sysconf(_SC_PAGESIZE) crashes if called from .preinit_array.
+ return 4096;
+}
+INLINE uptr GetPageSizeCached() {
+ return 4096;
+}
+#else
uptr GetPageSize();
extern uptr PageSizeCached;
INLINE uptr GetPageSizeCached() {
@@ -68,6 +77,7 @@ INLINE uptr GetPageSizeCached() {
PageSizeCached = GetPageSize();
return PageSizeCached;
}
+#endif
uptr GetMmapGranularity();
uptr GetMaxVirtualAddress();
uptr GetMaxUserVirtualAddress();
@@ -223,6 +233,7 @@ bool SetEnv(const char *name, const char *value);
u32 GetUid();
void ReExec();
void CheckASLR();
+void CheckMPROTECT();
char **GetArgv();
char **GetEnviron();
void PrintCmdline();
diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc
index 36d5f9c9f..50f783774 100644
--- a/lib/sanitizer_common/sanitizer_common_interceptors.inc
+++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc
@@ -95,6 +95,7 @@
#define getutxent __getutxent50
#define getutxid __getutxid50
#define getutxline __getutxline50
+#define pututxline __pututxline50
#define glob __glob30
#define gmtime __gmtime50
#define gmtime_r __gmtime_r50
@@ -5694,9 +5695,15 @@ INTERCEPTOR(void *, tsearch, void *key, void **rootp,
void unpoison_file(__sanitizer_FILE *fp) {
#if SANITIZER_HAS_STRUCT_FILE
COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp));
+#if SANITIZER_NETBSD
+ if (fp->_bf._base && fp->_bf._size > 0)
+ COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_bf._base,
+ fp->_bf._size);
+#else
if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end)
COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base,
fp->_IO_read_end - fp->_IO_read_base);
+#endif
#endif // SANITIZER_HAS_STRUCT_FILE
}
#endif
@@ -6566,10 +6573,21 @@ INTERCEPTOR(void *, getutxline, void *ut) {
COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz);
return res;
}
+INTERCEPTOR(void *, pututxline, const void *ut) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, pututxline, ut);
+ if (ut)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, ut, __sanitizer::struct_utmpx_sz);
+ void *res = REAL(pututxline)(ut);
+ if (res)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_utmpx_sz);
+ return res;
+}
#define INIT_UTMPX \
COMMON_INTERCEPT_FUNCTION(getutxent); \
COMMON_INTERCEPT_FUNCTION(getutxid); \
- COMMON_INTERCEPT_FUNCTION(getutxline);
+ COMMON_INTERCEPT_FUNCTION(getutxline); \
+ COMMON_INTERCEPT_FUNCTION(pututxline);
#else
#define INIT_UTMPX
#endif
@@ -7061,12 +7079,19 @@ INTERCEPTOR(char *, devname, u64 dev, u32 type) {
#endif
#if SANITIZER_INTERCEPT_DEVNAME_R
-INTERCEPTOR(int, devname_r, u64 dev, u32 type, char *path, uptr len) {
+#if SANITIZER_NETBSD
+#define DEVNAME_R_RETTYPE int
+#define DEVNAME_R_SUCCESS(x) (!(x))
+#else
+#define DEVNAME_R_RETTYPE char*
+#define DEVNAME_R_SUCCESS(x) (x)
+#endif
+INTERCEPTOR(DEVNAME_R_RETTYPE, devname_r, u64 dev, u32 type, char *path,
+ uptr len) {
void *ctx;
- int res;
COMMON_INTERCEPTOR_ENTER(ctx, devname_r, dev, type, path, len);
- res = REAL(devname_r)(dev, type, path, len);
- if (!res)
+ DEVNAME_R_RETTYPE res = REAL(devname_r)(dev, type, path, len);
+ if (DEVNAME_R_SUCCESS(res))
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, path, REAL(strlen)(path) + 1);
return res;
}
@@ -7421,6 +7446,16 @@ INTERCEPTOR(void, regfree, const void *preg) {
COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz);
REAL(regfree)(preg);
}
+#define INIT_REGEX \
+ COMMON_INTERCEPT_FUNCTION(regcomp); \
+ COMMON_INTERCEPT_FUNCTION(regexec); \
+ COMMON_INTERCEPT_FUNCTION(regerror); \
+ COMMON_INTERCEPT_FUNCTION(regfree);
+#else
+#define INIT_REGEX
+#endif
+
+#if SANITIZER_INTERCEPT_REGEXSUB
INTERCEPTOR(SSIZE_T, regnsub, char *buf, SIZE_T bufsiz, const char *sub,
const struct __sanitizer_regmatch *rm, const char *str) {
void *ctx;
@@ -7455,15 +7490,12 @@ INTERCEPTOR(SSIZE_T, regasub, char **buf, const char *sub,
}
return res;
}
-#define INIT_REGEX \
- COMMON_INTERCEPT_FUNCTION(regcomp); \
- COMMON_INTERCEPT_FUNCTION(regexec); \
- COMMON_INTERCEPT_FUNCTION(regerror); \
- COMMON_INTERCEPT_FUNCTION(regfree); \
+
+#define INIT_REGEXSUB \
COMMON_INTERCEPT_FUNCTION(regnsub); \
COMMON_INTERCEPT_FUNCTION(regasub);
#else
-#define INIT_REGEX
+#define INIT_REGEXSUB
#endif
#if SANITIZER_INTERCEPT_FTS
@@ -7539,6 +7571,8 @@ INTERCEPTOR(int, fts_close, void *ftsp) {
INTERCEPTOR(int, sysctl, int *name, unsigned int namelen, void *oldp,
SIZE_T *oldlenp, void *newp, SIZE_T newlen) {
void *ctx;
+ if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
+ return internal_sysctl(name, namelen, oldp, oldlenp, newp, newlen);
COMMON_INTERCEPTOR_ENTER(ctx, sysctl, name, namelen, oldp, oldlenp, newp,
newlen);
if (name)
@@ -7561,6 +7595,8 @@ INTERCEPTOR(int, sysctl, int *name, unsigned int namelen, void *oldp,
INTERCEPTOR(int, sysctlbyname, char *sname, void *oldp, SIZE_T *oldlenp,
void *newp, SIZE_T newlen) {
void *ctx;
+ if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED)
+ return internal_sysctlbyname(sname, oldp, oldlenp, newp, newlen);
COMMON_INTERCEPTOR_ENTER(ctx, sysctlbyname, sname, oldp, oldlenp, newp,
newlen);
if (sname)
@@ -7844,6 +7880,74 @@ INTERCEPTOR(UINTMAX_T, strtou, const char *nptr, char **endptr, int base,
#endif
#if SANITIZER_INTERCEPT_CAPSICUM
+#define CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights, ...) \
+ { \
+ void *ctx; \
+ COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_init, rights, ##__VA_ARGS__); \
+ if (rights) \
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \
+ __sanitizer_cap_rights_t *ret = \
+ REAL(cap_rights_init)(rights, ##__VA_ARGS__); \
+ if (ret) \
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \
+ return ret; \
+ }
+
+#define CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights, ...) \
+ { \
+ void *ctx; \
+ COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_set, rights, ##__VA_ARGS__); \
+ if (rights) \
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \
+ __sanitizer_cap_rights_t *ret = \
+ REAL(cap_rights_set)(rights, ##__VA_ARGS__); \
+ if (ret) \
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \
+ return ret; \
+ }
+
+#define CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights, ...) \
+ { \
+ void *ctx; \
+ COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_clear, rights, ##__VA_ARGS__); \
+ if (rights) \
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \
+ __sanitizer_cap_rights_t *ret = \
+ REAL(cap_rights_clear)(rights, ##__VA_ARGS__); \
+ if (ret) \
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \
+ return ret; \
+ }
+
+#define CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights, ...) \
+ { \
+ void *ctx; \
+ COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_set, rights, ##__VA_ARGS__); \
+ if (rights) \
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \
+ return REAL(cap_rights_is_set)(rights, ##__VA_ARGS__); \
+ }
+
+INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_init,
+ __sanitizer_cap_rights_t *rights) {
+ CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights);
+}
+
+INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_set,
+ __sanitizer_cap_rights_t *rights) {
+ CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights);
+}
+
+INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_clear,
+ __sanitizer_cap_rights_t *rights) {
+ CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights);
+}
+
+INTERCEPTOR(bool, cap_rights_is_set,
+ __sanitizer_cap_rights_t *rights) {
+ CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights);
+}
+
INTERCEPTOR(int, cap_rights_limit, int fd,
const __sanitizer_cap_rights_t *rights) {
void *ctx;
@@ -7932,6 +8036,10 @@ INTERCEPTOR(int, cap_ioctls_get, int fd, uptr *cmds, SIZE_T maxcmds) {
return ret;
}
#define INIT_CAPSICUM \
+ COMMON_INTERCEPT_FUNCTION(cap_rights_init); \
+ COMMON_INTERCEPT_FUNCTION(cap_rights_set); \
+ COMMON_INTERCEPT_FUNCTION(cap_rights_clear); \
+ COMMON_INTERCEPT_FUNCTION(cap_rights_is_set); \
COMMON_INTERCEPT_FUNCTION(cap_rights_get); \
COMMON_INTERCEPT_FUNCTION(cap_rights_limit); \
COMMON_INTERCEPT_FUNCTION(cap_rights_contains); \
@@ -8435,9 +8543,10 @@ INTERCEPTOR(char *, MD2Data, const unsigned char *data, unsigned int len,
if (context) \
COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
} \
- INTERCEPTOR(void, SHA##LEN##_Final, u8 digest[SHA##LEN##_digest_length], \
+ INTERCEPTOR(void, SHA##LEN##_Final, u8 digest[LEN/8], \
void *context) { \
void *ctx; \
+ CHECK_EQ(SHA##LEN##_digest_length, LEN/8); \
COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Final, digest, context); \
if (context) \
COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \
@@ -8961,6 +9070,403 @@ INTERCEPTOR(void, cdbw_close, struct __sanitizer_cdbw *cdbw) {
#define INIT_CDB
#endif
+#if SANITIZER_INTERCEPT_GETFSENT
+INTERCEPTOR(void *, getfsent) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, getfsent);
+ void *ret = REAL(getfsent)();
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
+ return ret;
+}
+
+INTERCEPTOR(void *, getfsspec, const char *spec) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, getfsspec, spec);
+ if (spec)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, spec, REAL(strlen)(spec) + 1);
+ void *ret = REAL(getfsspec)(spec);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
+ return ret;
+}
+
+INTERCEPTOR(void *, getfsfile, const char *file) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, getfsfile, file);
+ if (file)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, file, REAL(strlen)(file) + 1);
+ void *ret = REAL(getfsfile)(file);
+ if (ret)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz);
+ return ret;
+}
+
+#define INIT_GETFSENT \
+ COMMON_INTERCEPT_FUNCTION(getfsent); \
+ COMMON_INTERCEPT_FUNCTION(getfsspec); \
+ COMMON_INTERCEPT_FUNCTION(getfsfile);
+#else
+#define INIT_GETFSENT
+#endif
+
+#if SANITIZER_INTERCEPT_ARC4RANDOM
+INTERCEPTOR(void, arc4random_buf, void *buf, SIZE_T len) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, arc4random_buf, buf, len);
+ REAL(arc4random_buf)(buf, len);
+ if (buf && len)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, len);
+}
+
+INTERCEPTOR(void, arc4random_addrandom, u8 *dat, int datlen) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, arc4random_addrandom, dat, datlen);
+ if (dat && datlen)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, dat, datlen);
+ REAL(arc4random_addrandom)(dat, datlen);
+}
+
+#define INIT_ARC4RANDOM \
+ COMMON_INTERCEPT_FUNCTION(arc4random_buf); \
+ COMMON_INTERCEPT_FUNCTION(arc4random_addrandom);
+#else
+#define INIT_ARC4RANDOM
+#endif
+
+#if SANITIZER_INTERCEPT_POPEN
+INTERCEPTOR(__sanitizer_FILE *, popen, const char *command, const char *type) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, popen, command, type);
+ if (command)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, command, REAL(strlen)(command) + 1);
+ if (type)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1);
+ __sanitizer_FILE *res = REAL(popen)(command, type);
+ COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);
+ if (res) unpoison_file(res);
+ return res;
+}
+#define INIT_POPEN COMMON_INTERCEPT_FUNCTION(popen)
+#else
+#define INIT_POPEN
+#endif
+
+#if SANITIZER_INTERCEPT_POPENVE
+INTERCEPTOR(__sanitizer_FILE *, popenve, const char *path,
+ char *const *argv, char *const *envp, const char *type) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, popenve, path, argv, envp, type);
+ if (path)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1);
+ if (argv) {
+ for (char *const *pa = argv; ; ++pa) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
+ if (!*pa)
+ break;
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1);
+ }
+ }
+ if (envp) {
+ for (char *const *pa = envp; ; ++pa) {
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **));
+ if (!*pa)
+ break;
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1);
+ }
+ }
+ if (type)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1);
+ __sanitizer_FILE *res = REAL(popenve)(path, argv, envp, type);
+ COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr);
+ if (res) unpoison_file(res);
+ return res;
+}
+#define INIT_POPENVE COMMON_INTERCEPT_FUNCTION(popenve)
+#else
+#define INIT_POPENVE
+#endif
+
+#if SANITIZER_INTERCEPT_PCLOSE
+INTERCEPTOR(int, pclose, __sanitizer_FILE *fp) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, pclose, fp);
+ COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp);
+ const FileMetadata *m = GetInterceptorMetadata(fp);
+ int res = REAL(pclose)(fp);
+ if (m) {
+ COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size);
+ DeleteInterceptorMetadata(fp);
+ }
+ return res;
+}
+#define INIT_PCLOSE COMMON_INTERCEPT_FUNCTION(pclose);
+#else
+#define INIT_PCLOSE
+#endif
+
+#if SANITIZER_INTERCEPT_FUNOPEN
+typedef int (*funopen_readfn)(void *cookie, char *buf, int len);
+typedef int (*funopen_writefn)(void *cookie, const char *buf, int len);
+typedef OFF_T (*funopen_seekfn)(void *cookie, OFF_T offset, int whence);
+typedef int (*funopen_closefn)(void *cookie);
+
+struct WrappedFunopenCookie {
+ void *real_cookie;
+ funopen_readfn real_read;
+ funopen_writefn real_write;
+ funopen_seekfn real_seek;
+ funopen_closefn real_close;
+};
+
+static int wrapped_funopen_read(void *cookie, char *buf, int len) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
+ WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
+ funopen_readfn real_read = wrapped_cookie->real_read;
+ return real_read(wrapped_cookie->real_cookie, buf, len);
+}
+
+static int wrapped_funopen_write(void *cookie, const char *buf, int len) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
+ WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
+ funopen_writefn real_write = wrapped_cookie->real_write;
+ return real_write(wrapped_cookie->real_cookie, buf, len);
+}
+
+static OFF_T wrapped_funopen_seek(void *cookie, OFF_T offset, int whence) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
+ WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
+ funopen_seekfn real_seek = wrapped_cookie->real_seek;
+ return real_seek(wrapped_cookie->real_cookie, offset, whence);
+}
+
+static int wrapped_funopen_close(void *cookie) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
+ WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie;
+ funopen_closefn real_close = wrapped_cookie->real_close;
+ int res = real_close(wrapped_cookie->real_cookie);
+ InternalFree(wrapped_cookie);
+ return res;
+}
+
+INTERCEPTOR(__sanitizer_FILE *, funopen, void *cookie, funopen_readfn readfn,
+ funopen_writefn writefn, funopen_seekfn seekfn,
+ funopen_closefn closefn) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, funopen, cookie, readfn, writefn, seekfn,
+ closefn);
+
+ WrappedFunopenCookie *wrapped_cookie =
+ (WrappedFunopenCookie *)InternalAlloc(sizeof(WrappedFunopenCookie));
+ wrapped_cookie->real_cookie = cookie;
+ wrapped_cookie->real_read = readfn;
+ wrapped_cookie->real_write = writefn;
+ wrapped_cookie->real_seek = seekfn;
+ wrapped_cookie->real_close = closefn;
+
+ __sanitizer_FILE *res =
+ REAL(funopen)(wrapped_cookie,
+ readfn ? wrapped_funopen_read : nullptr,
+ writefn ? wrapped_funopen_write : nullptr,
+ seekfn ? wrapped_funopen_seek : nullptr,
+ closefn ? wrapped_funopen_close : nullptr);
+ if (res)
+ unpoison_file(res);
+ return res;
+}
+#define INIT_FUNOPEN COMMON_INTERCEPT_FUNCTION(funopen)
+#else
+#define INIT_FUNOPEN
+#endif
+
+#if SANITIZER_INTERCEPT_FUNOPEN2
+typedef SSIZE_T (*funopen2_readfn)(void *cookie, void *buf, SIZE_T len);
+typedef SSIZE_T (*funopen2_writefn)(void *cookie, const void *buf, SIZE_T len);
+typedef OFF_T (*funopen2_seekfn)(void *cookie, OFF_T offset, int whence);
+typedef int (*funopen2_flushfn)(void *cookie);
+typedef int (*funopen2_closefn)(void *cookie);
+
+struct WrappedFunopen2Cookie {
+ void *real_cookie;
+ funopen2_readfn real_read;
+ funopen2_writefn real_write;
+ funopen2_seekfn real_seek;
+ funopen2_flushfn real_flush;
+ funopen2_closefn real_close;
+};
+
+static SSIZE_T wrapped_funopen2_read(void *cookie, void *buf, SIZE_T len) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
+ WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
+ funopen2_readfn real_read = wrapped_cookie->real_read;
+ return real_read(wrapped_cookie->real_cookie, buf, len);
+}
+
+static SSIZE_T wrapped_funopen2_write(void *cookie, const void *buf,
+ SIZE_T len) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
+ WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
+ funopen2_writefn real_write = wrapped_cookie->real_write;
+ return real_write(wrapped_cookie->real_cookie, buf, len);
+}
+
+static OFF_T wrapped_funopen2_seek(void *cookie, OFF_T offset, int whence) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(3);
+ WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
+ funopen2_seekfn real_seek = wrapped_cookie->real_seek;
+ return real_seek(wrapped_cookie->real_cookie, offset, whence);
+}
+
+static int wrapped_funopen2_flush(void *cookie) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
+ WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
+ funopen2_flushfn real_flush = wrapped_cookie->real_flush;
+ return real_flush(wrapped_cookie->real_cookie);
+}
+
+static int wrapped_funopen2_close(void *cookie) {
+ COMMON_INTERCEPTOR_UNPOISON_PARAM(1);
+ WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie;
+ funopen2_closefn real_close = wrapped_cookie->real_close;
+ int res = real_close(wrapped_cookie->real_cookie);
+ InternalFree(wrapped_cookie);
+ return res;
+}
+
+INTERCEPTOR(__sanitizer_FILE *, funopen2, void *cookie, funopen2_readfn readfn,
+ funopen2_writefn writefn, funopen2_seekfn seekfn,
+ funopen2_flushfn flushfn, funopen2_closefn closefn) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, funopen2, cookie, readfn, writefn, seekfn,
+ flushfn, closefn);
+
+ WrappedFunopen2Cookie *wrapped_cookie =
+ (WrappedFunopen2Cookie *)InternalAlloc(sizeof(WrappedFunopen2Cookie));
+ wrapped_cookie->real_cookie = cookie;
+ wrapped_cookie->real_read = readfn;
+ wrapped_cookie->real_write = writefn;
+ wrapped_cookie->real_seek = seekfn;
+ wrapped_cookie->real_flush = flushfn;
+ wrapped_cookie->real_close = closefn;
+
+ __sanitizer_FILE *res =
+ REAL(funopen2)(wrapped_cookie,
+ readfn ? wrapped_funopen2_read : nullptr,
+ writefn ? wrapped_funopen2_write : nullptr,
+ seekfn ? wrapped_funopen2_seek : nullptr,
+ flushfn ? wrapped_funopen2_flush : nullptr,
+ closefn ? wrapped_funopen2_close : nullptr);
+ if (res)
+ unpoison_file(res);
+ return res;
+}
+#define INIT_FUNOPEN2 COMMON_INTERCEPT_FUNCTION(funopen2)
+#else
+#define INIT_FUNOPEN2
+#endif
+
+#if SANITIZER_INTERCEPT_FDEVNAME
+INTERCEPTOR(char *, fdevname, int fd) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, fdevname, fd);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+ char *name = REAL(fdevname)(fd);
+ if (name) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1);
+ if (fd > 0)
+ COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
+ }
+ return name;
+}
+
+INTERCEPTOR(char *, fdevname_r, int fd, char *buf, SIZE_T len) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, fdevname_r, fd, buf, len);
+ COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd);
+ char *name = REAL(fdevname_r)(fd, buf, len);
+ if (name && buf && len > 0) {
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1);
+ if (fd > 0)
+ COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd);
+ }
+ return name;
+}
+
+#define INIT_FDEVNAME \
+ COMMON_INTERCEPT_FUNCTION(fdevname); \
+ COMMON_INTERCEPT_FUNCTION(fdevname_r);
+#else
+#define INIT_FDEVNAME
+#endif
+
+#if SANITIZER_INTERCEPT_GETUSERSHELL
+INTERCEPTOR(char *, getusershell) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, getusershell);
+ char *res = REAL(getusershell)();
+ if (res)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
+ return res;
+}
+
+#define INIT_GETUSERSHELL COMMON_INTERCEPT_FUNCTION(getusershell);
+#else
+#define INIT_GETUSERSHELL
+#endif
+
+#if SANITIZER_INTERCEPT_SL_INIT
+INTERCEPTOR(void *, sl_init) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, sl_init);
+ void *res = REAL(sl_init)();
+ if (res)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_StringList_sz);
+ return res;
+}
+
+INTERCEPTOR(int, sl_add, void *sl, char *item) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, sl_add, sl, item);
+ if (sl)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
+ if (item)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, item, REAL(strlen)(item) + 1);
+ int res = REAL(sl_add)(sl, item);
+ if (!res)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
+ return res;
+}
+
+INTERCEPTOR(char *, sl_find, void *sl, const char *item) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, sl_find, sl, item);
+ if (sl)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
+ if (item)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, item, REAL(strlen)(item) + 1);
+ char *res = REAL(sl_find)(sl, item);
+ if (res)
+ COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1);
+ return res;
+}
+
+INTERCEPTOR(void, sl_free, void *sl, int freeall) {
+ void *ctx;
+ COMMON_INTERCEPTOR_ENTER(ctx, sl_free, sl, freeall);
+ if (sl)
+ COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz);
+ REAL(sl_free)(sl, freeall);
+}
+
+#define INIT_SL_INIT \
+ COMMON_INTERCEPT_FUNCTION(sl_init); \
+ COMMON_INTERCEPT_FUNCTION(sl_add); \
+ COMMON_INTERCEPT_FUNCTION(sl_find); \
+ COMMON_INTERCEPT_FUNCTION(sl_free);
+#else
+#define INIT_SL_INIT
+#endif
+
static void InitializeCommonInterceptors() {
static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1];
interceptor_metadata_map =
@@ -9220,6 +9726,7 @@ static void InitializeCommonInterceptors() {
INIT_SETVBUF;
INIT_GETVFSSTAT;
INIT_REGEX;
+ INIT_REGEXSUB;
INIT_FTS;
INIT_SYSCTL;
INIT_ASYSCTL;
@@ -9240,6 +9747,16 @@ static void InitializeCommonInterceptors() {
INIT_SHA2;
INIT_VIS;
INIT_CDB;
+ INIT_GETFSENT;
+ INIT_ARC4RANDOM;
+ INIT_POPEN;
+ INIT_POPENVE;
+ INIT_PCLOSE;
+ INIT_FUNOPEN;
+ INIT_FUNOPEN2;
+ INIT_FDEVNAME;
+ INIT_GETUSERSHELL;
+ INIT_SL_INIT;
INIT___PRINTF_CHK;
}
diff --git a/lib/sanitizer_common/sanitizer_common_libcdep.cc b/lib/sanitizer_common/sanitizer_common_libcdep.cc
index ab42b2167..1c0995b2d 100644
--- a/lib/sanitizer_common/sanitizer_common_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_common_libcdep.cc
@@ -25,7 +25,7 @@ void SetSoftRssLimitExceededCallback(void (*Callback)(bool exceeded)) {
SoftRssLimitExceededCallback = Callback;
}
-#if SANITIZER_LINUX && !SANITIZER_GO
+#if (SANITIZER_LINUX || SANITIZER_NETBSD) && !SANITIZER_GO
// Weak default implementation for when sanitizer_stackdepot is not linked in.
SANITIZER_WEAK_ATTRIBUTE StackDepotStats *StackDepotGetStats() {
return nullptr;
@@ -114,7 +114,7 @@ void WriteToSyslog(const char *msg) {
}
void MaybeStartBackgroudThread() {
-#if SANITIZER_LINUX && \
+#if (SANITIZER_LINUX || SANITIZER_NETBSD) && \
!SANITIZER_GO // Need to implement/test on other platforms.
// Start the background thread if one of the rss limits is given.
if (!common_flags()->hard_rss_limit_mb &&
diff --git a/lib/sanitizer_common/sanitizer_flags.inc b/lib/sanitizer_common/sanitizer_flags.inc
index cfe8af893..b047741b9 100644
--- a/lib/sanitizer_common/sanitizer_flags.inc
+++ b/lib/sanitizer_common/sanitizer_flags.inc
@@ -103,7 +103,7 @@ COMMON_FLAG(bool, allow_user_segv_handler, true,
"handle_*=1 will be upgraded to handle_*=2.")
COMMON_FLAG(bool, use_sigaltstack, true,
"If set, uses alternate stack for signal handling.")
-COMMON_FLAG(bool, detect_deadlocks, false,
+COMMON_FLAG(bool, detect_deadlocks, true,
"If set, deadlock detection is enabled.")
COMMON_FLAG(
uptr, clear_shadow_mmap_threshold, 64 * 1024,
@@ -243,3 +243,6 @@ COMMON_FLAG(bool, dump_registers, true,
COMMON_FLAG(bool, detect_write_exec, false,
"If true, triggers warning when writable-executable pages requests "
"are being made")
+COMMON_FLAG(bool, test_only_emulate_no_memorymap, false,
+ "TEST ONLY fail to read memory mappings to emulate sanitized "
+ "\"init\"")
diff --git a/lib/sanitizer_common/sanitizer_fuchsia.cc b/lib/sanitizer_common/sanitizer_fuchsia.cc
index 069866641..2c259b6cd 100644
--- a/lib/sanitizer_common/sanitizer_fuchsia.cc
+++ b/lib/sanitizer_common/sanitizer_fuchsia.cc
@@ -89,6 +89,7 @@ void GetThreadStackTopAndBottom(bool, uptr *stack_top, uptr *stack_bottom) {
void InitializePlatformEarly() {}
void MaybeReexec() {}
void CheckASLR() {}
+void CheckMPROTECT() {}
void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {}
void DisableCoreDumperIfNecessary() {}
void InstallDeadlySignalHandlers(SignalHandlerType handler) {}
@@ -209,10 +210,10 @@ uptr ReservedAddressRange::Init(uptr init_size, const char *name,
uintptr_t base;
zx_handle_t vmar;
zx_status_t status =
- _zx_vmar_allocate_old(_zx_vmar_root_self(), 0, init_size,
- ZX_VM_FLAG_CAN_MAP_READ | ZX_VM_FLAG_CAN_MAP_WRITE |
- ZX_VM_FLAG_CAN_MAP_SPECIFIC,
- &vmar, &base);
+ _zx_vmar_allocate(
+ _zx_vmar_root_self(),
+ ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE | ZX_VM_CAN_MAP_SPECIFIC,
+ 0, init_size, &vmar, &base);
if (status != ZX_OK)
ReportMmapFailureAndDie(init_size, name, "zx_vmar_allocate", status);
base_ = reinterpret_cast<void *>(base);
diff --git a/lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc b/lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc
index dcfce3c1e..86cb44047 100644
--- a/lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc
+++ b/lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc
@@ -25,7 +25,7 @@ struct ioctl_desc {
const char *name;
};
-const unsigned ioctl_table_max = 1201;
+const unsigned ioctl_table_max = 1202;
static ioctl_desc ioctl_table[ioctl_table_max];
static unsigned ioctl_table_size = 0;
@@ -649,6 +649,23 @@ static void ioctl_table_fill() {
_(SPKRTUNE, NONE, 0);
_(SPKRGETVOL, WRITE, sizeof(unsigned int));
_(SPKRSETVOL, READ, sizeof(unsigned int));
+ /* Entries from file: dev/nvmm/nvmm_ioctl.h */
+#if 0 /* WIP */
+ _(NVMM_IOC_CAPABILITY, WRITE, struct_nvmm_ioc_capability_sz);
+ _(NVMM_IOC_MACHINE_CREATE, READWRITE, struct_nvmm_ioc_machine_create_sz);
+ _(NVMM_IOC_MACHINE_DESTROY, READ, struct_nvmm_ioc_machine_destroy_sz);
+ _(NVMM_IOC_MACHINE_CONFIGURE, READ, struct_nvmm_ioc_machine_configure_sz);
+ _(NVMM_IOC_VCPU_CREATE, READ, struct_nvmm_ioc_vcpu_create_sz);
+ _(NVMM_IOC_VCPU_DESTROY, READ, struct_nvmm_ioc_vcpu_destroy_sz);
+ _(NVMM_IOC_VCPU_SETSTATE, READ, struct_nvmm_ioc_vcpu_setstate_sz);
+ _(NVMM_IOC_VCPU_GETSTATE, READ, struct_nvmm_ioc_vcpu_getstate_sz);
+ _(NVMM_IOC_VCPU_INJECT, READWRITE, struct_nvmm_ioc_vcpu_inject_sz);
+ _(NVMM_IOC_VCPU_RUN, READWRITE, struct_nvmm_ioc_vcpu_run_sz);
+ _(NVMM_IOC_GPA_MAP, READ, struct_nvmm_ioc_gpa_map_sz);
+ _(NVMM_IOC_GPA_UNMAP, READ, struct_nvmm_ioc_gpa_unmap_sz);
+ _(NVMM_IOC_HVA_MAP, READ, struct_nvmm_ioc_hva_map_sz);
+ _(NVMM_IOC_HVA_UNMAP, READ, struct_nvmm_ioc_hva_unmap_sz);
+#endif
/* Entries from file: fs/autofs/autofs_ioctl.h */
_(AUTOFSREQUEST, WRITE, struct_autofs_daemon_request_sz);
_(AUTOFSDONE, READ, struct_autofs_daemon_done_sz);
@@ -1192,6 +1209,7 @@ static void ioctl_table_fill() {
_(SIOCSLINKSTR, READ, struct_ifdrv_sz);
_(SIOCGETHERCAP, READWRITE, struct_eccapreq_sz);
_(SIOCGIFINDEX, READWRITE, struct_ifreq_sz);
+ _(SIOCSETHERCAP, READ, struct_eccapreq_sz);
_(SIOCGUMBINFO, READWRITE, struct_ifreq_sz);
_(SIOCSUMBPARAM, READ, struct_ifreq_sz);
_(SIOCGUMBPARAM, READWRITE, struct_ifreq_sz);
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc
index 6cfb61506..48795674c 100644
--- a/lib/sanitizer_common/sanitizer_linux.cc
+++ b/lib/sanitizer_common/sanitizer_linux.cc
@@ -381,6 +381,10 @@ uptr internal_filesize(fd_t fd) {
return (uptr)st.st_size;
}
+uptr internal_dup(int oldfd) {
+ return internal_syscall(SYSCALL(dup), oldfd);
+}
+
uptr internal_dup2(int oldfd, int newfd) {
#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
return internal_syscall(SYSCALL(dup3), oldfd, newfd, 0);
@@ -449,6 +453,8 @@ uptr internal_execve(const char *filename, char *const argv[],
// ----------------- sanitizer_common.h
bool FileExists(const char *filename) {
+ if (ShouldMockFailureToOpen(filename))
+ return false;
struct stat st;
#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
if (internal_syscall(SYSCALL(newfstatat), AT_FDCWD, filename, &st, 0))
@@ -1004,6 +1010,8 @@ static uptr GetKernelAreaSize() {
// Firstly check if there are writable segments
// mapped to top gigabyte (e.g. stack).
MemoryMappingLayout proc_maps(/*cache_enabled*/true);
+ if (proc_maps.Error())
+ return 0;
MemoryMappedSegment segment;
while (proc_maps.Next(&segment)) {
if ((segment.end >= 3 * gbyte) && segment.IsWritable()) return 0;
@@ -1069,11 +1077,9 @@ uptr GetMaxUserVirtualAddress() {
return addr;
}
+#if !SANITIZER_ANDROID
uptr GetPageSize() {
-// Android post-M sysconf(_SC_PAGESIZE) crashes if called from .preinit_array.
-#if SANITIZER_ANDROID
- return 4096;
-#elif SANITIZER_LINUX && (defined(__x86_64__) || defined(__i386__))
+#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__i386__))
return EXEC_PAGESIZE;
#elif SANITIZER_USE_GETAUXVAL
return getauxval(AT_PAGESZ);
@@ -1089,6 +1095,7 @@ uptr GetPageSize() {
return sysconf(_SC_PAGESIZE); // EXEC_PAGESIZE may not be trustworthy.
#endif
}
+#endif // !SANITIZER_ANDROID
#if !SANITIZER_OPENBSD
uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
@@ -2019,6 +2026,30 @@ void CheckASLR() {
#endif
}
+void CheckMPROTECT() {
+#if SANITIZER_NETBSD
+ int mib[3];
+ int paxflags;
+ uptr len = sizeof(paxflags);
+
+ mib[0] = CTL_PROC;
+ mib[1] = internal_getpid();
+ mib[2] = PROC_PID_PAXFLAGS;
+
+ if (UNLIKELY(internal_sysctl(mib, 3, &paxflags, &len, NULL, 0) == -1)) {
+ Printf("sysctl failed\n");
+ Die();
+ }
+
+ if (UNLIKELY(paxflags & CTL_PROC_PAXFLAGS_MPROTECT)) {
+ Printf("This sanitizer is not compatible with enabled MPROTECT\n");
+ Die();
+ }
+#else
+ // Do nothing
+#endif
+}
+
void PrintModuleMap() { }
void CheckNoDeepBind(const char *filename, int flag) {
diff --git a/lib/sanitizer_common/sanitizer_linux.h b/lib/sanitizer_common/sanitizer_linux.h
index 6f5387e16..c309e33f8 100644
--- a/lib/sanitizer_common/sanitizer_linux.h
+++ b/lib/sanitizer_common/sanitizer_linux.h
@@ -134,13 +134,13 @@ void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr));
#error "Unsupported architecture."
#endif
-// The Android Bionic team has allocated a TLS slot for TSan starting with N,
-// given that Android currently doesn't support ELF TLS. It is used to store
-// Sanitizers thread specific data.
-static const int TLS_SLOT_TSAN = 8;
+// The Android Bionic team has allocated a TLS slot for sanitizers starting
+// with Q, given that Android currently doesn't support ELF TLS. It is used to
+// store sanitizer thread specific data.
+static const int TLS_SLOT_SANITIZER = 6;
ALWAYS_INLINE uptr *get_android_tls_ptr() {
- return reinterpret_cast<uptr *>(&__get_tls()[TLS_SLOT_TSAN]);
+ return reinterpret_cast<uptr *>(&__get_tls()[TLS_SLOT_SANITIZER]);
}
#endif // SANITIZER_ANDROID
diff --git a/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_linux_libcdep.cc
index 84da23e3f..6ce47ec62 100644
--- a/lib/sanitizer_common/sanitizer_linux_libcdep.cc
+++ b/lib/sanitizer_common/sanitizer_linux_libcdep.cc
@@ -100,6 +100,10 @@ void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top,
// Find the mapping that contains a stack variable.
MemoryMappingLayout proc_maps(/*cache_enabled*/true);
+ if (proc_maps.Error()) {
+ *stack_top = *stack_bottom = 0;
+ return;
+ }
MemoryMappedSegment segment;
uptr prev_end = 0;
while (proc_maps.Next(&segment)) {
diff --git a/lib/sanitizer_common/sanitizer_local_address_space_view.h b/lib/sanitizer_common/sanitizer_local_address_space_view.h
index 9fbf593f4..ec1847abc 100644
--- a/lib/sanitizer_common/sanitizer_local_address_space_view.h
+++ b/lib/sanitizer_common/sanitizer_local_address_space_view.h
@@ -12,7 +12,7 @@
// provides a simple interface to load memory from another process (i.e.
// out-of-process)
//
-// The `AddressSpaveView` interface requires that the type can be used as a
+// The `AddressSpaceView` interface requires that the type can be used as a
// template parameter to objects that wish to be able to operate in an
// out-of-process manner. In normal usage, objects are in-process and are thus
// instantiated with the `LocalAddressSpaceView` type. This type is used to
@@ -31,18 +31,42 @@
namespace __sanitizer {
struct LocalAddressSpaceView {
- // Load memory `sizeof(T) * num_elements` bytes of memory
- // from the target process (always local for this implementation)
- // starting at address `target_address`. The local copy of
- // this memory is returned as a pointer. It is guaranteed that
+ // Load memory `sizeof(T) * num_elements` bytes of memory from the target
+ // process (always local for this implementation) starting at address
+ // `target_address`. The local copy of this memory is returned as a pointer.
+ // The caller should not write to this memory. The behaviour when doing so is
+ // undefined. Callers should use `LoadWritable()` to get access to memory
+ // that is writable.
//
- // * That the function will always return the same value
- // for a given set of arguments.
- // * That the memory returned is writable and that writes will persist.
+ // The lifetime of loaded memory is implementation defined.
+ template <typename T>
+ static const T *Load(const T *target_address, uptr num_elements = 1) {
+ // The target address space is the local address space so
+ // nothing needs to be copied. Just return the pointer.
+ return target_address;
+ }
+
+ // Load memory `sizeof(T) * num_elements` bytes of memory from the target
+ // process (always local for this implementation) starting at address
+ // `target_address`. The local copy of this memory is returned as a pointer.
+ // The memory returned may be written to.
+ //
+ // Writes made to the returned memory will be visible in the memory returned
+ // by subsequent `Load()` or `LoadWritable()` calls provided the
+ // `target_address` parameter is the same. It is not guaranteed that the
+ // memory returned by previous calls to `Load()` will contain any performed
+ // writes. If two or more overlapping regions of memory are loaded via
+ // separate calls to `LoadWritable()`, it is implementation defined whether
+ // writes made to the region returned by one call are visible in the regions
+ // returned by other calls.
+ //
+ // Given the above it is recommended to load the largest possible object
+ // that requires modification (e.g. a class) rather than individual fields
+ // from a class to avoid issues with overlapping writable regions.
//
// The lifetime of loaded memory is implementation defined.
template <typename T>
- static T *Load(T *target_address, uptr num_elements = 1) {
+ static T *LoadWritable(T *target_address, uptr num_elements = 1) {
// The target address space is the local address space so
// nothing needs to be copied. Just return the pointer.
return target_address;
diff --git a/lib/sanitizer_common/sanitizer_mac.cc b/lib/sanitizer_common/sanitizer_mac.cc
index 95c47babe..8954a7a88 100644
--- a/lib/sanitizer_common/sanitizer_mac.cc
+++ b/lib/sanitizer_common/sanitizer_mac.cc
@@ -174,6 +174,10 @@ uptr internal_filesize(fd_t fd) {
return (uptr)st.st_size;
}
+uptr internal_dup(int oldfd) {
+ return dup(oldfd);
+}
+
uptr internal_dup2(int oldfd, int newfd) {
return dup2(oldfd, newfd);
}
@@ -278,6 +282,8 @@ uptr internal_waitpid(int pid, int *status, int options) {
// ----------------- sanitizer_common.h
bool FileExists(const char *filename) {
+ if (ShouldMockFailureToOpen(filename))
+ return false;
struct stat st;
if (stat(filename, &st))
return false;
@@ -373,6 +379,10 @@ void CheckASLR() {
// Do nothing
}
+void CheckMPROTECT() {
+ // Do nothing
+}
+
uptr GetPageSize() {
return sysconf(_SC_PAGESIZE);
}
diff --git a/lib/sanitizer_common/sanitizer_netbsd.cc b/lib/sanitizer_common/sanitizer_netbsd.cc
index 83beb008f..80d0855ef 100644
--- a/lib/sanitizer_common/sanitizer_netbsd.cc
+++ b/lib/sanitizer_common/sanitizer_netbsd.cc
@@ -169,6 +169,11 @@ uptr internal_filesize(fd_t fd) {
return (uptr)st.st_size;
}
+uptr internal_dup(int oldfd) {
+ DEFINE__REAL(int, dup, int a);
+ return _REAL(dup, oldfd);
+}
+
uptr internal_dup2(int oldfd, int newfd) {
DEFINE__REAL(int, dup2, int a, int b);
return _REAL(dup2, oldfd, newfd);
@@ -202,7 +207,7 @@ void internal__exit(int exitcode) {
unsigned int internal_sleep(unsigned int seconds) {
struct timespec ts;
- ts.tv_sec = 1;
+ ts.tv_sec = seconds;
ts.tv_nsec = 0;
CHECK(&_sys___nanosleep50);
int res = _sys___nanosleep50(&ts, &ts);
diff --git a/lib/sanitizer_common/sanitizer_platform.h b/lib/sanitizer_common/sanitizer_platform.h
index fd7228c3b..82bb1af77 100644
--- a/lib/sanitizer_common/sanitizer_platform.h
+++ b/lib/sanitizer_common/sanitizer_platform.h
@@ -275,12 +275,6 @@
# define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 12)
#endif
-// Assume obsolete RPC headers are available by default
-#if !defined(HAVE_RPC_XDR_H) && !defined(HAVE_TIRPC_RPC_XDR_H)
-# define HAVE_RPC_XDR_H (SANITIZER_LINUX && !SANITIZER_ANDROID)
-# define HAVE_TIRPC_RPC_XDR_H 0
-#endif
-
/// \macro MSC_PREREQ
/// \brief Is the compiler MSVC of at least the specified version?
/// The common \param version values to check for are:
diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h
index aedcc7c5f..4d146651b 100644
--- a/lib/sanitizer_common/sanitizer_platform_interceptors.h
+++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h
@@ -387,7 +387,7 @@
#define SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP \
(SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_PTHREAD_GETNAME_NP \
- (SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
+ (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
#define SANITIZER_INTERCEPT_TLS_GET_ADDR \
(SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS)
@@ -522,15 +522,16 @@
#define SANITIZER_INTERCEPT_GETMNTINFO (SI_NETBSD || SI_FREEBSD || SI_MAC)
#define SANITIZER_INTERCEPT_MI_VECTOR_HASH SI_NETBSD
#define SANITIZER_INTERCEPT_GETVFSSTAT SI_NETBSD
-#define SANITIZER_INTERCEPT_REGEX SI_NETBSD
-#define SANITIZER_INTERCEPT_FTS SI_NETBSD
+#define SANITIZER_INTERCEPT_REGEX (SI_NETBSD || SI_FREEBSD || SI_LINUX)
+#define SANITIZER_INTERCEPT_REGEXSUB SI_NETBSD
+#define SANITIZER_INTERCEPT_FTS (SI_NETBSD || SI_FREEBSD)
#define SANITIZER_INTERCEPT_SYSCTL (SI_NETBSD || SI_FREEBSD || SI_MAC)
#define SANITIZER_INTERCEPT_ASYSCTL SI_NETBSD
#define SANITIZER_INTERCEPT_SYSCTLGETMIBINFO SI_NETBSD
#define SANITIZER_INTERCEPT_NL_LANGINFO (SI_NETBSD || SI_FREEBSD || SI_MAC)
#define SANITIZER_INTERCEPT_MODCTL SI_NETBSD
#define SANITIZER_INTERCEPT_CAPSICUM SI_FREEBSD
-#define SANITIZER_INTERCEPT_STRTONUM SI_NETBSD
+#define SANITIZER_INTERCEPT_STRTONUM (SI_NETBSD || SI_FREEBSD)
#define SANITIZER_INTERCEPT_FPARSELN SI_NETBSD
#define SANITIZER_INTERCEPT_STATVFS1 SI_NETBSD
#define SANITIZER_INTERCEPT_STRTOI SI_NETBSD
@@ -543,6 +544,16 @@
#define SANITIZER_INTERCEPT_MD2 SI_NETBSD
#define SANITIZER_INTERCEPT_SHA2 SI_NETBSD
#define SANITIZER_INTERCEPT_CDB SI_NETBSD
-#define SANITIZER_INTERCEPT_VIS SI_NETBSD
+#define SANITIZER_INTERCEPT_VIS (SI_NETBSD || SI_FREEBSD)
+#define SANITIZER_INTERCEPT_POPEN SI_POSIX
+#define SANITIZER_INTERCEPT_POPENVE SI_NETBSD
+#define SANITIZER_INTERCEPT_PCLOSE SI_POSIX
+#define SANITIZER_INTERCEPT_FUNOPEN (SI_NETBSD || SI_FREEBSD)
+#define SANITIZER_INTERCEPT_FUNOPEN2 SI_NETBSD
+#define SANITIZER_INTERCEPT_GETFSENT (SI_FREEBSD || SI_NETBSD || SI_MAC)
+#define SANITIZER_INTERCEPT_ARC4RANDOM (SI_FREEBSD || SI_NETBSD)
+#define SANITIZER_INTERCEPT_FDEVNAME SI_FREEBSD
+#define SANITIZER_INTERCEPT_GETUSERSHELL (SI_POSIX && !SI_POSIX)
+#define SANITIZER_INTERCEPT_SL_INIT (SI_FREEBSD || SI_NETBSD)
#endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cc b/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cc
index cebb216ec..377a62cab 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cc
+++ b/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cc
@@ -18,6 +18,8 @@
#include <arpa/inet.h>
#include <dirent.h>
+#include <fts.h>
+#include <fstab.h>
#include <grp.h>
#include <limits.h>
#include <net/if.h>
@@ -25,6 +27,7 @@
#include <poll.h>
#include <pthread.h>
#include <pwd.h>
+#include <regex.h>
#include <signal.h>
#include <stddef.h>
#include <sys/mman.h>
@@ -62,9 +65,11 @@
#include <net/ppp_defs.h>
#include <glob.h>
#include <stdio.h>
+#include <stringlist.h>
#include <term.h>
#include <utmpx.h>
#include <wchar.h>
+#include <vis.h>
#define _KERNEL // to declare 'shminfo' structure
# include <sys/shm.h>
@@ -124,6 +129,12 @@ namespace __sanitizer {
unsigned struct_statvfs_sz = sizeof(struct statvfs);
unsigned struct_shminfo_sz = sizeof(struct shminfo);
unsigned struct_shm_info_sz = sizeof(struct shm_info);
+ unsigned struct_regmatch_sz = sizeof(regmatch_t);
+ unsigned struct_regex_sz = sizeof(regex_t);
+ unsigned struct_fstab_sz = sizeof(struct fstab);
+ unsigned struct_FTS_sz = sizeof(FTS);
+ unsigned struct_FTSENT_sz = sizeof(FTSENT);
+ unsigned struct_StringList_sz = sizeof(StringList);
const uptr sig_ign = (uptr)SIG_IGN;
const uptr sig_dfl = (uptr)SIG_DFL;
@@ -338,6 +349,8 @@ namespace __sanitizer {
const int si_SEGV_MAPERR = SEGV_MAPERR;
const int si_SEGV_ACCERR = SEGV_ACCERR;
+ const int unvis_valid = UNVIS_VALID;
+ const int unvis_validpush = UNVIS_VALIDPUSH;
} // namespace __sanitizer
using namespace __sanitizer;
@@ -494,7 +507,7 @@ CHECK_SIZE_AND_OFFSET(group, gr_passwd);
CHECK_SIZE_AND_OFFSET(group, gr_gid);
CHECK_SIZE_AND_OFFSET(group, gr_mem);
-#if HAVE_RPC_XDR_H || HAVE_TIRPC_RPC_XDR_H
+#if HAVE_RPC_XDR_H
CHECK_TYPE_SIZE(XDR);
CHECK_SIZE_AND_OFFSET(XDR, x_op);
CHECK_SIZE_AND_OFFSET(XDR, x_ops);
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h b/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h
index 90329acb3..588bead2a 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h
+++ b/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h
@@ -62,6 +62,12 @@ namespace __sanitizer {
extern unsigned struct_rlimit_sz;
extern unsigned struct_utimbuf_sz;
extern unsigned struct_timespec_sz;
+ extern unsigned struct_regmatch_sz;
+ extern unsigned struct_regex_sz;
+ extern unsigned struct_FTS_sz;
+ extern unsigned struct_FTSENT_sz;
+ extern const int unvis_valid;
+ extern const int unvis_validpush;
struct __sanitizer_iocb {
u64 aio_data;
@@ -622,6 +628,9 @@ namespace __sanitizer {
typedef struct __sanitizer_cap_rights __sanitizer_cap_rights_t;
extern unsigned struct_cap_rights_sz;
+
+ extern unsigned struct_fstab_sz;
+ extern unsigned struct_StringList_sz;
} // namespace __sanitizer
#define CHECK_TYPE_SIZE(TYPE) \
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc b/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc
index 6633a36b4..b23b430d9 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc
+++ b/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc
@@ -125,6 +125,7 @@
#include <dev/isa/satlinkio.h>
#include <dev/isa/wtreg.h>
#include <dev/iscsi/iscsi_ioctl.h>
+#include <dev/nvmm/nvmm_ioctl.h>
#include <dev/ofw/openfirmio.h>
#include <dev/pci/amrio.h>
#include <dev/pci/mlyreg.h>
@@ -218,6 +219,8 @@
#include <ttyent.h>
#include <fts.h>
#include <regex.h>
+#include <fstab.h>
+#include <stringlist.h>
// clang-format on
// Include these after system headers to avoid name clashes and ambiguities.
@@ -257,6 +260,7 @@ unsigned struct_FTS_sz = sizeof(FTS);
unsigned struct_FTSENT_sz = sizeof(FTSENT);
unsigned struct_regex_sz = sizeof(regex_t);
unsigned struct_regmatch_sz = sizeof(regmatch_t);
+unsigned struct_fstab_sz = sizeof(struct fstab);
unsigned struct_utimbuf_sz = sizeof(struct utimbuf);
unsigned struct_itimerspec_sz = sizeof(struct itimerspec);
unsigned struct_timex_sz = sizeof(struct timex);
@@ -828,6 +832,7 @@ unsigned struct_RF_ComponentLabel_sz = sizeof(RF_ComponentLabel_t);
unsigned struct_RF_SingleComponent_sz = sizeof(RF_SingleComponent_t);
unsigned struct_RF_ProgressInfo_sz = sizeof(RF_ProgressInfo_t);
unsigned struct_nvlist_ref_sz = sizeof(struct __sanitizer_nvlist_ref_t);
+unsigned struct_StringList_sz = sizeof(StringList);
const unsigned IOCTL_NOT_PRESENT = 0;
@@ -1422,6 +1427,22 @@ unsigned IOCTL_SPKRTONE = SPKRTONE;
unsigned IOCTL_SPKRTUNE = SPKRTUNE;
unsigned IOCTL_SPKRGETVOL = SPKRGETVOL;
unsigned IOCTL_SPKRSETVOL = SPKRSETVOL;
+#if 0 /* interfaces are WIP */
+unsigned IOCTL_NVMM_IOC_CAPABILITY = NVMM_IOC_CAPABILITY;
+unsigned IOCTL_NVMM_IOC_MACHINE_CREATE = NVMM_IOC_MACHINE_CREATE;
+unsigned IOCTL_NVMM_IOC_MACHINE_DESTROY = NVMM_IOC_MACHINE_DESTROY;
+unsigned IOCTL_NVMM_IOC_MACHINE_CONFIGURE = NVMM_IOC_MACHINE_CONFIGURE;
+unsigned IOCTL_NVMM_IOC_VCPU_CREATE = NVMM_IOC_VCPU_CREATE;
+unsigned IOCTL_NVMM_IOC_VCPU_DESTROY = NVMM_IOC_VCPU_DESTROY;
+unsigned IOCTL_NVMM_IOC_VCPU_SETSTATE = NVMM_IOC_VCPU_SETSTATE;
+unsigned IOCTL_NVMM_IOC_VCPU_GETSTATE = NVMM_IOC_VCPU_GETSTATE;
+unsigned IOCTL_NVMM_IOC_VCPU_INJECT = NVMM_IOC_VCPU_INJECT;
+unsigned IOCTL_NVMM_IOC_VCPU_RUN = NVMM_IOC_VCPU_RUN;
+unsigned IOCTL_NVMM_IOC_GPA_MAP = NVMM_IOC_GPA_MAP;
+unsigned IOCTL_NVMM_IOC_GPA_UNMAP = NVMM_IOC_GPA_UNMAP;
+unsigned IOCTL_NVMM_IOC_HVA_MAP = NVMM_IOC_HVA_MAP;
+unsigned IOCTL_NVMM_IOC_HVA_UNMAP = NVMM_IOC_HVA_UNMAP;
+#endif
unsigned IOCTL_AUTOFSREQUEST = AUTOFSREQUEST;
unsigned IOCTL_AUTOFSDONE = AUTOFSDONE;
unsigned IOCTL_BIOCGBLEN = BIOCGBLEN;
@@ -1927,6 +1948,7 @@ unsigned IOCTL_SIOCGLINKSTR = SIOCGLINKSTR;
unsigned IOCTL_SIOCSLINKSTR = SIOCSLINKSTR;
unsigned IOCTL_SIOCGETHERCAP = SIOCGETHERCAP;
unsigned IOCTL_SIOCGIFINDEX = SIOCGIFINDEX;
+unsigned IOCTL_SIOCSETHERCAP = SIOCSETHERCAP;
unsigned IOCTL_SIOCGUMBINFO = SIOCGUMBINFO;
unsigned IOCTL_SIOCSUMBPARAM = SIOCSUMBPARAM;
unsigned IOCTL_SIOCGUMBPARAM = SIOCGUMBPARAM;
@@ -2224,6 +2246,29 @@ CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordc);
CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordv);
CHECK_SIZE_AND_OFFSET(wordexp_t, we_offs);
+COMPILER_CHECK(sizeof(__sanitizer_FILE) <= sizeof(FILE));
+CHECK_SIZE_AND_OFFSET(FILE, _p);
+CHECK_SIZE_AND_OFFSET(FILE, _r);
+CHECK_SIZE_AND_OFFSET(FILE, _w);
+CHECK_SIZE_AND_OFFSET(FILE, _flags);
+CHECK_SIZE_AND_OFFSET(FILE, _file);
+CHECK_SIZE_AND_OFFSET(FILE, _bf);
+CHECK_SIZE_AND_OFFSET(FILE, _lbfsize);
+CHECK_SIZE_AND_OFFSET(FILE, _cookie);
+CHECK_SIZE_AND_OFFSET(FILE, _close);
+CHECK_SIZE_AND_OFFSET(FILE, _read);
+CHECK_SIZE_AND_OFFSET(FILE, _seek);
+CHECK_SIZE_AND_OFFSET(FILE, _write);
+CHECK_SIZE_AND_OFFSET(FILE, _ext);
+CHECK_SIZE_AND_OFFSET(FILE, _up);
+CHECK_SIZE_AND_OFFSET(FILE, _ur);
+CHECK_SIZE_AND_OFFSET(FILE, _ubuf);
+CHECK_SIZE_AND_OFFSET(FILE, _nbuf);
+CHECK_SIZE_AND_OFFSET(FILE, _flush);
+CHECK_SIZE_AND_OFFSET(FILE, _lb_unused);
+CHECK_SIZE_AND_OFFSET(FILE, _blksize);
+CHECK_SIZE_AND_OFFSET(FILE, _offset);
+
CHECK_TYPE_SIZE(tm);
CHECK_SIZE_AND_OFFSET(tm, tm_sec);
CHECK_SIZE_AND_OFFSET(tm, tm_min);
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h b/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
index 39581361d..0c0c8a837 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
+++ b/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h
@@ -66,6 +66,8 @@ extern unsigned struct_FTSENT_sz;
extern unsigned struct_regex_sz;
extern unsigned struct_regmatch_sz;
+extern unsigned struct_fstab_sz;
+
struct __sanitizer_regmatch {
OFF_T rm_so;
OFF_T rm_eo;
@@ -446,8 +448,36 @@ struct __sanitizer_wordexp_t {
uptr we_nbytes;
};
-typedef char __sanitizer_FILE;
-#define SANITIZER_HAS_STRUCT_FILE 0
+struct __sanitizer_FILE {
+ unsigned char *_p;
+ int _r;
+ int _w;
+ unsigned short _flags;
+ short _file;
+ struct {
+ unsigned char *_base;
+ int _size;
+ } _bf;
+ int _lbfsize;
+ void *_cookie;
+ int (*_close)(void *ptr);
+ u64 (*_read)(void *, void *, uptr);
+ u64 (*_seek)(void *, u64, int);
+ uptr (*_write)(void *, const void *, uptr);
+ struct {
+ unsigned char *_base;
+ int _size;
+ } _ext;
+ unsigned char *_up;
+ int _ur;
+ unsigned char _ubuf[3];
+ unsigned char _nbuf[1];
+ int (*_flush)(void *ptr);
+ char _lb_unused[sizeof(uptr)];
+ int _blksize;
+ u64 _offset;
+};
+#define SANITIZER_HAS_STRUCT_FILE 1
extern int shmctl_ipc_stat;
@@ -959,6 +989,7 @@ extern unsigned struct_RF_ComponentLabel_sz;
extern unsigned struct_RF_SingleComponent_sz;
extern unsigned struct_RF_ProgressInfo_sz;
extern unsigned struct_nvlist_ref_sz;
+extern unsigned struct_StringList_sz;
// A special value to mark ioctls that are not present on the target platform,
@@ -1549,6 +1580,22 @@ extern unsigned IOCTL_SPKRTONE;
extern unsigned IOCTL_SPKRTUNE;
extern unsigned IOCTL_SPKRGETVOL;
extern unsigned IOCTL_SPKRSETVOL;
+#if 0 /* interfaces are WIP */
+extern unsigned IOCTL_NVMM_IOC_CAPABILITY;
+extern unsigned IOCTL_NVMM_IOC_MACHINE_CREATE;
+extern unsigned IOCTL_NVMM_IOC_MACHINE_DESTROY;
+extern unsigned IOCTL_NVMM_IOC_MACHINE_CONFIGURE;
+extern unsigned IOCTL_NVMM_IOC_VCPU_CREATE;
+extern unsigned IOCTL_NVMM_IOC_VCPU_DESTROY;
+extern unsigned IOCTL_NVMM_IOC_VCPU_SETSTATE;
+extern unsigned IOCTL_NVMM_IOC_VCPU_GETSTATE;
+extern unsigned IOCTL_NVMM_IOC_VCPU_INJECT;
+extern unsigned IOCTL_NVMM_IOC_VCPU_RUN;
+extern unsigned IOCTL_NVMM_IOC_GPA_MAP;
+extern unsigned IOCTL_NVMM_IOC_GPA_UNMAP;
+extern unsigned IOCTL_NVMM_IOC_HVA_MAP;
+extern unsigned IOCTL_NVMM_IOC_HVA_UNMAP;
+#endif
extern unsigned IOCTL_AUTOFSREQUEST;
extern unsigned IOCTL_AUTOFSDONE;
extern unsigned IOCTL_BIOCGBLEN;
@@ -2054,6 +2101,7 @@ extern unsigned IOCTL_SIOCGLINKSTR;
extern unsigned IOCTL_SIOCSLINKSTR;
extern unsigned IOCTL_SIOCGETHERCAP;
extern unsigned IOCTL_SIOCGIFINDEX;
+extern unsigned IOCTL_SIOCSETHERCAP;
extern unsigned IOCTL_SIOCGUMBINFO;
extern unsigned IOCTL_SIOCSUMBPARAM;
extern unsigned IOCTL_SIOCGUMBPARAM;
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
index a383ebf9f..ecc69bcea 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
+++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.cc
@@ -45,6 +45,7 @@
#include <termios.h>
#include <time.h>
#include <wchar.h>
+#include <regex.h>
#if !SANITIZER_MAC
#include <utmp.h>
#endif
@@ -54,6 +55,7 @@
#endif
#if !SANITIZER_ANDROID
+#include <fstab.h>
#include <sys/mount.h>
#include <sys/timeb.h>
#include <utmpx.h>
@@ -114,8 +116,6 @@ typedef struct user_fpregs elf_fpregset_t;
#include <netrom/netrom.h>
#if HAVE_RPC_XDR_H
# include <rpc/xdr.h>
-#elif HAVE_TIRPC_RPC_XDR_H
-# include <tirpc/rpc/xdr.h>
#endif
#include <scsi/scsi.h>
#include <sys/mtio.h>
@@ -189,13 +189,15 @@ namespace __sanitizer {
unsigned struct_tms_sz = sizeof(struct tms);
unsigned struct_sigevent_sz = sizeof(struct sigevent);
unsigned struct_sched_param_sz = sizeof(struct sched_param);
-
+ unsigned struct_regex_sz = sizeof(regex_t);
+ unsigned struct_regmatch_sz = sizeof(regmatch_t);
#if SANITIZER_MAC && !SANITIZER_IOS
unsigned struct_statfs64_sz = sizeof(struct statfs64);
#endif // SANITIZER_MAC && !SANITIZER_IOS
#if !SANITIZER_ANDROID
+ unsigned struct_fstab_sz = sizeof(struct fstab);
unsigned struct_statfs_sz = sizeof(struct statfs);
unsigned struct_sockaddr_sz = sizeof(struct sockaddr);
unsigned ucontext_t_sz = sizeof(ucontext_t);
@@ -1210,7 +1212,7 @@ CHECK_SIZE_AND_OFFSET(group, gr_passwd);
CHECK_SIZE_AND_OFFSET(group, gr_gid);
CHECK_SIZE_AND_OFFSET(group, gr_mem);
-#if HAVE_RPC_XDR_H || HAVE_TIRPC_RPC_XDR_H
+#if HAVE_RPC_XDR_H
CHECK_TYPE_SIZE(XDR);
CHECK_SIZE_AND_OFFSET(XDR, x_op);
CHECK_SIZE_AND_OFFSET(XDR, x_ops);
diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
index f51644e3c..de69852d3 100644
--- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h
+++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h
@@ -49,8 +49,11 @@ namespace __sanitizer {
extern unsigned struct_sigevent_sz;
extern unsigned struct_sched_param_sz;
extern unsigned struct_statfs64_sz;
+ extern unsigned struct_regex_sz;
+ extern unsigned struct_regmatch_sz;
#if !SANITIZER_ANDROID
+ extern unsigned struct_fstab_sz;
extern unsigned struct_statfs_sz;
extern unsigned struct_sockaddr_sz;
extern unsigned ucontext_t_sz;
diff --git a/lib/sanitizer_common/sanitizer_posix.cc b/lib/sanitizer_common/sanitizer_posix.cc
index 116270f8d..b965fb0da 100644
--- a/lib/sanitizer_common/sanitizer_posix.cc
+++ b/lib/sanitizer_common/sanitizer_posix.cc
@@ -18,6 +18,7 @@
#include "sanitizer_common.h"
#include "sanitizer_file.h"
+#include "sanitizer_flags.h"
#include "sanitizer_libc.h"
#include "sanitizer_posix.h"
#include "sanitizer_procmaps.h"
@@ -157,6 +158,8 @@ void MprotectMallocZones(void *addr, int prot) {}
#endif
fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *errno_p) {
+ if (ShouldMockFailureToOpen(filename))
+ return kInvalidFd;
int flags;
switch (mode) {
case RdOnly: flags = O_RDONLY; break;
@@ -166,7 +169,7 @@ fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *errno_p) {
fd_t res = internal_open(filename, flags, 0660);
if (internal_iserror(res, errno_p))
return kInvalidFd;
- return res;
+ return ReserveStandardFds(res);
}
void CloseFile(fd_t fd) {
@@ -230,6 +233,8 @@ static inline bool IntervalsAreSeparate(uptr start1, uptr end1,
// memory).
bool MemoryRangeIsAvailable(uptr range_start, uptr range_end) {
MemoryMappingLayout proc_maps(/*cache_enabled*/true);
+ if (proc_maps.Error())
+ return true; // and hope for the best
MemoryMappedSegment segment;
while (proc_maps.Next(&segment)) {
if (segment.start == segment.end) continue; // Empty range.
@@ -269,13 +274,8 @@ bool IsAbsolutePath(const char *path) {
void ReportFile::Write(const char *buffer, uptr length) {
SpinMutexLock l(mu);
- static const char *kWriteError =
- "ReportFile::Write() can't output requested buffer!\n";
ReopenIfNecessary();
- if (length != internal_write(fd, buffer, length)) {
- internal_write(fd, kWriteError, internal_strlen(kWriteError));
- Die();
- }
+ internal_write(fd, buffer, length);
}
bool GetCodeRangeForFile(const char *module, uptr *start, uptr *end) {
@@ -323,6 +323,27 @@ const char *SignalContext::Describe() const {
return "UNKNOWN SIGNAL";
}
+fd_t ReserveStandardFds(fd_t fd) {
+ CHECK_GE(fd, 0);
+ if (fd > 2)
+ return fd;
+ bool used[3];
+ internal_memset(used, 0, sizeof(used));
+ while (fd <= 2) {
+ used[fd] = true;
+ fd = internal_dup(fd);
+ }
+ for (int i = 0; i <= 2; ++i)
+ if (used[i])
+ internal_close(i);
+ return fd;
+}
+
+bool ShouldMockFailureToOpen(const char *path) {
+ return common_flags()->test_only_emulate_no_memorymap &&
+ internal_strncmp(path, "/proc/", 6) == 0;
+}
+
} // namespace __sanitizer
#endif // SANITIZER_POSIX
diff --git a/lib/sanitizer_common/sanitizer_posix.h b/lib/sanitizer_common/sanitizer_posix.h
index 2ebfae8ba..04a76445e 100644
--- a/lib/sanitizer_common/sanitizer_posix.h
+++ b/lib/sanitizer_common/sanitizer_posix.h
@@ -49,6 +49,7 @@ uptr internal_filesize(fd_t fd); // -1 on error.
uptr internal_stat(const char *path, void *buf);
uptr internal_lstat(const char *path, void *buf);
uptr internal_fstat(fd_t fd, void *buf);
+uptr internal_dup(int oldfd);
uptr internal_dup2(int oldfd, int newfd);
uptr internal_readlink(const char *path, char *buf, uptr bufsize);
uptr internal_unlink(const char *path);
@@ -99,6 +100,11 @@ uptr internal_execve(const char *filename, char *const argv[],
bool IsStateDetached(int state);
+// Move the fd out of {0, 1, 2} range.
+fd_t ReserveStandardFds(fd_t fd);
+
+bool ShouldMockFailureToOpen(const char *path);
+
} // namespace __sanitizer
#endif // SANITIZER_POSIX_H
diff --git a/lib/sanitizer_common/sanitizer_procmaps.h b/lib/sanitizer_common/sanitizer_procmaps.h
index 9fde040a1..acb7104f3 100644
--- a/lib/sanitizer_common/sanitizer_procmaps.h
+++ b/lib/sanitizer_common/sanitizer_procmaps.h
@@ -70,6 +70,7 @@ class MemoryMappingLayout {
explicit MemoryMappingLayout(bool cache_enabled);
~MemoryMappingLayout();
bool Next(MemoryMappedSegment *segment);
+ bool Error() const;
void Reset();
// In some cases, e.g. when running under a sandbox on Linux, ASan is unable
// to obtain the memory mappings. It should fall back to pre-cached data
diff --git a/lib/sanitizer_common/sanitizer_procmaps_bsd.cc b/lib/sanitizer_common/sanitizer_procmaps_bsd.cc
index 4cebd9858..362a424d7 100644
--- a/lib/sanitizer_common/sanitizer_procmaps_bsd.cc
+++ b/lib/sanitizer_common/sanitizer_procmaps_bsd.cc
@@ -99,6 +99,7 @@ void ReadProcMaps(ProcSelfMapsBuff *proc_maps) {
}
bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
+ CHECK(!Error()); // can not fail
char *last = data_.proc_self_maps.data + data_.proc_self_maps.len;
if (data_.current >= last)
return false;
diff --git a/lib/sanitizer_common/sanitizer_procmaps_common.cc b/lib/sanitizer_common/sanitizer_procmaps_common.cc
index 1f2b431c7..17d61b6c5 100644
--- a/lib/sanitizer_common/sanitizer_procmaps_common.cc
+++ b/lib/sanitizer_common/sanitizer_procmaps_common.cc
@@ -80,12 +80,14 @@ MemoryMappingLayout::MemoryMappingLayout(bool cache_enabled) {
ReadProcMaps(&data_.proc_self_maps);
if (cache_enabled && data_.proc_self_maps.mmaped_size == 0)
LoadFromCache();
- CHECK_GT(data_.proc_self_maps.mmaped_size, 0);
- CHECK_GT(data_.proc_self_maps.len, 0);
Reset();
}
+bool MemoryMappingLayout::Error() const {
+ return data_.current == nullptr;
+}
+
MemoryMappingLayout::~MemoryMappingLayout() {
// Only unmap the buffer if it is different from the cached one. Otherwise
// it will be unmapped when the cache is refreshed.
diff --git a/lib/sanitizer_common/sanitizer_procmaps_linux.cc b/lib/sanitizer_common/sanitizer_procmaps_linux.cc
index 633e9393c..cf9cb25ba 100644
--- a/lib/sanitizer_common/sanitizer_procmaps_linux.cc
+++ b/lib/sanitizer_common/sanitizer_procmaps_linux.cc
@@ -31,6 +31,7 @@ static bool IsOneOf(char c, char c1, char c2) {
}
bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
+ if (Error()) return false; // simulate empty maps
char *last = data_.proc_self_maps.data + data_.proc_self_maps.len;
if (data_.current >= last) return false;
char *next_line =
diff --git a/lib/sanitizer_common/sanitizer_procmaps_mac.cc b/lib/sanitizer_common/sanitizer_procmaps_mac.cc
index d90e4b993..267c960b5 100644
--- a/lib/sanitizer_common/sanitizer_procmaps_mac.cc
+++ b/lib/sanitizer_common/sanitizer_procmaps_mac.cc
@@ -88,6 +88,10 @@ MemoryMappingLayout::MemoryMappingLayout(bool cache_enabled) {
MemoryMappingLayout::~MemoryMappingLayout() {
}
+bool MemoryMappingLayout::Error() const {
+ return false;
+}
+
// More information about Mach-O headers can be found in mach-o/loader.h
// Each Mach-O image has a header (mach_header or mach_header_64) starting with
// a magic number, and a list of linker load commands directly following the
diff --git a/lib/sanitizer_common/sanitizer_procmaps_solaris.cc b/lib/sanitizer_common/sanitizer_procmaps_solaris.cc
index 9e5e37e6b..49bb46c31 100644
--- a/lib/sanitizer_common/sanitizer_procmaps_solaris.cc
+++ b/lib/sanitizer_common/sanitizer_procmaps_solaris.cc
@@ -21,11 +21,16 @@
namespace __sanitizer {
void ReadProcMaps(ProcSelfMapsBuff *proc_maps) {
- ReadFileToBuffer("/proc/self/xmap", &proc_maps->data, &proc_maps->mmaped_size,
- &proc_maps->len);
+ if (!ReadFileToBuffer("/proc/self/xmap", &proc_maps->data,
+ &proc_maps->mmaped_size, &proc_maps->len)) {
+ proc_maps->data = nullptr;
+ proc_maps->mmaped_size = 0;
+ proc_maps->len = 0;
+ }
}
bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) {
+ if (Error()) return false; // simulate empty maps
char *last = data_.proc_self_maps.data + data_.proc_self_maps.len;
if (data_.current >= last) return false;
diff --git a/lib/sanitizer_common/sanitizer_rtems.cc b/lib/sanitizer_common/sanitizer_rtems.cc
index 678906a18..76aebe419 100644
--- a/lib/sanitizer_common/sanitizer_rtems.cc
+++ b/lib/sanitizer_common/sanitizer_rtems.cc
@@ -98,6 +98,7 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size,
void InitializePlatformEarly() {}
void MaybeReexec() {}
void CheckASLR() {}
+void CheckMPROTECT() {}
void DisableCoreDumperIfNecessary() {}
void InstallDeadlySignalHandlers(SignalHandlerType handler) {}
void SetAlternateSignalStack() {}
diff --git a/lib/sanitizer_common/sanitizer_solaris.cc b/lib/sanitizer_common/sanitizer_solaris.cc
index 9d0c3d93d..cc0201c7a 100644
--- a/lib/sanitizer_common/sanitizer_solaris.cc
+++ b/lib/sanitizer_common/sanitizer_solaris.cc
@@ -88,8 +88,8 @@ uptr internal_open(const char *filename, int flags, u32 mode) {
}
uptr OpenFile(const char *filename, bool write) {
- return internal_open(filename,
- write ? O_WRONLY | O_CREAT : O_RDONLY, 0660);
+ return ReserveStandardFds(
+ internal_open(filename, write ? O_WRONLY | O_CREAT : O_RDONLY, 0660));
}
DECLARE__REAL_AND_INTERNAL(uptr, read, fd_t fd, void *buf, uptr count) {
diff --git a/lib/sanitizer_common/sanitizer_stackdepot.cc b/lib/sanitizer_common/sanitizer_stackdepot.cc
index 3bd5b677a..6aab98485 100644
--- a/lib/sanitizer_common/sanitizer_stackdepot.cc
+++ b/lib/sanitizer_common/sanitizer_stackdepot.cc
@@ -26,7 +26,7 @@ struct StackDepotNode {
u32 tag;
uptr stack[1]; // [size]
- static const u32 kTabSizeLog = 20;
+ static const u32 kTabSizeLog = SANITIZER_ANDROID ? 16 : 20;
// Lower kTabSizeLog bits are equal for all items in one bucket.
// We use these bits to store the per-stack use counter.
static const u32 kUseCountBits = kTabSizeLog;
diff --git a/lib/sanitizer_common/sanitizer_stackdepot.h b/lib/sanitizer_common/sanitizer_stackdepot.h
index cb7345002..e22ed2e38 100644
--- a/lib/sanitizer_common/sanitizer_stackdepot.h
+++ b/lib/sanitizer_common/sanitizer_stackdepot.h
@@ -32,7 +32,7 @@ struct StackDepotHandle {
void inc_use_count_unsafe();
};
-const int kStackDepotMaxUseCount = 1U << 20;
+const int kStackDepotMaxUseCount = 1U << (SANITIZER_ANDROID ? 16 : 20);
StackDepotStats *StackDepotGetStats();
u32 StackDepotPut(StackTrace stack);
diff --git a/lib/sanitizer_common/sanitizer_type_traits.cc b/lib/sanitizer_common/sanitizer_type_traits.cc
new file mode 100644
index 000000000..27fec6e1f
--- /dev/null
+++ b/lib/sanitizer_common/sanitizer_type_traits.cc
@@ -0,0 +1,21 @@
+//===-- sanitizer_type_traits.cc --------------------------------*- C++ -*-===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Implements a subset of C++ type traits. This is so we can avoid depending
+// on system C++ headers.
+//
+//===----------------------------------------------------------------------===//
+#include "sanitizer_type_traits.h"
+
+namespace __sanitizer {
+
+const bool true_type::value;
+const bool false_type::value;
+
+} // namespace __sanitizer
diff --git a/lib/sanitizer_common/sanitizer_type_traits.h b/lib/sanitizer_common/sanitizer_type_traits.h
index 572eaa5a0..4495f2c34 100644
--- a/lib/sanitizer_common/sanitizer_type_traits.h
+++ b/lib/sanitizer_common/sanitizer_type_traits.h
@@ -39,6 +39,6 @@ struct is_same : public false_type {};
template <typename T>
struct is_same<T, T> : public true_type {};
-}; // namespace __sanitizer
+} // namespace __sanitizer
#endif
diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cc
index d3b7df690..9a574dd23 100644
--- a/lib/sanitizer_common/sanitizer_win.cc
+++ b/lib/sanitizer_common/sanitizer_win.cc
@@ -1016,6 +1016,10 @@ void CheckASLR() {
// Do nothing
}
+void CheckMPROTECT() {
+ // Do nothing
+}
+
char **GetArgv() {
// FIXME: Actually implement this function.
return 0;
diff --git a/lib/sanitizer_common/scripts/gen_dynamic_list.py b/lib/sanitizer_common/scripts/gen_dynamic_list.py
index 25632ed77..4a9c7af95 100755
--- a/lib/sanitizer_common/scripts/gen_dynamic_list.py
+++ b/lib/sanitizer_common/scripts/gen_dynamic_list.py
@@ -14,6 +14,7 @@
# gen_dynamic_list.py libclang_rt.*san*.a [ files ... ]
#
#===------------------------------------------------------------------------===#
+from __future__ import print_function
import argparse
import os
import re
@@ -84,6 +85,7 @@ def main(argv):
parser.add_argument('--version-list', action='store_true')
parser.add_argument('--extra', default=[], action='append')
parser.add_argument('libraries', default=[], nargs='+')
+ parser.add_argument('-o', '--output', required=True)
args = parser.parse_args()
result = []
@@ -117,16 +119,17 @@ def main(argv):
for line in f:
result.append(line.rstrip())
# Print the resulting list in the format recognized by ld.
- print('{')
- if args.version_list:
- print('global:')
- result.sort()
- for f in result:
- print(u' %s;' % f)
- if args.version_list:
- print('local:')
- print(' *;')
- print('};')
+ with open(args.output, 'w') as f:
+ print('{', file=f)
+ if args.version_list:
+ print('global:', file=f)
+ result.sort()
+ for sym in result:
+ print(u' %s;' % sym, file=f)
+ if args.version_list:
+ print('local:', file=f)
+ print(' *;', file=f)
+ print('};', file=f)
if __name__ == '__main__':
main(sys.argv)
diff --git a/lib/sanitizer_common/tests/sanitizer_allocator_test.cc b/lib/sanitizer_common/tests/sanitizer_allocator_test.cc
index f12b70e7b..3123a1d5a 100644
--- a/lib/sanitizer_common/tests/sanitizer_allocator_test.cc
+++ b/lib/sanitizer_common/tests/sanitizer_allocator_test.cc
@@ -53,6 +53,7 @@ static const u64 kAddressSpaceSize = 1ULL << 47;
typedef DefaultSizeClassMap SizeClassMap;
#endif
+template <typename AddressSpaceViewTy>
struct AP64 { // Allocator Params. Short name for shorter demangled names..
static const uptr kSpaceBeg = kAllocatorSpace;
static const uptr kSpaceSize = kAllocatorSize;
@@ -60,8 +61,10 @@ struct AP64 { // Allocator Params. Short name for shorter demangled names..
typedef ::SizeClassMap SizeClassMap;
typedef NoOpMapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
+ using AddressSpaceView = AddressSpaceViewTy;
};
+template <typename AddressSpaceViewTy>
struct AP64Dyn {
static const uptr kSpaceBeg = ~(uptr)0;
static const uptr kSpaceSize = kAllocatorSize;
@@ -69,8 +72,10 @@ struct AP64Dyn {
typedef ::SizeClassMap SizeClassMap;
typedef NoOpMapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
+ using AddressSpaceView = AddressSpaceViewTy;
};
+template <typename AddressSpaceViewTy>
struct AP64Compact {
static const uptr kSpaceBeg = ~(uptr)0;
static const uptr kSpaceSize = kAllocatorSize;
@@ -78,8 +83,10 @@ struct AP64Compact {
typedef CompactSizeClassMap SizeClassMap;
typedef NoOpMapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
+ using AddressSpaceView = AddressSpaceViewTy;
};
+template <typename AddressSpaceViewTy>
struct AP64VeryCompact {
static const uptr kSpaceBeg = ~(uptr)0;
static const uptr kSpaceSize = 1ULL << 37;
@@ -87,8 +94,10 @@ struct AP64VeryCompact {
typedef VeryCompactSizeClassMap SizeClassMap;
typedef NoOpMapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
+ using AddressSpaceView = AddressSpaceViewTy;
};
+template <typename AddressSpaceViewTy>
struct AP64Dense {
static const uptr kSpaceBeg = kAllocatorSpace;
static const uptr kSpaceSize = kAllocatorSize;
@@ -96,13 +105,32 @@ struct AP64Dense {
typedef DenseSizeClassMap SizeClassMap;
typedef NoOpMapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
+ using AddressSpaceView = AddressSpaceViewTy;
};
-typedef SizeClassAllocator64<AP64> Allocator64;
-typedef SizeClassAllocator64<AP64Dyn> Allocator64Dynamic;
-typedef SizeClassAllocator64<AP64Compact> Allocator64Compact;
-typedef SizeClassAllocator64<AP64VeryCompact> Allocator64VeryCompact;
-typedef SizeClassAllocator64<AP64Dense> Allocator64Dense;
+template <typename AddressSpaceView>
+using Allocator64ASVT = SizeClassAllocator64<AP64<AddressSpaceView>>;
+using Allocator64 = Allocator64ASVT<LocalAddressSpaceView>;
+
+template <typename AddressSpaceView>
+using Allocator64DynamicASVT = SizeClassAllocator64<AP64Dyn<AddressSpaceView>>;
+using Allocator64Dynamic = Allocator64DynamicASVT<LocalAddressSpaceView>;
+
+template <typename AddressSpaceView>
+using Allocator64CompactASVT =
+ SizeClassAllocator64<AP64Compact<AddressSpaceView>>;
+using Allocator64Compact = Allocator64CompactASVT<LocalAddressSpaceView>;
+
+template <typename AddressSpaceView>
+using Allocator64VeryCompactASVT =
+ SizeClassAllocator64<AP64VeryCompact<AddressSpaceView>>;
+using Allocator64VeryCompact =
+ Allocator64VeryCompactASVT<LocalAddressSpaceView>;
+
+template <typename AddressSpaceView>
+using Allocator64DenseASVT = SizeClassAllocator64<AP64Dense<AddressSpaceView>>;
+using Allocator64Dense = Allocator64DenseASVT<LocalAddressSpaceView>;
+
#elif defined(__mips64)
static const u64 kAddressSpaceSize = 1ULL << 40;
#elif defined(__aarch64__)
@@ -404,6 +432,7 @@ int TestMapUnmapCallback::unmap_count;
// to run them all at the same time. FIXME: Make them not flaky and reenable.
#if !SANITIZER_WINDOWS
+template <typename AddressSpaceViewTy = LocalAddressSpaceView>
struct AP64WithCallback {
static const uptr kSpaceBeg = kAllocatorSpace;
static const uptr kSpaceSize = kAllocatorSize;
@@ -411,12 +440,13 @@ struct AP64WithCallback {
typedef ::SizeClassMap SizeClassMap;
typedef TestMapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
+ using AddressSpaceView = AddressSpaceViewTy;
};
TEST(SanitizerCommon, SizeClassAllocator64MapUnmapCallback) {
TestMapUnmapCallback::map_count = 0;
TestMapUnmapCallback::unmap_count = 0;
- typedef SizeClassAllocator64<AP64WithCallback> Allocator64WithCallBack;
+ typedef SizeClassAllocator64<AP64WithCallback<>> Allocator64WithCallBack;
Allocator64WithCallBack *a = new Allocator64WithCallBack;
a->Init(kReleaseToOSIntervalNever);
EXPECT_EQ(TestMapUnmapCallback::map_count, 1); // Allocator state.
@@ -1003,6 +1033,7 @@ TEST(SanitizerCommon, LargeMmapAllocatorBlockBegin) {
// machine to OOM.
#if SANITIZER_CAN_USE_ALLOCATOR64 && !SANITIZER_WINDOWS64 && !SANITIZER_ANDROID
typedef SizeClassMap<3, 4, 8, 63, 128, 16> SpecialSizeClassMap;
+template <typename AddressSpaceViewTy = LocalAddressSpaceView>
struct AP64_SpecialSizeClassMap {
static const uptr kSpaceBeg = kAllocatorSpace;
static const uptr kSpaceSize = kAllocatorSize;
@@ -1010,12 +1041,13 @@ struct AP64_SpecialSizeClassMap {
typedef SpecialSizeClassMap SizeClassMap;
typedef NoOpMapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
+ using AddressSpaceView = AddressSpaceViewTy;
};
// Regression test for out-of-memory condition in PopulateFreeList().
TEST(SanitizerCommon, SizeClassAllocator64PopulateFreeListOOM) {
// In a world where regions are small and chunks are huge...
- typedef SizeClassAllocator64<AP64_SpecialSizeClassMap> SpecialAllocator64;
+ typedef SizeClassAllocator64<AP64_SpecialSizeClassMap<>> SpecialAllocator64;
const uptr kRegionSize =
kAllocatorSize / SpecialSizeClassMap::kNumClassesRounded;
SpecialAllocator64 *a = new SpecialAllocator64;
diff --git a/lib/scudo/scudo_allocator.h b/lib/scudo/scudo_allocator.h
index 869e74a5e..814bb08ab 100644
--- a/lib/scudo/scudo_allocator.h
+++ b/lib/scudo/scudo_allocator.h
@@ -81,6 +81,7 @@ struct AP64 {
typedef NoOpMapUnmapCallback MapUnmapCallback;
static const uptr kFlags =
SizeClassAllocator64FlagMasks::kRandomShuffleChunks;
+ using AddressSpaceView = LocalAddressSpaceView;
};
typedef SizeClassAllocator64<AP64> PrimaryT;
#else
diff --git a/lib/tsan/CMakeLists.txt b/lib/tsan/CMakeLists.txt
index d501d0cba..e1da319cc 100644
--- a/lib/tsan/CMakeLists.txt
+++ b/lib/tsan/CMakeLists.txt
@@ -220,11 +220,12 @@ else()
endif()
# Make sure that non-platform-specific files don't include any system headers.
-# FreeBSD does not install a number of Clang-provided headers for the compiler
-# in the base system due to incompatibilities between FreeBSD's and Clang's
-# versions. As a workaround do not use --sysroot=. on FreeBSD until this is
-# addressed.
-if(COMPILER_RT_HAS_SYSROOT_FLAG AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD")
+# FreeBSD/NetBSD do not install a number of Clang-provided headers for the
+# compiler in the base system due to incompatibilities between FreeBSD/NetBSD's
+# and Clang's versions. As a workaround do not use --sysroot=. on FreeBSD/NetBSD
+# until this is addressed.
+if(COMPILER_RT_HAS_SYSROOT_FLAG AND NOT CMAKE_SYSTEM_NAME MATCHES "FreeBSD"
+ AND NOT CMAKE_SYSTEM_NAME MATCHES "NetBSD")
file(GLOB _tsan_generic_sources rtl/tsan*)
file(GLOB _tsan_platform_sources rtl/tsan*posix* rtl/tsan*mac*
rtl/tsan*linux*)
diff --git a/lib/tsan/rtl/tsan_debugging.cc b/lib/tsan/rtl/tsan_debugging.cc
index 9e5465d37..067aeef97 100644
--- a/lib/tsan/rtl/tsan_debugging.cc
+++ b/lib/tsan/rtl/tsan_debugging.cc
@@ -20,31 +20,37 @@
using namespace __tsan;
static const char *ReportTypeDescription(ReportType typ) {
- if (typ == ReportTypeRace) return "data-race";
- if (typ == ReportTypeVptrRace) return "data-race-vptr";
- if (typ == ReportTypeUseAfterFree) return "heap-use-after-free";
- if (typ == ReportTypeVptrUseAfterFree) return "heap-use-after-free-vptr";
- if (typ == ReportTypeExternalRace) return "external-race";
- if (typ == ReportTypeThreadLeak) return "thread-leak";
- if (typ == ReportTypeMutexDestroyLocked) return "locked-mutex-destroy";
- if (typ == ReportTypeMutexDoubleLock) return "mutex-double-lock";
- if (typ == ReportTypeMutexInvalidAccess) return "mutex-invalid-access";
- if (typ == ReportTypeMutexBadUnlock) return "mutex-bad-unlock";
- if (typ == ReportTypeMutexBadReadLock) return "mutex-bad-read-lock";
- if (typ == ReportTypeMutexBadReadUnlock) return "mutex-bad-read-unlock";
- if (typ == ReportTypeSignalUnsafe) return "signal-unsafe-call";
- if (typ == ReportTypeErrnoInSignal) return "errno-in-signal-handler";
- if (typ == ReportTypeDeadlock) return "lock-order-inversion";
- return "";
+ switch (typ) {
+ case ReportTypeRace: return "data-race";
+ case ReportTypeVptrRace: return "data-race-vptr";
+ case ReportTypeUseAfterFree: return "heap-use-after-free";
+ case ReportTypeVptrUseAfterFree: return "heap-use-after-free-vptr";
+ case ReportTypeExternalRace: return "external-race";
+ case ReportTypeThreadLeak: return "thread-leak";
+ case ReportTypeMutexDestroyLocked: return "locked-mutex-destroy";
+ case ReportTypeMutexDoubleLock: return "mutex-double-lock";
+ case ReportTypeMutexInvalidAccess: return "mutex-invalid-access";
+ case ReportTypeMutexBadUnlock: return "mutex-bad-unlock";
+ case ReportTypeMutexBadReadLock: return "mutex-bad-read-lock";
+ case ReportTypeMutexBadReadUnlock: return "mutex-bad-read-unlock";
+ case ReportTypeSignalUnsafe: return "signal-unsafe-call";
+ case ReportTypeErrnoInSignal: return "errno-in-signal-handler";
+ case ReportTypeDeadlock: return "lock-order-inversion";
+ // No default case so compiler warns us if we miss one
+ }
+ UNREACHABLE("missing case");
}
static const char *ReportLocationTypeDescription(ReportLocationType typ) {
- if (typ == ReportLocationGlobal) return "global";
- if (typ == ReportLocationHeap) return "heap";
- if (typ == ReportLocationStack) return "stack";
- if (typ == ReportLocationTLS) return "tls";
- if (typ == ReportLocationFD) return "fd";
- return "";
+ switch (typ) {
+ case ReportLocationGlobal: return "global";
+ case ReportLocationHeap: return "heap";
+ case ReportLocationStack: return "stack";
+ case ReportLocationTLS: return "tls";
+ case ReportLocationFD: return "fd";
+ // No default case so compiler warns us if we miss one
+ }
+ UNREACHABLE("missing case");
}
static void CopyTrace(SymbolizedStack *first_frame, void **trace,
diff --git a/lib/tsan/rtl/tsan_flags.cc b/lib/tsan/rtl/tsan_flags.cc
index 89e22a132..877fc8b81 100644
--- a/lib/tsan/rtl/tsan_flags.cc
+++ b/lib/tsan/rtl/tsan_flags.cc
@@ -61,8 +61,7 @@ void InitializeFlags(Flags *f, const char *env) {
// Does not work as expected for Go: runtime handles SIGABRT and crashes.
cf.abort_on_error = false;
// Go does not have mutexes.
- } else {
- cf.detect_deadlocks = true;
+ cf.detect_deadlocks = false;
}
cf.print_suppressions = false;
cf.stack_trace_format = " #%n %f %S %M";
diff --git a/lib/tsan/rtl/tsan_flags.inc b/lib/tsan/rtl/tsan_flags.inc
index e9b3e35f0..d3b678fdd 100644
--- a/lib/tsan/rtl/tsan_flags.inc
+++ b/lib/tsan/rtl/tsan_flags.inc
@@ -77,8 +77,6 @@ TSAN_FLAG(int, io_sync, 1,
TSAN_FLAG(bool, die_after_fork, true,
"Die after multi-threaded fork if the child creates new threads.")
TSAN_FLAG(const char *, suppressions, "", "Suppressions file name.")
-TSAN_FLAG(bool, ignore_interceptors_accesses, false,
- "Ignore reads and writes from all interceptors.")
TSAN_FLAG(bool, ignore_noninstrumented_modules, SANITIZER_MAC ? true : false,
"Interceptors should only detect races when called from instrumented "
"modules.")
diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors.cc
index cc6dab8f1..9e49dfe5d 100644
--- a/lib/tsan/rtl/tsan_interceptors.cc
+++ b/lib/tsan/rtl/tsan_interceptors.cc
@@ -42,16 +42,12 @@ using namespace __tsan; // NOLINT
#if SANITIZER_NETBSD
#define dirfd(dirp) (*(int *)(dirp))
-#define fileno_unlocked fileno
+#define fileno_unlocked(fp) \
+ (((__sanitizer_FILE*)fp)->_file == -1 ? -1 : \
+ (int)(unsigned short)(((__sanitizer_FILE*)fp)->_file)) // NOLINT
-#if _LP64
-#define __sF_size 152
-#else
-#define __sF_size 88
-#endif
-
-#define stdout ((char*)&__sF + (__sF_size * 1))
-#define stderr ((char*)&__sF + (__sF_size * 2))
+#define stdout ((__sanitizer_FILE*)&__sF[1])
+#define stderr ((__sanitizer_FILE*)&__sF[2])
#define nanosleep __nanosleep50
#define vfork __vfork14
@@ -96,8 +92,8 @@ DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr size)
DECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr)
extern "C" void *pthread_self();
extern "C" void _exit(int status);
-extern "C" int fileno_unlocked(void *stream);
#if !SANITIZER_NETBSD
+extern "C" int fileno_unlocked(void *stream);
extern "C" int dirfd(void *dirp);
#endif
#if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_NETBSD
@@ -258,8 +254,7 @@ ScopedInterceptor::ScopedInterceptor(ThreadState *thr, const char *fname,
if (!thr_->ignore_interceptors) FuncEntry(thr, pc);
DPrintf("#%d: intercept %s()\n", thr_->tid, fname);
ignoring_ =
- !thr_->in_ignored_lib && (flags()->ignore_interceptors_accesses ||
- libignore()->IsIgnored(pc, &in_ignored_lib_));
+ !thr_->in_ignored_lib && libignore()->IsIgnored(pc, &in_ignored_lib_);
EnableIgnores();
}
@@ -2254,7 +2249,8 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc,
(void) ctx;
#define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) \
- Acquire(thr, pc, File2addr(path)); \
+ if (path) \
+ Acquire(thr, pc, File2addr(path)); \
if (file) { \
int fd = fileno_unlocked(file); \
if (fd >= 0) FdFileCreate(thr, pc, fd); \
diff --git a/lib/tsan/rtl/tsan_interceptors_mac.cc b/lib/tsan/rtl/tsan_interceptors_mac.cc
index 5e8b58fc2..579c4d0c0 100644
--- a/lib/tsan/rtl/tsan_interceptors_mac.cc
+++ b/lib/tsan/rtl/tsan_interceptors_mac.cc
@@ -19,8 +19,10 @@
#include "tsan_interceptors.h"
#include "tsan_interface.h"
#include "tsan_interface_ann.h"
+#include "sanitizer_common/sanitizer_addrhashmap.h"
#include <libkern/OSAtomic.h>
+#include <objc/objc-sync.h>
#if defined(__has_include) && __has_include(<xpc/xpc.h>)
#include <xpc/xpc.h>
@@ -294,41 +296,62 @@ TSAN_INTERCEPTOR(void, xpc_connection_cancel, xpc_connection_t connection) {
#endif // #if defined(__has_include) && __has_include(<xpc/xpc.h>)
-// Is the Obj-C object a tagged pointer (i.e. isn't really a valid pointer and
-// contains data in the pointers bits instead)?
-static bool IsTaggedObjCPointer(void *obj) {
+// Determines whether the Obj-C object pointer is a tagged pointer. Tagged
+// pointers encode the object data directly in their pointer bits and do not
+// have an associated memory allocation. The Obj-C runtime uses tagged pointers
+// to transparently optimize small objects.
+static bool IsTaggedObjCPointer(id obj) {
const uptr kPossibleTaggedBits = 0x8000000000000001ull;
return ((uptr)obj & kPossibleTaggedBits) != 0;
}
-// Return an address on which we can synchronize (Acquire and Release) for a
-// Obj-C tagged pointer (which is not a valid pointer). Ideally should be a
-// derived address from 'obj', but for now just return the same global address.
-// TODO(kubamracek): Return different address for different pointers.
-static uptr SyncAddressForTaggedPointer(void *obj) {
- (void)obj;
- static u64 addr;
- return (uptr)&addr;
+// Returns an address which can be used to inform TSan about synchronization
+// points (MutexLock/Unlock). The TSan infrastructure expects this to be a valid
+// address in the process space. We do a small allocation here to obtain a
+// stable address (the array backing the hash map can change). The memory is
+// never free'd (leaked) and allocation and locking are slow, but this code only
+// runs for @synchronized with tagged pointers, which is very rare.
+static uptr GetOrCreateSyncAddress(uptr addr, ThreadState *thr, uptr pc) {
+ typedef AddrHashMap<uptr, 5> Map;
+ static Map Addresses;
+ Map::Handle h(&Addresses, addr);
+ if (h.created()) {
+ ThreadIgnoreBegin(thr, pc);
+ *h = (uptr) user_alloc(thr, pc, /*size=*/1);
+ ThreadIgnoreEnd(thr, pc);
+ }
+ return *h;
}
-// Address on which we can synchronize for an Objective-C object. Supports
-// tagged pointers.
-static uptr SyncAddressForObjCObject(void *obj) {
- if (IsTaggedObjCPointer(obj)) return SyncAddressForTaggedPointer(obj);
+// Returns an address on which we can synchronize given an Obj-C object pointer.
+// For normal object pointers, this is just the address of the object in memory.
+// Tagged pointers are not backed by an actual memory allocation, so we need to
+// synthesize a valid address.
+static uptr SyncAddressForObjCObject(id obj, ThreadState *thr, uptr pc) {
+ if (IsTaggedObjCPointer(obj))
+ return GetOrCreateSyncAddress((uptr)obj, thr, pc);
return (uptr)obj;
}
-TSAN_INTERCEPTOR(int, objc_sync_enter, void *obj) {
+TSAN_INTERCEPTOR(int, objc_sync_enter, id obj) {
SCOPED_TSAN_INTERCEPTOR(objc_sync_enter, obj);
+ if (!obj) return REAL(objc_sync_enter)(obj);
+ uptr addr = SyncAddressForObjCObject(obj, thr, pc);
+ MutexPreLock(thr, pc, addr, MutexFlagWriteReentrant);
int result = REAL(objc_sync_enter)(obj);
- if (obj) Acquire(thr, pc, SyncAddressForObjCObject(obj));
+ CHECK_EQ(result, OBJC_SYNC_SUCCESS);
+ MutexPostLock(thr, pc, addr, MutexFlagWriteReentrant);
return result;
}
-TSAN_INTERCEPTOR(int, objc_sync_exit, void *obj) {
+TSAN_INTERCEPTOR(int, objc_sync_exit, id obj) {
SCOPED_TSAN_INTERCEPTOR(objc_sync_exit, obj);
- if (obj) Release(thr, pc, SyncAddressForObjCObject(obj));
- return REAL(objc_sync_exit)(obj);
+ if (!obj) return REAL(objc_sync_exit)(obj);
+ uptr addr = SyncAddressForObjCObject(obj, thr, pc);
+ MutexUnlock(thr, pc, addr);
+ int result = REAL(objc_sync_exit)(obj);
+ if (result != OBJC_SYNC_SUCCESS) MutexInvalidAccess(thr, pc, addr);
+ return result;
}
// On macOS, libc++ is always linked dynamically, so intercepting works the
diff --git a/lib/tsan/rtl/tsan_report.cc b/lib/tsan/rtl/tsan_report.cc
index af4707696..629c3e933 100644
--- a/lib/tsan/rtl/tsan_report.cc
+++ b/lib/tsan/rtl/tsan_report.cc
@@ -77,39 +77,42 @@ const char *thread_name(char *buf, int tid) {
}
static const char *ReportTypeString(ReportType typ, uptr tag) {
- if (typ == ReportTypeRace)
- return "data race";
- if (typ == ReportTypeVptrRace)
- return "data race on vptr (ctor/dtor vs virtual call)";
- if (typ == ReportTypeUseAfterFree)
- return "heap-use-after-free";
- if (typ == ReportTypeVptrUseAfterFree)
- return "heap-use-after-free (virtual call vs free)";
- if (typ == ReportTypeExternalRace) {
- const char *str = GetReportHeaderFromTag(tag);
- return str ? str : "race on external object";
+ switch (typ) {
+ case ReportTypeRace:
+ return "data race";
+ case ReportTypeVptrRace:
+ return "data race on vptr (ctor/dtor vs virtual call)";
+ case ReportTypeUseAfterFree:
+ return "heap-use-after-free";
+ case ReportTypeVptrUseAfterFree:
+ return "heap-use-after-free (virtual call vs free)";
+ case ReportTypeExternalRace: {
+ const char *str = GetReportHeaderFromTag(tag);
+ return str ? str : "race on external object";
+ }
+ case ReportTypeThreadLeak:
+ return "thread leak";
+ case ReportTypeMutexDestroyLocked:
+ return "destroy of a locked mutex";
+ case ReportTypeMutexDoubleLock:
+ return "double lock of a mutex";
+ case ReportTypeMutexInvalidAccess:
+ return "use of an invalid mutex (e.g. uninitialized or destroyed)";
+ case ReportTypeMutexBadUnlock:
+ return "unlock of an unlocked mutex (or by a wrong thread)";
+ case ReportTypeMutexBadReadLock:
+ return "read lock of a write locked mutex";
+ case ReportTypeMutexBadReadUnlock:
+ return "read unlock of a write locked mutex";
+ case ReportTypeSignalUnsafe:
+ return "signal-unsafe call inside of a signal";
+ case ReportTypeErrnoInSignal:
+ return "signal handler spoils errno";
+ case ReportTypeDeadlock:
+ return "lock-order-inversion (potential deadlock)";
+ // No default case so compiler warns us if we miss one
}
- if (typ == ReportTypeThreadLeak)
- return "thread leak";
- if (typ == ReportTypeMutexDestroyLocked)
- return "destroy of a locked mutex";
- if (typ == ReportTypeMutexDoubleLock)
- return "double lock of a mutex";
- if (typ == ReportTypeMutexInvalidAccess)
- return "use of an invalid mutex (e.g. uninitialized or destroyed)";
- if (typ == ReportTypeMutexBadUnlock)
- return "unlock of an unlocked mutex (or by a wrong thread)";
- if (typ == ReportTypeMutexBadReadLock)
- return "read lock of a write locked mutex";
- if (typ == ReportTypeMutexBadReadUnlock)
- return "read unlock of a write locked mutex";
- if (typ == ReportTypeSignalUnsafe)
- return "signal-unsafe call inside of a signal";
- if (typ == ReportTypeErrnoInSignal)
- return "signal handler spoils errno";
- if (typ == ReportTypeDeadlock)
- return "lock-order-inversion (potential deadlock)";
- return "";
+ UNREACHABLE("missing case");
}
#if SANITIZER_MAC
diff --git a/lib/tsan/rtl/tsan_rtl.h b/lib/tsan/rtl/tsan_rtl.h
index 60e6f82f7..3410be294 100644
--- a/lib/tsan/rtl/tsan_rtl.h
+++ b/lib/tsan/rtl/tsan_rtl.h
@@ -81,6 +81,7 @@ struct AP64 { // Allocator64 parameters. Deliberately using a short name.
typedef DefaultSizeClassMap SizeClassMap;
typedef __tsan::MapUnmapCallback MapUnmapCallback;
static const uptr kFlags = 0;
+ using AddressSpaceView = LocalAddressSpaceView;
};
typedef SizeClassAllocator64<AP64> PrimaryAllocator;
#endif
diff --git a/lib/tsan/rtl/tsan_suppressions.cc b/lib/tsan/rtl/tsan_suppressions.cc
index be38f331a..6df074118 100644
--- a/lib/tsan/rtl/tsan_suppressions.cc
+++ b/lib/tsan/rtl/tsan_suppressions.cc
@@ -66,38 +66,30 @@ SuppressionContext *Suppressions() {
}
static const char *conv(ReportType typ) {
- if (typ == ReportTypeRace)
- return kSuppressionRace;
- else if (typ == ReportTypeVptrRace)
- return kSuppressionRace;
- else if (typ == ReportTypeUseAfterFree)
- return kSuppressionRace;
- else if (typ == ReportTypeVptrUseAfterFree)
- return kSuppressionRace;
- else if (typ == ReportTypeExternalRace)
- return kSuppressionRace;
- else if (typ == ReportTypeThreadLeak)
- return kSuppressionThread;
- else if (typ == ReportTypeMutexDestroyLocked)
- return kSuppressionMutex;
- else if (typ == ReportTypeMutexDoubleLock)
- return kSuppressionMutex;
- else if (typ == ReportTypeMutexInvalidAccess)
- return kSuppressionMutex;
- else if (typ == ReportTypeMutexBadUnlock)
- return kSuppressionMutex;
- else if (typ == ReportTypeMutexBadReadLock)
- return kSuppressionMutex;
- else if (typ == ReportTypeMutexBadReadUnlock)
- return kSuppressionMutex;
- else if (typ == ReportTypeSignalUnsafe)
- return kSuppressionSignal;
- else if (typ == ReportTypeErrnoInSignal)
- return kSuppressionNone;
- else if (typ == ReportTypeDeadlock)
- return kSuppressionDeadlock;
- Printf("ThreadSanitizer: unknown report type %d\n", typ);
- Die();
+ switch (typ) {
+ case ReportTypeRace:
+ case ReportTypeVptrRace:
+ case ReportTypeUseAfterFree:
+ case ReportTypeVptrUseAfterFree:
+ case ReportTypeExternalRace:
+ return kSuppressionRace;
+ case ReportTypeThreadLeak:
+ return kSuppressionThread;
+ case ReportTypeMutexDestroyLocked:
+ case ReportTypeMutexDoubleLock:
+ case ReportTypeMutexInvalidAccess:
+ case ReportTypeMutexBadUnlock:
+ case ReportTypeMutexBadReadLock:
+ case ReportTypeMutexBadReadUnlock:
+ return kSuppressionMutex;
+ case ReportTypeSignalUnsafe:
+ case ReportTypeErrnoInSignal:
+ return kSuppressionSignal;
+ case ReportTypeDeadlock:
+ return kSuppressionDeadlock;
+ // No default case so compiler warns us if we miss one
+ }
+ UNREACHABLE("missing case");
}
static uptr IsSuppressed(const char *stype, const AddressInfo &info,
diff --git a/lib/ubsan/ubsan_checks.inc b/lib/ubsan/ubsan_checks.inc
index e976ea4f6..ea82f89e1 100644
--- a/lib/ubsan/ubsan_checks.inc
+++ b/lib/ubsan/ubsan_checks.inc
@@ -21,6 +21,7 @@ UBSAN_CHECK(GenericUB, "undefined-behavior", "undefined")
UBSAN_CHECK(NullPointerUse, "null-pointer-use", "null")
UBSAN_CHECK(PointerOverflow, "pointer-overflow", "pointer-overflow")
UBSAN_CHECK(MisalignedPointerUse, "misaligned-pointer-use", "alignment")
+UBSAN_CHECK(AlignmentAssumption, "alignment-assumption", "alignment")
UBSAN_CHECK(InsufficientObjectSize, "insufficient-object-size", "object-size")
UBSAN_CHECK(SignedIntegerOverflow, "signed-integer-overflow",
"signed-integer-overflow")
diff --git a/lib/ubsan/ubsan_handlers.cc b/lib/ubsan/ubsan_handlers.cc
index 53430a607..11e09b0ff 100644
--- a/lib/ubsan/ubsan_handlers.cc
+++ b/lib/ubsan/ubsan_handlers.cc
@@ -106,6 +106,62 @@ void __ubsan::__ubsan_handle_type_mismatch_v1_abort(TypeMismatchData *Data,
Die();
}
+static void handleAlignmentAssumptionImpl(AlignmentAssumptionData *Data,
+ ValueHandle Pointer,
+ ValueHandle Alignment,
+ ValueHandle Offset,
+ ReportOptions Opts) {
+ Location Loc = Data->Loc.acquire();
+ SourceLocation AssumptionLoc = Data->AssumptionLoc.acquire();
+
+ ErrorType ET = ErrorType::AlignmentAssumption;
+
+ if (ignoreReport(Loc.getSourceLocation(), Opts, ET))
+ return;
+
+ ScopedReport R(Opts, Loc, ET);
+
+ uptr RealPointer = Pointer - Offset;
+ uptr LSB = LeastSignificantSetBitIndex(RealPointer);
+ uptr ActualAlignment = uptr(1) << LSB;
+
+ uptr Mask = Alignment - 1;
+ uptr MisAlignmentOffset = RealPointer & Mask;
+
+ if (!Offset) {
+ Diag(Loc, DL_Error, ET,
+ "assumption of %0 byte alignment for pointer of type %1 failed")
+ << Alignment << Data->Type;
+ } else {
+ Diag(Loc, DL_Error, ET,
+ "assumption of %0 byte alignment (with offset of %1 byte) for pointer "
+ "of type %2 failed")
+ << Alignment << Offset << Data->Type;
+ }
+
+ if (!AssumptionLoc.isInvalid())
+ Diag(AssumptionLoc, DL_Note, ET, "alignment assumption was specified here");
+
+ Diag(RealPointer, DL_Note, ET,
+ "%0address is %1 aligned, misalignment offset is %2 bytes")
+ << (Offset ? "offset " : "") << ActualAlignment << MisAlignmentOffset;
+}
+
+void __ubsan::__ubsan_handle_alignment_assumption(AlignmentAssumptionData *Data,
+ ValueHandle Pointer,
+ ValueHandle Alignment,
+ ValueHandle Offset) {
+ GET_REPORT_OPTIONS(false);
+ handleAlignmentAssumptionImpl(Data, Pointer, Alignment, Offset, Opts);
+}
+void __ubsan::__ubsan_handle_alignment_assumption_abort(
+ AlignmentAssumptionData *Data, ValueHandle Pointer, ValueHandle Alignment,
+ ValueHandle Offset) {
+ GET_REPORT_OPTIONS(true);
+ handleAlignmentAssumptionImpl(Data, Pointer, Alignment, Offset, Opts);
+ Die();
+}
+
/// \brief Common diagnostic emission for various forms of integer overflow.
template <typename T>
static void handleIntegerOverflowImpl(OverflowData *Data, ValueHandle LHS,
diff --git a/lib/ubsan/ubsan_handlers.h b/lib/ubsan/ubsan_handlers.h
index 04405770e..2bf9ff432 100644
--- a/lib/ubsan/ubsan_handlers.h
+++ b/lib/ubsan/ubsan_handlers.h
@@ -39,6 +39,17 @@ struct TypeMismatchData {
/// type.
RECOVERABLE(type_mismatch_v1, TypeMismatchData *Data, ValueHandle Pointer)
+struct AlignmentAssumptionData {
+ SourceLocation Loc;
+ SourceLocation AssumptionLoc;
+ const TypeDescriptor &Type;
+};
+
+/// \brief Handle a runtime alignment assumption check failure,
+/// caused by a misaligned pointer.
+RECOVERABLE(alignment_assumption, AlignmentAssumptionData *Data,
+ ValueHandle Pointer, ValueHandle Alignment, ValueHandle Offset)
+
struct OverflowData {
SourceLocation Loc;
const TypeDescriptor &Type;
diff --git a/lib/ubsan/ubsan_interface.inc b/lib/ubsan/ubsan_interface.inc
index 0be6010ad..81e06345d 100644
--- a/lib/ubsan/ubsan_interface.inc
+++ b/lib/ubsan/ubsan_interface.inc
@@ -10,6 +10,8 @@
//===----------------------------------------------------------------------===//
INTERFACE_FUNCTION(__ubsan_handle_add_overflow)
INTERFACE_FUNCTION(__ubsan_handle_add_overflow_abort)
+INTERFACE_FUNCTION(__ubsan_handle_alignment_assumption)
+INTERFACE_FUNCTION(__ubsan_handle_alignment_assumption_abort)
INTERFACE_FUNCTION(__ubsan_handle_builtin_unreachable)
INTERFACE_FUNCTION(__ubsan_handle_cfi_bad_type)
INTERFACE_FUNCTION(__ubsan_handle_cfi_check_fail)
diff --git a/lib/ubsan_minimal/ubsan_minimal_handlers.cc b/lib/ubsan_minimal/ubsan_minimal_handlers.cc
index e8fc3a849..ed62ddd0f 100644
--- a/lib/ubsan_minimal/ubsan_minimal_handlers.cc
+++ b/lib/ubsan_minimal/ubsan_minimal_handlers.cc
@@ -95,6 +95,7 @@ void NORETURN CheckFailed(const char *file, int, const char *cond, u64, u64) {
HANDLER_NORECOVER(name, msg)
HANDLER(type_mismatch, "type-mismatch")
+HANDLER(alignment_assumption, "alignment-assumption")
HANDLER(add_overflow, "add-overflow")
HANDLER(sub_overflow, "sub-overflow")
HANDLER(mul_overflow, "mul-overflow")
diff --git a/lib/xray/tests/CMakeLists.txt b/lib/xray/tests/CMakeLists.txt
index 16fb129d3..89a2b3b01 100644
--- a/lib/xray/tests/CMakeLists.txt
+++ b/lib/xray/tests/CMakeLists.txt
@@ -60,6 +60,10 @@ if (NOT APPLE)
if (COMPILER_RT_STANDALONE_BUILD)
append_list_if(COMPILER_RT_HAS_LLVMXRAY ${LLVM_XRAY_LDFLAGS} XRAY_UNITTEST_LINK_FLAGS)
append_list_if(COMPILER_RT_HAS_LLVMXRAY ${LLVM_XRAY_LIBLIST} XRAY_UNITTEST_LINK_FLAGS)
+ append_list_if(COMPILER_RT_HAS_LLVMTESTINGSUPPORT
+ ${LLVM_TESTINGSUPPORT_LDFLAGS} XRAY_UNITTEST_LINK_FLAGS)
+ append_list_if(COMPILER_RT_HAS_LLVMTESTINGSUPPORT
+ ${LLVM_TESTINGSUPPORT_LIBLIST} XRAY_UNITTEST_LINK_FLAGS)
else()
# We add the library directories one at a time in our CFLAGS.
foreach (DIR ${LLVM_LIBRARY_DIR})
diff --git a/lib/xray/tests/unit/CMakeLists.txt b/lib/xray/tests/unit/CMakeLists.txt
index 42ea43750..d10524b8d 100644
--- a/lib/xray/tests/unit/CMakeLists.txt
+++ b/lib/xray/tests/unit/CMakeLists.txt
@@ -1,10 +1,16 @@
-add_xray_unittest(XRayTest SOURCES
+set(TEST_SOURCES
allocator_test.cc
buffer_queue_test.cc
- fdr_controller_test.cc
- fdr_log_writer_test.cc
function_call_trie_test.cc
profile_collector_test.cc
segmented_array_test.cc
test_helpers.cc
xray_unit_test_main.cc)
+
+if (NOT COMPILER_RT_STANDALONE_BUILD OR COMPILER_RT_HAS_LLVMTESTINGSUPPORT)
+ list(APPEND TEST_SOURCES
+ fdr_controller_test.cc
+ fdr_log_writer_test.cc)
+endif()
+
+add_xray_unittest(XRayTest SOURCES ${TEST_SOURCES})
diff --git a/lib/xray/xray_basic_logging.cc b/lib/xray/xray_basic_logging.cc
index b65c0e43e..ae1cc0ba7 100644
--- a/lib/xray/xray_basic_logging.cc
+++ b/lib/xray/xray_basic_logging.cc
@@ -55,7 +55,7 @@ struct alignas(16) StackEntry {
static_assert(sizeof(StackEntry) == 16, "Wrong size for StackEntry");
-struct alignas(64) ThreadLocalData {
+struct XRAY_TLS_ALIGNAS(64) ThreadLocalData {
void *InMemoryBuffer = nullptr;
size_t BufferSize = 0;
size_t BufferOffset = 0;
diff --git a/lib/xray/xray_defs.h b/lib/xray/xray_defs.h
index e5c37c066..c009bcc87 100644
--- a/lib/xray/xray_defs.h
+++ b/lib/xray/xray_defs.h
@@ -19,4 +19,14 @@
#define XRAY_NEVER_INSTRUMENT
#endif
+#if SANITIZER_NETBSD
+// NetBSD: thread_local is not aligned properly, and the code relying
+// on it segfaults
+#define XRAY_TLS_ALIGNAS(x)
+#define XRAY_HAS_TLS_ALIGNAS 0
+#else
+#define XRAY_TLS_ALIGNAS(x) alignas(x)
+#define XRAY_HAS_TLS_ALIGNAS 1
+#endif
+
#endif // XRAY_XRAY_DEFS_H
diff --git a/lib/xray/xray_fdr_log_writer.h b/lib/xray/xray_fdr_log_writer.h
index dbd1a98fe..7712e1377 100644
--- a/lib/xray/xray_fdr_log_writer.h
+++ b/lib/xray/xray_fdr_log_writer.h
@@ -41,7 +41,7 @@ template <size_t Index> struct SerializerImpl {
Index >= std::tuple_size<typename std::remove_reference<
Tuple>::type>::value,
int>::type = 0>
- static void serializeTo(char *, Tuple &&){};
+ static void serializeTo(char *, Tuple &&) {}
};
using Serializer = SerializerImpl<0>;
diff --git a/lib/xray/xray_fdr_logging.cc b/lib/xray/xray_fdr_logging.cc
index 3893b7a2a..1eda26df7 100644
--- a/lib/xray/xray_fdr_logging.cc
+++ b/lib/xray/xray_fdr_logging.cc
@@ -51,7 +51,7 @@ namespace {
// call so that it can be initialized on first use instead of as a global. We
// force the alignment to 64-bytes for x86 cache line alignment, as this
// structure is used in the hot path of implementation.
-struct alignas(64) ThreadLocalData {
+struct XRAY_TLS_ALIGNAS(64) ThreadLocalData {
BufferQueue::Buffer Buffer{};
BufferQueue *BQ = nullptr;
@@ -124,8 +124,10 @@ static atomic_sint32_t LogFlushStatus = {
// critical section, calling a function that might be XRay instrumented (and
// thus in turn calling into malloc by virtue of registration of the
// thread_local's destructor).
+#if XRAY_HAS_TLS_ALIGNAS
static_assert(alignof(ThreadLocalData) >= 64,
"ThreadLocalData must be cache line aligned.");
+#endif
static ThreadLocalData &getThreadLocalData() {
thread_local typename std::aligned_storage<
sizeof(ThreadLocalData), alignof(ThreadLocalData)>::type TLDStorage{};
diff --git a/lib/xray/xray_init.cc b/lib/xray/xray_init.cc
index d1c750f0c..b0922aa8e 100644
--- a/lib/xray/xray_init.cc
+++ b/lib/xray/xray_init.cc
@@ -67,6 +67,9 @@ void __xray_init() XRAY_NEVER_INSTRUMENT {
if (atomic_load(&XRayInitialized, memory_order_acquire))
return;
+ // XRAY is not compatible with PaX MPROTECT
+ CheckMPROTECT();
+
if (!atomic_load(&XRayFlagsInitialized, memory_order_acquire)) {
initializeFlags();
atomic_store(&XRayFlagsInitialized, true, memory_order_release);
diff --git a/lib/xray/xray_trampoline_x86_64.S b/lib/xray/xray_trampoline_x86_64.S
index 9dffae048..52985ffd1 100644
--- a/lib/xray/xray_trampoline_x86_64.S
+++ b/lib/xray/xray_trampoline_x86_64.S
@@ -91,10 +91,10 @@
.text
#if !defined(__APPLE__)
.section .text
+ .file "xray_trampoline_x86.S"
#else
.section __TEXT,__text
#endif
- .file "xray_trampoline_x86.S"
//===----------------------------------------------------------------------===//
diff --git a/test/CMakeLists.txt b/test/CMakeLists.txt
index 554ba5fa0..2e239d54e 100644
--- a/test/CMakeLists.txt
+++ b/test/CMakeLists.txt
@@ -15,8 +15,6 @@ if(COMPILER_RT_BUILD_PROFILE AND COMPILER_RT_HAS_PROFILE)
endif()
if(COMPILER_RT_STANDALONE_BUILD)
- add_executable(FileCheck IMPORTED GLOBAL)
- set_property(TARGET FileCheck PROPERTY IMPORTED_LOCATION ${LLVM_TOOLS_BINARY_DIR}/FileCheck)
list(APPEND SANITIZER_COMMON_LIT_TEST_DEPS FileCheck)
endif()
diff --git a/test/asan/TestCases/Linux/asan_rt_confict_test-2.cc b/test/asan/TestCases/Linux/asan_rt_confict_test-2.cc
index 4c935e2b0..6328cbb2c 100644
--- a/test/asan/TestCases/Linux/asan_rt_confict_test-2.cc
+++ b/test/asan/TestCases/Linux/asan_rt_confict_test-2.cc
@@ -1,8 +1,8 @@
// Test that mixed static/dynamic sanitization of program objects
// is prohibited.
//
-// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t.so
-// RUN: %clangxx_asan_static %s %t.so -o %t
+// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %dynamiclib
+// RUN: %clangxx_asan_static %s %ld_flags_rpath_exe -o %t
// RUN: not %run %t 2>&1 | FileCheck %s
// REQUIRES: asan-dynamic-runtime
diff --git a/test/asan/TestCases/Linux/local_alias.cc b/test/asan/TestCases/Linux/local_alias.cc
index 635e30b87..a8b3d75e3 100644
--- a/test/asan/TestCases/Linux/local_alias.cc
+++ b/test/asan/TestCases/Linux/local_alias.cc
@@ -4,13 +4,10 @@
// false positive global-buffer-overflow due to sanitized library poisons
// globals from non-sanitized one.
//
-// FIXME: https://github.com/google/sanitizers/issues/316
-// XFAIL: android
-//
-// RUN: %clangxx_asan -DBUILD_INSTRUMENTED_DSO=1 -fPIC -shared -mllvm -asan-use-private-alias %s -o %t-INSTRUMENTED-SO.so
-// RUN: %clangxx -DBUILD_UNINSTRUMENTED_DSO=1 -fPIC -shared %s -o %t-UNINSTRUMENTED-SO.so
+// RUN: %clangxx_asan -DBUILD_INSTRUMENTED_DSO=1 -fPIC -shared -mllvm -asan-use-private-alias %s -o %dynamiclib1
+// RUN: %clangxx -DBUILD_UNINSTRUMENTED_DSO=1 -fPIC -shared %s -o %dynamiclib2
// RUN: %clangxx %s -c -mllvm -asan-use-private-alias -o %t.o
-// RUN: %clangxx_asan %t.o %t-UNINSTRUMENTED-SO.so %t-INSTRUMENTED-SO.so -o %t-EXE
+// RUN: %clangxx_asan %t.o %ld_flags_rpath_exe2 %ld_flags_rpath_exe1 -o %t-EXE
// RUN: %run %t-EXE
#if defined (BUILD_INSTRUMENTED_DSO)
diff --git a/test/asan/TestCases/Linux/new_delete_mismatch.cc b/test/asan/TestCases/Linux/new_delete_mismatch.cc
index 3a71862fb..05f74bda7 100644
--- a/test/asan/TestCases/Linux/new_delete_mismatch.cc
+++ b/test/asan/TestCases/Linux/new_delete_mismatch.cc
@@ -14,3 +14,4 @@ int main() {
}
// CHECK: AddressSanitizer: alloc-dealloc-mismatch (operator new [] vs operator delete) on 0x
+// CHECK: is located 0 bytes inside of 10-byte region
diff --git a/test/asan/TestCases/Linux/new_delete_mismatch_global.cc b/test/asan/TestCases/Linux/new_delete_mismatch_global.cc
new file mode 100644
index 000000000..3f1a78715
--- /dev/null
+++ b/test/asan/TestCases/Linux/new_delete_mismatch_global.cc
@@ -0,0 +1,16 @@
+// Check that we report delete on a memory that belongs to a global variable.
+
+// RUN: %clangxx_asan -g %s -o %t && %env_asan_opts=alloc_dealloc_mismatch=1 not %run %t 2>&1 | FileCheck %s
+
+#include <stdlib.h>
+
+static volatile char *x;
+char a[10];
+
+int main() {
+ x = &a[0];
+ delete x;
+}
+
+// CHECK: AddressSanitizer: attempting free on address which was not malloc()-ed
+// CHECK: is located 0 bytes inside of global variable 'a' defined in
diff --git a/test/asan/TestCases/Linux/new_delete_mismatch_stack.cc b/test/asan/TestCases/Linux/new_delete_mismatch_stack.cc
new file mode 100644
index 000000000..bbf07cc21
--- /dev/null
+++ b/test/asan/TestCases/Linux/new_delete_mismatch_stack.cc
@@ -0,0 +1,17 @@
+// Check that we report delete on a memory that belongs to a stack variable.
+
+// RUN: %clangxx_asan -g %s -o %t && %env_asan_opts=alloc_dealloc_mismatch=1 not %run %t 2>&1 | FileCheck %s
+
+#include <stdlib.h>
+
+static volatile char *x;
+
+int main() {
+ char a[10];
+ x = &a[0];
+ delete x;
+}
+
+// CHECK: AddressSanitizer: attempting free on address which was not malloc()-ed
+// CHECK: is located in stack of thread T0 at offset
+// CHECK: 'a'{{.*}} <== Memory access at offset {{16|32}} is inside this variable
diff --git a/test/asan/TestCases/Linux/odr-violation.cc b/test/asan/TestCases/Linux/odr-violation.cc
index 05ee1e5c1..a1941fcc8 100644
--- a/test/asan/TestCases/Linux/odr-violation.cc
+++ b/test/asan/TestCases/Linux/odr-violation.cc
@@ -5,15 +5,15 @@
// pointers. This setting is not on by default because it's too expensive.
//
// Different size: detect a bug if detect_odr_violation>=1
-// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t-ODR-SO.so
-// RUN: %clangxx_asan %s %t-ODR-SO.so -Wl,-R. -o %t-ODR-EXE
+// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %dynamiclib
+// RUN: %clangxx_asan %s %ld_flags_rpath_exe -o %t-ODR-EXE
// RUN: %env_asan_opts=fast_unwind_on_malloc=0:detect_odr_violation=1 not %run %t-ODR-EXE 2>&1 | FileCheck %s
// RUN: %env_asan_opts=fast_unwind_on_malloc=0:detect_odr_violation=2 not %run %t-ODR-EXE 2>&1 | FileCheck %s
// RUN: %env_asan_opts=fast_unwind_on_malloc=0:detect_odr_violation=0 %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED
// RUN: %env_asan_opts=fast_unwind_on_malloc=0 not %run %t-ODR-EXE 2>&1 | FileCheck %s
//
// Same size: report a bug only if detect_odr_violation>=2.
-// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %t-ODR-SO.so -DSZ=100
+// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared %s -o %dynamiclib -DSZ=100
// RUN: %env_asan_opts=fast_unwind_on_malloc=0:detect_odr_violation=1 %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED
// RUN: %env_asan_opts=fast_unwind_on_malloc=0:detect_odr_violation=2 not %run %t-ODR-EXE 2>&1 | FileCheck %s
// RUN: %env_asan_opts=fast_unwind_on_malloc=0 not %run %t-ODR-EXE 2>&1 | FileCheck %s
@@ -24,18 +24,18 @@
// RUN: rm -f %t.supp
//
// Use private aliases for global variables without indicator symbol.
-// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared -mllvm -asan-use-private-alias %s -o %t-ODR-SO.so -DSZ=100
-// RUN: %clangxx_asan -mllvm -asan-use-private-alias %s %t-ODR-SO.so -Wl,-R. -o %t-ODR-EXE
+// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared -mllvm -asan-use-private-alias %s -o %dynamiclib -DSZ=100
+// RUN: %clangxx_asan -mllvm -asan-use-private-alias %s %ld_flags_rpath_exe -o %t-ODR-EXE
// RUN: %env_asan_opts=fast_unwind_on_malloc=0 %run %t-ODR-EXE 2>&1 | FileCheck %s --check-prefix=DISABLED
// Use private aliases for global variables: use indicator symbol to detect ODR violation.
-// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared -mllvm -asan-use-private-alias -mllvm -asan-use-odr-indicator %s -o %t-ODR-SO.so -DSZ=100
-// RUN: %clangxx_asan -mllvm -asan-use-private-alias -mllvm -asan-use-odr-indicator %s %t-ODR-SO.so -Wl,-R. -o %t-ODR-EXE
+// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared -mllvm -asan-use-private-alias -mllvm -asan-use-odr-indicator %s -o %dynamiclib -DSZ=100
+// RUN: %clangxx_asan -mllvm -asan-use-private-alias -mllvm -asan-use-odr-indicator %s %ld_flags_rpath_exe -o %t-ODR-EXE
// RUN: %env_asan_opts=fast_unwind_on_malloc=0 not %run %t-ODR-EXE 2>&1 | FileCheck %s
// Same as above but with clang switches.
-// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared -fsanitize-address-use-odr-indicator %s -o %t-ODR-SO.so -DSZ=100
-// RUN: %clangxx_asan -fsanitize-address-use-odr-indicator %s %t-ODR-SO.so -Wl,-R. -o %t-ODR-EXE
+// RUN: %clangxx_asan -DBUILD_SO=1 -fPIC -shared -fsanitize-address-use-odr-indicator %s -o %dynamiclib -DSZ=100
+// RUN: %clangxx_asan -fsanitize-address-use-odr-indicator %s %ld_flags_rpath_exe -o %t-ODR-EXE
// RUN: %env_asan_opts=fast_unwind_on_malloc=0 not %run %t-ODR-EXE 2>&1 | FileCheck %s
// GNU driver doesn't handle .so files properly.
@@ -60,6 +60,6 @@ int main(int argc, char **argv) {
// CHECK: These globals were registered at these points:
// CHECK: ODR-EXE
-// CHECK: ODR-SO
+// CHECK: odr-violation.cc.dynamic
// CHECK: SUMMARY: AddressSanitizer: odr-violation: global 'foo::G' at {{.*}}odr-violation.cc
// DISABLED: PASS
diff --git a/test/asan/TestCases/Linux/odr-vtable.cc b/test/asan/TestCases/Linux/odr-vtable.cc
new file mode 100644
index 000000000..fdbab4bb1
--- /dev/null
+++ b/test/asan/TestCases/Linux/odr-vtable.cc
@@ -0,0 +1,26 @@
+// RUN: %clangxx_asan -fno-rtti -DBUILD_SO1 -fPIC -shared %s -o %dynamiclib1
+// RUN: %clangxx_asan -fno-rtti -DBUILD_SO2 -fPIC -shared %s -o %dynamiclib2
+// RUN: %clangxx_asan -fno-rtti %s %ld_flags_rpath_exe1 %ld_flags_rpath_exe2 -o %t
+// RUN: %env_asan_opts=fast_unwind_on_malloc=0:detect_odr_violation=2 not %run %t 2>&1 | FileCheck %s
+
+struct XYZ {
+ virtual void foo();
+};
+
+#if defined(BUILD_SO1)
+
+void XYZ::foo() {}
+
+#elif defined(BUILD_SO2)
+
+void XYZ::foo() {}
+
+#else
+
+int main() {}
+
+#endif
+
+// CHECK: AddressSanitizer: odr-violation
+// CHECK-NEXT: 'vtable for XYZ'
+// CHECK-NEXT: 'vtable for XYZ'
diff --git a/test/asan/TestCases/Linux/odr_c_test.c b/test/asan/TestCases/Linux/odr_c_test.c
index b1d23493b..c1423ed30 100644
--- a/test/asan/TestCases/Linux/odr_c_test.c
+++ b/test/asan/TestCases/Linux/odr_c_test.c
@@ -1,13 +1,11 @@
// Test that we can properly report an ODR violation
// between an instrumented global and a non-instrumented global.
-// RUN: %clang_asan %s -fPIC -shared -o %t-1.so -DFILE1
-// RUN: %clang_asan %s -fPIC -shared -o %t-2.so -DFILE2
-// RUN: %clang_asan %s -fPIE %t-1.so %t-2.so -Wl,-R`pwd` -o %t
+// RUN: %clang_asan %s -fPIC -shared -o %dynamiclib1 -DFILE1
+// RUN: %clang_asan %s -fPIC -shared -o %dynamiclib2 -DFILE2
+// RUN: %clang_asan %s -fPIE %ld_flags_rpath_exe1 %ld_flags_rpath_exe2 -o %t
// RUN: not %run %t 2>&1 | FileCheck %s
//
-// REQUIRES: x86_64-target-arch
-//
// CHECK: The following global variable is not properly aligned.
// CHECK: ERROR: AddressSanitizer: odr-violation
#if defined(FILE1)
diff --git a/test/asan/TestCases/Linux/preinit_test.cc b/test/asan/TestCases/Linux/preinit_test.cc
index 10dde67d6..f8c2b6bf5 100644
--- a/test/asan/TestCases/Linux/preinit_test.cc
+++ b/test/asan/TestCases/Linux/preinit_test.cc
@@ -1,8 +1,5 @@
-// FIXME: https://code.google.com/p/address-sanitizer/issues/detail?id=316
-// XFAIL: android
-//
-// RUN: %clangxx -DFUNC=zzzz %s -shared -o %t.so -fPIC
-// RUN: %clangxx_asan -DFUNC=main %s -o %t -Wl,-R. %t.so
+// RUN: %clangxx -DFUNC=zzzz %s -shared -o %dynamiclib -fPIC
+// RUN: %clangxx_asan -DFUNC=main %s -o %t %ld_flags_rpath_exe
// RUN: %run %t
// GNU driver doesn't handle .so files properly.
diff --git a/test/asan/TestCases/Posix/no-fd.cc b/test/asan/TestCases/Posix/no-fd.cc
new file mode 100644
index 000000000..086b01412
--- /dev/null
+++ b/test/asan/TestCases/Posix/no-fd.cc
@@ -0,0 +1,43 @@
+// RUN: %clangxx_asan -std=c++11 -O0 %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s
+// RUN: %env_asan_opts=debug=1,verbosity=2 %run %t 2>&1 | FileCheck %s
+
+// Test ASan initialization
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+extern "C" const char *__asan_default_options() {
+ return "test_only_emulate_no_memorymap=1";
+}
+
+void parent(int argc, char **argv) {
+ fprintf(stderr, "hello\n");
+ // CHECK: hello
+ close(0);
+ close(1);
+ dup2(2, 3);
+ close(2);
+ char *const newargv[] = {argv[0], (char *)"x", nullptr};
+ execv(argv[0], newargv);
+ perror("execve");
+ exit(1);
+}
+
+void child() {
+ assert(dup(3) == 0);
+ assert(dup(3) == 1);
+ assert(dup(3) == 2);
+ fprintf(stderr, "world\n");
+ // CHECK: world
+}
+
+int main(int argc, char **argv) {
+ if (argc == 1) {
+ parent(argc, argv);
+ } else {
+ child();
+ }
+}
diff --git a/test/asan/TestCases/Posix/tsd_dtor_leak.cc b/test/asan/TestCases/Posix/tsd_dtor_leak.cc
index 860f3459e..26109fe1a 100644
--- a/test/asan/TestCases/Posix/tsd_dtor_leak.cc
+++ b/test/asan/TestCases/Posix/tsd_dtor_leak.cc
@@ -3,6 +3,8 @@
// RUN: %clangxx_asan -O1 %s -pthread -o %t
// RUN: %env_asan_opts=quarantine_size_mb=0 %run %t
// XFAIL: x86_64-netbsd
+// Assertion fails
+// XFAIL: x86_64-freebsd
#include <pthread.h>
#include <stdio.h>
#include <stdlib.h>
diff --git a/test/asan/TestCases/asan_and_llvm_coverage_test.cc b/test/asan/TestCases/asan_and_llvm_coverage_test.cc
index 005bf7de1..2ba5a42d1 100644
--- a/test/asan/TestCases/asan_and_llvm_coverage_test.cc
+++ b/test/asan/TestCases/asan_and_llvm_coverage_test.cc
@@ -4,8 +4,6 @@
// We don't really support running tests using profile runtime on Windows.
// UNSUPPORTED: windows-msvc
-// profile is disabled by default
-// UNSUPPORTED: netbsd
#include <stdio.h>
int foo() { return 1; }
int XXX = foo();
diff --git a/test/asan/TestCases/printf-3.c b/test/asan/TestCases/printf-3.c
index 1183b2f6f..4f54ff956 100644
--- a/test/asan/TestCases/printf-3.c
+++ b/test/asan/TestCases/printf-3.c
@@ -6,6 +6,10 @@
// FIXME: printf is not intercepted on Windows yet.
// XFAIL: windows-msvc
+// New Bionic rejects %n
+// https://android.googlesource.com/platform/bionic/+/41398d03b7e8e0dfb951660ae713e682e9fc0336
+// UNSUPPORTED: android
+
#include <stdio.h>
int main() {
#ifdef _MSC_VER
diff --git a/test/builtins/Unit/ppc/fixtfdi_test.c b/test/builtins/Unit/ppc/fixtfdi_test.c
index ea6c40563..0dc663655 100644
--- a/test/builtins/Unit/ppc/fixtfdi_test.c
+++ b/test/builtins/Unit/ppc/fixtfdi_test.c
@@ -1,5 +1,5 @@
-// REQUIRES: powerpc-registered-target
-// RUN: %clang_builtins %s -o %t && %run %t
+// REQUIRES: target-is-powerpc64le
+// RUN: %clang_builtins %s %librt -o %t && %run %t
#include <stdio.h>
#include <limits.h>
#include <stdint.h>
@@ -476,4 +476,4 @@ int main(int argc, char *argv[]) {
}
return 0;
-} \ No newline at end of file
+}
diff --git a/test/builtins/Unit/ppc/fixunstfti_test.c b/test/builtins/Unit/ppc/fixunstfti_test.c
new file mode 100644
index 000000000..0eee31db1
--- /dev/null
+++ b/test/builtins/Unit/ppc/fixunstfti_test.c
@@ -0,0 +1,52 @@
+// REQUIRES: target-is-powerpc64le
+// RUN: %clang_builtins %s %librt -o %t && %run %t
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "fixunstfti_test.h"
+
+/* The long double representation, with the high and low portions of
+ * the long double, and the corresponding bit patterns of each double. */
+typedef union {
+ long double ld;
+ double d[2]; /* [0] is the high double, [1] is the low double. */
+ unsigned long long ull[2]; /* High and low doubles as 64-bit integers. */
+} ldUnion;
+
+__uint128_t __fixunstfti(long double);
+
+int main(int argc, char *argv[]) {
+ /* Necessary long double and (unsigned) 128 bit integer
+ * declarations used to compare the computed and expected results
+ * from converting the IBM double-double to int128. */
+ ldUnion ldInput;
+ __uint128_t expectedResult, computedResult;
+
+ for (int i = 0; i < numTests; ++i) {
+ /* Set the expected 128 bit integer and the high and low
+ * values of the long double input. */
+ ldInput.d[0] = testList[i].hiInput;
+ ldInput.d[1] = testList[i].loInput;
+ expectedResult = testList[i].result128;
+
+ /* Get the computed 128 bit integer from the long double->
+ * uint128 conversion, and check for errors between results. */
+ computedResult = __fixunstfti(ldInput.ld);
+
+ if (computedResult != expectedResult) {
+ printf("Error for __fixunstfti at input %La = ( %a , %a ):\n", ldInput.ld,
+ ldInput.d[0], ldInput.d[1]);
+ printf("\tExpected __uint128_t: 0x%016llx 0x%016llx\n",
+ (unsigned long long)(expectedResult >> 64),
+ (unsigned long long)expectedResult);
+ printf("\tComputed __uint128_t: 0x%016llx 0x%016llx\n\n",
+ (unsigned long long)(computedResult >> 64),
+ (unsigned long long)computedResult);
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/test/builtins/Unit/ppc/fixunstfti_test.h b/test/builtins/Unit/ppc/fixunstfti_test.h
new file mode 100644
index 000000000..d7de0ce14
--- /dev/null
+++ b/test/builtins/Unit/ppc/fixunstfti_test.h
@@ -0,0 +1,706 @@
+/*
+* Test case inputs for: __uint128_t __fixunstfti (long double)
+* Conversion from long double (IBM double-double) to 128 bit integer.
+*/
+
+#define INFINITY __builtin_inf()
+#define QNAN __builtin_nan("")
+#define INIT_U128(HI, LO) (((__uint128_t) (HI) << 64) | (LO))
+
+struct testCase {
+ double hiInput;
+ double loInput;
+ __uint128_t result128;
+};
+
+struct testCase testList[] = {
+ { 0x0p+0, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { -0x0p+0, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { -0x0p+0, -0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { 0x0p+0, -0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { -0x1p+0, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { 0x1p+0, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000001 ) },
+ { -INFINITY, 0x0p+0, ((__uint128_t)0x0000000000000000 << 64) | 0x0000000000000000 },
+ { INFINITY, 0x0p+0, ((__uint128_t)0xffffffffffffffff << 64) | 0xffffffffffffffff },
+ { QNAN, 0x0p+0, ((__uint128_t)0x7ff8000000000000 << 64) | 0x0000000000000000 },
+ { -QNAN, 0x0p+0, ((__uint128_t)0x7ff8000000000000 << 64) | 0x0000000000000000 },
+ { -0x1p+127, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { 0x1p+127, -0x1p+0, INIT_U128( 0x7fffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1p+0, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000001 ) },
+ { 0x1p+60, 0x0p+0, INIT_U128( 0x0000000000000000, 0x1000000000000000 ) },
+ { 0x1p+64, -0x1p+0, INIT_U128( 0x0000000000000000, 0xffffffffffffffff ) },
+ { 0x1p+63, -0x1p+0, INIT_U128( 0x0000000000000000, 0x7fffffffffffffff ) },
+ { 0x1p+64, 0x0p+0, INIT_U128( 0x0000000000000001, 0x0000000000000000 ) },
+ { 0x1p+64, 0x1p+0, INIT_U128( 0x0000000000000001, 0x0000000000000001 ) },
+ { 0x1.8p+64, -0x1p+0, INIT_U128( 0x0000000000000001, 0x7fffffffffffffff ) },
+ { 0x1.1p+64, 0x0p+0, INIT_U128( 0x0000000000000001, 0x1000000000000000 ) },
+ { 0x1p+65, -0x1p+0, INIT_U128( 0x0000000000000001, 0xffffffffffffffff ) },
+ { 0x1p+127, -0x1p+64, INIT_U128( 0x7fffffffffffffff, 0x0000000000000000 ) },
+ { 0x1p+127, -0x1.ep+64, INIT_U128( 0x7ffffffffffffffe, 0x2000000000000000 ) },
+ { 0x1p+127, -0x1p+63, INIT_U128( 0x7fffffffffffffff, 0x8000000000000000 ) },
+ { 0x1p+124, 0x0p+0, INIT_U128( 0x1000000000000000, 0x0000000000000000 ) },
+ { 0x1p+124, 0x1p+0, INIT_U128( 0x1000000000000000, 0x0000000000000001 ) },
+ { 0x1p+124, 0x1p+63, INIT_U128( 0x1000000000000000, 0x8000000000000000 ) },
+ { 0x1p+124, 0x1p+64, INIT_U128( 0x1000000000000001, 0x0000000000000000 ) },
+ { -0x1p+64, 0x0p+0, INIT_U128( 0x00000000000000000, 0x0000000000000000 ) },
+ { 0x1.84p+70, 0x1.84p+6, INIT_U128( 0x0000000000000061, 0x0000000000000061 ) },
+ { 0x1.5cp+6, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000057 ) },
+ { 0x1p+64, -0x1.88p+6, INIT_U128( 0x0000000000000000, 0xffffffffffffff9e ) },
+ { 0x1.88p+6, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000062 ) },
+ { 0x1.00cp+10, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000403 ) },
+ { 0x1.fffffffffffffp+63, 0x1.fep+9, INIT_U128( 0x0000000000000000, 0xfffffffffffffbfc ) },
+ { 0x1.028p+10, 0x0p+0, INIT_U128( 0x0000000000000000, 0x000000000000040a ) },
+ { 0x1.44p+10, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000510 ) },
+ { 0x1.fffffffffffffp+63, 0x1.738p+9, INIT_U128( 0x0000000000000000, 0xfffffffffffffae7 ) },
+ { 0x1.808p+10, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000602 ) },
+ { 0x1.fffffffffffffp+63, 0x1.fdp+8, INIT_U128( 0x0000000000000000, 0xfffffffffffff9fd ) },
+ { 0x1.048p+13, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000002090 ) },
+ { 0x1.ffffffffffffbp+63, 0x1.ed8p+9, INIT_U128( 0x0000000000000000, 0xffffffffffffdbdb ) },
+ { 0x1.0101p+17, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000020202 ) },
+ { 0x1.fffffffffffbep+63, -0x1.09p+8, INIT_U128( 0x0000000000000000, 0xfffffffffffdeef7 ) },
+ { 0x1.9002p+17, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000032004 ) },
+ { 0x1.fffffffffff9cp+63, -0x1.4p+2, INIT_U128( 0x0000000000000000, 0xfffffffffffcdffb ) },
+ { 0x1.902p+17, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000032040 ) },
+ { 0x1.ffffffffff7fcp+63, -0x1.14p+6, INIT_U128( 0x0000000000000000, 0xffffffffffbfdfbb ) },
+ { 0x1.00822p+22, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000402088 ) },
+ { 0x1.0010011p+31, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000080080088 ) },
+ { 0x1.0a000001p+35, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000850000008 ) },
+ { 0x1.000000224p+37, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000002000000448 ) },
+ { 0x1.ffffffbffefb8p+63, -0x1p+0, INIT_U128( 0x0000000000000000, 0xffffffdfff7dbfff ) },
+ { 0x1.00080044p+102, 0x1.00080044p+38, INIT_U128( 0x0000004002001100, 0x0000004002001100 ) },
+ { 0x1.00400000018p+107, 0x1.00400000018p+43, INIT_U128( 0x000008020000000c, 0x000008020000000c ) },
+ { 0x1.ffffeffcp+63, -0x1.ap+3, INIT_U128( 0x0000000000000000, 0xfffff7fdfffffff3 ) },
+ { 0x1.000000001048p+47, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000800000000824 ) },
+ { 0x1.fffbffffffp+63, -0x1.808p+9, INIT_U128( 0x0000000000000000, 0xfffdffffff7ffcff ) },
+ { 0x1.000810004p+62, 0x0p+0, INIT_U128( 0x0000000000000000, 0x4002040010000000 ) },
+ { 0x1.7ffbf7ffep+63, -0x1p+0, INIT_U128( 0x0000000000000000, 0xbffdfbffefffffff ) },
+ { 0x1p+63, 0x0p+0, INIT_U128( 0x0000000000000000, 0x8000000000000000 ) },
+ { 0x1.ffffffffe8319p+63, -0x1.1f8p+9, INIT_U128( 0x0000000000000000, 0xfffffffff418c5c1 ) },
+ { 0x1p+68, -0x1p+0, INIT_U128( 0x000000000000000f, 0xffffffffffffffff ) },
+ { 0x1p+72, -0x1p+0, INIT_U128( 0x00000000000000ff, 0xffffffffffffffff ) },
+ { 0x1p+76, -0x1p+0, INIT_U128( 0x0000000000000fff, 0xffffffffffffffff ) },
+ { 0x1p+80, -0x1p+0, INIT_U128( 0x000000000000ffff, 0xffffffffffffffff ) },
+ { 0x1p+84, -0x1p+0, INIT_U128( 0x00000000000fffff, 0xffffffffffffffff ) },
+ { 0x1p+88, -0x1p+0, INIT_U128( 0x0000000000ffffff, 0xffffffffffffffff ) },
+ { 0x1p+92, -0x1p+0, INIT_U128( 0x000000000fffffff, 0xffffffffffffffff ) },
+ { 0x1p+96, -0x1p+0, INIT_U128( 0x00000000ffffffff, 0xffffffffffffffff ) },
+ { 0x1p+100, -0x1p+0, INIT_U128( 0x0000000fffffffff, 0xffffffffffffffff ) },
+ { 0x1p+104, -0x1p+0, INIT_U128( 0x000000ffffffffff, 0xffffffffffffffff ) },
+ { 0x1p+108, -0x1p+0, INIT_U128( 0x00000fffffffffff, 0xffffffffffffffff ) },
+ { 0x1p+112, -0x1p+0, INIT_U128( 0x0000ffffffffffff, 0xffffffffffffffff ) },
+ { 0x1p+116, -0x1p+0, INIT_U128( 0x000fffffffffffff, 0xffffffffffffffff ) },
+ { 0x1p+120, -0x1p+0, INIT_U128( 0x00ffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1p+124, -0x1p+0, INIT_U128( 0x0fffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1p+124, 0x0p+0, INIT_U128( 0x1000000000000000, 0x0000000000000000 ) },
+ { 0x1p+124, 0x1.1p+4, INIT_U128( 0x1000000000000000, 0x0000000000000011 ) },
+ { 0x1p+124, 0x1.11p+8, INIT_U128( 0x1000000000000000, 0x0000000000000111 ) },
+ { 0x1p+124, 0x1.111p+12, INIT_U128( 0x1000000000000000, 0x0000000000001111 ) },
+ { 0x1p+124, 0x1.1111p+16, INIT_U128( 0x1000000000000000, 0x0000000000011111 ) },
+ { 0x1p+124, 0x1.11111p+20, INIT_U128( 0x1000000000000000, 0x0000000000111111 ) },
+ { 0x1p+124, 0x1.111111p+24, INIT_U128( 0x1000000000000000, 0x0000000001111111 ) },
+ { 0x1p+124, 0x1.1111111p+28, INIT_U128( 0x1000000000000000, 0x0000000011111111 ) },
+ { 0x1p+124, 0x1.11111111p+32, INIT_U128( 0x1000000000000000, 0x0000000111111111 ) },
+ { 0x1p+124, 0x1.111111111p+36, INIT_U128( 0x1000000000000000, 0x0000001111111111 ) },
+ { 0x1p+124, 0x1.1111111111p+40, INIT_U128( 0x1000000000000000, 0x0000011111111111 ) },
+ { 0x1p+124, 0x1.11111111111p+44, INIT_U128( 0x1000000000000000, 0x0000111111111111 ) },
+ { 0x1p+124, 0x1.111111111111p+48, INIT_U128( 0x1000000000000000, 0x0001111111111111 ) },
+ { 0x1p+124, 0x1.1111111111111p+52, INIT_U128( 0x1000000000000000, 0x0011111111111111 ) },
+ { 0x1p+124, 0x1.11111111111111p+56, INIT_U128( 0x1000000000000000, 0x0111111111111110 ) },
+ { 0x1p+124, 0x1.111111111111111p+60, INIT_U128( 0x1000000000000000, 0x1111111111111100 ) },
+ { 0x1.6ffffffefp+63, -0x1p+0, INIT_U128( 0x0000000000000000, 0xb7ffffff77ffffff ) },
+ { 0x1p+106, 0x0p+0, INIT_U128( 0x0000040000000000, 0x0000000000000000 ) },
+ { 0x1.ff8p+29, 0x0p+0, INIT_U128( 0x0000000000000000, 0x000000003ff00000 ) },
+ { 0x1.6ff7ffffffffcp+63, -0x1p+0, INIT_U128( 0x0000000000000000, 0xb7fbffffffffdfff ) },
+ { 0x1.2400000000004p+62, 0x0p+0, INIT_U128( 0x0000000000000000, 0x4900000000001000 ) },
+ { 0x1.24000000001p+126, 0x1.24000000001p+62, INIT_U128( 0x4900000000040000, 0x4900000000040000 ) },
+ { 0x1.2400001p+126, 0x1.2400001p+62, INIT_U128( 0x4900000400000000, 0x4900000400000000 ) },
+ { 0x1.240001p+126, 0x1.240001p+62, INIT_U128( 0x4900004000000000, 0x4900004000000000 ) },
+ { 0x1.24001p+126, 0x1.24001p+62, INIT_U128( 0x4900040000000000, 0x4900040000000000 ) },
+ { 0x1.24008p+126, 0x1.24008p+62, INIT_U128( 0x4900200000000000, 0x4900200000000000 ) },
+ { 0x1.2404p+126, 0x1.2404p+62, INIT_U128( 0x4901000000000000, 0x4901000000000000 ) },
+ { 0x1.244p+126, 0x1.244p+62, INIT_U128( 0x4910000000000000, 0x4910000000000000 ) },
+ { 0x1.26p+126, 0x1.26p+62, INIT_U128( 0x4980000000000000, 0x4980000000000000 ) },
+ { 0x1.3p+126, 0x1.3p+62, INIT_U128( 0x4c00000000000000, 0x4c00000000000000 ) },
+ { 0x1.800000000001p+126, 0x1.6000000000004p+64, INIT_U128( 0x6000000000004001, 0x6000000000004000 ) },
+ { 0x1.cp+126, 0x1.00ep+71, INIT_U128( 0x7000000000000080, 0x7000000000000000 ) },
+ { 0x1.c000000000008p+126, 0x1.c000000000008p+62, INIT_U128( 0x7000000000002000, 0x7000000000002000 ) },
+ { 0x1.c00000000004p+126, 0x1.c00000000004p+62, INIT_U128( 0x7000000000010000, 0x7000000000010000 ) },
+ { 0x1.c0000000002p+126, 0x1.c0000000002p+62, INIT_U128( 0x7000000000080000, 0x7000000000080000 ) },
+ { 0x1.c000000002p+126, 0x1.c000000002p+62, INIT_U128( 0x7000000000800000, 0x7000000000800000 ) },
+ { 0x1.c00000002p+126, 0x1.c00000002p+62, INIT_U128( 0x7000000008000000, 0x7000000008000000 ) },
+ { 0x1.c0000008p+126, 0x1.c0000008p+62, INIT_U128( 0x7000000200000000, 0x7000000200000000 ) },
+ { 0x1.c000002p+126, 0x1.c000002p+62, INIT_U128( 0x7000000800000000, 0x7000000800000000 ) },
+ { 0x1.c00004p+126, 0x1.c00004p+62, INIT_U128( 0x7000010000000000, 0x7000010000000000 ) },
+ { 0x1.c0002p+126, 0x1.c0002p+62, INIT_U128( 0x7000080000000000, 0x7000080000000000 ) },
+ { 0x1.c008p+126, 0x1.c008p+62, INIT_U128( 0x7002000000000000, 0x7002000000000000 ) },
+ { 0x1.c02p+126, 0x1.c02p+62, INIT_U128( 0x7008000000000000, 0x7008000000000000 ) },
+ { 0x1.c2p+126, 0x1.c2p+62, INIT_U128( 0x7080000000000000, 0x7080000000000000 ) },
+ { 0x1.dp+126, 0x1.dp+62, INIT_U128( 0x7400000000000000, 0x7400000000000000 ) },
+ { 0x1.80be0cccccccdp+63, 0x1.80bc266666666p+63, INIT_U128( 0x0000000000000001, 0x80bd199999999800 ) },
+ { 0x1.017c19999999ap+62, 0x1.01784cccccccdp+62, INIT_U128( 0x0000000000000000, 0x80bd199999999c00 ) },
+ { 0x1.80be0cccccccdp+63, 0x1.01784cccccccdp+62, INIT_U128( 0x0000000000000001, 0x00bd199999999c00 ) },
+ { 0x1.88a1831790ce8p+63, 0x1.1143062f219d8p+62, INIT_U128( 0x0000000000000001, 0x08a1831790cea000 ) },
+ { 0x1.1143062f219dp+62, 0x1.88a1831790cecp+63, INIT_U128( 0x0000000000000001, 0x08a1831790cea000 ) },
+ { 0x1.88a1831790ce8p+63, 0x1.88a1831790cecp+63, INIT_U128( 0x0000000000000001, 0x88a1831790cea000 ) },
+ { 0x1.00014f3089001p+64, 0x1.e133333333333p+6, INIT_U128( 0x0000000000000001, 0x00014f3089001078 ) },
+ { 0x1.fffffffffffffp+127, 0x1p+75, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { 0x1.fffffffffffffp+127, 0x1.fffffffffffffp+74, INIT_U128( 0xFFFFFFFFFFFFFFFF, 0xFFFFFFFFFFC00000 ) },
+ { 0x1.f066666666666p+6, -0x1.f066666666667p-768, INIT_U128( 0x0000000000000000, 0x000000000000007C ) },
+ { 0x1.f066666666666p+6, 0x1.f066666666667p-768, INIT_U128( 0x0000000000000000, 0x000000000000007C ) },
+ { 0x1.1111111111111p+124, 0x1.1p+68, INIT_U128( 0x1111111111111111, 0x0000000000000000 ) },
+ { 0x0.0000000000001p-1022, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { 0x0.0000001160e9fp-1022, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { 0x0.0000001a26f3cp-1022, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { -0x0.0000001134f35p-1022, -0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { 0x0.00003f9eec3ep-1022, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { 0x0.0a40bec0e4818p-1022, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { 0x0.0d4e1fcc5a9c4p-1022, 0x0p+0, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { 0x1.acf5f5ef59ebfp-1007, 0x0.00000000000a8p-1022, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { 0x1.1f45384e3e8a7p-1007, 0x0.00000000000b4p-1022, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { 0x1.8474983f08e93p-1007, 0x0.00000000000d9p-1022, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { 0x1.47ad6cf88f5aep-1007, 0x0.00000000000bcp-1022, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { 0x1.2da4480a5b489p-1, 0x1.9e20ea6f3c41dp-618, INIT_U128( 0x0000000000000000, 0x0000000000000000 ) },
+ { 0x1.438fba0a871f8p+0, 0x1.086e1f6e10dc4p-992, INIT_U128( 0x0000000000000000, 0x0000000000000001 ) },
+ { 0x1.51c874cca390ep+0, 0x1.5dd30576bba6p-992, INIT_U128( 0x0000000000000000, 0x0000000000000001 ) },
+ { 0x1.3691a8086d235p+1, 0x1.3670ebb66ce1ep-281, INIT_U128( 0x0000000000000000, 0x0000000000000002 ) },
+ { 0x1.b800c73570019p+1, 0x1.1bf9094c37f21p-281, INIT_U128( 0x0000000000000000, 0x0000000000000003 ) },
+ { 0x1.c1e89f3783d14p+1, 0x1.69999266d3332p-281, INIT_U128( 0x0000000000000000, 0x0000000000000003 ) },
+ { 0x1.390b19fa72163p+1, 0x1.25bf7f6c4b7fp-281, INIT_U128( 0x0000000000000000, 0x0000000000000002 ) },
+ { 0x1.4beee12897ddcp+2, 0x1.549d853aa93bp-815, INIT_U128( 0x0000000000000000, 0x0000000000000005 ) },
+ { 0x1.e37742bfc6ee9p+2, 0x1.081a6dda1034ep-815, INIT_U128( 0x0000000000000000, 0x0000000000000007 ) },
+ { 0x1.e6c0b50fcd816p+2, 0x1.c3d7967b87af3p-815, INIT_U128( 0x0000000000000000, 0x0000000000000007 ) },
+ { 0x1.590290feb2052p+2, 0x1.07756f600eeaep-815, INIT_U128( 0x0000000000000000, 0x0000000000000005 ) },
+ { 0x1.66154348cc2a8p+3, 0x1.bb93d1a97727ap-619, INIT_U128( 0x0000000000000000, 0x000000000000000b ) },
+ { 0x1.69cf9e9ed39f4p+3, 0x1.ce842e739d086p-619, INIT_U128( 0x0000000000000000, 0x000000000000000b ) },
+ { 0x1.e884574bd108bp+3, 0x1.9c6561f338cacp-619, INIT_U128( 0x0000000000000000, 0x000000000000000f ) },
+ { 0x1.6263a430c4c74p+4, 0x1.6b327792d664fp-117, INIT_U128( 0x0000000000000000, 0x0000000000000016 ) },
+ { 0x1.43637d1286c7p+4, 0x1.546df60aa8dbfp-117, INIT_U128( 0x0000000000000000, 0x0000000000000014 ) },
+ { 0x1.faa21259f5443p+4, 0x1.b6708ecf6ce12p-117, INIT_U128( 0x0000000000000000, 0x000000000000001f ) },
+ { 0x1.fd3105d1fa62p+4, 0x1.370912046e122p-117, INIT_U128( 0x0000000000000000, 0x000000000000001f ) },
+ { 0x1.cf952d399f2a5p+5, 0x1.0d283ebe1a508p-735, INIT_U128( 0x0000000000000000, 0x0000000000000039 ) },
+ { 0x1.6ac8f880d591fp+5, 0x1.ec284da5d8509p-735, INIT_U128( 0x0000000000000000, 0x000000000000002d ) },
+ { 0x1.919c82bf2339p+5, 0x1.a58971fd4b12ep-735, INIT_U128( 0x0000000000000000, 0x0000000000000032 ) },
+ { 0x1.789a89ccf1351p+5, 0x1.ebd48283d7a91p-735, INIT_U128( 0x0000000000000000, 0x000000000000002f ) },
+ { 0x1.8db2068d1b641p+6, 0x1.056174ca0ac2ep-802, INIT_U128( 0x0000000000000000, 0x0000000000000063 ) },
+ { 0x1.8d618e6f1ac32p+6, 0x1.0643da660c87cp-802, INIT_U128( 0x0000000000000000, 0x0000000000000063 ) },
+ { 0x1.f10fc45fe21f8p+6, 0x1.d71f2d6bae3e5p-802, INIT_U128( 0x0000000000000000, 0x000000000000007c ) },
+ { 0x1.1cafcb76395fap+8, 0x1.026dfe9a04dcp-78, INIT_U128( 0x0000000000000000, 0x000000000000011c ) },
+ { 0x1.8b9a3b5917348p+8, 0x1.f64ef081ec9dep-78, INIT_U128( 0x0000000000000000, 0x000000000000018b ) },
+ { 0x1.347ea22c68fd4p+8, 0x1.a86c77e750d8fp-78, INIT_U128( 0x0000000000000000, 0x0000000000000134 ) },
+ { 0x1.c498c82389319p+8, 0x1.0d4d96061a9b3p-78, INIT_U128( 0x0000000000000000, 0x00000000000001c4 ) },
+ { 0x1.3e4fa8b47c9f5p+9, 0x1.d0718139a0e3p-293, INIT_U128( 0x0000000000000000, 0x000000000000027c ) },
+ { 0x1.5ffd3878bffa7p+9, 0x1.1828a29c30514p-293, INIT_U128( 0x0000000000000000, 0x00000000000002bf ) },
+ { 0x1.bbbb3b8577768p+9, 0x1.ba79b21b74f36p-293, INIT_U128( 0x0000000000000000, 0x0000000000000377 ) },
+ { 0x1.8777cb810eefap+9, 0x1.bb3afdc57676p-293, INIT_U128( 0x0000000000000000, 0x000000000000030e ) },
+ { 0x1.8e7992a11cf32p+10, 0x1.a18e4033431c8p-789, INIT_U128( 0x0000000000000000, 0x0000000000000639 ) },
+ { 0x1.7684faeced0ap+10, 0x1.5f11706abe22ep-789, INIT_U128( 0x0000000000000000, 0x00000000000005da ) },
+ { 0x1.7d7ac11afaf58p+10, 0x1.64553beec8aa8p-789, INIT_U128( 0x0000000000000000, 0x00000000000005f5 ) },
+ { 0x1.a540fa454a81fp+10, 0x1.329efbd6653ep-789, INIT_U128( 0x0000000000000000, 0x0000000000000695 ) },
+ { 0x1.92ed812325dbp+11, 0x0.000012eafc716p-1022, INIT_U128( 0x0000000000000000, 0x0000000000000c97 ) },
+ { 0x1.b10abb4562158p+11, 0x0.00001e4765564p-1022, INIT_U128( 0x0000000000000000, 0x0000000000000d88 ) },
+ { 0x1.f6751879ecea3p+11, 0x0.000014435b4b9p-1022, INIT_U128( 0x0000000000000000, 0x0000000000000fb3 ) },
+ { 0x1.32e6b0a465cd6p+11, 0x0.00001729d5c09p-1022, INIT_U128( 0x0000000000000000, 0x0000000000000997 ) },
+ { 0x1.11f336c623e67p+12, 0x1.9d9af61f3b35fp-489, INIT_U128( 0x0000000000000000, 0x000000000000111f ) },
+ { 0x1.18ebab5631d76p+12, 0x1.47d8de9e8fb1cp-489, INIT_U128( 0x0000000000000000, 0x000000000000118e ) },
+ { 0x1.c25a29f984b45p+12, 0x1.c65b51e78cb6ap-489, INIT_U128( 0x0000000000000000, 0x0000000000001c25 ) },
+ { 0x1.cf37f3299e6ffp+12, 0x1.38601ed270c04p-489, INIT_U128( 0x0000000000000000, 0x0000000000001cf3 ) },
+ { 0x1.00db141c01b62p+13, 0x1.a4ea801149d5p-963, INIT_U128( 0x0000000000000000, 0x000000000000201b ) },
+ { 0x1.b81f3643703e7p+13, 0x1.849a11a509342p-963, INIT_U128( 0x0000000000000000, 0x0000000000003703 ) },
+ { 0x1.6dbbb6a4db777p+13, 0x1.362f46546c5e9p-963, INIT_U128( 0x0000000000000000, 0x0000000000002db7 ) },
+ { 0x1.eeb645abdd6c8p+13, 0x1.1edee6683dbddp-963, INIT_U128( 0x0000000000000000, 0x0000000000003dd6 ) },
+ { 0x1.dc7ac6d3b8f59p+14, 0x1.3a4d2846749a5p-96, INIT_U128( 0x0000000000000000, 0x000000000000771e ) },
+ { 0x1.51b38df4a3672p+14, 0x1.ef5f5533debeap-96, INIT_U128( 0x0000000000000000, 0x000000000000546c ) },
+ { 0x1.5cdcee10b9b9ep+14, 0x1.dd44c049ba898p-96, INIT_U128( 0x0000000000000000, 0x0000000000005737 ) },
+ { 0x1.f5266d45ea4cdp+14, 0x1.3970615e72e0cp-96, INIT_U128( 0x0000000000000000, 0x0000000000007d49 ) },
+ { 0x1.2ab9252a55724p+15, 0x1.a85ba3d950b74p-690, INIT_U128( 0x0000000000000000, 0x000000000000955c ) },
+ { 0x1.707a4edee0f4ap+15, 0x1.00541f2800a84p-690, INIT_U128( 0x0000000000000000, 0x000000000000b83d ) },
+ { 0x1.594c6252b298cp+15, 0x1.837b6c0706f6ep-690, INIT_U128( 0x0000000000000000, 0x000000000000aca6 ) },
+ { 0x1.41fad8e683f5bp+15, 0x1.7cb3a2bef9674p-690, INIT_U128( 0x0000000000000000, 0x000000000000a0fd ) },
+ { 0x1.f150e9b3e2a1dp+16, 0x1.155a86a62ab51p-762, INIT_U128( 0x0000000000000000, 0x000000000001f150 ) },
+ { 0x1.0a3ca44214794p+16, 0x1.5c85e07eb90bcp-762, INIT_U128( 0x0000000000000000, 0x0000000000010a3c ) },
+ { 0x1.0ef4814e1de9p+16, 0x1.2cd0510659a0ap-762, INIT_U128( 0x0000000000000000, 0x0000000000010ef4 ) },
+ { 0x1.99373a97326e7p+16, 0x1.98d239d731a47p-762, INIT_U128( 0x0000000000000000, 0x0000000000019937 ) },
+ { 0x1.0062da5400c5cp+17, 0x1.12b3124825662p-940, INIT_U128( 0x0000000000000000, 0x00000000000200c5 ) },
+ { 0x1.8ac0f0251581ep+17, 0x1.60b254d0c164ap-940, INIT_U128( 0x0000000000000000, 0x0000000000031581 ) },
+ { 0x1.51c0eb94a381ep+17, 0x1.ce1da4059c3b4p-940, INIT_U128( 0x0000000000000000, 0x000000000002a381 ) },
+ { 0x1.5e83e6a4bd07dp+17, 0x1.adcff7815b9ffp-940, INIT_U128( 0x0000000000000000, 0x000000000002bd07 ) },
+ { 0x1.242e55bc485cap+18, 0x0.000000000001fp-1022, INIT_U128( 0x0000000000000000, 0x00000000000490b9 ) },
+ { 0x1.7d59ac2cfab36p+18, 0x0.000000000001p-1022, INIT_U128( 0x0000000000000000, 0x000000000005f566 ) },
+ { 0x1.d19e6101a33ccp+18, 0x0.0000000000014p-1022, INIT_U128( 0x0000000000000000, 0x0000000000074679 ) },
+ { 0x1.34c9981869933p+18, 0x0.0000000000011p-1022, INIT_U128( 0x0000000000000000, 0x000000000004d326 ) },
+ { 0x1.c066e34f80cddp+19, 0x1.e3f363b5c7e6dp-881, INIT_U128( 0x0000000000000000, 0x00000000000e0337 ) },
+ { 0x1.df32bc2fbe658p+19, 0x1.df947163bf28ep-881, INIT_U128( 0x0000000000000000, 0x00000000000ef995 ) },
+ { 0x1.3bbc859e7779p+19, 0x1.0773506c0ee6ap-881, INIT_U128( 0x0000000000000000, 0x000000000009dde4 ) },
+ { 0x1.3b65fdae76ccp+19, 0x1.36924fde6d24ap-881, INIT_U128( 0x0000000000000000, 0x000000000009db2f ) },
+ { 0x1.52c7a810a58f5p+20, 0x1.a11a939f42352p-561, INIT_U128( 0x0000000000000000, 0x0000000000152c7a ) },
+ { 0x1.9546ee252a8dep+20, 0x1.eeb4a28ddd695p-561, INIT_U128( 0x0000000000000000, 0x000000000019546e ) },
+ { 0x1.f50465bdea08cp+20, 0x1.7288f4c2e511ep-561, INIT_U128( 0x0000000000000000, 0x00000000001f5046 ) },
+ { 0x1.b8199d2770334p+20, 0x1.a2d4ddfb45a9cp-561, INIT_U128( 0x0000000000000000, 0x00000000001b8199 ) },
+ { 0x1.efe67d0fdfccfp+21, 0x1.05ac37920b587p-121, INIT_U128( 0x0000000000000000, 0x00000000003dfccf ) },
+ { 0x1.a1c8a86343915p+21, 0x1.ff7f144bfefe2p-121, INIT_U128( 0x0000000000000000, 0x0000000000343915 ) },
+ { 0x1.0b3b76001676fp+21, 0x1.742fba58e85f8p-121, INIT_U128( 0x0000000000000000, 0x000000000021676e ) },
+ { 0x1.cb12f6579625fp+21, 0x1.5e77e020bcefcp-121, INIT_U128( 0x0000000000000000, 0x000000000039625e ) },
+ { 0x1.bd380f437a702p+22, 0x1.491fe5e8923fcp-995, INIT_U128( 0x0000000000000000, 0x00000000006f4e03 ) },
+ { 0x1.46fbb89c8df77p+22, 0x1.a09fc8f7413f9p-995, INIT_U128( 0x0000000000000000, 0x000000000051beee ) },
+ { 0x1.17e871f42fd0ep+22, 0x1.a11fc1a7423f8p-995, INIT_U128( 0x0000000000000000, 0x000000000045fa1c ) },
+ { 0x1.277e999a4efd3p+22, 0x1.4bd3e11097a7cp-995, INIT_U128( 0x0000000000000000, 0x000000000049dfa6 ) },
+ { 0x1.6e4d3250dc9a6p+23, 0x1.edf09145dbe12p-447, INIT_U128( 0x0000000000000000, 0x0000000000b72699 ) },
+ { 0x1.eb0413bfd6083p+23, 0x1.29c840b053908p-447, INIT_U128( 0x0000000000000000, 0x0000000000f58209 ) },
+ { 0x1.283f1d32507e4p+23, 0x1.06daa0fe0db54p-447, INIT_U128( 0x0000000000000000, 0x0000000000941f8e ) },
+ { 0x1.cf7790bd9eef2p+23, 0x1.22ebe99845d7dp-447, INIT_U128( 0x0000000000000000, 0x0000000000e7bbc8 ) },
+ { 0x1.39fb1e1473f64p+24, 0x1.baafa729755f5p-263, INIT_U128( 0x0000000000000000, 0x000000000139fb1e ) },
+ { 0x1.553510f0aa6a2p+24, 0x1.806a3d5d00d48p-263, INIT_U128( 0x0000000000000000, 0x0000000001553510 ) },
+ { 0x1.876715390ece3p+24, 0x1.cdf668119becdp-263, INIT_U128( 0x0000000000000000, 0x0000000001876715 ) },
+ { 0x1.11816ac62302ep+24, 0x1.5e8451ecbd08ap-263, INIT_U128( 0x0000000000000000, 0x000000000111816a ) },
+ { 0x1.3e7e811e7cfdp+25, 0x1.2dc6a5685b8d4p-155, INIT_U128( 0x0000000000000000, 0x00000000027cfd02 ) },
+ { 0x1.6ebc2c8cdd786p+25, 0x1.22f38cd645e72p-155, INIT_U128( 0x0000000000000000, 0x0000000002dd7859 ) },
+ { 0x1.421ccf068439ap+25, 0x1.bef8b6f57df17p-155, INIT_U128( 0x0000000000000000, 0x000000000284399e ) },
+ { 0x1.e10ee555c21dcp+25, 0x1.033cdd7a0679cp-155, INIT_U128( 0x0000000000000000, 0x0000000003c21dca ) },
+ { 0x1.f0b6e7ede16ddp+26, 0x1.bc0a81517815p-634, INIT_U128( 0x0000000000000000, 0x0000000007c2db9f ) },
+ { 0x1.f7b66dc5ef6cdp+26, 0x1.2bd3184a57a63p-634, INIT_U128( 0x0000000000000000, 0x0000000007ded9b7 ) },
+ { 0x1.259706244b2e1p+26, 0x1.8b7dd07716fbap-634, INIT_U128( 0x0000000000000000, 0x0000000004965c18 ) },
+ { 0x1.fdf5519ffbeaap+26, 0x1.19d4925433a92p-634, INIT_U128( 0x0000000000000000, 0x0000000007f7d546 ) },
+ { 0x1.bb13b1d776276p+27, 0x1.e509cb23ca13ap-395, INIT_U128( 0x0000000000000000, 0x000000000dd89d8e ) },
+ { 0x1.20754b2a40eaap+27, 0x1.bcc8cd6b7991ap-395, INIT_U128( 0x0000000000000000, 0x000000000903aa59 ) },
+ { 0x1.dc036999b806dp+27, 0x1.62b438eec5687p-395, INIT_U128( 0x0000000000000000, 0x000000000ee01b4c ) },
+ { 0x1.92b76e3d256eep+27, 0x1.33f6413067ec8p-395, INIT_U128( 0x0000000000000000, 0x000000000c95bb71 ) },
+ { 0x1.7a6c4408f4d88p+28, 0x1.0f6d05b41edap-716, INIT_U128( 0x0000000000000000, 0x0000000017a6c440 ) },
+ { 0x1.25d2c9ae4ba59p+28, 0x1.005f5a6a00becp-716, INIT_U128( 0x0000000000000000, 0x00000000125d2c9a ) },
+ { 0x1.c8949d0b91293p+28, 0x1.6e7ca504dcf94p-716, INIT_U128( 0x0000000000000000, 0x000000001c8949d0 ) },
+ { 0x1.21af1f7a435e4p+28, 0x1.98e05ef731c0cp-716, INIT_U128( 0x0000000000000000, 0x00000000121af1f7 ) },
+ { 0x1.307b63f060f6cp+29, 0x1.17d4949a2fa92p-112, INIT_U128( 0x0000000000000000, 0x00000000260f6c7e ) },
+ { 0x1.053d62740a7acp+29, 0x1.a8881e6551104p-112, INIT_U128( 0x0000000000000000, 0x0000000020a7ac4e ) },
+ { 0x1.9b60d35b36c1ap+29, 0x1.005bb09600b76p-112, INIT_U128( 0x0000000000000000, 0x00000000336c1a6b ) },
+ { 0x1.3ba73afe774e8p+29, 0x1.0efca74e1df95p-112, INIT_U128( 0x0000000000000000, 0x000000002774e75f ) },
+ { 0x1.dd796675baf2dp+30, 0x1.aaba00775574p-990, INIT_U128( 0x0000000000000000, 0x00000000775e599d ) },
+ { 0x1.8b282c8d16506p+30, 0x1.4e04f8449c09fp-990, INIT_U128( 0x0000000000000000, 0x0000000062ca0b23 ) },
+ { 0x1.7d6ab930fad57p+30, 0x1.764a6e3cec94ep-990, INIT_U128( 0x0000000000000000, 0x000000005f5aae4c ) },
+ { 0x1.6906027cd20cp+30, 0x1.d5b4ef4dab69ep-990, INIT_U128( 0x0000000000000000, 0x000000005a41809f ) },
+ { 0x1.04a9da360953cp+31, 0x1.6c11a2e4d8234p-857, INIT_U128( 0x0000000000000000, 0x000000008254ed1b ) },
+ { 0x1.fbba6e93f774ep+31, 0x1.0e9a6e5c1d34ep-857, INIT_U128( 0x0000000000000000, 0x00000000fddd3749 ) },
+ { 0x1.380b108470162p+31, 0x1.65c0e5f6cb81cp-857, INIT_U128( 0x0000000000000000, 0x000000009c058842 ) },
+ { 0x1.050dfc000a1cp+31, 0x1.1df2fc803be6p-857, INIT_U128( 0x0000000000000000, 0x000000008286fe00 ) },
+ { 0x1.88bf9e1d117f4p+32, 0x1.8dd4aa1b1ba95p-126, INIT_U128( 0x0000000000000000, 0x0000000188bf9e1d ) },
+ { 0x1.8b35d7ff166bbp+32, 0x1.91ca210923944p-126, INIT_U128( 0x0000000000000000, 0x000000018b35d7ff ) },
+ { 0x1.286a366250d47p+32, 0x1.012c86ac02591p-126, INIT_U128( 0x0000000000000000, 0x00000001286a3662 ) },
+ { 0x1.ef233cd5de467p+32, 0x1.2292a62645255p-126, INIT_U128( 0x0000000000000000, 0x00000001ef233cd5 ) },
+ { 0x1.917a959722f53p+33, 0x1.85a7d93f0b4fbp-478, INIT_U128( 0x0000000000000000, 0x0000000322f52b2e ) },
+ { 0x1.f630053bec6p+33, 0x1.f79a5227ef34bp-478, INIT_U128( 0x0000000000000000, 0x00000003ec600a77 ) },
+ { 0x1.1a062b14340c6p+33, 0x1.21179acc422f4p-478, INIT_U128( 0x0000000000000000, 0x00000002340c5628 ) },
+ { 0x1.d62acf15ac55ap+33, 0x1.bf1cd2697e39ap-478, INIT_U128( 0x0000000000000000, 0x00000003ac559e2b ) },
+ { 0x1.823ddfaf047bcp+34, 0x1.e2d35df1c5a6cp-649, INIT_U128( 0x0000000000000000, 0x0000000608f77ebc ) },
+ { 0x1.996ef6e332ddfp+34, 0x1.7af28278f5e5p-649, INIT_U128( 0x0000000000000000, 0x0000000665bbdb8c ) },
+ { 0x1.81a2bfc703458p+34, 0x1.acc15cd15982cp-649, INIT_U128( 0x0000000000000000, 0x00000006068aff1c ) },
+ { 0x1.4517e98e8a2fdp+34, 0x1.a3233fc546468p-649, INIT_U128( 0x0000000000000000, 0x00000005145fa63a ) },
+ { 0x1.09f551a013eaap+35, 0x0.0000000000006p-1022, INIT_U128( 0x0000000000000000, 0x000000084faa8d00 ) },
+ { 0x1.a2911b3d45224p+35, 0x0.0000000000005p-1022, INIT_U128( 0x0000000000000000, 0x0000000d1488d9ea ) },
+ { 0x1.77a301deef46p+35, 0x0.0000000000008p-1022, INIT_U128( 0x0000000000000000, 0x0000000bbd180ef7 ) },
+ { 0x1.f60ea85fec1d5p+35, 0x0.0000000000006p-1022, INIT_U128( 0x0000000000000000, 0x0000000fb07542ff ) },
+ { 0x1.75c28ed8eb852p+36, 0x1.64300234c86p-938, INIT_U128( 0x0000000000000000, 0x000000175c28ed8e ) },
+ { 0x1.394f8bae729f2p+36, 0x1.2119204042324p-938, INIT_U128( 0x0000000000000000, 0x0000001394f8bae7 ) },
+ { 0x1.94d6bc7929ad8p+36, 0x1.4a8aa2aa95154p-938, INIT_U128( 0x0000000000000000, 0x000000194d6bc792 ) },
+ { 0x1.1f519dcc3ea34p+36, 0x1.b4fbc9c969f79p-938, INIT_U128( 0x0000000000000000, 0x00000011f519dcc3 ) },
+ { 0x1.bb2fb46f765f6p+37, 0x1.cd4047139a809p-718, INIT_U128( 0x0000000000000000, 0x0000003765f68dee ) },
+ { 0x1.f80989d1f0131p+37, 0x1.c0546f4180a8ep-718, INIT_U128( 0x0000000000000000, 0x0000003f01313a3e ) },
+ { 0x1.90be9171217d2p+37, 0x1.bcc6089d798c1p-718, INIT_U128( 0x0000000000000000, 0x0000003217d22e24 ) },
+ { 0x1.37469d226e8d4p+37, 0x1.06aff8000d5ffp-718, INIT_U128( 0x0000000000000000, 0x00000026e8d3a44d ) },
+ { 0x1.2e0114905c022p+38, 0x1.298bde145317cp-115, INIT_U128( 0x0000000000000000, 0x0000004b80452417 ) },
+ { 0x1.77354c42ee6aap+38, 0x1.d9a75513b34eap-115, INIT_U128( 0x0000000000000000, 0x0000005dcd5310bb ) },
+ { 0x1.0881a80c11035p+38, 0x1.44e5e01889cbcp-115, INIT_U128( 0x0000000000000000, 0x00000042206a0304 ) },
+ { 0x1.a32b590f4656bp+38, 0x1.760fbd2eec1f8p-115, INIT_U128( 0x0000000000000000, 0x00000068cad643d1 ) },
+ { 0x1.e7bc6861cf78dp+39, 0x1.72addca8e55bcp-767, INIT_U128( 0x0000000000000000, 0x000000f3de3430e7 ) },
+ { 0x1.e1e11b1bc3c24p+39, 0x1.713729dae26e5p-767, INIT_U128( 0x0000000000000000, 0x000000f0f08d8de1 ) },
+ { 0x1.8bbb377f17767p+39, 0x1.c296d213852dap-767, INIT_U128( 0x0000000000000000, 0x000000c5dd9bbf8b ) },
+ { 0x1.7cb13d18f9628p+39, 0x1.8dcf87351b9f1p-767, INIT_U128( 0x0000000000000000, 0x000000be589e8c7c ) },
+ { 0x1.1ddbaf383bb76p+40, 0x1.20c8d9d04191bp-497, INIT_U128( 0x0000000000000000, 0x0000011ddbaf383b ) },
+ { 0x1.fde474e3fbc8ep+40, 0x1.7e6de35afcdbcp-497, INIT_U128( 0x0000000000000000, 0x000001fde474e3fb ) },
+ { 0x1.02a202b00544p+40, 0x1.311b40f462368p-497, INIT_U128( 0x0000000000000000, 0x00000102a202b005 ) },
+ { 0x1.ec0b6577d816cp+40, 0x1.8e49e85d1c93dp-497, INIT_U128( 0x0000000000000000, 0x000001ec0b6577d8 ) },
+ { 0x1.95fa4b912bf4ap+41, 0x1.295d953652bb2p-872, INIT_U128( 0x0000000000000000, 0x0000032bf4972257 ) },
+ { 0x1.fd243093fa486p+41, 0x1.91e0a45723c14p-872, INIT_U128( 0x0000000000000000, 0x000003fa486127f4 ) },
+ { 0x1.d0beeb21a17dep+41, 0x1.97f98e272ff32p-872, INIT_U128( 0x0000000000000000, 0x000003a17dd64342 ) },
+ { 0x1.750735faea0e6p+41, 0x1.97a4c8c92f499p-872, INIT_U128( 0x0000000000000000, 0x000002ea0e6bf5d4 ) },
+ { 0x1.ab409c8f56814p+42, 0x1.1e820fc23d042p-84, INIT_U128( 0x0000000000000000, 0x000006ad02723d5a ) },
+ { 0x1.85e79a910bcf3p+42, 0x1.75d44930eba89p-84, INIT_U128( 0x0000000000000000, 0x000006179e6a442f ) },
+ { 0x1.e2fa47dfc5f49p+42, 0x1.f91c1067f2382p-84, INIT_U128( 0x0000000000000000, 0x0000078be91f7f17 ) },
+ { 0x1.ecaf7567d95eep+42, 0x1.dd787be3baf1p-84, INIT_U128( 0x0000000000000000, 0x000007b2bdd59f65 ) },
+ { 0x1.4fd770a89faeep+43, 0x1.883956a11072bp-669, INIT_U128( 0x0000000000000000, 0x00000a7ebb8544fd ) },
+ { 0x1.b2b2aa2d65655p+43, 0x1.0c2516f2184a3p-669, INIT_U128( 0x0000000000000000, 0x00000d9595516b2b ) },
+ { 0x1.5848b5b4b0916p+43, 0x1.d9a0d8cfb341bp-669, INIT_U128( 0x0000000000000000, 0x00000ac245ada584 ) },
+ { 0x1.be7daa1f7cfb5p+43, 0x1.f0c9d223e193bp-669, INIT_U128( 0x0000000000000000, 0x00000df3ed50fbe7 ) },
+ { 0x1.3f6d46f07eda9p+44, 0x1.3d2fa1b27a5f4p-539, INIT_U128( 0x0000000000000000, 0x000013f6d46f07ed ) },
+ { 0x1.5eb8dcaebd71cp+44, 0x1.8e170e7b1c2e2p-539, INIT_U128( 0x0000000000000000, 0x000015eb8dcaebd7 ) },
+ { 0x1.893b63631276cp+44, 0x1.9447ca53288f9p-539, INIT_U128( 0x0000000000000000, 0x00001893b6363127 ) },
+ { 0x1.4e089b389c114p+44, 0x1.d191b053a3236p-539, INIT_U128( 0x0000000000000000, 0x000014e089b389c1 ) },
+ { 0x1.2e36d90e5c6dbp+45, 0x1.314d394c629a7p-889, INIT_U128( 0x0000000000000000, 0x000025c6db21cb8d ) },
+ { 0x1.7f784de4fef0ap+45, 0x1.5413e986a827dp-889, INIT_U128( 0x0000000000000000, 0x00002fef09bc9fde ) },
+ { 0x1.74448388e889p+45, 0x1.752c3c2cea588p-889, INIT_U128( 0x0000000000000000, 0x00002e8890711d11 ) },
+ { 0x1.ebb20c51d7641p+45, 0x1.50a52f7ca14a6p-889, INIT_U128( 0x0000000000000000, 0x00003d76418a3aec ) },
+ { 0x1.4b51066896a21p+46, 0x1.d43cc973a8799p-550, INIT_U128( 0x0000000000000000, 0x000052d4419a25a8 ) },
+ { 0x1.070f0d280e1e2p+46, 0x1.c25aa6dd84b55p-550, INIT_U128( 0x0000000000000000, 0x000041c3c34a0387 ) },
+ { 0x1.7f735ca4fee6cp+46, 0x1.a92889d752511p-550, INIT_U128( 0x0000000000000000, 0x00005fdcd7293fb9 ) },
+ { 0x1.72ed987ae5db3p+46, 0x1.fae14a03f5c29p-550, INIT_U128( 0x0000000000000000, 0x00005cbb661eb976 ) },
+ { 0x1.7352fdf0e6a6p+47, 0x1.1a64275034c85p-857, INIT_U128( 0x0000000000000000, 0x0000b9a97ef87353 ) },
+ { 0x1.9f4b98f33e973p+47, 0x1.657b10c0caf62p-857, INIT_U128( 0x0000000000000000, 0x0000cfa5cc799f4b ) },
+ { 0x1.b12eb79b625d7p+47, 0x1.4826ca96904dap-857, INIT_U128( 0x0000000000000000, 0x0000d8975bcdb12e ) },
+ { 0x1.6148cbcac291ap+47, 0x1.8672a1ad0ce54p-857, INIT_U128( 0x0000000000000000, 0x0000b0a465e56148 ) },
+ { 0x1.1df8159e3bf02p+48, 0x1.7c6dbd68f8db8p-407, INIT_U128( 0x0000000000000000, 0x00011df8159e3bf0 ) },
+ { 0x1.d8e17545b1c2ep+48, 0x1.959fcc5f2b3fap-407, INIT_U128( 0x0000000000000000, 0x0001d8e17545b1c2 ) },
+ { 0x1.ea57e075d4afcp+48, 0x1.56705400ace0ap-407, INIT_U128( 0x0000000000000000, 0x0001ea57e075d4af ) },
+ { 0x1.d2aa9e99a5554p+48, 0x1.9ebcab993d796p-407, INIT_U128( 0x0000000000000000, 0x0001d2aa9e99a555 ) },
+ { 0x1.4fe075a49fc0ep+49, 0x1.e950f533d2a1ep-694, INIT_U128( 0x0000000000000000, 0x00029fc0eb493f81 ) },
+ { 0x1.a936db51526dcp+49, 0x1.8a1397df14273p-694, INIT_U128( 0x0000000000000000, 0x0003526db6a2a4db ) },
+ { 0x1.138ce7682719dp+49, 0x1.7f879c76ff0f4p-694, INIT_U128( 0x0000000000000000, 0x00022719ced04e33 ) },
+ { 0x1.21e981b043d3p+49, 0x1.eaefe1f3d5dfcp-694, INIT_U128( 0x0000000000000000, 0x000243d3036087a6 ) },
+ { 0x1.793e9a3cf27d4p+50, 0x1.40169b90802d4p-934, INIT_U128( 0x0000000000000000, 0x0005e4fa68f3c9f5 ) },
+ { 0x1.7e1caadcfc396p+50, 0x1.371020466e204p-934, INIT_U128( 0x0000000000000000, 0x0005f872ab73f0e5 ) },
+ { 0x1.33a019d667403p+50, 0x1.9c77f7cb38effp-934, INIT_U128( 0x0000000000000000, 0x0004ce8067599d00 ) },
+ { 0x1.b4966ecb692cep+50, 0x1.c4dd0f8989ba2p-934, INIT_U128( 0x0000000000000000, 0x0006d259bb2da4b3 ) },
+ { 0x1.822ad9630455bp+51, 0x1.3fade6a07f5bdp-561, INIT_U128( 0x0000000000000000, 0x000c1156cb1822ad ) },
+ { 0x1.3a77dd3c74efcp+51, 0x1.55dd3018abba6p-561, INIT_U128( 0x0000000000000000, 0x0009d3bee9e3a77e ) },
+ { 0x1.d375773da6eafp+51, 0x1.ad40b9955a817p-561, INIT_U128( 0x0000000000000000, 0x000e9babb9ed3757 ) },
+ { 0x1.16059bfe2c0b4p+51, 0x1.ff801c63ff003p-561, INIT_U128( 0x0000000000000000, 0x0008b02cdff1605a ) },
+ { 0x1.af8f1e955f1e4p+52, 0x1.2c4cc4fa58998p-237, INIT_U128( 0x0000000000000000, 0x001af8f1e955f1e4 ) },
+ { 0x1.579e5322af3cap+52, 0x1.e9974457d32e8p-237, INIT_U128( 0x0000000000000000, 0x001579e5322af3ca ) },
+ { 0x1.2b9d921a573b2p+52, 0x1.d8798265b0f3p-237, INIT_U128( 0x0000000000000000, 0x0012b9d921a573b2 ) },
+ { 0x1.b746d5596e8dbp+52, 0x1.a75bfc954eb8p-237, INIT_U128( 0x0000000000000000, 0x001b746d5596e8db ) },
+ { 0x1.497ec4f092fd8p+53, 0x1.5c597ab2b8b3p-364, INIT_U128( 0x0000000000000000, 0x00292fd89e125fb0 ) },
+ { 0x1.8a65536914caap+53, 0x1.958565492b0adp-364, INIT_U128( 0x0000000000000000, 0x00314caa6d229954 ) },
+ { 0x1.11b7146c236e2p+53, 0x1.3154f5b662a9ep-364, INIT_U128( 0x0000000000000000, 0x002236e28d846dc4 ) },
+ { 0x1.f71b5e7bee36cp+53, 0x1.efc7aa5ddf8f6p-364, INIT_U128( 0x0000000000000000, 0x003ee36bcf7dc6d8 ) },
+ { 0x1.5a71157ab4e22p+54, 0x1.b4fd1c6b69fa4p-39, INIT_U128( 0x0000000000000000, 0x00569c455ead3888 ) },
+ { 0x1.4ab52e26956a6p+54, 0x1.204833ee40906p-39, INIT_U128( 0x0000000000000000, 0x0052ad4b89a55a98 ) },
+ { 0x1.7b9298b4f7253p+54, 0x1.084ca6f410995p-39, INIT_U128( 0x0000000000000000, 0x005ee4a62d3dc94c ) },
+ { 0x1.8be06c0317c0ep+54, 0x1.9677f6df2ceffp-39, INIT_U128( 0x0000000000000000, 0x0062f81b00c5f038 ) },
+ { 0x1.53534daca6a6ap+55, 0x1.af26be6f5e4d8p-905, INIT_U128( 0x0000000000000000, 0x00a9a9a6d6535350 ) },
+ { 0x1.ee7424c1dce84p+55, 0x1.38a375387146ep-905, INIT_U128( 0x0000000000000000, 0x00f73a1260ee7420 ) },
+ { 0x1.4275718484eaep+55, 0x1.693f342ed27e6p-905, INIT_U128( 0x0000000000000000, 0x00a13ab8c2427570 ) },
+ { 0x1.4e48bc049c918p+55, 0x1.30d3b39661a76p-905, INIT_U128( 0x0000000000000000, 0x00a7245e024e48c0 ) },
+ { 0x1.6fcb01f0df96p+56, 0x1.f3322f93e6646p-339, INIT_U128( 0x0000000000000000, 0x016fcb01f0df9600 ) },
+ { 0x1.6f16f2e4de2dep+56, 0x1.b50cb2d16a196p-339, INIT_U128( 0x0000000000000000, 0x016f16f2e4de2de0 ) },
+ { 0x1.6fcb3cb2df968p+56, 0x1.f7623e45eec48p-339, INIT_U128( 0x0000000000000000, 0x016fcb3cb2df9680 ) },
+ { 0x1.a41a78314834fp+56, 0x1.ee812a93dd026p-339, INIT_U128( 0x0000000000000000, 0x01a41a78314834f0 ) },
+ { 0x1.73544f7ce6a8ap+57, 0x1.fbf6a069f7ed4p-786, INIT_U128( 0x0000000000000000, 0x02e6a89ef9cd5140 ) },
+ { 0x1.8d4beb3f1a97ep+57, 0x1.6f6e15a0dedc2p-786, INIT_U128( 0x0000000000000000, 0x031a97d67e352fc0 ) },
+ { 0x1.70dfc328e1bf8p+57, 0x1.56963a34ad2c8p-786, INIT_U128( 0x0000000000000000, 0x02e1bf8651c37f00 ) },
+ { 0x1.6e5e39acdcbc7p+57, 0x1.62dfb7d4c5bf7p-786, INIT_U128( 0x0000000000000000, 0x02dcbc7359b978e0 ) },
+ { 0x1.10a375142146ep+58, 0x1.dde963f1bbd2cp-687, INIT_U128( 0x0000000000000000, 0x04428dd450851b80 ) },
+ { 0x1.7eacb1acfd596p+58, 0x1.e59952a9cb32bp-687, INIT_U128( 0x0000000000000000, 0x05fab2c6b3f56580 ) },
+ { 0x1.3f2bac4a7e576p+58, 0x1.d21ee367a43ddp-687, INIT_U128( 0x0000000000000000, 0x04fcaeb129f95d80 ) },
+ { 0x1.be738acb7ce71p+58, 0x1.d4b6334fa96c7p-687, INIT_U128( 0x0000000000000000, 0x06f9ce2b2df39c40 ) },
+ { 0x1.b322eff56645ep+59, 0x0.00000014b8158p-1022, INIT_U128( 0x0000000000000000, 0x0d99177fab322f00 ) },
+ { 0x1.b8dfbdbd71bf8p+59, 0x0.00000010ac2d6p-1022, INIT_U128( 0x0000000000000000, 0x0dc6fdedeb8dfc00 ) },
+ { 0x1.e45f6d33c8bedp+59, 0x0.0000001c79003p-1022, INIT_U128( 0x0000000000000000, 0x0f22fb699e45f680 ) },
+ { 0x1.10c7106e218e2p+59, 0x0.0000001ea2457p-1022, INIT_U128( 0x0000000000000000, 0x08863883710c7100 ) },
+ { 0x1.c48c230989185p+60, 0x1.a60d3fb34c1a8p-116, INIT_U128( 0x0000000000000000, 0x1c48c23098918500 ) },
+ { 0x1.5e9345fabd268p+60, 0x1.4898e6d49131dp-116, INIT_U128( 0x0000000000000000, 0x15e9345fabd26800 ) },
+ { 0x1.b56942576ad28p+60, 0x1.aff4a0655fe94p-116, INIT_U128( 0x0000000000000000, 0x1b56942576ad2800 ) },
+ { 0x1.7f865930ff0cbp+60, 0x1.13a0876e27411p-116, INIT_U128( 0x0000000000000000, 0x17f865930ff0cb00 ) },
+ { 0x1.ef482c31de906p+61, 0x1.43e655d887ccap-501, INIT_U128( 0x0000000000000000, 0x3de905863bd20c00 ) },
+ { 0x1.9fa15a7d3f42bp+61, 0x1.b00fcc55601fap-501, INIT_U128( 0x0000000000000000, 0x33f42b4fa7e85600 ) },
+ { 0x1.d2c465fda588dp+61, 0x1.98c2f6e73185fp-501, INIT_U128( 0x0000000000000000, 0x3a588cbfb4b11a00 ) },
+ { 0x1.f038608de070cp+61, 0x1.7b4fa8a0f69f5p-501, INIT_U128( 0x0000000000000000, 0x3e070c11bc0e1800 ) },
+ { 0x1.adfb2db35bf66p+62, 0x1.38efaf6271df6p+8, INIT_U128( 0x0000000000000000, 0x6b7ecb6cd6fd9938 ) },
+ { 0x1.1679474c2cf29p+62, 0x1.ae04d7f95c09bp+8, INIT_U128( 0x0000000000000000, 0x459e51d30b3ca5ae ) },
+ { 0x1.890c63b91218cp+62, 0x1.133030ac26606p+8, INIT_U128( 0x0000000000000000, 0x624318ee44863113 ) },
+ { 0x1.08fc576811f8bp+62, 0x1.521d194ea43a3p+8, INIT_U128( 0x0000000000000000, 0x423f15da047e2d52 ) },
+ { 0x1.5c2e1ea2b85c4p+63, 0x1.bbf1e79d77e3dp-836, INIT_U128( 0x0000000000000000, 0xae170f515c2e2000 ) },
+ { 0x1.3a1d0742743a1p+63, 0x1.849ecbad093dap-836, INIT_U128( 0x0000000000000000, 0x9d0e83a13a1d0800 ) },
+ { 0x1.ac698c2758d32p+63, 0x1.7a316edaf462ep-836, INIT_U128( 0x0000000000000000, 0xd634c613ac699000 ) },
+ { 0x1.8542412f0a848p+63, 0x1.a53fa9cd4a7f5p-836, INIT_U128( 0x0000000000000000, 0xc2a1209785424000 ) },
+ { 0x1.f526fb77ea4ep+64, 0x1.170327882e065p-848, INIT_U128( 0x0000000000000001, 0xf526fb77ea4e0000 ) },
+ { 0x1.acca54155994ap+64, 0x1.4c44fdb4988ap-848, INIT_U128( 0x0000000000000001, 0xacca54155994a000 ) },
+ { 0x1.b47ed77768fdbp+64, 0x1.e6883245cd107p-848, INIT_U128( 0x0000000000000001, 0xb47ed77768fdb000 ) },
+ { 0x1.bf32165b7e643p+64, 0x1.7da93100fb526p-848, INIT_U128( 0x0000000000000001, 0xbf32165b7e643000 ) },
+ { 0x1.c6aa72a58d54fp+65, 0x1.700d04ece01ap-810, INIT_U128( 0x0000000000000003, 0x8d54e54b1aa9e000 ) },
+ { 0x1.651ffffcca4p+65, 0x1.b6e3b8e56dc77p-810, INIT_U128( 0x0000000000000002, 0xca3ffff994800000 ) },
+ { 0x1.f59076c9eb20fp+65, 0x1.41622b1082c46p-810, INIT_U128( 0x0000000000000003, 0xeb20ed93d641e000 ) },
+ { 0x1.2362224a46c44p+65, 0x1.0fe4f0321fc9ep-810, INIT_U128( 0x0000000000000002, 0x46c444948d888000 ) },
+ { 0x1.96643d852cc88p+66, 0x1.5aadaff0b55b6p-820, INIT_U128( 0x0000000000000006, 0x5990f614b3220000 ) },
+ { 0x1.38a95f0e7152cp+66, 0x1.8432d89b0865bp-820, INIT_U128( 0x0000000000000004, 0xe2a57c39c54b0000 ) },
+ { 0x1.b674a85b6ce95p+66, 0x1.3adbee1a75b7ep-820, INIT_U128( 0x0000000000000006, 0xd9d2a16db3a54000 ) },
+ { 0x1.81b2bc3303658p+66, 0x1.0e771c4e1cee4p-820, INIT_U128( 0x0000000000000006, 0x06caf0cc0d960000 ) },
+ { 0x1.017e066002fc1p+67, 0x1.69eb9d80d3d74p-860, INIT_U128( 0x0000000000000008, 0x0bf0330017e08000 ) },
+ { 0x1.b75b9b136eb74p+67, 0x1.ddf2ec69bbe5ep-860, INIT_U128( 0x000000000000000d, 0xbadcd89b75ba0000 ) },
+ { 0x1.71432fe4e2866p+67, 0x1.cbea0a3797d41p-860, INIT_U128( 0x000000000000000b, 0x8a197f2714330000 ) },
+ { 0x1.65e3ce88cbc7ap+67, 0x1.dd466e4dba8cep-860, INIT_U128( 0x000000000000000b, 0x2f1e74465e3d0000 ) },
+ { 0x1.d76842dfaed09p+68, 0x1.d4739f6ba8e74p-740, INIT_U128( 0x000000000000001d, 0x76842dfaed090000 ) },
+ { 0x1.9180cb312301ap+68, 0x1.5961b442b2c36p-740, INIT_U128( 0x0000000000000019, 0x180cb312301a0000 ) },
+ { 0x1.5ea7abd8bd4f6p+68, 0x1.0afd825415fbp-740, INIT_U128( 0x0000000000000015, 0xea7abd8bd4f60000 ) },
+ { 0x1.bcf6493f79ec9p+68, 0x1.39f6643a73eccp-740, INIT_U128( 0x000000000000001b, 0xcf6493f79ec90000 ) },
+ { 0x1.6c264bbad84cap+69, 0x1.3d2b92de7a572p-358, INIT_U128( 0x000000000000002d, 0x84c9775b09940000 ) },
+ { 0x1.13b3e09a2767cp+69, 0x1.a3ead92f47d5bp-358, INIT_U128( 0x0000000000000022, 0x767c1344ecf80000 ) },
+ { 0x1.8518219d0a304p+69, 0x1.c9a99edf93534p-358, INIT_U128( 0x0000000000000030, 0xa30433a146080000 ) },
+ { 0x1.afa032e75f406p+69, 0x1.76f3e70cede7dp-358, INIT_U128( 0x0000000000000035, 0xf4065cebe80c0000 ) },
+ { 0x1.1aa2f5343545ep+70, 0x1.cd612ccd9ac25p-491, INIT_U128( 0x0000000000000046, 0xa8bd4d0d51780000 ) },
+ { 0x1.2c8c2e1a59186p+70, 0x1.53ac1260a7582p-491, INIT_U128( 0x000000000000004b, 0x230b869646180000 ) },
+ { 0x1.b92d16ef725a3p+70, 0x1.05faddde0bf5cp-491, INIT_U128( 0x000000000000006e, 0x4b45bbdc968c0000 ) },
+ { 0x1.9fc802a33f9p+70, 0x1.203a627a4074cp-491, INIT_U128( 0x0000000000000067, 0xf200a8cfe4000000 ) },
+ { 0x1.240746b6480e9p+71, 0x1.78c39518f1872p-676, INIT_U128( 0x0000000000000092, 0x03a35b2407480000 ) },
+ { 0x1.863a24750c744p+71, 0x1.96d2b31d2da56p-676, INIT_U128( 0x00000000000000c3, 0x1d123a863a200000 ) },
+ { 0x1.597fbe8ab2ff8p+71, 0x1.93afb023275f6p-676, INIT_U128( 0x00000000000000ac, 0xbfdf45597fc00000 ) },
+ { 0x1.e1080a67c2102p+71, 0x1.b5c9f2a36b93ep-676, INIT_U128( 0x00000000000000f0, 0x840533e108100000 ) },
+ { 0x1.5c1897a6b8313p+72, 0x1.e08b1a6fc1164p-272, INIT_U128( 0x000000000000015c, 0x1897a6b831300000 ) },
+ { 0x1.9ba232cf37446p+72, 0x1.5f66bf90becd8p-272, INIT_U128( 0x000000000000019b, 0xa232cf3744600000 ) },
+ { 0x1.595f744cb2beep+72, 0x1.f7a95a67ef52cp-272, INIT_U128( 0x0000000000000159, 0x5f744cb2bee00000 ) },
+ { 0x1.a763ae594ec76p+72, 0x1.c295524f852aap-272, INIT_U128( 0x00000000000001a7, 0x63ae594ec7600000 ) },
+ { 0x1.06eca6c40dd95p+73, 0x1.f918431ff2309p-572, INIT_U128( 0x000000000000020d, 0xd94d881bb2a00000 ) },
+ { 0x1.4f9fc82a9f3f9p+73, 0x1.257089f24ae11p-572, INIT_U128( 0x000000000000029f, 0x3f90553e7f200000 ) },
+ { 0x1.0fa3bdc41f478p+73, 0x1.1ca9162039523p-572, INIT_U128( 0x000000000000021f, 0x477b883e8f000000 ) },
+ { 0x1.be3be7ef7c77dp+73, 0x1.ae73d50d5ce7bp-572, INIT_U128( 0x000000000000037c, 0x77cfdef8efa00000 ) },
+ { 0x1.da6d4389b4da8p+74, 0x1.1806570a300cbp-230, INIT_U128( 0x0000000000000769, 0xb50e26d36a000000 ) },
+ { 0x1.55276624aa4edp+74, 0x1.004fb390009f6p-230, INIT_U128( 0x0000000000000554, 0x9d9892a93b400000 ) },
+ { 0x1.aeab3c995d568p+74, 0x1.08d9156011b22p-230, INIT_U128( 0x00000000000006ba, 0xacf265755a000000 ) },
+ { 0x1.a281549f4502ap+74, 0x1.cb98cbdf9731ap-230, INIT_U128( 0x000000000000068a, 0x05527d140a800000 ) },
+ { 0x1.35dae4746bb5cp+75, 0x1.492edd3c925dcp-684, INIT_U128( 0x00000000000009ae, 0xd723a35dae000000 ) },
+ { 0x1.e6b8db83cd71cp+75, 0x1.e8282f8fd0506p-684, INIT_U128( 0x0000000000000f35, 0xc6dc1e6b8e000000 ) },
+ { 0x1.17587f082eb1p+75, 0x1.45ebb9f28bd77p-684, INIT_U128( 0x00000000000008ba, 0xc3f8417588000000 ) },
+ { 0x1.957ac7292af59p+75, 0x1.35b408566b681p-684, INIT_U128( 0x0000000000000cab, 0xd6394957ac800000 ) },
+ { 0x1.6e0e0850dc1c1p+76, 0x1.9e623e393cc48p-1002, INIT_U128( 0x00000000000016e0, 0xe0850dc1c1000000 ) },
+ { 0x1.90fee6ff21fddp+76, 0x1.7ceca2caf9d94p-1002, INIT_U128( 0x000000000000190f, 0xee6ff21fdd000000 ) },
+ { 0x1.5798708eaf30ep+76, 0x1.d3322f4fa6646p-1002, INIT_U128( 0x0000000000001579, 0x8708eaf30e000000 ) },
+ { 0x1.c2ef5f4185decp+76, 0x1.96ad4d692d5aap-1002, INIT_U128( 0x0000000000001c2e, 0xf5f4185dec000000 ) },
+ { 0x1.ae14b81f5c297p+77, 0x1.062f208c0c5e4p-169, INIT_U128( 0x00000000000035c2, 0x9703eb852e000000 ) },
+ { 0x1.1f2ef58a3e5dep+77, 0x1.97a029192f405p-169, INIT_U128( 0x00000000000023e5, 0xdeb147cbbc000000 ) },
+ { 0x1.74861d64e90c4p+77, 0x1.fb289c69f6513p-169, INIT_U128( 0x0000000000002e90, 0xc3ac9d2188000000 ) },
+ { 0x1.11782bc422f06p+77, 0x1.fe294db5fc529p-169, INIT_U128( 0x000000000000222f, 0x0578845e0c000000 ) },
+ { 0x1.3af34bd275e6ap+78, 0x1.ba66054574cc1p-910, INIT_U128( 0x0000000000004ebc, 0xd2f49d79a8000000 ) },
+ { 0x1.0708e3fc0e11cp+78, 0x1.09ae142c135c2p-910, INIT_U128( 0x00000000000041c2, 0x38ff038470000000 ) },
+ { 0x1.c313a69786275p+78, 0x1.fc165a27f82ccp-910, INIT_U128( 0x00000000000070c4, 0xe9a5e189d4000000 ) },
+ { 0x1.990c9ad532193p+78, 0x1.072499060e493p-910, INIT_U128( 0x0000000000006643, 0x26b54c864c000000 ) },
+ { 0x1.dd2363c1ba46cp+79, 0x1.d163c99ba2c79p-815, INIT_U128( 0x000000000000ee91, 0xb1e0dd2360000000 ) },
+ { 0x1.b0ae4ad1615c9p+79, 0x1.8f2f90f91e5f2p-815, INIT_U128( 0x000000000000d857, 0x2568b0ae48000000 ) },
+ { 0x1.9a26bbb7344d8p+79, 0x1.ed90d6d9db21bp-815, INIT_U128( 0x000000000000cd13, 0x5ddb9a26c0000000 ) },
+ { 0x1.71ec17ace3d83p+79, 0x1.ec2b79cfd856fp-815, INIT_U128( 0x000000000000b8f6, 0x0bd671ec18000000 ) },
+ { 0x1.689f9cb2d13f4p+80, 0x1.adfbd9175bf7bp-935, INIT_U128( 0x000000000001689f, 0x9cb2d13f40000000 ) },
+ { 0x1.cde2888d9bc51p+80, 0x1.0d3598f01a6b3p-935, INIT_U128( 0x000000000001cde2, 0x888d9bc510000000 ) },
+ { 0x1.6866c948d0cd9p+80, 0x1.0d9da3cc1b3b4p-935, INIT_U128( 0x0000000000016866, 0xc948d0cd90000000 ) },
+ { 0x1.eee79cbdddcf3p+80, 0x1.a60bf9374c17fp-935, INIT_U128( 0x000000000001eee7, 0x9cbdddcf30000000 ) },
+ { 0x1.3a27b29c744f6p+81, 0x1.1270039224ep-231, INIT_U128( 0x000000000002744f, 0x6538e89ec0000000 ) },
+ { 0x1.608a6c38c114ep+81, 0x1.a6ff1b154dfe4p-231, INIT_U128( 0x000000000002c114, 0xd8718229c0000000 ) },
+ { 0x1.b8ddf2c971bbep+81, 0x1.7a6c452cf4d88p-231, INIT_U128( 0x00000000000371bb, 0xe592e377c0000000 ) },
+ { 0x1.34056f04680aep+81, 0x1.3aa39ba075474p-231, INIT_U128( 0x000000000002680a, 0xde08d015c0000000 ) },
+ { 0x1.df36567dbe6cbp+82, 0x1.948aa54b29155p-104, INIT_U128( 0x0000000000077cd9, 0x59f6f9b2c0000000 ) },
+ { 0x1.00c5bf20018b8p+82, 0x1.0354f44e06a9ep-104, INIT_U128( 0x0000000000040316, 0xfc80062e00000000 ) },
+ { 0x1.5a6d471ab4da9p+82, 0x1.ea755ca5d4eabp-104, INIT_U128( 0x00000000000569b5, 0x1c6ad36a40000000 ) },
+ { 0x1.58acff6eb15ap+82, 0x1.f6c3b1b9ed876p-104, INIT_U128( 0x00000000000562b3, 0xfdbac56800000000 ) },
+ { 0x1.9288c20b25118p+83, 0x1.477be5208ef7cp-445, INIT_U128( 0x00000000000c9446, 0x1059288c00000000 ) },
+ { 0x1.3556fa5c6aaep+83, 0x1.f200a591e4014p-445, INIT_U128( 0x000000000009aab7, 0xd2e3557000000000 ) },
+ { 0x1.88dec0dd11bd8p+83, 0x1.a1ceac19439d6p-445, INIT_U128( 0x00000000000c46f6, 0x06e88dec00000000 ) },
+ { 0x1.603498e4c0693p+83, 0x1.94ccf0d52999ep-445, INIT_U128( 0x00000000000b01a4, 0xc726034980000000 ) },
+ { 0x1.1dfbb7a43bf77p+84, 0x1.d7dd8bdbafbb2p-926, INIT_U128( 0x000000000011dfbb, 0x7a43bf7700000000 ) },
+ { 0x1.5f5d18b8beba3p+84, 0x1.ac1b923558372p-926, INIT_U128( 0x000000000015f5d1, 0x8b8beba300000000 ) },
+ { 0x1.8b32b85d16657p+84, 0x1.37ae11cc6f5c2p-926, INIT_U128( 0x000000000018b32b, 0x85d1665700000000 ) },
+ { 0x1.506f56eca0debp+84, 0x1.185445da30a88p-926, INIT_U128( 0x00000000001506f5, 0x6eca0deb00000000 ) },
+ { 0x1.506cf3dea0d9ep+85, 0x1.2e68e2945cd1cp-635, INIT_U128( 0x00000000002a0d9e, 0x7bd41b3c00000000 ) },
+ { 0x1.99ef268733de5p+85, 0x1.2ce0960e59c13p-635, INIT_U128( 0x0000000000333de4, 0xd0e67bca00000000 ) },
+ { 0x1.d46cd273a8d9ap+85, 0x1.fb0bae61f6176p-635, INIT_U128( 0x00000000003a8d9a, 0x4e751b3400000000 ) },
+ { 0x1.31deaa8263bd6p+85, 0x1.8a752b4514ea6p-635, INIT_U128( 0x0000000000263bd5, 0x504c77ac00000000 ) },
+ { 0x1.95956f032b2aep+86, 0x1.ddd18753bba31p-535, INIT_U128( 0x000000000065655b, 0xc0cacab800000000 ) },
+ { 0x1.db4b6705b696dp+86, 0x1.fc438061f887p-535, INIT_U128( 0x000000000076d2d9, 0xc16da5b400000000 ) },
+ { 0x1.42c9320885926p+86, 0x1.9258f3ab24b1ep-535, INIT_U128( 0x000000000050b24c, 0x8221649800000000 ) },
+ { 0x1.08ca2a0e11946p+86, 0x1.1c860974390c1p-535, INIT_U128( 0x000000000042328a, 0x8384651800000000 ) },
+ { 0x1.ddf27f51bbe5p+87, 0x1.a776e8c94eeddp-479, INIT_U128( 0x0000000000eef93f, 0xa8ddf28000000000 ) },
+ { 0x1.3f5b6af47eb6ep+87, 0x1.cf47dd9d9e8fcp-479, INIT_U128( 0x00000000009fadb5, 0x7a3f5b7000000000 ) },
+ { 0x1.4b9d6480973acp+87, 0x1.c249100d84922p-479, INIT_U128( 0x0000000000a5ceb2, 0x404b9d6000000000 ) },
+ { 0x1.eea053a5dd40bp+87, 0x1.26e6f8d24dcdfp-479, INIT_U128( 0x0000000000f75029, 0xd2eea05800000000 ) },
+ { 0x1.4e0a84329c15p+88, 0x1.b969043772d2p-931, INIT_U128( 0x00000000014e0a84, 0x329c150000000000 ) },
+ { 0x1.20fcf75c41f9fp+88, 0x1.a487f5bf490ffp-931, INIT_U128( 0x000000000120fcf7, 0x5c41f9f000000000 ) },
+ { 0x1.0937a468126f4p+88, 0x1.dd15685bba2adp-931, INIT_U128( 0x00000000010937a4, 0x68126f4000000000 ) },
+ { 0x1.3a1b94d674372p+88, 0x1.0e98a7441d315p-931, INIT_U128( 0x00000000013a1b94, 0xd674372000000000 ) },
+ { 0x1.b9b702f1736ep+89, 0x1.afdf8f8b5fbf2p-758, INIT_U128( 0x0000000003736e05, 0xe2e6dc0000000000 ) },
+ { 0x1.f93973b7f272fp+89, 0x1.77696130eed2cp-758, INIT_U128( 0x0000000003f272e7, 0x6fe4e5e000000000 ) },
+ { 0x1.85595b3b0ab2cp+89, 0x1.4c1c459298388p-758, INIT_U128( 0x00000000030ab2b6, 0x7615658000000000 ) },
+ { 0x1.89e4ed0b13c9ep+89, 0x1.4c88ddd89911cp-758, INIT_U128( 0x000000000313c9da, 0x162793c000000000 ) },
+ { 0x1.6d0dfe6ada1cp+90, 0x1.0873b16610e76p+20, INIT_U128( 0x0000000005b437f9, 0xab6870000010873b ) },
+ { 0x1.403e37e4807c7p+90, 0x1.630feeecc61fep+20, INIT_U128( 0x000000000500f8df, 0x9201f1c0001630fe ) },
+ { 0x1.1d3cdade3a79cp+90, 0x1.ecceb30bd99d7p+20, INIT_U128( 0x000000000474f36b, 0x78e9e700001ecceb ) },
+ { 0x1.f50698adea0d3p+90, 0x1.4ed5f3749dabep+20, INIT_U128( 0x0000000007d41a62, 0xb7a834c00014ed5f ) },
+ { 0x1.d869b87fb0d37p+91, 0x1.53d108a0a7a21p-525, INIT_U128( 0x000000000ec34dc3, 0xfd869b8000000000 ) },
+ { 0x1.cd078fb39a0f2p+91, 0x1.228b56084516bp-525, INIT_U128( 0x000000000e683c7d, 0x9cd0790000000000 ) },
+ { 0x1.c67dbd798cfb7p+91, 0x1.65e1ed28cbc3ep-525, INIT_U128( 0x000000000e33edeb, 0xcc67db8000000000 ) },
+ { 0x1.c41a2ed388346p+91, 0x1.4799717a8f32ep-525, INIT_U128( 0x000000000e20d176, 0x9c41a30000000000 ) },
+ { 0x1.db416739b682dp+92, 0x1.fea650affd4cap-706, INIT_U128( 0x000000001db41673, 0x9b682d0000000000 ) },
+ { 0x1.872189f10e431p+92, 0x1.e1de445fc3bc8p-706, INIT_U128( 0x000000001872189f, 0x10e4310000000000 ) },
+ { 0x1.d2ad0fd1a55a2p+92, 0x1.0a06ac7e140d6p-706, INIT_U128( 0x000000001d2ad0fd, 0x1a55a20000000000 ) },
+ { 0x1.2535c3a84a6b8p+92, 0x1.65205312ca40ap-706, INIT_U128( 0x0000000012535c3a, 0x84a6b80000000000 ) },
+ { 0x1.dd518ce9baa31p+93, 0x1.b123211362464p-663, INIT_U128( 0x000000003baa319d, 0x3754620000000000 ) },
+ { 0x1.9a89da733513bp+93, 0x1.8c0a0b2b18142p-663, INIT_U128( 0x0000000033513b4e, 0x66a2760000000000 ) },
+ { 0x1.01fc693203f8dp+93, 0x1.81040a6d02081p-663, INIT_U128( 0x00000000203f8d26, 0x407f1a0000000000 ) },
+ { 0x1.1d9ae72e3b35dp+93, 0x1.fb816ce9f702dp-663, INIT_U128( 0x0000000023b35ce5, 0xc766ba0000000000 ) },
+ { 0x1.1b8311c037062p+94, 0x1.3b413a6c76828p-946, INIT_U128( 0x0000000046e0c470, 0x0dc1880000000000 ) },
+ { 0x1.e7c1239fcf825p+94, 0x1.e89cbe61d1398p-946, INIT_U128( 0x0000000079f048e7, 0xf3e0940000000000 ) },
+ { 0x1.3ba2c92677459p+94, 0x1.4c19bb4098338p-946, INIT_U128( 0x000000004ee8b249, 0x9dd1640000000000 ) },
+ { 0x1.e81787a3d02f1p+94, 0x1.21981a6a43304p-946, INIT_U128( 0x000000007a05e1e8, 0xf40bc40000000000 ) },
+ { 0x1.e18ca9a3c3195p+95, 0x1.d2ce473ba59c9p-353, INIT_U128( 0x00000000f0c654d1, 0xe18ca80000000000 ) },
+ { 0x1.ec1a5457d834ap+95, 0x1.673af5f4ce75ep-353, INIT_U128( 0x00000000f60d2a2b, 0xec1a500000000000 ) },
+ { 0x1.3d4fcc727a9fap+95, 0x1.d577142daaee2p-353, INIT_U128( 0x000000009ea7e639, 0x3d4fd00000000000 ) },
+ { 0x1.6b318358d663p+95, 0x1.d96b9445b2d72p-353, INIT_U128( 0x00000000b598c1ac, 0x6b31800000000000 ) },
+ { 0x1.f8fedfa1f1fdcp+96, 0x1.6e54dd28dca9cp-828, INIT_U128( 0x00000001f8fedfa1, 0xf1fdc00000000000 ) },
+ { 0x1.4b5ec85896bd9p+96, 0x1.e4251105c84a2p-828, INIT_U128( 0x000000014b5ec858, 0x96bd900000000000 ) },
+ { 0x1.bc8f0397791ep+96, 0x1.b514998d6a293p-828, INIT_U128( 0x00000001bc8f0397, 0x791e000000000000 ) },
+ { 0x1.056a2dfe0ad46p+96, 0x1.c98d1a15931a3p-828, INIT_U128( 0x00000001056a2dfe, 0x0ad4600000000000 ) },
+ { 0x1.21192da842326p+97, 0x1.64dbdea4c9b7cp-314, INIT_U128( 0x0000000242325b50, 0x8464c00000000000 ) },
+ { 0x1.95c269f12b84dp+97, 0x1.31bfb62e637f7p-314, INIT_U128( 0x000000032b84d3e2, 0x5709a00000000000 ) },
+ { 0x1.f4a37e69e947p+97, 0x1.2c5cc8d658b99p-314, INIT_U128( 0x00000003e946fcd3, 0xd28e000000000000 ) },
+ { 0x1.73c765e6e78ecp+97, 0x1.34b3a3f469674p-314, INIT_U128( 0x00000002e78ecbcd, 0xcf1d800000000000 ) },
+ { 0x1.cafa773f95f4fp+98, 0x1.28d3338851a66p-207, INIT_U128( 0x000000072be9dcfe, 0x57d3c00000000000 ) },
+ { 0x1.7b7b6aa4f6f6ep+98, 0x1.2c99252259324p-207, INIT_U128( 0x00000005ededaa93, 0xdbdb800000000000 ) },
+ { 0x1.8c39a15918734p+98, 0x1.cdcd60b79b9acp-207, INIT_U128( 0x0000000630e68564, 0x61cd000000000000 ) },
+ { 0x1.da220eb5b4442p+98, 0x1.cd0b52b19a16bp-207, INIT_U128( 0x0000000768883ad6, 0xd110800000000000 ) },
+ { 0x1.0f34e6fa1e69dp+99, 0x1.596be5d4b2d7cp-575, INIT_U128( 0x0000000879a737d0, 0xf34e800000000000 ) },
+ { 0x1.5318af1aa6316p+99, 0x1.b2d7a70f65af5p-575, INIT_U128( 0x0000000a98c578d5, 0x318b000000000000 ) },
+ { 0x1.2f3f14005e7e2p+99, 0x1.bf1a11977e342p-575, INIT_U128( 0x0000000979f8a002, 0xf3f1000000000000 ) },
+ { 0x1.c95da71792bb5p+99, 0x1.b673d5896ce7bp-575, INIT_U128( 0x0000000e4aed38bc, 0x95da800000000000 ) },
+ { 0x1.fdead1dffbd5ap+100, 0x1.5a750c74b4ea2p-189, INIT_U128( 0x0000001fdead1dff, 0xbd5a000000000000 ) },
+ { 0x1.fe8116bbfd023p+100, 0x1.c0314d4580629p-189, INIT_U128( 0x0000001fe8116bbf, 0xd023000000000000 ) },
+ { 0x1.9177917922ef2p+100, 0x1.b5d94c0f6bb2ap-189, INIT_U128( 0x0000001917791792, 0x2ef2000000000000 ) },
+ { 0x1.39ab1bf273564p+100, 0x1.4de96f889bd2ep-189, INIT_U128( 0x000000139ab1bf27, 0x3564000000000000 ) },
+ { 0x1.52e21a8aa5c44p+101, 0x0.0000075bfbb25p-1022, INIT_U128( 0x0000002a5c435154, 0xb888000000000000 ) },
+ { 0x1.c362c16186c58p+101, 0x0.00000417370ap-1022, INIT_U128( 0x000000386c582c30, 0xd8b0000000000000 ) },
+ { 0x1.dcbb50a5b976ap+101, 0x0.000005dcb4b01p-1022, INIT_U128( 0x0000003b976a14b7, 0x2ed4000000000000 ) },
+ { 0x1.fae77febf5cfp+101, 0x0.00000567e1492p-1022, INIT_U128( 0x0000003f5ceffd7e, 0xb9e0000000000000 ) },
+ { 0x1.b94feaf3729fdp+102, 0x1.eb191b6bd6324p-32, INIT_U128( 0x0000006e53fabcdc, 0xa7f4000000000000 ) },
+ { 0x1.ffcd483fff9a9p+102, 0x1.f6c951e5ed92ap-32, INIT_U128( 0x0000007ff3520fff, 0xe6a4000000000000 ) },
+ { 0x1.f4a75991e94ebp+102, 0x1.5d81e52ebb03cp-32, INIT_U128( 0x0000007d29d6647a, 0x53ac000000000000 ) },
+ { 0x1.d9014a81b202ap+102, 0x1.1d1a5c4c3a34cp-32, INIT_U128( 0x000000764052a06c, 0x80a8000000000000 ) },
+ { 0x1.d33430cda6686p+103, 0x1.58855d10b10acp-383, INIT_U128( 0x000000e99a1866d3, 0x3430000000000000 ) },
+ { 0x1.5e801048bd002p+103, 0x1.54a52a72a94a6p-383, INIT_U128( 0x000000af4008245e, 0x8010000000000000 ) },
+ { 0x1.590a254ab2144p+103, 0x1.0307881c060f1p-383, INIT_U128( 0x000000ac8512a559, 0x0a20000000000000 ) },
+ { 0x1.6dfaecf0dbf5ep+103, 0x1.54a4b130a9496p-383, INIT_U128( 0x000000b6fd76786d, 0xfaf0000000000000 ) },
+ { 0x1.011eb1b0023d6p+104, 0x1.39df71da73beep-20, INIT_U128( 0x000001011eb1b002, 0x3d60000000000000 ) },
+ { 0x1.5ee2142ebdc42p+104, 0x1.43553d9086aa8p-20, INIT_U128( 0x0000015ee2142ebd, 0xc420000000000000 ) },
+ { 0x1.100502e4200ap+104, 0x1.534d9720a69b3p-20, INIT_U128( 0x000001100502e420, 0x0a00000000000000 ) },
+ { 0x1.2aefc5ac55df8p+104, 0x1.f553d14beaa7ap-20, INIT_U128( 0x0000012aefc5ac55, 0xdf80000000000000 ) },
+ { 0x1.d0559891a0ab3p+105, 0x1.87b2239d0f644p-316, INIT_U128( 0x000003a0ab312341, 0x5660000000000000 ) },
+ { 0x1.0929084e12521p+105, 0x1.e345fe55c68cp-316, INIT_U128( 0x0000021252109c24, 0xa420000000000000 ) },
+ { 0x1.70c26be4e184ep+105, 0x1.7a6011c6f4c02p-316, INIT_U128( 0x000002e184d7c9c3, 0x09c0000000000000 ) },
+ { 0x1.8c345d471868cp+105, 0x1.b4a5d903694bbp-316, INIT_U128( 0x0000031868ba8e30, 0xd180000000000000 ) },
+ { 0x1.66bf48cecd7e9p+106, 0x1.d926e3a9b24dcp-461, INIT_U128( 0x0000059afd233b35, 0xfa40000000000000 ) },
+ { 0x1.caf9648595f2cp+106, 0x1.3edd8e587dbb2p-461, INIT_U128( 0x0000072be5921657, 0xcb00000000000000 ) },
+ { 0x1.0ff9c5341ff38p+106, 0x1.5ecf4954bd9e9p-461, INIT_U128( 0x0000043fe714d07f, 0xce00000000000000 ) },
+ { 0x1.010bbf3602178p+106, 0x1.90183dfb20308p-461, INIT_U128( 0x000004042efcd808, 0x5e00000000000000 ) },
+ { 0x1.90f1198321e23p+107, 0x1.18ec849e31d9p-508, INIT_U128( 0x00000c8788cc190f, 0x1180000000000000 ) },
+ { 0x1.88876447110ecp+107, 0x1.3dbc4a967b78ap-508, INIT_U128( 0x00000c443b223888, 0x7600000000000000 ) },
+ { 0x1.e955d221d2abap+107, 0x1.1f1f0f983e3e2p-508, INIT_U128( 0x00000f4aae910e95, 0x5d00000000000000 ) },
+ { 0x1.79931aacf3264p+107, 0x1.5c6d47c2b8da9p-508, INIT_U128( 0x00000bcc98d56799, 0x3200000000000000 ) },
+ { 0x1.49a28e4c93452p+108, 0x1.0819b1c610336p-949, INIT_U128( 0x0000149a28e4c934, 0x5200000000000000 ) },
+ { 0x1.b61387f56c271p+108, 0x1.fda021a7fb404p-949, INIT_U128( 0x00001b61387f56c2, 0x7100000000000000 ) },
+ { 0x1.8364b71506c97p+108, 0x1.972f04852e5ep-949, INIT_U128( 0x000018364b71506c, 0x9700000000000000 ) },
+ { 0x1.a902b10952056p+108, 0x1.aee9cfcf5dd3ap-949, INIT_U128( 0x00001a902b109520, 0x5600000000000000 ) },
+ { 0x1.d96f1c29b2de4p+109, 0x1.8415bcdf082b8p-695, INIT_U128( 0x00003b2de385365b, 0xc800000000000000 ) },
+ { 0x1.e8dfe3f9d1bfcp+109, 0x1.c31bb2ed86377p-695, INIT_U128( 0x00003d1bfc7f3a37, 0xf800000000000000 ) },
+ { 0x1.3a0cc61474199p+109, 0x1.06f2795a0de4fp-695, INIT_U128( 0x0000274198c28e83, 0x3200000000000000 ) },
+ { 0x1.1f3e5f4a3e7ccp+109, 0x1.d7cc8b85af992p-695, INIT_U128( 0x000023e7cbe947cf, 0x9800000000000000 ) },
+ { 0x1.dc6af865b8d5fp+110, 0x1.b5d225136ba45p-22, INIT_U128( 0x0000771abe196e35, 0x7c00000000000000 ) },
+ { 0x1.4ca9fcc69954p+110, 0x1.eaa024f7d5404p-22, INIT_U128( 0x0000532a7f31a655, 0x0000000000000000 ) },
+ { 0x1.414c72988298ep+110, 0x1.a488753b4910fp-22, INIT_U128( 0x000050531ca620a6, 0x3800000000000000 ) },
+ { 0x1.dc6b39dbb8d67p+110, 0x1.068d04580d1ap-22, INIT_U128( 0x0000771ace76ee35, 0x9c00000000000000 ) },
+ { 0x1.74e50e90e9ca2p+111, 0x1.3f289f007e514p-487, INIT_U128( 0x0000ba72874874e5, 0x1000000000000000 ) },
+ { 0x1.5f0a2632be145p+111, 0x1.f790c8d9ef219p-487, INIT_U128( 0x0000af8513195f0a, 0x2800000000000000 ) },
+ { 0x1.d422bf03a8458p+111, 0x1.fbacd695f759bp-487, INIT_U128( 0x0000ea115f81d422, 0xc000000000000000 ) },
+ { 0x1.d9b5cefdb36bap+111, 0x1.c968397b92d07p-487, INIT_U128( 0x0000ecdae77ed9b5, 0xd000000000000000 ) },
+ { 0x1.f3e78001e7cfp+112, 0x1.4b4970649692ep-744, INIT_U128( 0x0001f3e78001e7cf, 0x0000000000000000 ) },
+ { 0x1.17c200042f84p+112, 0x1.8d8e8a711b1d1p-744, INIT_U128( 0x000117c200042f84, 0x0000000000000000 ) },
+ { 0x1.0fe4fde81fcap+112, 0x1.256616f84acc3p-744, INIT_U128( 0x00010fe4fde81fca, 0x0000000000000000 ) },
+ { 0x1.f2773487e4ee6p+112, 0x1.075dd87a0ebbbp-744, INIT_U128( 0x0001f2773487e4ee, 0x6000000000000000 ) },
+ { 0x1.7f2646f4fe4c9p+113, 0x1.bde0f7d57bc1fp-552, INIT_U128( 0x0002fe4c8de9fc99, 0x2000000000000000 ) },
+ { 0x1.552a71c4aa54ep+113, 0x1.5f75cb84beebap-552, INIT_U128( 0x0002aa54e38954a9, 0xc000000000000000 ) },
+ { 0x1.016211fe02c42p+113, 0x1.755a3ebeeab48p-552, INIT_U128( 0x000202c423fc0588, 0x4000000000000000 ) },
+ { 0x1.2da4a1405b494p+113, 0x1.c7b5a5b78f6b5p-552, INIT_U128( 0x00025b494280b692, 0x8000000000000000 ) },
+ { 0x1.454dcac88a9bap+114, 0x1.39e2f64073c5fp-541, INIT_U128( 0x000515372b222a6e, 0x8000000000000000 ) },
+ { 0x1.f5769ad1eaed4p+114, 0x1.273e2b1a4e7c6p-541, INIT_U128( 0x0007d5da6b47abb5, 0x0000000000000000 ) },
+ { 0x1.52bf04cca57ep+114, 0x1.2d92613e5b24cp-541, INIT_U128( 0x00054afc133295f8, 0x0000000000000000 ) },
+ { 0x1.1b84a7fc37095p+114, 0x1.8b3360311666cp-541, INIT_U128( 0x00046e129ff0dc25, 0x4000000000000000 ) },
+ { 0x1.82ef082b05de1p+115, 0x1.5205f44aa40bep-62, INIT_U128( 0x000c177841582ef0, 0x8000000000000000 ) },
+ { 0x1.bafcbdf175f98p+115, 0x1.a9ea203153d44p-62, INIT_U128( 0x000dd7e5ef8bafcc, 0x0000000000000000 ) },
+ { 0x1.64b56bd8c96aep+115, 0x1.42c3a3da85874p-62, INIT_U128( 0x000b25ab5ec64b57, 0x0000000000000000 ) },
+ { 0x1.55c9b3b6ab936p+115, 0x1.48f9d11a91f3ap-62, INIT_U128( 0x000aae4d9db55c9b, 0x0000000000000000 ) },
+ { 0x1.5321473ca6429p+116, 0x1.181db1c6303b6p-92, INIT_U128( 0x0015321473ca6429, 0x0000000000000000 ) },
+ { 0x1.cdc20a3f9b841p+116, 0x1.50077ebca00fp-92, INIT_U128( 0x001cdc20a3f9b841, 0x0000000000000000 ) },
+ { 0x1.92fee4f925fdcp+116, 0x1.028f8f16051f2p-92, INIT_U128( 0x00192fee4f925fdc, 0x0000000000000000 ) },
+ { 0x1.1bab55e43756ap+116, 0x1.40855e9c810acp-92, INIT_U128( 0x0011bab55e43756a, 0x0000000000000000 ) },
+ { 0x1.db43e365b687dp+117, 0x1.41baf8828375fp-732, INIT_U128( 0x003b687c6cb6d0fa, 0x0000000000000000 ) },
+ { 0x1.a552a1674aa54p+117, 0x1.baa689f9754d1p-732, INIT_U128( 0x0034aa542ce954a8, 0x0000000000000000 ) },
+ { 0x1.fe56ea4dfcadep+117, 0x1.5684197ead083p-732, INIT_U128( 0x003fcadd49bf95bc, 0x0000000000000000 ) },
+ { 0x1.6c9b7a08d937p+117, 0x1.2337f65a466ffp-732, INIT_U128( 0x002d936f411b26e0, 0x0000000000000000 ) },
+ { 0x1.076705de0ecep+118, 0x1.98bce7cb3179dp-844, INIT_U128( 0x0041d9c17783b380, 0x0000000000000000 ) },
+ { 0x1.9b22f3533645ep+118, 0x1.74f31c32e9e64p-844, INIT_U128( 0x0066c8bcd4cd9178, 0x0000000000000000 ) },
+ { 0x1.c1d136e583a27p+118, 0x1.767b76ceecf6fp-844, INIT_U128( 0x0070744db960e89c, 0x0000000000000000 ) },
+ { 0x1.c885934b910b3p+118, 0x1.cd65a24d9acb4p-844, INIT_U128( 0x00722164d2e442cc, 0x0000000000000000 ) },
+ { 0x1.fb2c8085f659p+119, 0x1.4485cbfc890bap-269, INIT_U128( 0x00fd964042fb2c80, 0x0000000000000000 ) },
+ { 0x1.78eebbd0f1dd8p+119, 0x1.373c5ea66e78cp-269, INIT_U128( 0x00bc775de878eec0, 0x0000000000000000 ) },
+ { 0x1.1cbf9dfc397f4p+119, 0x1.3a787bfa74f1p-269, INIT_U128( 0x008e5fcefe1cbfa0, 0x0000000000000000 ) },
+ { 0x1.0b37d4fc166fap+119, 0x1.3ec2f1ca7d85ep-269, INIT_U128( 0x00859bea7e0b37d0, 0x0000000000000000 ) },
+ { 0x1.f7d41d9befa83p+119, 0x1.737e360ee6fc7p+45, INIT_U128( 0x00fbea0ecdf7d418, 0x00002e6fc6c1dcdf ) },
+ { 0x1.5f9adea4bf35cp+119, 0x1.f2a34d73e5469p+45, INIT_U128( 0x00afcd6f525f9ae0, 0x00003e5469ae7ca8 ) },
+ { 0x1.1625a2842c4b4p+119, 0x1.dffa968fbff53p+45, INIT_U128( 0x008b12d1421625a0, 0x00003bff52d1f7fe ) },
+ { 0x1.77b9ea5cef73ep+119, 0x1.03d8c57207b18p+45, INIT_U128( 0x00bbdcf52e77b9f0, 0x0000207b18ae40f6 ) },
+ { 0x1.80c91d3d01924p+119, 0x1.dc2e84abb85dp+45, INIT_U128( 0x00c0648e9e80c920, 0x00003b85d095770b ) },
+ { 0x1.a13e2abb427c5p+119, 0x1.be5baad37cb75p+45, INIT_U128( 0x00d09f155da13e28, 0x000037cb755a6f96 ) },
+ { 0x1.3d0a39607a147p+119, 0x1.5d047beeba09p+45, INIT_U128( 0x009e851cb03d0a38, 0x00002ba08f7dd741 ) },
+ { 0x1.e914f2edd229fp+119, 0x1.a87d6b5150faep+45, INIT_U128( 0x00f48a7976e914f8, 0x0000350fad6a2a1f ) },
+ { 0x1.1bfba16037f74p+119, 0x1.f1667f23e2cdp+45, INIT_U128( 0x008dfdd0b01bfba0, 0x00003e2ccfe47c59 ) },
+ { 0x1.e409cc97c8139p+119, 0x1.760ec180ec1d8p+45, INIT_U128( 0x00f204e64be409c8, 0x00002ec1d8301d83 ) },
+ { 0x1.56095810ac12bp+119, 0x1.fd72c88bfae59p+45, INIT_U128( 0x00ab04ac08560958, 0x00003fae59117f5c ) },
+ { 0x1.014b8dfe02972p+119, 0x1.5051ec7ca0a3ep+45, INIT_U128( 0x0080a5c6ff014b90, 0x00002a0a3d8f9414 ) },
+ { 0x1.2c8071285900ep+119, 0x1.2df331a65be66p+45, INIT_U128( 0x00964038942c8070, 0x000025be6634cb7c ) },
+ { 0x1.ec4edc7bd89dbp+119, 0x1.5689910cad132p+45, INIT_U128( 0x00f6276e3dec4ed8, 0x00002ad1322195a2 ) },
+ { 0x1.acab22af59564p+120, 0x1.4302395486047p-789, INIT_U128( 0x01acab22af595640, 0x0000000000000000 ) },
+ { 0x1.6d777264daeeep+120, 0x1.a94793a7528f2p-789, INIT_U128( 0x016d777264daeee0, 0x0000000000000000 ) },
+ { 0x1.179807f22f301p+120, 0x1.f73f61cbee7ecp-789, INIT_U128( 0x01179807f22f3010, 0x0000000000000000 ) },
+ { 0x1.2306ea1a460dep+120, 0x1.7f322c14fe646p-789, INIT_U128( 0x012306ea1a460de0, 0x0000000000000000 ) },
+ { 0x1.4b89313897126p+121, 0x1.24f0cf5649e1ap-97, INIT_U128( 0x02971262712e24c0, 0x0000000000000000 ) },
+ { 0x1.977d3ba32efa8p+121, 0x1.8d5ae3291ab5cp-97, INIT_U128( 0x032efa77465df500, 0x0000000000000000 ) },
+ { 0x1.4951cf1a92a3ap+121, 0x1.ff3e4eaffe7cap-97, INIT_U128( 0x0292a39e35254740, 0x0000000000000000 ) },
+ { 0x1.6487918ac90f2p+121, 0x1.8e5a3b671cb48p-97, INIT_U128( 0x02c90f2315921e40, 0x0000000000000000 ) },
+ { 0x1.a71b395f4e367p+122, 0x1.4851ea7e90a3ep-824, INIT_U128( 0x069c6ce57d38d9c0, 0x0000000000000000 ) },
+ { 0x1.58097738b012fp+122, 0x1.a4e92d4749d26p-824, INIT_U128( 0x056025dce2c04bc0, 0x0000000000000000 ) },
+ { 0x1.431d2f4a863a6p+122, 0x1.ff84386fff087p-824, INIT_U128( 0x050c74bd2a18e980, 0x0000000000000000 ) },
+ { 0x1.9f1393ad3e272p+122, 0x1.d7c0a6ddaf815p-824, INIT_U128( 0x067c4e4eb4f89c80, 0x0000000000000000 ) },
+ { 0x1.8983ab7913076p+123, 0x1.fa01bdc9f4037p-825, INIT_U128( 0x0c4c1d5bc8983b00, 0x0000000000000000 ) },
+ { 0x1.f3551e67e6aa4p+123, 0x1.029c51f00538ap-825, INIT_U128( 0x0f9aa8f33f355200, 0x0000000000000000 ) },
+ { 0x1.a9da0d1d53b42p+123, 0x1.b5c718d36b8e3p-825, INIT_U128( 0x0d4ed068ea9da100, 0x0000000000000000 ) },
+ { 0x1.95c79e2b2b8f4p+123, 0x1.384e4c32709cap-825, INIT_U128( 0x0cae3cf1595c7a00, 0x0000000000000000 ) },
+ { 0x1.73af4650e75e9p+124, 0x1.ec4b7265d896fp-92, INIT_U128( 0x173af4650e75e900, 0x0000000000000000 ) },
+ { 0x1.5e15a3a0bc2b4p+124, 0x1.2ff859825ff0bp-92, INIT_U128( 0x15e15a3a0bc2b400, 0x0000000000000000 ) },
+ { 0x1.4dbe24a69b7c4p+124, 0x1.f5b685e5eb6d1p-92, INIT_U128( 0x14dbe24a69b7c400, 0x0000000000000000 ) },
+ { 0x1.cd65ac439acb6p+124, 0x1.164d910a2c9b2p-92, INIT_U128( 0x1cd65ac439acb600, 0x0000000000000000 ) },
+ { 0x1.f5bbadd5eb775p+125, 0x1.b16aeddb62d5ep-83, INIT_U128( 0x3eb775babd6eea00, 0x0000000000000000 ) },
+ { 0x1.b66841396cd08p+125, 0x1.f9957d69f32afp-83, INIT_U128( 0x36cd08272d9a1000, 0x0000000000000000 ) },
+ { 0x1.05be50760b7cap+125, 0x1.f9ebf8ddf3d7fp-83, INIT_U128( 0x20b7ca0ec16f9400, 0x0000000000000000 ) },
+ { 0x1.51312262a2624p+125, 0x1.11c69084238d2p-83, INIT_U128( 0x2a26244c544c4800, 0x0000000000000000 ) },
+ { 0x1.30eab12c61d56p+126, 0x1.f1e0e851e3c1dp-773, INIT_U128( 0x4c3aac4b18755800, 0x0000000000000000 ) },
+ { 0x1.ac34bcf158698p+126, 0x1.a55b126f4ab62p-773, INIT_U128( 0x6b0d2f3c561a6000, 0x0000000000000000 ) },
+ { 0x1.02246a040448ep+126, 0x1.61a83652c3507p-773, INIT_U128( 0x40891a8101123800, 0x0000000000000000 ) },
+ { 0x1.ae881f955d104p+126, 0x1.c694aaa18d296p-773, INIT_U128( 0x6ba207e557441000, 0x0000000000000000 ) },
+ { 0x1.08016b641002ep+127, 0x1.23a890d047512p-406, INIT_U128( 0x8400b5b208017000, 0x0000000000000000 ) },
+ { 0x1.3d90e7327b21dp+127, 0x1.0aa664c0154ccp-406, INIT_U128( 0x9ec873993d90e800, 0x0000000000000000 ) },
+ { 0x1.ff931617ff263p+127, 0x1.47d5e2a08fabcp-406, INIT_U128( 0xffc98b0bff931800, 0x0000000000000000 ) },
+ { 0x1.f565d1dfeacbap+127, 0x1.827bc0c304f78p-406, INIT_U128( 0xfab2e8eff565d000, 0x0000000000000000 ) },
+ { 0x1.fe1985fbfc33p+128, 0x1.a6e724cd4dce4p-1021, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.54709ed6a8e14p+128, 0x1.74a32d1ce9466p-1021, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.a8407dcf5081p+128, 0x1.ffb065f3ff60cp-1021, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.7a1cfcf2f43ap+130, 0x1.84bb5ea30976cp-548, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.6bddaae8d7bb6p+194, 0x1.de64c609bcc99p-754, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.5c6c29d4b8d85p+146, 0x1.0644f6d60c89fp-345, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.c6ce8bcf8d9d2p+158, 0x1.443b2e7088766p-26, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.747f6aa0e8feep+168, 0x1.fe663ae9fccc8p-143, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.26ee550a4ddcap+173, 0x1.951f708f2a3eep-45, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.3ecfe0ea7d9fcp+189, 0x1.9cb53593396a7p-619, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.9d394a313a729p+190, 0x1.9ecfff853dap-150, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.244a568a4894bp+241, 0x1.e23f42d7c47e9p-956, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.b564bb276ac98p+398, 0x1.7af8d1ccf5f1ap+215, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.ee06b389dc0d7p+468, 0x1.b54fa74f6a9f5p+322, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.ac0045bd58009p+588, 0x1.ba99775b7532fp-365, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.692078cad240fp+661, 0x1.bc4a88a978951p+356, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.be1e09dd7c3c1p+765, 0x1.428bc5dc85178p-848, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.5f5554c4beaaap+853, 0x1.a9e23bdd53c48p-807, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.748e96ace91d3p+993, 0x1.ab54ab4b56a96p-22, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { 0x1.0629e7380c53dp+1023, 0x1.c0b4b15581696p+323, INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ) },
+ { INFINITY, 0x1.21bff4bc437fep-333, ((__uint128_t) 0xffffffffffffffff << 64) | 0xffffffffffffffff },
+ { INFINITY, 0x1.47e9a0228fd34p-333, ((__uint128_t) 0xffffffffffffffff << 64) | 0xffffffffffffffff }
+};
+
+static const int numTests = sizeof(testList) / sizeof(struct testCase);
+
diff --git a/test/builtins/Unit/ppc/floatditf_test.c b/test/builtins/Unit/ppc/floatditf_test.c
index 5c08ade4b..e9b945834 100644
--- a/test/builtins/Unit/ppc/floatditf_test.c
+++ b/test/builtins/Unit/ppc/floatditf_test.c
@@ -1,7 +1,8 @@
-// REQUIRES: powerpc-registered-target
-// RUN: %clang_builtins %s -o %t && %run %t
+// REQUIRES: target-is-powerpc64le
+// RUN: %clang_builtins %s %librt -o %t && %run %t
#include <stdint.h>
#include <stdio.h>
+#include "int_lib.h"
COMPILER_RT_ABI long double __floatditf(int64_t);
diff --git a/test/builtins/Unit/ppc/floattitf_test.c b/test/builtins/Unit/ppc/floattitf_test.c
new file mode 100644
index 000000000..e89e5d946
--- /dev/null
+++ b/test/builtins/Unit/ppc/floattitf_test.c
@@ -0,0 +1,59 @@
+// REQUIRES: target-is-powerpc64le
+// RUN: %clang_builtins %s %librt -o %t && %run %t
+
+/*
+ * Test case execution for: long double __floattitf (__int128_t)
+ * Conversion from 128 bit integer to long double (IBM double-double).
+ */
+
+#include <stdint.h>
+#include <stdio.h>
+
+#include "floattitf_test.h"
+
+/* The long double representation, with the high and low portions of
+ * the long double, and the corresponding bit patterns of each double. */
+typedef union {
+ long double ld;
+ double d[2]; /* [0] is the high double, [1] is the low double. */
+ unsigned long long ull[2]; /* High and low doubles as 64-bit integers. */
+} ldUnion;
+
+long double __floattitf(__int128_t);
+
+int main(int argc, char *argv[]) {
+ /* Necessary long double and 128 bit integer declarations used to
+ * compare computed and expected high and low portions of the
+ * IBM double-double. */
+ ldUnion expectedLongDouble;
+ ldUnion computedLongDouble;
+ __int128_t result128;
+
+ for (int i = 0; i < numTests; ++i) {
+ /* Set the expected high and low values of the long double,
+ * and the 128 bit integer input to be converted. */
+ expectedLongDouble.d[0] = tests[i].hi;
+ expectedLongDouble.d[1] = tests[i].lo;
+ result128 = tests[i].input128;
+
+ /* Get the computed long double from the int128->long double conversion
+ * and check for errors between high and low portions. */
+ computedLongDouble.ld = __floattitf(result128);
+
+ if ((computedLongDouble.d[0] != expectedLongDouble.d[0]) ||
+ (computedLongDouble.d[1] != expectedLongDouble.d[1])) {
+
+ printf("Error on __floattitf( 0x%016llx 0x%016llx ):\n",
+ (long long)(tests[i].input128 >> 64),
+ (long long)tests[i].input128);
+ printf("\tExpected value - %La = ( %a, %a )\n", expectedLongDouble.ld,
+ expectedLongDouble.d[0], expectedLongDouble.d[1]);
+ printf("\tComputed value - %La = ( %a, %a )\n\n", computedLongDouble.ld,
+ computedLongDouble.d[0], computedLongDouble.d[1]);
+
+ return 1;
+ }
+ }
+
+ return 0;
+}
diff --git a/test/builtins/Unit/ppc/floattitf_test.h b/test/builtins/Unit/ppc/floattitf_test.h
new file mode 100644
index 000000000..1da8a6b52
--- /dev/null
+++ b/test/builtins/Unit/ppc/floattitf_test.h
@@ -0,0 +1,197 @@
+/*
+* Test case inputs for: long double __floattitf (__int128_t)
+* Conversion from 128 bit integer to long double (IBM double-double).
+*/
+
+#define INIT_U128(HI, LO) (((__uint128_t) (HI) << 64) | (LO))
+
+struct testCase {
+ __int128_t input128;
+ double hi;
+ double lo;
+};
+
+struct testCase tests[] = {
+ { INIT_U128( 0x0000000000000000, 0x0000000000000000 ), 0x0p+0, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0x0000000000000001 ), 0x1p+0, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0x1000000000000000 ), 0x1p+60, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0xffffffffffffffff ), 0x1p+64, -0x1p+0 },
+ { INIT_U128( 0x0000000000000000, 0x7fffffffffffffff ), 0x1p+63, -0x1p+0 },
+ { INIT_U128( 0x0000000000000001, 0x0000000000000000 ), 0x1p+64, 0x0p+0 },
+ { INIT_U128( 0x0000000000000001, 0x0000000000000001 ), 0x1p+64, 0x1p+0 },
+ { INIT_U128( 0x0000000000000001, 0x7fffffffffffffff ), 0x1.8p+64, -0x1p+0 },
+ { INIT_U128( 0x0000000000000001, 0x1000000000000000 ), 0x1.1p+64, 0x0p+0 },
+ { INIT_U128( 0x0000000000000001, 0xffffffffffffffff ), 0x1p+65, -0x1p+0 },
+ { INIT_U128( 0x7fffffffffffffff, 0x0000000000000000 ), 0x1p+127, -0x1p+64 },
+ { INIT_U128( 0x7fffffffffffffff, 0x0000000000000001 ), 0x1p+127, -0x1p+64 },
+ { INIT_U128( 0x7fffffffffffffff, 0x7fffffffffffffff ), 0x1p+127, -0x1p+63 },
+ { INIT_U128( 0x7fffffffffffffff, 0x1000000000000000 ), 0x1p+127, -0x1.ep+63 },
+ { INIT_U128( 0x7fffffffffffffff, 0xffffffffffffffff ), 0x1p+127, -0x1p+0 },
+ { INIT_U128( 0x1000000000000000, 0x0000000000000000 ), 0x1p+124, 0x0p+0 },
+ { INIT_U128( 0x1000000000000000, 0x0000000000000001 ), 0x1p+124, 0x1p+0 },
+ { INIT_U128( 0x1000000000000000, 0x7fffffffffffffff ), 0x1p+124, 0x1p+63 },
+ { INIT_U128( 0x1000000000000000, 0x1000000000000000 ), 0x1p+124, 0x1p+60 },
+ { INIT_U128( 0x1000000000000000, 0xffffffffffffffff ), 0x1p+124, 0x1p+64 },
+ { INIT_U128( 0xffffffffffffffff, 0x0000000000000000 ), -0x1p+64, 0x0p+0 },
+ { INIT_U128( 0xffffffffffffffff, 0x0000000000000001 ), -0x1p+64, 0x1p+0 },
+ { INIT_U128( 0xffffffffffffffff, 0x7fffffffffffffff ), -0x1p+63, -0x1p+0 },
+ { INIT_U128( 0xffffffffffffffff, 0x1000000000000000 ), -0x1.ep+63, 0x0p+0 },
+ { INIT_U128( 0xffffffffffffffff, 0xffffffffffffffff ), -0x1p+0, 0x0p+0 },
+ { INIT_U128( 0x0000000000000061, 0x0000000000000061 ), 0x1.84p+70, 0x1.84p+6 },
+ { INIT_U128( 0x0000000000000000, 0x0000000000000057 ), 0x1.5cp+6, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0xffffffffffffff9e ), 0x1p+64, -0x1.88p+6 },
+ { INIT_U128( 0x0000000000000000, 0x0000000000000062 ), 0x1.88p+6, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0x0000000000000403 ), 0x1.00cp+10, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0xfffffffffffffbfc ), 0x1.fffffffffffffp+63, 0x1.fep+9 },
+ { INIT_U128( 0x0000000000000000, 0x000000000000040a ), 0x1.028p+10, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0x000000000000040c ), 0x1.03p+10, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0x000000000000041a ), 0x1.068p+10, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0x0000000000000510 ), 0x1.44p+10, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0x0000000000000518 ), 0x1.46p+10, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0xfffffffffffffae7 ), 0x1.fffffffffffffp+63, 0x1.738p+9 },
+ { INIT_U128( 0x0000000000000000, 0x0000000000000602 ), 0x1.808p+10, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0xfffffffffffff9fd ), 0x1.fffffffffffffp+63, 0x1.fdp+8 },
+ { INIT_U128( 0x0000000000000000, 0x0000000000002090 ), 0x1.048p+13, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0xffffffffffffdbdb ), 0x1.ffffffffffffbp+63, 0x1.ed8p+9 },
+ { INIT_U128( 0x0000000000000000, 0x0000000000002430 ), 0x1.218p+13, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0x0000000000020202 ), 0x1.0101p+17, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0xfffffffffffdeef7 ), 0x1.fffffffffffbep+63, -0x1.09p+8 },
+ { INIT_U128( 0x0000000000000000, 0x0000000000032004 ), 0x1.9002p+17, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0xfffffffffffcdffb ), 0x1.fffffffffff9cp+63, -0x1.4p+2 },
+ { INIT_U128( 0x0000000000000000, 0x0000000000032040 ), 0x1.902p+17, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0xffffffffffbfdfbb ), 0x1.ffffffffff7fcp+63, -0x1.14p+6 },
+ { INIT_U128( 0x0000000000000000, 0x0000000000402088 ), 0x1.00822p+22, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0x0000000080080088 ), 0x1.0010011p+31, 0x0p+0 },
+ { INIT_U128( 0xffffffff7ff7ff77, 0xffffffff7ff7ff77 ), -0x1.0010011p+95, -0x1.00100112p+31 },
+ { INIT_U128( 0x0000000000000000, 0x0000000850000008 ), 0x1.0a000001p+35, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0x0000002000000448 ), 0x1.000000224p+37, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0xffffffdfff7dbfff ), 0x1.ffffffbffefb8p+63, -0x1p+0 },
+ { INIT_U128( 0x0000004002001100, 0x0000004002001100 ), 0x1.00080044p+102, 0x1.00080044p+38 },
+ { INIT_U128( 0x000008020000000c, 0x000008020000000c ), 0x1.00400000018p+107, 0x1.00400000018p+43 },
+ { INIT_U128( 0x0000000000000000, 0xfffff7fdfffffff3 ), 0x1.ffffeffcp+63, -0x1.ap+3 },
+ { INIT_U128( 0x0000000000000000, 0x0000800000000824 ), 0x1.000000001048p+47, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0xfffdffffff7ffcff ), 0x1.fffbffffffp+63, -0x1.808p+9 },
+ { INIT_U128( 0x0000000000000000, 0x4002040010000000 ), 0x1.000810004p+62, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0xbffdfbffefffffff ), 0x1.7ffbf7ffep+63, -0x1p+0 },
+ { INIT_U128( 0x0000000000000000, 0x8000000000000000 ), 0x1p+63, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0xfffffffff418c5c1 ), 0x1.ffffffffe8319p+63, -0x1.1f8p+9 },
+ { INIT_U128( 0x000000000000000f, 0xffffffffffffffff ), 0x1p+68, -0x1p+0 },
+ { INIT_U128( 0x00000000000000ff, 0xffffffffffffffff ), 0x1p+72, -0x1p+0 },
+ { INIT_U128( 0x0000000000000fff, 0xffffffffffffffff ), 0x1p+76, -0x1p+0 },
+ { INIT_U128( 0x000000000000ffff, 0xffffffffffffffff ), 0x1p+80, -0x1p+0 },
+ { INIT_U128( 0x00000000000fffff, 0xffffffffffffffff ), 0x1p+84, -0x1p+0 },
+ { INIT_U128( 0x0000000000ffffff, 0xffffffffffffffff ), 0x1p+88, -0x1p+0 },
+ { INIT_U128( 0x000000000fffffff, 0xffffffffffffffff ), 0x1p+92, -0x1p+0 },
+ { INIT_U128( 0x00000000ffffffff, 0xffffffffffffffff ), 0x1p+96, -0x1p+0 },
+ { INIT_U128( 0x0000000fffffffff, 0xffffffffffffffff ), 0x1p+100, -0x1p+0 },
+ { INIT_U128( 0x000000ffffffffff, 0xffffffffffffffff ), 0x1p+104, -0x1p+0 },
+ { INIT_U128( 0x00000fffffffffff, 0xffffffffffffffff ), 0x1p+108, -0x1p+0 },
+ { INIT_U128( 0x0000ffffffffffff, 0xffffffffffffffff ), 0x1p+112, -0x1p+0 },
+ { INIT_U128( 0x000fffffffffffff, 0xffffffffffffffff ), 0x1p+116, -0x1p+0 },
+ { INIT_U128( 0x00ffffffffffffff, 0xffffffffffffffff ), 0x1p+120, -0x1p+0 },
+ { INIT_U128( 0x0fffffffffffffff, 0xffffffffffffffff ), 0x1p+124, -0x1p+0 },
+ { INIT_U128( 0x1000000000000000, 0x0000000000000000 ), 0x1p+124, 0x0p+0 },
+ { INIT_U128( 0x1000000000000000, 0x0000000000000011 ), 0x1p+124, 0x1.1p+4 },
+ { INIT_U128( 0x1000000000000000, 0x0000000000000111 ), 0x1p+124, 0x1.11p+8 },
+ { INIT_U128( 0x1000000000000000, 0x0000000000001111 ), 0x1p+124, 0x1.111p+12 },
+ { INIT_U128( 0x1000000000000000, 0x0000000000011111 ), 0x1p+124, 0x1.1111p+16 },
+ { INIT_U128( 0x1000000000000000, 0x0000000000111111 ), 0x1p+124, 0x1.11111p+20 },
+ { INIT_U128( 0x1000000000000000, 0x0000000001111111 ), 0x1p+124, 0x1.111111p+24 },
+ { INIT_U128( 0x1000000000000000, 0x0000000011111111 ), 0x1p+124, 0x1.1111111p+28 },
+ { INIT_U128( 0x1000000000000000, 0x0000000111111111 ), 0x1p+124, 0x1.11111111p+32 },
+ { INIT_U128( 0x1000000000000000, 0x0000001111111111 ), 0x1p+124, 0x1.111111111p+36 },
+ { INIT_U128( 0x1000000000000000, 0x0000011111111111 ), 0x1p+124, 0x1.1111111111p+40 },
+ { INIT_U128( 0x1000000000000000, 0x0000111111111111 ), 0x1p+124, 0x1.11111111111p+44 },
+ { INIT_U128( 0x1000000000000000, 0x0001111111111111 ), 0x1p+124, 0x1.111111111111p+48 },
+ { INIT_U128( 0x1000000000000000, 0x0011111111111111 ), 0x1p+124, 0x1.1111111111111p+52 },
+ { INIT_U128( 0x1000000000000000, 0x0111111111111111 ), 0x1p+124, 0x1.11111111111111p+56 },
+ { INIT_U128( 0x1000000000000000, 0x1111111111111111 ), 0x1p+124, 0x1.111111111111111p+60 },
+ { INIT_U128( 0xffffffffffffffff, 0xf000000000000000 ), -0x1p+60, 0x0p+0 },
+ { INIT_U128( 0xffffffffffffffff, 0xff00000000000000 ), -0x1p+56, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0xb7ffffff77ffffff ), 0x1.6ffffffefp+63, -0x1p+0 },
+ { INIT_U128( 0xb7ffffff3fffffff, 0xb7ffffff3fffffff ), -0x1.20000003p+126, -0x1.20000003p+62 },
+ { INIT_U128( 0xb7fffffefffffffe, 0xb7fffffefffffffe ), -0x1.20000004p+126, -0x1.48000001p+64 },
+ { INIT_U128( 0xb7fffffeffffefff, 0xb7fffffeffffefff ), -0x1.2000000400004p+126, -0x1.2000000400004p+62 },
+ { INIT_U128( 0x0000040000000000, 0x0000000000000000 ), 0x1p+106, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0x000000003ff00000 ), 0x1.ff8p+29, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0xb7fbffffffffdfff ), 0x1.6ff7ffffffffcp+63, -0x1p+0 },
+ { INIT_U128( 0x0000000000000000, 0x4804000000010000 ), 0x1.201000000004p+62, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0x4900000000001000 ), 0x1.2400000000004p+62, 0x0p+0 },
+ { INIT_U128( 0x0000000000000000, 0xb6ffffffffffefff ), 0x1.6dffffffffffep+63, -0x1p+0 },
+ { INIT_U128( 0x0000000000000000, 0x4900000000008000 ), 0x1.240000000002p+62, 0x0p+0 },
+ { INIT_U128( 0xb6ffffffffff7fff, 0xb6ffffffffff7fff ), -0x1.240000000002p+126, -0x1.240000000002p+62 },
+ { INIT_U128( 0x4900000000040000, 0x4900000000040000 ), 0x1.24000000001p+126, 0x1.24000000001p+62 },
+ { INIT_U128( 0xb6fffffffffbffff, 0xb6fffffffffbffff ), -0x1.24000000001p+126, -0x1.24000000001p+62 },
+ { INIT_U128( 0x4900000000200000, 0x4900000000200000 ), 0x1.24000000008p+126, 0x1.24000000008p+62 },
+ { INIT_U128( 0xb6ffffffffdfffff, 0xb6ffffffffdfffff ), -0x1.24000000008p+126, -0x1.24000000008p+62 },
+ { INIT_U128( 0x4900000000800000, 0x4900000000800000 ), 0x1.2400000002p+126, 0x1.2400000002p+62 },
+ { INIT_U128( 0xb6ffffffff7fffff, 0xb6ffffffff7fffff ), -0x1.2400000002p+126, -0x1.2400000002p+62 },
+ { INIT_U128( 0x4900000008000000, 0x4900000008000000 ), 0x1.240000002p+126, 0x1.240000002p+62 },
+ { INIT_U128( 0xb6fffffff7ffffff, 0xb6fffffff7ffffff ), -0x1.240000002p+126, -0x1.240000002p+62 },
+ { INIT_U128( 0x4900000040000000, 0x4900000040000000 ), 0x1.24000001p+126, 0x1.24000001p+62 },
+ { INIT_U128( 0xb6ffffffbfffffff, 0xb6ffffffbfffffff ), -0x1.24000001p+126, -0x1.24000001p+62 },
+ { INIT_U128( 0x4900000080000000, 0x4900000080000000 ), 0x1.24000002p+126, 0x1.24000002p+62 },
+ { INIT_U128( 0xb6ffffff7fffffff, 0xb6ffffff7fffffff ), -0x1.24000002p+126, -0x1.24000002p+62 },
+ { INIT_U128( 0x4900000400000000, 0x4900000400000000 ), 0x1.2400001p+126, 0x1.2400001p+62 },
+ { INIT_U128( 0xb6fffffbffffffff, 0xb6fffffbffffffff ), -0x1.2400001p+126, -0x1.2400001p+62 },
+ { INIT_U128( 0x4900001000000000, 0x4900001000000000 ), 0x1.2400004p+126, 0x1.2400004p+62 },
+ { INIT_U128( 0xb6ffffefffffffff, 0xb6ffffefffffffff ), -0x1.2400004p+126, -0x1.2400004p+62 },
+ { INIT_U128( 0x4900004000000000, 0x4900004000000000 ), 0x1.240001p+126, 0x1.240001p+62 },
+ { INIT_U128( 0xb6ffffbfffffffff, 0xb6ffffbfffffffff ), -0x1.240001p+126, -0x1.240001p+62 },
+ { INIT_U128( 0x4900040000000000, 0x4900040000000000 ), 0x1.24001p+126, 0x1.24001p+62 },
+ { INIT_U128( 0xb6fffbffffffffff, 0xb6fffbffffffffff ), -0x1.24001p+126, -0x1.24001p+62 },
+ { INIT_U128( 0x4900200000000000, 0x4900200000000000 ), 0x1.24008p+126, 0x1.24008p+62 },
+ { INIT_U128( 0xb6ffdfffffffffff, 0xb6ffdfffffffffff ), -0x1.24008p+126, -0x1.24008p+62 },
+ { INIT_U128( 0x4901000000000000, 0x4901000000000000 ), 0x1.2404p+126, 0x1.2404p+62 },
+ { INIT_U128( 0xb6feffffffffffff, 0xb6feffffffffffff ), -0x1.2404p+126, -0x1.2404p+62 },
+ { INIT_U128( 0x4910000000000000, 0x4910000000000000 ), 0x1.244p+126, 0x1.244p+62 },
+ { INIT_U128( 0xb6efffffffffffff, 0xb6efffffffffffff ), -0x1.244p+126, -0x1.244p+62 },
+ { INIT_U128( 0x4980000000000000, 0x4980000000000000 ), 0x1.26p+126, 0x1.26p+62 },
+ { INIT_U128( 0xb67fffffffffffff, 0xb67fffffffffffff ), -0x1.26p+126, -0x1.26p+62 },
+ { INIT_U128( 0x4c00000000000000, 0x4c00000000000000 ), 0x1.3p+126, 0x1.3p+62 },
+ { INIT_U128( 0xb3ffffffffffffff, 0xb3ffffffffffffff ), -0x1.3p+126, -0x1.3p+62 },
+ { INIT_U128( 0x9fffffffffffbfff, 0x9fffffffffffbfff ), -0x1.800000000001p+126, -0x1.800000000001p+62 },
+ { INIT_U128( 0x6000000000004001, 0x6000000000004001 ), 0x1.800000000001p+126, 0x1.6000000000004p+64 },
+ { INIT_U128( 0x8fffffffffffffbf, 0x8fffffffffffffbf ), -0x1.cp+126, -0x1.01cp+70 },
+ { INIT_U128( 0x7000000000000080, 0x7000000000000080 ), 0x1.cp+126, 0x1.00ep+71 },
+ { INIT_U128( 0x8fffffffffffff7f, 0x8fffffffffffff7f ), -0x1.cp+126, -0x1.00ep+71 },
+ { INIT_U128( 0x7000000000000800, 0x7000000000000800 ), 0x1.c000000000002p+126, 0x1.c000000000002p+62 },
+ { INIT_U128( 0x8ffffffffffff7ff, 0x8ffffffffffff7ff ), -0x1.c000000000002p+126, -0x1.c000000000002p+62 },
+ { INIT_U128( 0x7000000000002000, 0x7000000000002000 ), 0x1.c000000000008p+126, 0x1.c000000000008p+62 },
+ { INIT_U128( 0x8fffffffffffdfff, 0x8fffffffffffdfff ), -0x1.c000000000008p+126, -0x1.c000000000008p+62 },
+ { INIT_U128( 0x7000000000010000, 0x7000000000010000 ), 0x1.c00000000004p+126, 0x1.c00000000004p+62 },
+ { INIT_U128( 0x8ffffffffffeffff, 0x8ffffffffffeffff ), -0x1.c00000000004p+126, -0x1.c00000000004p+62 },
+ { INIT_U128( 0x7000000000040000, 0x7000000000040000 ), 0x1.c0000000001p+126, 0x1.c0000000001p+62 },
+ { INIT_U128( 0x8ffffffffffbffff, 0x8ffffffffffbffff ), -0x1.c0000000001p+126, -0x1.c0000000001p+62 },
+ { INIT_U128( 0x7000000000080000, 0x7000000000080000 ), 0x1.c0000000002p+126, 0x1.c0000000002p+62 },
+ { INIT_U128( 0x8ffffffffff7ffff, 0x8ffffffffff7ffff ), -0x1.c0000000002p+126, -0x1.c0000000002p+62 },
+ { INIT_U128( 0x7000000000800000, 0x7000000000800000 ), 0x1.c000000002p+126, 0x1.c000000002p+62 },
+ { INIT_U128( 0x8fffffffff7fffff, 0x8fffffffff7fffff ), -0x1.c000000002p+126, -0x1.c000000002p+62 },
+ { INIT_U128( 0x7000000008000000, 0x7000000008000000 ), 0x1.c00000002p+126, 0x1.c00000002p+62 },
+ { INIT_U128( 0x8ffffffff7ffffff, 0x8ffffffff7ffffff ), -0x1.c00000002p+126, -0x1.c00000002p+62 },
+ { INIT_U128( 0x7000000010000000, 0x7000000010000000 ), 0x1.c00000004p+126, 0x1.c00000004p+62 },
+ { INIT_U128( 0x8fffffffefffffff, 0x8fffffffefffffff ), -0x1.c00000004p+126, -0x1.c00000004p+62 },
+ { INIT_U128( 0x7000000100000000, 0x7000000100000000 ), 0x1.c0000004p+126, 0x1.c0000004p+62 },
+ { INIT_U128( 0x8ffffffeffffffff, 0x8ffffffeffffffff ), -0x1.c0000004p+126, -0x1.c0000004p+62 },
+ { INIT_U128( 0x7000000200000000, 0x7000000200000000 ), 0x1.c0000008p+126, 0x1.c0000008p+62 },
+ { INIT_U128( 0x8ffffffdffffffff, 0x8ffffffdffffffff ), -0x1.c0000008p+126, -0x1.c0000008p+62 },
+ { INIT_U128( 0x7000000800000000, 0x7000000800000000 ), 0x1.c000002p+126, 0x1.c000002p+62 },
+ { INIT_U128( 0x8ffffff7ffffffff, 0x8ffffff7ffffffff ), -0x1.c000002p+126, -0x1.c000002p+62 },
+ { INIT_U128( 0x7000008000000000, 0x7000008000000000 ), 0x1.c00002p+126, 0x1.c00002p+62 },
+ { INIT_U128( 0x8fffff7fffffffff, 0x8fffff7fffffffff ), -0x1.c00002p+126, -0x1.c00002p+62 },
+ { INIT_U128( 0x7000010000000000, 0x7000010000000000 ), 0x1.c00004p+126, 0x1.c00004p+62 },
+ { INIT_U128( 0x8ffffeffffffffff, 0x8ffffeffffffffff ), -0x1.c00004p+126, -0x1.c00004p+62 },
+ { INIT_U128( 0x7000080000000000, 0x7000080000000000 ), 0x1.c0002p+126, 0x1.c0002p+62 },
+ { INIT_U128( 0x8ffff7ffffffffff, 0x8ffff7ffffffffff ), -0x1.c0002p+126, -0x1.c0002p+62 },
+ { INIT_U128( 0x7000800000000000, 0x7000800000000000 ), 0x1.c002p+126, 0x1.c002p+62 },
+ { INIT_U128( 0x8fff7fffffffffff, 0x8fff7fffffffffff ), -0x1.c002p+126, -0x1.c002p+62 },
+ { INIT_U128( 0x7002000000000000, 0x7002000000000000 ), 0x1.c008p+126, 0x1.c008p+62 },
+ { INIT_U128( 0x8ffdffffffffffff, 0x8ffdffffffffffff ), -0x1.c008p+126, -0x1.c008p+62 },
+ { INIT_U128( 0x7008000000000000, 0x7008000000000000 ), 0x1.c02p+126, 0x1.c02p+62 },
+ { INIT_U128( 0x8ff7ffffffffffff, 0x8ff7ffffffffffff ), -0x1.c02p+126, -0x1.c02p+62 },
+ { INIT_U128( 0x7080000000000000, 0x7080000000000000 ), 0x1.c2p+126, 0x1.c2p+62 },
+ { INIT_U128( 0x8f7fffffffffffff, 0x8f7fffffffffffff ), -0x1.c2p+126, -0x1.c2p+62 },
+ { INIT_U128( 0x7400000000000000, 0x7400000000000000 ), 0x1.dp+126, 0x1.dp+62 }
+};
+
+static const int numTests = sizeof(tests) / sizeof(struct testCase);
diff --git a/test/builtins/Unit/ppc/floatunditf_test.c b/test/builtins/Unit/ppc/floatunditf_test.c
index 3e5012857..fc6090be1 100644
--- a/test/builtins/Unit/ppc/floatunditf_test.c
+++ b/test/builtins/Unit/ppc/floatunditf_test.c
@@ -1,7 +1,8 @@
-// REQUIRES: powerpc-registered-target
-// RUN: %clang_builtins %s -o %t && %run %t
+// REQUIRES: target-is-powerpc64le
+// RUN: %clang_builtins %s %librt -o %t && %run %t
#include <stdint.h>
#include <stdio.h>
+#include "int_lib.h"
COMPILER_RT_ABI long double __floatunditf(uint64_t);
diff --git a/test/builtins/Unit/ppc/qadd_test.c b/test/builtins/Unit/ppc/qadd_test.c
index 327fd21e8..242850fff 100644
--- a/test/builtins/Unit/ppc/qadd_test.c
+++ b/test/builtins/Unit/ppc/qadd_test.c
@@ -1,5 +1,5 @@
-// REQUIRES: powerpc-registered-target
-// RUN: %clang_builtins %s -o %t && %run %t
+// REQUIRES: target-is-powerpc64le
+// RUN: %clang_builtins %s %librt -o %t && %run %t
#include <stdio.h>
#include "DD.h"
diff --git a/test/builtins/Unit/ppc/qdiv_test.c b/test/builtins/Unit/ppc/qdiv_test.c
index 7530e428f..15990f0c3 100644
--- a/test/builtins/Unit/ppc/qdiv_test.c
+++ b/test/builtins/Unit/ppc/qdiv_test.c
@@ -1,5 +1,5 @@
-// REQUIRES: powerpc-registered-target
-// RUN: %clang_builtins %s -o %t && %run %t
+// REQUIRES: target-is-powerpc64le
+// RUN: %clang_builtins %s %librt -o %t && %run %t
#include <stdio.h>
#include "DD.h"
diff --git a/test/builtins/Unit/ppc/qmul_test.c b/test/builtins/Unit/ppc/qmul_test.c
index dbe3536f3..c8e5bb096 100644
--- a/test/builtins/Unit/ppc/qmul_test.c
+++ b/test/builtins/Unit/ppc/qmul_test.c
@@ -1,5 +1,5 @@
-// REQUIRES: powerpc-registered-target
-// RUN: %clang_builtins %s -o %t && %run %t
+// REQUIRES: target-is-powerpc64le
+// RUN: %clang_builtins %s %librt -o %t && %run %t
#include <stdio.h>
#include "DD.h"
diff --git a/test/builtins/Unit/ppc/qsub_test.c b/test/builtins/Unit/ppc/qsub_test.c
index e21224096..1e456f83a 100644
--- a/test/builtins/Unit/ppc/qsub_test.c
+++ b/test/builtins/Unit/ppc/qsub_test.c
@@ -1,5 +1,5 @@
-// REQUIRES: powerpc-registered-target
-// RUN: %clang_builtins %s -o %t && %run %t
+// REQUIRES: target-is-powerpc64le
+// RUN: %clang_builtins %s %librt -o %t && %run %t
#include <stdio.h>
#include "DD.h"
diff --git a/test/fuzzer/AlignmentAssumptionTest.cpp b/test/fuzzer/AlignmentAssumptionTest.cpp
new file mode 100644
index 000000000..be51d37e8
--- /dev/null
+++ b/test/fuzzer/AlignmentAssumptionTest.cpp
@@ -0,0 +1,27 @@
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+
+// Test for alignment assumption failure.
+
+#include <assert.h>
+#include <climits>
+#include <cstddef>
+#include <cstdint>
+#include <cstdlib>
+#include <iostream>
+
+static volatile int32_t Sink;
+
+extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
+ assert(Data);
+ if (Size > 0 && Data[0] == 'H') {
+ Sink = 1;
+ if (Size > 1 && Data[1] == 'i') {
+ Sink = 2;
+ if (Size > 2 && Data[2] == '!') {
+ __builtin_assume_aligned(Data + 1, 0x8000);
+ }
+ }
+ }
+ return 0;
+}
diff --git a/test/fuzzer/PrintUnstableStatsTest.cpp b/test/fuzzer/PrintUnstableStatsTest.cpp
deleted file mode 100644
index 2b9de88d7..000000000
--- a/test/fuzzer/PrintUnstableStatsTest.cpp
+++ /dev/null
@@ -1,69 +0,0 @@
-#include <assert.h>
-#include <cstdint>
-#include <cstdio>
-#include <cstdlib>
-
-int x = 0;
-bool skip0 = false;
-bool skip1 = false;
-bool skip2 = false;
-
-__attribute__((noinline)) void det0() { x++; }
-__attribute__((noinline)) void det1() { x++; }
-__attribute__((noinline)) void det2() { x++; }
-__attribute__((noinline)) void det3() { x++; }
-__attribute__((noinline)) void det4() { x++; }
-
-__attribute__((noinline)) void ini0() { x++; }
-__attribute__((noinline)) void ini1() { x++; }
-__attribute__((noinline)) void ini2() { x++; }
-
-__attribute__((noinline)) void t0(int a) { x += a; }
-__attribute__((noinline)) void t1() { x++; }
-__attribute__((noinline)) void t2(int a, int b) { x += a + b; }
-__attribute__((noinline)) void t3() { x++; }
-__attribute__((noinline)) void t4(int a, int b, int c) { x += a + b +c; }
-
-extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) {
- if (Size == 1 && Data[0] == 'A' && !skip0) {
- skip0 = true;
- ini0();
- }
- if (Size == 1 && Data[0] == 'B' && !skip1) {
- skip1 = true;
- ini1();
- }
- if (Size == 1 && Data[0] == 'C' && !skip2) {
- skip2 = true;
- ini2();
- }
-
- det0();
- det1();
- int a = rand();
- det2();
-
- switch (a % 5) {
- case 0:
- t0(a);
- break;
- case 1:
- t1();
- break;
- case 2:
- t2(a, a);
- break;
- case 3:
- t3();
- break;
- case 4:
- t4(a, a, a);
- break;
- default:
- assert(false);
- }
-
- det3();
- det4();
- return 0;
-}
diff --git a/test/fuzzer/fuzzer-alignment-assumption.test b/test/fuzzer/fuzzer-alignment-assumption.test
new file mode 100644
index 000000000..6db77e19c
--- /dev/null
+++ b/test/fuzzer/fuzzer-alignment-assumption.test
@@ -0,0 +1,7 @@
+RUN: rm -f %t-AlignmentAssumptionTest-Ubsan
+RUN: %cpp_compiler -fsanitize=alignment -fno-sanitize-recover=all %S/AlignmentAssumptionTest.cpp -o %t-AlignmentAssumptionTest-Ubsan
+RUN: not %run %t-AlignmentAssumptionTest-Ubsan 2>&1 | FileCheck %s
+CHECK: AlignmentAssumptionTest.cpp:22:39: runtime error: assumption of 32768 byte alignment for pointer of type 'const {{.*}} *' (aka 'const unsigned char *') failed
+CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte
+
+CHECK: Test unit written to ./crash-
diff --git a/test/fuzzer/handle-unstable.test b/test/fuzzer/handle-unstable.test
deleted file mode 100644
index d20224689..000000000
--- a/test/fuzzer/handle-unstable.test
+++ /dev/null
@@ -1,43 +0,0 @@
-# Tests -handle_unstable
-# FIXME: Disabled on Windows until symbolization works properly.
-UNSUPPORTED: windows
-
-RUN: %cpp_compiler %S/PrintUnstableStatsTest.cpp -o %t-HandleUnstableTest
-
-; Normal
-RUN: %run %t-HandleUnstableTest -print_coverage=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=NORMAL
-NORMAL-DAG: det0()
-NORMAL-DAG: det1()
-NORMAL-DAG: det2()
-NORMAL-DAG: det3()
-NORMAL-DAG: det4()
-NORMAL-DAG: ini0()
-NORMAL-DAG: ini1()
-NORMAL-DAG: ini2()
-NORMAL-DAG: t0(int)
-NORMAL-DAG: t1()
-NORMAL-DAG: t2(int, int)
-NORMAL-DAG: t3()
-NORMAL-DAG: t4(int, int, int)
-
-; MinUnstable
-RUN: %run %t-HandleUnstableTest -print_coverage=1 -handle_unstable=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=MIN
-MIN-NOT: ini0()
-MIN-NOT: ini1()
-MIN-NOT: ini2()
-MIN: det0()
-MIN: det1()
-MIN: det2()
-MIN: det3()
-MIN: det4()
-
-; ZeroUnstable
-RUN: %run %t-HandleUnstableTest -print_coverage=1 -handle_unstable=2 -runs=1 2>&1 | FileCheck %s --check-prefix=ZERO
-ZERO-NOT: ini0()
-ZERO-NOT: ini1()
-ZERO-NOT: ini2()
-ZERO: det0()
-ZERO: det1()
-ZERO: det2()
-ZERO: det3()
-ZERO: det4()
diff --git a/test/fuzzer/print_unstable_stats.test b/test/fuzzer/print_unstable_stats.test
deleted file mode 100644
index 41b279130..000000000
--- a/test/fuzzer/print_unstable_stats.test
+++ /dev/null
@@ -1,24 +0,0 @@
-# Tests -print_unstable_stats
-# Disabled on Windows because of differences symbolizing and flakiness.
-UNSUPPORTED: aarch64, windows
-
-RUN: %cpp_compiler %S/PrintUnstableStatsTest.cpp -o %t-PrintUnstableStatsTest
-
-RUN: %run %t-PrintUnstableStatsTest -print_unstable_stats=1 -runs=100000 2>&1 | FileCheck %s --check-prefix=LONG
-# We do not observe ini functions since we take the minimum hit counts, and minimum hit counts for ini is 0.
-LONG: UNSTABLE_FUNCTIONS:
-LONG-NOT: det0()
-LONG-NOT: det1()
-LONG-NOT: det2()
-LONG-NOT: det3()
-LONG-NOT: det4()
-LONG-NOT: ini0()
-LONG-NOT: ini1()
-LONG-NOT: ini2()
-LONG-DAG: t0(int)
-LONG-DAG: t1()
-LONG-DAG: t2(int, int)
-LONG-DAG: t3()
-LONG-DAG: t4(int, int, int)
-
-LONG-DAG: stat::stability_rate: 27.59
diff --git a/test/hwasan/CMakeLists.txt b/test/hwasan/CMakeLists.txt
index 972c73250..3e397ac06 100644
--- a/test/hwasan/CMakeLists.txt
+++ b/test/hwasan/CMakeLists.txt
@@ -11,6 +11,9 @@ foreach(arch ${HWASAN_TEST_ARCH})
string(TOUPPER ${arch} ARCH_UPPER_CASE)
set(CONFIG_NAME ${ARCH_UPPER_CASE})
+ # FIXME: Set this.
+ set(HWASAN_ANDROID_FILES_TO_PUSH [])
+
configure_lit_site_cfg(
${CMAKE_CURRENT_SOURCE_DIR}/lit.site.cfg.in
${CMAKE_CURRENT_BINARY_DIR}/${CONFIG_NAME}/lit.site.cfg)
diff --git a/test/hwasan/TestCases/Posix/system-allocator-fallback.cc b/test/hwasan/TestCases/Posix/system-allocator-fallback.cc
new file mode 100644
index 000000000..8678d906d
--- /dev/null
+++ b/test/hwasan/TestCases/Posix/system-allocator-fallback.cc
@@ -0,0 +1,54 @@
+// RUN: %clangxx %s -o %t -ldl
+// RUN: %clangxx_hwasan -shared %s -o %t.so -DSHARED_LIB -shared-libsan -Wl,-rpath,%compiler_rt_libdir
+// RUN: %env_hwasan_opts=disable_allocator_tagging=0 %run %t
+
+// The dynamic loader on Android O appears to have a bug where it crashes when
+// dlopening DF_1_GLOBAL libraries.
+// REQUIRES: android-28
+
+#include <stddef.h>
+
+// Test that allocations made by the system allocator can be realloc'd and freed
+// by the hwasan allocator.
+
+typedef void run_test_fn(void *(*system_malloc)(size_t size));
+
+#ifdef SHARED_LIB
+
+// Call the __sanitizer_ versions of these functions so that the test
+// doesn't require the Android dynamic loader.
+extern "C" void *__sanitizer_realloc(void *ptr, size_t size);
+extern "C" void __sanitizer_free(void *ptr);
+
+extern "C" run_test_fn run_test;
+void run_test(void *(*system_malloc)(size_t size)) {
+ void *mem = system_malloc(64);
+ mem = __sanitizer_realloc(mem, 128);
+ __sanitizer_free(mem);
+}
+
+#else
+
+#include <dlfcn.h>
+#include <stdlib.h>
+#include <string>
+
+int main(int argc, char **argv) {
+ std::string path = argv[0];
+ path += ".so";
+ void *lib = dlopen(path.c_str(), RTLD_NOW);
+ if (!lib) {
+ printf("error in dlopen(): %s\n", dlerror());
+ return 1;
+ }
+
+ auto run_test = reinterpret_cast<run_test_fn *>(dlsym(lib, "run_test"));
+ if (!run_test) {
+ printf("failed dlsym\n");
+ return 1;
+ }
+
+ run_test(malloc);
+}
+
+#endif
diff --git a/test/hwasan/TestCases/deep-recursion.c b/test/hwasan/TestCases/deep-recursion.c
index 1ac0f5b15..2fe77a7bd 100644
--- a/test/hwasan/TestCases/deep-recursion.c
+++ b/test/hwasan/TestCases/deep-recursion.c
@@ -30,25 +30,25 @@ __attribute__((noinline)) void FUNC10() { int x; USE(&x); FUNC9(); }
int main() { FUNC10(); }
-// D1: Previosly allocated frames
+// D1: Previously allocated frames
// D1: in OOB
// D1-NOT: in FUNC
// D1: Memory tags around the buggy address
-// D2: Previosly allocated frames
+// D2: Previously allocated frames
// D2: in OOB
// D2: in FUNC1
// D2-NOT: in FUNC
// D2: Memory tags around the buggy address
-// D3: Previosly allocated frames
+// D3: Previously allocated frames
// D3: in OOB
// D3: in FUNC1
// D3: in FUNC2
// D3-NOT: in FUNC
// D3: Memory tags around the buggy address
-// D5: Previosly allocated frames
+// D5: Previously allocated frames
// D5: in OOB
// D5: in FUNC1
// D5: in FUNC2
@@ -57,7 +57,7 @@ int main() { FUNC10(); }
// D5-NOT: in FUNC
// D5: Memory tags around the buggy address
-// DEFAULT: Previosly allocated frames
+// DEFAULT: Previously allocated frames
// DEFAULT: in OOB
// DEFAULT: in FUNC1
// DEFAULT: in FUNC2
diff --git a/test/hwasan/TestCases/heap-buffer-overflow.c b/test/hwasan/TestCases/heap-buffer-overflow.c
index bff39d293..9f605b320 100644
--- a/test/hwasan/TestCases/heap-buffer-overflow.c
+++ b/test/hwasan/TestCases/heap-buffer-overflow.c
@@ -43,7 +43,6 @@ int main(int argc, char **argv) {
// CHECK80-RIGHT: allocated heap chunk; size: 32 offset:
// CHECK80-RIGHT: is located 50 bytes to the right of 30-byte region
//
-// CHECKm30: allocated heap chunk; size: 32 offset: 2
// CHECKm30: is located 30 bytes to the left of 30-byte region
//
// CHECKMm30: is a large allocated heap chunk; size: 1003520 offset: -30
diff --git a/test/hwasan/TestCases/mem-intrinsics-zero-size.c b/test/hwasan/TestCases/mem-intrinsics-zero-size.c
new file mode 100644
index 000000000..bcb8e0771
--- /dev/null
+++ b/test/hwasan/TestCases/mem-intrinsics-zero-size.c
@@ -0,0 +1,10 @@
+// RUN: %clang_hwasan %s -o %t && %run %t
+
+#include <string.h>
+
+int main() {
+ char a[1];
+ memset(a, 0, 0);
+ memmove(a, a, 0);
+ memcpy(a, a, 0);
+}
diff --git a/test/hwasan/TestCases/mem-intrinsics.c b/test/hwasan/TestCases/mem-intrinsics.c
new file mode 100644
index 000000000..164bc6d93
--- /dev/null
+++ b/test/hwasan/TestCases/mem-intrinsics.c
@@ -0,0 +1,37 @@
+// RUN: %clang_hwasan %s -DTEST_NO=1 -mllvm -hwasan-instrument-mem-intrinsics -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=WRITE
+// RUN: %clang_hwasan %s -DTEST_NO=2 -mllvm -hwasan-instrument-mem-intrinsics -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=READ
+// RUN: %clang_hwasan %s -DTEST_NO=3 -mllvm -hwasan-instrument-mem-intrinsics -o %t && not %run %t 2>&1 | FileCheck %s --check-prefix=WRITE
+// RUN: %clang_hwasan %s -DTEST_NO=2 -mllvm -hwasan-instrument-mem-intrinsics -o %t && not %env_hwasan_opts=halt_on_error=0 %run %t 2>&1 | FileCheck %s --check-prefix=RECOVER
+
+// REQUIRES: stable-runtime
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+
+int main() {
+ char Q[16];
+ char P[16];
+#if TEST_NO == 1
+ memset(Q, 0, 32);
+#elif TEST_NO == 2
+ memmove(Q, Q + 16, 16);
+#elif TEST_NO == 3
+ memcpy(Q, P, 32);
+#endif
+ write(STDOUT_FILENO, "recovered\n", 10);
+ // WRITE: ERROR: HWAddressSanitizer: tag-mismatch on address
+ // WRITE: WRITE {{.*}} tags: [[PTR_TAG:..]]/[[MEM_TAG:..]] (ptr/mem)
+ // WRITE: Memory tags around the buggy address (one tag corresponds to 16 bytes):
+ // WRITE: =>{{.*}}[[MEM_TAG]]
+ // WRITE-NOT: recovered
+
+ // READ: ERROR: HWAddressSanitizer: tag-mismatch on address
+ // READ: READ {{.*}} tags: [[PTR_TAG:..]]/[[MEM_TAG:..]] (ptr/mem)
+ // READ: Memory tags around the buggy address (one tag corresponds to 16 bytes):
+ // READ: =>{{.*}}[[MEM_TAG]]
+ // READ-NOT: recovered
+
+ // RECOVER: recovered
+ return 0;
+}
diff --git a/test/hwasan/TestCases/stack-history-length.c b/test/hwasan/TestCases/stack-history-length.c
index c8583c67c..0aefd40be 100644
--- a/test/hwasan/TestCases/stack-history-length.c
+++ b/test/hwasan/TestCases/stack-history-length.c
@@ -25,12 +25,12 @@ int main(int argc, char **argv) {
OOB();
}
-// YES: Previosly allocated frames
+// YES: Previously allocated frames
// YES: OOB
// YES: FUNC
// YES: FUNC0
-// NO: Previosly allocated frames
+// NO: Previously allocated frames
// NO: OOB
// NO: FUNC
// NO-NOT: FUNC0
diff --git a/test/hwasan/TestCases/stack-uar.c b/test/hwasan/TestCases/stack-uar.c
index 0b1faf8b5..863a84017 100644
--- a/test/hwasan/TestCases/stack-uar.c
+++ b/test/hwasan/TestCases/stack-uar.c
@@ -27,7 +27,7 @@ int main() {
// CHECK: READ of size 1 at
// CHECK: #0 {{.*}} in main{{.*}}stack-uar.c:[[@LINE-2]]
// CHECK: is located in stack of thread
- // CHECK: Previosly allocated frames:
+ // CHECK: Previously allocated frames:
// CHECK: Unrelated3
// CHECK: 16 CCC
// CHECK: Unrelated2
diff --git a/test/hwasan/TestCases/use-after-free.c b/test/hwasan/TestCases/use-after-free.c
index fcdd0771c..03a1771c1 100644
--- a/test/hwasan/TestCases/use-after-free.c
+++ b/test/hwasan/TestCases/use-after-free.c
@@ -23,7 +23,7 @@ int main() {
// CHECK: [[TYPE]] of size 1 at {{.*}} tags: [[PTR_TAG:[0-9a-f][0-9a-f]]]/[[MEM_TAG:[0-9a-f][0-9a-f]]] (ptr/mem)
// CHECK: #0 {{.*}} in main {{.*}}use-after-free.c:[[@LINE-2]]
// Offset is 5 or 11 depending on left/right alignment.
- // CHECK: is a small unallocated heap chunk; size: 16 offset: {{5|11}}
+ // CHECK: is a small unallocated heap chunk; size: 32 offset: {{5|11}}
// CHECK: is located 5 bytes inside of 10-byte region
//
// CHECK: freed by thread {{.*}} here:
diff --git a/test/hwasan/lit.cfg b/test/hwasan/lit.cfg
index 3ebba51d0..66008a632 100644
--- a/test/hwasan/lit.cfg
+++ b/test/hwasan/lit.cfg
@@ -9,14 +9,18 @@ config.name = 'HWAddressSanitizer' + getattr(config, 'name_suffix', 'default')
config.test_source_root = os.path.dirname(__file__)
# Setup default compiler flags used with -fsanitize=memory option.
-clang_hwasan_cflags = ["-fsanitize=hwaddress", "-mllvm", "-hwasan-generate-tags-with-calls", config.target_cflags] + config.debug_info_flags
+clang_cflags = [config.target_cflags] + config.debug_info_flags
+clang_cxxflags = config.cxx_mode_flags + clang_cflags
+clang_hwasan_cflags = ["-fsanitize=hwaddress", "-mllvm", "-hwasan-generate-tags-with-calls"] + clang_cflags
clang_hwasan_cxxflags = config.cxx_mode_flags + clang_hwasan_cflags
def build_invocation(compile_flags):
return " " + " ".join([config.clang] + compile_flags) + " "
+config.substitutions.append( ("%clangxx ", build_invocation(clang_cxxflags)) )
config.substitutions.append( ("%clang_hwasan ", build_invocation(clang_hwasan_cflags)) )
config.substitutions.append( ("%clangxx_hwasan ", build_invocation(clang_hwasan_cxxflags)) )
+config.substitutions.append( ("%compiler_rt_libdir", config.compiler_rt_libdir) )
default_hwasan_opts_str = ':'.join(['disable_allocator_tagging=1', 'random_tags=0'] + config.default_sanitizer_opts)
if default_hwasan_opts_str:
diff --git a/test/hwasan/lit.site.cfg.in b/test/hwasan/lit.site.cfg.in
index 7453d1b74..e95ea92cd 100644
--- a/test/hwasan/lit.site.cfg.in
+++ b/test/hwasan/lit.site.cfg.in
@@ -4,6 +4,7 @@
config.name_suffix = "@HWASAN_TEST_CONFIG_SUFFIX@"
config.target_cflags = "@HWASAN_TEST_TARGET_CFLAGS@"
config.target_arch = "@HWASAN_TEST_TARGET_ARCH@"
+config.android_files_to_push = @HWASAN_ANDROID_FILES_TO_PUSH@
# Load common config for all compiler-rt lit tests.
lit_config.load_config(config, "@COMPILER_RT_BINARY_DIR@/test/lit.common.configured")
diff --git a/test/lit.common.cfg b/test/lit.common.cfg
index cdcba5fc9..f06658ff2 100644
--- a/test/lit.common.cfg
+++ b/test/lit.common.cfg
@@ -55,10 +55,11 @@ config.available_features.add(compiler_id)
if config.asan_shadow_scale != '':
config.target_cflags += " -mllvm -asan-mapping-scale=" + config.asan_shadow_scale
-# BFD linker in 64-bit android toolchains fails to find libm.so, which is a
-# transitive shared library dependency (via asan runtime).
+# BFD linker in 64-bit android toolchains fails to find libc++_shared.so, which
+# is a transitive shared library dependency (via asan runtime).
if config.android:
- config.target_cflags += " -pie -fuse-ld=gold -Wl,--enable-new-dtags"
+ # Prepend the flag so that it can be overridden.
+ config.target_cflags = "-pie -fuse-ld=gold " + config.target_cflags
config.cxx_mode_flags.append('-stdlib=libstdc++')
# Clear some environment variables that might affect Clang.
@@ -275,9 +276,14 @@ else:
config.substitutions.append( ("%darwin_min_target_with_full_runtime_arc_support", "") )
if config.android:
+ env = os.environ.copy()
+ if config.android_serial:
+ env['ANDROID_SERIAL'] = config.android_serial
+ config.environment['ANDROID_SERIAL'] = config.android_serial
+
adb = os.environ.get('ADB', 'adb')
try:
- android_api_level_str = subprocess.check_output([adb, "shell", "getprop", "ro.build.version.sdk"]).rstrip()
+ android_api_level_str = subprocess.check_output([adb, "shell", "getprop", "ro.build.version.sdk"], env=env).rstrip()
except (subprocess.CalledProcessError, OSError):
lit_config.fatal("Failed to read ro.build.version.sdk (using '%s' as adb)" % adb)
try:
@@ -286,6 +292,29 @@ if config.android:
lit_config.fatal("Failed to read ro.build.version.sdk (using '%s' as adb): got '%s'" % (adb, android_api_level_str))
if android_api_level >= 26:
config.available_features.add('android-26')
+ if android_api_level >= 28:
+ config.available_features.add('android-28')
+
+ # Prepare the device.
+ android_tmpdir = '/data/local/tmp/Output'
+ subprocess.check_call([adb, "shell", "mkdir", "-p", android_tmpdir], env=env)
+ for file in config.android_files_to_push:
+ subprocess.check_call([adb, "push", file, android_tmpdir], env=env)
+
+if config.host_os == 'Linux':
+ # detect whether we are using glibc, and which version
+ # NB: 'ldd' is just one of the tools commonly installed as part of glibc
+ ldd_ver_cmd = subprocess.Popen(['ldd', '--version'],
+ stdout=subprocess.PIPE,
+ env={'LANG': 'C'})
+ sout, _ = ldd_ver_cmd.communicate()
+ ver_line = sout.splitlines()[0]
+ if ver_line.startswith(b"ldd "):
+ from distutils.version import LooseVersion
+ ver = LooseVersion(ver_line.split()[-1].decode())
+ # 2.27 introduced some incompatibilities
+ if ver >= LooseVersion("2.27"):
+ config.available_features.add("glibc-2.27")
sancovcc_path = os.path.join(config.llvm_tools_dir, "sancov")
if os.path.exists(sancovcc_path):
@@ -342,6 +371,9 @@ if config.lto_supported:
if config.use_newpm:
config.lto_flags += ["-fexperimental-new-pass-manager"]
+if config.have_rpc_xdr_h:
+ config.available_features.add('sunrpc')
+
# Ask llvm-config about assertion mode.
try:
llvm_config_cmd = subprocess.Popen(
diff --git a/test/lit.common.configured.in b/test/lit.common.configured.in
index 63d55bfde..4994ca69b 100644
--- a/test/lit.common.configured.in
+++ b/test/lit.common.configured.in
@@ -36,6 +36,9 @@ set_default("use_thinlto", False)
set_default("use_lto", config.use_thinlto)
set_default("use_newpm", False)
set_default("android", @ANDROID_PYBOOL@)
+set_default("android_serial", "@ANDROID_SERIAL_FOR_TESTING@")
+set_default("android_files_to_push", [])
+set_default("have_rpc_xdr_h", @HAVE_RPC_XDR_H@)
config.available_features.add('target-is-%s' % config.target_arch)
if config.enable_per_target_runtime_dir:
diff --git a/test/lsan/TestCases/Linux/use_tls_dynamic.cc b/test/lsan/TestCases/Linux/use_tls_dynamic.cc
index 4d70a46f8..8093d6f0e 100644
--- a/test/lsan/TestCases/Linux/use_tls_dynamic.cc
+++ b/test/lsan/TestCases/Linux/use_tls_dynamic.cc
@@ -1,4 +1,9 @@
// Test that dynamically allocated TLS space is included in the root set.
+
+// This is known to be broken with glibc-2.27+
+// https://bugs.llvm.org/show_bug.cgi?id=37804
+// XFAIL: glibc-2.27
+
// RUN: LSAN_BASE="report_objects=1:use_stacks=0:use_registers=0:use_ld_allocations=0"
// RUN: %clangxx %s -DBUILD_DSO -fPIC -shared -o %t-so.so
// RUN: %clangxx_lsan %s -o %t
diff --git a/test/msan/Linux/sunrpc.cc b/test/msan/Linux/sunrpc.cc
index c92ad632c..edf49c2a5 100644
--- a/test/msan/Linux/sunrpc.cc
+++ b/test/msan/Linux/sunrpc.cc
@@ -1,3 +1,5 @@
+// REQUIRES: sunrpc
+
// RUN: %clangxx_msan -g -O0 -DTYPE=int -DFN=xdr_int %s -o %t && \
// RUN: %run %t 2>&1
// RUN: %clangxx_msan -g -O0 -DTYPE=int -DFN=xdr_int -DUNINIT=1 %s -o %t && \
diff --git a/test/msan/Linux/sunrpc_bytes.cc b/test/msan/Linux/sunrpc_bytes.cc
index 477637af2..7eb47e178 100644
--- a/test/msan/Linux/sunrpc_bytes.cc
+++ b/test/msan/Linux/sunrpc_bytes.cc
@@ -1,3 +1,5 @@
+// REQUIRES: sunrpc
+
// RUN: %clangxx_msan -g -O0 %s -o %t && \
// RUN: %run %t 2>&1
// RUN: %clangxx_msan -g -O0 -DUNINIT=1 %s -o %t && \
diff --git a/test/msan/Linux/sunrpc_string.cc b/test/msan/Linux/sunrpc_string.cc
index 350222f5c..723b85592 100644
--- a/test/msan/Linux/sunrpc_string.cc
+++ b/test/msan/Linux/sunrpc_string.cc
@@ -1,3 +1,5 @@
+// REQUIRES: sunrpc
+
// RUN: %clangxx_msan -g -O0 %s -o %t && \
// RUN: %run %t 2>&1
// RUN: %clangxx_msan -g -O0 -DUNINIT=1 %s -o %t && \
diff --git a/test/msan/dtls_test.c b/test/msan/dtls_test.c
index ee91be2ff..bc1fe609a 100644
--- a/test/msan/dtls_test.c
+++ b/test/msan/dtls_test.c
@@ -11,6 +11,11 @@
// Reports use-of-uninitialized-value, not analyzed
XFAIL: netbsd
+
+ // This is known to be broken with glibc-2.27+
+ // https://bugs.llvm.org/show_bug.cgi?id=37804
+ XFAIL: glibc-2.27
+
*/
#ifndef BUILD_SO
diff --git a/test/msan/pthread_getname_np.cc b/test/msan/pthread_getname_np.cc
index e19b652a7..4827b3a00 100644
--- a/test/msan/pthread_getname_np.cc
+++ b/test/msan/pthread_getname_np.cc
@@ -1,7 +1,7 @@
// RUN: %clangxx_msan -std=c++11 -O0 %s -o %t && %run %t
// The main goal is getting the pthread name back and
// FreeBSD based do not support this feature
-// UNSUPPORTED: android, netbsd, freebsd
+// UNSUPPORTED: android, freebsd
// Regression test for a deadlock in pthread_getattr_np
@@ -32,7 +32,11 @@ int main(void) {
assert(!res);
const char *kMyThreadName = "my-thread-name";
+#if defined(__NetBSD__)
+ res = pthread_setname_np(t, "%s", (void *)kMyThreadName);
+#else
res = pthread_setname_np(t, kMyThreadName);
+#endif
assert(!res);
char buf[100];
diff --git a/test/profile/instrprof-dlopen-dlclose-gcov.test b/test/profile/instrprof-dlopen-dlclose-gcov.test
index 8b1b2e294..36b5dbd26 100644
--- a/test/profile/instrprof-dlopen-dlclose-gcov.test
+++ b/test/profile/instrprof-dlopen-dlclose-gcov.test
@@ -1,3 +1,6 @@
+# atexit(3) not supported in dlopen(3)ed+dlclose(3)d DSO
+XFAIL: netbsd
+
RUN: mkdir -p %t.d
RUN: cd %t.d
diff --git a/test/profile/lit.cfg b/test/profile/lit.cfg
index 1cd250967..7449650a6 100644
--- a/test/profile/lit.cfg
+++ b/test/profile/lit.cfg
@@ -67,7 +67,7 @@ config.substitutions.append( ("%clangxx_profuse=", build_invocation(clang_cxxfla
config.substitutions.append( ("%clang_lto_profgen=", build_invocation(clang_cflags, True) + " -fprofile-instr-generate=") )
-if config.host_os not in ['Darwin', 'FreeBSD', 'Linux', 'SunOS']:
+if config.host_os not in ['Darwin', 'FreeBSD', 'Linux', 'NetBSD', 'SunOS']:
config.unsupported = True
if config.target_arch in ['armv7l']:
diff --git a/test/sanitizer_common/CMakeLists.txt b/test/sanitizer_common/CMakeLists.txt
index 4e2c80390..23292e548 100644
--- a/test/sanitizer_common/CMakeLists.txt
+++ b/test/sanitizer_common/CMakeLists.txt
@@ -16,6 +16,13 @@ if(CMAKE_SYSTEM_NAME MATCHES "Linux" AND NOT ANDROID)
list(APPEND SUPPORTED_TOOLS lsan)
endif()
+# FIXME(dliew): Remove this.
+# Temporary helper for https://reviews.llvm.org/D55740
+message(
+ STATUS
+ "sanitizer_common tests on \"${CMAKE_SYSTEM_NAME}\" will run against "
+ "\"${SUPPORTED_TOOLS}\"")
+
# Create a separate config for each tool we support.
foreach(tool ${SUPPORTED_TOOLS})
string(TOUPPER ${tool} tool_toupper)
diff --git a/test/sanitizer_common/TestCases/FreeBSD/capsicum.cc b/test/sanitizer_common/TestCases/FreeBSD/capsicum.cc
index d17f27b38..1bfb6f8d9 100644
--- a/test/sanitizer_common/TestCases/FreeBSD/capsicum.cc
+++ b/test/sanitizer_common/TestCases/FreeBSD/capsicum.cc
@@ -49,6 +49,12 @@ void test_cap_rights() {
rv = cap_rights_get(STDIN_FILENO, &grights);
assert(rv == 0);
assert(memcmp(&grights, &rights, sizeof(grights)) == 0);
+ cap_rights_t *iptr = cap_rights_set(&rights, CAP_IOCTL);
+ assert(iptr);
+ cap_rights_t *eptr = cap_rights_clear(&rights, CAP_READ);
+ assert(eptr);
+ hasit = cap_rights_is_set(&rights, CAP_IOCTL);
+ assert(hasit == true);
printf("rights test: %d\n", rv);
}
diff --git a/test/sanitizer_common/TestCases/FreeBSD/fdevname.cc b/test/sanitizer_common/TestCases/FreeBSD/fdevname.cc
new file mode 100644
index 000000000..252335e9a
--- /dev/null
+++ b/test/sanitizer_common/TestCases/FreeBSD/fdevname.cc
@@ -0,0 +1,44 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
+
+#include <assert.h>
+#include <fcntl.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/stat.h>
+
+void test_fdevname() {
+ int fd = open("/dev/null", O_RDONLY);
+ char *name;
+
+ printf("test_fdevname\n");
+ assert(fd != -1);
+ assert((name = fdevname(fd)));
+ close(fd);
+
+ printf("%s\n", name);
+}
+
+void test_fdevname_r() {
+ int fd = open("/dev/null", O_RDONLY);
+ char *name;
+ char buf[5];
+
+ printf("test_fdevname_r\n");
+ assert(fd != -1);
+ assert((name = fdevname_r(fd, buf, sizeof(buf))));
+ close(fd);
+
+ printf("%s\n", name);
+}
+
+int main(void) {
+ test_fdevname();
+ test_fdevname_r();
+ // CHECK: test_fdevname
+ // CHECK: null
+ // CHECK: test_fdevname_r
+ // CHECK: null
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/NetBSD/funopen2.cc b/test/sanitizer_common/TestCases/NetBSD/funopen2.cc
new file mode 100644
index 000000000..181ad03c9
--- /dev/null
+++ b/test/sanitizer_common/TestCases/NetBSD/funopen2.cc
@@ -0,0 +1,110 @@
+// RUN: %clangxx -g %s -o %t && %run %t | FileCheck %s
+
+// CHECK: READ CALLED; len={{[0-9]*}}
+// CHECK-NEXT: READ: test
+// CHECK-NEXT: WRITE CALLED: test
+// CHECK-NEXT: READ CALLED; len={{[0-9]*}}
+// CHECK-NEXT: READ: test
+// CHECK-NEXT: WRITE CALLED: test
+// CHECK-NEXT: CLOSE CALLED
+// CHECK-NEXT: SEEK CALLED; off=100, whence=0
+// CHECK-NEXT: READ CALLED; len={{[0-9]*}}
+// CHECK-NEXT: READ: test
+// CHECK-NEXT: WRITE CALLED: test
+// CHECK-NEXT: FLUSH CALLED
+// CHECK-NEXT: WRITE CALLED: test
+// CHECK-NEXT: FLUSH CALLED
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int cookie_var;
+
+ssize_t f_read(void *cookie, void *buf, size_t len) {
+ assert(cookie == &cookie_var);
+ assert(len >= 6);
+ printf("READ CALLED; len=%zd\n", len);
+ return strlcpy((char*)buf, "test\n", len);
+}
+
+ssize_t f_write(void *cookie, const void *buf, size_t len) {
+ assert(cookie == &cookie_var);
+ char *data = strndup((char*)buf, len);
+ assert(data);
+ printf("WRITE CALLED: %s\n", data);
+ free(data);
+ return len;
+}
+
+off_t f_seek(void *cookie, off_t off, int whence) {
+ assert(cookie == &cookie_var);
+ assert(whence == SEEK_SET);
+ printf("SEEK CALLED; off=%d, whence=%d\n", (int)off, whence);
+ return off;
+}
+
+int f_flush(void *cookie) {
+ assert(cookie == &cookie_var);
+ printf("FLUSH CALLED\n");
+ return 0;
+}
+
+int f_close(void *cookie) {
+ assert(cookie == &cookie_var);
+ printf("CLOSE CALLED\n");
+ return 0;
+}
+
+int main(void) {
+ FILE *fp;
+ char buf[10];
+
+ // 1. read-only variant
+ fp = fropen2(&cookie_var, f_read);
+ assert(fp);
+ // verify that fileno() does not crash or report nonsense
+ assert(fileno(fp) == -1);
+ assert(fgets(buf, sizeof(buf), fp));
+ printf("READ: %s", buf);
+ assert(!fclose(fp));
+
+ // 2. write-only variant
+ fp = fwopen2(&cookie_var, f_write);
+ assert(fp);
+ assert(fileno(fp) == -1);
+ assert(fputs("test", fp) >= 0);
+ assert(!fclose(fp));
+
+ // 3. read+write+close
+ fp = funopen2(&cookie_var, f_read, f_write, NULL, NULL, f_close);
+ assert(fp);
+ assert(fileno(fp) == -1);
+ assert(fgets(buf, sizeof(buf), fp));
+ printf("READ: %s", buf);
+ assert(fputs("test", fp) >= 0);
+ assert(!fflush(fp));
+ assert(!fclose(fp));
+
+ // 4. read+seek
+ fp = funopen2(&cookie_var, f_read, NULL, f_seek, NULL, NULL);
+ assert(fp);
+ assert(fileno(fp) == -1);
+ assert(fseek(fp, 100, SEEK_SET) == 0);
+ assert(fgets(buf, sizeof(buf), fp));
+ printf("READ: %s", buf);
+ assert(!fclose(fp));
+
+ // 5. write+flush
+ fp = funopen2(&cookie_var, NULL, f_write, NULL, f_flush, NULL);
+ assert(fp);
+ assert(fileno(fp) == -1);
+ assert(fputs("test", fp) >= 0);
+ assert(!fflush(fp));
+ assert(fputs("test", fp) >= 0);
+ // NB: fclose() also implicitly calls flush
+ assert(!fclose(fp));
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/NetBSD/md2.cc b/test/sanitizer_common/TestCases/NetBSD/md2.cc
index f76a35aac..7738aecdf 100644
--- a/test/sanitizer_common/TestCases/NetBSD/md2.cc
+++ b/test/sanitizer_common/TestCases/NetBSD/md2.cc
@@ -105,10 +105,10 @@ int main(void) {
// CHECK: test1: 'e303e49b34f981c2740cdf809200d51b'
// CHECK: test2: 'e303e49b34f981c2740cdf809200d51b'
// CHECK: test3: 'e303e49b34f981c2740cdf809200d51b'
- // CHECK: test4: 'a409cff8627afa00f3b563cf5f09af05'
- // CHECK: test5: 'a409cff8627afa00f3b563cf5f09af05'
- // CHECK: test6: '{{.*}}'
- // CHECK: test7: '{{.*}}'
+ // CHECK: test4: '{{.*}}'
+ // CHECK: test5: '{{.*}}'
+ // CHECK: test6: 'e303e49b34f981c2740cdf809200d51b'
+ // CHECK: test7: 'e303e49b34f981c2740cdf809200d51b'
return 0;
}
diff --git a/test/sanitizer_common/TestCases/NetBSD/md4.cc b/test/sanitizer_common/TestCases/NetBSD/md4.cc
index 831832691..a319e89a3 100644
--- a/test/sanitizer_common/TestCases/NetBSD/md4.cc
+++ b/test/sanitizer_common/TestCases/NetBSD/md4.cc
@@ -105,10 +105,10 @@ int main(void) {
// CHECK: test1: 'bf78fda2ca35eb7a026bfcdd3d17283d'
// CHECK: test2: 'bf78fda2ca35eb7a026bfcdd3d17283d'
// CHECK: test3: 'bf78fda2ca35eb7a026bfcdd3d17283d'
- // CHECK: test4: '85b3d78ce68be51f710272728fe606af'
- // CHECK: test5: '85b3d78ce68be51f710272728fe606af'
- // CHECK: test6: '{{.*}}'
- // CHECK: test7: '{{.*}}'
+ // CHECK: test4: '{{.*}}'
+ // CHECK: test5: '{{.*}}'
+ // CHECK: test6: 'bf78fda2ca35eb7a026bfcdd3d17283d'
+ // CHECK: test7: 'bf78fda2ca35eb7a026bfcdd3d17283d'
return 0;
}
diff --git a/test/sanitizer_common/TestCases/NetBSD/md5.cc b/test/sanitizer_common/TestCases/NetBSD/md5.cc
index e27997906..aee216818 100644
--- a/test/sanitizer_common/TestCases/NetBSD/md5.cc
+++ b/test/sanitizer_common/TestCases/NetBSD/md5.cc
@@ -105,8 +105,8 @@ int main(void) {
// CHECK: test1: '86e65b1ef4a830af347ac05ab4f0e999'
// CHECK: test2: '86e65b1ef4a830af347ac05ab4f0e999'
// CHECK: test3: '86e65b1ef4a830af347ac05ab4f0e999'
- // CHECK: test4: 'd6798ca88175b5feece4dda691a5b9b5'
- // CHECK: test5: 'd6798ca88175b5feece4dda691a5b9b5'
+ // CHECK: test4: '{{.*}}'
+ // CHECK: test5: '{{.*}}'
// CHECK: test6: '86e65b1ef4a830af347ac05ab4f0e999'
// CHECK: test7: '86e65b1ef4a830af347ac05ab4f0e999'
diff --git a/test/sanitizer_common/TestCases/NetBSD/sha2.cc b/test/sanitizer_common/TestCases/NetBSD/sha2.cc
index 4c9066db8..e905e3b61 100644
--- a/test/sanitizer_common/TestCases/NetBSD/sha2.cc
+++ b/test/sanitizer_common/TestCases/NetBSD/sha2.cc
@@ -173,10 +173,10 @@ int main(void) {
// CHECK-256: test1: 'bb000ddd92a0a2a346f0b531f278af06e370f86932ccafccc892d68d350f80f8'
// CHECK-256: test2: 'bb000ddd92a0a2a346f0b531f278af06e370f86932ccafccc892d68d350f80f8'
// CHECK-256: test3: 'bb000ddd92a0a2a346f0b531f278af06e370f86932ccafccc892d68d350f80f8'
- // CHECK-256: test4: 'bb058583870ed830d9b74b4c24af7fa2ab5684f4d88158a8094a68bcf908dc48'
- // CHECK-256: test5: 'bb058583870ed830d9b74b4c24af7fa2ab5684f4d88158a8094a68bcf908dc48'
- // CHECK-256: test6: 'cc1c596e07913a44fe35a4d4fd76b4bd6313604fa4264e2e6fbae1db78c24b22'
- // CHECK-256: test7: 'cc1c596e07913a44fe35a4d4fd76b4bd6313604fa4264e2e6fbae1db78c24b22'
+ // CHECK-256: test4: '{{.*}}'
+ // CHECK-256: test5: '{{.*}}'
+ // CHECK-256: test6: '{{.*}}'
+ // CHECK-256: test7: '{{.*}}'
// CHECK-256: test8: 'bb000ddd92a0a2a346f0b531f278af06e370f86932ccafccc892d68d350f80f8'
// CHECK-256: test9: 'bb000ddd92a0a2a346f0b531f278af06e370f86932ccafccc892d68d350f80f8'
@@ -184,10 +184,10 @@ int main(void) {
// CHECK-384: test1: 'f450c023b168ebd56ff916ca9b1f1f0010b8c592d28205cc91fa3056f629eed108e8bac864f01ca37a3edee596739e12'
// CHECK-384: test2: 'f450c023b168ebd56ff916ca9b1f1f0010b8c592d28205cc91fa3056f629eed108e8bac864f01ca37a3edee596739e12'
// CHECK-384: test3: 'f450c023b168ebd56ff916ca9b1f1f0010b8c592d28205cc91fa3056f629eed108e8bac864f01ca37a3edee596739e12'
- // CHECK-384: test4: '330d1528c9828d46e200fbfe05cac41717bed2e5f87ba10d47c9d6098e94f5e902ad90d4dd9be0f4347bc026e1206abd'
- // CHECK-384: test5: '330d1528c9828d46e200fbfe05cac41717bed2e5f87ba10d47c9d6098e94f5e902ad90d4dd9be0f4347bc026e1206abd'
- // CHECK-384: test6: '60686e8385598c69a2309483b91c04a1e0deeef1201730607a1818d097e726a9cbde8f8b8de7ab76c1d347def17f5ab5'
- // CHECK-384: test7: '60686e8385598c69a2309483b91c04a1e0deeef1201730607a1818d097e726a9cbde8f8b8de7ab76c1d347def17f5ab5'
+ // CHECK-384: test4: '{{.*}}'
+ // CHECK-384: test5: '{{.*}}'
+ // CHECK-384: test6: '{{.*}}'
+ // CHECK-384: test7: '{{.*}}'
// CHECK-384: test8: 'f450c023b168ebd56ff916ca9b1f1f0010b8c592d28205cc91fa3056f629eed108e8bac864f01ca37a3edee596739e12'
// CHECK-384: test9: 'f450c023b168ebd56ff916ca9b1f1f0010b8c592d28205cc91fa3056f629eed108e8bac864f01ca37a3edee596739e12'
@@ -195,10 +195,10 @@ int main(void) {
// CHECK-512: test1: '0e3f68731c0e2a6a4eab5d713c9a80dc78086b5fa7d2b5ab127277958e68d1b1dee1882b083b0106cd4319de42c0c8f452871364f5baa8a6379690612c6b844e'
// CHECK-512: test2: '0e3f68731c0e2a6a4eab5d713c9a80dc78086b5fa7d2b5ab127277958e68d1b1dee1882b083b0106cd4319de42c0c8f452871364f5baa8a6379690612c6b844e'
// CHECK-512: test3: '0e3f68731c0e2a6a4eab5d713c9a80dc78086b5fa7d2b5ab127277958e68d1b1dee1882b083b0106cd4319de42c0c8f452871364f5baa8a6379690612c6b844e'
- // CHECK-512: test4: '56b925cd62d73643e0f5ab821e062be9157035652cfb6396cb08d84f88981b1a9dae79f3d2707ad4f821d86b5608ae93f71788724328bb6e4ed1704a985d07a7'
- // CHECK-512: test5: '56b925cd62d73643e0f5ab821e062be9157035652cfb6396cb08d84f88981b1a9dae79f3d2707ad4f821d86b5608ae93f71788724328bb6e4ed1704a985d07a7'
- // CHECK-512: test6: '273b577200f95cfcb1627d94c0e6f3dd1682f63b4dfcc315355a7b90586e4cfd8f65c7cb315bd2b29c7ec0942510ffaceb1f02c7041f45528a6357fd38f2fe39'
- // CHECK-512: test7: '273b577200f95cfcb1627d94c0e6f3dd1682f63b4dfcc315355a7b90586e4cfd8f65c7cb315bd2b29c7ec0942510ffaceb1f02c7041f45528a6357fd38f2fe39'
+ // CHECK-512: test4: '{{.*}}'
+ // CHECK-512: test5: '{{.*}}'
+ // CHECK-512: test6: '{{.*}}'
+ // CHECK-512: test7: '{{.*}}'
// CHECK-512: test8: '0e3f68731c0e2a6a4eab5d713c9a80dc78086b5fa7d2b5ab127277958e68d1b1dee1882b083b0106cd4319de42c0c8f452871364f5baa8a6379690612c6b844e'
// CHECK-512: test9: '0e3f68731c0e2a6a4eab5d713c9a80dc78086b5fa7d2b5ab127277958e68d1b1dee1882b083b0106cd4319de42c0c8f452871364f5baa8a6379690612c6b844e'
diff --git a/test/sanitizer_common/TestCases/Posix/arc4random.cc b/test/sanitizer_common/TestCases/Posix/arc4random.cc
new file mode 100644
index 000000000..0a983b58f
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/arc4random.cc
@@ -0,0 +1,71 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
+//
+// UNSUPPORTED: linux, darwin, solaris
+
+#include <cstdlib>
+#include <ctime>
+#include <cstdio>
+#include <inttypes.h>
+
+void print_buf(unsigned char *buf, size_t buflen) {
+ printf("buf '");
+ for (auto i = 0; i < buflen; i ++)
+ printf("%" PRIx8, buf[i]);
+ printf("'\n");
+}
+
+void test_seed() {
+#ifdef __NetBSD__
+ time_t now = ::time(nullptr);
+ arc4random_addrandom((unsigned char *)&now, sizeof(now));
+#endif
+}
+
+void test_arc4random() {
+ printf("test_arc4random\n");
+ auto i = arc4random();
+ print_buf((unsigned char *)&i, sizeof(i));
+}
+
+void test_arc4random_uniform() {
+ printf("test_arc4random_uniform\n");
+ auto i = arc4random_uniform(1024);
+ print_buf((unsigned char *)&i, sizeof(i));
+}
+
+void test_arc4random_buf10() {
+ printf("test_arc4random_buf10\n");
+ char buf[10];
+#ifdef __NetBSD__
+ arc4random_stir();
+#endif
+ arc4random_buf(buf, sizeof(buf));
+ print_buf((unsigned char *)buf, sizeof(buf));
+}
+
+void test_arc4random_buf256() {
+ printf("test_arc4random_buf256\n");
+ char buf[256];
+#ifdef __NetBSD__
+ arc4random_stir();
+#endif
+ arc4random_buf(buf, sizeof(buf));
+ print_buf((unsigned char *)buf, sizeof(buf));
+}
+
+int main(void) {
+ test_seed();
+ test_arc4random();
+ test_arc4random_uniform();
+ test_arc4random_buf10();
+ test_arc4random_buf256();
+ return 0;
+ // CHECK: test_arc4random
+ // CHECK: buf '{{.*}}'
+ // CHECK: test_arc4random_uniform
+ // CHECK: buf '{{.*}}'
+ // CHECK: test_arc4random_buf10
+ // CHECK: buf '{{.*}}'
+ // CHECK: test_arc4random_buf256
+ // CHECK: buf '{{.*}}'
+}
diff --git a/test/sanitizer_common/TestCases/Posix/devname.cc b/test/sanitizer_common/TestCases/Posix/devname.cc
index da4bb8853..1495f7d9d 100644
--- a/test/sanitizer_common/TestCases/Posix/devname.cc
+++ b/test/sanitizer_common/TestCases/Posix/devname.cc
@@ -1,6 +1,7 @@
// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
// UNSUPPORTED: linux, solaris
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
#include <sys/stat.h>
@@ -9,11 +10,8 @@ int main(void) {
struct stat st;
char *name;
- if (stat("/dev/null", &st))
- exit(1);
-
- if (!(name = devname(st.st_rdev, S_ISCHR(st.st_mode) ? S_IFCHR : S_IFBLK)))
- exit(1);
+ assert(!stat("/dev/null", &st));
+ assert((name = devname(st.st_rdev, S_ISCHR(st.st_mode) ? S_IFCHR : S_IFBLK)));
printf("%s\n", name);
diff --git a/test/sanitizer_common/TestCases/Posix/devname_r.cc b/test/sanitizer_common/TestCases/Posix/devname_r.cc
index 3a05dae72..ae10a7662 100644
--- a/test/sanitizer_common/TestCases/Posix/devname_r.cc
+++ b/test/sanitizer_common/TestCases/Posix/devname_r.cc
@@ -4,6 +4,7 @@
#include <sys/cdefs.h>
#include <sys/stat.h>
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
@@ -12,17 +13,14 @@ int main(void) {
char name[100];
mode_t type;
- if (stat("/dev/null", &st))
- exit(1);
+ assert(!stat("/dev/null", &st));
type = S_ISCHR(st.st_mode) ? S_IFCHR : S_IFBLK;
#if defined(__NetBSD__)
- if (devname_r(st.st_rdev, type, name, sizeof(name)))
- exit(1);
+ assert(!devname_r(st.st_rdev, type, name, sizeof(name)));
#else
- if (!devname_r(st.st_rdev, type, name, sizeof(name)))
- exit(1);
+ assert(devname_r(st.st_rdev, type, name, sizeof(name)));
#endif
printf("%s\n", name);
diff --git a/test/sanitizer_common/TestCases/Posix/feof_fileno_ferror.cc b/test/sanitizer_common/TestCases/Posix/feof_fileno_ferror.cc
new file mode 100644
index 000000000..cfcf0e397
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/feof_fileno_ferror.cc
@@ -0,0 +1,41 @@
+// RUN: %clangxx -g %s -o %t && %run %t
+
+#include <assert.h>
+#include <stdio.h>
+#include <unistd.h>
+
+int main(int argc, char **argv) {
+ FILE *fp = fopen(argv[0], "r");
+ assert(fp);
+
+ // file should be good upon opening
+ assert(!feof(fp) && !ferror(fp));
+
+ // read until EOF
+ char buf[BUFSIZ];
+ while (fread(buf, 1, sizeof buf, fp) != 0) {}
+ assert(feof(fp));
+
+ // clear EOF
+ clearerr(fp);
+ assert(!feof(fp) && !ferror(fp));
+
+ // get file descriptor
+ int fd = fileno(fp);
+ assert(fd != -1);
+
+ // break the file by closing underlying descriptor
+ assert(close(fd) != -1);
+
+ // verify that an error is signalled
+ assert(fread(buf, 1, sizeof buf, fp) == 0);
+ assert(ferror(fp));
+
+ // clear error
+ clearerr(fp);
+ assert(!feof(fp) && !ferror(fp));
+
+ // fclose() will return EBADF because of closed fd
+ assert(fclose(fp) == -1);
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/fgetc_ungetc_getc.cc b/test/sanitizer_common/TestCases/Posix/fgetc_ungetc_getc.cc
new file mode 100644
index 000000000..f895cf194
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/fgetc_ungetc_getc.cc
@@ -0,0 +1,19 @@
+// RUN: %clangxx -g %s -o %t && %run %t
+
+#include <assert.h>
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+ FILE *fp = fopen(argv[0], "r");
+ assert(fp);
+
+ // the file should be at least one character long, always
+ assert(fgetc(fp) != EOF);
+ // POSIX guarantees being able to ungetc() at least one character
+ assert(ungetc('X', fp) != EOF);
+ // check whether ungetc() worked
+ assert(getc(fp) == 'X');
+
+ assert(!fclose(fp));
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/fgetln.cc b/test/sanitizer_common/TestCases/Posix/fgetln.cc
index e98cf449a..b1b466538 100644
--- a/test/sanitizer_common/TestCases/Posix/fgetln.cc
+++ b/test/sanitizer_common/TestCases/Posix/fgetln.cc
@@ -1,24 +1,20 @@
// RUN: %clangxx -O0 -g %s -o %t && %run %t
// UNSUPPORTED: linux
+#include <assert.h>
#include <stdio.h>
#include <stdlib.h>
int main(void) {
- FILE *fp;
- size_t len;
- char *s;
-
- fp = fopen("/etc/hosts", "r");
- if (!fp)
- exit(1);
+ FILE *fp = fopen("/etc/hosts", "r");
+ assert(fp);
- s = fgetln(fp, &len);
+ size_t len;
+ char *s = fgetln(fp, &len);
printf("%.*s\n", (int)len, s);
- if (fclose(fp) == EOF)
- exit(1);
+ assert(!fclose(fp));
return 0;
}
diff --git a/test/sanitizer_common/TestCases/Posix/fgets.cc b/test/sanitizer_common/TestCases/Posix/fgets.cc
index 8dde5cd1a..6a639f804 100644
--- a/test/sanitizer_common/TestCases/Posix/fgets.cc
+++ b/test/sanitizer_common/TestCases/Posix/fgets.cc
@@ -1,20 +1,16 @@
// RUN: %clangxx -g %s -o %t && %run %t
+#include <assert.h>
#include <stdio.h>
int main(int argc, char **argv) {
- FILE *fp;
- char buf[2];
- char *s;
-
- fp = fopen(argv[0], "r");
- if (!fp)
- return 1;
+ FILE *fp = fopen(argv[0], "r");
+ assert(fp);
- s = fgets(buf, sizeof(buf), fp);
- if (!s)
- return 2;
+ char buf[2];
+ char *s = fgets(buf, sizeof(buf), fp);
+ assert(s);
- fclose(fp);
+ assert(!fclose(fp));
return 0;
}
diff --git a/test/sanitizer_common/TestCases/Posix/fputc_putc_putchar.cc b/test/sanitizer_common/TestCases/Posix/fputc_putc_putchar.cc
new file mode 100644
index 000000000..7e786cd9e
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/fputc_putc_putchar.cc
@@ -0,0 +1,13 @@
+// RUN: %clangxx -g %s -o %t && %run %t | FileCheck %s
+// CHECK: abc
+
+#include <assert.h>
+#include <stdio.h>
+
+int main(void) {
+ assert(fputc('a', stdout) != EOF);
+ assert(putc('b', stdout) != EOF);
+ assert(putchar('c') != EOF);
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/fputs_puts.cc b/test/sanitizer_common/TestCases/Posix/fputs_puts.cc
index 8e8f7d384..21bb93aa4 100644
--- a/test/sanitizer_common/TestCases/Posix/fputs_puts.cc
+++ b/test/sanitizer_common/TestCases/Posix/fputs_puts.cc
@@ -1,18 +1,12 @@
// RUN: %clangxx -g %s -o %t && %run %t | FileCheck %s
// CHECK: {{^foobar$}}
+#include <assert.h>
#include <stdio.h>
int main(void) {
- int r;
-
- r = fputs("foo", stdout);
- if (r < 0)
- return 1;
-
- r = puts("bar");
- if (r < 0)
- return 1;
+ assert(fputs("foo", stdout) >= 0);
+ assert(puts("bar") >= 0);
return 0;
}
diff --git a/test/sanitizer_common/TestCases/NetBSD/fts.cc b/test/sanitizer_common/TestCases/Posix/fts.cc
index 1461005ef..79c41f7de 100644
--- a/test/sanitizer_common/TestCases/NetBSD/fts.cc
+++ b/test/sanitizer_common/TestCases/Posix/fts.cc
@@ -1,4 +1,6 @@
// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
+//
+// UNSUPPORTED: linux, darwin, solaris
#include <sys/param.h>
#include <sys/types.h>
diff --git a/test/sanitizer_common/TestCases/Posix/funopen.cc b/test/sanitizer_common/TestCases/Posix/funopen.cc
new file mode 100644
index 000000000..7d3192488
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/funopen.cc
@@ -0,0 +1,91 @@
+// RUN: %clangxx -g %s -o %t && %run %t | FileCheck %s
+
+// CHECK: READ CALLED; len={{[0-9]*}}
+// CHECK-NEXT: READ: test
+// CHECK-NEXT: WRITE CALLED: test
+// CHECK-NEXT: READ CALLED; len={{[0-9]*}}
+// CHECK-NEXT: READ: test
+// CHECK-NEXT: WRITE CALLED: test
+// CHECK-NEXT: CLOSE CALLED
+// CHECK-NEXT: SEEK CALLED; off=100, whence=0
+// CHECK-NEXT: READ CALLED; len={{[0-9]*}}
+// CHECK-NEXT: READ: test
+//
+// UNSUPPORTED: linux, darwin, solaris
+
+#include <assert.h>
+#include <stdio.h>
+#include <stdlib.h>
+#include <string.h>
+
+int cookie_var;
+
+int f_read(void *cookie, char *buf, int len) {
+ assert(cookie == &cookie_var);
+ assert(len >= 6);
+ printf("READ CALLED; len=%d\n", len);
+ return strlcpy(buf, "test\n", len);
+}
+
+int f_write(void *cookie, const char *buf, int len) {
+ assert(cookie == &cookie_var);
+ char *data = strndup(buf, len);
+ assert(data);
+ printf("WRITE CALLED: %s\n", data);
+ free(data);
+ return len;
+}
+
+off_t f_seek(void *cookie, off_t off, int whence) {
+ assert(cookie == &cookie_var);
+ assert(whence == SEEK_SET);
+ printf("SEEK CALLED; off=%d, whence=%d\n", (int)off, whence);
+ return off;
+}
+
+int f_close(void *cookie) {
+ assert(cookie == &cookie_var);
+ printf("CLOSE CALLED\n");
+ return 0;
+}
+
+int main(void) {
+ FILE *fp;
+ char buf[10];
+
+ // 1. read-only variant
+ fp = fropen(&cookie_var, f_read);
+ assert(fp);
+ // verify that fileno() does not crash or report nonsense
+ assert(fileno(fp) == -1);
+ assert(fgets(buf, sizeof(buf), fp));
+ printf("READ: %s", buf);
+ assert(!fclose(fp));
+
+ // 2. write-only variant
+ fp = fwopen(&cookie_var, f_write);
+ assert(fp);
+ assert(fileno(fp) == -1);
+ assert(fputs("test", fp) >= 0);
+ assert(!fclose(fp));
+
+ // 3. read+write+close
+ fp = funopen(&cookie_var, f_read, f_write, NULL, f_close);
+ assert(fp);
+ assert(fileno(fp) == -1);
+ assert(fgets(buf, sizeof(buf), fp));
+ printf("READ: %s", buf);
+ assert(fputs("test", fp) >= 0);
+ assert(!fclose(fp));
+
+ // 4. read+seek
+ fp = funopen(&cookie_var, f_read, NULL, f_seek, NULL);
+ assert(fp);
+ assert(fileno(fp) == -1);
+ assert(fseek(fp, 100, SEEK_SET) == 0);
+ assert(fgets(buf, sizeof(buf), fp));
+ printf("READ: %s", buf);
+ assert(!fclose(fp));
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/getc_unlocked.cc b/test/sanitizer_common/TestCases/Posix/getc_unlocked.cc
new file mode 100644
index 000000000..c4257d130
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/getc_unlocked.cc
@@ -0,0 +1,20 @@
+// RUN: %clangxx -g %s -o %t && %run %t
+
+#include <assert.h>
+#include <stdio.h>
+
+int main(int argc, char **argv) {
+ FILE *fp = fopen(argv[0], "r");
+ assert(fp);
+
+ // the file should be at least one character long, always
+ assert(getc_unlocked(fp) != EOF);
+ // POSIX guarantees being able to ungetc() at least one character
+ // NB: ungetc_unlocked is apparently not present
+ assert(ungetc('X', fp) != EOF);
+ // check whether ungetc() works with getc_unlocked()
+ assert(getc_unlocked(fp) == 'X');
+
+ assert(!fclose(fp));
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/getfsent.cc b/test/sanitizer_common/TestCases/Posix/getfsent.cc
new file mode 100644
index 000000000..687a7a7d4
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/getfsent.cc
@@ -0,0 +1,36 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
+//
+// UNSUPPORTED: linux, darwin, solaris
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <fstab.h>
+
+int main(void) {
+ printf("getfsent\n");
+
+ setfsent();
+ struct fstab *fentry = getfsent();
+
+ assert(fentry);
+
+ setfsent();
+ struct fstab *pentry = getfsspec(fentry->fs_spec);
+ assert(pentry);
+ setfsent();
+ struct fstab *wentry = getfsfile(fentry->fs_file);
+ assert(wentry);
+ assert(!memcmp(fentry, wentry, sizeof(*wentry)));
+ assert(!memcmp(pentry, wentry, sizeof(*pentry)));
+
+ printf("First entry: device block '%s', mounted with '%s'\n",
+ fentry->fs_spec, fentry->fs_mntops);
+
+ endfsent();
+
+ return 0;
+ // CHECK: getfsent
+ // CHECK: First entry: device block '{{.*}}', mounted with '{{.*}}'
+}
diff --git a/test/sanitizer_common/TestCases/Posix/getusershell.cc b/test/sanitizer_common/TestCases/Posix/getusershell.cc
new file mode 100644
index 000000000..c00d75f11
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/getusershell.cc
@@ -0,0 +1,23 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
+
+// UNSUPPORTED: android
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <unistd.h>
+
+int main(void) {
+ printf("getusershell\n");
+
+ setusershell();
+ char *fentry = getusershell();
+
+ printf("First entry: '%s'\n", fentry);
+
+ endusershell();
+
+ return 0;
+ // CHECK: getusershell
+ // CHECK: First entry: '{{.*}}'
+}
diff --git a/test/sanitizer_common/TestCases/Posix/lstat.cc b/test/sanitizer_common/TestCases/Posix/lstat.cc
index 37237d821..01c2ea83d 100644
--- a/test/sanitizer_common/TestCases/Posix/lstat.cc
+++ b/test/sanitizer_common/TestCases/Posix/lstat.cc
@@ -1,16 +1,14 @@
// RUN: %clangxx -O0 -g %s -o %t && %run %t
+#include <assert.h>
#include <stdlib.h>
#include <sys/stat.h>
int main(void) {
struct stat st;
- if (lstat("/dev/null", &st))
- exit(1);
-
- if (!S_ISCHR(st.st_mode))
- exit(1);
+ assert(!lstat("/dev/null", &st));
+ assert(S_ISCHR(st.st_mode));
return 0;
}
diff --git a/test/sanitizer_common/TestCases/Posix/popen.cc b/test/sanitizer_common/TestCases/Posix/popen.cc
new file mode 100644
index 000000000..6bf6255a6
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/popen.cc
@@ -0,0 +1,23 @@
+// RUN: %clangxx -g %s -o %t && %run %t | FileCheck %s
+// CHECK: 1
+// CHECK-NEXT: 2
+
+#include <assert.h>
+#include <stdio.h>
+
+int main(void) {
+ // use a tool that produces different output than input to verify
+ // that everything worked correctly
+ FILE *fp = popen("sort", "w");
+ assert(fp);
+
+ // verify that fileno() returns a meaningful descriptor (needed
+ // for the implementation of TSan)
+ assert(fileno(fp) != -1);
+
+ assert(fputs("2\n", fp) >= 0);
+ assert(fputs("1\n", fp) >= 0);
+ assert(pclose(fp) == 0);
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/Posix/putc_putchar_unlocked.cc b/test/sanitizer_common/TestCases/Posix/putc_putchar_unlocked.cc
new file mode 100644
index 000000000..12c35c220
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/putc_putchar_unlocked.cc
@@ -0,0 +1,12 @@
+// RUN: %clangxx -g %s -o %t && %run %t | FileCheck %s
+// CHECK: bc
+
+#include <assert.h>
+#include <stdio.h>
+
+int main(void) {
+ assert(putc_unlocked('b', stdout) != EOF);
+ assert(putchar_unlocked('c') != EOF);
+
+ return 0;
+}
diff --git a/test/sanitizer_common/TestCases/NetBSD/regex.cc b/test/sanitizer_common/TestCases/Posix/regex.cc
index 8a4fb3885..3727f0132 100644
--- a/test/sanitizer_common/TestCases/NetBSD/regex.cc
+++ b/test/sanitizer_common/TestCases/Posix/regex.cc
@@ -1,10 +1,16 @@
// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
+//
+// UNSUPPORTED: darwin, solaris
#include <assert.h>
#include <regex.h>
#include <stdio.h>
#include <stdlib.h>
+#ifndef __arraycount
+#define __arraycount(a) ((sizeof(a) / sizeof(a[0])))
+#endif
+
void test_matched(const regex_t *preg, const char *string) {
int rv = regexec(preg, string, 0, NULL, 0);
if (!rv)
@@ -33,37 +39,6 @@ void test_print_matches(const regex_t *preg, const char *string) {
abort();
}
-void test_nsub(const regex_t *preg, const char *string) {
- regmatch_t rm[10];
- int rv = regexec(preg, string, __arraycount(rm), rm, 0);
- if (!rv) {
- char buf[1024];
- ssize_t ss = regnsub(buf, __arraycount(buf), "\\1xyz", rm, string);
- assert(ss != -1);
-
- printf("'%s' -> '%s'\n", string, buf);
- } else if (rv == REG_NOMATCH)
- printf("%s: not-matched\n", string);
- else
- abort();
-}
-
-void test_asub(const regex_t *preg, const char *string) {
- regmatch_t rm[10];
- int rv = regexec(preg, string, __arraycount(rm), rm, 0);
- if (!rv) {
- char *buf;
- ssize_t ss = regasub(&buf, "\\1xyz", rm, string);
- assert(ss != -1);
-
- printf("'%s' -> '%s'\n", string, buf);
- free(buf);
- } else if (rv == REG_NOMATCH)
- printf("%s: not-matched\n", string);
- else
- abort();
-}
-
int main(void) {
printf("regex\n");
@@ -76,9 +51,6 @@ int main(void) {
test_print_matches(&regex, "ABC");
- test_nsub(&regex, "ABC DEF");
- test_asub(&regex, "GHI JKL");
-
regfree(&regex);
rv = regcomp(&regex, "[[:upp:]]", 0);
@@ -93,8 +65,6 @@ int main(void) {
// CHECK: ABC: matched
// CHECK: matched[0]='AB'
// CHECK: matched[1]='B'
- // CHECK: 'ABC DEF' -> 'Bxyz'
- // CHECK: 'GHI JKL' -> 'Hxyz'
// CHECK: error:{{.*}}
return 0;
diff --git a/test/sanitizer_common/TestCases/Posix/sl_add.cc b/test/sanitizer_common/TestCases/Posix/sl_add.cc
new file mode 100644
index 000000000..4da70c788
--- /dev/null
+++ b/test/sanitizer_common/TestCases/Posix/sl_add.cc
@@ -0,0 +1,26 @@
+// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
+//
+// UNSUPPORTED: linux, darwin, solaris
+
+#include <assert.h>
+#include <errno.h>
+#include <stdio.h>
+#include <string.h>
+#include <stringlist.h>
+
+int main(void) {
+ printf("sl_add\n");
+
+ StringList *sl = sl_init();
+ assert(sl);
+ char *p = strdup("entry");
+ assert(!sl_add(sl, p));
+ char *entry = sl_find(sl, "entry");
+ assert(!strcmp(entry, p));
+ printf("Found '%s'\n", entry);
+ sl_free(sl, 1);
+
+ return 0;
+ // CHECK: sl_add
+ // CHECK: Found '{{.*}}'
+}
diff --git a/test/sanitizer_common/TestCases/NetBSD/strtonum.cc b/test/sanitizer_common/TestCases/Posix/strtonum.cc
index 2f47a3030..22346b2e1 100644
--- a/test/sanitizer_common/TestCases/NetBSD/strtonum.cc
+++ b/test/sanitizer_common/TestCases/Posix/strtonum.cc
@@ -1,4 +1,6 @@
// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
+//
+// UNSUPPORTED: linux, darwin, solaris
#define _OPENBSD_SOURCE
diff --git a/test/sanitizer_common/TestCases/NetBSD/vis.cc b/test/sanitizer_common/TestCases/Posix/vis.cc
index 89ea259e5..15f1bc949 100644
--- a/test/sanitizer_common/TestCases/NetBSD/vis.cc
+++ b/test/sanitizer_common/TestCases/Posix/vis.cc
@@ -1,4 +1,6 @@
// RUN: %clangxx -O0 -g %s -o %t && %run %t 2>&1 | FileCheck %s
+//
+// UNSUPPORTED: linux, solaris, darwin
#include <ctype.h>
#include <err.h>
diff --git a/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc b/test/sanitizer_common/TestCases/hard_rss_limit_mb_test.cc
index 3013a3c3f..e01d416cb 100644
--- a/test/sanitizer_common/TestCases/Linux/hard_rss_limit_mb_test.cc
+++ b/test/sanitizer_common/TestCases/hard_rss_limit_mb_test.cc
@@ -16,8 +16,7 @@
// XFAIL: msan
// XFAIL: ubsan
-// https://github.com/google/sanitizers/issues/981
-// UNSUPPORTED: android-26
+// UNSUPPORTED: freebsd, solaris, darwin
#include <string.h>
#include <stdio.h>
diff --git a/test/tsan/Darwin/ignore-noninstrumented.mm b/test/tsan/Darwin/ignore-noninstrumented.mm
index 668a76a46..88d39268f 100644
--- a/test/tsan/Darwin/ignore-noninstrumented.mm
+++ b/test/tsan/Darwin/ignore-noninstrumented.mm
@@ -1,4 +1,7 @@
-// Check that ignore_noninstrumented_modules=1 suppresses races from system libraries on OS X.
+// Check that ignore_noninstrumented_modules=1 suppresses reporting races from
+// system libraries on OS X. There are currently false positives coming from
+// libxpc, libdispatch, CoreFoundation and others, because these libraries use
+// TSan-invisible atomics as synchronization.
// RUN: %clang_tsan %s -o %t -framework Foundation
diff --git a/test/tsan/Darwin/ignored-interceptors.mm b/test/tsan/Darwin/ignored-interceptors.mm
deleted file mode 100644
index b2e40f07d..000000000
--- a/test/tsan/Darwin/ignored-interceptors.mm
+++ /dev/null
@@ -1,55 +0,0 @@
-// Check that ignore_interceptors_accesses=1 suppresses reporting races from
-// system libraries on OS X. There are currently false positives coming from
-// libxpc, libdispatch, CoreFoundation and others, because these libraries use
-// TSan-invisible atomics as synchronization.
-
-// RUN: %clang_tsan %s -o %t -framework Foundation
-
-// Check that without the flag, there are false positives.
-// RUN: %env_tsan_opts=ignore_noninstrumented_modules=0 %deflake %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RACE
-
-// With ignore_interceptors_accesses=1, no races are reported.
-// RUN: %env_tsan_opts=ignore_noninstrumented_modules=0:ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s
-
-// With ignore_interceptors_accesses=1, races in user's code are still reported.
-// RUN: %env_tsan_opts=ignore_noninstrumented_modules=0:ignore_interceptors_accesses=1 %deflake %run %t race 2>&1 | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-RACE
-
-#import <Foundation/Foundation.h>
-
-#import "../test.h"
-
-long global;
-
-void *Thread1(void *x) {
- barrier_wait(&barrier);
- global = 42;
- return NULL;
-}
-
-void *Thread2(void *x) {
- global = 43;
- barrier_wait(&barrier);
- return NULL;
-}
-
-int main(int argc, char *argv[]) {
- fprintf(stderr, "Hello world.\n");
-
- // NSUserDefaults uses XPC which triggers the false positive.
- NSDictionary *d = [[NSUserDefaults standardUserDefaults] dictionaryRepresentation];
-
- if (argc > 1 && strcmp(argv[1], "race") == 0) {
- barrier_init(&barrier, 2);
- pthread_t t[2];
- pthread_create(&t[0], NULL, Thread1, NULL);
- pthread_create(&t[1], NULL, Thread2, NULL);
- pthread_join(t[0], NULL);
- pthread_join(t[1], NULL);
- }
-
- fprintf(stderr, "Done.\n");
-}
-
-// CHECK: Hello world.
-// CHECK-RACE: SUMMARY: ThreadSanitizer: data race
-// CHECK: Done.
diff --git a/test/tsan/Darwin/objc-synchronize-cycle-tagged.mm b/test/tsan/Darwin/objc-synchronize-cycle-tagged.mm
new file mode 100644
index 000000000..5806e8af9
--- /dev/null
+++ b/test/tsan/Darwin/objc-synchronize-cycle-tagged.mm
@@ -0,0 +1,42 @@
+// RUN: %clangxx_tsan %s -o %t -framework Foundation -fobjc-arc %darwin_min_target_with_full_runtime_arc_support
+// RUN: %run %t 6 2>&1 | FileCheck %s --check-prefix=SIX
+// RUN: not %run %t 7 2>&1 | FileCheck %s --check-prefix=SEVEN
+
+#import <Foundation/Foundation.h>
+
+static bool isTaggedPtr(id obj) {
+ uintptr_t ptr = (uintptr_t) obj;
+ return (ptr & 0x8000000000000001ull) != 0;
+}
+
+int main(int argc, char* argv[]) {
+ assert(argc == 2);
+ int arg = atoi(argv[1]);
+
+ @autoreleasepool {
+ NSObject* obj = [NSObject new];
+ NSObject* num1 = @7;
+ NSObject* num2 = [NSNumber numberWithInt:arg];
+
+ assert(!isTaggedPtr(obj));
+ assert(isTaggedPtr(num1) && isTaggedPtr(num2));
+
+ // obj -> num1 (includes num2)
+ @synchronized(obj) {
+ @synchronized(num1) {
+ }
+ }
+
+ // num2 -> obj1
+ @synchronized(num2) {
+ @synchronized(obj) {
+// SEVEN: ThreadSanitizer: lock-order-inversion (potential deadlock)
+ }
+ }
+ }
+
+ NSLog(@"PASS");
+// SIX-NOT: ThreadSanitizer
+// SIX: PASS
+ return 0;
+}
diff --git a/test/tsan/Darwin/objc-synchronize-cycle.mm b/test/tsan/Darwin/objc-synchronize-cycle.mm
new file mode 100644
index 000000000..fb8163115
--- /dev/null
+++ b/test/tsan/Darwin/objc-synchronize-cycle.mm
@@ -0,0 +1,31 @@
+// RUN: %clangxx_tsan %s -o %t -framework Foundation -fobjc-arc %darwin_min_target_with_full_runtime_arc_support
+// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: %env_tsan_opts=detect_deadlocks=1 not %run %t 2>&1 | FileCheck %s
+// RUN: %env_tsan_opts=detect_deadlocks=0 %run %t 2>&1 | FileCheck %s --check-prefix=DISABLED
+
+#import <Foundation/Foundation.h>
+
+int main() {
+ @autoreleasepool {
+ NSObject* obj1 = [NSObject new];
+ NSObject* obj2 = [NSObject new];
+
+ // obj1 -> obj2
+ @synchronized(obj1) {
+ @synchronized(obj2) {
+ }
+ }
+
+ // obj1 -> obj1
+ @synchronized(obj2) {
+ @synchronized(obj1) {
+// CHECK: ThreadSanitizer: lock-order-inversion (potential deadlock)
+ }
+ }
+ }
+
+ NSLog(@"PASS");
+// DISABLED-NOT: ThreadSanitizer
+// DISABLED: PASS
+ return 0;
+}
diff --git a/test/tsan/Darwin/objc-synchronize-nested-recursive.mm b/test/tsan/Darwin/objc-synchronize-nested-recursive.mm
new file mode 100644
index 000000000..ab6643e5c
--- /dev/null
+++ b/test/tsan/Darwin/objc-synchronize-nested-recursive.mm
@@ -0,0 +1,35 @@
+// RUN: %clangxx_tsan %s -o %t -framework Foundation -fobjc-arc %darwin_min_target_with_full_runtime_arc_support
+// RUN: %run %t 2>&1 | FileCheck %s
+
+#import <Foundation/Foundation.h>
+
+int main() {
+ @autoreleasepool {
+ NSObject* obj1 = [NSObject new];
+ NSObject* obj2 = [NSObject new];
+
+ @synchronized(obj1) {
+ @synchronized(obj1) {
+ NSLog(@"nested 1-1");
+// CHECK: nested 1-1
+ }
+ }
+
+ @synchronized(obj1) {
+ @synchronized(obj2) {
+ @synchronized(obj1) {
+ @synchronized(obj2) {
+ NSLog(@"nested 1-2-1-2");
+// CHECK: nested 1-2-1-2
+ }
+ }
+ }
+ }
+
+ }
+
+ NSLog(@"PASS");
+// CHECK-NOT: ThreadSanitizer
+// CHECK: PASS
+ return 0;
+}
diff --git a/test/tsan/deadlock_detector_stress_test.cc b/test/tsan/deadlock_detector_stress_test.cc
index bbaaabbb3..f3d2fc712 100644
--- a/test/tsan/deadlock_detector_stress_test.cc
+++ b/test/tsan/deadlock_detector_stress_test.cc
@@ -1,12 +1,12 @@
// RUN: %clangxx_tsan %s -o %t -DLockType=PthreadMutex
-// RUN: %env_tsan_opts=detect_deadlocks=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOT-SECOND
-// RUN: %env_tsan_opts=detect_deadlocks=1:second_deadlock_stack=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-SECOND
+// RUN: %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-NOT-SECOND
+// RUN: %env_tsan_opts=second_deadlock_stack=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-SECOND
// RUN: %clangxx_tsan %s -o %t -DLockType=PthreadSpinLock
-// RUN: %env_tsan_opts=detect_deadlocks=1 %deflake %run %t | FileCheck %s
+// RUN: %deflake %run %t | FileCheck %s
// RUN: %clangxx_tsan %s -o %t -DLockType=PthreadRWLock
-// RUN: %env_tsan_opts=detect_deadlocks=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-RD
+// RUN: %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-RD
// RUN: %clangxx_tsan %s -o %t -DLockType=PthreadRecursiveMutex
-// RUN: %env_tsan_opts=detect_deadlocks=1 %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-REC
+// RUN: %deflake %run %t | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-REC
#include "test.h"
#undef NDEBUG
#include <assert.h>
diff --git a/test/tsan/ignored-interceptors-mmap.cc b/test/tsan/ignored-interceptors-mmap.cc
index 4686e8eb3..bb43250a6 100644
--- a/test/tsan/ignored-interceptors-mmap.cc
+++ b/test/tsan/ignored-interceptors-mmap.cc
@@ -1,10 +1,12 @@
// RUN: %clangxx_tsan -O0 %s -o %t
-// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NORMAL
-// RUN: %env_tsan_opts=ignore_interceptors_accesses=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-IGNORE
+// RUN: not %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-RACE
+// RUN: %run %t ignore 2>&1 | FileCheck %s --check-prefix=CHECK-IGNORE
// XFAIL: freebsd,netbsd
-#include <errno.h>
#include <sys/mman.h>
+#include <string.h>
+#include <assert.h>
+#include <atomic>
#include "test.h"
@@ -15,48 +17,45 @@ void AnnotateIgnoreWritesBegin(const char *f, int l);
void AnnotateIgnoreWritesEnd(const char *f, int l);
}
-void *global_p;
+// Use atomic to ensure we do not have a race for the pointer value itself. We
+// only want to check races in the mmap'd memory to isolate the test that mmap
+// respects ignore annotations.
+std::atomic<int*> global_p;
-int mmap_and_ignore_reads_and_writes() {
+void mmap_ignored(bool ignore) {
const size_t kSize = sysconf(_SC_PAGESIZE);
- void *p = mmap(0, kSize, PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_ANON, -1, 0);
- if (p == MAP_FAILED)
- return printf("mmap failed with %d\n", errno);
- munmap(p, kSize);
-
- void *new_p = mmap(p, kSize, PROT_READ|PROT_WRITE,
- MAP_PRIVATE|MAP_ANON, -1, 0);
- if (p == MAP_FAILED || p != new_p)
- return printf("second mmap failed with %d\n", errno);
-
- AnnotateIgnoreWritesBegin(__FILE__, __LINE__);
- global_p = p;
- AnnotateIgnoreWritesEnd(__FILE__, __LINE__);
+
+ if (ignore) AnnotateIgnoreWritesBegin(__FILE__, __LINE__);
+ void *p = mmap(0, kSize, PROT_READ|PROT_WRITE, MAP_PRIVATE|MAP_ANON, -1, 0);
+ if (ignore) AnnotateIgnoreWritesEnd(__FILE__, __LINE__);
+
+ // Use relaxed to retain the race between the mmap call and the memory write
+ global_p.store((int *)p, std::memory_order_relaxed);
barrier_wait(&barrier);
- return 0;
}
-void *Thread(void *a) {
+void *WriteToMemory(void *unused) {
barrier_wait(&barrier);
-
- ((int*)global_p)[1] = 10;
- printf("Read the zero value from mmapped memory %d\n", ((int*)global_p)[1]);
+ global_p[0] = 7;
return 0;
}
-int main() {
+// Create race between allocating (mmap) and writing memory
+int main(int argc, const char *argv[]) {
+ bool ignore = (argc > 1) && (strcmp(argv[1], "ignore") == 0);
+
barrier_init(&barrier, 2);
pthread_t t;
- pthread_create(&t, 0, Thread, 0);
- if (mmap_and_ignore_reads_and_writes())
- return 1;
+ pthread_create(&t, 0, WriteToMemory, 0);
+ mmap_ignored(ignore);
pthread_join(t, 0);
+
+ assert(global_p[0] == 7);
printf("OK\n");
return 0;
}
-// CHECK-NORMAL: WARNING: ThreadSanitizer: data race
-// CHECK-NORMAL: OK
-// CHECK-IGNORE_NOT: WARNING: ThreadSanitizer: data race
+// CHECK-RACE: WARNING: ThreadSanitizer: data race
+// CHECK-RACE: OK
+// CHECK-IGNORE-NOT: WARNING: ThreadSanitizer: data race
// CHECK-IGNORE: OK
diff --git a/test/tsan/mutex_cycle2.c b/test/tsan/mutex_cycle2.c
index 32659d4ee..0dc96d07c 100644
--- a/test/tsan/mutex_cycle2.c
+++ b/test/tsan/mutex_cycle2.c
@@ -1,5 +1,5 @@
// RUN: %clangxx_tsan %s -o %t
-// RUN: not %run %t 2>&1 | FileCheck %s
+// RUN: not %run %t 2>&1 | FileCheck %s
// RUN: %env_tsan_opts=detect_deadlocks=1 not %run %t 2>&1 | FileCheck %s
// RUN: %env_tsan_opts=detect_deadlocks=0 %run %t 2>&1 | FileCheck %s --check-prefix=DISABLED
// RUN: echo "deadlock:main" > %t.supp
diff --git a/test/tsan/sunrpc.cc b/test/tsan/sunrpc.cc
index 5cfb5344e..8e32d6d30 100644
--- a/test/tsan/sunrpc.cc
+++ b/test/tsan/sunrpc.cc
@@ -1,3 +1,5 @@
+// REQUIRES: sunrpc
+
// RUN: %clang_tsan -O1 %s -o %t && %run %t 2>&1 | FileCheck %s
#include <pthread.h>
diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-lvalue.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-lvalue.cpp
new file mode 100644
index 000000000..97d4b4623
--- /dev/null
+++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-lvalue.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+#include <stdlib.h>
+
+typedef char *__attribute__((align_value(0x8000))) aligned_char;
+
+struct ac_struct {
+ aligned_char a;
+};
+
+char *load_from_ac_struct(struct ac_struct *x) {
+ return x->a;
+}
+
+int main(int argc, char* argv[]) {
+ char *ptr = (char *)malloc(2);
+
+ struct ac_struct x;
+ x.a = ptr + 1; // FIXME: it is weird that this does not also have an assumption.
+ load_from_ac_struct(&x);
+ // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-9]]:13: runtime error: assumption of 32768 byte alignment for pointer of type 'aligned_char' (aka 'char *') failed
+ // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-17]]:30: note: alignment assumption was specified here
+ // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte
+
+ free(ptr);
+
+ return 0;
+}
diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-paramvar.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-paramvar.cpp
new file mode 100644
index 000000000..774ba90fb
--- /dev/null
+++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-align_value-on-paramvar.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+#include <stdlib.h>
+
+char *passthrough(__attribute__((align_value(0x8000))) char *x) {
+ return x;
+}
+
+int main(int argc, char* argv[]) {
+ char *ptr = (char *)malloc(2);
+
+ passthrough(ptr + 1);
+ // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-7]]:10: runtime error: assumption of 32768 byte alignment for pointer of type 'char *' failed
+ // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-9]]:34: note: alignment assumption was specified here
+ // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte
+
+ // FIXME: shouldn't there be an assumption on the caller's side too?
+
+ free(ptr);
+
+ return 0;
+}
diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function-variable.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function-variable.cpp
new file mode 100644
index 000000000..c71cb1e1b
--- /dev/null
+++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function-variable.cpp
@@ -0,0 +1,33 @@
+// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+#include <stdlib.h>
+
+char *__attribute__((alloc_align(2)))
+passthrough(char *x, unsigned long alignment) {
+ return x;
+}
+
+unsigned long alignment;
+
+int main(int argc, char* argv[]) {
+ char *ptr = (char *)malloc(2);
+
+ alignment = 0x8000;
+
+ passthrough(ptr + 1, alignment);
+ // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:3: runtime error: assumption of 32768 byte alignment for pointer of type 'char *' failed
+ // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-14]]:22: note: alignment assumption was specified here
+ // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte
+
+ free(ptr);
+
+ return 0;
+}
diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function.cpp
new file mode 100644
index 000000000..db22e3a8f
--- /dev/null
+++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-alloc_align-on-function.cpp
@@ -0,0 +1,29 @@
+// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+#include <stdlib.h>
+
+char *__attribute__((alloc_align(2)))
+passthrough(char *x, unsigned long alignment) {
+ return x;
+}
+
+int main(int argc, char* argv[]) {
+ char *ptr = (char *)malloc(2);
+
+ passthrough(ptr + 1, 0x8000);
+ // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:3: runtime error: assumption of 32768 byte alignment for pointer of type 'char *' failed
+ // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-10]]:22: note: alignment assumption was specified here
+ // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte
+
+ free(ptr);
+
+ return 0;
+}
diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp
new file mode 100644
index 000000000..33aa132f6
--- /dev/null
+++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function-two-params.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+#include <stdlib.h>
+
+char *__attribute__((assume_aligned(0x8000, 1))) passthrough(char *x) {
+ return x;
+}
+
+int main(int argc, char* argv[]) {
+ char *ptr = (char *)malloc(3);
+
+ passthrough(ptr + 2);
+ // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:3: runtime error: assumption of 32768 byte alignment (with offset of 1 byte) for pointer of type 'char *' failed
+ // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-9]]:22: note: alignment assumption was specified here
+ // CHECK: 0x{{.*}}: note: offset address is {{.*}} aligned, misalignment offset is {{.*}} byte
+
+ free(ptr);
+
+ return 0;
+}
diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function.cpp
new file mode 100644
index 000000000..202c0ce00
--- /dev/null
+++ b/test/ubsan/TestCases/Pointer/alignment-assumption-attribute-assume_aligned-on-function.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+#include <stdlib.h>
+
+char *__attribute__((assume_aligned(0x8000))) passthrough(char *x) {
+ return x;
+}
+
+int main(int argc, char* argv[]) {
+ char *ptr = (char *)malloc(2);
+
+ passthrough(ptr + 1);
+ // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:3: runtime error: assumption of 32768 byte alignment for pointer of type 'char *' failed
+ // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-9]]:22: note: alignment assumption was specified here
+ // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte
+
+ free(ptr);
+
+ return 0;
+}
diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-blacklist.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-blacklist.cpp
new file mode 100644
index 000000000..c0c7b373f
--- /dev/null
+++ b/test/ubsan/TestCases/Pointer/alignment-assumption-blacklist.cpp
@@ -0,0 +1,20 @@
+// RUN: %clang -fsanitize=alignment -fno-sanitize-recover=alignment -O0 %s -o %t && not %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption "
+
+// RUN: rm -f %tmp
+// RUN: echo "[alignment]" >> %tmp
+// RUN: echo "fun:main" >> %tmp
+// RUN: %clang -fsanitize=alignment -fno-sanitize-recover=alignment -fsanitize-blacklist=%tmp -O0 %s -o %t && %run %t 2>&1
+
+#include <stdlib.h>
+
+int main(int argc, char* argv[]) {
+ char *ptr = (char *)malloc(2);
+
+ __builtin_assume_aligned(ptr + 1, 0x8000);
+ // CHECK: {{.*}}alignment-assumption-blacklist.cpp:[[@LINE-1]]:32: runtime error: assumption of 32768 byte alignment for pointer of type 'char *' failed
+ // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte
+
+ free(ptr);
+
+ return 0;
+}
diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params-variable.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params-variable.cpp
new file mode 100644
index 000000000..cc4e1f218
--- /dev/null
+++ b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params-variable.cpp
@@ -0,0 +1,27 @@
+// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+#include <stdlib.h>
+
+volatile long offset;
+
+int main(int argc, char* argv[]) {
+ char *ptr = (char *)malloc(3);
+
+ offset = 1;
+
+ __builtin_assume_aligned(ptr + 2, 0x8000, offset);
+ // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:32: runtime error: assumption of 32768 byte alignment (with offset of 1 byte) for pointer of type 'char *' failed
+ // CHECK: 0x{{.*}}: note: offset address is {{.*}} aligned, misalignment offset is {{.*}} byte
+
+ free(ptr);
+
+ return 0;
+}
diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params.cpp
new file mode 100644
index 000000000..724abd540
--- /dev/null
+++ b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-three-params.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+#include <stdlib.h>
+
+int main(int argc, char* argv[]) {
+ char *ptr = (char *)malloc(3);
+
+ __builtin_assume_aligned(ptr + 2, 0x8000, 1);
+ // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:32: runtime error: assumption of 32768 byte alignment (with offset of 1 byte) for pointer of type 'char *' failed
+ // CHECK: 0x{{.*}}: note: offset address is {{.*}} aligned, misalignment offset is {{.*}} byte
+
+ free(ptr);
+
+ return 0;
+}
diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-two-params.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-two-params.cpp
new file mode 100644
index 000000000..2737f3d08
--- /dev/null
+++ b/test/ubsan/TestCases/Pointer/alignment-assumption-builtin_assume_aligned-two-params.cpp
@@ -0,0 +1,23 @@
+// RUN: %clang -x c -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+// RUN: %clang -x c++ -fsanitize=alignment -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+#include <stdlib.h>
+
+int main(int argc, char* argv[]) {
+ char *ptr = (char *)malloc(2);
+
+ __builtin_assume_aligned(ptr + 1, 0x8000);
+ // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-1]]:32: runtime error: assumption of 32768 byte alignment for pointer of type 'char *' failed
+ // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte
+
+ free(ptr);
+
+ return 0;
+}
diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-openmp.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-openmp.cpp
new file mode 100644
index 000000000..482316ee2
--- /dev/null
+++ b/test/ubsan/TestCases/Pointer/alignment-assumption-openmp.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang -x c -fsanitize=alignment -fopenmp-simd -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -fopenmp-simd -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -fopenmp-simd -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c -fsanitize=alignment -fopenmp-simd -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+// RUN: %clang -x c++ -fsanitize=alignment -fopenmp-simd -O0 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -fopenmp-simd -O1 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -fopenmp-simd -O2 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+// RUN: %clang -x c++ -fsanitize=alignment -fopenmp-simd -O3 %s -o %t && %run %t 2>&1 | FileCheck %s --implicit-check-not=" assumption " --implicit-check-not="note:" --implicit-check-not="error:"
+
+#include <stdlib.h>
+
+int main(int argc, char* argv[]) {
+ char *ptr = (char *)malloc(2);
+ char *data = ptr + 1;
+
+ data[0] = 0;
+
+#pragma omp for simd aligned(data : 0x8000)
+ for(int x = 0; x < 1; x++)
+ data[x] = data[x];
+ // CHECK: {{.*}}alignment-assumption-{{.*}}.cpp:[[@LINE-3]]:30: runtime error: assumption of 32768 byte alignment for pointer of type 'char *' failed
+ // CHECK: 0x{{.*}}: note: address is {{.*}} aligned, misalignment offset is {{.*}} byte
+
+ free(ptr);
+
+ return 0;
+}
diff --git a/test/ubsan/TestCases/Pointer/alignment-assumption-summary.cpp b/test/ubsan/TestCases/Pointer/alignment-assumption-summary.cpp
new file mode 100644
index 000000000..cc7769a06
--- /dev/null
+++ b/test/ubsan/TestCases/Pointer/alignment-assumption-summary.cpp
@@ -0,0 +1,17 @@
+// RUN: %clangxx -fsanitize=alignment %s -o %t
+// RUN: %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-NOTYPE
+// RUN: %env_ubsan_opts=report_error_type=1 %run %t 2>&1 | FileCheck %s --check-prefix=CHECK-TYPE
+// REQUIRES: !ubsan-standalone && !ubsan-standalone-static
+
+#include <stdlib.h>
+
+int main(int argc, char* argv[]) {
+ char *ptr = (char *)malloc(2);
+
+ __builtin_assume_aligned(ptr + 1, 0x8000);
+ // CHECK-NOTYPE: SUMMARY: UndefinedBehaviorSanitizer: undefined-behavior {{.*}}summary.cpp:[[@LINE-1]]:32
+ // CHECK-TYPE: SUMMARY: UndefinedBehaviorSanitizer: alignment-assumption {{.*}}summary.cpp:[[@LINE-2]]:32
+ free(ptr);
+
+ return 0;
+}
diff --git a/test/ubsan_minimal/TestCases/alignment-assumption.c b/test/ubsan_minimal/TestCases/alignment-assumption.c
new file mode 100644
index 000000000..ed6fff359
--- /dev/null
+++ b/test/ubsan_minimal/TestCases/alignment-assumption.c
@@ -0,0 +1,17 @@
+// RUN: %clang -fsanitize=alignment %s -o %t && %run %t 2>&1 | FileCheck %s --check-prefixes=CHECK
+
+#include <stdlib.h>
+
+int main(int argc, char* argv[]) {
+// CHECK-NOT: alignment-assumption
+
+char *ptr = (char *)malloc(2);
+
+__builtin_assume_aligned(ptr + 1, 0x8000);
+// CHECK: alignment-assumption
+// CHECK-NOT: alignment-assumption
+
+free(ptr);
+
+return 0;
+}