summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2019-10-23 17:52:22 +0000
committerDimitry Andric <dim@FreeBSD.org>2019-10-23 17:52:22 +0000
commit3a1720af1d7f43edc5b214cde0be11bfb94d077e (patch)
tree029e0ff2d5e3c0eaf2405fd8e669555fdf5e1297
parent8f3cadc28cb2bb9e8f9d69eeaaea1f57f2f7b2ab (diff)
downloadsrc-test2-vendor/compiler-rt.tar.gz
src-test2-vendor/compiler-rt.zip
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.h2
-rw-r--r--include/sanitizer/tsan_interface_atomic.h8
-rw-r--r--include/sanitizer/ubsan_interface.h32
-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.h2
-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.h4
-rw-r--r--lib/asan/asan_errors.cpp (renamed from lib/asan/asan_errors.cc)7
-rw-r--r--lib/asan/asan_errors.h3
-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.h2
-rw-r--r--lib/asan/asan_flags.cpp (renamed from lib/asan/asan_flags.cc)2
-rw-r--r--lib/asan/asan_flags.inc13
-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.h14
-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.h2
-rw-r--r--lib/asan/asan_internal.h12
-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.h2
-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.h2
-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.h2
-rw-r--r--lib/asan/asan_thread.cpp (renamed from lib/asan/asan_thread.cc)7
-rw-r--r--lib/asan/asan_thread.h2
-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.c59
-rw-r--r--lib/builtins/adddf3.c3
-rw-r--r--lib/builtins/addsf3.c3
-rw-r--r--lib/builtins/addtf3.c5
-rw-r--r--lib/builtins/arm/fp_mode.c59
-rw-r--r--lib/builtins/atomic.c4
-rw-r--r--lib/builtins/clear_cache.c68
-rw-r--r--lib/builtins/cpu_model.c12
-rw-r--r--lib/builtins/divtf3.c2
-rw-r--r--lib/builtins/emutls.c11
-rw-r--r--lib/builtins/extenddftf2.c2
-rw-r--r--lib/builtins/extendsftf2.c2
-rw-r--r--lib/builtins/fixunsxfdi.c11
-rw-r--r--lib/builtins/fixunsxfsi.c11
-rw-r--r--lib/builtins/fixxfdi.c11
-rw-r--r--lib/builtins/fp_add_impl.inc27
-rw-r--r--lib/builtins/fp_lib.h2
-rw-r--r--lib/builtins/fp_mode.c24
-rw-r--r--lib/builtins/fp_mode.h29
-rw-r--r--lib/builtins/fp_trunc_impl.inc2
-rw-r--r--lib/builtins/subdf3.c3
-rw-r--r--lib/builtins/subsf3.c3
-rw-r--r--lib/builtins/subtf3.c3
-rw-r--r--lib/builtins/udivmoddi4.c11
-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.h22
-rw-r--r--lib/fuzzer/FuzzerDefs.h5
-rw-r--r--lib/fuzzer/FuzzerDriver.cpp1
-rw-r--r--lib/fuzzer/FuzzerExtFunctions.def11
-rw-r--r--lib/fuzzer/FuzzerFlags.def3
-rw-r--r--lib/fuzzer/FuzzerInternal.h3
-rw-r--r--lib/fuzzer/FuzzerLoop.cpp19
-rw-r--r--lib/fuzzer/FuzzerMerge.cpp82
-rw-r--r--lib/fuzzer/FuzzerOptions.h1
-rw-r--r--lib/fuzzer/FuzzerTracePC.cpp41
-rw-r--r--lib/fuzzer/FuzzerTracePC.h3
-rw-r--r--lib/fuzzer/FuzzerUtil.h2
-rw-r--r--lib/fuzzer/FuzzerUtilFuchsia.cpp26
-rw-r--r--lib/fuzzer/FuzzerUtilPosix.cpp6
-rw-r--r--lib/fuzzer/FuzzerUtilWindows.cpp4
-rw-r--r--lib/gwp_asan/guarded_pool_allocator.cpp61
-rw-r--r--lib/gwp_asan/guarded_pool_allocator.h21
-rw-r--r--lib/gwp_asan/optional/backtrace.h7
-rw-r--r--lib/gwp_asan/optional/backtrace_linux_libc.cpp22
-rw-r--r--lib/gwp_asan/optional/backtrace_sanitizer_common.cpp29
-rw-r--r--lib/gwp_asan/options.h69
-rw-r--r--lib/gwp_asan/options.inc6
-rwxr-xr-xlib/gwp_asan/scripts/symbolize.sh55
-rw-r--r--lib/gwp_asan/stack_trace_compressor.cpp111
-rw-r--r--lib/gwp_asan/stack_trace_compressor.h38
-rw-r--r--lib/hwasan/hwasan.cpp155
-rw-r--r--lib/hwasan/hwasan.h2
-rw-r--r--lib/hwasan/hwasan_allocator.cpp29
-rw-r--r--lib/hwasan/hwasan_allocator.h6
-rw-r--r--lib/hwasan/hwasan_exceptions.cpp67
-rw-r--r--lib/hwasan/hwasan_flags.inc2
-rw-r--r--lib/hwasan/hwasan_interceptors.cpp2
-rw-r--r--lib/hwasan/hwasan_interface_internal.h9
-rw-r--r--lib/hwasan/hwasan_linux.cpp42
-rw-r--r--lib/hwasan/hwasan_new_delete.cpp2
-rw-r--r--lib/hwasan/hwasan_report.cpp25
-rw-r--r--lib/hwasan/hwasan_tag_mismatch_aarch64.S50
-rw-r--r--lib/interception/interception.h4
-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.h5
-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.h11
-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.h17
-rw-r--r--lib/profile/InstrProfilingFile.c11
-rw-r--r--lib/profile/InstrProfilingPlatformFuchsia.c93
-rw-r--r--lib/profile/InstrProfilingRuntime.cpp (renamed from lib/profile/InstrProfilingRuntime.cc)0
-rw-r--r--lib/profile/InstrProfilingUtil.c20
-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.h2
-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.h4
-rw-r--r--lib/sanitizer_common/sanitizer_atomic_msvc.h63
-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.h29
-rw-r--r--lib/sanitizer_common/sanitizer_common_interceptors.inc144
-rw-r--r--lib/sanitizer_common/sanitizer_common_interface.inc1
-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.inc12
-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.h4
-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.h30
-rw-r--r--lib/sanitizer_common/sanitizer_glibc_version.h26
-rw-r--r--lib/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc31
-rw-r--r--lib/sanitizer_common/sanitizer_internal_defs.h75
-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.inc11
-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.h24
-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.h1090
-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.h47
-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.h2168
-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.h7
-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.h2
-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.h2
-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.h2
-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.h19
-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.h2
-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.h6
-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.h12
-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-xlib/sanitizer_common/symbolizer/scripts/build_symbolizer.sh34
-rw-r--r--lib/sanitizer_common/symbolizer/scripts/global_symbols.txt7
-rw-r--r--lib/scudo/scudo_allocator_secondary.h28
-rw-r--r--lib/scudo/scudo_errors.cpp5
-rw-r--r--lib/scudo/standalone/allocator_config.h4
-rw-r--r--lib/scudo/standalone/checksum.cpp (renamed from lib/scudo/standalone/checksum.cc)2
-rw-r--r--lib/scudo/standalone/chunk.h26
-rw-r--r--lib/scudo/standalone/combined.h131
-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.h4
-rw-r--r--lib/scudo/standalone/linux.cpp (renamed from lib/scudo/standalone/linux.cc)4
-rw-r--r--lib/scudo/standalone/linux.h2
-rw-r--r--lib/scudo/standalone/list.h12
-rw-r--r--lib/scudo/standalone/local_cache.h16
-rw-r--r--lib/scudo/standalone/mutex.h6
-rw-r--r--lib/scudo/standalone/primary32.h60
-rw-r--r--lib/scudo/standalone/primary64.h89
-rw-r--r--lib/scudo/standalone/quarantine.h20
-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.h5
-rw-r--r--lib/scudo/standalone/size_class_map.h16
-rw-r--r--lib/scudo/standalone/stats.h2
-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.h1
-rw-r--r--lib/scudo/standalone/tsd_exclusive.h4
-rw-r--r--lib/scudo/standalone/tsd_shared.h5
-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.inc16
-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.h14
-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.cpp52
-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.h13
-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.h10
-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.h4
-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.h5
-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.h2
-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.h5
-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.inc5
-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.txt1
-rw-r--r--tools/gwp_asan/CMakeLists.txt20
-rw-r--r--tools/gwp_asan/stack_trace_compressor_fuzzer.cpp49
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 &region_address, uptr &region_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, &region_address, &region_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)() = &register_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, &param);
- UnlockAllocator();
- UnlockThreadRegistry();
+ LockStuffAndStopTheWorld(CheckForLeaksCallback, &param);
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 &region,
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, &param);
+ dl_iterate_phdr(LockStuffAndStopTheWorldCallback, &param);
}
} // 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;
+}