diff options
author | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:52:22 +0000 |
---|---|---|
committer | Dimitry Andric <dim@FreeBSD.org> | 2019-10-23 17:52:22 +0000 |
commit | 3a1720af1d7f43edc5b214cde0be11bfb94d077e (patch) | |
tree | 029e0ff2d5e3c0eaf2405fd8e669555fdf5e1297 | |
parent | 8f3cadc28cb2bb9e8f9d69eeaaea1f57f2f7b2ab (diff) |
Vendor import of stripped compiler-rt trunk r375505, the last commitvendor/compiler-rt/compiler-rt-trunk-r375505vendor/compiler-rt
before the upstream Subversion repository was made read-only, and the
LLVM project migrated to GitHub:
https://llvm.org/svn/llvm-project/compiler-rt/trunk@375505
Notes
Notes:
svn path=/vendor/compiler-rt/dist/; revision=353944
svn path=/vendor/compiler-rt/compiler-rt-r375505/; revision=353945; tag=vendor/compiler-rt/compiler-rt-trunk-r375505
-rw-r--r-- | include/fuzzer/FuzzedDataProvider.h (renamed from lib/fuzzer/utils/FuzzedDataProvider.h) | 78 | ||||
-rw-r--r-- | include/sanitizer/dfsan_interface.h | 2 | ||||
-rw-r--r-- | include/sanitizer/tsan_interface_atomic.h | 8 | ||||
-rw-r--r-- | include/sanitizer/ubsan_interface.h | 32 | ||||
-rw-r--r-- | lib/asan/asan_activation.cpp (renamed from lib/asan/asan_activation.cc) | 2 | ||||
-rw-r--r-- | lib/asan/asan_allocator.cpp (renamed from lib/asan/asan_allocator.cc) | 4 | ||||
-rw-r--r-- | lib/asan/asan_allocator.h | 2 | ||||
-rw-r--r-- | lib/asan/asan_debugging.cpp (renamed from lib/asan/asan_debugging.cc) | 10 | ||||
-rw-r--r-- | lib/asan/asan_descriptions.cpp (renamed from lib/asan/asan_descriptions.cc) | 2 | ||||
-rw-r--r-- | lib/asan/asan_descriptions.h | 4 | ||||
-rw-r--r-- | lib/asan/asan_errors.cpp (renamed from lib/asan/asan_errors.cc) | 7 | ||||
-rw-r--r-- | lib/asan/asan_errors.h | 3 | ||||
-rw-r--r-- | lib/asan/asan_fake_stack.cpp (renamed from lib/asan/asan_fake_stack.cc) | 2 | ||||
-rw-r--r-- | lib/asan/asan_fake_stack.h | 2 | ||||
-rw-r--r-- | lib/asan/asan_flags.cpp (renamed from lib/asan/asan_flags.cc) | 2 | ||||
-rw-r--r-- | lib/asan/asan_flags.inc | 13 | ||||
-rw-r--r-- | lib/asan/asan_fuchsia.cpp (renamed from lib/asan/asan_fuchsia.cc) | 6 | ||||
-rw-r--r-- | lib/asan/asan_globals.cpp (renamed from lib/asan/asan_globals.cc) | 10 | ||||
-rw-r--r-- | lib/asan/asan_globals_win.cpp (renamed from lib/asan/asan_globals_win.cc) | 10 | ||||
-rw-r--r-- | lib/asan/asan_interceptors.cpp (renamed from lib/asan/asan_interceptors.cc) | 125 | ||||
-rw-r--r-- | lib/asan/asan_interceptors.h | 14 | ||||
-rw-r--r-- | lib/asan/asan_interceptors_memintrinsics.cpp (renamed from lib/asan/asan_interceptors_memintrinsics.cc) | 4 | ||||
-rw-r--r-- | lib/asan/asan_interceptors_memintrinsics.h | 2 | ||||
-rw-r--r-- | lib/asan/asan_internal.h | 12 | ||||
-rw-r--r-- | lib/asan/asan_linux.cpp (renamed from lib/asan/asan_linux.cc) | 2 | ||||
-rw-r--r-- | lib/asan/asan_mac.cpp (renamed from lib/asan/asan_mac.cc) | 4 | ||||
-rw-r--r-- | lib/asan/asan_malloc_linux.cpp (renamed from lib/asan/asan_malloc_linux.cc) | 4 | ||||
-rw-r--r-- | lib/asan/asan_malloc_mac.cpp (renamed from lib/asan/asan_malloc_mac.cc) | 2 | ||||
-rw-r--r-- | lib/asan/asan_malloc_win.cpp (renamed from lib/asan/asan_malloc_win.cc) | 13 | ||||
-rw-r--r-- | lib/asan/asan_memory_profile.cpp (renamed from lib/asan/asan_memory_profile.cc) | 2 | ||||
-rw-r--r-- | lib/asan/asan_new_delete.cpp (renamed from lib/asan/asan_new_delete.cc) | 4 | ||||
-rw-r--r-- | lib/asan/asan_poisoning.cpp (renamed from lib/asan/asan_poisoning.cc) | 4 | ||||
-rw-r--r-- | lib/asan/asan_posix.cpp (renamed from lib/asan/asan_posix.cc) | 6 | ||||
-rw-r--r-- | lib/asan/asan_preinit.cpp (renamed from lib/asan/asan_preinit.cc) | 2 | ||||
-rw-r--r-- | lib/asan/asan_premap_shadow.cpp (renamed from lib/asan/asan_premap_shadow.cc) | 2 | ||||
-rw-r--r-- | lib/asan/asan_report.cpp (renamed from lib/asan/asan_report.cc) | 12 | ||||
-rw-r--r-- | lib/asan/asan_rtems.cpp (renamed from lib/asan/asan_rtems.cc) | 6 | ||||
-rw-r--r-- | lib/asan/asan_rtl.cpp (renamed from lib/asan/asan_rtl.cc) | 8 | ||||
-rw-r--r-- | lib/asan/asan_scariness_score.h | 2 | ||||
-rw-r--r-- | lib/asan/asan_shadow_setup.cpp (renamed from lib/asan/asan_shadow_setup.cc) | 7 | ||||
-rw-r--r-- | lib/asan/asan_stack.cpp (renamed from lib/asan/asan_stack.cc) | 2 | ||||
-rw-r--r-- | lib/asan/asan_stack.h | 2 | ||||
-rw-r--r-- | lib/asan/asan_stats.cpp (renamed from lib/asan/asan_stats.cc) | 4 | ||||
-rw-r--r-- | lib/asan/asan_suppressions.cpp (renamed from lib/asan/asan_suppressions.cc) | 4 | ||||
-rw-r--r-- | lib/asan/asan_suppressions.h | 2 | ||||
-rw-r--r-- | lib/asan/asan_thread.cpp (renamed from lib/asan/asan_thread.cc) | 7 | ||||
-rw-r--r-- | lib/asan/asan_thread.h | 2 | ||||
-rw-r--r-- | lib/asan/asan_win.cpp (renamed from lib/asan/asan_win.cc) | 12 | ||||
-rw-r--r-- | lib/asan/asan_win_dll_thunk.cpp (renamed from lib/asan/asan_win_dll_thunk.cc) | 12 | ||||
-rw-r--r-- | lib/asan/asan_win_dynamic_runtime_thunk.cpp (renamed from lib/asan/asan_win_dynamic_runtime_thunk.cc) | 16 | ||||
-rw-r--r-- | lib/asan/asan_win_weak_interception.cpp (renamed from lib/asan/asan_win_weak_interception.cc) | 2 | ||||
-rw-r--r-- | lib/builtins/aarch64/fp_mode.c | 59 | ||||
-rw-r--r-- | lib/builtins/adddf3.c | 3 | ||||
-rw-r--r-- | lib/builtins/addsf3.c | 3 | ||||
-rw-r--r-- | lib/builtins/addtf3.c | 5 | ||||
-rw-r--r-- | lib/builtins/arm/fp_mode.c | 59 | ||||
-rw-r--r-- | lib/builtins/atomic.c | 4 | ||||
-rw-r--r-- | lib/builtins/clear_cache.c | 68 | ||||
-rw-r--r-- | lib/builtins/cpu_model.c | 12 | ||||
-rw-r--r-- | lib/builtins/divtf3.c | 2 | ||||
-rw-r--r-- | lib/builtins/emutls.c | 11 | ||||
-rw-r--r-- | lib/builtins/extenddftf2.c | 2 | ||||
-rw-r--r-- | lib/builtins/extendsftf2.c | 2 | ||||
-rw-r--r-- | lib/builtins/fixunsxfdi.c | 11 | ||||
-rw-r--r-- | lib/builtins/fixunsxfsi.c | 11 | ||||
-rw-r--r-- | lib/builtins/fixxfdi.c | 11 | ||||
-rw-r--r-- | lib/builtins/fp_add_impl.inc | 27 | ||||
-rw-r--r-- | lib/builtins/fp_lib.h | 2 | ||||
-rw-r--r-- | lib/builtins/fp_mode.c | 24 | ||||
-rw-r--r-- | lib/builtins/fp_mode.h | 29 | ||||
-rw-r--r-- | lib/builtins/fp_trunc_impl.inc | 2 | ||||
-rw-r--r-- | lib/builtins/subdf3.c | 3 | ||||
-rw-r--r-- | lib/builtins/subsf3.c | 3 | ||||
-rw-r--r-- | lib/builtins/subtf3.c | 3 | ||||
-rw-r--r-- | lib/builtins/udivmoddi4.c | 11 | ||||
-rw-r--r-- | lib/dfsan/dfsan.cpp (renamed from lib/dfsan/dfsan.cc) | 2 | ||||
-rw-r--r-- | lib/dfsan/dfsan_custom.cpp (renamed from lib/dfsan/dfsan_custom.cc) | 4 | ||||
-rw-r--r-- | lib/dfsan/dfsan_interceptors.cpp (renamed from lib/dfsan/dfsan_interceptors.cc) | 2 | ||||
-rw-r--r-- | lib/fuzzer/FuzzerBuiltinsMsvc.h | 22 | ||||
-rw-r--r-- | lib/fuzzer/FuzzerDefs.h | 5 | ||||
-rw-r--r-- | lib/fuzzer/FuzzerDriver.cpp | 1 | ||||
-rw-r--r-- | lib/fuzzer/FuzzerExtFunctions.def | 11 | ||||
-rw-r--r-- | lib/fuzzer/FuzzerFlags.def | 3 | ||||
-rw-r--r-- | lib/fuzzer/FuzzerInternal.h | 3 | ||||
-rw-r--r-- | lib/fuzzer/FuzzerLoop.cpp | 19 | ||||
-rw-r--r-- | lib/fuzzer/FuzzerMerge.cpp | 82 | ||||
-rw-r--r-- | lib/fuzzer/FuzzerOptions.h | 1 | ||||
-rw-r--r-- | lib/fuzzer/FuzzerTracePC.cpp | 41 | ||||
-rw-r--r-- | lib/fuzzer/FuzzerTracePC.h | 3 | ||||
-rw-r--r-- | lib/fuzzer/FuzzerUtil.h | 2 | ||||
-rw-r--r-- | lib/fuzzer/FuzzerUtilFuchsia.cpp | 26 | ||||
-rw-r--r-- | lib/fuzzer/FuzzerUtilPosix.cpp | 6 | ||||
-rw-r--r-- | lib/fuzzer/FuzzerUtilWindows.cpp | 4 | ||||
-rw-r--r-- | lib/gwp_asan/guarded_pool_allocator.cpp | 61 | ||||
-rw-r--r-- | lib/gwp_asan/guarded_pool_allocator.h | 21 | ||||
-rw-r--r-- | lib/gwp_asan/optional/backtrace.h | 7 | ||||
-rw-r--r-- | lib/gwp_asan/optional/backtrace_linux_libc.cpp | 22 | ||||
-rw-r--r-- | lib/gwp_asan/optional/backtrace_sanitizer_common.cpp | 29 | ||||
-rw-r--r-- | lib/gwp_asan/options.h | 69 | ||||
-rw-r--r-- | lib/gwp_asan/options.inc | 6 | ||||
-rwxr-xr-x | lib/gwp_asan/scripts/symbolize.sh | 55 | ||||
-rw-r--r-- | lib/gwp_asan/stack_trace_compressor.cpp | 111 | ||||
-rw-r--r-- | lib/gwp_asan/stack_trace_compressor.h | 38 | ||||
-rw-r--r-- | lib/hwasan/hwasan.cpp | 155 | ||||
-rw-r--r-- | lib/hwasan/hwasan.h | 2 | ||||
-rw-r--r-- | lib/hwasan/hwasan_allocator.cpp | 29 | ||||
-rw-r--r-- | lib/hwasan/hwasan_allocator.h | 6 | ||||
-rw-r--r-- | lib/hwasan/hwasan_exceptions.cpp | 67 | ||||
-rw-r--r-- | lib/hwasan/hwasan_flags.inc | 2 | ||||
-rw-r--r-- | lib/hwasan/hwasan_interceptors.cpp | 2 | ||||
-rw-r--r-- | lib/hwasan/hwasan_interface_internal.h | 9 | ||||
-rw-r--r-- | lib/hwasan/hwasan_linux.cpp | 42 | ||||
-rw-r--r-- | lib/hwasan/hwasan_new_delete.cpp | 2 | ||||
-rw-r--r-- | lib/hwasan/hwasan_report.cpp | 25 | ||||
-rw-r--r-- | lib/hwasan/hwasan_tag_mismatch_aarch64.S | 50 | ||||
-rw-r--r-- | lib/interception/interception.h | 4 | ||||
-rw-r--r-- | lib/interception/interception_linux.cpp (renamed from lib/interception/interception_linux.cc) | 2 | ||||
-rw-r--r-- | lib/interception/interception_mac.cpp (renamed from lib/interception/interception_mac.cc) | 2 | ||||
-rw-r--r-- | lib/interception/interception_type_test.cpp (renamed from lib/interception/interception_type_test.cc) | 2 | ||||
-rw-r--r-- | lib/interception/interception_win.cpp (renamed from lib/interception/interception_win.cc) | 10 | ||||
-rw-r--r-- | lib/lsan/lsan.cpp (renamed from lib/lsan/lsan.cc) | 6 | ||||
-rw-r--r-- | lib/lsan/lsan_allocator.cpp (renamed from lib/lsan/lsan_allocator.cc) | 2 | ||||
-rw-r--r-- | lib/lsan/lsan_common.cpp (renamed from lib/lsan/lsan_common.cc) | 18 | ||||
-rw-r--r-- | lib/lsan/lsan_common.h | 5 | ||||
-rw-r--r-- | lib/lsan/lsan_common_linux.cpp (renamed from lib/lsan/lsan_common_linux.cc) | 14 | ||||
-rw-r--r-- | lib/lsan/lsan_common_mac.cpp (renamed from lib/lsan/lsan_common_mac.cc) | 8 | ||||
-rw-r--r-- | lib/lsan/lsan_interceptors.cpp (renamed from lib/lsan/lsan_interceptors.cc) | 57 | ||||
-rw-r--r-- | lib/lsan/lsan_linux.cpp (renamed from lib/lsan/lsan_linux.cc) | 2 | ||||
-rw-r--r-- | lib/lsan/lsan_mac.cpp (renamed from lib/lsan/lsan_mac.cc) | 4 | ||||
-rw-r--r-- | lib/lsan/lsan_malloc_mac.cpp (renamed from lib/lsan/lsan_malloc_mac.cc) | 2 | ||||
-rw-r--r-- | lib/lsan/lsan_preinit.cpp (renamed from lib/lsan/lsan_preinit.cc) | 2 | ||||
-rw-r--r-- | lib/lsan/lsan_thread.cpp (renamed from lib/lsan/lsan_thread.cc) | 2 | ||||
-rw-r--r-- | lib/msan/msan.cpp (renamed from lib/msan/msan.cc) | 10 | ||||
-rw-r--r-- | lib/msan/msan.h | 11 | ||||
-rw-r--r-- | lib/msan/msan_allocator.cpp (renamed from lib/msan/msan_allocator.cc) | 2 | ||||
-rw-r--r-- | lib/msan/msan_chained_origin_depot.cpp (renamed from lib/msan/msan_chained_origin_depot.cc) | 2 | ||||
-rw-r--r-- | lib/msan/msan_interceptors.cpp (renamed from lib/msan/msan_interceptors.cc) | 93 | ||||
-rw-r--r-- | lib/msan/msan_linux.cpp (renamed from lib/msan/msan_linux.cc) | 8 | ||||
-rw-r--r-- | lib/msan/msan_new_delete.cpp (renamed from lib/msan/msan_new_delete.cc) | 4 | ||||
-rw-r--r-- | lib/msan/msan_poisoning.cpp (renamed from lib/msan/msan_poisoning.cc) | 2 | ||||
-rw-r--r-- | lib/msan/msan_report.cpp (renamed from lib/msan/msan_report.cc) | 2 | ||||
-rw-r--r-- | lib/msan/msan_thread.cpp (renamed from lib/msan/msan_thread.cc) | 0 | ||||
-rw-r--r-- | lib/profile/InstrProfiling.h | 17 | ||||
-rw-r--r-- | lib/profile/InstrProfilingFile.c | 11 | ||||
-rw-r--r-- | lib/profile/InstrProfilingPlatformFuchsia.c | 93 | ||||
-rw-r--r-- | lib/profile/InstrProfilingRuntime.cpp (renamed from lib/profile/InstrProfilingRuntime.cc) | 0 | ||||
-rw-r--r-- | lib/profile/InstrProfilingUtil.c | 20 | ||||
-rw-r--r-- | lib/safestack/safestack.cpp (renamed from lib/safestack/safestack.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sancov_flags.cpp (renamed from lib/sanitizer_common/sancov_flags.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_allocator.cpp (renamed from lib/sanitizer_common/sanitizer_allocator.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_allocator_checks.cpp (renamed from lib/sanitizer_common/sanitizer_allocator_checks.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_allocator_checks.h | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_allocator_report.cpp (renamed from lib/sanitizer_common/sanitizer_allocator_report.cc) | 11 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_asm.h | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_atomic_msvc.h | 63 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_common.cpp (renamed from lib/sanitizer_common/sanitizer_common.cc) | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_common.h | 29 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_common_interceptors.inc | 144 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_common_interface.inc | 1 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_common_libcdep.cpp (renamed from lib/sanitizer_common/sanitizer_common_libcdep.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_common_nolibc.cpp (renamed from lib/sanitizer_common/sanitizer_common_nolibc.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_common_syscalls.inc | 12 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_coverage_fuchsia.cpp (renamed from lib/sanitizer_common/sanitizer_coverage_fuchsia.cc) | 8 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_coverage_libcdep_new.cpp (renamed from lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc) | 6 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_coverage_win_dll_thunk.cpp (renamed from lib/sanitizer_common/sanitizer_coverage_win_dll_thunk.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cpp (renamed from lib/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_coverage_win_sections.cpp (renamed from lib/sanitizer_common/sanitizer_coverage_win_sections.cc) | 14 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_coverage_win_weak_interception.cpp (renamed from lib/sanitizer_common/sanitizer_coverage_win_weak_interception.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_deadlock_detector1.cpp (renamed from lib/sanitizer_common/sanitizer_deadlock_detector1.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_deadlock_detector2.cpp (renamed from lib/sanitizer_common/sanitizer_deadlock_detector2.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_errno.cpp (renamed from lib/sanitizer_common/sanitizer_errno.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_file.cpp (renamed from lib/sanitizer_common/sanitizer_file.cc) | 6 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_flag_parser.cpp (renamed from lib/sanitizer_common/sanitizer_flag_parser.cc) | 5 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_flag_parser.h | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_flags.cpp (renamed from lib/sanitizer_common/sanitizer_flags.cc) | 6 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_fuchsia.cpp (renamed from lib/sanitizer_common/sanitizer_fuchsia.cc) | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_getauxval.h | 30 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_glibc_version.h | 26 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc | 31 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_internal_defs.h | 75 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_libc.cpp (renamed from lib/sanitizer_common/sanitizer_libc.cc) | 13 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_libignore.cpp (renamed from lib/sanitizer_common/sanitizer_libignore.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_linux.cpp (renamed from lib/sanitizer_common/sanitizer_linux.cc) | 47 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_linux_libcdep.cpp (renamed from lib/sanitizer_common/sanitizer_linux_libcdep.cc) | 9 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_linux_s390.cpp (renamed from lib/sanitizer_common/sanitizer_linux_s390.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_mac.cpp (renamed from lib/sanitizer_common/sanitizer_mac.cc) | 126 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_mac_libcdep.cpp (renamed from lib/sanitizer_common/sanitizer_mac_libcdep.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_malloc_mac.inc | 11 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_netbsd.cpp (renamed from lib/sanitizer_common/sanitizer_netbsd.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_openbsd.cpp (renamed from lib/sanitizer_common/sanitizer_openbsd.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_persistent_allocator.cpp (renamed from lib/sanitizer_common/sanitizer_persistent_allocator.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_interceptors.h | 24 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp (renamed from lib/sanitizer_common/sanitizer_platform_limits_freebsd.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_freebsd.h | 1090 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_linux.cpp (renamed from lib/sanitizer_common/sanitizer_platform_limits_linux.cc) | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp (renamed from lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc) | 60 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_netbsd.h | 47 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_openbsd.cpp (renamed from lib/sanitizer_common/sanitizer_platform_limits_openbsd.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_posix.cpp (renamed from lib/sanitizer_common/sanitizer_platform_limits_posix.cc) | 17 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_posix.h | 2168 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_solaris.cpp (renamed from lib/sanitizer_common/sanitizer_platform_limits_solaris.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_platform_limits_solaris.h | 7 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_posix.cpp (renamed from lib/sanitizer_common/sanitizer_posix.cc) | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_posix.h | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_posix_libcdep.cpp (renamed from lib/sanitizer_common/sanitizer_posix_libcdep.cc) | 37 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_printf.cpp (renamed from lib/sanitizer_common/sanitizer_printf.cc) | 8 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_procmaps.h | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_procmaps_bsd.cpp (renamed from lib/sanitizer_common/sanitizer_procmaps_bsd.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_procmaps_common.cpp (renamed from lib/sanitizer_common/sanitizer_procmaps_common.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_procmaps_linux.cpp (renamed from lib/sanitizer_common/sanitizer_procmaps_linux.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_procmaps_mac.cpp (renamed from lib/sanitizer_common/sanitizer_procmaps_mac.cc) | 27 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_procmaps_solaris.cpp (renamed from lib/sanitizer_common/sanitizer_procmaps_solaris.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_rtems.cpp (renamed from lib/sanitizer_common/sanitizer_rtems.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_solaris.cpp (renamed from lib/sanitizer_common/sanitizer_solaris.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_stackdepot.cpp (renamed from lib/sanitizer_common/sanitizer_stackdepot.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_stacktrace.cpp (renamed from lib/sanitizer_common/sanitizer_stacktrace.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp (renamed from lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc) | 7 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_stacktrace_printer.cpp (renamed from lib/sanitizer_common/sanitizer_stacktrace_printer.cc) | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_stacktrace_sparc.cpp (renamed from lib/sanitizer_common/sanitizer_stacktrace_sparc.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp (renamed from lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc) | 7 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_stoptheworld_mac.cpp (renamed from lib/sanitizer_common/sanitizer_stoptheworld_mac.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp (renamed from lib/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cc) | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_suppressions.cpp (renamed from lib/sanitizer_common/sanitizer_suppressions.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_suppressions.h | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer.cpp (renamed from lib/sanitizer_common/sanitizer_symbolizer.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer_internal.h | 19 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cpp (renamed from lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp (renamed from lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc) | 11 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer_mac.cpp (renamed from lib/sanitizer_common/sanitizer_symbolizer_mac.cc) | 9 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer_markup.cpp (renamed from lib/sanitizer_common/sanitizer_symbolizer_markup.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp (renamed from lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc) | 84 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer_report.cpp (renamed from lib/sanitizer_common/sanitizer_symbolizer_report.cc) | 22 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_symbolizer_win.cpp (renamed from lib/sanitizer_common/sanitizer_symbolizer_win.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_termination.cpp (renamed from lib/sanitizer_common/sanitizer_termination.cc) | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_thread_registry.cpp (renamed from lib/sanitizer_common/sanitizer_thread_registry.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_tls_get_addr.cpp (renamed from lib/sanitizer_common/sanitizer_tls_get_addr.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_tls_get_addr.h | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_type_traits.cpp (renamed from lib/sanitizer_common/sanitizer_type_traits.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp (renamed from lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc) | 70 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_unwind_win.cpp (renamed from lib/sanitizer_common/sanitizer_unwind_win.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_vector.h | 6 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_win.cpp (renamed from lib/sanitizer_common/sanitizer_win.cc) | 19 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_win_defs.h | 12 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_win_dll_thunk.cpp (renamed from lib/sanitizer_common/sanitizer_win_dll_thunk.cc) | 10 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cpp (renamed from lib/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cc) | 2 | ||||
-rw-r--r-- | lib/sanitizer_common/sanitizer_win_weak_interception.cpp (renamed from lib/sanitizer_common/sanitizer_win_weak_interception.cc) | 11 | ||||
-rw-r--r-- | lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp (renamed from lib/sanitizer_common/symbolizer/sanitizer_symbolize.cc) | 4 | ||||
-rw-r--r-- | lib/sanitizer_common/symbolizer/sanitizer_wrappers.cpp (renamed from lib/sanitizer_common/symbolizer/sanitizer_wrappers.cc) | 2 | ||||
-rwxr-xr-x | lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh | 34 | ||||
-rw-r--r-- | lib/sanitizer_common/symbolizer/scripts/global_symbols.txt | 7 | ||||
-rw-r--r-- | lib/scudo/scudo_allocator_secondary.h | 28 | ||||
-rw-r--r-- | lib/scudo/scudo_errors.cpp | 5 | ||||
-rw-r--r-- | lib/scudo/standalone/allocator_config.h | 4 | ||||
-rw-r--r-- | lib/scudo/standalone/checksum.cpp (renamed from lib/scudo/standalone/checksum.cc) | 2 | ||||
-rw-r--r-- | lib/scudo/standalone/chunk.h | 26 | ||||
-rw-r--r-- | lib/scudo/standalone/combined.h | 131 | ||||
-rw-r--r-- | lib/scudo/standalone/common.cpp (renamed from lib/scudo/standalone/common.cc) | 2 | ||||
-rw-r--r-- | lib/scudo/standalone/crc32_hw.cpp (renamed from lib/scudo/standalone/crc32_hw.cc) | 2 | ||||
-rw-r--r-- | lib/scudo/standalone/flags.cpp (renamed from lib/scudo/standalone/flags.cc) | 2 | ||||
-rw-r--r-- | lib/scudo/standalone/flags_parser.cpp (renamed from lib/scudo/standalone/flags_parser.cc) | 2 | ||||
-rw-r--r-- | lib/scudo/standalone/fuchsia.cpp (renamed from lib/scudo/standalone/fuchsia.cc) | 14 | ||||
-rw-r--r-- | lib/scudo/standalone/internal_defs.h | 4 | ||||
-rw-r--r-- | lib/scudo/standalone/linux.cpp (renamed from lib/scudo/standalone/linux.cc) | 4 | ||||
-rw-r--r-- | lib/scudo/standalone/linux.h | 2 | ||||
-rw-r--r-- | lib/scudo/standalone/list.h | 12 | ||||
-rw-r--r-- | lib/scudo/standalone/local_cache.h | 16 | ||||
-rw-r--r-- | lib/scudo/standalone/mutex.h | 6 | ||||
-rw-r--r-- | lib/scudo/standalone/primary32.h | 60 | ||||
-rw-r--r-- | lib/scudo/standalone/primary64.h | 89 | ||||
-rw-r--r-- | lib/scudo/standalone/quarantine.h | 20 | ||||
-rw-r--r-- | lib/scudo/standalone/report.cpp (renamed from lib/scudo/standalone/report.cc) | 2 | ||||
-rw-r--r-- | lib/scudo/standalone/secondary.cpp (renamed from lib/scudo/standalone/secondary.cc) | 27 | ||||
-rw-r--r-- | lib/scudo/standalone/secondary.h | 5 | ||||
-rw-r--r-- | lib/scudo/standalone/size_class_map.h | 16 | ||||
-rw-r--r-- | lib/scudo/standalone/stats.h | 2 | ||||
-rw-r--r-- | lib/scudo/standalone/string_utils.cpp (renamed from lib/scudo/standalone/string_utils.cc) | 24 | ||||
-rw-r--r-- | lib/scudo/standalone/string_utils.h | 1 | ||||
-rw-r--r-- | lib/scudo/standalone/tsd_exclusive.h | 4 | ||||
-rw-r--r-- | lib/scudo/standalone/tsd_shared.h | 5 | ||||
-rw-r--r-- | lib/scudo/standalone/wrappers_c.cpp (renamed from lib/scudo/standalone/wrappers_c.cc) | 2 | ||||
-rw-r--r-- | lib/scudo/standalone/wrappers_c.inc | 16 | ||||
-rw-r--r-- | lib/scudo/standalone/wrappers_c_bionic.cpp (renamed from lib/scudo/standalone/wrappers_c_bionic.cc) | 2 | ||||
-rw-r--r-- | lib/scudo/standalone/wrappers_cpp.cpp (renamed from lib/scudo/standalone/wrappers_cpp.cc) | 2 | ||||
-rw-r--r-- | lib/stats/stats.cpp (renamed from lib/stats/stats.cc) | 2 | ||||
-rw-r--r-- | lib/stats/stats_client.cpp (renamed from lib/stats/stats_client.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/benchmarks/func_entry_exit.cpp (renamed from lib/tsan/benchmarks/func_entry_exit.cc) | 0 | ||||
-rw-r--r-- | lib/tsan/benchmarks/mini_bench_local.cpp (renamed from lib/tsan/benchmarks/mini_bench_local.cc) | 0 | ||||
-rw-r--r-- | lib/tsan/benchmarks/mini_bench_shared.cpp (renamed from lib/tsan/benchmarks/mini_bench_shared.cc) | 0 | ||||
-rw-r--r-- | lib/tsan/benchmarks/mop.cpp (renamed from lib/tsan/benchmarks/mop.cc) | 0 | ||||
-rw-r--r-- | lib/tsan/benchmarks/start_many_threads.cpp (renamed from lib/tsan/benchmarks/start_many_threads.cc) | 0 | ||||
-rw-r--r-- | lib/tsan/benchmarks/vts_many_threads_bench.cpp (renamed from lib/tsan/benchmarks/vts_many_threads_bench.cc) | 0 | ||||
-rw-r--r-- | lib/tsan/dd/dd_interceptors.cpp (renamed from lib/tsan/dd/dd_interceptors.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/dd/dd_rtl.cpp (renamed from lib/tsan/dd/dd_rtl.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/go/tsan_go.cpp (renamed from lib/tsan/go/tsan_go.cc) | 27 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_clock.cpp (renamed from lib/tsan/rtl/tsan_clock.cc) | 4 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_debugging.cpp (renamed from lib/tsan/rtl/tsan_debugging.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_dispatch_defs.h | 14 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_external.cpp (renamed from lib/tsan/rtl/tsan_external.cc) | 4 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_fd.cpp (renamed from lib/tsan/rtl/tsan_fd.cc) | 5 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_flags.cpp (renamed from lib/tsan/rtl/tsan_flags.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_ignoreset.cpp (renamed from lib/tsan/rtl/tsan_ignoreset.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interceptors_libdispatch.cpp (renamed from lib/tsan/rtl/tsan_libdispatch.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interceptors_mac.cpp (renamed from lib/tsan/rtl/tsan_interceptors_mac.cc) | 44 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interceptors_mach_vm.cpp | 52 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interceptors_posix.cpp (renamed from lib/tsan/rtl/tsan_interceptors.cc) | 47 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interface.cpp (renamed from lib/tsan/rtl/tsan_interface.cc) | 4 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interface.h | 13 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interface_ann.cpp (renamed from lib/tsan/rtl/tsan_interface_ann.cc) | 6 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interface_atomic.cpp (renamed from lib/tsan/rtl/tsan_interface_atomic.cc) | 4 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interface_inl.h | 10 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interface_java.cpp (renamed from lib/tsan/rtl/tsan_interface_java.cc) | 4 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_interface_java.h | 4 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_malloc_mac.cpp (renamed from lib/tsan/rtl/tsan_malloc_mac.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_md5.cpp (renamed from lib/tsan/rtl/tsan_md5.cc) | 4 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_mman.cpp (renamed from lib/tsan/rtl/tsan_mman.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_mman.h | 5 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_mutex.cpp (renamed from lib/tsan/rtl/tsan_mutex.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_mutexset.cpp (renamed from lib/tsan/rtl/tsan_mutexset.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_new_delete.cpp (renamed from lib/tsan/rtl/tsan_new_delete.cc) | 4 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_platform.h | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_platform_linux.cpp (renamed from lib/tsan/rtl/tsan_platform_linux.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_platform_mac.cpp (renamed from lib/tsan/rtl/tsan_platform_mac.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_platform_posix.cpp (renamed from lib/tsan/rtl/tsan_platform_posix.cc) | 11 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_platform_windows.cpp (renamed from lib/tsan/rtl/tsan_platform_windows.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_preinit.cpp (renamed from lib/tsan/rtl/tsan_preinit.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_report.cpp (renamed from lib/tsan/rtl/tsan_report.cc) | 4 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_rtl.cpp (renamed from lib/tsan/rtl/tsan_rtl.cc) | 24 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_rtl.h | 5 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_rtl_mutex.cpp (renamed from lib/tsan/rtl/tsan_rtl_mutex.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_rtl_proc.cpp (renamed from lib/tsan/rtl/tsan_rtl_proc.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_rtl_report.cpp (renamed from lib/tsan/rtl/tsan_rtl_report.cc) | 9 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_rtl_thread.cpp (renamed from lib/tsan/rtl/tsan_rtl_thread.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_stack_trace.cpp (renamed from lib/tsan/rtl/tsan_stack_trace.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_stat.cpp (renamed from lib/tsan/rtl/tsan_stat.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_suppressions.cpp (renamed from lib/tsan/rtl/tsan_suppressions.cc) | 4 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_symbolize.cpp (renamed from lib/tsan/rtl/tsan_symbolize.cc) | 2 | ||||
-rw-r--r-- | lib/tsan/rtl/tsan_sync.cpp (renamed from lib/tsan/rtl/tsan_sync.cc) | 2 | ||||
-rw-r--r-- | lib/ubsan/ubsan_checks.inc | 5 | ||||
-rw-r--r-- | lib/ubsan/ubsan_diag.cpp (renamed from lib/ubsan/ubsan_diag.cc) | 4 | ||||
-rw-r--r-- | lib/ubsan/ubsan_diag_standalone.cpp (renamed from lib/ubsan/ubsan_diag_standalone.cc) | 2 | ||||
-rw-r--r-- | lib/ubsan/ubsan_flags.cpp (renamed from lib/ubsan/ubsan_flags.cc) | 3 | ||||
-rw-r--r-- | lib/ubsan/ubsan_handlers.cpp (renamed from lib/ubsan/ubsan_handlers.cc) | 25 | ||||
-rw-r--r-- | lib/ubsan/ubsan_handlers_cxx.cpp (renamed from lib/ubsan/ubsan_handlers_cxx.cc) | 2 | ||||
-rw-r--r-- | lib/ubsan/ubsan_init.cpp (renamed from lib/ubsan/ubsan_init.cc) | 2 | ||||
-rw-r--r-- | lib/ubsan/ubsan_init_standalone.cpp (renamed from lib/ubsan/ubsan_init_standalone.cc) | 2 | ||||
-rw-r--r-- | lib/ubsan/ubsan_init_standalone_preinit.cpp (renamed from lib/ubsan/ubsan_init_standalone_preinit.cc) | 2 | ||||
-rw-r--r-- | lib/ubsan/ubsan_monitor.cpp (renamed from lib/ubsan/ubsan_monitor.cc) | 2 | ||||
-rw-r--r-- | lib/ubsan/ubsan_signals_standalone.cpp (renamed from lib/ubsan/ubsan_signals_standalone.cc) | 8 | ||||
-rw-r--r-- | lib/ubsan/ubsan_type_hash.cpp (renamed from lib/ubsan/ubsan_type_hash.cc) | 4 | ||||
-rw-r--r-- | lib/ubsan/ubsan_type_hash_itanium.cpp (renamed from lib/ubsan/ubsan_type_hash_itanium.cc) | 2 | ||||
-rw-r--r-- | lib/ubsan/ubsan_type_hash_win.cpp (renamed from lib/ubsan/ubsan_type_hash_win.cc) | 2 | ||||
-rw-r--r-- | lib/ubsan/ubsan_value.cpp (renamed from lib/ubsan/ubsan_value.cc) | 2 | ||||
-rw-r--r-- | lib/ubsan/ubsan_win_dll_thunk.cpp (renamed from lib/ubsan/ubsan_win_dll_thunk.cc) | 2 | ||||
-rw-r--r-- | lib/ubsan/ubsan_win_dynamic_runtime_thunk.cpp (renamed from lib/ubsan/ubsan_win_dynamic_runtime_thunk.cc) | 2 | ||||
-rw-r--r-- | lib/ubsan/ubsan_win_weak_interception.cpp (renamed from lib/ubsan/ubsan_win_weak_interception.cc) | 2 | ||||
-rw-r--r-- | lib/ubsan_minimal/ubsan_minimal_handlers.cpp (renamed from lib/ubsan_minimal/ubsan_minimal_handlers.cc) | 0 | ||||
-rw-r--r-- | lib/xray/xray_AArch64.cpp (renamed from lib/xray/xray_AArch64.cc) | 2 | ||||
-rw-r--r-- | lib/xray/xray_arm.cpp (renamed from lib/xray/xray_arm.cc) | 2 | ||||
-rw-r--r-- | lib/xray/xray_basic_flags.cpp (renamed from lib/xray/xray_basic_flags.cc) | 2 | ||||
-rw-r--r-- | lib/xray/xray_basic_logging.cpp (renamed from lib/xray/xray_basic_logging.cc) | 2 | ||||
-rw-r--r-- | lib/xray/xray_buffer_queue.cpp (renamed from lib/xray/xray_buffer_queue.cc) | 2 | ||||
-rw-r--r-- | lib/xray/xray_fdr_flags.cpp (renamed from lib/xray/xray_fdr_flags.cc) | 2 | ||||
-rw-r--r-- | lib/xray/xray_fdr_logging.cpp (renamed from lib/xray/xray_fdr_logging.cc) | 2 | ||||
-rw-r--r-- | lib/xray/xray_flags.cpp (renamed from lib/xray/xray_flags.cc) | 2 | ||||
-rw-r--r-- | lib/xray/xray_init.cpp (renamed from lib/xray/xray_init.cc) | 2 | ||||
-rw-r--r-- | lib/xray/xray_interface.cpp (renamed from lib/xray/xray_interface.cc) | 0 | ||||
-rw-r--r-- | lib/xray/xray_log_interface.cpp (renamed from lib/xray/xray_log_interface.cc) | 2 | ||||
-rw-r--r-- | lib/xray/xray_mips.cpp (renamed from lib/xray/xray_mips.cc) | 2 | ||||
-rw-r--r-- | lib/xray/xray_mips64.cpp (renamed from lib/xray/xray_mips64.cc) | 2 | ||||
-rw-r--r-- | lib/xray/xray_powerpc64.cpp (renamed from lib/xray/xray_powerpc64.cc) | 2 | ||||
-rw-r--r-- | lib/xray/xray_profile_collector.cpp (renamed from lib/xray/xray_profile_collector.cc) | 2 | ||||
-rw-r--r-- | lib/xray/xray_profiling.cpp (renamed from lib/xray/xray_profiling.cc) | 2 | ||||
-rw-r--r-- | lib/xray/xray_profiling_flags.cpp (renamed from lib/xray/xray_profiling_flags.cc) | 0 | ||||
-rw-r--r-- | lib/xray/xray_trampoline_powerpc64.cpp (renamed from lib/xray/xray_trampoline_powerpc64.cc) | 0 | ||||
-rw-r--r-- | lib/xray/xray_utils.cpp (renamed from lib/xray/xray_utils.cc) | 2 | ||||
-rw-r--r-- | lib/xray/xray_x86_64.cpp (renamed from lib/xray/xray_x86_64.cc) | 0 | ||||
-rw-r--r-- | tools/CMakeLists.txt | 1 | ||||
-rw-r--r-- | tools/gwp_asan/CMakeLists.txt | 20 | ||||
-rw-r--r-- | tools/gwp_asan/stack_trace_compressor_fuzzer.cpp | 49 |
379 files changed, 4901 insertions, 3125 deletions
diff --git a/lib/fuzzer/utils/FuzzedDataProvider.h b/include/fuzzer/FuzzedDataProvider.h index 1b5b4bb01269..fd895b767d9e 100644 --- a/lib/fuzzer/utils/FuzzedDataProvider.h +++ b/include/fuzzer/FuzzedDataProvider.h @@ -13,11 +13,10 @@ #ifndef LLVM_FUZZER_FUZZED_DATA_PROVIDER_H_ #define LLVM_FUZZER_FUZZED_DATA_PROVIDER_H_ -#include <limits.h> -#include <stddef.h> -#include <stdint.h> - #include <algorithm> +#include <climits> +#include <cstddef> +#include <cstdint> #include <cstring> #include <initializer_list> #include <string> @@ -25,8 +24,10 @@ #include <utility> #include <vector> +// In addition to the comments below, the API is also briefly documented at +// https://github.com/google/fuzzing/blob/master/docs/split-inputs.md#fuzzed-data-provider class FuzzedDataProvider { -public: + public: // |data| is an array of length |size| that the FuzzedDataProvider wraps to // provide more granular access. |data| must outlive the FuzzedDataProvider. FuzzedDataProvider(const uint8_t *data, size_t size) @@ -143,9 +144,9 @@ public: return ConsumeBytes<T>(remaining_bytes_); } + // Returns a std::string containing all remaining bytes of the input data. // Prefer using |ConsumeRemainingBytes| unless you actually need a std::string // object. - // Returns a std::vector containing all remaining bytes of the input data. std::string ConsumeRemainingBytesAsString() { return ConsumeBytesAsString(remaining_bytes_); } @@ -161,7 +162,7 @@ public: // Reads one byte and returns a bool, or false when no data remains. bool ConsumeBool() { return 1 & ConsumeIntegral<uint8_t>(); } - // Returns a copy of a value selected from a fixed-size |array|. + // Returns a copy of the value selected from the given fixed-size |array|. template <typename T, size_t size> T PickValueInArray(const T (&array)[size]) { static_assert(size > 0, "The array must be non empty."); @@ -170,11 +171,14 @@ public: template <typename T> T PickValueInArray(std::initializer_list<const T> list) { - // static_assert(list.size() > 0, "The array must be non empty."); + // TODO(Dor1s): switch to static_assert once C++14 is allowed. + if (!list.size()) + abort(); + return *(list.begin() + ConsumeIntegralInRange<size_t>(0, list.size() - 1)); } - // Return an enum value. The enum must start at 0 and be contiguous. It must + // Returns an enum value. The enum must start at 0 and be contiguous. It must // also contain |kMaxValue| aliased to its largest (inclusive) value. Such as: // enum class Foo { SomeValue, OtherValue, kMaxValue = OtherValue }; template <typename T> T ConsumeEnum() { @@ -183,10 +187,60 @@ public: 0, static_cast<uint32_t>(T::kMaxValue))); } + // Returns a floating point number in the range [0.0, 1.0]. If there's no + // input data left, always returns 0. + template <typename T> T ConsumeProbability() { + static_assert(std::is_floating_point<T>::value, + "A floating point type is required."); + + // Use different integral types for different floating point types in order + // to provide better density of the resulting values. + using IntegralType = + typename std::conditional<(sizeof(T) <= sizeof(uint32_t)), uint32_t, + uint64_t>::type; + + T result = static_cast<T>(ConsumeIntegral<IntegralType>()); + result /= static_cast<T>(std::numeric_limits<IntegralType>::max()); + return result; + } + + // Returns a floating point value in the range [Type's lowest, Type's max] by + // consuming bytes from the input data. If there's no input data left, always + // returns approximately 0. + template <typename T> T ConsumeFloatingPoint() { + return ConsumeFloatingPointInRange<T>(std::numeric_limits<T>::lowest(), + std::numeric_limits<T>::max()); + } + + // Returns a floating point value in the given range by consuming bytes from + // the input data. If there's no input data left, returns |min|. Note that + // |min| must be less than or equal to |max|. + template <typename T> T ConsumeFloatingPointInRange(T min, T max) { + if (min > max) + abort(); + + T range = .0; + T result = min; + constexpr T zero(.0); + if (max > zero && min < zero && max > min + std::numeric_limits<T>::max()) { + // The diff |max - min| would overflow the given floating point type. Use + // the half of the diff as the range and consume a bool to decide whether + // the result is in the first of the second part of the diff. + range = (max / 2.0) - (min / 2.0); + if (ConsumeBool()) { + result += range; + } + } else { + range = max - min; + } + + return result + range * ConsumeProbability<T>(); + } + // Reports the remaining bytes available for fuzzed input. size_t remaining_bytes() { return remaining_bytes_; } -private: + private: FuzzedDataProvider(const FuzzedDataProvider &) = delete; FuzzedDataProvider &operator=(const FuzzedDataProvider &) = delete; @@ -230,9 +284,9 @@ private: // Avoid using implementation-defined unsigned to signer conversions. // To learn more, see https://stackoverflow.com/questions/13150449. - if (value <= std::numeric_limits<TS>::max()) + if (value <= std::numeric_limits<TS>::max()) { return static_cast<TS>(value); - else { + } else { constexpr auto TS_min = std::numeric_limits<TS>::min(); return TS_min + static_cast<char>(value - TS_min); } diff --git a/include/sanitizer/dfsan_interface.h b/include/sanitizer/dfsan_interface.h index c189ee55790a..81546e5df71a 100644 --- a/include/sanitizer/dfsan_interface.h +++ b/include/sanitizer/dfsan_interface.h @@ -112,7 +112,7 @@ void dfsan_weak_hook_strncmp(void *caller_pc, const char *s1, const char *s2, } // extern "C" template <typename T> -void dfsan_set_label(dfsan_label label, T &data) { // NOLINT +void dfsan_set_label(dfsan_label label, T &data) { // NOLINT dfsan_set_label(label, (void *)&data, sizeof(T)); } diff --git a/include/sanitizer/tsan_interface_atomic.h b/include/sanitizer/tsan_interface_atomic.h index 9ce0411917df..8052bc1d56b3 100644 --- a/include/sanitizer/tsan_interface_atomic.h +++ b/include/sanitizer/tsan_interface_atomic.h @@ -17,10 +17,10 @@ extern "C" { #endif -typedef char __tsan_atomic8; -typedef short __tsan_atomic16; // NOLINT -typedef int __tsan_atomic32; -typedef long __tsan_atomic64; // NOLINT +typedef char __tsan_atomic8; +typedef short __tsan_atomic16; +typedef int __tsan_atomic32; +typedef long __tsan_atomic64; #if defined(__SIZEOF_INT128__) \ || (__clang_major__ * 100 + __clang_minor__ >= 302) __extension__ typedef __int128 __tsan_atomic128; diff --git a/include/sanitizer/ubsan_interface.h b/include/sanitizer/ubsan_interface.h new file mode 100644 index 000000000000..59fc6c3c184c --- /dev/null +++ b/include/sanitizer/ubsan_interface.h @@ -0,0 +1,32 @@ +//===-- sanitizer/ubsan_interface.h -----------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of UBSanitizer (UBSan). +// +// Public interface header. +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_UBSAN_INTERFACE_H +#define SANITIZER_UBSAN_INTERFACE_H + +#ifdef __cplusplus +extern "C" { +#endif +/// User-provided default option settings. +/// +/// You can provide your own implementation of this function to return a string +/// containing UBSan runtime options (for example, +/// <c>verbosity=1:halt_on_error=0</c>). +/// +/// \returns Default options string. +const char* __ubsan_default_options(void); + +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // SANITIZER_UBSAN_INTERFACE_H diff --git a/lib/asan/asan_activation.cc b/lib/asan/asan_activation.cpp index fc97cbb554d0..795df95a5414 100644 --- a/lib/asan/asan_activation.cc +++ b/lib/asan/asan_activation.cpp @@ -1,4 +1,4 @@ -//===-- asan_activation.cc --------------------------------------*- C++ -*-===// +//===-- asan_activation.cpp -------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/asan/asan_allocator.cc b/lib/asan/asan_allocator.cpp index 2ca6220d8fd1..c9e9f5a93d0d 100644 --- a/lib/asan/asan_allocator.cc +++ b/lib/asan/asan_allocator.cpp @@ -1,4 +1,4 @@ -//===-- asan_allocator.cc -------------------------------------------------===// +//===-- asan_allocator.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -1075,7 +1075,7 @@ IgnoreObjectResult IgnoreObjectLocked(const void *p) { } // namespace __lsan // ---------------------- Interface ---------------- {{{1 -using namespace __asan; // NOLINT +using namespace __asan; // ASan allocator doesn't reserve extra bytes, so normally we would // just return "size". We don't want to expose our redzone sizes, etc here. diff --git a/lib/asan/asan_allocator.h b/lib/asan/asan_allocator.h index 6add47be2c9c..b37d8ef4e8d2 100644 --- a/lib/asan/asan_allocator.h +++ b/lib/asan/asan_allocator.h @@ -8,7 +8,7 @@ // // This file is a part of AddressSanitizer, an address sanity checker. // -// ASan-private header for asan_allocator.cc. +// ASan-private header for asan_allocator.cpp. //===----------------------------------------------------------------------===// #ifndef ASAN_ALLOCATOR_H diff --git a/lib/asan/asan_debugging.cc b/lib/asan/asan_debugging.cpp index 7052a371e676..c01360b52fc9 100644 --- a/lib/asan/asan_debugging.cc +++ b/lib/asan/asan_debugging.cpp @@ -1,4 +1,4 @@ -//===-- asan_debugging.cc -------------------------------------------------===// +//===-- asan_debugging.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,7 +25,7 @@ using namespace __asan; static void FindInfoForStackVar(uptr addr, const char *frame_descr, uptr offset, char *name, uptr name_size, - uptr ®ion_address, uptr ®ion_size) { + uptr *region_address, uptr *region_size) { InternalMmapVector<StackVarDescr> vars; vars.reserve(16); if (!ParseFrameDescription(frame_descr, &vars)) { @@ -39,8 +39,8 @@ static void FindInfoForStackVar(uptr addr, const char *frame_descr, uptr offset, // the whole name and then terminate with '\0'. internal_strlcpy(name, vars[i].name_pos, Min(name_size, vars[i].name_len + 1)); - region_address = addr - (offset - vars[i].beg); - region_size = vars[i].size; + *region_address = addr - (offset - vars[i].beg); + *region_size = vars[i].size; return; } } @@ -108,7 +108,7 @@ const char *__asan_locate_address(uptr addr, char *name, uptr name_size, // region_{address,size} are already 0 } else { FindInfoForStackVar(addr, stack->frame_descr, stack->offset, name, - name_size, region_address, region_size); + name_size, ®ion_address, ®ion_size); } } else if (auto global = descr.AsGlobal()) { region_kind = "global"; diff --git a/lib/asan/asan_descriptions.cc b/lib/asan/asan_descriptions.cpp index 9b1217a86652..153c874a4e77 100644 --- a/lib/asan/asan_descriptions.cc +++ b/lib/asan/asan_descriptions.cpp @@ -1,4 +1,4 @@ -//===-- asan_descriptions.cc ------------------------------------*- C++ -*-===// +//===-- asan_descriptions.cpp -----------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/asan/asan_descriptions.h b/lib/asan/asan_descriptions.h index 0226d844afc9..ee0e2061559e 100644 --- a/lib/asan/asan_descriptions.h +++ b/lib/asan/asan_descriptions.h @@ -8,7 +8,7 @@ // // This file is a part of AddressSanitizer, an address sanity checker. // -// ASan-private header for asan_descriptions.cc. +// ASan-private header for asan_descriptions.cpp. // TODO(filcab): Most struct definitions should move to the interface headers. //===----------------------------------------------------------------------===// #ifndef ASAN_DESCRIPTIONS_H @@ -203,7 +203,7 @@ class AddressDescription { AddressDescription() = default; // shouldLockThreadRegistry allows us to skip locking if we're sure we already // have done it. - AddressDescription(uptr addr, bool shouldLockThreadRegistry = true) + explicit AddressDescription(uptr addr, bool shouldLockThreadRegistry = true) : AddressDescription(addr, 1, shouldLockThreadRegistry) {} AddressDescription(uptr addr, uptr access_size, bool shouldLockThreadRegistry = true); diff --git a/lib/asan/asan_errors.cc b/lib/asan/asan_errors.cpp index d598e37b940e..541c6e0353b5 100644 --- a/lib/asan/asan_errors.cc +++ b/lib/asan/asan_errors.cpp @@ -1,4 +1,4 @@ -//===-- asan_errors.cc ------------------------------------------*- C++ -*-===// +//===-- asan_errors.cpp -----------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -35,7 +35,8 @@ static void OnStackUnwind(const SignalContext &sig, // corresponding code in the sanitizer_common and we use this callback to // print it. static_cast<const ScarinessScoreBase *>(callback_context)->Print(); - stack->Unwind(sig.pc, sig.bp, sig.context, fast); + stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, + fast); } void ErrorDeadlySignal::Print() { @@ -244,7 +245,7 @@ void ErrorInvalidPosixMemalignAlignment::Print() { "ERROR: AddressSanitizer: invalid alignment requested in posix_memalign: " "%zd, alignment must be a power of two and a multiple of sizeof(void*) " "== %zd (thread %s)\n", - alignment, sizeof(void*), AsanThreadIdAndName(tid).c_str()); // NOLINT + alignment, sizeof(void *), AsanThreadIdAndName(tid).c_str()); Printf("%s", d.Default()); stack->Print(); PrintHintAllocatorCannotReturnNull(); diff --git a/lib/asan/asan_errors.h b/lib/asan/asan_errors.h index b84f56c18535..a7fda2fd9f5d 100644 --- a/lib/asan/asan_errors.h +++ b/lib/asan/asan_errors.h @@ -48,7 +48,8 @@ struct ErrorDeadlySignal : ErrorBase { scariness.Scare(10, "stack-overflow"); } else if (!signal.is_memory_access) { scariness.Scare(10, "signal"); - } else if (signal.addr < GetPageSizeCached()) { + } else if (signal.is_true_faulting_addr && + signal.addr < GetPageSizeCached()) { scariness.Scare(10, "null-deref"); } else if (signal.addr == signal.pc) { scariness.Scare(60, "wild-jump"); diff --git a/lib/asan/asan_fake_stack.cc b/lib/asan/asan_fake_stack.cpp index f8e1ac4b7bfe..295e6debc96c 100644 --- a/lib/asan/asan_fake_stack.cc +++ b/lib/asan/asan_fake_stack.cpp @@ -1,4 +1,4 @@ -//===-- asan_fake_stack.cc ------------------------------------------------===// +//===-- asan_fake_stack.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/asan/asan_fake_stack.h b/lib/asan/asan_fake_stack.h index 59ba85218f88..270a19816d6e 100644 --- a/lib/asan/asan_fake_stack.h +++ b/lib/asan/asan_fake_stack.h @@ -8,7 +8,7 @@ // // This file is a part of AddressSanitizer, an address sanity checker. // -// ASan-private header for asan_fake_stack.cc, implements FakeStack. +// ASan-private header for asan_fake_stack.cpp, implements FakeStack. //===----------------------------------------------------------------------===// #ifndef ASAN_FAKE_STACK_H diff --git a/lib/asan/asan_flags.cc b/lib/asan/asan_flags.cpp index 89e98936129d..c5c70eaed737 100644 --- a/lib/asan/asan_flags.cc +++ b/lib/asan/asan_flags.cpp @@ -1,4 +1,4 @@ -//===-- asan_flags.cc -------------------------------------------*- C++ -*-===// +//===-- asan_flags.cpp ------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/asan/asan_flags.inc b/lib/asan/asan_flags.inc index d360e03ca55e..43c70dbca56b 100644 --- a/lib/asan/asan_flags.inc +++ b/lib/asan/asan_flags.inc @@ -139,10 +139,10 @@ ASAN_FLAG( "If >= 2, detect operations like <, <=, >, >= and - on invalid pointer " "pairs (e.g. when pointers belong to different objects); " "If == 1, detect invalid operations only when both pointers are non-null.") -ASAN_FLAG( - bool, detect_container_overflow, true, - "If true, honor the container overflow annotations. See " - "https://github.com/google/sanitizers/wiki/AddressSanitizerContainerOverflow") +ASAN_FLAG(bool, detect_container_overflow, true, + "If true, honor the container overflow annotations. See " + "https://github.com/google/sanitizers/wiki/" + "AddressSanitizerContainerOverflow") ASAN_FLAG(int, detect_odr_violation, 2, "If >=2, detect violation of One-Definition-Rule (ODR); " "If ==1, detect ODR-violation only if the two variables " @@ -158,5 +158,6 @@ ASAN_FLAG(bool, allocator_frees_and_returns_null_on_realloc_zero, true, ASAN_FLAG(bool, verify_asan_link_order, true, "Check position of ASan runtime in library list (needs to be disabled" " when other library has to be preloaded system-wide)") -ASAN_FLAG(bool, windows_hook_rtl_allocators, false, - "(Windows only) enable hooking of Rtl(Allocate|Free|Size|ReAllocate)Heap.") +ASAN_FLAG( + bool, windows_hook_rtl_allocators, false, + "(Windows only) enable hooking of Rtl(Allocate|Free|Size|ReAllocate)Heap.") diff --git a/lib/asan/asan_fuchsia.cc b/lib/asan/asan_fuchsia.cpp index aebc17f38b4b..f8b2d5f26979 100644 --- a/lib/asan/asan_fuchsia.cc +++ b/lib/asan/asan_fuchsia.cpp @@ -1,4 +1,4 @@ -//===-- asan_fuchsia.cc --------------------------------------------------===// +//===-- asan_fuchsia.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -28,7 +28,7 @@ namespace __asan { // The system already set up the shadow memory for us. // __sanitizer::GetMaxUserVirtualAddress has already been called by -// AsanInitInternal->InitializeHighMemEnd (asan_rtl.cc). +// AsanInitInternal->InitializeHighMemEnd (asan_rtl.cpp). // Just do some additional sanity checks here. void InitializeShadowMemory() { if (Verbosity()) PrintAddressSpaceLayout(); @@ -172,7 +172,7 @@ static void ThreadCreateHook(void *hook, bool aborted) { // This is called in the newly-created thread before it runs anything else, // with the pointer returned by BeforeThreadCreateHook (above). -// cf. asan_interceptors.cc:asan_thread_start +// cf. asan_interceptors.cpp:asan_thread_start static void ThreadStartHook(void *hook, uptr os_id) { AsanThread *thread = static_cast<AsanThread *>(hook); SetCurrentThread(thread); diff --git a/lib/asan/asan_globals.cc b/lib/asan/asan_globals.cpp index a831fdf9cd93..9d7dbc6f264c 100644 --- a/lib/asan/asan_globals.cc +++ b/lib/asan/asan_globals.cpp @@ -1,4 +1,4 @@ -//===-- asan_globals.cc ---------------------------------------------------===// +//===-- asan_globals.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -227,8 +227,7 @@ static void RegisterGlobal(const Global *g) { list_of_all_globals = l; if (g->has_dynamic_init) { if (!dynamic_init_globals) { - dynamic_init_globals = - new (allocator_for_globals) VectorOfGlobals; // NOLINT + dynamic_init_globals = new (allocator_for_globals) VectorOfGlobals; dynamic_init_globals->reserve(kDynamicInitGlobalsInitialCapacity); } DynInitGlobal dyn_global = { *g, false }; @@ -315,8 +314,7 @@ void PrintGlobalLocation(InternalScopedString *str, const __asan_global &g) { } // namespace __asan // ---------------------- Interface ---------------- {{{1 -using namespace __asan; // NOLINT - +using namespace __asan; // Apply __asan_register_globals to all globals found in the same loaded // executable or shared library as `flag'. The flag tracks whether globals have @@ -364,7 +362,7 @@ void __asan_register_globals(__asan_global *globals, uptr n) { BlockingMutexLock lock(&mu_for_globals); if (!global_registration_site_vector) { global_registration_site_vector = - new (allocator_for_globals) GlobalRegistrationSiteVector; // NOLINT + new (allocator_for_globals) GlobalRegistrationSiteVector; global_registration_site_vector->reserve(128); } GlobalRegistrationSite site = {stack_id, &globals[0], &globals[n - 1]}; diff --git a/lib/asan/asan_globals_win.cc b/lib/asan/asan_globals_win.cpp index bdce37f701e1..19af88ab12b4 100644 --- a/lib/asan/asan_globals_win.cc +++ b/lib/asan/asan_globals_win.cpp @@ -1,4 +1,4 @@ -//===-- asan_globals_win.cc -----------------------------------------------===// +//===-- asan_globals_win.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -15,8 +15,8 @@ namespace __asan { -#pragma section(".ASAN$GA", read, write) // NOLINT -#pragma section(".ASAN$GZ", read, write) // NOLINT +#pragma section(".ASAN$GA", read, write) +#pragma section(".ASAN$GZ", read, write) extern "C" __declspec(allocate(".ASAN$GA")) ALIGNED(sizeof(__asan_global)) __asan_global __asan_globals_start = {}; extern "C" __declspec(allocate(".ASAN$GZ")) @@ -49,8 +49,8 @@ static void unregister_dso_globals() { } // Register globals -#pragma section(".CRT$XCU", long, read) // NOLINT -#pragma section(".CRT$XTX", long, read) // NOLINT +#pragma section(".CRT$XCU", long, read) +#pragma section(".CRT$XTX", long, read) extern "C" __declspec(allocate(".CRT$XCU")) void (*const __asan_dso_reg_hook)() = ®ister_dso_globals; extern "C" __declspec(allocate(".CRT$XTX")) diff --git a/lib/asan/asan_interceptors.cc b/lib/asan/asan_interceptors.cpp index 7eea7d2f942b..b19cf25c7cd0 100644 --- a/lib/asan/asan_interceptors.cc +++ b/lib/asan/asan_interceptors.cpp @@ -1,4 +1,4 @@ -//===-- asan_interceptors.cc ----------------------------------------------===// +//===-- asan_interceptors.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -24,7 +24,7 @@ #include "sanitizer_common/sanitizer_libc.h" // There is no general interception at all on Fuchsia and RTEMS. -// Only the functions in asan_interceptors_memintrinsics.cc are +// Only the functions in asan_interceptors_memintrinsics.cpp are // really defined to replace libc functions. #if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS @@ -79,7 +79,7 @@ int OnExit() { } // namespace __asan // ---------------------- Wrappers ---------------- {{{1 -using namespace __asan; // NOLINT +using namespace __asan; DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr) DECLARE_REAL_AND_INTERCEPTOR(void, free, void *) @@ -164,6 +164,11 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *) ASAN_MEMSET_IMPL(ctx, block, c, size); \ } while (false) +#if CAN_SANITIZE_LEAKS +#define COMMON_INTERCEPTOR_STRERROR() \ + __lsan::ScopedInterceptorDisabler disabler +#endif + #include "sanitizer_common/sanitizer_common_interceptors.inc" #include "sanitizer_common/sanitizer_signal_interceptors.inc" @@ -373,26 +378,26 @@ DEFINE_REAL(char*, index, const char *string, int c) // For both strcat() and strncat() we need to check the validity of |to| // argument irrespective of the |from| length. -INTERCEPTOR(char*, strcat, char *to, const char *from) { // NOLINT - void *ctx; - ASAN_INTERCEPTOR_ENTER(ctx, strcat); // NOLINT - ENSURE_ASAN_INITED(); - if (flags()->replace_str) { - uptr from_length = REAL(strlen)(from); - ASAN_READ_RANGE(ctx, from, from_length + 1); - uptr to_length = REAL(strlen)(to); - ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length); - ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1); - // If the copying actually happens, the |from| string should not overlap - // with the resulting string starting at |to|, which has a length of - // to_length + from_length + 1. - if (from_length > 0) { - CHECK_RANGES_OVERLAP("strcat", to, from_length + to_length + 1, - from, from_length + 1); + INTERCEPTOR(char *, strcat, char *to, const char *from) { + void *ctx; + ASAN_INTERCEPTOR_ENTER(ctx, strcat); + ENSURE_ASAN_INITED(); + if (flags()->replace_str) { + uptr from_length = REAL(strlen)(from); + ASAN_READ_RANGE(ctx, from, from_length + 1); + uptr to_length = REAL(strlen)(to); + ASAN_READ_STRING_OF_LEN(ctx, to, to_length, to_length); + ASAN_WRITE_RANGE(ctx, to + to_length, from_length + 1); + // If the copying actually happens, the |from| string should not overlap + // with the resulting string starting at |to|, which has a length of + // to_length + from_length + 1. + if (from_length > 0) { + CHECK_RANGES_OVERLAP("strcat", to, from_length + to_length + 1, from, + from_length + 1); + } } + return REAL(strcat)(to, from); } - return REAL(strcat)(to, from); // NOLINT -} INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) { void *ctx; @@ -413,16 +418,17 @@ INTERCEPTOR(char*, strncat, char *to, const char *from, uptr size) { return REAL(strncat)(to, from, size); } -INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT +INTERCEPTOR(char *, strcpy, char *to, const char *from) { void *ctx; - ASAN_INTERCEPTOR_ENTER(ctx, strcpy); // NOLINT + ASAN_INTERCEPTOR_ENTER(ctx, strcpy); #if SANITIZER_MAC - if (UNLIKELY(!asan_inited)) return REAL(strcpy)(to, from); // NOLINT + if (UNLIKELY(!asan_inited)) + return REAL(strcpy)(to, from); #endif // strcpy is called from malloc_default_purgeable_zone() // in __asan::ReplaceSystemAlloc() on Mac. if (asan_init_is_running) { - return REAL(strcpy)(to, from); // NOLINT + return REAL(strcpy)(to, from); } ENSURE_ASAN_INITED(); if (flags()->replace_str) { @@ -431,7 +437,7 @@ INTERCEPTOR(char*, strcpy, char *to, const char *from) { // NOLINT ASAN_READ_RANGE(ctx, from, from_size); ASAN_WRITE_RANGE(ctx, to, from_size); } - return REAL(strcpy)(to, from); // NOLINT + return REAL(strcpy)(to, from); } INTERCEPTOR(char*, strdup, const char *s) { @@ -479,8 +485,7 @@ INTERCEPTOR(char*, strncpy, char *to, const char *from, uptr size) { return REAL(strncpy)(to, from, size); } -INTERCEPTOR(long, strtol, const char *nptr, // NOLINT - char **endptr, int base) { +INTERCEPTOR(long, strtol, const char *nptr, char **endptr, int base) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, strtol); ENSURE_ASAN_INITED(); @@ -488,7 +493,7 @@ INTERCEPTOR(long, strtol, const char *nptr, // NOLINT return REAL(strtol)(nptr, endptr, base); } char *real_endptr; - long result = REAL(strtol)(nptr, &real_endptr, base); // NOLINT + long result = REAL(strtol)(nptr, &real_endptr, base); StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); return result; } @@ -514,7 +519,7 @@ INTERCEPTOR(int, atoi, const char *nptr) { return result; } -INTERCEPTOR(long, atol, const char *nptr) { // NOLINT +INTERCEPTOR(long, atol, const char *nptr) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, atol); #if SANITIZER_MAC @@ -525,15 +530,14 @@ INTERCEPTOR(long, atol, const char *nptr) { // NOLINT return REAL(atol)(nptr); } char *real_endptr; - long result = REAL(strtol)(nptr, &real_endptr, 10); // NOLINT + long result = REAL(strtol)(nptr, &real_endptr, 10); FixRealStrtolEndptr(nptr, &real_endptr); ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1); return result; } #if ASAN_INTERCEPT_ATOLL_AND_STRTOLL -INTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT - char **endptr, int base) { +INTERCEPTOR(long long, strtoll, const char *nptr, char **endptr, int base) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, strtoll); ENSURE_ASAN_INITED(); @@ -541,12 +545,12 @@ INTERCEPTOR(long long, strtoll, const char *nptr, // NOLINT return REAL(strtoll)(nptr, endptr, base); } char *real_endptr; - long long result = REAL(strtoll)(nptr, &real_endptr, base); // NOLINT + long long result = REAL(strtoll)(nptr, &real_endptr, base); StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); return result; } -INTERCEPTOR(long long, atoll, const char *nptr) { // NOLINT +INTERCEPTOR(long long, atoll, const char *nptr) { void *ctx; ASAN_INTERCEPTOR_ENTER(ctx, atoll); ENSURE_ASAN_INITED(); @@ -554,31 +558,66 @@ INTERCEPTOR(long long, atoll, const char *nptr) { // NOLINT return REAL(atoll)(nptr); } char *real_endptr; - long long result = REAL(strtoll)(nptr, &real_endptr, 10); // NOLINT + long long result = REAL(strtoll)(nptr, &real_endptr, 10); FixRealStrtolEndptr(nptr, &real_endptr); ASAN_READ_STRING(ctx, nptr, (real_endptr - nptr) + 1); return result; } #endif // ASAN_INTERCEPT_ATOLL_AND_STRTOLL -#if ASAN_INTERCEPT___CXA_ATEXIT +#if ASAN_INTERCEPT___CXA_ATEXIT || ASAN_INTERCEPT_ATEXIT static void AtCxaAtexit(void *unused) { (void)unused; StopInitOrderChecking(); } +#endif +#if ASAN_INTERCEPT___CXA_ATEXIT INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg, void *dso_handle) { #if SANITIZER_MAC if (UNLIKELY(!asan_inited)) return REAL(__cxa_atexit)(func, arg, dso_handle); #endif ENSURE_ASAN_INITED(); +#if CAN_SANITIZE_LEAKS + __lsan::ScopedInterceptorDisabler disabler; +#endif int res = REAL(__cxa_atexit)(func, arg, dso_handle); REAL(__cxa_atexit)(AtCxaAtexit, nullptr, nullptr); return res; } #endif // ASAN_INTERCEPT___CXA_ATEXIT +#if ASAN_INTERCEPT_ATEXIT +INTERCEPTOR(int, atexit, void (*func)()) { + ENSURE_ASAN_INITED(); +#if CAN_SANITIZE_LEAKS + __lsan::ScopedInterceptorDisabler disabler; +#endif + // Avoid calling real atexit as it is unrechable on at least on Linux. + int res = REAL(__cxa_atexit)((void (*)(void *a))func, nullptr, nullptr); + REAL(__cxa_atexit)(AtCxaAtexit, nullptr, nullptr); + return res; +} +#endif + +#if ASAN_INTERCEPT_PTHREAD_ATFORK +extern "C" { +extern int _pthread_atfork(void (*prepare)(), void (*parent)(), + void (*child)()); +}; + +INTERCEPTOR(int, pthread_atfork, void (*prepare)(), void (*parent)(), + void (*child)()) { +#if CAN_SANITIZE_LEAKS + __lsan::ScopedInterceptorDisabler disabler; +#endif + // REAL(pthread_atfork) cannot be called due to symbol indirections at least + // on NetBSD + return _pthread_atfork(prepare, parent, child); +} +#endif + #if ASAN_INTERCEPT_VFORK DEFINE_REAL(int, vfork) DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(int, vfork) @@ -594,8 +633,8 @@ void InitializeAsanInterceptors() { InitializeSignalInterceptors(); // Intercept str* functions. - ASAN_INTERCEPT_FUNC(strcat); // NOLINT - ASAN_INTERCEPT_FUNC(strcpy); // NOLINT + ASAN_INTERCEPT_FUNC(strcat); + ASAN_INTERCEPT_FUNC(strcpy); ASAN_INTERCEPT_FUNC(strncat); ASAN_INTERCEPT_FUNC(strncpy); ASAN_INTERCEPT_FUNC(strdup); @@ -661,6 +700,14 @@ void InitializeAsanInterceptors() { ASAN_INTERCEPT_FUNC(__cxa_atexit); #endif +#if ASAN_INTERCEPT_ATEXIT + ASAN_INTERCEPT_FUNC(atexit); +#endif + +#if ASAN_INTERCEPT_PTHREAD_ATFORK + ASAN_INTERCEPT_FUNC(pthread_atfork); +#endif + #if ASAN_INTERCEPT_VFORK ASAN_INTERCEPT_FUNC(vfork); #endif diff --git a/lib/asan/asan_interceptors.h b/lib/asan/asan_interceptors.h index 381b03984191..344a64bd83d3 100644 --- a/lib/asan/asan_interceptors.h +++ b/lib/asan/asan_interceptors.h @@ -8,7 +8,7 @@ // // This file is a part of AddressSanitizer, an address sanity checker. // -// ASan-private header for asan_interceptors.cc +// ASan-private header for asan_interceptors.cpp //===----------------------------------------------------------------------===// #ifndef ASAN_INTERCEPTORS_H #define ASAN_INTERCEPTORS_H @@ -99,6 +99,12 @@ void InitializePlatformInterceptors(); # define ASAN_INTERCEPT___CXA_ATEXIT 0 #endif +#if SANITIZER_NETBSD +# define ASAN_INTERCEPT_ATEXIT 1 +#else +# define ASAN_INTERCEPT_ATEXIT 0 +#endif + #if SANITIZER_LINUX && !SANITIZER_ANDROID # define ASAN_INTERCEPT___STRDUP 1 #else @@ -112,6 +118,12 @@ void InitializePlatformInterceptors(); # define ASAN_INTERCEPT_VFORK 0 #endif +#if SANITIZER_NETBSD +# define ASAN_INTERCEPT_PTHREAD_ATFORK 1 +#else +# define ASAN_INTERCEPT_PTHREAD_ATFORK 0 +#endif + DECLARE_REAL(int, memcmp, const void *a1, const void *a2, uptr size) DECLARE_REAL(char*, strchr, const char *str, int c) DECLARE_REAL(SIZE_T, strlen, const char *s) diff --git a/lib/asan/asan_interceptors_memintrinsics.cc b/lib/asan/asan_interceptors_memintrinsics.cpp index e17f9ba4aab5..ccdd5159042c 100644 --- a/lib/asan/asan_interceptors_memintrinsics.cc +++ b/lib/asan/asan_interceptors_memintrinsics.cpp @@ -1,4 +1,4 @@ -//===-- asan_interceptors_memintrinsics.cc --------------------------------===// +//===-- asan_interceptors_memintrinsics.cpp -------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -16,7 +16,7 @@ #include "asan_stack.h" #include "asan_suppressions.h" -using namespace __asan; // NOLINT +using namespace __asan; void *__asan_memcpy(void *to, const void *from, uptr size) { ASAN_MEMCPY_IMPL(nullptr, to, from, size); diff --git a/lib/asan/asan_interceptors_memintrinsics.h b/lib/asan/asan_interceptors_memintrinsics.h index 1fd65fe24953..632f0515a9eb 100644 --- a/lib/asan/asan_interceptors_memintrinsics.h +++ b/lib/asan/asan_interceptors_memintrinsics.h @@ -8,7 +8,7 @@ // // This file is a part of AddressSanitizer, an address sanity checker. // -// ASan-private header for asan_memintrin.cc +// ASan-private header for asan_interceptors_memintrinsics.cpp //===---------------------------------------------------------------------===// #ifndef ASAN_MEMINTRIN_H #define ASAN_MEMINTRIN_H diff --git a/lib/asan/asan_internal.h b/lib/asan/asan_internal.h index e4f771079293..72a4c3f22ff1 100644 --- a/lib/asan/asan_internal.h +++ b/lib/asan/asan_internal.h @@ -61,29 +61,29 @@ using __sanitizer::StackTrace; void AsanInitFromRtl(); -// asan_win.cc +// asan_win.cpp void InitializePlatformExceptionHandlers(); // Returns whether an address is a valid allocated system heap block. // 'addr' must point to the beginning of the block. bool IsSystemHeapAddress(uptr addr); -// asan_rtl.cc +// asan_rtl.cpp void PrintAddressSpaceLayout(); void NORETURN ShowStatsAndAbort(); -// asan_shadow_setup.cc +// asan_shadow_setup.cpp void InitializeShadowMemory(); -// asan_malloc_linux.cc / asan_malloc_mac.cc +// asan_malloc_linux.cpp / asan_malloc_mac.cpp void ReplaceSystemMalloc(); -// asan_linux.cc / asan_mac.cc / asan_rtems.cc / asan_win.cc +// asan_linux.cpp / asan_mac.cpp / asan_rtems.cpp / asan_win.cpp uptr FindDynamicShadowStart(); void *AsanDoesNotSupportStaticLinkage(); void AsanCheckDynamicRTPrereqs(); void AsanCheckIncompatibleRT(); -// asan_thread.cc +// asan_thread.cpp AsanThread *CreateMainThread(); // Support function for __asan_(un)register_image_globals. Searches for the diff --git a/lib/asan/asan_linux.cc b/lib/asan/asan_linux.cpp index f9182328916f..ce5e873dc518 100644 --- a/lib/asan/asan_linux.cc +++ b/lib/asan/asan_linux.cpp @@ -1,4 +1,4 @@ -//===-- asan_linux.cc -----------------------------------------------------===// +//===-- asan_linux.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/asan/asan_mac.cc b/lib/asan/asan_mac.cpp index e776acd2f539..a8d3f5d3473c 100644 --- a/lib/asan/asan_mac.cc +++ b/lib/asan/asan_mac.cpp @@ -1,4 +1,4 @@ -//===-- asan_mac.cc -------------------------------------------------------===// +//===-- asan_mac.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -205,7 +205,7 @@ void asan_dispatch_call_block_and_release(void *block) { } // namespace __asan -using namespace __asan; // NOLINT +using namespace __asan; // Wrap |ctxt| and |func| into an asan_block_context_t. // The caller retains control of the allocated context. diff --git a/lib/asan/asan_malloc_linux.cc b/lib/asan/asan_malloc_linux.cpp index 86fcd3b12d58..faa8968a5d00 100644 --- a/lib/asan/asan_malloc_linux.cc +++ b/lib/asan/asan_malloc_linux.cpp @@ -1,4 +1,4 @@ -//===-- asan_malloc_linux.cc ----------------------------------------------===// +//===-- asan_malloc_linux.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -27,7 +27,7 @@ #include "asan_stack.h" // ---------------------- Replacement functions ---------------- {{{1 -using namespace __asan; // NOLINT +using namespace __asan; static uptr allocated_for_dlsym; static uptr last_dlsym_alloc_size_in_words; diff --git a/lib/asan/asan_malloc_mac.cc b/lib/asan/asan_malloc_mac.cpp index 06dc1c289267..e8484685daed 100644 --- a/lib/asan/asan_malloc_mac.cc +++ b/lib/asan/asan_malloc_mac.cpp @@ -1,4 +1,4 @@ -//===-- asan_malloc_mac.cc ------------------------------------------------===// +//===-- asan_malloc_mac.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/asan/asan_malloc_win.cc b/lib/asan/asan_malloc_win.cpp index 5fad55d6e284..13c6f652119b 100644 --- a/lib/asan/asan_malloc_win.cc +++ b/lib/asan/asan_malloc_win.cpp @@ -1,4 +1,4 @@ -//===-- asan_malloc_win.cc ------------------------------------------------===// +//===-- asan_malloc_win.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -54,7 +54,7 @@ size_t WINAPI HeapSize(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem); BOOL WINAPI HeapValidate(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem); } -using namespace __asan; // NOLINT +using namespace __asan; // MT: Simply defining functions with the same signature in *.obj // files overrides the standard functions in the CRT. @@ -528,10 +528,11 @@ void ReplaceSystemMalloc() { (uptr)WRAP(RtlAllocateHeap), (uptr *)&REAL(RtlAllocateHeap)); } else { -#define INTERCEPT_UCRT_FUNCTION(func) \ - if (!INTERCEPT_FUNCTION_DLLIMPORT("ucrtbase.dll", \ - "api-ms-win-core-heap-l1-1-0.dll", func)) \ - VPrintf(2, "Failed to intercept ucrtbase.dll import %s\n", #func); +#define INTERCEPT_UCRT_FUNCTION(func) \ + if (!INTERCEPT_FUNCTION_DLLIMPORT( \ + "ucrtbase.dll", "api-ms-win-core-heap-l1-1-0.dll", func)) { \ + VPrintf(2, "Failed to intercept ucrtbase.dll import %s\n", #func); \ + } INTERCEPT_UCRT_FUNCTION(HeapAlloc); INTERCEPT_UCRT_FUNCTION(HeapFree); INTERCEPT_UCRT_FUNCTION(HeapReAlloc); diff --git a/lib/asan/asan_memory_profile.cc b/lib/asan/asan_memory_profile.cpp index 87d874d2f274..4fcd5600ed1a 100644 --- a/lib/asan/asan_memory_profile.cc +++ b/lib/asan/asan_memory_profile.cpp @@ -1,4 +1,4 @@ -//===-- asan_memory_profile.cc.cc -----------------------------------------===// +//===-- asan_memory_profile.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/asan/asan_new_delete.cc b/lib/asan/asan_new_delete.cpp index 5f51d12b1b5a..5dfcc00fd5d1 100644 --- a/lib/asan/asan_new_delete.cc +++ b/lib/asan/asan_new_delete.cpp @@ -1,4 +1,4 @@ -//===-- asan_interceptors.cc ----------------------------------------------===// +//===-- asan_interceptors.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -48,7 +48,7 @@ COMMENT_EXPORT("??_V@YAXPAX@Z") // operator delete[] #define CXX_OPERATOR_ATTRIBUTE INTERCEPTOR_ATTRIBUTE #endif -using namespace __asan; // NOLINT +using namespace __asan; // FreeBSD prior v9.2 have wrong definition of 'size_t'. // http://svnweb.freebsd.org/base?view=revision&revision=232261 diff --git a/lib/asan/asan_poisoning.cc b/lib/asan/asan_poisoning.cpp index 44b87c76e9cc..f3fbe684e2cb 100644 --- a/lib/asan/asan_poisoning.cc +++ b/lib/asan/asan_poisoning.cpp @@ -1,4 +1,4 @@ -//===-- asan_poisoning.cc -------------------------------------------------===// +//===-- asan_poisoning.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -92,7 +92,7 @@ void AsanPoisonOrUnpoisonIntraObjectRedzone(uptr ptr, uptr size, bool poison) { } // namespace __asan // ---------------------- Interface ---------------- {{{1 -using namespace __asan; // NOLINT +using namespace __asan; // Current implementation of __asan_(un)poison_memory_region doesn't check // that user program (un)poisons the memory it owns. It poisons memory diff --git a/lib/asan/asan_posix.cc b/lib/asan/asan_posix.cpp index 5c5e0359ad6c..920d216624a3 100644 --- a/lib/asan/asan_posix.cc +++ b/lib/asan/asan_posix.cpp @@ -1,4 +1,4 @@ -//===-- asan_posix.cc -----------------------------------------------------===// +//===-- asan_posix.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -39,8 +39,8 @@ 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. +#if SANITIZER_NETBSD && !ASAN_DYNAMIC +// Thread Static Data cannot be used in early static ASan init on NetBSD. // Reuse the Asan TSD API for compatibility with existing code // with an alternative implementation. diff --git a/lib/asan/asan_preinit.cc b/lib/asan/asan_preinit.cpp index 444998c44176..b07556ec96f8 100644 --- a/lib/asan/asan_preinit.cc +++ b/lib/asan/asan_preinit.cpp @@ -1,4 +1,4 @@ -//===-- asan_preinit.cc ---------------------------------------------------===// +//===-- asan_preinit.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/asan/asan_premap_shadow.cc b/lib/asan/asan_premap_shadow.cpp index 6e547718c68e..7835e99748ff 100644 --- a/lib/asan/asan_premap_shadow.cc +++ b/lib/asan/asan_premap_shadow.cpp @@ -1,4 +1,4 @@ -//===-- asan_premap_shadow.cc ---------------------------------------------===// +//===-- asan_premap_shadow.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/asan/asan_report.cc b/lib/asan/asan_report.cpp index 49067437d9d4..2e6ce436d030 100644 --- a/lib/asan/asan_report.cc +++ b/lib/asan/asan_report.cpp @@ -1,4 +1,4 @@ -//===-- asan_report.cc ----------------------------------------------------===// +//===-- asan_report.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -410,8 +410,12 @@ static bool IsInvalidPointerPair(uptr a1, uptr a2) { static INLINE void CheckForInvalidPointerPair(void *p1, void *p2) { switch (flags()->detect_invalid_pointer_pairs) { - case 0 : return; - case 1 : if (p1 == nullptr || p2 == nullptr) return; break; + case 0: + return; + case 1: + if (p1 == nullptr || p2 == nullptr) + return; + break; } uptr a1 = reinterpret_cast<uptr>(p1); @@ -472,7 +476,7 @@ void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write, } // namespace __asan // --------------------------- Interface --------------------- {{{1 -using namespace __asan; // NOLINT +using namespace __asan; void __asan_report_error(uptr pc, uptr bp, uptr sp, uptr addr, int is_write, uptr access_size, u32 exp) { diff --git a/lib/asan/asan_rtems.cc b/lib/asan/asan_rtems.cpp index 4878f4d67c86..ecd568c5981b 100644 --- a/lib/asan/asan_rtems.cc +++ b/lib/asan/asan_rtems.cpp @@ -1,4 +1,4 @@ -//===-- asan_rtems.cc -----------------------------------------------------===// +//===-- asan_rtems.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -181,11 +181,11 @@ static void ThreadStartHook(void *hook, uptr os_id) { asanThreadRegistry().GetThreadLocked(thread->tid())->status; DCHECK(status == ThreadStatusCreated || status == ThreadStatusRunning); // Determine whether we are starting or restarting the thread. - if (status == ThreadStatusCreated) + if (status == ThreadStatusCreated) { // In lieu of AsanThread::ThreadStart. asanThreadRegistry().StartThread(thread->tid(), os_id, ThreadType::Regular, nullptr); - else { + } else { // In a thread restart, a thread may resume execution at an // arbitrary function entry point, with its stack and TLS state // reset. We unpoison the stack in that case. diff --git a/lib/asan/asan_rtl.cc b/lib/asan/asan_rtl.cpp index db8dcd0689a5..594d7752eea6 100644 --- a/lib/asan/asan_rtl.cc +++ b/lib/asan/asan_rtl.cpp @@ -1,4 +1,4 @@ -//===-- asan_rtl.cc -------------------------------------------------------===// +//===-- asan_rtl.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -402,7 +402,6 @@ static void AsanInitInternal() { asan_init_is_running = true; CacheBinaryName(); - CheckASLR(); // Initialize flags. This must be done early, because most of the // initialization steps look at flags(). @@ -450,6 +449,7 @@ static void AsanInitInternal() { SetLowLevelAllocateCallback(OnLowLevelAllocate); InitializeAsanInterceptors(); + CheckASLR(); // Enable system log ("adb logcat") on Android. // Doing this before interceptors are initialized crashes in: @@ -542,7 +542,7 @@ void AsanInitFromRtl() { // (and thus normal initializers from .preinit_array or modules haven't run). class AsanInitializer { -public: // NOLINT + public: AsanInitializer() { AsanInitFromRtl(); } @@ -554,7 +554,7 @@ static AsanInitializer asan_initializer; } // namespace __asan // ---------------------- Interface ---------------- {{{1 -using namespace __asan; // NOLINT +using namespace __asan; void NOINLINE __asan_handle_no_return() { if (asan_init_is_running) diff --git a/lib/asan/asan_scariness_score.h b/lib/asan/asan_scariness_score.h index 9e7ba47d82dc..3932973c225e 100644 --- a/lib/asan/asan_scariness_score.h +++ b/lib/asan/asan_scariness_score.h @@ -43,7 +43,7 @@ struct ScarinessScoreBase { internal_strlcat(descr, "-", sizeof(descr)); internal_strlcat(descr, reason, sizeof(descr)); score += add_to_score; - }; + } int GetScore() const { return score; } const char *GetDescription() const { return descr; } void Print() const { diff --git a/lib/asan/asan_shadow_setup.cc b/lib/asan/asan_shadow_setup.cpp index 9cfa4e2bd65d..17324932a86f 100644 --- a/lib/asan/asan_shadow_setup.cc +++ b/lib/asan/asan_shadow_setup.cpp @@ -1,4 +1,4 @@ -//===-- asan_shadow_setup.cc ----------------------------------------------===// +//===-- asan_shadow_setup.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,7 +13,7 @@ #include "sanitizer_common/sanitizer_platform.h" -// asan_fuchsia.cc and asan_rtems.cc have their own +// asan_fuchsia.cpp and asan_rtems.cpp have their own // InitializeShadowMemory implementation. #if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS @@ -30,14 +30,13 @@ void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name) { CHECK_EQ(((end + 1) % GetMmapGranularity()), 0); uptr size = end - beg + 1; DecreaseTotalMmap(size); // Don't count the shadow against mmap_limit_mb. - if (!MmapFixedNoReserve(beg, size, name)) { + if (!MmapFixedSuperNoReserve(beg, size, name)) { Report( "ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. " "Perhaps you're using ulimit -v\n", size); Abort(); } - if (common_flags()->no_huge_pages_for_shadow) NoHugePagesInRegion(beg, size); if (common_flags()->use_madv_dontdump) DontDumpShadowMemory(beg, size); } diff --git a/lib/asan/asan_stack.cc b/lib/asan/asan_stack.cpp index b244da4fa0ad..b7f4e6aeeab0 100644 --- a/lib/asan/asan_stack.cc +++ b/lib/asan/asan_stack.cpp @@ -1,4 +1,4 @@ -//===-- asan_stack.cc -----------------------------------------------------===// +//===-- asan_stack.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/asan/asan_stack.h b/lib/asan/asan_stack.h index 3a4b3cefc5de..4089d3d7340e 100644 --- a/lib/asan/asan_stack.h +++ b/lib/asan/asan_stack.h @@ -8,7 +8,7 @@ // // This file is a part of AddressSanitizer, an address sanity checker. // -// ASan-private header for asan_stack.cc. +// ASan-private header for asan_stack.cpp. //===----------------------------------------------------------------------===// #ifndef ASAN_STACK_H diff --git a/lib/asan/asan_stats.cc b/lib/asan/asan_stats.cpp index 2f996ce63ccc..00ded8f5ef50 100644 --- a/lib/asan/asan_stats.cc +++ b/lib/asan/asan_stats.cpp @@ -1,4 +1,4 @@ -//===-- asan_stats.cc -----------------------------------------------------===// +//===-- asan_stats.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -133,7 +133,7 @@ static void PrintAccumulatedStats() { } // namespace __asan // ---------------------- Interface ---------------- {{{1 -using namespace __asan; // NOLINT +using namespace __asan; uptr __sanitizer_get_current_allocated_bytes() { AsanStats stats; diff --git a/lib/asan/asan_suppressions.cc b/lib/asan/asan_suppressions.cpp index 118853e61b79..8cb2c3e3b9b6 100644 --- a/lib/asan/asan_suppressions.cc +++ b/lib/asan/asan_suppressions.cpp @@ -1,4 +1,4 @@ -//===-- asan_suppressions.cc ----------------------------------------------===// +//===-- asan_suppressions.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -36,7 +36,7 @@ SANITIZER_INTERFACE_WEAK_DEF(const char *, __asan_default_suppressions, void) { void InitializeSuppressions() { CHECK_EQ(nullptr, suppression_ctx); - suppression_ctx = new (suppression_placeholder) // NOLINT + suppression_ctx = new (suppression_placeholder) SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes)); suppression_ctx->ParseFromFile(flags()->suppressions); if (&__asan_default_suppressions) diff --git a/lib/asan/asan_suppressions.h b/lib/asan/asan_suppressions.h index 9bf297602cfa..121d4ddf1875 100644 --- a/lib/asan/asan_suppressions.h +++ b/lib/asan/asan_suppressions.h @@ -8,7 +8,7 @@ // // This file is a part of AddressSanitizer, an address sanity checker. // -// ASan-private header for asan_suppressions.cc. +// ASan-private header for asan_suppressions.cpp. //===----------------------------------------------------------------------===// #ifndef ASAN_SUPPRESSIONS_H #define ASAN_SUPPRESSIONS_H diff --git a/lib/asan/asan_thread.cc b/lib/asan/asan_thread.cpp index e63561c2243f..6734d9a1668c 100644 --- a/lib/asan/asan_thread.cc +++ b/lib/asan/asan_thread.cpp @@ -1,4 +1,4 @@ -//===-- asan_thread.cc ----------------------------------------------------===// +//===-- asan_thread.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -367,8 +367,9 @@ uptr AsanThread::GetStackVariableShadowStart(uptr addr) { } else if (has_fake_stack()) { bottom = fake_stack()->AddrIsInFakeStack(addr); CHECK(bottom); - } else + } else { return 0; + } uptr aligned_addr = RoundDownTo(addr, SANITIZER_WORDSIZE / 8); // align addr. u8 *shadow_ptr = (u8*)MemToShadow(aligned_addr); @@ -505,7 +506,7 @@ void EnsureMainThreadIDIsCorrect() { } // namespace __lsan // ---------------------- Interface ---------------- {{{1 -using namespace __asan; // NOLINT +using namespace __asan; extern "C" { SANITIZER_INTERFACE_ATTRIBUTE diff --git a/lib/asan/asan_thread.h b/lib/asan/asan_thread.h index d725e88864eb..c503f507059d 100644 --- a/lib/asan/asan_thread.h +++ b/lib/asan/asan_thread.h @@ -8,7 +8,7 @@ // // This file is a part of AddressSanitizer, an address sanity checker. // -// ASan-private header for asan_thread.cc. +// ASan-private header for asan_thread.cpp. //===----------------------------------------------------------------------===// #ifndef ASAN_THREAD_H diff --git a/lib/asan/asan_win.cc b/lib/asan/asan_win.cpp index f7601f3301ea..417892aaedd8 100644 --- a/lib/asan/asan_win.cc +++ b/lib/asan/asan_win.cpp @@ -1,4 +1,4 @@ -//===-- asan_win.cc -------------------------------------------------------===// +//===-- asan_win.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -29,7 +29,7 @@ #include "sanitizer_common/sanitizer_win.h" #include "sanitizer_common/sanitizer_win_defs.h" -using namespace __asan; // NOLINT +using namespace __asan; extern "C" { SANITIZER_INTERFACE_ATTRIBUTE @@ -106,7 +106,7 @@ INTERCEPTOR_WINAPI(void, RaiseException, void *a, void *b, void *c, void *d) { INTERCEPTOR_WINAPI(EXCEPTION_DISPOSITION, __C_specific_handler, _EXCEPTION_RECORD *a, void *b, _CONTEXT *c, - _DISPATCHER_CONTEXT *d) { // NOLINT + _DISPATCHER_CONTEXT *d) { CHECK(REAL(__C_specific_handler)); __asan_handle_no_return(); return REAL(__C_specific_handler)(a, b, c, d); @@ -362,7 +362,7 @@ bool HandleDlopenInit() { // beginning of C++ initialization. We set our priority to XCAB to run // immediately after the CRT runs. This way, our exception filter is called // first and we can delegate to their filter if appropriate. -#pragma section(".CRT$XCAB", long, read) // NOLINT +#pragma section(".CRT$XCAB", long, read) __declspec(allocate(".CRT$XCAB")) int (*__intercept_seh)() = __asan_set_seh_filter; @@ -375,7 +375,7 @@ static void NTAPI asan_thread_init(void *module, DWORD reason, void *reserved) { __asan_init(); } -#pragma section(".CRT$XLAB", long, read) // NOLINT +#pragma section(".CRT$XLAB", long, read) __declspec(allocate(".CRT$XLAB")) void(NTAPI *__asan_tls_init)( void *, unsigned long, void *) = asan_thread_init; #endif @@ -389,7 +389,7 @@ static void NTAPI asan_thread_exit(void *module, DWORD reason, void *reserved) { } } -#pragma section(".CRT$XLY", long, read) // NOLINT +#pragma section(".CRT$XLY", long, read) __declspec(allocate(".CRT$XLY")) void(NTAPI *__asan_tls_exit)( void *, unsigned long, void *) = asan_thread_exit; diff --git a/lib/asan/asan_win_dll_thunk.cc b/lib/asan/asan_win_dll_thunk.cpp index 47b3948c5aea..a5671cc9dffd 100644 --- a/lib/asan/asan_win_dll_thunk.cc +++ b/lib/asan/asan_win_dll_thunk.cpp @@ -1,4 +1,4 @@ -//===-- asan_win_dll_thunk.cc ---------------------------------------------===// +//===-- asan_win_dll_thunk.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -54,7 +54,7 @@ INTERCEPT_WRAP_W_W(_expand_dbg) // TODO(timurrrr): Might want to add support for _aligned_* allocation // functions to detect a bit more bugs. Those functions seem to wrap malloc(). -// TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cc). +// TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cpp) INTERCEPT_LIBRARY_FUNCTION(atoi); INTERCEPT_LIBRARY_FUNCTION(atol); @@ -67,10 +67,10 @@ INTERCEPT_LIBRARY_FUNCTION(memcmp); INTERCEPT_LIBRARY_FUNCTION(memcpy); INTERCEPT_LIBRARY_FUNCTION(memmove); INTERCEPT_LIBRARY_FUNCTION(memset); -INTERCEPT_LIBRARY_FUNCTION(strcat); // NOLINT +INTERCEPT_LIBRARY_FUNCTION(strcat); INTERCEPT_LIBRARY_FUNCTION(strchr); INTERCEPT_LIBRARY_FUNCTION(strcmp); -INTERCEPT_LIBRARY_FUNCTION(strcpy); // NOLINT +INTERCEPT_LIBRARY_FUNCTION(strcpy); INTERCEPT_LIBRARY_FUNCTION(strcspn); INTERCEPT_LIBRARY_FUNCTION(strdup); INTERCEPT_LIBRARY_FUNCTION(strlen); @@ -135,7 +135,7 @@ static int asan_dll_thunk_init() { return 0; } -#pragma section(".CRT$XIB", long, read) // NOLINT +#pragma section(".CRT$XIB", long, read) __declspec(allocate(".CRT$XIB")) int (*__asan_preinit)() = asan_dll_thunk_init; static void WINAPI asan_thread_init(void *mod, unsigned long reason, @@ -143,7 +143,7 @@ static void WINAPI asan_thread_init(void *mod, unsigned long reason, if (reason == /*DLL_PROCESS_ATTACH=*/1) asan_dll_thunk_init(); } -#pragma section(".CRT$XLAB", long, read) // NOLINT +#pragma section(".CRT$XLAB", long, read) __declspec(allocate(".CRT$XLAB")) void (WINAPI *__asan_tls_init)(void *, unsigned long, void *) = asan_thread_init; diff --git a/lib/asan/asan_win_dynamic_runtime_thunk.cc b/lib/asan/asan_win_dynamic_runtime_thunk.cpp index cf4a59842c4f..f0b5ec9eef7f 100644 --- a/lib/asan/asan_win_dynamic_runtime_thunk.cc +++ b/lib/asan/asan_win_dynamic_runtime_thunk.cpp @@ -1,4 +1,4 @@ -//===-- asan_win_dynamic_runtime_thunk.cc ---------------------------------===// +//===-- asan_win_dynamic_runtime_thunk.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -32,12 +32,12 @@ #include "asan_interface.inc" // First, declare CRT sections we'll be using in this file -#pragma section(".CRT$XIB", long, read) // NOLINT -#pragma section(".CRT$XID", long, read) // NOLINT -#pragma section(".CRT$XCAB", long, read) // NOLINT -#pragma section(".CRT$XTW", long, read) // NOLINT -#pragma section(".CRT$XTY", long, read) // NOLINT -#pragma section(".CRT$XLAB", long, read) // NOLINT +#pragma section(".CRT$XIB", long, read) +#pragma section(".CRT$XID", long, read) +#pragma section(".CRT$XCAB", long, read) +#pragma section(".CRT$XTW", long, read) +#pragma section(".CRT$XTY", long, read) +#pragma section(".CRT$XLAB", long, read) //////////////////////////////////////////////////////////////////////////////// // Define a copy of __asan_option_detect_stack_use_after_return that should be @@ -114,7 +114,7 @@ int (*__asan_schedule_unregister_globals)() = ScheduleUnregisterGlobals; //////////////////////////////////////////////////////////////////////////////// // ASan SEH handling. // We need to set the ASan-specific SEH handler at the end of CRT initialization -// of each module (see also asan_win.cc). +// of each module (see also asan_win.cpp). extern "C" { __declspec(dllimport) int __asan_set_seh_filter(); static int SetSEHFilter() { return __asan_set_seh_filter(); } diff --git a/lib/asan/asan_win_weak_interception.cc b/lib/asan/asan_win_weak_interception.cpp index 19965ca473b4..62534e12e2a6 100644 --- a/lib/asan/asan_win_weak_interception.cc +++ b/lib/asan/asan_win_weak_interception.cpp @@ -1,4 +1,4 @@ -//===-- asan_win_weak_interception.cc -------------------------------------===// +//===-- asan_win_weak_interception.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/builtins/aarch64/fp_mode.c b/lib/builtins/aarch64/fp_mode.c new file mode 100644 index 000000000000..5a413689d2c8 --- /dev/null +++ b/lib/builtins/aarch64/fp_mode.c @@ -0,0 +1,59 @@ +//===----- lib/aarch64/fp_mode.c - Floaing-point mode utilities ---*- C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <stdint.h> + +#include "../fp_mode.h" + +#define AARCH64_TONEAREST 0x0 +#define AARCH64_UPWARD 0x1 +#define AARCH64_DOWNWARD 0x2 +#define AARCH64_TOWARDZERO 0x3 +#define AARCH64_RMODE_MASK (AARCH64_TONEAREST | AARCH64_UPWARD | \ + AARCH64_DOWNWARD | AARCH64_TOWARDZERO) +#define AARCH64_RMODE_SHIFT 22 + +#define AARCH64_INEXACT 0x10 + +#ifndef __ARM_FP +// For soft float targets, allow changing rounding mode by overriding the weak +// __aarch64_fe_default_rmode symbol. +FE_ROUND_MODE __attribute__((weak)) __aarch64_fe_default_rmode = FE_TONEAREST; +#endif + +FE_ROUND_MODE __fe_getround() { +#ifdef __ARM_FP + uint64_t fpcr; + __asm__ __volatile__("mrs %0, fpcr" : "=r" (fpcr)); + fpcr = fpcr >> AARCH64_RMODE_SHIFT & AARCH64_RMODE_MASK; + switch (fpcr) { + case AARCH64_UPWARD: + return FE_UPWARD; + case AARCH64_DOWNWARD: + return FE_DOWNWARD; + case AARCH64_TOWARDZERO: + return FE_TOWARDZERO; + case AARCH64_TONEAREST: + default: + return FE_TONEAREST; + } +#else + return __aarch64_fe_default_rmode; +#endif +} + +int __fe_raise_inexact() { +#ifdef __ARM_FP + uint64_t fpsr; + __asm__ __volatile__("mrs %0, fpsr" : "=r" (fpsr)); + __asm__ __volatile__("msr fpsr, %0" : : "ri" (fpsr | AARCH64_INEXACT)); + return 0; +#else + return 0; +#endif +} diff --git a/lib/builtins/adddf3.c b/lib/builtins/adddf3.c index f2727fafcabe..26f11bfa2216 100644 --- a/lib/builtins/adddf3.c +++ b/lib/builtins/adddf3.c @@ -6,8 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements double-precision soft-float addition with the IEEE-754 -// default rounding (to nearest, ties to even). +// This file implements double-precision soft-float addition. // //===----------------------------------------------------------------------===// diff --git a/lib/builtins/addsf3.c b/lib/builtins/addsf3.c index 8fe8622aadd9..9f1d517c1fa1 100644 --- a/lib/builtins/addsf3.c +++ b/lib/builtins/addsf3.c @@ -6,8 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements single-precision soft-float addition with the IEEE-754 -// default rounding (to nearest, ties to even). +// This file implements single-precision soft-float addition. // //===----------------------------------------------------------------------===// diff --git a/lib/builtins/addtf3.c b/lib/builtins/addtf3.c index 570472a14554..86e4f4cfc3fc 100644 --- a/lib/builtins/addtf3.c +++ b/lib/builtins/addtf3.c @@ -6,8 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements quad-precision soft-float addition with the IEEE-754 -// default rounding (to nearest, ties to even). +// This file implements quad-precision soft-float addition. // //===----------------------------------------------------------------------===// @@ -17,7 +16,7 @@ #if defined(CRT_HAS_128BIT) && defined(CRT_LDBL_128BIT) #include "fp_add_impl.inc" -COMPILER_RT_ABI long double __addtf3(long double a, long double b) { +COMPILER_RT_ABI fp_t __addtf3(fp_t a, fp_t b) { return __addXf3__(a, b); } diff --git a/lib/builtins/arm/fp_mode.c b/lib/builtins/arm/fp_mode.c new file mode 100644 index 000000000000..300b71935ad4 --- /dev/null +++ b/lib/builtins/arm/fp_mode.c @@ -0,0 +1,59 @@ +//===----- lib/arm/fp_mode.c - Floaing-point mode utilities -------*- C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include <stdint.h> + +#include "../fp_mode.h" + +#define ARM_TONEAREST 0x0 +#define ARM_UPWARD 0x1 +#define ARM_DOWNWARD 0x2 +#define ARM_TOWARDZERO 0x3 +#define ARM_RMODE_MASK (ARM_TONEAREST | ARM_UPWARD | \ + ARM_DOWNWARD | ARM_TOWARDZERO) +#define ARM_RMODE_SHIFT 22 + +#define ARM_INEXACT 0x1000 + +#ifndef __ARM_FP +// For soft float targets, allow changing rounding mode by overriding the weak +// __arm_fe_default_rmode symbol. +FE_ROUND_MODE __attribute__((weak)) __arm_fe_default_rmode = FE_TONEAREST; +#endif + +FE_ROUND_MODE __fe_getround() { +#ifdef __ARM_FP + uint32_t fpscr; + __asm__ __volatile__("vmrs %0, fpscr" : "=r" (fpscr)); + fpscr = fpscr >> ARM_RMODE_SHIFT & ARM_RMODE_MASK; + switch (fpscr) { + case ARM_UPWARD: + return FE_UPWARD; + case ARM_DOWNWARD: + return FE_DOWNWARD; + case ARM_TOWARDZERO: + return FE_TOWARDZERO; + case ARM_TONEAREST: + default: + return FE_TONEAREST; + } +#else + return __arm_fe_default_rmode; +#endif +} + +int __fe_raise_inexact() { +#ifdef __ARM_FP + uint32_t fpscr; + __asm__ __volatile__("vmrs %0, fpscr" : "=r" (fpscr)); + __asm__ __volatile__("vmsr fpscr, %0" : : "ri" (fpscr | ARM_INEXACT)); + return 0; +#else + return 0; +#endif +} diff --git a/lib/builtins/atomic.c b/lib/builtins/atomic.c index 0f82803a6416..32b3a0f9ad23 100644 --- a/lib/builtins/atomic.c +++ b/lib/builtins/atomic.c @@ -51,9 +51,11 @@ static const long SPINLOCK_MASK = SPINLOCK_COUNT - 1; //////////////////////////////////////////////////////////////////////////////// #ifdef __FreeBSD__ #include <errno.h> -#include <machine/atomic.h> +// clang-format off #include <sys/types.h> +#include <machine/atomic.h> #include <sys/umtx.h> +// clang-format on typedef struct _usem Lock; __inline static void unlock(Lock *l) { __c11_atomic_store((_Atomic(uint32_t) *)&l->_count, 1, __ATOMIC_RELEASE); diff --git a/lib/builtins/clear_cache.c b/lib/builtins/clear_cache.c index 76dc1968cc7e..80d3b2f9f17d 100644 --- a/lib/builtins/clear_cache.c +++ b/lib/builtins/clear_cache.c @@ -23,8 +23,10 @@ uintptr_t GetCurrentProcess(void); #endif #if defined(__FreeBSD__) && defined(__arm__) -#include <machine/sysarch.h> +// clang-format off #include <sys/types.h> +#include <machine/sysarch.h> +// clang-format on #endif #if defined(__NetBSD__) && defined(__arm__) @@ -32,54 +34,16 @@ uintptr_t GetCurrentProcess(void); #endif #if defined(__OpenBSD__) && defined(__mips__) -#include <machine/sysarch.h> +// clang-format off #include <sys/types.h> +#include <machine/sysarch.h> +// clang-format on #endif #if defined(__linux__) && defined(__mips__) #include <sys/cachectl.h> #include <sys/syscall.h> #include <unistd.h> -#if defined(__ANDROID__) && defined(__LP64__) -// clear_mips_cache - Invalidates instruction cache for Mips. -static void clear_mips_cache(const void *Addr, size_t Size) { - __asm__ volatile( - ".set push\n" - ".set noreorder\n" - ".set noat\n" - "beq %[Size], $zero, 20f\n" // If size == 0, branch around. - "nop\n" - "daddu %[Size], %[Addr], %[Size]\n" // Calculate end address + 1 - "rdhwr $v0, $1\n" // Get step size for SYNCI. - // $1 is $HW_SYNCI_Step - "beq $v0, $zero, 20f\n" // If no caches require - // synchronization, branch - // around. - "nop\n" - "10:\n" - "synci 0(%[Addr])\n" // Synchronize all caches around - // address. - "daddu %[Addr], %[Addr], $v0\n" // Add step size. - "sltu $at, %[Addr], %[Size]\n" // Compare current with end - // address. - "bne $at, $zero, 10b\n" // Branch if more to do. - "nop\n" - "sync\n" // Clear memory hazards. - "20:\n" - "bal 30f\n" - "nop\n" - "30:\n" - "daddiu $ra, $ra, 12\n" // $ra has a value of $pc here. - // Add offset of 12 to point to the - // instruction after the last nop. - // - "jr.hb $ra\n" // Return, clearing instruction - // hazards. - "nop\n" - ".set pop\n" - : [ Addr ] "+r"(Addr), [ Size ] "+r"(Size)::"at", "ra", "v0", "memory"); -} -#endif #endif // The compiler generates calls to __clear_cache() when creating @@ -123,17 +87,7 @@ void __clear_cache(void *start, void *end) { #elif defined(__linux__) && defined(__mips__) const uintptr_t start_int = (uintptr_t)start; const uintptr_t end_int = (uintptr_t)end; -#if defined(__ANDROID__) && defined(__LP64__) - // Call synci implementation for short address range. - const uintptr_t address_range_limit = 256; - if ((end_int - start_int) <= address_range_limit) { - clear_mips_cache(start, (end_int - start_int)); - } else { - syscall(__NR_cacheflush, start, (end_int - start_int), BCACHE); - } -#else syscall(__NR_cacheflush, start, (end_int - start_int), BCACHE); -#endif #elif defined(__mips__) && defined(__OpenBSD__) cacheflush(start, (uintptr_t)end - (uintptr_t)start, BCACHE); #elif defined(__aarch64__) && !defined(__APPLE__) @@ -173,6 +127,16 @@ void __clear_cache(void *start, void *end) { for (uintptr_t line = start_line; line < end_line; line += line_size) __asm__ volatile("icbi 0, %0" : : "r"(line)); __asm__ volatile("isync"); +#elif defined(__sparc__) + const size_t dword_size = 8; + const size_t len = (uintptr_t)end - (uintptr_t)start; + + const uintptr_t mask = ~(dword_size - 1); + const uintptr_t start_dword = ((uintptr_t)start) & mask; + const uintptr_t end_dword = ((uintptr_t)start + len + dword_size - 1) & mask; + + for (uintptr_t dword = start_dword; dword < end_dword; dword += dword_size) + __asm__ volatile("flush %0" : : "r"(dword)); #else #if __APPLE__ // On Darwin, sys_icache_invalidate() provides this functionality diff --git a/lib/builtins/cpu_model.c b/lib/builtins/cpu_model.c index f953aed959e5..cdeb03794ecc 100644 --- a/lib/builtins/cpu_model.c +++ b/lib/builtins/cpu_model.c @@ -121,7 +121,8 @@ enum ProcessorFeatures { FEATURE_GFNI, FEATURE_VPCLMULQDQ, FEATURE_AVX512VNNI, - FEATURE_AVX512BITALG + FEATURE_AVX512BITALG, + FEATURE_AVX512BF16 }; // The check below for i386 was copied from clang's cpuid.h (__get_cpuid_max). @@ -415,8 +416,8 @@ static void getIntelProcessorTypeAndSubtype(unsigned Family, unsigned Model, default: // Unknown family 6 CPU. break; - break; } + break; default: break; // Unknown. } @@ -543,7 +544,7 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, setFeature(FEATURE_BMI); if (HasLeaf7 && ((EBX >> 5) & 1) && HasAVX) setFeature(FEATURE_AVX2); - if (HasLeaf7 && ((EBX >> 9) & 1)) + if (HasLeaf7 && ((EBX >> 8) & 1)) setFeature(FEATURE_BMI2); if (HasLeaf7 && ((EBX >> 16) & 1) && HasAVX512Save) setFeature(FEATURE_AVX512F); @@ -582,6 +583,11 @@ static void getAvailableFeatures(unsigned ECX, unsigned EDX, unsigned MaxLeaf, if (HasLeaf7 && ((EDX >> 3) & 1) && HasAVX512Save) setFeature(FEATURE_AVX5124FMAPS); + bool HasLeaf7Subleaf1 = + MaxLeaf >= 0x7 && !getX86CpuIDAndInfoEx(0x7, 0x1, &EAX, &EBX, &ECX, &EDX); + if (HasLeaf7Subleaf1 && ((EAX >> 5) & 1) && HasAVX512Save) + setFeature(FEATURE_AVX512BF16); + unsigned MaxExtLevel; getX86CpuIDAndInfo(0x80000000, &MaxExtLevel, &EBX, &ECX, &EDX); diff --git a/lib/builtins/divtf3.c b/lib/builtins/divtf3.c index 6e61d2e31b75..ce462d4d46c1 100644 --- a/lib/builtins/divtf3.c +++ b/lib/builtins/divtf3.c @@ -213,7 +213,7 @@ COMPILER_RT_ABI fp_t __divtf3(fp_t a, fp_t b) { // Round. absResult += round; // Insert the sign and return. - const long double result = fromRep(absResult | quotientSign); + const fp_t result = fromRep(absResult | quotientSign); return result; } } diff --git a/lib/builtins/emutls.c b/lib/builtins/emutls.c index da58feb7b906..e0aa19155f7d 100644 --- a/lib/builtins/emutls.c +++ b/lib/builtins/emutls.c @@ -26,12 +26,23 @@ #define EMUTLS_SKIP_DESTRUCTOR_ROUNDS 0 #endif +#if defined(_MSC_VER) && !defined(__clang__) +// MSVC raises a warning about a nonstandard extension being used for the 0 +// sized element in this array. Disable this for warn-as-error builds. +#pragma warning(push) +#pragma warning(disable : 4206) +#endif + typedef struct emutls_address_array { uintptr_t skip_destructor_rounds; uintptr_t size; // number of elements in the 'data' array void *data[]; } emutls_address_array; +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif + static void emutls_shutdown(emutls_address_array *array); #ifndef _WIN32 diff --git a/lib/builtins/extenddftf2.c b/lib/builtins/extenddftf2.c index 849a39da1915..ddf470ecd629 100644 --- a/lib/builtins/extenddftf2.c +++ b/lib/builtins/extenddftf2.c @@ -14,7 +14,7 @@ #define DST_QUAD #include "fp_extend_impl.inc" -COMPILER_RT_ABI long double __extenddftf2(double a) { +COMPILER_RT_ABI fp_t __extenddftf2(double a) { return __extendXfYf2__(a); } diff --git a/lib/builtins/extendsftf2.c b/lib/builtins/extendsftf2.c index c6368406dde1..cf1fd2face20 100644 --- a/lib/builtins/extendsftf2.c +++ b/lib/builtins/extendsftf2.c @@ -14,7 +14,7 @@ #define DST_QUAD #include "fp_extend_impl.inc" -COMPILER_RT_ABI long double __extendsftf2(float a) { +COMPILER_RT_ABI fp_t __extendsftf2(float a) { return __extendXfYf2__(a); } diff --git a/lib/builtins/fixunsxfdi.c b/lib/builtins/fixunsxfdi.c index 75c4f093794f..097a4e55e931 100644 --- a/lib/builtins/fixunsxfdi.c +++ b/lib/builtins/fixunsxfdi.c @@ -25,6 +25,13 @@ // eeee | 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm // mmmm mmmm mmmm +#if defined(_MSC_VER) && !defined(__clang__) +// MSVC throws a warning about 'unitialized variable use' here, +// disable it for builds that warn-as-error +#pragma warning(push) +#pragma warning(disable : 4700) +#endif + COMPILER_RT_ABI du_int __fixunsxfdi(long double a) { long_double_bits fb; fb.f = a; @@ -36,4 +43,8 @@ COMPILER_RT_ABI du_int __fixunsxfdi(long double a) { return fb.u.low.all >> (63 - e); } +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) #endif + +#endif //!_ARCH_PPC diff --git a/lib/builtins/fixunsxfsi.c b/lib/builtins/fixunsxfsi.c index 1432d8ba92d2..3bc1288d38a1 100644 --- a/lib/builtins/fixunsxfsi.c +++ b/lib/builtins/fixunsxfsi.c @@ -25,6 +25,13 @@ // eeee | 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm // mmmm mmmm mmmm +#if defined(_MSC_VER) && !defined(__clang__) +// MSVC throws a warning about 'unitialized variable use' here, +// disable it for builds that warn-as-error +#pragma warning(push) +#pragma warning(disable : 4700) +#endif + COMPILER_RT_ABI su_int __fixunsxfsi(long double a) { long_double_bits fb; fb.f = a; @@ -36,4 +43,8 @@ COMPILER_RT_ABI su_int __fixunsxfsi(long double a) { return fb.u.low.s.high >> (31 - e); } +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif + #endif // !_ARCH_PPC diff --git a/lib/builtins/fixxfdi.c b/lib/builtins/fixxfdi.c index 4783c0101740..a7a0464feb9d 100644 --- a/lib/builtins/fixxfdi.c +++ b/lib/builtins/fixxfdi.c @@ -24,6 +24,13 @@ // eeee | 1mmm mmmm mmmm mmmm mmmm mmmm mmmm mmmm | mmmm mmmm mmmm mmmm mmmm // mmmm mmmm mmmm +#if defined(_MSC_VER) && !defined(__clang__) +// MSVC throws a warning about 'unitialized variable use' here, +// disable it for builds that warn-as-error +#pragma warning(push) +#pragma warning(disable : 4700) +#endif + COMPILER_RT_ABI di_int __fixxfdi(long double a) { const di_int di_max = (di_int)((~(du_int)0) / 2); const di_int di_min = -di_max - 1; @@ -40,4 +47,8 @@ COMPILER_RT_ABI di_int __fixxfdi(long double a) { return (r ^ s) - s; } +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif + #endif // !_ARCH_PPC diff --git a/lib/builtins/fp_add_impl.inc b/lib/builtins/fp_add_impl.inc index da8639341703..ab6321349032 100644 --- a/lib/builtins/fp_add_impl.inc +++ b/lib/builtins/fp_add_impl.inc @@ -12,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "fp_lib.h" +#include "fp_mode.h" static __inline fp_t __addXf3__(fp_t a, fp_t b) { rep_t aRep = toRep(a); @@ -93,7 +94,7 @@ static __inline fp_t __addXf3__(fp_t a, fp_t b) { const unsigned int align = aExponent - bExponent; if (align) { if (align < typeWidth) { - const bool sticky = bSignificand << (typeWidth - align); + const bool sticky = (bSignificand << (typeWidth - align)) != 0; bSignificand = bSignificand >> align | sticky; } else { bSignificand = 1; // Set the sticky bit. b is known to be non-zero. @@ -132,7 +133,7 @@ static __inline fp_t __addXf3__(fp_t a, fp_t b) { // The result is denormal before rounding. The exponent is zero and we // need to shift the significand. const int shift = 1 - aExponent; - const bool sticky = aSignificand << (typeWidth - shift); + const bool sticky = (aSignificand << (typeWidth - shift)) != 0; aSignificand = aSignificand >> shift | sticky; aExponent = 0; } @@ -149,9 +150,23 @@ static __inline fp_t __addXf3__(fp_t a, fp_t b) { // Perform the final rounding. The result may overflow to infinity, but // that is the correct result in that case. - if (roundGuardSticky > 0x4) - result++; - if (roundGuardSticky == 0x4) - result += result & 1; + switch (__fe_getround()) { + case FE_TONEAREST: + if (roundGuardSticky > 0x4) + result++; + if (roundGuardSticky == 0x4) + result += result & 1; + break; + case FE_DOWNWARD: + if (resultSign && roundGuardSticky) result++; + break; + case FE_UPWARD: + if (!resultSign && roundGuardSticky) result++; + break; + case FE_TOWARDZERO: + break; + } + if (roundGuardSticky) + __fe_raise_inexact(); return fromRep(result); } diff --git a/lib/builtins/fp_lib.h b/lib/builtins/fp_lib.h index d1a988ea4713..e2a906681c46 100644 --- a/lib/builtins/fp_lib.h +++ b/lib/builtins/fp_lib.h @@ -245,7 +245,7 @@ static __inline void wideLeftShift(rep_t *hi, rep_t *lo, int count) { static __inline void wideRightShiftWithSticky(rep_t *hi, rep_t *lo, unsigned int count) { if (count < typeWidth) { - const bool sticky = *lo << (typeWidth - count); + const bool sticky = (*lo << (typeWidth - count)) != 0; *lo = *hi << (typeWidth - count) | *lo >> count | sticky; *hi = *hi >> count; } else if (count < 2 * typeWidth) { diff --git a/lib/builtins/fp_mode.c b/lib/builtins/fp_mode.c new file mode 100644 index 000000000000..c1b6c1f6b8a3 --- /dev/null +++ b/lib/builtins/fp_mode.c @@ -0,0 +1,24 @@ +//===----- lib/fp_mode.c - Floaing-point environment mode utilities --C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file provides a default implementation of fp_mode.h for architectures +// that does not support or does not have an implementation of floating point +// environment mode. +// +//===----------------------------------------------------------------------===// + +#include "fp_mode.h" + +// IEEE-754 default rounding (to nearest, ties to even). +FE_ROUND_MODE __fe_getround() { + return FE_TONEAREST; +} + +int __fe_raise_inexact() { + return 0; +} diff --git a/lib/builtins/fp_mode.h b/lib/builtins/fp_mode.h new file mode 100644 index 000000000000..51bec0431a40 --- /dev/null +++ b/lib/builtins/fp_mode.h @@ -0,0 +1,29 @@ +//===----- lib/fp_mode.h - Floaing-point environment mode utilities --C -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is not part of the interface of this library. +// +// This file defines an interface for accessing hardware floating point +// environment mode. +// +//===----------------------------------------------------------------------===// + +#ifndef FP_MODE +#define FP_MODE + +typedef enum { + FE_TONEAREST, + FE_DOWNWARD, + FE_UPWARD, + FE_TOWARDZERO +} FE_ROUND_MODE; + +FE_ROUND_MODE __fe_getround(); +int __fe_raise_inexact(); + +#endif // FP_MODE_H diff --git a/lib/builtins/fp_trunc_impl.inc b/lib/builtins/fp_trunc_impl.inc index 133c8bbe5c2f..6662be7607e7 100644 --- a/lib/builtins/fp_trunc_impl.inc +++ b/lib/builtins/fp_trunc_impl.inc @@ -113,7 +113,7 @@ static __inline dst_t __truncXfYf2__(src_t a) { if (shift > srcSigBits) { absResult = 0; } else { - const bool sticky = significand << (srcBits - shift); + const bool sticky = (significand << (srcBits - shift)) != 0; src_rep_t denormalizedSignificand = significand >> shift | sticky; absResult = denormalizedSignificand >> (srcSigBits - dstSigBits); const src_rep_t roundBits = denormalizedSignificand & roundMask; diff --git a/lib/builtins/subdf3.c b/lib/builtins/subdf3.c index 5346dbc970fa..2100fd39c4ef 100644 --- a/lib/builtins/subdf3.c +++ b/lib/builtins/subdf3.c @@ -6,8 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements double-precision soft-float subtraction with the -// IEEE-754 default rounding (to nearest, ties to even). +// This file implements double-precision soft-float subtraction. // //===----------------------------------------------------------------------===// diff --git a/lib/builtins/subsf3.c b/lib/builtins/subsf3.c index 85bde029b5bc..ecfc24f7dd30 100644 --- a/lib/builtins/subsf3.c +++ b/lib/builtins/subsf3.c @@ -6,8 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements single-precision soft-float subtraction with the -// IEEE-754 default rounding (to nearest, ties to even). +// This file implements single-precision soft-float subtraction. // //===----------------------------------------------------------------------===// diff --git a/lib/builtins/subtf3.c b/lib/builtins/subtf3.c index c96814692d2c..3364c28f8179 100644 --- a/lib/builtins/subtf3.c +++ b/lib/builtins/subtf3.c @@ -6,8 +6,7 @@ // //===----------------------------------------------------------------------===// // -// This file implements quad-precision soft-float subtraction with the -// IEEE-754 default rounding (to nearest, ties to even). +// This file implements quad-precision soft-float subtraction. // //===----------------------------------------------------------------------===// diff --git a/lib/builtins/udivmoddi4.c b/lib/builtins/udivmoddi4.c index 2914cc0fb46d..5b297c32d790 100644 --- a/lib/builtins/udivmoddi4.c +++ b/lib/builtins/udivmoddi4.c @@ -17,6 +17,13 @@ // Translated from Figure 3-40 of The PowerPC Compiler Writer's Guide +#if defined(_MSC_VER) && !defined(__clang__) +// MSVC throws a warning about mod 0 here, disable it for builds that +// warn-as-error +#pragma warning(push) +#pragma warning(disable : 4724) +#endif + COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int *rem) { const unsigned n_uword_bits = sizeof(su_int) * CHAR_BIT; const unsigned n_udword_bits = sizeof(du_int) * CHAR_BIT; @@ -187,3 +194,7 @@ COMPILER_RT_ABI du_int __udivmoddi4(du_int a, du_int b, du_int *rem) { *rem = r.all; return q.all; } + +#if defined(_MSC_VER) && !defined(__clang__) +#pragma warning(pop) +#endif diff --git a/lib/dfsan/dfsan.cc b/lib/dfsan/dfsan.cpp index f4ba1148f782..0e2fb9f5f334 100644 --- a/lib/dfsan/dfsan.cc +++ b/lib/dfsan/dfsan.cpp @@ -1,4 +1,4 @@ -//===-- dfsan.cc ----------------------------------------------------------===// +//===-- dfsan.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/dfsan/dfsan_custom.cc b/lib/dfsan/dfsan_custom.cpp index dc7b81da4566..84f0271b15e0 100644 --- a/lib/dfsan/dfsan_custom.cc +++ b/lib/dfsan/dfsan_custom.cpp @@ -1,4 +1,4 @@ -//===-- dfsan.cc ----------------------------------------------------------===// +//===-- dfsan.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -505,7 +505,7 @@ int __dfsw_getrusage(int who, struct rusage *usage, dfsan_label who_label, SANITIZER_INTERFACE_ATTRIBUTE char *__dfsw_strcpy(char *dest, const char *src, dfsan_label dst_label, dfsan_label src_label, dfsan_label *ret_label) { - char *ret = strcpy(dest, src); + char *ret = strcpy(dest, src); // NOLINT if (ret) { internal_memcpy(shadow_for(dest), shadow_for(src), sizeof(dfsan_label) * (strlen(src) + 1)); diff --git a/lib/dfsan/dfsan_interceptors.cc b/lib/dfsan/dfsan_interceptors.cpp index f4b4babc65c2..673171c46f5a 100644 --- a/lib/dfsan/dfsan_interceptors.cc +++ b/lib/dfsan/dfsan_interceptors.cpp @@ -1,4 +1,4 @@ -//===-- dfsan_interceptors.cc ---------------------------------------------===// +//===-- dfsan_interceptors.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/fuzzer/FuzzerBuiltinsMsvc.h b/lib/fuzzer/FuzzerBuiltinsMsvc.h index 82709cfe7b40..bc65c60098be 100644 --- a/lib/fuzzer/FuzzerBuiltinsMsvc.h +++ b/lib/fuzzer/FuzzerBuiltinsMsvc.h @@ -15,9 +15,6 @@ #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> @@ -40,7 +37,18 @@ inline uint64_t Bswap(uint64_t x) { return _byteswap_uint64(x); } // outside of Windows. inline uint32_t Clzll(uint64_t X) { unsigned long LeadZeroIdx = 0; + +#if !defined(_M_ARM) && !defined(_M_X64) + // Scan the high 32 bits. + if (_BitScanReverse(&LeadZeroIdx, static_cast<unsigned long>(X >> 32))) + return static_cast<int>(63 - (LeadZeroIdx + 32)); // Create a bit offset from the MSB. + // Scan the low 32 bits. + if (_BitScanReverse(&LeadZeroIdx, static_cast<unsigned long>(X))) + return static_cast<int>(63 - LeadZeroIdx); + +#else if (_BitScanReverse64(&LeadZeroIdx, X)) return 63 - LeadZeroIdx; +#endif return 64; } @@ -50,7 +58,13 @@ inline uint32_t Clz(uint32_t X) { return 32; } -inline int Popcountll(unsigned long long X) { return __popcnt64(X); } +inline int Popcountll(unsigned long long X) { +#if !defined(_M_ARM) && !defined(_M_X64) + return __popcnt(X) + __popcnt(X >> 32); +#else + return __popcnt64(X); +#endif +} } // namespace fuzzer diff --git a/lib/fuzzer/FuzzerDefs.h b/lib/fuzzer/FuzzerDefs.h index 320b37d5f8e3..5dc2d8e1ac09 100644 --- a/lib/fuzzer/FuzzerDefs.h +++ b/lib/fuzzer/FuzzerDefs.h @@ -15,10 +15,11 @@ #include <cstddef> #include <cstdint> #include <cstring> +#include <memory> +#include <set> #include <string> #include <vector> -#include <set> -#include <memory> + // Platform detection. #ifdef __linux__ diff --git a/lib/fuzzer/FuzzerDriver.cpp b/lib/fuzzer/FuzzerDriver.cpp index 54c7ff079585..44c90655b932 100644 --- a/lib/fuzzer/FuzzerDriver.cpp +++ b/lib/fuzzer/FuzzerDriver.cpp @@ -708,7 +708,6 @@ int FuzzerDriver(int *argc, char ***argv, UserCallback Callback) { Options.FeaturesDir = Flags.features_dir; if (Flags.collect_data_flow) Options.CollectDataFlow = Flags.collect_data_flow; - Options.LazyCounters = Flags.lazy_counters; if (Flags.stop_file) Options.StopFile = Flags.stop_file; diff --git a/lib/fuzzer/FuzzerExtFunctions.def b/lib/fuzzer/FuzzerExtFunctions.def index 41fa0fd2b748..51edf8444e94 100644 --- a/lib/fuzzer/FuzzerExtFunctions.def +++ b/lib/fuzzer/FuzzerExtFunctions.def @@ -16,12 +16,12 @@ // Optional user functions EXT_FUNC(LLVMFuzzerInitialize, int, (int *argc, char ***argv), false); EXT_FUNC(LLVMFuzzerCustomMutator, size_t, - (uint8_t * Data, size_t Size, size_t MaxSize, unsigned int Seed), + (uint8_t *Data, size_t Size, size_t MaxSize, unsigned int Seed), false); EXT_FUNC(LLVMFuzzerCustomCrossOver, size_t, - (const uint8_t * Data1, size_t Size1, - const uint8_t * Data2, size_t Size2, - uint8_t * Out, size_t MaxOutSize, unsigned int Seed), + (const uint8_t *Data1, size_t Size1, + const uint8_t *Data2, size_t Size2, + uint8_t *Out, size_t MaxOutSize, unsigned int Seed), false); // Sanitizer functions @@ -33,8 +33,9 @@ EXT_FUNC(__sanitizer_install_malloc_and_free_hooks, int, (void (*malloc_hook)(const volatile void *, size_t), void (*free_hook)(const volatile void *)), false); +EXT_FUNC(__sanitizer_log_write, void, (const char *buf, size_t len), false); EXT_FUNC(__sanitizer_purge_allocator, void, (), false); -EXT_FUNC(__sanitizer_print_memory_profile, int, (size_t, size_t), false); +EXT_FUNC(__sanitizer_print_memory_profile, void, (size_t, size_t), false); EXT_FUNC(__sanitizer_print_stack_trace, void, (), true); EXT_FUNC(__sanitizer_symbolize_pc, void, (void *, const char *fmt, char *out_buf, size_t out_buf_size), false); diff --git a/lib/fuzzer/FuzzerFlags.def b/lib/fuzzer/FuzzerFlags.def index a11cfe4405f3..0e19a9cde6ca 100644 --- a/lib/fuzzer/FuzzerFlags.def +++ b/lib/fuzzer/FuzzerFlags.def @@ -123,9 +123,6 @@ FUZZER_FLAG_INT(handle_term, 1, "If 1, try to intercept SIGTERM.") FUZZER_FLAG_INT(handle_xfsz, 1, "If 1, try to intercept SIGXFSZ.") FUZZER_FLAG_INT(handle_usr1, 1, "If 1, try to intercept SIGUSR1.") FUZZER_FLAG_INT(handle_usr2, 1, "If 1, try to intercept SIGUSR2.") -FUZZER_FLAG_INT(lazy_counters, 0, "If 1, a performance optimization is" - "enabled for the 8bit inline counters. " - "Requires that libFuzzer successfully installs its SEGV handler") FUZZER_FLAG_INT(close_fd_mask, 0, "If 1, close stdout at startup; " "if 2, close stderr; if 3, close both. " "Be careful, this will also close e.g. stderr of asan.") diff --git a/lib/fuzzer/FuzzerInternal.h b/lib/fuzzer/FuzzerInternal.h index f2a4c437de38..31096ce804bc 100644 --- a/lib/fuzzer/FuzzerInternal.h +++ b/lib/fuzzer/FuzzerInternal.h @@ -98,7 +98,8 @@ private: void ReportNewCoverage(InputInfo *II, const Unit &U); void PrintPulseAndReportSlowInput(const uint8_t *Data, size_t Size); void WriteUnitToFileWithPrefix(const Unit &U, const char *Prefix); - void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0); + void PrintStats(const char *Where, const char *End = "\n", size_t Units = 0, + size_t Features = 0); void PrintStatusForNewUnit(const Unit &U, const char *Text); void CheckExitOnSrcPosOrItem(); diff --git a/lib/fuzzer/FuzzerLoop.cpp b/lib/fuzzer/FuzzerLoop.cpp index f773f9a13398..451a4c173167 100644 --- a/lib/fuzzer/FuzzerLoop.cpp +++ b/lib/fuzzer/FuzzerLoop.cpp @@ -273,9 +273,9 @@ void Fuzzer::InterruptCallback() { NO_SANITIZE_MEMORY void Fuzzer::AlarmCallback() { assert(Options.UnitTimeoutSec > 0); - // In Windows Alarm callback is executed by a different thread. + // In Windows and Fuchsia, Alarm callback is executed by a different thread. // NetBSD's current behavior needs this change too. -#if !LIBFUZZER_WINDOWS && !LIBFUZZER_NETBSD +#if !LIBFUZZER_WINDOWS && !LIBFUZZER_NETBSD && !LIBFUZZER_FUCHSIA if (!InFuzzingThread()) return; #endif @@ -319,14 +319,15 @@ void Fuzzer::RssLimitCallback() { _Exit(Options.OOMExitCode); // Stop right now. } -void Fuzzer::PrintStats(const char *Where, const char *End, size_t Units) { +void Fuzzer::PrintStats(const char *Where, const char *End, size_t Units, + size_t Features) { size_t ExecPerSec = execPerSec(); if (!Options.Verbosity) return; Printf("#%zd\t%s", TotalNumberOfRuns, Where); if (size_t N = TPC.GetTotalPCCoverage()) Printf(" cov: %zd", N); - if (size_t N = Corpus.NumFeatures()) + if (size_t N = Features ? Features : Corpus.NumFeatures()) Printf(" ft: %zd", N); if (!Corpus.empty()) { Printf(" corp: %zd", Corpus.NumActiveUnits()); @@ -512,10 +513,12 @@ size_t Fuzzer::GetCurrentUnitInFuzzingThead(const uint8_t **Data) const { } void Fuzzer::CrashOnOverwrittenData() { - Printf("==%d== ERROR: libFuzzer: fuzz target overwrites it's const input\n", + Printf("==%d== ERROR: libFuzzer: fuzz target overwrites its const input\n", GetPid()); + PrintStackTrace(); + Printf("SUMMARY: libFuzzer: overwrites-const-input\n"); DumpCurrentUnit("crash-"); - Printf("SUMMARY: libFuzzer: out-of-memory\n"); + PrintFinalStats(); _Exit(Options.ErrorExitCode); // Stop right now. } @@ -739,10 +742,6 @@ void Fuzzer::ReadAndExecuteSeedCorpora(Vector<SizedFile> &CorporaFiles) { uint8_t dummy = 0; ExecuteCallback(&dummy, 0); - // Protect lazy counters here, after the once-init code has been executed. - if (Options.LazyCounters) - TPC.ProtectLazyCounters(); - if (CorporaFiles.empty()) { Printf("INFO: A corpus is not provided, starting from an empty corpus\n"); Unit U({'\n'}); // Valid ASCII input. diff --git a/lib/fuzzer/FuzzerMerge.cpp b/lib/fuzzer/FuzzerMerge.cpp index 75b2b5d59b9c..e3ad8b3851e7 100644 --- a/lib/fuzzer/FuzzerMerge.cpp +++ b/lib/fuzzer/FuzzerMerge.cpp @@ -19,6 +19,7 @@ #include <iterator> #include <set> #include <sstream> +#include <unordered_set> namespace fuzzer { @@ -210,6 +211,9 @@ void Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) { std::ofstream OF(CFPath, std::ofstream::out | std::ofstream::app); Set<size_t> AllFeatures; + auto PrintStatsWrapper = [this, &AllFeatures](const char* Where) { + this->PrintStats(Where, "\n", 0, AllFeatures.size()); + }; Set<const TracePC::PCTableEntry *> AllPCs; for (size_t i = M.FirstNotProcessedFile; i < M.Files.size(); i++) { Fuzzer::MaybeExitGracefully(); @@ -218,7 +222,7 @@ void Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) { U.resize(MaxInputLen); U.shrink_to_fit(); } - std::ostringstream StartedLine; + // Write the pre-run marker. OF << "STARTED " << i << " " << U.size() << "\n"; OF.flush(); // Flush is important since Command::Execute may crash. @@ -238,7 +242,9 @@ void Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) { TPC.UpdateObservedPCs(); // Show stats. if (!(TotalNumberOfRuns & (TotalNumberOfRuns - 1))) - PrintStats("pulse "); + PrintStatsWrapper("pulse "); + if (TotalNumberOfRuns == M.NumFilesInFirstCorpus) + PrintStatsWrapper("LOADED"); // Write the post-run marker and the coverage. OF << "FT " << i; for (size_t F : UniqFeatures) @@ -252,25 +258,42 @@ void Fuzzer::CrashResistantMergeInternalStep(const std::string &CFPath) { OF << "\n"; OF.flush(); } - PrintStats("DONE "); + PrintStatsWrapper("DONE "); } -static void WriteNewControlFile(const std::string &CFPath, - const Vector<SizedFile> &OldCorpus, - const Vector<SizedFile> &NewCorpus) { - RemoveFile(CFPath); - std::ofstream ControlFile(CFPath); - ControlFile << (OldCorpus.size() + NewCorpus.size()) << "\n"; - ControlFile << OldCorpus.size() << "\n"; +static size_t WriteNewControlFile(const std::string &CFPath, + const Vector<SizedFile> &OldCorpus, + const Vector<SizedFile> &NewCorpus, + const Vector<MergeFileInfo> &KnownFiles) { + std::unordered_set<std::string> FilesToSkip; + for (auto &SF: KnownFiles) + FilesToSkip.insert(SF.Name); + + Vector<std::string> FilesToUse; + auto MaybeUseFile = [=, &FilesToUse](std::string Name) { + if (FilesToSkip.find(Name) == FilesToSkip.end()) + FilesToUse.push_back(Name); + }; for (auto &SF: OldCorpus) - ControlFile << SF.File << "\n"; + MaybeUseFile(SF.File); + auto FilesToUseFromOldCorpus = FilesToUse.size(); for (auto &SF: NewCorpus) - ControlFile << SF.File << "\n"; + MaybeUseFile(SF.File); + + RemoveFile(CFPath); + std::ofstream ControlFile(CFPath); + ControlFile << FilesToUse.size() << "\n"; + ControlFile << FilesToUseFromOldCorpus << "\n"; + for (auto &FN: FilesToUse) + ControlFile << FN << "\n"; + if (!ControlFile) { Printf("MERGE-OUTER: failed to write to the control file: %s\n", CFPath.c_str()); exit(1); } + + return FilesToUse.size(); } // Outer process. Does not call the target code and thus should not fail. @@ -286,12 +309,13 @@ void CrashResistantMerge(const Vector<std::string> &Args, bool V /*Verbose*/) { if (NewCorpus.empty() && OldCorpus.empty()) return; // Nothing to merge. size_t NumAttempts = 0; + Vector<MergeFileInfo> KnownFiles; if (FileSize(CFPath)) { VPrintf(V, "MERGE-OUTER: non-empty control file provided: '%s'\n", CFPath.c_str()); Merger M; std::ifstream IF(CFPath); - if (M.Parse(IF, /*ParseCoverage=*/false)) { + if (M.Parse(IF, /*ParseCoverage=*/true)) { VPrintf(V, "MERGE-OUTER: control file ok, %zd files total," " first not processed file %zd\n", M.Files.size(), M.FirstNotProcessedFile); @@ -300,12 +324,25 @@ void CrashResistantMerge(const Vector<std::string> &Args, "(merge has stumbled on it the last time)\n", M.LastFailure.c_str()); if (M.FirstNotProcessedFile >= M.Files.size()) { + // Merge has already been completed with the given merge control file. + if (M.Files.size() == OldCorpus.size() + NewCorpus.size()) { + VPrintf( + V, + "MERGE-OUTER: nothing to do, merge has been completed before\n"); + exit(0); + } + + // Number of input files likely changed, start merge from scratch, but + // reuse coverage information from the given merge control file. VPrintf( - V, "MERGE-OUTER: nothing to do, merge has been completed before\n"); - exit(0); + V, + "MERGE-OUTER: starting merge from scratch, but reusing coverage " + "information from the given control file\n"); + KnownFiles = M.Files; + } else { + // There is a merge in progress, continue. + NumAttempts = M.Files.size() - M.FirstNotProcessedFile; } - - NumAttempts = M.Files.size() - M.FirstNotProcessedFile; } else { VPrintf(V, "MERGE-OUTER: bad control file, will overwrite it\n"); } @@ -313,10 +350,11 @@ void CrashResistantMerge(const Vector<std::string> &Args, if (!NumAttempts) { // The supplied control file is empty or bad, create a fresh one. - NumAttempts = OldCorpus.size() + NewCorpus.size(); - VPrintf(V, "MERGE-OUTER: %zd files, %zd in the initial corpus\n", - NumAttempts, OldCorpus.size()); - WriteNewControlFile(CFPath, OldCorpus, NewCorpus); + VPrintf(V, "MERGE-OUTER: " + "%zd files, %zd in the initial corpus, %zd processed earlier\n", + OldCorpus.size() + NewCorpus.size(), OldCorpus.size(), + KnownFiles.size()); + NumAttempts = WriteNewControlFile(CFPath, OldCorpus, NewCorpus, KnownFiles); } // Execute the inner process until it passes. @@ -353,6 +391,8 @@ void CrashResistantMerge(const Vector<std::string> &Args, VPrintf(V, "MERGE-OUTER: consumed %zdMb (%zdMb rss) to parse the control file\n", M.ApproximateMemoryConsumption() >> 20, GetPeakRSSMb()); + + M.Files.insert(M.Files.end(), KnownFiles.begin(), KnownFiles.end()); M.Merge(InitialFeatures, NewFeatures, InitialCov, NewCov, NewFiles); VPrintf(V, "MERGE-OUTER: %zd new files with %zd new features added; " "%zd new coverage edges\n", diff --git a/lib/fuzzer/FuzzerOptions.h b/lib/fuzzer/FuzzerOptions.h index ad3df015bc77..beecc980380b 100644 --- a/lib/fuzzer/FuzzerOptions.h +++ b/lib/fuzzer/FuzzerOptions.h @@ -75,7 +75,6 @@ struct FuzzingOptions { bool HandleXfsz = false; bool HandleUsr1 = false; bool HandleUsr2 = false; - bool LazyCounters = false; }; } // namespace fuzzer diff --git a/lib/fuzzer/FuzzerTracePC.cpp b/lib/fuzzer/FuzzerTracePC.cpp index 4a1308de5504..f03be7a39502 100644 --- a/lib/fuzzer/FuzzerTracePC.cpp +++ b/lib/fuzzer/FuzzerTracePC.cpp @@ -67,45 +67,6 @@ void TracePC::HandleInline8bitCountersInit(uint8_t *Start, uint8_t *Stop) { NumInline8bitCounters += M.Size(); } -// Mark all full page counter regions as PROT_NONE and set Enabled=false. -// The first time the instrumented code hits such a protected/disabled -// counter region we should catch a SEGV and call UnprotectLazyCounters, -// which will mark the page as PROT_READ|PROT_WRITE and set Enabled=true. -// -// Whenever other functions iterate over the counters they should ignore -// regions with Enabled=false. -void TracePC::ProtectLazyCounters() { - size_t NumPagesProtected = 0; - IterateCounterRegions([&](Module::Region &R) { - if (!R.OneFullPage) return; - if (Mprotect(R.Start, R.Stop - R.Start, false)) { - R.Enabled = false; - NumPagesProtected++; - } - }); - if (NumPagesProtected) - Printf("INFO: %zd pages of counters where protected;" - " libFuzzer's SEGV handler must be installed\n", - NumPagesProtected); -} - -bool TracePC::UnprotectLazyCounters(void *CounterPtr) { - // Printf("UnprotectLazyCounters: %p\n", CounterPtr); - if (!CounterPtr) - return false; - bool Done = false; - uint8_t *Addr = reinterpret_cast<uint8_t *>(CounterPtr); - IterateCounterRegions([&](Module::Region &R) { - if (!R.OneFullPage || R.Enabled || Done) return; - if (Addr >= R.Start && Addr < R.Stop) - if (Mprotect(R.Start, R.Stop - R.Start, true)) { - R.Enabled = true; - Done = true; - } - }); - return Done; -} - void TracePC::HandlePCsInit(const uintptr_t *Start, const uintptr_t *Stop) { const PCTableEntry *B = reinterpret_cast<const PCTableEntry *>(Start); const PCTableEntry *E = reinterpret_cast<const PCTableEntry *>(Stop); @@ -173,7 +134,7 @@ inline ALWAYS_INLINE uintptr_t GetPreviousInstructionPc(uintptr_t PC) { } /// \return the address of the next instruction. -/// Note: the logic is copied from `sanitizer_common/sanitizer_stacktrace.cc` +/// Note: the logic is copied from `sanitizer_common/sanitizer_stacktrace.cpp` ALWAYS_INLINE uintptr_t TracePC::GetNextInstructionPc(uintptr_t PC) { #if defined(__mips__) return PC + 8; diff --git a/lib/fuzzer/FuzzerTracePC.h b/lib/fuzzer/FuzzerTracePC.h index 4f5ebeb047a1..501f3b544971 100644 --- a/lib/fuzzer/FuzzerTracePC.h +++ b/lib/fuzzer/FuzzerTracePC.h @@ -119,9 +119,6 @@ class TracePC { void SetFocusFunction(const std::string &FuncName); bool ObservedFocusFunction(); - void ProtectLazyCounters(); - bool UnprotectLazyCounters(void *CounterPtr); - struct PCTableEntry { uintptr_t PC, PCFlags; }; diff --git a/lib/fuzzer/FuzzerUtil.h b/lib/fuzzer/FuzzerUtil.h index 0a127911df3c..85c5571d684f 100644 --- a/lib/fuzzer/FuzzerUtil.h +++ b/lib/fuzzer/FuzzerUtil.h @@ -52,8 +52,6 @@ void SetSignalHandler(const FuzzingOptions& Options); void SleepSeconds(int Seconds); -bool Mprotect(void *Ptr, size_t Size, bool AllowReadWrite); - unsigned long GetPid(); size_t GetPeakRSSMb(); diff --git a/lib/fuzzer/FuzzerUtilFuchsia.cpp b/lib/fuzzer/FuzzerUtilFuchsia.cpp index 1f04b33c154e..79fd950bbf97 100644 --- a/lib/fuzzer/FuzzerUtilFuchsia.cpp +++ b/lib/fuzzer/FuzzerUtilFuchsia.cpp @@ -305,12 +305,19 @@ void CrashHandler(zx_handle_t *Event) { } // namespace -bool Mprotect(void *Ptr, size_t Size, bool AllowReadWrite) { - return false; // UNIMPLEMENTED -} - // Platform specific functions. void SetSignalHandler(const FuzzingOptions &Options) { + // Make sure information from libFuzzer and the sanitizers are easy to + // reassemble. `__sanitizer_log_write` has the added benefit of ensuring the + // DSO map is always available for the symbolizer. + // A uint64_t fits in 20 chars, so 64 is plenty. + char Buf[64]; + memset(Buf, 0, sizeof(Buf)); + snprintf(Buf, sizeof(Buf), "==%lu== INFO: libFuzzer starting.\n", GetPid()); + if (EF->__sanitizer_log_write) + __sanitizer_log_write(Buf, sizeof(Buf)); + Printf("%s", Buf); + // Set up alarm handler if needed. if (Options.UnitTimeoutSec > 0) { std::thread T(AlarmHandler, Options.UnitTimeoutSec / 2 + 1); @@ -400,13 +407,14 @@ int ExecuteCommand(const Command &Cmd) { // that lacks a mutable working directory. Fortunately, when this is the case // a mutable output directory must be specified using "-artifact_prefix=...", // so write the log file(s) there. + // However, we don't want to apply this logic for absolute paths. int FdOut = STDOUT_FILENO; if (Cmd.hasOutputFile()) { - std::string Path; - if (Cmd.hasFlag("artifact_prefix")) - Path = Cmd.getFlagValue("artifact_prefix") + "/" + Cmd.getOutputFile(); - else - Path = Cmd.getOutputFile(); + std::string Path = Cmd.getOutputFile(); + bool IsAbsolutePath = Path.length() > 1 && Path[0] == '/'; + if (!IsAbsolutePath && Cmd.hasFlag("artifact_prefix")) + Path = Cmd.getFlagValue("artifact_prefix") + "/" + Path; + FdOut = open(Path.c_str(), O_WRONLY | O_CREAT | O_TRUNC, 0); if (FdOut == -1) { Printf("libFuzzer: failed to open %s: %s\n", Path.c_str(), diff --git a/lib/fuzzer/FuzzerUtilPosix.cpp b/lib/fuzzer/FuzzerUtilPosix.cpp index 110785d87413..cefe7ae181e7 100644 --- a/lib/fuzzer/FuzzerUtilPosix.cpp +++ b/lib/fuzzer/FuzzerUtilPosix.cpp @@ -37,7 +37,6 @@ static void (*upstream_segv_handler)(int, siginfo_t *, void *); static void SegvHandler(int sig, siginfo_t *si, void *ucontext) { assert(si->si_signo == SIGSEGV); - if (TPC.UnprotectLazyCounters(si->si_addr)) return; if (upstream_segv_handler) return upstream_segv_handler(sig, si, ucontext); Fuzzer::StaticCrashSignalCallback(); @@ -98,11 +97,6 @@ void SetTimer(int Seconds) { SetSigaction(SIGALRM, AlarmHandler); } -bool Mprotect(void *Ptr, size_t Size, bool AllowReadWrite) { - return 0 == mprotect(Ptr, Size, - AllowReadWrite ? (PROT_READ | PROT_WRITE) : PROT_NONE); -} - void SetSignalHandler(const FuzzingOptions& Options) { if (Options.UnitTimeoutSec > 0) SetTimer(Options.UnitTimeoutSec / 2 + 1); diff --git a/lib/fuzzer/FuzzerUtilWindows.cpp b/lib/fuzzer/FuzzerUtilWindows.cpp index 074e1eb42309..ed90044c3f83 100644 --- a/lib/fuzzer/FuzzerUtilWindows.cpp +++ b/lib/fuzzer/FuzzerUtilWindows.cpp @@ -111,10 +111,6 @@ static TimerQ Timer; static void CrashHandler(int) { Fuzzer::StaticCrashSignalCallback(); } -bool Mprotect(void *Ptr, size_t Size, bool AllowReadWrite) { - return false; // UNIMPLEMENTED -} - void SetSignalHandler(const FuzzingOptions& Options) { HandlerOpt = &Options; diff --git a/lib/gwp_asan/guarded_pool_allocator.cpp b/lib/gwp_asan/guarded_pool_allocator.cpp index 7e3628eba6ff..ef497336025f 100644 --- a/lib/gwp_asan/guarded_pool_allocator.cpp +++ b/lib/gwp_asan/guarded_pool_allocator.cpp @@ -13,7 +13,7 @@ // RHEL creates the PRIu64 format macro (for printing uint64_t's) only when this // macro is defined before including <inttypes.h>. #ifndef __STDC_FORMAT_MACROS - #define __STDC_FORMAT_MACROS 1 +#define __STDC_FORMAT_MACROS 1 #endif #include <assert.h> @@ -44,11 +44,12 @@ private: bool &Bool; }; -void defaultPrintStackTrace(uintptr_t *Trace, options::Printf_t Printf) { - if (Trace[0] == 0) +void defaultPrintStackTrace(uintptr_t *Trace, size_t TraceLength, + options::Printf_t Printf) { + if (TraceLength == 0) Printf(" <unknown (does your allocator support backtracing?)>\n"); - for (size_t i = 0; Trace[i] != 0; ++i) { + for (size_t i = 0; i < TraceLength; ++i) { Printf(" #%zu 0x%zx in <unknown>\n", i, Trace[i]); } Printf("\n"); @@ -68,12 +69,18 @@ void GuardedPoolAllocator::AllocationMetadata::RecordAllocation( // TODO(hctim): Ask the caller to provide the thread ID, so we don't waste // other thread's time getting the thread ID under lock. AllocationTrace.ThreadID = getThreadID(); + AllocationTrace.TraceSize = 0; + DeallocationTrace.TraceSize = 0; DeallocationTrace.ThreadID = kInvalidThreadID; - if (Backtrace) - Backtrace(AllocationTrace.Trace, kMaximumStackFrames); - else - AllocationTrace.Trace[0] = 0; - DeallocationTrace.Trace[0] = 0; + + if (Backtrace) { + uintptr_t UncompressedBuffer[kMaxTraceLengthToCollect]; + size_t BacktraceLength = + Backtrace(UncompressedBuffer, kMaxTraceLengthToCollect); + AllocationTrace.TraceSize = compression::pack( + UncompressedBuffer, BacktraceLength, AllocationTrace.CompressedTrace, + kStackFrameStorageBytes); + } } void GuardedPoolAllocator::AllocationMetadata::RecordDeallocation( @@ -81,11 +88,16 @@ void GuardedPoolAllocator::AllocationMetadata::RecordDeallocation( IsDeallocated = true; // Ensure that the unwinder is not called if the recursive flag is set, // otherwise non-reentrant unwinders may deadlock. + DeallocationTrace.TraceSize = 0; if (Backtrace && !ThreadLocals.RecursiveGuard) { ScopedBoolean B(ThreadLocals.RecursiveGuard); - Backtrace(DeallocationTrace.Trace, kMaximumStackFrames); - } else { - DeallocationTrace.Trace[0] = 0; + + uintptr_t UncompressedBuffer[kMaxTraceLengthToCollect]; + size_t BacktraceLength = + Backtrace(UncompressedBuffer, kMaxTraceLengthToCollect); + DeallocationTrace.TraceSize = compression::pack( + UncompressedBuffer, BacktraceLength, DeallocationTrace.CompressedTrace, + kStackFrameStorageBytes); } DeallocationTrace.ThreadID = getThreadID(); } @@ -161,7 +173,7 @@ void GuardedPoolAllocator::init(const options::Options &Opts) { // Ensure that signal handlers are installed as late as possible, as the class // is not thread-safe until init() is finished, and thus a SIGSEGV may cause a - // race to members if recieved during init(). + // race to members if received during init(). if (Opts.InstallSignalHandlers) installSignalHandlers(); } @@ -373,7 +385,7 @@ void printErrorType(Error E, uintptr_t AccessPtr, AllocationMetadata *Meta, case Error::UNKNOWN: ErrorString = "GWP-ASan couldn't automatically determine the source of " "the memory error. It was likely caused by a wild memory " - "access into the GWP-ASan pool. The error occured"; + "access into the GWP-ASan pool. The error occurred"; break; case Error::USE_AFTER_FREE: ErrorString = "Use after free"; @@ -442,7 +454,13 @@ void printAllocDeallocTraces(uintptr_t AccessPtr, AllocationMetadata *Meta, Printf("0x%zx was deallocated by thread %zu here:\n", AccessPtr, Meta->DeallocationTrace.ThreadID); - PrintBacktrace(Meta->DeallocationTrace.Trace, Printf); + uintptr_t UncompressedTrace[AllocationMetadata::kMaxTraceLengthToCollect]; + size_t UncompressedLength = compression::unpack( + Meta->DeallocationTrace.CompressedTrace, + Meta->DeallocationTrace.TraceSize, UncompressedTrace, + AllocationMetadata::kMaxTraceLengthToCollect); + + PrintBacktrace(UncompressedTrace, UncompressedLength, Printf); } if (Meta->AllocationTrace.ThreadID == GuardedPoolAllocator::kInvalidThreadID) @@ -451,7 +469,12 @@ void printAllocDeallocTraces(uintptr_t AccessPtr, AllocationMetadata *Meta, Printf("0x%zx was allocated by thread %zu here:\n", Meta->Addr, Meta->AllocationTrace.ThreadID); - PrintBacktrace(Meta->AllocationTrace.Trace, Printf); + uintptr_t UncompressedTrace[AllocationMetadata::kMaxTraceLengthToCollect]; + size_t UncompressedLength = compression::unpack( + Meta->AllocationTrace.CompressedTrace, Meta->AllocationTrace.TraceSize, + UncompressedTrace, AllocationMetadata::kMaxTraceLengthToCollect); + + PrintBacktrace(UncompressedTrace, UncompressedLength, Printf); } struct ScopedEndOfReportDecorator { @@ -491,11 +514,11 @@ void GuardedPoolAllocator::reportErrorInternal(uintptr_t AccessPtr, Error E) { uint64_t ThreadID = getThreadID(); printErrorType(E, AccessPtr, Meta, Printf, ThreadID); if (Backtrace) { - static constexpr unsigned kMaximumStackFramesForCrashTrace = 128; + static constexpr unsigned kMaximumStackFramesForCrashTrace = 512; uintptr_t Trace[kMaximumStackFramesForCrashTrace]; - Backtrace(Trace, kMaximumStackFramesForCrashTrace); + size_t TraceLength = Backtrace(Trace, kMaximumStackFramesForCrashTrace); - PrintBacktrace(Trace, Printf); + PrintBacktrace(Trace, TraceLength, Printf); } else { Printf(" <unknown (does your allocator support backtracing?)>\n\n"); } diff --git a/lib/gwp_asan/guarded_pool_allocator.h b/lib/gwp_asan/guarded_pool_allocator.h index 28a41110faed..57ad61e9cf4f 100644 --- a/lib/gwp_asan/guarded_pool_allocator.h +++ b/lib/gwp_asan/guarded_pool_allocator.h @@ -13,6 +13,7 @@ #include "gwp_asan/mutex.h" #include "gwp_asan/options.h" #include "gwp_asan/random.h" +#include "gwp_asan/stack_trace_compressor.h" #include <stddef.h> #include <stdint.h> @@ -39,9 +40,15 @@ public: }; struct AllocationMetadata { - // Maximum number of stack trace frames to collect for allocations + frees. - // TODO(hctim): Implement stack frame compression, a-la Chromium. - static constexpr size_t kMaximumStackFrames = 64; + // The number of bytes used to store a compressed stack frame. On 64-bit + // platforms, assuming a compression ratio of 50%, this should allow us to + // store ~64 frames per trace. + static constexpr size_t kStackFrameStorageBytes = 256; + + // Maximum number of stack frames to collect on allocation/deallocation. The + // actual number of collected frames may be less than this as the stack + // frames are compressed into a fixed memory range. + static constexpr size_t kMaxTraceLengthToCollect = 128; // Records the given allocation metadata into this struct. void RecordAllocation(uintptr_t Addr, size_t Size, @@ -51,11 +58,13 @@ public: void RecordDeallocation(options::Backtrace_t Backtrace); struct CallSiteInfo { - // The backtrace to the allocation/deallocation. If the first value is - // zero, we did not collect a trace. - uintptr_t Trace[kMaximumStackFrames] = {}; + // The compressed backtrace to the allocation/deallocation. + uint8_t CompressedTrace[kStackFrameStorageBytes]; // The thread ID for this trace, or kInvalidThreadID if not available. uint64_t ThreadID = kInvalidThreadID; + // The size of the compressed trace (in bytes). Zero indicates that no + // trace was collected. + size_t TraceSize = 0; }; // The address of this allocation. diff --git a/lib/gwp_asan/optional/backtrace.h b/lib/gwp_asan/optional/backtrace.h index 2700970e5e8e..6c9ee9f6506d 100644 --- a/lib/gwp_asan/optional/backtrace.h +++ b/lib/gwp_asan/optional/backtrace.h @@ -14,7 +14,12 @@ namespace gwp_asan { namespace options { // Functions to get the platform-specific and implementation-specific backtrace -// and backtrace printing functions. +// and backtrace printing functions when RTGwpAsanBacktraceLibc or +// RTGwpAsanBacktraceSanitizerCommon are linked. Use these functions to get the +// backtrace function for populating the Options::Backtrace and +// Options::PrintBacktrace when initialising the GuardedPoolAllocator. Please +// note any thread-safety descriptions for the implementation of these functions +// that you use. Backtrace_t getBacktraceFunction(); PrintBacktrace_t getPrintBacktraceFunction(); } // namespace options diff --git a/lib/gwp_asan/optional/backtrace_linux_libc.cpp b/lib/gwp_asan/optional/backtrace_linux_libc.cpp index f20a3100927e..a656c9b41d5d 100644 --- a/lib/gwp_asan/optional/backtrace_linux_libc.cpp +++ b/lib/gwp_asan/optional/backtrace_linux_libc.cpp @@ -17,33 +17,23 @@ #include "gwp_asan/options.h" namespace { -void Backtrace(uintptr_t *TraceBuffer, size_t Size) { - // Grab (what seems to be) one more trace than we need. TraceBuffer needs to - // be null-terminated, but we wish to remove the frame of this function call. +size_t Backtrace(uintptr_t *TraceBuffer, size_t Size) { static_assert(sizeof(uintptr_t) == sizeof(void *), "uintptr_t is not void*"); - int NumTraces = - backtrace(reinterpret_cast<void **>(TraceBuffer), Size); - // Now shift the entire trace one place to the left and null-terminate. - memmove(TraceBuffer, TraceBuffer + 1, NumTraces * sizeof(void *)); - TraceBuffer[NumTraces - 1] = 0; + return backtrace(reinterpret_cast<void **>(TraceBuffer), Size); } -static void PrintBacktrace(uintptr_t *Trace, +static void PrintBacktrace(uintptr_t *Trace, size_t TraceLength, gwp_asan::options::Printf_t Printf) { - size_t NumTraces = 0; - for (; Trace[NumTraces] != 0; ++NumTraces) { - } - - if (NumTraces == 0) { + if (TraceLength == 0) { Printf(" <not found (does your allocator support backtracing?)>\n\n"); return; } char **BacktraceSymbols = - backtrace_symbols(reinterpret_cast<void **>(Trace), NumTraces); + backtrace_symbols(reinterpret_cast<void **>(Trace), TraceLength); - for (size_t i = 0; i < NumTraces; ++i) { + for (size_t i = 0; i < TraceLength; ++i) { if (!BacktraceSymbols) Printf(" #%zu %p\n", i, Trace[i]); else diff --git a/lib/gwp_asan/optional/backtrace_sanitizer_common.cpp b/lib/gwp_asan/optional/backtrace_sanitizer_common.cpp index 7d17eec0da2f..5e07fd6f465a 100644 --- a/lib/gwp_asan/optional/backtrace_sanitizer_common.cpp +++ b/lib/gwp_asan/optional/backtrace_sanitizer_common.cpp @@ -13,6 +13,9 @@ #include "gwp_asan/optional/backtrace.h" #include "gwp_asan/options.h" +#include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_flag_parser.h" +#include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_stacktrace.h" void __sanitizer::BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, @@ -26,7 +29,7 @@ void __sanitizer::BufferedStackTrace::UnwindImpl(uptr pc, uptr bp, } namespace { -void Backtrace(uintptr_t *TraceBuffer, size_t Size) { +size_t Backtrace(uintptr_t *TraceBuffer, size_t Size) { __sanitizer::BufferedStackTrace Trace; Trace.Reset(); if (Size > __sanitizer::kStackTraceMax) @@ -38,19 +41,14 @@ void Backtrace(uintptr_t *TraceBuffer, size_t Size) { /* fast unwind */ true, Size - 1); memcpy(TraceBuffer, Trace.trace, Trace.size * sizeof(uintptr_t)); - TraceBuffer[Trace.size] = 0; + return Trace.size; } -static void PrintBacktrace(uintptr_t *Trace, +static void PrintBacktrace(uintptr_t *Trace, size_t TraceLength, gwp_asan::options::Printf_t Printf) { __sanitizer::StackTrace StackTrace; StackTrace.trace = reinterpret_cast<__sanitizer::uptr *>(Trace); - - for (StackTrace.size = 0; StackTrace.size < __sanitizer::kStackTraceMax; - ++StackTrace.size) { - if (Trace[StackTrace.size] == 0) - break; - } + StackTrace.size = TraceLength; if (StackTrace.size == 0) { Printf(" <unknown (does your allocator support backtracing?)>\n\n"); @@ -63,7 +61,18 @@ static void PrintBacktrace(uintptr_t *Trace, namespace gwp_asan { namespace options { -Backtrace_t getBacktraceFunction() { return Backtrace; } +// This function is thread-compatible. It must be synchronised in respect to any +// other calls to getBacktraceFunction(), calls to getPrintBacktraceFunction(), +// and calls to either of the functions that they return. Furthermore, this may +// require synchronisation with any calls to sanitizer_common that use flags. +// Generally, this function will be called during the initialisation of the +// allocator, which is done in a thread-compatible manner. +Backtrace_t getBacktraceFunction() { + // The unwinder requires the default flags to be set. + __sanitizer::SetCommonFlagsDefaults(); + __sanitizer::InitializeCommonFlags(); + return Backtrace; +} PrintBacktrace_t getPrintBacktraceFunction() { return PrintBacktrace; } } // namespace options } // namespace gwp_asan diff --git a/lib/gwp_asan/options.h b/lib/gwp_asan/options.h index 6423e16526f4..ae3f3d45e946 100644 --- a/lib/gwp_asan/options.h +++ b/lib/gwp_asan/options.h @@ -14,22 +14,63 @@ namespace gwp_asan { namespace options { -// The function pointer type for printf(). Follows the standard format from the -// sanitizers library. If the supported allocator exposes printing via a -// different function signature, please provide a wrapper which has this -// printf() signature, and pass the wrapper instead. +// ================================ Requirements =============================== +// This function is required to be implemented by the supporting allocator. The +// sanitizer::Printf() function can be simply used here. +// ================================ Description ================================ +// This function shall produce output according to a strict subset of the C +// standard library's printf() family. This function must support printing the +// following formats: +// 1. integers: "%([0-9]*)?(z|ll)?{d,u,x,X}" +// 2. pointers: "%p" +// 3. strings: "%[-]([0-9]*)?(\\.\\*)?s" +// 4. chars: "%c" +// This function must be implemented in a signal-safe manner. +// =================================== Notes =================================== +// This function has a slightly different signature than the C standard +// library's printf(). Notably, it returns 'void' rather than 'int'. typedef void (*Printf_t)(const char *Format, ...); -// The function pointer type for backtrace information. Required to be -// implemented by the supporting allocator. The callee should elide itself and -// all frames below itself from TraceBuffer, i.e. the caller's frame should be -// in TraceBuffer[0], and subsequent frames 1..n into TraceBuffer[1..n], where a -// maximum of `MaximumDepth - 1` frames are stored. TraceBuffer should be -// nullptr-terminated (i.e. if there are 5 frames; TraceBuffer[5] == nullptr). -// If the allocator cannot supply backtrace information, it should set -// TraceBuffer[0] == nullptr. -typedef void (*Backtrace_t)(uintptr_t *TraceBuffer, size_t Size); -typedef void (*PrintBacktrace_t)(uintptr_t *TraceBuffer, Printf_t Print); +// ================================ Requirements =============================== +// This function is required to be either implemented by the supporting +// allocator, or one of the two provided implementations may be used +// (RTGwpAsanBacktraceLibc or RTGwpAsanBacktraceSanitizerCommon). +// ================================ Description ================================ +// This function shall collect the backtrace for the calling thread and place +// the result in `TraceBuffer`. This function should elide itself and all frames +// below itself from `TraceBuffer`, i.e. the caller's frame should be in +// TraceBuffer[0], and subsequent frames 1..n into TraceBuffer[1..n], where a +// maximum of `Size` frames are stored. Returns the number of frames stored into +// `TraceBuffer`, and zero on failure. If the return value of this function is +// equal to `Size`, it may indicate that the backtrace is truncated. +// =================================== Notes =================================== +// This function may directly or indirectly call malloc(), as the +// GuardedPoolAllocator contains a reentrancy barrier to prevent infinite +// recursion. Any allocation made inside this function will be served by the +// supporting allocator, and will not have GWP-ASan protections. +typedef size_t (*Backtrace_t)(uintptr_t *TraceBuffer, size_t Size); + +// ================================ Requirements =============================== +// This function is optional for the supporting allocator, but one of the two +// provided implementations may be used (RTGwpAsanBacktraceLibc or +// RTGwpAsanBacktraceSanitizerCommon). If not provided, a default implementation +// is used which prints the raw pointers only. +// ================================ Description ================================ +// This function shall take the backtrace provided in `TraceBuffer`, and print +// it in a human-readable format using `Print`. Generally, this function shall +// resolve raw pointers to section offsets and print them with the following +// sanitizer-common format: +// " #{frame_number} {pointer} in {function name} ({binary name}+{offset}" +// e.g. " #5 0x420459 in _start (/tmp/uaf+0x420459)" +// This format allows the backtrace to be symbolized offline successfully using +// llvm-symbolizer. +// =================================== Notes =================================== +// This function may directly or indirectly call malloc(), as the +// GuardedPoolAllocator contains a reentrancy barrier to prevent infinite +// recursion. Any allocation made inside this function will be served by the +// supporting allocator, and will not have GWP-ASan protections. +typedef void (*PrintBacktrace_t)(uintptr_t *TraceBuffer, size_t TraceLength, + Printf_t Print); struct Options { Printf_t Printf = nullptr; diff --git a/lib/gwp_asan/options.inc b/lib/gwp_asan/options.inc index 9042b11895ae..df6c46e6e98f 100644 --- a/lib/gwp_asan/options.inc +++ b/lib/gwp_asan/options.inc @@ -21,9 +21,9 @@ GWP_ASAN_OPTION( "byte buffer-overflows for multibyte allocations at the cost of " "performance, and may be incompatible with some architectures.") -GWP_ASAN_OPTION( - int, MaxSimultaneousAllocations, 16, - "Number of usable guarded slots in the allocation pool. Defaults to 16.") +GWP_ASAN_OPTION(int, MaxSimultaneousAllocations, 16, + "Number of simultaneously-guarded allocations available in the " + "pool. Defaults to 16.") GWP_ASAN_OPTION(int, SampleRate, 5000, "The probability (1 / SampleRate) that an allocation is " diff --git a/lib/gwp_asan/scripts/symbolize.sh b/lib/gwp_asan/scripts/symbolize.sh new file mode 100755 index 000000000000..fad9620a676e --- /dev/null +++ b/lib/gwp_asan/scripts/symbolize.sh @@ -0,0 +1,55 @@ +#!/bin/bash + +# The lines that we're looking to symbolize look like this: + #0 ./a.out(_foo+0x3e6) [0x55a52e64c696] +# ... which come from the backtrace_symbols() symbolisation function used by +# default in Scudo's implementation of GWP-ASan. + +while read -r line; do + # Check that this line needs symbolization. + should_symbolize="$(echo $line |\ + grep -E '^[ ]*\#.*\(.*\+0x[0-9a-f]+\) \[0x[0-9a-f]+\]$')" + + if [ -z "$should_symbolize" ]; then + echo "$line" + continue + fi + + # Carve up the input line into sections. + binary_name="$(echo $line | grep -oE ' .*\(' | rev | cut -c2- | rev |\ + cut -c2-)" + function_name="$(echo $line | grep -oE '\([^+]*' | cut -c2-)" + function_offset="$(echo $line | grep -oE '\(.*\)' | grep -oE '\+.*\)' |\ + cut -c2- | rev | cut -c2- | rev)" + frame_number="$(echo $line | grep -oE '\#[0-9]+ ')" + + if [ -z "$function_name" ]; then + # If the offset is binary-relative, just resolve that. + symbolized="$(echo $function_offset | addr2line -e $binary_name)" + else + # Otherwise, the offset is function-relative. Get the address of the + # function, and add it to the offset, then symbolize. + function_addr="0x$(echo $function_offset |\ + nm --defined-only $binary_name 2> /dev/null |\ + grep -E " $function_name$" | cut -d' ' -f1)" + + # Check that we could get the function address from nm. + if [ -z "$function_addr" ]; then + echo "$line" + continue + fi + + # Add the function address and offset to get the offset into the binary. + binary_offset="$(printf "0x%X" "$((function_addr+function_offset))")" + symbolized="$(echo $binary_offset | addr2line -e $binary_name)" + fi + + # Check that it symbolized properly. If it didn't, output the old line. + echo $symbolized | grep -E ".*\?.*:" > /dev/null + if [ "$?" -eq "0" ]; then + echo "$line" + continue + else + echo "${frame_number}${symbolized}" + fi +done diff --git a/lib/gwp_asan/stack_trace_compressor.cpp b/lib/gwp_asan/stack_trace_compressor.cpp new file mode 100644 index 000000000000..ca3167fb83a8 --- /dev/null +++ b/lib/gwp_asan/stack_trace_compressor.cpp @@ -0,0 +1,111 @@ +//===-- stack_trace_compressor.cpp ------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#include "gwp_asan/stack_trace_compressor.h" + +namespace gwp_asan { +namespace compression { +namespace { +// Encodes `Value` as a variable-length integer to `Out`. Returns zero if there +// was not enough space in the output buffer to write the complete varInt. +// Otherwise returns the length of the encoded integer. +size_t varIntEncode(uintptr_t Value, uint8_t *Out, size_t OutLen) { + for (size_t i = 0; i < OutLen; ++i) { + Out[i] = Value & 0x7f; + Value >>= 7; + if (!Value) + return i + 1; + + Out[i] |= 0x80; + } + + return 0; +} + +// Decodes a variable-length integer to `Out`. Returns zero if the integer was +// too large to be represented in a uintptr_t, or if the input buffer finished +// before the integer was decoded (either case meaning that the `In` does not +// point to a valid varInt buffer). Otherwise, returns the number of bytes that +// were used to store the decoded integer. +size_t varIntDecode(const uint8_t *In, size_t InLen, uintptr_t *Out) { + *Out = 0; + uint8_t Shift = 0; + + for (size_t i = 0; i < InLen; ++i) { + *Out |= (static_cast<uintptr_t>(In[i]) & 0x7f) << Shift; + + if (In[i] < 0x80) + return i + 1; + + Shift += 7; + + // Disallow overflowing the range of the output integer. + if (Shift >= sizeof(uintptr_t) * 8) + return 0; + } + return 0; +} + +uintptr_t zigzagEncode(uintptr_t Value) { + uintptr_t Encoded = Value << 1; + if (static_cast<intptr_t>(Value) >= 0) + return Encoded; + return ~Encoded; +} + +uintptr_t zigzagDecode(uintptr_t Value) { + uintptr_t Decoded = Value >> 1; + if (!(Value & 1)) + return Decoded; + return ~Decoded; +} +} // anonymous namespace + +size_t pack(const uintptr_t *Unpacked, size_t UnpackedSize, uint8_t *Packed, + size_t PackedMaxSize) { + size_t Index = 0; + for (size_t CurrentDepth = 0; CurrentDepth < UnpackedSize; CurrentDepth++) { + uintptr_t Diff = Unpacked[CurrentDepth]; + if (CurrentDepth > 0) + Diff -= Unpacked[CurrentDepth - 1]; + size_t EncodedLength = + varIntEncode(zigzagEncode(Diff), Packed + Index, PackedMaxSize - Index); + if (!EncodedLength) + break; + + Index += EncodedLength; + } + + return Index; +} + +size_t unpack(const uint8_t *Packed, size_t PackedSize, uintptr_t *Unpacked, + size_t UnpackedMaxSize) { + size_t CurrentDepth; + size_t Index = 0; + for (CurrentDepth = 0; CurrentDepth < UnpackedMaxSize; CurrentDepth++) { + uintptr_t EncodedDiff; + size_t DecodedLength = + varIntDecode(Packed + Index, PackedSize - Index, &EncodedDiff); + if (!DecodedLength) + break; + Index += DecodedLength; + + Unpacked[CurrentDepth] = zigzagDecode(EncodedDiff); + if (CurrentDepth > 0) + Unpacked[CurrentDepth] += Unpacked[CurrentDepth - 1]; + } + + if (Index != PackedSize && CurrentDepth != UnpackedMaxSize) + return 0; + + return CurrentDepth; +} + +} // namespace compression +} // namespace gwp_asan diff --git a/lib/gwp_asan/stack_trace_compressor.h b/lib/gwp_asan/stack_trace_compressor.h new file mode 100644 index 000000000000..dcbd9a3c1f0a --- /dev/null +++ b/lib/gwp_asan/stack_trace_compressor.h @@ -0,0 +1,38 @@ +//===-- stack_trace_compressor.h --------------------------------*- C++ -*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// + +#ifndef GWP_ASAN_STACK_TRACE_COMPRESSOR_ +#define GWP_ASAN_STACK_TRACE_COMPRESSOR_ + +#include <stddef.h> +#include <stdint.h> + +// These functions implement stack frame compression and decompression. We store +// the zig-zag encoded pointer difference between frame[i] and frame[i - 1] as +// a variable-length integer. This can reduce the memory overhead of stack +// traces by 50%. + +namespace gwp_asan { +namespace compression { + +// For the stack trace in `Unpacked` with length `UnpackedSize`, pack it into +// the buffer `Packed` maximum length `PackedMaxSize`. The return value is the +// number of bytes that were written to the output buffer. +size_t pack(const uintptr_t *Unpacked, size_t UnpackedSize, uint8_t *Packed, + size_t PackedMaxSize); + +// From the packed stack trace in `Packed` of length `PackedSize`, write the +// unpacked stack trace of maximum length `UnpackedMaxSize` into `Unpacked`. +// Returns the number of full entries unpacked, or zero on error. +size_t unpack(const uint8_t *Packed, size_t PackedSize, uintptr_t *Unpacked, + size_t UnpackedMaxSize); + +} // namespace compression +} // namespace gwp_asan + +#endif // GWP_ASAN_STACK_TRACE_COMPRESSOR_ diff --git a/lib/hwasan/hwasan.cpp b/lib/hwasan/hwasan.cpp index 6f2246552164..7b5c6c694be9 100644 --- a/lib/hwasan/hwasan.cpp +++ b/lib/hwasan/hwasan.cpp @@ -193,27 +193,12 @@ void UpdateMemoryUsage() { void UpdateMemoryUsage() {} #endif -// Prepare to run instrumented code on the main thread. -void InitInstrumentation() { - if (hwasan_instrumentation_inited) return; - - if (!InitShadow()) { - Printf("FATAL: HWAddressSanitizer cannot mmap the shadow memory.\n"); - DumpProcessMap(); - Die(); - } - - InitThreads(); - hwasanThreadList().CreateCurrentThread(); - - hwasan_instrumentation_inited = 1; -} - } // namespace __hwasan +using namespace __hwasan; + void __sanitizer::BufferedStackTrace::UnwindImpl( uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) { - using namespace __hwasan; Thread *t = GetCurrentThread(); if (!t) { // the thread is still being created. @@ -231,9 +216,117 @@ void __sanitizer::BufferedStackTrace::UnwindImpl( Unwind(max_depth, pc, 0, context, 0, 0, false); } -// Interface. +struct hwasan_global { + s32 gv_relptr; + u32 info; +}; + +static void InitGlobals(const hwasan_global *begin, const hwasan_global *end) { + for (auto *desc = begin; desc != end; ++desc) { + uptr gv = reinterpret_cast<uptr>(desc) + desc->gv_relptr; + uptr size = desc->info & 0xffffff; + uptr full_granule_size = RoundDownTo(size, 16); + u8 tag = desc->info >> 24; + TagMemoryAligned(gv, full_granule_size, tag); + if (size % 16) + TagMemoryAligned(gv + full_granule_size, 16, size % 16); + } +} -using namespace __hwasan; +enum { NT_LLVM_HWASAN_GLOBALS = 3 }; + +struct hwasan_global_note { + s32 begin_relptr; + s32 end_relptr; +}; + +// Check that the given library meets the code model requirements for tagged +// globals. These properties are not checked at link time so they need to be +// checked at runtime. +static void CheckCodeModel(ElfW(Addr) base, const ElfW(Phdr) * phdr, + ElfW(Half) phnum) { + ElfW(Addr) min_addr = -1ull, max_addr = 0; + for (unsigned i = 0; i != phnum; ++i) { + if (phdr[i].p_type != PT_LOAD) + continue; + ElfW(Addr) lo = base + phdr[i].p_vaddr, hi = lo + phdr[i].p_memsz; + if (min_addr > lo) + min_addr = lo; + if (max_addr < hi) + max_addr = hi; + } + + if (max_addr - min_addr > 1ull << 32) { + Report("FATAL: HWAddressSanitizer: library size exceeds 2^32\n"); + Die(); + } + if (max_addr > 1ull << 48) { + Report("FATAL: HWAddressSanitizer: library loaded above address 2^48\n"); + Die(); + } +} + +static void InitGlobalsFromPhdrs(ElfW(Addr) base, const ElfW(Phdr) * phdr, + ElfW(Half) phnum) { + for (unsigned i = 0; i != phnum; ++i) { + if (phdr[i].p_type != PT_NOTE) + continue; + const char *note = reinterpret_cast<const char *>(base + phdr[i].p_vaddr); + const char *nend = note + phdr[i].p_memsz; + while (note < nend) { + auto *nhdr = reinterpret_cast<const ElfW(Nhdr) *>(note); + const char *name = note + sizeof(ElfW(Nhdr)); + const char *desc = name + RoundUpTo(nhdr->n_namesz, 4); + if (nhdr->n_type != NT_LLVM_HWASAN_GLOBALS || + internal_strcmp(name, "LLVM") != 0) { + note = desc + RoundUpTo(nhdr->n_descsz, 4); + continue; + } + + // Only libraries with instrumented globals need to be checked against the + // code model since they use relocations that aren't checked at link time. + CheckCodeModel(base, phdr, phnum); + + auto *global_note = reinterpret_cast<const hwasan_global_note *>(desc); + auto *global_begin = reinterpret_cast<const hwasan_global *>( + note + global_note->begin_relptr); + auto *global_end = reinterpret_cast<const hwasan_global *>( + note + global_note->end_relptr); + InitGlobals(global_begin, global_end); + return; + } + } +} + +static void InitLoadedGlobals() { + dl_iterate_phdr( + [](dl_phdr_info *info, size_t size, void *data) { + InitGlobalsFromPhdrs(info->dlpi_addr, info->dlpi_phdr, + info->dlpi_phnum); + return 0; + }, + nullptr); +} + +// Prepare to run instrumented code on the main thread. +static void InitInstrumentation() { + if (hwasan_instrumentation_inited) return; + + InitPrctl(); + + if (!InitShadow()) { + Printf("FATAL: HWAddressSanitizer cannot mmap the shadow memory.\n"); + DumpProcessMap(); + Die(); + } + + InitThreads(); + hwasanThreadList().CreateCurrentThread(); + + hwasan_instrumentation_inited = 1; +} + +// Interface. uptr __hwasan_shadow_memory_dynamic_address; // Global interface symbol. @@ -244,6 +337,17 @@ void __hwasan_init_frames(uptr beg, uptr end) {} void __hwasan_init_static() { InitShadowGOT(); InitInstrumentation(); + + // In the non-static code path we call dl_iterate_phdr here. But at this point + // libc might not have been initialized enough for dl_iterate_phdr to work. + // Fortunately, since this is a statically linked executable we can use the + // linker-defined symbol __ehdr_start to find the only relevant set of phdrs. + extern ElfW(Ehdr) __ehdr_start; + InitGlobalsFromPhdrs( + 0, + reinterpret_cast<const ElfW(Phdr) *>( + reinterpret_cast<const char *>(&__ehdr_start) + __ehdr_start.e_phoff), + __ehdr_start.e_phnum); } void __hwasan_init() { @@ -267,6 +371,7 @@ void __hwasan_init() { DisableCoreDumperIfNecessary(); InitInstrumentation(); + InitLoadedGlobals(); // Needs to be called here because flags()->random_tags might not have been // initialized when InitInstrumentation() was called. @@ -301,6 +406,18 @@ void __hwasan_init() { hwasan_inited = 1; } +void __hwasan_library_loaded(ElfW(Addr) base, const ElfW(Phdr) * phdr, + ElfW(Half) phnum) { + InitGlobalsFromPhdrs(base, phdr, phnum); +} + +void __hwasan_library_unloaded(ElfW(Addr) base, const ElfW(Phdr) * phdr, + ElfW(Half) phnum) { + for (; phnum != 0; ++phdr, --phnum) + if (phdr->p_type == PT_LOAD) + TagMemory(base + phdr->p_vaddr, phdr->p_memsz, 0); +} + void __hwasan_print_shadow(const void *p, uptr sz) { uptr ptr_raw = UntagAddr(reinterpret_cast<uptr>(p)); uptr shadow_first = MemToShadow(ptr_raw); diff --git a/lib/hwasan/hwasan.h b/lib/hwasan/hwasan.h index 465e56c3a8cc..9e0ced93b55d 100644 --- a/lib/hwasan/hwasan.h +++ b/lib/hwasan/hwasan.h @@ -74,8 +74,8 @@ extern int hwasan_report_count; bool ProtectRange(uptr beg, uptr end); bool InitShadow(); +void InitPrctl(); void InitThreads(); -void InitInstrumentation(); void MadviseShadow(); char *GetProcSelfMaps(); void InitializeInterceptors(); diff --git a/lib/hwasan/hwasan_allocator.cpp b/lib/hwasan/hwasan_allocator.cpp index b4fae5820d0a..81a57d3afd4d 100644 --- a/lib/hwasan/hwasan_allocator.cpp +++ b/lib/hwasan/hwasan_allocator.cpp @@ -22,11 +22,6 @@ #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; @@ -301,14 +296,6 @@ 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; @@ -381,13 +368,6 @@ int hwasan_posix_memalign(void **memptr, uptr alignment, uptr size, } 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); } @@ -400,15 +380,6 @@ 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 3a50a11f3526..f62be2696021 100644 --- a/lib/hwasan/hwasan_allocator.h +++ b/lib/hwasan/hwasan_allocator.h @@ -13,7 +13,6 @@ #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,11 +25,6 @@ #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 { diff --git a/lib/hwasan/hwasan_exceptions.cpp b/lib/hwasan/hwasan_exceptions.cpp new file mode 100644 index 000000000000..169e7876cb58 --- /dev/null +++ b/lib/hwasan/hwasan_exceptions.cpp @@ -0,0 +1,67 @@ +//===-- hwasan_exceptions.cpp ---------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of HWAddressSanitizer. +// +// HWAddressSanitizer runtime. +//===----------------------------------------------------------------------===// + +#include "hwasan_poisoning.h" +#include "sanitizer_common/sanitizer_common.h" + +#include <unwind.h> + +using namespace __hwasan; +using namespace __sanitizer; + +typedef _Unwind_Reason_Code PersonalityFn(int version, _Unwind_Action actions, + uint64_t exception_class, + _Unwind_Exception* unwind_exception, + _Unwind_Context* context); + +// Pointers to the _Unwind_GetGR and _Unwind_GetCFA functions are passed in +// instead of being called directly. This is to handle cases where the unwinder +// is statically linked and the sanitizer runtime and the program are linked +// against different unwinders. The _Unwind_Context data structure is opaque so +// it may be incompatible between unwinders. +typedef _Unwind_Word GetGRFn(_Unwind_Context* context, int index); +typedef _Unwind_Word GetCFAFn(_Unwind_Context* context); + +extern "C" SANITIZER_INTERFACE_ATTRIBUTE _Unwind_Reason_Code +__hwasan_personality_wrapper(int version, _Unwind_Action actions, + uint64_t exception_class, + _Unwind_Exception* unwind_exception, + _Unwind_Context* context, + PersonalityFn* real_personality, GetGRFn* get_gr, + GetCFAFn* get_cfa) { + _Unwind_Reason_Code rc; + if (real_personality) + rc = real_personality(version, actions, exception_class, unwind_exception, + context); + else + rc = _URC_CONTINUE_UNWIND; + + // We only untag frames without a landing pad because landing pads are + // responsible for untagging the stack themselves if they resume. + // + // Here we assume that the frame record appears after any locals. This is not + // required by AAPCS but is a requirement for HWASAN instrumented functions. + if ((actions & _UA_CLEANUP_PHASE) && rc == _URC_CONTINUE_UNWIND) { +#if defined(__x86_64__) + uptr fp = get_gr(context, 6); // rbp +#elif defined(__aarch64__) + uptr fp = get_gr(context, 29); // x29 +#else +#error Unsupported architecture +#endif + uptr sp = get_cfa(context); + TagMemory(sp, fp - sp, 0); + } + + return rc; +} diff --git a/lib/hwasan/hwasan_flags.inc b/lib/hwasan/hwasan_flags.inc index 2dff2b9aca6e..dffbf56cb155 100644 --- a/lib/hwasan/hwasan_flags.inc +++ b/lib/hwasan/hwasan_flags.inc @@ -1,4 +1,4 @@ -//===-- hwasan_flags.inc ------------------------------------------*- C++ -*-===// +//===-- hwasan_flags.inc ----------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/hwasan/hwasan_interceptors.cpp b/lib/hwasan/hwasan_interceptors.cpp index 47fed0fc9abb..95e2e865717d 100644 --- a/lib/hwasan/hwasan_interceptors.cpp +++ b/lib/hwasan/hwasan_interceptors.cpp @@ -260,8 +260,6 @@ void InitializeInterceptors() { #if !defined(__aarch64__) INTERCEPT_FUNCTION(pthread_create); #endif // __aarch64__ - 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 1b10d76c78e9..ca57f0fe437b 100644 --- a/lib/hwasan/hwasan_interface_internal.h +++ b/lib/hwasan/hwasan_interface_internal.h @@ -16,6 +16,7 @@ #include "sanitizer_common/sanitizer_internal_defs.h" #include "sanitizer_common/sanitizer_platform_limits_posix.h" +#include <link.h> extern "C" { @@ -25,6 +26,14 @@ void __hwasan_init_static(); SANITIZER_INTERFACE_ATTRIBUTE void __hwasan_init(); +SANITIZER_INTERFACE_ATTRIBUTE +void __hwasan_library_loaded(ElfW(Addr) base, const ElfW(Phdr) * phdr, + ElfW(Half) phnum); + +SANITIZER_INTERFACE_ATTRIBUTE +void __hwasan_library_unloaded(ElfW(Addr) base, const ElfW(Phdr) * phdr, + ElfW(Half) phnum); + using __sanitizer::uptr; using __sanitizer::sptr; using __sanitizer::uu64; diff --git a/lib/hwasan/hwasan_linux.cpp b/lib/hwasan/hwasan_linux.cpp index d932976489e9..948e40154fec 100644 --- a/lib/hwasan/hwasan_linux.cpp +++ b/lib/hwasan/hwasan_linux.cpp @@ -34,6 +34,8 @@ #include <sys/time.h> #include <unistd.h> #include <unwind.h> +#include <sys/prctl.h> +#include <errno.h> #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_procmaps.h" @@ -144,6 +146,43 @@ static void InitializeShadowBaseAddress(uptr shadow_size_bytes) { FindDynamicShadowStart(shadow_size_bytes); } +void InitPrctl() { +#define PR_SET_TAGGED_ADDR_CTRL 55 +#define PR_GET_TAGGED_ADDR_CTRL 56 +#define PR_TAGGED_ADDR_ENABLE (1UL << 0) + // Check we're running on a kernel that can use the tagged address ABI. + if (internal_prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0) == (uptr)-1 && + errno == EINVAL) { +#if SANITIZER_ANDROID + // Some older Android kernels have the tagged pointer ABI on + // unconditionally, and hence don't have the tagged-addr prctl while still + // allow the ABI. + // If targeting Android and the prctl is not around we assume this is the + // case. + return; +#else + Printf( + "FATAL: " + "HWAddressSanitizer requires a kernel with tagged address ABI.\n"); + Die(); +#endif + } + + // Turn on the tagged address ABI. + if (internal_prctl(PR_SET_TAGGED_ADDR_CTRL, PR_TAGGED_ADDR_ENABLE, 0, 0, 0) == + (uptr)-1 || + !internal_prctl(PR_GET_TAGGED_ADDR_CTRL, 0, 0, 0, 0)) { + Printf( + "FATAL: HWAddressSanitizer failed to enable tagged address syscall " + "ABI.\nSuggest check `sysctl abi.tagged_addr_disabled` " + "configuration.\n"); + Die(); + } +#undef PR_SET_TAGGED_ADDR_CTRL +#undef PR_GET_TAGGED_ADDR_CTRL +#undef PR_TAGGED_ADDR_ENABLE +} + bool InitShadow() { // Define the entire memory range. kHighMemEnd = GetHighMemEnd(); @@ -211,8 +250,7 @@ void InitThreads() { static void MadviseShadowRegion(uptr beg, uptr end) { uptr size = end - beg + 1; - if (common_flags()->no_huge_pages_for_shadow) - NoHugePagesInRegion(beg, size); + SetShadowRegionHugePageMode(beg, size); if (common_flags()->use_madv_dontdump) DontDumpShadowMemory(beg, size); } diff --git a/lib/hwasan/hwasan_new_delete.cpp b/lib/hwasan/hwasan_new_delete.cpp index 4a9c79fe41b3..191c17e56a74 100644 --- a/lib/hwasan/hwasan_new_delete.cpp +++ b/lib/hwasan/hwasan_new_delete.cpp @@ -20,7 +20,7 @@ #include <stddef.h> -using namespace __hwasan; // NOLINT +using namespace __hwasan; // Fake std::nothrow_t to avoid including <new>. namespace std { diff --git a/lib/hwasan/hwasan_report.cpp b/lib/hwasan/hwasan_report.cpp index 346889797888..19cb27554bc6 100644 --- a/lib/hwasan/hwasan_report.cpp +++ b/lib/hwasan/hwasan_report.cpp @@ -278,6 +278,31 @@ void PrintAddressDescription( Printf("%s", d.Default()); GetStackTraceFromId(chunk.GetAllocStackId()).Print(); num_descriptions_printed++; + } else { + // Check whether the address points into a loaded library. If so, this is + // most likely a global variable. + const char *module_name; + uptr module_address; + Symbolizer *sym = Symbolizer::GetOrInit(); + if (sym->GetModuleNameAndOffsetForPC(mem, &module_name, + &module_address)) { + DataInfo info; + if (sym->SymbolizeData(mem, &info) && info.start) { + Printf( + "%p is located %zd bytes to the %s of %zd-byte global variable " + "%s [%p,%p) in %s\n", + untagged_addr, + candidate == left ? untagged_addr - (info.start + info.size) + : info.start - untagged_addr, + candidate == left ? "right" : "left", info.size, info.name, + info.start, info.start + info.size, module_name); + } else { + Printf("%p is located to the %s of a global variable in (%s+0x%x)\n", + untagged_addr, candidate == left ? "right" : "left", + module_name, module_address); + } + num_descriptions_printed++; + } } } diff --git a/lib/hwasan/hwasan_tag_mismatch_aarch64.S b/lib/hwasan/hwasan_tag_mismatch_aarch64.S index 92f627480486..4c060a61e98e 100644 --- a/lib/hwasan/hwasan_tag_mismatch_aarch64.S +++ b/lib/hwasan/hwasan_tag_mismatch_aarch64.S @@ -51,14 +51,60 @@ // +---------------------------------+ <-- [x30 / SP] // This function takes two arguments: -// * x0: The address of read/write instruction that caused HWASan check fail. -// * x1: The tag size. +// * x0: The data address. +// * x1: The encoded access info for the failing access. +// This function has two entry points. The first, __hwasan_tag_mismatch, is used +// by clients that were compiled without short tag checks (i.e. binaries built +// by older compilers and binaries targeting older runtimes). In this case the +// outlined tag check will be missing the code handling short tags (which won't +// be used in the binary's own stack variables but may be used on the heap +// or stack variables in other binaries), so the check needs to be done here. +// +// The second, __hwasan_tag_mismatch_v2, is used by binaries targeting newer +// runtimes. This entry point bypasses the short tag check since it will have +// already been done as part of the outlined tag check. Since tag mismatches are +// uncommon, there isn't a significant performance benefit to being able to +// bypass the check; the main benefits are that we can sometimes avoid +// clobbering the x17 register in error reports, and that the program will have +// a runtime dependency on the __hwasan_tag_mismatch_v2 symbol therefore it will +// fail to start up given an older (i.e. incompatible) runtime. .section .text .file "hwasan_tag_mismatch_aarch64.S" .global __hwasan_tag_mismatch .type __hwasan_tag_mismatch, %function __hwasan_tag_mismatch: + // Compute the granule position one past the end of the access. + mov x16, #1 + and x17, x1, #0xf + lsl x16, x16, x17 + and x17, x0, #0xf + add x17, x16, x17 + + // Load the shadow byte again and check whether it is a short tag within the + // range of the granule position computed above. + ubfx x16, x0, #4, #52 + ldrb w16, [x9, x16] + cmp w16, #0xf + b.hi __hwasan_tag_mismatch_v2 + cmp w16, w17 + b.lo __hwasan_tag_mismatch_v2 + + // Load the real tag from the last byte of the granule and compare against + // the pointer tag. + orr x16, x0, #0xf + ldrb w16, [x16] + cmp x16, x0, lsr #56 + b.ne __hwasan_tag_mismatch_v2 + + // Restore x0, x1 and sp to their values from before the __hwasan_tag_mismatch + // call and resume execution. + ldp x0, x1, [sp], #256 + ret + +.global __hwasan_tag_mismatch_v2 +.type __hwasan_tag_mismatch_v2, %function +__hwasan_tag_mismatch_v2: CFI_STARTPROC // Set the CFA to be the return address for caller of __hwasan_check_*. Note diff --git a/lib/interception/interception.h b/lib/interception/interception.h index dacfa5ede28d..d27a8ccf92a8 100644 --- a/lib/interception/interception.h +++ b/lib/interception/interception.h @@ -272,9 +272,9 @@ const interpose_substitution substitution_##func_name[] \ // INTERCEPT_FUNCTION macro, only its name. namespace __interception { #if defined(_WIN64) -typedef unsigned long long uptr; // NOLINT +typedef unsigned long long uptr; #else -typedef unsigned long uptr; // NOLINT +typedef unsigned long uptr; #endif // _WIN64 } // namespace __interception diff --git a/lib/interception/interception_linux.cc b/lib/interception/interception_linux.cpp index 4b27102a159c..950cd5126538 100644 --- a/lib/interception/interception_linux.cc +++ b/lib/interception/interception_linux.cpp @@ -1,4 +1,4 @@ -//===-- interception_linux.cc -----------------------------------*- C++ -*-===// +//===-- interception_linux.cpp ----------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/interception/interception_mac.cc b/lib/interception/interception_mac.cpp index 5bfc1514d2b8..fb6eadcff597 100644 --- a/lib/interception/interception_mac.cc +++ b/lib/interception/interception_mac.cpp @@ -1,4 +1,4 @@ -//===-- interception_mac.cc -------------------------------------*- C++ -*-===// +//===-- interception_mac.cpp ------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/interception/interception_type_test.cc b/lib/interception/interception_type_test.cpp index c00294a9b474..a611604a700c 100644 --- a/lib/interception/interception_type_test.cc +++ b/lib/interception/interception_type_test.cpp @@ -1,4 +1,4 @@ -//===-- interception_type_test.cc -------------------------------*- C++ -*-===// +//===-- interception_type_test.cpp ------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/interception/interception_win.cc b/lib/interception/interception_win.cpp index 40bde008052b..1a1c327e6124 100644 --- a/lib/interception/interception_win.cc +++ b/lib/interception/interception_win.cpp @@ -1,4 +1,4 @@ -//===-- interception_linux.cc -----------------------------------*- C++ -*-===// +//===-- interception_linux.cpp ----------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -883,8 +883,8 @@ uptr InternalGetProcAddress(void *module, const char *func_name) { // Check that the module header is full and present. RVAPtr<IMAGE_DOS_HEADER> dos_stub(module, 0); RVAPtr<IMAGE_NT_HEADERS> headers(module, dos_stub->e_lfanew); - if (!module || dos_stub->e_magic != IMAGE_DOS_SIGNATURE || // "MZ" - headers->Signature != IMAGE_NT_SIGNATURE || // "PE\0\0" + if (!module || dos_stub->e_magic != IMAGE_DOS_SIGNATURE || // "MZ" + headers->Signature != IMAGE_NT_SIGNATURE || // "PE\0\0" headers->FileHeader.SizeOfOptionalHeader < sizeof(IMAGE_OPTIONAL_HEADER)) { return 0; @@ -963,8 +963,8 @@ bool OverrideImportedFunction(const char *module_to_patch, // Check that the module header is full and present. RVAPtr<IMAGE_DOS_HEADER> dos_stub(module, 0); RVAPtr<IMAGE_NT_HEADERS> headers(module, dos_stub->e_lfanew); - if (!module || dos_stub->e_magic != IMAGE_DOS_SIGNATURE || // "MZ" - headers->Signature != IMAGE_NT_SIGNATURE || // "PE\0\0" + if (!module || dos_stub->e_magic != IMAGE_DOS_SIGNATURE || // "MZ" + headers->Signature != IMAGE_NT_SIGNATURE || // "PE\0\0" headers->FileHeader.SizeOfOptionalHeader < sizeof(IMAGE_OPTIONAL_HEADER)) { return false; diff --git a/lib/lsan/lsan.cc b/lib/lsan/lsan.cpp index 68697a6363e8..4ce03046ffb7 100644 --- a/lib/lsan/lsan.cc +++ b/lib/lsan/lsan.cpp @@ -1,4 +1,4 @@ -//=-- lsan.cc -------------------------------------------------------------===// +//=-- lsan.cpp ------------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -50,7 +50,7 @@ void __sanitizer::BufferedStackTrace::UnwindImpl( } } -using namespace __lsan; // NOLINT +using namespace __lsan; static void InitializeFlags() { // Set all the default values. @@ -89,7 +89,7 @@ static void InitializeFlags() { static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { - stack->Unwind(sig.pc, sig.bp, sig.context, + stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, common_flags()->fast_unwind_on_fatal); } diff --git a/lib/lsan/lsan_allocator.cc b/lib/lsan/lsan_allocator.cpp index 8b13e4c028d4..66a81ab350e5 100644 --- a/lib/lsan/lsan_allocator.cc +++ b/lib/lsan/lsan_allocator.cpp @@ -1,4 +1,4 @@ -//=-- lsan_allocator.cc ---------------------------------------------------===// +//=-- lsan_allocator.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/lsan/lsan_common.cc b/lib/lsan/lsan_common.cpp index 7c842a152d54..9ff9f4c5d1c9 100644 --- a/lib/lsan/lsan_common.cc +++ b/lib/lsan/lsan_common.cpp @@ -1,4 +1,4 @@ -//=-- lsan_common.cc ------------------------------------------------------===// +//=-- lsan_common.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -84,7 +84,7 @@ static const char kStdSuppressions[] = void InitializeSuppressions() { CHECK_EQ(nullptr, suppression_ctx); - suppression_ctx = new (suppression_placeholder) // NOLINT + suppression_ctx = new (suppression_placeholder) SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes)); suppression_ctx->ParseFromFile(flags()->suppressions); if (&__lsan_default_suppressions) @@ -104,7 +104,7 @@ InternalMmapVector<RootRegion> const *GetRootRegions() { return root_regions; } void InitializeRootRegions() { CHECK(!root_regions); ALIGNED(64) static char placeholder[sizeof(InternalMmapVector<RootRegion>)]; - root_regions = new (placeholder) InternalMmapVector<RootRegion>(); // NOLINT + root_regions = new (placeholder) InternalMmapVector<RootRegion>(); } const char *MaybeCallLsanDefaultOptions() { @@ -162,7 +162,7 @@ void ScanRangeForPointers(uptr begin, uptr end, uptr pp = begin; if (pp % alignment) pp = pp + alignment - pp % alignment; - for (; pp + sizeof(void *) <= end; pp += alignment) { // NOLINT + for (; pp + sizeof(void *) <= end; pp += alignment) { void *p = *reinterpret_cast<void **>(pp); if (!CanBeAHeapPointer(reinterpret_cast<uptr>(p))) continue; uptr chunk = PointsIntoChunk(p); @@ -535,7 +535,7 @@ static void ReportIfNotSuspended(ThreadContextBase *tctx, void *arg) { if (i >= suspended_threads.size() || suspended_threads[i] != tctx->os_id) Report("Running thread %d was not suspended. False leaks are possible.\n", tctx->os_id); - }; + } } static void ReportUnsuspendedThreads( @@ -570,11 +570,7 @@ static bool CheckForLeaks() { EnsureMainThreadIDIsCorrect(); CheckForLeaksParam param; param.success = false; - LockThreadRegistry(); - LockAllocator(); - DoStopTheWorld(CheckForLeaksCallback, ¶m); - UnlockAllocator(); - UnlockThreadRegistry(); + LockStuffAndStopTheWorld(CheckForLeaksCallback, ¶m); if (!param.success) { Report("LeakSanitizer has encountered a fatal error.\n"); @@ -794,7 +790,7 @@ void EnableInThisThread() { } } #endif // CAN_SANITIZE_LEAKS -using namespace __lsan; // NOLINT +using namespace __lsan; extern "C" { SANITIZER_INTERFACE_ATTRIBUTE diff --git a/lib/lsan/lsan_common.h b/lib/lsan/lsan_common.h index 58dc00faaee5..d24abe31b71b 100644 --- a/lib/lsan/lsan_common.h +++ b/lib/lsan/lsan_common.h @@ -129,8 +129,9 @@ struct RootRegion { InternalMmapVector<RootRegion> const *GetRootRegions(); void ScanRootRegion(Frontier *frontier, RootRegion const ®ion, uptr region_begin, uptr region_end, bool is_readable); -// Run stoptheworld while holding any platform-specific locks. -void DoStopTheWorld(StopTheWorldCallback callback, void* argument); +// Run stoptheworld while holding any platform-specific locks, as well as the +// allocator and thread registry locks. +void LockStuffAndStopTheWorld(StopTheWorldCallback callback, void* argument); void ScanRangeForPointers(uptr begin, uptr end, Frontier *frontier, diff --git a/lib/lsan/lsan_common_linux.cc b/lib/lsan/lsan_common_linux.cpp index ef4f591d88f7..ea1a4a2f569d 100644 --- a/lib/lsan/lsan_common_linux.cc +++ b/lib/lsan/lsan_common_linux.cpp @@ -1,4 +1,4 @@ -//=-- lsan_common_linux.cc ------------------------------------------------===// +//=-- lsan_common_linux.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -115,10 +115,14 @@ void HandleLeaks() { if (common_flags()->exitcode) Die(); } -static int DoStopTheWorldCallback(struct dl_phdr_info *info, size_t size, - void *data) { +static int LockStuffAndStopTheWorldCallback(struct dl_phdr_info *info, + size_t size, void *data) { + LockThreadRegistry(); + LockAllocator(); DoStopTheWorldParam *param = reinterpret_cast<DoStopTheWorldParam *>(data); StopTheWorld(param->callback, param->argument); + UnlockAllocator(); + UnlockThreadRegistry(); return 1; } @@ -130,9 +134,9 @@ static int DoStopTheWorldCallback(struct dl_phdr_info *info, size_t size, // while holding the libdl lock in the parent thread, we can safely reenter it // in the tracer. The solution is to run stoptheworld from a dl_iterate_phdr() // callback in the parent thread. -void DoStopTheWorld(StopTheWorldCallback callback, void *argument) { +void LockStuffAndStopTheWorld(StopTheWorldCallback callback, void *argument) { DoStopTheWorldParam param = {callback, argument}; - dl_iterate_phdr(DoStopTheWorldCallback, ¶m); + dl_iterate_phdr(LockStuffAndStopTheWorldCallback, ¶m); } } // namespace __lsan diff --git a/lib/lsan/lsan_common_mac.cc b/lib/lsan/lsan_common_mac.cpp index 14c2b3711994..c1804e93c11d 100644 --- a/lib/lsan/lsan_common_mac.cc +++ b/lib/lsan/lsan_common_mac.cpp @@ -1,4 +1,4 @@ -//=-- lsan_common_mac.cc --------------------------------------------------===// +//=-- lsan_common_mac.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -193,8 +193,12 @@ void ProcessPlatformSpecificAllocations(Frontier *frontier) { // causes rare race conditions. void HandleLeaks() {} -void DoStopTheWorld(StopTheWorldCallback callback, void *argument) { +void LockStuffAndStopTheWorld(StopTheWorldCallback callback, void *argument) { + LockThreadRegistry(); + LockAllocator(); StopTheWorld(callback, argument); + UnlockAllocator(); + UnlockThreadRegistry(); } } // namespace __lsan diff --git a/lib/lsan/lsan_interceptors.cc b/lib/lsan/lsan_interceptors.cpp index 4a4c86a9dca0..f642bb807bc8 100644 --- a/lib/lsan/lsan_interceptors.cc +++ b/lib/lsan/lsan_interceptors.cpp @@ -1,4 +1,4 @@ -//=-- lsan_interceptors.cc ------------------------------------------------===// +//=-- lsan_interceptors.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -345,6 +345,55 @@ INTERCEPTOR(void, thr_exit, tid_t *state) { #define LSAN_MAYBE_INTERCEPT_THR_EXIT #endif +#if SANITIZER_INTERCEPT___CXA_ATEXIT +INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg, + void *dso_handle) { + __lsan::ScopedInterceptorDisabler disabler; + return REAL(__cxa_atexit)(func, arg, dso_handle); +} +#define LSAN_MAYBE_INTERCEPT___CXA_ATEXIT INTERCEPT_FUNCTION(__cxa_atexit) +#else +#define LSAN_MAYBE_INTERCEPT___CXA_ATEXIT +#endif + +#if SANITIZER_INTERCEPT_ATEXIT +INTERCEPTOR(int, atexit, void (*f)()) { + __lsan::ScopedInterceptorDisabler disabler; + return REAL(__cxa_atexit)((void (*)(void *a))f, 0, 0); +} +#define LSAN_MAYBE_INTERCEPT_ATEXIT INTERCEPT_FUNCTION(atexit) +#else +#define LSAN_MAYBE_INTERCEPT_ATEXIT +#endif + +#if SANITIZER_INTERCEPT_PTHREAD_ATFORK +extern "C" { +extern int _pthread_atfork(void (*prepare)(), void (*parent)(), + void (*child)()); +}; + +INTERCEPTOR(int, pthread_atfork, void (*prepare)(), void (*parent)(), + void (*child)()) { + __lsan::ScopedInterceptorDisabler disabler; + // REAL(pthread_atfork) cannot be called due to symbol indirections at least + // on NetBSD + return _pthread_atfork(prepare, parent, child); +} +#define LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK INTERCEPT_FUNCTION(pthread_atfork) +#else +#define LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK +#endif + +#if SANITIZER_INTERCEPT_STRERROR +INTERCEPTOR(char *, strerror, int errnum) { + __lsan::ScopedInterceptorDisabler disabler; + return REAL(strerror)(errnum); +} +#define LSAN_MAYBE_INTERCEPT_STRERROR INTERCEPT_FUNCTION(strerror) +#else +#define LSAN_MAYBE_INTERCEPT_STRERROR +#endif + struct ThreadParam { void *(*callback)(void *arg); void *param; @@ -454,6 +503,12 @@ void InitializeInterceptors() { LSAN_MAYBE_INTERCEPT__LWP_EXIT; LSAN_MAYBE_INTERCEPT_THR_EXIT; + LSAN_MAYBE_INTERCEPT___CXA_ATEXIT; + LSAN_MAYBE_INTERCEPT_ATEXIT; + LSAN_MAYBE_INTERCEPT_PTHREAD_ATFORK; + + LSAN_MAYBE_INTERCEPT_STRERROR; + #if !SANITIZER_NETBSD && !SANITIZER_FREEBSD if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) { Report("LeakSanitizer: failed to create thread key.\n"); diff --git a/lib/lsan/lsan_linux.cc b/lib/lsan/lsan_linux.cpp index 22d034280d7d..14a42b75d2af 100644 --- a/lib/lsan/lsan_linux.cc +++ b/lib/lsan/lsan_linux.cpp @@ -1,4 +1,4 @@ -//=-- lsan_linux.cc -------------------------------------------------------===// +//=-- lsan_linux.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/lsan/lsan_mac.cc b/lib/lsan/lsan_mac.cpp index 435f41b6f8bc..b96893e2801b 100644 --- a/lib/lsan/lsan_mac.cc +++ b/lib/lsan/lsan_mac.cpp @@ -1,4 +1,4 @@ -//===-- lsan_mac.cc -------------------------------------------------------===// +//===-- lsan_mac.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -90,7 +90,7 @@ extern "C" void lsan_dispatch_call_block_and_release(void *block) { } // namespace __lsan -using namespace __lsan; // NOLINT +using namespace __lsan; // Wrap |ctxt| and |func| into an lsan_block_context_t. // The caller retains control of the allocated context. diff --git a/lib/lsan/lsan_malloc_mac.cc b/lib/lsan/lsan_malloc_mac.cpp index 34447b4b39fc..d03eb2e915c0 100644 --- a/lib/lsan/lsan_malloc_mac.cc +++ b/lib/lsan/lsan_malloc_mac.cpp @@ -1,4 +1,4 @@ -//===-- lsan_malloc_mac.cc ------------------------------------------------===// +//===-- lsan_malloc_mac.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/lsan/lsan_preinit.cc b/lib/lsan/lsan_preinit.cpp index 5d0ad89a8b02..cd94e1e8718e 100644 --- a/lib/lsan/lsan_preinit.cc +++ b/lib/lsan/lsan_preinit.cpp @@ -1,4 +1,4 @@ -//===-- lsan_preinit.cc ---------------------------------------------------===// +//===-- lsan_preinit.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/lsan/lsan_thread.cc b/lib/lsan/lsan_thread.cpp index 77f6a9236dde..84e7ce61b975 100644 --- a/lib/lsan/lsan_thread.cc +++ b/lib/lsan/lsan_thread.cpp @@ -1,4 +1,4 @@ -//=-- lsan_thread.cc ------------------------------------------------------===// +//=-- lsan_thread.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/msan/msan.cc b/lib/msan/msan.cpp index c62e5cd4c518..6ea63cb2c48f 100644 --- a/lib/msan/msan.cc +++ b/lib/msan/msan.cpp @@ -1,4 +1,4 @@ -//===-- msan.cc -----------------------------------------------------------===// +//===-- msan.cpp ----------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -130,8 +130,8 @@ static void RegisterMsanFlags(FlagParser *parser, Flags *f) { #include "msan_flags.inc" #undef MSAN_FLAG - FlagHandlerKeepGoing *fh_keep_going = new (FlagParser::Alloc) // NOLINT - FlagHandlerKeepGoing(&f->halt_on_error); + FlagHandlerKeepGoing *fh_keep_going = + new (FlagParser::Alloc) FlagHandlerKeepGoing(&f->halt_on_error); parser->RegisterHandler("keep_going", fh_keep_going, "deprecated, use halt_on_error"); } @@ -378,7 +378,7 @@ void __msan_warning_noreturn() { static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { - stack->Unwind(sig.pc, sig.bp, sig.context, + stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, common_flags()->fast_unwind_on_fatal); } @@ -403,7 +403,6 @@ void __msan_init() { AvoidCVE_2016_2143(); CacheBinaryName(); - CheckASLR(); InitializeFlags(); // Install tool-specific callbacks in sanitizer_common. @@ -412,6 +411,7 @@ void __msan_init() { __sanitizer_set_report_path(common_flags()->log_path); InitializeInterceptors(); + CheckASLR(); InitTlsSize(); InstallDeadlySignalHandlers(MsanOnDeadlySignal); InstallAtExitHandler(); // Needs __cxa_atexit interceptor. diff --git a/lib/msan/msan.h b/lib/msan/msan.h index ac5f67e6ab3d..12aeaa43519a 100644 --- a/lib/msan/msan.h +++ b/lib/msan/msan.h @@ -267,7 +267,7 @@ inline bool addr_is_type(uptr addr, MappingDesc::Type mapping_type) { #define MEM_IS_SHADOW(mem) addr_is_type((uptr)(mem), MappingDesc::SHADOW) #define MEM_IS_ORIGIN(mem) addr_is_type((uptr)(mem), MappingDesc::ORIGIN) -// These constants must be kept in sync with the ones in MemorySanitizer.cc. +// These constants must be kept in sync with the ones in MemorySanitizer.cpp. const int kMsanParamTlsSize = 800; const int kMsanRetvalTlsSize = 800; @@ -346,10 +346,11 @@ const int STACK_TRACE_TAG_POISON = StackTrace::TAG_CUSTOM + 1; #define GET_STORE_STACK_TRACE \ GET_STORE_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME()) -#define GET_FATAL_STACK_TRACE_PC_BP(pc, bp) \ - BufferedStackTrace stack; \ - if (msan_inited) \ - stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal) +#define GET_FATAL_STACK_TRACE_PC_BP(pc, bp) \ + BufferedStackTrace stack; \ + if (msan_inited) { \ + stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal); \ + } #define GET_FATAL_STACK_TRACE_HERE \ GET_FATAL_STACK_TRACE_PC_BP(StackTrace::GetCurrentPc(), GET_CURRENT_FRAME()) diff --git a/lib/msan/msan_allocator.cc b/lib/msan/msan_allocator.cpp index 1816840012e4..6aa4e2738075 100644 --- a/lib/msan/msan_allocator.cc +++ b/lib/msan/msan_allocator.cpp @@ -1,4 +1,4 @@ -//===-- msan_allocator.cc --------------------------- ---------------------===// +//===-- msan_allocator.cpp -------------------------- ---------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/msan/msan_chained_origin_depot.cc b/lib/msan/msan_chained_origin_depot.cpp index 6c634252e0b1..d2897481a4b9 100644 --- a/lib/msan/msan_chained_origin_depot.cc +++ b/lib/msan/msan_chained_origin_depot.cpp @@ -1,4 +1,4 @@ -//===-- msan_chained_origin_depot.cc -----------------------------------===// +//===-- msan_chained_origin_depot.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/msan/msan_interceptors.cc b/lib/msan/msan_interceptors.cpp index b055bb749cb8..1d9d9f7986d7 100644 --- a/lib/msan/msan_interceptors.cc +++ b/lib/msan/msan_interceptors.cpp @@ -1,4 +1,4 @@ -//===-- msan_interceptors.cc ----------------------------------------------===// +//===-- msan_interceptors.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -282,35 +282,35 @@ INTERCEPTOR(void, malloc_stats, void) { #define MSAN_MAYBE_INTERCEPT_MALLOC_STATS #endif -INTERCEPTOR(char *, strcpy, char *dest, const char *src) { // NOLINT +INTERCEPTOR(char *, strcpy, char *dest, const char *src) { ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; SIZE_T n = REAL(strlen)(src); CHECK_UNPOISONED_STRING(src + n, 0); - char *res = REAL(strcpy)(dest, src); // NOLINT + char *res = REAL(strcpy)(dest, src); CopyShadowAndOrigin(dest, src, n + 1, &stack); return res; } -INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) { // NOLINT +INTERCEPTOR(char *, strncpy, char *dest, const char *src, SIZE_T n) { ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; SIZE_T copy_size = REAL(strnlen)(src, n); if (copy_size < n) copy_size++; // trailing \0 - char *res = REAL(strncpy)(dest, src, n); // NOLINT + char *res = REAL(strncpy)(dest, src, n); CopyShadowAndOrigin(dest, src, copy_size, &stack); __msan_unpoison(dest + copy_size, n - copy_size); return res; } #if !SANITIZER_NETBSD -INTERCEPTOR(char *, stpcpy, char *dest, const char *src) { // NOLINT +INTERCEPTOR(char *, stpcpy, char *dest, const char *src) { ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; SIZE_T n = REAL(strlen)(src); CHECK_UNPOISONED_STRING(src + n, 0); - char *res = REAL(stpcpy)(dest, src); // NOLINT + char *res = REAL(stpcpy)(dest, src); CopyShadowAndOrigin(dest, src, n + 1, &stack); return res; } @@ -359,25 +359,25 @@ INTERCEPTOR(char *, gcvt, double number, SIZE_T ndigit, char *buf) { #define MSAN_MAYBE_INTERCEPT_GCVT #endif -INTERCEPTOR(char *, strcat, char *dest, const char *src) { // NOLINT +INTERCEPTOR(char *, strcat, char *dest, const char *src) { ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; SIZE_T src_size = REAL(strlen)(src); SIZE_T dest_size = REAL(strlen)(dest); CHECK_UNPOISONED_STRING(src + src_size, 0); CHECK_UNPOISONED_STRING(dest + dest_size, 0); - char *res = REAL(strcat)(dest, src); // NOLINT + char *res = REAL(strcat)(dest, src); CopyShadowAndOrigin(dest + dest_size, src, src_size + 1, &stack); return res; } -INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) { // NOLINT +INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) { ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; SIZE_T dest_size = REAL(strlen)(dest); SIZE_T copy_size = REAL(strnlen)(src, n); CHECK_UNPOISONED_STRING(dest + dest_size, 0); - char *res = REAL(strncat)(dest, src, n); // NOLINT + char *res = REAL(strncat)(dest, src, n); CopyShadowAndOrigin(dest + dest_size, src, copy_size, &stack); __msan_unpoison(dest + dest_size + copy_size, 1); // \0 return res; @@ -437,22 +437,22 @@ INTERCEPTOR(char *, strncat, char *dest, const char *src, SIZE_T n) { // NOLINT INTERCEPTOR_STRTO_BASE_LOC(ret_type, __##func##_internal, char_type) #endif -INTERCEPTORS_STRTO(double, strtod, char) // NOLINT -INTERCEPTORS_STRTO(float, strtof, char) // NOLINT -INTERCEPTORS_STRTO(long double, strtold, char) // NOLINT -INTERCEPTORS_STRTO_BASE(long, strtol, char) // NOLINT -INTERCEPTORS_STRTO_BASE(long long, strtoll, char) // NOLINT -INTERCEPTORS_STRTO_BASE(unsigned long, strtoul, char) // NOLINT -INTERCEPTORS_STRTO_BASE(unsigned long long, strtoull, char) // NOLINT -INTERCEPTORS_STRTO_BASE(u64, strtouq, char) // NOLINT - -INTERCEPTORS_STRTO(double, wcstod, wchar_t) // NOLINT -INTERCEPTORS_STRTO(float, wcstof, wchar_t) // NOLINT -INTERCEPTORS_STRTO(long double, wcstold, wchar_t) // NOLINT -INTERCEPTORS_STRTO_BASE(long, wcstol, wchar_t) // NOLINT -INTERCEPTORS_STRTO_BASE(long long, wcstoll, wchar_t) // NOLINT -INTERCEPTORS_STRTO_BASE(unsigned long, wcstoul, wchar_t) // NOLINT -INTERCEPTORS_STRTO_BASE(unsigned long long, wcstoull, wchar_t) // NOLINT +INTERCEPTORS_STRTO(double, strtod, char) +INTERCEPTORS_STRTO(float, strtof, char) +INTERCEPTORS_STRTO(long double, strtold, char) +INTERCEPTORS_STRTO_BASE(long, strtol, char) +INTERCEPTORS_STRTO_BASE(long long, strtoll, char) +INTERCEPTORS_STRTO_BASE(unsigned long, strtoul, char) +INTERCEPTORS_STRTO_BASE(unsigned long long, strtoull, char) +INTERCEPTORS_STRTO_BASE(u64, strtouq, char) + +INTERCEPTORS_STRTO(double, wcstod, wchar_t) +INTERCEPTORS_STRTO(float, wcstof, wchar_t) +INTERCEPTORS_STRTO(long double, wcstold, wchar_t) +INTERCEPTORS_STRTO_BASE(long, wcstol, wchar_t) +INTERCEPTORS_STRTO_BASE(long long, wcstoll, wchar_t) +INTERCEPTORS_STRTO_BASE(unsigned long, wcstoul, wchar_t) +INTERCEPTORS_STRTO_BASE(unsigned long long, wcstoull, wchar_t) #if SANITIZER_NETBSD #define INTERCEPT_STRTO(func) \ @@ -765,17 +765,24 @@ INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) { #define MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED #endif +#define INTERCEPTOR_GETRLIMIT_BODY(func, resource, rlim) \ + if (msan_init_is_running) \ + return REAL(getrlimit)(resource, rlim); \ + ENSURE_MSAN_INITED(); \ + int res = REAL(func)(resource, rlim); \ + if (!res) \ + __msan_unpoison(rlim, __sanitizer::struct_rlimit_sz); \ + return res + INTERCEPTOR(int, getrlimit, int resource, void *rlim) { - if (msan_init_is_running) - return REAL(getrlimit)(resource, rlim); - ENSURE_MSAN_INITED(); - int res = REAL(getrlimit)(resource, rlim); - if (!res) - __msan_unpoison(rlim, __sanitizer::struct_rlimit_sz); - return res; + INTERCEPTOR_GETRLIMIT_BODY(getrlimit, resource, rlim); } #if !SANITIZER_FREEBSD && !SANITIZER_NETBSD +INTERCEPTOR(int, __getrlimit, int resource, void *rlim) { + INTERCEPTOR_GETRLIMIT_BODY(__getrlimit, resource, rlim); +} + INTERCEPTOR(int, getrlimit64, int resource, void *rlim) { if (msan_init_is_running) return REAL(getrlimit64)(resource, rlim); ENSURE_MSAN_INITED(); @@ -806,10 +813,12 @@ INTERCEPTOR(int, prlimit64, int pid, int resource, void *new_rlimit, return res; } +#define MSAN_MAYBE_INTERCEPT___GETRLIMIT INTERCEPT_FUNCTION(__getrlimit) #define MSAN_MAYBE_INTERCEPT_GETRLIMIT64 INTERCEPT_FUNCTION(getrlimit64) #define MSAN_MAYBE_INTERCEPT_PRLIMIT INTERCEPT_FUNCTION(prlimit) #define MSAN_MAYBE_INTERCEPT_PRLIMIT64 INTERCEPT_FUNCTION(prlimit64) #else +#define MSAN_MAYBE_INTERCEPT___GETRLIMIT #define MSAN_MAYBE_INTERCEPT_GETRLIMIT64 #define MSAN_MAYBE_INTERCEPT_PRLIMIT #define MSAN_MAYBE_INTERCEPT_PRLIMIT64 @@ -1514,13 +1523,12 @@ INTERCEPTOR(wchar_t *, wcscpy, wchar_t *dest, const wchar_t *src) { return res; } -INTERCEPTOR(wchar_t *, wcsncpy, wchar_t *dest, const wchar_t *src, - SIZE_T n) { // NOLINT +INTERCEPTOR(wchar_t *, wcsncpy, wchar_t *dest, const wchar_t *src, SIZE_T n) { ENSURE_MSAN_INITED(); GET_STORE_STACK_TRACE; SIZE_T copy_size = REAL(wcsnlen)(src, n); if (copy_size < n) copy_size++; // trailing \0 - wchar_t *res = REAL(wcsncpy)(dest, src, n); // NOLINT + wchar_t *res = REAL(wcsncpy)(dest, src, n); CopyShadowAndOrigin(dest, src, copy_size * sizeof(wchar_t), &stack); __msan_unpoison(dest + copy_size, (n - copy_size) * sizeof(wchar_t)); return res; @@ -1620,14 +1628,14 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(wmemcpy); MSAN_MAYBE_INTERCEPT_WMEMPCPY; INTERCEPT_FUNCTION(wmemmove); - INTERCEPT_FUNCTION(strcpy); // NOLINT - MSAN_MAYBE_INTERCEPT_STPCPY; // NOLINT + INTERCEPT_FUNCTION(strcpy); + MSAN_MAYBE_INTERCEPT_STPCPY; INTERCEPT_FUNCTION(strdup); MSAN_MAYBE_INTERCEPT___STRDUP; - INTERCEPT_FUNCTION(strncpy); // NOLINT + INTERCEPT_FUNCTION(strncpy); MSAN_MAYBE_INTERCEPT_GCVT; - INTERCEPT_FUNCTION(strcat); // NOLINT - INTERCEPT_FUNCTION(strncat); // NOLINT + INTERCEPT_FUNCTION(strcat); + INTERCEPT_FUNCTION(strncat); INTERCEPT_STRTO(strtod); INTERCEPT_STRTO(strtof); INTERCEPT_STRTO(strtold); @@ -1679,6 +1687,7 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(socketpair); MSAN_MAYBE_INTERCEPT_FGETS_UNLOCKED; INTERCEPT_FUNCTION(getrlimit); + MSAN_MAYBE_INTERCEPT___GETRLIMIT; MSAN_MAYBE_INTERCEPT_GETRLIMIT64; MSAN_MAYBE_INTERCEPT_PRLIMIT; MSAN_MAYBE_INTERCEPT_PRLIMIT64; diff --git a/lib/msan/msan_linux.cc b/lib/msan/msan_linux.cpp index 3b6e6cb85f33..d61e9dee3065 100644 --- a/lib/msan/msan_linux.cc +++ b/lib/msan/msan_linux.cpp @@ -1,4 +1,4 @@ -//===-- msan_linux.cc -----------------------------------------------------===// +//===-- msan_linux.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -125,7 +125,7 @@ bool InitShadow(bool init_origins) { for (unsigned i = 0; i < kMemoryLayoutSize; ++i) { uptr start = kMemoryLayout[i].start; uptr end = kMemoryLayout[i].end; - uptr size= end - start; + uptr size = end - start; MappingDesc::Type type = kMemoryLayout[i].type; // Check if the segment should be mapped based on platform constraints. @@ -174,8 +174,8 @@ void InstallAtExitHandler() { // ---------------------- TSD ---------------- {{{1 -#if SANITIZER_NETBSD || SANITIZER_FREEBSD -// Thread Static Data cannot be used in early init on NetBSD and FreeBSD. +#if SANITIZER_NETBSD +// Thread Static Data cannot be used in early init on NetBSD. // Reuse the MSan TSD API for compatibility with existing code // with an alternative implementation. diff --git a/lib/msan/msan_new_delete.cc b/lib/msan/msan_new_delete.cpp index 750981eb55eb..d4e95c0f6513 100644 --- a/lib/msan/msan_new_delete.cc +++ b/lib/msan/msan_new_delete.cpp @@ -1,4 +1,4 @@ -//===-- msan_new_delete.cc ------------------------------------------------===// +//===-- msan_new_delete.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -20,7 +20,7 @@ #include <stddef.h> -using namespace __msan; // NOLINT +using namespace __msan; // Fake std::nothrow_t and std::align_val_t to avoid including <new>. namespace std { diff --git a/lib/msan/msan_poisoning.cc b/lib/msan/msan_poisoning.cpp index 5ea01f51a835..ef3c74e0a35a 100644 --- a/lib/msan/msan_poisoning.cc +++ b/lib/msan/msan_poisoning.cpp @@ -1,4 +1,4 @@ -//===-- msan_poisoning.cc ---------------------------------------*- C++ -*-===// +//===-- msan_poisoning.cpp --------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/msan/msan_report.cc b/lib/msan/msan_report.cpp index 73bce3972593..e10d9eb62231 100644 --- a/lib/msan/msan_report.cc +++ b/lib/msan/msan_report.cpp @@ -1,4 +1,4 @@ -//===-- msan_report.cc ----------------------------------------------------===// +//===-- msan_report.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/msan/msan_thread.cc b/lib/msan/msan_thread.cpp index 0ba499350064..0ba499350064 100644 --- a/lib/msan/msan_thread.cc +++ b/lib/msan/msan_thread.cpp diff --git a/lib/profile/InstrProfiling.h b/lib/profile/InstrProfiling.h index 4d196a89b492..ffc4396169d0 100644 --- a/lib/profile/InstrProfiling.h +++ b/lib/profile/InstrProfiling.h @@ -155,6 +155,10 @@ int __llvm_orderfile_dump(void); * * \c Name is not copied, so it must remain valid. Passing NULL resets the * filename logic to the default behaviour. + * + * Note: There may be multiple copies of the profile runtime (one for each + * instrumented image/DSO). This API only modifies the filename within the + * copy of the runtime available to the calling image. */ void __llvm_profile_set_filename(const char *Name); @@ -173,6 +177,10 @@ void __llvm_profile_set_filename(const char *Name); * with the contents of the profiling file. If EnableMerge is zero, the runtime * may still merge the data if it would have merged for another reason (for * example, because of a %m specifier in the file name). + * + * Note: There may be multiple copies of the profile runtime (one for each + * instrumented image/DSO). This API only modifies the file object within the + * copy of the runtime available to the calling image. */ void __llvm_profile_set_file_object(FILE *File, int EnableMerge); @@ -196,7 +204,12 @@ const char *__llvm_profile_get_path_prefix(); * \brief Return filename (including path) of the profile data. Note that if the * user calls __llvm_profile_set_filename later after invoking this interface, * the actual file name may differ from what is returned here. - * Side-effect: this API call will invoke malloc with dynamic memory allocation. + * Side-effect: this API call will invoke malloc with dynamic memory allocation + * (the returned pointer must be passed to `free` to avoid a leak). + * + * Note: There may be multiple copies of the profile runtime (one for each + * instrumented image/DSO). This API only retrieves the filename from the copy + * of the runtime available to the calling image. */ const char *__llvm_profile_get_filename(); @@ -219,7 +232,7 @@ uint64_t __llvm_profile_get_data_size(const __llvm_profile_data *Begin, void __llvm_profile_set_dumped(); /*! - * This variable is defined in InstrProfilingRuntime.cc as a hidden + * This variable is defined in InstrProfilingRuntime.cpp as a hidden * symbol. Its main purpose is to enable profile runtime user to * bypass runtime initialization code -- if the client code explicitly * define this variable, then InstProfileRuntime.o won't be linked in. diff --git a/lib/profile/InstrProfilingFile.c b/lib/profile/InstrProfilingFile.c index e7996e282894..1b253c3e865e 100644 --- a/lib/profile/InstrProfilingFile.c +++ b/lib/profile/InstrProfilingFile.c @@ -70,7 +70,6 @@ typedef struct lprofFilename { * by runtime. */ unsigned OwnsFilenamePat; const char *ProfilePathPrefix; - const char *Filename; char PidChars[MAX_PID_SIZE]; char Hostname[COMPILER_RT_MAX_HOSTLEN]; unsigned NumPids; @@ -86,8 +85,8 @@ typedef struct lprofFilename { ProfileNameSpecifier PNS; } lprofFilename; -COMPILER_RT_WEAK lprofFilename lprofCurFilename = {0, 0, 0, 0, {0}, - {0}, 0, 0, 0, PNS_unknown}; +static lprofFilename lprofCurFilename = {0, 0, 0, {0}, {0}, + 0, 0, 0, PNS_unknown}; static int ProfileMergeRequested = 0; static int isProfileMergeRequested() { return ProfileMergeRequested; } @@ -387,8 +386,6 @@ static int parseFilenamePattern(const char *FilenamePat, /* Clean up cached prefix and filename. */ if (lprofCurFilename.ProfilePathPrefix) free((void *)lprofCurFilename.ProfilePathPrefix); - if (lprofCurFilename.Filename) - free((void *)lprofCurFilename.Filename); if (lprofCurFilename.FilenamePat && lprofCurFilename.OwnsFilenamePat) { free((void *)lprofCurFilename.FilenamePat); @@ -602,9 +599,6 @@ const char *__llvm_profile_get_filename(void) { char *FilenameBuf; const char *Filename; - if (lprofCurFilename.Filename) - return lprofCurFilename.Filename; - Length = getCurFilenameLength(); FilenameBuf = (char *)malloc(Length + 1); if (!FilenameBuf) { @@ -615,7 +609,6 @@ const char *__llvm_profile_get_filename(void) { if (!Filename) return "\0"; - lprofCurFilename.Filename = FilenameBuf; return FilenameBuf; } diff --git a/lib/profile/InstrProfilingPlatformFuchsia.c b/lib/profile/InstrProfilingPlatformFuchsia.c index 80beb4145460..2388871a2d54 100644 --- a/lib/profile/InstrProfilingPlatformFuchsia.c +++ b/lib/profile/InstrProfilingPlatformFuchsia.c @@ -27,6 +27,7 @@ #include <zircon/process.h> #include <zircon/sanitizer.h> +#include <zircon/status.h> #include <zircon/syscalls.h> #include "InstrProfiling.h" @@ -57,45 +58,57 @@ static inline void lprofWrite(const char *fmt, ...) { __sanitizer_log_write(s, ret + 1); } -static uint32_t lprofVMOWriter(ProfDataWriter *This, ProfDataIOVec *IOVecs, - uint32_t NumIOVecs) { - /* Allocate VMO if it hasn't been created yet. */ - if (__llvm_profile_vmo == ZX_HANDLE_INVALID) { - /* Get information about the current process. */ - zx_info_handle_basic_t Info; - zx_status_t Status = - _zx_object_get_info(_zx_process_self(), ZX_INFO_HANDLE_BASIC, &Info, - sizeof(Info), NULL, NULL); - if (Status != ZX_OK) - return -1; - - /* Create VMO to hold the profile data. */ - Status = _zx_vmo_create(0, ZX_VMO_RESIZABLE, &__llvm_profile_vmo); - if (Status != ZX_OK) - return -1; - - /* Give the VMO a name including our process KOID so it's easy to spot. */ - char VmoName[ZX_MAX_NAME_LEN]; - snprintf(VmoName, sizeof(VmoName), "%s.%" PRIu64, ProfileSinkName, - Info.koid); - _zx_object_set_property(__llvm_profile_vmo, ZX_PROP_NAME, VmoName, - strlen(VmoName)); - - /* Duplicate the handle since __sanitizer_publish_data consumes it. */ - zx_handle_t Handle; - Status = - _zx_handle_duplicate(__llvm_profile_vmo, ZX_RIGHT_SAME_RIGHTS, &Handle); - if (Status != ZX_OK) - return -1; - - /* Publish the VMO which contains profile data to the system. */ - __sanitizer_publish_data(ProfileSinkName, Handle); - - /* Use the dumpfile symbolizer markup element to write the name of VMO. */ - lprofWrite("LLVM Profile: {{{dumpfile:%s:%s}}}\n", - ProfileSinkName, VmoName); +static void createVMO() { + /* Don't create VMO if it has been alread created. */ + if (__llvm_profile_vmo != ZX_HANDLE_INVALID) + return; + + /* Get information about the current process. */ + zx_info_handle_basic_t Info; + zx_status_t Status = + _zx_object_get_info(_zx_process_self(), ZX_INFO_HANDLE_BASIC, &Info, + sizeof(Info), NULL, NULL); + if (Status != ZX_OK) { + lprofWrite("LLVM Profile: cannot get info about current process: %s\n", + _zx_status_get_string(Status)); + return; } + /* Create VMO to hold the profile data. */ + Status = _zx_vmo_create(0, ZX_VMO_RESIZABLE, &__llvm_profile_vmo); + if (Status != ZX_OK) { + lprofWrite("LLVM Profile: cannot create VMO: %s\n", + _zx_status_get_string(Status)); + return; + } + + /* Give the VMO a name including our process KOID so it's easy to spot. */ + char VmoName[ZX_MAX_NAME_LEN]; + snprintf(VmoName, sizeof(VmoName), "%s.%" PRIu64, ProfileSinkName, Info.koid); + _zx_object_set_property(__llvm_profile_vmo, ZX_PROP_NAME, VmoName, + strlen(VmoName)); + + /* Duplicate the handle since __sanitizer_publish_data consumes it. */ + zx_handle_t Handle; + Status = + _zx_handle_duplicate(__llvm_profile_vmo, ZX_RIGHT_SAME_RIGHTS, &Handle); + if (Status != ZX_OK) { + lprofWrite("LLVM Profile: cannot duplicate VMO handle: %s\n", + _zx_status_get_string(Status)); + _zx_handle_close(__llvm_profile_vmo); + __llvm_profile_vmo = ZX_HANDLE_INVALID; + return; + } + + /* Publish the VMO which contains profile data to the system. */ + __sanitizer_publish_data(ProfileSinkName, Handle); + + /* Use the dumpfile symbolizer markup element to write the name of VMO. */ + lprofWrite("LLVM Profile: {{{dumpfile:%s:%s}}}\n", ProfileSinkName, VmoName); +} + +static uint32_t lprofVMOWriter(ProfDataWriter *This, ProfDataIOVec *IOVecs, + uint32_t NumIOVecs) { /* Compute the total length of data to be written. */ size_t Length = 0; for (uint32_t I = 0; I < NumIOVecs; I++) @@ -129,13 +142,13 @@ static void initVMOWriter(ProfDataWriter *This) { static int dump(void) { if (lprofProfileDumped()) { - lprofWrite("Profile data not published: already written.\n"); + lprofWrite("LLVM Profile: data not published: already written.\n"); return 0; } /* Check if there is llvm/runtime version mismatch. */ if (GET_VERSION(__llvm_profile_get_version()) != INSTR_PROF_RAW_VERSION) { - lprofWrite("Runtime and instrumentation version mismatch : " + lprofWrite("LLVM Profile: runtime and instrumentation version mismatch: " "expected %d, but got %d\n", INSTR_PROF_RAW_VERSION, (int)GET_VERSION(__llvm_profile_get_version())); @@ -164,7 +177,7 @@ static void dumpWithoutReturn(void) { dump(); } * InstrProfilingRuntime.o if it is linked in. */ COMPILER_RT_VISIBILITY -void __llvm_profile_initialize_file(void) {} +void __llvm_profile_initialize_file(void) { createVMO(); } COMPILER_RT_VISIBILITY int __llvm_profile_register_write_file_atexit(void) { diff --git a/lib/profile/InstrProfilingRuntime.cc b/lib/profile/InstrProfilingRuntime.cpp index 679186ef8309..679186ef8309 100644 --- a/lib/profile/InstrProfilingRuntime.cc +++ b/lib/profile/InstrProfilingRuntime.cpp diff --git a/lib/profile/InstrProfilingUtil.c b/lib/profile/InstrProfilingUtil.c index 02d100792db8..13301f341fc5 100644 --- a/lib/profile/InstrProfilingUtil.c +++ b/lib/profile/InstrProfilingUtil.c @@ -12,6 +12,7 @@ #include <windows.h> #include "WindowsMMap.h" #else +#include <sys/file.h> #include <sys/stat.h> #include <sys/types.h> #include <unistd.h> @@ -39,8 +40,25 @@ COMPILER_RT_WEAK unsigned lprofDirMode = 0755; COMPILER_RT_VISIBILITY void __llvm_profile_recursive_mkdir(char *path) { int i; + int start = 1; + +#if defined(__ANDROID__) && defined(__ANDROID_API__) && \ + defined(__ANDROID_API_FUTURE__) && \ + __ANDROID_API__ == __ANDROID_API_FUTURE__ + // Avoid spammy selinux denial messages in Android by not attempting to + // create directories in GCOV_PREFIX. These denials occur when creating (or + // even attempting to stat()) top-level directories like "/data". + // + // Do so by ignoring ${GCOV_PREFIX} when invoking mkdir(). + const char *gcov_prefix = getenv("GCOV_PREFIX"); + if (gcov_prefix != NULL) { + const int gcov_prefix_len = strlen(gcov_prefix); + if (strncmp(path, gcov_prefix, gcov_prefix_len) == 0) + start = gcov_prefix_len; + } +#endif - for (i = 1; path[i] != '\0'; ++i) { + for (i = start; path[i] != '\0'; ++i) { char save = path[i]; if (!IS_DIR_SEPARATOR(path[i])) continue; diff --git a/lib/safestack/safestack.cc b/lib/safestack/safestack.cpp index f713d5e68718..0751f3988b9c 100644 --- a/lib/safestack/safestack.cc +++ b/lib/safestack/safestack.cpp @@ -1,4 +1,4 @@ -//===-- safestack.cc ------------------------------------------------------===// +//===-- safestack.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sancov_flags.cc b/lib/sanitizer_common/sancov_flags.cpp index ec6c14b1e2e4..ed46e88acdfc 100644 --- a/lib/sanitizer_common/sancov_flags.cc +++ b/lib/sanitizer_common/sancov_flags.cpp @@ -1,4 +1,4 @@ -//===-- sancov_flags.cc -----------------------------------------*- C++ -*-===// +//===-- sancov_flags.cpp ----------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_allocator.cc b/lib/sanitizer_common/sanitizer_allocator.cpp index 1739bb66b657..8d07906cca03 100644 --- a/lib/sanitizer_common/sanitizer_allocator.cc +++ b/lib/sanitizer_common/sanitizer_allocator.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_allocator.cc --------------------------------------------===// +//===-- sanitizer_allocator.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_allocator_checks.cc b/lib/sanitizer_common/sanitizer_allocator_checks.cpp index bb56010f1074..9d67f679b56c 100644 --- a/lib/sanitizer_common/sanitizer_allocator_checks.cc +++ b/lib/sanitizer_common/sanitizer_allocator_checks.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_allocator_checks.cc ---------------------------*- C++ -*-===// +//===-- sanitizer_allocator_checks.cpp --------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_allocator_checks.h b/lib/sanitizer_common/sanitizer_allocator_checks.h index f436ce9ecdea..fc426f0e74f4 100644 --- a/lib/sanitizer_common/sanitizer_allocator_checks.h +++ b/lib/sanitizer_common/sanitizer_allocator_checks.h @@ -54,7 +54,7 @@ INLINE bool CheckAlignedAllocAlignmentAndSize(uptr alignment, uptr size) { // and a multiple of sizeof(void *). INLINE bool CheckPosixMemalignAlignment(uptr alignment) { return alignment != 0 && IsPowerOfTwo(alignment) && - (alignment % sizeof(void *)) == 0; // NOLINT + (alignment % sizeof(void *)) == 0; } // Returns true if calloc(size, n) call overflows on size*n calculation. diff --git a/lib/sanitizer_common/sanitizer_allocator_report.cc b/lib/sanitizer_common/sanitizer_allocator_report.cpp index dfc418166556..d74e08010d5d 100644 --- a/lib/sanitizer_common/sanitizer_allocator_report.cc +++ b/lib/sanitizer_common/sanitizer_allocator_report.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_allocator_report.cc ---------------------------*- C++ -*-===// +//===-- sanitizer_allocator_report.cpp --------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -106,10 +106,11 @@ void NORETURN ReportInvalidPosixMemalignAlignment(uptr alignment, { ScopedAllocatorErrorReport report("invalid-posix-memalign-alignment", stack); - Report("ERROR: %s: invalid alignment requested in " - "posix_memalign: %zd, alignment must be a power of two and a " - "multiple of sizeof(void*) == %zd\n", SanitizerToolName, alignment, - sizeof(void*)); // NOLINT + Report( + "ERROR: %s: invalid alignment requested in " + "posix_memalign: %zd, alignment must be a power of two and a " + "multiple of sizeof(void*) == %zd\n", + SanitizerToolName, alignment, sizeof(void *)); } Die(); } diff --git a/lib/sanitizer_common/sanitizer_asm.h b/lib/sanitizer_common/sanitizer_asm.h index 184d118d97d8..803af3285e18 100644 --- a/lib/sanitizer_common/sanitizer_asm.h +++ b/lib/sanitizer_common/sanitizer_asm.h @@ -60,7 +60,9 @@ #if defined(__ELF__) && (defined(__GNU__) || defined(__FreeBSD__) || \ defined(__Fuchsia__) || defined(__linux__)) -#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits // NOLINT +// clang-format off +#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits // NOLINT +// clang-format on #else #define NO_EXEC_STACK_DIRECTIVE #endif diff --git a/lib/sanitizer_common/sanitizer_atomic_msvc.h b/lib/sanitizer_common/sanitizer_atomic_msvc.h index a249657d6617..6a7c5465dcbb 100644 --- a/lib/sanitizer_common/sanitizer_atomic_msvc.h +++ b/lib/sanitizer_common/sanitizer_atomic_msvc.h @@ -20,44 +20,35 @@ extern "C" void _mm_mfence(); #pragma intrinsic(_mm_mfence) extern "C" void _mm_pause(); #pragma intrinsic(_mm_pause) -extern "C" char _InterlockedExchange8( // NOLINT - char volatile *Addend, char Value); // NOLINT +extern "C" char _InterlockedExchange8(char volatile *Addend, char Value); #pragma intrinsic(_InterlockedExchange8) -extern "C" short _InterlockedExchange16( // NOLINT - short volatile *Addend, short Value); // NOLINT +extern "C" short _InterlockedExchange16(short volatile *Addend, short Value); #pragma intrinsic(_InterlockedExchange16) -extern "C" long _InterlockedExchange( // NOLINT - long volatile *Addend, long Value); // NOLINT +extern "C" long _InterlockedExchange(long volatile *Addend, long Value); #pragma intrinsic(_InterlockedExchange) -extern "C" long _InterlockedExchangeAdd( // NOLINT - long volatile * Addend, long Value); // NOLINT +extern "C" long _InterlockedExchangeAdd(long volatile *Addend, long Value); #pragma intrinsic(_InterlockedExchangeAdd) -extern "C" char _InterlockedCompareExchange8( // NOLINT - char volatile *Destination, // NOLINT - char Exchange, char Comparand); // NOLINT +extern "C" char _InterlockedCompareExchange8(char volatile *Destination, + char Exchange, char Comparand); #pragma intrinsic(_InterlockedCompareExchange8) -extern "C" short _InterlockedCompareExchange16( // NOLINT - short volatile *Destination, // NOLINT - short Exchange, short Comparand); // NOLINT +extern "C" short _InterlockedCompareExchange16(short volatile *Destination, + short Exchange, short Comparand); #pragma intrinsic(_InterlockedCompareExchange16) -extern "C" -long long _InterlockedCompareExchange64( // NOLINT - long long volatile *Destination, // NOLINT - long long Exchange, long long Comparand); // NOLINT +extern "C" long long _InterlockedCompareExchange64( + long long volatile *Destination, long long Exchange, long long Comparand); #pragma intrinsic(_InterlockedCompareExchange64) extern "C" void *_InterlockedCompareExchangePointer( void *volatile *Destination, void *Exchange, void *Comparand); #pragma intrinsic(_InterlockedCompareExchangePointer) -extern "C" -long __cdecl _InterlockedCompareExchange( // NOLINT - long volatile *Destination, // NOLINT - long Exchange, long Comparand); // NOLINT +extern "C" long __cdecl _InterlockedCompareExchange(long volatile *Destination, + long Exchange, + long Comparand); #pragma intrinsic(_InterlockedCompareExchange) #ifdef _WIN64 -extern "C" long long _InterlockedExchangeAdd64( // NOLINT - long long volatile * Addend, long long Value); // NOLINT +extern "C" long long _InterlockedExchangeAdd64(long long volatile *Addend, + long long Value); #pragma intrinsic(_InterlockedExchangeAdd64) #endif @@ -115,8 +106,8 @@ INLINE u32 atomic_fetch_add(volatile atomic_uint32_t *a, u32 v, memory_order mo) { (void)mo; DCHECK(!((uptr)a % sizeof(*a))); - return (u32)_InterlockedExchangeAdd( - (volatile long*)&a->val_dont_use, (long)v); // NOLINT + return (u32)_InterlockedExchangeAdd((volatile long *)&a->val_dont_use, + (long)v); } INLINE uptr atomic_fetch_add(volatile atomic_uintptr_t *a, @@ -124,11 +115,11 @@ INLINE uptr atomic_fetch_add(volatile atomic_uintptr_t *a, (void)mo; DCHECK(!((uptr)a % sizeof(*a))); #ifdef _WIN64 - return (uptr)_InterlockedExchangeAdd64( - (volatile long long*)&a->val_dont_use, (long long)v); // NOLINT + return (uptr)_InterlockedExchangeAdd64((volatile long long *)&a->val_dont_use, + (long long)v); #else - return (uptr)_InterlockedExchangeAdd( - (volatile long*)&a->val_dont_use, (long)v); // NOLINT + return (uptr)_InterlockedExchangeAdd((volatile long *)&a->val_dont_use, + (long)v); #endif } @@ -136,8 +127,8 @@ INLINE u32 atomic_fetch_sub(volatile atomic_uint32_t *a, u32 v, memory_order mo) { (void)mo; DCHECK(!((uptr)a % sizeof(*a))); - return (u32)_InterlockedExchangeAdd( - (volatile long*)&a->val_dont_use, -(long)v); // NOLINT + return (u32)_InterlockedExchangeAdd((volatile long *)&a->val_dont_use, + -(long)v); } INLINE uptr atomic_fetch_sub(volatile atomic_uintptr_t *a, @@ -145,11 +136,11 @@ INLINE uptr atomic_fetch_sub(volatile atomic_uintptr_t *a, (void)mo; DCHECK(!((uptr)a % sizeof(*a))); #ifdef _WIN64 - return (uptr)_InterlockedExchangeAdd64( - (volatile long long*)&a->val_dont_use, -(long long)v); // NOLINT + return (uptr)_InterlockedExchangeAdd64((volatile long long *)&a->val_dont_use, + -(long long)v); #else - return (uptr)_InterlockedExchangeAdd( - (volatile long*)&a->val_dont_use, -(long)v); // NOLINT + return (uptr)_InterlockedExchangeAdd((volatile long *)&a->val_dont_use, + -(long)v); #endif } diff --git a/lib/sanitizer_common/sanitizer_common.cc b/lib/sanitizer_common/sanitizer_common.cpp index 80fb8f60fc0b..f5f9f49d8cff 100644 --- a/lib/sanitizer_common/sanitizer_common.cc +++ b/lib/sanitizer_common/sanitizer_common.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_common.cc -----------------------------------------------===// +//===-- sanitizer_common.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -323,7 +323,7 @@ static int InstallMallocFreeHooks(void (*malloc_hook)(const void *, uptr), } // namespace __sanitizer -using namespace __sanitizer; // NOLINT +using namespace __sanitizer; extern "C" { SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_report_error_summary, diff --git a/lib/sanitizer_common/sanitizer_common.h b/lib/sanitizer_common/sanitizer_common.h index 1703899e32b5..87b8f02b5b73 100644 --- a/lib/sanitizer_common/sanitizer_common.h +++ b/lib/sanitizer_common/sanitizer_common.h @@ -100,6 +100,8 @@ void UnmapOrDie(void *addr, uptr size); void *MmapOrDieOnFatalError(uptr size, const char *mem_type); bool MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name = nullptr) WARN_UNUSED_RESULT; +bool MmapFixedSuperNoReserve(uptr fixed_addr, uptr size, + const char *name = nullptr) WARN_UNUSED_RESULT; void *MmapNoReserveOrDie(uptr size, const char *mem_type); void *MmapFixedOrDie(uptr fixed_addr, uptr size, const char *name = nullptr); // Behaves just like MmapFixedOrDie, but tolerates out of memory condition, in @@ -131,7 +133,7 @@ void ReleaseMemoryPagesToOS(uptr beg, uptr end); void IncreaseTotalMmap(uptr size); void DecreaseTotalMmap(uptr size); uptr GetRSS(); -bool NoHugePagesInRegion(uptr addr, uptr length); +void SetShadowRegionHugePageMode(uptr addr, uptr length); bool DontDumpShadowMemory(uptr addr, uptr length); // Check if the built VMA size matches the runtime one. void CheckVMASize(); @@ -337,18 +339,18 @@ void ReportMmapWriteExec(int prot); // Math #if SANITIZER_WINDOWS && !defined(__clang__) && !defined(__GNUC__) extern "C" { -unsigned char _BitScanForward(unsigned long *index, unsigned long mask); // NOLINT -unsigned char _BitScanReverse(unsigned long *index, unsigned long mask); // NOLINT +unsigned char _BitScanForward(unsigned long *index, unsigned long mask); +unsigned char _BitScanReverse(unsigned long *index, unsigned long mask); #if defined(_WIN64) -unsigned char _BitScanForward64(unsigned long *index, unsigned __int64 mask); // NOLINT -unsigned char _BitScanReverse64(unsigned long *index, unsigned __int64 mask); // NOLINT +unsigned char _BitScanForward64(unsigned long *index, unsigned __int64 mask); +unsigned char _BitScanReverse64(unsigned long *index, unsigned __int64 mask); #endif } #endif INLINE uptr MostSignificantSetBitIndex(uptr x) { CHECK_NE(x, 0U); - unsigned long up; // NOLINT + unsigned long up; #if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__) # ifdef _WIN64 up = SANITIZER_WORDSIZE - 1 - __builtin_clzll(x); @@ -365,7 +367,7 @@ INLINE uptr MostSignificantSetBitIndex(uptr x) { INLINE uptr LeastSignificantSetBitIndex(uptr x) { CHECK_NE(x, 0U); - unsigned long up; // NOLINT + unsigned long up; #if !SANITIZER_WINDOWS || defined(__clang__) || defined(__GNUC__) # ifdef _WIN64 up = __builtin_ctzll(x); @@ -669,7 +671,7 @@ bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size, error_t *errno_p = nullptr); // When adding a new architecture, don't forget to also update -// script/asan_symbolize.py and sanitizer_symbolizer_libcdep.cc. +// script/asan_symbolize.py and sanitizer_symbolizer_libcdep.cpp. inline const char *ModuleArchToString(ModuleArch arch) { switch (arch) { case kModuleArchUnknown: @@ -879,6 +881,11 @@ struct SignalContext { bool is_memory_access; enum WriteFlag { UNKNOWN, READ, WRITE } write_flag; + // In some cases the kernel cannot provide the true faulting address; `addr` + // will be zero then. This field allows to distinguish between these cases + // and dereferences of null. + bool is_true_faulting_addr; + // VS2013 doesn't implement unrestricted unions, so we need a trivial default // constructor SignalContext() = default; @@ -891,7 +898,8 @@ struct SignalContext { context(context), addr(GetAddress()), is_memory_access(IsMemoryAccess()), - write_flag(GetWriteFlag()) { + write_flag(GetWriteFlag()), + is_true_faulting_addr(IsTrueFaultingAddress()) { InitPcSpBp(); } @@ -912,6 +920,7 @@ struct SignalContext { uptr GetAddress() const; WriteFlag GetWriteFlag() const; bool IsMemoryAccess() const; + bool IsTrueFaultingAddress() const; }; void InitializePlatformEarly(); @@ -971,7 +980,7 @@ INLINE u32 GetNumberOfCPUsCached() { } // namespace __sanitizer inline void *operator new(__sanitizer::operator_new_size_type size, - __sanitizer::LowLevelAllocator &alloc) { + __sanitizer::LowLevelAllocator &alloc) { // NOLINT return alloc.Allocate(size); } diff --git a/lib/sanitizer_common/sanitizer_common_interceptors.inc b/lib/sanitizer_common/sanitizer_common_interceptors.inc index 9f5a91ac99dc..50e3558b52e8 100644 --- a/lib/sanitizer_common/sanitizer_common_interceptors.inc +++ b/lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -36,6 +36,7 @@ // COMMON_INTERCEPTOR_MMAP_IMPL // COMMON_INTERCEPTOR_COPY_STRING // COMMON_INTERCEPTOR_STRNDUP_IMPL +// COMMON_INTERCEPTOR_STRERROR //===----------------------------------------------------------------------===// #include "interception/interception.h" @@ -301,6 +302,10 @@ bool PlatformHasDifferentMemcpyAndMemmove(); return new_mem; #endif +#ifndef COMMON_INTERCEPTOR_STRERROR +#define COMMON_INTERCEPTOR_STRERROR() {} +#endif + struct FileMetadata { // For open_memstream(). char **addr; @@ -317,11 +322,11 @@ struct CommonInterceptorMetadata { }; }; +#if SI_POSIX typedef AddrHashMap<CommonInterceptorMetadata, 31051> MetadataHashMap; static MetadataHashMap *interceptor_metadata_map; -#if SI_POSIX UNUSED static void SetInterceptorMetadata(__sanitizer_FILE *addr, const FileMetadata &file) { MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr); @@ -1241,8 +1246,9 @@ INTERCEPTOR_WITH_SUFFIX(int, fputs, char *s, void *file) { // libc file streams can call user-supplied functions, see fopencookie. void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, fputs, s, file); - if (!SANITIZER_MAC || s) + if (!SANITIZER_MAC || s) { // `fputs(NULL, file)` is supported on Darwin. COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); + } return REAL(fputs)(s, file); } #define INIT_FPUTS COMMON_INTERCEPT_FUNCTION(fputs) @@ -1255,8 +1261,9 @@ INTERCEPTOR(int, puts, char *s) { // libc file streams can call user-supplied functions, see fopencookie. void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, puts, s); - if (!SANITIZER_MAC || s) + if (!SANITIZER_MAC || s) { // `puts(NULL)` is supported on Darwin. COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); + } return REAL(puts)(s); } #define INIT_PUTS COMMON_INTERCEPT_FUNCTION(puts) @@ -1265,9 +1272,8 @@ INTERCEPTOR(int, puts, char *s) { #endif #if SANITIZER_INTERCEPT_PRCTL -INTERCEPTOR(int, prctl, int option, unsigned long arg2, - unsigned long arg3, // NOLINT - unsigned long arg4, unsigned long arg5) { // NOLINT +INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3, + unsigned long arg4, unsigned long arg5) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, prctl, option, arg2, arg3, arg4, arg5); static const int PR_SET_NAME = 15; @@ -1699,13 +1705,13 @@ INTERCEPTOR(int, __fprintf_chk, __sanitizer_FILE *stream, SIZE_T size, FORMAT_INTERCEPTOR_IMPL(__fprintf_chk, vfprintf, stream, format) #endif -INTERCEPTOR(int, sprintf, char *str, const char *format, ...) // NOLINT -FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) // NOLINT +INTERCEPTOR(int, sprintf, char *str, const char *format, ...) +FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) #if SANITIZER_INTERCEPT___PRINTF_CHK INTERCEPTOR(int, __sprintf_chk, char *str, int flag, SIZE_T size_to, - const char *format, ...) // NOLINT -FORMAT_INTERCEPTOR_IMPL(__sprintf_chk, vsprintf, str, format) // NOLINT + const char *format, ...) +FORMAT_INTERCEPTOR_IMPL(__sprintf_chk, vsprintf, str, format) #endif INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...) @@ -1713,8 +1719,8 @@ FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format) #if SANITIZER_INTERCEPT___PRINTF_CHK INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag, - SIZE_T size_to, const char *format, ...) // NOLINT -FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format) // NOLINT + SIZE_T size_to, const char *format, ...) +FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format) #endif INTERCEPTOR(int, asprintf, char **strp, const char *format, ...) @@ -3069,13 +3075,14 @@ INTERCEPTOR(int, sendmmsg, int fd, struct __sanitizer_mmsghdr *msgvec, COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); } int res = REAL(sendmmsg)(fd, msgvec, vlen, flags); - if (res >= 0 && msgvec) + if (res >= 0 && msgvec) { for (int i = 0; i < res; ++i) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len, sizeof(msgvec[i].msg_len)); if (common_flags()->intercept_send) read_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len); } + } return res; } #define INIT_SENDMMSG COMMON_INTERCEPT_FUNCTION(sendmmsg); @@ -3206,20 +3213,21 @@ INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { __sanitizer_iovec local_iovec; if (data) { - if (request == ptrace_setregs) + if (request == ptrace_setregs) { COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_regs_struct_sz); - else if (request == ptrace_setfpregs) + } else if (request == ptrace_setfpregs) { COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpregs_struct_sz); - else if (request == ptrace_setfpxregs) + } else if (request == ptrace_setfpxregs) { COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_fpxregs_struct_sz); - else if (request == ptrace_setvfpregs) + } else if (request == ptrace_setvfpregs) { COMMON_INTERCEPTOR_READ_RANGE(ctx, data, struct_user_vfpregs_struct_sz); - else if (request == ptrace_setsiginfo) + } else if (request == ptrace_setsiginfo) { COMMON_INTERCEPTOR_READ_RANGE(ctx, data, siginfo_t_sz); + // Some kernel might zero the iovec::iov_base in case of invalid // write access. In this case copy the invalid address for further // inspection. - else if (request == ptrace_setregset || request == ptrace_getregset) { + } else if (request == ptrace_setregset || request == ptrace_getregset) { __sanitizer_iovec *iovec = (__sanitizer_iovec*)data; COMMON_INTERCEPTOR_READ_RANGE(ctx, iovec, sizeof(*iovec)); local_iovec = *iovec; @@ -3236,19 +3244,19 @@ INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { if (!res && data) { // Note that PEEK* requests assign different meaning to the return value. // This function does not handle them (nor does it need to). - if (request == ptrace_getregs) + if (request == ptrace_getregs) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_regs_struct_sz); - else if (request == ptrace_getfpregs) + } else if (request == ptrace_getfpregs) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpregs_struct_sz); - else if (request == ptrace_getfpxregs) + } else if (request == ptrace_getfpxregs) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_fpxregs_struct_sz); - else if (request == ptrace_getvfpregs) + } else if (request == ptrace_getvfpregs) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, struct_user_vfpregs_struct_sz); - else if (request == ptrace_getsiginfo) + } else if (request == ptrace_getsiginfo) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, siginfo_t_sz); - else if (request == ptrace_geteventmsg) + } else if (request == ptrace_geteventmsg) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(unsigned long)); - else if (request == ptrace_getregset) { + } else if (request == ptrace_getregset) { __sanitizer_iovec *iovec = (__sanitizer_iovec*)data; COMMON_INTERCEPTOR_WRITE_RANGE(ctx, iovec, sizeof(*iovec)); COMMON_INTERCEPTOR_WRITE_RANGE(ctx, local_iovec.iov_base, @@ -3674,6 +3682,7 @@ INTERCEPTOR(int, sched_getparam, int pid, void *param) { INTERCEPTOR(char *, strerror, int errnum) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, strerror, errnum); + COMMON_INTERCEPTOR_STRERROR(); char *res = REAL(strerror)(errnum); if (res) COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); return res; @@ -6714,7 +6723,7 @@ INTERCEPTOR(wchar_t *, wcscat, wchar_t *dst, const wchar_t *src) { COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t)); COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size, (src_size + 1) * sizeof(wchar_t)); - return REAL(wcscat)(dst, src); // NOLINT + return REAL(wcscat)(dst, src); } INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) { @@ -6727,7 +6736,7 @@ INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) { COMMON_INTERCEPTOR_READ_RANGE(ctx, dst, (dst_size + 1) * sizeof(wchar_t)); COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst + dst_size, (src_size + 1) * sizeof(wchar_t)); - return REAL(wcsncat)(dst, src, n); // NOLINT + return REAL(wcsncat)(dst, src, n); } #define INIT_WCSCAT \ COMMON_INTERCEPT_FUNCTION(wcscat); \ @@ -7841,10 +7850,11 @@ INTERCEPTOR(int, modctl, int operation, void *argp) { if (iov) COMMON_INTERCEPTOR_WRITE_RANGE( ctx, iov->iov_base, Min(iov_len, iov->iov_len)); - } else if (operation == modctl_exists) + } else if (operation == modctl_exists) { ret = REAL(modctl)(operation, argp); - else + } else { ret = REAL(modctl)(operation, argp); + } return ret; } @@ -9548,10 +9558,76 @@ INTERCEPTOR(void, sl_free, void *sl, int freeall) { #define INIT_SL_INIT #endif +#if SANITIZER_INTERCEPT_GETRANDOM +INTERCEPTOR(SSIZE_T, getrandom, void *buf, SIZE_T buflen, unsigned int flags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getrandom, buf, buflen, flags); + SSIZE_T n = REAL(getrandom)(buf, buflen, flags); + if (n > 0) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, n); + } + return n; +} +#define INIT_GETRANDOM COMMON_INTERCEPT_FUNCTION(getrandom) +#else +#define INIT_GETRANDOM +#endif + +#if SANITIZER_INTERCEPT_CRYPT +INTERCEPTOR(char *, crypt, char *key, char *salt) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, crypt, key, salt); + COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1); + char *res = REAL(crypt)(key, salt); + if (res != nullptr) + COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); + return res; +} +#define INIT_CRYPT COMMON_INTERCEPT_FUNCTION(crypt); +#else +#define INIT_CRYPT +#endif + +#if SANITIZER_INTERCEPT_CRYPT_R +INTERCEPTOR(char *, crypt_r, char *key, char *salt, void *data) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, crypt_r, key, salt, data); + COMMON_INTERCEPTOR_READ_RANGE(ctx, key, internal_strlen(key) + 1); + COMMON_INTERCEPTOR_READ_RANGE(ctx, salt, internal_strlen(salt) + 1); + char *res = REAL(crypt_r)(key, salt, data); + if (res != nullptr) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, + __sanitizer::struct_crypt_data_sz); + COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, internal_strlen(res) + 1); + } + return res; +} +#define INIT_CRYPT_R COMMON_INTERCEPT_FUNCTION(crypt_r); +#else +#define INIT_CRYPT_R +#endif + +#if SANITIZER_INTERCEPT_GETENTROPY +INTERCEPTOR(int, getentropy, void *buf, SIZE_T buflen) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getentropy, buf, buflen); + int r = REAL(getentropy)(buf, buflen); + if (r == 0) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); + } + return r; +} +#define INIT_GETENTROPY COMMON_INTERCEPT_FUNCTION(getentropy) +#else +#define INIT_GETENTROPY +#endif + static void InitializeCommonInterceptors() { +#if SI_POSIX static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; - interceptor_metadata_map = - new ((void *)&metadata_mem) MetadataHashMap(); // NOLINT + interceptor_metadata_map = new ((void *)&metadata_mem) MetadataHashMap(); +#endif INIT_MMAP; INIT_MMAP64; @@ -9844,6 +9920,10 @@ static void InitializeCommonInterceptors() { INIT_FDEVNAME; INIT_GETUSERSHELL; INIT_SL_INIT; + INIT_GETRANDOM; + INIT_CRYPT; + INIT_CRYPT_R; + INIT_GETENTROPY; INIT___PRINTF_CHK; } diff --git a/lib/sanitizer_common/sanitizer_common_interface.inc b/lib/sanitizer_common/sanitizer_common_interface.inc index c72554973b05..c78b6e10b689 100644 --- a/lib/sanitizer_common/sanitizer_common_interface.inc +++ b/lib/sanitizer_common/sanitizer_common_interface.inc @@ -14,6 +14,7 @@ INTERFACE_FUNCTION(__sanitizer_set_death_callback) INTERFACE_FUNCTION(__sanitizer_set_report_path) INTERFACE_FUNCTION(__sanitizer_set_report_fd) INTERFACE_FUNCTION(__sanitizer_verify_contiguous_container) +INTERFACE_WEAK_FUNCTION(__sanitizer_on_print) INTERFACE_WEAK_FUNCTION(__sanitizer_report_error_summary) INTERFACE_WEAK_FUNCTION(__sanitizer_sandbox_on_notify) // Sanitizer weak hooks diff --git a/lib/sanitizer_common/sanitizer_common_libcdep.cc b/lib/sanitizer_common/sanitizer_common_libcdep.cpp index 363eb4c146ce..27d6a177760e 100644 --- a/lib/sanitizer_common/sanitizer_common_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_common_libcdep.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_common_libcdep.cc ---------------------------------------===// +//===-- sanitizer_common_libcdep.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_common_nolibc.cc b/lib/sanitizer_common/sanitizer_common_nolibc.cpp index fdd858781216..3b278e017eb7 100644 --- a/lib/sanitizer_common/sanitizer_common_nolibc.cc +++ b/lib/sanitizer_common/sanitizer_common_nolibc.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_common_nolibc.cc ----------------------------------------===// +//===-- sanitizer_common_nolibc.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_common_syscalls.inc b/lib/sanitizer_common/sanitizer_common_syscalls.inc index 00bb2aeef111..31ff48cfd2cf 100644 --- a/lib/sanitizer_common/sanitizer_common_syscalls.inc +++ b/lib/sanitizer_common/sanitizer_common_syscalls.inc @@ -2873,6 +2873,18 @@ POST_SYSCALL(rt_sigaction)(long res, long signum, POST_WRITE(oldact, oldact_sz); } } + +PRE_SYSCALL(getrandom)(void *buf, uptr count, long flags) { + if (buf) { + PRE_WRITE(buf, count); + } +} + +POST_SYSCALL(getrandom)(long res, void *buf, uptr count, long flags) { + if (res > 0 && buf) { + POST_WRITE(buf, res); + } +} } // extern "C" #undef PRE_SYSCALL diff --git a/lib/sanitizer_common/sanitizer_coverage_fuchsia.cc b/lib/sanitizer_common/sanitizer_coverage_fuchsia.cpp index 2c7180122148..f18cee66b843 100644 --- a/lib/sanitizer_common/sanitizer_coverage_fuchsia.cc +++ b/lib/sanitizer_common/sanitizer_coverage_fuchsia.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_coverage_fuchsia.cc -------------------------------------===// +//===-- sanitizer_coverage_fuchsia.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -36,7 +36,7 @@ #include <zircon/sanitizer.h> #include <zircon/syscalls.h> -using namespace __sanitizer; // NOLINT +using namespace __sanitizer; namespace __sancov { namespace { @@ -198,8 +198,8 @@ void InitializeCoverage(bool enabled, const char *dir) { } // namespace __sanitizer extern "C" { -SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_dump_coverage( // NOLINT - const uptr *pcs, uptr len) { +SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_dump_coverage(const uptr *pcs, + uptr len) { UNIMPLEMENTED(); } diff --git a/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc b/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cpp index 9dbf2eb52978..6a75792f9262 100644 --- a/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cc +++ b/lib/sanitizer_common/sanitizer_coverage_libcdep_new.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_coverage_libcdep_new.cc ---------------------------------===// +//===-- sanitizer_coverage_libcdep_new.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -166,8 +166,8 @@ void InitializeCoverage(bool enabled, const char *dir) { } // namespace __sanitizer extern "C" { -SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_dump_coverage( // NOLINT - const uptr* pcs, uptr len) { +SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_dump_coverage(const uptr* pcs, + uptr len) { return __sancov::SanitizerDumpCoverage(pcs, len); } diff --git a/lib/sanitizer_common/sanitizer_coverage_win_dll_thunk.cc b/lib/sanitizer_common/sanitizer_coverage_win_dll_thunk.cpp index 1f0f69dc43eb..d0bf8a455643 100644 --- a/lib/sanitizer_common/sanitizer_coverage_win_dll_thunk.cc +++ b/lib/sanitizer_common/sanitizer_coverage_win_dll_thunk.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_coverage_win_dll_thunk.cc -------------------------------===// +//===-- sanitizer_coverage_win_dll_thunk.cpp ------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cc b/lib/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cpp index 2a4199756f3b..0bdf0c5aed41 100644 --- a/lib/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cc +++ b/lib/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_coverage_win_dynamic_runtime_thunk.cc -------------------===// +//===-- sanitizer_coverage_win_dynamic_runtime_thunk.cpp ------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_coverage_win_sections.cc b/lib/sanitizer_common/sanitizer_coverage_win_sections.cpp index 403d46c8c4f1..e7d6563393cf 100644 --- a/lib/sanitizer_common/sanitizer_coverage_win_sections.cc +++ b/lib/sanitizer_common/sanitizer_coverage_win_sections.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_coverage_win_sections.cc --------------------------------===// +//===-- sanitizer_coverage_win_sections.cpp -------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -31,7 +31,7 @@ extern "C" { // Use uint64_t so the linker won't need to add any padding if it tries to word // align the start of the 8-bit counters array. The array will always start 8 // bytes after __start_sancov_cntrs. -#pragma section(".SCOV$CA", read, write) // NOLINT +#pragma section(".SCOV$CA", read, write) __declspec(allocate(".SCOV$CA")) uint64_t __start___sancov_cntrs = 0; // Even though we said not to align __stop__sancov_cntrs (using the "align" @@ -41,13 +41,13 @@ __declspec(allocate(".SCOV$CA")) uint64_t __start___sancov_cntrs = 0; // padding would be added to align .SCOVP$Z, However, if .SCOV$CZ section is 1 // byte, the linker won't try to align it on an 8-byte boundary, so use a // uint8_t for __stop_sancov_cntrs. -#pragma section(".SCOV$CZ", read, write) // NOLINT +#pragma section(".SCOV$CZ", read, write) __declspec(allocate(".SCOV$CZ")) __declspec(align(1)) uint8_t __stop___sancov_cntrs = 0; -#pragma section(".SCOV$GA", read, write) // NOLINT +#pragma section(".SCOV$GA", read, write) __declspec(allocate(".SCOV$GA")) uint64_t __start___sancov_guards = 0; -#pragma section(".SCOV$GZ", read, write) // NOLINT +#pragma section(".SCOV$GZ", read, write) __declspec(allocate(".SCOV$GZ")) __declspec(align(1)) uint8_t __stop___sancov_guards = 0; @@ -56,9 +56,9 @@ __declspec(allocate(".SCOV$GZ")) __declspec(align(1)) uint8_t // constant it should be merged with the .rdata section. #pragma comment(linker, "/MERGE:.SCOV=.data") -#pragma section(".SCOVP$A", read) // NOLINT +#pragma section(".SCOVP$A", read) __declspec(allocate(".SCOVP$A")) uint64_t __start___sancov_pcs = 0; -#pragma section(".SCOVP$Z", read) // NOLINT +#pragma section(".SCOVP$Z", read) __declspec(allocate(".SCOVP$Z")) __declspec(align(1)) uint8_t __stop___sancov_pcs = 0; diff --git a/lib/sanitizer_common/sanitizer_coverage_win_weak_interception.cc b/lib/sanitizer_common/sanitizer_coverage_win_weak_interception.cpp index 1fd10d5b83a1..55263981705f 100644 --- a/lib/sanitizer_common/sanitizer_coverage_win_weak_interception.cc +++ b/lib/sanitizer_common/sanitizer_coverage_win_weak_interception.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_coverage_win_weak_interception.cc -----------------------===// +//===-- sanitizer_coverage_win_weak_interception.cpp ----------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_deadlock_detector1.cc b/lib/sanitizer_common/sanitizer_deadlock_detector1.cpp index a151a190c180..d4a325bea4b2 100644 --- a/lib/sanitizer_common/sanitizer_deadlock_detector1.cc +++ b/lib/sanitizer_common/sanitizer_deadlock_detector1.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_deadlock_detector1.cc -----------------------------------===// +//===-- sanitizer_deadlock_detector1.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_deadlock_detector2.cc b/lib/sanitizer_common/sanitizer_deadlock_detector2.cpp index ed9ea26d3902..4026739d4e51 100644 --- a/lib/sanitizer_common/sanitizer_deadlock_detector2.cc +++ b/lib/sanitizer_common/sanitizer_deadlock_detector2.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_deadlock_detector2.cc -----------------------------------===// +//===-- sanitizer_deadlock_detector2.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_errno.cc b/lib/sanitizer_common/sanitizer_errno.cpp index 1600de566393..cbadf4d924a7 100644 --- a/lib/sanitizer_common/sanitizer_errno.cc +++ b/lib/sanitizer_common/sanitizer_errno.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_errno.cc --------------------------------------*- C++ -*-===// +//===-- sanitizer_errno.cpp -------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_file.cc b/lib/sanitizer_common/sanitizer_file.cpp index 3cb4974bdab2..79930d794250 100644 --- a/lib/sanitizer_common/sanitizer_file.cc +++ b/lib/sanitizer_common/sanitizer_file.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_file.cc ------------------------------------------------===// +//===-- sanitizer_file.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -8,7 +8,7 @@ // // This file is shared between AddressSanitizer and ThreadSanitizer // run-time libraries. It defines filesystem-related interfaces. This -// is separate from sanitizer_common.cc so that it's simpler to disable +// is separate from sanitizer_common.cpp so that it's simpler to disable // all the filesystem support code for a port that doesn't use it. // //===---------------------------------------------------------------------===// @@ -199,7 +199,7 @@ char *FindPathToBinary(const char *name) { } // namespace __sanitizer -using namespace __sanitizer; // NOLINT +using namespace __sanitizer; extern "C" { void __sanitizer_set_report_path(const char *path) { diff --git a/lib/sanitizer_common/sanitizer_flag_parser.cc b/lib/sanitizer_common/sanitizer_flag_parser.cpp index e380d3b55e36..1e2bc6652617 100644 --- a/lib/sanitizer_common/sanitizer_flag_parser.cc +++ b/lib/sanitizer_common/sanitizer_flag_parser.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_flag_parser.cc ------------------------------------------===// +//===-- sanitizer_flag_parser.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -83,8 +83,9 @@ void FlagParser::parse_flag(const char *env_option_name) { Printf("%s: ERROR: expected '=' in %s\n", SanitizerToolName, env_option_name); Die(); - } else + } else { fatal_error("expected '='"); + } } char *name = ll_strndup(buf_ + name_start, pos_ - name_start); diff --git a/lib/sanitizer_common/sanitizer_flag_parser.h b/lib/sanitizer_common/sanitizer_flag_parser.h index 8e12700bbe8c..c24ad25626ba 100644 --- a/lib/sanitizer_common/sanitizer_flag_parser.h +++ b/lib/sanitizer_common/sanitizer_flag_parser.h @@ -24,7 +24,7 @@ class FlagHandlerBase { virtual bool Parse(const char *value) { return false; } protected: - ~FlagHandlerBase() {}; + ~FlagHandlerBase() {} }; template <typename T> @@ -144,7 +144,7 @@ class FlagParser { template <typename T> static void RegisterFlag(FlagParser *parser, const char *name, const char *desc, T *var) { - FlagHandler<T> *fh = new (FlagParser::Alloc) FlagHandler<T>(var); // NOLINT + FlagHandler<T> *fh = new (FlagParser::Alloc) FlagHandler<T>(var); parser->RegisterHandler(name, fh, desc); } diff --git a/lib/sanitizer_common/sanitizer_flags.cc b/lib/sanitizer_common/sanitizer_flags.cpp index c587b1884935..66a0a5579ed3 100644 --- a/lib/sanitizer_common/sanitizer_flags.cc +++ b/lib/sanitizer_common/sanitizer_flags.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_flags.cc ------------------------------------------------===// +//===-- sanitizer_flags.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -92,11 +92,11 @@ class FlagHandlerInclude : public FlagHandlerBase { }; void RegisterIncludeFlags(FlagParser *parser, CommonFlags *cf) { - FlagHandlerInclude *fh_include = new (FlagParser::Alloc) // NOLINT + FlagHandlerInclude *fh_include = new (FlagParser::Alloc) FlagHandlerInclude(parser, /*ignore_missing*/ false); parser->RegisterHandler("include", fh_include, "read more options from the given file"); - FlagHandlerInclude *fh_include_if_exists = new (FlagParser::Alloc) // NOLINT + FlagHandlerInclude *fh_include_if_exists = new (FlagParser::Alloc) FlagHandlerInclude(parser, /*ignore_missing*/ true); parser->RegisterHandler( "include_if_exists", fh_include_if_exists, diff --git a/lib/sanitizer_common/sanitizer_fuchsia.cc b/lib/sanitizer_common/sanitizer_fuchsia.cpp index 9c032fa8995c..6e2c6137f0ce 100644 --- a/lib/sanitizer_common/sanitizer_fuchsia.cc +++ b/lib/sanitizer_common/sanitizer_fuchsia.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_fuchsia.cc ----------------------------------------------===// +//===-- sanitizer_fuchsia.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -502,7 +502,7 @@ uptr GetRSS() { UNIMPLEMENTED(); } } // namespace __sanitizer -using namespace __sanitizer; // NOLINT +using namespace __sanitizer; extern "C" { void __sanitizer_startup_hook(int argc, char **argv, char **envp, diff --git a/lib/sanitizer_common/sanitizer_getauxval.h b/lib/sanitizer_common/sanitizer_getauxval.h index cbd1af12c04f..86ad3a5e2c2a 100644 --- a/lib/sanitizer_common/sanitizer_getauxval.h +++ b/lib/sanitizer_common/sanitizer_getauxval.h @@ -9,6 +9,7 @@ // Common getauxval() guards and definitions. // getauxval() is not defined until glibc version 2.16, or until API level 21 // for Android. +// Implement the getauxval() compat function for NetBSD. // //===----------------------------------------------------------------------===// @@ -16,15 +17,10 @@ #define SANITIZER_GETAUXVAL_H #include "sanitizer_platform.h" +#include "sanitizer_glibc_version.h" #if SANITIZER_LINUX || SANITIZER_FUCHSIA -# include <features.h> - -# ifndef __GLIBC_PREREQ -# define __GLIBC_PREREQ(x, y) 0 -# endif - # if __GLIBC_PREREQ(2, 16) || (SANITIZER_ANDROID && __ANDROID_API__ >= 21) || \ SANITIZER_FUCHSIA # define SANITIZER_USE_GETAUXVAL 1 @@ -38,10 +34,26 @@ // The weak getauxval definition allows to check for the function at runtime. // This is useful for Android, when compiled at a lower API level yet running // on a more recent platform that offers the function. -extern "C" SANITIZER_WEAK_ATTRIBUTE -unsigned long getauxval(unsigned long type); // NOLINT +extern "C" SANITIZER_WEAK_ATTRIBUTE unsigned long getauxval(unsigned long type); # endif -#endif // SANITIZER_LINUX || SANITIZER_FUCHSIA +#elif SANITIZER_NETBSD + +#define SANITIZER_USE_GETAUXVAL 1 + +#include <dlfcn.h> +#include <elf.h> + +static inline decltype(AuxInfo::a_v) getauxval(decltype(AuxInfo::a_type) type) { + for (const AuxInfo *aux = (const AuxInfo *)_dlauxinfo(); + aux->a_type != AT_NULL; ++aux) { + if (type == aux->a_type) + return aux->a_v; + } + + return 0; +} + +#endif #endif // SANITIZER_GETAUXVAL_H diff --git a/lib/sanitizer_common/sanitizer_glibc_version.h b/lib/sanitizer_common/sanitizer_glibc_version.h new file mode 100644 index 000000000000..47175f20aa01 --- /dev/null +++ b/lib/sanitizer_common/sanitizer_glibc_version.h @@ -0,0 +1,26 @@ +//===-- sanitizer_glibc_version.h -----------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of Sanitizer common code. +// +//===----------------------------------------------------------------------===// + +#ifndef SANITIZER_GLIBC_VERSION_H +#define SANITIZER_GLIBC_VERSION_H + +#include "sanitizer_platform.h" + +#if SANITIZER_LINUX || SANITIZER_FUCHSIA +#include <features.h> +#endif + +#ifndef __GLIBC_PREREQ +#define __GLIBC_PREREQ(x, y) 0 +#endif + +#endif diff --git a/lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc b/lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc index f29226b3ee3a..03ef7c1788cd 100644 --- a/lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc +++ b/lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc @@ -24,7 +24,7 @@ struct ioctl_desc { const char *name; }; -const unsigned ioctl_table_max = 1200; +const unsigned ioctl_table_max = 1236; static ioctl_desc ioctl_table[ioctl_table_max]; static unsigned ioctl_table_size = 0; @@ -645,7 +645,7 @@ static void ioctl_table_fill() { _(SPKRTUNE, NONE, 0); _(SPKRGETVOL, WRITE, sizeof(unsigned int)); _(SPKRSETVOL, READ, sizeof(unsigned int)); -#if 0 /* WIP */ +#if defined(__x86_64__) /* Entries from file: dev/nvmm/nvmm_ioctl.h */ _(NVMM_IOC_CAPABILITY, WRITE, struct_nvmm_ioc_capability_sz); _(NVMM_IOC_MACHINE_CREATE, READWRITE, struct_nvmm_ioc_machine_create_sz); @@ -661,7 +661,11 @@ static void ioctl_table_fill() { _(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); + _(NVMM_IOC_CTL, READ, struct_nvmm_ioc_ctl_sz); #endif + /* Entries from file: dev/spi/spi_io.h */ + _(SPI_IOCTL_CONFIGURE, READ, struct_spi_ioctl_configure_sz); + _(SPI_IOCTL_TRANSFER, READ, struct_spi_ioctl_transfer_sz); /* Entries from file: fs/autofs/autofs_ioctl.h */ _(AUTOFSREQUEST, WRITE, struct_autofs_daemon_request_sz); _(AUTOFSDONE, READ, struct_autofs_daemon_done_sz); @@ -895,6 +899,9 @@ static void ioctl_table_fill() { _(AUDIO_GETBUFINFO, WRITE, struct_audio_info_sz); _(AUDIO_SETCHAN, READ, sizeof(int)); _(AUDIO_GETCHAN, WRITE, sizeof(int)); + _(AUDIO_QUERYFORMAT, READWRITE, struct_audio_format_query_sz); + _(AUDIO_GETFORMAT, WRITE, struct_audio_info_sz); + _(AUDIO_SETFORMAT, READ, struct_audio_info_sz); _(AUDIO_MIXER_READ, READWRITE, struct_mixer_ctrl_sz); _(AUDIO_MIXER_WRITE, READWRITE, struct_mixer_ctrl_sz); _(AUDIO_MIXER_DEVINFO, READWRITE, struct_mixer_devinfo_sz); @@ -985,6 +992,7 @@ static void ioctl_table_fill() { _(DIOCMWEDGES, WRITE, sizeof(int)); _(DIOCGSECTORSIZE, WRITE, sizeof(unsigned int)); _(DIOCGMEDIASIZE, WRITE, sizeof(uptr)); + _(DIOCRMWEDGES, WRITE, sizeof(int)); /* Entries from file: sys/drvctlio.h */ _(DRVDETACHDEV, READ, struct_devdetachargs_sz); _(DRVRESCANBUS, READ, struct_devrescanargs_sz); @@ -1206,6 +1214,8 @@ static void ioctl_table_fill() { _(SIOCGETHERCAP, READWRITE, struct_eccapreq_sz); _(SIOCGIFINDEX, READWRITE, struct_ifreq_sz); _(SIOCSETHERCAP, READ, struct_eccapreq_sz); + _(SIOCSIFDESCR, READ, struct_ifreq_sz); + _(SIOCGIFDESCR, READWRITE, struct_ifreq_sz); _(SIOCGUMBINFO, READWRITE, struct_ifreq_sz); _(SIOCSUMBPARAM, READ, struct_ifreq_sz); _(SIOCGUMBPARAM, READWRITE, struct_ifreq_sz); @@ -1335,6 +1345,21 @@ static void ioctl_table_fill() { _(WDOGIOC_TICKLE, NONE, 0); _(WDOGIOC_GTICKLER, WRITE, sizeof(int)); _(WDOGIOC_GWDOGS, READWRITE, struct_wdog_conf_sz); + /* Entries from file: sys/kcov.h */ + _(KCOV_IOC_SETBUFSIZE, READ, sizeof(u64)); + _(KCOV_IOC_ENABLE, READ, sizeof(int)); + _(KCOV_IOC_DISABLE, NONE, 0); + /* Entries from file: sys/ipmi.h */ + _(IPMICTL_RECEIVE_MSG_TRUNC, READWRITE, struct_ipmi_recv_sz); + _(IPMICTL_RECEIVE_MSG, READWRITE, struct_ipmi_recv_sz); + _(IPMICTL_SEND_COMMAND, READ, struct_ipmi_req_sz); + _(IPMICTL_REGISTER_FOR_CMD, READ, struct_ipmi_cmdspec_sz); + _(IPMICTL_UNREGISTER_FOR_CMD, READ, struct_ipmi_cmdspec_sz); + _(IPMICTL_SET_GETS_EVENTS_CMD, READ, sizeof(int)); + _(IPMICTL_SET_MY_ADDRESS_CMD, READ, sizeof(unsigned int)); + _(IPMICTL_GET_MY_ADDRESS_CMD, WRITE, sizeof(unsigned int)); + _(IPMICTL_SET_MY_LUN_CMD, READ, sizeof(unsigned int)); + _(IPMICTL_GET_MY_LUN_CMD, WRITE, sizeof(unsigned int)); /* Entries from file: soundcard.h */ _(SNDCTL_DSP_RESET, NONE, 0); _(SNDCTL_DSP_SYNC, NONE, 0); @@ -1379,7 +1404,7 @@ static void ioctl_table_fill() { _(SNDCTL_DSP_SKIP, NONE, 0); _(SNDCTL_DSP_SILENCE, NONE, 0); #undef _ -} +} // NOLINT static bool ioctl_initialized = false; diff --git a/lib/sanitizer_common/sanitizer_internal_defs.h b/lib/sanitizer_common/sanitizer_internal_defs.h index e0c6506bed51..00226305e07c 100644 --- a/lib/sanitizer_common/sanitizer_internal_defs.h +++ b/lib/sanitizer_common/sanitizer_internal_defs.h @@ -133,27 +133,27 @@ namespace __sanitizer { #if defined(_WIN64) // 64-bit Windows uses LLP64 data model. -typedef unsigned long long uptr; // NOLINT -typedef signed long long sptr; // NOLINT +typedef unsigned long long uptr; +typedef signed long long sptr; #else -typedef unsigned long uptr; // NOLINT -typedef signed long sptr; // NOLINT +typedef unsigned long uptr; +typedef signed long sptr; #endif // defined(_WIN64) #if defined(__x86_64__) // Since x32 uses ILP32 data model in 64-bit hardware mode, we must use // 64-bit pointer to unwind stack frame. -typedef unsigned long long uhwptr; // NOLINT +typedef unsigned long long uhwptr; #else -typedef uptr uhwptr; // NOLINT +typedef uptr uhwptr; #endif typedef unsigned char u8; -typedef unsigned short u16; // NOLINT +typedef unsigned short u16; typedef unsigned int u32; -typedef unsigned long long u64; // NOLINT -typedef signed char s8; -typedef signed short s16; // NOLINT -typedef signed int s32; -typedef signed long long s64; // NOLINT +typedef unsigned long long u64; +typedef signed char s8; +typedef signed short s16; +typedef signed int s32; +typedef signed long long s64; #if SANITIZER_WINDOWS // On Windows, files are HANDLE, which is a synonim of void*. // Use void* to avoid including <windows.h> everywhere. @@ -264,7 +264,7 @@ typedef ALIGNED(1) s64 us64; #if SANITIZER_WINDOWS } // namespace __sanitizer -typedef unsigned long DWORD; // NOLINT +typedef unsigned long DWORD; namespace __sanitizer { typedef DWORD thread_return_t; # define THREAD_CALLING_CONV __stdcall @@ -419,18 +419,41 @@ inline void Trap() { } // namespace __sanitizer -namespace __asan { using namespace __sanitizer; } // NOLINT -namespace __dsan { using namespace __sanitizer; } // NOLINT -namespace __dfsan { using namespace __sanitizer; } // NOLINT -namespace __lsan { using namespace __sanitizer; } // NOLINT -namespace __msan { using namespace __sanitizer; } // NOLINT -namespace __hwasan { using namespace __sanitizer; } // NOLINT -namespace __tsan { using namespace __sanitizer; } // NOLINT -namespace __scudo { using namespace __sanitizer; } // NOLINT -namespace __ubsan { using namespace __sanitizer; } // NOLINT -namespace __xray { using namespace __sanitizer; } // NOLINT -namespace __interception { using namespace __sanitizer; } // NOLINT -namespace __hwasan { using namespace __sanitizer; } // NOLINT - +namespace __asan { +using namespace __sanitizer; +} +namespace __dsan { +using namespace __sanitizer; +} +namespace __dfsan { +using namespace __sanitizer; +} +namespace __lsan { +using namespace __sanitizer; +} +namespace __msan { +using namespace __sanitizer; +} +namespace __hwasan { +using namespace __sanitizer; +} +namespace __tsan { +using namespace __sanitizer; +} +namespace __scudo { +using namespace __sanitizer; +} +namespace __ubsan { +using namespace __sanitizer; +} +namespace __xray { +using namespace __sanitizer; +} +namespace __interception { +using namespace __sanitizer; +} +namespace __hwasan { +using namespace __sanitizer; +} #endif // SANITIZER_DEFS_H diff --git a/lib/sanitizer_common/sanitizer_libc.cc b/lib/sanitizer_common/sanitizer_libc.cpp index 95c74441fd21..4bc04b486870 100644 --- a/lib/sanitizer_common/sanitizer_libc.cc +++ b/lib/sanitizer_common/sanitizer_libc.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_libc.cc -------------------------------------------------===// +//===-- sanitizer_libc.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -63,10 +63,11 @@ void *internal_memmove(void *dest, const void *src, uptr n) { for (i = 0; i < signed_n; ++i) d[i] = s[i]; } else { - if (d > s && signed_n > 0) - for (i = signed_n - 1; i >= 0 ; --i) { + if (d > s && signed_n > 0) { + for (i = signed_n - 1; i >= 0; --i) { d[i] = s[i]; } + } } return dest; } @@ -270,9 +271,9 @@ bool mem_is_zero(const char *beg, uptr size) { for (; aligned_beg < aligned_end; aligned_beg++) all |= *aligned_beg; // Epilogue. - if ((char*)aligned_end >= beg) - for (const char *mem = (char*)aligned_end; mem < end; mem++) - all |= *mem; + if ((char *)aligned_end >= beg) { + for (const char *mem = (char *)aligned_end; mem < end; mem++) all |= *mem; + } return all == 0; } diff --git a/lib/sanitizer_common/sanitizer_libignore.cc b/lib/sanitizer_common/sanitizer_libignore.cpp index 6c7c132e99eb..eb9bb765013d 100644 --- a/lib/sanitizer_common/sanitizer_libignore.cc +++ b/lib/sanitizer_common/sanitizer_libignore.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_libignore.cc --------------------------------------------===// +//===-- sanitizer_libignore.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cpp index 88ab0979bb05..0b53da6c349f 100644 --- a/lib/sanitizer_common/sanitizer_linux.cc +++ b/lib/sanitizer_common/sanitizer_linux.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_linux.cc ------------------------------------------------===// +//===-- sanitizer_linux.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -779,7 +779,11 @@ int internal_sysctl(const int *name, unsigned int namelen, void *oldp, #if SANITIZER_FREEBSD int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp, const void *newp, uptr newlen) { - return sysctlbyname(sname, oldp, (size_t *)oldlenp, newp, (size_t)newlen); + static decltype(sysctlbyname) *real = nullptr; + if (!real) + real = (decltype(sysctlbyname) *)dlsym(RTLD_NEXT, "sysctlbyname"); + CHECK(real); + return real(sname, oldp, (size_t *)oldlenp, newp, (size_t)newlen); } #endif #endif @@ -1058,8 +1062,6 @@ uptr GetMaxUserVirtualAddress() { uptr GetPageSize() { #if SANITIZER_LINUX && (defined(__x86_64__) || defined(__i386__)) return EXEC_PAGESIZE; -#elif SANITIZER_USE_GETAUXVAL - return getauxval(AT_PAGESZ); #elif SANITIZER_FREEBSD || SANITIZER_NETBSD // Use sysctl as sysconf can trigger interceptors internally. int pz = 0; @@ -1068,6 +1070,8 @@ uptr GetPageSize() { int rv = internal_sysctl(mib, 2, &pz, &pzl, nullptr, 0); CHECK_EQ(rv, 0); return (uptr)pz; +#elif SANITIZER_USE_GETAUXVAL + return getauxval(AT_PAGESZ); #else return sysconf(_SC_PAGESIZE); // EXEC_PAGESIZE may not be trustworthy. #endif @@ -1845,6 +1849,12 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { #endif } +bool SignalContext::IsTrueFaultingAddress() const { + auto si = static_cast<const siginfo_t *>(siginfo); + // SIGSEGV signals without a true fault address have si_code set to 128. + return si->si_signo == SIGSEGV && si->si_code != 128; +} + void SignalContext::DumpAllRegisters(void *context) { // FIXME: Implement this. } @@ -2007,6 +2017,35 @@ void CheckASLR() { CHECK_NE(personality(old_personality | ADDR_NO_RANDOMIZE), -1); ReExec(); } +#elif SANITIZER_FREEBSD + int aslr_pie; + uptr len = sizeof(aslr_pie); +#if SANITIZER_WORDSIZE == 64 + if (UNLIKELY(internal_sysctlbyname("kern.elf64.aslr.pie_enable", + &aslr_pie, &len, NULL, 0) == -1)) { + // We're making things less 'dramatic' here since + // the OID is not necessarily guaranteed to be here + // just yet regarding FreeBSD release + return; + } + + if (aslr_pie > 0) { + Printf("This sanitizer is not compatible with enabled ASLR " + "and binaries compiled with PIE\n"); + Die(); + } +#endif + // there might be 32 bits compat for 64 bits + if (UNLIKELY(internal_sysctlbyname("kern.elf32.aslr.pie_enable", + &aslr_pie, &len, NULL, 0) == -1)) { + return; + } + + if (aslr_pie > 0) { + Printf("This sanitizer is not compatible with enabled ASLR " + "and binaries compiled with PIE\n"); + Die(); + } #else // Do nothing #endif diff --git a/lib/sanitizer_common/sanitizer_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_linux_libcdep.cpp index 0608898a1464..cd503718205a 100644 --- a/lib/sanitizer_common/sanitizer_linux_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_linux_libcdep.cc ----------------------------------------===// +//===-- sanitizer_linux_libcdep.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -23,6 +23,7 @@ #include "sanitizer_flags.h" #include "sanitizer_freebsd.h" #include "sanitizer_getauxval.h" +#include "sanitizer_glibc_version.h" #include "sanitizer_linux.h" #include "sanitizer_placement_new.h" #include "sanitizer_procmaps.h" @@ -188,11 +189,7 @@ __attribute__((unused)) static bool GetLibcVersion(int *major, int *minor, static uptr g_tls_size; #ifdef __i386__ -# ifndef __GLIBC_PREREQ -# define CHECK_GET_TLS_STATIC_INFO_VERSION 1 -# else -# define CHECK_GET_TLS_STATIC_INFO_VERSION (!__GLIBC_PREREQ(2, 27)) -# endif +# define CHECK_GET_TLS_STATIC_INFO_VERSION (!__GLIBC_PREREQ(2, 27)) #else # define CHECK_GET_TLS_STATIC_INFO_VERSION 0 #endif diff --git a/lib/sanitizer_common/sanitizer_linux_s390.cc b/lib/sanitizer_common/sanitizer_linux_s390.cpp index b681bef35b76..41e187eaf8da 100644 --- a/lib/sanitizer_common/sanitizer_linux_s390.cc +++ b/lib/sanitizer_common/sanitizer_linux_s390.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_linux_s390.cc -------------------------------------------===// +//===-- sanitizer_linux_s390.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_mac.cc b/lib/sanitizer_common/sanitizer_mac.cpp index d9b7c4b12926..ea4bd02aa92e 100644 --- a/lib/sanitizer_common/sanitizer_mac.cc +++ b/lib/sanitizer_common/sanitizer_mac.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_mac.cc --------------------------------------------------===// +//===-- sanitizer_mac.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,6 +13,7 @@ #include "sanitizer_platform.h" #if SANITIZER_MAC #include "sanitizer_mac.h" +#include "interception/interception.h" // Use 64-bit inodes in file operations. ASan does not support OS X 10.5, so // the clients will most certainly use 64-bit ones as well. @@ -64,7 +65,9 @@ extern "C" { #include <pthread.h> #include <sched.h> #include <signal.h> +#include <spawn.h> #include <stdlib.h> +#include <sys/ioctl.h> #include <sys/mman.h> #include <sys/resource.h> #include <sys/stat.h> @@ -239,27 +242,102 @@ int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp, (size_t)newlen); } -int internal_forkpty(int *aparent) { - int parent, worker; - if (openpty(&parent, &worker, nullptr, nullptr, nullptr) == -1) return -1; - int pid = internal_fork(); - if (pid == -1) { - close(parent); - close(worker); - return -1; +static fd_t internal_spawn_impl(const char *argv[], pid_t *pid) { + fd_t master_fd = kInvalidFd; + fd_t slave_fd = kInvalidFd; + + auto fd_closer = at_scope_exit([&] { + internal_close(master_fd); + internal_close(slave_fd); + }); + + // We need a new pseudoterminal to avoid buffering problems. The 'atos' tool + // in particular detects when it's talking to a pipe and forgets to flush the + // output stream after sending a response. + master_fd = posix_openpt(O_RDWR); + if (master_fd == kInvalidFd) return kInvalidFd; + + int res = grantpt(master_fd) || unlockpt(master_fd); + if (res != 0) return kInvalidFd; + + // Use TIOCPTYGNAME instead of ptsname() to avoid threading problems. + char slave_pty_name[128]; + res = ioctl(master_fd, TIOCPTYGNAME, slave_pty_name); + if (res == -1) return kInvalidFd; + + slave_fd = internal_open(slave_pty_name, O_RDWR); + if (slave_fd == kInvalidFd) return kInvalidFd; + + // File descriptor actions + posix_spawn_file_actions_t acts; + res = posix_spawn_file_actions_init(&acts); + if (res != 0) return kInvalidFd; + + auto acts_cleanup = at_scope_exit([&] { + posix_spawn_file_actions_destroy(&acts); + }); + + res = posix_spawn_file_actions_adddup2(&acts, slave_fd, STDIN_FILENO) || + posix_spawn_file_actions_adddup2(&acts, slave_fd, STDOUT_FILENO) || + posix_spawn_file_actions_addclose(&acts, slave_fd); + if (res != 0) return kInvalidFd; + + // Spawn attributes + posix_spawnattr_t attrs; + res = posix_spawnattr_init(&attrs); + if (res != 0) return kInvalidFd; + + auto attrs_cleanup = at_scope_exit([&] { + posix_spawnattr_destroy(&attrs); + }); + + // In the spawned process, close all file descriptors that are not explicitly + // described by the file actions object. This is Darwin-specific extension. + res = posix_spawnattr_setflags(&attrs, POSIX_SPAWN_CLOEXEC_DEFAULT); + if (res != 0) return kInvalidFd; + + // posix_spawn + char **argv_casted = const_cast<char **>(argv); + char **env = GetEnviron(); + res = posix_spawn(pid, argv[0], &acts, &attrs, argv_casted, env); + if (res != 0) return kInvalidFd; + + // Disable echo in the new terminal, disable CR. + struct termios termflags; + tcgetattr(master_fd, &termflags); + termflags.c_oflag &= ~ONLCR; + termflags.c_lflag &= ~ECHO; + tcsetattr(master_fd, TCSANOW, &termflags); + + // On success, do not close master_fd on scope exit. + fd_t fd = master_fd; + master_fd = kInvalidFd; + + return fd; +} + +fd_t internal_spawn(const char *argv[], pid_t *pid) { + // The client program may close its stdin and/or stdout and/or stderr thus + // allowing open/posix_openpt to reuse file descriptors 0, 1 or 2. In this + // case the communication is broken if either the parent or the child tries to + // close or duplicate these descriptors. We temporarily reserve these + // descriptors here to prevent this. + fd_t low_fds[3]; + size_t count = 0; + + for (; count < 3; count++) { + low_fds[count] = posix_openpt(O_RDWR); + if (low_fds[count] >= STDERR_FILENO) + break; } - if (pid == 0) { - close(parent); - if (login_tty(worker) != 0) { - // We already forked, there's not much we can do. Let's quit. - Report("login_tty failed (errno %d)\n", errno); - internal__exit(1); - } - } else { - *aparent = parent; - close(worker); + + fd_t fd = internal_spawn_impl(argv, pid); + + for (; count > 0; count--) { + internal_close(low_fds[count]); } - return pid; + + return fd; } uptr internal_rename(const char *oldpath, const char *newpath) { @@ -676,6 +754,12 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { #endif } +bool SignalContext::IsTrueFaultingAddress() const { + auto si = static_cast<const siginfo_t *>(siginfo); + // "Real" SIGSEGV codes (e.g., SEGV_MAPERR, SEGV_MAPERR) are non-zero. + return si->si_signo == SIGSEGV && si->si_code != 0; +} + static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { ucontext_t *ucontext = (ucontext_t*)context; # if defined(__aarch64__) @@ -1122,7 +1206,7 @@ bool GetRandom(void *buffer, uptr length, bool blocking) { if (!buffer || !length || length > 256) return false; // arc4random never fails. - arc4random_buf(buffer, length); + REAL(arc4random_buf)(buffer, length); return true; } diff --git a/lib/sanitizer_common/sanitizer_mac_libcdep.cc b/lib/sanitizer_common/sanitizer_mac_libcdep.cpp index 93fb5b2f96c6..ac7e328946bf 100644 --- a/lib/sanitizer_common/sanitizer_mac_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_mac_libcdep.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_mac_libcdep.cc ------------------------------------------===// +//===-- sanitizer_mac_libcdep.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_malloc_mac.inc b/lib/sanitizer_common/sanitizer_malloc_mac.inc index 3f3581eeb484..11adbe5c25b4 100644 --- a/lib/sanitizer_common/sanitizer_malloc_mac.inc +++ b/lib/sanitizer_common/sanitizer_malloc_mac.inc @@ -91,6 +91,15 @@ INTERCEPTOR(malloc_zone_t *, malloc_default_zone, void) { return &sanitizer_zone; } +INTERCEPTOR(malloc_zone_t *, malloc_zone_from_ptr, const void *ptr) { + COMMON_MALLOC_ENTER(); + size_t size = sanitizer_zone.size(&sanitizer_zone, ptr); + if (size) { // Claimed by sanitizer zone? + return &sanitizer_zone; + } + return REAL(malloc_zone_from_ptr)(ptr); +} + INTERCEPTOR(malloc_zone_t *, malloc_default_purgeable_zone, void) { // FIXME: ASan should support purgeable allocations. // https://github.com/google/sanitizers/issues/139 @@ -226,7 +235,7 @@ void __sanitizer_mz_free(malloc_zone_t *zone, void *ptr) { } #define GET_ZONE_FOR_PTR(ptr) \ - malloc_zone_t *zone_ptr = malloc_zone_from_ptr(ptr); \ + malloc_zone_t *zone_ptr = WRAP(malloc_zone_from_ptr)(ptr); \ const char *zone_name = (zone_ptr == 0) ? 0 : zone_ptr->zone_name extern "C" diff --git a/lib/sanitizer_common/sanitizer_netbsd.cc b/lib/sanitizer_common/sanitizer_netbsd.cpp index 385008e4c95a..4e74f6a3b516 100644 --- a/lib/sanitizer_common/sanitizer_netbsd.cc +++ b/lib/sanitizer_common/sanitizer_netbsd.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_netbsd.cc -----------------------------------------------===// +//===-- sanitizer_netbsd.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_openbsd.cc b/lib/sanitizer_common/sanitizer_openbsd.cpp index b6e9bdfa87e5..ed2d8edeb7a2 100644 --- a/lib/sanitizer_common/sanitizer_openbsd.cc +++ b/lib/sanitizer_common/sanitizer_openbsd.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_openbsd.cc ----------------------------------------------===// +//===-- sanitizer_openbsd.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_persistent_allocator.cc b/lib/sanitizer_common/sanitizer_persistent_allocator.cpp index ddd9ae9ec64d..1ca0375b8a54 100644 --- a/lib/sanitizer_common/sanitizer_persistent_allocator.cc +++ b/lib/sanitizer_common/sanitizer_persistent_allocator.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_persistent_allocator.cc -----------------------*- C++ -*-===// +//===-- sanitizer_persistent_allocator.cpp ----------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_platform_interceptors.h b/lib/sanitizer_common/sanitizer_platform_interceptors.h index 817d24b3492f..61a6b82ef818 100644 --- a/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ b/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -13,6 +13,7 @@ #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H #define SANITIZER_PLATFORM_INTERCEPTORS_H +#include "sanitizer_glibc_version.h" #include "sanitizer_internal_defs.h" #if SANITIZER_POSIX @@ -331,10 +332,9 @@ #define SANITIZER_INTERCEPT_ETHER_HOST \ (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_ETHER_R (SI_FREEBSD || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_SHMCTL \ - (SI_NETBSD || SI_OPENBSD || SI_SOLARIS || \ - ((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && \ - SANITIZER_WORDSIZE == 64)) // NOLINT +#define SANITIZER_INTERCEPT_SHMCTL \ + (((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && SANITIZER_WORDSIZE == 64) || \ + SI_NETBSD || SI_OPENBSD || SI_SOLARIS) // NOLINT #define SANITIZER_INTERCEPT_RANDOM_R SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET SI_POSIX #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED \ @@ -489,7 +489,8 @@ SI_NOT_RTEMS) #define SANITIZER_INTERCEPT_REALLOCARRAY SI_POSIX #define SANITIZER_INTERCEPT_ALIGNED_ALLOC (!SI_MAC && SI_NOT_RTEMS) -#define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE (!SI_MAC && !SI_OPENBSD) +#define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE \ + (!SI_MAC && !SI_OPENBSD && !SI_NETBSD) #define SANITIZER_INTERCEPT_MCHECK_MPROBE SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_WCSCAT SI_POSIX #define SANITIZER_INTERCEPT_WCSDUP SI_POSIX @@ -561,9 +562,18 @@ #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_ARC4RANDOM (SI_FREEBSD || SI_NETBSD || SI_MAC) #define SANITIZER_INTERCEPT_FDEVNAME SI_FREEBSD -#define SANITIZER_INTERCEPT_GETUSERSHELL (SI_POSIX && !SI_POSIX) +#define SANITIZER_INTERCEPT_GETUSERSHELL (SI_POSIX && !SI_ANDROID) #define SANITIZER_INTERCEPT_SL_INIT (SI_FREEBSD || SI_NETBSD) +#define SANITIZER_INTERCEPT_CRYPT (SI_POSIX && !SI_ANDROID) +#define SANITIZER_INTERCEPT_CRYPT_R (SI_LINUX && !SI_ANDROID) + +#define SANITIZER_INTERCEPT_GETRANDOM \ + ((SI_LINUX && __GLIBC_PREREQ(2, 25)) || SI_FREEBSD) +#define SANITIZER_INTERCEPT___CXA_ATEXIT SI_NETBSD +#define SANITIZER_INTERCEPT_ATEXIT SI_NETBSD +#define SANITIZER_INTERCEPT_PTHREAD_ATFORK SI_NETBSD +#define SANITIZER_INTERCEPT_GETENTROPY SI_FREEBSD #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.cpp index 034848742697..2d1bb1a12da6 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cc +++ b/lib/sanitizer_common/sanitizer_platform_limits_freebsd.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_platform_limits_freebsd.cc ------------------------------===// +//===-- sanitizer_platform_limits_freebsd.cpp -----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h b/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h index 7e162a5e49d7..71cf5b9c3571 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h +++ b/lib/sanitizer_common/sanitizer_platform_limits_freebsd.h @@ -30,373 +30,373 @@ #include <sys/_types.h> namespace __sanitizer { - extern unsigned struct_utsname_sz; - extern unsigned struct_stat_sz; +extern unsigned struct_utsname_sz; +extern unsigned struct_stat_sz; #if defined(__powerpc64__) - const unsigned struct___old_kernel_stat_sz = 0; +const unsigned struct___old_kernel_stat_sz = 0; #else - const unsigned struct___old_kernel_stat_sz = 32; +const unsigned struct___old_kernel_stat_sz = 32; #endif - extern unsigned struct_rusage_sz; - extern unsigned siginfo_t_sz; - extern unsigned struct_itimerval_sz; - extern unsigned pthread_t_sz; - extern unsigned pthread_mutex_t_sz; - extern unsigned pthread_cond_t_sz; - extern unsigned pid_t_sz; - extern unsigned timeval_sz; - extern unsigned uid_t_sz; - extern unsigned gid_t_sz; - extern unsigned fpos_t_sz; - extern unsigned mbstate_t_sz; - extern unsigned struct_timezone_sz; - extern unsigned struct_tms_sz; - extern unsigned struct_itimerspec_sz; - extern unsigned struct_sigevent_sz; - extern unsigned struct_sched_param_sz; - extern unsigned struct_statfs64_sz; - extern unsigned struct_statfs_sz; - extern unsigned struct_sockaddr_sz; - extern unsigned ucontext_t_sz; - 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; - u32 aio_key_or_aio_reserved1; // Simply crazy. - u32 aio_reserved1_or_aio_key; // Luckily, we don't need these. - u16 aio_lio_opcode; - s16 aio_reqprio; - u32 aio_fildes; - u64 aio_buf; - u64 aio_nbytes; - s64 aio_offset; - u64 aio_reserved2; - u64 aio_reserved3; - }; - - struct __sanitizer_io_event { - u64 data; - u64 obj; - u64 res; - u64 res2; - }; - - const unsigned iocb_cmd_pread = 0; - const unsigned iocb_cmd_pwrite = 1; - const unsigned iocb_cmd_preadv = 7; - const unsigned iocb_cmd_pwritev = 8; - - struct __sanitizer___sysctl_args { - int *name; - int nlen; - void *oldval; - uptr *oldlenp; - void *newval; - uptr newlen; - unsigned long ___unused[4]; - }; - - struct __sanitizer_ipc_perm { - unsigned int cuid; - unsigned int cgid; - unsigned int uid; - unsigned int gid; - unsigned short mode; - unsigned short seq; - long key; - }; - - struct __sanitizer_shmid_ds { - __sanitizer_ipc_perm shm_perm; - unsigned long shm_segsz; - unsigned int shm_lpid; - unsigned int shm_cpid; - int shm_nattch; - unsigned long shm_atime; - unsigned long shm_dtime; - unsigned long shm_ctime; - }; - - extern unsigned struct_msqid_ds_sz; - extern unsigned struct_mq_attr_sz; - extern unsigned struct_timeb_sz; - extern unsigned struct_statvfs_sz; - - struct __sanitizer_iovec { - void *iov_base; - uptr iov_len; - }; - - struct __sanitizer_ifaddrs { - struct __sanitizer_ifaddrs *ifa_next; - char *ifa_name; - unsigned int ifa_flags; - void *ifa_addr; // (struct sockaddr *) - void *ifa_netmask; // (struct sockaddr *) -# undef ifa_dstaddr - void *ifa_dstaddr; // (struct sockaddr *) - void *ifa_data; - }; - - typedef unsigned __sanitizer_pthread_key_t; - - struct __sanitizer_passwd { - char *pw_name; - char *pw_passwd; - int pw_uid; - int pw_gid; - long pw_change; - char *pw_class; - char *pw_gecos; - char *pw_dir; - char *pw_shell; - long pw_expire; - int pw_fields; - }; - - struct __sanitizer_group { - char *gr_name; - char *gr_passwd; - int gr_gid; - char **gr_mem; - }; - -#if defined(__LP64___) - typedef long long __sanitizer_time_t; +extern unsigned struct_rusage_sz; +extern unsigned siginfo_t_sz; +extern unsigned struct_itimerval_sz; +extern unsigned pthread_t_sz; +extern unsigned pthread_mutex_t_sz; +extern unsigned pthread_cond_t_sz; +extern unsigned pid_t_sz; +extern unsigned timeval_sz; +extern unsigned uid_t_sz; +extern unsigned gid_t_sz; +extern unsigned fpos_t_sz; +extern unsigned mbstate_t_sz; +extern unsigned struct_timezone_sz; +extern unsigned struct_tms_sz; +extern unsigned struct_itimerspec_sz; +extern unsigned struct_sigevent_sz; +extern unsigned struct_sched_param_sz; +extern unsigned struct_statfs64_sz; +extern unsigned struct_statfs_sz; +extern unsigned struct_sockaddr_sz; +extern unsigned ucontext_t_sz; +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; + u32 aio_key_or_aio_reserved1; // Simply crazy. + u32 aio_reserved1_or_aio_key; // Luckily, we don't need these. + u16 aio_lio_opcode; + s16 aio_reqprio; + u32 aio_fildes; + u64 aio_buf; + u64 aio_nbytes; + s64 aio_offset; + u64 aio_reserved2; + u64 aio_reserved3; +}; + +struct __sanitizer_io_event { + u64 data; + u64 obj; + u64 res; + u64 res2; +}; + +const unsigned iocb_cmd_pread = 0; +const unsigned iocb_cmd_pwrite = 1; +const unsigned iocb_cmd_preadv = 7; +const unsigned iocb_cmd_pwritev = 8; + +struct __sanitizer___sysctl_args { + int *name; + int nlen; + void *oldval; + uptr *oldlenp; + void *newval; + uptr newlen; + unsigned long ___unused[4]; +}; + +struct __sanitizer_ipc_perm { + unsigned int cuid; + unsigned int cgid; + unsigned int uid; + unsigned int gid; + unsigned short mode; + unsigned short seq; + long key; +}; + +#if !defined(__i386__) +typedef long long __sanitizer_time_t; #else - typedef long __sanitizer_time_t; +typedef long __sanitizer_time_t; #endif - typedef long __sanitizer_suseconds_t; - - struct __sanitizer_timeval { - __sanitizer_time_t tv_sec; - __sanitizer_suseconds_t tv_usec; - }; - - struct __sanitizer_itimerval { - struct __sanitizer_timeval it_interval; - struct __sanitizer_timeval it_value; - }; - - struct __sanitizer_timeb { - __sanitizer_time_t time; - unsigned short millitm; - short timezone; - short dstflag; - }; - - struct __sanitizer_ether_addr { - u8 octet[6]; - }; - - struct __sanitizer_tm { - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; - int tm_wday; - int tm_yday; - int tm_isdst; - long int tm_gmtoff; - const char *tm_zone; - }; - - struct __sanitizer_msghdr { - void *msg_name; - unsigned msg_namelen; - struct __sanitizer_iovec *msg_iov; - unsigned msg_iovlen; - void *msg_control; - unsigned msg_controllen; - int msg_flags; - }; - - struct __sanitizer_cmsghdr { - unsigned cmsg_len; - int cmsg_level; - int cmsg_type; - }; - - struct __sanitizer_dirent { +struct __sanitizer_shmid_ds { + __sanitizer_ipc_perm shm_perm; + unsigned long shm_segsz; + unsigned int shm_lpid; + unsigned int shm_cpid; + int shm_nattch; + __sanitizer_time_t shm_atime; + __sanitizer_time_t shm_dtime; + __sanitizer_time_t shm_ctime; +}; + +extern unsigned struct_msqid_ds_sz; +extern unsigned struct_mq_attr_sz; +extern unsigned struct_timeb_sz; +extern unsigned struct_statvfs_sz; + +struct __sanitizer_iovec { + void *iov_base; + uptr iov_len; +}; + +struct __sanitizer_ifaddrs { + struct __sanitizer_ifaddrs *ifa_next; + char *ifa_name; + unsigned int ifa_flags; + void *ifa_addr; // (struct sockaddr *) + void *ifa_netmask; // (struct sockaddr *) +# undef ifa_dstaddr + void *ifa_dstaddr; // (struct sockaddr *) + void *ifa_data; +}; + +typedef unsigned __sanitizer_pthread_key_t; + +struct __sanitizer_passwd { + char *pw_name; + char *pw_passwd; + int pw_uid; + int pw_gid; + __sanitizer_time_t pw_change; + char *pw_class; + char *pw_gecos; + char *pw_dir; + char *pw_shell; + __sanitizer_time_t pw_expire; + int pw_fields; +}; + +struct __sanitizer_group { + char *gr_name; + char *gr_passwd; + int gr_gid; + char **gr_mem; +}; + +typedef long __sanitizer_suseconds_t; + +struct __sanitizer_timeval { + __sanitizer_time_t tv_sec; + __sanitizer_suseconds_t tv_usec; +}; + +struct __sanitizer_itimerval { + struct __sanitizer_timeval it_interval; + struct __sanitizer_timeval it_value; +}; + +struct __sanitizer_timeb { + __sanitizer_time_t time; + unsigned short millitm; + short timezone; + short dstflag; +}; + +struct __sanitizer_ether_addr { + u8 octet[6]; +}; + +struct __sanitizer_tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + long int tm_gmtoff; + const char *tm_zone; +}; + +struct __sanitizer_msghdr { + void *msg_name; + unsigned msg_namelen; + struct __sanitizer_iovec *msg_iov; + unsigned msg_iovlen; + void *msg_control; + unsigned msg_controllen; + int msg_flags; +}; + +struct __sanitizer_cmsghdr { + unsigned cmsg_len; + int cmsg_level; + int cmsg_type; +}; + +struct __sanitizer_dirent { #if defined(__INO64) - unsigned long long d_fileno; - unsigned long long d_off; + unsigned long long d_fileno; + unsigned long long d_off; #else - unsigned int d_fileno; + unsigned int d_fileno; #endif - unsigned short d_reclen; - // more fields that we don't care about - }; + unsigned short d_reclen; + // more fields that we don't care about +}; // 'clock_t' is 32 bits wide on x64 FreeBSD - typedef int __sanitizer_clock_t; - typedef int __sanitizer_clockid_t; +typedef int __sanitizer_clock_t; +typedef int __sanitizer_clockid_t; -#if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__)\ - || defined(__mips__) - typedef unsigned __sanitizer___kernel_uid_t; - typedef unsigned __sanitizer___kernel_gid_t; +#if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__) || \ + defined(__mips__) +typedef unsigned __sanitizer___kernel_uid_t; +typedef unsigned __sanitizer___kernel_gid_t; #else - typedef unsigned short __sanitizer___kernel_uid_t; - typedef unsigned short __sanitizer___kernel_gid_t; +typedef unsigned short __sanitizer___kernel_uid_t; +typedef unsigned short __sanitizer___kernel_gid_t; #endif - typedef long long __sanitizer___kernel_off_t; +typedef long long __sanitizer___kernel_off_t; #if defined(__powerpc__) || defined(__mips__) - typedef unsigned int __sanitizer___kernel_old_uid_t; - typedef unsigned int __sanitizer___kernel_old_gid_t; +typedef unsigned int __sanitizer___kernel_old_uid_t; +typedef unsigned int __sanitizer___kernel_old_gid_t; #else - typedef unsigned short __sanitizer___kernel_old_uid_t; - typedef unsigned short __sanitizer___kernel_old_gid_t; +typedef unsigned short __sanitizer___kernel_old_uid_t; +typedef unsigned short __sanitizer___kernel_old_gid_t; #endif - typedef long long __sanitizer___kernel_loff_t; - typedef struct { - unsigned long fds_bits[1024 / (8 * sizeof(long))]; - } __sanitizer___kernel_fd_set; - - // This thing depends on the platform. We are only interested in the upper - // limit. Verified with a compiler assert in .cc. - const int pthread_attr_t_max_sz = 128; - union __sanitizer_pthread_attr_t { - char size[pthread_attr_t_max_sz]; // NOLINT - void *align; - }; - - const unsigned old_sigset_t_sz = sizeof(unsigned long); - - struct __sanitizer_sigset_t { - // uint32_t * 4 - unsigned int __bits[4]; - }; - - typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t; - - struct __sanitizer_siginfo { - // The size is determined by looking at sizeof of real siginfo_t on linux. - u64 opaque[128 / sizeof(u64)]; - }; - - using __sanitizer_sighandler_ptr = void (*)(int sig); - using __sanitizer_sigactionhandler_ptr = - void (*)(int sig, __sanitizer_siginfo *siginfo, void *uctx); - - struct __sanitizer_sigaction { - union { - __sanitizer_sigactionhandler_ptr sigaction; - __sanitizer_sighandler_ptr handler; - }; - int sa_flags; - __sanitizer_sigset_t sa_mask; - }; - - struct __sanitizer_sem_t { - u32 data[4]; - }; - - extern const uptr sig_ign; - extern const uptr sig_dfl; - extern const uptr sig_err; - extern const uptr sa_siginfo; - - extern int af_inet; - extern int af_inet6; - uptr __sanitizer_in_addr_sz(int af); - - struct __sanitizer_dl_phdr_info { - uptr dlpi_addr; - const char *dlpi_name; - const void *dlpi_phdr; - short dlpi_phnum; - }; - - extern unsigned struct_ElfW_Phdr_sz; - - struct __sanitizer_addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; - unsigned ai_addrlen; - char *ai_canonname; - void *ai_addr; - struct __sanitizer_addrinfo *ai_next; - }; - - struct __sanitizer_hostent { - char *h_name; - char **h_aliases; - int h_addrtype; - int h_length; - char **h_addr_list; - }; - - struct __sanitizer_pollfd { - int fd; - short events; - short revents; - }; - - typedef unsigned __sanitizer_nfds_t; - - struct __sanitizer_glob_t { - uptr gl_pathc; - uptr gl_matchc; - uptr gl_offs; - int gl_flags; - char **gl_pathv; - int (*gl_errfunc)(const char*, int); - void (*gl_closedir)(void *dirp); - struct dirent *(*gl_readdir)(void *dirp); - void *(*gl_opendir)(const char*); - int (*gl_lstat)(const char*, void* /* struct stat* */); - int (*gl_stat)(const char*, void* /* struct stat* */); - }; - - extern int glob_nomatch; - extern int glob_altdirfunc; - - extern unsigned path_max; - - struct __sanitizer_wordexp_t { - uptr we_wordc; - char **we_wordv; - uptr we_offs; - char *we_strings; - uptr we_nbytes; - }; - - typedef void __sanitizer_FILE; - - extern unsigned struct_shminfo_sz; - extern unsigned struct_shm_info_sz; - extern int shmctl_ipc_stat; - extern int shmctl_ipc_info; - extern int shmctl_shm_info; - extern int shmctl_shm_stat; - - extern unsigned struct_utmpx_sz; - - extern int map_fixed; - - // ioctl arguments - struct __sanitizer_ifconf { - int ifc_len; - union { - void *ifcu_req; - } ifc_ifcu; +typedef long long __sanitizer___kernel_loff_t; +typedef struct { + unsigned long fds_bits[1024 / (8 * sizeof(long))]; +} __sanitizer___kernel_fd_set; + +// This thing depends on the platform. We are only interested in the upper +// limit. Verified with a compiler assert in .cpp. +union __sanitizer_pthread_attr_t { + char size[128]; + void *align; +}; + +const unsigned old_sigset_t_sz = sizeof(unsigned long); + +struct __sanitizer_sigset_t { + // uint32_t * 4 + unsigned int __bits[4]; +}; + +typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t; + +struct __sanitizer_siginfo { + // The size is determined by looking at sizeof of real siginfo_t on linux. + u64 opaque[128 / sizeof(u64)]; +}; + +using __sanitizer_sighandler_ptr = void (*)(int sig); +using __sanitizer_sigactionhandler_ptr = void (*)(int sig, + __sanitizer_siginfo *siginfo, + void *uctx); + +struct __sanitizer_sigaction { + union { + __sanitizer_sigactionhandler_ptr sigaction; + __sanitizer_sighandler_ptr handler; }; + int sa_flags; + __sanitizer_sigset_t sa_mask; +}; + +struct __sanitizer_sem_t { + u32 data[4]; +}; + +extern const uptr sig_ign; +extern const uptr sig_dfl; +extern const uptr sig_err; +extern const uptr sa_siginfo; + +extern int af_inet; +extern int af_inet6; +uptr __sanitizer_in_addr_sz(int af); + +struct __sanitizer_dl_phdr_info { + uptr dlpi_addr; + const char *dlpi_name; + const void *dlpi_phdr; + short dlpi_phnum; +}; + +extern unsigned struct_ElfW_Phdr_sz; + +struct __sanitizer_addrinfo { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + unsigned ai_addrlen; + char *ai_canonname; + void *ai_addr; + struct __sanitizer_addrinfo *ai_next; +}; + +struct __sanitizer_hostent { + char *h_name; + char **h_aliases; + int h_addrtype; + int h_length; + char **h_addr_list; +}; + +struct __sanitizer_pollfd { + int fd; + short events; + short revents; +}; + +typedef unsigned __sanitizer_nfds_t; + +struct __sanitizer_glob_t { + uptr gl_pathc; + uptr gl_matchc; + uptr gl_offs; + int gl_flags; + char **gl_pathv; + int (*gl_errfunc)(const char *, int); + void (*gl_closedir)(void *dirp); + struct dirent *(*gl_readdir)(void *dirp); + void *(*gl_opendir)(const char *); + int (*gl_lstat)(const char *, void * /* struct stat* */); + int (*gl_stat)(const char *, void * /* struct stat* */); +}; + +extern int glob_nomatch; +extern int glob_altdirfunc; + +extern unsigned path_max; + +struct __sanitizer_wordexp_t { + uptr we_wordc; + char **we_wordv; + uptr we_offs; + char *we_strings; + uptr we_nbytes; +}; + +typedef void __sanitizer_FILE; + +extern unsigned struct_shminfo_sz; +extern unsigned struct_shm_info_sz; +extern int shmctl_ipc_stat; +extern int shmctl_ipc_info; +extern int shmctl_shm_info; +extern int shmctl_shm_stat; + +extern unsigned struct_utmpx_sz; + +extern int map_fixed; + +// ioctl arguments +struct __sanitizer_ifconf { + int ifc_len; + union { + void *ifcu_req; + } ifc_ifcu; +}; #define IOC_NRBITS 8 #define IOC_TYPEBITS 8 @@ -432,204 +432,204 @@ namespace __sanitizer { #define IOC_NR(nr) (((nr) >> IOC_NRSHIFT) & IOC_NRMASK) #define IOC_SIZE(nr) (((nr) >> IOC_SIZESHIFT) & IOC_SIZEMASK) - extern unsigned struct_ifreq_sz; - extern unsigned struct_termios_sz; - extern unsigned struct_winsize_sz; - - extern unsigned struct_copr_buffer_sz; - extern unsigned struct_copr_debug_buf_sz; - extern unsigned struct_copr_msg_sz; - extern unsigned struct_midi_info_sz; - extern unsigned struct_mtget_sz; - extern unsigned struct_mtop_sz; - extern unsigned struct_rtentry_sz; - extern unsigned struct_sbi_instrument_sz; - extern unsigned struct_seq_event_rec_sz; - extern unsigned struct_synth_info_sz; - extern unsigned struct_vt_mode_sz; - - extern const unsigned long __sanitizer_bufsiz; - extern unsigned struct_audio_buf_info_sz; - extern unsigned struct_ppp_stats_sz; - extern unsigned struct_sioc_sg_req_sz; - extern unsigned struct_sioc_vif_req_sz; - - // ioctl request identifiers - - // A special value to mark ioctls that are not present on the target platform, - // when it can not be determined without including any system headers. - extern const unsigned IOCTL_NOT_PRESENT; - - extern unsigned IOCTL_FIOASYNC; - extern unsigned IOCTL_FIOCLEX; - extern unsigned IOCTL_FIOGETOWN; - extern unsigned IOCTL_FIONBIO; - extern unsigned IOCTL_FIONCLEX; - extern unsigned IOCTL_FIOSETOWN; - extern unsigned IOCTL_SIOCADDMULTI; - extern unsigned IOCTL_SIOCATMARK; - extern unsigned IOCTL_SIOCDELMULTI; - extern unsigned IOCTL_SIOCGIFADDR; - extern unsigned IOCTL_SIOCGIFBRDADDR; - extern unsigned IOCTL_SIOCGIFCONF; - extern unsigned IOCTL_SIOCGIFDSTADDR; - extern unsigned IOCTL_SIOCGIFFLAGS; - extern unsigned IOCTL_SIOCGIFMETRIC; - extern unsigned IOCTL_SIOCGIFMTU; - extern unsigned IOCTL_SIOCGIFNETMASK; - extern unsigned IOCTL_SIOCGPGRP; - extern unsigned IOCTL_SIOCSIFADDR; - extern unsigned IOCTL_SIOCSIFBRDADDR; - extern unsigned IOCTL_SIOCSIFDSTADDR; - extern unsigned IOCTL_SIOCSIFFLAGS; - extern unsigned IOCTL_SIOCSIFMETRIC; - extern unsigned IOCTL_SIOCSIFMTU; - extern unsigned IOCTL_SIOCSIFNETMASK; - extern unsigned IOCTL_SIOCSPGRP; - extern unsigned IOCTL_TIOCCONS; - extern unsigned IOCTL_TIOCEXCL; - extern unsigned IOCTL_TIOCGETD; - extern unsigned IOCTL_TIOCGPGRP; - extern unsigned IOCTL_TIOCGWINSZ; - extern unsigned IOCTL_TIOCMBIC; - extern unsigned IOCTL_TIOCMBIS; - extern unsigned IOCTL_TIOCMGET; - extern unsigned IOCTL_TIOCMSET; - extern unsigned IOCTL_TIOCNOTTY; - extern unsigned IOCTL_TIOCNXCL; - extern unsigned IOCTL_TIOCOUTQ; - extern unsigned IOCTL_TIOCPKT; - extern unsigned IOCTL_TIOCSCTTY; - extern unsigned IOCTL_TIOCSETD; - extern unsigned IOCTL_TIOCSPGRP; - extern unsigned IOCTL_TIOCSTI; - extern unsigned IOCTL_TIOCSWINSZ; - extern unsigned IOCTL_SIOCGETSGCNT; - extern unsigned IOCTL_SIOCGETVIFCNT; - extern unsigned IOCTL_MTIOCGET; - extern unsigned IOCTL_MTIOCTOP; - extern unsigned IOCTL_SIOCADDRT; - extern unsigned IOCTL_SIOCDELRT; - extern unsigned IOCTL_SNDCTL_DSP_GETBLKSIZE; - extern unsigned IOCTL_SNDCTL_DSP_GETFMTS; - extern unsigned IOCTL_SNDCTL_DSP_NONBLOCK; - extern unsigned IOCTL_SNDCTL_DSP_POST; - extern unsigned IOCTL_SNDCTL_DSP_RESET; - extern unsigned IOCTL_SNDCTL_DSP_SETFMT; - extern unsigned IOCTL_SNDCTL_DSP_SETFRAGMENT; - extern unsigned IOCTL_SNDCTL_DSP_SPEED; - extern unsigned IOCTL_SNDCTL_DSP_STEREO; - extern unsigned IOCTL_SNDCTL_DSP_SUBDIVIDE; - extern unsigned IOCTL_SNDCTL_DSP_SYNC; - extern unsigned IOCTL_SNDCTL_FM_4OP_ENABLE; - extern unsigned IOCTL_SNDCTL_FM_LOAD_INSTR; - extern unsigned IOCTL_SNDCTL_MIDI_INFO; - extern unsigned IOCTL_SNDCTL_MIDI_PRETIME; - extern unsigned IOCTL_SNDCTL_SEQ_CTRLRATE; - extern unsigned IOCTL_SNDCTL_SEQ_GETINCOUNT; - extern unsigned IOCTL_SNDCTL_SEQ_GETOUTCOUNT; - extern unsigned IOCTL_SNDCTL_SEQ_NRMIDIS; - extern unsigned IOCTL_SNDCTL_SEQ_NRSYNTHS; - extern unsigned IOCTL_SNDCTL_SEQ_OUTOFBAND; - extern unsigned IOCTL_SNDCTL_SEQ_PANIC; - extern unsigned IOCTL_SNDCTL_SEQ_PERCMODE; - extern unsigned IOCTL_SNDCTL_SEQ_RESET; - extern unsigned IOCTL_SNDCTL_SEQ_RESETSAMPLES; - extern unsigned IOCTL_SNDCTL_SEQ_SYNC; - extern unsigned IOCTL_SNDCTL_SEQ_TESTMIDI; - extern unsigned IOCTL_SNDCTL_SEQ_THRESHOLD; - extern unsigned IOCTL_SNDCTL_SYNTH_INFO; - extern unsigned IOCTL_SNDCTL_SYNTH_MEMAVL; - extern unsigned IOCTL_SNDCTL_TMR_CONTINUE; - extern unsigned IOCTL_SNDCTL_TMR_METRONOME; - extern unsigned IOCTL_SNDCTL_TMR_SELECT; - extern unsigned IOCTL_SNDCTL_TMR_SOURCE; - extern unsigned IOCTL_SNDCTL_TMR_START; - extern unsigned IOCTL_SNDCTL_TMR_STOP; - extern unsigned IOCTL_SNDCTL_TMR_TEMPO; - extern unsigned IOCTL_SNDCTL_TMR_TIMEBASE; - extern unsigned IOCTL_SOUND_MIXER_READ_ALTPCM; - extern unsigned IOCTL_SOUND_MIXER_READ_BASS; - extern unsigned IOCTL_SOUND_MIXER_READ_CAPS; - extern unsigned IOCTL_SOUND_MIXER_READ_CD; - extern unsigned IOCTL_SOUND_MIXER_READ_DEVMASK; - extern unsigned IOCTL_SOUND_MIXER_READ_ENHANCE; - extern unsigned IOCTL_SOUND_MIXER_READ_IGAIN; - extern unsigned IOCTL_SOUND_MIXER_READ_IMIX; - extern unsigned IOCTL_SOUND_MIXER_READ_LINE1; - extern unsigned IOCTL_SOUND_MIXER_READ_LINE2; - extern unsigned IOCTL_SOUND_MIXER_READ_LINE3; - extern unsigned IOCTL_SOUND_MIXER_READ_LINE; - extern unsigned IOCTL_SOUND_MIXER_READ_LOUD; - extern unsigned IOCTL_SOUND_MIXER_READ_MIC; - extern unsigned IOCTL_SOUND_MIXER_READ_MUTE; - extern unsigned IOCTL_SOUND_MIXER_READ_OGAIN; - extern unsigned IOCTL_SOUND_MIXER_READ_PCM; - extern unsigned IOCTL_SOUND_MIXER_READ_RECLEV; - extern unsigned IOCTL_SOUND_MIXER_READ_RECMASK; - extern unsigned IOCTL_SOUND_MIXER_READ_RECSRC; - extern unsigned IOCTL_SOUND_MIXER_READ_SPEAKER; - extern unsigned IOCTL_SOUND_MIXER_READ_STEREODEVS; - extern unsigned IOCTL_SOUND_MIXER_READ_SYNTH; - extern unsigned IOCTL_SOUND_MIXER_READ_TREBLE; - extern unsigned IOCTL_SOUND_MIXER_READ_VOLUME; - extern unsigned IOCTL_SOUND_MIXER_WRITE_ALTPCM; - extern unsigned IOCTL_SOUND_MIXER_WRITE_BASS; - extern unsigned IOCTL_SOUND_MIXER_WRITE_CD; - extern unsigned IOCTL_SOUND_MIXER_WRITE_ENHANCE; - extern unsigned IOCTL_SOUND_MIXER_WRITE_IGAIN; - extern unsigned IOCTL_SOUND_MIXER_WRITE_IMIX; - extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE1; - extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE2; - extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE3; - extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE; - extern unsigned IOCTL_SOUND_MIXER_WRITE_LOUD; - extern unsigned IOCTL_SOUND_MIXER_WRITE_MIC; - extern unsigned IOCTL_SOUND_MIXER_WRITE_MUTE; - extern unsigned IOCTL_SOUND_MIXER_WRITE_OGAIN; - extern unsigned IOCTL_SOUND_MIXER_WRITE_PCM; - extern unsigned IOCTL_SOUND_MIXER_WRITE_RECLEV; - extern unsigned IOCTL_SOUND_MIXER_WRITE_RECSRC; - extern unsigned IOCTL_SOUND_MIXER_WRITE_SPEAKER; - extern unsigned IOCTL_SOUND_MIXER_WRITE_SYNTH; - extern unsigned IOCTL_SOUND_MIXER_WRITE_TREBLE; - extern unsigned IOCTL_SOUND_MIXER_WRITE_VOLUME; - extern unsigned IOCTL_SOUND_PCM_READ_BITS; - extern unsigned IOCTL_SOUND_PCM_READ_CHANNELS; - extern unsigned IOCTL_SOUND_PCM_READ_FILTER; - extern unsigned IOCTL_SOUND_PCM_READ_RATE; - extern unsigned IOCTL_SOUND_PCM_WRITE_CHANNELS; - extern unsigned IOCTL_SOUND_PCM_WRITE_FILTER; - extern unsigned IOCTL_VT_ACTIVATE; - extern unsigned IOCTL_VT_GETMODE; - extern unsigned IOCTL_VT_OPENQRY; - extern unsigned IOCTL_VT_RELDISP; - extern unsigned IOCTL_VT_SETMODE; - extern unsigned IOCTL_VT_WAITACTIVE; - extern unsigned IOCTL_GIO_SCRNMAP; - extern unsigned IOCTL_KDDISABIO; - extern unsigned IOCTL_KDENABIO; - extern unsigned IOCTL_KDGETLED; - extern unsigned IOCTL_KDGETMODE; - extern unsigned IOCTL_KDGKBMODE; - extern unsigned IOCTL_KDGKBTYPE; - extern unsigned IOCTL_KDMKTONE; - extern unsigned IOCTL_KDSETLED; - extern unsigned IOCTL_KDSETMODE; - extern unsigned IOCTL_KDSKBMODE; - - extern const int si_SEGV_MAPERR; - extern const int si_SEGV_ACCERR; - - struct __sanitizer_cap_rights { - u64 cr_rights[2]; - }; - - 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; +extern unsigned struct_ifreq_sz; +extern unsigned struct_termios_sz; +extern unsigned struct_winsize_sz; + +extern unsigned struct_copr_buffer_sz; +extern unsigned struct_copr_debug_buf_sz; +extern unsigned struct_copr_msg_sz; +extern unsigned struct_midi_info_sz; +extern unsigned struct_mtget_sz; +extern unsigned struct_mtop_sz; +extern unsigned struct_rtentry_sz; +extern unsigned struct_sbi_instrument_sz; +extern unsigned struct_seq_event_rec_sz; +extern unsigned struct_synth_info_sz; +extern unsigned struct_vt_mode_sz; + +extern const unsigned long __sanitizer_bufsiz; +extern unsigned struct_audio_buf_info_sz; +extern unsigned struct_ppp_stats_sz; +extern unsigned struct_sioc_sg_req_sz; +extern unsigned struct_sioc_vif_req_sz; + +// ioctl request identifiers + +// A special value to mark ioctls that are not present on the target platform, +// when it can not be determined without including any system headers. +extern const unsigned IOCTL_NOT_PRESENT; + +extern unsigned IOCTL_FIOASYNC; +extern unsigned IOCTL_FIOCLEX; +extern unsigned IOCTL_FIOGETOWN; +extern unsigned IOCTL_FIONBIO; +extern unsigned IOCTL_FIONCLEX; +extern unsigned IOCTL_FIOSETOWN; +extern unsigned IOCTL_SIOCADDMULTI; +extern unsigned IOCTL_SIOCATMARK; +extern unsigned IOCTL_SIOCDELMULTI; +extern unsigned IOCTL_SIOCGIFADDR; +extern unsigned IOCTL_SIOCGIFBRDADDR; +extern unsigned IOCTL_SIOCGIFCONF; +extern unsigned IOCTL_SIOCGIFDSTADDR; +extern unsigned IOCTL_SIOCGIFFLAGS; +extern unsigned IOCTL_SIOCGIFMETRIC; +extern unsigned IOCTL_SIOCGIFMTU; +extern unsigned IOCTL_SIOCGIFNETMASK; +extern unsigned IOCTL_SIOCGPGRP; +extern unsigned IOCTL_SIOCSIFADDR; +extern unsigned IOCTL_SIOCSIFBRDADDR; +extern unsigned IOCTL_SIOCSIFDSTADDR; +extern unsigned IOCTL_SIOCSIFFLAGS; +extern unsigned IOCTL_SIOCSIFMETRIC; +extern unsigned IOCTL_SIOCSIFMTU; +extern unsigned IOCTL_SIOCSIFNETMASK; +extern unsigned IOCTL_SIOCSPGRP; +extern unsigned IOCTL_TIOCCONS; +extern unsigned IOCTL_TIOCEXCL; +extern unsigned IOCTL_TIOCGETD; +extern unsigned IOCTL_TIOCGPGRP; +extern unsigned IOCTL_TIOCGWINSZ; +extern unsigned IOCTL_TIOCMBIC; +extern unsigned IOCTL_TIOCMBIS; +extern unsigned IOCTL_TIOCMGET; +extern unsigned IOCTL_TIOCMSET; +extern unsigned IOCTL_TIOCNOTTY; +extern unsigned IOCTL_TIOCNXCL; +extern unsigned IOCTL_TIOCOUTQ; +extern unsigned IOCTL_TIOCPKT; +extern unsigned IOCTL_TIOCSCTTY; +extern unsigned IOCTL_TIOCSETD; +extern unsigned IOCTL_TIOCSPGRP; +extern unsigned IOCTL_TIOCSTI; +extern unsigned IOCTL_TIOCSWINSZ; +extern unsigned IOCTL_SIOCGETSGCNT; +extern unsigned IOCTL_SIOCGETVIFCNT; +extern unsigned IOCTL_MTIOCGET; +extern unsigned IOCTL_MTIOCTOP; +extern unsigned IOCTL_SIOCADDRT; +extern unsigned IOCTL_SIOCDELRT; +extern unsigned IOCTL_SNDCTL_DSP_GETBLKSIZE; +extern unsigned IOCTL_SNDCTL_DSP_GETFMTS; +extern unsigned IOCTL_SNDCTL_DSP_NONBLOCK; +extern unsigned IOCTL_SNDCTL_DSP_POST; +extern unsigned IOCTL_SNDCTL_DSP_RESET; +extern unsigned IOCTL_SNDCTL_DSP_SETFMT; +extern unsigned IOCTL_SNDCTL_DSP_SETFRAGMENT; +extern unsigned IOCTL_SNDCTL_DSP_SPEED; +extern unsigned IOCTL_SNDCTL_DSP_STEREO; +extern unsigned IOCTL_SNDCTL_DSP_SUBDIVIDE; +extern unsigned IOCTL_SNDCTL_DSP_SYNC; +extern unsigned IOCTL_SNDCTL_FM_4OP_ENABLE; +extern unsigned IOCTL_SNDCTL_FM_LOAD_INSTR; +extern unsigned IOCTL_SNDCTL_MIDI_INFO; +extern unsigned IOCTL_SNDCTL_MIDI_PRETIME; +extern unsigned IOCTL_SNDCTL_SEQ_CTRLRATE; +extern unsigned IOCTL_SNDCTL_SEQ_GETINCOUNT; +extern unsigned IOCTL_SNDCTL_SEQ_GETOUTCOUNT; +extern unsigned IOCTL_SNDCTL_SEQ_NRMIDIS; +extern unsigned IOCTL_SNDCTL_SEQ_NRSYNTHS; +extern unsigned IOCTL_SNDCTL_SEQ_OUTOFBAND; +extern unsigned IOCTL_SNDCTL_SEQ_PANIC; +extern unsigned IOCTL_SNDCTL_SEQ_PERCMODE; +extern unsigned IOCTL_SNDCTL_SEQ_RESET; +extern unsigned IOCTL_SNDCTL_SEQ_RESETSAMPLES; +extern unsigned IOCTL_SNDCTL_SEQ_SYNC; +extern unsigned IOCTL_SNDCTL_SEQ_TESTMIDI; +extern unsigned IOCTL_SNDCTL_SEQ_THRESHOLD; +extern unsigned IOCTL_SNDCTL_SYNTH_INFO; +extern unsigned IOCTL_SNDCTL_SYNTH_MEMAVL; +extern unsigned IOCTL_SNDCTL_TMR_CONTINUE; +extern unsigned IOCTL_SNDCTL_TMR_METRONOME; +extern unsigned IOCTL_SNDCTL_TMR_SELECT; +extern unsigned IOCTL_SNDCTL_TMR_SOURCE; +extern unsigned IOCTL_SNDCTL_TMR_START; +extern unsigned IOCTL_SNDCTL_TMR_STOP; +extern unsigned IOCTL_SNDCTL_TMR_TEMPO; +extern unsigned IOCTL_SNDCTL_TMR_TIMEBASE; +extern unsigned IOCTL_SOUND_MIXER_READ_ALTPCM; +extern unsigned IOCTL_SOUND_MIXER_READ_BASS; +extern unsigned IOCTL_SOUND_MIXER_READ_CAPS; +extern unsigned IOCTL_SOUND_MIXER_READ_CD; +extern unsigned IOCTL_SOUND_MIXER_READ_DEVMASK; +extern unsigned IOCTL_SOUND_MIXER_READ_ENHANCE; +extern unsigned IOCTL_SOUND_MIXER_READ_IGAIN; +extern unsigned IOCTL_SOUND_MIXER_READ_IMIX; +extern unsigned IOCTL_SOUND_MIXER_READ_LINE1; +extern unsigned IOCTL_SOUND_MIXER_READ_LINE2; +extern unsigned IOCTL_SOUND_MIXER_READ_LINE3; +extern unsigned IOCTL_SOUND_MIXER_READ_LINE; +extern unsigned IOCTL_SOUND_MIXER_READ_LOUD; +extern unsigned IOCTL_SOUND_MIXER_READ_MIC; +extern unsigned IOCTL_SOUND_MIXER_READ_MUTE; +extern unsigned IOCTL_SOUND_MIXER_READ_OGAIN; +extern unsigned IOCTL_SOUND_MIXER_READ_PCM; +extern unsigned IOCTL_SOUND_MIXER_READ_RECLEV; +extern unsigned IOCTL_SOUND_MIXER_READ_RECMASK; +extern unsigned IOCTL_SOUND_MIXER_READ_RECSRC; +extern unsigned IOCTL_SOUND_MIXER_READ_SPEAKER; +extern unsigned IOCTL_SOUND_MIXER_READ_STEREODEVS; +extern unsigned IOCTL_SOUND_MIXER_READ_SYNTH; +extern unsigned IOCTL_SOUND_MIXER_READ_TREBLE; +extern unsigned IOCTL_SOUND_MIXER_READ_VOLUME; +extern unsigned IOCTL_SOUND_MIXER_WRITE_ALTPCM; +extern unsigned IOCTL_SOUND_MIXER_WRITE_BASS; +extern unsigned IOCTL_SOUND_MIXER_WRITE_CD; +extern unsigned IOCTL_SOUND_MIXER_WRITE_ENHANCE; +extern unsigned IOCTL_SOUND_MIXER_WRITE_IGAIN; +extern unsigned IOCTL_SOUND_MIXER_WRITE_IMIX; +extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE1; +extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE2; +extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE3; +extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE; +extern unsigned IOCTL_SOUND_MIXER_WRITE_LOUD; +extern unsigned IOCTL_SOUND_MIXER_WRITE_MIC; +extern unsigned IOCTL_SOUND_MIXER_WRITE_MUTE; +extern unsigned IOCTL_SOUND_MIXER_WRITE_OGAIN; +extern unsigned IOCTL_SOUND_MIXER_WRITE_PCM; +extern unsigned IOCTL_SOUND_MIXER_WRITE_RECLEV; +extern unsigned IOCTL_SOUND_MIXER_WRITE_RECSRC; +extern unsigned IOCTL_SOUND_MIXER_WRITE_SPEAKER; +extern unsigned IOCTL_SOUND_MIXER_WRITE_SYNTH; +extern unsigned IOCTL_SOUND_MIXER_WRITE_TREBLE; +extern unsigned IOCTL_SOUND_MIXER_WRITE_VOLUME; +extern unsigned IOCTL_SOUND_PCM_READ_BITS; +extern unsigned IOCTL_SOUND_PCM_READ_CHANNELS; +extern unsigned IOCTL_SOUND_PCM_READ_FILTER; +extern unsigned IOCTL_SOUND_PCM_READ_RATE; +extern unsigned IOCTL_SOUND_PCM_WRITE_CHANNELS; +extern unsigned IOCTL_SOUND_PCM_WRITE_FILTER; +extern unsigned IOCTL_VT_ACTIVATE; +extern unsigned IOCTL_VT_GETMODE; +extern unsigned IOCTL_VT_OPENQRY; +extern unsigned IOCTL_VT_RELDISP; +extern unsigned IOCTL_VT_SETMODE; +extern unsigned IOCTL_VT_WAITACTIVE; +extern unsigned IOCTL_GIO_SCRNMAP; +extern unsigned IOCTL_KDDISABIO; +extern unsigned IOCTL_KDENABIO; +extern unsigned IOCTL_KDGETLED; +extern unsigned IOCTL_KDGETMODE; +extern unsigned IOCTL_KDGKBMODE; +extern unsigned IOCTL_KDGKBTYPE; +extern unsigned IOCTL_KDMKTONE; +extern unsigned IOCTL_KDSETLED; +extern unsigned IOCTL_KDSETMODE; +extern unsigned IOCTL_KDSKBMODE; + +extern const int si_SEGV_MAPERR; +extern const int si_SEGV_ACCERR; + +struct __sanitizer_cap_rights { + u64 cr_rights[2]; +}; + +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_linux.cc b/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp index 14b0821cb819..842bc789f479 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_linux.cc +++ b/lib/sanitizer_common/sanitizer_platform_limits_linux.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_platform_limits_linux.cc --------------------------------===// +//===-- sanitizer_platform_limits_linux.cpp -------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -13,7 +13,7 @@ // This is a separate compilation unit for linux headers that conflict with // userspace headers. -// Most "normal" includes go in sanitizer_platform_limits_posix.cc +// Most "normal" includes go in sanitizer_platform_limits_posix.cpp #include "sanitizer_platform.h" #if SANITIZER_LINUX diff --git a/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc b/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp index b2fb5cb76463..f01de6c995e6 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cc +++ b/lib/sanitizer_common/sanitizer_platform_limits_netbsd.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_platform_limits_netbsd.cc -------------------------------===// +//===-- sanitizer_platform_limits_netbsd.cpp ------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -62,6 +62,8 @@ #include <sys/event.h> #include <sys/filio.h> #include <sys/ipc.h> +#include <sys/ipmi.h> +#include <sys/kcov.h> #include <sys/mman.h> #include <sys/module.h> #include <sys/mount.h> @@ -123,9 +125,6 @@ #include <dev/isa/isvio.h> #include <dev/isa/wtreg.h> #include <dev/iscsi/iscsi_ioctl.h> -#if 0 -#include <dev/nvmm/nvmm_ioctl.h> -#endif #include <dev/ofw/openfirmio.h> #include <dev/pci/amrio.h> #include <dev/pci/mlyreg.h> @@ -168,6 +167,7 @@ #include <dev/raidframe/raidframeio.h> #include <dev/sbus/mbppio.h> #include <dev/scsipi/ses.h> +#include <dev/spi/spi_io.h> #include <dev/spkrio.h> #include <dev/sun/disklabel.h> #include <dev/sun/fbio.h> @@ -221,6 +221,10 @@ #include <regex.h> #include <fstab.h> #include <stringlist.h> + +#if defined(__x86_64__) +#include <nvmm.h> +#endif // clang-format on // Include these after system headers to avoid name clashes and ambiguities. @@ -686,6 +690,26 @@ unsigned struct_usb_config_desc_sz = sizeof(usb_config_desc); unsigned struct_usb_ctl_report_desc_sz = sizeof(usb_ctl_report_desc); unsigned struct_usb_ctl_report_sz = sizeof(usb_ctl_report); unsigned struct_usb_ctl_request_sz = sizeof(usb_ctl_request); +#if defined(__x86_64__) +unsigned struct_nvmm_ioc_capability_sz = sizeof(nvmm_ioc_capability); +unsigned struct_nvmm_ioc_machine_create_sz = sizeof(nvmm_ioc_machine_create); +unsigned struct_nvmm_ioc_machine_destroy_sz = sizeof(nvmm_ioc_machine_destroy); +unsigned struct_nvmm_ioc_machine_configure_sz = + sizeof(nvmm_ioc_machine_configure); +unsigned struct_nvmm_ioc_vcpu_create_sz = sizeof(nvmm_ioc_vcpu_create); +unsigned struct_nvmm_ioc_vcpu_destroy_sz = sizeof(nvmm_ioc_vcpu_destroy); +unsigned struct_nvmm_ioc_vcpu_setstate_sz = sizeof(nvmm_ioc_vcpu_destroy); +unsigned struct_nvmm_ioc_vcpu_getstate_sz = sizeof(nvmm_ioc_vcpu_getstate); +unsigned struct_nvmm_ioc_vcpu_inject_sz = sizeof(nvmm_ioc_vcpu_inject); +unsigned struct_nvmm_ioc_vcpu_run_sz = sizeof(nvmm_ioc_vcpu_run); +unsigned struct_nvmm_ioc_gpa_map_sz = sizeof(nvmm_ioc_gpa_map); +unsigned struct_nvmm_ioc_gpa_unmap_sz = sizeof(nvmm_ioc_gpa_unmap); +unsigned struct_nvmm_ioc_hva_map_sz = sizeof(nvmm_ioc_hva_map); +unsigned struct_nvmm_ioc_hva_unmap_sz = sizeof(nvmm_ioc_hva_unmap); +unsigned struct_nvmm_ioc_ctl_sz = sizeof(nvmm_ioc_ctl); +#endif +unsigned struct_spi_ioctl_configure_sz = sizeof(spi_ioctl_configure); +unsigned struct_spi_ioctl_transfer_sz = sizeof(spi_ioctl_transfer); unsigned struct_autofs_daemon_request_sz = sizeof(autofs_daemon_request); unsigned struct_autofs_daemon_done_sz = sizeof(autofs_daemon_done); unsigned struct_sctp_connectx_addrs_sz = sizeof(sctp_connectx_addrs); @@ -728,6 +752,9 @@ unsigned struct_vnd_user_sz = sizeof(vnd_user); unsigned struct_vt_stat_sz = sizeof(vt_stat); unsigned struct_wdog_conf_sz = sizeof(wdog_conf); unsigned struct_wdog_mode_sz = sizeof(wdog_mode); +unsigned struct_ipmi_recv_sz = sizeof(ipmi_recv); +unsigned struct_ipmi_req_sz = sizeof(ipmi_req); +unsigned struct_ipmi_cmdspec_sz = sizeof(ipmi_cmdspec); unsigned struct_wfq_conf_sz = sizeof(wfq_conf); unsigned struct_wfq_getqid_sz = sizeof(wfq_getqid); unsigned struct_wfq_getstats_sz = sizeof(wfq_getstats); @@ -813,6 +840,7 @@ unsigned struct_iscsi_wait_event_parameters_sz = unsigned struct_isp_stats_sz = sizeof(isp_stats_t); unsigned struct_lsenable_sz = sizeof(struct lsenable); unsigned struct_lsdisable_sz = sizeof(struct lsdisable); +unsigned struct_audio_format_query_sz = sizeof(audio_format_query); unsigned struct_mixer_ctrl_sz = sizeof(struct mixer_ctrl); unsigned struct_mixer_devinfo_sz = sizeof(struct mixer_devinfo); unsigned struct_mpu_command_rec_sz = sizeof(mpu_command_rec); @@ -1423,7 +1451,7 @@ unsigned IOCTL_SPKRTONE = SPKRTONE; unsigned IOCTL_SPKRTUNE = SPKRTUNE; unsigned IOCTL_SPKRGETVOL = SPKRGETVOL; unsigned IOCTL_SPKRSETVOL = SPKRSETVOL; -#if 0 /* interfaces are WIP */ +#if defined(__x86_64__) 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; @@ -1438,7 +1466,10 @@ 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; +unsigned IOCTL_NVMM_IOC_CTL = NVMM_IOC_CTL; #endif +unsigned IOCTL_SPI_IOCTL_CONFIGURE = SPI_IOCTL_CONFIGURE; +unsigned IOCTL_SPI_IOCTL_TRANSFER = SPI_IOCTL_TRANSFER; unsigned IOCTL_AUTOFSREQUEST = AUTOFSREQUEST; unsigned IOCTL_AUTOFSDONE = AUTOFSDONE; unsigned IOCTL_BIOCGBLEN = BIOCGBLEN; @@ -1656,6 +1687,9 @@ unsigned IOCTL_AUDIO_GETPROPS = AUDIO_GETPROPS; unsigned IOCTL_AUDIO_GETBUFINFO = AUDIO_GETBUFINFO; unsigned IOCTL_AUDIO_SETCHAN = AUDIO_SETCHAN; unsigned IOCTL_AUDIO_GETCHAN = AUDIO_GETCHAN; +unsigned IOCTL_AUDIO_QUERYFORMAT = AUDIO_QUERYFORMAT; +unsigned IOCTL_AUDIO_GETFORMAT = AUDIO_GETFORMAT; +unsigned IOCTL_AUDIO_SETFORMAT = AUDIO_SETFORMAT; unsigned IOCTL_AUDIO_MIXER_READ = AUDIO_MIXER_READ; unsigned IOCTL_AUDIO_MIXER_WRITE = AUDIO_MIXER_WRITE; unsigned IOCTL_AUDIO_MIXER_DEVINFO = AUDIO_MIXER_DEVINFO; @@ -1741,6 +1775,7 @@ unsigned IOCTL_DIOCTUR = DIOCTUR; unsigned IOCTL_DIOCMWEDGES = DIOCMWEDGES; unsigned IOCTL_DIOCGSECTORSIZE = DIOCGSECTORSIZE; unsigned IOCTL_DIOCGMEDIASIZE = DIOCGMEDIASIZE; +unsigned IOCTL_DIOCRMWEDGES = DIOCRMWEDGES; unsigned IOCTL_DRVDETACHDEV = DRVDETACHDEV; unsigned IOCTL_DRVRESCANBUS = DRVRESCANBUS; unsigned IOCTL_DRVCTLCOMMAND = DRVCTLCOMMAND; @@ -1945,6 +1980,8 @@ unsigned IOCTL_SIOCSLINKSTR = SIOCSLINKSTR; unsigned IOCTL_SIOCGETHERCAP = SIOCGETHERCAP; unsigned IOCTL_SIOCGIFINDEX = SIOCGIFINDEX; unsigned IOCTL_SIOCSETHERCAP = SIOCSETHERCAP; +unsigned IOCTL_SIOCSIFDESCR = SIOCSIFDESCR; +unsigned IOCTL_SIOCGIFDESCR = SIOCGIFDESCR; unsigned IOCTL_SIOCGUMBINFO = SIOCGUMBINFO; unsigned IOCTL_SIOCSUMBPARAM = SIOCSUMBPARAM; unsigned IOCTL_SIOCGUMBPARAM = SIOCGUMBPARAM; @@ -2069,6 +2106,19 @@ unsigned IOCTL_WDOGIOC_WHICH = WDOGIOC_WHICH; unsigned IOCTL_WDOGIOC_TICKLE = WDOGIOC_TICKLE; unsigned IOCTL_WDOGIOC_GTICKLER = WDOGIOC_GTICKLER; unsigned IOCTL_WDOGIOC_GWDOGS = WDOGIOC_GWDOGS; +unsigned IOCTL_KCOV_IOC_SETBUFSIZE = KCOV_IOC_SETBUFSIZE; +unsigned IOCTL_KCOV_IOC_ENABLE = KCOV_IOC_ENABLE; +unsigned IOCTL_KCOV_IOC_DISABLE = KCOV_IOC_DISABLE; +unsigned IOCTL_IPMICTL_RECEIVE_MSG_TRUNC = IPMICTL_RECEIVE_MSG_TRUNC; +unsigned IOCTL_IPMICTL_RECEIVE_MSG = IPMICTL_RECEIVE_MSG; +unsigned IOCTL_IPMICTL_SEND_COMMAND = IPMICTL_SEND_COMMAND; +unsigned IOCTL_IPMICTL_REGISTER_FOR_CMD = IPMICTL_REGISTER_FOR_CMD; +unsigned IOCTL_IPMICTL_UNREGISTER_FOR_CMD = IPMICTL_UNREGISTER_FOR_CMD; +unsigned IOCTL_IPMICTL_SET_GETS_EVENTS_CMD = IPMICTL_SET_GETS_EVENTS_CMD; +unsigned IOCTL_IPMICTL_SET_MY_ADDRESS_CMD = IPMICTL_SET_MY_ADDRESS_CMD; +unsigned IOCTL_IPMICTL_GET_MY_ADDRESS_CMD = IPMICTL_GET_MY_ADDRESS_CMD; +unsigned IOCTL_IPMICTL_SET_MY_LUN_CMD = IPMICTL_SET_MY_LUN_CMD; +unsigned IOCTL_IPMICTL_GET_MY_LUN_CMD = IPMICTL_GET_MY_LUN_CMD; unsigned IOCTL_SNDCTL_DSP_RESET = SNDCTL_DSP_RESET; unsigned IOCTL_SNDCTL_DSP_SYNC = SNDCTL_DSP_SYNC; unsigned IOCTL_SNDCTL_DSP_SPEED = SNDCTL_DSP_SPEED; diff --git a/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h b/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h index add9852ec6c3..4fb3b8c0e06f 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h +++ b/lib/sanitizer_common/sanitizer_platform_limits_netbsd.h @@ -849,6 +849,25 @@ extern unsigned struct_usb_config_desc_sz; extern unsigned struct_usb_ctl_report_desc_sz; extern unsigned struct_usb_ctl_report_sz; extern unsigned struct_usb_ctl_request_sz; +#if defined(__x86_64__) +extern unsigned struct_nvmm_ioc_capability_sz; +extern unsigned struct_nvmm_ioc_machine_create_sz; +extern unsigned struct_nvmm_ioc_machine_destroy_sz; +extern unsigned struct_nvmm_ioc_machine_configure_sz; +extern unsigned struct_nvmm_ioc_vcpu_create_sz; +extern unsigned struct_nvmm_ioc_vcpu_destroy_sz; +extern unsigned struct_nvmm_ioc_vcpu_setstate_sz; +extern unsigned struct_nvmm_ioc_vcpu_getstate_sz; +extern unsigned struct_nvmm_ioc_vcpu_inject_sz; +extern unsigned struct_nvmm_ioc_vcpu_run_sz; +extern unsigned struct_nvmm_ioc_gpa_map_sz; +extern unsigned struct_nvmm_ioc_gpa_unmap_sz; +extern unsigned struct_nvmm_ioc_hva_map_sz; +extern unsigned struct_nvmm_ioc_hva_unmap_sz; +extern unsigned struct_nvmm_ioc_ctl_sz; +#endif +extern unsigned struct_spi_ioctl_configure_sz; +extern unsigned struct_spi_ioctl_transfer_sz; extern unsigned struct_autofs_daemon_request_sz; extern unsigned struct_autofs_daemon_done_sz; extern unsigned struct_sctp_connectx_addrs_sz; @@ -891,6 +910,9 @@ extern unsigned struct_vnd_user_sz; extern unsigned struct_vt_stat_sz; extern unsigned struct_wdog_conf_sz; extern unsigned struct_wdog_mode_sz; +extern unsigned struct_ipmi_recv_sz; +extern unsigned struct_ipmi_req_sz; +extern unsigned struct_ipmi_cmdspec_sz; extern unsigned struct_wfq_conf_sz; extern unsigned struct_wfq_getqid_sz; extern unsigned struct_wfq_getstats_sz; @@ -969,6 +991,7 @@ extern unsigned struct_iscsi_wait_event_parameters_sz; extern unsigned struct_isp_stats_sz; extern unsigned struct_lsenable_sz; extern unsigned struct_lsdisable_sz; +extern unsigned struct_audio_format_query_sz; extern unsigned struct_mixer_ctrl_sz; extern unsigned struct_mixer_devinfo_sz; extern unsigned struct_mpu_command_rec_sz; @@ -1575,7 +1598,7 @@ extern unsigned IOCTL_SPKRTONE; extern unsigned IOCTL_SPKRTUNE; extern unsigned IOCTL_SPKRGETVOL; extern unsigned IOCTL_SPKRSETVOL; -#if 0 /* interfaces are WIP */ +#if defined(__x86_64__) extern unsigned IOCTL_NVMM_IOC_CAPABILITY; extern unsigned IOCTL_NVMM_IOC_MACHINE_CREATE; extern unsigned IOCTL_NVMM_IOC_MACHINE_DESTROY; @@ -1590,6 +1613,7 @@ 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; +extern unsigned IOCTL_NVMM_IOC_CTL; #endif extern unsigned IOCTL_AUTOFSREQUEST; extern unsigned IOCTL_AUTOFSDONE; @@ -1808,6 +1832,9 @@ extern unsigned IOCTL_AUDIO_GETPROPS; extern unsigned IOCTL_AUDIO_GETBUFINFO; extern unsigned IOCTL_AUDIO_SETCHAN; extern unsigned IOCTL_AUDIO_GETCHAN; +extern unsigned IOCTL_AUDIO_QUERYFORMAT; +extern unsigned IOCTL_AUDIO_GETFORMAT; +extern unsigned IOCTL_AUDIO_SETFORMAT; extern unsigned IOCTL_AUDIO_MIXER_READ; extern unsigned IOCTL_AUDIO_MIXER_WRITE; extern unsigned IOCTL_AUDIO_MIXER_DEVINFO; @@ -1893,6 +1920,7 @@ extern unsigned IOCTL_DIOCTUR; extern unsigned IOCTL_DIOCMWEDGES; extern unsigned IOCTL_DIOCGSECTORSIZE; extern unsigned IOCTL_DIOCGMEDIASIZE; +extern unsigned IOCTL_DIOCRMWEDGES; extern unsigned IOCTL_DRVDETACHDEV; extern unsigned IOCTL_DRVRESCANBUS; extern unsigned IOCTL_DRVCTLCOMMAND; @@ -1994,6 +2022,8 @@ extern unsigned IOCTL_SEQUENCER_TMR_TEMPO; extern unsigned IOCTL_SEQUENCER_TMR_SOURCE; extern unsigned IOCTL_SEQUENCER_TMR_METRONOME; extern unsigned IOCTL_SEQUENCER_TMR_SELECT; +extern unsigned IOCTL_SPI_IOCTL_CONFIGURE; +extern unsigned IOCTL_SPI_IOCTL_TRANSFER; extern unsigned IOCTL_MTIOCTOP; extern unsigned IOCTL_MTIOCGET; extern unsigned IOCTL_MTIOCIEOT; @@ -2097,6 +2127,8 @@ extern unsigned IOCTL_SIOCSLINKSTR; extern unsigned IOCTL_SIOCGETHERCAP; extern unsigned IOCTL_SIOCGIFINDEX; extern unsigned IOCTL_SIOCSETHERCAP; +extern unsigned IOCTL_SIOCSIFDESCR; +extern unsigned IOCTL_SIOCGIFDESCR; extern unsigned IOCTL_SIOCGUMBINFO; extern unsigned IOCTL_SIOCSUMBPARAM; extern unsigned IOCTL_SIOCGUMBPARAM; @@ -2221,6 +2253,19 @@ extern unsigned IOCTL_WDOGIOC_WHICH; extern unsigned IOCTL_WDOGIOC_TICKLE; extern unsigned IOCTL_WDOGIOC_GTICKLER; extern unsigned IOCTL_WDOGIOC_GWDOGS; +extern unsigned IOCTL_KCOV_IOC_SETBUFSIZE; +extern unsigned IOCTL_KCOV_IOC_ENABLE; +extern unsigned IOCTL_KCOV_IOC_DISABLE; +extern unsigned IOCTL_IPMICTL_RECEIVE_MSG_TRUNC; +extern unsigned IOCTL_IPMICTL_RECEIVE_MSG; +extern unsigned IOCTL_IPMICTL_SEND_COMMAND; +extern unsigned IOCTL_IPMICTL_REGISTER_FOR_CMD; +extern unsigned IOCTL_IPMICTL_UNREGISTER_FOR_CMD; +extern unsigned IOCTL_IPMICTL_SET_GETS_EVENTS_CMD; +extern unsigned IOCTL_IPMICTL_SET_MY_ADDRESS_CMD; +extern unsigned IOCTL_IPMICTL_GET_MY_ADDRESS_CMD; +extern unsigned IOCTL_IPMICTL_SET_MY_LUN_CMD; +extern unsigned IOCTL_IPMICTL_GET_MY_LUN_CMD; extern unsigned IOCTL_SNDCTL_DSP_RESET; extern unsigned IOCTL_SNDCTL_DSP_SYNC; extern unsigned IOCTL_SNDCTL_DSP_SPEED; diff --git a/lib/sanitizer_common/sanitizer_platform_limits_openbsd.cc b/lib/sanitizer_common/sanitizer_platform_limits_openbsd.cpp index 5a1b07fa9c5e..12515626ce53 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_openbsd.cc +++ b/lib/sanitizer_common/sanitizer_platform_limits_openbsd.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_platform_limits_openbsd.cc ------------------------------===// +//===-- sanitizer_platform_limits_openbsd.cpp -----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc b/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp index b7fa6e8f7e07..9852e6ba7879 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.cc +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_platform_limits_posix.cc --------------------------------===// +//===-- sanitizer_platform_limits_posix.cpp -------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -22,6 +22,10 @@ #ifdef _FILE_OFFSET_BITS #undef _FILE_OFFSET_BITS #endif + +// Must go after undef _FILE_OFFSET_BITS. +#include "sanitizer_glibc_version.h" + #include <arpa/inet.h> #include <dirent.h> #include <grp.h> @@ -136,6 +140,7 @@ typedef struct user_fpregs elf_fpregset_t; #include <linux/serial.h> #include <sys/msg.h> #include <sys/ipc.h> +#include <crypt.h> #endif // SANITIZER_LINUX && !SANITIZER_ANDROID #if SANITIZER_ANDROID @@ -236,6 +241,7 @@ namespace __sanitizer { unsigned struct_ustat_sz = SIZEOF_STRUCT_USTAT; unsigned struct_rlimit64_sz = sizeof(struct rlimit64); unsigned struct_statvfs64_sz = sizeof(struct statvfs64); + unsigned struct_crypt_data_sz = sizeof(struct crypt_data); #endif // SANITIZER_LINUX && !SANITIZER_ANDROID #if SANITIZER_LINUX && !SANITIZER_ANDROID @@ -1005,10 +1011,6 @@ CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_len); CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_level); CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_type); -#ifndef __GLIBC_PREREQ -#define __GLIBC_PREREQ(x, y) 0 -#endif - #if SANITIZER_LINUX && (__ANDROID_API__ >= 21 || __GLIBC_PREREQ (2, 14)) CHECK_TYPE_SIZE(mmsghdr); CHECK_SIZE_AND_OFFSET(mmsghdr, msg_hdr); @@ -1126,8 +1128,11 @@ CHECK_SIZE_AND_OFFSET(ipc_perm, uid); CHECK_SIZE_AND_OFFSET(ipc_perm, gid); CHECK_SIZE_AND_OFFSET(ipc_perm, cuid); CHECK_SIZE_AND_OFFSET(ipc_perm, cgid); -#if !defined(__aarch64__) || !SANITIZER_LINUX || __GLIBC_PREREQ (2, 21) +#if (!defined(__aarch64__) || !SANITIZER_LINUX || __GLIBC_PREREQ (2, 21)) && \ + !defined(__arm__) /* On aarch64 glibc 2.20 and earlier provided incorrect mode field. */ +/* On Arm newer glibc provide a different mode field, it's hard to detect + so just disable the check. */ CHECK_SIZE_AND_OFFSET(ipc_perm, mode); #endif diff --git a/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/lib/sanitizer_common/sanitizer_platform_limits_posix.h index f1a4fd7d3709..db2c4f07b3ae 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -19,844 +19,846 @@ #include "sanitizer_internal_defs.h" #include "sanitizer_platform.h" -# define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) ((link_map*)(handle)) - -#ifndef __GLIBC_PREREQ -#define __GLIBC_PREREQ(x, y) 0 +#if defined(__sparc__) +// FIXME: This can't be included from tsan which does not support sparc yet. +#include "sanitizer_glibc_version.h" #endif +# define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) ((link_map*)(handle)) + namespace __sanitizer { - extern unsigned struct_utsname_sz; - extern unsigned struct_stat_sz; +extern unsigned struct_utsname_sz; +extern unsigned struct_stat_sz; #if !SANITIZER_IOS - extern unsigned struct_stat64_sz; -#endif - extern unsigned struct_rusage_sz; - extern unsigned siginfo_t_sz; - extern unsigned struct_itimerval_sz; - extern unsigned pthread_t_sz; - extern unsigned pthread_mutex_t_sz; - extern unsigned pthread_cond_t_sz; - extern unsigned pid_t_sz; - extern unsigned timeval_sz; - extern unsigned uid_t_sz; - extern unsigned gid_t_sz; - extern unsigned mbstate_t_sz; - extern unsigned struct_timezone_sz; - extern unsigned struct_tms_sz; - extern unsigned struct_itimerspec_sz; - 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; +extern unsigned struct_stat64_sz; +#endif +extern unsigned struct_rusage_sz; +extern unsigned siginfo_t_sz; +extern unsigned struct_itimerval_sz; +extern unsigned pthread_t_sz; +extern unsigned pthread_mutex_t_sz; +extern unsigned pthread_cond_t_sz; +extern unsigned pid_t_sz; +extern unsigned timeval_sz; +extern unsigned uid_t_sz; +extern unsigned gid_t_sz; +extern unsigned mbstate_t_sz; +extern unsigned struct_timezone_sz; +extern unsigned struct_tms_sz; +extern unsigned struct_itimerspec_sz; +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; +extern unsigned struct_fstab_sz; +extern unsigned struct_statfs_sz; +extern unsigned struct_sockaddr_sz; +extern unsigned ucontext_t_sz; #endif // !SANITIZER_ANDROID #if SANITIZER_LINUX #if defined(__x86_64__) - const unsigned struct_kernel_stat_sz = 144; - const unsigned struct_kernel_stat64_sz = 0; +const unsigned struct_kernel_stat_sz = 144; +const unsigned struct_kernel_stat64_sz = 0; #elif defined(__i386__) - const unsigned struct_kernel_stat_sz = 64; - const unsigned struct_kernel_stat64_sz = 96; +const unsigned struct_kernel_stat_sz = 64; +const unsigned struct_kernel_stat64_sz = 96; #elif defined(__arm__) - const unsigned struct_kernel_stat_sz = 64; - const unsigned struct_kernel_stat64_sz = 104; +const unsigned struct_kernel_stat_sz = 64; +const unsigned struct_kernel_stat64_sz = 104; #elif defined(__aarch64__) - const unsigned struct_kernel_stat_sz = 128; - const unsigned struct_kernel_stat64_sz = 104; +const unsigned struct_kernel_stat_sz = 128; +const unsigned struct_kernel_stat64_sz = 104; #elif defined(__powerpc__) && !defined(__powerpc64__) - const unsigned struct_kernel_stat_sz = 72; - const unsigned struct_kernel_stat64_sz = 104; +const unsigned struct_kernel_stat_sz = 72; +const unsigned struct_kernel_stat64_sz = 104; #elif defined(__powerpc64__) - const unsigned struct_kernel_stat_sz = 144; - const unsigned struct_kernel_stat64_sz = 104; +const unsigned struct_kernel_stat_sz = 144; +const unsigned struct_kernel_stat64_sz = 104; #elif defined(__mips__) - const unsigned struct_kernel_stat_sz = - SANITIZER_ANDROID ? FIRST_32_SECOND_64(104, 128) : - FIRST_32_SECOND_64(160, 216); - const unsigned struct_kernel_stat64_sz = 104; +const unsigned struct_kernel_stat_sz = SANITIZER_ANDROID + ? FIRST_32_SECOND_64(104, 128) + : FIRST_32_SECOND_64(160, 216); +const unsigned struct_kernel_stat64_sz = 104; #elif defined(__s390__) && !defined(__s390x__) - const unsigned struct_kernel_stat_sz = 64; - const unsigned struct_kernel_stat64_sz = 104; +const unsigned struct_kernel_stat_sz = 64; +const unsigned struct_kernel_stat64_sz = 104; #elif defined(__s390x__) - const unsigned struct_kernel_stat_sz = 144; - const unsigned struct_kernel_stat64_sz = 0; +const unsigned struct_kernel_stat_sz = 144; +const unsigned struct_kernel_stat64_sz = 0; #elif defined(__sparc__) && defined(__arch64__) - const unsigned struct___old_kernel_stat_sz = 0; - const unsigned struct_kernel_stat_sz = 104; - const unsigned struct_kernel_stat64_sz = 144; +const unsigned struct___old_kernel_stat_sz = 0; +const unsigned struct_kernel_stat_sz = 104; +const unsigned struct_kernel_stat64_sz = 144; #elif defined(__sparc__) && !defined(__arch64__) - const unsigned struct___old_kernel_stat_sz = 0; - const unsigned struct_kernel_stat_sz = 64; - const unsigned struct_kernel_stat64_sz = 104; -#endif - struct __sanitizer_perf_event_attr { - unsigned type; - unsigned size; - // More fields that vary with the kernel version. - }; +const unsigned struct___old_kernel_stat_sz = 0; +const unsigned struct_kernel_stat_sz = 64; +const unsigned struct_kernel_stat64_sz = 104; +#endif +struct __sanitizer_perf_event_attr { + unsigned type; + unsigned size; + // More fields that vary with the kernel version. +}; - extern unsigned struct_epoll_event_sz; - extern unsigned struct_sysinfo_sz; - extern unsigned __user_cap_header_struct_sz; - extern unsigned __user_cap_data_struct_sz; - extern unsigned struct_new_utsname_sz; - extern unsigned struct_old_utsname_sz; - extern unsigned struct_oldold_utsname_sz; +extern unsigned struct_epoll_event_sz; +extern unsigned struct_sysinfo_sz; +extern unsigned __user_cap_header_struct_sz; +extern unsigned __user_cap_data_struct_sz; +extern unsigned struct_new_utsname_sz; +extern unsigned struct_old_utsname_sz; +extern unsigned struct_oldold_utsname_sz; - const unsigned struct_kexec_segment_sz = 4 * sizeof(unsigned long); +const unsigned struct_kexec_segment_sz = 4 * sizeof(unsigned long); #endif // SANITIZER_LINUX #if SANITIZER_LINUX #if defined(__powerpc64__) || defined(__s390__) - const unsigned struct___old_kernel_stat_sz = 0; +const unsigned struct___old_kernel_stat_sz = 0; #elif !defined(__sparc__) - const unsigned struct___old_kernel_stat_sz = 32; -#endif - - extern unsigned struct_rlimit_sz; - extern unsigned struct_utimbuf_sz; - extern unsigned struct_timespec_sz; - - struct __sanitizer_iocb { - u64 aio_data; - u32 aio_key_or_aio_reserved1; // Simply crazy. - u32 aio_reserved1_or_aio_key; // Luckily, we don't need these. - u16 aio_lio_opcode; - s16 aio_reqprio; - u32 aio_fildes; - u64 aio_buf; - u64 aio_nbytes; - s64 aio_offset; - u64 aio_reserved2; - u64 aio_reserved3; - }; +const unsigned struct___old_kernel_stat_sz = 32; +#endif - struct __sanitizer_io_event { - u64 data; - u64 obj; - u64 res; - u64 res2; - }; +extern unsigned struct_rlimit_sz; +extern unsigned struct_utimbuf_sz; +extern unsigned struct_timespec_sz; + +struct __sanitizer_iocb { + u64 aio_data; + u32 aio_key_or_aio_reserved1; // Simply crazy. + u32 aio_reserved1_or_aio_key; // Luckily, we don't need these. + u16 aio_lio_opcode; + s16 aio_reqprio; + u32 aio_fildes; + u64 aio_buf; + u64 aio_nbytes; + s64 aio_offset; + u64 aio_reserved2; + u64 aio_reserved3; +}; - const unsigned iocb_cmd_pread = 0; - const unsigned iocb_cmd_pwrite = 1; - const unsigned iocb_cmd_preadv = 7; - const unsigned iocb_cmd_pwritev = 8; - - struct __sanitizer___sysctl_args { - int *name; - int nlen; - void *oldval; - uptr *oldlenp; - void *newval; - uptr newlen; - unsigned long ___unused[4]; - }; +struct __sanitizer_io_event { + u64 data; + u64 obj; + u64 res; + u64 res2; +}; - const unsigned old_sigset_t_sz = sizeof(unsigned long); +const unsigned iocb_cmd_pread = 0; +const unsigned iocb_cmd_pwrite = 1; +const unsigned iocb_cmd_preadv = 7; +const unsigned iocb_cmd_pwritev = 8; + +struct __sanitizer___sysctl_args { + int *name; + int nlen; + void *oldval; + uptr *oldlenp; + void *newval; + uptr newlen; + unsigned long ___unused[4]; +}; - struct __sanitizer_sem_t { +const unsigned old_sigset_t_sz = sizeof(unsigned long); + +struct __sanitizer_sem_t { #if SANITIZER_ANDROID && defined(_LP64) - int data[4]; + int data[4]; #elif SANITIZER_ANDROID && !defined(_LP64) - int data; + int data; #elif SANITIZER_LINUX - uptr data[4]; + uptr data[4]; #endif - }; +}; #endif // SANITIZER_LINUX #if SANITIZER_ANDROID - struct __sanitizer_struct_mallinfo { - uptr v[10]; - }; +struct __sanitizer_struct_mallinfo { + uptr v[10]; +}; #endif #if SANITIZER_LINUX && !SANITIZER_ANDROID - struct __sanitizer_struct_mallinfo { - int v[10]; - }; +struct __sanitizer_struct_mallinfo { + int v[10]; +}; - extern unsigned struct_ustat_sz; - extern unsigned struct_rlimit64_sz; - extern unsigned struct_statvfs64_sz; +extern unsigned struct_ustat_sz; +extern unsigned struct_rlimit64_sz; +extern unsigned struct_statvfs64_sz; - struct __sanitizer_ipc_perm { - int __key; - int uid; - int gid; - int cuid; - int cgid; +struct __sanitizer_ipc_perm { + int __key; + int uid; + int gid; + int cuid; + int cgid; #ifdef __powerpc__ - unsigned mode; - unsigned __seq; - u64 __unused1; - u64 __unused2; + unsigned mode; + unsigned __seq; + u64 __unused1; + u64 __unused2; #elif defined(__sparc__) #if defined(__arch64__) - unsigned mode; - unsigned short __pad1; + unsigned mode; + unsigned short __pad1; #else - unsigned short __pad1; - unsigned short mode; - unsigned short __pad2; + unsigned short __pad1; + unsigned short mode; + unsigned short __pad2; #endif - unsigned short __seq; - unsigned long long __unused1; - unsigned long long __unused2; + unsigned short __seq; + unsigned long long __unused1; + unsigned long long __unused2; #elif defined(__mips__) || defined(__aarch64__) || defined(__s390x__) - unsigned int mode; - unsigned short __seq; - unsigned short __pad1; - unsigned long __unused1; - unsigned long __unused2; + unsigned int mode; + unsigned short __seq; + unsigned short __pad1; + unsigned long __unused1; + unsigned long __unused2; #else - unsigned short mode; - unsigned short __pad1; - unsigned short __seq; - unsigned short __pad2; + unsigned short mode; + unsigned short __pad1; + unsigned short __seq; + unsigned short __pad2; #if defined(__x86_64__) && !defined(_LP64) - u64 __unused1; - u64 __unused2; + u64 __unused1; + u64 __unused2; #else - unsigned long __unused1; - unsigned long __unused2; + unsigned long __unused1; + unsigned long __unused2; #endif #endif - }; +}; - struct __sanitizer_shmid_ds { - __sanitizer_ipc_perm shm_perm; - #if defined(__sparc__) - #if !defined(__arch64__) - u32 __pad1; - #endif - long shm_atime; - #if !defined(__arch64__) - u32 __pad2; - #endif - long shm_dtime; - #if !defined(__arch64__) - u32 __pad3; - #endif - long shm_ctime; - uptr shm_segsz; - int shm_cpid; - int shm_lpid; - unsigned long shm_nattch; - unsigned long __glibc_reserved1; - unsigned long __glibc_reserved2; - #else - #ifndef __powerpc__ - uptr shm_segsz; - #elif !defined(__powerpc64__) - uptr __unused0; - #endif - #if defined(__x86_64__) && !defined(_LP64) - u64 shm_atime; - u64 shm_dtime; - u64 shm_ctime; - #else - uptr shm_atime; - #if !defined(_LP64) && !defined(__mips__) - uptr __unused1; - #endif - uptr shm_dtime; - #if !defined(_LP64) && !defined(__mips__) - uptr __unused2; - #endif - uptr shm_ctime; - #if !defined(_LP64) && !defined(__mips__) - uptr __unused3; - #endif - #endif - #ifdef __powerpc__ - uptr shm_segsz; - #endif - int shm_cpid; - int shm_lpid; - #if defined(__x86_64__) && !defined(_LP64) - u64 shm_nattch; - u64 __unused4; - u64 __unused5; - #else - uptr shm_nattch; - uptr __unused4; - uptr __unused5; - #endif +struct __sanitizer_shmid_ds { + __sanitizer_ipc_perm shm_perm; +#if defined(__sparc__) +#if !defined(__arch64__) + u32 __pad1; #endif - }; + long shm_atime; +#if !defined(__arch64__) + u32 __pad2; +#endif + long shm_dtime; +#if !defined(__arch64__) + u32 __pad3; +#endif + long shm_ctime; + uptr shm_segsz; + int shm_cpid; + int shm_lpid; + unsigned long shm_nattch; + unsigned long __glibc_reserved1; + unsigned long __glibc_reserved2; +#else +#ifndef __powerpc__ + uptr shm_segsz; +#elif !defined(__powerpc64__) + uptr __unused0; +#endif +#if defined(__x86_64__) && !defined(_LP64) + u64 shm_atime; + u64 shm_dtime; + u64 shm_ctime; +#else + uptr shm_atime; +#if !defined(_LP64) && !defined(__mips__) + uptr __unused1; +#endif + uptr shm_dtime; +#if !defined(_LP64) && !defined(__mips__) + uptr __unused2; +#endif + uptr shm_ctime; +#if !defined(_LP64) && !defined(__mips__) + uptr __unused3; +#endif +#endif +#ifdef __powerpc__ + uptr shm_segsz; +#endif + int shm_cpid; + int shm_lpid; +#if defined(__x86_64__) && !defined(_LP64) + u64 shm_nattch; + u64 __unused4; + u64 __unused5; +#else + uptr shm_nattch; + uptr __unused4; + uptr __unused5; +#endif +#endif +}; #endif #if SANITIZER_LINUX && !SANITIZER_ANDROID - extern unsigned struct_msqid_ds_sz; - extern unsigned struct_mq_attr_sz; - extern unsigned struct_timex_sz; - extern unsigned struct_statvfs_sz; +extern unsigned struct_msqid_ds_sz; +extern unsigned struct_mq_attr_sz; +extern unsigned struct_timex_sz; +extern unsigned struct_statvfs_sz; +extern unsigned struct_crypt_data_sz; #endif // SANITIZER_LINUX && !SANITIZER_ANDROID - struct __sanitizer_iovec { - void *iov_base; - uptr iov_len; - }; +struct __sanitizer_iovec { + void *iov_base; + uptr iov_len; +}; #if !SANITIZER_ANDROID - struct __sanitizer_ifaddrs { - struct __sanitizer_ifaddrs *ifa_next; - char *ifa_name; - unsigned int ifa_flags; - void *ifa_addr; // (struct sockaddr *) - void *ifa_netmask; // (struct sockaddr *) - // This is a union on Linux. +struct __sanitizer_ifaddrs { + struct __sanitizer_ifaddrs *ifa_next; + char *ifa_name; + unsigned int ifa_flags; + void *ifa_addr; // (struct sockaddr *) + void *ifa_netmask; // (struct sockaddr *) + // This is a union on Linux. # ifdef ifa_dstaddr # undef ifa_dstaddr # endif - void *ifa_dstaddr; // (struct sockaddr *) - void *ifa_data; - }; + void *ifa_dstaddr; // (struct sockaddr *) + void *ifa_data; +}; #endif // !SANITIZER_ANDROID #if SANITIZER_MAC - typedef unsigned long __sanitizer_pthread_key_t; +typedef unsigned long __sanitizer_pthread_key_t; #else - typedef unsigned __sanitizer_pthread_key_t; +typedef unsigned __sanitizer_pthread_key_t; #endif #if SANITIZER_LINUX && !SANITIZER_ANDROID - struct __sanitizer_XDR { - int x_op; - void *x_ops; - uptr x_public; - uptr x_private; - uptr x_base; - unsigned x_handy; - }; +struct __sanitizer_XDR { + int x_op; + void *x_ops; + uptr x_public; + uptr x_private; + uptr x_base; + unsigned x_handy; +}; - const int __sanitizer_XDR_ENCODE = 0; - const int __sanitizer_XDR_DECODE = 1; - const int __sanitizer_XDR_FREE = 2; +const int __sanitizer_XDR_ENCODE = 0; +const int __sanitizer_XDR_DECODE = 1; +const int __sanitizer_XDR_FREE = 2; #endif - struct __sanitizer_passwd { - char *pw_name; - char *pw_passwd; - int pw_uid; - int pw_gid; +struct __sanitizer_passwd { + char *pw_name; + char *pw_passwd; + int pw_uid; + int pw_gid; #if SANITIZER_MAC - long pw_change; - char *pw_class; + long pw_change; + char *pw_class; #endif #if !(SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 32)) - char *pw_gecos; + char *pw_gecos; #endif - char *pw_dir; - char *pw_shell; + char *pw_dir; + char *pw_shell; #if SANITIZER_MAC - long pw_expire; + long pw_expire; #endif - }; +}; - struct __sanitizer_group { - char *gr_name; - char *gr_passwd; - int gr_gid; - char **gr_mem; - }; +struct __sanitizer_group { + char *gr_name; + char *gr_passwd; + int gr_gid; + char **gr_mem; +}; #if defined(__x86_64__) && !defined(_LP64) - typedef long long __sanitizer_time_t; +typedef long long __sanitizer_time_t; #else - typedef long __sanitizer_time_t; +typedef long __sanitizer_time_t; #endif - typedef long __sanitizer_suseconds_t; +typedef long __sanitizer_suseconds_t; - struct __sanitizer_timeval { - __sanitizer_time_t tv_sec; - __sanitizer_suseconds_t tv_usec; - }; +struct __sanitizer_timeval { + __sanitizer_time_t tv_sec; + __sanitizer_suseconds_t tv_usec; +}; - struct __sanitizer_itimerval { - struct __sanitizer_timeval it_interval; - struct __sanitizer_timeval it_value; - }; +struct __sanitizer_itimerval { + struct __sanitizer_timeval it_interval; + struct __sanitizer_timeval it_value; +}; - struct __sanitizer_timeb { - __sanitizer_time_t time; - unsigned short millitm; - short timezone; - short dstflag; - }; +struct __sanitizer_timeb { + __sanitizer_time_t time; + unsigned short millitm; + short timezone; + short dstflag; +}; - struct __sanitizer_ether_addr { - u8 octet[6]; - }; +struct __sanitizer_ether_addr { + u8 octet[6]; +}; - struct __sanitizer_tm { - int tm_sec; - int tm_min; - int tm_hour; - int tm_mday; - int tm_mon; - int tm_year; - int tm_wday; - int tm_yday; - int tm_isdst; - long int tm_gmtoff; - const char *tm_zone; - }; +struct __sanitizer_tm { + int tm_sec; + int tm_min; + int tm_hour; + int tm_mday; + int tm_mon; + int tm_year; + int tm_wday; + int tm_yday; + int tm_isdst; + long int tm_gmtoff; + const char *tm_zone; +}; #if SANITIZER_LINUX - struct __sanitizer_mntent { - char *mnt_fsname; - char *mnt_dir; - char *mnt_type; - char *mnt_opts; - int mnt_freq; - int mnt_passno; - }; +struct __sanitizer_mntent { + char *mnt_fsname; + char *mnt_dir; + char *mnt_type; + char *mnt_opts; + int mnt_freq; + int mnt_passno; +}; - struct __sanitizer_file_handle { - unsigned int handle_bytes; - int handle_type; - unsigned char f_handle[1]; // variable sized - }; +struct __sanitizer_file_handle { + unsigned int handle_bytes; + int handle_type; + unsigned char f_handle[1]; // variable sized +}; #endif #if SANITIZER_MAC - struct __sanitizer_msghdr { - void *msg_name; - unsigned msg_namelen; - struct __sanitizer_iovec *msg_iov; - unsigned msg_iovlen; - void *msg_control; - unsigned msg_controllen; - int msg_flags; - }; - struct __sanitizer_cmsghdr { - unsigned cmsg_len; - int cmsg_level; - int cmsg_type; - }; +struct __sanitizer_msghdr { + void *msg_name; + unsigned msg_namelen; + struct __sanitizer_iovec *msg_iov; + unsigned msg_iovlen; + void *msg_control; + unsigned msg_controllen; + int msg_flags; +}; +struct __sanitizer_cmsghdr { + unsigned cmsg_len; + int cmsg_level; + int cmsg_type; +}; #else - struct __sanitizer_msghdr { - void *msg_name; - unsigned msg_namelen; - struct __sanitizer_iovec *msg_iov; - uptr msg_iovlen; - void *msg_control; - uptr msg_controllen; - int msg_flags; - }; - struct __sanitizer_cmsghdr { - uptr cmsg_len; - int cmsg_level; - int cmsg_type; - }; +struct __sanitizer_msghdr { + void *msg_name; + unsigned msg_namelen; + struct __sanitizer_iovec *msg_iov; + uptr msg_iovlen; + void *msg_control; + uptr msg_controllen; + int msg_flags; +}; +struct __sanitizer_cmsghdr { + uptr cmsg_len; + int cmsg_level; + int cmsg_type; +}; #endif #if SANITIZER_LINUX - struct __sanitizer_mmsghdr { - __sanitizer_msghdr msg_hdr; - unsigned int msg_len; - }; +struct __sanitizer_mmsghdr { + __sanitizer_msghdr msg_hdr; + unsigned int msg_len; +}; #endif #if SANITIZER_MAC - struct __sanitizer_dirent { - unsigned long long d_ino; - unsigned long long d_seekoff; - unsigned short d_reclen; - // more fields that we don't care about - }; +struct __sanitizer_dirent { + unsigned long long d_ino; + unsigned long long d_seekoff; + unsigned short d_reclen; + // more fields that we don't care about +}; #elif SANITIZER_ANDROID || defined(__x86_64__) - struct __sanitizer_dirent { - unsigned long long d_ino; - unsigned long long d_off; - unsigned short d_reclen; - // more fields that we don't care about - }; +struct __sanitizer_dirent { + unsigned long long d_ino; + unsigned long long d_off; + unsigned short d_reclen; + // more fields that we don't care about +}; #else - struct __sanitizer_dirent { - uptr d_ino; - uptr d_off; - unsigned short d_reclen; - // more fields that we don't care about - }; +struct __sanitizer_dirent { + uptr d_ino; + uptr d_off; + unsigned short d_reclen; + // more fields that we don't care about +}; #endif #if SANITIZER_LINUX && !SANITIZER_ANDROID - struct __sanitizer_dirent64 { - unsigned long long d_ino; - unsigned long long d_off; - unsigned short d_reclen; - // more fields that we don't care about - }; +struct __sanitizer_dirent64 { + unsigned long long d_ino; + unsigned long long d_off; + unsigned short d_reclen; + // more fields that we don't care about +}; #endif #if defined(__x86_64__) && !defined(_LP64) - typedef long long __sanitizer_clock_t; +typedef long long __sanitizer_clock_t; #else - typedef long __sanitizer_clock_t; +typedef long __sanitizer_clock_t; #endif #if SANITIZER_LINUX - typedef int __sanitizer_clockid_t; +typedef int __sanitizer_clockid_t; #endif #if SANITIZER_LINUX -#if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__)\ - || defined(__mips__) - typedef unsigned __sanitizer___kernel_uid_t; - typedef unsigned __sanitizer___kernel_gid_t; +#if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__) || \ + defined(__mips__) +typedef unsigned __sanitizer___kernel_uid_t; +typedef unsigned __sanitizer___kernel_gid_t; #else - typedef unsigned short __sanitizer___kernel_uid_t; - typedef unsigned short __sanitizer___kernel_gid_t; +typedef unsigned short __sanitizer___kernel_uid_t; +typedef unsigned short __sanitizer___kernel_gid_t; #endif #if defined(__x86_64__) && !defined(_LP64) - typedef long long __sanitizer___kernel_off_t; +typedef long long __sanitizer___kernel_off_t; #else - typedef long __sanitizer___kernel_off_t; +typedef long __sanitizer___kernel_off_t; #endif #if defined(__powerpc__) || defined(__mips__) - typedef unsigned int __sanitizer___kernel_old_uid_t; - typedef unsigned int __sanitizer___kernel_old_gid_t; +typedef unsigned int __sanitizer___kernel_old_uid_t; +typedef unsigned int __sanitizer___kernel_old_gid_t; #else - typedef unsigned short __sanitizer___kernel_old_uid_t; - typedef unsigned short __sanitizer___kernel_old_gid_t; +typedef unsigned short __sanitizer___kernel_old_uid_t; +typedef unsigned short __sanitizer___kernel_old_gid_t; #endif - typedef long long __sanitizer___kernel_loff_t; - typedef struct { - unsigned long fds_bits[1024 / (8 * sizeof(long))]; - } __sanitizer___kernel_fd_set; +typedef long long __sanitizer___kernel_loff_t; +typedef struct { + unsigned long fds_bits[1024 / (8 * sizeof(long))]; +} __sanitizer___kernel_fd_set; #endif - // This thing depends on the platform. We are only interested in the upper - // limit. Verified with a compiler assert in .cc. - const int pthread_attr_t_max_sz = 128; - union __sanitizer_pthread_attr_t { - char size[pthread_attr_t_max_sz]; // NOLINT - void *align; - }; +// This thing depends on the platform. We are only interested in the upper +// limit. Verified with a compiler assert in .cpp. +union __sanitizer_pthread_attr_t { + char size[128]; + void *align; +}; #if SANITIZER_ANDROID # if SANITIZER_MIPS - typedef unsigned long __sanitizer_sigset_t[16/sizeof(unsigned long)]; +typedef unsigned long __sanitizer_sigset_t[16 / sizeof(unsigned long)]; # else - typedef unsigned long __sanitizer_sigset_t; +typedef unsigned long __sanitizer_sigset_t; # endif #elif SANITIZER_MAC - typedef unsigned __sanitizer_sigset_t; +typedef unsigned __sanitizer_sigset_t; #elif SANITIZER_LINUX - struct __sanitizer_sigset_t { - // The size is determined by looking at sizeof of real sigset_t on linux. - uptr val[128 / sizeof(uptr)]; - }; +struct __sanitizer_sigset_t { + // The size is determined by looking at sizeof of real sigset_t on linux. + uptr val[128 / sizeof(uptr)]; +}; #endif - struct __sanitizer_siginfo { - // The size is determined by looking at sizeof of real siginfo_t on linux. - u64 opaque[128 / sizeof(u64)]; - }; +struct __sanitizer_siginfo { + // The size is determined by looking at sizeof of real siginfo_t on linux. + u64 opaque[128 / sizeof(u64)]; +}; - using __sanitizer_sighandler_ptr = void (*)(int sig); - using __sanitizer_sigactionhandler_ptr = - void (*)(int sig, __sanitizer_siginfo *siginfo, void *uctx); +using __sanitizer_sighandler_ptr = void (*)(int sig); +using __sanitizer_sigactionhandler_ptr = void (*)(int sig, + __sanitizer_siginfo *siginfo, + void *uctx); - // Linux system headers define the 'sa_handler' and 'sa_sigaction' macros. +// Linux system headers define the 'sa_handler' and 'sa_sigaction' macros. #if SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 64) - struct __sanitizer_sigaction { - unsigned sa_flags; - union { - __sanitizer_sigactionhandler_ptr sigaction; - __sanitizer_sighandler_ptr handler; - }; - __sanitizer_sigset_t sa_mask; - void (*sa_restorer)(); +struct __sanitizer_sigaction { + unsigned sa_flags; + union { + __sanitizer_sigactionhandler_ptr sigaction; + __sanitizer_sighandler_ptr handler; }; + __sanitizer_sigset_t sa_mask; + void (*sa_restorer)(); +}; #elif SANITIZER_ANDROID && SANITIZER_MIPS32 // check this before WORDSIZE == 32 - struct __sanitizer_sigaction { - unsigned sa_flags; - union { - __sanitizer_sigactionhandler_ptr sigaction; - __sanitizer_sighandler_ptr handler; - }; - __sanitizer_sigset_t sa_mask; +struct __sanitizer_sigaction { + unsigned sa_flags; + union { + __sanitizer_sigactionhandler_ptr sigaction; + __sanitizer_sighandler_ptr handler; }; + __sanitizer_sigset_t sa_mask; +}; #elif SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 32) - struct __sanitizer_sigaction { - union { - __sanitizer_sigactionhandler_ptr sigaction; - __sanitizer_sighandler_ptr handler; - }; - __sanitizer_sigset_t sa_mask; - uptr sa_flags; - void (*sa_restorer)(); +struct __sanitizer_sigaction { + union { + __sanitizer_sigactionhandler_ptr sigaction; + __sanitizer_sighandler_ptr handler; }; + __sanitizer_sigset_t sa_mask; + uptr sa_flags; + void (*sa_restorer)(); +}; #else // !SANITIZER_ANDROID - struct __sanitizer_sigaction { +struct __sanitizer_sigaction { #if defined(__mips__) && !SANITIZER_FREEBSD - unsigned int sa_flags; + unsigned int sa_flags; #endif - union { - __sanitizer_sigactionhandler_ptr sigaction; - __sanitizer_sighandler_ptr handler; - }; + union { + __sanitizer_sigactionhandler_ptr sigaction; + __sanitizer_sighandler_ptr handler; + }; #if SANITIZER_FREEBSD - int sa_flags; - __sanitizer_sigset_t sa_mask; + int sa_flags; + __sanitizer_sigset_t sa_mask; #else #if defined(__s390x__) - int sa_resv; + int sa_resv; #else - __sanitizer_sigset_t sa_mask; + __sanitizer_sigset_t sa_mask; #endif #ifndef __mips__ #if defined(__sparc__) #if __GLIBC_PREREQ (2, 20) - // On sparc glibc 2.19 and earlier sa_flags was unsigned long. + // On sparc glibc 2.19 and earlier sa_flags was unsigned long. #if defined(__arch64__) - // To maintain ABI compatibility on sparc64 when switching to an int, - // __glibc_reserved0 was added. - int __glibc_reserved0; + // To maintain ABI compatibility on sparc64 when switching to an int, + // __glibc_reserved0 was added. + int __glibc_reserved0; #endif - int sa_flags; + int sa_flags; #else - unsigned long sa_flags; + unsigned long sa_flags; #endif #else - int sa_flags; + int sa_flags; #endif #endif #endif #if SANITIZER_LINUX - void (*sa_restorer)(); + void (*sa_restorer)(); #endif #if defined(__mips__) && (SANITIZER_WORDSIZE == 32) - int sa_resv[1]; + int sa_resv[1]; #endif #if defined(__s390x__) - __sanitizer_sigset_t sa_mask; + __sanitizer_sigset_t sa_mask; #endif - }; +}; #endif // !SANITIZER_ANDROID #if defined(__mips__) - struct __sanitizer_kernel_sigset_t { - uptr sig[2]; - }; +struct __sanitizer_kernel_sigset_t { + uptr sig[2]; +}; #else - struct __sanitizer_kernel_sigset_t { - u8 sig[8]; - }; +struct __sanitizer_kernel_sigset_t { + u8 sig[8]; +}; #endif - // Linux system headers define the 'sa_handler' and 'sa_sigaction' macros. +// Linux system headers define the 'sa_handler' and 'sa_sigaction' macros. #if SANITIZER_MIPS - struct __sanitizer_kernel_sigaction_t { - unsigned int sa_flags; - union { - void (*handler)(int signo); - void (*sigaction)(int signo, __sanitizer_siginfo *info, void *ctx); - }; - __sanitizer_kernel_sigset_t sa_mask; - void (*sa_restorer)(void); +struct __sanitizer_kernel_sigaction_t { + unsigned int sa_flags; + union { + void (*handler)(int signo); + void (*sigaction)(int signo, __sanitizer_siginfo *info, void *ctx); }; + __sanitizer_kernel_sigset_t sa_mask; + void (*sa_restorer)(void); +}; #else - struct __sanitizer_kernel_sigaction_t { - union { - void (*handler)(int signo); - void (*sigaction)(int signo, __sanitizer_siginfo *info, void *ctx); - }; - unsigned long sa_flags; - void (*sa_restorer)(void); - __sanitizer_kernel_sigset_t sa_mask; +struct __sanitizer_kernel_sigaction_t { + union { + void (*handler)(int signo); + void (*sigaction)(int signo, __sanitizer_siginfo *info, void *ctx); }; + unsigned long sa_flags; + void (*sa_restorer)(void); + __sanitizer_kernel_sigset_t sa_mask; +}; #endif - extern const uptr sig_ign; - extern const uptr sig_dfl; - extern const uptr sig_err; - extern const uptr sa_siginfo; +extern const uptr sig_ign; +extern const uptr sig_dfl; +extern const uptr sig_err; +extern const uptr sa_siginfo; #if SANITIZER_LINUX - extern int e_tabsz; +extern int e_tabsz; #endif - extern int af_inet; - extern int af_inet6; - uptr __sanitizer_in_addr_sz(int af); +extern int af_inet; +extern int af_inet6; +uptr __sanitizer_in_addr_sz(int af); #if SANITIZER_LINUX - struct __sanitizer_dl_phdr_info { - uptr dlpi_addr; - const char *dlpi_name; - const void *dlpi_phdr; - short dlpi_phnum; - }; +struct __sanitizer_dl_phdr_info { + uptr dlpi_addr; + const char *dlpi_name; + const void *dlpi_phdr; + short dlpi_phnum; +}; - extern unsigned struct_ElfW_Phdr_sz; +extern unsigned struct_ElfW_Phdr_sz; #endif - struct __sanitizer_addrinfo { - int ai_flags; - int ai_family; - int ai_socktype; - int ai_protocol; +struct __sanitizer_addrinfo { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; #if SANITIZER_ANDROID || SANITIZER_MAC - unsigned ai_addrlen; - char *ai_canonname; - void *ai_addr; + unsigned ai_addrlen; + char *ai_canonname; + void *ai_addr; #else // LINUX - unsigned ai_addrlen; - void *ai_addr; - char *ai_canonname; + unsigned ai_addrlen; + void *ai_addr; + char *ai_canonname; #endif - struct __sanitizer_addrinfo *ai_next; - }; + struct __sanitizer_addrinfo *ai_next; +}; - struct __sanitizer_hostent { - char *h_name; - char **h_aliases; - int h_addrtype; - int h_length; - char **h_addr_list; - }; +struct __sanitizer_hostent { + char *h_name; + char **h_aliases; + int h_addrtype; + int h_length; + char **h_addr_list; +}; - struct __sanitizer_pollfd { - int fd; - short events; - short revents; - }; +struct __sanitizer_pollfd { + int fd; + short events; + short revents; +}; #if SANITIZER_ANDROID || SANITIZER_MAC - typedef unsigned __sanitizer_nfds_t; +typedef unsigned __sanitizer_nfds_t; #else - typedef unsigned long __sanitizer_nfds_t; +typedef unsigned long __sanitizer_nfds_t; #endif #if !SANITIZER_ANDROID # if SANITIZER_LINUX - struct __sanitizer_glob_t { - uptr gl_pathc; - char **gl_pathv; - uptr gl_offs; - int gl_flags; - - void (*gl_closedir)(void *dirp); - void *(*gl_readdir)(void *dirp); - void *(*gl_opendir)(const char *); - int (*gl_lstat)(const char *, void *); - int (*gl_stat)(const char *, void *); - }; +struct __sanitizer_glob_t { + uptr gl_pathc; + char **gl_pathv; + uptr gl_offs; + int gl_flags; + + void (*gl_closedir)(void *dirp); + void *(*gl_readdir)(void *dirp); + void *(*gl_opendir)(const char *); + int (*gl_lstat)(const char *, void *); + int (*gl_stat)(const char *, void *); +}; # endif // SANITIZER_LINUX # if SANITIZER_LINUX - extern int glob_nomatch; - extern int glob_altdirfunc; +extern int glob_nomatch; +extern int glob_altdirfunc; # endif #endif // !SANITIZER_ANDROID - extern unsigned path_max; +extern unsigned path_max; - struct __sanitizer_wordexp_t { - uptr we_wordc; - char **we_wordv; - uptr we_offs; - }; +struct __sanitizer_wordexp_t { + uptr we_wordc; + char **we_wordv; + uptr we_offs; +}; #if SANITIZER_LINUX && !SANITIZER_ANDROID - struct __sanitizer_FILE { - int _flags; - char *_IO_read_ptr; - char *_IO_read_end; - char *_IO_read_base; - char *_IO_write_base; - char *_IO_write_ptr; - char *_IO_write_end; - char *_IO_buf_base; - char *_IO_buf_end; - char *_IO_save_base; - char *_IO_backup_base; - char *_IO_save_end; - void *_markers; - __sanitizer_FILE *_chain; - int _fileno; - }; +struct __sanitizer_FILE { + int _flags; + char *_IO_read_ptr; + char *_IO_read_end; + char *_IO_read_base; + char *_IO_write_base; + char *_IO_write_ptr; + char *_IO_write_end; + char *_IO_buf_base; + char *_IO_buf_end; + char *_IO_save_base; + char *_IO_backup_base; + char *_IO_save_end; + void *_markers; + __sanitizer_FILE *_chain; + int _fileno; +}; # define SANITIZER_HAS_STRUCT_FILE 1 #else - typedef void __sanitizer_FILE; +typedef void __sanitizer_FILE; # define SANITIZER_HAS_STRUCT_FILE 0 #endif -#if SANITIZER_LINUX && !SANITIZER_ANDROID && \ - (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ - defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ - defined(__s390__)) - extern unsigned struct_user_regs_struct_sz; - extern unsigned struct_user_fpregs_struct_sz; - extern unsigned struct_user_fpxregs_struct_sz; - extern unsigned struct_user_vfpregs_struct_sz; - - extern int ptrace_peektext; - extern int ptrace_peekdata; - extern int ptrace_peekuser; - extern int ptrace_getregs; - extern int ptrace_setregs; - extern int ptrace_getfpregs; - extern int ptrace_setfpregs; - extern int ptrace_getfpxregs; - extern int ptrace_setfpxregs; - extern int ptrace_getvfpregs; - extern int ptrace_setvfpregs; - extern int ptrace_getsiginfo; - extern int ptrace_setsiginfo; - extern int ptrace_getregset; - extern int ptrace_setregset; - extern int ptrace_geteventmsg; +#if SANITIZER_LINUX && !SANITIZER_ANDROID && \ + (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ + defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ + defined(__s390__)) +extern unsigned struct_user_regs_struct_sz; +extern unsigned struct_user_fpregs_struct_sz; +extern unsigned struct_user_fpxregs_struct_sz; +extern unsigned struct_user_vfpregs_struct_sz; + +extern int ptrace_peektext; +extern int ptrace_peekdata; +extern int ptrace_peekuser; +extern int ptrace_getregs; +extern int ptrace_setregs; +extern int ptrace_getfpregs; +extern int ptrace_setfpregs; +extern int ptrace_getfpxregs; +extern int ptrace_setfpxregs; +extern int ptrace_getvfpregs; +extern int ptrace_setvfpregs; +extern int ptrace_getsiginfo; +extern int ptrace_setsiginfo; +extern int ptrace_getregset; +extern int ptrace_setregset; +extern int ptrace_geteventmsg; #endif #if SANITIZER_LINUX && !SANITIZER_ANDROID - extern unsigned struct_shminfo_sz; - extern unsigned struct_shm_info_sz; - extern int shmctl_ipc_stat; - extern int shmctl_ipc_info; - extern int shmctl_shm_info; - extern int shmctl_shm_stat; +extern unsigned struct_shminfo_sz; +extern unsigned struct_shm_info_sz; +extern int shmctl_ipc_stat; +extern int shmctl_ipc_info; +extern int shmctl_shm_info; +extern int shmctl_shm_stat; #endif #if !SANITIZER_MAC && !SANITIZER_FREEBSD - extern unsigned struct_utmp_sz; +extern unsigned struct_utmp_sz; #endif #if !SANITIZER_ANDROID - extern unsigned struct_utmpx_sz; +extern unsigned struct_utmpx_sz; #endif - extern int map_fixed; +extern int map_fixed; - // ioctl arguments - struct __sanitizer_ifconf { - int ifc_len; - union { - void *ifcu_req; - } ifc_ifcu; +// ioctl arguments +struct __sanitizer_ifconf { + int ifc_len; + union { + void *ifcu_req; + } ifc_ifcu; #if SANITIZER_MAC - } __attribute__((packed)); +} __attribute__((packed)); #else - }; +}; #endif #if SANITIZER_LINUX && !SANITIZER_ANDROID @@ -932,519 +934,519 @@ struct __sanitizer_cookie_io_functions_t { #define IOC_SIZE(nr) (((nr) >> IOC_SIZESHIFT) & IOC_SIZEMASK) #endif - extern unsigned struct_ifreq_sz; - extern unsigned struct_termios_sz; - extern unsigned struct_winsize_sz; +extern unsigned struct_ifreq_sz; +extern unsigned struct_termios_sz; +extern unsigned struct_winsize_sz; #if SANITIZER_LINUX - extern unsigned struct_arpreq_sz; - extern unsigned struct_cdrom_msf_sz; - extern unsigned struct_cdrom_multisession_sz; - extern unsigned struct_cdrom_read_audio_sz; - extern unsigned struct_cdrom_subchnl_sz; - extern unsigned struct_cdrom_ti_sz; - extern unsigned struct_cdrom_tocentry_sz; - extern unsigned struct_cdrom_tochdr_sz; - extern unsigned struct_cdrom_volctrl_sz; - extern unsigned struct_ff_effect_sz; - extern unsigned struct_floppy_drive_params_sz; - extern unsigned struct_floppy_drive_struct_sz; - extern unsigned struct_floppy_fdc_state_sz; - extern unsigned struct_floppy_max_errors_sz; - extern unsigned struct_floppy_raw_cmd_sz; - extern unsigned struct_floppy_struct_sz; - extern unsigned struct_floppy_write_errors_sz; - extern unsigned struct_format_descr_sz; - extern unsigned struct_hd_driveid_sz; - extern unsigned struct_hd_geometry_sz; - extern unsigned struct_input_absinfo_sz; - extern unsigned struct_input_id_sz; - extern unsigned struct_mtpos_sz; - extern unsigned struct_termio_sz; - extern unsigned struct_vt_consize_sz; - extern unsigned struct_vt_sizes_sz; - extern unsigned struct_vt_stat_sz; +extern unsigned struct_arpreq_sz; +extern unsigned struct_cdrom_msf_sz; +extern unsigned struct_cdrom_multisession_sz; +extern unsigned struct_cdrom_read_audio_sz; +extern unsigned struct_cdrom_subchnl_sz; +extern unsigned struct_cdrom_ti_sz; +extern unsigned struct_cdrom_tocentry_sz; +extern unsigned struct_cdrom_tochdr_sz; +extern unsigned struct_cdrom_volctrl_sz; +extern unsigned struct_ff_effect_sz; +extern unsigned struct_floppy_drive_params_sz; +extern unsigned struct_floppy_drive_struct_sz; +extern unsigned struct_floppy_fdc_state_sz; +extern unsigned struct_floppy_max_errors_sz; +extern unsigned struct_floppy_raw_cmd_sz; +extern unsigned struct_floppy_struct_sz; +extern unsigned struct_floppy_write_errors_sz; +extern unsigned struct_format_descr_sz; +extern unsigned struct_hd_driveid_sz; +extern unsigned struct_hd_geometry_sz; +extern unsigned struct_input_absinfo_sz; +extern unsigned struct_input_id_sz; +extern unsigned struct_mtpos_sz; +extern unsigned struct_termio_sz; +extern unsigned struct_vt_consize_sz; +extern unsigned struct_vt_sizes_sz; +extern unsigned struct_vt_stat_sz; #endif // SANITIZER_LINUX #if SANITIZER_LINUX - extern unsigned struct_copr_buffer_sz; - extern unsigned struct_copr_debug_buf_sz; - extern unsigned struct_copr_msg_sz; - extern unsigned struct_midi_info_sz; - extern unsigned struct_mtget_sz; - extern unsigned struct_mtop_sz; - extern unsigned struct_rtentry_sz; - extern unsigned struct_sbi_instrument_sz; - extern unsigned struct_seq_event_rec_sz; - extern unsigned struct_synth_info_sz; - extern unsigned struct_vt_mode_sz; +extern unsigned struct_copr_buffer_sz; +extern unsigned struct_copr_debug_buf_sz; +extern unsigned struct_copr_msg_sz; +extern unsigned struct_midi_info_sz; +extern unsigned struct_mtget_sz; +extern unsigned struct_mtop_sz; +extern unsigned struct_rtentry_sz; +extern unsigned struct_sbi_instrument_sz; +extern unsigned struct_seq_event_rec_sz; +extern unsigned struct_synth_info_sz; +extern unsigned struct_vt_mode_sz; #endif // SANITIZER_LINUX #if SANITIZER_LINUX && !SANITIZER_ANDROID - extern unsigned struct_ax25_parms_struct_sz; - extern unsigned struct_cyclades_monitor_sz; - extern unsigned struct_input_keymap_entry_sz; - extern unsigned struct_ipx_config_data_sz; - extern unsigned struct_kbdiacrs_sz; - extern unsigned struct_kbentry_sz; - extern unsigned struct_kbkeycode_sz; - extern unsigned struct_kbsentry_sz; - extern unsigned struct_mtconfiginfo_sz; - extern unsigned struct_nr_parms_struct_sz; - extern unsigned struct_scc_modem_sz; - extern unsigned struct_scc_stat_sz; - extern unsigned struct_serial_multiport_struct_sz; - extern unsigned struct_serial_struct_sz; - extern unsigned struct_sockaddr_ax25_sz; - extern unsigned struct_unimapdesc_sz; - extern unsigned struct_unimapinit_sz; +extern unsigned struct_ax25_parms_struct_sz; +extern unsigned struct_cyclades_monitor_sz; +extern unsigned struct_input_keymap_entry_sz; +extern unsigned struct_ipx_config_data_sz; +extern unsigned struct_kbdiacrs_sz; +extern unsigned struct_kbentry_sz; +extern unsigned struct_kbkeycode_sz; +extern unsigned struct_kbsentry_sz; +extern unsigned struct_mtconfiginfo_sz; +extern unsigned struct_nr_parms_struct_sz; +extern unsigned struct_scc_modem_sz; +extern unsigned struct_scc_stat_sz; +extern unsigned struct_serial_multiport_struct_sz; +extern unsigned struct_serial_struct_sz; +extern unsigned struct_sockaddr_ax25_sz; +extern unsigned struct_unimapdesc_sz; +extern unsigned struct_unimapinit_sz; #endif // SANITIZER_LINUX && !SANITIZER_ANDROID - extern const unsigned long __sanitizer_bufsiz; +extern const unsigned long __sanitizer_bufsiz; #if SANITIZER_LINUX && !SANITIZER_ANDROID - extern unsigned struct_audio_buf_info_sz; - extern unsigned struct_ppp_stats_sz; +extern unsigned struct_audio_buf_info_sz; +extern unsigned struct_ppp_stats_sz; #endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID #if !SANITIZER_ANDROID && !SANITIZER_MAC - extern unsigned struct_sioc_sg_req_sz; - extern unsigned struct_sioc_vif_req_sz; -#endif - - // ioctl request identifiers - - // A special value to mark ioctls that are not present on the target platform, - // when it can not be determined without including any system headers. - extern const unsigned IOCTL_NOT_PRESENT; - - extern unsigned IOCTL_FIOASYNC; - extern unsigned IOCTL_FIOCLEX; - extern unsigned IOCTL_FIOGETOWN; - extern unsigned IOCTL_FIONBIO; - extern unsigned IOCTL_FIONCLEX; - extern unsigned IOCTL_FIOSETOWN; - extern unsigned IOCTL_SIOCADDMULTI; - extern unsigned IOCTL_SIOCATMARK; - extern unsigned IOCTL_SIOCDELMULTI; - extern unsigned IOCTL_SIOCGIFADDR; - extern unsigned IOCTL_SIOCGIFBRDADDR; - extern unsigned IOCTL_SIOCGIFCONF; - extern unsigned IOCTL_SIOCGIFDSTADDR; - extern unsigned IOCTL_SIOCGIFFLAGS; - extern unsigned IOCTL_SIOCGIFMETRIC; - extern unsigned IOCTL_SIOCGIFMTU; - extern unsigned IOCTL_SIOCGIFNETMASK; - extern unsigned IOCTL_SIOCGPGRP; - extern unsigned IOCTL_SIOCSIFADDR; - extern unsigned IOCTL_SIOCSIFBRDADDR; - extern unsigned IOCTL_SIOCSIFDSTADDR; - extern unsigned IOCTL_SIOCSIFFLAGS; - extern unsigned IOCTL_SIOCSIFMETRIC; - extern unsigned IOCTL_SIOCSIFMTU; - extern unsigned IOCTL_SIOCSIFNETMASK; - extern unsigned IOCTL_SIOCSPGRP; - extern unsigned IOCTL_TIOCCONS; - extern unsigned IOCTL_TIOCEXCL; - extern unsigned IOCTL_TIOCGETD; - extern unsigned IOCTL_TIOCGPGRP; - extern unsigned IOCTL_TIOCGWINSZ; - extern unsigned IOCTL_TIOCMBIC; - extern unsigned IOCTL_TIOCMBIS; - extern unsigned IOCTL_TIOCMGET; - extern unsigned IOCTL_TIOCMSET; - extern unsigned IOCTL_TIOCNOTTY; - extern unsigned IOCTL_TIOCNXCL; - extern unsigned IOCTL_TIOCOUTQ; - extern unsigned IOCTL_TIOCPKT; - extern unsigned IOCTL_TIOCSCTTY; - extern unsigned IOCTL_TIOCSETD; - extern unsigned IOCTL_TIOCSPGRP; - extern unsigned IOCTL_TIOCSTI; - extern unsigned IOCTL_TIOCSWINSZ; +extern unsigned struct_sioc_sg_req_sz; +extern unsigned struct_sioc_vif_req_sz; +#endif + +// ioctl request identifiers + +// A special value to mark ioctls that are not present on the target platform, +// when it can not be determined without including any system headers. +extern const unsigned IOCTL_NOT_PRESENT; + +extern unsigned IOCTL_FIOASYNC; +extern unsigned IOCTL_FIOCLEX; +extern unsigned IOCTL_FIOGETOWN; +extern unsigned IOCTL_FIONBIO; +extern unsigned IOCTL_FIONCLEX; +extern unsigned IOCTL_FIOSETOWN; +extern unsigned IOCTL_SIOCADDMULTI; +extern unsigned IOCTL_SIOCATMARK; +extern unsigned IOCTL_SIOCDELMULTI; +extern unsigned IOCTL_SIOCGIFADDR; +extern unsigned IOCTL_SIOCGIFBRDADDR; +extern unsigned IOCTL_SIOCGIFCONF; +extern unsigned IOCTL_SIOCGIFDSTADDR; +extern unsigned IOCTL_SIOCGIFFLAGS; +extern unsigned IOCTL_SIOCGIFMETRIC; +extern unsigned IOCTL_SIOCGIFMTU; +extern unsigned IOCTL_SIOCGIFNETMASK; +extern unsigned IOCTL_SIOCGPGRP; +extern unsigned IOCTL_SIOCSIFADDR; +extern unsigned IOCTL_SIOCSIFBRDADDR; +extern unsigned IOCTL_SIOCSIFDSTADDR; +extern unsigned IOCTL_SIOCSIFFLAGS; +extern unsigned IOCTL_SIOCSIFMETRIC; +extern unsigned IOCTL_SIOCSIFMTU; +extern unsigned IOCTL_SIOCSIFNETMASK; +extern unsigned IOCTL_SIOCSPGRP; +extern unsigned IOCTL_TIOCCONS; +extern unsigned IOCTL_TIOCEXCL; +extern unsigned IOCTL_TIOCGETD; +extern unsigned IOCTL_TIOCGPGRP; +extern unsigned IOCTL_TIOCGWINSZ; +extern unsigned IOCTL_TIOCMBIC; +extern unsigned IOCTL_TIOCMBIS; +extern unsigned IOCTL_TIOCMGET; +extern unsigned IOCTL_TIOCMSET; +extern unsigned IOCTL_TIOCNOTTY; +extern unsigned IOCTL_TIOCNXCL; +extern unsigned IOCTL_TIOCOUTQ; +extern unsigned IOCTL_TIOCPKT; +extern unsigned IOCTL_TIOCSCTTY; +extern unsigned IOCTL_TIOCSETD; +extern unsigned IOCTL_TIOCSPGRP; +extern unsigned IOCTL_TIOCSTI; +extern unsigned IOCTL_TIOCSWINSZ; #if SANITIZER_LINUX && !SANITIZER_ANDROID - extern unsigned IOCTL_SIOCGETSGCNT; - extern unsigned IOCTL_SIOCGETVIFCNT; +extern unsigned IOCTL_SIOCGETSGCNT; +extern unsigned IOCTL_SIOCGETVIFCNT; #endif #if SANITIZER_LINUX - extern unsigned IOCTL_EVIOCGABS; - extern unsigned IOCTL_EVIOCGBIT; - extern unsigned IOCTL_EVIOCGEFFECTS; - extern unsigned IOCTL_EVIOCGID; - extern unsigned IOCTL_EVIOCGKEY; - extern unsigned IOCTL_EVIOCGKEYCODE; - extern unsigned IOCTL_EVIOCGLED; - extern unsigned IOCTL_EVIOCGNAME; - extern unsigned IOCTL_EVIOCGPHYS; - extern unsigned IOCTL_EVIOCGRAB; - extern unsigned IOCTL_EVIOCGREP; - extern unsigned IOCTL_EVIOCGSND; - extern unsigned IOCTL_EVIOCGSW; - extern unsigned IOCTL_EVIOCGUNIQ; - extern unsigned IOCTL_EVIOCGVERSION; - extern unsigned IOCTL_EVIOCRMFF; - extern unsigned IOCTL_EVIOCSABS; - extern unsigned IOCTL_EVIOCSFF; - extern unsigned IOCTL_EVIOCSKEYCODE; - extern unsigned IOCTL_EVIOCSREP; - extern unsigned IOCTL_BLKFLSBUF; - extern unsigned IOCTL_BLKGETSIZE; - extern unsigned IOCTL_BLKRAGET; - extern unsigned IOCTL_BLKRASET; - extern unsigned IOCTL_BLKROGET; - extern unsigned IOCTL_BLKROSET; - extern unsigned IOCTL_BLKRRPART; - extern unsigned IOCTL_CDROMAUDIOBUFSIZ; - extern unsigned IOCTL_CDROMEJECT; - extern unsigned IOCTL_CDROMEJECT_SW; - extern unsigned IOCTL_CDROMMULTISESSION; - extern unsigned IOCTL_CDROMPAUSE; - extern unsigned IOCTL_CDROMPLAYMSF; - extern unsigned IOCTL_CDROMPLAYTRKIND; - extern unsigned IOCTL_CDROMREADAUDIO; - extern unsigned IOCTL_CDROMREADCOOKED; - extern unsigned IOCTL_CDROMREADMODE1; - extern unsigned IOCTL_CDROMREADMODE2; - extern unsigned IOCTL_CDROMREADRAW; - extern unsigned IOCTL_CDROMREADTOCENTRY; - extern unsigned IOCTL_CDROMREADTOCHDR; - extern unsigned IOCTL_CDROMRESET; - extern unsigned IOCTL_CDROMRESUME; - extern unsigned IOCTL_CDROMSEEK; - extern unsigned IOCTL_CDROMSTART; - extern unsigned IOCTL_CDROMSTOP; - extern unsigned IOCTL_CDROMSUBCHNL; - extern unsigned IOCTL_CDROMVOLCTRL; - extern unsigned IOCTL_CDROMVOLREAD; - extern unsigned IOCTL_CDROM_GET_UPC; - extern unsigned IOCTL_FDCLRPRM; - extern unsigned IOCTL_FDDEFPRM; - extern unsigned IOCTL_FDFLUSH; - extern unsigned IOCTL_FDFMTBEG; - extern unsigned IOCTL_FDFMTEND; - extern unsigned IOCTL_FDFMTTRK; - extern unsigned IOCTL_FDGETDRVPRM; - extern unsigned IOCTL_FDGETDRVSTAT; - extern unsigned IOCTL_FDGETDRVTYP; - extern unsigned IOCTL_FDGETFDCSTAT; - extern unsigned IOCTL_FDGETMAXERRS; - extern unsigned IOCTL_FDGETPRM; - extern unsigned IOCTL_FDMSGOFF; - extern unsigned IOCTL_FDMSGON; - extern unsigned IOCTL_FDPOLLDRVSTAT; - extern unsigned IOCTL_FDRAWCMD; - extern unsigned IOCTL_FDRESET; - extern unsigned IOCTL_FDSETDRVPRM; - extern unsigned IOCTL_FDSETEMSGTRESH; - extern unsigned IOCTL_FDSETMAXERRS; - extern unsigned IOCTL_FDSETPRM; - extern unsigned IOCTL_FDTWADDLE; - extern unsigned IOCTL_FDWERRORCLR; - extern unsigned IOCTL_FDWERRORGET; - extern unsigned IOCTL_HDIO_DRIVE_CMD; - extern unsigned IOCTL_HDIO_GETGEO; - extern unsigned IOCTL_HDIO_GET_32BIT; - extern unsigned IOCTL_HDIO_GET_DMA; - extern unsigned IOCTL_HDIO_GET_IDENTITY; - extern unsigned IOCTL_HDIO_GET_KEEPSETTINGS; - extern unsigned IOCTL_HDIO_GET_MULTCOUNT; - extern unsigned IOCTL_HDIO_GET_NOWERR; - extern unsigned IOCTL_HDIO_GET_UNMASKINTR; - extern unsigned IOCTL_HDIO_SET_32BIT; - extern unsigned IOCTL_HDIO_SET_DMA; - extern unsigned IOCTL_HDIO_SET_KEEPSETTINGS; - extern unsigned IOCTL_HDIO_SET_MULTCOUNT; - extern unsigned IOCTL_HDIO_SET_NOWERR; - extern unsigned IOCTL_HDIO_SET_UNMASKINTR; - extern unsigned IOCTL_MTIOCPOS; - extern unsigned IOCTL_PPPIOCGASYNCMAP; - extern unsigned IOCTL_PPPIOCGDEBUG; - extern unsigned IOCTL_PPPIOCGFLAGS; - extern unsigned IOCTL_PPPIOCGUNIT; - extern unsigned IOCTL_PPPIOCGXASYNCMAP; - extern unsigned IOCTL_PPPIOCSASYNCMAP; - extern unsigned IOCTL_PPPIOCSDEBUG; - extern unsigned IOCTL_PPPIOCSFLAGS; - extern unsigned IOCTL_PPPIOCSMAXCID; - extern unsigned IOCTL_PPPIOCSMRU; - extern unsigned IOCTL_PPPIOCSXASYNCMAP; - extern unsigned IOCTL_SIOCDARP; - extern unsigned IOCTL_SIOCDRARP; - extern unsigned IOCTL_SIOCGARP; - extern unsigned IOCTL_SIOCGIFENCAP; - extern unsigned IOCTL_SIOCGIFHWADDR; - extern unsigned IOCTL_SIOCGIFMAP; - extern unsigned IOCTL_SIOCGIFMEM; - extern unsigned IOCTL_SIOCGIFNAME; - extern unsigned IOCTL_SIOCGIFSLAVE; - extern unsigned IOCTL_SIOCGRARP; - extern unsigned IOCTL_SIOCGSTAMP; - extern unsigned IOCTL_SIOCSARP; - extern unsigned IOCTL_SIOCSIFENCAP; - extern unsigned IOCTL_SIOCSIFHWADDR; - extern unsigned IOCTL_SIOCSIFLINK; - extern unsigned IOCTL_SIOCSIFMAP; - extern unsigned IOCTL_SIOCSIFMEM; - extern unsigned IOCTL_SIOCSIFSLAVE; - extern unsigned IOCTL_SIOCSRARP; - extern unsigned IOCTL_SNDCTL_COPR_HALT; - extern unsigned IOCTL_SNDCTL_COPR_LOAD; - extern unsigned IOCTL_SNDCTL_COPR_RCODE; - extern unsigned IOCTL_SNDCTL_COPR_RCVMSG; - extern unsigned IOCTL_SNDCTL_COPR_RDATA; - extern unsigned IOCTL_SNDCTL_COPR_RESET; - extern unsigned IOCTL_SNDCTL_COPR_RUN; - extern unsigned IOCTL_SNDCTL_COPR_SENDMSG; - extern unsigned IOCTL_SNDCTL_COPR_WCODE; - extern unsigned IOCTL_SNDCTL_COPR_WDATA; - extern unsigned IOCTL_TCFLSH; - extern unsigned IOCTL_TCGETA; - extern unsigned IOCTL_TCGETS; - extern unsigned IOCTL_TCSBRK; - extern unsigned IOCTL_TCSBRKP; - extern unsigned IOCTL_TCSETA; - extern unsigned IOCTL_TCSETAF; - extern unsigned IOCTL_TCSETAW; - extern unsigned IOCTL_TCSETS; - extern unsigned IOCTL_TCSETSF; - extern unsigned IOCTL_TCSETSW; - extern unsigned IOCTL_TCXONC; - extern unsigned IOCTL_TIOCGLCKTRMIOS; - extern unsigned IOCTL_TIOCGSOFTCAR; - extern unsigned IOCTL_TIOCINQ; - extern unsigned IOCTL_TIOCLINUX; - extern unsigned IOCTL_TIOCSERCONFIG; - extern unsigned IOCTL_TIOCSERGETLSR; - extern unsigned IOCTL_TIOCSERGWILD; - extern unsigned IOCTL_TIOCSERSWILD; - extern unsigned IOCTL_TIOCSLCKTRMIOS; - extern unsigned IOCTL_TIOCSSOFTCAR; - extern unsigned IOCTL_VT_DISALLOCATE; - extern unsigned IOCTL_VT_GETSTATE; - extern unsigned IOCTL_VT_RESIZE; - extern unsigned IOCTL_VT_RESIZEX; - extern unsigned IOCTL_VT_SENDSIG; - extern unsigned IOCTL_MTIOCGET; - extern unsigned IOCTL_MTIOCTOP; - extern unsigned IOCTL_SIOCADDRT; - extern unsigned IOCTL_SIOCDELRT; - extern unsigned IOCTL_SNDCTL_DSP_GETBLKSIZE; - extern unsigned IOCTL_SNDCTL_DSP_GETFMTS; - extern unsigned IOCTL_SNDCTL_DSP_NONBLOCK; - extern unsigned IOCTL_SNDCTL_DSP_POST; - extern unsigned IOCTL_SNDCTL_DSP_RESET; - extern unsigned IOCTL_SNDCTL_DSP_SETFMT; - extern unsigned IOCTL_SNDCTL_DSP_SETFRAGMENT; - extern unsigned IOCTL_SNDCTL_DSP_SPEED; - extern unsigned IOCTL_SNDCTL_DSP_STEREO; - extern unsigned IOCTL_SNDCTL_DSP_SUBDIVIDE; - extern unsigned IOCTL_SNDCTL_DSP_SYNC; - extern unsigned IOCTL_SNDCTL_FM_4OP_ENABLE; - extern unsigned IOCTL_SNDCTL_FM_LOAD_INSTR; - extern unsigned IOCTL_SNDCTL_MIDI_INFO; - extern unsigned IOCTL_SNDCTL_MIDI_PRETIME; - extern unsigned IOCTL_SNDCTL_SEQ_CTRLRATE; - extern unsigned IOCTL_SNDCTL_SEQ_GETINCOUNT; - extern unsigned IOCTL_SNDCTL_SEQ_GETOUTCOUNT; - extern unsigned IOCTL_SNDCTL_SEQ_NRMIDIS; - extern unsigned IOCTL_SNDCTL_SEQ_NRSYNTHS; - extern unsigned IOCTL_SNDCTL_SEQ_OUTOFBAND; - extern unsigned IOCTL_SNDCTL_SEQ_PANIC; - extern unsigned IOCTL_SNDCTL_SEQ_PERCMODE; - extern unsigned IOCTL_SNDCTL_SEQ_RESET; - extern unsigned IOCTL_SNDCTL_SEQ_RESETSAMPLES; - extern unsigned IOCTL_SNDCTL_SEQ_SYNC; - extern unsigned IOCTL_SNDCTL_SEQ_TESTMIDI; - extern unsigned IOCTL_SNDCTL_SEQ_THRESHOLD; - extern unsigned IOCTL_SNDCTL_SYNTH_INFO; - extern unsigned IOCTL_SNDCTL_SYNTH_MEMAVL; - extern unsigned IOCTL_SNDCTL_TMR_CONTINUE; - extern unsigned IOCTL_SNDCTL_TMR_METRONOME; - extern unsigned IOCTL_SNDCTL_TMR_SELECT; - extern unsigned IOCTL_SNDCTL_TMR_SOURCE; - extern unsigned IOCTL_SNDCTL_TMR_START; - extern unsigned IOCTL_SNDCTL_TMR_STOP; - extern unsigned IOCTL_SNDCTL_TMR_TEMPO; - extern unsigned IOCTL_SNDCTL_TMR_TIMEBASE; - extern unsigned IOCTL_SOUND_MIXER_READ_ALTPCM; - extern unsigned IOCTL_SOUND_MIXER_READ_BASS; - extern unsigned IOCTL_SOUND_MIXER_READ_CAPS; - extern unsigned IOCTL_SOUND_MIXER_READ_CD; - extern unsigned IOCTL_SOUND_MIXER_READ_DEVMASK; - extern unsigned IOCTL_SOUND_MIXER_READ_ENHANCE; - extern unsigned IOCTL_SOUND_MIXER_READ_IGAIN; - extern unsigned IOCTL_SOUND_MIXER_READ_IMIX; - extern unsigned IOCTL_SOUND_MIXER_READ_LINE1; - extern unsigned IOCTL_SOUND_MIXER_READ_LINE2; - extern unsigned IOCTL_SOUND_MIXER_READ_LINE3; - extern unsigned IOCTL_SOUND_MIXER_READ_LINE; - extern unsigned IOCTL_SOUND_MIXER_READ_LOUD; - extern unsigned IOCTL_SOUND_MIXER_READ_MIC; - extern unsigned IOCTL_SOUND_MIXER_READ_MUTE; - extern unsigned IOCTL_SOUND_MIXER_READ_OGAIN; - extern unsigned IOCTL_SOUND_MIXER_READ_PCM; - extern unsigned IOCTL_SOUND_MIXER_READ_RECLEV; - extern unsigned IOCTL_SOUND_MIXER_READ_RECMASK; - extern unsigned IOCTL_SOUND_MIXER_READ_RECSRC; - extern unsigned IOCTL_SOUND_MIXER_READ_SPEAKER; - extern unsigned IOCTL_SOUND_MIXER_READ_STEREODEVS; - extern unsigned IOCTL_SOUND_MIXER_READ_SYNTH; - extern unsigned IOCTL_SOUND_MIXER_READ_TREBLE; - extern unsigned IOCTL_SOUND_MIXER_READ_VOLUME; - extern unsigned IOCTL_SOUND_MIXER_WRITE_ALTPCM; - extern unsigned IOCTL_SOUND_MIXER_WRITE_BASS; - extern unsigned IOCTL_SOUND_MIXER_WRITE_CD; - extern unsigned IOCTL_SOUND_MIXER_WRITE_ENHANCE; - extern unsigned IOCTL_SOUND_MIXER_WRITE_IGAIN; - extern unsigned IOCTL_SOUND_MIXER_WRITE_IMIX; - extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE1; - extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE2; - extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE3; - extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE; - extern unsigned IOCTL_SOUND_MIXER_WRITE_LOUD; - extern unsigned IOCTL_SOUND_MIXER_WRITE_MIC; - extern unsigned IOCTL_SOUND_MIXER_WRITE_MUTE; - extern unsigned IOCTL_SOUND_MIXER_WRITE_OGAIN; - extern unsigned IOCTL_SOUND_MIXER_WRITE_PCM; - extern unsigned IOCTL_SOUND_MIXER_WRITE_RECLEV; - extern unsigned IOCTL_SOUND_MIXER_WRITE_RECSRC; - extern unsigned IOCTL_SOUND_MIXER_WRITE_SPEAKER; - extern unsigned IOCTL_SOUND_MIXER_WRITE_SYNTH; - extern unsigned IOCTL_SOUND_MIXER_WRITE_TREBLE; - extern unsigned IOCTL_SOUND_MIXER_WRITE_VOLUME; - extern unsigned IOCTL_SOUND_PCM_READ_BITS; - extern unsigned IOCTL_SOUND_PCM_READ_CHANNELS; - extern unsigned IOCTL_SOUND_PCM_READ_FILTER; - extern unsigned IOCTL_SOUND_PCM_READ_RATE; - extern unsigned IOCTL_SOUND_PCM_WRITE_CHANNELS; - extern unsigned IOCTL_SOUND_PCM_WRITE_FILTER; - extern unsigned IOCTL_VT_ACTIVATE; - extern unsigned IOCTL_VT_GETMODE; - extern unsigned IOCTL_VT_OPENQRY; - extern unsigned IOCTL_VT_RELDISP; - extern unsigned IOCTL_VT_SETMODE; - extern unsigned IOCTL_VT_WAITACTIVE; +extern unsigned IOCTL_EVIOCGABS; +extern unsigned IOCTL_EVIOCGBIT; +extern unsigned IOCTL_EVIOCGEFFECTS; +extern unsigned IOCTL_EVIOCGID; +extern unsigned IOCTL_EVIOCGKEY; +extern unsigned IOCTL_EVIOCGKEYCODE; +extern unsigned IOCTL_EVIOCGLED; +extern unsigned IOCTL_EVIOCGNAME; +extern unsigned IOCTL_EVIOCGPHYS; +extern unsigned IOCTL_EVIOCGRAB; +extern unsigned IOCTL_EVIOCGREP; +extern unsigned IOCTL_EVIOCGSND; +extern unsigned IOCTL_EVIOCGSW; +extern unsigned IOCTL_EVIOCGUNIQ; +extern unsigned IOCTL_EVIOCGVERSION; +extern unsigned IOCTL_EVIOCRMFF; +extern unsigned IOCTL_EVIOCSABS; +extern unsigned IOCTL_EVIOCSFF; +extern unsigned IOCTL_EVIOCSKEYCODE; +extern unsigned IOCTL_EVIOCSREP; +extern unsigned IOCTL_BLKFLSBUF; +extern unsigned IOCTL_BLKGETSIZE; +extern unsigned IOCTL_BLKRAGET; +extern unsigned IOCTL_BLKRASET; +extern unsigned IOCTL_BLKROGET; +extern unsigned IOCTL_BLKROSET; +extern unsigned IOCTL_BLKRRPART; +extern unsigned IOCTL_CDROMAUDIOBUFSIZ; +extern unsigned IOCTL_CDROMEJECT; +extern unsigned IOCTL_CDROMEJECT_SW; +extern unsigned IOCTL_CDROMMULTISESSION; +extern unsigned IOCTL_CDROMPAUSE; +extern unsigned IOCTL_CDROMPLAYMSF; +extern unsigned IOCTL_CDROMPLAYTRKIND; +extern unsigned IOCTL_CDROMREADAUDIO; +extern unsigned IOCTL_CDROMREADCOOKED; +extern unsigned IOCTL_CDROMREADMODE1; +extern unsigned IOCTL_CDROMREADMODE2; +extern unsigned IOCTL_CDROMREADRAW; +extern unsigned IOCTL_CDROMREADTOCENTRY; +extern unsigned IOCTL_CDROMREADTOCHDR; +extern unsigned IOCTL_CDROMRESET; +extern unsigned IOCTL_CDROMRESUME; +extern unsigned IOCTL_CDROMSEEK; +extern unsigned IOCTL_CDROMSTART; +extern unsigned IOCTL_CDROMSTOP; +extern unsigned IOCTL_CDROMSUBCHNL; +extern unsigned IOCTL_CDROMVOLCTRL; +extern unsigned IOCTL_CDROMVOLREAD; +extern unsigned IOCTL_CDROM_GET_UPC; +extern unsigned IOCTL_FDCLRPRM; +extern unsigned IOCTL_FDDEFPRM; +extern unsigned IOCTL_FDFLUSH; +extern unsigned IOCTL_FDFMTBEG; +extern unsigned IOCTL_FDFMTEND; +extern unsigned IOCTL_FDFMTTRK; +extern unsigned IOCTL_FDGETDRVPRM; +extern unsigned IOCTL_FDGETDRVSTAT; +extern unsigned IOCTL_FDGETDRVTYP; +extern unsigned IOCTL_FDGETFDCSTAT; +extern unsigned IOCTL_FDGETMAXERRS; +extern unsigned IOCTL_FDGETPRM; +extern unsigned IOCTL_FDMSGOFF; +extern unsigned IOCTL_FDMSGON; +extern unsigned IOCTL_FDPOLLDRVSTAT; +extern unsigned IOCTL_FDRAWCMD; +extern unsigned IOCTL_FDRESET; +extern unsigned IOCTL_FDSETDRVPRM; +extern unsigned IOCTL_FDSETEMSGTRESH; +extern unsigned IOCTL_FDSETMAXERRS; +extern unsigned IOCTL_FDSETPRM; +extern unsigned IOCTL_FDTWADDLE; +extern unsigned IOCTL_FDWERRORCLR; +extern unsigned IOCTL_FDWERRORGET; +extern unsigned IOCTL_HDIO_DRIVE_CMD; +extern unsigned IOCTL_HDIO_GETGEO; +extern unsigned IOCTL_HDIO_GET_32BIT; +extern unsigned IOCTL_HDIO_GET_DMA; +extern unsigned IOCTL_HDIO_GET_IDENTITY; +extern unsigned IOCTL_HDIO_GET_KEEPSETTINGS; +extern unsigned IOCTL_HDIO_GET_MULTCOUNT; +extern unsigned IOCTL_HDIO_GET_NOWERR; +extern unsigned IOCTL_HDIO_GET_UNMASKINTR; +extern unsigned IOCTL_HDIO_SET_32BIT; +extern unsigned IOCTL_HDIO_SET_DMA; +extern unsigned IOCTL_HDIO_SET_KEEPSETTINGS; +extern unsigned IOCTL_HDIO_SET_MULTCOUNT; +extern unsigned IOCTL_HDIO_SET_NOWERR; +extern unsigned IOCTL_HDIO_SET_UNMASKINTR; +extern unsigned IOCTL_MTIOCPOS; +extern unsigned IOCTL_PPPIOCGASYNCMAP; +extern unsigned IOCTL_PPPIOCGDEBUG; +extern unsigned IOCTL_PPPIOCGFLAGS; +extern unsigned IOCTL_PPPIOCGUNIT; +extern unsigned IOCTL_PPPIOCGXASYNCMAP; +extern unsigned IOCTL_PPPIOCSASYNCMAP; +extern unsigned IOCTL_PPPIOCSDEBUG; +extern unsigned IOCTL_PPPIOCSFLAGS; +extern unsigned IOCTL_PPPIOCSMAXCID; +extern unsigned IOCTL_PPPIOCSMRU; +extern unsigned IOCTL_PPPIOCSXASYNCMAP; +extern unsigned IOCTL_SIOCDARP; +extern unsigned IOCTL_SIOCDRARP; +extern unsigned IOCTL_SIOCGARP; +extern unsigned IOCTL_SIOCGIFENCAP; +extern unsigned IOCTL_SIOCGIFHWADDR; +extern unsigned IOCTL_SIOCGIFMAP; +extern unsigned IOCTL_SIOCGIFMEM; +extern unsigned IOCTL_SIOCGIFNAME; +extern unsigned IOCTL_SIOCGIFSLAVE; +extern unsigned IOCTL_SIOCGRARP; +extern unsigned IOCTL_SIOCGSTAMP; +extern unsigned IOCTL_SIOCSARP; +extern unsigned IOCTL_SIOCSIFENCAP; +extern unsigned IOCTL_SIOCSIFHWADDR; +extern unsigned IOCTL_SIOCSIFLINK; +extern unsigned IOCTL_SIOCSIFMAP; +extern unsigned IOCTL_SIOCSIFMEM; +extern unsigned IOCTL_SIOCSIFSLAVE; +extern unsigned IOCTL_SIOCSRARP; +extern unsigned IOCTL_SNDCTL_COPR_HALT; +extern unsigned IOCTL_SNDCTL_COPR_LOAD; +extern unsigned IOCTL_SNDCTL_COPR_RCODE; +extern unsigned IOCTL_SNDCTL_COPR_RCVMSG; +extern unsigned IOCTL_SNDCTL_COPR_RDATA; +extern unsigned IOCTL_SNDCTL_COPR_RESET; +extern unsigned IOCTL_SNDCTL_COPR_RUN; +extern unsigned IOCTL_SNDCTL_COPR_SENDMSG; +extern unsigned IOCTL_SNDCTL_COPR_WCODE; +extern unsigned IOCTL_SNDCTL_COPR_WDATA; +extern unsigned IOCTL_TCFLSH; +extern unsigned IOCTL_TCGETA; +extern unsigned IOCTL_TCGETS; +extern unsigned IOCTL_TCSBRK; +extern unsigned IOCTL_TCSBRKP; +extern unsigned IOCTL_TCSETA; +extern unsigned IOCTL_TCSETAF; +extern unsigned IOCTL_TCSETAW; +extern unsigned IOCTL_TCSETS; +extern unsigned IOCTL_TCSETSF; +extern unsigned IOCTL_TCSETSW; +extern unsigned IOCTL_TCXONC; +extern unsigned IOCTL_TIOCGLCKTRMIOS; +extern unsigned IOCTL_TIOCGSOFTCAR; +extern unsigned IOCTL_TIOCINQ; +extern unsigned IOCTL_TIOCLINUX; +extern unsigned IOCTL_TIOCSERCONFIG; +extern unsigned IOCTL_TIOCSERGETLSR; +extern unsigned IOCTL_TIOCSERGWILD; +extern unsigned IOCTL_TIOCSERSWILD; +extern unsigned IOCTL_TIOCSLCKTRMIOS; +extern unsigned IOCTL_TIOCSSOFTCAR; +extern unsigned IOCTL_VT_DISALLOCATE; +extern unsigned IOCTL_VT_GETSTATE; +extern unsigned IOCTL_VT_RESIZE; +extern unsigned IOCTL_VT_RESIZEX; +extern unsigned IOCTL_VT_SENDSIG; +extern unsigned IOCTL_MTIOCGET; +extern unsigned IOCTL_MTIOCTOP; +extern unsigned IOCTL_SIOCADDRT; +extern unsigned IOCTL_SIOCDELRT; +extern unsigned IOCTL_SNDCTL_DSP_GETBLKSIZE; +extern unsigned IOCTL_SNDCTL_DSP_GETFMTS; +extern unsigned IOCTL_SNDCTL_DSP_NONBLOCK; +extern unsigned IOCTL_SNDCTL_DSP_POST; +extern unsigned IOCTL_SNDCTL_DSP_RESET; +extern unsigned IOCTL_SNDCTL_DSP_SETFMT; +extern unsigned IOCTL_SNDCTL_DSP_SETFRAGMENT; +extern unsigned IOCTL_SNDCTL_DSP_SPEED; +extern unsigned IOCTL_SNDCTL_DSP_STEREO; +extern unsigned IOCTL_SNDCTL_DSP_SUBDIVIDE; +extern unsigned IOCTL_SNDCTL_DSP_SYNC; +extern unsigned IOCTL_SNDCTL_FM_4OP_ENABLE; +extern unsigned IOCTL_SNDCTL_FM_LOAD_INSTR; +extern unsigned IOCTL_SNDCTL_MIDI_INFO; +extern unsigned IOCTL_SNDCTL_MIDI_PRETIME; +extern unsigned IOCTL_SNDCTL_SEQ_CTRLRATE; +extern unsigned IOCTL_SNDCTL_SEQ_GETINCOUNT; +extern unsigned IOCTL_SNDCTL_SEQ_GETOUTCOUNT; +extern unsigned IOCTL_SNDCTL_SEQ_NRMIDIS; +extern unsigned IOCTL_SNDCTL_SEQ_NRSYNTHS; +extern unsigned IOCTL_SNDCTL_SEQ_OUTOFBAND; +extern unsigned IOCTL_SNDCTL_SEQ_PANIC; +extern unsigned IOCTL_SNDCTL_SEQ_PERCMODE; +extern unsigned IOCTL_SNDCTL_SEQ_RESET; +extern unsigned IOCTL_SNDCTL_SEQ_RESETSAMPLES; +extern unsigned IOCTL_SNDCTL_SEQ_SYNC; +extern unsigned IOCTL_SNDCTL_SEQ_TESTMIDI; +extern unsigned IOCTL_SNDCTL_SEQ_THRESHOLD; +extern unsigned IOCTL_SNDCTL_SYNTH_INFO; +extern unsigned IOCTL_SNDCTL_SYNTH_MEMAVL; +extern unsigned IOCTL_SNDCTL_TMR_CONTINUE; +extern unsigned IOCTL_SNDCTL_TMR_METRONOME; +extern unsigned IOCTL_SNDCTL_TMR_SELECT; +extern unsigned IOCTL_SNDCTL_TMR_SOURCE; +extern unsigned IOCTL_SNDCTL_TMR_START; +extern unsigned IOCTL_SNDCTL_TMR_STOP; +extern unsigned IOCTL_SNDCTL_TMR_TEMPO; +extern unsigned IOCTL_SNDCTL_TMR_TIMEBASE; +extern unsigned IOCTL_SOUND_MIXER_READ_ALTPCM; +extern unsigned IOCTL_SOUND_MIXER_READ_BASS; +extern unsigned IOCTL_SOUND_MIXER_READ_CAPS; +extern unsigned IOCTL_SOUND_MIXER_READ_CD; +extern unsigned IOCTL_SOUND_MIXER_READ_DEVMASK; +extern unsigned IOCTL_SOUND_MIXER_READ_ENHANCE; +extern unsigned IOCTL_SOUND_MIXER_READ_IGAIN; +extern unsigned IOCTL_SOUND_MIXER_READ_IMIX; +extern unsigned IOCTL_SOUND_MIXER_READ_LINE1; +extern unsigned IOCTL_SOUND_MIXER_READ_LINE2; +extern unsigned IOCTL_SOUND_MIXER_READ_LINE3; +extern unsigned IOCTL_SOUND_MIXER_READ_LINE; +extern unsigned IOCTL_SOUND_MIXER_READ_LOUD; +extern unsigned IOCTL_SOUND_MIXER_READ_MIC; +extern unsigned IOCTL_SOUND_MIXER_READ_MUTE; +extern unsigned IOCTL_SOUND_MIXER_READ_OGAIN; +extern unsigned IOCTL_SOUND_MIXER_READ_PCM; +extern unsigned IOCTL_SOUND_MIXER_READ_RECLEV; +extern unsigned IOCTL_SOUND_MIXER_READ_RECMASK; +extern unsigned IOCTL_SOUND_MIXER_READ_RECSRC; +extern unsigned IOCTL_SOUND_MIXER_READ_SPEAKER; +extern unsigned IOCTL_SOUND_MIXER_READ_STEREODEVS; +extern unsigned IOCTL_SOUND_MIXER_READ_SYNTH; +extern unsigned IOCTL_SOUND_MIXER_READ_TREBLE; +extern unsigned IOCTL_SOUND_MIXER_READ_VOLUME; +extern unsigned IOCTL_SOUND_MIXER_WRITE_ALTPCM; +extern unsigned IOCTL_SOUND_MIXER_WRITE_BASS; +extern unsigned IOCTL_SOUND_MIXER_WRITE_CD; +extern unsigned IOCTL_SOUND_MIXER_WRITE_ENHANCE; +extern unsigned IOCTL_SOUND_MIXER_WRITE_IGAIN; +extern unsigned IOCTL_SOUND_MIXER_WRITE_IMIX; +extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE1; +extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE2; +extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE3; +extern unsigned IOCTL_SOUND_MIXER_WRITE_LINE; +extern unsigned IOCTL_SOUND_MIXER_WRITE_LOUD; +extern unsigned IOCTL_SOUND_MIXER_WRITE_MIC; +extern unsigned IOCTL_SOUND_MIXER_WRITE_MUTE; +extern unsigned IOCTL_SOUND_MIXER_WRITE_OGAIN; +extern unsigned IOCTL_SOUND_MIXER_WRITE_PCM; +extern unsigned IOCTL_SOUND_MIXER_WRITE_RECLEV; +extern unsigned IOCTL_SOUND_MIXER_WRITE_RECSRC; +extern unsigned IOCTL_SOUND_MIXER_WRITE_SPEAKER; +extern unsigned IOCTL_SOUND_MIXER_WRITE_SYNTH; +extern unsigned IOCTL_SOUND_MIXER_WRITE_TREBLE; +extern unsigned IOCTL_SOUND_MIXER_WRITE_VOLUME; +extern unsigned IOCTL_SOUND_PCM_READ_BITS; +extern unsigned IOCTL_SOUND_PCM_READ_CHANNELS; +extern unsigned IOCTL_SOUND_PCM_READ_FILTER; +extern unsigned IOCTL_SOUND_PCM_READ_RATE; +extern unsigned IOCTL_SOUND_PCM_WRITE_CHANNELS; +extern unsigned IOCTL_SOUND_PCM_WRITE_FILTER; +extern unsigned IOCTL_VT_ACTIVATE; +extern unsigned IOCTL_VT_GETMODE; +extern unsigned IOCTL_VT_OPENQRY; +extern unsigned IOCTL_VT_RELDISP; +extern unsigned IOCTL_VT_SETMODE; +extern unsigned IOCTL_VT_WAITACTIVE; #endif // SANITIZER_LINUX #if SANITIZER_LINUX && !SANITIZER_ANDROID - extern unsigned IOCTL_CYGETDEFTHRESH; - extern unsigned IOCTL_CYGETDEFTIMEOUT; - extern unsigned IOCTL_CYGETMON; - extern unsigned IOCTL_CYGETTHRESH; - extern unsigned IOCTL_CYGETTIMEOUT; - extern unsigned IOCTL_CYSETDEFTHRESH; - extern unsigned IOCTL_CYSETDEFTIMEOUT; - extern unsigned IOCTL_CYSETTHRESH; - extern unsigned IOCTL_CYSETTIMEOUT; - extern unsigned IOCTL_EQL_EMANCIPATE; - extern unsigned IOCTL_EQL_ENSLAVE; - extern unsigned IOCTL_EQL_GETMASTRCFG; - extern unsigned IOCTL_EQL_GETSLAVECFG; - extern unsigned IOCTL_EQL_SETMASTRCFG; - extern unsigned IOCTL_EQL_SETSLAVECFG; - extern unsigned IOCTL_EVIOCGKEYCODE_V2; - extern unsigned IOCTL_EVIOCGPROP; - extern unsigned IOCTL_EVIOCSKEYCODE_V2; - extern unsigned IOCTL_FS_IOC_GETFLAGS; - extern unsigned IOCTL_FS_IOC_GETVERSION; - extern unsigned IOCTL_FS_IOC_SETFLAGS; - extern unsigned IOCTL_FS_IOC_SETVERSION; - extern unsigned IOCTL_GIO_CMAP; - extern unsigned IOCTL_GIO_FONT; - extern unsigned IOCTL_GIO_UNIMAP; - extern unsigned IOCTL_GIO_UNISCRNMAP; - extern unsigned IOCTL_KDADDIO; - extern unsigned IOCTL_KDDELIO; - extern unsigned IOCTL_KDGETKEYCODE; - extern unsigned IOCTL_KDGKBDIACR; - extern unsigned IOCTL_KDGKBENT; - extern unsigned IOCTL_KDGKBLED; - extern unsigned IOCTL_KDGKBMETA; - extern unsigned IOCTL_KDGKBSENT; - extern unsigned IOCTL_KDMAPDISP; - extern unsigned IOCTL_KDSETKEYCODE; - extern unsigned IOCTL_KDSIGACCEPT; - extern unsigned IOCTL_KDSKBDIACR; - extern unsigned IOCTL_KDSKBENT; - extern unsigned IOCTL_KDSKBLED; - extern unsigned IOCTL_KDSKBMETA; - extern unsigned IOCTL_KDSKBSENT; - extern unsigned IOCTL_KDUNMAPDISP; - extern unsigned IOCTL_LPABORT; - extern unsigned IOCTL_LPABORTOPEN; - extern unsigned IOCTL_LPCAREFUL; - extern unsigned IOCTL_LPCHAR; - extern unsigned IOCTL_LPGETIRQ; - extern unsigned IOCTL_LPGETSTATUS; - extern unsigned IOCTL_LPRESET; - extern unsigned IOCTL_LPSETIRQ; - extern unsigned IOCTL_LPTIME; - extern unsigned IOCTL_LPWAIT; - extern unsigned IOCTL_MTIOCGETCONFIG; - extern unsigned IOCTL_MTIOCSETCONFIG; - extern unsigned IOCTL_PIO_CMAP; - extern unsigned IOCTL_PIO_FONT; - extern unsigned IOCTL_PIO_UNIMAP; - extern unsigned IOCTL_PIO_UNIMAPCLR; - extern unsigned IOCTL_PIO_UNISCRNMAP; - extern unsigned IOCTL_SCSI_IOCTL_GET_IDLUN; - extern unsigned IOCTL_SCSI_IOCTL_PROBE_HOST; - extern unsigned IOCTL_SCSI_IOCTL_TAGGED_DISABLE; - extern unsigned IOCTL_SCSI_IOCTL_TAGGED_ENABLE; - extern unsigned IOCTL_SIOCAIPXITFCRT; - extern unsigned IOCTL_SIOCAIPXPRISLT; - extern unsigned IOCTL_SIOCAX25ADDUID; - extern unsigned IOCTL_SIOCAX25DELUID; - extern unsigned IOCTL_SIOCAX25GETPARMS; - extern unsigned IOCTL_SIOCAX25GETUID; - extern unsigned IOCTL_SIOCAX25NOUID; - extern unsigned IOCTL_SIOCAX25SETPARMS; - extern unsigned IOCTL_SIOCDEVPLIP; - extern unsigned IOCTL_SIOCIPXCFGDATA; - extern unsigned IOCTL_SIOCNRDECOBS; - extern unsigned IOCTL_SIOCNRGETPARMS; - extern unsigned IOCTL_SIOCNRRTCTL; - extern unsigned IOCTL_SIOCNRSETPARMS; - extern unsigned IOCTL_SNDCTL_DSP_GETISPACE; - extern unsigned IOCTL_SNDCTL_DSP_GETOSPACE; - extern unsigned IOCTL_TIOCGSERIAL; - extern unsigned IOCTL_TIOCSERGETMULTI; - extern unsigned IOCTL_TIOCSERSETMULTI; - extern unsigned IOCTL_TIOCSSERIAL; - extern unsigned IOCTL_GIO_SCRNMAP; - extern unsigned IOCTL_KDDISABIO; - extern unsigned IOCTL_KDENABIO; - extern unsigned IOCTL_KDGETLED; - extern unsigned IOCTL_KDGETMODE; - extern unsigned IOCTL_KDGKBMODE; - extern unsigned IOCTL_KDGKBTYPE; - extern unsigned IOCTL_KDMKTONE; - extern unsigned IOCTL_KDSETLED; - extern unsigned IOCTL_KDSETMODE; - extern unsigned IOCTL_KDSKBMODE; - extern unsigned IOCTL_KIOCSOUND; - extern unsigned IOCTL_PIO_SCRNMAP; -#endif - - extern const int si_SEGV_MAPERR; - extern const int si_SEGV_ACCERR; +extern unsigned IOCTL_CYGETDEFTHRESH; +extern unsigned IOCTL_CYGETDEFTIMEOUT; +extern unsigned IOCTL_CYGETMON; +extern unsigned IOCTL_CYGETTHRESH; +extern unsigned IOCTL_CYGETTIMEOUT; +extern unsigned IOCTL_CYSETDEFTHRESH; +extern unsigned IOCTL_CYSETDEFTIMEOUT; +extern unsigned IOCTL_CYSETTHRESH; +extern unsigned IOCTL_CYSETTIMEOUT; +extern unsigned IOCTL_EQL_EMANCIPATE; +extern unsigned IOCTL_EQL_ENSLAVE; +extern unsigned IOCTL_EQL_GETMASTRCFG; +extern unsigned IOCTL_EQL_GETSLAVECFG; +extern unsigned IOCTL_EQL_SETMASTRCFG; +extern unsigned IOCTL_EQL_SETSLAVECFG; +extern unsigned IOCTL_EVIOCGKEYCODE_V2; +extern unsigned IOCTL_EVIOCGPROP; +extern unsigned IOCTL_EVIOCSKEYCODE_V2; +extern unsigned IOCTL_FS_IOC_GETFLAGS; +extern unsigned IOCTL_FS_IOC_GETVERSION; +extern unsigned IOCTL_FS_IOC_SETFLAGS; +extern unsigned IOCTL_FS_IOC_SETVERSION; +extern unsigned IOCTL_GIO_CMAP; +extern unsigned IOCTL_GIO_FONT; +extern unsigned IOCTL_GIO_UNIMAP; +extern unsigned IOCTL_GIO_UNISCRNMAP; +extern unsigned IOCTL_KDADDIO; +extern unsigned IOCTL_KDDELIO; +extern unsigned IOCTL_KDGETKEYCODE; +extern unsigned IOCTL_KDGKBDIACR; +extern unsigned IOCTL_KDGKBENT; +extern unsigned IOCTL_KDGKBLED; +extern unsigned IOCTL_KDGKBMETA; +extern unsigned IOCTL_KDGKBSENT; +extern unsigned IOCTL_KDMAPDISP; +extern unsigned IOCTL_KDSETKEYCODE; +extern unsigned IOCTL_KDSIGACCEPT; +extern unsigned IOCTL_KDSKBDIACR; +extern unsigned IOCTL_KDSKBENT; +extern unsigned IOCTL_KDSKBLED; +extern unsigned IOCTL_KDSKBMETA; +extern unsigned IOCTL_KDSKBSENT; +extern unsigned IOCTL_KDUNMAPDISP; +extern unsigned IOCTL_LPABORT; +extern unsigned IOCTL_LPABORTOPEN; +extern unsigned IOCTL_LPCAREFUL; +extern unsigned IOCTL_LPCHAR; +extern unsigned IOCTL_LPGETIRQ; +extern unsigned IOCTL_LPGETSTATUS; +extern unsigned IOCTL_LPRESET; +extern unsigned IOCTL_LPSETIRQ; +extern unsigned IOCTL_LPTIME; +extern unsigned IOCTL_LPWAIT; +extern unsigned IOCTL_MTIOCGETCONFIG; +extern unsigned IOCTL_MTIOCSETCONFIG; +extern unsigned IOCTL_PIO_CMAP; +extern unsigned IOCTL_PIO_FONT; +extern unsigned IOCTL_PIO_UNIMAP; +extern unsigned IOCTL_PIO_UNIMAPCLR; +extern unsigned IOCTL_PIO_UNISCRNMAP; +extern unsigned IOCTL_SCSI_IOCTL_GET_IDLUN; +extern unsigned IOCTL_SCSI_IOCTL_PROBE_HOST; +extern unsigned IOCTL_SCSI_IOCTL_TAGGED_DISABLE; +extern unsigned IOCTL_SCSI_IOCTL_TAGGED_ENABLE; +extern unsigned IOCTL_SIOCAIPXITFCRT; +extern unsigned IOCTL_SIOCAIPXPRISLT; +extern unsigned IOCTL_SIOCAX25ADDUID; +extern unsigned IOCTL_SIOCAX25DELUID; +extern unsigned IOCTL_SIOCAX25GETPARMS; +extern unsigned IOCTL_SIOCAX25GETUID; +extern unsigned IOCTL_SIOCAX25NOUID; +extern unsigned IOCTL_SIOCAX25SETPARMS; +extern unsigned IOCTL_SIOCDEVPLIP; +extern unsigned IOCTL_SIOCIPXCFGDATA; +extern unsigned IOCTL_SIOCNRDECOBS; +extern unsigned IOCTL_SIOCNRGETPARMS; +extern unsigned IOCTL_SIOCNRRTCTL; +extern unsigned IOCTL_SIOCNRSETPARMS; +extern unsigned IOCTL_SNDCTL_DSP_GETISPACE; +extern unsigned IOCTL_SNDCTL_DSP_GETOSPACE; +extern unsigned IOCTL_TIOCGSERIAL; +extern unsigned IOCTL_TIOCSERGETMULTI; +extern unsigned IOCTL_TIOCSERSETMULTI; +extern unsigned IOCTL_TIOCSSERIAL; +extern unsigned IOCTL_GIO_SCRNMAP; +extern unsigned IOCTL_KDDISABIO; +extern unsigned IOCTL_KDENABIO; +extern unsigned IOCTL_KDGETLED; +extern unsigned IOCTL_KDGETMODE; +extern unsigned IOCTL_KDGKBMODE; +extern unsigned IOCTL_KDGKBTYPE; +extern unsigned IOCTL_KDMKTONE; +extern unsigned IOCTL_KDSETLED; +extern unsigned IOCTL_KDSETMODE; +extern unsigned IOCTL_KDSKBMODE; +extern unsigned IOCTL_KIOCSOUND; +extern unsigned IOCTL_PIO_SCRNMAP; +#endif + +extern const int si_SEGV_MAPERR; +extern const int si_SEGV_ACCERR; } // namespace __sanitizer #define CHECK_TYPE_SIZE(TYPE) \ COMPILER_CHECK(sizeof(__sanitizer_##TYPE) == sizeof(TYPE)) -#define CHECK_SIZE_AND_OFFSET(CLASS, MEMBER) \ - COMPILER_CHECK(sizeof(((__sanitizer_##CLASS *) NULL)->MEMBER) == \ - sizeof(((CLASS *) NULL)->MEMBER)); \ - COMPILER_CHECK(offsetof(__sanitizer_##CLASS, MEMBER) == \ +#define CHECK_SIZE_AND_OFFSET(CLASS, MEMBER) \ + COMPILER_CHECK(sizeof(((__sanitizer_##CLASS *)NULL)->MEMBER) == \ + sizeof(((CLASS *)NULL)->MEMBER)); \ + COMPILER_CHECK(offsetof(__sanitizer_##CLASS, MEMBER) == \ offsetof(CLASS, MEMBER)) // For sigaction, which is a function and struct at the same time, // and thus requires explicit "struct" in sizeof() expression. -#define CHECK_STRUCT_SIZE_AND_OFFSET(CLASS, MEMBER) \ - COMPILER_CHECK(sizeof(((struct __sanitizer_##CLASS *) NULL)->MEMBER) == \ - sizeof(((struct CLASS *) NULL)->MEMBER)); \ - COMPILER_CHECK(offsetof(struct __sanitizer_##CLASS, MEMBER) == \ +#define CHECK_STRUCT_SIZE_AND_OFFSET(CLASS, MEMBER) \ + COMPILER_CHECK(sizeof(((struct __sanitizer_##CLASS *)NULL)->MEMBER) == \ + sizeof(((struct CLASS *)NULL)->MEMBER)); \ + COMPILER_CHECK(offsetof(struct __sanitizer_##CLASS, MEMBER) == \ offsetof(struct CLASS, MEMBER)) #define SIGACTION_SYMNAME sigaction diff --git a/lib/sanitizer_common/sanitizer_platform_limits_solaris.cc b/lib/sanitizer_common/sanitizer_platform_limits_solaris.cpp index 3503eb2eab34..9717d98ebf1a 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_solaris.cc +++ b/lib/sanitizer_common/sanitizer_platform_limits_solaris.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_platform_limits_solaris.cc ------------------------------===// +//===-- sanitizer_platform_limits_solaris.cpp -----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_platform_limits_solaris.h b/lib/sanitizer_common/sanitizer_platform_limits_solaris.h index eb5c5855b378..77ae6e6a44db 100644 --- a/lib/sanitizer_common/sanitizer_platform_limits_solaris.h +++ b/lib/sanitizer_common/sanitizer_platform_limits_solaris.h @@ -68,7 +68,7 @@ struct __sanitizer_ipc_perm { #if !defined(_LP64) int pad[4]; #endif - }; +}; struct __sanitizer_shmid_ds { __sanitizer_ipc_perm shm_perm; @@ -236,10 +236,9 @@ typedef long __sanitizer_clock_t; typedef int __sanitizer_clockid_t; // This thing depends on the platform. We are only interested in the upper -// limit. Verified with a compiler assert in .cc. -const int pthread_attr_t_max_sz = 128; +// limit. Verified with a compiler assert in .cpp. union __sanitizer_pthread_attr_t { - char size[pthread_attr_t_max_sz]; // NOLINT + char size[128]; void *align; }; diff --git a/lib/sanitizer_common/sanitizer_posix.cc b/lib/sanitizer_common/sanitizer_posix.cpp index bf7127443c41..d890a3a31773 100644 --- a/lib/sanitizer_common/sanitizer_posix.cc +++ b/lib/sanitizer_common/sanitizer_posix.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_posix.cc ------------------------------------------------===// +//===-- sanitizer_posix.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -312,6 +312,8 @@ const char *SignalContext::Describe() const { return "SEGV"; case SIGBUS: return "BUS"; + case SIGTRAP: + return "TRAP"; } return "UNKNOWN SIGNAL"; } diff --git a/lib/sanitizer_common/sanitizer_posix.h b/lib/sanitizer_common/sanitizer_posix.h index 6cf5ce75b12e..05fb0f630207 100644 --- a/lib/sanitizer_common/sanitizer_posix.h +++ b/lib/sanitizer_common/sanitizer_posix.h @@ -63,7 +63,7 @@ uptr internal_ptrace(int request, int pid, void *addr, void *data); uptr internal_waitpid(int pid, int *status, int options); int internal_fork(); -int internal_forkpty(int *amaster); +fd_t internal_spawn(const char *argv[], pid_t *pid); int internal_sysctl(const int *name, unsigned int namelen, void *oldp, uptr *oldlenp, const void *newp, uptr newlen); diff --git a/lib/sanitizer_common/sanitizer_posix_libcdep.cc b/lib/sanitizer_common/sanitizer_posix_libcdep.cpp index 23a2f84ac887..304b3a01a08b 100644 --- a/lib/sanitizer_common/sanitizer_posix_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_posix_libcdep.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_posix_libcdep.cc ----------------------------------------===// +//===-- sanitizer_posix_libcdep.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -68,11 +68,12 @@ void ReleaseMemoryPagesToOS(uptr beg, uptr end) { SANITIZER_MADVISE_DONTNEED); } -bool NoHugePagesInRegion(uptr addr, uptr size) { +void SetShadowRegionHugePageMode(uptr addr, uptr size) { #ifdef MADV_NOHUGEPAGE // May not be defined on old systems. - return madvise((char *)addr, size, MADV_NOHUGEPAGE) == 0; -#else - return true; + if (common_flags()->no_huge_pages_for_shadow) + madvise((char *)addr, size, MADV_NOHUGEPAGE); + else + madvise((char *)addr, size, MADV_HUGEPAGE); #endif // MADV_NOHUGEPAGE } @@ -303,11 +304,13 @@ void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args) { MemoryMappingLayout::CacheMemoryMappings(); } -bool MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) { +static bool MmapFixed(uptr fixed_addr, uptr size, int additional_flags, + const char *name) { size = RoundUpTo(size, GetPageSizeCached()); fixed_addr = RoundDownTo(fixed_addr, GetPageSizeCached()); - uptr p = MmapNamed((void *)fixed_addr, size, PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_FIXED | MAP_NORESERVE | MAP_ANON, name); + uptr p = + MmapNamed((void *)fixed_addr, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_FIXED | additional_flags | MAP_ANON, name); int reserrno; if (internal_iserror(p, &reserrno)) { Report("ERROR: %s failed to " @@ -319,6 +322,24 @@ bool MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) { return true; } +bool MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) { + return MmapFixed(fixed_addr, size, MAP_NORESERVE, name); +} + +bool MmapFixedSuperNoReserve(uptr fixed_addr, uptr size, const char *name) { +#if SANITIZER_FREEBSD + if (common_flags()->no_huge_pages_for_shadow) + return MmapFixedNoReserve(fixed_addr, size, name); + // MAP_NORESERVE is implicit with FreeBSD + return MmapFixed(fixed_addr, size, MAP_ALIGNED_SUPER, name); +#else + bool r = MmapFixedNoReserve(fixed_addr, size, name); + if (r) + SetShadowRegionHugePageMode(fixed_addr, size); + return r; +#endif +} + uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) { base_ = fixed_addr ? MmapFixedNoAccess(fixed_addr, size, name) : MmapNoAccess(size); diff --git a/lib/sanitizer_common/sanitizer_printf.cc b/lib/sanitizer_common/sanitizer_printf.cpp index f4e17a8f51fd..a032787114bb 100644 --- a/lib/sanitizer_common/sanitizer_printf.cc +++ b/lib/sanitizer_common/sanitizer_printf.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_printf.cc -----------------------------------------------===// +//===-- sanitizer_printf.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -229,15 +229,15 @@ void SetPrintfAndReportCallback(void (*callback)(const char *)) { // Can be overriden in frontend. #if SANITIZER_GO && defined(TSAN_EXTERNAL_HOOKS) // Implementation must be defined in frontend. -extern "C" void OnPrint(const char *str); +extern "C" void __sanitizer_on_print(const char *str); #else -SANITIZER_INTERFACE_WEAK_DEF(void, OnPrint, const char *str) { +SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_on_print, const char *str) { (void)str; } #endif static void CallPrintfAndReportCallback(const char *str) { - OnPrint(str); + __sanitizer_on_print(str); if (PrintfAndReportCallback) PrintfAndReportCallback(str); } diff --git a/lib/sanitizer_common/sanitizer_procmaps.h b/lib/sanitizer_common/sanitizer_procmaps.h index 052027111ceb..d0e5245f84da 100644 --- a/lib/sanitizer_common/sanitizer_procmaps.h +++ b/lib/sanitizer_common/sanitizer_procmaps.h @@ -37,7 +37,7 @@ struct MemoryMappedSegmentData; class MemoryMappedSegment { public: - MemoryMappedSegment(char *buff = nullptr, uptr size = 0) + explicit MemoryMappedSegment(char *buff = nullptr, uptr size = 0) : filename(buff), filename_size(size), data_(nullptr) {} ~MemoryMappedSegment() {} diff --git a/lib/sanitizer_common/sanitizer_procmaps_bsd.cc b/lib/sanitizer_common/sanitizer_procmaps_bsd.cpp index c38bafd9f52f..02ff7c0e91a8 100644 --- a/lib/sanitizer_common/sanitizer_procmaps_bsd.cc +++ b/lib/sanitizer_common/sanitizer_procmaps_bsd.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_procmaps_bsd.cc -----------------------------------------===// +//===-- sanitizer_procmaps_bsd.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_procmaps_common.cc b/lib/sanitizer_common/sanitizer_procmaps_common.cpp index 4a2b0a047ad6..e0cb47f8ca9a 100644 --- a/lib/sanitizer_common/sanitizer_procmaps_common.cc +++ b/lib/sanitizer_common/sanitizer_procmaps_common.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_procmaps_common.cc --------------------------------------===// +//===-- sanitizer_procmaps_common.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_procmaps_linux.cc b/lib/sanitizer_common/sanitizer_procmaps_linux.cpp index fd5e03619bdd..c7af57355b91 100644 --- a/lib/sanitizer_common/sanitizer_procmaps_linux.cc +++ b/lib/sanitizer_common/sanitizer_procmaps_linux.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_procmaps_linux.cc ---------------------------------------===// +//===-- sanitizer_procmaps_linux.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_procmaps_mac.cc b/lib/sanitizer_common/sanitizer_procmaps_mac.cpp index 148910f42061..d02afcfe87ae 100644 --- a/lib/sanitizer_common/sanitizer_procmaps_mac.cc +++ b/lib/sanitizer_common/sanitizer_procmaps_mac.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_procmaps_mac.cc -----------------------------------------===// +//===-- sanitizer_procmaps_mac.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -181,13 +181,14 @@ const mach_header *get_dyld_hdr() { // Note that the segment addresses are not necessarily sorted. template <u32 kLCSegment, typename SegmentCommand> static bool NextSegmentLoad(MemoryMappedSegment *segment, -MemoryMappedSegmentData *seg_data, MemoryMappingLayoutData &layout_data) { - const char *lc = layout_data.current_load_cmd_addr; - layout_data.current_load_cmd_addr += ((const load_command *)lc)->cmdsize; + MemoryMappedSegmentData *seg_data, + MemoryMappingLayoutData *layout_data) { + const char *lc = layout_data->current_load_cmd_addr; + layout_data->current_load_cmd_addr += ((const load_command *)lc)->cmdsize; if (((const load_command *)lc)->cmd == kLCSegment) { const SegmentCommand* sc = (const SegmentCommand *)lc; uptr base_virt_addr, addr_mask; - if (layout_data.current_image == kDyldImageIdx) { + if (layout_data->current_image == kDyldImageIdx) { base_virt_addr = (uptr)get_dyld_hdr(); // vmaddr is masked with 0xfffff because on macOS versions < 10.12, // it contains an absolute address rather than an offset for dyld. @@ -198,7 +199,7 @@ MemoryMappedSegmentData *seg_data, MemoryMappingLayoutData &layout_data) { addr_mask = 0xfffff; } else { base_virt_addr = - (uptr)_dyld_get_image_vmaddr_slide(layout_data.current_image); + (uptr)_dyld_get_image_vmaddr_slide(layout_data->current_image); addr_mask = ~0; } @@ -219,18 +220,18 @@ MemoryMappedSegmentData *seg_data, MemoryMappingLayoutData &layout_data) { // Return the initial protection. segment->protection = sc->initprot; - segment->offset = (layout_data.current_filetype == + segment->offset = (layout_data->current_filetype == /*MH_EXECUTE*/ 0x2) ? sc->vmaddr : sc->fileoff; if (segment->filename) { - const char *src = (layout_data.current_image == kDyldImageIdx) + const char *src = (layout_data->current_image == kDyldImageIdx) ? kDyldPath - : _dyld_get_image_name(layout_data.current_image); + : _dyld_get_image_name(layout_data->current_image); internal_strncpy(segment->filename, src, segment->filename_size); } - segment->arch = layout_data.current_arch; - internal_memcpy(segment->uuid, layout_data.current_uuid, kModuleUUIDSize); + segment->arch = layout_data->current_arch; + internal_memcpy(segment->uuid, layout_data->current_uuid, kModuleUUIDSize); return true; } return false; @@ -331,14 +332,14 @@ bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { #ifdef MH_MAGIC_64 case MH_MAGIC_64: { if (NextSegmentLoad<LC_SEGMENT_64, struct segment_command_64>( - segment, segment->data_, data_)) + segment, segment->data_, &data_)) return true; break; } #endif case MH_MAGIC: { if (NextSegmentLoad<LC_SEGMENT, struct segment_command>( - segment, segment->data_, data_)) + segment, segment->data_, &data_)) return true; break; } diff --git a/lib/sanitizer_common/sanitizer_procmaps_solaris.cc b/lib/sanitizer_common/sanitizer_procmaps_solaris.cpp index b5df6fe4c41e..8793423a6017 100644 --- a/lib/sanitizer_common/sanitizer_procmaps_solaris.cc +++ b/lib/sanitizer_common/sanitizer_procmaps_solaris.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_procmaps_solaris.cc -------------------------------------===// +//===-- sanitizer_procmaps_solaris.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_rtems.cc b/lib/sanitizer_common/sanitizer_rtems.cpp index ffc21b958b8e..0d2576c00ab3 100644 --- a/lib/sanitizer_common/sanitizer_rtems.cc +++ b/lib/sanitizer_common/sanitizer_rtems.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_rtems.cc ------------------------------------------------===// +//===-- sanitizer_rtems.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_solaris.cc b/lib/sanitizer_common/sanitizer_solaris.cpp index 37b50c6b243a..035f2d0ca292 100644 --- a/lib/sanitizer_common/sanitizer_solaris.cc +++ b/lib/sanitizer_common/sanitizer_solaris.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_solaris.cc ----------------------------------------------===// +//===-- sanitizer_solaris.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_stackdepot.cc b/lib/sanitizer_common/sanitizer_stackdepot.cpp index 1cdedfa32fbe..30073a96ceeb 100644 --- a/lib/sanitizer_common/sanitizer_stackdepot.cc +++ b/lib/sanitizer_common/sanitizer_stackdepot.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_stackdepot.cc -------------------------------------------===// +//===-- sanitizer_stackdepot.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_stacktrace.cc b/lib/sanitizer_common/sanitizer_stacktrace.cpp index 26474037ff35..ef14fb704eed 100644 --- a/lib/sanitizer_common/sanitizer_stacktrace.cc +++ b/lib/sanitizer_common/sanitizer_stacktrace.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_stacktrace.cc -------------------------------------------===// +//===-- sanitizer_stacktrace.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc b/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp index 859032ba84e1..4ef305cf1799 100644 --- a/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_stacktrace_libcdep.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_stacktrace_libcdep.cc -----------------------------------===// +//===-- sanitizer_stacktrace_libcdep.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -150,8 +150,9 @@ void __sanitizer_symbolize_global(uptr data_addr, const char *fmt, } SANITIZER_INTERFACE_ATTRIBUTE -int __sanitizer_get_module_and_offset_for_pc( // NOLINT - uptr pc, char *module_name, uptr module_name_len, uptr *pc_offset) { +int __sanitizer_get_module_and_offset_for_pc(uptr pc, char *module_name, + uptr module_name_len, + uptr *pc_offset) { return __sanitizer::GetModuleAndOffsetForPc(pc, module_name, module_name_len, pc_offset); } diff --git a/lib/sanitizer_common/sanitizer_stacktrace_printer.cc b/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp index 17bbf6c0b868..150ff475316b 100644 --- a/lib/sanitizer_common/sanitizer_stacktrace_printer.cc +++ b/lib/sanitizer_common/sanitizer_stacktrace_printer.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_common.cc -----------------------------------------------===// +//===-- sanitizer_common.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -16,7 +16,7 @@ namespace __sanitizer { -// sanitizer_symbolizer_markup.cc implements these differently. +// sanitizer_symbolizer_markup.cpp implements these differently. #if !SANITIZER_SYMBOLIZER_MARKUP static const char *StripFunctionName(const char *function, const char *prefix) { diff --git a/lib/sanitizer_common/sanitizer_stacktrace_sparc.cc b/lib/sanitizer_common/sanitizer_stacktrace_sparc.cpp index b238cfbc26a3..34190fb1bbb2 100644 --- a/lib/sanitizer_common/sanitizer_stacktrace_sparc.cc +++ b/lib/sanitizer_common/sanitizer_stacktrace_sparc.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_stacktrace_sparc.cc -------------------------------------===// +//===-- sanitizer_stacktrace_sparc.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp index 716f0d226954..651d5056dd9d 100644 --- a/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_stoptheworld_linux_libcdep.cc ---------------------------===// +//===-- sanitizer_stoptheworld_linux_libcdep.cpp --------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -223,10 +223,11 @@ bool ThreadSuspender::SuspendAllThreads() { case ThreadLister::Ok: break; } - for (tid_t tid : threads) + for (tid_t tid : threads) { if (SuspendThread(tid)) retry = true; - }; + } + } return suspended_threads_list_.ThreadCount(); } diff --git a/lib/sanitizer_common/sanitizer_stoptheworld_mac.cc b/lib/sanitizer_common/sanitizer_stoptheworld_mac.cpp index e79edc40f98f..9dffd21ecb7c 100644 --- a/lib/sanitizer_common/sanitizer_stoptheworld_mac.cc +++ b/lib/sanitizer_common/sanitizer_stoptheworld_mac.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_stoptheworld_mac.cc -------------------------------------===// +//===-- sanitizer_stoptheworld_mac.cpp ------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cc b/lib/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp index 7a8d14ae741e..5690d75097f9 100644 --- a/lib/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_stoptheworld_netbsd_libcdep.cc --------------------------===// +//===-- sanitizer_stoptheworld_netbsd_libcdep.cpp -------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -10,7 +10,7 @@ // This implementation was inspired by Markus Gutschke's linuxthreads.cc. // // This is a NetBSD variation of Linux stoptheworld implementation -// See sanitizer_stoptheworld_linux_libcdep.cc for code comments. +// See sanitizer_stoptheworld_linux_libcdep.cpp for code comments. // //===----------------------------------------------------------------------===// diff --git a/lib/sanitizer_common/sanitizer_suppressions.cc b/lib/sanitizer_common/sanitizer_suppressions.cpp index 12ecd9a2e368..44c83a66c5fe 100644 --- a/lib/sanitizer_common/sanitizer_suppressions.cc +++ b/lib/sanitizer_common/sanitizer_suppressions.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_suppressions.cc -----------------------------------------===// +//===-- sanitizer_suppressions.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_suppressions.h b/lib/sanitizer_common/sanitizer_suppressions.h index f9da7af7e6ab..2d88b1f72fa6 100644 --- a/lib/sanitizer_common/sanitizer_suppressions.h +++ b/lib/sanitizer_common/sanitizer_suppressions.h @@ -42,7 +42,7 @@ class SuppressionContext { void GetMatched(InternalMmapVector<Suppression *> *matched); private: - static const int kMaxSuppressionTypes = 32; + static const int kMaxSuppressionTypes = 64; const char **const suppression_types_; const int suppression_types_num_; diff --git a/lib/sanitizer_common/sanitizer_symbolizer.cc b/lib/sanitizer_common/sanitizer_symbolizer.cpp index 216ce585a0c6..ce2ece5f4d51 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_symbolizer.cc -------------------------------------------===// +//===-- sanitizer_symbolizer.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_symbolizer_internal.h b/lib/sanitizer_common/sanitizer_symbolizer_internal.h index 4611b7dfe1e5..c04797dd61b8 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer_internal.h +++ b/lib/sanitizer_common/sanitizer_symbolizer_internal.h @@ -76,30 +76,31 @@ class SymbolizerTool { // SymbolizerProcess may not be used from two threads simultaneously. class SymbolizerProcess { public: - explicit SymbolizerProcess(const char *path, bool use_forkpty = false); + explicit SymbolizerProcess(const char *path, bool use_posix_spawn = false); const char *SendCommand(const char *command); protected: + /// The maximum number of arguments required to invoke a tool process. + static const unsigned kArgVMax = 6; + + // Customizable by subclasses. + virtual bool StartSymbolizerSubprocess(); + virtual bool ReadFromSymbolizer(char *buffer, uptr max_length); + + private: virtual bool ReachedEndOfOutput(const char *buffer, uptr length) const { UNIMPLEMENTED(); } - /// The maximum number of arguments required to invoke a tool process. - enum { kArgVMax = 6 }; - /// Fill in an argv array to invoke the child process. virtual void GetArgV(const char *path_to_binary, const char *(&argv)[kArgVMax]) const { UNIMPLEMENTED(); } - virtual bool ReadFromSymbolizer(char *buffer, uptr max_length); - - private: bool Restart(); const char *SendCommandImpl(const char *command); bool WriteToSymbolizer(const char *buffer, uptr length); - bool StartSymbolizerSubprocess(); const char *path_; fd_t input_fd_; @@ -113,7 +114,7 @@ class SymbolizerProcess { uptr times_restarted_; bool failed_to_start_; bool reported_invalid_path_; - bool use_forkpty_; + bool use_posix_spawn_; }; class LLVMSymbolizerProcess; diff --git a/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc b/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cpp index 8a20e062cf47..27ed222745ec 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer_libbacktrace.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_symbolizer_libbacktrace.cc ------------------------------===// +//===-- sanitizer_symbolizer_libbacktrace.cpp -----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc b/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp index 7f5bc55bd865..3b19a6836ec5 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer_libcdep.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_symbolizer_libcdep.cc -----------------------------------===// +//===-- sanitizer_symbolizer_libcdep.cpp ----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,7 +25,7 @@ Symbolizer *Symbolizer::GetOrInit() { return symbolizer_; } -// See sanitizer_symbolizer_markup.cc. +// See sanitizer_symbolizer_markup.cpp. #if !SANITIZER_SYMBOLIZER_MARKUP const char *ExtractToken(const char *str, const char *delims, char **result) { @@ -238,7 +238,8 @@ const LoadedModule *Symbolizer::FindModuleForAddress(uptr address) { // <empty line> class LLVMSymbolizerProcess : public SymbolizerProcess { public: - explicit LLVMSymbolizerProcess(const char *path) : SymbolizerProcess(path) {} + explicit LLVMSymbolizerProcess(const char *path) + : SymbolizerProcess(path, /*use_posix_spawn=*/SANITIZER_MAC) {} private: bool ReachedEndOfOutput(const char *buffer, uptr length) const override { @@ -452,14 +453,14 @@ const char *LLVMSymbolizer::FormatAndSendCommand(const char *command_prefix, return symbolizer_process_->SendCommand(buffer_); } -SymbolizerProcess::SymbolizerProcess(const char *path, bool use_forkpty) +SymbolizerProcess::SymbolizerProcess(const char *path, bool use_posix_spawn) : path_(path), input_fd_(kInvalidFd), output_fd_(kInvalidFd), times_restarted_(0), failed_to_start_(false), reported_invalid_path_(false), - use_forkpty_(use_forkpty) { + use_posix_spawn_(use_posix_spawn) { CHECK(path_); CHECK_NE(path_[0], '\0'); } diff --git a/lib/sanitizer_common/sanitizer_symbolizer_mac.cc b/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp index d3566571948e..a619ed092f0b 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer_mac.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer_mac.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_symbolizer_mac.cc ---------------------------------------===// +//===-- sanitizer_symbolizer_mac.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -50,13 +50,18 @@ bool DlAddrSymbolizer::SymbolizeData(uptr addr, DataInfo *datainfo) { class AtosSymbolizerProcess : public SymbolizerProcess { public: explicit AtosSymbolizerProcess(const char *path, pid_t parent_pid) - : SymbolizerProcess(path, /*use_forkpty*/ true) { + : SymbolizerProcess(path, /*use_posix_spawn*/ true) { // Put the string command line argument in the object so that it outlives // the call to GetArgV. internal_snprintf(pid_str_, sizeof(pid_str_), "%d", parent_pid); } private: + bool StartSymbolizerSubprocess() override { + // Configure sandbox before starting atos process. + return SymbolizerProcess::StartSymbolizerSubprocess(); + } + bool ReachedEndOfOutput(const char *buffer, uptr length) const override { return (length >= 1 && buffer[length - 1] == '\n'); } diff --git a/lib/sanitizer_common/sanitizer_symbolizer_markup.cc b/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp index aee49b4c4567..57b4d0c9d961 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer_markup.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer_markup.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_symbolizer_markup.cc ------------------------------------===// +//===-- sanitizer_symbolizer_markup.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc b/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp index 2df3a90bafaa..c123ecb11206 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_symbolizer_posix_libcdep.cc -----------------------------===// +//===-- sanitizer_symbolizer_posix_libcdep.cpp ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -33,10 +33,6 @@ #include <sys/wait.h> #include <unistd.h> -#if SANITIZER_MAC -#include <util.h> // for forkpty() -#endif // SANITIZER_MAC - // C++ demangling function, as required by Itanium C++ ABI. This is weak, // because we do not require a C++ ABI library to be linked to a program // using sanitizers; if it's not present, we'll just use the mangled name. @@ -151,80 +147,32 @@ bool SymbolizerProcess::StartSymbolizerSubprocess() { return false; } - int pid = -1; - - int infd[2]; - internal_memset(&infd, 0, sizeof(infd)); - int outfd[2]; - internal_memset(&outfd, 0, sizeof(outfd)); - if (!CreateTwoHighNumberedPipes(infd, outfd)) { - Report("WARNING: Can't create a socket pair to start " - "external symbolizer (errno: %d)\n", errno); - return false; - } + const char *argv[kArgVMax]; + GetArgV(path_, argv); + pid_t pid; - if (use_forkpty_) { + if (use_posix_spawn_) { #if SANITIZER_MAC - fd_t fd = kInvalidFd; - - // forkpty redirects stdout and stderr into a single stream, so we would - // receive error messages as standard replies. To avoid that, let's dup - // stderr and restore it in the child. - int saved_stderr = dup(STDERR_FILENO); - CHECK_GE(saved_stderr, 0); - - // We only need one pipe, for stdin of the child. - close(outfd[0]); - close(outfd[1]); - - // Use forkpty to disable buffering in the new terminal. - pid = internal_forkpty(&fd); - if (pid == -1) { - // forkpty() failed. - Report("WARNING: failed to fork external symbolizer (errno: %d)\n", + fd_t fd = internal_spawn(argv, &pid); + if (fd == kInvalidFd) { + Report("WARNING: failed to spawn external symbolizer (errno: %d)\n", errno); return false; - } else if (pid == 0) { - // Child subprocess. - - // infd[0] is the child's reading end. - close(infd[1]); - - // Set up stdin to read from the pipe. - CHECK_GE(dup2(infd[0], STDIN_FILENO), 0); - close(infd[0]); - - // Restore stderr. - CHECK_GE(dup2(saved_stderr, STDERR_FILENO), 0); - close(saved_stderr); - - const char *argv[kArgVMax]; - GetArgV(path_, argv); - execv(path_, const_cast<char **>(&argv[0])); - internal__exit(1); } - // Input for the child, infd[1] is our writing end. - output_fd_ = infd[1]; - close(infd[0]); - - // Continue execution in parent process. input_fd_ = fd; - - close(saved_stderr); - - // Disable echo in the new terminal, disable CR. - struct termios termflags; - tcgetattr(fd, &termflags); - termflags.c_oflag &= ~ONLCR; - termflags.c_lflag &= ~ECHO; - tcsetattr(fd, TCSANOW, &termflags); + output_fd_ = fd; #else // SANITIZER_MAC UNIMPLEMENTED(); #endif // SANITIZER_MAC } else { - const char *argv[kArgVMax]; - GetArgV(path_, argv); + fd_t infd[2] = {}, outfd[2] = {}; + if (!CreateTwoHighNumberedPipes(infd, outfd)) { + Report("WARNING: Can't create a socket pair to start " + "external symbolizer (errno: %d)\n", errno); + return false; + } + pid = StartSubprocess(path_, argv, /* stdin */ outfd[0], /* stdout */ infd[1]); if (pid < 0) { diff --git a/lib/sanitizer_common/sanitizer_symbolizer_report.cc b/lib/sanitizer_common/sanitizer_symbolizer_report.cpp index f4167d160ae8..c26724ceb7a7 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer_report.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer_report.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_symbolizer_report.cc ------------------------------------===// +//===-- sanitizer_symbolizer_report.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -106,8 +106,9 @@ void ReportMmapWriteExec(int prot) { if (StackTrace::WillUseFastUnwind(fast)) { GetThreadStackTopAndBottom(false, &top, &bottom); stack->Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, true); - } else + } else { stack->Unwind(kStackTraceMax, pc, 0, nullptr, 0, 0, false); + } Printf("%s", d.Warning()); Report("WARNING: %s: writable-executable page usage\n", SanitizerToolName); @@ -190,9 +191,14 @@ static void ReportDeadlySignalImpl(const SignalContext &sig, u32 tid, SanitizerCommonDecorator d; Printf("%s", d.Warning()); const char *description = sig.Describe(); - Report("ERROR: %s: %s on unknown address %p (pc %p bp %p sp %p T%d)\n", - SanitizerToolName, description, (void *)sig.addr, (void *)sig.pc, - (void *)sig.bp, (void *)sig.sp, tid); + if (sig.is_memory_access && !sig.is_true_faulting_addr) + Report("ERROR: %s: %s on unknown address (pc %p bp %p sp %p T%d)\n", + SanitizerToolName, description, (void *)sig.pc, (void *)sig.bp, + (void *)sig.sp, tid); + else + Report("ERROR: %s: %s on unknown address %p (pc %p bp %p sp %p T%d)\n", + SanitizerToolName, description, (void *)sig.addr, (void *)sig.pc, + (void *)sig.bp, (void *)sig.sp, tid); Printf("%s", d.Default()); if (sig.pc < GetPageSizeCached()) Report("Hint: pc points to the zero page.\n"); @@ -202,7 +208,11 @@ static void ReportDeadlySignalImpl(const SignalContext &sig, u32 tid, ? "WRITE" : (sig.write_flag == SignalContext::READ ? "READ" : "UNKNOWN"); Report("The signal is caused by a %s memory access.\n", access_type); - if (sig.addr < GetPageSizeCached()) + if (!sig.is_true_faulting_addr) + Report("Hint: this fault was caused by a dereference of a high value " + "address (see register values below). Dissassemble the provided " + "pc to learn which register was used.\n"); + else if (sig.addr < GetPageSizeCached()) Report("Hint: address points to the zero page.\n"); } MaybeReportNonExecRegion(sig.pc); diff --git a/lib/sanitizer_common/sanitizer_symbolizer_win.cc b/lib/sanitizer_common/sanitizer_symbolizer_win.cpp index 1badcf5f0a35..2808779156ed 100644 --- a/lib/sanitizer_common/sanitizer_symbolizer_win.cc +++ b/lib/sanitizer_common/sanitizer_symbolizer_win.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_symbolizer_win.cc ---------------------------------------===// +//===-- sanitizer_symbolizer_win.cpp --------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_termination.cc b/lib/sanitizer_common/sanitizer_termination.cpp index a011cce42aa2..84be6fc32342 100644 --- a/lib/sanitizer_common/sanitizer_termination.cc +++ b/lib/sanitizer_common/sanitizer_termination.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_termination.cc --------------------------------*- C++ -*-===// +//===-- sanitizer_termination.cpp -------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -84,7 +84,7 @@ void NORETURN CheckFailed(const char *file, int line, const char *cond, } // namespace __sanitizer -using namespace __sanitizer; // NOLINT +using namespace __sanitizer; extern "C" { SANITIZER_INTERFACE_ATTRIBUTE diff --git a/lib/sanitizer_common/sanitizer_thread_registry.cc b/lib/sanitizer_common/sanitizer_thread_registry.cpp index 02691287d763..f2c6f2799315 100644 --- a/lib/sanitizer_common/sanitizer_thread_registry.cc +++ b/lib/sanitizer_common/sanitizer_thread_registry.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_thread_registry.cc --------------------------------------===// +//===-- sanitizer_thread_registry.cpp -------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_tls_get_addr.cc b/lib/sanitizer_common/sanitizer_tls_get_addr.cpp index 5e33e2a514f4..9ca898a306a8 100644 --- a/lib/sanitizer_common/sanitizer_tls_get_addr.cc +++ b/lib/sanitizer_common/sanitizer_tls_get_addr.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_tls_get_addr.cc -----------------------------------------===// +//===-- sanitizer_tls_get_addr.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_tls_get_addr.h b/lib/sanitizer_common/sanitizer_tls_get_addr.h index cc178d3d15ae..c7cd5a8bffcf 100644 --- a/lib/sanitizer_common/sanitizer_tls_get_addr.h +++ b/lib/sanitizer_common/sanitizer_tls_get_addr.h @@ -42,7 +42,7 @@ struct DTLS { uptr dtv_size; DTV *dtv; // dtv_size elements, allocated by MmapOrDie. - // Auxiliary fields, don't access them outside sanitizer_tls_get_addr.cc + // Auxiliary fields, don't access them outside sanitizer_tls_get_addr.cpp uptr last_memalign_size; uptr last_memalign_ptr; }; diff --git a/lib/sanitizer_common/sanitizer_type_traits.cc b/lib/sanitizer_common/sanitizer_type_traits.cpp index e3e431a13d44..5ee37d7376f9 100644 --- a/lib/sanitizer_common/sanitizer_type_traits.cc +++ b/lib/sanitizer_common/sanitizer_type_traits.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_type_traits.cc --------------------------------*- C++ -*-===// +//===-- sanitizer_type_traits.cpp -------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc b/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp index 30581e848594..b2628dcc4dc1 100644 --- a/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc +++ b/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_unwind_linux_libcdep.cc ---------------------------------===// +//===-- sanitizer_unwind_linux_libcdep.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -27,6 +27,8 @@ namespace __sanitizer { +namespace { + //---------------------------- UnwindSlow -------------------------------------- typedef struct { @@ -46,38 +48,6 @@ release_my_map_info_list_func release_my_map_info_list; unwind_backtrace_signal_arch_func unwind_backtrace_signal_arch; } // extern "C" -#if SANITIZER_ANDROID -void SanitizerInitializeUnwinder() { - if (AndroidGetApiLevel() >= ANDROID_LOLLIPOP_MR1) return; - - // Pre-lollipop Android can not unwind through signal handler frames with - // libgcc unwinder, but it has a libcorkscrew.so library with the necessary - // workarounds. - void *p = dlopen("libcorkscrew.so", RTLD_LAZY); - if (!p) { - VReport(1, - "Failed to open libcorkscrew.so. You may see broken stack traces " - "in SEGV reports."); - return; - } - acquire_my_map_info_list = - (acquire_my_map_info_list_func)(uptr)dlsym(p, "acquire_my_map_info_list"); - release_my_map_info_list = - (release_my_map_info_list_func)(uptr)dlsym(p, "release_my_map_info_list"); - unwind_backtrace_signal_arch = (unwind_backtrace_signal_arch_func)(uptr)dlsym( - p, "unwind_backtrace_signal_arch"); - if (!acquire_my_map_info_list || !release_my_map_info_list || - !unwind_backtrace_signal_arch) { - VReport(1, - "Failed to find one of the required symbols in libcorkscrew.so. " - "You may see broken stack traces in SEGV reports."); - acquire_my_map_info_list = 0; - unwind_backtrace_signal_arch = 0; - release_my_map_info_list = 0; - } -} -#endif - #if defined(__arm__) && !SANITIZER_NETBSD // NetBSD uses dwarf EH #define UNWIND_STOP _URC_END_OF_STACK @@ -119,6 +89,40 @@ _Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) { return UNWIND_CONTINUE; } +} // namespace + +#if SANITIZER_ANDROID +void SanitizerInitializeUnwinder() { + if (AndroidGetApiLevel() >= ANDROID_LOLLIPOP_MR1) return; + + // Pre-lollipop Android can not unwind through signal handler frames with + // libgcc unwinder, but it has a libcorkscrew.so library with the necessary + // workarounds. + void *p = dlopen("libcorkscrew.so", RTLD_LAZY); + if (!p) { + VReport(1, + "Failed to open libcorkscrew.so. You may see broken stack traces " + "in SEGV reports."); + return; + } + acquire_my_map_info_list = + (acquire_my_map_info_list_func)(uptr)dlsym(p, "acquire_my_map_info_list"); + release_my_map_info_list = + (release_my_map_info_list_func)(uptr)dlsym(p, "release_my_map_info_list"); + unwind_backtrace_signal_arch = (unwind_backtrace_signal_arch_func)(uptr)dlsym( + p, "unwind_backtrace_signal_arch"); + if (!acquire_my_map_info_list || !release_my_map_info_list || + !unwind_backtrace_signal_arch) { + VReport(1, + "Failed to find one of the required symbols in libcorkscrew.so. " + "You may see broken stack traces in SEGV reports."); + acquire_my_map_info_list = 0; + unwind_backtrace_signal_arch = 0; + release_my_map_info_list = 0; + } +} +#endif + void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) { CHECK_GE(max_depth, 2); size = 0; diff --git a/lib/sanitizer_common/sanitizer_unwind_win.cc b/lib/sanitizer_common/sanitizer_unwind_win.cpp index 93908ababe25..8e06940685dc 100644 --- a/lib/sanitizer_common/sanitizer_unwind_win.cc +++ b/lib/sanitizer_common/sanitizer_unwind_win.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_unwind_win.cc -------------------------------------------===// +//===-- sanitizer_unwind_win.cpp ------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_vector.h b/lib/sanitizer_common/sanitizer_vector.h index 4b9ae7db4c13..31216f3ec3a6 100644 --- a/lib/sanitizer_common/sanitizer_vector.h +++ b/lib/sanitizer_common/sanitizer_vector.h @@ -23,11 +23,7 @@ namespace __sanitizer { template<typename T> class Vector { public: - explicit Vector() - : begin_() - , end_() - , last_() { - } + Vector() : begin_(), end_(), last_() {} ~Vector() { if (begin_) diff --git a/lib/sanitizer_common/sanitizer_win.cc b/lib/sanitizer_common/sanitizer_win.cpp index 457cecb8cec1..36dde49d8708 100644 --- a/lib/sanitizer_common/sanitizer_win.cc +++ b/lib/sanitizer_common/sanitizer_win.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_win.cc --------------------------------------------------===// +//===-- sanitizer_win.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -239,6 +239,11 @@ bool MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) { return true; } +bool MmapFixedSuperNoReserve(uptr fixed_addr, uptr size, const char *name) { + // FIXME: Windows support large pages too. Might be worth checking + return MmapFixedNoReserve(fixed_addr, size, name); +} + // Memory space mapped by 'MmapFixedOrDie' must have been reserved by // 'MmapFixedNoAccess'. void *MmapFixedOrDie(uptr fixed_addr, uptr size, const char *name) { @@ -329,9 +334,8 @@ void ReleaseMemoryPagesToOS(uptr beg, uptr end) { // FIXME: add madvise-analog when we move to 64-bits. } -bool NoHugePagesInRegion(uptr addr, uptr size) { +void SetShadowRegionHugePageMode(uptr addr, uptr size) { // FIXME: probably similar to ReleaseMemoryToOS. - return true; } bool DontDumpShadowMemory(uptr addr, uptr length) { @@ -672,7 +676,7 @@ static int RunAtexit() { return ret; } -#pragma section(".CRT$XID", long, read) // NOLINT +#pragma section(".CRT$XID", long, read) __declspec(allocate(".CRT$XID")) int (*__run_atexit)() = RunAtexit; #endif @@ -941,6 +945,11 @@ bool SignalContext::IsMemoryAccess() const { return GetWriteFlag() != SignalContext::UNKNOWN; } +bool SignalContext::IsTrueFaultingAddress() const { + // FIXME: Provide real implementation for this. See Linux and Mac variants. + return IsMemoryAccess(); +} + SignalContext::WriteFlag SignalContext::GetWriteFlag() const { EXCEPTION_RECORD *exception_record = (EXCEPTION_RECORD *)siginfo; // The contents of this array are documented at @@ -1055,7 +1064,7 @@ pid_t StartSubprocess(const char *program, const char *const argv[], // FIXME: implement on this platform // Should be implemented based on // SymbolizerProcess::StarAtSymbolizerSubprocess - // from lib/sanitizer_common/sanitizer_symbolizer_win.cc. + // from lib/sanitizer_common/sanitizer_symbolizer_win.cpp. return -1; } diff --git a/lib/sanitizer_common/sanitizer_win_defs.h b/lib/sanitizer_common/sanitizer_win_defs.h index bcd94a08dc44..bfe38a332367 100644 --- a/lib/sanitizer_common/sanitizer_win_defs.h +++ b/lib/sanitizer_common/sanitizer_win_defs.h @@ -43,6 +43,8 @@ #define STRINGIFY_(A) #A #define STRINGIFY(A) STRINGIFY_(A) +#if !SANITIZER_GO + // ----------------- A workaround for the absence of weak symbols -------------- // We don't have a direct equivalent of weak symbols when using MSVC, but we can // use the /alternatename directive to tell the linker to default a specific @@ -158,5 +160,15 @@ // return a >= b; // } // + +#else // SANITIZER_GO + +// Go neither needs nor wants weak references. +// The shenanigans above don't work for gcc. +# define WIN_WEAK_EXPORT_DEF(ReturnType, Name, ...) \ + extern "C" ReturnType Name(__VA_ARGS__) + +#endif // SANITIZER_GO + #endif // SANITIZER_WINDOWS #endif // SANITIZER_WIN_DEFS_H diff --git a/lib/sanitizer_common/sanitizer_win_dll_thunk.cc b/lib/sanitizer_common/sanitizer_win_dll_thunk.cpp index 5a947916de0a..1562c161a762 100644 --- a/lib/sanitizer_common/sanitizer_win_dll_thunk.cc +++ b/lib/sanitizer_common/sanitizer_win_dll_thunk.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_win_dll_thunk.cc ----------------------------------------===// +//===-- sanitizer_win_dll_thunk.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -54,8 +54,8 @@ int dllThunkInterceptWhenPossible(const char* main_function, #define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name) #include "sanitizer_common_interface.inc" -#pragma section(".DLLTH$A", read) // NOLINT -#pragma section(".DLLTH$Z", read) // NOLINT +#pragma section(".DLLTH$A", read) +#pragma section(".DLLTH$Z", read) typedef void (*DllThunkCB)(); extern "C" { @@ -85,7 +85,7 @@ extern "C" int __dll_thunk_init() { // We want to call dll_thunk_init before C/C++ initializers / constructors are // executed, otherwise functions like memset might be invoked. -#pragma section(".CRT$XIB", long, read) // NOLINT +#pragma section(".CRT$XIB", long, read) __declspec(allocate(".CRT$XIB")) int (*__dll_thunk_preinit)() = __dll_thunk_init; @@ -94,7 +94,7 @@ static void WINAPI dll_thunk_thread_init(void *mod, unsigned long reason, if (reason == /*DLL_PROCESS_ATTACH=*/1) __dll_thunk_init(); } -#pragma section(".CRT$XLAB", long, read) // NOLINT +#pragma section(".CRT$XLAB", long, read) __declspec(allocate(".CRT$XLAB")) void (WINAPI *__dll_thunk_tls_init)(void *, unsigned long, void *) = dll_thunk_thread_init; diff --git a/lib/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cc b/lib/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cpp index 89756f1b70af..87c032c6e61b 100644 --- a/lib/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cc +++ b/lib/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cpp @@ -1,4 +1,4 @@ -//===-- santizer_win_dynamic_runtime_thunk.cc -----------------------------===// +//===-- santizer_win_dynamic_runtime_thunk.cpp ----------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/sanitizer_win_weak_interception.cc b/lib/sanitizer_common/sanitizer_win_weak_interception.cpp index b1ac44d75ceb..b14bbf76d9a7 100644 --- a/lib/sanitizer_common/sanitizer_win_weak_interception.cc +++ b/lib/sanitizer_common/sanitizer_win_weak_interception.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_win_weak_interception.cc --------------------------------===// +//===-- sanitizer_win_weak_interception.cpp -------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -38,6 +38,7 @@ int interceptWhenPossible(uptr dll_function, const char *real_function) { // Declare weak hooks. extern "C" { +void __sanitizer_on_print(const char *str); void __sanitizer_weak_hook_memcmp(uptr called_pc, const void *s1, const void *s2, uptr n, int result); void __sanitizer_weak_hook_strcmp(uptr called_pc, const char *s1, @@ -53,8 +54,8 @@ void __sanitizer_weak_hook_strstr(uptr called_pc, const char *s1, #define INTERFACE_WEAK_FUNCTION(Name) INTERCEPT_SANITIZER_WEAK_FUNCTION(Name) #include "sanitizer_common_interface.inc" -#pragma section(".WEAK$A", read) // NOLINT -#pragma section(".WEAK$Z", read) // NOLINT +#pragma section(".WEAK$A", read) +#pragma section(".WEAK$Z", read) typedef void (*InterceptCB)(); extern "C" { @@ -77,7 +78,7 @@ static int weak_intercept_init() { return 0; } -#pragma section(".CRT$XIB", long, read) // NOLINT +#pragma section(".CRT$XIB", long, read) __declspec(allocate(".CRT$XIB")) int (*__weak_intercept_preinit)() = weak_intercept_init; @@ -86,7 +87,7 @@ static void WINAPI weak_intercept_thread_init(void *mod, unsigned long reason, if (reason == /*DLL_PROCESS_ATTACH=*/1) weak_intercept_init(); } -#pragma section(".CRT$XLAB", long, read) // NOLINT +#pragma section(".CRT$XLAB", long, read) __declspec(allocate(".CRT$XLAB")) void(WINAPI *__weak_intercept_tls_init)( void *, unsigned long, void *) = weak_intercept_thread_init; diff --git a/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cc b/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp index 8150b7a09a0e..ba285bc1e884 100644 --- a/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cc +++ b/lib/sanitizer_common/symbolizer/sanitizer_symbolize.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_symbolize.cc ----------------------------------*- C++ -*-===// +//===-- sanitizer_symbolize.cpp ---------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -6,7 +6,7 @@ // //===----------------------------------------------------------------------===// // -// Implementation of weak hooks from sanitizer_symbolizer_posix_libcdep.cc. +// Implementation of weak hooks from sanitizer_symbolizer_posix_libcdep.cpp. // //===----------------------------------------------------------------------===// diff --git a/lib/sanitizer_common/symbolizer/sanitizer_wrappers.cc b/lib/sanitizer_common/symbolizer/sanitizer_wrappers.cpp index c85ebe5e2e29..ac351d3a8362 100644 --- a/lib/sanitizer_common/symbolizer/sanitizer_wrappers.cc +++ b/lib/sanitizer_common/symbolizer/sanitizer_wrappers.cpp @@ -1,4 +1,4 @@ -//===-- sanitizer_wrappers.cc -----------------------------------*- C++ -*-===// +//===-- sanitizer_wrappers.cpp ----------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh b/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh index 0c3917c6b17b..be79f1df64ba 100755 --- a/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh +++ b/lib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh @@ -25,15 +25,25 @@ # object file with only our entry points exposed. However, this does not work at # present, see PR30750. -SCRIPT_DIR="$(cd "$(dirname "$0")" && pwd)" +set -x +set -e +set -u + +SCRIPT_DIR=$(cd "$(dirname "$0")" && pwd) SRC_DIR=$(readlink -f $SCRIPT_DIR/..) TARGE_DIR=$(readlink -f $1) - -LLVM_SRC="${LLVM_SRC:-$SCRIPT_DIR/../../../../../..}" +COMPILER_RT_SRC=$(readlink -f ${SCRIPT_DIR}/../../../..) +LLVM_SRC=${LLVM_SRC:-${COMPILER_RT_SRC}/../llvm} LLVM_SRC=$(readlink -f $LLVM_SRC) +if [[ ! -d "${LLVM_SRC}/../llvm" ]] ; then + LLVM_SRC=$(readlink -f ${COMPILER_RT_SRC}/../../../llvm) +fi +LIBCXX_SRC=$(readlink -f ${COMPILER_RT_SRC}/../libcxx) +LIBCXXABI_SRC=$(readlink -f ${COMPILER_RT_SRC}/../libcxxabi) -if [[ ! -d "${LLVM_SRC}/projects/libcxxabi" || - ! -d "${LLVM_SRC}/projects/libcxx" ]]; then +if [[ ! -d "${LLVM_SRC}/../llvm" || + ! -d "${LIBCXX_SRC}" || + ! -d "${LIBCXXABI_SRC}" ]]; then echo "Missing or incomplete LLVM_SRC" exit 1 fi @@ -88,8 +98,13 @@ make -j${J} libz.a if [[ ! -d ${LIBCXX_BUILD} ]]; then mkdir -p ${LIBCXX_BUILD} cd ${LIBCXX_BUILD} - LIBCXX_FLAGS="${FLAGS} -Wno-macro-redefined -I${LLVM_SRC}/projects/libcxxabi/include" + LIBCXX_FLAGS="${FLAGS} -Wno-macro-redefined -I${LIBCXX_SRC}/include" + PROJECTS= + if [[ ! -d $LLVM_SRC/projects/libcxxabi ]] ; then + PROJECTS="-DLLVM_ENABLE_PROJECTS='libcxx;libcxxabi'" + fi cmake -GNinja \ + ${PROJECTS} \ -DCMAKE_BUILD_TYPE=Release \ -DCMAKE_C_COMPILER=$CC \ -DCMAKE_CXX_COMPILER=$CXX \ @@ -127,7 +142,7 @@ if [[ ! -d ${LLVM_BUILD} ]]; then $LLVM_SRC fi cd ${LLVM_BUILD} -ninja LLVMSymbolize LLVMObject LLVMBinaryFormat LLVMDebugInfoDWARF LLVMSupport LLVMDebugInfoPDB LLVMMC LLVMDemangle +ninja LLVMSymbolize LLVMObject LLVMBinaryFormat LLVMDebugInfoDWARF LLVMSupport LLVMDebugInfoPDB LLVMMC LLVMDemangle LLVMTextAPI cd ${BUILD_DIR} rm -rf ${SYMBOLIZER_BUILD} @@ -135,8 +150,8 @@ mkdir ${SYMBOLIZER_BUILD} cd ${SYMBOLIZER_BUILD} echo "Compiling..." -SYMBOLIZER_FLAGS="$LLVM_FLAGS -I${LLVM_SRC}/include -I${LLVM_BUILD}/include -std=c++11" -$CXX $SYMBOLIZER_FLAGS ${SRC_DIR}/sanitizer_symbolize.cc ${SRC_DIR}/sanitizer_wrappers.cc -c +SYMBOLIZER_FLAGS="$LLVM_FLAGS -I${LLVM_SRC}/include -I${LLVM_BUILD}/include -std=c++14" +$CXX $SYMBOLIZER_FLAGS ${SRC_DIR}/sanitizer_symbolize.cpp ${SRC_DIR}/sanitizer_wrappers.cpp -c $AR rc symbolizer.a sanitizer_symbolize.o sanitizer_wrappers.o SYMBOLIZER_API_LIST=__sanitizer_symbolize_code,__sanitizer_symbolize_data,__sanitizer_symbolize_flush,__sanitizer_symbolize_demangle @@ -152,6 +167,7 @@ $SCRIPT_DIR/ar_to_bc.sh $LIBCXX_BUILD/lib/libc++.a \ $LLVM_BUILD/lib/libLLVMDebugInfoPDB.a \ $LLVM_BUILD/lib/libLLVMDemangle.a \ $LLVM_BUILD/lib/libLLVMMC.a \ + $LLVM_BUILD/lib/libLLVMTextAPI.a \ $ZLIB_BUILD/libz.a \ symbolizer.a \ all.bc diff --git a/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt b/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt index 2a0f76b80ef4..fa42e2a01965 100644 --- a/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt +++ b/lib/sanitizer_common/symbolizer/scripts/global_symbols.txt @@ -19,8 +19,13 @@ __interceptor_pthread_cond_broadcast w __interceptor_pthread_cond_wait w __interceptor_pthread_getspecific w __interceptor_pthread_key_create w +__interceptor_pthread_mutex_destroy w +__interceptor_pthread_mutex_init w __interceptor_pthread_mutex_lock w __interceptor_pthread_mutex_unlock w +__interceptor_pthread_mutexattr_destroy w +__interceptor_pthread_mutexattr_init w +__interceptor_pthread_mutexattr_settype w __interceptor_pthread_once w __interceptor_pthread_setspecific w __interceptor_read w @@ -70,9 +75,11 @@ getpid U getrlimit U gettimeofday U ioctl U +isalnum U isalpha U isatty U islower U +isspace U isprint U isupper U isxdigit U diff --git a/lib/scudo/scudo_allocator_secondary.h b/lib/scudo/scudo_allocator_secondary.h index 151ff9931f6c..80198c4aebf5 100644 --- a/lib/scudo/scudo_allocator_secondary.h +++ b/lib/scudo/scudo_allocator_secondary.h @@ -49,20 +49,20 @@ // +--------------------+ namespace LargeChunk { - struct Header { - ReservedAddressRange StoredRange; - uptr CommittedSize; - uptr Size; - }; - constexpr uptr getHeaderSize() { - return RoundUpTo(sizeof(Header), MinAlignment); - } - static Header *getHeader(uptr Ptr) { - return reinterpret_cast<Header *>(Ptr - getHeaderSize()); - } - static Header *getHeader(const void *Ptr) { - return getHeader(reinterpret_cast<uptr>(Ptr)); - } +struct Header { + ReservedAddressRange StoredRange; + uptr CommittedSize; + uptr Size; +}; +constexpr uptr getHeaderSize() { + return RoundUpTo(sizeof(Header), MinAlignment); +} +static Header *getHeader(uptr Ptr) { + return reinterpret_cast<Header *>(Ptr - getHeaderSize()); +} +static Header *getHeader(const void *Ptr) { + return getHeader(reinterpret_cast<uptr>(Ptr)); +} } // namespace LargeChunk class LargeMmapAllocator { diff --git a/lib/scudo/scudo_errors.cpp b/lib/scudo/scudo_errors.cpp index 34e57bf71016..4bea9ebc6ab0 100644 --- a/lib/scudo/scudo_errors.cpp +++ b/lib/scudo/scudo_errors.cpp @@ -39,9 +39,10 @@ void NORETURN reportAllocationAlignmentNotPowerOfTwo(uptr Alignment) { } void NORETURN reportInvalidPosixMemalignAlignment(uptr Alignment) { - dieWithMessage("invalid alignment requested in posix_memalign: %zd, alignment" + dieWithMessage( + "invalid alignment requested in posix_memalign: %zd, alignment" " must be a power of two and a multiple of sizeof(void *) == %zd\n", - Alignment, sizeof(void *)); // NOLINT + Alignment, sizeof(void *)); } void NORETURN reportInvalidAlignedAllocAlignment(uptr Size, uptr Alignment) { diff --git a/lib/scudo/standalone/allocator_config.h b/lib/scudo/standalone/allocator_config.h index 06ec4f3f795a..62c6f2875106 100644 --- a/lib/scudo/standalone/allocator_config.h +++ b/lib/scudo/standalone/allocator_config.h @@ -53,8 +53,8 @@ struct AndroidSvelteConfig { // 512MB regions typedef SizeClassAllocator64<SizeClassMap, 29U> Primary; #else - // 256KB regions - typedef SizeClassAllocator32<SizeClassMap, 18U> Primary; + // 64KB regions + typedef SizeClassAllocator32<SizeClassMap, 16U> Primary; #endif template <class A> using TSDRegistryT = TSDRegistrySharedT<A, 1U>; // Shared, only 1 TSD. diff --git a/lib/scudo/standalone/checksum.cc b/lib/scudo/standalone/checksum.cpp index 0896d5bdccd5..f713f5a81609 100644 --- a/lib/scudo/standalone/checksum.cc +++ b/lib/scudo/standalone/checksum.cpp @@ -1,4 +1,4 @@ -//===-- checksum.cc ---------------------------------------------*- C++ -*-===// +//===-- checksum.cpp --------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/scudo/standalone/chunk.h b/lib/scudo/standalone/chunk.h index 76ef661b0dc5..9ae75823ba77 100644 --- a/lib/scudo/standalone/chunk.h +++ b/lib/scudo/standalone/chunk.h @@ -22,22 +22,22 @@ extern Checksum HashAlgorithm; INLINE u16 computeChecksum(u32 Seed, uptr Value, uptr *Array, uptr ArraySize) { // If the hardware CRC32 feature is defined here, it was enabled everywhere, - // as opposed to only for crc32_hw.cc. This means that other hardware specific - // instructions were likely emitted at other places, and as a result there is - // no reason to not use it here. + // as opposed to only for crc32_hw.cpp. This means that other hardware + // specific instructions were likely emitted at other places, and as a result + // there is no reason to not use it here. #if defined(__SSE4_2__) || defined(__ARM_FEATURE_CRC32) u32 Crc = static_cast<u32>(CRC32_INTRINSIC(Seed, Value)); for (uptr I = 0; I < ArraySize; I++) Crc = static_cast<u32>(CRC32_INTRINSIC(Crc, Array[I])); - return static_cast<u16>((Crc & 0xffff) ^ (Crc >> 16)); + return static_cast<u16>(Crc ^ (Crc >> 16)); #else if (HashAlgorithm == Checksum::HardwareCRC32) { u32 Crc = computeHardwareCRC32(Seed, Value); for (uptr I = 0; I < ArraySize; I++) Crc = computeHardwareCRC32(Crc, Array[I]); - return static_cast<u16>((Crc & 0xffff) ^ (Crc >> 16)); + return static_cast<u16>(Crc ^ (Crc >> 16)); } else { - u16 Checksum = computeBSDChecksum(static_cast<u16>(Seed & 0xffff), Value); + u16 Checksum = computeBSDChecksum(static_cast<u16>(Seed), Value); for (uptr I = 0; I < ArraySize; I++) Checksum = computeBSDChecksum(Checksum, Array[I]); return Checksum; @@ -63,24 +63,24 @@ enum State : u8 { Available = 0, Allocated = 1, Quarantined = 2 }; typedef u64 PackedHeader; // Update the 'Mask' constants to reflect changes in this structure. struct UnpackedHeader { - u64 Checksum : 16; - u64 ClassId : 8; - u64 SizeOrUnusedBytes : 20; + uptr ClassId : 8; u8 State : 2; u8 Origin : 2; - u64 Offset : 16; + uptr SizeOrUnusedBytes : 20; + uptr Offset : 16; + uptr Checksum : 16; }; typedef atomic_u64 AtomicPackedHeader; COMPILER_CHECK(sizeof(UnpackedHeader) == sizeof(PackedHeader)); // Those constants are required to silence some -Werror=conversion errors when // assigning values to the related bitfield variables. -constexpr uptr ChecksumMask = (1UL << 16) - 1; constexpr uptr ClassIdMask = (1UL << 8) - 1; +constexpr u8 StateMask = (1U << 2) - 1; +constexpr u8 OriginMask = (1U << 2) - 1; constexpr uptr SizeOrUnusedBytesMask = (1UL << 20) - 1; -constexpr uptr StateMask = (1UL << 2) - 1; -constexpr uptr OriginMask = (1UL << 2) - 1; constexpr uptr OffsetMask = (1UL << 16) - 1; +constexpr uptr ChecksumMask = (1UL << 16) - 1; constexpr uptr getHeaderSize() { return roundUpTo(sizeof(PackedHeader), 1U << SCUDO_MIN_ALIGNMENT_LOG); diff --git a/lib/scudo/standalone/combined.h b/lib/scudo/standalone/combined.h index 4c1c1196bf8f..60be1dd20d39 100644 --- a/lib/scudo/standalone/combined.h +++ b/lib/scudo/standalone/combined.h @@ -46,8 +46,8 @@ public: Chunk::compareExchangeHeader(Allocator.Cookie, Ptr, &NewHeader, &Header); void *BlockBegin = Allocator::getBlockBegin(Ptr, &NewHeader); - const uptr ClassId = Header.ClassId; - if (ClassId) + const uptr ClassId = NewHeader.ClassId; + if (LIKELY(ClassId)) Cache.deallocate(ClassId, BlockBegin); else Allocator.Secondary.deallocate(BlockBegin); @@ -123,14 +123,16 @@ public: Options.ZeroContents = getFlags()->zero_contents; Options.DeallocTypeMismatch = getFlags()->dealloc_type_mismatch; Options.DeleteSizeMismatch = getFlags()->delete_size_mismatch; - Options.QuarantineMaxChunkSize = getFlags()->quarantine_max_chunk_size; + Options.QuarantineMaxChunkSize = + static_cast<u32>(getFlags()->quarantine_max_chunk_size); Stats.initLinkerInitialized(); Primary.initLinkerInitialized(getFlags()->release_to_os_interval_ms); Secondary.initLinkerInitialized(&Stats); - Quarantine.init(getFlags()->quarantine_size_kb << 10, - getFlags()->thread_local_quarantine_size_kb << 10); + Quarantine.init( + static_cast<uptr>(getFlags()->quarantine_size_kb << 10), + static_cast<uptr>(getFlags()->thread_local_quarantine_size_kb << 10)); } void reset() { memset(this, 0, sizeof(*this)); } @@ -165,16 +167,17 @@ public: return nullptr; reportAlignmentTooBig(Alignment, MaxAlignment); } - if (UNLIKELY(Alignment < MinAlignment)) + if (Alignment < MinAlignment) Alignment = MinAlignment; // If the requested size happens to be 0 (more common than you might think), - // allocate 1 byte on top of the header. Then add the extra bytes required - // to fulfill the alignment requirements: we allocate enough to be sure that - // there will be an address in the block that will satisfy the alignment. + // allocate MinAlignment bytes on top of the header. Then add the extra + // bytes required to fulfill the alignment requirements: we allocate enough + // to be sure that there will be an address in the block that will satisfy + // the alignment. const uptr NeededSize = - Chunk::getHeaderSize() + roundUpTo(Size ? Size : 1, MinAlignment) + - ((Alignment > MinAlignment) ? (Alignment - Chunk::getHeaderSize()) : 0); + roundUpTo(Size, MinAlignment) + + ((Alignment > MinAlignment) ? Alignment : Chunk::getHeaderSize()); // Takes care of extravagantly large sizes as well as integer overflows. if (UNLIKELY(Size >= MaxAllowedMallocSize || @@ -186,9 +189,10 @@ public: void *Block; uptr ClassId; - uptr BlockEnd = 0; - if (PrimaryT::canAllocate(NeededSize)) { + uptr BlockEnd; + if (LIKELY(PrimaryT::canAllocate(NeededSize))) { ClassId = SizeClassMap::getClassIdBySize(NeededSize); + DCHECK_NE(ClassId, 0U); bool UnlockRequired; auto *TSD = TSDRegistry.getTSDAndLock(&UnlockRequired); Block = TSD->Cache.allocate(ClassId); @@ -205,17 +209,17 @@ public: reportOutOfMemory(NeededSize); } - // We only need to zero the contents for Primary backed allocations. - if ((ZeroContents || Options.ZeroContents) && ClassId) + // We only need to zero the contents for Primary backed allocations. This + // condition is not necessarily unlikely, but since memset is costly, we + // might as well mark it as such. + if (UNLIKELY((ZeroContents || Options.ZeroContents) && ClassId)) memset(Block, 0, PrimaryT::getSizeByClassId(ClassId)); Chunk::UnpackedHeader Header = {}; uptr UserPtr = reinterpret_cast<uptr>(Block) + Chunk::getHeaderSize(); - // The following condition isn't necessarily "UNLIKELY". - if (!isAligned(UserPtr, Alignment)) { + if (UNLIKELY(!isAligned(UserPtr, Alignment))) { const uptr AlignedUserPtr = roundUpTo(UserPtr, Alignment); const uptr Offset = AlignedUserPtr - UserPtr; - Header.Offset = (Offset >> MinAlignmentLog) & Chunk::OffsetMask; DCHECK_GT(Offset, 2 * sizeof(u32)); // The BlockMarker has no security purpose, but is specifically meant for // the chunk iteration function that can be used in debugging situations. @@ -224,16 +228,13 @@ public: reinterpret_cast<u32 *>(Block)[0] = BlockMarker; reinterpret_cast<u32 *>(Block)[1] = static_cast<u32>(Offset); UserPtr = AlignedUserPtr; + Header.Offset = (Offset >> MinAlignmentLog) & Chunk::OffsetMask; } + Header.ClassId = ClassId & Chunk::ClassIdMask; Header.State = Chunk::State::Allocated; Header.Origin = Origin & Chunk::OriginMask; - if (ClassId) { - Header.ClassId = ClassId & Chunk::ClassIdMask; - Header.SizeOrUnusedBytes = Size & Chunk::SizeOrUnusedBytesMask; - } else { - Header.SizeOrUnusedBytes = - (BlockEnd - (UserPtr + Size)) & Chunk::SizeOrUnusedBytesMask; - } + Header.SizeOrUnusedBytes = (ClassId ? Size : BlockEnd - (UserPtr + Size)) & + Chunk::SizeOrUnusedBytesMask; void *Ptr = reinterpret_cast<void *>(UserPtr); Chunk::storeHeader(Cookie, Ptr, &Header); @@ -310,18 +311,30 @@ public: OldHeader.Origin, Chunk::Origin::Malloc); } - const uptr OldSize = getSize(OldPtr, &OldHeader); - // If the new size is identical to the old one, or lower but within an - // acceptable range, we just keep the old chunk, and update its header. - if (NewSize == OldSize) - return OldPtr; - if (NewSize < OldSize) { - const uptr Delta = OldSize - NewSize; - if (Delta < (SizeClassMap::MaxSize / 2)) { + void *BlockBegin = getBlockBegin(OldPtr, &OldHeader); + uptr BlockEnd; + uptr OldSize; + const uptr ClassId = OldHeader.ClassId; + if (LIKELY(ClassId)) { + BlockEnd = reinterpret_cast<uptr>(BlockBegin) + + SizeClassMap::getSizeByClassId(ClassId); + OldSize = OldHeader.SizeOrUnusedBytes; + } else { + BlockEnd = SecondaryT::getBlockEnd(BlockBegin); + OldSize = BlockEnd - + (reinterpret_cast<uptr>(OldPtr) + OldHeader.SizeOrUnusedBytes); + } + // If the new chunk still fits in the previously allocated block (with a + // reasonable delta), we just keep the old block, and update the chunk + // header to reflect the size change. + if (reinterpret_cast<uptr>(OldPtr) + NewSize <= BlockEnd) { + const uptr Delta = + OldSize < NewSize ? NewSize - OldSize : OldSize - NewSize; + if (Delta <= SizeClassMap::MaxSize / 2) { Chunk::UnpackedHeader NewHeader = OldHeader; NewHeader.SizeOrUnusedBytes = - (OldHeader.ClassId ? NewHeader.SizeOrUnusedBytes - Delta - : NewHeader.SizeOrUnusedBytes + Delta) & + (ClassId ? NewSize + : BlockEnd - (reinterpret_cast<uptr>(OldPtr) + NewSize)) & Chunk::SizeOrUnusedBytesMask; Chunk::compareExchangeHeader(Cookie, OldPtr, &NewHeader, &OldHeader); return OldPtr; @@ -334,6 +347,7 @@ public: // are currently unclear. void *NewPtr = allocate(NewSize, Chunk::Origin::Malloc, Alignment); if (NewPtr) { + const uptr OldSize = getSize(OldPtr, &OldHeader); memcpy(NewPtr, OldPtr, Min(NewSize, OldSize)); quarantineOrDeallocateChunk(OldPtr, &OldHeader, OldSize); } @@ -355,12 +369,31 @@ public: Primary.enable(); } + // The function returns the amount of bytes required to store the statistics, + // which might be larger than the amount of bytes provided. Note that the + // statistics buffer is not necessarily constant between calls to this + // function. This can be called with a null buffer or zero size for buffer + // sizing purposes. + uptr getStats(char *Buffer, uptr Size) { + ScopedString Str(1024); + disable(); + const uptr Length = getStats(&Str) + 1; + enable(); + if (Length < Size) + Size = Length; + if (Buffer && Size) { + memcpy(Buffer, Str.data(), Size); + Buffer[Size - 1] = '\0'; + } + return Length; + } + void printStats() { + ScopedString Str(1024); disable(); - Primary.printStats(); - Secondary.printStats(); - Quarantine.printStats(); + getStats(&Str); enable(); + Str.output(); } void releaseToOS() { Primary.releaseToOS(); } @@ -374,7 +407,7 @@ public: const uptr From = Base; const uptr To = Base + Size; auto Lambda = [this, From, To, Callback, Arg](uptr Block) { - if (Block < From || Block > To) + if (Block < From || Block >= To) return; uptr ChunkSize; const uptr ChunkBase = getChunkFromBlock(Block, &ChunkSize); @@ -471,8 +504,7 @@ private: // last and last class sizes, as well as the dynamic base for the Primary. // The following is an over-approximation that works for our needs. const uptr MaxSizeOrUnusedBytes = SizeClassMap::MaxSize - 1; - Header.SizeOrUnusedBytes = - MaxSizeOrUnusedBytes & Chunk::SizeOrUnusedBytesMask; + Header.SizeOrUnusedBytes = MaxSizeOrUnusedBytes; if (UNLIKELY(Header.SizeOrUnusedBytes != MaxSizeOrUnusedBytes)) reportSanityCheckError("size (or unused bytes)"); @@ -484,15 +516,15 @@ private: static INLINE void *getBlockBegin(const void *Ptr, Chunk::UnpackedHeader *Header) { - return reinterpret_cast<void *>(reinterpret_cast<uptr>(Ptr) - - Chunk::getHeaderSize() - - (Header->Offset << MinAlignmentLog)); + return reinterpret_cast<void *>( + reinterpret_cast<uptr>(Ptr) - Chunk::getHeaderSize() - + (static_cast<uptr>(Header->Offset) << MinAlignmentLog)); } // Return the size of a chunk as requested during its allocation. INLINE uptr getSize(const void *Ptr, Chunk::UnpackedHeader *Header) { const uptr SizeOrUnusedBytes = Header->SizeOrUnusedBytes; - if (Header->ClassId) + if (LIKELY(Header->ClassId)) return SizeOrUnusedBytes; return SecondaryT::getBlockEnd(getBlockBegin(Ptr, Header)) - reinterpret_cast<uptr>(Ptr) - SizeOrUnusedBytes; @@ -514,7 +546,7 @@ private: Chunk::compareExchangeHeader(Cookie, Ptr, &NewHeader, Header); void *BlockBegin = getBlockBegin(Ptr, &NewHeader); const uptr ClassId = NewHeader.ClassId; - if (ClassId) { + if (LIKELY(ClassId)) { bool UnlockRequired; auto *TSD = TSDRegistry.getTSDAndLock(&UnlockRequired); TSD->Cache.deallocate(ClassId, BlockBegin); @@ -550,6 +582,13 @@ private: *Size = getSize(Ptr, &Header); return P; } + + uptr getStats(ScopedString *Str) { + Primary.getStats(Str); + Secondary.getStats(Str); + Quarantine.getStats(Str); + return Str->length(); + } }; } // namespace scudo diff --git a/lib/scudo/standalone/common.cc b/lib/scudo/standalone/common.cpp index 2a26efbb9c89..d93bfc59b3ca 100644 --- a/lib/scudo/standalone/common.cc +++ b/lib/scudo/standalone/common.cpp @@ -1,4 +1,4 @@ -//===-- common.cc -----------------------------------------------*- C++ -*-===// +//===-- common.cpp ----------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/scudo/standalone/crc32_hw.cc b/lib/scudo/standalone/crc32_hw.cpp index f4dae7b5fea8..62841ba51019 100644 --- a/lib/scudo/standalone/crc32_hw.cc +++ b/lib/scudo/standalone/crc32_hw.cpp @@ -1,4 +1,4 @@ -//===-- crc32_hw.h ----------------------------------------------*- C++ -*-===// +//===-- crc32_hw.cpp --------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/scudo/standalone/flags.cc b/lib/scudo/standalone/flags.cpp index 21144f211102..1e970ae49505 100644 --- a/lib/scudo/standalone/flags.cc +++ b/lib/scudo/standalone/flags.cpp @@ -1,4 +1,4 @@ -//===-- flags.cc ------------------------------------------------*- C++ -*-===// +//===-- flags.cpp -----------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/scudo/standalone/flags_parser.cc b/lib/scudo/standalone/flags_parser.cpp index 5f1253f58d52..070c08b01938 100644 --- a/lib/scudo/standalone/flags_parser.cc +++ b/lib/scudo/standalone/flags_parser.cpp @@ -1,4 +1,4 @@ -//===-- flags_parser.cc -----------------------------------------*- C++ -*-===// +//===-- flags_parser.cpp ----------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/scudo/standalone/fuchsia.cc b/lib/scudo/standalone/fuchsia.cpp index 896d346e7e72..0a9483ae1dd0 100644 --- a/lib/scudo/standalone/fuchsia.cc +++ b/lib/scudo/standalone/fuchsia.cpp @@ -1,4 +1,4 @@ -//===-- fuchsia.cc ----------------------------------------------*- C++ -*-===// +//===-- fuchsia.cpp ---------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -40,7 +40,7 @@ static void *allocateVmar(uptr Size, MapPlatformData *Data, bool AllowNoMem) { _zx_vmar_root_self(), ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE | ZX_VM_CAN_MAP_SPECIFIC, 0, Size, &Data->Vmar, &Data->VmarBase); - if (Status != ZX_OK) { + if (UNLIKELY(Status != ZX_OK)) { if (Status != ZX_ERR_NO_MEMORY || !AllowNoMem) dieOnMapUnmapError(Status == ZX_ERR_NO_MEMORY); return nullptr; @@ -78,7 +78,7 @@ void *map(void *Addr, uptr Size, const char *Name, uptr Flags, } else { // Otherwise, create a Vmo and set its name. Status = _zx_vmo_create(Size, ZX_VMO_RESIZABLE, &Vmo); - if (Status != ZX_OK) { + if (UNLIKELY(Status != ZX_OK)) { if (Status != ZX_ERR_NO_MEMORY || !AllowNoMem) dieOnMapUnmapError(Status == ZX_ERR_NO_MEMORY); return nullptr; @@ -102,7 +102,7 @@ void *map(void *Addr, uptr Size, const char *Name, uptr Flags, } else { CHECK_EQ(_zx_handle_close(Vmo), ZX_OK); } - if (Status != ZX_OK) { + if (UNLIKELY(Status != ZX_OK)) { if (Status != ZX_ERR_NO_MEMORY || !AllowNoMem) dieOnMapUnmapError(Status == ZX_ERR_NO_MEMORY); return nullptr; @@ -125,7 +125,7 @@ void unmap(void *Addr, uptr Size, uptr Flags, MapPlatformData *Data) { const zx_handle_t Vmar = Data ? Data->Vmar : _zx_vmar_root_self(); const zx_status_t Status = _zx_vmar_unmap(Vmar, reinterpret_cast<uintptr_t>(Addr), Size); - if (Status != ZX_OK) + if (UNLIKELY(Status != ZX_OK)) dieOnMapUnmapError(); } if (Data) { @@ -170,9 +170,9 @@ u64 getMonotonicTime() { return _zx_clock_get_monotonic(); } u32 getNumberOfCPUs() { return _zx_system_get_num_cpus(); } -bool getRandom(void *Buffer, uptr Length, bool Blocking) { +bool getRandom(void *Buffer, uptr Length, UNUSED bool Blocking) { COMPILER_CHECK(MaxRandomLength <= ZX_CPRNG_DRAW_MAX_LEN); - if (!Buffer || !Length || Length > MaxRandomLength) + if (UNLIKELY(!Buffer || !Length || Length > MaxRandomLength)) return false; _zx_cprng_draw(Buffer, Length); return true; diff --git a/lib/scudo/standalone/internal_defs.h b/lib/scudo/standalone/internal_defs.h index 901eac372b36..64ed238ebfec 100644 --- a/lib/scudo/standalone/internal_defs.h +++ b/lib/scudo/standalone/internal_defs.h @@ -55,11 +55,11 @@ namespace scudo { typedef unsigned long uptr; -typedef signed long sptr; typedef unsigned char u8; typedef unsigned short u16; typedef unsigned int u32; typedef unsigned long long u64; +typedef signed long sptr; typedef signed char s8; typedef signed short s16; typedef signed int s32; @@ -128,8 +128,6 @@ void NORETURN reportCheckFailed(const char *File, int Line, #define COMPILER_CHECK(Pred) static_assert(Pred, "") -enum LinkerInitialized { LINKER_INITIALIZED = 0 }; - } // namespace scudo #endif // SCUDO_INTERNAL_DEFS_H_ diff --git a/lib/scudo/standalone/linux.cc b/lib/scudo/standalone/linux.cpp index 049477bba8b0..8266a528f42c 100644 --- a/lib/scudo/standalone/linux.cc +++ b/lib/scudo/standalone/linux.cpp @@ -1,4 +1,4 @@ -//===-- linux.cc ------------------------------------------------*- C++ -*-===// +//===-- linux.cpp -----------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -43,7 +43,7 @@ void NORETURN die() { abort(); } void *map(void *Addr, uptr Size, UNUSED const char *Name, uptr Flags, UNUSED MapPlatformData *Data) { - int MmapFlags = MAP_PRIVATE | MAP_ANON; + int MmapFlags = MAP_PRIVATE | MAP_ANONYMOUS; int MmapProt; if (Flags & MAP_NOACCESS) { MmapFlags |= MAP_NORESERVE; diff --git a/lib/scudo/standalone/linux.h b/lib/scudo/standalone/linux.h index 92c9eb5e97ee..c8e41484c851 100644 --- a/lib/scudo/standalone/linux.h +++ b/lib/scudo/standalone/linux.h @@ -55,7 +55,7 @@ struct MapPlatformData {}; // 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 = 8; // TODO(kostyak): 6 for Q!! +static const int TLS_SLOT_SANITIZER = 6; ALWAYS_INLINE uptr *getAndroidTlsPtr() { return reinterpret_cast<uptr *>(&__get_tls()[TLS_SLOT_SANITIZER]); diff --git a/lib/scudo/standalone/list.h b/lib/scudo/standalone/list.h index 139e73eff5ad..6a7b9bd747a7 100644 --- a/lib/scudo/standalone/list.h +++ b/lib/scudo/standalone/list.h @@ -106,17 +106,17 @@ template <class Item> struct IntrusiveList { void checkConsistency() { if (Size == 0) { - CHECK_EQ(First, 0); - CHECK_EQ(Last, 0); + CHECK_EQ(First, nullptr); + CHECK_EQ(Last, nullptr); } else { - uptr count = 0; + uptr Count = 0; for (Item *I = First;; I = I->Next) { - count++; + Count++; if (I == Last) break; } - CHECK_EQ(size(), count); - CHECK_EQ(Last->Next, 0); + CHECK_EQ(size(), Count); + CHECK_EQ(Last->Next, nullptr); } } diff --git a/lib/scudo/standalone/local_cache.h b/lib/scudo/standalone/local_cache.h index 2acc28874015..b08abd3e5d9b 100644 --- a/lib/scudo/standalone/local_cache.h +++ b/lib/scudo/standalone/local_cache.h @@ -22,9 +22,8 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache { static const u32 MaxNumCached = SizeClassMap::MaxNumCachedHint; void setFromArray(void **Array, u32 N) { DCHECK_LE(N, MaxNumCached); - for (u32 I = 0; I < N; I++) - Batch[I] = Array[I]; Count = N; + memcpy(Batch, Array, sizeof(void *) * Count); } void clear() { Count = 0; } void add(void *P) { @@ -32,8 +31,7 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache { Batch[Count++] = P; } void copyToArray(void **Array) const { - for (u32 I = 0; I < Count; I++) - Array[I] = Batch[I]; + memcpy(Array, Batch, sizeof(void *) * Count); } u32 getCount() const { return Count; } void *get(u32 I) const { @@ -52,7 +50,7 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache { void initLinkerInitialized(GlobalStats *S, SizeClassAllocator *A) { Stats.initLinkerInitialized(); - if (S) + if (LIKELY(S)) S->link(&Stats); Allocator = A; } @@ -64,12 +62,12 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache { void destroy(GlobalStats *S) { drain(); - if (S) + if (LIKELY(S)) S->unlink(&Stats); } void *allocate(uptr ClassId) { - CHECK_LT(ClassId, NumClasses); + DCHECK_LT(ClassId, NumClasses); PerClass *C = &PerClassArray[ClassId]; if (C->Count == 0) { if (UNLIKELY(!refill(C, ClassId))) @@ -85,6 +83,7 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache { // performance. It definitely decreases performance on Android though. // if (!SCUDO_ANDROID) PREFETCH(P); Stats.add(StatAllocated, ClassSize); + Stats.sub(StatFree, ClassSize); return P; } @@ -100,6 +99,7 @@ template <class SizeClassAllocator> struct SizeClassAllocatorLocalCache { const uptr ClassSize = C->ClassSize; C->Chunks[C->Count++] = P; Stats.sub(StatAllocated, ClassSize); + Stats.add(StatFree, ClassSize); } void drain() { @@ -157,8 +157,8 @@ private: if (UNLIKELY(!B)) return false; DCHECK_GT(B->getCount(), 0); - B->copyToArray(C->Chunks); C->Count = B->getCount(); + B->copyToArray(C->Chunks); destroyBatch(ClassId, B); return true; } diff --git a/lib/scudo/standalone/mutex.h b/lib/scudo/standalone/mutex.h index b6dc9188d347..b26b2df06627 100644 --- a/lib/scudo/standalone/mutex.h +++ b/lib/scudo/standalone/mutex.h @@ -25,7 +25,7 @@ public: void init() { memset(this, 0, sizeof(*this)); } bool tryLock(); NOINLINE void lock() { - if (tryLock()) + if (LIKELY(tryLock())) return; // The compiler may try to fully unroll the loop, ending up in a // NumberOfTries*NumberOfYields block of pauses mixed with tryLocks. This @@ -44,8 +44,8 @@ public: void unlock(); private: - static constexpr u8 NumberOfTries = 10U; - static constexpr u8 NumberOfYields = 10U; + static constexpr u8 NumberOfTries = 8U; + static constexpr u8 NumberOfYields = 8U; #if SCUDO_LINUX atomic_u32 M; diff --git a/lib/scudo/standalone/primary32.h b/lib/scudo/standalone/primary32.h index 2b2fa8b3d793..9123d07b49b9 100644 --- a/lib/scudo/standalone/primary32.h +++ b/lib/scudo/standalone/primary32.h @@ -72,7 +72,7 @@ public: SizeClassInfo *Sci = getSizeClassInfo(I); Sci->RandState = getRandomU32(&Seed); // See comment in the 64-bit primary about releasing smaller size classes. - Sci->CanRelease = (ReleaseToOsInterval > 0) && + Sci->CanRelease = (ReleaseToOsInterval >= 0) && (I != SizeClassMap::BatchClassId) && (getSizeByClassId(I) >= (PageSize / 32)); } @@ -99,9 +99,9 @@ public: SizeClassInfo *Sci = getSizeClassInfo(ClassId); ScopedLock L(Sci->Mutex); TransferBatch *B = Sci->FreeList.front(); - if (B) + if (B) { Sci->FreeList.pop_front(); - else { + } else { B = populateFreeList(C, ClassId, Sci); if (UNLIKELY(!B)) return nullptr; @@ -129,7 +129,7 @@ public: void enable() { for (sptr I = static_cast<sptr>(NumClasses) - 1; I >= 0; I--) - getSizeClassInfo(I)->Mutex.unlock(); + getSizeClassInfo(static_cast<uptr>(I))->Mutex.unlock(); } template <typename F> void iterateOverBlocks(F Callback) { @@ -143,7 +143,7 @@ public: } } - void printStats() { + void getStats(ScopedString *Str) { // TODO(kostyak): get the RSS per region. uptr TotalMapped = 0; uptr PoppedBlocks = 0; @@ -154,21 +154,23 @@ public: PoppedBlocks += Sci->Stats.PoppedBlocks; PushedBlocks += Sci->Stats.PushedBlocks; } - Printf("Stats: SizeClassAllocator32: %zuM mapped in %zu allocations; " - "remains %zu\n", - TotalMapped >> 20, PoppedBlocks, PoppedBlocks - PushedBlocks); + Str->append("Stats: SizeClassAllocator32: %zuM mapped in %zu allocations; " + "remains %zu\n", + TotalMapped >> 20, PoppedBlocks, PoppedBlocks - PushedBlocks); for (uptr I = 0; I < NumClasses; I++) - printStats(I, 0); + getStats(Str, I, 0); } - void releaseToOS() { + uptr releaseToOS() { + uptr TotalReleasedBytes = 0; for (uptr I = 0; I < NumClasses; I++) { if (I == SizeClassMap::BatchClassId) continue; SizeClassInfo *Sci = getSizeClassInfo(I); ScopedLock L(Sci->Mutex); - releaseToOSMaybe(Sci, I, /*Force=*/true); + TotalReleasedBytes += releaseToOSMaybe(Sci, I, /*Force=*/true); } + return TotalReleasedBytes; } private: @@ -318,53 +320,59 @@ private: } DCHECK(B); DCHECK_GT(B->getCount(), 0); + + C->getStats().add(StatFree, AllocatedUser); Sci->AllocatedUser += AllocatedUser; if (Sci->CanRelease) Sci->ReleaseInfo.LastReleaseAtNs = getMonotonicTime(); return B; } - void printStats(uptr ClassId, uptr Rss) { + void getStats(ScopedString *Str, uptr ClassId, uptr Rss) { SizeClassInfo *Sci = getSizeClassInfo(ClassId); if (Sci->AllocatedUser == 0) return; const uptr InUse = Sci->Stats.PoppedBlocks - Sci->Stats.PushedBlocks; const uptr AvailableChunks = Sci->AllocatedUser / getSizeByClassId(ClassId); - Printf(" %02zu (%6zu): mapped: %6zuK popped: %7zu pushed: %7zu inuse: %6zu" - " avail: %6zu rss: %6zuK\n", - ClassId, getSizeByClassId(ClassId), Sci->AllocatedUser >> 10, - Sci->Stats.PoppedBlocks, Sci->Stats.PushedBlocks, InUse, - AvailableChunks, Rss >> 10); + Str->append(" %02zu (%6zu): mapped: %6zuK popped: %7zu pushed: %7zu " + "inuse: %6zu avail: %6zu rss: %6zuK\n", + ClassId, getSizeByClassId(ClassId), Sci->AllocatedUser >> 10, + Sci->Stats.PoppedBlocks, Sci->Stats.PushedBlocks, InUse, + AvailableChunks, Rss >> 10); } - NOINLINE void releaseToOSMaybe(SizeClassInfo *Sci, uptr ClassId, + NOINLINE uptr releaseToOSMaybe(SizeClassInfo *Sci, uptr ClassId, bool Force = false) { const uptr BlockSize = getSizeByClassId(ClassId); const uptr PageSize = getPageSizeCached(); CHECK_GE(Sci->Stats.PoppedBlocks, Sci->Stats.PushedBlocks); - const uptr N = Sci->Stats.PoppedBlocks - Sci->Stats.PushedBlocks; - if (N * BlockSize < PageSize) - return; // No chance to release anything. + const uptr BytesInFreeList = + Sci->AllocatedUser - + (Sci->Stats.PoppedBlocks - Sci->Stats.PushedBlocks) * BlockSize; + if (BytesInFreeList < PageSize) + return 0; // No chance to release anything. if ((Sci->Stats.PushedBlocks - Sci->ReleaseInfo.PushedBlocksAtLastRelease) * BlockSize < PageSize) { - return; // Nothing new to release. + return 0; // Nothing new to release. } if (!Force) { const s32 IntervalMs = ReleaseToOsIntervalMs; if (IntervalMs < 0) - return; - if (Sci->ReleaseInfo.LastReleaseAtNs + IntervalMs * 1000000ULL > + return 0; + if (Sci->ReleaseInfo.LastReleaseAtNs + + static_cast<uptr>(IntervalMs) * 1000000ULL > getMonotonicTime()) { - return; // Memory was returned recently. + return 0; // Memory was returned recently. } } // TODO(kostyak): currently not ideal as we loop over all regions and // iterate multiple times over the same freelist if a ClassId spans multiple // regions. But it will have to do for now. + uptr TotalReleasedBytes = 0; for (uptr I = MinRegionIndex; I <= MaxRegionIndex; I++) { if (PossibleRegions[I] == ClassId) { ReleaseRecorder Recorder(I * RegionSize); @@ -374,10 +382,12 @@ private: Sci->ReleaseInfo.PushedBlocksAtLastRelease = Sci->Stats.PushedBlocks; Sci->ReleaseInfo.RangesReleased += Recorder.getReleasedRangesCount(); Sci->ReleaseInfo.LastReleasedBytes = Recorder.getReleasedBytes(); + TotalReleasedBytes += Sci->ReleaseInfo.LastReleasedBytes; } } } Sci->ReleaseInfo.LastReleaseAtNs = getMonotonicTime(); + return TotalReleasedBytes; } SizeClassInfo SizeClassInfoArray[NumClasses]; diff --git a/lib/scudo/standalone/primary64.h b/lib/scudo/standalone/primary64.h index 035182b33ef4..8f443ea7fa3f 100644 --- a/lib/scudo/standalone/primary64.h +++ b/lib/scudo/standalone/primary64.h @@ -36,7 +36,7 @@ namespace scudo { // freelist to the thread specific freelist, and back. // // The memory used by this allocator is never unmapped, but can be partially -// released it the platform allows for it. +// released if the platform allows for it. template <class SizeClassMapT, uptr RegionSizeLog> class SizeClassAllocator64 { public: @@ -79,7 +79,7 @@ public: // memory accesses which ends up being fairly costly. The current lower // limit is mostly arbitrary and based on empirical observations. // TODO(kostyak): make the lower limit a runtime option - Region->CanRelease = (ReleaseToOsInterval > 0) && + Region->CanRelease = (ReleaseToOsInterval >= 0) && (I != SizeClassMap::BatchClassId) && (getSizeByClassId(I) >= (PageSize / 32)); Region->RandState = getRandomU32(&Seed); @@ -102,9 +102,9 @@ public: RegionInfo *Region = getRegionInfo(ClassId); ScopedLock L(Region->Mutex); TransferBatch *B = Region->FreeList.front(); - if (B) + if (B) { Region->FreeList.pop_front(); - else { + } else { B = populateFreeList(C, ClassId, Region); if (UNLIKELY(!B)) return nullptr; @@ -131,11 +131,13 @@ public: void enable() { for (sptr I = static_cast<sptr>(NumClasses) - 1; I >= 0; I--) - getRegionInfo(I)->Mutex.unlock(); + getRegionInfo(static_cast<uptr>(I))->Mutex.unlock(); } template <typename F> void iterateOverBlocks(F Callback) const { - for (uptr I = 1; I < NumClasses; I++) { + for (uptr I = 0; I < NumClasses; I++) { + if (I == SizeClassMap::BatchClassId) + continue; const RegionInfo *Region = getRegionInfo(I); const uptr BlockSize = getSizeByClassId(I); const uptr From = Region->RegionBeg; @@ -145,7 +147,7 @@ public: } } - void printStats() const { + void getStats(ScopedString *Str) const { // TODO(kostyak): get the RSS per region. uptr TotalMapped = 0; uptr PoppedBlocks = 0; @@ -157,22 +159,25 @@ public: PoppedBlocks += Region->Stats.PoppedBlocks; PushedBlocks += Region->Stats.PushedBlocks; } - Printf("Stats: Primary64: %zuM mapped (%zuM rss) in %zu allocations; " - "remains %zu\n", - TotalMapped >> 20, 0, PoppedBlocks, PoppedBlocks - PushedBlocks); + Str->append("Stats: SizeClassAllocator64: %zuM mapped (%zuM rss) in %zu " + "allocations; remains %zu\n", + TotalMapped >> 20, 0, PoppedBlocks, + PoppedBlocks - PushedBlocks); for (uptr I = 0; I < NumClasses; I++) - printStats(I, 0); + getStats(Str, I, 0); } - void releaseToOS() { + uptr releaseToOS() { + uptr TotalReleasedBytes = 0; for (uptr I = 0; I < NumClasses; I++) { if (I == SizeClassMap::BatchClassId) continue; RegionInfo *Region = getRegionInfo(I); ScopedLock L(Region->Mutex); - releaseToOSMaybe(Region, I, /*Force=*/true); + TotalReleasedBytes += releaseToOSMaybe(Region, I, /*Force=*/true); } + return TotalReleasedBytes; } private: @@ -181,7 +186,7 @@ private: static const uptr PrimarySize = RegionSize * NumClasses; // Call map for user memory with at least this size. - static const uptr MapSizeIncrement = 1UL << 16; + static const uptr MapSizeIncrement = 1UL << 17; struct RegionStats { uptr PoppedBlocks; @@ -257,7 +262,7 @@ private: const uptr MappedUser = Region->MappedUser; const uptr TotalUserBytes = Region->AllocatedUser + MaxCount * Size; // Map more space for blocks, if necessary. - if (LIKELY(TotalUserBytes > MappedUser)) { + if (TotalUserBytes > MappedUser) { // Do the mmap for the user memory. const uptr UserMapSize = roundUpTo(TotalUserBytes - MappedUser, MapSizeIncrement); @@ -265,14 +270,16 @@ private: if (UNLIKELY(RegionBase + MappedUser + UserMapSize > RegionSize)) { if (!Region->Exhausted) { Region->Exhausted = true; - printStats(); - Printf( + ScopedString Str(1024); + getStats(&Str); + Str.append( "Scudo OOM: The process has Exhausted %zuM for size class %zu.\n", RegionSize >> 20, Size); + Str.output(); } return nullptr; } - if (MappedUser == 0) + if (UNLIKELY(MappedUser == 0)) Region->Data = Data; if (UNLIKELY(!map(reinterpret_cast<void *>(RegionBeg + MappedUser), UserMapSize, "scudo:primary", @@ -307,8 +314,9 @@ private: return nullptr; } DCHECK(B); - CHECK_GT(B->getCount(), 0); + DCHECK_GT(B->getCount(), 0); + C->getStats().add(StatFree, AllocatedUser); Region->AllocatedUser += AllocatedUser; Region->Exhausted = false; if (Region->CanRelease) @@ -317,47 +325,49 @@ private: return B; } - void printStats(uptr ClassId, uptr Rss) const { + void getStats(ScopedString *Str, uptr ClassId, uptr Rss) const { RegionInfo *Region = getRegionInfo(ClassId); if (Region->MappedUser == 0) return; const uptr InUse = Region->Stats.PoppedBlocks - Region->Stats.PushedBlocks; - const uptr AvailableChunks = - Region->AllocatedUser / getSizeByClassId(ClassId); - Printf("%s %02zu (%6zu): mapped: %6zuK popped: %7zu pushed: %7zu inuse: " - "%6zu avail: %6zu rss: %6zuK releases: %6zu last released: %6zuK " - "region: 0x%zx (0x%zx)\n", - Region->Exhausted ? "F" : " ", ClassId, getSizeByClassId(ClassId), - Region->MappedUser >> 10, Region->Stats.PoppedBlocks, - Region->Stats.PushedBlocks, InUse, AvailableChunks, Rss >> 10, - Region->ReleaseInfo.RangesReleased, - Region->ReleaseInfo.LastReleasedBytes >> 10, Region->RegionBeg, - getRegionBaseByClassId(ClassId)); + const uptr TotalChunks = Region->AllocatedUser / getSizeByClassId(ClassId); + Str->append("%s %02zu (%6zu): mapped: %6zuK popped: %7zu pushed: %7zu " + "inuse: %6zu total: %6zu rss: %6zuK releases: %6zu last " + "released: %6zuK region: 0x%zx (0x%zx)\n", + Region->Exhausted ? "F" : " ", ClassId, + getSizeByClassId(ClassId), Region->MappedUser >> 10, + Region->Stats.PoppedBlocks, Region->Stats.PushedBlocks, InUse, + TotalChunks, Rss >> 10, Region->ReleaseInfo.RangesReleased, + Region->ReleaseInfo.LastReleasedBytes >> 10, Region->RegionBeg, + getRegionBaseByClassId(ClassId)); } - NOINLINE void releaseToOSMaybe(RegionInfo *Region, uptr ClassId, + NOINLINE uptr releaseToOSMaybe(RegionInfo *Region, uptr ClassId, bool Force = false) { const uptr BlockSize = getSizeByClassId(ClassId); const uptr PageSize = getPageSizeCached(); CHECK_GE(Region->Stats.PoppedBlocks, Region->Stats.PushedBlocks); - const uptr N = Region->Stats.PoppedBlocks - Region->Stats.PushedBlocks; - if (N * BlockSize < PageSize) - return; // No chance to release anything. + const uptr BytesInFreeList = + Region->AllocatedUser - + (Region->Stats.PoppedBlocks - Region->Stats.PushedBlocks) * BlockSize; + if (BytesInFreeList < PageSize) + return 0; // No chance to release anything. if ((Region->Stats.PushedBlocks - Region->ReleaseInfo.PushedBlocksAtLastRelease) * BlockSize < PageSize) { - return; // Nothing new to release. + return 0; // Nothing new to release. } if (!Force) { const s32 IntervalMs = ReleaseToOsIntervalMs; if (IntervalMs < 0) - return; - if (Region->ReleaseInfo.LastReleaseAtNs + IntervalMs * 1000000ULL > + return 0; + if (Region->ReleaseInfo.LastReleaseAtNs + + static_cast<uptr>(IntervalMs) * 1000000ULL > getMonotonicTime()) { - return; // Memory was returned recently. + return 0; // Memory was returned recently. } } @@ -373,6 +383,7 @@ private: Region->ReleaseInfo.LastReleasedBytes = Recorder.getReleasedBytes(); } Region->ReleaseInfo.LastReleaseAtNs = getMonotonicTime(); + return Recorder.getReleasedBytes(); } }; diff --git a/lib/scudo/standalone/quarantine.h b/lib/scudo/standalone/quarantine.h index bac36e01c1dd..35fd0bc197ea 100644 --- a/lib/scudo/standalone/quarantine.h +++ b/lib/scudo/standalone/quarantine.h @@ -130,7 +130,7 @@ public: subFromSize(ExtractedSize); } - void printStats() const { + void getStats(ScopedString *Str) const { uptr BatchCount = 0; uptr TotalOverheadBytes = 0; uptr TotalBytes = 0; @@ -152,11 +152,11 @@ public: (TotalQuarantinedBytes == 0) ? 0 : TotalOverheadBytes * 100 / TotalQuarantinedBytes; - Printf("Global quarantine stats: batches: %zd; bytes: %zd (user: %zd); " - "chunks: %zd (capacity: %zd); %zd%% chunks used; %zd%% memory " - "overhead\n", - BatchCount, TotalBytes, TotalQuarantinedBytes, TotalQuarantineChunks, - QuarantineChunksCapacity, ChunksUsagePercent, MemoryOverheadPercent); + Str->append( + "Stats: Quarantine: batches: %zu; bytes: %zu (user: %zu); chunks: %zu " + "(capacity: %zu); %zu%% chunks used; %zu%% memory overhead\n", + BatchCount, TotalBytes, TotalQuarantinedBytes, TotalQuarantineChunks, + QuarantineChunksCapacity, ChunksUsagePercent, MemoryOverheadPercent); } private: @@ -218,11 +218,11 @@ public: recycle(0, Cb); } - void printStats() const { + void getStats(ScopedString *Str) const { // It assumes that the world is stopped, just as the allocator's printStats. - Printf("Quarantine limits: global: %zdM; thread local: %zdK\n", - getMaxSize() >> 20, getCacheSize() >> 10); - Cache.printStats(); + Cache.getStats(Str); + Str->append("Quarantine limits: global: %zuK; thread local: %zuK\n", + getMaxSize() >> 10, getCacheSize() >> 10); } private: diff --git a/lib/scudo/standalone/report.cc b/lib/scudo/standalone/report.cpp index 47cd951e8ed4..12d851ff019a 100644 --- a/lib/scudo/standalone/report.cc +++ b/lib/scudo/standalone/report.cpp @@ -1,4 +1,4 @@ -//===-- report.cc -----------------------------------------------*- C++ -*-===// +//===-- report.cpp ----------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/scudo/standalone/secondary.cc b/lib/scudo/standalone/secondary.cpp index 75f9171f1617..db7361d7134a 100644 --- a/lib/scudo/standalone/secondary.cc +++ b/lib/scudo/standalone/secondary.cpp @@ -1,4 +1,4 @@ -//===-- secondary.cc --------------------------------------------*- C++ -*-===// +//===-- secondary.cpp -------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -32,14 +32,14 @@ void *MapAllocator::allocate(uptr Size, uptr AlignmentHint, uptr *BlockEnd) { uptr MapBase = reinterpret_cast<uptr>(map(nullptr, MapSize, "scudo:secondary", MAP_NOACCESS | MAP_ALLOWNOMEM, &Data)); - if (!MapBase) + if (UNLIKELY(!MapBase)) return nullptr; uptr CommitBase = MapBase + PageSize; uptr MapEnd = MapBase + MapSize; // In the unlikely event of alignments larger than a page, adjust the amount // of memory we want to commit, and trim the extra memory. - if (AlignmentHint >= PageSize) { + if (UNLIKELY(AlignmentHint >= PageSize)) { // For alignments greater than or equal to a page, the user pointer (eg: the // pointer that is returned by the C or C++ allocation APIs) ends up on a // page boundary , and our headers will live in the preceding page. @@ -73,13 +73,11 @@ void *MapAllocator::allocate(uptr Size, uptr AlignmentHint, uptr *BlockEnd) { H->Data = Data; { ScopedLock L(Mutex); - if (!Tail) { - Tail = H; - } else { + if (LIKELY(Tail)) { Tail->Next = H; H->Prev = Tail; - Tail = H; } + Tail = H; AllocatedBytes += CommitSize; if (LargestSize < CommitSize) LargestSize = CommitSize; @@ -106,7 +104,7 @@ void MapAllocator::deallocate(void *Ptr) { CHECK_EQ(Next->Prev, H); Next->Prev = Prev; } - if (Tail == H) { + if (UNLIKELY(Tail == H)) { CHECK(!Next); Tail = Prev; } else { @@ -125,12 +123,13 @@ void MapAllocator::deallocate(void *Ptr) { unmap(Addr, Size, UNMAP_ALL, &Data); } -void MapAllocator::printStats() const { - Printf("Stats: MapAllocator: allocated %zd times (%zdK), freed %zd times " - "(%zdK), remains %zd (%zdK) max %zdM\n", - NumberOfAllocs, AllocatedBytes >> 10, NumberOfFrees, FreedBytes >> 10, - NumberOfAllocs - NumberOfFrees, (AllocatedBytes - FreedBytes) >> 10, - LargestSize >> 20); +void MapAllocator::getStats(ScopedString *Str) const { + Str->append( + "Stats: MapAllocator: allocated %zu times (%zuK), freed %zu times " + "(%zuK), remains %zu (%zuK) max %zuM\n", + NumberOfAllocs, AllocatedBytes >> 10, NumberOfFrees, FreedBytes >> 10, + NumberOfAllocs - NumberOfFrees, (AllocatedBytes - FreedBytes) >> 10, + LargestSize >> 20); } } // namespace scudo diff --git a/lib/scudo/standalone/secondary.h b/lib/scudo/standalone/secondary.h index 9124e2a41c6a..9d074a57c772 100644 --- a/lib/scudo/standalone/secondary.h +++ b/lib/scudo/standalone/secondary.h @@ -12,6 +12,7 @@ #include "common.h" #include "mutex.h" #include "stats.h" +#include "string_utils.h" namespace scudo { @@ -50,7 +51,7 @@ class MapAllocator { public: void initLinkerInitialized(GlobalStats *S) { Stats.initLinkerInitialized(); - if (S) + if (LIKELY(S)) S->link(&Stats); } void init(GlobalStats *S) { @@ -70,7 +71,7 @@ public: return getBlockEnd(Ptr) - reinterpret_cast<uptr>(Ptr); } - void printStats() const; + void getStats(ScopedString *Str) const; void disable() { Mutex.lock(); } diff --git a/lib/scudo/standalone/size_class_map.h b/lib/scudo/standalone/size_class_map.h index b7df54cf8098..dfef0865b9d9 100644 --- a/lib/scudo/standalone/size_class_map.h +++ b/lib/scudo/standalone/size_class_map.h @@ -86,6 +86,7 @@ public: } static void print() { + ScopedString Buffer(1024); uptr PrevS = 0; uptr TotalCached = 0; for (uptr I = 0; I < NumClasses; I++) { @@ -93,19 +94,20 @@ public: continue; const uptr S = getSizeByClassId(I); if (S >= MidSize / 2 && (S & (S - 1)) == 0) - Printf("\n"); + Buffer.append("\n"); const uptr D = S - PrevS; const uptr P = PrevS ? (D * 100 / PrevS) : 0; const uptr L = S ? getMostSignificantSetBitIndex(S) : 0; const uptr Cached = getMaxCachedHint(S) * S; - Printf( + Buffer.append( "C%02zu => S: %zu diff: +%zu %02zu%% L %zu Cached: %zu %zu; id %zu\n", I, getSizeByClassId(I), D, P, L, getMaxCachedHint(S), Cached, getClassIdBySize(S)); TotalCached += Cached; PrevS = S; } - Printf("Total Cached: %zu\n", TotalCached); + Buffer.append("Total Cached: %zu\n", TotalCached); + Buffer.output(); } static void validate() { @@ -137,11 +139,11 @@ typedef SizeClassMap<3, 5, 8, 17, 8, 10> DefaultSizeClassMap; // TODO(kostyak): further tune class maps for Android & Fuchsia. #if SCUDO_WORDSIZE == 64U -typedef SizeClassMap<3, 5, 8, 15, 8, 10> SvelteSizeClassMap; -typedef SizeClassMap<3, 5, 8, 16, 14, 12> AndroidSizeClassMap; +typedef SizeClassMap<4, 4, 8, 14, 4, 10> SvelteSizeClassMap; +typedef SizeClassMap<3, 5, 8, 17, 14, 14> AndroidSizeClassMap; #else -typedef SizeClassMap<3, 4, 7, 15, 8, 10> SvelteSizeClassMap; -typedef SizeClassMap<3, 4, 7, 16, 14, 12> AndroidSizeClassMap; +typedef SizeClassMap<4, 3, 7, 14, 5, 10> SvelteSizeClassMap; +typedef SizeClassMap<3, 5, 8, 17, 14, 14> AndroidSizeClassMap; #endif } // namespace scudo diff --git a/lib/scudo/standalone/stats.h b/lib/scudo/standalone/stats.h index 12436756226b..16ef5b89b854 100644 --- a/lib/scudo/standalone/stats.h +++ b/lib/scudo/standalone/stats.h @@ -17,7 +17,7 @@ namespace scudo { // Memory allocator statistics -enum StatType { StatAllocated, StatMapped, StatCount }; +enum StatType { StatAllocated, StatFree, StatMapped, StatCount }; typedef uptr StatCounters[StatCount]; diff --git a/lib/scudo/standalone/string_utils.cc b/lib/scudo/standalone/string_utils.cpp index f0068afc1e8b..5de8b57bfcd1 100644 --- a/lib/scudo/standalone/string_utils.cc +++ b/lib/scudo/standalone/string_utils.cpp @@ -1,4 +1,4 @@ -//===-- string_utils.cc -----------------------------------------*- C++ -*-===// +//===-- string_utils.cpp ----------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -9,7 +9,6 @@ #include "string_utils.h" #include "common.h" -#include <ctype.h> #include <stdarg.h> #include <string.h> @@ -44,7 +43,7 @@ static int appendNumber(char **Buffer, const char *BufferEnd, u64 AbsoluteValue, do { RAW_CHECK_MSG(static_cast<uptr>(Pos) < MaxLen, "appendNumber buffer overflow"); - NumBuffer[Pos++] = AbsoluteValue % Base; + NumBuffer[Pos++] = static_cast<uptr>(AbsoluteValue % Base); AbsoluteValue /= Base; } while (AbsoluteValue > 0); if (Pos < MinNumberLength) { @@ -117,7 +116,7 @@ static int appendPointer(char **Buffer, const char *BufferEnd, u64 ptr_value) { int formatString(char *Buffer, uptr BufferLength, const char *Format, va_list Args) { - UNUSED static const char *PrintfFormatsHelp = + static const char *PrintfFormatsHelp = "Supported formatString formats: %([0-9]*)?(z|ll)?{d,u,x,X}; %p; " "%[-]([0-9]*)?(\\.\\*)?s; %c\n"; RAW_CHECK(Format); @@ -209,9 +208,18 @@ int formatString(char *Buffer, uptr BufferLength, const char *Format, } void ScopedString::append(const char *Format, va_list Args) { - CHECK_LT(Length, String.size()); - formatString(String.data() + Length, String.size() - Length, Format, Args); - Length += strlen(String.data() + Length); + DCHECK_LT(Length, String.size()); + va_list ArgsCopy; + va_copy(ArgsCopy, Args); + // formatString doesn't currently support a null buffer or zero buffer length, + // so in order to get the resulting formatted string length, we use a one-char + // buffer. + char C[1]; + const uptr AdditionalLength = + static_cast<uptr>(formatString(C, sizeof(C), Format, Args)) + 1; + String.resize(Length + AdditionalLength); + formatString(String.data() + Length, AdditionalLength, Format, ArgsCopy); + Length = strlen(String.data()); CHECK_LT(Length, String.size()); } @@ -227,7 +235,7 @@ FORMAT(1, 2) void Printf(const char *Format, ...) { va_list Args; va_start(Args, Format); - ScopedString Msg(512); + ScopedString Msg(1024); Msg.append(Format, Args); outputRaw(Msg.data()); va_end(Args); diff --git a/lib/scudo/standalone/string_utils.h b/lib/scudo/standalone/string_utils.h index aea7b3ffd7a5..acd60bda9d8d 100644 --- a/lib/scudo/standalone/string_utils.h +++ b/lib/scudo/standalone/string_utils.h @@ -29,6 +29,7 @@ public: } void append(const char *Format, va_list Args); void append(const char *Format, ...); + void output() const { outputRaw(String.data()); } private: Vector<char> String; diff --git a/lib/scudo/standalone/tsd_exclusive.h b/lib/scudo/standalone/tsd_exclusive.h index 18cce1c56af8..971ae4857fca 100644 --- a/lib/scudo/standalone/tsd_exclusive.h +++ b/lib/scudo/standalone/tsd_exclusive.h @@ -61,7 +61,7 @@ template <class Allocator> struct TSDRegistryExT { private: void initOnceMaybe(Allocator *Instance) { ScopedLock L(Mutex); - if (Initialized) + if (LIKELY(Initialized)) return; initLinkerInitialized(Instance); // Sets Initialized. } @@ -71,7 +71,7 @@ private: // used instead. NOINLINE void initThread(Allocator *Instance, bool MinimalInit) { initOnceMaybe(Instance); - if (MinimalInit) + if (UNLIKELY(MinimalInit)) return; CHECK_EQ( pthread_setspecific(PThreadKey, reinterpret_cast<void *>(Instance)), 0); diff --git a/lib/scudo/standalone/tsd_shared.h b/lib/scudo/standalone/tsd_shared.h index 0f0a83a3eed4..da88a897b8f5 100644 --- a/lib/scudo/standalone/tsd_shared.h +++ b/lib/scudo/standalone/tsd_shared.h @@ -95,7 +95,7 @@ private: void initOnceMaybe(Allocator *Instance) { ScopedLock L(Mutex); - if (Initialized) + if (LIKELY(Initialized)) return; initLinkerInitialized(Instance); // Sets Initialized. } @@ -112,8 +112,7 @@ private: // Use the Precedence of the current TSD as our random seed. Since we are // in the slow path, it means that tryLock failed, and as a result it's // very likely that said Precedence is non-zero. - u32 RandState = static_cast<u32>(CurrentTSD->getPrecedence()); - const u32 R = getRandomU32(&RandState); + const u32 R = static_cast<u32>(CurrentTSD->getPrecedence()); const u32 Inc = CoPrimes[R % NumberOfCoPrimes]; u32 Index = R % NumberOfTSDs; uptr LowestPrecedence = UINTPTR_MAX; diff --git a/lib/scudo/standalone/wrappers_c.cc b/lib/scudo/standalone/wrappers_c.cpp index 5908c600be33..dffd7cc26fe8 100644 --- a/lib/scudo/standalone/wrappers_c.cc +++ b/lib/scudo/standalone/wrappers_c.cpp @@ -1,4 +1,4 @@ -//===-- wrappers_c.cc -------------------------------------------*- C++ -*-===// +//===-- wrappers_c.cpp ------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/scudo/standalone/wrappers_c.inc b/lib/scudo/standalone/wrappers_c.inc index 2beddc724800..a9adbc83588b 100644 --- a/lib/scudo/standalone/wrappers_c.inc +++ b/lib/scudo/standalone/wrappers_c.inc @@ -38,8 +38,17 @@ INTERFACE WEAK struct SCUDO_MALLINFO SCUDO_PREFIX(mallinfo)(void) { struct SCUDO_MALLINFO Info = {}; scudo::StatCounters Stats; SCUDO_ALLOCATOR.getStats(Stats); + // Space allocated in mmapped regions (bytes) + Info.hblkhd = static_cast<__scudo_mallinfo_data_t>(Stats[scudo::StatMapped]); + // Maximum total allocated space (bytes) + Info.usmblks = Info.hblkhd; + // Space in freed fastbin blocks (bytes) + Info.fsmblks = static_cast<__scudo_mallinfo_data_t>(Stats[scudo::StatFree]); + // Total allocated space (bytes) Info.uordblks = static_cast<__scudo_mallinfo_data_t>(Stats[scudo::StatAllocated]); + // Total free space (bytes) + Info.fordblks = Info.fsmblks; return Info; } @@ -170,7 +179,8 @@ INTERFACE WEAK void *SCUDO_PREFIX(aligned_alloc)(size_t alignment, SCUDO_ALLOCATOR.allocate(size, scudo::Chunk::Origin::Malloc, alignment)); } -INTERFACE WEAK int SCUDO_PREFIX(malloc_info)(int, FILE *) { - errno = ENOTSUP; - return -1; +INTERFACE WEAK int SCUDO_PREFIX(malloc_info)(UNUSED int options, FILE *stream) { + fputs("<malloc version=\"scudo-1\">", stream); + fputs("</malloc>", stream); + return 0; } diff --git a/lib/scudo/standalone/wrappers_c_bionic.cc b/lib/scudo/standalone/wrappers_c_bionic.cpp index f6e863deb973..fa4145c066b6 100644 --- a/lib/scudo/standalone/wrappers_c_bionic.cc +++ b/lib/scudo/standalone/wrappers_c_bionic.cpp @@ -1,4 +1,4 @@ -//===-- wrappers_c_bionic.cc ------------------------------------*- C++ -*-===// +//===-- wrappers_c_bionic.cpp -----------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/scudo/standalone/wrappers_cpp.cc b/lib/scudo/standalone/wrappers_cpp.cpp index 3ae1cdc05a06..72235e9c9820 100644 --- a/lib/scudo/standalone/wrappers_cpp.cc +++ b/lib/scudo/standalone/wrappers_cpp.cpp @@ -1,4 +1,4 @@ -//===-- wrappers_cpp.cc -----------------------------------------*- C++ -*-===// +//===-- wrappers_cpp.cpp ----------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/stats/stats.cc b/lib/stats/stats.cpp index 8d4a115d1aef..da254fdb5a52 100644 --- a/lib/stats/stats.cc +++ b/lib/stats/stats.cpp @@ -1,4 +1,4 @@ -//===-- stats.cc ----------------------------------------------------------===// +//===-- stats.cpp ---------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/stats/stats_client.cc b/lib/stats/stats_client.cpp index 0790f57372f4..52eab8eea079 100644 --- a/lib/stats/stats_client.cc +++ b/lib/stats/stats_client.cpp @@ -1,4 +1,4 @@ -//===-- stats_client.cc ---------------------------------------------------===// +//===-- stats_client.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/benchmarks/func_entry_exit.cc b/lib/tsan/benchmarks/func_entry_exit.cpp index 5e0ba1d6981b..5e0ba1d6981b 100644 --- a/lib/tsan/benchmarks/func_entry_exit.cc +++ b/lib/tsan/benchmarks/func_entry_exit.cpp diff --git a/lib/tsan/benchmarks/mini_bench_local.cc b/lib/tsan/benchmarks/mini_bench_local.cpp index accdcb63878f..accdcb63878f 100644 --- a/lib/tsan/benchmarks/mini_bench_local.cc +++ b/lib/tsan/benchmarks/mini_bench_local.cpp diff --git a/lib/tsan/benchmarks/mini_bench_shared.cc b/lib/tsan/benchmarks/mini_bench_shared.cpp index f9b9f42f78a4..f9b9f42f78a4 100644 --- a/lib/tsan/benchmarks/mini_bench_shared.cc +++ b/lib/tsan/benchmarks/mini_bench_shared.cpp diff --git a/lib/tsan/benchmarks/mop.cc b/lib/tsan/benchmarks/mop.cpp index e87fab856969..e87fab856969 100644 --- a/lib/tsan/benchmarks/mop.cc +++ b/lib/tsan/benchmarks/mop.cpp diff --git a/lib/tsan/benchmarks/start_many_threads.cc b/lib/tsan/benchmarks/start_many_threads.cpp index 1e86fa6c502e..1e86fa6c502e 100644 --- a/lib/tsan/benchmarks/start_many_threads.cc +++ b/lib/tsan/benchmarks/start_many_threads.cpp diff --git a/lib/tsan/benchmarks/vts_many_threads_bench.cc b/lib/tsan/benchmarks/vts_many_threads_bench.cpp index f1056e20c874..f1056e20c874 100644 --- a/lib/tsan/benchmarks/vts_many_threads_bench.cc +++ b/lib/tsan/benchmarks/vts_many_threads_bench.cpp diff --git a/lib/tsan/dd/dd_interceptors.cc b/lib/tsan/dd/dd_interceptors.cpp index 35a72eb36a30..35a0beb19196 100644 --- a/lib/tsan/dd/dd_interceptors.cc +++ b/lib/tsan/dd/dd_interceptors.cpp @@ -1,4 +1,4 @@ -//===-- dd_interceptors.cc ------------------------------------------------===// +//===-- dd_interceptors.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/dd/dd_rtl.cc b/lib/tsan/dd/dd_rtl.cpp index 08652ba01cdd..2095217586a8 100644 --- a/lib/tsan/dd/dd_rtl.cc +++ b/lib/tsan/dd/dd_rtl.cpp @@ -1,4 +1,4 @@ -//===-- dd_rtl.cc ---------------------------------------------------------===// +//===-- dd_rtl.cpp --------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/go/tsan_go.cc b/lib/tsan/go/tsan_go.cpp index dfd1e1da158f..f5998c0c7816 100644 --- a/lib/tsan/go/tsan_go.cc +++ b/lib/tsan/go/tsan_go.cpp @@ -1,4 +1,4 @@ -//===-- tsan_go.cc --------------------------------------------------------===// +//===-- tsan_go.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -54,20 +54,31 @@ struct SymbolizeCodeContext { }; SymbolizedStack *SymbolizeCode(uptr addr) { - SymbolizedStack *s = SymbolizedStack::New(addr); - SymbolizeCodeContext cbctx; - internal_memset(&cbctx, 0, sizeof(cbctx)); - cbctx.pc = addr; - go_runtime_cb(CallbackSymbolizeCode, &cbctx); - if (cbctx.res) { + SymbolizedStack *first = SymbolizedStack::New(addr); + SymbolizedStack *s = first; + for (;;) { + SymbolizeCodeContext cbctx; + internal_memset(&cbctx, 0, sizeof(cbctx)); + cbctx.pc = addr; + go_runtime_cb(CallbackSymbolizeCode, &cbctx); + if (cbctx.res == 0) + break; AddressInfo &info = s->info; info.module_offset = cbctx.off; info.function = internal_strdup(cbctx.func ? cbctx.func : "??"); info.file = internal_strdup(cbctx.file ? cbctx.file : "-"); info.line = cbctx.line; info.column = 0; + + if (cbctx.pc == addr) // outermost (non-inlined) function + break; + addr = cbctx.pc; + // Allocate a stack entry for the parent of the inlined function. + SymbolizedStack *s2 = SymbolizedStack::New(addr); + s->next = s2; + s = s2; } - return s; + return first; } struct SymbolizeDataContext { diff --git a/lib/tsan/rtl/tsan_clock.cc b/lib/tsan/rtl/tsan_clock.cpp index 685ca5518009..4b7aa0653da6 100644 --- a/lib/tsan/rtl/tsan_clock.cc +++ b/lib/tsan/rtl/tsan_clock.cpp @@ -1,4 +1,4 @@ -//===-- tsan_clock.cc -----------------------------------------------------===// +//===-- tsan_clock.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -40,7 +40,7 @@ // release(dst); // } // -// Conformance to this model is extensively verified in tsan_clock_test.cc. +// Conformance to this model is extensively verified in tsan_clock_test.cpp. // However, the implementation is significantly more complex. The complexity // allows to implement important classes of use cases in O(1) instead of O(N). // diff --git a/lib/tsan/rtl/tsan_debugging.cc b/lib/tsan/rtl/tsan_debugging.cpp index 8579db12b666..d3d6255090b7 100644 --- a/lib/tsan/rtl/tsan_debugging.cc +++ b/lib/tsan/rtl/tsan_debugging.cpp @@ -1,4 +1,4 @@ -//===-- tsan_debugging.cc -------------------------------------------------===// +//===-- tsan_debugging.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_dispatch_defs.h b/lib/tsan/rtl/tsan_dispatch_defs.h index 6f1d1f75f600..298297af31eb 100644 --- a/lib/tsan/rtl/tsan_dispatch_defs.h +++ b/lib/tsan/rtl/tsan_dispatch_defs.h @@ -31,11 +31,11 @@ typedef void (^dispatch_block_t)(void); typedef void (^dispatch_io_handler_t)(bool done, dispatch_data_t data, int error); -typedef long dispatch_once_t; // NOLINT +typedef long dispatch_once_t; typedef __sanitizer::u64 dispatch_time_t; -typedef int dispatch_fd_t; // NOLINT -typedef unsigned long dispatch_io_type_t; // NOLINT -typedef unsigned long dispatch_io_close_flags_t; // NOLINT +typedef int dispatch_fd_t; +typedef unsigned long dispatch_io_type_t; +typedef unsigned long dispatch_io_close_flags_t; extern "C" { void *dispatch_get_context(dispatch_object_t object); @@ -57,10 +57,10 @@ extern const dispatch_block_t _dispatch_data_destructor_munmap; #endif // Data types used in dispatch APIs -typedef unsigned long size_t; // NOLINT -typedef unsigned long uintptr_t; // NOLINT +typedef unsigned long size_t; +typedef unsigned long uintptr_t; typedef __sanitizer::s64 off_t; typedef __sanitizer::u16 mode_t; -typedef long long_t; // NOLINT +typedef long long_t; #endif // TSAN_DISPATCH_DEFS_H diff --git a/lib/tsan/rtl/tsan_external.cc b/lib/tsan/rtl/tsan_external.cpp index ba8bb71be43b..0faa1ee93a13 100644 --- a/lib/tsan/rtl/tsan_external.cc +++ b/lib/tsan/rtl/tsan_external.cpp @@ -1,4 +1,4 @@ -//===-- tsan_external.cc --------------------------------------------------===// +//===-- tsan_external.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,7 +25,7 @@ static TagData registered_tags[kExternalTagMax] = { {}, {"Swift variable", "Swift access race"}, }; -static atomic_uint32_t used_tags{kExternalTagFirstUserAvailable}; // NOLINT. +static atomic_uint32_t used_tags{kExternalTagFirstUserAvailable}; static TagData *GetTagData(uptr tag) { // Invalid/corrupted tag? Better return NULL and let the caller deal with it. if (tag >= atomic_load(&used_tags, memory_order_relaxed)) return nullptr; diff --git a/lib/tsan/rtl/tsan_fd.cc b/lib/tsan/rtl/tsan_fd.cpp index 5b562ae68d5a..50a6b56916aa 100644 --- a/lib/tsan/rtl/tsan_fd.cc +++ b/lib/tsan/rtl/tsan_fd.cpp @@ -1,4 +1,4 @@ -//===-- tsan_fd.cc --------------------------------------------------------===// +//===-- tsan_fd.cpp -------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -86,7 +86,8 @@ static FdDesc *fddesc(ThreadState *thr, uptr pc, int fd) { else user_free(thr, pc, p, false); } - return &((FdDesc*)l1)[fd % kTableSizeL2]; // NOLINT + FdDesc *fds = reinterpret_cast<FdDesc *>(l1); + return &fds[fd % kTableSizeL2]; } // pd must be already ref'ed. diff --git a/lib/tsan/rtl/tsan_flags.cc b/lib/tsan/rtl/tsan_flags.cpp index a5abb183a753..44bf325cd35b 100644 --- a/lib/tsan/rtl/tsan_flags.cc +++ b/lib/tsan/rtl/tsan_flags.cpp @@ -1,4 +1,4 @@ -//===-- tsan_flags.cc -----------------------------------------------------===// +//===-- tsan_flags.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_ignoreset.cc b/lib/tsan/rtl/tsan_ignoreset.cpp index b2f657939cce..f6e41f668618 100644 --- a/lib/tsan/rtl/tsan_ignoreset.cc +++ b/lib/tsan/rtl/tsan_ignoreset.cpp @@ -1,4 +1,4 @@ -//===-- tsan_ignoreset.cc -------------------------------------------------===// +//===-- tsan_ignoreset.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_libdispatch.cc b/lib/tsan/rtl/tsan_interceptors_libdispatch.cpp index 48ac6a2824a8..5dacd3256abc 100644 --- a/lib/tsan/rtl/tsan_libdispatch.cc +++ b/lib/tsan/rtl/tsan_interceptors_libdispatch.cpp @@ -1,4 +1,4 @@ -//===-- tsan_libdispatch.cc -----------------------------------------------===// +//===-- tsan_interceptors_libdispatch.cpp ---------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_interceptors_mac.cc b/lib/tsan/rtl/tsan_interceptors_mac.cpp index 99c6df9dfde7..aa29536d8616 100644 --- a/lib/tsan/rtl/tsan_interceptors_mac.cc +++ b/lib/tsan/rtl/tsan_interceptors_mac.cpp @@ -1,4 +1,4 @@ -//===-- tsan_interceptors_mac.cc ------------------------------------------===// +//===-- tsan_interceptors_mac.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -23,13 +23,14 @@ #include <errno.h> #include <libkern/OSAtomic.h> #include <objc/objc-sync.h> +#include <os/lock.h> #include <sys/ucontext.h> #if defined(__has_include) && __has_include(<xpc/xpc.h>) #include <xpc/xpc.h> #endif // #if defined(__has_include) && __has_include(<xpc/xpc.h>) -typedef long long_t; // NOLINT +typedef long long_t; extern "C" { int getcontext(ucontext_t *ucp) __attribute__((returns_twice)); @@ -246,6 +247,45 @@ TSAN_INTERCEPTOR(void, os_lock_unlock, void *lock) { REAL(os_lock_unlock)(lock); } +TSAN_INTERCEPTOR(void, os_unfair_lock_lock, os_unfair_lock_t lock) { + if (!cur_thread()->is_inited || cur_thread()->is_dead) { + return REAL(os_unfair_lock_lock)(lock); + } + SCOPED_TSAN_INTERCEPTOR(os_unfair_lock_lock, lock); + REAL(os_unfair_lock_lock)(lock); + Acquire(thr, pc, (uptr)lock); +} + +TSAN_INTERCEPTOR(void, os_unfair_lock_lock_with_options, os_unfair_lock_t lock, + u32 options) { + if (!cur_thread()->is_inited || cur_thread()->is_dead) { + return REAL(os_unfair_lock_lock_with_options)(lock, options); + } + SCOPED_TSAN_INTERCEPTOR(os_unfair_lock_lock_with_options, lock, options); + REAL(os_unfair_lock_lock_with_options)(lock, options); + Acquire(thr, pc, (uptr)lock); +} + +TSAN_INTERCEPTOR(bool, os_unfair_lock_trylock, os_unfair_lock_t lock) { + if (!cur_thread()->is_inited || cur_thread()->is_dead) { + return REAL(os_unfair_lock_trylock)(lock); + } + SCOPED_TSAN_INTERCEPTOR(os_unfair_lock_trylock, lock); + bool result = REAL(os_unfair_lock_trylock)(lock); + if (result) + Acquire(thr, pc, (uptr)lock); + return result; +} + +TSAN_INTERCEPTOR(void, os_unfair_lock_unlock, os_unfair_lock_t lock) { + if (!cur_thread()->is_inited || cur_thread()->is_dead) { + return REAL(os_unfair_lock_unlock)(lock); + } + SCOPED_TSAN_INTERCEPTOR(os_unfair_lock_unlock, lock); + Release(thr, pc, (uptr)lock); + REAL(os_unfair_lock_unlock)(lock); +} + #if defined(__has_include) && __has_include(<xpc/xpc.h>) TSAN_INTERCEPTOR(void, xpc_connection_set_event_handler, diff --git a/lib/tsan/rtl/tsan_interceptors_mach_vm.cpp b/lib/tsan/rtl/tsan_interceptors_mach_vm.cpp new file mode 100644 index 000000000000..cd318f8af93f --- /dev/null +++ b/lib/tsan/rtl/tsan_interceptors_mach_vm.cpp @@ -0,0 +1,52 @@ +//===-- tsan_interceptors_mach_vm.cpp -------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of ThreadSanitizer (TSan), a race detector. +// +// Interceptors for mach_vm_* user space memory routines on Darwin. +//===----------------------------------------------------------------------===// + +#include "interception/interception.h" +#include "tsan_interceptors.h" +#include "tsan_platform.h" + +#include <mach/mach.h> + +namespace __tsan { + +static bool intersects_with_shadow(mach_vm_address_t *address, + mach_vm_size_t size, int flags) { + // VM_FLAGS_FIXED is 0x0, so we have to test for VM_FLAGS_ANYWHERE. + if (flags & VM_FLAGS_ANYWHERE) return false; + uptr ptr = *address; + return !IsAppMem(ptr) || !IsAppMem(ptr + size - 1); +} + +TSAN_INTERCEPTOR(kern_return_t, mach_vm_allocate, vm_map_t target, + mach_vm_address_t *address, mach_vm_size_t size, int flags) { + SCOPED_TSAN_INTERCEPTOR(mach_vm_allocate, target, address, size, flags); + if (target != mach_task_self()) + return REAL(mach_vm_allocate)(target, address, size, flags); + if (intersects_with_shadow(address, size, flags)) + return KERN_NO_SPACE; + kern_return_t res = REAL(mach_vm_allocate)(target, address, size, flags); + if (res == KERN_SUCCESS) + MemoryRangeImitateWriteOrResetRange(thr, pc, *address, size); + return res; +} + +TSAN_INTERCEPTOR(kern_return_t, mach_vm_deallocate, vm_map_t target, + mach_vm_address_t address, mach_vm_size_t size) { + SCOPED_TSAN_INTERCEPTOR(mach_vm_deallocate, target, address, size); + if (target != mach_task_self()) + return REAL(mach_vm_deallocate)(target, address, size); + UnmapShadow(thr, address, size); + return REAL(mach_vm_deallocate)(target, address, size); +} + +} // namespace __tsan diff --git a/lib/tsan/rtl/tsan_interceptors.cc b/lib/tsan/rtl/tsan_interceptors_posix.cpp index 9a184c797985..8aea1e4ec051 100644 --- a/lib/tsan/rtl/tsan_interceptors.cc +++ b/lib/tsan/rtl/tsan_interceptors_posix.cpp @@ -1,4 +1,4 @@ -//===-- tsan_interceptors.cc ----------------------------------------------===// +//===-- tsan_interceptors_posix.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -31,8 +31,7 @@ #include "tsan_mman.h" #include "tsan_fd.h" - -using namespace __tsan; // NOLINT +using namespace __tsan; #if SANITIZER_FREEBSD || SANITIZER_MAC #define stdout __stdoutp @@ -41,9 +40,10 @@ using namespace __tsan; // NOLINT #if SANITIZER_NETBSD #define dirfd(dirp) (*(int *)(dirp)) -#define fileno_unlocked(fp) \ - (((__sanitizer_FILE*)fp)->_file == -1 ? -1 : \ - (int)(unsigned short)(((__sanitizer_FILE*)fp)->_file)) // NOLINT +#define fileno_unlocked(fp) \ + (((__sanitizer_FILE *)fp)->_file == -1 \ + ? -1 \ + : (int)(unsigned short)(((__sanitizer_FILE *)fp)->_file)) #define stdout ((__sanitizer_FILE*)&__sF[1]) #define stderr ((__sanitizer_FILE*)&__sF[2]) @@ -114,6 +114,7 @@ const int PTHREAD_MUTEX_RECURSIVE_NP = 2; const int EPOLL_CTL_ADD = 1; #endif const int SIGILL = 4; +const int SIGTRAP = 5; const int SIGABRT = 6; const int SIGFPE = 8; const int SIGSEGV = 11; @@ -133,7 +134,7 @@ const int PTHREAD_BARRIER_SERIAL_THREAD = 1234567; const int PTHREAD_BARRIER_SERIAL_THREAD = -1; #endif const int MAP_FIXED = 0x10; -typedef long long_t; // NOLINT +typedef long long_t; // From /usr/include/unistd.h # define F_ULOCK 0 /* Unlock a previously locked region. */ @@ -723,12 +724,12 @@ TSAN_INTERCEPTOR(uptr, malloc_usable_size, void *p) { } #endif -TSAN_INTERCEPTOR(char*, strcpy, char *dst, const char *src) { // NOLINT - SCOPED_TSAN_INTERCEPTOR(strcpy, dst, src); // NOLINT +TSAN_INTERCEPTOR(char *, strcpy, char *dst, const char *src) { + SCOPED_TSAN_INTERCEPTOR(strcpy, dst, src); uptr srclen = internal_strlen(src); MemoryAccessRange(thr, pc, (uptr)dst, srclen + 1, true); MemoryAccessRange(thr, pc, (uptr)src, srclen + 1, false); - return REAL(strcpy)(dst, src); // NOLINT + return REAL(strcpy)(dst, src); } TSAN_INTERCEPTOR(char*, strncpy, char *dst, char *src, uptr n) { @@ -745,6 +746,8 @@ TSAN_INTERCEPTOR(char*, strdup, const char *str) { return REAL(strdup)(str); } +// Zero out addr if it points into shadow memory and was provided as a hint +// only, i.e., MAP_FIXED is not set. static bool fix_mmap_addr(void **addr, long_t sz, int flags) { if (*addr) { if (!IsAppMem((uptr)*addr) || !IsAppMem((uptr)*addr + sz - 1)) { @@ -767,22 +770,14 @@ static void *mmap_interceptor(ThreadState *thr, uptr pc, Mmap real_mmap, void *res = real_mmap(addr, sz, prot, flags, fd, off); if (res != MAP_FAILED) { if (fd > 0) FdAccess(thr, pc, fd); - if (thr->ignore_reads_and_writes == 0) - MemoryRangeImitateWrite(thr, pc, (uptr)res, sz); - else - MemoryResetRange(thr, pc, (uptr)res, sz); + MemoryRangeImitateWriteOrResetRange(thr, pc, (uptr)res, sz); } return res; } TSAN_INTERCEPTOR(int, munmap, void *addr, long_t sz) { SCOPED_TSAN_INTERCEPTOR(munmap, addr, sz); - if (sz != 0) { - // If sz == 0, munmap will return EINVAL and don't unmap any memory. - DontNeedShadowFor((uptr)addr, sz); - ScopedGlobalProcessor sgp; - ctx->metamap.ResetRange(thr->proc(), (uptr)addr, (uptr)sz); - } + UnmapShadow(thr, (uptr)addr, sz); int res = REAL(munmap)(addr, sz); return res; } @@ -1157,7 +1152,7 @@ static int cond_wait(ThreadState *thr, uptr pc, ScopedInterceptor *si, CondMutexUnlockCtx arg = {si, thr, pc, m}; int res = 0; // This ensures that we handle mutex lock even in case of pthread_cancel. - // See test/tsan/cond_cancel.cc. + // See test/tsan/cond_cancel.cpp. { // Enable signal delivery while the thread is blocked. BlockingCall bc(thr); @@ -1968,10 +1963,10 @@ void ProcessPendingSignals(ThreadState *thr) { } // namespace __tsan static bool is_sync_signal(ThreadSignalContext *sctx, int sig) { - return sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || - sig == SIGABRT || sig == SIGFPE || sig == SIGPIPE || sig == SIGSYS || - // If we are sending signal to ourselves, we must process it now. - (sctx && sig == sctx->int_signal_send); + return sig == SIGSEGV || sig == SIGBUS || sig == SIGILL || sig == SIGTRAP || + sig == SIGABRT || sig == SIGFPE || sig == SIGPIPE || sig == SIGSYS || + // If we are sending signal to ourselves, we must process it now. + (sctx && sig == sctx->int_signal_send); } void ALWAYS_INLINE rtl_generic_sighandler(bool sigact, int sig, @@ -2666,7 +2661,7 @@ void InitializeInterceptors() { TSAN_MAYBE_INTERCEPT_PVALLOC; TSAN_INTERCEPT(posix_memalign); - TSAN_INTERCEPT(strcpy); // NOLINT + TSAN_INTERCEPT(strcpy); TSAN_INTERCEPT(strncpy); TSAN_INTERCEPT(strdup); diff --git a/lib/tsan/rtl/tsan_interface.cc b/lib/tsan/rtl/tsan_interface.cpp index 508aadb08f62..2b3a0889b70a 100644 --- a/lib/tsan/rtl/tsan_interface.cc +++ b/lib/tsan/rtl/tsan_interface.cpp @@ -1,4 +1,4 @@ -//===-- tsan_interface.cc -------------------------------------------------===// +//===-- tsan_interface.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -17,7 +17,7 @@ #define CALLERPC ((uptr)__builtin_return_address(0)) -using namespace __tsan; // NOLINT +using namespace __tsan; typedef u16 uint16_t; typedef u32 uint32_t; diff --git a/lib/tsan/rtl/tsan_interface.h b/lib/tsan/rtl/tsan_interface.h index fac57809aa24..6d7286ca5b8a 100644 --- a/lib/tsan/rtl/tsan_interface.h +++ b/lib/tsan/rtl/tsan_interface.h @@ -90,9 +90,14 @@ SANITIZER_INTERFACE_ATTRIBUTE void __tsan_external_write(void *addr, void *caller_pc, void *tag); SANITIZER_INTERFACE_ATTRIBUTE -void __tsan_read_range(void *addr, unsigned long size); // NOLINT +void __tsan_read_range(void *addr, unsigned long size); SANITIZER_INTERFACE_ATTRIBUTE -void __tsan_write_range(void *addr, unsigned long size); // NOLINT +void __tsan_write_range(void *addr, unsigned long size); + +SANITIZER_INTERFACE_ATTRIBUTE +void __tsan_read_range_pc(void *addr, unsigned long size, void *pc); // NOLINT +SANITIZER_INTERFACE_ATTRIBUTE +void __tsan_write_range_pc(void *addr, unsigned long size, void *pc); // NOLINT // User may provide function that would be called right when TSan detects // an error. The argument 'report' is an opaque pointer that can be used to @@ -187,9 +192,9 @@ namespace __tsan { // These should match declarations from public tsan_interface_atomic.h header. typedef unsigned char a8; -typedef unsigned short a16; // NOLINT +typedef unsigned short a16; typedef unsigned int a32; -typedef unsigned long long a64; // NOLINT +typedef unsigned long long a64; #if !SANITIZER_GO && (defined(__SIZEOF_INT128__) \ || (__clang_major__ * 100 + __clang_minor__ >= 302)) && !defined(__mips64) __extension__ typedef __int128 a128; diff --git a/lib/tsan/rtl/tsan_interface_ann.cc b/lib/tsan/rtl/tsan_interface_ann.cpp index e141ddbb751a..99516d94bba3 100644 --- a/lib/tsan/rtl/tsan_interface_ann.cc +++ b/lib/tsan/rtl/tsan_interface_ann.cpp @@ -1,4 +1,4 @@ -//===-- tsan_interface_ann.cc ---------------------------------------------===// +//===-- tsan_interface_ann.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -24,7 +24,7 @@ #define CALLERPC ((uptr)__builtin_return_address(0)) -using namespace __tsan; // NOLINT +using namespace __tsan; namespace __tsan { @@ -220,7 +220,7 @@ static void ReportMissedExpectedRace(ExpectRace *race) { } } // namespace __tsan -using namespace __tsan; // NOLINT +using namespace __tsan; extern "C" { void INTERFACE_ATTRIBUTE AnnotateHappensBefore(char *f, int l, uptr addr) { diff --git a/lib/tsan/rtl/tsan_interface_atomic.cc b/lib/tsan/rtl/tsan_interface_atomic.cpp index a6b7b0f656d3..3f459aff532c 100644 --- a/lib/tsan/rtl/tsan_interface_atomic.cc +++ b/lib/tsan/rtl/tsan_interface_atomic.cpp @@ -1,4 +1,4 @@ -//===-- tsan_interface_atomic.cc ------------------------------------------===// +//===-- tsan_interface_atomic.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -25,7 +25,7 @@ #include "tsan_interface.h" #include "tsan_rtl.h" -using namespace __tsan; // NOLINT +using namespace __tsan; #if !SANITIZER_GO && __TSAN_HAS_INT128 // Protects emulation of 128-bit atomic operations. diff --git a/lib/tsan/rtl/tsan_interface_inl.h b/lib/tsan/rtl/tsan_interface_inl.h index bf4a1658625c..f955ddf99247 100644 --- a/lib/tsan/rtl/tsan_interface_inl.h +++ b/lib/tsan/rtl/tsan_interface_inl.h @@ -15,7 +15,7 @@ #define CALLERPC ((uptr)__builtin_return_address(0)) -using namespace __tsan; // NOLINT +using namespace __tsan; void __tsan_read1(void *addr) { MemoryRead(cur_thread(), CALLERPC, (uptr)addr, kSizeLog1); @@ -122,3 +122,11 @@ void __tsan_read_range(void *addr, uptr size) { void __tsan_write_range(void *addr, uptr size) { MemoryAccessRange(cur_thread(), CALLERPC, (uptr)addr, size, true); } + +void __tsan_read_range_pc(void *addr, uptr size, void *pc) { + MemoryAccessRange(cur_thread(), (uptr)pc, (uptr)addr, size, false); +} + +void __tsan_write_range_pc(void *addr, uptr size, void *pc) { + MemoryAccessRange(cur_thread(), (uptr)pc, (uptr)addr, size, true); +} diff --git a/lib/tsan/rtl/tsan_interface_java.cc b/lib/tsan/rtl/tsan_interface_java.cpp index 9f227f09589e..081c6ff1022e 100644 --- a/lib/tsan/rtl/tsan_interface_java.cc +++ b/lib/tsan/rtl/tsan_interface_java.cpp @@ -1,4 +1,4 @@ -//===-- tsan_interface_java.cc --------------------------------------------===// +//===-- tsan_interface_java.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -19,7 +19,7 @@ #include "sanitizer_common/sanitizer_stacktrace.h" #include "sanitizer_common/sanitizer_procmaps.h" -using namespace __tsan; // NOLINT +using namespace __tsan; const jptr kHeapAlignment = 8; diff --git a/lib/tsan/rtl/tsan_interface_java.h b/lib/tsan/rtl/tsan_interface_java.h index 5ad16e959093..51b445251e09 100644 --- a/lib/tsan/rtl/tsan_interface_java.h +++ b/lib/tsan/rtl/tsan_interface_java.h @@ -18,7 +18,7 @@ // For volatile memory accesses and atomic operations JVM is intended to use // standard atomics API: __tsan_atomicN_load/store/etc. // -// For usage examples see lit_tests/java_*.cc +// For usage examples see lit_tests/java_*.cpp //===----------------------------------------------------------------------===// #ifndef TSAN_INTERFACE_JAVA_H #define TSAN_INTERFACE_JAVA_H @@ -31,7 +31,7 @@ extern "C" { #endif -typedef unsigned long jptr; // NOLINT +typedef unsigned long jptr; // Must be called before any other callback from Java. void __tsan_java_init(jptr heap_begin, jptr heap_size) INTERFACE_ATTRIBUTE; diff --git a/lib/tsan/rtl/tsan_malloc_mac.cc b/lib/tsan/rtl/tsan_malloc_mac.cpp index 0b874aecb99c..0e861bf1f962 100644 --- a/lib/tsan/rtl/tsan_malloc_mac.cc +++ b/lib/tsan/rtl/tsan_malloc_mac.cpp @@ -1,4 +1,4 @@ -//===-- tsan_malloc_mac.cc ------------------------------------------------===// +//===-- tsan_malloc_mac.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_md5.cc b/lib/tsan/rtl/tsan_md5.cpp index bfe0c17bae75..72857b773fed 100644 --- a/lib/tsan/rtl/tsan_md5.cc +++ b/lib/tsan/rtl/tsan_md5.cpp @@ -1,4 +1,4 @@ -//===-- tsan_md5.cc -------------------------------------------------------===// +//===-- tsan_md5.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -29,7 +29,7 @@ namespace __tsan { SET(n) typedef unsigned int MD5_u32plus; -typedef unsigned long ulong_t; // NOLINT +typedef unsigned long ulong_t; typedef struct { MD5_u32plus lo, hi; diff --git a/lib/tsan/rtl/tsan_mman.cc b/lib/tsan/rtl/tsan_mman.cpp index f4a95d870cab..1b2c0549d399 100644 --- a/lib/tsan/rtl/tsan_mman.cc +++ b/lib/tsan/rtl/tsan_mman.cpp @@ -1,4 +1,4 @@ -//===-- tsan_mman.cc ------------------------------------------------------===// +//===-- tsan_mman.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_mman.h b/lib/tsan/rtl/tsan_mman.h index 467aabdf2b9d..a5280d4472c9 100644 --- a/lib/tsan/rtl/tsan_mman.h +++ b/lib/tsan/rtl/tsan_mman.h @@ -79,11 +79,10 @@ enum MBlockType { void *internal_alloc(MBlockType typ, uptr sz); void internal_free(void *p); -template<typename T> -void DestroyAndFree(T *&p) { +template <typename T> +void DestroyAndFree(T *p) { p->~T(); internal_free(p); - p = 0; } } // namespace __tsan diff --git a/lib/tsan/rtl/tsan_mutex.cc b/lib/tsan/rtl/tsan_mutex.cpp index bb7531325aed..7a0918f2a2c0 100644 --- a/lib/tsan/rtl/tsan_mutex.cc +++ b/lib/tsan/rtl/tsan_mutex.cpp @@ -1,4 +1,4 @@ -//===-- tsan_mutex.cc -----------------------------------------------------===// +//===-- tsan_mutex.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_mutexset.cc b/lib/tsan/rtl/tsan_mutexset.cpp index 02e5f9da6080..813fa3bca936 100644 --- a/lib/tsan/rtl/tsan_mutexset.cc +++ b/lib/tsan/rtl/tsan_mutexset.cpp @@ -1,4 +1,4 @@ -//===-- tsan_mutexset.cc --------------------------------------------------===// +//===-- tsan_mutexset.cpp -------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_new_delete.cc b/lib/tsan/rtl/tsan_new_delete.cpp index 4cbdf703ad28..fc44a5221b5b 100644 --- a/lib/tsan/rtl/tsan_new_delete.cc +++ b/lib/tsan/rtl/tsan_new_delete.cpp @@ -1,4 +1,4 @@ -//===-- tsan_new_delete.cc ----------------------------------------------===// +//===-- tsan_new_delete.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -17,7 +17,7 @@ #include "tsan_interceptors.h" #include "tsan_rtl.h" -using namespace __tsan; // NOLINT +using namespace __tsan; namespace std { struct nothrow_t {}; diff --git a/lib/tsan/rtl/tsan_platform.h b/lib/tsan/rtl/tsan_platform.h index 0d106c4147c8..63eb14fcd340 100644 --- a/lib/tsan/rtl/tsan_platform.h +++ b/lib/tsan/rtl/tsan_platform.h @@ -457,6 +457,8 @@ struct Mapping47 { static const uptr kAppMemEnd = 0x00e000000000ull; }; +#define TSAN_RUNTIME_VMA 1 + #elif SANITIZER_GO && defined(__aarch64__) /* Go on linux/aarch64 (48-bit VMA) diff --git a/lib/tsan/rtl/tsan_platform_linux.cc b/lib/tsan/rtl/tsan_platform_linux.cpp index ec8606f65d5c..33fa586ca1b0 100644 --- a/lib/tsan/rtl/tsan_platform_linux.cc +++ b/lib/tsan/rtl/tsan_platform_linux.cpp @@ -1,4 +1,4 @@ -//===-- tsan_platform_linux.cc --------------------------------------------===// +//===-- tsan_platform_linux.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_platform_mac.cc b/lib/tsan/rtl/tsan_platform_mac.cpp index 0c2d2aa9338e..326ca8532e52 100644 --- a/lib/tsan/rtl/tsan_platform_mac.cc +++ b/lib/tsan/rtl/tsan_platform_mac.cpp @@ -1,4 +1,4 @@ -//===-- tsan_platform_mac.cc ----------------------------------------------===// +//===-- tsan_platform_mac.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_platform_posix.cc b/lib/tsan/rtl/tsan_platform_posix.cpp index 3bd0f1bd48d8..1a0faee0252e 100644 --- a/lib/tsan/rtl/tsan_platform_posix.cc +++ b/lib/tsan/rtl/tsan_platform_posix.cpp @@ -1,4 +1,4 @@ -//===-- tsan_platform_posix.cc --------------------------------------------===// +//===-- tsan_platform_posix.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -30,14 +30,7 @@ static const char kShadowMemoryMappingHint[] = "TSAN_OPTIONS=%s=0\n"; static void NoHugePagesInShadow(uptr addr, uptr size) { - if (common_flags()->no_huge_pages_for_shadow) - if (!NoHugePagesInRegion(addr, size)) { - Printf(kShadowMemoryMappingWarning, SanitizerToolName, addr, addr + size, - "MADV_NOHUGEPAGE", errno); - Printf(kShadowMemoryMappingHint, "MADV_NOHUGEPAGE", - "no_huge_pages_for_shadow"); - Die(); - } + SetShadowRegionHugePageMode(addr, size); } static void DontDumpShadow(uptr addr, uptr size) { diff --git a/lib/tsan/rtl/tsan_platform_windows.cc b/lib/tsan/rtl/tsan_platform_windows.cpp index 037297559ee0..19437879a41c 100644 --- a/lib/tsan/rtl/tsan_platform_windows.cc +++ b/lib/tsan/rtl/tsan_platform_windows.cpp @@ -1,4 +1,4 @@ -//===-- tsan_platform_windows.cc ------------------------------------------===// +//===-- tsan_platform_windows.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_preinit.cc b/lib/tsan/rtl/tsan_preinit.cpp index 052b353091d1..205bdbf93b20 100644 --- a/lib/tsan/rtl/tsan_preinit.cc +++ b/lib/tsan/rtl/tsan_preinit.cpp @@ -1,4 +1,4 @@ -//===-- tsan_preinit.cc ---------------------------------------------------===// +//===-- tsan_preinit.cpp --------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_report.cc b/lib/tsan/rtl/tsan_report.cpp index ae669024a879..368f1ca8adf2 100644 --- a/lib/tsan/rtl/tsan_report.cc +++ b/lib/tsan/rtl/tsan_report.cpp @@ -1,4 +1,4 @@ -//===-- tsan_report.cc ----------------------------------------------------===// +//===-- tsan_report.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -298,7 +298,7 @@ static bool FrameIsInternal(const SymbolizedStack *frame) { const char *file = frame->info.file; const char *module = frame->info.module; if (file != 0 && - (internal_strstr(file, "tsan_interceptors.cc") || + (internal_strstr(file, "tsan_interceptors_posix.cpp") || internal_strstr(file, "sanitizer_common_interceptors.inc") || internal_strstr(file, "tsan_interface_"))) return true; diff --git a/lib/tsan/rtl/tsan_rtl.cc b/lib/tsan/rtl/tsan_rtl.cpp index 8a2704ff0631..3f3c0cce119c 100644 --- a/lib/tsan/rtl/tsan_rtl.cc +++ b/lib/tsan/rtl/tsan_rtl.cpp @@ -1,4 +1,4 @@ -//===-- tsan_rtl.cc -------------------------------------------------------===// +//===-- tsan_rtl.cpp ------------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -149,6 +149,7 @@ static void BackgroundThread(void *arg) { // We don't use ScopedIgnoreInterceptors, because we want ignores to be // enabled even when the thread function exits (e.g. during pthread thread // shutdown code). + cur_thread_init(); cur_thread()->ignore_interceptors++; const u64 kMs2Ns = 1000 * 1000; @@ -238,6 +239,15 @@ void DontNeedShadowFor(uptr addr, uptr size) { ReleaseMemoryPagesToOS(MemToShadow(addr), MemToShadow(addr + size)); } +#if !SANITIZER_GO +void UnmapShadow(ThreadState *thr, uptr addr, uptr size) { + if (size == 0) return; + DontNeedShadowFor(addr, size); + ScopedGlobalProcessor sgp; + ctx->metamap.ResetRange(thr->proc(), addr, size); +} +#endif + void MapShadow(uptr addr, uptr size) { // Global data is not 64K aligned, but there are no adjacent mappings, // so we can get away with unaligned mapping. @@ -328,7 +338,7 @@ static void CheckShadowMapping() { #if !SANITIZER_GO static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { - stack->Unwind(sig.pc, sig.bp, sig.context, + stack->Unwind(StackTrace::GetNextInstructionPc(sig.pc), sig.bp, sig.context, common_flags()->fast_unwind_on_fatal); } @@ -869,7 +879,7 @@ void MemoryAccess(ThreadState *thr, uptr pc, uptr addr, shadow_mem, cur); } -// Called by MemoryAccessRange in tsan_rtl_thread.cc +// Called by MemoryAccessRange in tsan_rtl_thread.cpp ALWAYS_INLINE USED void MemoryAccessImpl(ThreadState *thr, uptr addr, int kAccessSizeLog, bool kAccessIsWrite, bool kIsAtomic, @@ -986,6 +996,14 @@ void MemoryRangeImitateWrite(ThreadState *thr, uptr pc, uptr addr, uptr size) { MemoryRangeSet(thr, pc, addr, size, s.raw()); } +void MemoryRangeImitateWriteOrResetRange(ThreadState *thr, uptr pc, uptr addr, + uptr size) { + if (thr->ignore_reads_and_writes == 0) + MemoryRangeImitateWrite(thr, pc, addr, size); + else + MemoryResetRange(thr, pc, addr, size); +} + ALWAYS_INLINE USED void FuncEntry(ThreadState *thr, uptr pc) { StatInc(thr, StatFuncEnter); diff --git a/lib/tsan/rtl/tsan_rtl.h b/lib/tsan/rtl/tsan_rtl.h index 3a8231bda9a9..c38fc43a9f84 100644 --- a/lib/tsan/rtl/tsan_rtl.h +++ b/lib/tsan/rtl/tsan_rtl.h @@ -238,7 +238,7 @@ class Shadow : public FastState { unsigned kS2AccessSize) { bool res = false; u64 diff = s1.addr0() - s2.addr0(); - if ((s64)diff < 0) { // s1.addr0 < s2.addr0 // NOLINT + if ((s64)diff < 0) { // s1.addr0 < s2.addr0 // if (s1.addr0() + size1) > s2.addr0()) return true; if (s1.size() > -diff) res = true; @@ -680,6 +680,7 @@ void ALWAYS_INLINE StatSet(ThreadState *thr, StatType typ, u64 n) { void MapShadow(uptr addr, uptr size); void MapThreadTrace(uptr addr, uptr size, const char *name); void DontNeedShadowFor(uptr addr, uptr size); +void UnmapShadow(ThreadState *thr, uptr addr, uptr size); void InitializeShadowMemory(); void InitializeInterceptors(); void InitializeLibIgnore(); @@ -759,6 +760,8 @@ void ALWAYS_INLINE MemoryWriteAtomic(ThreadState *thr, uptr pc, void MemoryResetRange(ThreadState *thr, uptr pc, uptr addr, uptr size); void MemoryRangeFreed(ThreadState *thr, uptr pc, uptr addr, uptr size); void MemoryRangeImitateWrite(ThreadState *thr, uptr pc, uptr addr, uptr size); +void MemoryRangeImitateWriteOrResetRange(ThreadState *thr, uptr pc, uptr addr, + uptr size); void ThreadIgnoreBegin(ThreadState *thr, uptr pc, bool save_stack = true); void ThreadIgnoreEnd(ThreadState *thr, uptr pc); diff --git a/lib/tsan/rtl/tsan_rtl_mutex.cc b/lib/tsan/rtl/tsan_rtl_mutex.cpp index 941e70f98872..ce6e7cb2c4ef 100644 --- a/lib/tsan/rtl/tsan_rtl_mutex.cc +++ b/lib/tsan/rtl/tsan_rtl_mutex.cpp @@ -1,4 +1,4 @@ -//===-- tsan_rtl_mutex.cc -------------------------------------------------===// +//===-- tsan_rtl_mutex.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_rtl_proc.cc b/lib/tsan/rtl/tsan_rtl_proc.cpp index 94bbed25b8f5..def61cca14d5 100644 --- a/lib/tsan/rtl/tsan_rtl_proc.cc +++ b/lib/tsan/rtl/tsan_rtl_proc.cpp @@ -1,4 +1,4 @@ -//===-- tsan_rtl_proc.cc ------------------------------------------------===// +//===-- tsan_rtl_proc.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_rtl_report.cc b/lib/tsan/rtl/tsan_rtl_report.cpp index 220a425a2c5b..949beac1c551 100644 --- a/lib/tsan/rtl/tsan_rtl_report.cc +++ b/lib/tsan/rtl/tsan_rtl_report.cpp @@ -1,4 +1,4 @@ -//===-- tsan_rtl_report.cc ------------------------------------------------===// +//===-- tsan_rtl_report.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -27,7 +27,7 @@ namespace __tsan { -using namespace __sanitizer; // NOLINT +using namespace __sanitizer; static ReportStack *SymbolizeStack(StackTrace trace); @@ -154,6 +154,7 @@ ScopedReportBase::ScopedReportBase(ReportType typ, uptr tag) { ScopedReportBase::~ScopedReportBase() { ctx->report_mtx.Unlock(); DestroyAndFree(rep_); + rep_ = nullptr; } void ScopedReportBase::AddStack(StackTrace stack, bool suppressable) { @@ -650,7 +651,7 @@ void ReportRace(ThreadState *thr) { // and the resulting PC has kExternalPCBit set, so we pass it to // __tsan_symbolize_external_ex. __tsan_symbolize_external_ex is within its // rights to crash since the PC is completely bogus. - // test/tsan/double_race.cc contains a test case for this. + // test/tsan/double_race.cpp contains a test case for this. toppc = 0; } ObtainCurrentStack(thr, toppc, &traces[0], &tags[0]); @@ -700,7 +701,7 @@ void ReportRace(ThreadState *thr) { rep.AddLocation(addr_min, addr_max - addr_min); #if !SANITIZER_GO - { // NOLINT + { Shadow s(thr->racy_state[1]); if (s.epoch() <= thr->last_sleep_clock.get(s.tid())) rep.AddSleep(thr->last_sleep_stack_id); diff --git a/lib/tsan/rtl/tsan_rtl_thread.cc b/lib/tsan/rtl/tsan_rtl_thread.cpp index fd95cfed4f51..0ac1ee99c470 100644 --- a/lib/tsan/rtl/tsan_rtl_thread.cc +++ b/lib/tsan/rtl/tsan_rtl_thread.cpp @@ -1,4 +1,4 @@ -//===-- tsan_rtl_thread.cc ------------------------------------------------===// +//===-- tsan_rtl_thread.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_stack_trace.cc b/lib/tsan/rtl/tsan_stack_trace.cpp index dbaca23c68aa..403a21ae4ae3 100644 --- a/lib/tsan/rtl/tsan_stack_trace.cc +++ b/lib/tsan/rtl/tsan_stack_trace.cpp @@ -1,4 +1,4 @@ -//===-- tsan_stack_trace.cc -----------------------------------------------===// +//===-- tsan_stack_trace.cpp ----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_stat.cc b/lib/tsan/rtl/tsan_stat.cpp index d23ff47d9af0..78f3cce91384 100644 --- a/lib/tsan/rtl/tsan_stat.cc +++ b/lib/tsan/rtl/tsan_stat.cpp @@ -1,4 +1,4 @@ -//===-- tsan_stat.cc ------------------------------------------------------===// +//===-- tsan_stat.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_suppressions.cc b/lib/tsan/rtl/tsan_suppressions.cpp index b3eea9ab5869..a1c1bf81bf67 100644 --- a/lib/tsan/rtl/tsan_suppressions.cc +++ b/lib/tsan/rtl/tsan_suppressions.cpp @@ -1,4 +1,4 @@ -//===-- tsan_suppressions.cc ----------------------------------------------===// +//===-- tsan_suppressions.cpp ---------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -50,7 +50,7 @@ static const char *kSuppressionTypes[] = { void InitializeSuppressions() { CHECK_EQ(nullptr, suppression_ctx); - suppression_ctx = new (suppression_placeholder) // NOLINT + suppression_ctx = new (suppression_placeholder) SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes)); suppression_ctx->ParseFromFile(flags()->suppressions); #if !SANITIZER_GO diff --git a/lib/tsan/rtl/tsan_symbolize.cc b/lib/tsan/rtl/tsan_symbolize.cpp index cb60763f42f8..6478f3a754ac 100644 --- a/lib/tsan/rtl/tsan_symbolize.cc +++ b/lib/tsan/rtl/tsan_symbolize.cpp @@ -1,4 +1,4 @@ -//===-- tsan_symbolize.cc -------------------------------------------------===// +//===-- tsan_symbolize.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/tsan/rtl/tsan_sync.cc b/lib/tsan/rtl/tsan_sync.cpp index c613b116e3a8..7f686dc5fcdc 100644 --- a/lib/tsan/rtl/tsan_sync.cc +++ b/lib/tsan/rtl/tsan_sync.cpp @@ -1,4 +1,4 @@ -//===-- tsan_sync.cc ------------------------------------------------------===// +//===-- tsan_sync.cpp -----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/ubsan/ubsan_checks.inc b/lib/ubsan/ubsan_checks.inc index 7e7216c5b4ab..33a8dfcde026 100644 --- a/lib/ubsan/ubsan_checks.inc +++ b/lib/ubsan/ubsan_checks.inc @@ -18,6 +18,11 @@ UBSAN_CHECK(GenericUB, "undefined-behavior", "undefined") UBSAN_CHECK(NullPointerUse, "null-pointer-use", "null") +UBSAN_CHECK(NullptrWithOffset, "nullptr-with-offset", "pointer-overflow") +UBSAN_CHECK(NullptrWithNonZeroOffset, "nullptr-with-nonzero-offset", + "pointer-overflow") +UBSAN_CHECK(NullptrAfterNonZeroOffset, "nullptr-after-nonzero-offset", + "pointer-overflow") UBSAN_CHECK(PointerOverflow, "pointer-overflow", "pointer-overflow") UBSAN_CHECK(MisalignedPointerUse, "misaligned-pointer-use", "alignment") UBSAN_CHECK(AlignmentAssumption, "alignment-assumption", "alignment") diff --git a/lib/ubsan/ubsan_diag.cc b/lib/ubsan/ubsan_diag.cpp index 529cc6985763..1b2828d236d6 100644 --- a/lib/ubsan/ubsan_diag.cc +++ b/lib/ubsan/ubsan_diag.cpp @@ -1,4 +1,4 @@ -//===-- ubsan_diag.cc -----------------------------------------------------===// +//===-- ubsan_diag.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -404,7 +404,7 @@ static const char *kSuppressionTypes[] = { void __ubsan::InitializeSuppressions() { CHECK_EQ(nullptr, suppression_ctx); - suppression_ctx = new (suppression_placeholder) // NOLINT + suppression_ctx = new (suppression_placeholder) SuppressionContext(kSuppressionTypes, ARRAY_SIZE(kSuppressionTypes)); suppression_ctx->ParseFromFile(flags()->suppressions); } diff --git a/lib/ubsan/ubsan_diag_standalone.cc b/lib/ubsan/ubsan_diag_standalone.cpp index c22fd1749972..300179adae28 100644 --- a/lib/ubsan/ubsan_diag_standalone.cc +++ b/lib/ubsan/ubsan_diag_standalone.cpp @@ -1,4 +1,4 @@ -//===-- ubsan_diag_standalone.cc ------------------------------------------===// +//===-- ubsan_diag_standalone.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/ubsan/ubsan_flags.cc b/lib/ubsan/ubsan_flags.cpp index 8a9498011932..721c2273f133 100644 --- a/lib/ubsan/ubsan_flags.cc +++ b/lib/ubsan/ubsan_flags.cpp @@ -1,4 +1,4 @@ -//===-- ubsan_flags.cc ----------------------------------------------------===// +//===-- ubsan_flags.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -54,7 +54,6 @@ void InitializeFlags() { { CommonFlags cf; cf.CopyFrom(*common_flags()); - cf.print_summary = false; cf.external_symbolizer_path = GetFlag("UBSAN_SYMBOLIZER_PATH"); OverrideCommonFlags(cf); } diff --git a/lib/ubsan/ubsan_handlers.cc b/lib/ubsan/ubsan_handlers.cpp index 938ac89750f3..3f9da75a12a8 100644 --- a/lib/ubsan/ubsan_handlers.cc +++ b/lib/ubsan/ubsan_handlers.cpp @@ -1,4 +1,4 @@ -//===-- ubsan_handlers.cc -------------------------------------------------===// +//===-- ubsan_handlers.cpp ------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -691,14 +691,33 @@ static void handlePointerOverflowImpl(PointerOverflowData *Data, ValueHandle Result, ReportOptions Opts) { SourceLocation Loc = Data->Loc.acquire(); - ErrorType ET = ErrorType::PointerOverflow; + ErrorType ET; + + if (Base == 0 && Result == 0) + ET = ErrorType::NullptrWithOffset; + else if (Base == 0 && Result != 0) + ET = ErrorType::NullptrWithNonZeroOffset; + else if (Base != 0 && Result == 0) + ET = ErrorType::NullptrAfterNonZeroOffset; + else + ET = ErrorType::PointerOverflow; if (ignoreReport(Loc, Opts, ET)) return; ScopedReport R(Opts, Loc, ET); - if ((sptr(Base) >= 0) == (sptr(Result) >= 0)) { + if (ET == ErrorType::NullptrWithOffset) { + Diag(Loc, DL_Error, ET, "applying zero offset to null pointer"); + } else if (ET == ErrorType::NullptrWithNonZeroOffset) { + Diag(Loc, DL_Error, ET, "applying non-zero offset %0 to null pointer") + << Result; + } else if (ET == ErrorType::NullptrAfterNonZeroOffset) { + Diag( + Loc, DL_Error, ET, + "applying non-zero offset to non-null pointer %0 produced null pointer") + << (void *)Base; + } else if ((sptr(Base) >= 0) == (sptr(Result) >= 0)) { if (Base > Result) Diag(Loc, DL_Error, ET, "addition of unsigned offset to %0 overflowed to %1") diff --git a/lib/ubsan/ubsan_handlers_cxx.cc b/lib/ubsan/ubsan_handlers_cxx.cpp index 9c324cc19a11..2a6d558de034 100644 --- a/lib/ubsan/ubsan_handlers_cxx.cc +++ b/lib/ubsan/ubsan_handlers_cxx.cpp @@ -1,4 +1,4 @@ -//===-- ubsan_handlers_cxx.cc ---------------------------------------------===// +//===-- ubsan_handlers_cxx.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/ubsan/ubsan_init.cc b/lib/ubsan/ubsan_init.cpp index f0bbe1ef1076..1a3b7d372674 100644 --- a/lib/ubsan/ubsan_init.cc +++ b/lib/ubsan/ubsan_init.cpp @@ -1,4 +1,4 @@ -//===-- ubsan_init.cc -----------------------------------------------------===// +//===-- ubsan_init.cpp ----------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/ubsan/ubsan_init_standalone.cc b/lib/ubsan/ubsan_init_standalone.cpp index 323c2c1f9a47..91c3f57b424b 100644 --- a/lib/ubsan/ubsan_init_standalone.cc +++ b/lib/ubsan/ubsan_init_standalone.cpp @@ -1,4 +1,4 @@ -//===-- ubsan_init_standalone.cc ------------------------------------------===// +//===-- ubsan_init_standalone.cpp -----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/ubsan/ubsan_init_standalone_preinit.cc b/lib/ubsan/ubsan_init_standalone_preinit.cpp index bf344a2a9fcd..fabbf919a402 100644 --- a/lib/ubsan/ubsan_init_standalone_preinit.cc +++ b/lib/ubsan/ubsan_init_standalone_preinit.cpp @@ -1,4 +1,4 @@ -//===-- ubsan_init_standalone_preinit.cc ---------------------------------===// +//===-- ubsan_init_standalone_preinit.cpp --------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/ubsan/ubsan_monitor.cc b/lib/ubsan/ubsan_monitor.cpp index cb97a8ff1b88..d064e95f76f7 100644 --- a/lib/ubsan/ubsan_monitor.cc +++ b/lib/ubsan/ubsan_monitor.cpp @@ -1,4 +1,4 @@ -//===-- ubsan_monitor.cc ----------------------------------------*- C++ -*-===// +//===-- ubsan_monitor.cpp ---------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/ubsan/ubsan_signals_standalone.cc b/lib/ubsan/ubsan_signals_standalone.cpp index cc7900cb1364..2c91db8ca397 100644 --- a/lib/ubsan/ubsan_signals_standalone.cc +++ b/lib/ubsan/ubsan_signals_standalone.cpp @@ -1,5 +1,4 @@ -//=-- ubsan_signals_standalone.cc -//------------------------------------------------===// +//=-- ubsan_signals_standalone.cpp ----------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -46,8 +45,9 @@ namespace __ubsan { static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { - ubsan_GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context, - common_flags()->fast_unwind_on_fatal); + ubsan_GetStackTrace(stack, kStackTraceMax, + StackTrace::GetNextInstructionPc(sig.pc), sig.bp, + sig.context, common_flags()->fast_unwind_on_fatal); } static void UBsanOnDeadlySignal(int signo, void *siginfo, void *context) { diff --git a/lib/ubsan/ubsan_type_hash.cc b/lib/ubsan/ubsan_type_hash.cpp index 431495672b55..8f4b9aee50bb 100644 --- a/lib/ubsan/ubsan_type_hash.cc +++ b/lib/ubsan/ubsan_type_hash.cpp @@ -1,4 +1,4 @@ -//===-- ubsan_type_hash.cc ------------------------------------------------===// +//===-- ubsan_type_hash.cpp -----------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. @@ -11,7 +11,7 @@ // permitted to use language features which require a C++ ABI library. // // Most of the implementation lives in an ABI-specific source file -// (ubsan_type_hash_{itanium,win}.cc). +// (ubsan_type_hash_{itanium,win}.cpp). // //===----------------------------------------------------------------------===// diff --git a/lib/ubsan/ubsan_type_hash_itanium.cc b/lib/ubsan/ubsan_type_hash_itanium.cpp index c4b048f20a8c..97846d4dd434 100644 --- a/lib/ubsan/ubsan_type_hash_itanium.cc +++ b/lib/ubsan/ubsan_type_hash_itanium.cpp @@ -1,4 +1,4 @@ -//===-- ubsan_type_hash_itanium.cc ----------------------------------------===// +//===-- ubsan_type_hash_itanium.cpp ---------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/ubsan/ubsan_type_hash_win.cc b/lib/ubsan/ubsan_type_hash_win.cpp index c7b2e45af4e6..45dcb758ec44 100644 --- a/lib/ubsan/ubsan_type_hash_win.cc +++ b/lib/ubsan/ubsan_type_hash_win.cpp @@ -1,4 +1,4 @@ -//===-- ubsan_type_hash_win.cc --------------------------------------------===// +//===-- ubsan_type_hash_win.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/ubsan/ubsan_value.cc b/lib/ubsan/ubsan_value.cpp index ba336a6673ca..60f0b5c99348 100644 --- a/lib/ubsan/ubsan_value.cc +++ b/lib/ubsan/ubsan_value.cpp @@ -1,4 +1,4 @@ -//===-- ubsan_value.cc ----------------------------------------------------===// +//===-- ubsan_value.cpp ---------------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/ubsan/ubsan_win_dll_thunk.cc b/lib/ubsan/ubsan_win_dll_thunk.cpp index fd39e210af0a..5ac7fc3e08e4 100644 --- a/lib/ubsan/ubsan_win_dll_thunk.cc +++ b/lib/ubsan/ubsan_win_dll_thunk.cpp @@ -1,4 +1,4 @@ -//===-- ubsan_win_dll_thunk.cc --------------------------------------------===// +//===-- ubsan_win_dll_thunk.cpp -------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/ubsan/ubsan_win_dynamic_runtime_thunk.cc b/lib/ubsan/ubsan_win_dynamic_runtime_thunk.cpp index 87ada6131cde..00722b4033a5 100644 --- a/lib/ubsan/ubsan_win_dynamic_runtime_thunk.cc +++ b/lib/ubsan/ubsan_win_dynamic_runtime_thunk.cpp @@ -1,4 +1,4 @@ -//===-- ubsan_win_dynamic_runtime_thunk.cc --------------------------------===// +//===-- ubsan_win_dynamic_runtime_thunk.cpp -------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/ubsan/ubsan_win_weak_interception.cc b/lib/ubsan/ubsan_win_weak_interception.cpp index 8cf6344ce1d8..01db0c0ce78a 100644 --- a/lib/ubsan/ubsan_win_weak_interception.cc +++ b/lib/ubsan/ubsan_win_weak_interception.cpp @@ -1,4 +1,4 @@ -//===-- ubsan_win_weak_interception.cc ------------------------------------===// +//===-- ubsan_win_weak_interception.cpp -----------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/ubsan_minimal/ubsan_minimal_handlers.cc b/lib/ubsan_minimal/ubsan_minimal_handlers.cpp index ed62ddd0fa34..ed62ddd0fa34 100644 --- a/lib/ubsan_minimal/ubsan_minimal_handlers.cc +++ b/lib/ubsan_minimal/ubsan_minimal_handlers.cpp diff --git a/lib/xray/xray_AArch64.cc b/lib/xray/xray_AArch64.cpp index 4c7805488ab8..081941b70375 100644 --- a/lib/xray/xray_AArch64.cc +++ b/lib/xray/xray_AArch64.cpp @@ -1,4 +1,4 @@ -//===-- xray_AArch64.cc -----------------------------------------*- C++ -*-===// +//===-- xray_AArch64.cpp ----------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/xray/xray_arm.cc b/lib/xray/xray_arm.cpp index db26efaa782a..9ad8065eb886 100644 --- a/lib/xray/xray_arm.cc +++ b/lib/xray/xray_arm.cpp @@ -1,4 +1,4 @@ -//===-- xray_arm.cc ---------------------------------------------*- C++ -*-===// +//===-- xray_arm.cpp --------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/xray/xray_basic_flags.cc b/lib/xray/xray_basic_flags.cpp index 75b674c85656..e0a5e7bb29ee 100644 --- a/lib/xray/xray_basic_flags.cc +++ b/lib/xray/xray_basic_flags.cpp @@ -1,4 +1,4 @@ -//===-- xray_basic_flags.cc -------------------------------------*- C++ -*-===// +//===-- xray_basic_flags.cpp ------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/xray/xray_basic_logging.cc b/lib/xray/xray_basic_logging.cpp index 553041ce0c31..6e8e93131451 100644 --- a/lib/xray/xray_basic_logging.cc +++ b/lib/xray/xray_basic_logging.cpp @@ -1,4 +1,4 @@ -//===-- xray_basic_logging.cc -----------------------------------*- C++ -*-===// +//===-- xray_basic_logging.cpp ----------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/xray/xray_buffer_queue.cc b/lib/xray/xray_buffer_queue.cpp index 4cfa717de208..bad91e036cef 100644 --- a/lib/xray/xray_buffer_queue.cc +++ b/lib/xray/xray_buffer_queue.cpp @@ -1,4 +1,4 @@ -//===-- xray_buffer_queue.cc -----------------------------------*- C++ -*-===// +//===-- xray_buffer_queue.cpp ----------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/xray/xray_fdr_flags.cc b/lib/xray/xray_fdr_flags.cpp index 8d432d298d88..272b0b7cb1f7 100644 --- a/lib/xray/xray_fdr_flags.cc +++ b/lib/xray/xray_fdr_flags.cpp @@ -1,4 +1,4 @@ -//===-- xray_fdr_flags.cc ---------------------------------------*- C++ -*-===// +//===-- xray_fdr_flags.cpp --------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/xray/xray_fdr_logging.cc b/lib/xray/xray_fdr_logging.cpp index abba06576da1..16ce483502f0 100644 --- a/lib/xray/xray_fdr_logging.cc +++ b/lib/xray/xray_fdr_logging.cpp @@ -1,4 +1,4 @@ -//===-- xray_fdr_logging.cc ------------------------------------*- C++ -*-===// +//===-- xray_fdr_logging.cpp -----------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/xray/xray_flags.cc b/lib/xray/xray_flags.cpp index b9e8324a7874..e4c6906dc443 100644 --- a/lib/xray/xray_flags.cc +++ b/lib/xray/xray_flags.cpp @@ -1,4 +1,4 @@ -//===-- xray_flags.cc -------------------------------------------*- C++ -*-===// +//===-- xray_flags.cpp ------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/xray/xray_init.cc b/lib/xray/xray_init.cpp index b79bc08c5f4d..408396477975 100644 --- a/lib/xray/xray_init.cc +++ b/lib/xray/xray_init.cpp @@ -1,4 +1,4 @@ -//===-- xray_init.cc --------------------------------------------*- C++ -*-===// +//===-- xray_init.cpp -------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/xray/xray_interface.cc b/lib/xray/xray_interface.cpp index 0d22893eb30f..0d22893eb30f 100644 --- a/lib/xray/xray_interface.cc +++ b/lib/xray/xray_interface.cpp diff --git a/lib/xray/xray_log_interface.cc b/lib/xray/xray_log_interface.cpp index 7916a9e2b8ad..fc70373f9dac 100644 --- a/lib/xray/xray_log_interface.cc +++ b/lib/xray/xray_log_interface.cpp @@ -1,4 +1,4 @@ -//===-- xray_log_interface.cc ---------------------------------------------===// +//===-- xray_log_interface.cpp --------------------------------------------===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/xray/xray_mips.cc b/lib/xray/xray_mips.cpp index 80990ab8d639..26fc50374471 100644 --- a/lib/xray/xray_mips.cc +++ b/lib/xray/xray_mips.cpp @@ -1,4 +1,4 @@ -//===-- xray_mips.cc --------------------------------------------*- C++ -*-===// +//===-- xray_mips.cpp -------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/xray/xray_mips64.cc b/lib/xray/xray_mips64.cpp index 73c8924f9a0b..62c67ff7376d 100644 --- a/lib/xray/xray_mips64.cc +++ b/lib/xray/xray_mips64.cpp @@ -1,4 +1,4 @@ -//===-- xray_mips64.cc ------------------------------------------*- C++ -*-===// +//===-- xray_mips64.cpp -----------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/xray/xray_powerpc64.cc b/lib/xray/xray_powerpc64.cpp index abc2becf5b4d..b41f1bce6f21 100644 --- a/lib/xray/xray_powerpc64.cc +++ b/lib/xray/xray_powerpc64.cpp @@ -1,4 +1,4 @@ -//===-- xray_powerpc64.cc ---------------------------------------*- C++ -*-===// +//===-- xray_powerpc64.cpp --------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/xray/xray_profile_collector.cc b/lib/xray/xray_profile_collector.cpp index 97b52e1d9a22..bef2504f2a16 100644 --- a/lib/xray/xray_profile_collector.cc +++ b/lib/xray/xray_profile_collector.cpp @@ -1,4 +1,4 @@ -//===-- xray_profile_collector.cc ------------------------------*- C++ -*-===// +//===-- xray_profile_collector.cpp -----------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/xray/xray_profiling.cc b/lib/xray/xray_profiling.cpp index 66def6cf2485..ef16691562cc 100644 --- a/lib/xray/xray_profiling.cc +++ b/lib/xray/xray_profiling.cpp @@ -1,4 +1,4 @@ -//===-- xray_profiling.cc ---------------------------------------*- C++ -*-===// +//===-- xray_profiling.cpp --------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/xray/xray_profiling_flags.cc b/lib/xray/xray_profiling_flags.cpp index 0e89b7420f8c..0e89b7420f8c 100644 --- a/lib/xray/xray_profiling_flags.cc +++ b/lib/xray/xray_profiling_flags.cpp diff --git a/lib/xray/xray_trampoline_powerpc64.cc b/lib/xray/xray_trampoline_powerpc64.cpp index 878c46930fee..878c46930fee 100644 --- a/lib/xray/xray_trampoline_powerpc64.cc +++ b/lib/xray/xray_trampoline_powerpc64.cpp diff --git a/lib/xray/xray_utils.cc b/lib/xray/xray_utils.cpp index 82674baa5a0c..1036d17a7725 100644 --- a/lib/xray/xray_utils.cc +++ b/lib/xray/xray_utils.cpp @@ -1,4 +1,4 @@ -//===-- xray_utils.cc -------------------------------------------*- C++ -*-===// +//===-- xray_utils.cpp ------------------------------------------*- C++ -*-===// // // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. // See https://llvm.org/LICENSE.txt for license information. diff --git a/lib/xray/xray_x86_64.cc b/lib/xray/xray_x86_64.cpp index e63ee1b3bd02..e63ee1b3bd02 100644 --- a/lib/xray/xray_x86_64.cc +++ b/lib/xray/xray_x86_64.cpp diff --git a/tools/CMakeLists.txt b/tools/CMakeLists.txt new file mode 100644 index 000000000000..aa4aff34b1bb --- /dev/null +++ b/tools/CMakeLists.txt @@ -0,0 +1 @@ +add_subdirectory(gwp_asan) diff --git a/tools/gwp_asan/CMakeLists.txt b/tools/gwp_asan/CMakeLists.txt new file mode 100644 index 000000000000..b0f9f0cf9e5d --- /dev/null +++ b/tools/gwp_asan/CMakeLists.txt @@ -0,0 +1,20 @@ +# Build the stack trace compressor fuzzer. This will require Clang >= 6.0.0, as +# -fsanitize=fuzzer-no-link was not a valid command line flag prior to this. +if (LLVM_USE_SANITIZE_COVERAGE) + add_executable(stack_trace_compressor_fuzzer + ../../lib/gwp_asan/stack_trace_compressor.cpp + ../../lib/gwp_asan/stack_trace_compressor.h + stack_trace_compressor_fuzzer.cpp) + set_target_properties( + stack_trace_compressor_fuzzer PROPERTIES FOLDER "Fuzzers") + target_compile_options( + stack_trace_compressor_fuzzer PRIVATE -fsanitize=fuzzer-no-link) + set_target_properties( + stack_trace_compressor_fuzzer PROPERTIES LINK_FLAGS -fsanitize=fuzzer) + target_include_directories( + stack_trace_compressor_fuzzer PRIVATE ../../lib/) + + if (TARGET gwp_asan) + add_dependencies(gwp_asan stack_trace_compressor_fuzzer) + endif() +endif() diff --git a/tools/gwp_asan/stack_trace_compressor_fuzzer.cpp b/tools/gwp_asan/stack_trace_compressor_fuzzer.cpp new file mode 100644 index 000000000000..aa57fdaff636 --- /dev/null +++ b/tools/gwp_asan/stack_trace_compressor_fuzzer.cpp @@ -0,0 +1,49 @@ +#include <cstddef> +#include <cstdint> +#include <cstdio> +#include <cstdlib> +#include <vector> + +#include "gwp_asan/stack_trace_compressor.h" + +constexpr size_t kBytesForLargestVarInt = (sizeof(uintptr_t) * 8) / 7 + 1; + +extern "C" int LLVMFuzzerTestOneInput(const uint8_t *Data, size_t Size) { + size_t BufferSize = kBytesForLargestVarInt * Size / sizeof(uintptr_t); + std::vector<uint8_t> Buffer(BufferSize); + std::vector<uint8_t> Buffer2(BufferSize); + + // Unpack the fuzz bytes. + gwp_asan::compression::unpack(Data, Size, + reinterpret_cast<uintptr_t *>(Buffer2.data()), + BufferSize / sizeof(uintptr_t)); + + // Pack the fuzz bytes. + size_t BytesWritten = gwp_asan::compression::pack( + reinterpret_cast<const uintptr_t *>(Data), Size / sizeof(uintptr_t), + Buffer.data(), BufferSize); + + // Unpack the compressed buffer. + size_t DecodedElements = gwp_asan::compression::unpack( + Buffer.data(), BytesWritten, + reinterpret_cast<uintptr_t *>(Buffer2.data()), + BufferSize / sizeof(uintptr_t)); + + // Ensure that every element was encoded and decoded properly. + if (DecodedElements != Size / sizeof(uintptr_t)) + abort(); + + // Ensure that the compression and uncompression resulted in the same trace. + const uintptr_t *FuzzPtrs = reinterpret_cast<const uintptr_t *>(Data); + const uintptr_t *DecodedPtrs = + reinterpret_cast<const uintptr_t *>(Buffer2.data()); + for (size_t i = 0; i < Size / sizeof(uintptr_t); ++i) { + if (FuzzPtrs[i] != DecodedPtrs[i]) { + fprintf(stderr, "FuzzPtrs[%zu] != DecodedPtrs[%zu] (0x%zx vs. 0x%zx)", i, + i, FuzzPtrs[i], DecodedPtrs[i]); + abort(); + } + } + + return 0; +} |