From b667dd7017a8f9d36d3ab266f22290d75fa527b0 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 14 Aug 2019 10:47:11 +0200 Subject: [PATCH] Libsanitizer merge from trunk r368656. 2019-08-14 Martin Liska PR sanitizer/89832 PR sanitizer/91325 * All source files: Merge from upstream 368656. From-SVN: r274426 --- libsanitizer/ChangeLog | 6 + libsanitizer/MERGE | 2 +- libsanitizer/Makefile.in | 8 +- libsanitizer/aclocal.m4 | 191 +- libsanitizer/asan/Makefile.am | 63 +- libsanitizer/asan/Makefile.in | 323 +- ...asan_activation.cc => asan_activation.cpp} | 7 +- libsanitizer/asan/asan_activation.h | 5 +- libsanitizer/asan/asan_activation_flags.inc | 5 +- .../{asan_allocator.cc => asan_allocator.cpp} | 18 +- libsanitizer/asan/asan_allocator.h | 44 +- .../{asan_debugging.cc => asan_debugging.cpp} | 7 +- ..._descriptions.cc => asan_descriptions.cpp} | 7 +- libsanitizer/asan/asan_descriptions.h | 7 +- .../asan/{asan_errors.cc => asan_errors.cpp} | 22 +- libsanitizer/asan/asan_errors.h | 27 +- ...asan_fake_stack.cc => asan_fake_stack.cpp} | 7 +- libsanitizer/asan/asan_fake_stack.h | 7 +- .../asan/{asan_flags.cc => asan_flags.cpp} | 13 +- libsanitizer/asan/asan_flags.h | 5 +- libsanitizer/asan/asan_flags.inc | 9 +- .../{asan_fuchsia.cc => asan_fuchsia.cpp} | 20 +- .../{asan_globals.cc => asan_globals.cpp} | 50 +- ...an_globals_win.cc => asan_globals_win.cpp} | 7 +- libsanitizer/asan/asan_init_version.h | 5 +- ..._interceptors.cc => asan_interceptors.cpp} | 18 +- libsanitizer/asan/asan_interceptors.h | 39 +- ...cc => asan_interceptors_memintrinsics.cpp} | 7 +- .../asan/asan_interceptors_memintrinsics.h | 7 +- libsanitizer/asan/asan_interceptors_vfork.S | 12 + libsanitizer/asan/asan_interface.inc | 6 +- libsanitizer/asan/asan_interface_internal.h | 7 +- libsanitizer/asan/asan_internal.h | 22 +- .../asan/{asan_linux.cc => asan_linux.cpp} | 14 +- .../asan/{asan_mac.cc => asan_mac.cpp} | 11 +- ..._malloc_linux.cc => asan_malloc_linux.cpp} | 17 +- libsanitizer/asan/asan_malloc_local.h | 30 +- ...asan_malloc_mac.cc => asan_malloc_mac.cpp} | 46 +- libsanitizer/asan/asan_malloc_win.cc | 259 -- libsanitizer/asan/asan_malloc_win.cpp | 553 ++++ libsanitizer/asan/asan_mapping.h | 27 +- libsanitizer/asan/asan_mapping_myriad.h | 5 +- libsanitizer/asan/asan_mapping_sparc64.h | 5 +- ...ory_profile.cc => asan_memory_profile.cpp} | 7 +- ...asan_new_delete.cc => asan_new_delete.cpp} | 37 +- .../{asan_poisoning.cc => asan_poisoning.cpp} | 7 +- libsanitizer/asan/asan_poisoning.h | 15 +- .../asan/{asan_posix.cc => asan_posix.cpp} | 53 +- .../{asan_preinit.cc => asan_preinit.cpp} | 7 +- ...remap_shadow.cc => asan_premap_shadow.cpp} | 7 +- libsanitizer/asan/asan_premap_shadow.h | 5 +- .../asan/{asan_report.cc => asan_report.cpp} | 16 +- libsanitizer/asan/asan_report.h | 7 +- .../asan/{asan_rtems.cc => asan_rtems.cpp} | 17 +- .../asan/{asan_rtl.cc => asan_rtl.cpp} | 45 +- libsanitizer/asan/asan_scariness_score.h | 5 +- ..._shadow_setup.cc => asan_shadow_setup.cpp} | 11 +- libsanitizer/asan/asan_stack.cc | 38 - libsanitizer/asan/asan_stack.cpp | 88 + libsanitizer/asan/asan_stack.h | 47 +- .../asan/{asan_stats.cc => asan_stats.cpp} | 7 +- libsanitizer/asan/asan_stats.h | 5 +- ..._suppressions.cc => asan_suppressions.cpp} | 7 +- libsanitizer/asan/asan_suppressions.h | 7 +- .../asan/{asan_thread.cc => asan_thread.cpp} | 34 +- libsanitizer/asan/asan_thread.h | 22 +- .../asan/{asan_win.cc => asan_win.cpp} | 115 +- ...in_dll_thunk.cc => asan_win_dll_thunk.cpp} | 10 +- ....cc => asan_win_dynamic_runtime_thunk.cpp} | 9 +- ...tion.cc => asan_win_weak_interception.cpp} | 7 +- libsanitizer/builtins/assembly.h | 36 +- libsanitizer/configure | 191 +- libsanitizer/configure.tgt | 3 - .../include/sanitizer/allocator_interface.h | 5 +- .../include/sanitizer/asan_interface.h | 407 ++- .../include/sanitizer/common_interface_defs.h | 507 ++-- .../include/sanitizer/coverage_interface.h | 5 +- .../include/sanitizer/dfsan_interface.h | 11 +- .../include/sanitizer/esan_interface.h | 48 - .../include/sanitizer/hwasan_interface.h | 26 +- .../include/sanitizer/linux_syscall_hooks.h | 5 +- .../include/sanitizer/lsan_interface.h | 5 +- .../include/sanitizer/msan_interface.h | 8 +- .../include/sanitizer/netbsd_syscall_hooks.h | 51 +- .../include/sanitizer/scudo_interface.h | 5 +- .../include/sanitizer/tsan_interface.h | 23 +- .../include/sanitizer/tsan_interface_atomic.h | 7 +- libsanitizer/interception/Makefile.am | 8 +- libsanitizer/interception/Makefile.in | 80 +- libsanitizer/interception/interception.h | 15 +- .../interception/interception_linux.cc | 53 - .../interception/interception_linux.cpp | 83 + .../interception/interception_linux.h | 29 +- ...terception_mac.cc => interception_mac.cpp} | 7 +- libsanitizer/interception/interception_mac.h | 5 +- ...ype_test.cc => interception_type_test.cpp} | 7 +- ...terception_win.cc => interception_win.cpp} | 13 +- libsanitizer/interception/interception_win.h | 5 +- libsanitizer/libbacktrace/Makefile.in | 107 +- libsanitizer/lsan/Makefile.am | 20 +- libsanitizer/lsan/Makefile.in | 99 +- libsanitizer/lsan/{lsan.cc => lsan.cpp} | 29 +- libsanitizer/lsan/lsan.h | 27 +- .../{lsan_allocator.cc => lsan_allocator.cpp} | 21 +- libsanitizer/lsan/lsan_allocator.h | 34 +- .../lsan/{lsan_common.cc => lsan_common.cpp} | 7 +- libsanitizer/lsan/lsan_common.h | 11 +- ..._common_linux.cc => lsan_common_linux.cpp} | 14 +- ...lsan_common_mac.cc => lsan_common_mac.cpp} | 11 +- libsanitizer/lsan/lsan_flags.inc | 5 +- ..._interceptors.cc => lsan_interceptors.cpp} | 15 +- .../lsan/{lsan_linux.cc => lsan_linux.cpp} | 13 +- .../lsan/{lsan_mac.cc => lsan_mac.cpp} | 7 +- ...lsan_malloc_mac.cc => lsan_malloc_mac.cpp} | 9 +- .../{lsan_preinit.cc => lsan_preinit.cpp} | 7 +- .../lsan/{lsan_thread.cc => lsan_thread.cpp} | 11 +- libsanitizer/lsan/lsan_thread.h | 8 +- libsanitizer/merge.sh | 3 +- libsanitizer/sanitizer_common/Makefile.am | 118 +- libsanitizer/sanitizer_common/Makefile.in | 514 ++-- libsanitizer/sanitizer_common/sancov_begin.S | 5 - libsanitizer/sanitizer_common/sancov_end.S | 5 - .../{sancov_flags.cc => sancov_flags.cpp} | 9 +- libsanitizer/sanitizer_common/sancov_flags.h | 5 +- .../sanitizer_common/sancov_flags.inc | 5 +- .../sanitizer_common/sanitizer_addrhashmap.h | 5 +- ...r_allocator.cc => sanitizer_allocator.cpp} | 19 +- .../sanitizer_common/sanitizer_allocator.h | 11 +- .../sanitizer_allocator_bytemap.h | 17 +- ...ecks.cc => sanitizer_allocator_checks.cpp} | 7 +- .../sanitizer_allocator_checks.h | 5 +- .../sanitizer_allocator_combined.h | 19 +- .../sanitizer_allocator_interface.h | 5 +- .../sanitizer_allocator_internal.h | 34 +- .../sanitizer_allocator_local_cache.h | 12 +- .../sanitizer_allocator_primary32.h | 21 +- .../sanitizer_allocator_primary64.h | 35 +- ...port.cc => sanitizer_allocator_report.cpp} | 19 +- .../sanitizer_allocator_report.h | 7 +- .../sanitizer_allocator_secondary.h | 52 +- .../sanitizer_allocator_size_class_map.h | 8 +- .../sanitizer_allocator_stats.h | 7 +- libsanitizer/sanitizer_common/sanitizer_asm.h | 16 +- .../sanitizer_common/sanitizer_atomic.h | 5 +- .../sanitizer_common/sanitizer_atomic_clang.h | 5 +- .../sanitizer_atomic_clang_mips.h | 6 +- .../sanitizer_atomic_clang_other.h | 5 +- .../sanitizer_atomic_clang_x86.h | 5 +- .../sanitizer_common/sanitizer_atomic_msvc.h | 5 +- .../sanitizer_common/sanitizer_bitvector.h | 5 +- .../sanitizer_common/sanitizer_bvgraph.h | 5 +- ...nitizer_common.cc => sanitizer_common.cpp} | 7 +- .../sanitizer_common/sanitizer_common.h | 42 +- .../sanitizer_common_interceptors.inc | 2620 ++++++++++++++++- .../sanitizer_common_interceptors_format.inc | 5 +- .../sanitizer_common_interceptors_ioctl.inc | 5 +- ...er_common_interceptors_vfork_aarch64.inc.S | 43 + ...itizer_common_interceptors_vfork_arm.inc.S | 49 + ...tizer_common_interceptors_vfork_i386.inc.S | 63 + ...zer_common_interceptors_vfork_x86_64.inc.S | 41 + .../sanitizer_common_interface.inc | 5 +- .../sanitizer_common_interface_posix.inc | 5 +- ...ibcdep.cc => sanitizer_common_libcdep.cpp} | 11 +- ..._nolibc.cc => sanitizer_common_nolibc.cpp} | 7 +- .../sanitizer_common_syscalls.inc | 17 +- ...hsia.cc => sanitizer_coverage_fuchsia.cpp} | 12 +- .../sanitizer_coverage_interface.inc | 5 +- ....cc => sanitizer_coverage_libcdep_new.cpp} | 7 +- ...c => sanitizer_coverage_win_dll_thunk.cpp} | 7 +- ...er_coverage_win_dynamic_runtime_thunk.cpp} | 13 +- ...cc => sanitizer_coverage_win_sections.cpp} | 52 +- ...itizer_coverage_win_weak_interception.cpp} | 7 +- .../sanitizer_common/sanitizer_dbghelp.h | 5 +- .../sanitizer_deadlock_detector.h | 12 +- ...r1.cc => sanitizer_deadlock_detector1.cpp} | 7 +- ...r2.cc => sanitizer_deadlock_detector2.cpp} | 7 +- .../sanitizer_deadlock_detector_interface.h | 5 +- ...sanitizer_errno.cc => sanitizer_errno.cpp} | 7 +- .../sanitizer_common/sanitizer_errno.h | 5 +- .../sanitizer_common/sanitizer_errno_codes.h | 5 +- .../{sanitizer_file.cc => sanitizer_file.cpp} | 9 +- .../sanitizer_common/sanitizer_file.h | 8 +- ...ag_parser.cc => sanitizer_flag_parser.cpp} | 36 +- .../sanitizer_common/sanitizer_flag_parser.h | 24 +- ...sanitizer_flags.cc => sanitizer_flags.cpp} | 7 +- .../sanitizer_common/sanitizer_flags.h | 5 +- .../sanitizer_common/sanitizer_flags.inc | 16 +- .../sanitizer_common/sanitizer_freebsd.h | 5 +- ...tizer_fuchsia.cc => sanitizer_fuchsia.cpp} | 38 +- .../sanitizer_common/sanitizer_fuchsia.h | 5 +- .../sanitizer_common/sanitizer_getauxval.h | 5 +- .../sanitizer_common/sanitizer_hash.h | 43 + .../sanitizer_interceptors_ioctl_netbsd.inc | 88 +- .../sanitizer_interface_internal.h | 5 +- .../sanitizer_internal_defs.h | 8 +- .../sanitizer_common/sanitizer_lfstack.h | 5 +- .../{sanitizer_libc.cc => sanitizer_libc.cpp} | 7 +- .../sanitizer_common/sanitizer_libc.h | 5 +- ...r_libignore.cc => sanitizer_libignore.cpp} | 7 +- .../sanitizer_common/sanitizer_libignore.h | 5 +- ...sanitizer_linux.cc => sanitizer_linux.cpp} | 155 +- .../sanitizer_common/sanitizer_linux.h | 34 +- ...libcdep.cc => sanitizer_linux_libcdep.cpp} | 51 +- .../sanitizer_common/sanitizer_linux_mips64.S | 23 - ...linux_s390.cc => sanitizer_linux_s390.cpp} | 7 +- .../sanitizer_common/sanitizer_linux_x86_64.S | 25 - .../sanitizer_common/sanitizer_list.h | 5 +- .../sanitizer_local_address_space_view.h | 76 + .../{sanitizer_mac.cc => sanitizer_mac.cpp} | 148 +- libsanitizer/sanitizer_common/sanitizer_mac.h | 7 +- ...c_libcdep.cc => sanitizer_mac_libcdep.cpp} | 7 +- .../sanitizer_common/sanitizer_malloc_mac.inc | 101 +- .../sanitizer_common/sanitizer_mutex.h | 5 +- ...nitizer_netbsd.cc => sanitizer_netbsd.cpp} | 36 +- ...tizer_openbsd.cc => sanitizer_openbsd.cpp} | 13 +- ....cc => sanitizer_persistent_allocator.cpp} | 7 +- .../sanitizer_persistent_allocator.h | 5 +- .../sanitizer_placement_new.h | 5 +- .../sanitizer_common/sanitizer_platform.h | 26 +- .../sanitizer_platform_interceptors.h | 69 +- .../sanitizer_platform_limits_freebsd.cpp | 525 ++++ .../sanitizer_platform_limits_freebsd.h | 656 +++++ ...cc => sanitizer_platform_limits_linux.cpp} | 16 +- ...c => sanitizer_platform_limits_netbsd.cpp} | 422 ++- .../sanitizer_platform_limits_netbsd.h | 229 +- ... => sanitizer_platform_limits_openbsd.cpp} | 7 +- .../sanitizer_platform_limits_openbsd.h | 5 +- ...cc => sanitizer_platform_limits_posix.cpp} | 90 +- .../sanitizer_platform_limits_posix.h | 144 +- ... => sanitizer_platform_limits_solaris.cpp} | 7 +- .../sanitizer_platform_limits_solaris.h | 7 +- ...sanitizer_posix.cc => sanitizer_posix.cpp} | 133 +- .../sanitizer_common/sanitizer_posix.h | 28 +- ...libcdep.cc => sanitizer_posix_libcdep.cpp} | 89 +- ...nitizer_printf.cc => sanitizer_printf.cpp} | 7 +- .../sanitizer_common/sanitizer_procmaps.h | 6 +- ...maps_bsd.cc => sanitizer_procmaps_bsd.cpp} | 8 +- ...ommon.cc => sanitizer_procmaps_common.cpp} | 13 +- ..._linux.cc => sanitizer_procmaps_linux.cpp} | 8 +- ...maps_mac.cc => sanitizer_procmaps_mac.cpp} | 11 +- ...aris.cc => sanitizer_procmaps_solaris.cpp} | 22 +- .../sanitizer_common/sanitizer_quarantine.h | 5 +- .../sanitizer_report_decorator.h | 5 +- .../sanitizer_common/sanitizer_ring_buffer.h | 7 +- ...sanitizer_rtems.cc => sanitizer_rtems.cpp} | 15 +- .../sanitizer_common/sanitizer_rtems.h | 5 +- .../sanitizer_signal_interceptors.inc | 5 +- ...tizer_solaris.cc => sanitizer_solaris.cpp} | 16 +- ...stackdepot.cc => sanitizer_stackdepot.cpp} | 30 +- .../sanitizer_common/sanitizer_stackdepot.h | 7 +- .../sanitizer_stackdepotbase.h | 5 +- ...stacktrace.cc => sanitizer_stacktrace.cpp} | 32 +- .../sanitizer_common/sanitizer_stacktrace.h | 61 +- ...ep.cc => sanitizer_stacktrace_libcdep.cpp} | 15 +- ...er.cc => sanitizer_stacktrace_printer.cpp} | 11 +- .../sanitizer_stacktrace_printer.h | 5 +- ...parc.cc => sanitizer_stacktrace_sparc.cpp} | 27 +- .../sanitizer_common/sanitizer_stoptheworld.h | 5 +- ... sanitizer_stoptheworld_linux_libcdep.cpp} | 7 +- ..._mac.cc => sanitizer_stoptheworld_mac.cpp} | 7 +- .../sanitizer_stoptheworld_netbsd_libcdep.cpp | 356 +++ ...ressions.cc => sanitizer_suppressions.cpp} | 38 +- .../sanitizer_common/sanitizer_suppressions.h | 5 +- ...symbolizer.cc => sanitizer_symbolizer.cpp} | 17 +- .../sanitizer_common/sanitizer_symbolizer.h | 33 +- .../sanitizer_symbolizer_fuchsia.h | 8 +- .../sanitizer_symbolizer_internal.h | 32 +- ... => sanitizer_symbolizer_libbacktrace.cpp} | 7 +- .../sanitizer_symbolizer_libbacktrace.h | 5 +- ...ep.cc => sanitizer_symbolizer_libcdep.cpp} | 88 +- ...er_mac.cc => sanitizer_symbolizer_mac.cpp} | 12 +- .../sanitizer_symbolizer_mac.h | 5 +- ...kup.cc => sanitizer_symbolizer_markup.cpp} | 15 +- ...=> sanitizer_symbolizer_posix_libcdep.cpp} | 7 +- ...ort.cc => sanitizer_symbolizer_report.cpp} | 13 +- .../sanitizer_symbolizer_rtems.h | 5 +- ...er_win.cc => sanitizer_symbolizer_win.cpp} | 10 +- .../sanitizer_syscall_generic.inc | 5 +- .../sanitizer_syscall_linux_aarch64.inc | 5 +- .../sanitizer_syscall_linux_arm.inc | 5 +- .../sanitizer_syscall_linux_x86_64.inc | 5 +- .../sanitizer_syscalls_netbsd.inc | 43 +- ...rmination.cc => sanitizer_termination.cpp} | 7 +- ...istry.cc => sanitizer_thread_registry.cpp} | 30 +- .../sanitizer_thread_registry.h | 18 +- ...get_addr.cc => sanitizer_tls_get_addr.cpp} | 7 +- .../sanitizer_common/sanitizer_tls_get_addr.h | 7 +- .../sanitizer_type_traits.cpp | 20 + .../sanitizer_common/sanitizer_type_traits.h | 62 + ....cc => sanitizer_unwind_linux_libcdep.cpp} | 19 +- ...unwind_win.cc => sanitizer_unwind_win.cpp} | 14 +- .../sanitizer_common/sanitizer_vector.h | 5 +- .../{sanitizer_win.cc => sanitizer_win.cpp} | 86 +- libsanitizer/sanitizer_common/sanitizer_win.h | 5 +- .../sanitizer_common/sanitizer_win_defs.h | 5 +- ...l_thunk.cc => sanitizer_win_dll_thunk.cpp} | 7 +- .../sanitizer_win_dll_thunk.h | 5 +- ...> sanitizer_win_dynamic_runtime_thunk.cpp} | 13 +- ...cc => sanitizer_win_weak_interception.cpp} | 7 +- .../sanitizer_win_weak_interception.h | 5 +- libsanitizer/tsan/Makefile.am | 67 +- libsanitizer/tsan/Makefile.in | 306 +- .../tsan/{tsan_clock.cc => tsan_clock.cpp} | 9 +- libsanitizer/tsan/tsan_clock.h | 5 +- .../{tsan_debugging.cc => tsan_debugging.cpp} | 57 +- libsanitizer/tsan/tsan_defs.h | 5 +- libsanitizer/tsan/tsan_dense_alloc.h | 5 +- libsanitizer/tsan/tsan_dispatch_defs.h | 66 + .../{tsan_external.cc => tsan_external.cpp} | 7 +- libsanitizer/tsan/{tsan_fd.cc => tsan_fd.cpp} | 7 +- libsanitizer/tsan/tsan_fd.h | 5 +- .../tsan/{tsan_flags.cc => tsan_flags.cpp} | 16 +- libsanitizer/tsan/tsan_flags.h | 8 +- libsanitizer/tsan/tsan_flags.inc | 7 +- .../{tsan_ignoreset.cc => tsan_ignoreset.cpp} | 7 +- libsanitizer/tsan/tsan_ignoreset.h | 5 +- ..._interceptors.cc => tsan_interceptors.cpp} | 203 +- libsanitizer/tsan/tsan_interceptors.h | 12 + ...ptors_mac.cc => tsan_interceptors_mac.cpp} | 104 +- .../{tsan_interface.cc => tsan_interface.cpp} | 33 +- libsanitizer/tsan/tsan_interface.h | 7 +- ...nterface_ann.cc => tsan_interface_ann.cpp} | 7 +- libsanitizer/tsan/tsan_interface_ann.h | 5 +- ...ce_atomic.cc => tsan_interface_atomic.cpp} | 9 +- libsanitizer/tsan/tsan_interface_inl.h | 5 +- ...erface_java.cc => tsan_interface_java.cpp} | 7 +- libsanitizer/tsan/tsan_interface_java.h | 7 +- ...ibdispatch_mac.cc => tsan_libdispatch.cpp} | 198 +- ...tsan_malloc_mac.cc => tsan_malloc_mac.cpp} | 21 +- .../tsan/{tsan_md5.cc => tsan_md5.cpp} | 15 +- .../tsan/{tsan_mman.cc => tsan_mman.cpp} | 17 +- libsanitizer/tsan/tsan_mman.h | 6 +- .../tsan/{tsan_mutex.cc => tsan_mutex.cpp} | 7 +- libsanitizer/tsan/tsan_mutex.h | 5 +- .../{tsan_mutexset.cc => tsan_mutexset.cpp} | 7 +- libsanitizer/tsan/tsan_mutexset.h | 5 +- ...tsan_new_delete.cc => tsan_new_delete.cpp} | 13 +- libsanitizer/tsan/tsan_platform.h | 6 +- ...tform_linux.cc => tsan_platform_linux.cpp} | 117 +- ..._platform_mac.cc => tsan_platform_mac.cpp} | 67 +- ...tform_posix.cc => tsan_platform_posix.cpp} | 16 +- ...m_windows.cc => tsan_platform_windows.cpp} | 7 +- .../{tsan_preinit.cc => tsan_preinit.cpp} | 7 +- .../tsan/{tsan_report.cc => tsan_report.cpp} | 78 +- libsanitizer/tsan/tsan_report.h | 8 +- .../tsan/{tsan_rtl.cc => tsan_rtl.cpp} | 47 +- libsanitizer/tsan/tsan_rtl.h | 52 +- libsanitizer/tsan/tsan_rtl_aarch64.S | 196 +- libsanitizer/tsan/tsan_rtl_amd64.S | 48 +- .../{tsan_rtl_mutex.cc => tsan_rtl_mutex.cpp} | 7 +- libsanitizer/tsan/tsan_rtl_ppc64.S | 1 - .../{tsan_rtl_proc.cc => tsan_rtl_proc.cpp} | 7 +- ...tsan_rtl_report.cc => tsan_rtl_report.cpp} | 15 +- ...tsan_rtl_thread.cc => tsan_rtl_thread.cpp} | 57 +- ...an_stack_trace.cc => tsan_stack_trace.cpp} | 20 +- libsanitizer/tsan/tsan_stack_trace.h | 5 +- .../tsan/{tsan_stat.cc => tsan_stat.cpp} | 7 +- libsanitizer/tsan/tsan_stat.h | 5 +- ..._suppressions.cc => tsan_suppressions.cpp} | 63 +- libsanitizer/tsan/tsan_suppressions.h | 5 +- .../{tsan_symbolize.cc => tsan_symbolize.cpp} | 7 +- libsanitizer/tsan/tsan_symbolize.h | 5 +- .../tsan/{tsan_sync.cc => tsan_sync.cpp} | 7 +- libsanitizer/tsan/tsan_sync.h | 5 +- libsanitizer/tsan/tsan_trace.h | 5 +- .../tsan/tsan_update_shadow_word_inl.h | 29 +- libsanitizer/ubsan/Makefile.am | 20 +- libsanitizer/ubsan/Makefile.in | 123 +- libsanitizer/ubsan/ubsan_checks.inc | 12 +- .../ubsan/{ubsan_diag.cc => ubsan_diag.cpp} | 25 +- libsanitizer/ubsan/ubsan_diag.h | 8 +- libsanitizer/ubsan/ubsan_diag_standalone.cc | 36 - libsanitizer/ubsan/ubsan_diag_standalone.cpp | 40 + .../ubsan/{ubsan_flags.cc => ubsan_flags.cpp} | 9 +- libsanitizer/ubsan/ubsan_flags.h | 5 +- libsanitizer/ubsan/ubsan_flags.inc | 9 +- .../{ubsan_handlers.cc => ubsan_handlers.cpp} | 124 +- libsanitizer/ubsan/ubsan_handlers.h | 35 +- ...handlers_cxx.cc => ubsan_handlers_cxx.cpp} | 51 +- libsanitizer/ubsan/ubsan_handlers_cxx.h | 21 +- .../ubsan/{ubsan_init.cc => ubsan_init.cpp} | 7 +- libsanitizer/ubsan/ubsan_init.h | 5 +- ...tandalone.cc => ubsan_init_standalone.cpp} | 7 +- ...t.cc => ubsan_init_standalone_preinit.cpp} | 7 +- libsanitizer/ubsan/ubsan_interface.inc | 11 +- .../{ubsan_monitor.cc => ubsan_monitor.cpp} | 7 +- libsanitizer/ubsan/ubsan_monitor.h | 5 +- libsanitizer/ubsan/ubsan_platform.h | 7 +- ...dalone.cc => ubsan_signals_standalone.cpp} | 16 +- libsanitizer/ubsan/ubsan_signals_standalone.h | 7 +- ...ubsan_type_hash.cc => ubsan_type_hash.cpp} | 9 +- libsanitizer/ubsan/ubsan_type_hash.h | 9 +- ...itanium.cc => ubsan_type_hash_itanium.cpp} | 20 +- ...pe_hash_win.cc => ubsan_type_hash_win.cpp} | 11 +- .../ubsan/{ubsan_value.cc => ubsan_value.cpp} | 7 +- libsanitizer/ubsan/ubsan_value.h | 5 +- ...n_dll_thunk.cc => ubsan_win_dll_thunk.cpp} | 7 +- ...cc => ubsan_win_dynamic_runtime_thunk.cpp} | 7 +- ...ion.cc => ubsan_win_weak_interception.cpp} | 7 +- 399 files changed, 11985 insertions(+), 4516 deletions(-) rename libsanitizer/asan/{asan_activation.cc => asan_activation.cpp} (94%) rename libsanitizer/asan/{asan_allocator.cc => asan_allocator.cpp} (98%) rename libsanitizer/asan/{asan_debugging.cc => asan_debugging.cpp} (94%) rename libsanitizer/asan/{asan_descriptions.cc => asan_descriptions.cpp} (98%) rename libsanitizer/asan/{asan_errors.cc => asan_errors.cpp} (96%) rename libsanitizer/asan/{asan_fake_stack.cc => asan_fake_stack.cpp} (97%) rename libsanitizer/asan/{asan_flags.cc => asan_flags.cpp} (94%) rename libsanitizer/asan/{asan_fuchsia.cc => asan_fuchsia.cpp} (92%) rename libsanitizer/asan/{asan_globals.cc => asan_globals.cpp} (90%) rename libsanitizer/asan/{asan_globals_win.cc => asan_globals_win.cpp} (87%) rename libsanitizer/asan/{asan_interceptors.cc => asan_interceptors.cpp} (97%) rename libsanitizer/asan/{asan_interceptors_memintrinsics.cc => asan_interceptors_memintrinsics.cpp} (83%) create mode 100644 libsanitizer/asan/asan_interceptors_vfork.S rename libsanitizer/asan/{asan_linux.cc => asan_linux.cpp} (93%) rename libsanitizer/asan/{asan_mac.cc => asan_mac.cpp} (96%) rename libsanitizer/asan/{asan_malloc_linux.cc => asan_malloc_linux.cpp} (94%) rename libsanitizer/asan/{asan_malloc_mac.cc => asan_malloc_mac.cpp} (57%) delete mode 100644 libsanitizer/asan/asan_malloc_win.cc create mode 100644 libsanitizer/asan/asan_malloc_win.cpp rename libsanitizer/asan/{asan_memory_profile.cc => asan_memory_profile.cpp} (93%) rename libsanitizer/asan/{asan_new_delete.cc => asan_new_delete.cpp} (88%) rename libsanitizer/asan/{asan_poisoning.cc => asan_poisoning.cpp} (98%) rename libsanitizer/asan/{asan_posix.cc => asan_posix.cpp} (57%) rename libsanitizer/asan/{asan_preinit.cc => asan_preinit.cpp} (74%) rename libsanitizer/asan/{asan_premap_shadow.cc => asan_premap_shadow.cpp} (90%) rename libsanitizer/asan/{asan_report.cc => asan_report.cpp} (96%) rename libsanitizer/asan/{asan_rtems.cc => asan_rtems.cpp} (93%) rename libsanitizer/asan/{asan_rtl.cc => asan_rtl.cpp} (94%) rename libsanitizer/asan/{asan_shadow_setup.cc => asan_shadow_setup.cpp} (94%) delete mode 100644 libsanitizer/asan/asan_stack.cc create mode 100644 libsanitizer/asan/asan_stack.cpp rename libsanitizer/asan/{asan_stats.cc => asan_stats.cpp} (95%) rename libsanitizer/asan/{asan_suppressions.cc => asan_suppressions.cpp} (92%) rename libsanitizer/asan/{asan_thread.cc => asan_thread.cpp} (95%) rename libsanitizer/asan/{asan_win.cc => asan_win.cpp} (75%) rename libsanitizer/asan/{asan_win_dll_thunk.cc => asan_win_dll_thunk.cpp} (94%) rename libsanitizer/asan/{asan_win_dynamic_runtime_thunk.cc => asan_win_dynamic_runtime_thunk.cpp} (94%) rename libsanitizer/asan/{asan_win_weak_interception.cc => asan_win_weak_interception.cpp} (77%) delete mode 100644 libsanitizer/include/sanitizer/esan_interface.h delete mode 100644 libsanitizer/interception/interception_linux.cc create mode 100644 libsanitizer/interception/interception_linux.cpp rename libsanitizer/interception/{interception_mac.cc => interception_mac.cpp} (58%) rename libsanitizer/interception/{interception_type_test.cc => interception_type_test.cpp} (81%) rename libsanitizer/interception/{interception_win.cc => interception_win.cpp} (98%) rename libsanitizer/lsan/{lsan.cc => lsan.cpp} (74%) rename libsanitizer/lsan/{lsan_allocator.cc => lsan_allocator.cpp} (94%) rename libsanitizer/lsan/{lsan_common.cc => lsan_common.cpp} (99%) rename libsanitizer/lsan/{lsan_common_linux.cc => lsan_common_linux.cpp} (91%) rename libsanitizer/lsan/{lsan_common_mac.cc => lsan_common_mac.cpp} (94%) rename libsanitizer/lsan/{lsan_interceptors.cc => lsan_interceptors.cpp} (96%) rename libsanitizer/lsan/{lsan_linux.cc => lsan_linux.cpp} (60%) rename libsanitizer/lsan/{lsan_mac.cc => lsan_mac.cpp} (96%) rename libsanitizer/lsan/{lsan_malloc_mac.cc => lsan_malloc_mac.cpp} (83%) rename libsanitizer/lsan/{lsan_preinit.cc => lsan_preinit.cpp} (68%) rename libsanitizer/lsan/{lsan_thread.cc => lsan_thread.cpp} (91%) delete mode 100644 libsanitizer/sanitizer_common/sancov_begin.S delete mode 100644 libsanitizer/sanitizer_common/sancov_end.S rename libsanitizer/sanitizer_common/{sancov_flags.cc => sancov_flags.cpp} (81%) rename libsanitizer/sanitizer_common/{sanitizer_allocator.cc => sanitizer_allocator.cpp} (92%) rename libsanitizer/sanitizer_common/{sanitizer_allocator_checks.cc => sanitizer_allocator_checks.cpp} (61%) rename libsanitizer/sanitizer_common/{sanitizer_allocator_report.cc => sanitizer_allocator_report.cpp} (85%) rename libsanitizer/sanitizer_common/{sanitizer_common.cc => sanitizer_common.cpp} (97%) create mode 100644 libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S create mode 100644 libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_arm.inc.S create mode 100644 libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S create mode 100644 libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S rename libsanitizer/sanitizer_common/{sanitizer_common_libcdep.cc => sanitizer_common_libcdep.cpp} (92%) rename libsanitizer/sanitizer_common/{sanitizer_common_nolibc.cc => sanitizer_common_nolibc.cpp} (76%) rename libsanitizer/sanitizer_common/{sanitizer_coverage_fuchsia.cc => sanitizer_coverage_fuchsia.cpp} (95%) rename libsanitizer/sanitizer_common/{sanitizer_coverage_libcdep_new.cc => sanitizer_coverage_libcdep_new.cpp} (96%) rename libsanitizer/sanitizer_common/{sanitizer_coverage_win_dll_thunk.cc => sanitizer_coverage_win_dll_thunk.cpp} (74%) rename libsanitizer/sanitizer_common/{sanitizer_coverage_win_dynamic_runtime_thunk.cc => sanitizer_coverage_win_dynamic_runtime_thunk.cpp} (59%) rename libsanitizer/sanitizer_common/{sanitizer_coverage_win_sections.cc => sanitizer_coverage_win_sections.cpp} (57%) rename libsanitizer/sanitizer_common/{sanitizer_coverage_win_weak_interception.cc => sanitizer_coverage_win_weak_interception.cpp} (77%) rename libsanitizer/sanitizer_common/{sanitizer_deadlock_detector1.cc => sanitizer_deadlock_detector1.cpp} (95%) rename libsanitizer/sanitizer_common/{sanitizer_deadlock_detector2.cc => sanitizer_deadlock_detector2.cpp} (97%) rename libsanitizer/sanitizer_common/{sanitizer_errno.cc => sanitizer_errno.cpp} (76%) rename libsanitizer/sanitizer_common/{sanitizer_file.cc => sanitizer_file.cpp} (94%) rename libsanitizer/sanitizer_common/{sanitizer_flag_parser.cc => sanitizer_flag_parser.cpp} (81%) rename libsanitizer/sanitizer_common/{sanitizer_flags.cc => sanitizer_flags.cpp} (92%) rename libsanitizer/sanitizer_common/{sanitizer_fuchsia.cc => sanitizer_fuchsia.cpp} (93%) create mode 100644 libsanitizer/sanitizer_common/sanitizer_hash.h rename libsanitizer/sanitizer_common/{sanitizer_libc.cc => sanitizer_libc.cpp} (96%) rename libsanitizer/sanitizer_common/{sanitizer_libignore.cc => sanitizer_libignore.cpp} (93%) rename libsanitizer/sanitizer_common/{sanitizer_linux.cc => sanitizer_linux.cpp} (96%) rename libsanitizer/sanitizer_common/{sanitizer_linux_libcdep.cc => sanitizer_linux_libcdep.cpp} (94%) delete mode 100644 libsanitizer/sanitizer_common/sanitizer_linux_mips64.S rename libsanitizer/sanitizer_common/{sanitizer_linux_s390.cc => sanitizer_linux_s390.cpp} (96%) delete mode 100644 libsanitizer/sanitizer_common/sanitizer_linux_x86_64.S create mode 100644 libsanitizer/sanitizer_common/sanitizer_local_address_space_view.h rename libsanitizer/sanitizer_common/{sanitizer_mac.cc => sanitizer_mac.cpp} (92%) rename libsanitizer/sanitizer_common/{sanitizer_mac_libcdep.cc => sanitizer_mac_libcdep.cpp} (72%) rename libsanitizer/sanitizer_common/{sanitizer_netbsd.cc => sanitizer_netbsd.cpp} (90%) rename libsanitizer/sanitizer_common/{sanitizer_openbsd.cc => sanitizer_openbsd.cpp} (88%) rename libsanitizer/sanitizer_common/{sanitizer_persistent_allocator.cc => sanitizer_persistent_allocator.cpp} (61%) create mode 100644 libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.cpp create mode 100644 libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.h rename libsanitizer/sanitizer_common/{sanitizer_platform_limits_linux.cc => sanitizer_platform_limits_linux.cpp} (86%) rename libsanitizer/sanitizer_common/{sanitizer_platform_limits_netbsd.cc => sanitizer_platform_limits_netbsd.cpp} (92%) rename libsanitizer/sanitizer_common/{sanitizer_platform_limits_openbsd.cc => sanitizer_platform_limits_openbsd.cpp} (97%) rename libsanitizer/sanitizer_common/{sanitizer_platform_limits_posix.cc => sanitizer_platform_limits_posix.cpp} (96%) rename libsanitizer/sanitizer_common/{sanitizer_platform_limits_solaris.cc => sanitizer_platform_limits_solaris.cpp} (97%) rename libsanitizer/sanitizer_common/{sanitizer_posix.cc => sanitizer_posix.cpp} (72%) rename libsanitizer/sanitizer_common/{sanitizer_posix_libcdep.cc => sanitizer_posix_libcdep.cpp} (85%) rename libsanitizer/sanitizer_common/{sanitizer_printf.cc => sanitizer_printf.cpp} (97%) rename libsanitizer/sanitizer_common/{sanitizer_procmaps_bsd.cc => sanitizer_procmaps_bsd.cpp} (92%) rename libsanitizer/sanitizer_common/{sanitizer_procmaps_common.cc => sanitizer_procmaps_common.cpp} (93%) rename libsanitizer/sanitizer_common/{sanitizer_procmaps_linux.cc => sanitizer_procmaps_linux.cpp} (89%) rename libsanitizer/sanitizer_common/{sanitizer_procmaps_mac.cc => sanitizer_procmaps_mac.cpp} (97%) rename libsanitizer/sanitizer_common/{sanitizer_procmaps_solaris.cc => sanitizer_procmaps_solaris.cpp} (67%) rename libsanitizer/sanitizer_common/{sanitizer_rtems.cc => sanitizer_rtems.cpp} (95%) rename libsanitizer/sanitizer_common/{sanitizer_solaris.cc => sanitizer_solaris.cpp} (94%) rename libsanitizer/sanitizer_common/{sanitizer_stackdepot.cc => sanitizer_stackdepot.cpp} (87%) rename libsanitizer/sanitizer_common/{sanitizer_stacktrace.cc => sanitizer_stacktrace.cpp} (82%) rename libsanitizer/sanitizer_common/{sanitizer_stacktrace_libcdep.cc => sanitizer_stacktrace_libcdep.cpp} (90%) rename libsanitizer/sanitizer_common/{sanitizer_stacktrace_printer.cc => sanitizer_stacktrace_printer.cpp} (95%) rename libsanitizer/sanitizer_common/{sanitizer_stacktrace_sparc.cc => sanitizer_stacktrace_sparc.cpp} (74%) rename libsanitizer/sanitizer_common/{sanitizer_stoptheworld_linux_libcdep.cc => sanitizer_stoptheworld_linux_libcdep.cpp} (98%) rename libsanitizer/sanitizer_common/{sanitizer_stoptheworld_mac.cc => sanitizer_stoptheworld_mac.cpp} (94%) create mode 100644 libsanitizer/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp rename libsanitizer/sanitizer_common/{sanitizer_suppressions.cc => sanitizer_suppressions.cpp} (84%) rename libsanitizer/sanitizer_common/{sanitizer_symbolizer.cc => sanitizer_symbolizer.cpp} (86%) rename libsanitizer/sanitizer_common/{sanitizer_symbolizer_libbacktrace.cc => sanitizer_symbolizer_libbacktrace.cpp} (95%) rename libsanitizer/sanitizer_common/{sanitizer_symbolizer_libcdep.cc => sanitizer_symbolizer_libcdep.cpp} (85%) rename libsanitizer/sanitizer_common/{sanitizer_symbolizer_mac.cc => sanitizer_symbolizer_mac.cpp} (92%) rename libsanitizer/sanitizer_common/{sanitizer_symbolizer_markup.cc => sanitizer_symbolizer_markup.cpp} (91%) rename libsanitizer/sanitizer_common/{sanitizer_symbolizer_posix_libcdep.cc => sanitizer_symbolizer_posix_libcdep.cpp} (98%) rename libsanitizer/sanitizer_common/{sanitizer_symbolizer_report.cc => sanitizer_symbolizer_report.cpp} (95%) rename libsanitizer/sanitizer_common/{sanitizer_symbolizer_win.cc => sanitizer_symbolizer_win.cpp} (97%) rename libsanitizer/sanitizer_common/{sanitizer_termination.cc => sanitizer_termination.cpp} (90%) rename libsanitizer/sanitizer_common/{sanitizer_thread_registry.cc => sanitizer_thread_registry.cpp} (91%) rename libsanitizer/sanitizer_common/{sanitizer_tls_get_addr.cc => sanitizer_tls_get_addr.cpp} (95%) create mode 100644 libsanitizer/sanitizer_common/sanitizer_type_traits.cpp create mode 100644 libsanitizer/sanitizer_common/sanitizer_type_traits.h rename libsanitizer/sanitizer_common/{sanitizer_unwind_linux_libcdep.cc => sanitizer_unwind_linux_libcdep.cpp} (90%) rename libsanitizer/sanitizer_common/{sanitizer_unwind_win.cc => sanitizer_unwind_win.cpp} (81%) rename libsanitizer/sanitizer_common/{sanitizer_win.cc => sanitizer_win.cpp} (92%) rename libsanitizer/sanitizer_common/{sanitizer_win_dll_thunk.cc => sanitizer_win_dll_thunk.cpp} (92%) rename libsanitizer/sanitizer_common/{sanitizer_win_dynamic_runtime_thunk.cc => sanitizer_win_dynamic_runtime_thunk.cpp} (58%) rename libsanitizer/sanitizer_common/{sanitizer_win_weak_interception.cc => sanitizer_win_weak_interception.cpp} (92%) rename libsanitizer/tsan/{tsan_clock.cc => tsan_clock.cpp} (98%) rename libsanitizer/tsan/{tsan_debugging.cc => tsan_debugging.cpp} (82%) create mode 100644 libsanitizer/tsan/tsan_dispatch_defs.h rename libsanitizer/tsan/{tsan_external.cc => tsan_external.cpp} (93%) rename libsanitizer/tsan/{tsan_fd.cc => tsan_fd.cpp} (97%) rename libsanitizer/tsan/{tsan_flags.cc => tsan_flags.cpp} (86%) rename libsanitizer/tsan/{tsan_ignoreset.cc => tsan_ignoreset.cpp} (75%) rename libsanitizer/tsan/{tsan_interceptors.cc => tsan_interceptors.cpp} (95%) rename libsanitizer/tsan/{tsan_interceptors_mac.cc => tsan_interceptors_mac.cpp} (82%) rename libsanitizer/tsan/{tsan_interface.cc => tsan_interface.cpp} (78%) rename libsanitizer/tsan/{tsan_interface_ann.cc => tsan_interface_ann.cpp} (98%) rename libsanitizer/tsan/{tsan_interface_atomic.cc => tsan_interface_atomic.cpp} (98%) rename libsanitizer/tsan/{tsan_interface_java.cc => tsan_interface_java.cpp} (96%) rename libsanitizer/tsan/{tsan_libdispatch_mac.cc => tsan_libdispatch.cpp} (82%) rename libsanitizer/tsan/{tsan_malloc_mac.cc => tsan_malloc_mac.cpp} (78%) rename libsanitizer/tsan/{tsan_md5.cc => tsan_md5.cpp} (95%) rename libsanitizer/tsan/{tsan_mman.cc => tsan_mman.cpp} (94%) rename libsanitizer/tsan/{tsan_mutex.cc => tsan_mutex.cpp} (96%) rename libsanitizer/tsan/{tsan_mutexset.cc => tsan_mutexset.cpp} (87%) rename libsanitizer/tsan/{tsan_new_delete.cc => tsan_new_delete.cpp} (95%) rename libsanitizer/tsan/{tsan_platform_linux.cc => tsan_platform_linux.cpp} (82%) rename libsanitizer/tsan/{tsan_platform_mac.cc => tsan_platform_mac.cpp} (85%) rename libsanitizer/tsan/{tsan_platform_posix.cc => tsan_platform_posix.cpp} (91%) rename libsanitizer/tsan/{tsan_platform_windows.cc => tsan_platform_windows.cpp} (71%) rename libsanitizer/tsan/{tsan_preinit.cc => tsan_preinit.cpp} (74%) rename libsanitizer/tsan/{tsan_report.cc => tsan_report.cpp} (88%) rename libsanitizer/tsan/{tsan_rtl.cc => tsan_rtl.cpp} (96%) rename libsanitizer/tsan/{tsan_rtl_mutex.cc => tsan_rtl_mutex.cpp} (98%) rename libsanitizer/tsan/{tsan_rtl_proc.cc => tsan_rtl_proc.cpp} (84%) rename libsanitizer/tsan/{tsan_rtl_report.cc => tsan_rtl_report.cpp} (98%) rename libsanitizer/tsan/{tsan_rtl_thread.cc => tsan_rtl_thread.cpp} (86%) rename libsanitizer/tsan/{tsan_stack_trace.cc => tsan_stack_trace.cpp} (64%) rename libsanitizer/tsan/{tsan_stat.cc => tsan_stat.cpp} (97%) rename libsanitizer/tsan/{tsan_suppressions.cc => tsan_suppressions.cpp} (77%) rename libsanitizer/tsan/{tsan_symbolize.cc => tsan_symbolize.cpp} (93%) rename libsanitizer/tsan/{tsan_sync.cc => tsan_sync.cpp} (96%) rename libsanitizer/ubsan/{ubsan_diag.cc => ubsan_diag.cpp} (93%) delete mode 100644 libsanitizer/ubsan/ubsan_diag_standalone.cc create mode 100644 libsanitizer/ubsan/ubsan_diag_standalone.cpp rename libsanitizer/ubsan/{ubsan_flags.cc => ubsan_flags.cpp} (86%) rename libsanitizer/ubsan/{ubsan_handlers.cc => ubsan_handlers.cpp} (90%) rename libsanitizer/ubsan/{ubsan_handlers_cxx.cc => ubsan_handlers_cxx.cpp} (74%) rename libsanitizer/ubsan/{ubsan_init.cc => ubsan_init.cpp} (84%) rename libsanitizer/ubsan/{ubsan_init_standalone.cc => ubsan_init_standalone.cpp} (72%) rename libsanitizer/ubsan/{ubsan_init_standalone_preinit.cc => ubsan_init_standalone_preinit.cpp} (75%) rename libsanitizer/ubsan/{ubsan_monitor.cc => ubsan_monitor.cpp} (90%) rename libsanitizer/ubsan/{ubsan_signals_standalone.cc => ubsan_signals_standalone.cpp} (77%) rename libsanitizer/ubsan/{ubsan_type_hash.cc => ubsan_type_hash.cpp} (76%) rename libsanitizer/ubsan/{ubsan_type_hash_itanium.cc => ubsan_type_hash_itanium.cpp} (92%) rename libsanitizer/ubsan/{ubsan_type_hash_win.cc => ubsan_type_hash_win.cpp} (87%) rename libsanitizer/ubsan/{ubsan_value.cc => ubsan_value.cpp} (92%) rename libsanitizer/ubsan/{ubsan_win_dll_thunk.cc => ubsan_win_dll_thunk.cpp} (74%) rename libsanitizer/ubsan/{ubsan_win_dynamic_runtime_thunk.cc => ubsan_win_dynamic_runtime_thunk.cpp} (72%) rename libsanitizer/ubsan/{ubsan_win_weak_interception.cc => ubsan_win_weak_interception.cpp} (77%) diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog index 52c119ff690..1049000c4a3 100644 --- a/libsanitizer/ChangeLog +++ b/libsanitizer/ChangeLog @@ -1,3 +1,9 @@ +2019-08-14 Martin Liska + + PR sanitizer/89832 + PR sanitizer/91325 + * All source files: Merge from upstream 368656. + 2019-06-26 Rainer Orth * sanitizer_common/sanitizer_posix_libcdep.cc: Cherry-pick diff --git a/libsanitizer/MERGE b/libsanitizer/MERGE index 8f02e230649..bb1b045f488 100644 --- a/libsanitizer/MERGE +++ b/libsanitizer/MERGE @@ -1,4 +1,4 @@ -345033 +368656 The first line of this file holds the svn revision number of the last merge done from the master library sources. diff --git a/libsanitizer/Makefile.in b/libsanitizer/Makefile.in index 0d789b3a59d..8f59d804790 100644 --- a/libsanitizer/Makefile.in +++ b/libsanitizer/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -435,8 +435,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status echo ' $(SHELL) ./config.status'; \ $(SHELL) ./config.status;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $@ $(am__maybe_remake_depfiles);; \ esac; $(top_srcdir)/../multilib.am $(am__empty): diff --git a/libsanitizer/aclocal.m4 b/libsanitizer/aclocal.m4 index dba827747d7..6c7c3d5f941 100644 --- a/libsanitizer/aclocal.m4 +++ b/libsanitizer/aclocal.m4 @@ -1,6 +1,6 @@ -# generated automatically by aclocal 1.15.1 -*- Autoconf -*- +# generated automatically by aclocal 1.16.1 -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -20,7 +20,7 @@ You have another version of autoconf. It may work, but is not guaranteed to. If you have problems, you may need to regenerate the build system entirely. To do so, use the procedure documented by the package, typically 'autoreconf'.])]) -# Copyright (C) 2002-2017 Free Software Foundation, Inc. +# Copyright (C) 2002-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -32,10 +32,10 @@ To do so, use the procedure documented by the package, typically 'autoreconf'.]) # generated from the m4 files accompanying Automake X.Y. # (This private macro should not be called outside this file.) AC_DEFUN([AM_AUTOMAKE_VERSION], -[am__api_version='1.15' +[am__api_version='1.16' dnl Some users find AM_AUTOMAKE_VERSION and mistake it for a way to dnl require some minimum version. Point them to the right macro. -m4_if([$1], [1.15.1], [], +m4_if([$1], [1.16.1], [], [AC_FATAL([Do not call $0, use AM_INIT_AUTOMAKE([$1]).])])dnl ]) @@ -51,14 +51,14 @@ m4_define([_AM_AUTOCONF_VERSION], []) # Call AM_AUTOMAKE_VERSION and AM_AUTOMAKE_VERSION so they can be traced. # This function is AC_REQUIREd by AM_INIT_AUTOMAKE. AC_DEFUN([AM_SET_CURRENT_AUTOMAKE_VERSION], -[AM_AUTOMAKE_VERSION([1.15.1])dnl +[AM_AUTOMAKE_VERSION([1.16.1])dnl m4_ifndef([AC_AUTOCONF_VERSION], [m4_copy([m4_PACKAGE_VERSION], [AC_AUTOCONF_VERSION])])dnl _AM_AUTOCONF_VERSION(m4_defn([AC_AUTOCONF_VERSION]))]) # Figure out how to run the assembler. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -78,7 +78,7 @@ _AM_IF_OPTION([no-dependencies],, [_AM_DEPENDENCIES([CCAS])])dnl # AM_AUX_DIR_EXPAND -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -130,7 +130,7 @@ am_aux_dir=`cd "$ac_aux_dir" && pwd` # AM_CONDITIONAL -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -161,7 +161,7 @@ AC_CONFIG_COMMANDS_PRE( Usually this means the macro was only invoked conditionally.]]) fi])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -352,13 +352,12 @@ _AM_SUBST_NOTMAKE([am__nodep])dnl # Generate code to set up dependency tracking. -*- Autoconf -*- -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, # with or without modifications, as long as this notice is preserved. - # _AM_OUTPUT_DEPENDENCY_COMMANDS # ------------------------------ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], @@ -366,49 +365,41 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + AS_CASE([$CONFIG_FILES], + [*\'*], [eval set x "$CONFIG_FILES"], + [*], [set x $CONFIG_FILES]) shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`AS_ECHO(["$am_mf"]) | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`AS_DIRNAME("$mf")` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`AS_DIRNAME(["$file"])` - AS_MKDIR_P([$dirpart/$fdir]) - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`AS_DIRNAME(["$am_mf"])` + am_filepart=`AS_BASENAME(["$am_mf"])` + AM_RUN_LOG([cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles]) || am_rc=$? done + if test $am_rc -ne 0; then + AC_MSG_FAILURE([Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. Try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking).]) + fi + AS_UNSET([am_dirpart]) + AS_UNSET([am_filepart]) + AS_UNSET([am_mf]) + AS_UNSET([am_rc]) + rm -f conftest-deps.mk } ])# _AM_OUTPUT_DEPENDENCY_COMMANDS @@ -417,18 +408,17 @@ AC_DEFUN([_AM_OUTPUT_DEPENDENCY_COMMANDS], # ----------------------------- # This macro should only be invoked once -- use via AC_REQUIRE. # -# This code is only required when automatic dependency tracking -# is enabled. FIXME. This creates each '.P' file that we will -# need in order to bootstrap the dependency handling code. +# This code is only required when automatic dependency tracking is enabled. +# This creates each '.Po' and '.Plo' makefile fragment that we'll need in +# order to bootstrap the dependency handling code. AC_DEFUN([AM_OUTPUT_DEPENDENCY_COMMANDS], [AC_CONFIG_COMMANDS([depfiles], [test x"$AMDEP_TRUE" != x"" || _AM_OUTPUT_DEPENDENCY_COMMANDS], - [AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"]) -]) + [AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}"])]) # Do all the work for Automake. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -515,8 +505,8 @@ AC_REQUIRE([AM_PROG_INSTALL_STRIP])dnl AC_REQUIRE([AC_PROG_MKDIR_P])dnl # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# -# +# +# AC_SUBST([mkdir_p], ['$(MKDIR_P)']) # We need awk for the "check" target (and possibly the TAP driver). The # system "awk" is bad on some platforms. @@ -583,7 +573,7 @@ END Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . +that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -625,7 +615,7 @@ for _am_header in $config_headers :; do done echo "timestamp for $_am_arg" >`AS_DIRNAME(["$_am_arg"])`/stamp-h[]$_am_stamp_count]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -649,7 +639,7 @@ AC_SUBST([install_sh])]) # Add --enable-maintainer-mode option to configure. -*- Autoconf -*- # From Jim Meyering -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -684,7 +674,7 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) # Check to see how 'make' treats includes. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -692,49 +682,42 @@ AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles]) # AM_MAKE_INCLUDE() # ----------------- -# Check to see how make treats includes. +# Check whether make has an 'include' directive that can support all +# the idioms we need for our automatic dependency tracking code. AC_DEFUN([AM_MAKE_INCLUDE], -[am_make=${MAKE-make} -cat > confinc << 'END' +[AC_MSG_CHECKING([whether ${MAKE-make} supports the include directive]) +cat > confinc.mk << 'END' am__doit: - @echo this is the am__doit target + @echo this is the am__doit target >confinc.out .PHONY: am__doit END -# If we don't find an include directive, just comment out the code. -AC_MSG_CHECKING([for style of include used by $am_make]) am__include="#" am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD - ;; - esac -fi -AC_SUBST([am__include]) -AC_SUBST([am__quote]) -AC_MSG_RESULT([$_am_result]) -rm -f confinc confmf -]) +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + AM_RUN_LOG([${MAKE-make} -f confmf.$s && cat confinc.out]) + AS_CASE([$?:`cat confinc.out 2>/dev/null`], + ['0:this is the am__doit target'], + [AS_CASE([$s], + [BSD], [am__include='.include' am__quote='"'], + [am__include='include' am__quote=''])]) + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +AC_MSG_RESULT([${_am_result}]) +AC_SUBST([am__include])]) +AC_SUBST([am__quote])]) # Fake the existence of programs that GNU maintainers use. -*- Autoconf -*- -# Copyright (C) 1997-2017 Free Software Foundation, Inc. +# Copyright (C) 1997-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -773,7 +756,7 @@ fi # Helper functions for option handling. -*- Autoconf -*- -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -802,7 +785,7 @@ AC_DEFUN([_AM_SET_OPTIONS], AC_DEFUN([_AM_IF_OPTION], [m4_ifset(_AM_MANGLE_OPTION([$1]), [$2], [$3])]) -# Copyright (C) 1999-2017 Free Software Foundation, Inc. +# Copyright (C) 1999-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -849,7 +832,7 @@ AC_LANG_POP([C])]) # For backward compatibility. AC_DEFUN_ONCE([AM_PROG_CC_C_O], [AC_REQUIRE([AC_PROG_CC])]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -868,7 +851,7 @@ AC_DEFUN([AM_RUN_LOG], # Check to make sure that the build environment is sane. -*- Autoconf -*- -# Copyright (C) 1996-2017 Free Software Foundation, Inc. +# Copyright (C) 1996-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -949,7 +932,7 @@ AC_CONFIG_COMMANDS_PRE( rm -f conftest.file ]) -# Copyright (C) 2009-2017 Free Software Foundation, Inc. +# Copyright (C) 2009-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1009,7 +992,7 @@ AC_SUBST([AM_BACKSLASH])dnl _AM_SUBST_NOTMAKE([AM_BACKSLASH])dnl ]) -# Copyright (C) 2001-2017 Free Software Foundation, Inc. +# Copyright (C) 2001-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1037,7 +1020,7 @@ fi INSTALL_STRIP_PROGRAM="\$(install_sh) -c -s" AC_SUBST([INSTALL_STRIP_PROGRAM])]) -# Copyright (C) 2006-2017 Free Software Foundation, Inc. +# Copyright (C) 2006-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -1056,7 +1039,7 @@ AC_DEFUN([AM_SUBST_NOTMAKE], [_AM_SUBST_NOTMAKE($@)]) # Check how to create a tarball. -*- Autoconf -*- -# Copyright (C) 2004-2017 Free Software Foundation, Inc. +# Copyright (C) 2004-2018 Free Software Foundation, Inc. # # This file is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, diff --git a/libsanitizer/asan/Makefile.am b/libsanitizer/asan/Makefile.am index b18ab2a9211..7bba555b171 100644 --- a/libsanitizer/asan/Makefile.am +++ b/libsanitizer/asan/Makefile.am @@ -17,37 +17,38 @@ toolexeclib_LTLIBRARIES = libasan.la nodist_toolexeclib_HEADERS = libasan_preinit.o asan_files = \ - asan_activation.cc \ - asan_allocator.cc \ - asan_debugging.cc \ - asan_descriptions.cc \ - asan_errors.cc \ - asan_fake_stack.cc \ - asan_flags.cc \ - asan_globals.cc \ - asan_interceptors.cc \ - asan_interceptors_memintrinsics.cc \ - asan_linux.cc \ - asan_mac.cc \ - asan_malloc_linux.cc \ - asan_malloc_mac.cc \ - asan_malloc_win.cc \ - asan_memory_profile.cc \ - asan_new_delete.cc \ - asan_poisoning.cc \ - asan_posix.cc \ - asan_premap_shadow.cc \ - asan_report.cc \ - asan_rtems.cc \ - asan_rtl.cc \ - asan_shadow_setup.cc \ - asan_stack.cc \ - asan_stats.cc \ - asan_suppressions.cc \ - asan_thread.cc \ - asan_win.cc \ - asan_win_dll_thunk.cc \ - asan_win_dynamic_runtime_thunk.cc + asan_activation.cpp \ + asan_allocator.cpp \ + asan_debugging.cpp \ + asan_descriptions.cpp \ + asan_errors.cpp \ + asan_fake_stack.cpp \ + asan_flags.cpp \ + asan_globals.cpp \ + asan_interceptors.cpp \ + asan_interceptors_memintrinsics.cpp \ + asan_linux.cpp \ + asan_mac.cpp \ + asan_malloc_linux.cpp \ + asan_malloc_mac.cpp \ + asan_malloc_win.cpp \ + asan_memory_profile.cpp \ + asan_new_delete.cpp \ + asan_poisoning.cpp \ + asan_posix.cpp \ + asan_premap_shadow.cpp \ + asan_report.cpp \ + asan_rtems.cpp \ + asan_rtl.cpp \ + asan_shadow_setup.cpp \ + asan_stack.cpp \ + asan_stats.cpp \ + asan_suppressions.cpp \ + asan_thread.cpp \ + asan_win.cpp \ + asan_win_dll_thunk.cpp \ + asan_win_dynamic_runtime_thunk.cpp \ + asan_interceptors_vfork.S libasan_la_SOURCES = $(asan_files) libasan_la_LIBADD = $(top_builddir)/sanitizer_common/libsanitizer_common.la $(top_builddir)/lsan/libsanitizer_lsan.la diff --git a/libsanitizer/asan/Makefile.in b/libsanitizer/asan/Makefile.in index 41bace42383..40041575394 100644 --- a/libsanitizer/asan/Makefile.in +++ b/libsanitizer/asan/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -158,7 +158,8 @@ am__objects_1 = asan_activation.lo asan_allocator.lo asan_debugging.lo \ asan_posix.lo asan_premap_shadow.lo asan_report.lo \ asan_rtems.lo asan_rtl.lo asan_shadow_setup.lo asan_stack.lo \ asan_stats.lo asan_suppressions.lo asan_thread.lo asan_win.lo \ - asan_win_dll_thunk.lo asan_win_dynamic_runtime_thunk.lo + asan_win_dll_thunk.lo asan_win_dynamic_runtime_thunk.lo \ + asan_interceptors_vfork.lo am_libasan_la_OBJECTS = $(am__objects_1) libasan_la_OBJECTS = $(am_libasan_la_OBJECTS) AM_V_lt = $(am__v_lt_@AM_V@) @@ -182,8 +183,38 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/../depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/asan_activation.Plo \ + ./$(DEPDIR)/asan_allocator.Plo ./$(DEPDIR)/asan_debugging.Plo \ + ./$(DEPDIR)/asan_descriptions.Plo ./$(DEPDIR)/asan_errors.Plo \ + ./$(DEPDIR)/asan_fake_stack.Plo ./$(DEPDIR)/asan_flags.Plo \ + ./$(DEPDIR)/asan_globals.Plo ./$(DEPDIR)/asan_interceptors.Plo \ + ./$(DEPDIR)/asan_interceptors_memintrinsics.Plo \ + ./$(DEPDIR)/asan_interceptors_vfork.Plo \ + ./$(DEPDIR)/asan_linux.Plo ./$(DEPDIR)/asan_mac.Plo \ + ./$(DEPDIR)/asan_malloc_linux.Plo \ + ./$(DEPDIR)/asan_malloc_mac.Plo \ + ./$(DEPDIR)/asan_malloc_win.Plo \ + ./$(DEPDIR)/asan_memory_profile.Plo \ + ./$(DEPDIR)/asan_new_delete.Plo ./$(DEPDIR)/asan_poisoning.Plo \ + ./$(DEPDIR)/asan_posix.Plo ./$(DEPDIR)/asan_premap_shadow.Plo \ + ./$(DEPDIR)/asan_report.Plo ./$(DEPDIR)/asan_rtems.Plo \ + ./$(DEPDIR)/asan_rtl.Plo ./$(DEPDIR)/asan_shadow_setup.Plo \ + ./$(DEPDIR)/asan_stack.Plo ./$(DEPDIR)/asan_stats.Plo \ + ./$(DEPDIR)/asan_suppressions.Plo ./$(DEPDIR)/asan_thread.Plo \ + ./$(DEPDIR)/asan_win.Plo ./$(DEPDIR)/asan_win_dll_thunk.Plo \ + ./$(DEPDIR)/asan_win_dynamic_runtime_thunk.Plo am__mv = mv -f +CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ + $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) +LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CCASFLAGS) $(CCASFLAGS) +AM_V_CPPAS = $(am__v_CPPAS_@AM_V@) +am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@) +am__v_CPPAS_0 = @echo " CPPAS " $@; +am__v_CPPAS_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ @@ -202,6 +233,24 @@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = +COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ + $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) +LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ + $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ + $(AM_CFLAGS) $(CFLAGS) +AM_V_CC = $(am__v_CC_@AM_V@) +am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) +am__v_CC_0 = @echo " CC " $@; +am__v_CC_1 = +CCLD = $(CC) +LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ + $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ + $(AM_LDFLAGS) $(LDFLAGS) -o $@ +AM_V_CCLD = $(am__v_CCLD_@AM_V@) +am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) +am__v_CCLD_0 = @echo " CCLD " $@; +am__v_CCLD_1 = SOURCES = $(libasan_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ @@ -256,8 +305,8 @@ CYGPATH_W = @CYGPATH_W@ DEFS = -D_GNU_SOURCE -D_DEBUG -D__STDC_CONSTANT_MACROS \ -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS \ -DASAN_HAS_EXCEPTIONS=1 -DASAN_NEEDS_SEGV=1 \ - -DCAN_SANITIZE_UB=0 \ - -DASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION=0 $(am__append_1) + -DCAN_SANITIZE_UB=0 -DASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION=0 \ + $(am__append_1) DEPDIR = @DEPDIR@ DSYMUTIL = @DSYMUTIL@ DUMPBIN = @DUMPBIN@ @@ -394,37 +443,38 @@ ACLOCAL_AMFLAGS = -I $(top_srcdir) -I $(top_srcdir)/config toolexeclib_LTLIBRARIES = libasan.la nodist_toolexeclib_HEADERS = libasan_preinit.o asan_files = \ - asan_activation.cc \ - asan_allocator.cc \ - asan_debugging.cc \ - asan_descriptions.cc \ - asan_errors.cc \ - asan_fake_stack.cc \ - asan_flags.cc \ - asan_globals.cc \ - asan_interceptors.cc \ - asan_interceptors_memintrinsics.cc \ - asan_linux.cc \ - asan_mac.cc \ - asan_malloc_linux.cc \ - asan_malloc_mac.cc \ - asan_malloc_win.cc \ - asan_memory_profile.cc \ - asan_new_delete.cc \ - asan_poisoning.cc \ - asan_posix.cc \ - asan_premap_shadow.cc \ - asan_report.cc \ - asan_rtems.cc \ - asan_rtl.cc \ - asan_shadow_setup.cc \ - asan_stack.cc \ - asan_stats.cc \ - asan_suppressions.cc \ - asan_thread.cc \ - asan_win.cc \ - asan_win_dll_thunk.cc \ - asan_win_dynamic_runtime_thunk.cc + asan_activation.cpp \ + asan_allocator.cpp \ + asan_debugging.cpp \ + asan_descriptions.cpp \ + asan_errors.cpp \ + asan_fake_stack.cpp \ + asan_flags.cpp \ + asan_globals.cpp \ + asan_interceptors.cpp \ + asan_interceptors_memintrinsics.cpp \ + asan_linux.cpp \ + asan_mac.cpp \ + asan_malloc_linux.cpp \ + asan_malloc_mac.cpp \ + asan_malloc_win.cpp \ + asan_memory_profile.cpp \ + asan_new_delete.cpp \ + asan_poisoning.cpp \ + asan_posix.cpp \ + asan_premap_shadow.cpp \ + asan_report.cpp \ + asan_rtems.cpp \ + asan_rtl.cpp \ + asan_shadow_setup.cpp \ + asan_stack.cpp \ + asan_stats.cpp \ + asan_suppressions.cpp \ + asan_thread.cpp \ + asan_win.cpp \ + asan_win_dll_thunk.cpp \ + asan_win_dynamic_runtime_thunk.cpp \ + asan_interceptors_vfork.S libasan_la_SOURCES = $(asan_files) libasan_la_LIBADD = \ @@ -475,7 +525,7 @@ MAKEOVERRIDES = all: all-am .SUFFIXES: -.SUFFIXES: .cc .lo .o .obj +.SUFFIXES: .S .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -493,8 +543,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -550,53 +600,81 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_activation.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_allocator.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_debugging.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_descriptions.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_errors.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_fake_stack.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_flags.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_globals.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_interceptors.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_interceptors_memintrinsics.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_linux.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_mac.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_malloc_linux.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_malloc_mac.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_malloc_win.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_memory_profile.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_new_delete.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_poisoning.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_posix.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_premap_shadow.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_report.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_rtems.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_rtl.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_shadow_setup.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_stack.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_stats.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_suppressions.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_thread.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_win.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_win_dll_thunk.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_win_dynamic_runtime_thunk.Plo@am__quote@ - -.cc.o: +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_activation.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_allocator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_debugging.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_descriptions.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_errors.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_fake_stack.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_flags.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_globals.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_interceptors.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_interceptors_memintrinsics.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_interceptors_vfork.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_linux.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_mac.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_malloc_linux.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_malloc_mac.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_malloc_win.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_memory_profile.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_new_delete.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_poisoning.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_posix.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_premap_shadow.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_report.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_rtems.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_rtl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_shadow_setup.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_stack.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_stats.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_suppressions.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_thread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_win.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_win_dll_thunk.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/asan_win_dynamic_runtime_thunk.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.S.o: +@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ $< + +.S.obj: +@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` +@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` + +.S.lo: +@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< +@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ +@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ +@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(LTCPPASCOMPILE) -c -o $@ $< + +.cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< -.cc.obj: +.cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` -.cc.lo: +.cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @@ -724,7 +802,38 @@ clean-am: clean-generic clean-libtool clean-toolexeclibLTLIBRARIES \ mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/asan_activation.Plo + -rm -f ./$(DEPDIR)/asan_allocator.Plo + -rm -f ./$(DEPDIR)/asan_debugging.Plo + -rm -f ./$(DEPDIR)/asan_descriptions.Plo + -rm -f ./$(DEPDIR)/asan_errors.Plo + -rm -f ./$(DEPDIR)/asan_fake_stack.Plo + -rm -f ./$(DEPDIR)/asan_flags.Plo + -rm -f ./$(DEPDIR)/asan_globals.Plo + -rm -f ./$(DEPDIR)/asan_interceptors.Plo + -rm -f ./$(DEPDIR)/asan_interceptors_memintrinsics.Plo + -rm -f ./$(DEPDIR)/asan_interceptors_vfork.Plo + -rm -f ./$(DEPDIR)/asan_linux.Plo + -rm -f ./$(DEPDIR)/asan_mac.Plo + -rm -f ./$(DEPDIR)/asan_malloc_linux.Plo + -rm -f ./$(DEPDIR)/asan_malloc_mac.Plo + -rm -f ./$(DEPDIR)/asan_malloc_win.Plo + -rm -f ./$(DEPDIR)/asan_memory_profile.Plo + -rm -f ./$(DEPDIR)/asan_new_delete.Plo + -rm -f ./$(DEPDIR)/asan_poisoning.Plo + -rm -f ./$(DEPDIR)/asan_posix.Plo + -rm -f ./$(DEPDIR)/asan_premap_shadow.Plo + -rm -f ./$(DEPDIR)/asan_report.Plo + -rm -f ./$(DEPDIR)/asan_rtems.Plo + -rm -f ./$(DEPDIR)/asan_rtl.Plo + -rm -f ./$(DEPDIR)/asan_shadow_setup.Plo + -rm -f ./$(DEPDIR)/asan_stack.Plo + -rm -f ./$(DEPDIR)/asan_stats.Plo + -rm -f ./$(DEPDIR)/asan_suppressions.Plo + -rm -f ./$(DEPDIR)/asan_thread.Plo + -rm -f ./$(DEPDIR)/asan_win.Plo + -rm -f ./$(DEPDIR)/asan_win_dll_thunk.Plo + -rm -f ./$(DEPDIR)/asan_win_dynamic_runtime_thunk.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -771,7 +880,38 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/asan_activation.Plo + -rm -f ./$(DEPDIR)/asan_allocator.Plo + -rm -f ./$(DEPDIR)/asan_debugging.Plo + -rm -f ./$(DEPDIR)/asan_descriptions.Plo + -rm -f ./$(DEPDIR)/asan_errors.Plo + -rm -f ./$(DEPDIR)/asan_fake_stack.Plo + -rm -f ./$(DEPDIR)/asan_flags.Plo + -rm -f ./$(DEPDIR)/asan_globals.Plo + -rm -f ./$(DEPDIR)/asan_interceptors.Plo + -rm -f ./$(DEPDIR)/asan_interceptors_memintrinsics.Plo + -rm -f ./$(DEPDIR)/asan_interceptors_vfork.Plo + -rm -f ./$(DEPDIR)/asan_linux.Plo + -rm -f ./$(DEPDIR)/asan_mac.Plo + -rm -f ./$(DEPDIR)/asan_malloc_linux.Plo + -rm -f ./$(DEPDIR)/asan_malloc_mac.Plo + -rm -f ./$(DEPDIR)/asan_malloc_win.Plo + -rm -f ./$(DEPDIR)/asan_memory_profile.Plo + -rm -f ./$(DEPDIR)/asan_new_delete.Plo + -rm -f ./$(DEPDIR)/asan_poisoning.Plo + -rm -f ./$(DEPDIR)/asan_posix.Plo + -rm -f ./$(DEPDIR)/asan_premap_shadow.Plo + -rm -f ./$(DEPDIR)/asan_report.Plo + -rm -f ./$(DEPDIR)/asan_rtems.Plo + -rm -f ./$(DEPDIR)/asan_rtl.Plo + -rm -f ./$(DEPDIR)/asan_shadow_setup.Plo + -rm -f ./$(DEPDIR)/asan_stack.Plo + -rm -f ./$(DEPDIR)/asan_stats.Plo + -rm -f ./$(DEPDIR)/asan_suppressions.Plo + -rm -f ./$(DEPDIR)/asan_thread.Plo + -rm -f ./$(DEPDIR)/asan_win.Plo + -rm -f ./$(DEPDIR)/asan_win_dll_thunk.Plo + -rm -f ./$(DEPDIR)/asan_win_dynamic_runtime_thunk.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -793,20 +933,21 @@ uninstall-am: uninstall-nodist_toolexeclibHEADERS \ .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-toolexeclibLTLIBRARIES cscopelist-am ctags \ - ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags dvi dvi-am html html-am info \ - info-am install install-am install-data install-data-am \ - install-dvi install-dvi-am install-exec install-exec-am \ - install-html install-html-am install-info install-info-am \ - install-man install-nodist_toolexeclibHEADERS install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - install-toolexeclibLTLIBRARIES installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am uninstall-nodist_toolexeclibHEADERS \ +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-toolexeclibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags dvi dvi-am \ + html html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-nodist_toolexeclibHEADERS \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip install-toolexeclibLTLIBRARIES installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am \ + uninstall-nodist_toolexeclibHEADERS \ uninstall-toolexeclibLTLIBRARIES .PRECIOUS: Makefile diff --git a/libsanitizer/asan/asan_activation.cc b/libsanitizer/asan/asan_activation.cpp similarity index 94% rename from libsanitizer/asan/asan_activation.cc rename to libsanitizer/asan/asan_activation.cpp index 6f69f700c06..795df95a541 100644 --- a/libsanitizer/asan/asan_activation.cc +++ b/libsanitizer/asan/asan_activation.cpp @@ -1,7 +1,8 @@ -//===-- asan_activation.cc --------------------------------------*- C++ -*-===// +//===-- asan_activation.cpp -------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_activation.h b/libsanitizer/asan/asan_activation.h index 162a5ebcea9..93c290c2ae2 100644 --- a/libsanitizer/asan/asan_activation.h +++ b/libsanitizer/asan/asan_activation.h @@ -1,7 +1,8 @@ //===-- asan_activation.h ---------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_activation_flags.inc b/libsanitizer/asan/asan_activation_flags.inc index e71abb96e5b..e0fdffc82ac 100644 --- a/libsanitizer/asan/asan_activation_flags.inc +++ b/libsanitizer/asan/asan_activation_flags.inc @@ -1,7 +1,8 @@ //===-- asan_activation_flags.inc -------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_allocator.cc b/libsanitizer/asan/asan_allocator.cpp similarity index 98% rename from libsanitizer/asan/asan_allocator.cc rename to libsanitizer/asan/asan_allocator.cpp index c2b31a543e7..b58116e17b7 100644 --- a/libsanitizer/asan/asan_allocator.cc +++ b/libsanitizer/asan/asan_allocator.cpp @@ -1,7 +1,8 @@ -//===-- asan_allocator.cc -------------------------------------------------===// +//===-- asan_allocator.cpp ------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -878,6 +879,17 @@ void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack) { return SetErrnoOnNull(instance.Calloc(nmemb, size, stack)); } +void *asan_reallocarray(void *p, uptr nmemb, uptr size, + BufferedStackTrace *stack) { + if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) { + errno = errno_ENOMEM; + if (AllocatorMayReturnNull()) + return nullptr; + ReportReallocArrayOverflow(nmemb, size, stack); + } + return asan_realloc(p, nmemb * size, stack); +} + void *asan_realloc(void *p, uptr size, BufferedStackTrace *stack) { if (!p) return SetErrnoOnNull(instance.Allocate(size, 8, stack, FROM_MALLOC, true)); diff --git a/libsanitizer/asan/asan_allocator.h b/libsanitizer/asan/asan_allocator.h index 1f58bb16859..b37d8ef4e8d 100644 --- a/libsanitizer/asan/asan_allocator.h +++ b/libsanitizer/asan/asan_allocator.h @@ -1,13 +1,14 @@ //===-- asan_allocator.h ----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 AddressSanitizer, an address sanity checker. // -// ASan-private header for asan_allocator.cc. +// ASan-private header for asan_allocator.cpp. //===----------------------------------------------------------------------===// #ifndef ASAN_ALLOCATOR_H @@ -137,9 +138,9 @@ typedef VeryCompactSizeClassMap SizeClassMap; const uptr kAllocatorSpace = 0x10000000000ULL; const uptr kAllocatorSize = 0x10000000000ULL; // 3T. typedef DefaultSizeClassMap SizeClassMap; -# elif defined(__sparc__) +#elif defined(__sparc__) const uptr kAllocatorSpace = ~(uptr)0; -const uptr kAllocatorSize = 0x20000000000ULL; // 2T. +const uptr kAllocatorSize = 0x20000000000ULL; // 2T. typedef DefaultSizeClassMap SizeClassMap; # elif SANITIZER_WINDOWS const uptr kAllocatorSpace = ~(uptr)0; @@ -150,6 +151,7 @@ const uptr kAllocatorSpace = 0x600000000000ULL; const uptr kAllocatorSize = 0x40000000000ULL; // 4T. typedef DefaultSizeClassMap SizeClassMap; # endif +template struct AP64 { // Allocator64 parameters. Deliberately using a short name. static const uptr kSpaceBeg = kAllocatorSpace; static const uptr kSpaceSize = kAllocatorSize; @@ -157,37 +159,37 @@ struct AP64 { // Allocator64 parameters. Deliberately using a short name. typedef __asan::SizeClassMap SizeClassMap; typedef AsanMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; + using AddressSpaceView = AddressSpaceViewTy; }; -typedef SizeClassAllocator64 PrimaryAllocator; +template +using PrimaryAllocatorASVT = SizeClassAllocator64>; +using PrimaryAllocator = PrimaryAllocatorASVT; #else // Fallback to SizeClassAllocator32. -static const uptr kRegionSizeLog = 20; -static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog; -# if SANITIZER_WORDSIZE == 32 -typedef FlatByteMap ByteMap; -# elif SANITIZER_WORDSIZE == 64 -typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap; -# endif typedef CompactSizeClassMap SizeClassMap; +template struct AP32 { static const uptr kSpaceBeg = 0; static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; static const uptr kMetadataSize = 16; typedef __asan::SizeClassMap SizeClassMap; - static const uptr kRegionSizeLog = __asan::kRegionSizeLog; - typedef __asan::ByteMap ByteMap; + static const uptr kRegionSizeLog = 20; + using AddressSpaceView = AddressSpaceViewTy; typedef AsanMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; -typedef SizeClassAllocator32 PrimaryAllocator; +template +using PrimaryAllocatorASVT = SizeClassAllocator32 >; +using PrimaryAllocator = PrimaryAllocatorASVT; #endif // SANITIZER_CAN_USE_ALLOCATOR64 static const uptr kNumberOfSizeClasses = SizeClassMap::kNumClasses; -typedef SizeClassAllocatorLocalCache AllocatorCache; -typedef LargeMmapAllocator SecondaryAllocator; -typedef CombinedAllocator AsanAllocator; +template +using AsanAllocatorASVT = + CombinedAllocator>; +using AsanAllocator = AsanAllocatorASVT; +using AllocatorCache = AsanAllocator::AllocatorCache; struct AsanThreadLocalMallocStorage { uptr quarantine_cache[16]; @@ -207,6 +209,8 @@ void asan_delete(void *ptr, uptr size, uptr alignment, void *asan_malloc(uptr size, BufferedStackTrace *stack); void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack); void *asan_realloc(void *p, uptr size, BufferedStackTrace *stack); +void *asan_reallocarray(void *p, uptr nmemb, uptr size, + BufferedStackTrace *stack); void *asan_valloc(uptr size, BufferedStackTrace *stack); void *asan_pvalloc(uptr size, BufferedStackTrace *stack); diff --git a/libsanitizer/asan/asan_debugging.cc b/libsanitizer/asan/asan_debugging.cpp similarity index 94% rename from libsanitizer/asan/asan_debugging.cc rename to libsanitizer/asan/asan_debugging.cpp index 075af3375cd..3fc15adf7b8 100644 --- a/libsanitizer/asan/asan_debugging.cc +++ b/libsanitizer/asan/asan_debugging.cpp @@ -1,7 +1,8 @@ -//===-- asan_debugging.cc -------------------------------------------------===// +//===-- asan_debugging.cpp ------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_descriptions.cc b/libsanitizer/asan/asan_descriptions.cpp similarity index 98% rename from libsanitizer/asan/asan_descriptions.cc rename to libsanitizer/asan/asan_descriptions.cpp index 99f226da899..153c874a4e7 100644 --- a/libsanitizer/asan/asan_descriptions.cc +++ b/libsanitizer/asan/asan_descriptions.cpp @@ -1,7 +1,8 @@ -//===-- asan_descriptions.cc ------------------------------------*- C++ -*-===// +//===-- asan_descriptions.cpp -----------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_descriptions.h b/libsanitizer/asan/asan_descriptions.h index 43d0cbfeff3..28b38100b85 100644 --- a/libsanitizer/asan/asan_descriptions.h +++ b/libsanitizer/asan/asan_descriptions.h @@ -1,13 +1,14 @@ //===-- asan_descriptions.h -------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 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 diff --git a/libsanitizer/asan/asan_errors.cc b/libsanitizer/asan/asan_errors.cpp similarity index 96% rename from libsanitizer/asan/asan_errors.cc rename to libsanitizer/asan/asan_errors.cpp index 65941f65bf8..75ee996ceef 100644 --- a/libsanitizer/asan/asan_errors.cc +++ b/libsanitizer/asan/asan_errors.cpp @@ -1,7 +1,8 @@ -//===-- asan_errors.cc ------------------------------------------*- C++ -*-===// +//===-- asan_errors.cpp -----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -34,7 +35,7 @@ static void OnStackUnwind(const SignalContext &sig, // corresponding code in the sanitizer_common and we use this callback to // print it. static_cast(callback_context)->Print(); - GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context, fast); + stack->Unwind(sig.pc, sig.bp, sig.context, fast); } void ErrorDeadlySignal::Print() { @@ -176,6 +177,19 @@ void ErrorCallocOverflow::Print() { ReportErrorSummary(scariness.GetDescription(), stack); } +void ErrorReallocArrayOverflow::Print() { + Decorator d; + Printf("%s", d.Error()); + Report( + "ERROR: AddressSanitizer: reallocarray parameters overflow: count * size " + "(%zd * %zd) cannot be represented in type size_t (thread %s)\n", + count, size, AsanThreadIdAndName(tid).c_str()); + Printf("%s", d.Default()); + stack->Print(); + PrintHintAllocatorCannotReturnNull(); + ReportErrorSummary(scariness.GetDescription(), stack); +} + void ErrorPvallocOverflow::Print() { Decorator d; Printf("%s", d.Error()); diff --git a/libsanitizer/asan/asan_errors.h b/libsanitizer/asan/asan_errors.h index b155f2452af..b84f56c1853 100644 --- a/libsanitizer/asan/asan_errors.h +++ b/libsanitizer/asan/asan_errors.h @@ -1,7 +1,8 @@ //===-- asan_errors.h -------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -162,6 +163,21 @@ struct ErrorCallocOverflow : ErrorBase { void Print(); }; +struct ErrorReallocArrayOverflow : ErrorBase { + const BufferedStackTrace *stack; + uptr count; + uptr size; + + ErrorReallocArrayOverflow() = default; // (*) + ErrorReallocArrayOverflow(u32 tid, BufferedStackTrace *stack_, uptr count_, + uptr size_) + : ErrorBase(tid, 10, "reallocarray-overflow"), + stack(stack_), + count(count_), + size(size_) {} + void Print(); +}; + struct ErrorPvallocOverflow : ErrorBase { const BufferedStackTrace *stack; uptr size; @@ -370,6 +386,7 @@ struct ErrorGeneric : ErrorBase { macro(MallocUsableSizeNotOwned) \ macro(SanitizerGetAllocatedSizeNotOwned) \ macro(CallocOverflow) \ + macro(ReallocArrayOverflow) \ macro(PvallocOverflow) \ macro(InvalidAllocationAlignment) \ macro(InvalidAlignedAllocAlignment) \ @@ -387,8 +404,10 @@ struct ErrorGeneric : ErrorBase { #define ASAN_DEFINE_ERROR_KIND(name) kErrorKind##name, #define ASAN_ERROR_DESCRIPTION_MEMBER(name) Error##name name; -#define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \ - ErrorDescription(Error##name const &e) : kind(kErrorKind##name), name(e) {} +#define ASAN_ERROR_DESCRIPTION_CONSTRUCTOR(name) \ + ErrorDescription(Error##name const &e) : kind(kErrorKind##name) { \ + internal_memcpy(&name, &e, sizeof(name)); \ + } #define ASAN_ERROR_DESCRIPTION_PRINT(name) \ case kErrorKind##name: \ return name.Print(); diff --git a/libsanitizer/asan/asan_fake_stack.cc b/libsanitizer/asan/asan_fake_stack.cpp similarity index 97% rename from libsanitizer/asan/asan_fake_stack.cc rename to libsanitizer/asan/asan_fake_stack.cpp index f4a5bb75c28..295e6debc96 100644 --- a/libsanitizer/asan/asan_fake_stack.cc +++ b/libsanitizer/asan/asan_fake_stack.cpp @@ -1,7 +1,8 @@ -//===-- asan_fake_stack.cc ------------------------------------------------===// +//===-- asan_fake_stack.cpp -----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_fake_stack.h b/libsanitizer/asan/asan_fake_stack.h index 6ac61ddd24e..270a19816d6 100644 --- a/libsanitizer/asan/asan_fake_stack.h +++ b/libsanitizer/asan/asan_fake_stack.h @@ -1,13 +1,14 @@ //===-- asan_fake_stack.h ---------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 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/libsanitizer/asan/asan_flags.cc b/libsanitizer/asan/asan_flags.cpp similarity index 94% rename from libsanitizer/asan/asan_flags.cc rename to libsanitizer/asan/asan_flags.cpp index 522fce30f05..c5c70eaed73 100644 --- a/libsanitizer/asan/asan_flags.cc +++ b/libsanitizer/asan/asan_flags.cpp @@ -1,7 +1,8 @@ -//===-- asan_flags.cc -------------------------------------------*- C++ -*-===// +//===-- asan_flags.cpp ------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -119,12 +120,12 @@ void InitializeFlags() { #endif // Override from command line. - asan_parser.ParseString(GetEnv("ASAN_OPTIONS")); + asan_parser.ParseStringFromEnv("ASAN_OPTIONS"); #if CAN_SANITIZE_LEAKS - lsan_parser.ParseString(GetEnv("LSAN_OPTIONS")); + lsan_parser.ParseStringFromEnv("LSAN_OPTIONS"); #endif #if CAN_SANITIZE_UB - ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS")); + ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS"); #endif InitializeCommonFlags(); diff --git a/libsanitizer/asan/asan_flags.h b/libsanitizer/asan/asan_flags.h index 6b33789b84c..b55c81f07d4 100644 --- a/libsanitizer/asan/asan_flags.h +++ b/libsanitizer/asan/asan_flags.h @@ -1,7 +1,8 @@ //===-- asan_flags.h -------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_flags.inc b/libsanitizer/asan/asan_flags.inc index 9cd1f60db60..d360e03ca55 100644 --- a/libsanitizer/asan/asan_flags.inc +++ b/libsanitizer/asan/asan_flags.inc @@ -1,7 +1,8 @@ //===-- asan_flags.inc ------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -150,8 +151,6 @@ ASAN_FLAG(const char *, suppressions, "", "Suppressions file name.") ASAN_FLAG(bool, halt_on_error, true, "Crash the program after printing the first error report " "(WARNING: USE AT YOUR OWN RISK!)") -ASAN_FLAG(bool, use_odr_indicator, false, - "Use special ODR indicator symbol for ODR violation detection") ASAN_FLAG(bool, allocator_frees_and_returns_null_on_realloc_zero, true, "realloc(p, 0) is equivalent to free(p) by default (Same as the " "POSIX standard). If set to false, realloc(p, 0) will return a " @@ -159,3 +158,5 @@ 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.") diff --git a/libsanitizer/asan/asan_fuchsia.cc b/libsanitizer/asan/asan_fuchsia.cpp similarity index 92% rename from libsanitizer/asan/asan_fuchsia.cc rename to libsanitizer/asan/asan_fuchsia.cpp index f8207ecccd1..f8b2d5f2697 100644 --- a/libsanitizer/asan/asan_fuchsia.cc +++ b/libsanitizer/asan/asan_fuchsia.cpp @@ -1,7 +1,8 @@ -//===-- asan_fuchsia.cc --------------------------------------------------===// +//===-- asan_fuchsia.cpp -------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===---------------------------------------------------------------------===// // @@ -27,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(); @@ -171,13 +172,13 @@ 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(hook); SetCurrentThread(thread); // In lieu of AsanThread::ThreadStart. - asanThreadRegistry().StartThread(thread->tid(), os_id, /*workerthread*/ false, + asanThreadRegistry().StartThread(thread->tid(), os_id, ThreadType::Regular, nullptr); } @@ -188,6 +189,13 @@ static void ThreadExitHook(void *hook, uptr os_id) { AsanThread::TSDDtor(per_thread); } +bool HandleDlopenInit() { + // Not supported on this platform. + static_assert(!SANITIZER_SUPPORTS_INIT_FOR_DLOPEN, + "Expected SANITIZER_SUPPORTS_INIT_FOR_DLOPEN to be false"); + return false; +} + } // namespace __asan // These are declared (in extern "C") by . diff --git a/libsanitizer/asan/asan_globals.cc b/libsanitizer/asan/asan_globals.cpp similarity index 90% rename from libsanitizer/asan/asan_globals.cc rename to libsanitizer/asan/asan_globals.cpp index 10f090940fe..54e75f3cee7 100644 --- a/libsanitizer/asan/asan_globals.cc +++ b/libsanitizer/asan/asan_globals.cpp @@ -1,7 +1,8 @@ -//===-- asan_globals.cc ---------------------------------------------------===// +//===-- asan_globals.cpp --------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -81,9 +82,11 @@ static bool IsAddressNearGlobal(uptr addr, const __asan_global &g) { } static void ReportGlobal(const Global &g, const char *prefix) { - Report("%s Global[%p]: beg=%p size=%zu/%zu name=%s module=%s dyn_init=%zu\n", - prefix, &g, (void *)g.beg, g.size, g.size_with_redzone, g.name, - g.module_name, g.has_dynamic_init); + Report( + "%s Global[%p]: beg=%p size=%zu/%zu name=%s module=%s dyn_init=%zu " + "odr_indicator=%p\n", + prefix, &g, (void *)g.beg, g.size, g.size_with_redzone, g.name, + g.module_name, g.has_dynamic_init, (void *)g.odr_indicator); if (g.location) { Report(" location (%p): name=%s[%p], %d %d\n", g.location, g.location->filename, g.location->filename, g.location->line_no, @@ -112,15 +115,12 @@ int GetGlobalsForAddress(uptr addr, Global *globals, u32 *reg_sites, if (flags()->report_globals >= 2) ReportGlobal(g, "Search"); if (IsAddressNearGlobal(addr, g)) { -#if defined(__GNUC__) && defined(__sparc__) internal_memcpy(&globals[res], &g, sizeof(g)); -#else - globals[res] = g; -#endif if (reg_sites) reg_sites[res] = FindRegistrationSite(&g); res++; - if (res == max_globals) break; + if (res == max_globals) + break; } } return res; @@ -135,6 +135,9 @@ enum GlobalSymbolState { // this method in case compiler instruments global variables through their // local aliases. static void CheckODRViolationViaIndicator(const Global *g) { + // Instrumentation requests to skip ODR check. + if (g->odr_indicator == UINTPTR_MAX) + return; u8 *odr_indicator = reinterpret_cast(g->odr_indicator); if (*odr_indicator == UNREGISTERED) { *odr_indicator = REGISTERED; @@ -151,6 +154,23 @@ static void CheckODRViolationViaIndicator(const Global *g) { } } +// Check ODR violation for given global G by checking if it's already poisoned. +// We use this method in case compiler doesn't use private aliases for global +// variables. +static void CheckODRViolationViaPoisoning(const Global *g) { + if (__asan_region_is_poisoned(g->beg, g->size_with_redzone)) { + // This check may not be enough: if the first global is much larger + // the entire redzone of the second global may be within the first global. + for (ListOfGlobals *l = list_of_all_globals; l; l = l->next) { + if (g->beg == l->g->beg && + (flags()->detect_odr_violation >= 2 || g->size != l->g->size) && + !IsODRViolationSuppressed(g->name)) + ReportODRViolation(g, FindRegistrationSite(g), + l->g, FindRegistrationSite(l->g)); + } + } +} + // Clang provides two different ways for global variables protection: // it can poison the global itself or its private alias. In former // case we may poison same symbol multiple times, that can help us to @@ -168,9 +188,7 @@ static void CheckODRViolationViaIndicator(const Global *g) { // This routine chooses between two different methods of ODR violation // detection. static inline bool UseODRIndicator(const Global *g) { - // Use ODR indicator method iff use_odr_indicator flag is set and - // indicator symbol address is not 0. - return flags()->use_odr_indicator && g->odr_indicator > 0; + return g->odr_indicator > 0; } // Register a global variable. @@ -198,6 +216,8 @@ static void RegisterGlobal(const Global *g) { // where two globals with the same name are defined in different modules. if (UseODRIndicator(g)) CheckODRViolationViaIndicator(g); + else + CheckODRViolationViaPoisoning(g); } if (CanPoisonMemory()) PoisonRedZones(*g); @@ -231,7 +251,7 @@ static void UnregisterGlobal(const Global *g) { // implementation. It might not be worth doing anyway. // Release ODR indicator. - if (UseODRIndicator(g)) { + if (UseODRIndicator(g) && g->odr_indicator != UINTPTR_MAX) { u8 *odr_indicator = reinterpret_cast(g->odr_indicator); *odr_indicator = UNREGISTERED; } diff --git a/libsanitizer/asan/asan_globals_win.cc b/libsanitizer/asan/asan_globals_win.cpp similarity index 87% rename from libsanitizer/asan/asan_globals_win.cc rename to libsanitizer/asan/asan_globals_win.cpp index a78bc878f9c..ff5fe226b53 100644 --- a/libsanitizer/asan/asan_globals_win.cc +++ b/libsanitizer/asan/asan_globals_win.cpp @@ -1,7 +1,8 @@ -//===-- asan_globals_win.cc -----------------------------------------------===// +//===-- asan_globals_win.cpp ----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_init_version.h b/libsanitizer/asan/asan_init_version.h index 7833133938d..b806d794e05 100644 --- a/libsanitizer/asan/asan_init_version.h +++ b/libsanitizer/asan/asan_init_version.h @@ -1,7 +1,8 @@ //===-- asan_init_version.h -------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_interceptors.cc b/libsanitizer/asan/asan_interceptors.cpp similarity index 97% rename from libsanitizer/asan/asan_interceptors.cc rename to libsanitizer/asan/asan_interceptors.cpp index fc9818bee8a..482e44d83b7 100644 --- a/libsanitizer/asan/asan_interceptors.cc +++ b/libsanitizer/asan/asan_interceptors.cpp @@ -1,7 +1,8 @@ -//===-- asan_interceptors.cc ----------------------------------------------===// +//===-- asan_interceptors.cpp ---------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -23,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 @@ -578,6 +579,11 @@ INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg, } #endif // ASAN_INTERCEPT___CXA_ATEXIT +#if ASAN_INTERCEPT_VFORK +DEFINE_REAL(int, vfork) +DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(int, vfork) +#endif + // ---------------------- InitializeAsanInterceptors ---------------- {{{1 namespace __asan { void InitializeAsanInterceptors() { @@ -655,6 +661,10 @@ void InitializeAsanInterceptors() { ASAN_INTERCEPT_FUNC(__cxa_atexit); #endif +#if ASAN_INTERCEPT_VFORK + ASAN_INTERCEPT_FUNC(vfork); +#endif + InitializePlatformInterceptors(); VReport(1, "AddressSanitizer: libc interceptors initialized\n"); diff --git a/libsanitizer/asan/asan_interceptors.h b/libsanitizer/asan/asan_interceptors.h index beb1dc9532b..155ea4156ab 100644 --- a/libsanitizer/asan/asan_interceptors.h +++ b/libsanitizer/asan/asan_interceptors.h @@ -1,13 +1,14 @@ //===-- asan_interceptors.h -------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 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 @@ -79,12 +80,7 @@ void InitializePlatformInterceptors(); #if ASAN_HAS_EXCEPTIONS && !SANITIZER_WINDOWS && !SANITIZER_SOLARIS && \ !SANITIZER_NETBSD # define ASAN_INTERCEPT___CXA_THROW 1 -# if ! defined(ASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION) \ - || ASAN_HAS_CXA_RETHROW_PRIMARY_EXCEPTION -# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1 -# else -# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 0 -# endif +# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 1 # if defined(_GLIBCXX_SJLJ_EXCEPTIONS) || (SANITIZER_IOS && defined(__arm__)) # define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 1 # else @@ -109,6 +105,13 @@ void InitializePlatformInterceptors(); # define ASAN_INTERCEPT___STRDUP 0 #endif +#if SANITIZER_LINUX && (defined(__arm__) || defined(__aarch64__) || \ + defined(__i386__) || defined(__x86_64__)) +# define ASAN_INTERCEPT_VFORK 1 +#else +# define ASAN_INTERCEPT_VFORK 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) @@ -117,16 +120,16 @@ DECLARE_REAL(uptr, strnlen, const char *s, uptr maxlen) DECLARE_REAL(char*, strstr, const char *s1, const char *s2) #if !SANITIZER_MAC -#define ASAN_INTERCEPT_FUNC(name) \ - do { \ - if ((!INTERCEPT_FUNCTION(name) || !REAL(name))) \ - VReport(1, "AddressSanitizer: failed to intercept '" #name "'\n"); \ +#define ASAN_INTERCEPT_FUNC(name) \ + do { \ + if (!INTERCEPT_FUNCTION(name)) \ + VReport(1, "AddressSanitizer: failed to intercept '%s'\n'", #name); \ } while (0) -#define ASAN_INTERCEPT_FUNC_VER(name, ver) \ - do { \ - if ((!INTERCEPT_FUNCTION_VER(name, ver) || !REAL(name))) \ - VReport( \ - 1, "AddressSanitizer: failed to intercept '" #name "@@" #ver "'\n"); \ +#define ASAN_INTERCEPT_FUNC_VER(name, ver) \ + do { \ + if (!INTERCEPT_FUNCTION_VER(name, ver)) \ + VReport(1, "AddressSanitizer: failed to intercept '%s@@%s'\n", #name, \ + #ver); \ } while (0) #else // OS X interceptors don't need to be initialized with INTERCEPT_FUNCTION. diff --git a/libsanitizer/asan/asan_interceptors_memintrinsics.cc b/libsanitizer/asan/asan_interceptors_memintrinsics.cpp similarity index 83% rename from libsanitizer/asan/asan_interceptors_memintrinsics.cc rename to libsanitizer/asan/asan_interceptors_memintrinsics.cpp index b0c06a04cac..56df60ba681 100644 --- a/libsanitizer/asan/asan_interceptors_memintrinsics.cc +++ b/libsanitizer/asan/asan_interceptors_memintrinsics.cpp @@ -1,7 +1,8 @@ -//===-- asan_interceptors_memintrinsics.cc --------------------------------===// +//===-- asan_interceptors_memintrinsics.cpp -------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===---------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_interceptors_memintrinsics.h b/libsanitizer/asan/asan_interceptors_memintrinsics.h index faf8119c937..632f0515a9e 100644 --- a/libsanitizer/asan/asan_interceptors_memintrinsics.h +++ b/libsanitizer/asan/asan_interceptors_memintrinsics.h @@ -1,13 +1,14 @@ //===-- asan_interceptors_memintrinsics.h -----------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 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/libsanitizer/asan/asan_interceptors_vfork.S b/libsanitizer/asan/asan_interceptors_vfork.S new file mode 100644 index 00000000000..90a169d4b60 --- /dev/null +++ b/libsanitizer/asan/asan_interceptors_vfork.S @@ -0,0 +1,12 @@ +#include "sanitizer_common/sanitizer_asm.h" + +#if defined(__linux__) +#define COMMON_INTERCEPTOR_SPILL_AREA __asan_extra_spill_area +#define COMMON_INTERCEPTOR_HANDLE_VFORK __asan_handle_vfork +#include "sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S" +#include "sanitizer_common/sanitizer_common_interceptors_vfork_arm.inc.S" +#include "sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S" +#include "sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S" +#endif + +NO_EXEC_STACK_DIRECTIVE diff --git a/libsanitizer/asan/asan_interface.inc b/libsanitizer/asan/asan_interface.inc index b2fcde1c770..7c341f22e15 100644 --- a/libsanitizer/asan/asan_interface.inc +++ b/libsanitizer/asan/asan_interface.inc @@ -1,7 +1,8 @@ //===-- asan_interface.inc ------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // Asan interface list. @@ -37,6 +38,7 @@ INTERFACE_FUNCTION(__asan_get_report_pc) INTERFACE_FUNCTION(__asan_get_report_sp) INTERFACE_FUNCTION(__asan_get_shadow_mapping) INTERFACE_FUNCTION(__asan_handle_no_return) +INTERFACE_FUNCTION(__asan_handle_vfork) INTERFACE_FUNCTION(__asan_init) INTERFACE_FUNCTION(__asan_load_cxx_array_cookie) INTERFACE_FUNCTION(__asan_load1) diff --git a/libsanitizer/asan/asan_interface_internal.h b/libsanitizer/asan/asan_interface_internal.h index be9605d9e6e..c83aa11d741 100644 --- a/libsanitizer/asan/asan_interface_internal.h +++ b/libsanitizer/asan/asan_interface_internal.h @@ -1,7 +1,8 @@ //===-- asan_interface_internal.h -------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -248,6 +249,8 @@ extern "C" { SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE const char* __asan_default_suppressions(); + + SANITIZER_INTERFACE_ATTRIBUTE void __asan_handle_vfork(void *sp); } // extern "C" #endif // ASAN_INTERFACE_INTERNAL_H diff --git a/libsanitizer/asan/asan_internal.h b/libsanitizer/asan/asan_internal.h index 7c239895e39..72a4c3f22ff 100644 --- a/libsanitizer/asan/asan_internal.h +++ b/libsanitizer/asan/asan_internal.h @@ -1,7 +1,8 @@ //===-- asan_internal.h -----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -60,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 @@ -109,6 +110,11 @@ void *AsanDlSymNext(const char *sym); void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name); +// Returns `true` iff most of ASan init process should be skipped due to the +// ASan library being loaded via `dlopen()`. Platforms may perform any +// `dlopen()` specific initialization inside this function. +bool HandleDlopenInit(); + // Add convenient macro for interface functions that may be represented as // weak hooks. #define ASAN_MALLOC_HOOK(ptr, size) \ diff --git a/libsanitizer/asan/asan_linux.cc b/libsanitizer/asan/asan_linux.cpp similarity index 93% rename from libsanitizer/asan/asan_linux.cc rename to libsanitizer/asan/asan_linux.cpp index d92d0596b7c..ce5e873dc51 100644 --- a/libsanitizer/asan/asan_linux.cc +++ b/libsanitizer/asan/asan_linux.cpp @@ -1,7 +1,8 @@ -//===-- asan_linux.cc -----------------------------------------------------===// +//===-- asan_linux.cpp ----------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -246,6 +247,13 @@ void *AsanDlSymNext(const char *sym) { return dlsym(RTLD_NEXT, sym); } +bool HandleDlopenInit() { + // Not supported on this platform. + static_assert(!SANITIZER_SUPPORTS_INIT_FOR_DLOPEN, + "Expected SANITIZER_SUPPORTS_INIT_FOR_DLOPEN to be false"); + return false; +} + } // namespace __asan #endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || diff --git a/libsanitizer/asan/asan_mac.cc b/libsanitizer/asan/asan_mac.cpp similarity index 96% rename from libsanitizer/asan/asan_mac.cc rename to libsanitizer/asan/asan_mac.cpp index 89a3db4c2fb..769d499672d 100644 --- a/libsanitizer/asan/asan_mac.cc +++ b/libsanitizer/asan/asan_mac.cpp @@ -1,7 +1,8 @@ -//===-- asan_mac.cc -------------------------------------------------------===// +//===-- asan_mac.cpp ------------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -180,8 +181,8 @@ void asan_register_worker_thread(int parent_tid, StackTrace *stack) { t = AsanThread::Create(/* start_routine */ nullptr, /* arg */ nullptr, parent_tid, stack, /* detached */ true); t->Init(); - asanThreadRegistry().StartThread(t->tid(), GetTid(), - /* workerthread */ true, 0); + asanThreadRegistry().StartThread(t->tid(), GetTid(), ThreadType::Worker, + nullptr); SetCurrentThread(t); } } diff --git a/libsanitizer/asan/asan_malloc_linux.cc b/libsanitizer/asan/asan_malloc_linux.cpp similarity index 94% rename from libsanitizer/asan/asan_malloc_linux.cc rename to libsanitizer/asan/asan_malloc_linux.cpp index a6e692759ce..706bc39f0c4 100644 --- a/libsanitizer/asan/asan_malloc_linux.cc +++ b/libsanitizer/asan/asan_malloc_linux.cpp @@ -1,7 +1,8 @@ -//===-- asan_malloc_linux.cc ----------------------------------------------===// +//===-- asan_malloc_linux.cpp ---------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -164,6 +165,14 @@ INTERCEPTOR(void*, realloc, void *ptr, uptr size) { return asan_realloc(ptr, size, &stack); } +#if SANITIZER_INTERCEPT_REALLOCARRAY +INTERCEPTOR(void*, reallocarray, void *ptr, uptr nmemb, uptr size) { + ENSURE_ASAN_INITED(); + GET_STACK_TRACE_MALLOC; + return asan_reallocarray(ptr, nmemb, size, &stack); +} +#endif // SANITIZER_INTERCEPT_REALLOCARRAY + #if SANITIZER_INTERCEPT_MEMALIGN INTERCEPTOR(void*, memalign, uptr boundary, uptr size) { GET_STACK_TRACE_MALLOC; @@ -207,7 +216,7 @@ INTERCEPTOR(struct fake_mallinfo, mallinfo, void) { } INTERCEPTOR(int, mallopt, int cmd, int value) { - return -1; + return 0; } #endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO diff --git a/libsanitizer/asan/asan_malloc_local.h b/libsanitizer/asan/asan_malloc_local.h index 354189315fb..3f784b90c73 100644 --- a/libsanitizer/asan/asan_malloc_local.h +++ b/libsanitizer/asan/asan_malloc_local.h @@ -1,7 +1,8 @@ //===-- asan_malloc_local.h -------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -16,25 +17,34 @@ #include "sanitizer_common/sanitizer_platform.h" #include "asan_internal.h" -// On RTEMS, we use the local pool to handle memory allocation when the ASan -// run-time is not up. static INLINE bool EarlyMalloc() { - return SANITIZER_RTEMS && (!__asan::asan_inited || - __asan::asan_init_is_running); + return SANITIZER_RTEMS && + (!__asan::asan_inited || __asan::asan_init_is_running); } -void* MemalignFromLocalPool(uptr alignment, uptr size); - #if SANITIZER_RTEMS bool IsFromLocalPool(const void *ptr); +void *MemalignFromLocalPool(uptr alignment, uptr size); + +// On RTEMS, we use the local pool to handle memory allocation when the ASan +// run-time is not up. This macro is expanded in the context of the operator new +// implementation. +#define MAYBE_ALLOCATE_FROM_LOCAL_POOL(nothrow) \ + do { \ + if (UNLIKELY(EarlyMalloc())) { \ + void *res = MemalignFromLocalPool(SHADOW_GRANULARITY, size); \ + if (!nothrow) \ + CHECK(res); \ + return res; \ + } \ + } while (0) -#define ALLOCATE_FROM_LOCAL_POOL UNLIKELY(EarlyMalloc()) #define IS_FROM_LOCAL_POOL(ptr) UNLIKELY(IsFromLocalPool(ptr)) #else // SANITIZER_RTEMS -#define ALLOCATE_FROM_LOCAL_POOL 0 +#define MAYBE_ALLOCATE_FROM_LOCAL_POOL(nothrow) #define IS_FROM_LOCAL_POOL(ptr) 0 #endif // SANITIZER_RTEMS diff --git a/libsanitizer/asan/asan_malloc_mac.cc b/libsanitizer/asan/asan_malloc_mac.cpp similarity index 57% rename from libsanitizer/asan/asan_malloc_mac.cc rename to libsanitizer/asan/asan_malloc_mac.cpp index e34884be85b..e8484685dae 100644 --- a/libsanitizer/asan/asan_malloc_mac.cc +++ b/libsanitizer/asan/asan_malloc_mac.cpp @@ -1,7 +1,8 @@ -//===-- asan_malloc_mac.cc ------------------------------------------------===// +//===-- asan_malloc_mac.cpp -----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -17,6 +18,7 @@ #include "asan_report.h" #include "asan_stack.h" #include "asan_stats.h" +#include "lsan/lsan_common.h" using namespace __asan; #define COMMON_MALLOC_ZONE_NAME "asan" @@ -56,7 +58,45 @@ using namespace __asan; GET_STACK_TRACE_FREE; \ ReportMacMzReallocUnknown((uptr)ptr, (uptr)zone_ptr, zone_name, &stack); #define COMMON_MALLOC_NAMESPACE __asan +#define COMMON_MALLOC_HAS_ZONE_ENUMERATOR 0 +#define COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT 1 #include "sanitizer_common/sanitizer_malloc_mac.inc" +namespace COMMON_MALLOC_NAMESPACE { + +bool HandleDlopenInit() { + static_assert(SANITIZER_SUPPORTS_INIT_FOR_DLOPEN, + "Expected SANITIZER_SUPPORTS_INIT_FOR_DLOPEN to be true"); + // We have no reliable way of knowing how we are being loaded + // so make it a requirement on Apple platforms to set this environment + // variable to indicate that we want to perform initialization via + // dlopen(). + auto init_str = GetEnv("APPLE_ASAN_INIT_FOR_DLOPEN"); + if (!init_str) + return false; + if (internal_strncmp(init_str, "1", 1) != 0) + return false; + // When we are loaded via `dlopen()` path we still initialize the malloc zone + // so Symbolication clients (e.g. `leaks`) that load the ASan allocator can + // find an initialized malloc zone. + InitMallocZoneFields(); + return true; +} +} // namespace COMMON_MALLOC_NAMESPACE + +namespace { + +void mi_extra_init(sanitizer_malloc_introspection_t *mi) { + uptr last_byte_plus_one = 0; + mi->allocator_ptr = 0; + // Range is [begin_ptr, end_ptr) + __lsan::GetAllocatorGlobalRange(&(mi->allocator_ptr), &last_byte_plus_one); + CHECK_NE(mi->allocator_ptr, 0); + CHECK_GT(last_byte_plus_one, mi->allocator_ptr); + mi->allocator_size = last_byte_plus_one - (mi->allocator_ptr); + CHECK_GT(mi->allocator_size, 0); +} +} // namespace + #endif diff --git a/libsanitizer/asan/asan_malloc_win.cc b/libsanitizer/asan/asan_malloc_win.cc deleted file mode 100644 index 24518603792..00000000000 --- a/libsanitizer/asan/asan_malloc_win.cc +++ /dev/null @@ -1,259 +0,0 @@ -//===-- asan_malloc_win.cc ------------------------------------------------===// -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file is a part of AddressSanitizer, an address sanity checker. -// -// Windows-specific malloc interception. -//===----------------------------------------------------------------------===// - -#include "sanitizer_common/sanitizer_platform.h" -#if SANITIZER_WINDOWS -// Intentionally not including windows.h here, to avoid the risk of -// pulling in conflicting declarations of these functions. (With mingw-w64, -// there's a risk of windows.h pulling in stdint.h.) -typedef int BOOL; -typedef void *HANDLE; -typedef const void *LPCVOID; -typedef void *LPVOID; - -#define HEAP_ZERO_MEMORY 0x00000008 -#define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010 - - -#include "asan_allocator.h" -#include "asan_interceptors.h" -#include "asan_internal.h" -#include "asan_stack.h" -#include "interception/interception.h" - -#include - -using namespace __asan; // NOLINT - -// MT: Simply defining functions with the same signature in *.obj -// files overrides the standard functions in the CRT. -// MD: Memory allocation functions are defined in the CRT .dll, -// so we have to intercept them before they are called for the first time. - -#if ASAN_DYNAMIC -# define ALLOCATION_FUNCTION_ATTRIBUTE -#else -# define ALLOCATION_FUNCTION_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE -#endif - -extern "C" { -ALLOCATION_FUNCTION_ATTRIBUTE -void free(void *ptr) { - GET_STACK_TRACE_FREE; - return asan_free(ptr, &stack, FROM_MALLOC); -} - -ALLOCATION_FUNCTION_ATTRIBUTE -void _free_dbg(void *ptr, int) { - free(ptr); -} - -ALLOCATION_FUNCTION_ATTRIBUTE -void _free_base(void *ptr) { - free(ptr); -} - -ALLOCATION_FUNCTION_ATTRIBUTE -void *malloc(size_t size) { - GET_STACK_TRACE_MALLOC; - return asan_malloc(size, &stack); -} - -ALLOCATION_FUNCTION_ATTRIBUTE -void *_malloc_base(size_t size) { - return malloc(size); -} - -ALLOCATION_FUNCTION_ATTRIBUTE -void *_malloc_dbg(size_t size, int, const char *, int) { - return malloc(size); -} - -ALLOCATION_FUNCTION_ATTRIBUTE -void *calloc(size_t nmemb, size_t size) { - GET_STACK_TRACE_MALLOC; - return asan_calloc(nmemb, size, &stack); -} - -ALLOCATION_FUNCTION_ATTRIBUTE -void *_calloc_base(size_t nmemb, size_t size) { - return calloc(nmemb, size); -} - -ALLOCATION_FUNCTION_ATTRIBUTE -void *_calloc_dbg(size_t nmemb, size_t size, int, const char *, int) { - return calloc(nmemb, size); -} - -ALLOCATION_FUNCTION_ATTRIBUTE -void *_calloc_impl(size_t nmemb, size_t size, int *errno_tmp) { - return calloc(nmemb, size); -} - -ALLOCATION_FUNCTION_ATTRIBUTE -void *realloc(void *ptr, size_t size) { - GET_STACK_TRACE_MALLOC; - return asan_realloc(ptr, size, &stack); -} - -ALLOCATION_FUNCTION_ATTRIBUTE -void *_realloc_dbg(void *ptr, size_t size, int) { - UNREACHABLE("_realloc_dbg should not exist!"); - return 0; -} - -ALLOCATION_FUNCTION_ATTRIBUTE -void *_realloc_base(void *ptr, size_t size) { - return realloc(ptr, size); -} - -ALLOCATION_FUNCTION_ATTRIBUTE -void *_recalloc(void *p, size_t n, size_t elem_size) { - if (!p) - return calloc(n, elem_size); - const size_t size = n * elem_size; - if (elem_size != 0 && size / elem_size != n) - return 0; - return realloc(p, size); -} - -ALLOCATION_FUNCTION_ATTRIBUTE -void *_recalloc_base(void *p, size_t n, size_t elem_size) { - return _recalloc(p, n, elem_size); -} - -ALLOCATION_FUNCTION_ATTRIBUTE -size_t _msize(void *ptr) { - GET_CURRENT_PC_BP_SP; - (void)sp; - return asan_malloc_usable_size(ptr, pc, bp); -} - -ALLOCATION_FUNCTION_ATTRIBUTE -void *_expand(void *memblock, size_t size) { - // _expand is used in realloc-like functions to resize the buffer if possible. - // We don't want memory to stand still while resizing buffers, so return 0. - return 0; -} - -ALLOCATION_FUNCTION_ATTRIBUTE -void *_expand_dbg(void *memblock, size_t size) { - return _expand(memblock, size); -} - -// TODO(timurrrr): Might want to add support for _aligned_* allocation -// functions to detect a bit more bugs. Those functions seem to wrap malloc(). - -int _CrtDbgReport(int, const char*, int, - const char*, const char*, ...) { - ShowStatsAndAbort(); -} - -int _CrtDbgReportW(int reportType, const wchar_t*, int, - const wchar_t*, const wchar_t*, ...) { - ShowStatsAndAbort(); -} - -int _CrtSetReportMode(int, int) { - return 0; -} -} // extern "C" - -INTERCEPTOR_WINAPI(LPVOID, HeapAlloc, HANDLE hHeap, DWORD dwFlags, - SIZE_T dwBytes) { - GET_STACK_TRACE_MALLOC; - void *p = asan_malloc(dwBytes, &stack); - // Reading MSDN suggests that the *entire* usable allocation is zeroed out. - // Otherwise it is difficult to HeapReAlloc with HEAP_ZERO_MEMORY. - // https://blogs.msdn.microsoft.com/oldnewthing/20120316-00/?p=8083 - if (dwFlags == HEAP_ZERO_MEMORY) - internal_memset(p, 0, asan_mz_size(p)); - else - CHECK(dwFlags == 0 && "unsupported heap flags"); - return p; -} - -INTERCEPTOR_WINAPI(BOOL, HeapFree, HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) { - CHECK(dwFlags == 0 && "unsupported heap flags"); - GET_STACK_TRACE_FREE; - asan_free(lpMem, &stack, FROM_MALLOC); - return true; -} - -INTERCEPTOR_WINAPI(LPVOID, HeapReAlloc, HANDLE hHeap, DWORD dwFlags, - LPVOID lpMem, SIZE_T dwBytes) { - GET_STACK_TRACE_MALLOC; - // Realloc should never reallocate in place. - if (dwFlags & HEAP_REALLOC_IN_PLACE_ONLY) - return nullptr; - CHECK(dwFlags == 0 && "unsupported heap flags"); - return asan_realloc(lpMem, dwBytes, &stack); -} - -INTERCEPTOR_WINAPI(SIZE_T, HeapSize, HANDLE hHeap, DWORD dwFlags, - LPCVOID lpMem) { - CHECK(dwFlags == 0 && "unsupported heap flags"); - GET_CURRENT_PC_BP_SP; - (void)sp; - return asan_malloc_usable_size(lpMem, pc, bp); -} - -namespace __asan { - -static void TryToOverrideFunction(const char *fname, uptr new_func) { - // Failure here is not fatal. The CRT may not be present, and different CRT - // versions use different symbols. - if (!__interception::OverrideFunction(fname, new_func)) - VPrintf(2, "Failed to override function %s\n", fname); -} - -void ReplaceSystemMalloc() { -#if defined(ASAN_DYNAMIC) - TryToOverrideFunction("free", (uptr)free); - TryToOverrideFunction("_free_base", (uptr)free); - TryToOverrideFunction("malloc", (uptr)malloc); - TryToOverrideFunction("_malloc_base", (uptr)malloc); - TryToOverrideFunction("_malloc_crt", (uptr)malloc); - TryToOverrideFunction("calloc", (uptr)calloc); - TryToOverrideFunction("_calloc_base", (uptr)calloc); - TryToOverrideFunction("_calloc_crt", (uptr)calloc); - TryToOverrideFunction("realloc", (uptr)realloc); - TryToOverrideFunction("_realloc_base", (uptr)realloc); - TryToOverrideFunction("_realloc_crt", (uptr)realloc); - TryToOverrideFunction("_recalloc", (uptr)_recalloc); - TryToOverrideFunction("_recalloc_base", (uptr)_recalloc); - TryToOverrideFunction("_recalloc_crt", (uptr)_recalloc); - TryToOverrideFunction("_msize", (uptr)_msize); - TryToOverrideFunction("_expand", (uptr)_expand); - TryToOverrideFunction("_expand_base", (uptr)_expand); - - // Recent versions of ucrtbase.dll appear to be built with PGO and LTCG, which - // enable cross-module inlining. This means our _malloc_base hook won't catch - // all CRT allocations. This code here patches the import table of - // ucrtbase.dll so that all attempts to use the lower-level win32 heap - // allocation API will be directed to ASan's heap. We don't currently - // intercept all calls to HeapAlloc. If we did, we would have to check on - // HeapFree whether the pointer came from ASan of from the system. -#define INTERCEPT_UCRT_FUNCTION(func) \ - if (!INTERCEPT_FUNCTION_DLLIMPORT("ucrtbase.dll", \ - "api-ms-win-core-heap-l1-1-0.dll", func)) \ - VPrintf(2, "Failed to intercept ucrtbase.dll import %s\n", #func); - INTERCEPT_UCRT_FUNCTION(HeapAlloc); - INTERCEPT_UCRT_FUNCTION(HeapFree); - INTERCEPT_UCRT_FUNCTION(HeapReAlloc); - INTERCEPT_UCRT_FUNCTION(HeapSize); -#undef INTERCEPT_UCRT_FUNCTION -#endif -} -} // namespace __asan - -#endif // _WIN32 diff --git a/libsanitizer/asan/asan_malloc_win.cpp b/libsanitizer/asan/asan_malloc_win.cpp new file mode 100644 index 00000000000..291d411ea79 --- /dev/null +++ b/libsanitizer/asan/asan_malloc_win.cpp @@ -0,0 +1,553 @@ +//===-- 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. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Windows-specific malloc interception. +//===----------------------------------------------------------------------===// + +#include "sanitizer_common/sanitizer_allocator_interface.h" +#include "sanitizer_common/sanitizer_platform.h" +#if SANITIZER_WINDOWS +#include "asan_allocator.h" +#include "asan_interceptors.h" +#include "asan_internal.h" +#include "asan_stack.h" +#include "interception/interception.h" +#include + +// Intentionally not including windows.h here, to avoid the risk of +// pulling in conflicting declarations of these functions. (With mingw-w64, +// there's a risk of windows.h pulling in stdint.h.) +typedef int BOOL; +typedef void *HANDLE; +typedef const void *LPCVOID; +typedef void *LPVOID; + +typedef unsigned long DWORD; +constexpr unsigned long HEAP_ZERO_MEMORY = 0x00000008; +constexpr unsigned long HEAP_REALLOC_IN_PLACE_ONLY = 0x00000010; +constexpr unsigned long HEAP_ALLOCATE_SUPPORTED_FLAGS = (HEAP_ZERO_MEMORY); +constexpr unsigned long HEAP_ALLOCATE_UNSUPPORTED_FLAGS = + (~HEAP_ALLOCATE_SUPPORTED_FLAGS); +constexpr unsigned long HEAP_FREE_SUPPORTED_FLAGS = (0); +constexpr unsigned long HEAP_FREE_UNSUPPORTED_FLAGS = + (~HEAP_ALLOCATE_SUPPORTED_FLAGS); +constexpr unsigned long HEAP_REALLOC_SUPPORTED_FLAGS = + (HEAP_REALLOC_IN_PLACE_ONLY | HEAP_ZERO_MEMORY); +constexpr unsigned long HEAP_REALLOC_UNSUPPORTED_FLAGS = + (~HEAP_ALLOCATE_SUPPORTED_FLAGS); + + +extern "C" { +LPVOID WINAPI HeapAlloc(HANDLE hHeap, DWORD dwFlags, size_t dwBytes); +LPVOID WINAPI HeapReAlloc(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, + size_t dwBytes); +BOOL WINAPI HeapFree(HANDLE hHeap, DWORD dwFlags, LPVOID lpMem); +size_t WINAPI HeapSize(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem); + +BOOL WINAPI HeapValidate(HANDLE hHeap, DWORD dwFlags, LPCVOID lpMem); +} + +using namespace __asan; // NOLINT + +// MT: Simply defining functions with the same signature in *.obj +// files overrides the standard functions in the CRT. +// MD: Memory allocation functions are defined in the CRT .dll, +// so we have to intercept them before they are called for the first time. + +#if ASAN_DYNAMIC +# define ALLOCATION_FUNCTION_ATTRIBUTE +#else +# define ALLOCATION_FUNCTION_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE +#endif + +extern "C" { +ALLOCATION_FUNCTION_ATTRIBUTE +size_t _msize(void *ptr) { + GET_CURRENT_PC_BP_SP; + (void)sp; + return asan_malloc_usable_size(ptr, pc, bp); +} + +ALLOCATION_FUNCTION_ATTRIBUTE +size_t _msize_base(void *ptr) { + return _msize(ptr); +} + +ALLOCATION_FUNCTION_ATTRIBUTE +void free(void *ptr) { + GET_STACK_TRACE_FREE; + return asan_free(ptr, &stack, FROM_MALLOC); +} + +ALLOCATION_FUNCTION_ATTRIBUTE +void _free_dbg(void *ptr, int) { + free(ptr); +} + +ALLOCATION_FUNCTION_ATTRIBUTE +void _free_base(void *ptr) { + free(ptr); +} + +ALLOCATION_FUNCTION_ATTRIBUTE +void *malloc(size_t size) { + GET_STACK_TRACE_MALLOC; + return asan_malloc(size, &stack); +} + +ALLOCATION_FUNCTION_ATTRIBUTE +void *_malloc_base(size_t size) { + return malloc(size); +} + +ALLOCATION_FUNCTION_ATTRIBUTE +void *_malloc_dbg(size_t size, int, const char *, int) { + return malloc(size); +} + +ALLOCATION_FUNCTION_ATTRIBUTE +void *calloc(size_t nmemb, size_t size) { + GET_STACK_TRACE_MALLOC; + return asan_calloc(nmemb, size, &stack); +} + +ALLOCATION_FUNCTION_ATTRIBUTE +void *_calloc_base(size_t nmemb, size_t size) { + return calloc(nmemb, size); +} + +ALLOCATION_FUNCTION_ATTRIBUTE +void *_calloc_dbg(size_t nmemb, size_t size, int, const char *, int) { + return calloc(nmemb, size); +} + +ALLOCATION_FUNCTION_ATTRIBUTE +void *_calloc_impl(size_t nmemb, size_t size, int *errno_tmp) { + return calloc(nmemb, size); +} + +ALLOCATION_FUNCTION_ATTRIBUTE +void *realloc(void *ptr, size_t size) { + GET_STACK_TRACE_MALLOC; + return asan_realloc(ptr, size, &stack); +} + +ALLOCATION_FUNCTION_ATTRIBUTE +void *_realloc_dbg(void *ptr, size_t size, int) { + UNREACHABLE("_realloc_dbg should not exist!"); + return 0; +} + +ALLOCATION_FUNCTION_ATTRIBUTE +void *_realloc_base(void *ptr, size_t size) { + return realloc(ptr, size); +} + +ALLOCATION_FUNCTION_ATTRIBUTE +void *_recalloc(void *p, size_t n, size_t elem_size) { + if (!p) + return calloc(n, elem_size); + const size_t size = n * elem_size; + if (elem_size != 0 && size / elem_size != n) + return 0; + + size_t old_size = _msize(p); + void *new_alloc = malloc(size); + if (new_alloc) { + REAL(memcpy)(new_alloc, p, Min(size, old_size)); + if (old_size < size) + REAL(memset)(((u8 *)new_alloc) + old_size, 0, size - old_size); + free(p); + } + return new_alloc; +} + +ALLOCATION_FUNCTION_ATTRIBUTE +void *_recalloc_base(void *p, size_t n, size_t elem_size) { + return _recalloc(p, n, elem_size); +} + +ALLOCATION_FUNCTION_ATTRIBUTE +void *_expand(void *memblock, size_t size) { + // _expand is used in realloc-like functions to resize the buffer if possible. + // We don't want memory to stand still while resizing buffers, so return 0. + return 0; +} + +ALLOCATION_FUNCTION_ATTRIBUTE +void *_expand_dbg(void *memblock, size_t size) { + return _expand(memblock, size); +} + +// TODO(timurrrr): Might want to add support for _aligned_* allocation +// functions to detect a bit more bugs. Those functions seem to wrap malloc(). + +int _CrtDbgReport(int, const char*, int, + const char*, const char*, ...) { + ShowStatsAndAbort(); +} + +int _CrtDbgReportW(int reportType, const wchar_t*, int, + const wchar_t*, const wchar_t*, ...) { + ShowStatsAndAbort(); +} + +int _CrtSetReportMode(int, int) { + return 0; +} +} // extern "C" + +#define OWNED_BY_RTL(heap, memory) \ + (!__sanitizer_get_ownership(memory) && HeapValidate(heap, 0, memory)) + +INTERCEPTOR_WINAPI(size_t, HeapSize, HANDLE hHeap, DWORD dwFlags, + LPCVOID lpMem) { + // If the RTL allocators are hooked we need to check whether the ASAN + // allocator owns the pointer we're about to use. Allocations occur before + // interception takes place, so if it is not owned by the RTL heap we can + // pass it to the ASAN heap for inspection. + if (flags()->windows_hook_rtl_allocators) { + if (!asan_inited || OWNED_BY_RTL(hHeap, lpMem)) + return REAL(HeapSize)(hHeap, dwFlags, lpMem); + } else { + CHECK(dwFlags == 0 && "unsupported heap flags"); + } + GET_CURRENT_PC_BP_SP; + (void)sp; + return asan_malloc_usable_size(lpMem, pc, bp); +} + +INTERCEPTOR_WINAPI(LPVOID, HeapAlloc, HANDLE hHeap, DWORD dwFlags, + size_t dwBytes) { + // If the ASAN runtime is not initialized, or we encounter an unsupported + // flag, fall back to the original allocator. + if (flags()->windows_hook_rtl_allocators) { + if (UNLIKELY(!asan_inited || + (dwFlags & HEAP_ALLOCATE_UNSUPPORTED_FLAGS) != 0)) { + return REAL(HeapAlloc)(hHeap, dwFlags, dwBytes); + } + } else { + // In the case that we don't hook the rtl allocators, + // this becomes an assert since there is no failover to the original + // allocator. + CHECK((HEAP_ALLOCATE_UNSUPPORTED_FLAGS & dwFlags) != 0 && + "unsupported flags"); + } + GET_STACK_TRACE_MALLOC; + void *p = asan_malloc(dwBytes, &stack); + // Reading MSDN suggests that the *entire* usable allocation is zeroed out. + // Otherwise it is difficult to HeapReAlloc with HEAP_ZERO_MEMORY. + // https://blogs.msdn.microsoft.com/oldnewthing/20120316-00/?p=8083 + if (p && (dwFlags & HEAP_ZERO_MEMORY)) { + GET_CURRENT_PC_BP_SP; + (void)sp; + auto usable_size = asan_malloc_usable_size(p, pc, bp); + internal_memset(p, 0, usable_size); + } + return p; +} + +INTERCEPTOR_WINAPI(BOOL, HeapFree, HANDLE hHeap, DWORD dwFlags, LPVOID lpMem) { + // Heap allocations happen before this function is hooked, so we must fall + // back to the original function if the pointer is not from the ASAN heap, + // or unsupported flags are provided. + if (flags()->windows_hook_rtl_allocators) { + if (OWNED_BY_RTL(hHeap, lpMem)) + return REAL(HeapFree)(hHeap, dwFlags, lpMem); + } else { + CHECK((HEAP_FREE_UNSUPPORTED_FLAGS & dwFlags) != 0 && "unsupported flags"); + } + GET_STACK_TRACE_FREE; + asan_free(lpMem, &stack, FROM_MALLOC); + return true; +} + +namespace __asan { +using AllocFunction = LPVOID(WINAPI *)(HANDLE, DWORD, size_t); +using ReAllocFunction = LPVOID(WINAPI *)(HANDLE, DWORD, LPVOID, size_t); +using SizeFunction = size_t(WINAPI *)(HANDLE, DWORD, LPVOID); +using FreeFunction = BOOL(WINAPI *)(HANDLE, DWORD, LPVOID); + +void *SharedReAlloc(ReAllocFunction reallocFunc, SizeFunction heapSizeFunc, + FreeFunction freeFunc, AllocFunction allocFunc, + HANDLE hHeap, DWORD dwFlags, LPVOID lpMem, size_t dwBytes) { + CHECK(reallocFunc && heapSizeFunc && freeFunc && allocFunc); + GET_STACK_TRACE_MALLOC; + GET_CURRENT_PC_BP_SP; + (void)sp; + if (flags()->windows_hook_rtl_allocators) { + enum AllocationOwnership { NEITHER = 0, ASAN = 1, RTL = 2 }; + AllocationOwnership ownershipState; + bool owned_rtlalloc = false; + bool owned_asan = __sanitizer_get_ownership(lpMem); + + if (!owned_asan) + owned_rtlalloc = HeapValidate(hHeap, 0, lpMem); + + if (owned_asan && !owned_rtlalloc) + ownershipState = ASAN; + else if (!owned_asan && owned_rtlalloc) + ownershipState = RTL; + else if (!owned_asan && !owned_rtlalloc) + ownershipState = NEITHER; + + // If this heap block which was allocated before the ASAN + // runtime came up, use the real HeapFree function. + if (UNLIKELY(!asan_inited)) { + return reallocFunc(hHeap, dwFlags, lpMem, dwBytes); + } + bool only_asan_supported_flags = + (HEAP_REALLOC_UNSUPPORTED_FLAGS & dwFlags) == 0; + + if (ownershipState == RTL || + (ownershipState == NEITHER && !only_asan_supported_flags)) { + if (only_asan_supported_flags) { + // if this is a conversion to ASAN upported flags, transfer this + // allocation to the ASAN allocator + void *replacement_alloc; + if (dwFlags & HEAP_ZERO_MEMORY) + replacement_alloc = asan_calloc(1, dwBytes, &stack); + else + replacement_alloc = asan_malloc(dwBytes, &stack); + if (replacement_alloc) { + size_t old_size = heapSizeFunc(hHeap, dwFlags, lpMem); + if (old_size == ((size_t)0) - 1) { + asan_free(replacement_alloc, &stack, FROM_MALLOC); + return nullptr; + } + REAL(memcpy)(replacement_alloc, lpMem, old_size); + freeFunc(hHeap, dwFlags, lpMem); + } + return replacement_alloc; + } else { + // owned by rtl or neither with unsupported ASAN flags, + // just pass back to original allocator + CHECK(ownershipState == RTL || ownershipState == NEITHER); + CHECK(!only_asan_supported_flags); + return reallocFunc(hHeap, dwFlags, lpMem, dwBytes); + } + } + + if (ownershipState == ASAN && !only_asan_supported_flags) { + // Conversion to unsupported flags allocation, + // transfer this allocation back to the original allocator. + void *replacement_alloc = allocFunc(hHeap, dwFlags, dwBytes); + size_t old_usable_size = 0; + if (replacement_alloc) { + old_usable_size = asan_malloc_usable_size(lpMem, pc, bp); + REAL(memcpy)(replacement_alloc, lpMem, + Min(dwBytes, old_usable_size)); + asan_free(lpMem, &stack, FROM_MALLOC); + } + return replacement_alloc; + } + + CHECK((ownershipState == ASAN || ownershipState == NEITHER) && + only_asan_supported_flags); + // At this point we should either be ASAN owned with ASAN supported flags + // or we owned by neither and have supported flags. + // Pass through even when it's neither since this could be a null realloc or + // UAF that ASAN needs to catch. + } else { + CHECK((HEAP_REALLOC_UNSUPPORTED_FLAGS & dwFlags) != 0 && + "unsupported flags"); + } + // asan_realloc will never reallocate in place, so for now this flag is + // unsupported until we figure out a way to fake this. + if (dwFlags & HEAP_REALLOC_IN_PLACE_ONLY) + return nullptr; + + // HeapReAlloc and HeapAlloc both happily accept 0 sized allocations. + // passing a 0 size into asan_realloc will free the allocation. + // To avoid this and keep behavior consistent, fudge the size if 0. + // (asan_malloc already does this) + if (dwBytes == 0) + dwBytes = 1; + + size_t old_size; + if (dwFlags & HEAP_ZERO_MEMORY) + old_size = asan_malloc_usable_size(lpMem, pc, bp); + + void *ptr = asan_realloc(lpMem, dwBytes, &stack); + if (ptr == nullptr) + return nullptr; + + if (dwFlags & HEAP_ZERO_MEMORY) { + size_t new_size = asan_malloc_usable_size(ptr, pc, bp); + if (old_size < new_size) + REAL(memset)(((u8 *)ptr) + old_size, 0, new_size - old_size); + } + + return ptr; +} +} // namespace __asan + +INTERCEPTOR_WINAPI(LPVOID, HeapReAlloc, HANDLE hHeap, DWORD dwFlags, + LPVOID lpMem, size_t dwBytes) { + return SharedReAlloc(REAL(HeapReAlloc), (SizeFunction)REAL(HeapSize), + REAL(HeapFree), REAL(HeapAlloc), hHeap, dwFlags, lpMem, + dwBytes); +} + +// The following functions are undocumented and subject to change. +// However, hooking them is necessary to hook Windows heap +// allocations with detours and their definitions are unlikely to change. +// Comments in /minkernel/ntos/rtl/heappublic.c indicate that these functions +// are part of the heap's public interface. +typedef unsigned long LOGICAL; + +// This function is documented as part of the Driver Development Kit but *not* +// the Windows Development Kit. +LOGICAL RtlFreeHeap(void* HeapHandle, DWORD Flags, + void* BaseAddress); + +// This function is documented as part of the Driver Development Kit but *not* +// the Windows Development Kit. +void* RtlAllocateHeap(void* HeapHandle, DWORD Flags, size_t Size); + +// This function is completely undocumented. +void* +RtlReAllocateHeap(void* HeapHandle, DWORD Flags, void* BaseAddress, + size_t Size); + +// This function is completely undocumented. +size_t RtlSizeHeap(void* HeapHandle, DWORD Flags, void* BaseAddress); + +INTERCEPTOR_WINAPI(size_t, RtlSizeHeap, HANDLE HeapHandle, DWORD Flags, + void* BaseAddress) { + if (!flags()->windows_hook_rtl_allocators || + UNLIKELY(!asan_inited || OWNED_BY_RTL(HeapHandle, BaseAddress))) { + return REAL(RtlSizeHeap)(HeapHandle, Flags, BaseAddress); + } + GET_CURRENT_PC_BP_SP; + (void)sp; + return asan_malloc_usable_size(BaseAddress, pc, bp); +} + +INTERCEPTOR_WINAPI(BOOL, RtlFreeHeap, HANDLE HeapHandle, DWORD Flags, + void* BaseAddress) { + // Heap allocations happen before this function is hooked, so we must fall + // back to the original function if the pointer is not from the ASAN heap, or + // unsupported flags are provided. + if (!flags()->windows_hook_rtl_allocators || + UNLIKELY((HEAP_FREE_UNSUPPORTED_FLAGS & Flags) != 0 || + OWNED_BY_RTL(HeapHandle, BaseAddress))) { + return REAL(RtlFreeHeap)(HeapHandle, Flags, BaseAddress); + } + GET_STACK_TRACE_FREE; + asan_free(BaseAddress, &stack, FROM_MALLOC); + return true; +} + +INTERCEPTOR_WINAPI(void*, RtlAllocateHeap, HANDLE HeapHandle, DWORD Flags, + size_t Size) { + // If the ASAN runtime is not initialized, or we encounter an unsupported + // flag, fall back to the original allocator. + if (!flags()->windows_hook_rtl_allocators || + UNLIKELY(!asan_inited || + (Flags & HEAP_ALLOCATE_UNSUPPORTED_FLAGS) != 0)) { + return REAL(RtlAllocateHeap)(HeapHandle, Flags, Size); + } + GET_STACK_TRACE_MALLOC; + void *p; + // Reading MSDN suggests that the *entire* usable allocation is zeroed out. + // Otherwise it is difficult to HeapReAlloc with HEAP_ZERO_MEMORY. + // https://blogs.msdn.microsoft.com/oldnewthing/20120316-00/?p=8083 + if (Flags & HEAP_ZERO_MEMORY) { + p = asan_calloc(Size, 1, &stack); + } else { + p = asan_malloc(Size, &stack); + } + return p; +} + +INTERCEPTOR_WINAPI(void*, RtlReAllocateHeap, HANDLE HeapHandle, DWORD Flags, + void* BaseAddress, size_t Size) { + // If it's actually a heap block which was allocated before the ASAN runtime + // came up, use the real RtlFreeHeap function. + if (!flags()->windows_hook_rtl_allocators) + return REAL(RtlReAllocateHeap)(HeapHandle, Flags, BaseAddress, Size); + + return SharedReAlloc(REAL(RtlReAllocateHeap), REAL(RtlSizeHeap), + REAL(RtlFreeHeap), REAL(RtlAllocateHeap), HeapHandle, + Flags, BaseAddress, Size); +} + +namespace __asan { + +static void TryToOverrideFunction(const char *fname, uptr new_func) { + // Failure here is not fatal. The CRT may not be present, and different CRT + // versions use different symbols. + if (!__interception::OverrideFunction(fname, new_func)) + VPrintf(2, "Failed to override function %s\n", fname); +} + +void ReplaceSystemMalloc() { +#if defined(ASAN_DYNAMIC) + TryToOverrideFunction("free", (uptr)free); + TryToOverrideFunction("_free_base", (uptr)free); + TryToOverrideFunction("malloc", (uptr)malloc); + TryToOverrideFunction("_malloc_base", (uptr)malloc); + TryToOverrideFunction("_malloc_crt", (uptr)malloc); + TryToOverrideFunction("calloc", (uptr)calloc); + TryToOverrideFunction("_calloc_base", (uptr)calloc); + TryToOverrideFunction("_calloc_crt", (uptr)calloc); + TryToOverrideFunction("realloc", (uptr)realloc); + TryToOverrideFunction("_realloc_base", (uptr)realloc); + TryToOverrideFunction("_realloc_crt", (uptr)realloc); + TryToOverrideFunction("_recalloc", (uptr)_recalloc); + TryToOverrideFunction("_recalloc_base", (uptr)_recalloc); + TryToOverrideFunction("_recalloc_crt", (uptr)_recalloc); + TryToOverrideFunction("_msize", (uptr)_msize); + TryToOverrideFunction("_msize_base", (uptr)_msize); + TryToOverrideFunction("_expand", (uptr)_expand); + TryToOverrideFunction("_expand_base", (uptr)_expand); + + if (flags()->windows_hook_rtl_allocators) { + INTERCEPT_FUNCTION(HeapSize); + INTERCEPT_FUNCTION(HeapFree); + INTERCEPT_FUNCTION(HeapReAlloc); + INTERCEPT_FUNCTION(HeapAlloc); + + // Undocumented functions must be intercepted by name, not by symbol. + __interception::OverrideFunction("RtlSizeHeap", (uptr)WRAP(RtlSizeHeap), + (uptr *)&REAL(RtlSizeHeap)); + __interception::OverrideFunction("RtlFreeHeap", (uptr)WRAP(RtlFreeHeap), + (uptr *)&REAL(RtlFreeHeap)); + __interception::OverrideFunction("RtlReAllocateHeap", + (uptr)WRAP(RtlReAllocateHeap), + (uptr *)&REAL(RtlReAllocateHeap)); + __interception::OverrideFunction("RtlAllocateHeap", + (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); + INTERCEPT_UCRT_FUNCTION(HeapAlloc); + INTERCEPT_UCRT_FUNCTION(HeapFree); + INTERCEPT_UCRT_FUNCTION(HeapReAlloc); + INTERCEPT_UCRT_FUNCTION(HeapSize); +#undef INTERCEPT_UCRT_FUNCTION + } + // Recent versions of ucrtbase.dll appear to be built with PGO and LTCG, which + // enable cross-module inlining. This means our _malloc_base hook won't catch + // all CRT allocations. This code here patches the import table of + // ucrtbase.dll so that all attempts to use the lower-level win32 heap + // allocation API will be directed to ASan's heap. We don't currently + // intercept all calls to HeapAlloc. If we did, we would have to check on + // HeapFree whether the pointer came from ASan of from the system. + +#endif // defined(ASAN_DYNAMIC) +} +} // namespace __asan + +#endif // _WIN32 diff --git a/libsanitizer/asan/asan_mapping.h b/libsanitizer/asan/asan_mapping.h index 2357c50e67f..41fb49ee46d 100644 --- a/libsanitizer/asan/asan_mapping.h +++ b/libsanitizer/asan/asan_mapping.h @@ -1,7 +1,8 @@ //===-- asan_mapping.h ------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -159,14 +160,10 @@ static const u64 kDefaultShadowOffset32 = 1ULL << 29; // 0x20000000 static const u64 kDefaultShadowOffset64 = 1ULL << 44; static const u64 kDefaultShort64bitShadowOffset = 0x7FFFFFFF & (~0xFFFULL << kDefaultShadowScale); // < 2G. -static const u64 kIosShadowOffset32 = 1ULL << 30; // 0x40000000 -static const u64 kIosShadowOffset64 = 0x120200000; -static const u64 kIosSimShadowOffset32 = 1ULL << 30; -static const u64 kIosSimShadowOffset64 = kDefaultShadowOffset64; static const u64 kAArch64_ShadowOffset64 = 1ULL << 36; static const u64 kMIPS32_ShadowOffset32 = 0x0aaa0000; static const u64 kMIPS64_ShadowOffset64 = 1ULL << 37; -static const u64 kPPC64_ShadowOffset64 = 1ULL << 41; +static const u64 kPPC64_ShadowOffset64 = 1ULL << 44; static const u64 kSystemZ_ShadowOffset64 = 1ULL << 52; static const u64 kSPARC64_ShadowOffset64 = 1ULL << 43; // 0x80000000000 static const u64 kFreeBSD_ShadowOffset32 = 1ULL << 30; // 0x40000000 @@ -200,11 +197,7 @@ static const u64 kMyriadCacheBitMask32 = 0x40000000ULL; # elif SANITIZER_WINDOWS # define SHADOW_OFFSET kWindowsShadowOffset32 # elif SANITIZER_IOS -# if SANITIZER_IOSSIM -# define SHADOW_OFFSET kIosSimShadowOffset32 -# else -# define SHADOW_OFFSET kIosShadowOffset32 -# endif +# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address # elif SANITIZER_MYRIAD2 # define SHADOW_OFFSET kMyriadShadowOffset32 # else @@ -212,11 +205,7 @@ static const u64 kMyriadCacheBitMask32 = 0x40000000ULL; # endif #else # if SANITIZER_IOS -# if SANITIZER_IOSSIM -# define SHADOW_OFFSET kIosSimShadowOffset64 -# else -# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address -# endif +# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address # elif defined(__aarch64__) # define SHADOW_OFFSET kAArch64_ShadowOffset64 # elif defined(__powerpc64__) @@ -231,8 +220,8 @@ static const u64 kMyriadCacheBitMask32 = 0x40000000ULL; # define SHADOW_OFFSET kDefaultShadowOffset64 # elif defined(__mips64) # define SHADOW_OFFSET kMIPS64_ShadowOffset64 -# elif defined(__sparc__) -# define SHADOW_OFFSET kSPARC64_ShadowOffset64 +#elif defined(__sparc__) +#define SHADOW_OFFSET kSPARC64_ShadowOffset64 # elif SANITIZER_WINDOWS64 # define SHADOW_OFFSET __asan_shadow_memory_dynamic_address # else diff --git a/libsanitizer/asan/asan_mapping_myriad.h b/libsanitizer/asan/asan_mapping_myriad.h index fa8d4fe0270..6969e3a4931 100644 --- a/libsanitizer/asan/asan_mapping_myriad.h +++ b/libsanitizer/asan/asan_mapping_myriad.h @@ -1,7 +1,8 @@ //===-- asan_mapping_myriad.h -----------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_mapping_sparc64.h b/libsanitizer/asan/asan_mapping_sparc64.h index ecde5cac9e1..432a1816f79 100644 --- a/libsanitizer/asan/asan_mapping_sparc64.h +++ b/libsanitizer/asan/asan_mapping_sparc64.h @@ -1,7 +1,8 @@ //===-- asan_mapping_sparc64.h ----------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_memory_profile.cc b/libsanitizer/asan/asan_memory_profile.cpp similarity index 93% rename from libsanitizer/asan/asan_memory_profile.cc rename to libsanitizer/asan/asan_memory_profile.cpp index 23183bda79b..4fcd5600ed1 100644 --- a/libsanitizer/asan/asan_memory_profile.cc +++ b/libsanitizer/asan/asan_memory_profile.cpp @@ -1,7 +1,8 @@ -//===-- asan_memory_profile.cc.cc -----------------------------------------===// +//===-- asan_memory_profile.cpp ----------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_new_delete.cc b/libsanitizer/asan/asan_new_delete.cpp similarity index 88% rename from libsanitizer/asan/asan_new_delete.cc rename to libsanitizer/asan/asan_new_delete.cpp index 7e194e2229c..c15e208094e 100644 --- a/libsanitizer/asan/asan_new_delete.cc +++ b/libsanitizer/asan/asan_new_delete.cpp @@ -1,7 +1,8 @@ -//===-- asan_interceptors.cc ----------------------------------------------===// +//===-- asan_interceptors.cpp ---------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -70,25 +71,19 @@ enum class align_val_t: size_t {}; // TODO(alekseyshl): throw std::bad_alloc instead of dying on OOM. // For local pool allocation, align to SHADOW_GRANULARITY to match asan // allocator behavior. -#define OPERATOR_NEW_BODY(type, nothrow) \ - if (ALLOCATE_FROM_LOCAL_POOL) {\ - void *res = MemalignFromLocalPool(SHADOW_GRANULARITY, size);\ - if (!nothrow) CHECK(res);\ - return res;\ - }\ - GET_STACK_TRACE_MALLOC;\ - void *res = asan_memalign(0, size, &stack, type);\ - if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\ +#define OPERATOR_NEW_BODY(type, nothrow) \ + MAYBE_ALLOCATE_FROM_LOCAL_POOL(nothrow); \ + GET_STACK_TRACE_MALLOC; \ + void *res = asan_memalign(0, size, &stack, type); \ + if (!nothrow && UNLIKELY(!res)) \ + ReportOutOfMemory(size, &stack); \ return res; -#define OPERATOR_NEW_BODY_ALIGN(type, nothrow) \ - if (ALLOCATE_FROM_LOCAL_POOL) {\ - void *res = MemalignFromLocalPool((uptr)align, size);\ - if (!nothrow) CHECK(res);\ - return res;\ - }\ - GET_STACK_TRACE_MALLOC;\ - void *res = asan_memalign((uptr)align, size, &stack, type);\ - if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\ +#define OPERATOR_NEW_BODY_ALIGN(type, nothrow) \ + MAYBE_ALLOCATE_FROM_LOCAL_POOL(nothrow); \ + GET_STACK_TRACE_MALLOC; \ + void *res = asan_memalign((uptr)align, size, &stack, type); \ + if (!nothrow && UNLIKELY(!res)) \ + ReportOutOfMemory(size, &stack); \ return res; // On OS X it's not enough to just provide our own 'operator new' and diff --git a/libsanitizer/asan/asan_poisoning.cc b/libsanitizer/asan/asan_poisoning.cpp similarity index 98% rename from libsanitizer/asan/asan_poisoning.cc rename to libsanitizer/asan/asan_poisoning.cpp index 35409baf612..6b36be7d1cd 100644 --- a/libsanitizer/asan/asan_poisoning.cc +++ b/libsanitizer/asan/asan_poisoning.cpp @@ -1,7 +1,8 @@ -//===-- asan_poisoning.cc -------------------------------------------------===// +//===-- asan_poisoning.cpp ------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_poisoning.h b/libsanitizer/asan/asan_poisoning.h index 7e8c5886831..62dd9bd0edd 100644 --- a/libsanitizer/asan/asan_poisoning.h +++ b/libsanitizer/asan/asan_poisoning.h @@ -1,7 +1,8 @@ //===-- asan_poisoning.h ----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -14,6 +15,7 @@ #include "asan_internal.h" #include "asan_mapping.h" #include "sanitizer_common/sanitizer_flags.h" +#include "sanitizer_common/sanitizer_platform.h" namespace __asan { @@ -37,6 +39,10 @@ void PoisonShadowPartialRightRedzone(uptr addr, ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size, u8 value) { DCHECK(!value || CanPoisonMemory()); +#if SANITIZER_FUCHSIA + __sanitizer_fill_shadow(aligned_beg, aligned_size, value, + common_flags()->clear_shadow_mmap_threshold); +#else uptr shadow_beg = MEM_TO_SHADOW(aligned_beg); uptr shadow_end = MEM_TO_SHADOW( aligned_beg + aligned_size - SHADOW_GRANULARITY) + 1; @@ -45,10 +51,6 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size, // probably provide higher-level interface for these operations. // For now, just memset on Windows. if (value || SANITIZER_WINDOWS == 1 || - // TODO(mcgrathr): Fuchsia doesn't allow the shadow mapping to be - // changed at all. It doesn't currently have an efficient means - // to zero a bunch of pages, but maybe we should add one. - SANITIZER_FUCHSIA == 1 || // RTEMS doesn't have have pages, let alone a fast way to zero // them, so default to memset. SANITIZER_RTEMS == 1 || @@ -71,6 +73,7 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size, ReserveShadowMemoryRange(page_beg, page_end - 1, nullptr); } } +#endif // SANITIZER_FUCHSIA } ALWAYS_INLINE void FastPoisonShadowPartialRightRedzone( diff --git a/libsanitizer/asan/asan_posix.cc b/libsanitizer/asan/asan_posix.cpp similarity index 57% rename from libsanitizer/asan/asan_posix.cc rename to libsanitizer/asan/asan_posix.cpp index d765dc79c51..920d216624a 100644 --- a/libsanitizer/asan/asan_posix.cc +++ b/libsanitizer/asan/asan_posix.cpp @@ -1,7 +1,8 @@ -//===-- asan_posix.cc -----------------------------------------------------===// +//===-- asan_posix.cpp ----------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -38,6 +39,51 @@ void AsanOnDeadlySignal(int signo, void *siginfo, void *context) { // ---------------------- TSD ---------------- {{{1 +#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. + +static void (*tsd_destructor)(void *tsd) = nullptr; + +struct tsd_key { + tsd_key() : key(nullptr) {} + ~tsd_key() { + CHECK(tsd_destructor); + if (key) + (*tsd_destructor)(key); + } + void *key; +}; + +static thread_local struct tsd_key key; + +void AsanTSDInit(void (*destructor)(void *tsd)) { + CHECK(!tsd_destructor); + tsd_destructor = destructor; +} + +void *AsanTSDGet() { + CHECK(tsd_destructor); + return key.key; +} + +void AsanTSDSet(void *tsd) { + CHECK(tsd_destructor); + CHECK(tsd); + CHECK(!key.key); + key.key = tsd; +} + +void PlatformTSDDtor(void *tsd) { + CHECK(tsd_destructor); + CHECK_EQ(key.key, tsd); + key.key = nullptr; + // Make sure that signal handler can not see a stale current thread pointer. + atomic_signal_fence(memory_order_seq_cst); + AsanThread::TSDDtor(tsd); +} +#else static pthread_key_t tsd_key; static bool tsd_key_inited = false; void AsanTSDInit(void (*destructor)(void *tsd)) { @@ -65,6 +111,7 @@ void PlatformTSDDtor(void *tsd) { } AsanThread::TSDDtor(tsd); } +#endif } // namespace __asan #endif // SANITIZER_POSIX diff --git a/libsanitizer/asan/asan_preinit.cc b/libsanitizer/asan/asan_preinit.cpp similarity index 74% rename from libsanitizer/asan/asan_preinit.cc rename to libsanitizer/asan/asan_preinit.cpp index 6cb115bd369..b07556ec96f 100644 --- a/libsanitizer/asan/asan_preinit.cc +++ b/libsanitizer/asan/asan_preinit.cpp @@ -1,7 +1,8 @@ -//===-- asan_preinit.cc ---------------------------------------------------===// +//===-- asan_preinit.cpp --------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_premap_shadow.cc b/libsanitizer/asan/asan_premap_shadow.cpp similarity index 90% rename from libsanitizer/asan/asan_premap_shadow.cc rename to libsanitizer/asan/asan_premap_shadow.cpp index 4273ae5e389..7835e99748f 100644 --- a/libsanitizer/asan/asan_premap_shadow.cc +++ b/libsanitizer/asan/asan_premap_shadow.cpp @@ -1,7 +1,8 @@ -//===-- asan_premap_shadow.cc ---------------------------------------------===// +//===-- asan_premap_shadow.cpp --------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_premap_shadow.h b/libsanitizer/asan/asan_premap_shadow.h index 345b56ea6a6..c9c886e8dca 100644 --- a/libsanitizer/asan/asan_premap_shadow.h +++ b/libsanitizer/asan/asan_premap_shadow.h @@ -1,7 +1,8 @@ //===-- asan_mapping.h ------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_report.cc b/libsanitizer/asan/asan_report.cpp similarity index 96% rename from libsanitizer/asan/asan_report.cc rename to libsanitizer/asan/asan_report.cpp index 787b6890a34..d36b0b4c594 100644 --- a/libsanitizer/asan/asan_report.cc +++ b/libsanitizer/asan/asan_report.cpp @@ -1,7 +1,8 @@ -//===-- asan_report.cc ----------------------------------------------------===// +//===-- asan_report.cpp ---------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -189,7 +190,7 @@ class ScopedInErrorReport { void ReportError(const ErrorDescription &description) { // Can only report one error per ScopedInErrorReport. CHECK_EQ(current_error_.kind, kErrorKindInvalid); - current_error_ = description; + internal_memcpy(¤t_error_, &description, sizeof(current_error_)); } static ErrorDescription &CurrentError() { @@ -262,6 +263,13 @@ void ReportCallocOverflow(uptr count, uptr size, BufferedStackTrace *stack) { in_report.ReportError(error); } +void ReportReallocArrayOverflow(uptr count, uptr size, + BufferedStackTrace *stack) { + ScopedInErrorReport in_report(/*fatal*/ true); + ErrorReallocArrayOverflow error(GetCurrentTidOrInvalid(), stack, count, size); + in_report.ReportError(error); +} + void ReportPvallocOverflow(uptr size, BufferedStackTrace *stack) { ScopedInErrorReport in_report(/*fatal*/ true); ErrorPvallocOverflow error(GetCurrentTidOrInvalid(), stack, size); diff --git a/libsanitizer/asan/asan_report.h b/libsanitizer/asan/asan_report.h index b48605da41e..dcf60894ef3 100644 --- a/libsanitizer/asan/asan_report.h +++ b/libsanitizer/asan/asan_report.h @@ -1,7 +1,8 @@ //===-- asan_report.h -------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -60,6 +61,8 @@ void ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack); void ReportSanitizerGetAllocatedSizeNotOwned(uptr addr, BufferedStackTrace *stack); void ReportCallocOverflow(uptr count, uptr size, BufferedStackTrace *stack); +void ReportReallocArrayOverflow(uptr count, uptr size, + BufferedStackTrace *stack); void ReportPvallocOverflow(uptr size, BufferedStackTrace *stack); void ReportInvalidAllocationAlignment(uptr alignment, BufferedStackTrace *stack); diff --git a/libsanitizer/asan/asan_rtems.cc b/libsanitizer/asan/asan_rtems.cpp similarity index 93% rename from libsanitizer/asan/asan_rtems.cc rename to libsanitizer/asan/asan_rtems.cpp index fa68373e63a..360d5780a3f 100644 --- a/libsanitizer/asan/asan_rtems.cc +++ b/libsanitizer/asan/asan_rtems.cpp @@ -1,7 +1,8 @@ -//===-- asan_rtems.cc -----------------------------------------------------===// +//===-- asan_rtems.cpp ----------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -182,8 +183,8 @@ static void ThreadStartHook(void *hook, uptr os_id) { // Determine whether we are starting or restarting the thread. if (status == ThreadStatusCreated) // In lieu of AsanThread::ThreadStart. - asanThreadRegistry().StartThread(thread->tid(), os_id, - /*workerthread*/ false, nullptr); + asanThreadRegistry().StartThread(thread->tid(), os_id, ThreadType::Regular, + nullptr); else { // In a thread restart, a thread may resume execution at an // arbitrary function entry point, with its stack and TLS state @@ -211,6 +212,12 @@ static void HandleExit() { } } +bool HandleDlopenInit() { + // Not supported on this platform. + static_assert(!SANITIZER_SUPPORTS_INIT_FOR_DLOPEN, + "Expected SANITIZER_SUPPORTS_INIT_FOR_DLOPEN to be false"); + return false; +} } // namespace __asan // These are declared (in extern "C") by . diff --git a/libsanitizer/asan/asan_rtl.cc b/libsanitizer/asan/asan_rtl.cpp similarity index 94% rename from libsanitizer/asan/asan_rtl.cc rename to libsanitizer/asan/asan_rtl.cpp index ba3acf2c5d2..b16ca950518 100644 --- a/libsanitizer/asan/asan_rtl.cc +++ b/libsanitizer/asan/asan_rtl.cpp @@ -1,7 +1,8 @@ -//===-- asan_rtl.cc -------------------------------------------------------===// +//===-- asan_rtl.cpp ------------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -381,6 +382,19 @@ void PrintAddressSpaceLayout() { kHighShadowBeg > kMidMemEnd); } +#if defined(__thumb__) && defined(__linux__) +#define START_BACKGROUND_THREAD_IN_ASAN_INTERNAL +#endif + +#ifndef START_BACKGROUND_THREAD_IN_ASAN_INTERNAL +static bool UNUSED __local_asan_dyninit = [] { + MaybeStartBackgroudThread(); + SetSoftRssLimitExceededCallback(AsanSoftRssLimitExceededCallback); + + return false; +}(); +#endif + static void AsanInitInternal() { if (LIKELY(asan_inited)) return; SanitizerToolName = "AddressSanitizer"; @@ -394,6 +408,14 @@ static void AsanInitInternal() { // initialization steps look at flags(). InitializeFlags(); + // Stop performing init at this point if we are being loaded via + // dlopen() and the platform supports it. + if (SANITIZER_SUPPORTS_INIT_FOR_DLOPEN && UNLIKELY(HandleDlopenInit())) { + asan_init_is_running = false; + VReport(1, "AddressSanitizer init is being performed for dlopen().\n"); + return; + } + AsanCheckIncompatibleRT(); AsanCheckDynamicRTPrereqs(); AvoidCVE_2016_2143(); @@ -418,6 +440,8 @@ static void AsanInitInternal() { __asan_option_detect_stack_use_after_return = flags()->detect_stack_use_after_return; + __sanitizer::InitializePlatformEarly(); + // Re-exec ourselves if we need to set additional env or command line args. MaybeReexec(); @@ -445,8 +469,10 @@ static void AsanInitInternal() { allocator_options.SetFrom(flags(), common_flags()); InitializeAllocator(allocator_options); +#ifdef START_BACKGROUND_THREAD_IN_ASAN_INTERNAL MaybeStartBackgroudThread(); SetSoftRssLimitExceededCallback(AsanSoftRssLimitExceededCallback); +#endif // On Linux AsanThread::ThreadStart() calls malloc() that's why asan_inited // should be set to 1 prior to initializing the threads. @@ -571,6 +597,19 @@ void NOINLINE __asan_handle_no_return() { curr_thread->fake_stack()->HandleNoReturn(); } +extern "C" void *__asan_extra_spill_area() { + AsanThread *t = GetCurrentThread(); + CHECK(t); + return t->extra_spill_area(); +} + +void __asan_handle_vfork(void *sp) { + AsanThread *t = GetCurrentThread(); + CHECK(t); + uptr bottom = t->stack_bottom(); + PoisonShadow(bottom, (uptr)sp - bottom, 0); +} + void NOINLINE __asan_set_death_callback(void (*callback)(void)) { SetUserDieCallback(callback); } diff --git a/libsanitizer/asan/asan_scariness_score.h b/libsanitizer/asan/asan_scariness_score.h index aa947ed2732..9e7ba47d82d 100644 --- a/libsanitizer/asan/asan_scariness_score.h +++ b/libsanitizer/asan/asan_scariness_score.h @@ -1,7 +1,8 @@ //===-- asan_scariness_score.h ----------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_shadow_setup.cc b/libsanitizer/asan/asan_shadow_setup.cpp similarity index 94% rename from libsanitizer/asan/asan_shadow_setup.cc rename to libsanitizer/asan/asan_shadow_setup.cpp index 823187bf5f1..fc9bf51e1b5 100644 --- a/libsanitizer/asan/asan_shadow_setup.cc +++ b/libsanitizer/asan/asan_shadow_setup.cpp @@ -1,7 +1,8 @@ -//===-- asan_shadow_setup.cc ----------------------------------------------===// +//===-- asan_shadow_setup.cpp ---------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -12,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 @@ -36,7 +37,7 @@ void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name) { size); Abort(); } - 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/libsanitizer/asan/asan_stack.cc b/libsanitizer/asan/asan_stack.cc deleted file mode 100644 index 973c5ce59ef..00000000000 --- a/libsanitizer/asan/asan_stack.cc +++ /dev/null @@ -1,38 +0,0 @@ -//===-- asan_stack.cc -----------------------------------------------------===// -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file is a part of AddressSanitizer, an address sanity checker. -// -// Code for ASan stack trace. -//===----------------------------------------------------------------------===// -#include "asan_internal.h" -#include "asan_stack.h" -#include "sanitizer_common/sanitizer_atomic.h" - -namespace __asan { - -static atomic_uint32_t malloc_context_size; - -void SetMallocContextSize(u32 size) { - atomic_store(&malloc_context_size, size, memory_order_release); -} - -u32 GetMallocContextSize() { - return atomic_load(&malloc_context_size, memory_order_acquire); -} - -} // namespace __asan - -// ------------------ Interface -------------- {{{1 - -extern "C" { -SANITIZER_INTERFACE_ATTRIBUTE -void __sanitizer_print_stack_trace() { - using namespace __asan; - PRINT_CURRENT_STACK(); -} -} // extern "C" diff --git a/libsanitizer/asan/asan_stack.cpp b/libsanitizer/asan/asan_stack.cpp new file mode 100644 index 00000000000..b7f4e6aeeab --- /dev/null +++ b/libsanitizer/asan/asan_stack.cpp @@ -0,0 +1,88 @@ +//===-- 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. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Code for ASan stack trace. +//===----------------------------------------------------------------------===// +#include "asan_internal.h" +#include "asan_stack.h" +#include "sanitizer_common/sanitizer_atomic.h" + +namespace __asan { + +static atomic_uint32_t malloc_context_size; + +void SetMallocContextSize(u32 size) { + atomic_store(&malloc_context_size, size, memory_order_release); +} + +u32 GetMallocContextSize() { + return atomic_load(&malloc_context_size, memory_order_acquire); +} + +namespace { + +// ScopedUnwinding is a scope for stacktracing member of a context +class ScopedUnwinding { + public: + explicit ScopedUnwinding(AsanThread *t) : thread(t) { + if (thread) { + can_unwind = !thread->isUnwinding(); + thread->setUnwinding(true); + } + } + ~ScopedUnwinding() { + if (thread) + thread->setUnwinding(false); + } + + bool CanUnwind() const { return can_unwind; } + + private: + AsanThread *thread = nullptr; + bool can_unwind = true; +}; + +} // namespace + +} // namespace __asan + +void __sanitizer::BufferedStackTrace::UnwindImpl( + uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) { + using namespace __asan; + size = 0; + if (UNLIKELY(!asan_inited)) + return; + request_fast = StackTrace::WillUseFastUnwind(request_fast); + AsanThread *t = GetCurrentThread(); + ScopedUnwinding unwind_scope(t); + if (!unwind_scope.CanUnwind()) + return; + if (request_fast) { + if (t) { + Unwind(max_depth, pc, bp, nullptr, t->stack_top(), t->stack_bottom(), + true); + } + return; + } + if (SANITIZER_MIPS && t && + !IsValidFrame(bp, t->stack_top(), t->stack_bottom())) + return; + Unwind(max_depth, pc, bp, context, 0, 0, false); +} + +// ------------------ Interface -------------- {{{1 + +extern "C" { +SANITIZER_INTERFACE_ATTRIBUTE +void __sanitizer_print_stack_trace() { + using namespace __asan; + PRINT_CURRENT_STACK(); +} +} // extern "C" diff --git a/libsanitizer/asan/asan_stack.h b/libsanitizer/asan/asan_stack.h index 5775e9d325c..4089d3d7340 100644 --- a/libsanitizer/asan/asan_stack.h +++ b/libsanitizer/asan/asan_stack.h @@ -1,13 +1,14 @@ //===-- asan_stack.h --------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 AddressSanitizer, an address sanity checker. // -// ASan-private header for asan_stack.cc. +// ASan-private header for asan_stack.cpp. //===----------------------------------------------------------------------===// #ifndef ASAN_STACK_H @@ -25,34 +26,6 @@ static const u32 kDefaultMallocContextSize = 30; void SetMallocContextSize(u32 size); u32 GetMallocContextSize(); -// Get the stack trace with the given pc and bp. -// The pc will be in the position 0 of the resulting stack trace. -// The bp may refer to the current frame or to the caller's frame. -ALWAYS_INLINE -void GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, uptr bp, - void *context, bool fast) { -#if SANITIZER_WINDOWS - stack->Unwind(max_depth, pc, bp, context, 0, 0, fast); -#else - AsanThread *t; - stack->size = 0; - if (LIKELY(asan_inited)) { - if ((t = GetCurrentThread()) && !t->isUnwinding()) { - uptr stack_top = t->stack_top(); - uptr stack_bottom = t->stack_bottom(); - ScopedUnwinding unwind_scope(t); - if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) { - stack->Unwind(max_depth, pc, bp, context, stack_top, stack_bottom, - fast); - } - } else if (!t && !fast) { - /* If GetCurrentThread() has failed, try to do slow unwind anyways. */ - stack->Unwind(max_depth, pc, bp, context, 0, 0, false); - } - } -#endif // SANITIZER_WINDOWS -} - } // namespace __asan // NOTE: A Rule of thumb is to retrieve stack trace in the interceptors @@ -69,19 +42,19 @@ void GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, uptr bp, if (max_size > 1) stack.trace_buffer[1] = GET_CALLER_PC(); \ } \ } else { \ - GetStackTrace(&stack, max_size, StackTrace::GetCurrentPc(), \ - GET_CURRENT_FRAME(), 0, fast); \ + stack.Unwind(StackTrace::GetCurrentPc(), \ + GET_CURRENT_FRAME(), nullptr, fast, max_size); \ } #define GET_STACK_TRACE_FATAL(pc, bp) \ BufferedStackTrace stack; \ - GetStackTrace(&stack, kStackTraceMax, pc, bp, 0, \ - common_flags()->fast_unwind_on_fatal) + stack.Unwind(pc, bp, nullptr, \ + common_flags()->fast_unwind_on_fatal) #define GET_STACK_TRACE_SIGNAL(sig) \ BufferedStackTrace stack; \ - GetStackTrace(&stack, kStackTraceMax, (sig).pc, (sig).bp, (sig).context, \ - common_flags()->fast_unwind_on_fatal) + stack.Unwind((sig).pc, (sig).bp, (sig).context, \ + common_flags()->fast_unwind_on_fatal) #define GET_STACK_TRACE_FATAL_HERE \ GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_fatal) diff --git a/libsanitizer/asan/asan_stats.cc b/libsanitizer/asan/asan_stats.cpp similarity index 95% rename from libsanitizer/asan/asan_stats.cc rename to libsanitizer/asan/asan_stats.cpp index 64a788a6a5d..bc4e8c15cc1 100644 --- a/libsanitizer/asan/asan_stats.cc +++ b/libsanitizer/asan/asan_stats.cpp @@ -1,7 +1,8 @@ -//===-- asan_stats.cc -----------------------------------------------------===// +//===-- asan_stats.cpp ----------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_stats.h b/libsanitizer/asan/asan_stats.h index a48e3f916a9..d6da6534081 100644 --- a/libsanitizer/asan/asan_stats.h +++ b/libsanitizer/asan/asan_stats.h @@ -1,7 +1,8 @@ //===-- asan_stats.h --------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_suppressions.cc b/libsanitizer/asan/asan_suppressions.cpp similarity index 92% rename from libsanitizer/asan/asan_suppressions.cc rename to libsanitizer/asan/asan_suppressions.cpp index 00406020054..a9c0d107694 100644 --- a/libsanitizer/asan/asan_suppressions.cc +++ b/libsanitizer/asan/asan_suppressions.cpp @@ -1,7 +1,8 @@ -//===-- asan_suppressions.cc ----------------------------------------------===// +//===-- asan_suppressions.cpp ---------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/asan/asan_suppressions.h b/libsanitizer/asan/asan_suppressions.h index 331d7224548..121d4ddf187 100644 --- a/libsanitizer/asan/asan_suppressions.h +++ b/libsanitizer/asan/asan_suppressions.h @@ -1,13 +1,14 @@ //===-- asan_suppressions.h -------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 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/libsanitizer/asan/asan_thread.cc b/libsanitizer/asan/asan_thread.cpp similarity index 95% rename from libsanitizer/asan/asan_thread.cc rename to libsanitizer/asan/asan_thread.cpp index 82da9a28e82..d48b3414dd5 100644 --- a/libsanitizer/asan/asan_thread.cc +++ b/libsanitizer/asan/asan_thread.cpp @@ -1,7 +1,8 @@ -//===-- asan_thread.cc ----------------------------------------------------===// +//===-- asan_thread.cpp ---------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -221,9 +222,11 @@ void AsanThread::Init(const InitOptions *options) { atomic_store(&stack_switching_, false, memory_order_release); CHECK_EQ(this->stack_size(), 0U); SetThreadStackAndTls(options); - CHECK_GT(this->stack_size(), 0U); - CHECK(AddrIsInMem(stack_bottom_)); - CHECK(AddrIsInMem(stack_top_ - 1)); + if (stack_top_ != stack_bottom_) { + CHECK_GT(this->stack_size(), 0U); + CHECK(AddrIsInMem(stack_bottom_)); + CHECK(AddrIsInMem(stack_top_ - 1)); + } ClearShadowForThreadStackAndTLS(); fake_stack_ = nullptr; if (__asan_option_detect_stack_use_after_return) @@ -242,8 +245,7 @@ void AsanThread::Init(const InitOptions *options) { thread_return_t AsanThread::ThreadStart( tid_t os_id, atomic_uintptr_t *signal_thread_is_registered) { Init(); - asanThreadRegistry().StartThread(tid(), os_id, /*workerthread*/ false, - nullptr); + asanThreadRegistry().StartThread(tid(), os_id, ThreadType::Regular, nullptr); if (signal_thread_is_registered) atomic_store(signal_thread_is_registered, 1, memory_order_release); @@ -287,20 +289,23 @@ void AsanThread::SetThreadStackAndTls(const InitOptions *options) { DCHECK_EQ(options, nullptr); uptr tls_size = 0; uptr stack_size = 0; - GetThreadStackAndTls(tid() == 0, const_cast(&stack_bottom_), - const_cast(&stack_size), &tls_begin_, &tls_size); + GetThreadStackAndTls(tid() == 0, &stack_bottom_, &stack_size, &tls_begin_, + &tls_size); stack_top_ = stack_bottom_ + stack_size; tls_end_ = tls_begin_ + tls_size; dtls_ = DTLS_Get(); - int local; - CHECK(AddrIsInStack((uptr)&local)); + if (stack_top_ != stack_bottom_) { + int local; + CHECK(AddrIsInStack((uptr)&local)); + } } #endif // !SANITIZER_FUCHSIA && !SANITIZER_RTEMS void AsanThread::ClearShadowForThreadStackAndTLS() { - PoisonShadow(stack_bottom_, stack_top_ - stack_bottom_, 0); + if (stack_top_ != stack_bottom_) + PoisonShadow(stack_bottom_, stack_top_ - stack_bottom_, 0); if (tls_begin_ != tls_end_) { uptr tls_begin_aligned = RoundDownTo(tls_begin_, SHADOW_GRANULARITY); uptr tls_end_aligned = RoundUpTo(tls_end_, SHADOW_GRANULARITY); @@ -312,6 +317,9 @@ void AsanThread::ClearShadowForThreadStackAndTLS() { bool AsanThread::GetStackFrameAccessByAddr(uptr addr, StackFrameAccess *access) { + if (stack_top_ == stack_bottom_) + return false; + uptr bottom = 0; if (AddrIsInStack(addr)) { bottom = stack_bottom(); diff --git a/libsanitizer/asan/asan_thread.h b/libsanitizer/asan/asan_thread.h index 187cb13e85b..c503f507059 100644 --- a/libsanitizer/asan/asan_thread.h +++ b/libsanitizer/asan/asan_thread.h @@ -1,13 +1,14 @@ //===-- asan_thread.h -------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 AddressSanitizer, an address sanity checker. // -// ASan-private header for asan_thread.cc. +// ASan-private header for asan_thread.cpp. //===----------------------------------------------------------------------===// #ifndef ASAN_THREAD_H @@ -129,6 +130,8 @@ class AsanThread { AsanThreadLocalMallocStorage &malloc_storage() { return malloc_storage_; } AsanStats &stats() { return stats_; } + void *extra_spill_area() { return &extra_spill_area_; } + private: // NOTE: There is no AsanThread constructor. It is allocated // via mmap() and *must* be valid in zero-initialized state. @@ -164,18 +167,7 @@ class AsanThread { AsanThreadLocalMallocStorage malloc_storage_; AsanStats stats_; bool unwinding_; -}; - -// ScopedUnwinding is a scope for stacktracing member of a context -class ScopedUnwinding { - public: - explicit ScopedUnwinding(AsanThread *t) : thread(t) { - t->setUnwinding(true); - } - ~ScopedUnwinding() { thread->setUnwinding(false); } - - private: - AsanThread *thread; + uptr extra_spill_area_; }; // Returns a single instance of registry. diff --git a/libsanitizer/asan/asan_win.cc b/libsanitizer/asan/asan_win.cpp similarity index 75% rename from libsanitizer/asan/asan_win.cc rename to libsanitizer/asan/asan_win.cpp index 8473f59c78a..f8b98ca3366 100644 --- a/libsanitizer/asan/asan_win.cc +++ b/libsanitizer/asan/asan_win.cpp @@ -1,7 +1,8 @@ -//===-- asan_win.cc -------------------------------------------------------===// +//===-- asan_win.cpp ------------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -19,10 +20,10 @@ #include "asan_interceptors.h" #include "asan_internal.h" +#include "asan_mapping.h" #include "asan_report.h" #include "asan_stack.h" #include "asan_thread.h" -#include "asan_mapping.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_mutex.h" #include "sanitizer_common/sanitizer_win.h" @@ -76,7 +77,7 @@ static long WINAPI SEHHandler(EXCEPTION_POINTERS *info) { } INTERCEPTOR_WINAPI(LPTOP_LEVEL_EXCEPTION_FILTER, SetUnhandledExceptionFilter, - LPTOP_LEVEL_EXCEPTION_FILTER ExceptionFilter) { + LPTOP_LEVEL_EXCEPTION_FILTER ExceptionFilter) { CHECK(REAL(SetUnhandledExceptionFilter)); if (ExceptionFilter == &SEHHandler) return REAL(SetUnhandledExceptionFilter)(ExceptionFilter); @@ -103,7 +104,9 @@ INTERCEPTOR_WINAPI(void, RaiseException, void *a, void *b, void *c, void *d) { #ifdef _WIN64 -INTERCEPTOR_WINAPI(int, __C_specific_handler, void *a, void *b, void *c, void *d) { // NOLINT +INTERCEPTOR_WINAPI(EXCEPTION_DISPOSITION, __C_specific_handler, + _EXCEPTION_RECORD *a, void *b, _CONTEXT *c, + _DISPATCHER_CONTEXT *d) { // NOLINT CHECK(REAL(__C_specific_handler)); __asan_handle_no_return(); return REAL(__C_specific_handler)(a, b, c, d); @@ -129,15 +132,14 @@ INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) { #endif static thread_return_t THREAD_CALLING_CONV asan_thread_start(void *arg) { - AsanThread *t = (AsanThread*)arg; + AsanThread *t = (AsanThread *)arg; SetCurrentThread(t); return t->ThreadStart(GetTid(), /* signal_thread_is_registered */ nullptr); } -INTERCEPTOR_WINAPI(DWORD, CreateThread, - void* security, uptr stack_size, - DWORD (__stdcall *start_routine)(void*), void* arg, - DWORD thr_flags, void* tid) { +INTERCEPTOR_WINAPI(HANDLE, CreateThread, LPSECURITY_ATTRIBUTES security, + SIZE_T stack_size, LPTHREAD_START_ROUTINE start_routine, + void *arg, DWORD thr_flags, DWORD *tid) { // Strict init-order checking is thread-hostile. if (flags()->strict_init_order) StopInitOrderChecking(); @@ -147,9 +149,9 @@ INTERCEPTOR_WINAPI(DWORD, CreateThread, bool detached = false; // FIXME: how can we determine it on Windows? u32 current_tid = GetCurrentTidOrInvalid(); AsanThread *t = - AsanThread::Create(start_routine, arg, current_tid, &stack, detached); - return REAL(CreateThread)(security, stack_size, - asan_thread_start, t, thr_flags, tid); + AsanThread::Create(start_routine, arg, current_tid, &stack, detached); + return REAL(CreateThread)(security, stack_size, asan_thread_start, t, + thr_flags, tid); } // }}} @@ -160,10 +162,9 @@ void InitializePlatformInterceptors() { // The interceptors were not designed to be removable, so we have to keep this // module alive for the life of the process. HMODULE pinned; - CHECK(GetModuleHandleExW(GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | - GET_MODULE_HANDLE_EX_FLAG_PIN, - (LPCWSTR)&InitializePlatformInterceptors, - &pinned)); + CHECK(GetModuleHandleExW( + GET_MODULE_HANDLE_EX_FLAG_FROM_ADDRESS | GET_MODULE_HANDLE_EX_FLAG_PIN, + (LPCWSTR)&InitializePlatformInterceptors, &pinned)); ASAN_INTERCEPT_FUNC(CreateThread); ASAN_INTERCEPT_FUNC(SetUnhandledExceptionFilter); @@ -195,6 +196,30 @@ static bool tsd_key_inited = false; static __declspec(thread) void *fake_tsd = 0; +// https://docs.microsoft.com/en-us/windows/desktop/api/winternl/ns-winternl-_teb +// "[This structure may be altered in future versions of Windows. Applications +// should use the alternate functions listed in this topic.]" +typedef struct _TEB { + PVOID Reserved1[12]; + // PVOID ThreadLocalStoragePointer; is here, at the last field in Reserved1. + PVOID ProcessEnvironmentBlock; + PVOID Reserved2[399]; + BYTE Reserved3[1952]; + PVOID TlsSlots[64]; + BYTE Reserved4[8]; + PVOID Reserved5[26]; + PVOID ReservedForOle; + PVOID Reserved6[4]; + PVOID TlsExpansionSlots; +} TEB, *PTEB; + +constexpr size_t TEB_RESERVED_FIELDS_THREAD_LOCAL_STORAGE_OFFSET = 11; +BOOL IsTlsInitialized() { + PTEB teb = (PTEB)NtCurrentTeb(); + return teb->Reserved1[TEB_RESERVED_FIELDS_THREAD_LOCAL_STORAGE_OFFSET] != + nullptr; +} + void AsanTSDInit(void (*destructor)(void *tsd)) { // FIXME: we're ignoring the destructor for now. tsd_key_inited = true; @@ -202,7 +227,7 @@ void AsanTSDInit(void (*destructor)(void *tsd)) { void *AsanTSDGet() { CHECK(tsd_key_inited); - return fake_tsd; + return IsTlsInitialized() ? fake_tsd : nullptr; } void AsanTSDSet(void *tsd) { @@ -210,9 +235,7 @@ void AsanTSDSet(void *tsd) { fake_tsd = tsd; } -void PlatformTSDDtor(void *tsd) { - AsanThread::TSDDtor(tsd); -} +void PlatformTSDDtor(void *tsd) { AsanThread::TSDDtor(tsd); } // }}} // ---------------------- Various stuff ---------------- {{{ @@ -243,9 +266,7 @@ void ReadContextStack(void *context, uptr *stack, uptr *ssize) { UNIMPLEMENTED(); } -void AsanOnDeadlySignal(int, void *siginfo, void *context) { - UNIMPLEMENTED(); -} +void AsanOnDeadlySignal(int, void *siginfo, void *context) { UNIMPLEMENTED(); } #if SANITIZER_WINDOWS64 // Exception handler for dealing with shadow memory. @@ -254,7 +275,9 @@ ShadowExceptionHandler(PEXCEPTION_POINTERS exception_pointers) { uptr page_size = GetPageSizeCached(); // Only handle access violations. if (exception_pointers->ExceptionRecord->ExceptionCode != - EXCEPTION_ACCESS_VIOLATION) { + EXCEPTION_ACCESS_VIOLATION || + exception_pointers->ExceptionRecord->NumberParameters < 2) { + __asan_handle_no_return(); return EXCEPTION_CONTINUE_SEARCH; } @@ -263,7 +286,10 @@ ShadowExceptionHandler(PEXCEPTION_POINTERS exception_pointers) { (uptr)(exception_pointers->ExceptionRecord->ExceptionInformation[1]); // Check valid shadow range. - if (!AddrIsInShadow(addr)) return EXCEPTION_CONTINUE_SEARCH; + if (!AddrIsInShadow(addr)) { + __asan_handle_no_return(); + return EXCEPTION_CONTINUE_SEARCH; + } // This is an access violation while trying to read from the shadow. Commit // the relevant page and let execution continue. @@ -274,7 +300,8 @@ ShadowExceptionHandler(PEXCEPTION_POINTERS exception_pointers) { // Commit the page. uptr result = (uptr)::VirtualAlloc((LPVOID)page, page_size, MEM_COMMIT, PAGE_READWRITE); - if (result != page) return EXCEPTION_CONTINUE_SEARCH; + if (result != page) + return EXCEPTION_CONTINUE_SEARCH; // The page mapping succeeded, so continue execution as usual. return EXCEPTION_CONTINUE_EXECUTION; @@ -291,7 +318,7 @@ void InitializePlatformExceptionHandlers() { } bool IsSystemHeapAddress(uptr addr) { - return ::HeapValidate(GetProcessHeap(), 0, (void*)addr) != FALSE; + return ::HeapValidate(GetProcessHeap(), 0, (void *)addr) != FALSE; } // We want to install our own exception handler (EH) to print helpful reports @@ -310,8 +337,7 @@ bool IsSystemHeapAddress(uptr addr) { // asan_dynamic_runtime_thunk.lib to all the modules, thus __asan_set_seh_filter // will be called for each instrumented module. This ensures that at least one // __asan_set_seh_filter call happens after the .exe module CRT is initialized. -extern "C" SANITIZER_INTERFACE_ATTRIBUTE -int __asan_set_seh_filter() { +extern "C" SANITIZER_INTERFACE_ATTRIBUTE int __asan_set_seh_filter() { // We should only store the previous handler if it's not our own handler in // order to avoid loops in the EH chain. auto prev_seh_handler = SetUnhandledExceptionFilter(SEHHandler); @@ -320,6 +346,13 @@ int __asan_set_seh_filter() { return 0; } +bool HandleDlopenInit() { + // Not supported on this platform. + static_assert(!SANITIZER_SUPPORTS_INIT_FOR_DLOPEN, + "Expected SANITIZER_SUPPORTS_INIT_FOR_DLOPEN to be false"); + return false; +} + #if !ASAN_DYNAMIC // The CRT runs initializers in this order: // - C initializers, from XIA to XIZ @@ -338,14 +371,28 @@ __declspec(allocate(".CRT$XCAB")) int (*__intercept_seh)() = // which run before the CRT. Users also add code to .CRT$XLC, so it's important // to run our initializers first. static void NTAPI asan_thread_init(void *module, DWORD reason, void *reserved) { - if (reason == DLL_PROCESS_ATTACH) __asan_init(); + if (reason == DLL_PROCESS_ATTACH) + __asan_init(); } #pragma section(".CRT$XLAB", long, read) // NOLINT -__declspec(allocate(".CRT$XLAB")) void (NTAPI *__asan_tls_init)(void *, - unsigned long, void *) = asan_thread_init; +__declspec(allocate(".CRT$XLAB")) void(NTAPI *__asan_tls_init)( + void *, unsigned long, void *) = asan_thread_init; #endif +static void NTAPI asan_thread_exit(void *module, DWORD reason, void *reserved) { + if (reason == DLL_THREAD_DETACH) { + // Unpoison the thread's stack because the memory may be re-used. + NT_TIB *tib = (NT_TIB *)NtCurrentTeb(); + uptr stackSize = (uptr)tib->StackBase - (uptr)tib->StackLimit; + __asan_unpoison_memory_region(tib->StackLimit, stackSize); + } +} + +#pragma section(".CRT$XLY", long, read) // NOLINT +__declspec(allocate(".CRT$XLY")) void(NTAPI *__asan_tls_exit)( + void *, unsigned long, void *) = asan_thread_exit; + WIN_FORCE_LINK(__asan_dso_reg_hook) // }}} diff --git a/libsanitizer/asan/asan_win_dll_thunk.cc b/libsanitizer/asan/asan_win_dll_thunk.cpp similarity index 94% rename from libsanitizer/asan/asan_win_dll_thunk.cc rename to libsanitizer/asan/asan_win_dll_thunk.cpp index 8df7ab2b177..95eee5eed0d 100644 --- a/libsanitizer/asan/asan_win_dll_thunk.cc +++ b/libsanitizer/asan/asan_win_dll_thunk.cpp @@ -1,7 +1,8 @@ -//===-- asan_win_dll_thunk.cc ---------------------------------------------===// +//===-- asan_win_dll_thunk.cpp --------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -46,13 +47,14 @@ INTERCEPT_WRAP_W_WWW(_recalloc) INTERCEPT_WRAP_W_WWW(_recalloc_base) INTERCEPT_WRAP_W_W(_msize) +INTERCEPT_WRAP_W_W(_msize_base) INTERCEPT_WRAP_W_W(_expand) INTERCEPT_WRAP_W_W(_expand_dbg) // TODO(timurrrr): Might want to add support for _aligned_* allocation // functions to detect a bit more bugs. Those functions seem to wrap malloc(). -// TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cc). +// TODO(timurrrr): Do we need to add _Crt* stuff here? (see asan_malloc_win.cpp) INTERCEPT_LIBRARY_FUNCTION(atoi); INTERCEPT_LIBRARY_FUNCTION(atol); diff --git a/libsanitizer/asan/asan_win_dynamic_runtime_thunk.cc b/libsanitizer/asan/asan_win_dynamic_runtime_thunk.cpp similarity index 94% rename from libsanitizer/asan/asan_win_dynamic_runtime_thunk.cc rename to libsanitizer/asan/asan_win_dynamic_runtime_thunk.cpp index d431b78d605..5bd457a22b6 100644 --- a/libsanitizer/asan/asan_win_dynamic_runtime_thunk.cc +++ b/libsanitizer/asan/asan_win_dynamic_runtime_thunk.cpp @@ -1,7 +1,8 @@ -//===-- asan_win_dynamic_runtime_thunk.cc ---------------------------------===// +//===-- asan_win_dynamic_runtime_thunk.cpp --------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -113,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/libsanitizer/asan/asan_win_weak_interception.cc b/libsanitizer/asan/asan_win_weak_interception.cpp similarity index 77% rename from libsanitizer/asan/asan_win_weak_interception.cc rename to libsanitizer/asan/asan_win_weak_interception.cpp index 74c1dcdb729..62534e12e2a 100644 --- a/libsanitizer/asan/asan_win_weak_interception.cc +++ b/libsanitizer/asan/asan_win_weak_interception.cpp @@ -1,7 +1,8 @@ -//===-- asan_win_weak_interception.cc -------------------------------------===// +//===-- asan_win_weak_interception.cpp ------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 module should be included in Address Sanitizer when it is implemented as diff --git a/libsanitizer/builtins/assembly.h b/libsanitizer/builtins/assembly.h index 3f5e59b2544..f437cb87f60 100644 --- a/libsanitizer/builtins/assembly.h +++ b/libsanitizer/builtins/assembly.h @@ -1,17 +1,15 @@ -/* ===-- assembly.h - compiler-rt assembler support macros -----------------=== - * - * The LLVM Compiler Infrastructure - * - * This file is dual licensed under the MIT and the University of Illinois Open - * Source Licenses. See LICENSE.TXT for details. - * - * ===----------------------------------------------------------------------=== - * - * This file defines macros for use in compiler-rt assembler source. - * This file is not part of the interface of this library. - * - * ===----------------------------------------------------------------------=== - */ +//===-- assembly.h - compiler-rt assembler support macros -----------------===// +// +// 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 defines macros for use in compiler-rt assembler source. +// This file is not part of the interface of this library. +// +//===----------------------------------------------------------------------===// #ifndef COMPILERRT_ASSEMBLY_H #define COMPILERRT_ASSEMBLY_H @@ -69,11 +67,9 @@ #if defined(__arm__) -/* - * Determine actual [ARM][THUMB[1][2]] ISA using compiler predefined macros: - * - for '-mthumb -march=armv6' compiler defines '__thumb__' - * - for '-mthumb -march=armv7' compiler defines '__thumb__' and '__thumb2__' - */ +// Determine actual [ARM][THUMB[1][2]] ISA using compiler predefined macros: +// - for '-mthumb -march=armv6' compiler defines '__thumb__' +// - for '-mthumb -march=armv7' compiler defines '__thumb__' and '__thumb2__' #if defined(__thumb2__) || defined(__thumb__) #define DEFINE_CODE_STATE .thumb SEPARATOR #define DECLARE_FUNC_ENCODING .thumb_func SEPARATOR @@ -201,4 +197,4 @@ #define END_COMPILERRT_FUNCTION(name) #endif -#endif /* COMPILERRT_ASSEMBLY_H */ +#endif // COMPILERRT_ASSEMBLY_H diff --git a/libsanitizer/configure b/libsanitizer/configure index 2d25147adba..106bc0cfa6a 100755 --- a/libsanitizer/configure +++ b/libsanitizer/configure @@ -708,7 +708,6 @@ am__nodep AMDEPBACKSLASH AMDEP_FALSE AMDEP_TRUE -am__quote am__include DEPDIR am__untar @@ -797,7 +796,8 @@ PACKAGE_VERSION PACKAGE_TARNAME PACKAGE_NAME PATH_SEPARATOR -SHELL' +SHELL +am__quote' ac_subst_files='' ac_user_opts=' enable_option_checking @@ -4221,7 +4221,7 @@ esac -am__api_version='1.15' +am__api_version='1.16' # Find a good install program. We prefer a C program (faster), # so one script is as good as another. But avoid the broken or @@ -4647,45 +4647,45 @@ DEPDIR="${am__leading_dot}deps" ac_config_commands="$ac_config_commands depfiles" - -am_make=${MAKE-make} -cat > confinc << 'END' +{ $as_echo "$as_me:${as_lineno-$LINENO}: checking whether ${MAKE-make} supports the include directive" >&5 +$as_echo_n "checking whether ${MAKE-make} supports the include directive... " >&6; } +cat > confinc.mk << 'END' am__doit: - @echo this is the am__doit target + @echo this is the am__doit target >confinc.out .PHONY: am__doit END -# If we don't find an include directive, just comment out the code. -{ $as_echo "$as_me:${as_lineno-$LINENO}: checking for style of include used by $am_make" >&5 -$as_echo_n "checking for style of include used by $am_make... " >&6; } am__include="#" am__quote= -_am_result=none -# First try GNU make style include. -echo "include confinc" > confmf -# Ignore all kinds of additional output from 'make'. -case `$am_make -s -f confmf 2> /dev/null` in #( -*the\ am__doit\ target*) - am__include=include - am__quote= - _am_result=GNU - ;; -esac -# Now try BSD make style include. -if test "$am__include" = "#"; then - echo '.include "confinc"' > confmf - case `$am_make -s -f confmf 2> /dev/null` in #( - *the\ am__doit\ target*) - am__include=.include - am__quote="\"" - _am_result=BSD +# BSD make does it like this. +echo '.include "confinc.mk" # ignored' > confmf.BSD +# Other make implementations (GNU, Solaris 10, AIX) do it like this. +echo 'include confinc.mk # ignored' > confmf.GNU +_am_result=no +for s in GNU BSD; do + { echo "$as_me:$LINENO: ${MAKE-make} -f confmf.$s && cat confinc.out" >&5 + (${MAKE-make} -f confmf.$s && cat confinc.out) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } + case $?:`cat confinc.out 2>/dev/null` in #( + '0:this is the am__doit target') : + case $s in #( + BSD) : + am__include='.include' am__quote='"' ;; #( + *) : + am__include='include' am__quote='' ;; +esac ;; #( + *) : ;; - esac -fi - - -{ $as_echo "$as_me:${as_lineno-$LINENO}: result: $_am_result" >&5 -$as_echo "$_am_result" >&6; } -rm -f confinc confmf +esac + if test "$am__include" != "#"; then + _am_result="yes ($s style)" + break + fi +done +rm -f confinc.* confmf.* +{ $as_echo "$as_me:${as_lineno-$LINENO}: result: ${_am_result}" >&5 +$as_echo "${_am_result}" >&6; } # Check whether --enable-dependency-tracking was given. if test "${enable_dependency_tracking+set}" = set; then : @@ -4797,8 +4797,8 @@ MAKEINFO=${MAKEINFO-"${am_missing_run}makeinfo"} # For better backward compatibility. To be removed once Automake 1.9.x # dies out for good. For more background, see: -# -# +# +# mkdir_p='$(MKDIR_P)' # We need awk for the "check" target (and possibly the TAP driver). The @@ -4977,7 +4977,7 @@ END Aborting the configuration process, to ensure you take notice of the issue. You can download and install GNU coreutils to get an 'rm' implementation -that behaves properly: . +that behaves properly: . If you want to complete the configuration process using your problematic 'rm' anyway, export the environment variable ACCEPT_INFERIOR_RM_PROGRAM @@ -17652,7 +17652,7 @@ CC="$CC" CXX="$CXX" GFORTRAN="$GFORTRAN" GDC="$GDC" -AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir" +AMDEP_TRUE="$AMDEP_TRUE" MAKE="${MAKE-make}" # The HP-UX ksh and POSIX shell print the target directory to stdout @@ -18662,29 +18662,35 @@ esac ;; # Older Autoconf quotes --file arguments for eval, but not when files # are listed without --file. Let's play safe and only enable the eval # if we detect the quoting. - case $CONFIG_FILES in - *\'*) eval set x "$CONFIG_FILES" ;; - *) set x $CONFIG_FILES ;; - esac + # TODO: see whether this extra hack can be removed once we start + # requiring Autoconf 2.70 or later. + case $CONFIG_FILES in #( + *\'*) : + eval set x "$CONFIG_FILES" ;; #( + *) : + set x $CONFIG_FILES ;; #( + *) : + ;; +esac shift - for mf + # Used to flag and report bootstrapping failures. + am_rc=0 + for am_mf do # Strip MF so we end up with the name of the file. - mf=`echo "$mf" | sed -e 's/:.*$//'` - # Check whether this is an Automake generated Makefile or not. - # We used to match only the files named 'Makefile.in', but - # some people rename them; so instead we look at the file content. - # Grep'ing the first line is not enough: some people post-process - # each Makefile.in and add a new line on top of each file to say so. - # Grep'ing the whole file is not good either: AIX grep has a line + am_mf=`$as_echo "$am_mf" | sed -e 's/:.*$//'` + # Check whether this is an Automake generated Makefile which includes + # dependency-tracking related rules and includes. + # Grep'ing the whole file directly is not great: AIX grep has a line # limit of 2048, but all sed's we know have understand at least 4000. - if sed -n 's,^#.*generated by automake.*,X,p' "$mf" | grep X >/dev/null 2>&1; then - dirpart=`$as_dirname -- "$mf" || -$as_expr X"$mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$mf" : 'X\(//\)[^/]' \| \ - X"$mf" : 'X\(//\)$' \| \ - X"$mf" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$mf" | + sed -n 's,^am--depfiles:.*,X,p' "$am_mf" | grep X >/dev/null 2>&1 \ + || continue + am_dirpart=`$as_dirname -- "$am_mf" || +$as_expr X"$am_mf" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ + X"$am_mf" : 'X\(//\)[^/]' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X"$am_mf" | sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ s//\1/ q @@ -18702,53 +18708,48 @@ $as_echo X"$mf" | q } s/.*/./; q'` - else - continue - fi - # Extract the definition of DEPDIR, am__include, and am__quote - # from the Makefile without running 'make'. - DEPDIR=`sed -n 's/^DEPDIR = //p' < "$mf"` - test -z "$DEPDIR" && continue - am__include=`sed -n 's/^am__include = //p' < "$mf"` - test -z "$am__include" && continue - am__quote=`sed -n 's/^am__quote = //p' < "$mf"` - # Find all dependency output files, they are included files with - # $(DEPDIR) in their names. We invoke sed twice because it is the - # simplest approach to changing $(DEPDIR) to its actual value in the - # expansion. - for file in `sed -n " - s/^$am__include $am__quote\(.*(DEPDIR).*\)$am__quote"'$/\1/p' <"$mf" | \ - sed -e 's/\$(DEPDIR)/'"$DEPDIR"'/g'`; do - # Make sure the directory exists. - test -f "$dirpart/$file" && continue - fdir=`$as_dirname -- "$file" || -$as_expr X"$file" : 'X\(.*[^/]\)//*[^/][^/]*/*$' \| \ - X"$file" : 'X\(//\)[^/]' \| \ - X"$file" : 'X\(//\)$' \| \ - X"$file" : 'X\(/\)' \| . 2>/dev/null || -$as_echo X"$file" | - sed '/^X\(.*[^/]\)\/\/*[^/][^/]*\/*$/{ - s//\1/ - q - } - /^X\(\/\/\)[^/].*/{ + am_filepart=`$as_basename -- "$am_mf" || +$as_expr X/"$am_mf" : '.*/\([^/][^/]*\)/*$' \| \ + X"$am_mf" : 'X\(//\)$' \| \ + X"$am_mf" : 'X\(/\)' \| . 2>/dev/null || +$as_echo X/"$am_mf" | + sed '/^.*\/\([^/][^/]*\)\/*$/{ s//\1/ q } - /^X\(\/\/\)$/{ + /^X\/\(\/\/\)$/{ s//\1/ q } - /^X\(\/\).*/{ + /^X\/\(\/\).*/{ s//\1/ q } s/.*/./; q'` - as_dir=$dirpart/$fdir; as_fn_mkdir_p - # echo "creating $dirpart/$file" - echo '# dummy' > "$dirpart/$file" - done + { echo "$as_me:$LINENO: cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles" >&5 + (cd "$am_dirpart" \ + && sed -e '/# am--include-marker/d' "$am_filepart" \ + | $MAKE -f - am--depfiles) >&5 2>&5 + ac_status=$? + echo "$as_me:$LINENO: \$? = $ac_status" >&5 + (exit $ac_status); } || am_rc=$? done + if test $am_rc -ne 0; then + { { $as_echo "$as_me:${as_lineno-$LINENO}: error: in \`$ac_pwd':" >&5 +$as_echo "$as_me: error: in \`$ac_pwd':" >&2;} +as_fn_error $? "Something went wrong bootstrapping makefile fragments + for automatic dependency tracking. Try re-running configure with the + '--disable-dependency-tracking' option to at least be able to build + the package (albeit without support for automatic dependency tracking). +See \`config.log' for more details" "$LINENO" 5; } + fi + { am_dirpart=; unset am_dirpart;} + { am_filepart=; unset am_filepart;} + { am_mf=; unset am_mf;} + { am_rc=; unset am_rc;} + rm -f conftest-deps.mk } ;; "libtool":C) diff --git a/libsanitizer/configure.tgt b/libsanitizer/configure.tgt index b241ddbfec4..3fb90eab021 100644 --- a/libsanitizer/configure.tgt +++ b/libsanitizer/configure.tgt @@ -28,9 +28,6 @@ case "${target}" in LSAN_SUPPORTED=yes TSAN_TARGET_DEPENDENT_OBJECTS=tsan_rtl_amd64.lo fi - if echo "int x = __x86_64__;" | $CC -c -x c -o /dev/null - > /dev/null 2>&1; then - SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS=sanitizer_linux_x86_64.lo - fi ;; powerpc*-*-linux*) if test x$ac_cv_sizeof_void_p = x8; then diff --git a/libsanitizer/include/sanitizer/allocator_interface.h b/libsanitizer/include/sanitizer/allocator_interface.h index e125ad21d31..6226135ef84 100644 --- a/libsanitizer/include/sanitizer/allocator_interface.h +++ b/libsanitizer/include/sanitizer/allocator_interface.h @@ -1,7 +1,8 @@ //===-- allocator_interface.h ---------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/include/sanitizer/asan_interface.h b/libsanitizer/include/sanitizer/asan_interface.h index 6e8fe256a95..ab2dc97ed24 100644 --- a/libsanitizer/include/sanitizer/asan_interface.h +++ b/libsanitizer/include/sanitizer/asan_interface.h @@ -1,11 +1,12 @@ //===-- sanitizer/asan_interface.h ------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 AddressSanitizer. +// This file is a part of AddressSanitizer (ASan). // // Public interface header. //===----------------------------------------------------------------------===// @@ -17,28 +18,54 @@ #ifdef __cplusplus extern "C" { #endif - // Marks memory region [addr, addr+size) as unaddressable. - // This memory must be previously allocated by the user program. Accessing - // addresses in this region from instrumented code is forbidden until - // this region is unpoisoned. This function is not guaranteed to poison - // the whole region - it may poison only subregion of [addr, addr+size) due - // to ASan alignment restrictions. - // Method is NOT thread-safe in the sense that no two threads can - // (un)poison memory in the same memory region simultaneously. - void __asan_poison_memory_region(void const volatile *addr, size_t size); - // Marks memory region [addr, addr+size) as addressable. - // This memory must be previously allocated by the user program. Accessing - // addresses in this region is allowed until this region is poisoned again. - // This function may unpoison a superregion of [addr, addr+size) due to - // ASan alignment restrictions. - // Method is NOT thread-safe in the sense that no two threads can - // (un)poison memory in the same memory region simultaneously. - void __asan_unpoison_memory_region(void const volatile *addr, size_t size); - -// User code should use macros instead of functions. +/// Marks a memory region ([addr, addr+size)) as unaddressable. +/// +/// This memory must be previously allocated by your program. Instrumented +/// code is forbidden from accessing addresses in this region until it is +/// unpoisoned. This function is not guaranteed to poison the entire region - +/// it could poison only a subregion of [addr, addr+size) due to ASan +/// alignment restrictions. +/// +/// \note This function is not thread-safe because no two threads can poison or +/// unpoison memory in the same memory region simultaneously. +/// +/// \param addr Start of memory region. +/// \param size Size of memory region. +void __asan_poison_memory_region(void const volatile *addr, size_t size); + +/// Marks a memory region ([addr, addr+size)) as addressable. +/// +/// This memory must be previously allocated by your program. Accessing +/// addresses in this region is allowed until this region is poisoned again. +/// This function could unpoison a super-region of [addr, addr+size) due +/// to ASan alignment restrictions. +/// +/// \note This function is not thread-safe because no two threads can +/// poison or unpoison memory in the same memory region simultaneously. +/// +/// \param addr Start of memory region. +/// \param size Size of memory region. +void __asan_unpoison_memory_region(void const volatile *addr, size_t size); + +// Macros provided for convenience. #if __has_feature(address_sanitizer) || defined(__SANITIZE_ADDRESS__) +/// Marks a memory region as unaddressable. +/// +/// \note Macro provided for convenience; defined as a no-op if ASan is not +/// enabled. +/// +/// \param addr Start of memory region. +/// \param size Size of memory region. #define ASAN_POISON_MEMORY_REGION(addr, size) \ __asan_poison_memory_region((addr), (size)) + +/// Marks a memory region as addressable. +/// +/// \note Macro provided for convenience; defined as a no-op if ASan is not +/// enabled. +/// +/// \param addr Start of memory region. +/// \param size Size of memory region. #define ASAN_UNPOISON_MEMORY_REGION(addr, size) \ __asan_unpoison_memory_region((addr), (size)) #else @@ -48,103 +75,245 @@ extern "C" { ((void)(addr), (void)(size)) #endif - // Returns 1 if addr is poisoned (i.e. 1-byte read/write access to this - // address will result in error report from AddressSanitizer). - // Otherwise returns 0. - int __asan_address_is_poisoned(void const volatile *addr); - - // If at least one byte in [beg, beg+size) is poisoned, return the address - // of the first such byte. Otherwise return 0. - void *__asan_region_is_poisoned(void *beg, size_t size); - - // Print the description of addr (useful when debugging in gdb). - void __asan_describe_address(void *addr); - - // Useful for calling from a debugger to get information about an ASan error. - // Returns 1 if an error has been (or is being) reported, otherwise returns 0. - int __asan_report_present(void); - - // Useful for calling from a debugger to get information about an ASan error. - // If an error has been (or is being) reported, the following functions return - // the pc, bp, sp, address, access type (0 = read, 1 = write), access size and - // bug description (e.g. "heap-use-after-free"). Otherwise they return 0. - void *__asan_get_report_pc(void); - void *__asan_get_report_bp(void); - void *__asan_get_report_sp(void); - void *__asan_get_report_address(void); - int __asan_get_report_access_type(void); - size_t __asan_get_report_access_size(void); - const char *__asan_get_report_description(void); - - // Useful for calling from the debugger to get information about a pointer. - // Returns the category of the given pointer as a constant string. - // Possible return values are "global", "stack", "stack-fake", "heap", - // "heap-invalid", "shadow-low", "shadow-gap", "shadow-high", "unknown". - // If global or stack, tries to also return the variable name, address and - // size. If heap, tries to return the chunk address and size. 'name' should - // point to an allocated buffer of size 'name_size'. - const char *__asan_locate_address(void *addr, char *name, size_t name_size, - void **region_address, size_t *region_size); - - // Useful for calling from the debugger to get the allocation stack trace - // and thread ID for a heap address. Stores up to 'size' frames into 'trace', - // returns the number of stored frames or 0 on error. - size_t __asan_get_alloc_stack(void *addr, void **trace, size_t size, - int *thread_id); - - // Useful for calling from the debugger to get the free stack trace - // and thread ID for a heap address. Stores up to 'size' frames into 'trace', - // returns the number of stored frames or 0 on error. - size_t __asan_get_free_stack(void *addr, void **trace, size_t size, - int *thread_id); - - // Useful for calling from the debugger to get the current shadow memory - // mapping. - void __asan_get_shadow_mapping(size_t *shadow_scale, size_t *shadow_offset); - - // This is an internal function that is called to report an error. - // However it is still a part of the interface because users may want to - // set a breakpoint on this function in a debugger. - void __asan_report_error(void *pc, void *bp, void *sp, - void *addr, int is_write, size_t access_size); - - // Deprecated. Call __sanitizer_set_death_callback instead. - void __asan_set_death_callback(void (*callback)(void)); - - void __asan_set_error_report_callback(void (*callback)(const char*)); - - // User may provide function that would be called right when ASan detects - // an error. This can be used to notice cases when ASan detects an error, but - // the program crashes before ASan report is printed. - void __asan_on_error(void); - - // Prints accumulated stats to stderr. Used for debugging. - void __asan_print_accumulated_stats(void); - - // This function may be optionally provided by user and should return - // a string containing ASan runtime options. See asan_flags.h for details. - const char* __asan_default_options(void); - - // The following 2 functions facilitate garbage collection in presence of - // asan's fake stack. - - // Returns an opaque handler to be used later in __asan_addr_is_in_fake_stack. - // Returns NULL if the current thread does not have a fake stack. - void *__asan_get_current_fake_stack(void); - - // If fake_stack is non-NULL and addr belongs to a fake frame in - // fake_stack, returns the address on real stack that corresponds to - // the fake frame and sets beg/end to the boundaries of this fake frame. - // Otherwise returns NULL and does not touch beg/end. - // If beg/end are NULL, they are not touched. - // This function may be called from a thread other than the owner of - // fake_stack, but the owner thread need to be alive. - void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg, - void **end); - - // Performs cleanup before a [[noreturn]] function. Must be called - // before things like _exit and execl to avoid false positives on stack. - void __asan_handle_no_return(void); +/// Checks if an address is poisoned. +/// +/// Returns 1 if addr is poisoned (that is, 1-byte read/write +/// access to this address would result in an error report from ASan). +/// Otherwise returns 0. +/// +/// \param addr Address to check. +/// +/// \retval 1 Address is poisoned. +/// \retval 0 Address is not poisoned. +int __asan_address_is_poisoned(void const volatile *addr); + +/// Checks if a region is poisoned. +/// +/// If at least one byte in [beg, beg+size) is poisoned, returns the +/// address of the first such byte. Otherwise returns 0. +/// +/// \param beg Start of memory region. +/// \param size Start of memory region. +/// \returns Address of first poisoned byte. +void *__asan_region_is_poisoned(void *beg, size_t size); + +/// Describes an address (useful for calling from the debugger). +/// +/// Prints the description of addr. +/// +/// \param addr Address to describe. +void __asan_describe_address(void *addr); + +/// Checks if an error has been or is being reported (useful for calling from +/// the debugger to get information about an ASan error). +/// +/// Returns 1 if an error has been (or is being) reported. Otherwise returns 0. +/// +/// \returns 1 if an error has been (or is being) reported. Otherwise returns +/// 0. +int __asan_report_present(void); + +/// Gets the PC (program counter) register value of an ASan error (useful for +/// calling from the debugger). +/// +/// Returns PC if an error has been (or is being) reported. +/// Otherwise returns 0. +/// +/// \returns PC value. +void *__asan_get_report_pc(void); + +/// Gets the BP (base pointer) register value of an ASan error (useful for +/// calling from the debugger). +/// +/// Returns BP if an error has been (or is being) reported. +/// Otherwise returns 0. +/// +/// \returns BP value. +void *__asan_get_report_bp(void); + +/// Gets the SP (stack pointer) register value of an ASan error (useful for +/// calling from the debugger). +/// +/// If an error has been (or is being) reported, returns SP. +/// Otherwise returns 0. +/// +/// \returns SP value. +void *__asan_get_report_sp(void); + +/// Gets the address of the report buffer of an ASan error (useful for calling +/// from the debugger). +/// +/// Returns the address of the report buffer if an error has been (or is being) +/// reported. Otherwise returns 0. +/// +/// \returns Address of report buffer. +void *__asan_get_report_address(void); + +/// Gets access type of an ASan error (useful for calling from the debugger). +/// +/// Returns access type (read or write) if an error has been (or is being) +/// reported. Otherwise returns 0. +/// +/// \returns Access type (0 = read, 1 = write). +int __asan_get_report_access_type(void); + +/// Gets access size of an ASan error (useful for calling from the debugger). +/// +/// Returns access size if an error has been (or is being) reported. Otherwise +/// returns 0. +/// +/// \returns Access size in bytes. +size_t __asan_get_report_access_size(void); + +/// Gets the bug description of an ASan error (useful for calling from a +/// debugger). +/// +/// \returns Returns a bug description if an error has been (or is being) +/// reported - for example, "heap-use-after-free". Otherwise returns an empty +/// string. +const char *__asan_get_report_description(void); + +/// Gets information about a pointer (useful for calling from the debugger). +/// +/// Returns the category of the given pointer as a constant string. +/// Possible return values are global, stack, stack-fake, +/// heap, heap-invalid, shadow-low, shadow-gap, +/// shadow-high, and unknown. +/// +/// If the return value is global or stack, tries to also return +/// the variable name, address, and size. If the return value is heap, +/// tries to return the chunk address and size. name should point +/// to an allocated buffer of size name_size. +/// +/// \param addr Address to locate. +/// \param name Buffer to store the variable's name. +/// \param name_size Size in bytes of the variable's name buffer. +/// \param region_address [out] Address of the region. +/// \param region_size [out] Size of the region in bytes. +/// +/// \returns Returns the category of the given pointer as a constant string. +const char *__asan_locate_address(void *addr, char *name, size_t name_size, + void **region_address, size_t *region_size); + +/// Gets the allocation stack trace and thread ID for a heap address (useful +/// for calling from the debugger). +/// +/// Stores up to size frames in trace. Returns +/// the number of stored frames or 0 on error. +/// +/// \param addr A heap address. +/// \param trace A buffer to store the stack trace. +/// \param size Size in bytes of the trace buffer. +/// \param thread_id [out] The thread ID of the address. +/// +/// \returns Returns the number of stored frames or 0 on error. +size_t __asan_get_alloc_stack(void *addr, void **trace, size_t size, + int *thread_id); + +/// Gets the free stack trace and thread ID for a heap address (useful for +/// calling from the debugger). +/// +/// Stores up to size frames in trace. Returns +/// the number of stored frames or 0 on error. +/// +/// \param addr A heap address. +/// \param trace A buffer to store the stack trace. +/// \param size Size in bytes of the trace buffer. +/// \param thread_id [out] The thread ID of the address. +/// +/// \returns Returns the number of stored frames or 0 on error. +size_t __asan_get_free_stack(void *addr, void **trace, size_t size, + int *thread_id); + +/// Gets the current shadow memory mapping (useful for calling from the +/// debugger). +/// +/// \param shadow_scale [out] Shadow scale value. +/// \param shadow_offset [out] Offset value. +void __asan_get_shadow_mapping(size_t *shadow_scale, size_t *shadow_offset); + +/// This is an internal function that is called to report an error. However, +/// it is still a part of the interface because you might want to set a +/// breakpoint on this function in the debugger. +/// +/// \param pc pc value of the ASan error. +/// \param bp bp value of the ASan error. +/// \param sp sp value of the ASan error. +/// \param addr Address of the ASan error. +/// \param is_write True if the error is a write error; false otherwise. +/// \param access_size Size of the memory access of the ASan error. +void __asan_report_error(void *pc, void *bp, void *sp, + void *addr, int is_write, size_t access_size); + +// Deprecated. Call __sanitizer_set_death_callback instead. +void __asan_set_death_callback(void (*callback)(void)); + +/// Sets the callback function to be called during ASan error reporting. +/// +/// The callback provides a string pointer to the report. +/// +/// \param callback User-provided function. +void __asan_set_error_report_callback(void (*callback)(const char *)); + +/// User-provided callback on ASan errors. +/// +/// You can provide a function that would be called immediately when ASan +/// detects an error. This is useful in cases when ASan detects an error but +/// your program crashes before the ASan report is printed. +void __asan_on_error(void); + +/// Prints accumulated statistics to stderr (useful for calling from the +/// debugger). +void __asan_print_accumulated_stats(void); + +/// User-provided default option settings. +/// +/// You can provide your own implementation of this function to return a string +/// containing ASan runtime options (for example, +/// verbosity=1:halt_on_error=0). +/// +/// \returns Default options string. +const char* __asan_default_options(void); + +// The following two functions facilitate garbage collection in presence of +// ASan's fake stack. + +/// Gets an opaque handler to the current thread's fake stack. +/// +/// Returns an opaque handler to be used by +/// __asan_addr_is_in_fake_stack(). Returns NULL if the current thread +/// does not have a fake stack. +/// +/// \returns An opaque handler to the fake stack or NULL. +void *__asan_get_current_fake_stack(void); + +/// Checks if an address belongs to a given fake stack. +/// +/// If fake_stack is non-NULL and addr belongs to a +/// fake frame in fake_stack, returns the address of the real +/// stack that corresponds to the fake frame and sets beg and +/// end to the boundaries of this fake frame. Otherwise returns +/// NULL and does not touch beg and end. +/// +/// If beg or end are NULL, they are not touched. +/// +/// \note This function can be called from a thread other than the owner of +/// fake_stack, but the owner thread needs to be alive. +/// +/// \param fake_stack An opaque handler to a fake stack. +/// \param addr Address to test. +/// \param beg [out] Beginning of fake frame. +/// \param end [out] End of fake frame. +/// \returns Stack address or NULL. +void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg, + void **end); + +/// Performs shadow memory cleanup of the current thread's stack before a +/// function marked with the [[noreturn]] attribute is called. +/// +/// To avoid false positives on the stack, must be called before no-return +/// functions like _exit() and execl(). +void __asan_handle_no_return(void); #ifdef __cplusplus } // extern "C" diff --git a/libsanitizer/include/sanitizer/common_interface_defs.h b/libsanitizer/include/sanitizer/common_interface_defs.h index b8ae094ac5f..f979c6a8f63 100644 --- a/libsanitizer/include/sanitizer/common_interface_defs.h +++ b/libsanitizer/include/sanitizer/common_interface_defs.h @@ -1,7 +1,8 @@ //===-- sanitizer/common_interface_defs.h -----------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -16,189 +17,335 @@ // GCC does not understand __has_feature. #if !defined(__has_feature) -# define __has_feature(x) 0 +#define __has_feature(x) 0 #endif #ifdef __cplusplus extern "C" { #endif - // Arguments for __sanitizer_sandbox_on_notify() below. - typedef struct { - // Enable sandbox support in sanitizer coverage. - int coverage_sandboxed; - // File descriptor to write coverage data to. If -1 is passed, a file will - // be pre-opened by __sanitizer_sandobx_on_notify(). This field has no - // effect if coverage_sandboxed == 0. - intptr_t coverage_fd; - // If non-zero, split the coverage data into well-formed blocks. This is - // useful when coverage_fd is a socket descriptor. Each block will contain - // a header, allowing data from multiple processes to be sent over the same - // socket. - unsigned int coverage_max_block_size; - } __sanitizer_sandbox_arguments; - - // Tell the tools to write their reports to "path." instead of stderr. - void __sanitizer_set_report_path(const char *path); - // Tell the tools to write their reports to the provided file descriptor - // (casted to void *). - void __sanitizer_set_report_fd(void *fd); - - // Notify the tools that the sandbox is going to be turned on. The reserved - // parameter will be used in the future to hold a structure with functions - // that the tools may call to bypass the sandbox. - void __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args); - - // This function is called by the tool when it has just finished reporting - // an error. 'error_summary' is a one-line string that summarizes - // the error message. This function can be overridden by the client. - void __sanitizer_report_error_summary(const char *error_summary); - - // Some of the sanitizers (e.g. asan/tsan) may miss bugs that happen - // in unaligned loads/stores. In order to find such bugs reliably one needs - // to replace plain unaligned loads/stores with these calls. - uint16_t __sanitizer_unaligned_load16(const void *p); - uint32_t __sanitizer_unaligned_load32(const void *p); - uint64_t __sanitizer_unaligned_load64(const void *p); - void __sanitizer_unaligned_store16(void *p, uint16_t x); - void __sanitizer_unaligned_store32(void *p, uint32_t x); - void __sanitizer_unaligned_store64(void *p, uint64_t x); - - // Returns 1 on the first call, then returns 0 thereafter. Called by the tool - // to ensure only one report is printed when multiple errors occur - // simultaneously. - int __sanitizer_acquire_crash_state(); - - // Annotate the current state of a contiguous container, such as - // std::vector, std::string or similar. - // A contiguous container is a container that keeps all of its elements - // in a contiguous region of memory. The container owns the region of memory - // [beg, end); the memory [beg, mid) is used to store the current elements - // and the memory [mid, end) is reserved for future elements; - // beg <= mid <= end. For example, in "std::vector<> v" - // beg = &v[0]; - // end = beg + v.capacity() * sizeof(v[0]); - // mid = beg + v.size() * sizeof(v[0]); - // - // This annotation tells the Sanitizer tool about the current state of the - // container so that the tool can report errors when memory from [mid, end) - // is accessed. Insert this annotation into methods like push_back/pop_back. - // Supply the old and the new values of mid (old_mid/new_mid). - // In the initial state mid == end and so should be the final - // state when the container is destroyed or when it reallocates the storage. - // - // Use with caution and don't use for anything other than vector-like classes. - // - // For AddressSanitizer, 'beg' should be 8-aligned and 'end' should - // be either 8-aligned or it should point to the end of a separate heap-, - // stack-, or global- allocated buffer. I.e. the following will not work: - // int64_t x[2]; // 16 bytes, 8-aligned. - // char *beg = (char *)&x[0]; - // char *end = beg + 12; // Not 8 aligned, not the end of the buffer. - // This however will work fine: - // int32_t x[3]; // 12 bytes, but 8-aligned under AddressSanitizer. - // char *beg = (char*)&x[0]; - // char *end = beg + 12; // Not 8-aligned, but is the end of the buffer. - void __sanitizer_annotate_contiguous_container(const void *beg, - const void *end, - const void *old_mid, - const void *new_mid); - // Returns true if the contiguous container [beg, end) is properly poisoned - // (e.g. with __sanitizer_annotate_contiguous_container), i.e. if - // - [beg, mid) is addressable, - // - [mid, end) is unaddressable. - // Full verification requires O(end-beg) time; this function tries to avoid - // such complexity by touching only parts of the container around beg/mid/end. - int __sanitizer_verify_contiguous_container(const void *beg, const void *mid, - const void *end); - - // Similar to __sanitizer_verify_contiguous_container but returns the address - // of the first improperly poisoned byte otherwise. Returns null if the area - // is poisoned properly. - const void *__sanitizer_contiguous_container_find_bad_address( - const void *beg, const void *mid, const void *end); - - // Print the stack trace leading to this call. Useful for debugging user code. - void __sanitizer_print_stack_trace(void); - - // Symbolizes the supplied 'pc' using the format string 'fmt'. - // Outputs at most 'out_buf_size' bytes into 'out_buf'. - // If 'out_buf' is not empty then output is zero or more non empty C strings - // followed by single empty C string. Multiple strings can be returned if PC - // corresponds to inlined function. Inlined frames are printed in the order - // from "most-inlined" to the "least-inlined", so the last frame should be the - // not inlined function. - // Inlined frames can be removed with 'symbolize_inline_frames=0'. - // The format syntax is described in - // lib/sanitizer_common/sanitizer_stacktrace_printer.h. - void __sanitizer_symbolize_pc(void *pc, const char *fmt, char *out_buf, - size_t out_buf_size); - // Same as __sanitizer_symbolize_pc, but for data section (i.e. globals). - void __sanitizer_symbolize_global(void *data_ptr, const char *fmt, - char *out_buf, size_t out_buf_size); - - // Sets the callback to be called right before death on error. - // Passing 0 will unset the callback. - void __sanitizer_set_death_callback(void (*callback)(void)); - - // Interceptor hooks. - // Whenever a libc function interceptor is called it checks if the - // corresponding weak hook is defined, and it so -- calls it. - // The primary use case is data-flow-guided fuzzing, where the fuzzer needs - // to know what is being passed to libc functions, e.g. memcmp. - // FIXME: implement more hooks. - void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1, - const void *s2, size_t n, int result); - void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1, - const char *s2, size_t n, int result); - void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1, - const char *s2, size_t n, int result); - void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1, - const char *s2, int result); - void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1, - const char *s2, int result); - void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1, - const char *s2, char *result); - void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1, - const char *s2, char *result); - void __sanitizer_weak_hook_memmem(void *called_pc, - const void *s1, size_t len1, - const void *s2, size_t len2, void *result); - - // Prints stack traces for all live heap allocations ordered by total - // allocation size until `top_percent` of total live heap is shown. - // `top_percent` should be between 1 and 100. - // At most `max_number_of_contexts` contexts (stack traces) is printed. - // Experimental feature currently available only with asan on Linux/x86_64. - void __sanitizer_print_memory_profile(size_t top_percent, - size_t max_number_of_contexts); - - // Fiber annotation interface. - // Before switching to a different stack, one must call - // __sanitizer_start_switch_fiber with a pointer to the bottom of the - // destination stack and its size. When code starts running on the new stack, - // it must call __sanitizer_finish_switch_fiber to finalize the switch. - // The start_switch function takes a void** to store the current fake stack if - // there is one (it is needed when detect_stack_use_after_return is enabled). - // When restoring a stack, this pointer must be given to the finish_switch - // function. In most cases, this void* can be stored on the stack just before - // switching. When leaving a fiber definitely, null must be passed as first - // argument to the start_switch function so that the fake stack is destroyed. - // If you do not want support for stack use-after-return detection, you can - // always pass null to these two functions. - // Note that the fake stack mechanism is disabled during fiber switch, so if a - // signal callback runs during the switch, it will not benefit from the stack - // use-after-return detection. - void __sanitizer_start_switch_fiber(void **fake_stack_save, - const void *bottom, size_t size); - void __sanitizer_finish_switch_fiber(void *fake_stack_save, - const void **bottom_old, - size_t *size_old); - - // Get full module name and calculate pc offset within it. - // Returns 1 if pc belongs to some module, 0 if module was not found. - int __sanitizer_get_module_and_offset_for_pc(void *pc, char *module_path, - size_t module_path_len, - void **pc_offset); +// Arguments for __sanitizer_sandbox_on_notify() below. +typedef struct { + // Enable sandbox support in sanitizer coverage. + int coverage_sandboxed; + // File descriptor to write coverage data to. If -1 is passed, a file will + // be pre-opened by __sanitizer_sandobx_on_notify(). This field has no + // effect if coverage_sandboxed == 0. + intptr_t coverage_fd; + // If non-zero, split the coverage data into well-formed blocks. This is + // useful when coverage_fd is a socket descriptor. Each block will contain + // a header, allowing data from multiple processes to be sent over the same + // socket. + unsigned int coverage_max_block_size; +} __sanitizer_sandbox_arguments; + +// Tell the tools to write their reports to "path." instead of stderr. +void __sanitizer_set_report_path(const char *path); +// Tell the tools to write their reports to the provided file descriptor +// (casted to void *). +void __sanitizer_set_report_fd(void *fd); + +// Notify the tools that the sandbox is going to be turned on. The reserved +// parameter will be used in the future to hold a structure with functions +// that the tools may call to bypass the sandbox. +void __sanitizer_sandbox_on_notify(__sanitizer_sandbox_arguments *args); + +// This function is called by the tool when it has just finished reporting +// an error. 'error_summary' is a one-line string that summarizes +// the error message. This function can be overridden by the client. +void __sanitizer_report_error_summary(const char *error_summary); + +// Some of the sanitizers (for example ASan/TSan) could miss bugs that happen +// in unaligned loads/stores. To find such bugs reliably, you need to replace +// plain unaligned loads/stores with these calls. + +/// Loads a 16-bit unaligned value. +/// +/// \param p Pointer to unaligned memory. +/// +/// \returns Loaded value. +uint16_t __sanitizer_unaligned_load16(const void *p); + +/// Loads a 32-bit unaligned value. +/// +/// \param p Pointer to unaligned memory. +/// +/// \returns Loaded value. +uint32_t __sanitizer_unaligned_load32(const void *p); + +/// Loads a 64-bit unaligned value. +/// +/// \param p Pointer to unaligned memory. +/// +/// \returns Loaded value. +uint64_t __sanitizer_unaligned_load64(const void *p); + +/// Stores a 16-bit unaligned value. +/// +/// \param p Pointer to unaligned memory. +/// \param x 16-bit value to store. +void __sanitizer_unaligned_store16(void *p, uint16_t x); + +/// Stores a 32-bit unaligned value. +/// +/// \param p Pointer to unaligned memory. +/// \param x 32-bit value to store. +void __sanitizer_unaligned_store32(void *p, uint32_t x); + +/// Stores a 64-bit unaligned value. +/// +/// \param p Pointer to unaligned memory. +/// \param x 64-bit value to store. +void __sanitizer_unaligned_store64(void *p, uint64_t x); + +// Returns 1 on the first call, then returns 0 thereafter. Called by the tool +// to ensure only one report is printed when multiple errors occur +// simultaneously. +int __sanitizer_acquire_crash_state(); + +/// Annotates the current state of a contiguous container, such as +/// std::vector, std::string, or similar. +/// +/// A contiguous container is a container that keeps all of its elements +/// in a contiguous region of memory. The container owns the region of memory +/// [beg, end); the memory [beg, mid) is used to store the +/// current elements, and the memory [mid, end) is reserved for future +/// elements (beg <= mid <= end). For example, in +/// std::vector<> v: +/// +/// \code +/// beg = &v[0]; +/// end = beg + v.capacity() * sizeof(v[0]); +/// mid = beg + v.size() * sizeof(v[0]); +/// \endcode +/// +/// This annotation tells the Sanitizer tool about the current state of the +/// container so that the tool can report errors when memory from +/// [mid, end) is accessed. Insert this annotation into methods like +/// push_back() or pop_back(). Supply the old and new values of +/// mid(old_mid and new_mid). In the initial +/// state mid == end, so that should be the final state when the +/// container is destroyed or when the container reallocates the storage. +/// +/// For ASan, beg should be 8-aligned and end +/// should be either 8-aligned or it should point to the end of a separate +/// heap-, stack-, or global-allocated buffer. So the following example will +/// not work: +/// +/// \code +/// int64_t x[2]; // 16 bytes, 8-aligned +/// char *beg = (char *)&x[0]; +/// char *end = beg + 12; // Not 8-aligned, not the end of the buffer +/// \endcode +/// +/// The following, however, will work: +/// \code +/// int32_t x[3]; // 12 bytes, but 8-aligned under ASan. +/// char *beg = (char*)&x[0]; +/// char *end = beg + 12; // Not 8-aligned, but is the end of the buffer +/// \endcode +/// +/// \note Use this function with caution and do not use for anything other +/// than vector-like classes. +/// +/// \param beg Beginning of memory region. +/// \param end End of memory region. +/// \param old_mid Old middle of memory region. +/// \param new_mid New middle of memory region. +void __sanitizer_annotate_contiguous_container(const void *beg, + const void *end, + const void *old_mid, + const void *new_mid); + +/// Returns true if the contiguous container [beg, end) is properly +/// poisoned. +/// +/// Proper poisoning could occur, for example, with +/// __sanitizer_annotate_contiguous_container), that is, if +/// [beg, mid) is addressable and [mid, end) is unaddressable. +/// Full verification requires O (end - beg) time; this function tries +/// to avoid such complexity by touching only parts of the container around +/// beg, mid, and end. +/// +/// \param beg Beginning of memory region. +/// \param mid Middle of memory region. +/// \param end Old end of memory region. +/// +/// \returns True if the contiguous container [beg, end) is properly +/// poisoned. +int __sanitizer_verify_contiguous_container(const void *beg, const void *mid, + const void *end); + +/// Similar to __sanitizer_verify_contiguous_container() but also +/// returns the address of the first improperly poisoned byte. +/// +/// Returns NULL if the area is poisoned properly. +/// +/// \param beg Beginning of memory region. +/// \param mid Middle of memory region. +/// \param end Old end of memory region. +/// +/// \returns The bad address or NULL. +const void *__sanitizer_contiguous_container_find_bad_address(const void *beg, + const void *mid, + const void *end); + +/// Prints the stack trace leading to this call (useful for calling from the +/// debugger). +void __sanitizer_print_stack_trace(void); + +// Symbolizes the supplied 'pc' using the format string 'fmt'. +// Outputs at most 'out_buf_size' bytes into 'out_buf'. +// If 'out_buf' is not empty then output is zero or more non empty C strings +// followed by single empty C string. Multiple strings can be returned if PC +// corresponds to inlined function. Inlined frames are printed in the order +// from "most-inlined" to the "least-inlined", so the last frame should be the +// not inlined function. +// Inlined frames can be removed with 'symbolize_inline_frames=0'. +// The format syntax is described in +// lib/sanitizer_common/sanitizer_stacktrace_printer.h. +void __sanitizer_symbolize_pc(void *pc, const char *fmt, char *out_buf, + size_t out_buf_size); +// Same as __sanitizer_symbolize_pc, but for data section (i.e. globals). +void __sanitizer_symbolize_global(void *data_ptr, const char *fmt, + char *out_buf, size_t out_buf_size); + +/// Sets the callback to be called immediately before death on error. +/// +/// Passing 0 will unset the callback. +/// +/// \param callback User-provided callback. +void __sanitizer_set_death_callback(void (*callback)(void)); + + +// Interceptor hooks. +// Whenever a libc function interceptor is called, it checks if the +// corresponding weak hook is defined, and calls it if it is indeed defined. +// The primary use-case is data-flow-guided fuzzing, where the fuzzer needs +// to know what is being passed to libc functions (for example memcmp). +// FIXME: implement more hooks. + +/// Interceptor hook for memcmp(). +/// +/// \param called_pc PC (program counter) address of the original call. +/// \param s1 Pointer to block of memory. +/// \param s2 Pointer to block of memory. +/// \param n Number of bytes to compare. +/// \param result Value returned by the intercepted function. +void __sanitizer_weak_hook_memcmp(void *called_pc, const void *s1, + const void *s2, size_t n, int result); + +/// Interceptor hook for strncmp(). +/// +/// \param called_pc PC (program counter) address of the original call. +/// \param s1 Pointer to block of memory. +/// \param s2 Pointer to block of memory. +/// \param n Number of bytes to compare. +/// \param result Value returned by the intercepted function. +void __sanitizer_weak_hook_strncmp(void *called_pc, const char *s1, + const char *s2, size_t n, int result); + +/// Interceptor hook for strncasecmp(). +/// +/// \param called_pc PC (program counter) address of the original call. +/// \param s1 Pointer to block of memory. +/// \param s2 Pointer to block of memory. +/// \param n Number of bytes to compare. +/// \param result Value returned by the intercepted function. +void __sanitizer_weak_hook_strncasecmp(void *called_pc, const char *s1, + const char *s2, size_t n, int result); + +/// Interceptor hook for strcmp(). +/// +/// \param called_pc PC (program counter) address of the original call. +/// \param s1 Pointer to block of memory. +/// \param s2 Pointer to block of memory. +/// \param result Value returned by the intercepted function. +void __sanitizer_weak_hook_strcmp(void *called_pc, const char *s1, + const char *s2, int result); + +/// Interceptor hook for strcasecmp(). +/// +/// \param called_pc PC (program counter) address of the original call. +/// \param s1 Pointer to block of memory. +/// \param s2 Pointer to block of memory. +/// \param result Value returned by the intercepted function. +void __sanitizer_weak_hook_strcasecmp(void *called_pc, const char *s1, + const char *s2, int result); + +/// Interceptor hook for strstr(). +/// +/// \param called_pc PC (program counter) address of the original call. +/// \param s1 Pointer to block of memory. +/// \param s2 Pointer to block of memory. +/// \param result Value returned by the intercepted function. +void __sanitizer_weak_hook_strstr(void *called_pc, const char *s1, + const char *s2, char *result); + +void __sanitizer_weak_hook_strcasestr(void *called_pc, const char *s1, + const char *s2, char *result); + +void __sanitizer_weak_hook_memmem(void *called_pc, + const void *s1, size_t len1, + const void *s2, size_t len2, void *result); + +// Prints stack traces for all live heap allocations ordered by total +// allocation size until top_percent of total live heap is shown. top_percent +// should be between 1 and 100. At most max_number_of_contexts contexts +// (stack traces) are printed. +// Experimental feature currently available only with ASan on Linux/x86_64. +void __sanitizer_print_memory_profile(size_t top_percent, + size_t max_number_of_contexts); + +/// Notify ASan that a fiber switch has started (required only if implementing +/// your own fiber library). +/// +/// Before switching to a different stack, you must call +/// __sanitizer_start_switch_fiber() with a pointer to the bottom of the +/// destination stack and with its size. When code starts running on the new +/// stack, it must call __sanitizer_finish_switch_fiber() to finalize +/// the switch. The __sanitizer_start_switch_fiber() function takes a +/// void** pointer argument to store the current fake stack if there is +/// one (it is necessary when the runtime option +/// detect_stack_use_after_return is enabled). +/// +/// When restoring a stack, this void** pointer must be given to the +/// __sanitizer_finish_switch_fiber() function. In most cases, this +/// pointer can be stored on the stack immediately before switching. When +/// leaving a fiber definitely, NULL must be passed as the first argument to +/// the __sanitizer_start_switch_fiber() function so that the fake stack +/// is destroyed. If your program does not need stack use-after-return +/// detection, you can always pass NULL to these two functions. +/// +/// \note The fake stack mechanism is disabled during fiber switch, so if a +/// signal callback runs during the switch, it will not benefit from stack +/// use-after-return detection. +/// +/// \param fake_stack_save [out] Fake stack save location. +/// \param bottom Bottom address of stack. +/// \param size Size of stack in bytes. +void __sanitizer_start_switch_fiber(void **fake_stack_save, + const void *bottom, size_t size); + +/// Notify ASan that a fiber switch has completed (required only if +/// implementing your own fiber library). +/// +/// When code starts running on the new stack, it must call +/// __sanitizer_finish_switch_fiber() to finalize +/// the switch. For usage details, see the description of +/// __sanitizer_start_switch_fiber(). +/// +/// \param fake_stack_save Fake stack save location. +/// \param bottom_old [out] Bottom address of old stack. +/// \param size_old [out] Size of old stack in bytes. +void __sanitizer_finish_switch_fiber(void *fake_stack_save, + const void **bottom_old, + size_t *size_old); + +// Get full module name and calculate pc offset within it. +// Returns 1 if pc belongs to some module, 0 if module was not found. +int __sanitizer_get_module_and_offset_for_pc(void *pc, char *module_path, + size_t module_path_len, + void **pc_offset); #ifdef __cplusplus } // extern "C" diff --git a/libsanitizer/include/sanitizer/coverage_interface.h b/libsanitizer/include/sanitizer/coverage_interface.h index 2f3613583da..c063cfe60c5 100644 --- a/libsanitizer/include/sanitizer/coverage_interface.h +++ b/libsanitizer/include/sanitizer/coverage_interface.h @@ -1,7 +1,8 @@ //===-- sanitizer/coverage_interface.h --------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/include/sanitizer/dfsan_interface.h b/libsanitizer/include/sanitizer/dfsan_interface.h index 0cebccf945e..c189ee55790 100644 --- a/libsanitizer/include/sanitizer/dfsan_interface.h +++ b/libsanitizer/include/sanitizer/dfsan_interface.h @@ -1,7 +1,8 @@ //===-- dfsan_interface.h -------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -78,6 +79,12 @@ dfsan_label dfsan_has_label_with_desc(dfsan_label label, const char *desc); /// Returns the number of labels allocated. size_t dfsan_get_label_count(void); +/// Flushes the DFSan shadow, i.e. forgets about all labels currently associated +/// with the application memory. Will work only if there are no other +/// threads executing DFSan-instrumented code concurrently. +/// Use this call to start over the taint tracking within the same procces. +void dfsan_flush(void); + /// Sets a callback to be invoked on calls to write(). The callback is invoked /// before the write is done. The write is not guaranteed to succeed when the /// callback executes. Pass in NULL to remove any callback. diff --git a/libsanitizer/include/sanitizer/esan_interface.h b/libsanitizer/include/sanitizer/esan_interface.h deleted file mode 100644 index e22b6a8f4d7..00000000000 --- a/libsanitizer/include/sanitizer/esan_interface.h +++ /dev/null @@ -1,48 +0,0 @@ -//===-- sanitizer/esan_interface.h ------------------------------*- C++ -*-===// -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file is a part of EfficiencySanitizer, a family of performance tuners. -// -// Public interface header. -//===----------------------------------------------------------------------===// -#ifndef SANITIZER_ESAN_INTERFACE_H -#define SANITIZER_ESAN_INTERFACE_H - -#include - -// We declare our interface routines as weak to allow the user to avoid -// ifdefs and instead use this pattern to allow building the same sources -// with and without our runtime library: -// if (__esan_report) -// __esan_report(); -#ifdef _MSC_VER -/* selectany is as close to weak as we'll get. */ -#define COMPILER_RT_WEAK __declspec(selectany) -#elif __GNUC__ -#define COMPILER_RT_WEAK __attribute__((weak)) -#else -#define COMPILER_RT_WEAK -#endif - -#ifdef __cplusplus -extern "C" { -#endif - -// This function can be called mid-run (or at the end of a run for -// a server process that doesn't shut down normally) to request that -// data for that point in the run be reported from the tool. -void COMPILER_RT_WEAK __esan_report(void); - -// This function returns the number of samples that the esan tool has collected -// to this point. This is useful for testing. -unsigned int COMPILER_RT_WEAK __esan_get_sample_count(void); - -#ifdef __cplusplus -} // extern "C" -#endif - -#endif // SANITIZER_ESAN_INTERFACE_H diff --git a/libsanitizer/include/sanitizer/hwasan_interface.h b/libsanitizer/include/sanitizer/hwasan_interface.h index 938e9ac464a..4c9ad13aa0c 100644 --- a/libsanitizer/include/sanitizer/hwasan_interface.h +++ b/libsanitizer/include/sanitizer/hwasan_interface.h @@ -1,7 +1,8 @@ //===-- sanitizer/asan_interface.h ------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -17,11 +18,15 @@ #ifdef __cplusplus extern "C" { #endif - // Initialize shadow but not the rest of the runtime. + // Libc hook for program startup in statically linked executables. + // Initializes enough of the runtime to run instrumented code. This function + // should only be called in statically linked executables because it modifies + // the GOT, which won't work in regular binaries because RELRO will already + // have been applied by the time the function is called. This also means that + // the function should be called before libc applies RELRO. // Does not call libc unless there is an error. - // Can be called multiple times, or not at all (in which case shadow will - // be initialized in compiler-inserted __hwasan_init() call). - void __hwasan_shadow_init(void); + // Can be called multiple times. + void __hwasan_init_static(void); // This function may be optionally provided by user and should return // a string containing HWASan runtime options. See asan_flags.h for details. @@ -45,6 +50,10 @@ extern "C" { // does would cause false reports. void __hwasan_handle_longjmp(const void *sp_dst); + // Set memory tag for the part of the current thread stack below sp_dst to + // zero. Call this in vfork() before returning in the parent process. + void __hwasan_handle_vfork(const void *sp_dst); + // Libc hook for thread creation. Should be called in the child thread before // any instrumented code. void __hwasan_thread_enter(); @@ -60,6 +69,10 @@ extern "C" { // Print one-line report about the memory usage of the current process. void __hwasan_print_memory_usage(); + /* Returns the offset of the first byte in the memory range that can not be + * accessed through the pointer in x, or -1 if the whole range is good. */ + intptr_t __hwasan_test_shadow(const volatile void *x, size_t size); + int __sanitizer_posix_memalign(void **memptr, size_t alignment, size_t size); void * __sanitizer_memalign(size_t alignment, size_t size); void * __sanitizer_aligned_alloc(size_t alignment, size_t size); @@ -74,6 +87,7 @@ extern "C" { void __sanitizer_malloc_stats(void); void * __sanitizer_calloc(size_t nmemb, size_t size); void * __sanitizer_realloc(void *ptr, size_t size); + void * __sanitizer_reallocarray(void *ptr, size_t nmemb, size_t size); void * __sanitizer_malloc(size_t size); #ifdef __cplusplus } // extern "C" diff --git a/libsanitizer/include/sanitizer/linux_syscall_hooks.h b/libsanitizer/include/sanitizer/linux_syscall_hooks.h index 34bb2912406..a1794b71af5 100644 --- a/libsanitizer/include/sanitizer/linux_syscall_hooks.h +++ b/libsanitizer/include/sanitizer/linux_syscall_hooks.h @@ -1,7 +1,8 @@ //===-- linux_syscall_hooks.h ---------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/include/sanitizer/lsan_interface.h b/libsanitizer/include/sanitizer/lsan_interface.h index 93b2e9ca3f1..2bb992672f2 100644 --- a/libsanitizer/include/sanitizer/lsan_interface.h +++ b/libsanitizer/include/sanitizer/lsan_interface.h @@ -1,7 +1,8 @@ //===-- sanitizer/lsan_interface.h ------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/include/sanitizer/msan_interface.h b/libsanitizer/include/sanitizer/msan_interface.h index 4dfae604f7a..d40c556a46d 100644 --- a/libsanitizer/include/sanitizer/msan_interface.h +++ b/libsanitizer/include/sanitizer/msan_interface.h @@ -1,7 +1,8 @@ //===-- msan_interface.h --------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -41,6 +42,9 @@ extern "C" { contents). */ void __msan_unpoison_string(const volatile char *a); + /* Make first n parameters of the next function call fully initialized. */ + void __msan_unpoison_param(size_t n); + /* Make memory region fully uninitialized (without changing its contents). This is a legacy interface that does not update origin information. Use __msan_allocated_memory() instead. */ diff --git a/libsanitizer/include/sanitizer/netbsd_syscall_hooks.h b/libsanitizer/include/sanitizer/netbsd_syscall_hooks.h index 8cf5121726e..27780e0d419 100644 --- a/libsanitizer/include/sanitizer/netbsd_syscall_hooks.h +++ b/libsanitizer/include/sanitizer/netbsd_syscall_hooks.h @@ -1,7 +1,8 @@ //===-- netbsd_syscall_hooks.h --------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -19,8 +20,8 @@ // DO NOT EDIT! THIS FILE HAS BEEN GENERATED! // // Generated with: generate_netbsd_syscalls.awk -// Generated date: 2018-03-03 -// Generated from: syscalls.master,v 1.291 2018/01/06 16:41:23 kamil Exp +// Generated date: 2018-10-30 +// Generated from: syscalls.master,v 1.293 2018/07/31 13:00:13 rjs Exp // //===----------------------------------------------------------------------===// #ifndef SANITIZER_NETBSD_SYSCALL_HOOKS_H @@ -984,7 +985,15 @@ #define __sanitizer_syscall_post_fpathconf(res, fd, name) \ __sanitizer_syscall_post_impl_fpathconf(res, (long long)(fd), \ (long long)(name)) -/* syscall 193 has been skipped */ +#define __sanitizer_syscall_pre_getsockopt2(s, level, name, val, avalsize) \ + __sanitizer_syscall_pre_impl_getsockopt2( \ + (long long)(s), (long long)(level), (long long)(name), (long long)(val), \ + (long long)(avalsize)) +#define __sanitizer_syscall_post_getsockopt2(res, s, level, name, val, \ + avalsize) \ + __sanitizer_syscall_post_impl_getsockopt2( \ + res, (long long)(s), (long long)(level), (long long)(name), \ + (long long)(val), (long long)(avalsize)) #define __sanitizer_syscall_pre_getrlimit(which, rlp) \ __sanitizer_syscall_pre_impl_getrlimit((long long)(which), (long long)(rlp)) #define __sanitizer_syscall_post_getrlimit(res, which, rlp) \ @@ -1750,18 +1759,8 @@ __sanitizer_syscall_post_impl___sigaction_sigtramp( \ res, (long long)(signum), (long long)(nsa), (long long)(osa), \ (long long)(tramp), (long long)(vers)) -#define __sanitizer_syscall_pre_pmc_get_info(ctr, op, args) \ - __sanitizer_syscall_pre_impl_pmc_get_info((long long)(ctr), (long long)(op), \ - (long long)(args)) -#define __sanitizer_syscall_post_pmc_get_info(res, ctr, op, args) \ - __sanitizer_syscall_post_impl_pmc_get_info( \ - res, (long long)(ctr), (long long)(op), (long long)(args)) -#define __sanitizer_syscall_pre_pmc_control(ctr, op, args) \ - __sanitizer_syscall_pre_impl_pmc_control((long long)(ctr), (long long)(op), \ - (long long)(args)) -#define __sanitizer_syscall_post_pmc_control(res, ctr, op, args) \ - __sanitizer_syscall_post_impl_pmc_control( \ - res, (long long)(ctr), (long long)(op), (long long)(args)) +/* syscall 341 has been skipped */ +/* syscall 342 has been skipped */ #define __sanitizer_syscall_pre_rasctl(addr, len, op) \ __sanitizer_syscall_pre_impl_rasctl((long long)(addr), (long long)(len), \ (long long)(op)) @@ -3442,7 +3441,13 @@ void __sanitizer_syscall_post_impl_pathconf(long long res, long long path, void __sanitizer_syscall_pre_impl_fpathconf(long long fd, long long name); void __sanitizer_syscall_post_impl_fpathconf(long long res, long long fd, long long name); -/* syscall 193 has been skipped */ +void __sanitizer_syscall_pre_impl_getsockopt2(long long s, long long level, + long long name, long long val, + long long avalsize); +void __sanitizer_syscall_post_impl_getsockopt2(long long res, long long s, + long long level, long long name, + long long val, + long long avalsize); void __sanitizer_syscall_pre_impl_getrlimit(long long which, long long rlp); void __sanitizer_syscall_post_impl_getrlimit(long long res, long long which, long long rlp); @@ -3999,14 +4004,8 @@ void __sanitizer_syscall_pre_impl___sigaction_sigtramp(long long signum, void __sanitizer_syscall_post_impl___sigaction_sigtramp( long long res, long long signum, long long nsa, long long osa, long long tramp, long long vers); -void __sanitizer_syscall_pre_impl_pmc_get_info(long long ctr, long long op, - long long args); -void __sanitizer_syscall_post_impl_pmc_get_info(long long res, long long ctr, - long long op, long long args); -void __sanitizer_syscall_pre_impl_pmc_control(long long ctr, long long op, - long long args); -void __sanitizer_syscall_post_impl_pmc_control(long long res, long long ctr, - long long op, long long args); +/* syscall 341 has been skipped */ +/* syscall 342 has been skipped */ void __sanitizer_syscall_pre_impl_rasctl(long long addr, long long len, long long op); void __sanitizer_syscall_post_impl_rasctl(long long res, long long addr, diff --git a/libsanitizer/include/sanitizer/scudo_interface.h b/libsanitizer/include/sanitizer/scudo_interface.h index ca9a6f1fcb7..dd522c1efc2 100644 --- a/libsanitizer/include/sanitizer/scudo_interface.h +++ b/libsanitizer/include/sanitizer/scudo_interface.h @@ -1,7 +1,8 @@ //===-- sanitizer/scudo_interface.h -----------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/include/sanitizer/tsan_interface.h b/libsanitizer/include/sanitizer/tsan_interface.h index b86062bb119..011b23350ca 100644 --- a/libsanitizer/include/sanitizer/tsan_interface.h +++ b/libsanitizer/include/sanitizer/tsan_interface.h @@ -1,7 +1,8 @@ //===-- tsan_interface.h ----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -135,6 +136,24 @@ void __tsan_external_assign_tag(void *addr, void *tag); void __tsan_external_read(void *addr, void *caller_pc, void *tag); void __tsan_external_write(void *addr, void *caller_pc, void *tag); +// Fiber switching API. +// - TSAN context for fiber can be created by __tsan_create_fiber +// and freed by __tsan_destroy_fiber. +// - TSAN context of current fiber or thread can be obtained +// by calling __tsan_get_current_fiber. +// - __tsan_switch_to_fiber should be called immediatly before switch +// to fiber, such as call of swapcontext. +// - Fiber name can be set by __tsan_set_fiber_name. +void *__tsan_get_current_fiber(void); +void *__tsan_create_fiber(unsigned flags); +void __tsan_destroy_fiber(void *fiber); +void __tsan_switch_to_fiber(void *fiber, unsigned flags); +void __tsan_set_fiber_name(void *fiber, const char *name); + +// Flags for __tsan_switch_to_fiber: +// Do not establish a happens-before relation between fibers +const unsigned __tsan_switch_to_fiber_no_sync = 1 << 0; + #ifdef __cplusplus } // extern "C" #endif diff --git a/libsanitizer/include/sanitizer/tsan_interface_atomic.h b/libsanitizer/include/sanitizer/tsan_interface_atomic.h index d19c9109416..9ce0411917d 100644 --- a/libsanitizer/include/sanitizer/tsan_interface_atomic.h +++ b/libsanitizer/include/sanitizer/tsan_interface_atomic.h @@ -1,7 +1,8 @@ //===-- tsan_interface_atomic.h ---------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -29,7 +30,7 @@ __extension__ typedef __int128 __tsan_atomic128; #endif // Part of ABI, do not change. -// http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/atomic?view=markup +// https://github.com/llvm/llvm-project/blob/master/libcxx/include/atomic typedef enum { __tsan_memory_order_relaxed, __tsan_memory_order_consume, diff --git a/libsanitizer/interception/Makefile.am b/libsanitizer/interception/Makefile.am index 22ce8d5edac..a22e0b4e2af 100644 --- a/libsanitizer/interception/Makefile.am +++ b/libsanitizer/interception/Makefile.am @@ -13,10 +13,10 @@ ACLOCAL_AMFLAGS = -I m4 noinst_LTLIBRARIES = libinterception.la interception_files = \ - interception_linux.cc \ - interception_mac.cc \ - interception_win.cc \ - interception_type_test.cc + interception_linux.cpp \ + interception_mac.cpp \ + interception_win.cpp \ + interception_type_test.cpp libinterception_la_SOURCES = $(interception_files) diff --git a/libsanitizer/interception/Makefile.in b/libsanitizer/interception/Makefile.in index 08a33e0e567..5f7f0685a77 100644 --- a/libsanitizer/interception/Makefile.in +++ b/libsanitizer/interception/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -134,7 +134,11 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/../depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/interception_linux.Plo \ + ./$(DEPDIR)/interception_mac.Plo \ + ./$(DEPDIR)/interception_type_test.Plo \ + ./$(DEPDIR)/interception_win.Plo am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) @@ -340,10 +344,10 @@ AM_CXXFLAGS = -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic \ ACLOCAL_AMFLAGS = -I m4 noinst_LTLIBRARIES = libinterception.la interception_files = \ - interception_linux.cc \ - interception_mac.cc \ - interception_win.cc \ - interception_type_test.cc + interception_linux.cpp \ + interception_mac.cpp \ + interception_win.cpp \ + interception_type_test.cpp libinterception_la_SOURCES = $(interception_files) @@ -389,7 +393,7 @@ MAKEOVERRIDES = all: all-am .SUFFIXES: -.SUFFIXES: .cc .lo .o .obj +.SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -407,8 +411,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -440,26 +444,32 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interception_linux.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interception_mac.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interception_type_test.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interception_win.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interception_linux.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interception_mac.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interception_type_test.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/interception_win.Plo@am__quote@ # am--include-marker -.cc.o: +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< -.cc.obj: +.cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` -.cc.lo: +.cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @@ -563,7 +573,10 @@ clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/interception_linux.Plo + -rm -f ./$(DEPDIR)/interception_mac.Plo + -rm -f ./$(DEPDIR)/interception_type_test.Plo + -rm -f ./$(DEPDIR)/interception_win.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -609,7 +622,10 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/interception_linux.Plo + -rm -f ./$(DEPDIR)/interception_mac.Plo + -rm -f ./$(DEPDIR)/interception_type_test.Plo + -rm -f ./$(DEPDIR)/interception_win.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -630,19 +646,19 @@ uninstall-am: .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ - ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags dvi dvi-am html html-am info \ - info-am install install-am install-data install-data-am \ - install-dvi install-dvi-am install-exec install-exec-am \ - install-html install-html-am install-info install-info-am \ - install-man install-pdf install-pdf-am install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags dvi dvi-am \ + html html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am .PRECIOUS: Makefile diff --git a/libsanitizer/interception/interception.h b/libsanitizer/interception/interception.h index 3d43df804f3..dacfa5ede28 100644 --- a/libsanitizer/interception/interception.h +++ b/libsanitizer/interception/interception.h @@ -1,7 +1,8 @@ //===-- interception.h ------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -184,11 +185,17 @@ const interpose_substitution substitution_##func_name[] \ #endif // SANITIZER_MAC #if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS -#define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...) \ +# define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...) \ DECLARE_REAL(ret_type, func, __VA_ARGS__) \ extern "C" ret_type WRAP(func)(__VA_ARGS__); +// Declare an interceptor and its wrapper defined in a different translation +// unit (ex. asm). +# define DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(ret_type, func, ...) \ + extern "C" ret_type WRAP(func)(__VA_ARGS__); \ + extern "C" ret_type func(__VA_ARGS__); #else -#define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...) +# define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...) +# define DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(ret_type, func, ...) #endif // Generally, you don't need to use DEFINE_REAL by itself, as INTERCEPTOR diff --git a/libsanitizer/interception/interception_linux.cc b/libsanitizer/interception/interception_linux.cc deleted file mode 100644 index 781b77e46fd..00000000000 --- a/libsanitizer/interception/interception_linux.cc +++ /dev/null @@ -1,53 +0,0 @@ -//===-- interception_linux.cc -----------------------------------*- C++ -*-===// -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// This file is a part of AddressSanitizer, an address sanity checker. -// -// Linux-specific interception methods. -//===----------------------------------------------------------------------===// - -#include "interception.h" - -#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ - SANITIZER_OPENBSD || SANITIZER_SOLARIS - -#include // for dlsym() and dlvsym() - -#if SANITIZER_NETBSD -#include "sanitizer_common/sanitizer_libc.h" -#endif - -namespace __interception { -bool GetRealFunctionAddress(const char *func_name, uptr *func_addr, - uptr real, uptr wrapper) { -#if SANITIZER_NETBSD - // XXX: Find a better way to handle renames - if (internal_strcmp(func_name, "sigaction") == 0) func_name = "__sigaction14"; -#endif - *func_addr = (uptr)dlsym(RTLD_NEXT, func_name); - if (!*func_addr) { - // If the lookup using RTLD_NEXT failed, the sanitizer runtime library is - // later in the library search order than the DSO that we are trying to - // intercept, which means that we cannot intercept this function. We still - // want the address of the real definition, though, so look it up using - // RTLD_DEFAULT. - *func_addr = (uptr)dlsym(RTLD_DEFAULT, func_name); - } - return real == wrapper; -} - -// Android and Solaris do not have dlvsym -#if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD -void *GetFuncAddrVer(const char *func_name, const char *ver) { - return dlvsym(RTLD_NEXT, func_name, ver); -} -#endif // !SANITIZER_ANDROID - -} // namespace __interception - -#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || - // SANITIZER_OPENBSD || SANITIZER_SOLARIS diff --git a/libsanitizer/interception/interception_linux.cpp b/libsanitizer/interception/interception_linux.cpp new file mode 100644 index 00000000000..950cd512653 --- /dev/null +++ b/libsanitizer/interception/interception_linux.cpp @@ -0,0 +1,83 @@ +//===-- 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. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// Linux-specific interception methods. +//===----------------------------------------------------------------------===// + +#include "interception.h" + +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ + SANITIZER_OPENBSD || SANITIZER_SOLARIS + +#include // for dlsym() and dlvsym() + +namespace __interception { + +#if SANITIZER_NETBSD +static int StrCmp(const char *s1, const char *s2) { + while (true) { + if (*s1 != *s2) + return false; + if (*s1 == 0) + return true; + s1++; + s2++; + } +} +#endif + +static void *GetFuncAddr(const char *name, uptr wrapper_addr) { +#if SANITIZER_NETBSD + // FIXME: Find a better way to handle renames + if (StrCmp(name, "sigaction")) + name = "__sigaction14"; +#endif + void *addr = dlsym(RTLD_NEXT, name); + if (!addr) { + // If the lookup using RTLD_NEXT failed, the sanitizer runtime library is + // later in the library search order than the DSO that we are trying to + // intercept, which means that we cannot intercept this function. We still + // want the address of the real definition, though, so look it up using + // RTLD_DEFAULT. + addr = dlsym(RTLD_DEFAULT, name); + + // In case `name' is not loaded, dlsym ends up finding the actual wrapper. + // We don't want to intercept the wrapper and have it point to itself. + if ((uptr)addr == wrapper_addr) + addr = nullptr; + } + return addr; +} + +bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func, + uptr wrapper) { + void *addr = GetFuncAddr(name, wrapper); + *ptr_to_real = (uptr)addr; + return addr && (func == wrapper); +} + +// Android and Solaris do not have dlvsym +#if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD +static void *GetFuncAddr(const char *name, const char *ver) { + return dlvsym(RTLD_NEXT, name, ver); +} + +bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real, + uptr func, uptr wrapper) { + void *addr = GetFuncAddr(name, ver); + *ptr_to_real = (uptr)addr; + return addr && (func == wrapper); +} +#endif // !SANITIZER_ANDROID + +} // namespace __interception + +#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || + // SANITIZER_OPENBSD || SANITIZER_SOLARIS diff --git a/libsanitizer/interception/interception_linux.h b/libsanitizer/interception/interception_linux.h index 37e6386df5b..e578da0cf64 100644 --- a/libsanitizer/interception/interception_linux.h +++ b/libsanitizer/interception/interception_linux.h @@ -1,7 +1,8 @@ //===-- interception_linux.h ------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -21,23 +22,27 @@ #define INTERCEPTION_LINUX_H namespace __interception { -// returns true if a function with the given name was found. -bool GetRealFunctionAddress(const char *func_name, uptr *func_addr, - uptr real, uptr wrapper); -void *GetFuncAddrVer(const char *func_name, const char *ver); +bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func, + uptr wrapper); +bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real, + uptr func, uptr wrapper); } // namespace __interception -#define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) \ - ::__interception::GetRealFunctionAddress( \ - #func, (::__interception::uptr *)&__interception::PTR_TO_REAL(func), \ - (::__interception::uptr) & (func), \ +#define INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) \ + ::__interception::InterceptFunction( \ + #func, \ + (::__interception::uptr *) & REAL(func), \ + (::__interception::uptr) & (func), \ (::__interception::uptr) & WRAP(func)) // Android, Solaris and OpenBSD do not have dlvsym #if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD #define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \ - (::__interception::real_##func = (func##_type)( \ - unsigned long)::__interception::GetFuncAddrVer(#func, symver)) + ::__interception::InterceptFunction( \ + #func, symver, \ + (::__interception::uptr *) & REAL(func), \ + (::__interception::uptr) & (func), \ + (::__interception::uptr) & WRAP(func)) #else #define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \ INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) diff --git a/libsanitizer/interception/interception_mac.cc b/libsanitizer/interception/interception_mac.cpp similarity index 58% rename from libsanitizer/interception/interception_mac.cc rename to libsanitizer/interception/interception_mac.cpp index 1ffc1af9d55..fb6eadcff59 100644 --- a/libsanitizer/interception/interception_mac.cc +++ b/libsanitizer/interception/interception_mac.cpp @@ -1,7 +1,8 @@ -//===-- interception_mac.cc -------------------------------------*- C++ -*-===// +//===-- interception_mac.cpp ------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/interception/interception_mac.h b/libsanitizer/interception/interception_mac.h index c3a3eace53d..eddedb8959c 100644 --- a/libsanitizer/interception/interception_mac.h +++ b/libsanitizer/interception/interception_mac.h @@ -1,7 +1,8 @@ //===-- interception_mac.h --------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/interception/interception_type_test.cc b/libsanitizer/interception/interception_type_test.cpp similarity index 81% rename from libsanitizer/interception/interception_type_test.cc rename to libsanitizer/interception/interception_type_test.cpp index 726cc7b71b2..a611604a700 100644 --- a/libsanitizer/interception/interception_type_test.cc +++ b/libsanitizer/interception/interception_type_test.cpp @@ -1,7 +1,8 @@ -//===-- interception_type_test.cc -------------------------------*- C++ -*-===// +//===-- interception_type_test.cpp ------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/interception/interception_win.cc b/libsanitizer/interception/interception_win.cpp similarity index 98% rename from libsanitizer/interception/interception_win.cc rename to libsanitizer/interception/interception_win.cpp index 74f444d8f4a..b94e214fdff 100644 --- a/libsanitizer/interception/interception_win.cc +++ b/libsanitizer/interception/interception_win.cpp @@ -1,7 +1,8 @@ -//===-- interception_linux.cc -----------------------------------*- C++ -*-===// +//===-- interception_linux.cpp ----------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -511,10 +512,12 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { case 0xc0854d: // 4d 85 c0 : test r8, r8 case 0xc2b60f: // 0f b6 c2 : movzx eax, dl case 0xc03345: // 45 33 c0 : xor r8d, r8d + case 0xc93345: // 45 33 c9 : xor r9d, r9d case 0xdb3345: // 45 33 DB : xor r11d, r11d case 0xd98b4c: // 4c 8b d9 : mov r11, rcx case 0xd28b4c: // 4c 8b d2 : mov r10, rdx case 0xc98b4c: // 4C 8B C9 : mov r9, rcx + case 0xc18b4c: // 4C 8B C1 : mov r8, rcx case 0xd2b60f: // 0f b6 d2 : movzx edx, dl case 0xca2b48: // 48 2b ca : sub rcx, rdx case 0x10b70f: // 0f b7 10 : movzx edx, WORD PTR [rax] @@ -522,6 +525,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { case 0xd18b48: // 48 8b d1 : mov rdx, rcx case 0xdc8b4c: // 4c 8b dc : mov r11, rsp case 0xd18b4c: // 4c 8b d1 : mov r10, rcx + case 0xE0E483: // 83 E4 E0 : and esp, 0xFFFFFFE0 return 3; case 0xec8348: // 48 83 ec XX : sub rsp, XX @@ -553,6 +557,9 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { case 0x245c8948: // 48 89 5c 24 XX : mov QWORD PTR [rsp + XX], rbx case 0x24748948: // 48 89 74 24 XX : mov QWORD PTR [rsp + XX], rsi case 0x244C8948: // 48 89 4C 24 XX : mov QWORD PTR [rsp + XX], rcx + case 0x24548948: // 48 89 54 24 XX : mov QWORD PTR [rsp + XX], rdx + case 0x244c894c: // 4c 89 4c 24 XX : mov QWORD PTR [rsp + XX], r9 + case 0x2444894c: // 4c 89 44 24 XX : mov QWORD PTR [rsp + XX], r8 return 5; case 0x24648348: // 48 83 64 24 XX : and QWORD PTR [rsp + XX], YY return 6; diff --git a/libsanitizer/interception/interception_win.h b/libsanitizer/interception/interception_win.h index 3202a0e37b6..4590013019e 100644 --- a/libsanitizer/interception/interception_win.h +++ b/libsanitizer/interception/interception_win.h @@ -1,7 +1,8 @@ //===-- interception_linux.h ------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/libbacktrace/Makefile.in b/libsanitizer/libbacktrace/Makefile.in index f0e190a81d8..36d4638a9b1 100644 --- a/libsanitizer/libbacktrace/Makefile.in +++ b/libsanitizer/libbacktrace/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -165,7 +165,14 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/../depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/alloc.Plo ./$(DEPDIR)/atomic.Plo \ + ./$(DEPDIR)/bridge.Plo ./$(DEPDIR)/cp-demangle.Plo \ + ./$(DEPDIR)/dwarf.Plo ./$(DEPDIR)/elf.Plo \ + ./$(DEPDIR)/fileline.Plo ./$(DEPDIR)/mmap.Plo \ + ./$(DEPDIR)/mmapio.Plo ./$(DEPDIR)/posix.Plo \ + ./$(DEPDIR)/read.Plo ./$(DEPDIR)/sort.Plo \ + ./$(DEPDIR)/state.Plo ./$(DEPDIR)/unknown.Plo am__mv = mv -f COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) @@ -447,8 +454,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -482,20 +489,26 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomic.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bridge.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cp-demangle.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileline.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmap.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmapio.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/posix.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sort.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/state.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unknown.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/alloc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/atomic.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/bridge.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/cp-demangle.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/dwarf.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/elf.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/fileline.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmap.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/mmapio.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/posix.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/read.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sort.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/state.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/unknown.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) .c.o: @am__fastdepCC_TRUE@ $(AM_V_CC)$(COMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -727,7 +740,20 @@ clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/alloc.Plo + -rm -f ./$(DEPDIR)/atomic.Plo + -rm -f ./$(DEPDIR)/bridge.Plo + -rm -f ./$(DEPDIR)/cp-demangle.Plo + -rm -f ./$(DEPDIR)/dwarf.Plo + -rm -f ./$(DEPDIR)/elf.Plo + -rm -f ./$(DEPDIR)/fileline.Plo + -rm -f ./$(DEPDIR)/mmap.Plo + -rm -f ./$(DEPDIR)/mmapio.Plo + -rm -f ./$(DEPDIR)/posix.Plo + -rm -f ./$(DEPDIR)/read.Plo + -rm -f ./$(DEPDIR)/sort.Plo + -rm -f ./$(DEPDIR)/state.Plo + -rm -f ./$(DEPDIR)/unknown.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -773,7 +799,20 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/alloc.Plo + -rm -f ./$(DEPDIR)/atomic.Plo + -rm -f ./$(DEPDIR)/bridge.Plo + -rm -f ./$(DEPDIR)/cp-demangle.Plo + -rm -f ./$(DEPDIR)/dwarf.Plo + -rm -f ./$(DEPDIR)/elf.Plo + -rm -f ./$(DEPDIR)/fileline.Plo + -rm -f ./$(DEPDIR)/mmap.Plo + -rm -f ./$(DEPDIR)/mmapio.Plo + -rm -f ./$(DEPDIR)/posix.Plo + -rm -f ./$(DEPDIR)/read.Plo + -rm -f ./$(DEPDIR)/sort.Plo + -rm -f ./$(DEPDIR)/state.Plo + -rm -f ./$(DEPDIR)/unknown.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -794,19 +833,19 @@ uninstall-am: .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ - ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags dvi dvi-am html html-am info \ - info-am install install-am install-data install-data-am \ - install-dvi install-dvi-am install-exec install-exec-am \ - install-html install-html-am install-info install-info-am \ - install-man install-pdf install-pdf-am install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags dvi dvi-am \ + html html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am .PRECIOUS: Makefile diff --git a/libsanitizer/lsan/Makefile.am b/libsanitizer/lsan/Makefile.am index 423ffc249e0..62ea17dccec 100644 --- a/libsanitizer/lsan/Makefile.am +++ b/libsanitizer/lsan/Makefile.am @@ -17,19 +17,19 @@ nodist_toolexeclib_HEADERS = liblsan_preinit.o endif sanitizer_lsan_files = \ - lsan_common.cc \ - lsan_common_linux.cc \ - lsan_common_mac.cc + lsan_common.cpp \ + lsan_common_linux.cpp \ + lsan_common_mac.cpp lsan_files = \ $(sanitizer_lsan_files) \ - lsan.cc \ - lsan_linux.cc \ - lsan_mac.cc \ - lsan_malloc_mac.cc \ - lsan_allocator.cc \ - lsan_interceptors.cc \ - lsan_thread.cc + lsan.cpp \ + lsan_linux.cpp \ + lsan_mac.cpp \ + lsan_malloc_mac.cpp \ + lsan_allocator.cpp \ + lsan_interceptors.cpp \ + lsan_thread.cpp libsanitizer_lsan_la_SOURCES = $(sanitizer_lsan_files) diff --git a/libsanitizer/lsan/Makefile.in b/libsanitizer/lsan/Makefile.in index a11baed30c8..e40913e0e9f 100644 --- a/libsanitizer/lsan/Makefile.in +++ b/libsanitizer/lsan/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -178,7 +178,14 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/../depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/lsan.Plo \ + ./$(DEPDIR)/lsan_allocator.Plo ./$(DEPDIR)/lsan_common.Plo \ + ./$(DEPDIR)/lsan_common_linux.Plo \ + ./$(DEPDIR)/lsan_common_mac.Plo \ + ./$(DEPDIR)/lsan_interceptors.Plo ./$(DEPDIR)/lsan_linux.Plo \ + ./$(DEPDIR)/lsan_mac.Plo ./$(DEPDIR)/lsan_malloc_mac.Plo \ + ./$(DEPDIR)/lsan_thread.Plo am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) @@ -387,19 +394,19 @@ noinst_LTLIBRARIES = libsanitizer_lsan.la @LSAN_SUPPORTED_TRUE@toolexeclib_LTLIBRARIES = liblsan.la @LSAN_SUPPORTED_TRUE@nodist_toolexeclib_HEADERS = liblsan_preinit.o sanitizer_lsan_files = \ - lsan_common.cc \ - lsan_common_linux.cc \ - lsan_common_mac.cc + lsan_common.cpp \ + lsan_common_linux.cpp \ + lsan_common_mac.cpp lsan_files = \ $(sanitizer_lsan_files) \ - lsan.cc \ - lsan_linux.cc \ - lsan_mac.cc \ - lsan_malloc_mac.cc \ - lsan_allocator.cc \ - lsan_interceptors.cc \ - lsan_thread.cc + lsan.cpp \ + lsan_linux.cpp \ + lsan_mac.cpp \ + lsan_malloc_mac.cpp \ + lsan_allocator.cpp \ + lsan_interceptors.cpp \ + lsan_thread.cpp libsanitizer_lsan_la_SOURCES = $(sanitizer_lsan_files) liblsan_la_SOURCES = $(lsan_files) @@ -451,7 +458,7 @@ MAKEOVERRIDES = all: all-am .SUFFIXES: -.SUFFIXES: .cc .lo .o .obj +.SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -469,8 +476,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -540,32 +547,38 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_allocator.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_common.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_common_linux.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_common_mac.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_interceptors.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_linux.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_mac.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_malloc_mac.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_thread.Plo@am__quote@ - -.cc.o: +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_allocator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_common.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_common_linux.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_common_mac.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_interceptors.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_linux.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_mac.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_malloc_mac.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/lsan_thread.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< -.cc.obj: +.cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` -.cc.lo: +.cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @@ -693,7 +706,16 @@ clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ clean-toolexeclibLTLIBRARIES mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/lsan.Plo + -rm -f ./$(DEPDIR)/lsan_allocator.Plo + -rm -f ./$(DEPDIR)/lsan_common.Plo + -rm -f ./$(DEPDIR)/lsan_common_linux.Plo + -rm -f ./$(DEPDIR)/lsan_common_mac.Plo + -rm -f ./$(DEPDIR)/lsan_interceptors.Plo + -rm -f ./$(DEPDIR)/lsan_linux.Plo + -rm -f ./$(DEPDIR)/lsan_mac.Plo + -rm -f ./$(DEPDIR)/lsan_malloc_mac.Plo + -rm -f ./$(DEPDIR)/lsan_thread.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -740,7 +762,16 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/lsan.Plo + -rm -f ./$(DEPDIR)/lsan_allocator.Plo + -rm -f ./$(DEPDIR)/lsan_common.Plo + -rm -f ./$(DEPDIR)/lsan_common_linux.Plo + -rm -f ./$(DEPDIR)/lsan_common_mac.Plo + -rm -f ./$(DEPDIR)/lsan_interceptors.Plo + -rm -f ./$(DEPDIR)/lsan_linux.Plo + -rm -f ./$(DEPDIR)/lsan_mac.Plo + -rm -f ./$(DEPDIR)/lsan_malloc_mac.Plo + -rm -f ./$(DEPDIR)/lsan_thread.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -762,8 +793,8 @@ uninstall-am: uninstall-nodist_toolexeclibHEADERS \ .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES \ +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ clean-toolexeclibLTLIBRARIES cscopelist-am ctags ctags-am \ distclean distclean-compile distclean-generic \ distclean-libtool distclean-tags dvi dvi-am html html-am info \ diff --git a/libsanitizer/lsan/lsan.cc b/libsanitizer/lsan/lsan.cpp similarity index 74% rename from libsanitizer/lsan/lsan.cc rename to libsanitizer/lsan/lsan.cpp index e9261109c9e..5b5f6198a69 100644 --- a/libsanitizer/lsan/lsan.cc +++ b/libsanitizer/lsan/lsan.cpp @@ -1,7 +1,8 @@ -//=-- lsan.cc -------------------------------------------------------------===// +//=-- lsan.cpp ------------------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -31,6 +32,24 @@ bool WordIsPoisoned(uptr addr) { } // namespace __lsan +void __sanitizer::BufferedStackTrace::UnwindImpl( + uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) { + using namespace __lsan; + uptr stack_top = 0, stack_bottom = 0; + ThreadContext *t; + if (StackTrace::WillUseFastUnwind(request_fast) && + (t = CurrentThreadContext())) { + stack_top = t->stack_end(); + stack_bottom = t->stack_begin(); + } + if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) { + if (StackTrace::WillUseFastUnwind(request_fast)) + Unwind(max_depth, pc, bp, nullptr, stack_top, stack_bottom, true); + else + Unwind(max_depth, pc, 0, context, 0, 0, false); + } +} + using namespace __lsan; // NOLINT static void InitializeFlags() { @@ -57,7 +76,7 @@ static void InitializeFlags() { // Override from user-specified string. const char *lsan_default_options = MaybeCallLsanDefaultOptions(); parser.ParseString(lsan_default_options); - parser.ParseString(GetEnv("LSAN_OPTIONS")); + parser.ParseStringFromEnv("LSAN_OPTIONS"); SetVerbosity(common_flags()->verbosity); @@ -70,7 +89,7 @@ static void InitializeFlags() { static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { - GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context, + stack->Unwind(sig.pc, sig.bp, sig.context, common_flags()->fast_unwind_on_fatal); } diff --git a/libsanitizer/lsan/lsan.h b/libsanitizer/lsan/lsan.h index a40493c8879..9904ada4bb3 100644 --- a/libsanitizer/lsan/lsan.h +++ b/libsanitizer/lsan/lsan.h @@ -1,7 +1,8 @@ //=-- lsan.h --------------------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -16,8 +17,8 @@ #define GET_STACK_TRACE(max_size, fast) \ __sanitizer::BufferedStackTrace stack; \ - GetStackTrace(&stack, max_size, StackTrace::GetCurrentPc(), \ - GET_CURRENT_FRAME(), nullptr, fast); + stack.Unwind(StackTrace::GetCurrentPc(), \ + GET_CURRENT_FRAME(), nullptr, fast, max_size); #define GET_STACK_TRACE_FATAL \ GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_fatal) @@ -39,24 +40,6 @@ void ReplaceSystemMalloc(); __lsan_init(); \ } while (0) -// Get the stack trace with the given pc and bp. -// The pc will be in the position 0 of the resulting stack trace. -// The bp may refer to the current frame or to the caller's frame. -ALWAYS_INLINE -void GetStackTrace(__sanitizer::BufferedStackTrace *stack, - __sanitizer::uptr max_depth, __sanitizer::uptr pc, - __sanitizer::uptr bp, void *context, bool fast) { - uptr stack_top = 0, stack_bottom = 0; - ThreadContext *t; - if (fast && (t = CurrentThreadContext())) { - stack_top = t->stack_end(); - stack_bottom = t->stack_begin(); - } - if (!SANITIZER_MIPS || IsValidFrame(bp, stack_top, stack_bottom)) { - stack->Unwind(max_depth, pc, bp, context, stack_top, stack_bottom, fast); - } -} - } // namespace __lsan extern bool lsan_inited; diff --git a/libsanitizer/lsan/lsan_allocator.cc b/libsanitizer/lsan/lsan_allocator.cpp similarity index 94% rename from libsanitizer/lsan/lsan_allocator.cc rename to libsanitizer/lsan/lsan_allocator.cpp index 6b57c5070a9..66a81ab350e 100644 --- a/libsanitizer/lsan/lsan_allocator.cc +++ b/libsanitizer/lsan/lsan_allocator.cpp @@ -1,7 +1,8 @@ -//=-- lsan_allocator.cc ---------------------------------------------------===// +//=-- lsan_allocator.cpp --------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -32,9 +33,6 @@ static const uptr kMaxAllowedMallocSize = 4UL << 30; #else static const uptr kMaxAllowedMallocSize = 8UL << 30; #endif -typedef LargeMmapAllocator<> SecondaryAllocator; -typedef CombinedAllocator Allocator; static Allocator allocator; @@ -187,6 +185,17 @@ void *lsan_realloc(void *p, uptr size, const StackTrace &stack) { return SetErrnoOnNull(Reallocate(stack, p, size, 1)); } +void *lsan_reallocarray(void *ptr, uptr nmemb, uptr size, + const StackTrace &stack) { + if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) { + errno = errno_ENOMEM; + if (AllocatorMayReturnNull()) + return nullptr; + ReportReallocArrayOverflow(nmemb, size, &stack); + } + return lsan_realloc(ptr, nmemb * size, stack); +} + void *lsan_calloc(uptr nmemb, uptr size, const StackTrace &stack) { return SetErrnoOnNull(Calloc(nmemb, size, stack)); } diff --git a/libsanitizer/lsan/lsan_allocator.h b/libsanitizer/lsan/lsan_allocator.h index 37260c0b5ae..e1397099767 100644 --- a/libsanitizer/lsan/lsan_allocator.h +++ b/libsanitizer/lsan/lsan_allocator.h @@ -1,7 +1,8 @@ //=-- lsan_allocator.h ----------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -50,21 +51,20 @@ struct ChunkMetadata { #if defined(__mips64) || defined(__aarch64__) || defined(__i386__) || \ defined(__arm__) -static const uptr kRegionSizeLog = 20; -static const uptr kNumRegions = SANITIZER_MMAP_RANGE_SIZE >> kRegionSizeLog; -typedef TwoLevelByteMap<(kNumRegions >> 12), 1 << 12> ByteMap; - +template struct AP32 { static const uptr kSpaceBeg = 0; static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; static const uptr kMetadataSize = sizeof(ChunkMetadata); typedef __sanitizer::CompactSizeClassMap SizeClassMap; - static const uptr kRegionSizeLog = __lsan::kRegionSizeLog; - typedef __lsan::ByteMap ByteMap; + static const uptr kRegionSizeLog = 20; + using AddressSpaceView = AddressSpaceViewTy; typedef NoOpMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; -typedef SizeClassAllocator32 PrimaryAllocator; +template +using PrimaryAllocatorASVT = SizeClassAllocator32>; +using PrimaryAllocator = PrimaryAllocatorASVT; #elif defined(__x86_64__) || defined(__powerpc64__) # if defined(__powerpc64__) const uptr kAllocatorSpace = 0xa0000000000ULL; @@ -73,6 +73,7 @@ const uptr kAllocatorSize = 0x20000000000ULL; // 2T. const uptr kAllocatorSpace = 0x600000000000ULL; const uptr kAllocatorSize = 0x40000000000ULL; // 4T. # endif +template struct AP64 { // Allocator64 parameters. Deliberately using a short name. static const uptr kSpaceBeg = kAllocatorSpace; static const uptr kSpaceSize = kAllocatorSize; @@ -80,13 +81,20 @@ struct AP64 { // Allocator64 parameters. Deliberately using a short name. typedef DefaultSizeClassMap SizeClassMap; typedef NoOpMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; + using AddressSpaceView = AddressSpaceViewTy; }; -typedef SizeClassAllocator64 PrimaryAllocator; +template +using PrimaryAllocatorASVT = SizeClassAllocator64>; +using PrimaryAllocator = PrimaryAllocatorASVT; #endif -typedef SizeClassAllocatorLocalCache AllocatorCache; -AllocatorCache *GetAllocatorCache(); +template +using AllocatorASVT = CombinedAllocator>; +using Allocator = AllocatorASVT; +using AllocatorCache = Allocator::AllocatorCache; + +Allocator::AllocatorCache *GetAllocatorCache(); int lsan_posix_memalign(void **memptr, uptr alignment, uptr size, const StackTrace &stack); @@ -95,6 +103,8 @@ void *lsan_memalign(uptr alignment, uptr size, const StackTrace &stack); void *lsan_malloc(uptr size, const StackTrace &stack); void lsan_free(void *p); void *lsan_realloc(void *p, uptr size, const StackTrace &stack); +void *lsan_reallocarray(void *p, uptr nmemb, uptr size, + const StackTrace &stack); void *lsan_calloc(uptr nmemb, uptr size, const StackTrace &stack); void *lsan_valloc(uptr size, const StackTrace &stack); void *lsan_pvalloc(uptr size, const StackTrace &stack); diff --git a/libsanitizer/lsan/lsan_common.cc b/libsanitizer/lsan/lsan_common.cpp similarity index 99% rename from libsanitizer/lsan/lsan_common.cc rename to libsanitizer/lsan/lsan_common.cpp index a4424a8871a..c39fab97c64 100644 --- a/libsanitizer/lsan/lsan_common.cc +++ b/libsanitizer/lsan/lsan_common.cpp @@ -1,7 +1,8 @@ -//=-- lsan_common.cc ------------------------------------------------------===// +//=-- lsan_common.cpp -----------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/lsan/lsan_common.h b/libsanitizer/lsan/lsan_common.h index b82474a51c9..58dc00faaee 100644 --- a/libsanitizer/lsan/lsan_common.h +++ b/libsanitizer/lsan/lsan_common.h @@ -1,7 +1,8 @@ //=-- lsan_common.h -------------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -20,8 +21,8 @@ #include "sanitizer_common/sanitizer_stoptheworld.h" #include "sanitizer_common/sanitizer_symbolizer.h" -// LeakSanitizer relies on some Glibc's internals (e.g. TLS machinery) thus -// supported for Linux only. Also, LSan doesn't like 32 bit architectures +// LeakSanitizer relies on some Glibc's internals (e.g. TLS machinery) on Linux. +// Also, LSan doesn't like 32 bit architectures // because of "small" (4 bytes) pointer size that leads to high false negative // ratio on large leaks. But we still want to have it for some 32 bit arches // (e.g. x86), see https://github.com/google/sanitizers/issues/403. @@ -39,6 +40,8 @@ #elif defined(__arm__) && \ SANITIZER_LINUX && !SANITIZER_ANDROID #define CAN_SANITIZE_LEAKS 1 +#elif SANITIZER_NETBSD +#define CAN_SANITIZE_LEAKS 1 #else #define CAN_SANITIZE_LEAKS 0 #endif diff --git a/libsanitizer/lsan/lsan_common_linux.cc b/libsanitizer/lsan/lsan_common_linux.cpp similarity index 91% rename from libsanitizer/lsan/lsan_common_linux.cc rename to libsanitizer/lsan/lsan_common_linux.cpp index cffbfc9f8b1..9ce27a983b5 100644 --- a/libsanitizer/lsan/lsan_common_linux.cc +++ b/libsanitizer/lsan/lsan_common_linux.cpp @@ -1,19 +1,21 @@ -//=-- lsan_common_linux.cc ------------------------------------------------===// +//=-- lsan_common_linux.cpp -----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 LeakSanitizer. -// Implementation of common leak checking functionality. Linux-specific code. +// Implementation of common leak checking functionality. Linux/NetBSD-specific +// code. // //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" #include "lsan_common.h" -#if CAN_SANITIZE_LEAKS && SANITIZER_LINUX +#if CAN_SANITIZE_LEAKS && (SANITIZER_LINUX || SANITIZER_NETBSD) #include #include "sanitizer_common/sanitizer_common.h" @@ -135,4 +137,4 @@ void DoStopTheWorld(StopTheWorldCallback callback, void *argument) { } // namespace __lsan -#endif // CAN_SANITIZE_LEAKS && SANITIZER_LINUX +#endif diff --git a/libsanitizer/lsan/lsan_common_mac.cc b/libsanitizer/lsan/lsan_common_mac.cpp similarity index 94% rename from libsanitizer/lsan/lsan_common_mac.cc rename to libsanitizer/lsan/lsan_common_mac.cpp index 8337cd2116f..5204a6624ed 100644 --- a/libsanitizer/lsan/lsan_common_mac.cc +++ b/libsanitizer/lsan/lsan_common_mac.cpp @@ -1,7 +1,8 @@ -//=-- lsan_common_mac.cc --------------------------------------------------===// +//=-- lsan_common_mac.cpp -------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -11,6 +12,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" +#include "sanitizer_common/sanitizer_libc.h" #include "lsan_common.h" #if CAN_SANITIZE_LEAKS && SANITIZER_MAC @@ -114,7 +116,8 @@ static const char *kSkippedSecNames[] = { // Scans global variables for heap pointers. void ProcessGlobalRegions(Frontier *frontier) { - for (auto name : kSkippedSecNames) CHECK(ARRAY_SIZE(name) < kMaxSegName); + for (auto name : kSkippedSecNames) + CHECK(internal_strnlen(name, kMaxSegName + 1) <= kMaxSegName); MemoryMappingLayout memory_mapping(false); InternalMmapVector modules; diff --git a/libsanitizer/lsan/lsan_flags.inc b/libsanitizer/lsan/lsan_flags.inc index 98611257494..9350f4bcdc3 100644 --- a/libsanitizer/lsan/lsan_flags.inc +++ b/libsanitizer/lsan/lsan_flags.inc @@ -1,7 +1,8 @@ //===-- lsan_flags.inc ------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/lsan/lsan_interceptors.cc b/libsanitizer/lsan/lsan_interceptors.cpp similarity index 96% rename from libsanitizer/lsan/lsan_interceptors.cc rename to libsanitizer/lsan/lsan_interceptors.cpp index 7c594e5ed17..f06d5fff706 100644 --- a/libsanitizer/lsan/lsan_interceptors.cc +++ b/libsanitizer/lsan/lsan_interceptors.cpp @@ -1,7 +1,8 @@ -//=-- lsan_interceptors.cc ------------------------------------------------===// +//=-- lsan_interceptors.cpp -----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -82,6 +83,12 @@ INTERCEPTOR(void*, realloc, void *q, uptr size) { return lsan_realloc(q, size, stack); } +INTERCEPTOR(void*, reallocarray, void *q, uptr nmemb, uptr size) { + ENSURE_LSAN_INITED; + GET_STACK_TRACE_MALLOC; + return lsan_reallocarray(q, nmemb, size, stack); +} + INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) { ENSURE_LSAN_INITED; GET_STACK_TRACE_MALLOC; @@ -151,7 +158,7 @@ INTERCEPTOR(struct fake_mallinfo, mallinfo, void) { #define LSAN_MAYBE_INTERCEPT_MALLINFO INTERCEPT_FUNCTION(mallinfo) INTERCEPTOR(int, mallopt, int cmd, int value) { - return -1; + return 0; } #define LSAN_MAYBE_INTERCEPT_MALLOPT INTERCEPT_FUNCTION(mallopt) #else diff --git a/libsanitizer/lsan/lsan_linux.cc b/libsanitizer/lsan/lsan_linux.cpp similarity index 60% rename from libsanitizer/lsan/lsan_linux.cc rename to libsanitizer/lsan/lsan_linux.cpp index aa6445a9877..14a42b75d2a 100644 --- a/libsanitizer/lsan/lsan_linux.cc +++ b/libsanitizer/lsan/lsan_linux.cpp @@ -1,17 +1,18 @@ -//=-- lsan_linux.cc -------------------------------------------------------===// +//=-- lsan_linux.cpp ------------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 LeakSanitizer. Linux-specific code. +// This file is a part of LeakSanitizer. Linux/NetBSD-specific code. // //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" -#if SANITIZER_LINUX +#if SANITIZER_LINUX || SANITIZER_NETBSD #include "lsan_allocator.h" @@ -28,4 +29,4 @@ void ReplaceSystemMalloc() {} } // namespace __lsan -#endif // SANITIZER_LINUX +#endif // SANITIZER_LINUX || SANITIZER_NETBSD diff --git a/libsanitizer/lsan/lsan_mac.cc b/libsanitizer/lsan/lsan_mac.cpp similarity index 96% rename from libsanitizer/lsan/lsan_mac.cc rename to libsanitizer/lsan/lsan_mac.cpp index ca38c1c6f8a..7bcd9c828ef 100644 --- a/libsanitizer/lsan/lsan_mac.cc +++ b/libsanitizer/lsan/lsan_mac.cpp @@ -1,7 +1,8 @@ -//===-- lsan_mac.cc -------------------------------------------------------===// +//===-- lsan_mac.cpp ------------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/lsan/lsan_malloc_mac.cc b/libsanitizer/lsan/lsan_malloc_mac.cpp similarity index 83% rename from libsanitizer/lsan/lsan_malloc_mac.cc rename to libsanitizer/lsan/lsan_malloc_mac.cpp index 2458b50892f..d03eb2e915c 100644 --- a/libsanitizer/lsan/lsan_malloc_mac.cc +++ b/libsanitizer/lsan/lsan_malloc_mac.cpp @@ -1,7 +1,8 @@ -//===-- lsan_malloc_mac.cc ------------------------------------------------===// +//===-- lsan_malloc_mac.cpp -----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -50,6 +51,8 @@ using namespace __lsan; (void)zone_name; \ Report("mz_realloc(%p) -- attempting to realloc unallocated memory.\n", ptr); #define COMMON_MALLOC_NAMESPACE __lsan +#define COMMON_MALLOC_HAS_ZONE_ENUMERATOR 0 +#define COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT 0 #include "sanitizer_common/sanitizer_malloc_mac.inc" diff --git a/libsanitizer/lsan/lsan_preinit.cc b/libsanitizer/lsan/lsan_preinit.cpp similarity index 68% rename from libsanitizer/lsan/lsan_preinit.cc rename to libsanitizer/lsan/lsan_preinit.cpp index d1efd31406b..cd94e1e8718 100644 --- a/libsanitizer/lsan/lsan_preinit.cc +++ b/libsanitizer/lsan/lsan_preinit.cpp @@ -1,7 +1,8 @@ -//===-- lsan_preinit.cc ---------------------------------------------------===// +//===-- lsan_preinit.cpp --------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/lsan/lsan_thread.cc b/libsanitizer/lsan/lsan_thread.cpp similarity index 91% rename from libsanitizer/lsan/lsan_thread.cc rename to libsanitizer/lsan/lsan_thread.cpp index 388990bf5fd..84e7ce61b97 100644 --- a/libsanitizer/lsan/lsan_thread.cc +++ b/libsanitizer/lsan/lsan_thread.cpp @@ -1,7 +1,8 @@ -//=-- lsan_thread.cc ------------------------------------------------------===// +//=-- lsan_thread.cpp -----------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -75,7 +76,7 @@ u32 ThreadCreate(u32 parent_tid, uptr user_id, bool detached) { /* arg */ nullptr); } -void ThreadStart(u32 tid, tid_t os_id, bool workerthread) { +void ThreadStart(u32 tid, tid_t os_id, ThreadType thread_type) { OnStartedArgs args; uptr stack_size = 0; uptr tls_size = 0; @@ -85,7 +86,7 @@ void ThreadStart(u32 tid, tid_t os_id, bool workerthread) { args.tls_end = args.tls_begin + tls_size; GetAllocatorCacheRange(&args.cache_begin, &args.cache_end); args.dtls = DTLS_Get(); - thread_registry->StartThread(tid, os_id, workerthread, &args); + thread_registry->StartThread(tid, os_id, thread_type, &args); } void ThreadFinish() { diff --git a/libsanitizer/lsan/lsan_thread.h b/libsanitizer/lsan/lsan_thread.h index 86758347432..b869d066d9d 100644 --- a/libsanitizer/lsan/lsan_thread.h +++ b/libsanitizer/lsan/lsan_thread.h @@ -1,7 +1,8 @@ //=-- lsan_thread.h -------------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -43,7 +44,8 @@ class ThreadContext : public ThreadContextBase { void InitializeThreadRegistry(); -void ThreadStart(u32 tid, tid_t os_id, bool workerthread = false); +void ThreadStart(u32 tid, tid_t os_id, + ThreadType thread_type = ThreadType::Regular); void ThreadFinish(); u32 ThreadCreate(u32 tid, uptr uid, bool detached); void ThreadJoin(u32 tid); diff --git a/libsanitizer/merge.sh b/libsanitizer/merge.sh index fa340bedbac..168fbbc9729 100755 --- a/libsanitizer/merge.sh +++ b/libsanitizer/merge.sh @@ -18,7 +18,7 @@ get_current_rev() { } list_files() { - (cd $1; ls *.{cc,h,inc,S} 2> /dev/null) + (cd $1; ls *.{cc,cpp,h,inc,S} 2> /dev/null) } @@ -74,6 +74,7 @@ merge lib/tsan/rtl tsan merge lib/sanitizer_common sanitizer_common merge lib/interception interception merge lib/ubsan ubsan +merge lib/BlocksRuntime/ BlocksRuntime # Need to merge lib/builtins/assembly.h file: mkdir -p builtins diff --git a/libsanitizer/sanitizer_common/Makefile.am b/libsanitizer/sanitizer_common/Makefile.am index b04e755b660..7e8ce9476ed 100644 --- a/libsanitizer/sanitizer_common/Makefile.am +++ b/libsanitizer/sanitizer_common/Makefile.am @@ -10,6 +10,7 @@ AM_CXXFLAGS += -std=gnu++11 AM_CXXFLAGS += $(EXTRA_CXXFLAGS) if LIBBACKTRACE_SUPPORTED AM_CXXFLAGS += -DSANITIZER_LIBBACKTRACE -DSANITIZER_CP_DEMANGLE \ + -I $(top_srcdir)/ \ -I $(top_srcdir)/../libbacktrace \ -I $(top_builddir)/libbacktrace \ -I $(top_srcdir)/../include \ @@ -21,68 +22,67 @@ ACLOCAL_AMFLAGS = -I m4 noinst_LTLIBRARIES = libsanitizer_common.la sanitizer_common_files = \ - sancov_flags.cc \ - sanitizer_allocator.cc \ - sanitizer_allocator_checks.cc \ - sanitizer_allocator_report.cc \ - sanitizer_common.cc \ - sanitizer_common_libcdep.cc \ - sanitizer_coverage_libcdep_new.cc \ - sanitizer_deadlock_detector1.cc \ - sanitizer_deadlock_detector2.cc \ - sanitizer_errno.cc \ - sanitizer_file.cc \ - sanitizer_flags.cc \ - sanitizer_flag_parser.cc \ - sanitizer_libc.cc \ - sanitizer_libignore.cc \ - sanitizer_linux.cc \ - sanitizer_linux_libcdep.cc \ - sanitizer_linux_s390.cc \ - sanitizer_mac.cc \ - sanitizer_mac_libcdep.cc \ - sanitizer_netbsd.cc \ - sanitizer_openbsd.cc \ - sanitizer_persistent_allocator.cc \ - sanitizer_platform_limits_linux.cc \ - sanitizer_platform_limits_openbsd.cc \ - sanitizer_platform_limits_posix.cc \ - sanitizer_platform_limits_solaris.cc \ - sanitizer_posix.cc \ - sanitizer_posix_libcdep.cc \ - sanitizer_printf.cc \ - sanitizer_procmaps_bsd.cc \ - sanitizer_procmaps_common.cc \ - sanitizer_procmaps_linux.cc \ - sanitizer_procmaps_mac.cc \ - sanitizer_procmaps_solaris.cc \ - sanitizer_rtems.cc \ - sanitizer_solaris.cc \ - sanitizer_stackdepot.cc \ - sanitizer_stacktrace.cc \ - sanitizer_stacktrace_libcdep.cc \ - sanitizer_stacktrace_sparc.cc \ - sanitizer_symbolizer_mac.cc \ - sanitizer_symbolizer_report.cc \ - sanitizer_stacktrace_printer.cc \ - sanitizer_stoptheworld_linux_libcdep.cc \ - sanitizer_stoptheworld_mac.cc \ - sanitizer_suppressions.cc \ - sanitizer_symbolizer.cc \ - sanitizer_symbolizer_libbacktrace.cc \ - sanitizer_symbolizer_libcdep.cc \ - sanitizer_symbolizer_posix_libcdep.cc \ - sanitizer_symbolizer_win.cc \ - sanitizer_termination.cc \ - sanitizer_thread_registry.cc \ - sanitizer_tls_get_addr.cc \ - sanitizer_unwind_linux_libcdep.cc \ - sanitizer_unwind_win.cc \ - sanitizer_win.cc + sancov_flags.cpp \ + sanitizer_allocator.cpp \ + sanitizer_allocator_checks.cpp \ + sanitizer_allocator_report.cpp \ + sanitizer_common.cpp \ + sanitizer_common_libcdep.cpp \ + sanitizer_coverage_libcdep_new.cpp \ + sanitizer_deadlock_detector1.cpp \ + sanitizer_deadlock_detector2.cpp \ + sanitizer_errno.cpp \ + sanitizer_file.cpp \ + sanitizer_flags.cpp \ + sanitizer_flag_parser.cpp \ + sanitizer_libc.cpp \ + sanitizer_libignore.cpp \ + sanitizer_linux.cpp \ + sanitizer_linux_libcdep.cpp \ + sanitizer_linux_s390.cpp \ + sanitizer_mac.cpp \ + sanitizer_mac_libcdep.cpp \ + sanitizer_netbsd.cpp \ + sanitizer_openbsd.cpp \ + sanitizer_persistent_allocator.cpp \ + sanitizer_platform_limits_linux.cpp \ + sanitizer_platform_limits_openbsd.cpp \ + sanitizer_platform_limits_posix.cpp \ + sanitizer_platform_limits_solaris.cpp \ + sanitizer_posix.cpp \ + sanitizer_posix_libcdep.cpp \ + sanitizer_printf.cpp \ + sanitizer_procmaps_bsd.cpp \ + sanitizer_procmaps_common.cpp \ + sanitizer_procmaps_linux.cpp \ + sanitizer_procmaps_mac.cpp \ + sanitizer_procmaps_solaris.cpp \ + sanitizer_rtems.cpp \ + sanitizer_solaris.cpp \ + sanitizer_stackdepot.cpp \ + sanitizer_stacktrace.cpp \ + sanitizer_stacktrace_libcdep.cpp \ + sanitizer_stacktrace_sparc.cpp \ + sanitizer_symbolizer_mac.cpp \ + sanitizer_symbolizer_report.cpp \ + sanitizer_stacktrace_printer.cpp \ + sanitizer_stoptheworld_linux_libcdep.cpp \ + sanitizer_stoptheworld_mac.cpp \ + sanitizer_suppressions.cpp \ + sanitizer_symbolizer.cpp \ + sanitizer_symbolizer_libbacktrace.cpp \ + sanitizer_symbolizer_libcdep.cpp \ + sanitizer_symbolizer_posix_libcdep.cpp \ + sanitizer_symbolizer_win.cpp \ + sanitizer_termination.cpp \ + sanitizer_thread_registry.cpp \ + sanitizer_tls_get_addr.cpp \ + sanitizer_unwind_linux_libcdep.cpp \ + sanitizer_unwind_win.cpp \ + sanitizer_win.cpp libsanitizer_common_la_SOURCES = $(sanitizer_common_files) -EXTRA_libsanitizer_common_la_SOURCES = sanitizer_linux_mips64.S sanitizer_linux_x86_64.S libsanitizer_common_la_LIBADD = $(SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS) libsanitizer_common_la_DEPENDENCIES = $(SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS) diff --git a/libsanitizer/sanitizer_common/Makefile.in b/libsanitizer/sanitizer_common/Makefile.in index d33d2227938..6cc219fbf34 100644 --- a/libsanitizer/sanitizer_common/Makefile.in +++ b/libsanitizer/sanitizer_common/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -90,6 +90,7 @@ build_triplet = @build@ host_triplet = @host@ target_triplet = @target@ @LIBBACKTRACE_SUPPORTED_TRUE@am__append_1 = -DSANITIZER_LIBBACKTRACE -DSANITIZER_CP_DEMANGLE \ +@LIBBACKTRACE_SUPPORTED_TRUE@ -I $(top_srcdir)/ \ @LIBBACKTRACE_SUPPORTED_TRUE@ -I $(top_srcdir)/../libbacktrace \ @LIBBACKTRACE_SUPPORTED_TRUE@ -I $(top_builddir)/libbacktrace \ @LIBBACKTRACE_SUPPORTED_TRUE@ -I $(top_srcdir)/../include \ @@ -170,18 +171,64 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/../depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/sancov_flags.Plo \ + ./$(DEPDIR)/sanitizer_allocator.Plo \ + ./$(DEPDIR)/sanitizer_allocator_checks.Plo \ + ./$(DEPDIR)/sanitizer_allocator_report.Plo \ + ./$(DEPDIR)/sanitizer_common.Plo \ + ./$(DEPDIR)/sanitizer_common_libcdep.Plo \ + ./$(DEPDIR)/sanitizer_coverage_libcdep_new.Plo \ + ./$(DEPDIR)/sanitizer_deadlock_detector1.Plo \ + ./$(DEPDIR)/sanitizer_deadlock_detector2.Plo \ + ./$(DEPDIR)/sanitizer_errno.Plo ./$(DEPDIR)/sanitizer_file.Plo \ + ./$(DEPDIR)/sanitizer_flag_parser.Plo \ + ./$(DEPDIR)/sanitizer_flags.Plo ./$(DEPDIR)/sanitizer_libc.Plo \ + ./$(DEPDIR)/sanitizer_libignore.Plo \ + ./$(DEPDIR)/sanitizer_linux.Plo \ + ./$(DEPDIR)/sanitizer_linux_libcdep.Plo \ + ./$(DEPDIR)/sanitizer_linux_s390.Plo \ + ./$(DEPDIR)/sanitizer_mac.Plo \ + ./$(DEPDIR)/sanitizer_mac_libcdep.Plo \ + ./$(DEPDIR)/sanitizer_netbsd.Plo \ + ./$(DEPDIR)/sanitizer_openbsd.Plo \ + ./$(DEPDIR)/sanitizer_persistent_allocator.Plo \ + ./$(DEPDIR)/sanitizer_platform_limits_linux.Plo \ + ./$(DEPDIR)/sanitizer_platform_limits_openbsd.Plo \ + ./$(DEPDIR)/sanitizer_platform_limits_posix.Plo \ + ./$(DEPDIR)/sanitizer_platform_limits_solaris.Plo \ + ./$(DEPDIR)/sanitizer_posix.Plo \ + ./$(DEPDIR)/sanitizer_posix_libcdep.Plo \ + ./$(DEPDIR)/sanitizer_printf.Plo \ + ./$(DEPDIR)/sanitizer_procmaps_bsd.Plo \ + ./$(DEPDIR)/sanitizer_procmaps_common.Plo \ + ./$(DEPDIR)/sanitizer_procmaps_linux.Plo \ + ./$(DEPDIR)/sanitizer_procmaps_mac.Plo \ + ./$(DEPDIR)/sanitizer_procmaps_solaris.Plo \ + ./$(DEPDIR)/sanitizer_rtems.Plo \ + ./$(DEPDIR)/sanitizer_solaris.Plo \ + ./$(DEPDIR)/sanitizer_stackdepot.Plo \ + ./$(DEPDIR)/sanitizer_stacktrace.Plo \ + ./$(DEPDIR)/sanitizer_stacktrace_libcdep.Plo \ + ./$(DEPDIR)/sanitizer_stacktrace_printer.Plo \ + ./$(DEPDIR)/sanitizer_stacktrace_sparc.Plo \ + ./$(DEPDIR)/sanitizer_stoptheworld_linux_libcdep.Plo \ + ./$(DEPDIR)/sanitizer_stoptheworld_mac.Plo \ + ./$(DEPDIR)/sanitizer_suppressions.Plo \ + ./$(DEPDIR)/sanitizer_symbolizer.Plo \ + ./$(DEPDIR)/sanitizer_symbolizer_libbacktrace.Plo \ + ./$(DEPDIR)/sanitizer_symbolizer_libcdep.Plo \ + ./$(DEPDIR)/sanitizer_symbolizer_mac.Plo \ + ./$(DEPDIR)/sanitizer_symbolizer_posix_libcdep.Plo \ + ./$(DEPDIR)/sanitizer_symbolizer_report.Plo \ + ./$(DEPDIR)/sanitizer_symbolizer_win.Plo \ + ./$(DEPDIR)/sanitizer_termination.Plo \ + ./$(DEPDIR)/sanitizer_thread_registry.Plo \ + ./$(DEPDIR)/sanitizer_tls_get_addr.Plo \ + ./$(DEPDIR)/sanitizer_unwind_linux_libcdep.Plo \ + ./$(DEPDIR)/sanitizer_unwind_win.Plo \ + ./$(DEPDIR)/sanitizer_win.Plo am__mv = mv -f -CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ - $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CCASFLAGS) $(CCASFLAGS) -AM_V_CPPAS = $(am__v_CPPAS_@AM_V@) -am__v_CPPAS_ = $(am__v_CPPAS_@AM_DEFAULT_V@) -am__v_CPPAS_0 = @echo " CPPAS " $@; -am__v_CPPAS_1 = CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ @@ -200,26 +247,7 @@ AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) am__v_CXXLD_0 = @echo " CXXLD " $@; am__v_CXXLD_1 = -COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ - $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) -LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ - $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ - $(AM_CFLAGS) $(CFLAGS) -AM_V_CC = $(am__v_CC_@AM_V@) -am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) -am__v_CC_0 = @echo " CC " $@; -am__v_CC_1 = -CCLD = $(CC) -LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ - $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ - $(AM_LDFLAGS) $(LDFLAGS) -o $@ -AM_V_CCLD = $(am__v_CCLD_@AM_V@) -am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) -am__v_CCLD_0 = @echo " CCLD " $@; -am__v_CCLD_1 = -SOURCES = $(libsanitizer_common_la_SOURCES) \ - $(EXTRA_libsanitizer_common_la_SOURCES) +SOURCES = $(libsanitizer_common_la_SOURCES) am__can_run_installinfo = \ case $$AM_UPDATE_INFO_DIR in \ n|no|NO) false;; \ @@ -406,67 +434,66 @@ AM_CCASFLAGS = $(EXTRA_ASFLAGS) ACLOCAL_AMFLAGS = -I m4 noinst_LTLIBRARIES = libsanitizer_common.la sanitizer_common_files = \ - sancov_flags.cc \ - sanitizer_allocator.cc \ - sanitizer_allocator_checks.cc \ - sanitizer_allocator_report.cc \ - sanitizer_common.cc \ - sanitizer_common_libcdep.cc \ - sanitizer_coverage_libcdep_new.cc \ - sanitizer_deadlock_detector1.cc \ - sanitizer_deadlock_detector2.cc \ - sanitizer_errno.cc \ - sanitizer_file.cc \ - sanitizer_flags.cc \ - sanitizer_flag_parser.cc \ - sanitizer_libc.cc \ - sanitizer_libignore.cc \ - sanitizer_linux.cc \ - sanitizer_linux_libcdep.cc \ - sanitizer_linux_s390.cc \ - sanitizer_mac.cc \ - sanitizer_mac_libcdep.cc \ - sanitizer_netbsd.cc \ - sanitizer_openbsd.cc \ - sanitizer_persistent_allocator.cc \ - sanitizer_platform_limits_linux.cc \ - sanitizer_platform_limits_openbsd.cc \ - sanitizer_platform_limits_posix.cc \ - sanitizer_platform_limits_solaris.cc \ - sanitizer_posix.cc \ - sanitizer_posix_libcdep.cc \ - sanitizer_printf.cc \ - sanitizer_procmaps_bsd.cc \ - sanitizer_procmaps_common.cc \ - sanitizer_procmaps_linux.cc \ - sanitizer_procmaps_mac.cc \ - sanitizer_procmaps_solaris.cc \ - sanitizer_rtems.cc \ - sanitizer_solaris.cc \ - sanitizer_stackdepot.cc \ - sanitizer_stacktrace.cc \ - sanitizer_stacktrace_libcdep.cc \ - sanitizer_stacktrace_sparc.cc \ - sanitizer_symbolizer_mac.cc \ - sanitizer_symbolizer_report.cc \ - sanitizer_stacktrace_printer.cc \ - sanitizer_stoptheworld_linux_libcdep.cc \ - sanitizer_stoptheworld_mac.cc \ - sanitizer_suppressions.cc \ - sanitizer_symbolizer.cc \ - sanitizer_symbolizer_libbacktrace.cc \ - sanitizer_symbolizer_libcdep.cc \ - sanitizer_symbolizer_posix_libcdep.cc \ - sanitizer_symbolizer_win.cc \ - sanitizer_termination.cc \ - sanitizer_thread_registry.cc \ - sanitizer_tls_get_addr.cc \ - sanitizer_unwind_linux_libcdep.cc \ - sanitizer_unwind_win.cc \ - sanitizer_win.cc + sancov_flags.cpp \ + sanitizer_allocator.cpp \ + sanitizer_allocator_checks.cpp \ + sanitizer_allocator_report.cpp \ + sanitizer_common.cpp \ + sanitizer_common_libcdep.cpp \ + sanitizer_coverage_libcdep_new.cpp \ + sanitizer_deadlock_detector1.cpp \ + sanitizer_deadlock_detector2.cpp \ + sanitizer_errno.cpp \ + sanitizer_file.cpp \ + sanitizer_flags.cpp \ + sanitizer_flag_parser.cpp \ + sanitizer_libc.cpp \ + sanitizer_libignore.cpp \ + sanitizer_linux.cpp \ + sanitizer_linux_libcdep.cpp \ + sanitizer_linux_s390.cpp \ + sanitizer_mac.cpp \ + sanitizer_mac_libcdep.cpp \ + sanitizer_netbsd.cpp \ + sanitizer_openbsd.cpp \ + sanitizer_persistent_allocator.cpp \ + sanitizer_platform_limits_linux.cpp \ + sanitizer_platform_limits_openbsd.cpp \ + sanitizer_platform_limits_posix.cpp \ + sanitizer_platform_limits_solaris.cpp \ + sanitizer_posix.cpp \ + sanitizer_posix_libcdep.cpp \ + sanitizer_printf.cpp \ + sanitizer_procmaps_bsd.cpp \ + sanitizer_procmaps_common.cpp \ + sanitizer_procmaps_linux.cpp \ + sanitizer_procmaps_mac.cpp \ + sanitizer_procmaps_solaris.cpp \ + sanitizer_rtems.cpp \ + sanitizer_solaris.cpp \ + sanitizer_stackdepot.cpp \ + sanitizer_stacktrace.cpp \ + sanitizer_stacktrace_libcdep.cpp \ + sanitizer_stacktrace_sparc.cpp \ + sanitizer_symbolizer_mac.cpp \ + sanitizer_symbolizer_report.cpp \ + sanitizer_stacktrace_printer.cpp \ + sanitizer_stoptheworld_linux_libcdep.cpp \ + sanitizer_stoptheworld_mac.cpp \ + sanitizer_suppressions.cpp \ + sanitizer_symbolizer.cpp \ + sanitizer_symbolizer_libbacktrace.cpp \ + sanitizer_symbolizer_libcdep.cpp \ + sanitizer_symbolizer_posix_libcdep.cpp \ + sanitizer_symbolizer_win.cpp \ + sanitizer_termination.cpp \ + sanitizer_thread_registry.cpp \ + sanitizer_tls_get_addr.cpp \ + sanitizer_unwind_linux_libcdep.cpp \ + sanitizer_unwind_win.cpp \ + sanitizer_win.cpp libsanitizer_common_la_SOURCES = $(sanitizer_common_files) -EXTRA_libsanitizer_common_la_SOURCES = sanitizer_linux_mips64.S sanitizer_linux_x86_64.S libsanitizer_common_la_LIBADD = $(SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS) libsanitizer_common_la_DEPENDENCIES = $(SANITIZER_COMMON_TARGET_DEPENDENT_OBJECTS) @@ -512,7 +539,7 @@ MAKEOVERRIDES = all: all-am .SUFFIXES: -.SUFFIXES: .S .cc .lo .o .obj +.SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -530,8 +557,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -563,103 +590,86 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sancov_flags.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_allocator.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_allocator_checks.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_allocator_report.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_common.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_common_libcdep.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_coverage_libcdep_new.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_deadlock_detector1.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_deadlock_detector2.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_errno.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_file.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_flag_parser.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_flags.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_libc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_libignore.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux_libcdep.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux_mips64.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux_s390.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux_x86_64.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_mac.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_mac_libcdep.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_netbsd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_openbsd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_persistent_allocator.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_platform_limits_linux.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_platform_limits_openbsd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_platform_limits_posix.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_platform_limits_solaris.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_posix.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_posix_libcdep.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_printf.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_procmaps_bsd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_procmaps_common.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_procmaps_linux.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_procmaps_mac.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_procmaps_solaris.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_rtems.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_solaris.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_stackdepot.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_stacktrace.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_stacktrace_libcdep.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_stacktrace_printer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_stacktrace_sparc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_stoptheworld_linux_libcdep.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_stoptheworld_mac.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_suppressions.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_symbolizer.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_symbolizer_libbacktrace.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_symbolizer_libcdep.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_symbolizer_mac.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_symbolizer_posix_libcdep.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_symbolizer_report.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_symbolizer_win.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_termination.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_thread_registry.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_tls_get_addr.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_unwind_linux_libcdep.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_unwind_win.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_win.Plo@am__quote@ - -.S.o: -@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ $< - -.S.obj: -@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` -@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po -@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(CPPASCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` - -.S.lo: -@am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(LTCPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< -@am__fastdepCCAS_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo -@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ -@AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ -@am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(LTCPPASCOMPILE) -c -o $@ $< - -.cc.o: +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sancov_flags.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_allocator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_allocator_checks.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_allocator_report.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_common.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_common_libcdep.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_coverage_libcdep_new.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_deadlock_detector1.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_deadlock_detector2.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_errno.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_file.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_flag_parser.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_flags.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_libc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_libignore.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux_libcdep.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_linux_s390.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_mac.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_mac_libcdep.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_netbsd.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_openbsd.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_persistent_allocator.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_platform_limits_linux.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_platform_limits_openbsd.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_platform_limits_posix.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_platform_limits_solaris.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_posix.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_posix_libcdep.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_printf.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_procmaps_bsd.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_procmaps_common.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_procmaps_linux.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_procmaps_mac.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_procmaps_solaris.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_rtems.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_solaris.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_stackdepot.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_stacktrace.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_stacktrace_libcdep.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_stacktrace_printer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_stacktrace_sparc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_stoptheworld_linux_libcdep.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_stoptheworld_mac.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_suppressions.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_symbolizer.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_symbolizer_libbacktrace.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_symbolizer_libcdep.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_symbolizer_mac.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_symbolizer_posix_libcdep.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_symbolizer_report.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_symbolizer_win.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_termination.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_thread_registry.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_tls_get_addr.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_unwind_linux_libcdep.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_unwind_win.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/sanitizer_win.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< -.cc.obj: +.cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` -.cc.lo: +.cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @@ -763,7 +773,64 @@ clean-am: clean-generic clean-libtool clean-noinstLTLIBRARIES \ mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/sancov_flags.Plo + -rm -f ./$(DEPDIR)/sanitizer_allocator.Plo + -rm -f ./$(DEPDIR)/sanitizer_allocator_checks.Plo + -rm -f ./$(DEPDIR)/sanitizer_allocator_report.Plo + -rm -f ./$(DEPDIR)/sanitizer_common.Plo + -rm -f ./$(DEPDIR)/sanitizer_common_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_coverage_libcdep_new.Plo + -rm -f ./$(DEPDIR)/sanitizer_deadlock_detector1.Plo + -rm -f ./$(DEPDIR)/sanitizer_deadlock_detector2.Plo + -rm -f ./$(DEPDIR)/sanitizer_errno.Plo + -rm -f ./$(DEPDIR)/sanitizer_file.Plo + -rm -f ./$(DEPDIR)/sanitizer_flag_parser.Plo + -rm -f ./$(DEPDIR)/sanitizer_flags.Plo + -rm -f ./$(DEPDIR)/sanitizer_libc.Plo + -rm -f ./$(DEPDIR)/sanitizer_libignore.Plo + -rm -f ./$(DEPDIR)/sanitizer_linux.Plo + -rm -f ./$(DEPDIR)/sanitizer_linux_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_linux_s390.Plo + -rm -f ./$(DEPDIR)/sanitizer_mac.Plo + -rm -f ./$(DEPDIR)/sanitizer_mac_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_netbsd.Plo + -rm -f ./$(DEPDIR)/sanitizer_openbsd.Plo + -rm -f ./$(DEPDIR)/sanitizer_persistent_allocator.Plo + -rm -f ./$(DEPDIR)/sanitizer_platform_limits_linux.Plo + -rm -f ./$(DEPDIR)/sanitizer_platform_limits_openbsd.Plo + -rm -f ./$(DEPDIR)/sanitizer_platform_limits_posix.Plo + -rm -f ./$(DEPDIR)/sanitizer_platform_limits_solaris.Plo + -rm -f ./$(DEPDIR)/sanitizer_posix.Plo + -rm -f ./$(DEPDIR)/sanitizer_posix_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_printf.Plo + -rm -f ./$(DEPDIR)/sanitizer_procmaps_bsd.Plo + -rm -f ./$(DEPDIR)/sanitizer_procmaps_common.Plo + -rm -f ./$(DEPDIR)/sanitizer_procmaps_linux.Plo + -rm -f ./$(DEPDIR)/sanitizer_procmaps_mac.Plo + -rm -f ./$(DEPDIR)/sanitizer_procmaps_solaris.Plo + -rm -f ./$(DEPDIR)/sanitizer_rtems.Plo + -rm -f ./$(DEPDIR)/sanitizer_solaris.Plo + -rm -f ./$(DEPDIR)/sanitizer_stackdepot.Plo + -rm -f ./$(DEPDIR)/sanitizer_stacktrace.Plo + -rm -f ./$(DEPDIR)/sanitizer_stacktrace_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_stacktrace_printer.Plo + -rm -f ./$(DEPDIR)/sanitizer_stacktrace_sparc.Plo + -rm -f ./$(DEPDIR)/sanitizer_stoptheworld_linux_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_stoptheworld_mac.Plo + -rm -f ./$(DEPDIR)/sanitizer_suppressions.Plo + -rm -f ./$(DEPDIR)/sanitizer_symbolizer.Plo + -rm -f ./$(DEPDIR)/sanitizer_symbolizer_libbacktrace.Plo + -rm -f ./$(DEPDIR)/sanitizer_symbolizer_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_symbolizer_mac.Plo + -rm -f ./$(DEPDIR)/sanitizer_symbolizer_posix_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_symbolizer_report.Plo + -rm -f ./$(DEPDIR)/sanitizer_symbolizer_win.Plo + -rm -f ./$(DEPDIR)/sanitizer_termination.Plo + -rm -f ./$(DEPDIR)/sanitizer_thread_registry.Plo + -rm -f ./$(DEPDIR)/sanitizer_tls_get_addr.Plo + -rm -f ./$(DEPDIR)/sanitizer_unwind_linux_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_unwind_win.Plo + -rm -f ./$(DEPDIR)/sanitizer_win.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -809,7 +876,64 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/sancov_flags.Plo + -rm -f ./$(DEPDIR)/sanitizer_allocator.Plo + -rm -f ./$(DEPDIR)/sanitizer_allocator_checks.Plo + -rm -f ./$(DEPDIR)/sanitizer_allocator_report.Plo + -rm -f ./$(DEPDIR)/sanitizer_common.Plo + -rm -f ./$(DEPDIR)/sanitizer_common_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_coverage_libcdep_new.Plo + -rm -f ./$(DEPDIR)/sanitizer_deadlock_detector1.Plo + -rm -f ./$(DEPDIR)/sanitizer_deadlock_detector2.Plo + -rm -f ./$(DEPDIR)/sanitizer_errno.Plo + -rm -f ./$(DEPDIR)/sanitizer_file.Plo + -rm -f ./$(DEPDIR)/sanitizer_flag_parser.Plo + -rm -f ./$(DEPDIR)/sanitizer_flags.Plo + -rm -f ./$(DEPDIR)/sanitizer_libc.Plo + -rm -f ./$(DEPDIR)/sanitizer_libignore.Plo + -rm -f ./$(DEPDIR)/sanitizer_linux.Plo + -rm -f ./$(DEPDIR)/sanitizer_linux_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_linux_s390.Plo + -rm -f ./$(DEPDIR)/sanitizer_mac.Plo + -rm -f ./$(DEPDIR)/sanitizer_mac_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_netbsd.Plo + -rm -f ./$(DEPDIR)/sanitizer_openbsd.Plo + -rm -f ./$(DEPDIR)/sanitizer_persistent_allocator.Plo + -rm -f ./$(DEPDIR)/sanitizer_platform_limits_linux.Plo + -rm -f ./$(DEPDIR)/sanitizer_platform_limits_openbsd.Plo + -rm -f ./$(DEPDIR)/sanitizer_platform_limits_posix.Plo + -rm -f ./$(DEPDIR)/sanitizer_platform_limits_solaris.Plo + -rm -f ./$(DEPDIR)/sanitizer_posix.Plo + -rm -f ./$(DEPDIR)/sanitizer_posix_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_printf.Plo + -rm -f ./$(DEPDIR)/sanitizer_procmaps_bsd.Plo + -rm -f ./$(DEPDIR)/sanitizer_procmaps_common.Plo + -rm -f ./$(DEPDIR)/sanitizer_procmaps_linux.Plo + -rm -f ./$(DEPDIR)/sanitizer_procmaps_mac.Plo + -rm -f ./$(DEPDIR)/sanitizer_procmaps_solaris.Plo + -rm -f ./$(DEPDIR)/sanitizer_rtems.Plo + -rm -f ./$(DEPDIR)/sanitizer_solaris.Plo + -rm -f ./$(DEPDIR)/sanitizer_stackdepot.Plo + -rm -f ./$(DEPDIR)/sanitizer_stacktrace.Plo + -rm -f ./$(DEPDIR)/sanitizer_stacktrace_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_stacktrace_printer.Plo + -rm -f ./$(DEPDIR)/sanitizer_stacktrace_sparc.Plo + -rm -f ./$(DEPDIR)/sanitizer_stoptheworld_linux_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_stoptheworld_mac.Plo + -rm -f ./$(DEPDIR)/sanitizer_suppressions.Plo + -rm -f ./$(DEPDIR)/sanitizer_symbolizer.Plo + -rm -f ./$(DEPDIR)/sanitizer_symbolizer_libbacktrace.Plo + -rm -f ./$(DEPDIR)/sanitizer_symbolizer_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_symbolizer_mac.Plo + -rm -f ./$(DEPDIR)/sanitizer_symbolizer_posix_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_symbolizer_report.Plo + -rm -f ./$(DEPDIR)/sanitizer_symbolizer_win.Plo + -rm -f ./$(DEPDIR)/sanitizer_termination.Plo + -rm -f ./$(DEPDIR)/sanitizer_thread_registry.Plo + -rm -f ./$(DEPDIR)/sanitizer_tls_get_addr.Plo + -rm -f ./$(DEPDIR)/sanitizer_unwind_linux_libcdep.Plo + -rm -f ./$(DEPDIR)/sanitizer_unwind_win.Plo + -rm -f ./$(DEPDIR)/sanitizer_win.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -830,19 +954,19 @@ uninstall-am: .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-noinstLTLIBRARIES cscopelist-am ctags \ - ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags dvi dvi-am html html-am info \ - info-am install install-am install-data install-data-am \ - install-dvi install-dvi-am install-exec install-exec-am \ - install-html install-html-am install-info install-info-am \ - install-man install-pdf install-pdf-am install-ps \ - install-ps-am install-strip installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-noinstLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags dvi dvi-am \ + html html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am .PRECIOUS: Makefile diff --git a/libsanitizer/sanitizer_common/sancov_begin.S b/libsanitizer/sanitizer_common/sancov_begin.S deleted file mode 100644 index c8ad0a0bcb5..00000000000 --- a/libsanitizer/sanitizer_common/sancov_begin.S +++ /dev/null @@ -1,5 +0,0 @@ - .type __start___sancov_guards,@object - .globl __start___sancov_guards - .section __sancov_guards,"aw",@progbits - .p2align 2 -__start___sancov_guards: diff --git a/libsanitizer/sanitizer_common/sancov_end.S b/libsanitizer/sanitizer_common/sancov_end.S deleted file mode 100644 index 31117b1c0b5..00000000000 --- a/libsanitizer/sanitizer_common/sancov_end.S +++ /dev/null @@ -1,5 +0,0 @@ - .type __stop___sancov_guards,@object - .globl __stop___sancov_guards - .section __sancov_guards,"aw",@progbits - .p2align 2 -__stop___sancov_guards: diff --git a/libsanitizer/sanitizer_common/sancov_flags.cc b/libsanitizer/sanitizer_common/sancov_flags.cpp similarity index 81% rename from libsanitizer/sanitizer_common/sancov_flags.cc rename to libsanitizer/sanitizer_common/sancov_flags.cpp index e600cdac33c..ed46e88acdf 100644 --- a/libsanitizer/sanitizer_common/sancov_flags.cc +++ b/libsanitizer/sanitizer_common/sancov_flags.cpp @@ -1,7 +1,8 @@ -//===-- sancov_flags.cc -----------------------------------------*- C++ -*-===// +//===-- sancov_flags.cpp ----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -48,7 +49,7 @@ void InitializeSancovFlags() { RegisterSancovFlags(&parser, f); parser.ParseString(MaybeCallSancovDefaultOptions()); - parser.ParseString(GetEnv("SANCOV_OPTIONS")); + parser.ParseStringFromEnv("SANCOV_OPTIONS"); ReportUnrecognizedFlags(); if (f->help) parser.PrintFlagDescriptions(); diff --git a/libsanitizer/sanitizer_common/sancov_flags.h b/libsanitizer/sanitizer_common/sancov_flags.h index f7e0186c511..95d4ee5ca43 100644 --- a/libsanitizer/sanitizer_common/sancov_flags.h +++ b/libsanitizer/sanitizer_common/sancov_flags.h @@ -1,7 +1,8 @@ //===-- sancov_flags.h ------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sancov_flags.inc b/libsanitizer/sanitizer_common/sancov_flags.inc index a6107cc8583..cca33fc359f 100644 --- a/libsanitizer/sanitizer_common/sancov_flags.inc +++ b/libsanitizer/sanitizer_common/sancov_flags.inc @@ -1,7 +1,8 @@ //===-- sancov_flags.inc ----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_addrhashmap.h b/libsanitizer/sanitizer_common/sanitizer_addrhashmap.h index a67ec84373e..a033e788cbf 100644 --- a/libsanitizer/sanitizer_common/sanitizer_addrhashmap.h +++ b/libsanitizer/sanitizer_common/sanitizer_addrhashmap.h @@ -1,7 +1,8 @@ //===-- sanitizer_addrhashmap.h ---------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator.cc b/libsanitizer/sanitizer_common/sanitizer_allocator.cpp similarity index 92% rename from libsanitizer/sanitizer_common/sanitizer_allocator.cc rename to libsanitizer/sanitizer_common/sanitizer_allocator.cpp index 2fd6e8a4248..8d07906cca0 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator.cc +++ b/libsanitizer/sanitizer_common/sanitizer_allocator.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_allocator.cc --------------------------------------------===// +//===-- sanitizer_allocator.cpp -------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -169,6 +170,18 @@ void *InternalRealloc(void *addr, uptr size, InternalAllocatorCache *cache) { return (char*)p + sizeof(u64); } +void *InternalReallocArray(void *addr, uptr count, uptr size, + InternalAllocatorCache *cache) { + if (UNLIKELY(CheckForCallocOverflow(count, size))) { + Report( + "FATAL: %s: reallocarray parameters overflow: count * size (%zd * %zd) " + "cannot be represented in type size_t\n", + SanitizerToolName, count, size); + Die(); + } + return InternalRealloc(addr, count * size, cache); +} + void *InternalCalloc(uptr count, uptr size, InternalAllocatorCache *cache) { if (UNLIKELY(CheckForCallocOverflow(count, size))) { Report("FATAL: %s: calloc parameters overflow: count * size (%zd * %zd) " diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator.h b/libsanitizer/sanitizer_common/sanitizer_allocator.h index 7dbb9f72017..23d589888d3 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator.h @@ -1,7 +1,8 @@ //===-- sanitizer_allocator.h -----------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -12,13 +13,15 @@ #ifndef SANITIZER_ALLOCATOR_H #define SANITIZER_ALLOCATOR_H -#include "sanitizer_internal_defs.h" #include "sanitizer_common.h" +#include "sanitizer_internal_defs.h" +#include "sanitizer_lfstack.h" #include "sanitizer_libc.h" #include "sanitizer_list.h" +#include "sanitizer_local_address_space_view.h" #include "sanitizer_mutex.h" -#include "sanitizer_lfstack.h" #include "sanitizer_procmaps.h" +#include "sanitizer_type_traits.h" namespace __sanitizer { diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_bytemap.h b/libsanitizer/sanitizer_common/sanitizer_allocator_bytemap.h index 3a3f22266f7..0084bb62c83 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_bytemap.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_bytemap.h @@ -1,7 +1,8 @@ //===-- sanitizer_allocator_bytemap.h ---------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -13,9 +14,10 @@ #endif // Maps integers in rage [0, kSize) to u8 values. -template +template class FlatByteMap { public: + using AddressSpaceView = AddressSpaceViewTy; void Init() { internal_memset(map_, 0, sizeof(map_)); } @@ -39,9 +41,12 @@ class FlatByteMap { // to kSize2-byte arrays. The secondary arrays are mmaped on demand. // Each value is initially zero and can be set to something else only once. // Setting and getting values from multiple threads is safe w/o extra locking. -template +template class TwoLevelByteMap { public: + using AddressSpaceView = AddressSpaceViewTy; void Init() { internal_memset(map1_, 0, sizeof(map1_)); mu_.Init(); @@ -71,7 +76,8 @@ class TwoLevelByteMap { CHECK_LT(idx, kSize1 * kSize2); u8 *map2 = Get(idx / kSize2); if (!map2) return 0; - return map2[idx % kSize2]; + auto value_ptr = AddressSpaceView::Load(&map2[idx % kSize2]); + return *value_ptr; } private: @@ -98,3 +104,4 @@ class TwoLevelByteMap { atomic_uintptr_t map1_[kSize1]; StaticSpinMutex mu_; }; + diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_checks.cc b/libsanitizer/sanitizer_common/sanitizer_allocator_checks.cpp similarity index 61% rename from libsanitizer/sanitizer_common/sanitizer_allocator_checks.cc rename to libsanitizer/sanitizer_common/sanitizer_allocator_checks.cpp index 3e6eb61a7d5..9d67f679b56 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_checks.cc +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_checks.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_allocator_checks.cc ---------------------------*- C++ -*-===// +//===-- sanitizer_allocator_checks.cpp --------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_checks.h b/libsanitizer/sanitizer_common/sanitizer_allocator_checks.h index 9056ed57987..f436ce9ecde 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_checks.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_checks.h @@ -1,7 +1,8 @@ //===-- sanitizer_allocator_checks.h ----------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_combined.h b/libsanitizer/sanitizer_common/sanitizer_allocator_combined.h index ec6c0da8538..33f89d6d499 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_combined.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_combined.h @@ -1,7 +1,8 @@ //===-- sanitizer_allocator_combined.h --------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -18,20 +19,26 @@ // When allocating 2^x bytes it should return 2^x aligned chunk. // PrimaryAllocator is used via a local AllocatorCache. // SecondaryAllocator can allocate anything, but is not efficient. -template // NOLINT +template class CombinedAllocator { public: + using AllocatorCache = typename PrimaryAllocator::AllocatorCache; + using SecondaryAllocator = + LargeMmapAllocator; + void InitLinkerInitialized(s32 release_to_os_interval_ms) { + stats_.InitLinkerInitialized(); primary_.Init(release_to_os_interval_ms); secondary_.InitLinkerInitialized(); - stats_.InitLinkerInitialized(); } void Init(s32 release_to_os_interval_ms) { + stats_.Init(); primary_.Init(release_to_os_interval_ms); secondary_.Init(); - stats_.Init(); } void *Allocate(AllocatorCache *cache, uptr size, uptr alignment) { diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_interface.h b/libsanitizer/sanitizer_common/sanitizer_allocator_interface.h index 35213c74c00..c1b27563e2f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_interface.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_interface.h @@ -1,7 +1,8 @@ //===-- sanitizer_allocator_interface.h ------------------------- C++ -----===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_internal.h b/libsanitizer/sanitizer_common/sanitizer_allocator_internal.h index 05aed0ecfe0..32849036fd0 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_internal.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_internal.h @@ -1,7 +1,8 @@ //===-- sanitizer_allocator_internal.h --------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -21,41 +22,30 @@ namespace __sanitizer { // purposes. typedef CompactSizeClassMap InternalSizeClassMap; -static const uptr kInternalAllocatorRegionSizeLog = 20; -static const uptr kInternalAllocatorNumRegions = - SANITIZER_MMAP_RANGE_SIZE >> kInternalAllocatorRegionSizeLog; -#if SANITIZER_WORDSIZE == 32 -typedef FlatByteMap ByteMap; -#else -typedef TwoLevelByteMap<(kInternalAllocatorNumRegions >> 12), 1 << 12> ByteMap; -#endif struct AP32 { static const uptr kSpaceBeg = 0; static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; static const uptr kMetadataSize = 0; typedef InternalSizeClassMap SizeClassMap; - static const uptr kRegionSizeLog = kInternalAllocatorRegionSizeLog; - typedef __sanitizer::ByteMap ByteMap; + static const uptr kRegionSizeLog = 20; + using AddressSpaceView = LocalAddressSpaceView; typedef NoOpMapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; typedef SizeClassAllocator32 PrimaryInternalAllocator; -typedef SizeClassAllocatorLocalCache - InternalAllocatorCache; - -typedef LargeMmapAllocator - SecondaryInternalAllocator; - -typedef CombinedAllocator InternalAllocator; +typedef CombinedAllocator + InternalAllocator; +typedef InternalAllocator::AllocatorCache InternalAllocatorCache; void *InternalAlloc(uptr size, InternalAllocatorCache *cache = nullptr, uptr alignment = 0); void *InternalRealloc(void *p, uptr size, InternalAllocatorCache *cache = nullptr); -void *InternalCalloc(uptr countr, uptr size, +void *InternalReallocArray(void *p, uptr count, uptr size, + InternalAllocatorCache *cache = nullptr); +void *InternalCalloc(uptr count, uptr size, InternalAllocatorCache *cache = nullptr); void InternalFree(void *p, InternalAllocatorCache *cache = nullptr); InternalAllocator *internal_allocator(); diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_local_cache.h b/libsanitizer/sanitizer_common/sanitizer_allocator_local_cache.h index d23c59aa05c..108dfc231a2 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_local_cache.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_local_cache.h @@ -1,7 +1,8 @@ //===-- sanitizer_allocator_local_cache.h -----------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -12,13 +13,6 @@ #error This file must be included inside sanitizer_allocator.h #endif -// Objects of this type should be used as local caches for SizeClassAllocator64 -// or SizeClassAllocator32. Since the typical use of this class is to have one -// object per thread in TLS, is has to be POD. -template -struct SizeClassAllocatorLocalCache - : SizeClassAllocator::AllocatorCache {}; - // Cache used by SizeClassAllocator64. template struct SizeClassAllocator64LocalCache { diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_primary32.h b/libsanitizer/sanitizer_common/sanitizer_allocator_primary32.h index de16cf29151..3b1838b3985 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_primary32.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_primary32.h @@ -1,7 +1,8 @@ //===-- sanitizer_allocator_primary32.h -------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -45,14 +46,24 @@ struct SizeClassAllocator32FlagMasks { // Bit masks. template class SizeClassAllocator32 { + private: + static const u64 kTwoLevelByteMapSize1 = + (Params::kSpaceSize >> Params::kRegionSizeLog) >> 12; + static const u64 kMinFirstMapSizeTwoLevelByteMap = 4; + public: + using AddressSpaceView = typename Params::AddressSpaceView; static const uptr kSpaceBeg = Params::kSpaceBeg; static const u64 kSpaceSize = Params::kSpaceSize; static const uptr kMetadataSize = Params::kMetadataSize; typedef typename Params::SizeClassMap SizeClassMap; static const uptr kRegionSizeLog = Params::kRegionSizeLog; - typedef typename Params::ByteMap ByteMap; typedef typename Params::MapUnmapCallback MapUnmapCallback; + using ByteMap = typename conditional< + (kTwoLevelByteMapSize1 < kMinFirstMapSizeTwoLevelByteMap), + FlatByteMap<(Params::kSpaceSize >> Params::kRegionSizeLog), + AddressSpaceView>, + TwoLevelByteMap>::type; COMPILER_CHECK(!SANITIZER_SIGN_EXTENDED_ADDRESSES || (kSpaceSize & (kSpaceSize - 1)) == 0); @@ -205,7 +216,7 @@ class SizeClassAllocator32 { return ClassIdToSize(GetSizeClass(p)); } - uptr ClassID(uptr size) { return SizeClassMap::ClassID(size); } + static uptr ClassID(uptr size) { return SizeClassMap::ClassID(size); } uptr TotalMemoryUsed() { // No need to lock here. @@ -271,7 +282,7 @@ class SizeClassAllocator32 { }; COMPILER_CHECK(sizeof(SizeClassInfo) % kCacheLineSize == 0); - uptr ComputeRegionId(uptr mem) { + uptr ComputeRegionId(uptr mem) const { if (SANITIZER_SIGN_EXTENDED_ADDRESSES) mem &= (kSpaceSize - 1); const uptr res = mem >> kRegionSizeLog; diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h b/libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h index 119443b3ebe..90603280e7c 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h @@ -1,7 +1,8 @@ //===-- sanitizer_allocator_primary64.h -------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -44,6 +45,7 @@ struct SizeClassAllocator64FlagMasks { // Bit masks. template class SizeClassAllocator64 { public: + using AddressSpaceView = typename Params::AddressSpaceView; static const uptr kSpaceBeg = Params::kSpaceBeg; static const uptr kSpaceSize = Params::kSpaceSize; static const uptr kMetadataSize = Params::kMetadataSize; @@ -78,7 +80,8 @@ class SizeClassAllocator64 { CHECK_NE(NonConstSpaceBeg, ~(uptr)0); } SetReleaseToOSIntervalMs(release_to_os_interval_ms); - MapWithCallbackOrDie(SpaceEnd(), AdditionalSize()); + MapWithCallbackOrDie(SpaceEnd(), AdditionalSize(), + "SizeClassAllocator: region info"); // Check that the RegionInfo array is aligned on the CacheLine size. DCHECK_EQ(SpaceEnd() % kCacheLineSize, 0); } @@ -151,7 +154,7 @@ class SizeClassAllocator64 { return true; } - bool PointerIsMine(const void *p) { + bool PointerIsMine(const void *p) const { uptr P = reinterpret_cast(p); if (kUsingConstantSpaceBeg && (kSpaceBeg % kSpaceSize) == 0) return P / kSpaceSize == kSpaceBeg / kSpaceSize; @@ -186,7 +189,7 @@ class SizeClassAllocator64 { uptr beg = chunk_idx * size; uptr next_beg = beg + size; if (class_id >= kNumClasses) return nullptr; - RegionInfo *region = GetRegionInfo(class_id); + const RegionInfo *region = AddressSpaceView::Load(GetRegionInfo(class_id)); if (region->mapped_user >= next_beg) return reinterpret_cast(reg_beg + beg); return nullptr; @@ -197,7 +200,7 @@ class SizeClassAllocator64 { return ClassIdToSize(GetSizeClass(p)); } - uptr ClassID(uptr size) { return SizeClassMap::ClassID(size); } + static uptr ClassID(uptr size) { return SizeClassMap::ClassID(size); } void *GetMetaData(const void *p) { uptr class_id = GetSizeClass(p); @@ -292,8 +295,10 @@ class SizeClassAllocator64 { RegionInfo *region = GetRegionInfo(class_id); uptr chunk_size = ClassIdToSize(class_id); uptr region_beg = SpaceBeg() + class_id * kRegionSize; + uptr region_allocated_user_size = + AddressSpaceView::Load(region)->allocated_user; for (uptr chunk = region_beg; - chunk < region_beg + region->allocated_user; + chunk < region_beg + region_allocated_user_size; chunk += chunk_size) { // Too slow: CHECK_EQ((void *)chunk, GetBlockBegin((void *)chunk)); callback(chunk, arg); @@ -629,8 +634,8 @@ class SizeClassAllocator64 { return reinterpret_cast(GetMetadataEnd(region_beg)); } - bool MapWithCallback(uptr beg, uptr size) { - uptr mapped = address_range.Map(beg, size); + bool MapWithCallback(uptr beg, uptr size, const char *name) { + uptr mapped = address_range.Map(beg, size, name); if (UNLIKELY(!mapped)) return false; CHECK_EQ(beg, mapped); @@ -638,8 +643,8 @@ class SizeClassAllocator64 { return true; } - void MapWithCallbackOrDie(uptr beg, uptr size) { - CHECK_EQ(beg, address_range.MapOrDie(beg, size)); + void MapWithCallbackOrDie(uptr beg, uptr size, const char *name) { + CHECK_EQ(beg, address_range.MapOrDie(beg, size, name)); MapUnmapCallback().OnMap(beg, size); } @@ -657,7 +662,8 @@ class SizeClassAllocator64 { uptr current_map_end = reinterpret_cast(GetFreeArray(region_beg)) + region->mapped_free_array; uptr new_map_size = new_mapped_free_array - region->mapped_free_array; - if (UNLIKELY(!MapWithCallback(current_map_end, new_map_size))) + if (UNLIKELY(!MapWithCallback(current_map_end, new_map_size, + "SizeClassAllocator: freearray"))) return false; region->mapped_free_array = new_mapped_free_array; } @@ -708,7 +714,8 @@ class SizeClassAllocator64 { if (UNLIKELY(IsRegionExhausted(region, class_id, user_map_size))) return false; if (UNLIKELY(!MapWithCallback(region_beg + region->mapped_user, - user_map_size))) + user_map_size, + "SizeClassAllocator: region data"))) return false; stat->Add(AllocatorStatMapped, user_map_size); region->mapped_user += user_map_size; @@ -728,7 +735,7 @@ class SizeClassAllocator64 { return false; if (UNLIKELY(!MapWithCallback( GetMetadataEnd(region_beg) - region->mapped_meta - meta_map_size, - meta_map_size))) + meta_map_size, "SizeClassAllocator: region metadata"))) return false; region->mapped_meta += meta_map_size; } diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_report.cc b/libsanitizer/sanitizer_common/sanitizer_allocator_report.cpp similarity index 85% rename from libsanitizer/sanitizer_common/sanitizer_allocator_report.cc rename to libsanitizer/sanitizer_common/sanitizer_allocator_report.cpp index a09fb91e6b1..dbcf2b7bf26 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_report.cc +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_report.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_allocator_report.cc ---------------------------*- C++ -*-===// +//===-- sanitizer_allocator_report.cpp --------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// @@ -50,6 +51,18 @@ void NORETURN ReportCallocOverflow(uptr count, uptr size, Die(); } +void NORETURN ReportReallocArrayOverflow(uptr count, uptr size, + const StackTrace *stack) { + { + ScopedAllocatorErrorReport report("reallocarray-overflow", stack); + Report( + "ERROR: %s: reallocarray parameters overflow: count * size (%zd * %zd) " + "cannot be represented in type size_t\n", + SanitizerToolName, count, size); + } + Die(); +} + void NORETURN ReportPvallocOverflow(uptr size, const StackTrace *stack) { { ScopedAllocatorErrorReport report("pvalloc-overflow", stack); diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_report.h b/libsanitizer/sanitizer_common/sanitizer_allocator_report.h index 892f7ffb7f8..0653c365c1c 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_report.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_report.h @@ -1,7 +1,8 @@ //===-- sanitizer_allocator_report.h ----------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// @@ -20,6 +21,8 @@ namespace __sanitizer { void NORETURN ReportCallocOverflow(uptr count, uptr size, const StackTrace *stack); +void NORETURN ReportReallocArrayOverflow(uptr count, uptr size, + const StackTrace *stack); void NORETURN ReportPvallocOverflow(uptr size, const StackTrace *stack); void NORETURN ReportInvalidAllocationAlignment(uptr alignment, const StackTrace *stack); diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_secondary.h b/libsanitizer/sanitizer_common/sanitizer_allocator_secondary.h index 1dbca60b823..1d128f55de0 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_secondary.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_secondary.h @@ -1,7 +1,8 @@ //===-- sanitizer_allocator_secondary.h -------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -66,9 +67,11 @@ typedef LargeMmapAllocatorPtrArrayDynamic DefaultLargeMmapAllocatorPtrArray; // The main purpose of this allocator is to cover large and rare allocation // sizes not covered by more efficient allocators (e.g. SizeClassAllocator64). template + class PtrArrayT = DefaultLargeMmapAllocatorPtrArray, + class AddressSpaceViewTy = LocalAddressSpaceView> class LargeMmapAllocator { public: + using AddressSpaceView = AddressSpaceViewTy; void InitLinkerInitialized() { page_size_ = GetPageSizeCached(); chunks_ = reinterpret_cast(ptr_array_.Init()); @@ -180,29 +183,33 @@ class LargeMmapAllocator { uptr p = reinterpret_cast(ptr); SpinMutexLock l(&mutex_); uptr nearest_chunk = 0; + Header *const *chunks = AddressSpaceView::Load(chunks_, n_chunks_); // Cache-friendly linear search. for (uptr i = 0; i < n_chunks_; i++) { - uptr ch = reinterpret_cast(chunks_[i]); + uptr ch = reinterpret_cast(chunks[i]); if (p < ch) continue; // p is at left to this chunk, skip it. if (p - ch < p - nearest_chunk) nearest_chunk = ch; } if (!nearest_chunk) return nullptr; - Header *h = reinterpret_cast
(nearest_chunk); + const Header *h = + AddressSpaceView::Load(reinterpret_cast
(nearest_chunk)); + Header *h_ptr = reinterpret_cast
(nearest_chunk); CHECK_GE(nearest_chunk, h->map_beg); CHECK_LT(nearest_chunk, h->map_beg + h->map_size); CHECK_LE(nearest_chunk, p); if (h->map_beg + h->map_size <= p) return nullptr; - return GetUser(h); + return GetUser(h_ptr); } void EnsureSortedChunks() { if (chunks_sorted_) return; - Sort(reinterpret_cast(chunks_), n_chunks_); + Header **chunks = AddressSpaceView::LoadWritable(chunks_, n_chunks_); + Sort(reinterpret_cast(chunks), n_chunks_); for (uptr i = 0; i < n_chunks_; i++) - chunks_[i]->chunk_idx = i; + AddressSpaceView::LoadWritable(chunks[i])->chunk_idx = i; chunks_sorted_ = true; } @@ -214,9 +221,10 @@ class LargeMmapAllocator { uptr n = n_chunks_; if (!n) return nullptr; EnsureSortedChunks(); - auto min_mmap_ = reinterpret_cast(chunks_[0]); - auto max_mmap_ = - reinterpret_cast(chunks_[n - 1]) + chunks_[n - 1]->map_size; + Header *const *chunks = AddressSpaceView::Load(chunks_, n_chunks_); + auto min_mmap_ = reinterpret_cast(chunks[0]); + auto max_mmap_ = reinterpret_cast(chunks[n - 1]) + + AddressSpaceView::Load(chunks[n - 1])->map_size; if (p < min_mmap_ || p >= max_mmap_) return nullptr; uptr beg = 0, end = n - 1; @@ -224,23 +232,24 @@ class LargeMmapAllocator { // to avoid expensive cache-thrashing loads. while (end - beg >= 2) { uptr mid = (beg + end) / 2; // Invariant: mid >= beg + 1 - if (p < reinterpret_cast(chunks_[mid])) - end = mid - 1; // We are not interested in chunks_[mid]. + if (p < reinterpret_cast(chunks[mid])) + end = mid - 1; // We are not interested in chunks[mid]. else - beg = mid; // chunks_[mid] may still be what we want. + beg = mid; // chunks[mid] may still be what we want. } if (beg < end) { CHECK_EQ(beg + 1, end); // There are 2 chunks left, choose one. - if (p >= reinterpret_cast(chunks_[end])) + if (p >= reinterpret_cast(chunks[end])) beg = end; } - Header *h = chunks_[beg]; + const Header *h = AddressSpaceView::Load(chunks[beg]); + Header *h_ptr = chunks[beg]; if (h->map_beg + h->map_size <= p || p < h->map_beg) return nullptr; - return GetUser(h); + return GetUser(h_ptr); } void PrintStats() { @@ -270,12 +279,13 @@ class LargeMmapAllocator { // The allocator must be locked when calling this function. void ForEachChunk(ForEachChunkCallback callback, void *arg) { EnsureSortedChunks(); // Avoid doing the sort while iterating. + const Header *const *chunks = AddressSpaceView::Load(chunks_, n_chunks_); for (uptr i = 0; i < n_chunks_; i++) { - auto t = chunks_[i]; + const Header *t = chunks[i]; callback(reinterpret_cast(GetUser(t)), arg); // Consistency check: verify that the array did not change. - CHECK_EQ(chunks_[i], t); - CHECK_EQ(chunks_[i]->chunk_idx, i); + CHECK_EQ(chunks[i], t); + CHECK_EQ(AddressSpaceView::Load(chunks[i])->chunk_idx, i); } } @@ -295,7 +305,7 @@ class LargeMmapAllocator { return GetHeader(reinterpret_cast(p)); } - void *GetUser(Header *h) { + void *GetUser(const Header *h) { CHECK(IsAligned((uptr)h, page_size_)); return reinterpret_cast(reinterpret_cast(h) + page_size_); } diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_size_class_map.h b/libsanitizer/sanitizer_common/sanitizer_allocator_size_class_map.h index cfe6299fdec..12d8c892307 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_size_class_map.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_size_class_map.h @@ -1,7 +1,8 @@ //===-- sanitizer_allocator_size_class_map.h --------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -235,3 +236,6 @@ typedef SizeClassMap<2, 5, 9, 16, 64, 14> VeryCompactSizeClassMap; // allowing for denser per-class arrays, smaller memory footprint and usually // better performances in threaded environments. typedef SizeClassMap<3, 4, 8, 17, 8, 10> DenseSizeClassMap; +// Similar to VeryCompact map above, this one has a small number of different +// size classes, and also reduced thread-local caches. +typedef SizeClassMap<2, 5, 9, 16, 8, 10> VeryDenseSizeClassMap; diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_stats.h b/libsanitizer/sanitizer_common/sanitizer_allocator_stats.h index 93360919fee..6f14e3863c3 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_stats.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_stats.h @@ -1,7 +1,8 @@ //===-- sanitizer_allocator_stats.h -----------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -101,3 +102,5 @@ class AllocatorGlobalStats : public AllocatorStats { private: mutable StaticSpinMutex mu_; }; + + diff --git a/libsanitizer/sanitizer_common/sanitizer_asm.h b/libsanitizer/sanitizer_common/sanitizer_asm.h index 4c75b413268..184d118d97d 100644 --- a/libsanitizer/sanitizer_common/sanitizer_asm.h +++ b/libsanitizer/sanitizer_common/sanitizer_asm.h @@ -1,7 +1,8 @@ //===-- sanitizer_asm.h -----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -43,14 +44,23 @@ #if !defined(__APPLE__) # define ASM_HIDDEN(symbol) .hidden symbol -# define ASM_TYPE_FUNCTION(symbol) .type symbol, @function +# define ASM_TYPE_FUNCTION(symbol) .type symbol, %function # define ASM_SIZE(symbol) .size symbol, .-symbol # define ASM_SYMBOL(symbol) symbol # define ASM_SYMBOL_INTERCEPTOR(symbol) symbol +# define ASM_WRAPPER_NAME(symbol) __interceptor_##symbol #else # define ASM_HIDDEN(symbol) # define ASM_TYPE_FUNCTION(symbol) # define ASM_SIZE(symbol) # define ASM_SYMBOL(symbol) _##symbol # define ASM_SYMBOL_INTERCEPTOR(symbol) _wrap_##symbol +# define ASM_WRAPPER_NAME(symbol) __interceptor_##symbol +#endif + +#if defined(__ELF__) && (defined(__GNU__) || defined(__FreeBSD__) || \ + defined(__Fuchsia__) || defined(__linux__)) +#define NO_EXEC_STACK_DIRECTIVE .section .note.GNU-stack,"",%progbits // NOLINT +#else +#define NO_EXEC_STACK_DIRECTIVE #endif diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic.h b/libsanitizer/sanitizer_common/sanitizer_atomic.h index 82de0c6d446..a798a0cf25d 100644 --- a/libsanitizer/sanitizer_common/sanitizer_atomic.h +++ b/libsanitizer/sanitizer_common/sanitizer_atomic.h @@ -1,7 +1,8 @@ //===-- sanitizer_atomic.h --------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic_clang.h b/libsanitizer/sanitizer_common/sanitizer_atomic_clang.h index 89fb748e758..c40461ebc3b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_atomic_clang.h +++ b/libsanitizer/sanitizer_common/sanitizer_atomic_clang.h @@ -1,7 +1,8 @@ //===-- sanitizer_atomic_clang.h --------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_mips.h b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_mips.h index 41e58dcae4d..d369aeb9935 100644 --- a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_mips.h +++ b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_mips.h @@ -1,7 +1,8 @@ //===-- sanitizer_atomic_clang_mips.h ---------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -113,3 +114,4 @@ INLINE void atomic_store(volatile atomic_uint64_t *ptr, atomic_uint64_t::Type v, } // namespace __sanitizer #endif // SANITIZER_ATOMIC_CLANG_MIPS_H + diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_other.h b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_other.h index b11efccc91b..b8685a85426 100644 --- a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_other.h +++ b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_other.h @@ -1,7 +1,8 @@ //===-- sanitizer_atomic_clang_other.h --------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_x86.h b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_x86.h index aab9935676f..f2ce553baa7 100644 --- a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_x86.h +++ b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_x86.h @@ -1,7 +1,8 @@ //===-- sanitizer_atomic_clang_x86.h ----------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic_msvc.h b/libsanitizer/sanitizer_common/sanitizer_atomic_msvc.h index 4ae87142d46..a249657d661 100644 --- a/libsanitizer/sanitizer_common/sanitizer_atomic_msvc.h +++ b/libsanitizer/sanitizer_common/sanitizer_atomic_msvc.h @@ -1,7 +1,8 @@ //===-- sanitizer_atomic_msvc.h ---------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_bitvector.h b/libsanitizer/sanitizer_common/sanitizer_bitvector.h index 6ecac818845..07a59ab11c4 100644 --- a/libsanitizer/sanitizer_common/sanitizer_bitvector.h +++ b/libsanitizer/sanitizer_common/sanitizer_bitvector.h @@ -1,7 +1,8 @@ //===-- sanitizer_bitvector.h -----------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_bvgraph.h b/libsanitizer/sanitizer_common/sanitizer_bvgraph.h index a7f76bf585f..e7249055bee 100644 --- a/libsanitizer/sanitizer_common/sanitizer_bvgraph.h +++ b/libsanitizer/sanitizer_common/sanitizer_bvgraph.h @@ -1,7 +1,8 @@ //===-- sanitizer_bvgraph.h -------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_common.cc b/libsanitizer/sanitizer_common/sanitizer_common.cpp similarity index 97% rename from libsanitizer/sanitizer_common/sanitizer_common.cc rename to libsanitizer/sanitizer_common/sanitizer_common.cpp index 7f0f47c005d..451c9e526e0 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common.cc +++ b/libsanitizer/sanitizer_common/sanitizer_common.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_common.cc -----------------------------------------------===// +//===-- sanitizer_common.cpp ----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_common.h b/libsanitizer/sanitizer_common/sanitizer_common.h index 603d922b969..4f0f16d3532 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common.h +++ b/libsanitizer/sanitizer_common/sanitizer_common.h @@ -1,7 +1,8 @@ //===-- sanitizer_common.h --------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -59,6 +60,15 @@ INLINE int Verbosity() { return atomic_load(¤t_verbosity, memory_order_relaxed); } +#if SANITIZER_ANDROID +INLINE uptr GetPageSize() { +// Android post-M sysconf(_SC_PAGESIZE) crashes if called from .preinit_array. + return 4096; +} +INLINE uptr GetPageSizeCached() { + return 4096; +} +#else uptr GetPageSize(); extern uptr PageSizeCached; INLINE uptr GetPageSizeCached() { @@ -66,6 +76,7 @@ INLINE uptr GetPageSizeCached() { PageSizeCached = GetPageSize(); return PageSizeCached; } +#endif uptr GetMmapGranularity(); uptr GetMaxVirtualAddress(); uptr GetMaxUserVirtualAddress(); @@ -90,10 +101,11 @@ void *MmapOrDieOnFatalError(uptr size, const char *mem_type); bool MmapFixedNoReserve(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); +void *MmapFixedOrDie(uptr fixed_addr, uptr size, const char *name = nullptr); // Behaves just like MmapFixedOrDie, but tolerates out of memory condition, in // that case returns nullptr. -void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size); +void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size, + const char *name = nullptr); void *MmapFixedNoAccess(uptr fixed_addr, uptr size, const char *name = nullptr); void *MmapNoAccess(uptr size); // Map aligned chunk of address space; size and alignment are powers of two. @@ -119,7 +131,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(); @@ -129,8 +141,8 @@ void RunFreeHooks(const void *ptr); class ReservedAddressRange { public: uptr Init(uptr size, const char *name = nullptr, uptr fixed_addr = 0); - uptr Map(uptr fixed_addr, uptr size); - uptr MapOrDie(uptr fixed_addr, uptr size); + uptr Map(uptr fixed_addr, uptr size, const char *name = nullptr); + uptr MapOrDie(uptr fixed_addr, uptr size, const char *name = nullptr); void Unmap(uptr addr, uptr size); void *base() const { return base_; } uptr size() const { return size_; } @@ -221,10 +233,11 @@ bool SetEnv(const char *name, const char *value); u32 GetUid(); void ReExec(); void CheckASLR(); +void CheckMPROTECT(); char **GetArgv(); +char **GetEnviron(); void PrintCmdline(); bool StackSizeIsUnlimited(); -uptr GetStackSizeLimitInBytes(); void SetStackSizeLimitInBytes(uptr limit); bool AddressSpaceIsUnlimited(); void SetAddressSpaceUnlimited(); @@ -656,7 +669,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: @@ -790,7 +803,13 @@ enum AndroidApiLevel { void WriteToSyslog(const char *buffer); -#if SANITIZER_MAC +#if defined(SANITIZER_WINDOWS) && defined(_MSC_VER) && !defined(__clang__) +#define SANITIZER_WIN_TRACE 1 +#else +#define SANITIZER_WIN_TRACE 0 +#endif + +#if SANITIZER_MAC || SANITIZER_WIN_TRACE void LogFullErrorReport(const char *buffer); #else INLINE void LogFullErrorReport(const char *buffer) {} @@ -804,7 +823,7 @@ INLINE void WriteOneLineToSyslog(const char *s) {} INLINE void LogMessageOnPrintf(const char *str) {} #endif -#if SANITIZER_LINUX +#if SANITIZER_LINUX || SANITIZER_WIN_TRACE // Initialize Android logging. Any writes before this are silently lost. void AndroidLogInit(); void SetAbortMessage(const char *); @@ -895,6 +914,7 @@ struct SignalContext { bool IsMemoryAccess() const; }; +void InitializePlatformEarly(); void MaybeReexec(); template diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc index c810e65f0ad..9975f5321a5 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc @@ -1,7 +1,8 @@ //===-- sanitizer_common_interceptors.inc -----------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -75,7 +76,15 @@ #define ctime __ctime50 #define ctime_r __ctime_r50 #define devname __devname50 +#define fgetpos __fgetpos50 +#define fsetpos __fsetpos50 +#define fts_children __fts_children60 +#define fts_close __fts_close60 +#define fts_open __fts_open60 +#define fts_read __fts_read60 +#define fts_set __fts_set60 #define getitimer __getitimer50 +#define getmntinfo __getmntinfo13 #define getpwent __getpwent50 #define getpwnam __getpwnam50 #define getpwnam_r __getpwnam_r50 @@ -85,6 +94,7 @@ #define getutxent __getutxent50 #define getutxid __getutxid50 #define getutxline __getutxline50 +#define pututxline __pututxline50 #define glob __glob30 #define gmtime __gmtime50 #define gmtime_r __gmtime_r50 @@ -107,6 +117,7 @@ #define stat __stat50 #define time __time50 #define times __times13 +#define unvis __unvis50 #define wait3 __wait350 #define wait4 __wait450 extern const unsigned short *_ctype_tab_; @@ -306,11 +317,11 @@ struct CommonInterceptorMetadata { }; }; +#if SI_POSIX typedef AddrHashMap 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); @@ -808,16 +819,14 @@ INTERCEPTOR(void *, memcpy, void *dst, const void *src, uptr size) { #endif #if SANITIZER_INTERCEPT_MEMCMP - DECLARE_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, uptr called_pc, const void *s1, const void *s2, uptr n, int result) -INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) { - if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) - return internal_memcmp(a1, a2, size); - void *ctx; - COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size); +// Common code for `memcmp` and `bcmp`. +int MemcmpInterceptorCommon(void *ctx, + int (*real_fn)(const void *, const void *, uptr), + const void *a1, const void *a2, uptr size) { if (common_flags()->intercept_memcmp) { if (common_flags()->strict_memcmp) { // Check the entire regions even if the first bytes of the buffers are @@ -843,17 +852,39 @@ INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) { return r; } } - int result = REAL(memcmp(a1, a2, size)); + int result = real_fn(a1, a2, size); CALL_WEAK_INTERCEPTOR_HOOK(__sanitizer_weak_hook_memcmp, GET_CALLER_PC(), a1, a2, size, result); return result; } +INTERCEPTOR(int, memcmp, const void *a1, const void *a2, uptr size) { + if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) + return internal_memcmp(a1, a2, size); + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, memcmp, a1, a2, size); + return MemcmpInterceptorCommon(ctx, REAL(memcmp), a1, a2, size); +} + #define INIT_MEMCMP COMMON_INTERCEPT_FUNCTION(memcmp) #else #define INIT_MEMCMP #endif +#if SANITIZER_INTERCEPT_BCMP +INTERCEPTOR(int, bcmp, const void *a1, const void *a2, uptr size) { + if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) + return internal_memcmp(a1, a2, size); + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, bcmp, a1, a2, size); + return MemcmpInterceptorCommon(ctx, REAL(bcmp), a1, a2, size); +} + +#define INIT_BCMP COMMON_INTERCEPT_FUNCTION(bcmp) +#else +#define INIT_BCMP +#endif + #if SANITIZER_INTERCEPT_MEMCHR INTERCEPTOR(void*, memchr, const void *s, int c, SIZE_T n) { if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) @@ -1210,7 +1241,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); - COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); + 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) @@ -1223,7 +1256,9 @@ INTERCEPTOR(int, puts, char *s) { // libc file streams can call user-supplied functions, see fopencookie. void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, puts, s); - COMMON_INTERCEPTOR_READ_RANGE(ctx, s, REAL(strlen)(s) + 1); + 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) @@ -1806,58 +1841,53 @@ INTERCEPTOR(int, ioctl, int d, unsigned long request, ...) { #define INIT_IOCTL #endif -#if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || \ - SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT || \ - SANITIZER_INTERCEPT_GETPWENT_R || SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS -static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) { +#if SANITIZER_POSIX +UNUSED static void unpoison_passwd(void *ctx, __sanitizer_passwd *pwd) { if (pwd) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd, sizeof(*pwd)); if (pwd->pw_name) - COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_name, - REAL(strlen)(pwd->pw_name) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_name, + REAL(strlen)(pwd->pw_name) + 1); if (pwd->pw_passwd) - COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_passwd, - REAL(strlen)(pwd->pw_passwd) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_passwd, + REAL(strlen)(pwd->pw_passwd) + 1); #if !SANITIZER_ANDROID if (pwd->pw_gecos) - COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_gecos, - REAL(strlen)(pwd->pw_gecos) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_gecos, + REAL(strlen)(pwd->pw_gecos) + 1); #endif -#if SANITIZER_MAC +#if SANITIZER_MAC || SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD if (pwd->pw_class) - COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_class, - REAL(strlen)(pwd->pw_class) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_class, + REAL(strlen)(pwd->pw_class) + 1); #endif if (pwd->pw_dir) - COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_dir, - REAL(strlen)(pwd->pw_dir) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_dir, + REAL(strlen)(pwd->pw_dir) + 1); if (pwd->pw_shell) - COMMON_INTERCEPTOR_INITIALIZE_RANGE(pwd->pw_shell, - REAL(strlen)(pwd->pw_shell) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwd->pw_shell, + REAL(strlen)(pwd->pw_shell) + 1); } } -static void unpoison_group(void *ctx, __sanitizer_group *grp) { +UNUSED static void unpoison_group(void *ctx, __sanitizer_group *grp) { if (grp) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp, sizeof(*grp)); if (grp->gr_name) - COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_name, - REAL(strlen)(grp->gr_name) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_name, + REAL(strlen)(grp->gr_name) + 1); if (grp->gr_passwd) - COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_passwd, - REAL(strlen)(grp->gr_passwd) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_passwd, + REAL(strlen)(grp->gr_passwd) + 1); char **p = grp->gr_mem; for (; *p; ++p) { - COMMON_INTERCEPTOR_INITIALIZE_RANGE(*p, REAL(strlen)(*p) + 1); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *p, REAL(strlen)(*p) + 1); } - COMMON_INTERCEPTOR_INITIALIZE_RANGE(grp->gr_mem, - (p - grp->gr_mem + 1) * sizeof(*p)); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, grp->gr_mem, + (p - grp->gr_mem + 1) * sizeof(*p)); } } -#endif // SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS || - // SANITIZER_INTERCEPT_GETPWENT || SANITIZER_INTERCEPT_FGETPWENT || - // SANITIZER_INTERCEPT_GETPWENT_R || - // SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS +#endif // SANITIZER_POSIX #if SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) { @@ -1866,14 +1896,14 @@ INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) { if (name) COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); __sanitizer_passwd *res = REAL(getpwnam)(name); - if (res) unpoison_passwd(ctx, res); + unpoison_passwd(ctx, res); return res; } INTERCEPTOR(__sanitizer_passwd *, getpwuid, u32 uid) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getpwuid, uid); __sanitizer_passwd *res = REAL(getpwuid)(uid); - if (res) unpoison_passwd(ctx, res); + unpoison_passwd(ctx, res); return res; } INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) { @@ -1881,14 +1911,14 @@ INTERCEPTOR(__sanitizer_group *, getgrnam, const char *name) { COMMON_INTERCEPTOR_ENTER(ctx, getgrnam, name); COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); __sanitizer_group *res = REAL(getgrnam)(name); - if (res) unpoison_group(ctx, res); + unpoison_group(ctx, res); return res; } INTERCEPTOR(__sanitizer_group *, getgrgid, u32 gid) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getgrgid, gid); __sanitizer_group *res = REAL(getgrgid)(gid); - if (res) unpoison_group(ctx, res); + unpoison_group(ctx, res); return res; } #define INIT_GETPWNAM_AND_FRIENDS \ @@ -1910,10 +1940,8 @@ INTERCEPTOR(int, getpwnam_r, const char *name, __sanitizer_passwd *pwd, // its metadata. See // https://github.com/google/sanitizers/issues/321. int res = REAL(getpwnam_r)(name, pwd, buf, buflen, result); - if (!res) { - if (result && *result) unpoison_passwd(ctx, *result); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); - } + if (!res && result) + unpoison_passwd(ctx, *result); if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); return res; } @@ -1925,10 +1953,8 @@ INTERCEPTOR(int, getpwuid_r, u32 uid, __sanitizer_passwd *pwd, char *buf, // its metadata. See // https://github.com/google/sanitizers/issues/321. int res = REAL(getpwuid_r)(uid, pwd, buf, buflen, result); - if (!res) { - if (result && *result) unpoison_passwd(ctx, *result); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); - } + if (!res && result) + unpoison_passwd(ctx, *result); if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); return res; } @@ -1941,10 +1967,8 @@ INTERCEPTOR(int, getgrnam_r, const char *name, __sanitizer_group *grp, // its metadata. See // https://github.com/google/sanitizers/issues/321. int res = REAL(getgrnam_r)(name, grp, buf, buflen, result); - if (!res) { - if (result && *result) unpoison_group(ctx, *result); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); - } + if (!res && result) + unpoison_group(ctx, *result); if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); return res; } @@ -1956,10 +1980,8 @@ INTERCEPTOR(int, getgrgid_r, u32 gid, __sanitizer_group *grp, char *buf, // its metadata. See // https://github.com/google/sanitizers/issues/321. int res = REAL(getgrgid_r)(gid, grp, buf, buflen, result); - if (!res) { - if (result && *result) unpoison_group(ctx, *result); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); - } + if (!res && result) + unpoison_group(ctx, *result); if (result) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(*result)); return res; } @@ -1977,14 +1999,14 @@ INTERCEPTOR(__sanitizer_passwd *, getpwent, int dummy) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getpwent, dummy); __sanitizer_passwd *res = REAL(getpwent)(dummy); - if (res) unpoison_passwd(ctx, res); + unpoison_passwd(ctx, res); return res; } INTERCEPTOR(__sanitizer_group *, getgrent, int dummy) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getgrent, dummy); __sanitizer_group *res = REAL(getgrent)(dummy); - if (res) unpoison_group(ctx, res);; + unpoison_group(ctx, res); return res; } #define INIT_GETPWENT \ @@ -1999,14 +2021,14 @@ INTERCEPTOR(__sanitizer_passwd *, fgetpwent, void *fp) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent, fp); __sanitizer_passwd *res = REAL(fgetpwent)(fp); - if (res) unpoison_passwd(ctx, res); + unpoison_passwd(ctx, res); return res; } INTERCEPTOR(__sanitizer_group *, fgetgrent, void *fp) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, fgetgrent, fp); __sanitizer_group *res = REAL(fgetgrent)(fp); - if (res) unpoison_group(ctx, res); + unpoison_group(ctx, res); return res; } #define INIT_FGETPWENT \ @@ -2025,43 +2047,52 @@ INTERCEPTOR(int, getpwent_r, __sanitizer_passwd *pwbuf, char *buf, // its metadata. See // https://github.com/google/sanitizers/issues/321. int res = REAL(getpwent_r)(pwbuf, buf, buflen, pwbufp); - if (!res) { - if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); - } + if (!res && pwbufp) + unpoison_passwd(ctx, *pwbufp); if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); return res; } -INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf, - SIZE_T buflen, __sanitizer_passwd **pwbufp) { +INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen, + __sanitizer_group **pwbufp) { void *ctx; - COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp); + COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp); // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. - int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp); - if (!res) { - if (pwbufp && *pwbufp) unpoison_passwd(ctx, *pwbufp); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); - } + int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp); + if (!res && pwbufp) + unpoison_group(ctx, *pwbufp); if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); return res; } -INTERCEPTOR(int, getgrent_r, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen, - __sanitizer_group **pwbufp) { +#define INIT_GETPWENT_R \ + COMMON_INTERCEPT_FUNCTION(getpwent_r); \ + COMMON_INTERCEPT_FUNCTION(getgrent_r); +#else +#define INIT_GETPWENT_R +#endif + +#if SANITIZER_INTERCEPT_FGETPWENT_R +INTERCEPTOR(int, fgetpwent_r, void *fp, __sanitizer_passwd *pwbuf, char *buf, + SIZE_T buflen, __sanitizer_passwd **pwbufp) { void *ctx; - COMMON_INTERCEPTOR_ENTER(ctx, getgrent_r, pwbuf, buf, buflen, pwbufp); + COMMON_INTERCEPTOR_ENTER(ctx, fgetpwent_r, fp, pwbuf, buf, buflen, pwbufp); // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. - int res = REAL(getgrent_r)(pwbuf, buf, buflen, pwbufp); - if (!res) { - if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); - } + int res = REAL(fgetpwent_r)(fp, pwbuf, buf, buflen, pwbufp); + if (!res && pwbufp) + unpoison_passwd(ctx, *pwbufp); if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); return res; } +#define INIT_FGETPWENT_R \ + COMMON_INTERCEPT_FUNCTION(fgetpwent_r); +#else +#define INIT_FGETPWENT_R +#endif + +#if SANITIZER_INTERCEPT_FGETGRENT_R INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf, SIZE_T buflen, __sanitizer_group **pwbufp) { void *ctx; @@ -2070,20 +2101,15 @@ INTERCEPTOR(int, fgetgrent_r, void *fp, __sanitizer_group *pwbuf, char *buf, // its metadata. See // https://github.com/google/sanitizers/issues/321. int res = REAL(fgetgrent_r)(fp, pwbuf, buf, buflen, pwbufp); - if (!res) { - if (pwbufp && *pwbufp) unpoison_group(ctx, *pwbufp); - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, buflen); - } + if (!res && pwbufp) + unpoison_group(ctx, *pwbufp); if (pwbufp) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pwbufp, sizeof(*pwbufp)); return res; } -#define INIT_GETPWENT_R \ - COMMON_INTERCEPT_FUNCTION(getpwent_r); \ - COMMON_INTERCEPT_FUNCTION(fgetpwent_r); \ - COMMON_INTERCEPT_FUNCTION(getgrent_r); \ +#define INIT_FGETGRENT_R \ COMMON_INTERCEPT_FUNCTION(fgetgrent_r); #else -#define INIT_GETPWENT_R +#define INIT_FGETGRENT_R #endif #if SANITIZER_INTERCEPT_SETPWENT @@ -2147,6 +2173,8 @@ INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { namespace __sanitizer { extern "C" { int real_clock_gettime(u32 clk_id, void *tp) { + if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) + return internal_clock_gettime(clk_id, tp); return REAL(clock_gettime)(clk_id, tp); } } // extern "C" @@ -3500,13 +3528,16 @@ INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, wcrtomb, dest, src, ps); if (ps) COMMON_INTERCEPTOR_READ_RANGE(ctx, ps, mbstate_t_sz); - // FIXME: under ASan the call below may write to freed memory and corrupt - // its metadata. See - // https://github.com/google/sanitizers/issues/321. - SIZE_T res = REAL(wcrtomb)(dest, src, ps); - if (res != ((SIZE_T)-1) && dest) { - SIZE_T write_cnt = res; - COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, write_cnt); + + if (!dest) + return REAL(wcrtomb)(dest, src, ps); + + char local_dest[32]; + SIZE_T res = REAL(wcrtomb)(local_dest, src, ps); + if (res != ((SIZE_T)-1)) { + CHECK_LE(res, sizeof(local_dest)); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res); + REAL(memcpy)(dest, local_dest, res); } return res; } @@ -3516,6 +3547,28 @@ INTERCEPTOR(SIZE_T, wcrtomb, char *dest, wchar_t src, void *ps) { #define INIT_WCRTOMB #endif +#if SANITIZER_INTERCEPT_WCTOMB +INTERCEPTOR(int, wctomb, char *dest, wchar_t src) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, wctomb, dest, src); + if (!dest) + return REAL(wctomb)(dest, src); + + char local_dest[32]; + int res = REAL(wctomb)(local_dest, src); + if (res != -1) { + CHECK_LE(res, sizeof(local_dest)); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, res); + REAL(memcpy)(dest, local_dest, res); + } + return res; +} + +#define INIT_WCTOMB COMMON_INTERCEPT_FUNCTION(wctomb); +#else +#define INIT_WCTOMB +#endif + #if SANITIZER_INTERCEPT_TCGETATTR INTERCEPTOR(int, tcgetattr, int fd, void *termios_p) { void *ctx; @@ -4012,6 +4065,25 @@ INTERCEPTOR(int, sigprocmask, int how, __sanitizer_sigset_t *set, #define INIT_SIGPROCMASK #endif +#if SANITIZER_INTERCEPT_PTHREAD_SIGMASK +INTERCEPTOR(int, pthread_sigmask, int how, __sanitizer_sigset_t *set, + __sanitizer_sigset_t *oldset) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, pthread_sigmask, how, set, oldset); + if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); + // FIXME: under ASan the call below may write to freed memory and corrupt + // its metadata. See + // https://github.com/google/sanitizers/issues/321. + int res = REAL(pthread_sigmask)(how, set, oldset); + if (!res && oldset) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldset, sizeof(*oldset)); + return res; +} +#define INIT_PTHREAD_SIGMASK COMMON_INTERCEPT_FUNCTION(pthread_sigmask); +#else +#define INIT_PTHREAD_SIGMASK +#endif + #if SANITIZER_INTERCEPT_BACKTRACE INTERCEPTOR(int, backtrace, void **buffer, int size) { void *ctx; @@ -4252,11 +4324,16 @@ INTERCEPTOR(int, statvfs, char *path, void *buf) { INTERCEPTOR(int, fstatvfs, int fd, void *buf) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs, fd, buf); + COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. int res = REAL(fstatvfs)(fd, buf); - if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); + if (!res) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); + if (fd >= 0) + COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); + } return res; } #define INIT_STATVFS \ @@ -4690,6 +4767,20 @@ INTERCEPTOR(char *, tmpnam_r, char *s) { #define INIT_TMPNAM_R #endif +#if SANITIZER_INTERCEPT_TTYNAME +INTERCEPTOR(char *, ttyname, int fd) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, ttyname, fd); + char *res = REAL(ttyname)(fd); + if (res != nullptr) + COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, REAL(strlen)(res) + 1); + return res; +} +#define INIT_TTYNAME COMMON_INTERCEPT_FUNCTION(ttyname); +#else +#define INIT_TTYNAME +#endif + #if SANITIZER_INTERCEPT_TTYNAME_R INTERCEPTOR(int, ttyname_r, int fd, char *name, SIZE_T namesize) { void *ctx; @@ -4817,6 +4908,14 @@ INTERCEPTOR(float, remquof, float x, float y, int *quo) { if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); return res; } +#define INIT_REMQUO \ + COMMON_INTERCEPT_FUNCTION(remquo); \ + COMMON_INTERCEPT_FUNCTION(remquof); +#else +#define INIT_REMQUO +#endif + +#if SANITIZER_INTERCEPT_REMQUOL INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, remquol, x, y, quo); @@ -4827,12 +4926,10 @@ INTERCEPTOR(long double, remquol, long double x, long double y, int *quo) { if (quo) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, quo, sizeof(*quo)); return res; } -#define INIT_REMQUO \ - COMMON_INTERCEPT_FUNCTION(remquo); \ - COMMON_INTERCEPT_FUNCTION(remquof); \ +#define INIT_REMQUOL \ COMMON_INTERCEPT_FUNCTION_LDBL(remquol); #else -#define INIT_REMQUO +#define INIT_REMQUOL #endif #if SANITIZER_INTERCEPT_LGAMMA @@ -4851,6 +4948,14 @@ INTERCEPTOR(float, lgammaf, float x) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); return res; } +#define INIT_LGAMMA \ + COMMON_INTERCEPT_FUNCTION(lgamma); \ + COMMON_INTERCEPT_FUNCTION(lgammaf); +#else +#define INIT_LGAMMA +#endif + +#if SANITIZER_INTERCEPT_LGAMMAL INTERCEPTOR(long double, lgammal, long double x) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, lgammal, x); @@ -4858,12 +4963,10 @@ INTERCEPTOR(long double, lgammal, long double x) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &signgam, sizeof(signgam)); return res; } -#define INIT_LGAMMA \ - COMMON_INTERCEPT_FUNCTION(lgamma); \ - COMMON_INTERCEPT_FUNCTION(lgammaf); \ +#define INIT_LGAMMAL \ COMMON_INTERCEPT_FUNCTION_LDBL(lgammal); #else -#define INIT_LGAMMA +#define INIT_LGAMMAL #endif #if SANITIZER_INTERCEPT_LGAMMA_R @@ -5455,12 +5558,21 @@ INTERCEPTOR(void *, __bzero, void *block, uptr size) { void *ctx; COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); } - #define INIT___BZERO COMMON_INTERCEPT_FUNCTION(__bzero); #else #define INIT___BZERO #endif // SANITIZER_INTERCEPT___BZERO +#if SANITIZER_INTERCEPT_BZERO +INTERCEPTOR(void *, bzero, void *block, uptr size) { + void *ctx; + COMMON_INTERCEPTOR_MEMSET_IMPL(ctx, block, 0, size); +} +#define INIT_BZERO COMMON_INTERCEPT_FUNCTION(bzero); +#else +#define INIT_BZERO +#endif // SANITIZER_INTERCEPT_BZERO + #if SANITIZER_INTERCEPT_FTIME INTERCEPTOR(int, ftime, __sanitizer_timeb *tp) { void *ctx; @@ -5649,9 +5761,15 @@ INTERCEPTOR(void *, tsearch, void *key, void **rootp, void unpoison_file(__sanitizer_FILE *fp) { #if SANITIZER_HAS_STRUCT_FILE COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp, sizeof(*fp)); +#if SANITIZER_NETBSD + if (fp->_bf._base && fp->_bf._size > 0) + COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_bf._base, + fp->_bf._size); +#else if (fp->_IO_read_base && fp->_IO_read_base < fp->_IO_read_end) COMMON_INTERCEPTOR_INITIALIZE_RANGE(fp->_IO_read_base, fp->_IO_read_end - fp->_IO_read_base); +#endif #endif // SANITIZER_HAS_STRUCT_FILE } #endif @@ -6521,10 +6639,21 @@ INTERCEPTOR(void *, getutxline, void *ut) { COMMON_INTERCEPTOR_INITIALIZE_RANGE(res, __sanitizer::struct_utmpx_sz); return res; } +INTERCEPTOR(void *, pututxline, const void *ut) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, pututxline, ut); + if (ut) + COMMON_INTERCEPTOR_READ_RANGE(ctx, ut, __sanitizer::struct_utmpx_sz); + void *res = REAL(pututxline)(ut); + if (res) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_utmpx_sz); + return res; +} #define INIT_UTMPX \ COMMON_INTERCEPT_FUNCTION(getutxent); \ COMMON_INTERCEPT_FUNCTION(getutxid); \ - COMMON_INTERCEPT_FUNCTION(getutxline); + COMMON_INTERCEPT_FUNCTION(getutxline); \ + COMMON_INTERCEPT_FUNCTION(pututxline); #else #define INIT_UTMPX #endif @@ -6609,6 +6738,23 @@ INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) { #define INIT_WCSCAT #endif +#if SANITIZER_INTERCEPT_WCSDUP +INTERCEPTOR(wchar_t *, wcsdup, wchar_t *s) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, wcsdup, s); + SIZE_T len = REAL(wcslen)(s); + COMMON_INTERCEPTOR_READ_RANGE(ctx, s, sizeof(wchar_t) * (len + 1)); + wchar_t *result = REAL(wcsdup)(s); + if (result) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, result, sizeof(wchar_t) * (len + 1)); + return result; +} + +#define INIT_WCSDUP COMMON_INTERCEPT_FUNCTION(wcsdup); +#else +#define INIT_WCSDUP +#endif + #if SANITIZER_INTERCEPT_STRXFRM static SIZE_T RealStrLen(const char *str) { return REAL(strlen)(str); } @@ -7016,12 +7162,19 @@ INTERCEPTOR(char *, devname, u64 dev, u32 type) { #endif #if SANITIZER_INTERCEPT_DEVNAME_R -INTERCEPTOR(int, devname_r, u64 dev, u32 type, char *path, uptr len) { +#if SANITIZER_NETBSD +#define DEVNAME_R_RETTYPE int +#define DEVNAME_R_SUCCESS(x) (!(x)) +#else +#define DEVNAME_R_RETTYPE char* +#define DEVNAME_R_SUCCESS(x) (x) +#endif +INTERCEPTOR(DEVNAME_R_RETTYPE, devname_r, u64 dev, u32 type, char *path, + uptr len) { void *ctx; - int res; COMMON_INTERCEPTOR_ENTER(ctx, devname_r, dev, type, path, len); - res = REAL(devname_r)(dev, type, path, len); - if (!res) + DEVNAME_R_RETTYPE res = REAL(devname_r)(dev, type, path, len); + if (DEVNAME_R_SUCCESS(res)) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, path, REAL(strlen)(path) + 1); return res; } @@ -7233,9 +7386,2191 @@ INTERCEPTOR(struct __sanitizer_netent *, getnetbyaddr, u32 net, int type) { #define INIT_NETENT #endif -static void InitializeCommonInterceptors() { - static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; - interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap(); +#if SANITIZER_INTERCEPT_GETMNTINFO +INTERCEPTOR(int, getmntinfo, void **mntbufp, int flags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getmntinfo, mntbufp, flags); + int cnt = REAL(getmntinfo)(mntbufp, flags); + if (cnt > 0 && mntbufp) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mntbufp, sizeof(void *)); + if (*mntbufp) +#if SANITIZER_NETBSD + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statvfs_sz); +#else + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *mntbufp, cnt * struct_statfs_sz); +#endif + } + return cnt; +} +#define INIT_GETMNTINFO COMMON_INTERCEPT_FUNCTION(getmntinfo) +#else +#define INIT_GETMNTINFO +#endif + +#if SANITIZER_INTERCEPT_MI_VECTOR_HASH +INTERCEPTOR(void, mi_vector_hash, const void *key, SIZE_T len, u32 seed, + u32 hashes[3]) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, mi_vector_hash, key, len, seed, hashes); + if (key) + COMMON_INTERCEPTOR_READ_RANGE(ctx, key, len); + REAL(mi_vector_hash)(key, len, seed, hashes); + if (hashes) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, hashes, sizeof(hashes[0]) * 3); +} +#define INIT_MI_VECTOR_HASH COMMON_INTERCEPT_FUNCTION(mi_vector_hash) +#else +#define INIT_MI_VECTOR_HASH +#endif + +#if SANITIZER_INTERCEPT_SETVBUF +INTERCEPTOR(int, setvbuf, __sanitizer_FILE *stream, char *buf, int mode, + SIZE_T size) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, setvbuf, stream, buf, mode, size); + int ret = REAL(setvbuf)(stream, buf, mode, size); + if (buf) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, size); + if (stream) + unpoison_file(stream); + return ret; +} + +INTERCEPTOR(void, setbuf, __sanitizer_FILE *stream, char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, setbuf, stream, buf); + REAL(setbuf)(stream, buf); + if (buf) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz); + } + if (stream) + unpoison_file(stream); +} + +INTERCEPTOR(void, setbuffer, __sanitizer_FILE *stream, char *buf, int mode) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, setbuffer, stream, buf, mode); + REAL(setbuffer)(stream, buf, mode); + if (buf) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer_bufsiz); + } + if (stream) + unpoison_file(stream); +} + +INTERCEPTOR(void, setlinebuf, __sanitizer_FILE *stream) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, setlinebuf, stream); + REAL(setlinebuf)(stream); + if (stream) + unpoison_file(stream); +} +#define INIT_SETVBUF COMMON_INTERCEPT_FUNCTION(setvbuf); \ + COMMON_INTERCEPT_FUNCTION(setbuf); \ + COMMON_INTERCEPT_FUNCTION(setbuffer); \ + COMMON_INTERCEPT_FUNCTION(setlinebuf) +#else +#define INIT_SETVBUF +#endif + +#if SANITIZER_INTERCEPT_GETVFSSTAT +INTERCEPTOR(int, getvfsstat, void *buf, SIZE_T bufsize, int flags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getvfsstat, buf, bufsize, flags); + int ret = REAL(getvfsstat)(buf, bufsize, flags); + if (buf && ret > 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, ret * struct_statvfs_sz); + return ret; +} +#define INIT_GETVFSSTAT COMMON_INTERCEPT_FUNCTION(getvfsstat) +#else +#define INIT_GETVFSSTAT +#endif + +#if SANITIZER_INTERCEPT_REGEX +INTERCEPTOR(int, regcomp, void *preg, const char *pattern, int cflags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, regcomp, preg, pattern, cflags); + if (pattern) + COMMON_INTERCEPTOR_READ_RANGE(ctx, pattern, REAL(strlen)(pattern) + 1); + int res = REAL(regcomp)(preg, pattern, cflags); + if (!res) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, preg, struct_regex_sz); + return res; +} +INTERCEPTOR(int, regexec, const void *preg, const char *string, SIZE_T nmatch, + struct __sanitizer_regmatch *pmatch[], int eflags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, regexec, preg, string, nmatch, pmatch, eflags); + if (preg) + COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz); + if (string) + COMMON_INTERCEPTOR_READ_RANGE(ctx, string, REAL(strlen)(string) + 1); + int res = REAL(regexec)(preg, string, nmatch, pmatch, eflags); + if (!res && pmatch) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pmatch, nmatch * struct_regmatch_sz); + return res; +} +INTERCEPTOR(SIZE_T, regerror, int errcode, const void *preg, char *errbuf, + SIZE_T errbuf_size) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, regerror, errcode, preg, errbuf, errbuf_size); + if (preg) + COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz); + SIZE_T res = REAL(regerror)(errcode, preg, errbuf, errbuf_size); + if (errbuf) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errbuf, REAL(strlen)(errbuf) + 1); + return res; +} +INTERCEPTOR(void, regfree, const void *preg) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, regfree, preg); + if (preg) + COMMON_INTERCEPTOR_READ_RANGE(ctx, preg, struct_regex_sz); + REAL(regfree)(preg); +} +#define INIT_REGEX \ + COMMON_INTERCEPT_FUNCTION(regcomp); \ + COMMON_INTERCEPT_FUNCTION(regexec); \ + COMMON_INTERCEPT_FUNCTION(regerror); \ + COMMON_INTERCEPT_FUNCTION(regfree); +#else +#define INIT_REGEX +#endif + +#if SANITIZER_INTERCEPT_REGEXSUB +INTERCEPTOR(SSIZE_T, regnsub, char *buf, SIZE_T bufsiz, const char *sub, + const struct __sanitizer_regmatch *rm, const char *str) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, regnsub, buf, bufsiz, sub, rm, str); + if (sub) + COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, REAL(strlen)(sub) + 1); + // The implementation demands and hardcodes 10 elements + if (rm) + COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz); + if (str) + COMMON_INTERCEPTOR_READ_RANGE(ctx, str, REAL(strlen)(str) + 1); + SSIZE_T res = REAL(regnsub)(buf, bufsiz, sub, rm, str); + if (res > 0 && buf) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1); + return res; +} +INTERCEPTOR(SSIZE_T, regasub, char **buf, const char *sub, + const struct __sanitizer_regmatch *rm, const char *sstr) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, regasub, buf, sub, rm, sstr); + if (sub) + COMMON_INTERCEPTOR_READ_RANGE(ctx, sub, REAL(strlen)(sub) + 1); + // Hardcode 10 elements as this is hardcoded size + if (rm) + COMMON_INTERCEPTOR_READ_RANGE(ctx, rm, 10 * struct_regmatch_sz); + if (sstr) + COMMON_INTERCEPTOR_READ_RANGE(ctx, sstr, REAL(strlen)(sstr) + 1); + SSIZE_T res = REAL(regasub)(buf, sub, rm, sstr); + if (res > 0 && buf) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sizeof(char *)); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *buf, REAL(strlen)(*buf) + 1); + } + return res; +} + +#define INIT_REGEXSUB \ + COMMON_INTERCEPT_FUNCTION(regnsub); \ + COMMON_INTERCEPT_FUNCTION(regasub); +#else +#define INIT_REGEXSUB +#endif + +#if SANITIZER_INTERCEPT_FTS +INTERCEPTOR(void *, fts_open, char *const *path_argv, int options, + int (*compar)(void **, void **)) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, fts_open, path_argv, options, compar); + if (path_argv) { + for (char *const *pa = path_argv; ; ++pa) { + COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **)); + if (!*pa) + break; + COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1); + } + } + // TODO(kamil): handle compar callback + void *fts = REAL(fts_open)(path_argv, options, compar); + if (fts) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, fts, struct_FTS_sz); + return fts; +} + +INTERCEPTOR(void *, fts_read, void *ftsp) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, fts_read, ftsp); + if (ftsp) + COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz); + void *ftsent = REAL(fts_read)(ftsp); + if (ftsent) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz); + return ftsent; +} + +INTERCEPTOR(void *, fts_children, void *ftsp, int options) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, fts_children, ftsp, options); + if (ftsp) + COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz); + void *ftsent = REAL(fts_children)(ftsp, options); + if (ftsent) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ftsent, struct_FTSENT_sz); + return ftsent; +} + +INTERCEPTOR(int, fts_set, void *ftsp, void *f, int options) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, fts_set, ftsp, f, options); + if (ftsp) + COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz); + if (f) + COMMON_INTERCEPTOR_READ_RANGE(ctx, f, struct_FTSENT_sz); + return REAL(fts_set)(ftsp, f, options); +} + +INTERCEPTOR(int, fts_close, void *ftsp) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, fts_close, ftsp); + if (ftsp) + COMMON_INTERCEPTOR_READ_RANGE(ctx, ftsp, struct_FTS_sz); + return REAL(fts_close)(ftsp); +} +#define INIT_FTS \ + COMMON_INTERCEPT_FUNCTION(fts_open); \ + COMMON_INTERCEPT_FUNCTION(fts_read); \ + COMMON_INTERCEPT_FUNCTION(fts_children); \ + COMMON_INTERCEPT_FUNCTION(fts_set); \ + COMMON_INTERCEPT_FUNCTION(fts_close); +#else +#define INIT_FTS +#endif + +#if SANITIZER_INTERCEPT_SYSCTL +INTERCEPTOR(int, sysctl, int *name, unsigned int namelen, void *oldp, + SIZE_T *oldlenp, void *newp, SIZE_T newlen) { + void *ctx; + if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) + return internal_sysctl(name, namelen, oldp, oldlenp, newp, newlen); + COMMON_INTERCEPTOR_ENTER(ctx, sysctl, name, namelen, oldp, oldlenp, newp, + newlen); + if (name) + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, namelen * sizeof(*name)); + if (oldlenp) + COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp)); + if (newp && newlen) + COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen); + int res = REAL(sysctl)(name, namelen, oldp, oldlenp, newp, newlen); + if (!res) { + if (oldlenp) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp)); + if (oldp) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp); + } + } + return res; +} + +INTERCEPTOR(int, sysctlbyname, char *sname, void *oldp, SIZE_T *oldlenp, + void *newp, SIZE_T newlen) { + void *ctx; + if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) + return internal_sysctlbyname(sname, oldp, oldlenp, newp, newlen); + COMMON_INTERCEPTOR_ENTER(ctx, sysctlbyname, sname, oldp, oldlenp, newp, + newlen); + if (sname) + COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1); + if (oldlenp) + COMMON_INTERCEPTOR_READ_RANGE(ctx, oldlenp, sizeof(*oldlenp)); + if (newp && newlen) + COMMON_INTERCEPTOR_READ_RANGE(ctx, newp, newlen); + int res = REAL(sysctlbyname)(sname, oldp, oldlenp, newp, newlen); + if (!res) { + if (oldlenp) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldlenp, sizeof(*oldlenp)); + if (oldp) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldp, *oldlenp); + } + } + return res; +} + +INTERCEPTOR(int, sysctlnametomib, const char *sname, int *name, + SIZE_T *namelenp) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, sysctlnametomib, sname, name, namelenp); + if (sname) + COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1); + if (namelenp) + COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp)); + int res = REAL(sysctlnametomib)(sname, name, namelenp); + if (!res) { + if (namelenp) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp)); + if (name) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name)); + } + } + return res; +} + +#define INIT_SYSCTL \ + COMMON_INTERCEPT_FUNCTION(sysctl); \ + COMMON_INTERCEPT_FUNCTION(sysctlbyname); \ + COMMON_INTERCEPT_FUNCTION(sysctlnametomib); +#else +#define INIT_SYSCTL +#endif + +#if SANITIZER_INTERCEPT_ASYSCTL +INTERCEPTOR(void *, asysctl, const int *name, SIZE_T namelen, SIZE_T *len) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, asysctl, name, namelen, len); + if (name) + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, sizeof(*name) * namelen); + void *res = REAL(asysctl)(name, namelen, len); + if (res && len) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len)); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len); + } + return res; +} + +INTERCEPTOR(void *, asysctlbyname, const char *sname, SIZE_T *len) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, asysctlbyname, sname, len); + if (sname) + COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1); + void *res = REAL(asysctlbyname)(sname, len); + if (res && len) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len)); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, *len); + } + return res; +} +#define INIT_ASYSCTL \ + COMMON_INTERCEPT_FUNCTION(asysctl); \ + COMMON_INTERCEPT_FUNCTION(asysctlbyname); +#else +#define INIT_ASYSCTL +#endif + +#if SANITIZER_INTERCEPT_SYSCTLGETMIBINFO +INTERCEPTOR(int, sysctlgetmibinfo, char *sname, int *name, + unsigned int *namelenp, char *cname, SIZE_T *csz, void **rnode, + int v) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, sysctlgetmibinfo, sname, name, namelenp, cname, + csz, rnode, v); + if (sname) + COMMON_INTERCEPTOR_READ_RANGE(ctx, sname, REAL(strlen)(sname) + 1); + if (namelenp) + COMMON_INTERCEPTOR_READ_RANGE(ctx, namelenp, sizeof(*namelenp)); + if (csz) + COMMON_INTERCEPTOR_READ_RANGE(ctx, csz, sizeof(*csz)); + // Skip rnode, it's rarely used and not trivial to sanitize + // It's also used mostly internally + int res = REAL(sysctlgetmibinfo)(sname, name, namelenp, cname, csz, rnode, v); + if (!res) { + if (namelenp) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, namelenp, sizeof(*namelenp)); + if (name) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, *namelenp * sizeof(*name)); + } + if (csz) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, csz, sizeof(*csz)); + if (cname) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cname, *csz); + } + } + return res; +} +#define INIT_SYSCTLGETMIBINFO \ + COMMON_INTERCEPT_FUNCTION(sysctlgetmibinfo); +#else +#define INIT_SYSCTLGETMIBINFO +#endif + +#if SANITIZER_INTERCEPT_NL_LANGINFO +INTERCEPTOR(char *, nl_langinfo, long item) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, nl_langinfo, item); + char *ret = REAL(nl_langinfo)(item); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, REAL(strlen)(ret) + 1); + return ret; +} +#define INIT_NL_LANGINFO COMMON_INTERCEPT_FUNCTION(nl_langinfo) +#else +#define INIT_NL_LANGINFO +#endif + +#if SANITIZER_INTERCEPT_MODCTL +INTERCEPTOR(int, modctl, int operation, void *argp) { + void *ctx; + int ret; + COMMON_INTERCEPTOR_ENTER(ctx, modctl, operation, argp); + + if (operation == modctl_load) { + if (argp) { + __sanitizer_modctl_load_t *ml = (__sanitizer_modctl_load_t *)argp; + COMMON_INTERCEPTOR_READ_RANGE(ctx, ml, sizeof(*ml)); + if (ml->ml_filename) + COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_filename, + REAL(strlen)(ml->ml_filename) + 1); + if (ml->ml_props) + COMMON_INTERCEPTOR_READ_RANGE(ctx, ml->ml_props, ml->ml_propslen); + } + ret = REAL(modctl)(operation, argp); + } else if (operation == modctl_unload) { + if (argp) { + const char *name = (const char *)argp; + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + } + ret = REAL(modctl)(operation, argp); + } else if (operation == modctl_stat) { + uptr iov_len; + struct __sanitizer_iovec *iov = (struct __sanitizer_iovec *)argp; + if (iov) { + COMMON_INTERCEPTOR_READ_RANGE(ctx, iov, sizeof(*iov)); + iov_len = iov->iov_len; + } + ret = REAL(modctl)(operation, argp); + if (iov) + COMMON_INTERCEPTOR_WRITE_RANGE( + ctx, iov->iov_base, Min(iov_len, iov->iov_len)); + } else if (operation == modctl_exists) + ret = REAL(modctl)(operation, argp); + else + ret = REAL(modctl)(operation, argp); + + return ret; +} +#define INIT_MODCTL COMMON_INTERCEPT_FUNCTION(modctl) +#else +#define INIT_MODCTL +#endif + +#if SANITIZER_INTERCEPT_STRTONUM +INTERCEPTOR(long long, strtonum, const char *nptr, long long minval, + long long maxval, const char **errstr) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strtonum, nptr, minval, maxval, errstr); + + // TODO(kamil): Implement strtoll as a common inteceptor + char *real_endptr; + long long ret = (long long)REAL(strtoimax)(nptr, &real_endptr, 10); + StrtolFixAndCheck(ctx, nptr, nullptr, real_endptr, 10); + + ret = REAL(strtonum)(nptr, minval, maxval, errstr); + if (errstr) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, errstr, sizeof(const char *)); + if (*errstr) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *errstr, REAL(strlen)(*errstr) + 1); + } + return ret; +} +#define INIT_STRTONUM COMMON_INTERCEPT_FUNCTION(strtonum) +#else +#define INIT_STRTONUM +#endif + +#if SANITIZER_INTERCEPT_FPARSELN +INTERCEPTOR(char *, fparseln, __sanitizer_FILE *stream, SIZE_T *len, + SIZE_T *lineno, const char delim[3], int flags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, fparseln, stream, len, lineno, delim, flags); + if (lineno) + COMMON_INTERCEPTOR_READ_RANGE(ctx, lineno, sizeof(*lineno)); + if (delim) + COMMON_INTERCEPTOR_READ_RANGE(ctx, delim, sizeof(delim[0]) * 3); + char *ret = REAL(fparseln)(stream, len, lineno, delim, flags); + if (ret) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, REAL(strlen)(ret) + 1); + if (len) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len)); + if (lineno) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, lineno, sizeof(*lineno)); + } + return ret; +} +#define INIT_FPARSELN COMMON_INTERCEPT_FUNCTION(fparseln) +#else +#define INIT_FPARSELN +#endif + +#if SANITIZER_INTERCEPT_STATVFS1 +INTERCEPTOR(int, statvfs1, const char *path, void *buf, int flags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, statvfs1, path, buf, flags); + if (path) COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + int res = REAL(statvfs1)(path, buf, flags); + if (!res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); + return res; +} +INTERCEPTOR(int, fstatvfs1, int fd, void *buf, int flags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, fstatvfs1, fd, buf, flags); + COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); + int res = REAL(fstatvfs1)(fd, buf, flags); + if (!res) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, struct_statvfs_sz); + if (fd >= 0) + COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); + } + return res; +} +#define INIT_STATVFS1 \ + COMMON_INTERCEPT_FUNCTION(statvfs1); \ + COMMON_INTERCEPT_FUNCTION(fstatvfs1); +#else +#define INIT_STATVFS1 +#endif + +#if SANITIZER_INTERCEPT_STRTOI +INTERCEPTOR(INTMAX_T, strtoi, const char *nptr, char **endptr, int base, + INTMAX_T low, INTMAX_T high, int *rstatus) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strtoi, nptr, endptr, base, low, high, rstatus); + char *real_endptr; + INTMAX_T ret = REAL(strtoi)(nptr, &real_endptr, base, low, high, rstatus); + StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); + if (rstatus) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus)); + return ret; +} + +INTERCEPTOR(UINTMAX_T, strtou, const char *nptr, char **endptr, int base, + UINTMAX_T low, UINTMAX_T high, int *rstatus) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strtou, nptr, endptr, base, low, high, rstatus); + char *real_endptr; + UINTMAX_T ret = REAL(strtou)(nptr, &real_endptr, base, low, high, rstatus); + StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); + if (rstatus) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rstatus, sizeof(*rstatus)); + return ret; +} +#define INIT_STRTOI \ + COMMON_INTERCEPT_FUNCTION(strtoi); \ + COMMON_INTERCEPT_FUNCTION(strtou) +#else +#define INIT_STRTOI +#endif + +#if SANITIZER_INTERCEPT_CAPSICUM +#define CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights, ...) \ + { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_init, rights, ##__VA_ARGS__); \ + if (rights) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \ + __sanitizer_cap_rights_t *ret = \ + REAL(cap_rights_init)(rights, ##__VA_ARGS__); \ + if (ret) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \ + return ret; \ + } + +#define CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights, ...) \ + { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_set, rights, ##__VA_ARGS__); \ + if (rights) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \ + __sanitizer_cap_rights_t *ret = \ + REAL(cap_rights_set)(rights, ##__VA_ARGS__); \ + if (ret) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \ + return ret; \ + } + +#define CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights, ...) \ + { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_clear, rights, ##__VA_ARGS__); \ + if (rights) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \ + __sanitizer_cap_rights_t *ret = \ + REAL(cap_rights_clear)(rights, ##__VA_ARGS__); \ + if (ret) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); \ + return ret; \ + } + +#define CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights, ...) \ + { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_set, rights, ##__VA_ARGS__); \ + if (rights) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); \ + return REAL(cap_rights_is_set)(rights, ##__VA_ARGS__); \ + } + +INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_init, + __sanitizer_cap_rights_t *rights) { + CAP_RIGHTS_INIT_INTERCEPTOR(cap_rights_init, rights); +} + +INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_set, + __sanitizer_cap_rights_t *rights) { + CAP_RIGHTS_SET_INTERCEPTOR(cap_rights_set, rights); +} + +INTERCEPTOR(__sanitizer_cap_rights_t *, cap_rights_clear, + __sanitizer_cap_rights_t *rights) { + CAP_RIGHTS_CLEAR_INTERCEPTOR(cap_rights_clear, rights); +} + +INTERCEPTOR(bool, cap_rights_is_set, + __sanitizer_cap_rights_t *rights) { + CAP_RIGHTS_IS_SET_INTERCEPTOR(cap_rights_is_set, rights); +} + +INTERCEPTOR(int, cap_rights_limit, int fd, + const __sanitizer_cap_rights_t *rights) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_limit, fd, rights); + if (rights) + COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); + + return REAL(cap_rights_limit)(fd, rights); +} + +INTERCEPTOR(int, cap_rights_get, int fd, __sanitizer_cap_rights_t *rights) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_get, fd, rights); + int ret = REAL(cap_rights_get)(fd, rights); + if (!ret && rights) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, rights, sizeof(*rights)); + + return ret; +} + +INTERCEPTOR(bool, cap_rights_is_valid, const __sanitizer_cap_rights_t *rights) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_is_valid, rights); + if (rights) + COMMON_INTERCEPTOR_READ_RANGE(ctx, rights, sizeof(*rights)); + + return REAL(cap_rights_is_valid(rights)); +} + +INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_merge, + __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_merge, dst, src); + if (src) + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); + + __sanitizer_cap_rights *ret = REAL(cap_rights_merge)(dst, src); + if (dst) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst)); + + return ret; +} + +INTERCEPTOR(__sanitizer_cap_rights *, cap_rights_remove, + __sanitizer_cap_rights *dst, const __sanitizer_cap_rights *src) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_remove, dst, src); + if (src) + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, sizeof(*src)); + + __sanitizer_cap_rights *ret = REAL(cap_rights_remove)(dst, src); + if (dst) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(*dst)); + + return ret; +} + +INTERCEPTOR(bool, cap_rights_contains, const __sanitizer_cap_rights *big, + const __sanitizer_cap_rights *little) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cap_rights_contains, big, little); + if (little) + COMMON_INTERCEPTOR_READ_RANGE(ctx, little, sizeof(*little)); + if (big) + COMMON_INTERCEPTOR_READ_RANGE(ctx, big, sizeof(*big)); + + return REAL(cap_rights_contains)(big, little); +} + +INTERCEPTOR(int, cap_ioctls_limit, int fd, const uptr *cmds, SIZE_T ncmds) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_limit, fd, cmds, ncmds); + if (cmds) + COMMON_INTERCEPTOR_READ_RANGE(ctx, cmds, sizeof(*cmds) * ncmds); + + return REAL(cap_ioctls_limit)(fd, cmds, ncmds); +} + +INTERCEPTOR(int, cap_ioctls_get, int fd, uptr *cmds, SIZE_T maxcmds) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cap_ioctls_get, fd, cmds, maxcmds); + int ret = REAL(cap_ioctls_get)(fd, cmds, maxcmds); + if (!ret && cmds) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cmds, sizeof(*cmds) * maxcmds); + + return ret; +} +#define INIT_CAPSICUM \ + COMMON_INTERCEPT_FUNCTION(cap_rights_init); \ + COMMON_INTERCEPT_FUNCTION(cap_rights_set); \ + COMMON_INTERCEPT_FUNCTION(cap_rights_clear); \ + COMMON_INTERCEPT_FUNCTION(cap_rights_is_set); \ + COMMON_INTERCEPT_FUNCTION(cap_rights_get); \ + COMMON_INTERCEPT_FUNCTION(cap_rights_limit); \ + COMMON_INTERCEPT_FUNCTION(cap_rights_contains); \ + COMMON_INTERCEPT_FUNCTION(cap_rights_remove); \ + COMMON_INTERCEPT_FUNCTION(cap_rights_merge); \ + COMMON_INTERCEPT_FUNCTION(cap_rights_is_valid); \ + COMMON_INTERCEPT_FUNCTION(cap_ioctls_get); \ + COMMON_INTERCEPT_FUNCTION(cap_ioctls_limit) +#else +#define INIT_CAPSICUM +#endif + +#if SANITIZER_INTERCEPT_SHA1 +INTERCEPTOR(void, SHA1Init, void *context) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, SHA1Init, context); + REAL(SHA1Init)(context); + if (context) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz); +} +INTERCEPTOR(void, SHA1Update, void *context, const u8 *data, unsigned len) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, SHA1Update, context, data, len); + if (data && len > 0) + COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); + if (context) + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz); + REAL(SHA1Update)(context, data, len); + if (context) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA1_CTX_sz); +} +INTERCEPTOR(void, SHA1Final, u8 digest[20], void *context) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, SHA1Final, digest, context); + if (context) + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz); + REAL(SHA1Final)(digest, context); + if (digest) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20); +} +INTERCEPTOR(void, SHA1Transform, u32 state[5], u8 buffer[64]) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, SHA1Transform, state, buffer); + if (state) + COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5); + if (buffer) + COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u8) * 64); + REAL(SHA1Transform)(state, buffer); + if (state) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5); +} +INTERCEPTOR(char *, SHA1End, void *context, char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, SHA1End, context, buf); + if (context) + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA1_CTX_sz); + char *ret = REAL(SHA1End)(context, buf); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length); + return ret; +} +INTERCEPTOR(char *, SHA1File, char *filename, char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, SHA1File, filename, buf); + if (filename) + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); + char *ret = REAL(SHA1File)(filename, buf); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length); + return ret; +} +INTERCEPTOR(char *, SHA1FileChunk, char *filename, char *buf, OFF_T offset, + OFF_T length) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, SHA1FileChunk, filename, buf, offset, length); + if (filename) + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); + char *ret = REAL(SHA1FileChunk)(filename, buf, offset, length); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length); + return ret; +} +INTERCEPTOR(char *, SHA1Data, u8 *data, SIZE_T len, char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, SHA1Data, data, len, buf); + if (data) + COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); + char *ret = REAL(SHA1Data)(data, len, buf); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA1_return_length); + return ret; +} +#define INIT_SHA1 \ + COMMON_INTERCEPT_FUNCTION(SHA1Init); \ + COMMON_INTERCEPT_FUNCTION(SHA1Update); \ + COMMON_INTERCEPT_FUNCTION(SHA1Final); \ + COMMON_INTERCEPT_FUNCTION(SHA1Transform); \ + COMMON_INTERCEPT_FUNCTION(SHA1End); \ + COMMON_INTERCEPT_FUNCTION(SHA1File); \ + COMMON_INTERCEPT_FUNCTION(SHA1FileChunk); \ + COMMON_INTERCEPT_FUNCTION(SHA1Data) +#else +#define INIT_SHA1 +#endif + +#if SANITIZER_INTERCEPT_MD4 +INTERCEPTOR(void, MD4Init, void *context) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD4Init, context); + REAL(MD4Init)(context); + if (context) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz); +} + +INTERCEPTOR(void, MD4Update, void *context, const unsigned char *data, + unsigned int len) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD4Update, context, data, len); + if (data && len > 0) + COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); + if (context) + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz); + REAL(MD4Update)(context, data, len); + if (context) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD4_CTX_sz); +} + +INTERCEPTOR(void, MD4Final, unsigned char digest[16], void *context) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD4Final, digest, context); + if (context) + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz); + REAL(MD4Final)(digest, context); + if (digest) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16); +} + +INTERCEPTOR(char *, MD4End, void *context, char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD4End, context, buf); + if (context) + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD4_CTX_sz); + char *ret = REAL(MD4End)(context, buf); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length); + return ret; +} + +INTERCEPTOR(char *, MD4File, const char *filename, char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD4File, filename, buf); + if (filename) + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); + char *ret = REAL(MD4File)(filename, buf); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length); + return ret; +} + +INTERCEPTOR(char *, MD4Data, const unsigned char *data, unsigned int len, + char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD4Data, data, len, buf); + if (data && len > 0) + COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); + char *ret = REAL(MD4Data)(data, len, buf); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD4_return_length); + return ret; +} + +#define INIT_MD4 \ + COMMON_INTERCEPT_FUNCTION(MD4Init); \ + COMMON_INTERCEPT_FUNCTION(MD4Update); \ + COMMON_INTERCEPT_FUNCTION(MD4Final); \ + COMMON_INTERCEPT_FUNCTION(MD4End); \ + COMMON_INTERCEPT_FUNCTION(MD4File); \ + COMMON_INTERCEPT_FUNCTION(MD4Data) +#else +#define INIT_MD4 +#endif + +#if SANITIZER_INTERCEPT_RMD160 +INTERCEPTOR(void, RMD160Init, void *context) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, RMD160Init, context); + REAL(RMD160Init)(context); + if (context) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz); +} +INTERCEPTOR(void, RMD160Update, void *context, const u8 *data, unsigned len) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, RMD160Update, context, data, len); + if (data && len > 0) + COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); + if (context) + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz); + REAL(RMD160Update)(context, data, len); + if (context) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, RMD160_CTX_sz); +} +INTERCEPTOR(void, RMD160Final, u8 digest[20], void *context) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, RMD160Final, digest, context); + if (context) + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz); + REAL(RMD160Final)(digest, context); + if (digest) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(u8) * 20); +} +INTERCEPTOR(void, RMD160Transform, u32 state[5], u16 buffer[16]) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, RMD160Transform, state, buffer); + if (state) + COMMON_INTERCEPTOR_READ_RANGE(ctx, state, sizeof(u32) * 5); + if (buffer) + COMMON_INTERCEPTOR_READ_RANGE(ctx, buffer, sizeof(u32) * 16); + REAL(RMD160Transform)(state, buffer); + if (state) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, state, sizeof(u32) * 5); +} +INTERCEPTOR(char *, RMD160End, void *context, char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, RMD160End, context, buf); + if (context) + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, RMD160_CTX_sz); + char *ret = REAL(RMD160End)(context, buf); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length); + return ret; +} +INTERCEPTOR(char *, RMD160File, char *filename, char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, RMD160File, filename, buf); + if (filename) + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); + char *ret = REAL(RMD160File)(filename, buf); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length); + return ret; +} +INTERCEPTOR(char *, RMD160FileChunk, char *filename, char *buf, OFF_T offset, + OFF_T length) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, RMD160FileChunk, filename, buf, offset, length); + if (filename) + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); + char *ret = REAL(RMD160FileChunk)(filename, buf, offset, length); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length); + return ret; +} +INTERCEPTOR(char *, RMD160Data, u8 *data, SIZE_T len, char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, RMD160Data, data, len, buf); + if (data && len > 0) + COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); + char *ret = REAL(RMD160Data)(data, len, buf); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, RMD160_return_length); + return ret; +} +#define INIT_RMD160 \ + COMMON_INTERCEPT_FUNCTION(RMD160Init); \ + COMMON_INTERCEPT_FUNCTION(RMD160Update); \ + COMMON_INTERCEPT_FUNCTION(RMD160Final); \ + COMMON_INTERCEPT_FUNCTION(RMD160Transform); \ + COMMON_INTERCEPT_FUNCTION(RMD160End); \ + COMMON_INTERCEPT_FUNCTION(RMD160File); \ + COMMON_INTERCEPT_FUNCTION(RMD160FileChunk); \ + COMMON_INTERCEPT_FUNCTION(RMD160Data) +#else +#define INIT_RMD160 +#endif + +#if SANITIZER_INTERCEPT_MD5 +INTERCEPTOR(void, MD5Init, void *context) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD5Init, context); + REAL(MD5Init)(context); + if (context) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD5_CTX_sz); +} + +INTERCEPTOR(void, MD5Update, void *context, const unsigned char *data, + unsigned int len) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD5Update, context, data, len); + if (data && len > 0) + COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); + if (context) + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz); + REAL(MD5Update)(context, data, len); + if (context) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD5_CTX_sz); +} + +INTERCEPTOR(void, MD5Final, unsigned char digest[16], void *context) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD5Final, digest, context); + if (context) + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz); + REAL(MD5Final)(digest, context); + if (digest) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16); +} + +INTERCEPTOR(char *, MD5End, void *context, char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD5End, context, buf); + if (context) + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD5_CTX_sz); + char *ret = REAL(MD5End)(context, buf); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length); + return ret; +} + +INTERCEPTOR(char *, MD5File, const char *filename, char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD5File, filename, buf); + if (filename) + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); + char *ret = REAL(MD5File)(filename, buf); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length); + return ret; +} + +INTERCEPTOR(char *, MD5Data, const unsigned char *data, unsigned int len, + char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD5Data, data, len, buf); + if (data && len > 0) + COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); + char *ret = REAL(MD5Data)(data, len, buf); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD5_return_length); + return ret; +} + +#define INIT_MD5 \ + COMMON_INTERCEPT_FUNCTION(MD5Init); \ + COMMON_INTERCEPT_FUNCTION(MD5Update); \ + COMMON_INTERCEPT_FUNCTION(MD5Final); \ + COMMON_INTERCEPT_FUNCTION(MD5End); \ + COMMON_INTERCEPT_FUNCTION(MD5File); \ + COMMON_INTERCEPT_FUNCTION(MD5Data) +#else +#define INIT_MD5 +#endif + +#if SANITIZER_INTERCEPT_FSEEK +INTERCEPTOR(int, fseek, __sanitizer_FILE *stream, long int offset, int whence) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, fseek, stream, offset, whence); + return REAL(fseek)(stream, offset, whence); +} +INTERCEPTOR(int, fseeko, __sanitizer_FILE *stream, OFF_T offset, int whence) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, fseeko, stream, offset, whence); + return REAL(fseeko)(stream, offset, whence); +} +INTERCEPTOR(long int, ftell, __sanitizer_FILE *stream) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, ftell, stream); + return REAL(ftell)(stream); +} +INTERCEPTOR(OFF_T, ftello, __sanitizer_FILE *stream) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, ftello, stream); + return REAL(ftello)(stream); +} +INTERCEPTOR(void, rewind, __sanitizer_FILE *stream) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, rewind, stream); + return REAL(rewind)(stream); +} +INTERCEPTOR(int, fgetpos, __sanitizer_FILE *stream, void *pos) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, fgetpos, stream, pos); + int ret = REAL(fgetpos)(stream, pos); + if (pos && !ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, pos, fpos_t_sz); + return ret; +} +INTERCEPTOR(int, fsetpos, __sanitizer_FILE *stream, const void *pos) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, fsetpos, stream, pos); + if (pos) + COMMON_INTERCEPTOR_READ_RANGE(ctx, pos, fpos_t_sz); + return REAL(fsetpos)(stream, pos); +} +#define INIT_FSEEK \ + COMMON_INTERCEPT_FUNCTION(fseek); \ + COMMON_INTERCEPT_FUNCTION(fseeko); \ + COMMON_INTERCEPT_FUNCTION(ftell); \ + COMMON_INTERCEPT_FUNCTION(ftello); \ + COMMON_INTERCEPT_FUNCTION(rewind); \ + COMMON_INTERCEPT_FUNCTION(fgetpos); \ + COMMON_INTERCEPT_FUNCTION(fsetpos) +#else +#define INIT_FSEEK +#endif + +#if SANITIZER_INTERCEPT_MD2 +INTERCEPTOR(void, MD2Init, void *context) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD2Init, context); + REAL(MD2Init)(context); + if (context) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz); +} + +INTERCEPTOR(void, MD2Update, void *context, const unsigned char *data, + unsigned int len) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD2Update, context, data, len); + if (data && len > 0) + COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); + if (context) + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz); + REAL(MD2Update)(context, data, len); + if (context) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, MD2_CTX_sz); +} + +INTERCEPTOR(void, MD2Final, unsigned char digest[16], void *context) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD2Final, digest, context); + if (context) + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz); + REAL(MD2Final)(digest, context); + if (digest) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, sizeof(unsigned char) * 16); +} + +INTERCEPTOR(char *, MD2End, void *context, char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD2End, context, buf); + if (context) + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, MD2_CTX_sz); + char *ret = REAL(MD2End)(context, buf); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length); + return ret; +} + +INTERCEPTOR(char *, MD2File, const char *filename, char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD2File, filename, buf); + if (filename) + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1); + char *ret = REAL(MD2File)(filename, buf); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length); + return ret; +} + +INTERCEPTOR(char *, MD2Data, const unsigned char *data, unsigned int len, + char *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, MD2Data, data, len, buf); + if (data && len > 0) + COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); + char *ret = REAL(MD2Data)(data, len, buf); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, MD2_return_length); + return ret; +} + +#define INIT_MD2 \ + COMMON_INTERCEPT_FUNCTION(MD2Init); \ + COMMON_INTERCEPT_FUNCTION(MD2Update); \ + COMMON_INTERCEPT_FUNCTION(MD2Final); \ + COMMON_INTERCEPT_FUNCTION(MD2End); \ + COMMON_INTERCEPT_FUNCTION(MD2File); \ + COMMON_INTERCEPT_FUNCTION(MD2Data) +#else +#define INIT_MD2 +#endif + +#if SANITIZER_INTERCEPT_SHA2 +#define SHA2_INTERCEPTORS(LEN, SHA2_STATE_T) \ + INTERCEPTOR(void, SHA##LEN##_Init, void *context) { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Init, context); \ + REAL(SHA##LEN##_Init)(context); \ + if (context) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ + } \ + INTERCEPTOR(void, SHA##LEN##_Update, void *context, \ + const u8 *data, SIZE_T len) { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Update, context, data, len); \ + if (data && len > 0) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \ + if (context) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ + REAL(SHA##LEN##_Update)(context, data, len); \ + if (context) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ + } \ + INTERCEPTOR(void, SHA##LEN##_Final, u8 digest[LEN/8], \ + void *context) { \ + void *ctx; \ + CHECK_EQ(SHA##LEN##_digest_length, LEN/8); \ + COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Final, digest, context); \ + if (context) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ + REAL(SHA##LEN##_Final)(digest, context); \ + if (digest) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, digest, \ + sizeof(digest[0]) * \ + SHA##LEN##_digest_length); \ + } \ + INTERCEPTOR(char *, SHA##LEN##_End, void *context, char *buf) { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_End, context, buf); \ + if (context) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, context, SHA##LEN##_CTX_sz); \ + char *ret = REAL(SHA##LEN##_End)(context, buf); \ + if (ret) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ + return ret; \ + } \ + INTERCEPTOR(char *, SHA##LEN##_File, const char *filename, char *buf) { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_File, filename, buf); \ + if (filename) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);\ + char *ret = REAL(SHA##LEN##_File)(filename, buf); \ + if (ret) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ + return ret; \ + } \ + INTERCEPTOR(char *, SHA##LEN##_FileChunk, const char *filename, char *buf, \ + OFF_T offset, OFF_T length) { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_FileChunk, filename, buf, offset, \ + length); \ + if (filename) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, filename, REAL(strlen)(filename) + 1);\ + char *ret = REAL(SHA##LEN##_FileChunk)(filename, buf, offset, length); \ + if (ret) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ + return ret; \ + } \ + INTERCEPTOR(char *, SHA##LEN##_Data, u8 *data, SIZE_T len, char *buf) { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, SHA##LEN##_Data, data, len, buf); \ + if (data && len > 0) \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, data, len); \ + char *ret = REAL(SHA##LEN##_Data)(data, len, buf); \ + if (ret) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, SHA##LEN##_return_length); \ + return ret; \ + } + +SHA2_INTERCEPTORS(224, u32); +SHA2_INTERCEPTORS(256, u32); +SHA2_INTERCEPTORS(384, u64); +SHA2_INTERCEPTORS(512, u64); + +#define INIT_SHA2_INTECEPTORS(LEN) \ + COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Init); \ + COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Update); \ + COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Final); \ + COMMON_INTERCEPT_FUNCTION(SHA##LEN##_End); \ + COMMON_INTERCEPT_FUNCTION(SHA##LEN##_File); \ + COMMON_INTERCEPT_FUNCTION(SHA##LEN##_FileChunk); \ + COMMON_INTERCEPT_FUNCTION(SHA##LEN##_Data) + +#define INIT_SHA2 \ + INIT_SHA2_INTECEPTORS(224); \ + INIT_SHA2_INTECEPTORS(256); \ + INIT_SHA2_INTECEPTORS(384); \ + INIT_SHA2_INTECEPTORS(512) +#undef SHA2_INTERCEPTORS +#else +#define INIT_SHA2 +#endif + +#if SANITIZER_INTERCEPT_VIS +INTERCEPTOR(char *, vis, char *dst, int c, int flag, int nextc) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, vis, dst, c, flag, nextc); + char *end = REAL(vis)(dst, c, flag, nextc); + // dst is NULL terminated and end points to the NULL char + if (dst && end) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1); + return end; +} +INTERCEPTOR(char *, nvis, char *dst, SIZE_T dlen, int c, int flag, int nextc) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, nvis, dst, dlen, c, flag, nextc); + char *end = REAL(nvis)(dst, dlen, c, flag, nextc); + // nvis cannot make sure the dst is NULL terminated + if (dst && end) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1); + return end; +} +INTERCEPTOR(int, strvis, char *dst, const char *src, int flag) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strvis, dst, src, flag); + if (src) + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + int len = REAL(strvis)(dst, src, flag); + if (dst) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1); + return len; +} +INTERCEPTOR(int, stravis, char **dst, const char *src, int flag) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, stravis, dst, src, flag); + if (src) + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + int len = REAL(stravis)(dst, src, flag); + if (dst) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, sizeof(char *)); + if (*dst) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *dst, len + 1); + } + return len; +} +INTERCEPTOR(int, strnvis, char *dst, SIZE_T dlen, const char *src, int flag) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strnvis, dst, dlen, src, flag); + if (src) + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + int len = REAL(strnvis)(dst, dlen, src, flag); + // The interface will be valid even if there is no space for NULL char + if (dst && len > 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1); + return len; +} +INTERCEPTOR(int, strvisx, char *dst, const char *src, SIZE_T len, int flag) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strvisx, dst, src, len, flag); + if (src) + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); + int ret = REAL(strvisx)(dst, src, len, flag); + if (dst) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); + return ret; +} +INTERCEPTOR(int, strnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len, + int flag) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strnvisx, dst, dlen, src, len, flag); + if (src) + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); + int ret = REAL(strnvisx)(dst, dlen, src, len, flag); + if (dst && ret >= 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); + return ret; +} +INTERCEPTOR(int, strenvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len, + int flag, int *cerr_ptr) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strenvisx, dst, dlen, src, len, flag, cerr_ptr); + if (src) + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); + // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold + // according to the implementation + if (cerr_ptr) + COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int)); + int ret = REAL(strenvisx)(dst, dlen, src, len, flag, cerr_ptr); + if (dst && ret >= 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); + if (cerr_ptr) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int)); + return ret; +} +INTERCEPTOR(char *, svis, char *dst, int c, int flag, int nextc, + const char *extra) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, svis, dst, c, flag, nextc, extra); + if (extra) + COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); + char *end = REAL(svis)(dst, c, flag, nextc, extra); + if (dst && end) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, end - dst + 1); + return end; +} +INTERCEPTOR(char *, snvis, char *dst, SIZE_T dlen, int c, int flag, int nextc, + const char *extra) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, snvis, dst, dlen, c, flag, nextc, extra); + if (extra) + COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); + char *end = REAL(snvis)(dst, dlen, c, flag, nextc, extra); + if (dst && end) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, + Min((SIZE_T)(end - dst + 1), dlen)); + return end; +} +INTERCEPTOR(int, strsvis, char *dst, const char *src, int flag, + const char *extra) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strsvis, dst, src, flag, extra); + if (src) + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + if (extra) + COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); + int len = REAL(strsvis)(dst, src, flag, extra); + if (dst) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1); + return len; +} +INTERCEPTOR(int, strsnvis, char *dst, SIZE_T dlen, const char *src, int flag, + const char *extra) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strsnvis, dst, dlen, src, flag, extra); + if (src) + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + if (extra) + COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); + int len = REAL(strsnvis)(dst, dlen, src, flag, extra); + // The interface will be valid even if there is no space for NULL char + if (dst && len >= 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, len + 1); + return len; +} +INTERCEPTOR(int, strsvisx, char *dst, const char *src, SIZE_T len, int flag, + const char *extra) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strsvisx, dst, src, len, flag, extra); + if (src) + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); + if (extra) + COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); + int ret = REAL(strsvisx)(dst, src, len, flag, extra); + if (dst) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); + return ret; +} +INTERCEPTOR(int, strsnvisx, char *dst, SIZE_T dlen, const char *src, SIZE_T len, + int flag, const char *extra) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strsnvisx, dst, dlen, src, len, flag, extra); + if (src) + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); + if (extra) + COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); + int ret = REAL(strsnvisx)(dst, dlen, src, len, flag, extra); + if (dst && ret >= 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); + return ret; +} +INTERCEPTOR(int, strsenvisx, char *dst, SIZE_T dlen, const char *src, + SIZE_T len, int flag, const char *extra, int *cerr_ptr) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strsenvisx, dst, dlen, src, len, flag, extra, + cerr_ptr); + if (src) + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, len); + if (extra) + COMMON_INTERCEPTOR_READ_RANGE(ctx, extra, REAL(strlen)(extra) + 1); + // FIXME: only need to be checked when "flag | VIS_NOLOCALE" doesn't hold + // according to the implementation + if (cerr_ptr) + COMMON_INTERCEPTOR_READ_RANGE(ctx, cerr_ptr, sizeof(int)); + int ret = REAL(strsenvisx)(dst, dlen, src, len, flag, extra, cerr_ptr); + if (dst && ret >= 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); + if (cerr_ptr) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cerr_ptr, sizeof(int)); + return ret; +} +INTERCEPTOR(int, unvis, char *cp, int c, int *astate, int flag) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, unvis, cp, c, astate, flag); + if (astate) + COMMON_INTERCEPTOR_READ_RANGE(ctx, astate, sizeof(*astate)); + int ret = REAL(unvis)(cp, c, astate, flag); + if (ret == unvis_valid || ret == unvis_validpush) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cp, sizeof(*cp)); + } + return ret; +} +INTERCEPTOR(int, strunvis, char *dst, const char *src) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strunvis, dst, src); + if (src) + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + int ret = REAL(strunvis)(dst, src); + if (ret != -1) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); + return ret; +} +INTERCEPTOR(int, strnunvis, char *dst, SIZE_T dlen, const char *src) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strnunvis, dst, dlen, src); + if (src) + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + int ret = REAL(strnunvis)(dst, dlen, src); + if (ret != -1) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); + return ret; +} +INTERCEPTOR(int, strunvisx, char *dst, const char *src, int flag) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strunvisx, dst, src, flag); + if (src) + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + int ret = REAL(strunvisx)(dst, src, flag); + if (ret != -1) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); + return ret; +} +INTERCEPTOR(int, strnunvisx, char *dst, SIZE_T dlen, const char *src, + int flag) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strnunvisx, dst, dlen, src, flag); + if (src) + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, REAL(strlen)(src) + 1); + int ret = REAL(strnunvisx)(dst, dlen, src, flag); + if (ret != -1) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dst, ret + 1); + return ret; +} +#define INIT_VIS \ + COMMON_INTERCEPT_FUNCTION(vis); \ + COMMON_INTERCEPT_FUNCTION(nvis); \ + COMMON_INTERCEPT_FUNCTION(strvis); \ + COMMON_INTERCEPT_FUNCTION(stravis); \ + COMMON_INTERCEPT_FUNCTION(strnvis); \ + COMMON_INTERCEPT_FUNCTION(strvisx); \ + COMMON_INTERCEPT_FUNCTION(strnvisx); \ + COMMON_INTERCEPT_FUNCTION(strenvisx); \ + COMMON_INTERCEPT_FUNCTION(svis); \ + COMMON_INTERCEPT_FUNCTION(snvis); \ + COMMON_INTERCEPT_FUNCTION(strsvis); \ + COMMON_INTERCEPT_FUNCTION(strsnvis); \ + COMMON_INTERCEPT_FUNCTION(strsvisx); \ + COMMON_INTERCEPT_FUNCTION(strsnvisx); \ + COMMON_INTERCEPT_FUNCTION(strsenvisx); \ + COMMON_INTERCEPT_FUNCTION(unvis); \ + COMMON_INTERCEPT_FUNCTION(strunvis); \ + COMMON_INTERCEPT_FUNCTION(strnunvis); \ + COMMON_INTERCEPT_FUNCTION(strunvisx); \ + COMMON_INTERCEPT_FUNCTION(strnunvisx) +#else +#define INIT_VIS +#endif + +#if SANITIZER_INTERCEPT_CDB +INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open, const char *path, int flags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open, path, flags); + if (path) + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + struct __sanitizer_cdbr *cdbr = REAL(cdbr_open)(path, flags); + if (cdbr) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr)); + return cdbr; +} + +INTERCEPTOR(struct __sanitizer_cdbr *, cdbr_open_mem, void *base, SIZE_T size, + int flags, void (*unmap)(void *, void *, SIZE_T), void *cookie) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cdbr_open_mem, base, size, flags, unmap, + cookie); + if (base && size) + COMMON_INTERCEPTOR_READ_RANGE(ctx, base, size); + struct __sanitizer_cdbr *cdbr = + REAL(cdbr_open_mem)(base, size, flags, unmap, cookie); + if (cdbr) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbr, sizeof(*cdbr)); + return cdbr; +} + +INTERCEPTOR(u32, cdbr_entries, struct __sanitizer_cdbr *cdbr) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cdbr_entries, cdbr); + if (cdbr) + COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr)); + return REAL(cdbr_entries)(cdbr); +} + +INTERCEPTOR(int, cdbr_get, struct __sanitizer_cdbr *cdbr, u32 index, + const void **data, SIZE_T *datalen) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cdbr_get, cdbr, index, data, datalen); + if (cdbr) + COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr)); + int ret = REAL(cdbr_get)(cdbr, index, data, datalen); + if (!ret) { + if (data) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data)); + if (datalen) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen)); + if (data && datalen) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen); + } + return ret; +} + +INTERCEPTOR(int, cdbr_find, struct __sanitizer_cdbr *cdbr, const void *key, + SIZE_T keylen, const void **data, SIZE_T *datalen) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cdbr_find, cdbr, key, keylen, data, datalen); + if (cdbr) + COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr)); + if (key) + COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen); + int ret = REAL(cdbr_find)(cdbr, key, keylen, data, datalen); + if (!ret) { + if (data) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, data, sizeof(*data)); + if (datalen) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, datalen, sizeof(*datalen)); + if (data && datalen) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *data, *datalen); + } + return ret; +} + +INTERCEPTOR(void, cdbr_close, struct __sanitizer_cdbr *cdbr) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cdbr_close, cdbr); + if (cdbr) + COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbr, sizeof(*cdbr)); + REAL(cdbr_close)(cdbr); +} + +INTERCEPTOR(struct __sanitizer_cdbw *, cdbw_open) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cdbw_open); + struct __sanitizer_cdbw *ret = REAL(cdbw_open)(); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, sizeof(*ret)); + return ret; +} + +INTERCEPTOR(int, cdbw_put, struct __sanitizer_cdbw *cdbw, const void *key, + SIZE_T keylen, const void *data, SIZE_T datalen) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put, cdbw, key, keylen, data, datalen); + if (cdbw) + COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw)); + if (data && datalen) + COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen); + if (key && keylen) + COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen); + int ret = REAL(cdbw_put)(cdbw, key, keylen, data, datalen); + if (!ret && cdbw) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw)); + return ret; +} + +INTERCEPTOR(int, cdbw_put_data, struct __sanitizer_cdbw *cdbw, const void *data, + SIZE_T datalen, u32 *index) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_data, cdbw, data, datalen, index); + if (cdbw) + COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw)); + if (data && datalen) + COMMON_INTERCEPTOR_READ_RANGE(ctx, data, datalen); + int ret = REAL(cdbw_put_data)(cdbw, data, datalen, index); + if (!ret) { + if (index) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, index, sizeof(*index)); + if (cdbw) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw)); + } + return ret; +} + +INTERCEPTOR(int, cdbw_put_key, struct __sanitizer_cdbw *cdbw, const void *key, + SIZE_T keylen, u32 index) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cdbw_put_key, cdbw, key, keylen, index); + if (cdbw) + COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw)); + if (key && keylen) + COMMON_INTERCEPTOR_READ_RANGE(ctx, key, keylen); + int ret = REAL(cdbw_put_key)(cdbw, key, keylen, index); + if (!ret && cdbw) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw)); + return ret; +} + +INTERCEPTOR(int, cdbw_output, struct __sanitizer_cdbw *cdbw, int output, + const char descr[16], u32 (*seedgen)(void)) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cdbw_output, cdbw, output, descr, seedgen); + COMMON_INTERCEPTOR_FD_ACCESS(ctx, output); + if (cdbw) + COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw)); + if (descr) + COMMON_INTERCEPTOR_READ_RANGE(ctx, descr, internal_strnlen(descr, 16)); + if (seedgen) + COMMON_INTERCEPTOR_READ_RANGE(ctx, (void *)seedgen, sizeof(seedgen)); + int ret = REAL(cdbw_output)(cdbw, output, descr, seedgen); + if (!ret) { + if (cdbw) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, cdbw, sizeof(*cdbw)); + if (output >= 0) + COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, output); + } + return ret; +} + +INTERCEPTOR(void, cdbw_close, struct __sanitizer_cdbw *cdbw) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, cdbw_close, cdbw); + if (cdbw) + COMMON_INTERCEPTOR_READ_RANGE(ctx, cdbw, sizeof(*cdbw)); + REAL(cdbw_close)(cdbw); +} + +#define INIT_CDB \ + COMMON_INTERCEPT_FUNCTION(cdbr_open); \ + COMMON_INTERCEPT_FUNCTION(cdbr_open_mem); \ + COMMON_INTERCEPT_FUNCTION(cdbr_entries); \ + COMMON_INTERCEPT_FUNCTION(cdbr_get); \ + COMMON_INTERCEPT_FUNCTION(cdbr_find); \ + COMMON_INTERCEPT_FUNCTION(cdbr_close); \ + COMMON_INTERCEPT_FUNCTION(cdbw_open); \ + COMMON_INTERCEPT_FUNCTION(cdbw_put); \ + COMMON_INTERCEPT_FUNCTION(cdbw_put_data); \ + COMMON_INTERCEPT_FUNCTION(cdbw_put_key); \ + COMMON_INTERCEPT_FUNCTION(cdbw_output); \ + COMMON_INTERCEPT_FUNCTION(cdbw_close) +#else +#define INIT_CDB +#endif + +#if SANITIZER_INTERCEPT_GETFSENT +INTERCEPTOR(void *, getfsent) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getfsent); + void *ret = REAL(getfsent)(); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz); + return ret; +} + +INTERCEPTOR(void *, getfsspec, const char *spec) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getfsspec, spec); + if (spec) + COMMON_INTERCEPTOR_READ_RANGE(ctx, spec, REAL(strlen)(spec) + 1); + void *ret = REAL(getfsspec)(spec); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz); + return ret; +} + +INTERCEPTOR(void *, getfsfile, const char *file) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getfsfile, file); + if (file) + COMMON_INTERCEPTOR_READ_RANGE(ctx, file, REAL(strlen)(file) + 1); + void *ret = REAL(getfsfile)(file); + if (ret) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ret, struct_fstab_sz); + return ret; +} + +#define INIT_GETFSENT \ + COMMON_INTERCEPT_FUNCTION(getfsent); \ + COMMON_INTERCEPT_FUNCTION(getfsspec); \ + COMMON_INTERCEPT_FUNCTION(getfsfile); +#else +#define INIT_GETFSENT +#endif + +#if SANITIZER_INTERCEPT_ARC4RANDOM +INTERCEPTOR(void, arc4random_buf, void *buf, SIZE_T len) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, arc4random_buf, buf, len); + REAL(arc4random_buf)(buf, len); + if (buf && len) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, len); +} + +INTERCEPTOR(void, arc4random_addrandom, u8 *dat, int datlen) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, arc4random_addrandom, dat, datlen); + if (dat && datlen) + COMMON_INTERCEPTOR_READ_RANGE(ctx, dat, datlen); + REAL(arc4random_addrandom)(dat, datlen); +} + +#define INIT_ARC4RANDOM \ + COMMON_INTERCEPT_FUNCTION(arc4random_buf); \ + COMMON_INTERCEPT_FUNCTION(arc4random_addrandom); +#else +#define INIT_ARC4RANDOM +#endif + +#if SANITIZER_INTERCEPT_POPEN +INTERCEPTOR(__sanitizer_FILE *, popen, const char *command, const char *type) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, popen, command, type); + if (command) + COMMON_INTERCEPTOR_READ_RANGE(ctx, command, REAL(strlen)(command) + 1); + if (type) + COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1); + __sanitizer_FILE *res = REAL(popen)(command, type); + COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr); + if (res) unpoison_file(res); + return res; +} +#define INIT_POPEN COMMON_INTERCEPT_FUNCTION(popen) +#else +#define INIT_POPEN +#endif + +#if SANITIZER_INTERCEPT_POPENVE +INTERCEPTOR(__sanitizer_FILE *, popenve, const char *path, + char *const *argv, char *const *envp, const char *type) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, popenve, path, argv, envp, type); + if (path) + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + if (argv) { + for (char *const *pa = argv; ; ++pa) { + COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **)); + if (!*pa) + break; + COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1); + } + } + if (envp) { + for (char *const *pa = envp; ; ++pa) { + COMMON_INTERCEPTOR_READ_RANGE(ctx, pa, sizeof(char **)); + if (!*pa) + break; + COMMON_INTERCEPTOR_READ_RANGE(ctx, *pa, REAL(strlen)(*pa) + 1); + } + } + if (type) + COMMON_INTERCEPTOR_READ_RANGE(ctx, type, REAL(strlen)(type) + 1); + __sanitizer_FILE *res = REAL(popenve)(path, argv, envp, type); + COMMON_INTERCEPTOR_FILE_OPEN(ctx, res, nullptr); + if (res) unpoison_file(res); + return res; +} +#define INIT_POPENVE COMMON_INTERCEPT_FUNCTION(popenve) +#else +#define INIT_POPENVE +#endif + +#if SANITIZER_INTERCEPT_PCLOSE +INTERCEPTOR(int, pclose, __sanitizer_FILE *fp) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, pclose, fp); + COMMON_INTERCEPTOR_FILE_CLOSE(ctx, fp); + const FileMetadata *m = GetInterceptorMetadata(fp); + int res = REAL(pclose)(fp); + if (m) { + COMMON_INTERCEPTOR_INITIALIZE_RANGE(*m->addr, *m->size); + DeleteInterceptorMetadata(fp); + } + return res; +} +#define INIT_PCLOSE COMMON_INTERCEPT_FUNCTION(pclose); +#else +#define INIT_PCLOSE +#endif + +#if SANITIZER_INTERCEPT_FUNOPEN +typedef int (*funopen_readfn)(void *cookie, char *buf, int len); +typedef int (*funopen_writefn)(void *cookie, const char *buf, int len); +typedef OFF_T (*funopen_seekfn)(void *cookie, OFF_T offset, int whence); +typedef int (*funopen_closefn)(void *cookie); + +struct WrappedFunopenCookie { + void *real_cookie; + funopen_readfn real_read; + funopen_writefn real_write; + funopen_seekfn real_seek; + funopen_closefn real_close; +}; + +static int wrapped_funopen_read(void *cookie, char *buf, int len) { + COMMON_INTERCEPTOR_UNPOISON_PARAM(3); + WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie; + funopen_readfn real_read = wrapped_cookie->real_read; + return real_read(wrapped_cookie->real_cookie, buf, len); +} + +static int wrapped_funopen_write(void *cookie, const char *buf, int len) { + COMMON_INTERCEPTOR_UNPOISON_PARAM(3); + WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie; + funopen_writefn real_write = wrapped_cookie->real_write; + return real_write(wrapped_cookie->real_cookie, buf, len); +} + +static OFF_T wrapped_funopen_seek(void *cookie, OFF_T offset, int whence) { + COMMON_INTERCEPTOR_UNPOISON_PARAM(3); + WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie; + funopen_seekfn real_seek = wrapped_cookie->real_seek; + return real_seek(wrapped_cookie->real_cookie, offset, whence); +} + +static int wrapped_funopen_close(void *cookie) { + COMMON_INTERCEPTOR_UNPOISON_PARAM(1); + WrappedFunopenCookie *wrapped_cookie = (WrappedFunopenCookie *)cookie; + funopen_closefn real_close = wrapped_cookie->real_close; + int res = real_close(wrapped_cookie->real_cookie); + InternalFree(wrapped_cookie); + return res; +} + +INTERCEPTOR(__sanitizer_FILE *, funopen, void *cookie, funopen_readfn readfn, + funopen_writefn writefn, funopen_seekfn seekfn, + funopen_closefn closefn) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, funopen, cookie, readfn, writefn, seekfn, + closefn); + + WrappedFunopenCookie *wrapped_cookie = + (WrappedFunopenCookie *)InternalAlloc(sizeof(WrappedFunopenCookie)); + wrapped_cookie->real_cookie = cookie; + wrapped_cookie->real_read = readfn; + wrapped_cookie->real_write = writefn; + wrapped_cookie->real_seek = seekfn; + wrapped_cookie->real_close = closefn; + + __sanitizer_FILE *res = + REAL(funopen)(wrapped_cookie, + readfn ? wrapped_funopen_read : nullptr, + writefn ? wrapped_funopen_write : nullptr, + seekfn ? wrapped_funopen_seek : nullptr, + closefn ? wrapped_funopen_close : nullptr); + if (res) + unpoison_file(res); + return res; +} +#define INIT_FUNOPEN COMMON_INTERCEPT_FUNCTION(funopen) +#else +#define INIT_FUNOPEN +#endif + +#if SANITIZER_INTERCEPT_FUNOPEN2 +typedef SSIZE_T (*funopen2_readfn)(void *cookie, void *buf, SIZE_T len); +typedef SSIZE_T (*funopen2_writefn)(void *cookie, const void *buf, SIZE_T len); +typedef OFF_T (*funopen2_seekfn)(void *cookie, OFF_T offset, int whence); +typedef int (*funopen2_flushfn)(void *cookie); +typedef int (*funopen2_closefn)(void *cookie); + +struct WrappedFunopen2Cookie { + void *real_cookie; + funopen2_readfn real_read; + funopen2_writefn real_write; + funopen2_seekfn real_seek; + funopen2_flushfn real_flush; + funopen2_closefn real_close; +}; + +static SSIZE_T wrapped_funopen2_read(void *cookie, void *buf, SIZE_T len) { + COMMON_INTERCEPTOR_UNPOISON_PARAM(3); + WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie; + funopen2_readfn real_read = wrapped_cookie->real_read; + return real_read(wrapped_cookie->real_cookie, buf, len); +} + +static SSIZE_T wrapped_funopen2_write(void *cookie, const void *buf, + SIZE_T len) { + COMMON_INTERCEPTOR_UNPOISON_PARAM(3); + WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie; + funopen2_writefn real_write = wrapped_cookie->real_write; + return real_write(wrapped_cookie->real_cookie, buf, len); +} + +static OFF_T wrapped_funopen2_seek(void *cookie, OFF_T offset, int whence) { + COMMON_INTERCEPTOR_UNPOISON_PARAM(3); + WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie; + funopen2_seekfn real_seek = wrapped_cookie->real_seek; + return real_seek(wrapped_cookie->real_cookie, offset, whence); +} + +static int wrapped_funopen2_flush(void *cookie) { + COMMON_INTERCEPTOR_UNPOISON_PARAM(1); + WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie; + funopen2_flushfn real_flush = wrapped_cookie->real_flush; + return real_flush(wrapped_cookie->real_cookie); +} + +static int wrapped_funopen2_close(void *cookie) { + COMMON_INTERCEPTOR_UNPOISON_PARAM(1); + WrappedFunopen2Cookie *wrapped_cookie = (WrappedFunopen2Cookie *)cookie; + funopen2_closefn real_close = wrapped_cookie->real_close; + int res = real_close(wrapped_cookie->real_cookie); + InternalFree(wrapped_cookie); + return res; +} + +INTERCEPTOR(__sanitizer_FILE *, funopen2, void *cookie, funopen2_readfn readfn, + funopen2_writefn writefn, funopen2_seekfn seekfn, + funopen2_flushfn flushfn, funopen2_closefn closefn) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, funopen2, cookie, readfn, writefn, seekfn, + flushfn, closefn); + + WrappedFunopen2Cookie *wrapped_cookie = + (WrappedFunopen2Cookie *)InternalAlloc(sizeof(WrappedFunopen2Cookie)); + wrapped_cookie->real_cookie = cookie; + wrapped_cookie->real_read = readfn; + wrapped_cookie->real_write = writefn; + wrapped_cookie->real_seek = seekfn; + wrapped_cookie->real_flush = flushfn; + wrapped_cookie->real_close = closefn; + + __sanitizer_FILE *res = + REAL(funopen2)(wrapped_cookie, + readfn ? wrapped_funopen2_read : nullptr, + writefn ? wrapped_funopen2_write : nullptr, + seekfn ? wrapped_funopen2_seek : nullptr, + flushfn ? wrapped_funopen2_flush : nullptr, + closefn ? wrapped_funopen2_close : nullptr); + if (res) + unpoison_file(res); + return res; +} +#define INIT_FUNOPEN2 COMMON_INTERCEPT_FUNCTION(funopen2) +#else +#define INIT_FUNOPEN2 +#endif + +#if SANITIZER_INTERCEPT_FDEVNAME +INTERCEPTOR(char *, fdevname, int fd) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, fdevname, fd); + COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); + char *name = REAL(fdevname)(fd); + if (name) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1); + if (fd > 0) + COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); + } + return name; +} + +INTERCEPTOR(char *, fdevname_r, int fd, char *buf, SIZE_T len) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, fdevname_r, fd, buf, len); + COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); + char *name = REAL(fdevname_r)(fd, buf, len); + if (name && buf && len > 0) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, REAL(strlen)(buf) + 1); + if (fd > 0) + COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); + } + return name; +} + +#define INIT_FDEVNAME \ + COMMON_INTERCEPT_FUNCTION(fdevname); \ + COMMON_INTERCEPT_FUNCTION(fdevname_r); +#else +#define INIT_FDEVNAME +#endif + +#if SANITIZER_INTERCEPT_GETUSERSHELL +INTERCEPTOR(char *, getusershell) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getusershell); + char *res = REAL(getusershell)(); + if (res) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + return res; +} + +#define INIT_GETUSERSHELL COMMON_INTERCEPT_FUNCTION(getusershell); +#else +#define INIT_GETUSERSHELL +#endif + +#if SANITIZER_INTERCEPT_SL_INIT +INTERCEPTOR(void *, sl_init) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, sl_init); + void *res = REAL(sl_init)(); + if (res) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, __sanitizer::struct_StringList_sz); + return res; +} + +INTERCEPTOR(int, sl_add, void *sl, char *item) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, sl_add, sl, item); + if (sl) + COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz); + if (item) + COMMON_INTERCEPTOR_READ_RANGE(ctx, item, REAL(strlen)(item) + 1); + int res = REAL(sl_add)(sl, item); + if (!res) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, sl, __sanitizer::struct_StringList_sz); + return res; +} + +INTERCEPTOR(char *, sl_find, void *sl, const char *item) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, sl_find, sl, item); + if (sl) + COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz); + if (item) + COMMON_INTERCEPTOR_READ_RANGE(ctx, item, REAL(strlen)(item) + 1); + char *res = REAL(sl_find)(sl, item); + if (res) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + return res; +} + +INTERCEPTOR(void, sl_free, void *sl, int freeall) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, sl_free, sl, freeall); + if (sl) + COMMON_INTERCEPTOR_READ_RANGE(ctx, sl, __sanitizer::struct_StringList_sz); + REAL(sl_free)(sl, freeall); +} + +#define INIT_SL_INIT \ + COMMON_INTERCEPT_FUNCTION(sl_init); \ + COMMON_INTERCEPT_FUNCTION(sl_add); \ + COMMON_INTERCEPT_FUNCTION(sl_find); \ + COMMON_INTERCEPT_FUNCTION(sl_free); +#else +#define INIT_SL_INIT +#endif + +#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 + +static void InitializeCommonInterceptors() { +#if SI_POSIX + static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; + interceptor_metadata_map = + new ((void *)&metadata_mem) MetadataHashMap(); // NOLINT +#endif INIT_MMAP; INIT_MMAP64; @@ -7263,6 +9598,7 @@ static void InitializeCommonInterceptors() { INIT_MEMCPY; INIT_MEMCHR; INIT_MEMCMP; + INIT_BCMP; INIT_MEMRCHR; INIT_MEMMEM; INIT_READ; @@ -7297,6 +9633,8 @@ static void InitializeCommonInterceptors() { INIT_GETPWENT; INIT_FGETPWENT; INIT_GETPWENT_R; + INIT_FGETPWENT_R; + INIT_FGETGRENT_R; INIT_SETPWENT; INIT_CLOCK_GETTIME; INIT_GETITIMER; @@ -7341,6 +9679,7 @@ static void InitializeCommonInterceptors() { INIT_WCSTOMBS; INIT_WCSNRTOMBS; INIT_WCRTOMB; + INIT_WCTOMB; INIT_TCGETATTR; INIT_REALPATH; INIT_CANONICALIZE_FILE_NAME; @@ -7362,6 +9701,7 @@ static void InitializeCommonInterceptors() { INIT_SIGSETOPS; INIT_SIGPENDING; INIT_SIGPROCMASK; + INIT_PTHREAD_SIGMASK; INIT_BACKTRACE; INIT__EXIT; INIT_PTHREAD_MUTEX_LOCK; @@ -7400,13 +9740,16 @@ static void InitializeCommonInterceptors() { INIT_PTHREAD_BARRIERATTR_GETPSHARED; INIT_TMPNAM; INIT_TMPNAM_R; + INIT_TTYNAME; INIT_TTYNAME_R; INIT_TEMPNAM; INIT_PTHREAD_SETNAME_NP; INIT_PTHREAD_GETNAME_NP; INIT_SINCOS; INIT_REMQUO; + INIT_REMQUOL; INIT_LGAMMA; + INIT_LGAMMAL; INIT_LGAMMA_R; INIT_LGAMMAL_R; INIT_DRAND48_R; @@ -7423,6 +9766,7 @@ static void InitializeCommonInterceptors() { INIT_CAPGET; INIT_AEABI_MEM; INIT___BZERO; + INIT_BZERO; INIT_FTIME; INIT_XDR; INIT_TSEARCH; @@ -7459,6 +9803,7 @@ static void InitializeCommonInterceptors() { INIT_GETLOADAVG; INIT_WCSLEN; INIT_WCSCAT; + INIT_WCSDUP; INIT_WCSXFRM; INIT___WCSXFRM_L; INIT_ACCT; @@ -7482,6 +9827,43 @@ static void InitializeCommonInterceptors() { INIT_TTYENT; INIT_PROTOENT; INIT_NETENT; + INIT_GETMNTINFO; + INIT_MI_VECTOR_HASH; + INIT_SETVBUF; + INIT_GETVFSSTAT; + INIT_REGEX; + INIT_REGEXSUB; + INIT_FTS; + INIT_SYSCTL; + INIT_ASYSCTL; + INIT_SYSCTLGETMIBINFO; + INIT_NL_LANGINFO; + INIT_MODCTL; + INIT_STRTONUM; + INIT_FPARSELN; + INIT_STATVFS1; + INIT_STRTOI; + INIT_CAPSICUM; + INIT_SHA1; + INIT_MD4; + INIT_RMD160; + INIT_MD5; + INIT_FSEEK; + INIT_MD2; + INIT_SHA2; + INIT_VIS; + INIT_CDB; + INIT_GETFSENT; + INIT_ARC4RANDOM; + INIT_POPEN; + INIT_POPENVE; + INIT_PCLOSE; + INIT_FUNOPEN; + INIT_FUNOPEN2; + INIT_FDEVNAME; + INIT_GETUSERSHELL; + INIT_SL_INIT; + INIT_GETRANDOM; INIT___PRINTF_CHK; } diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_format.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_format.inc index 30927d2a229..bbbedda8fbe 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_format.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_format.inc @@ -1,7 +1,8 @@ //===-- sanitizer_common_interceptors_format.inc ----------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_ioctl.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_ioctl.inc index 5408ea17c59..490a04b2181 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_ioctl.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_ioctl.inc @@ -1,7 +1,8 @@ //===-- sanitizer_common_interceptors_ioctl.inc -----------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S new file mode 100644 index 00000000000..20f42f1ea94 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_aarch64.inc.S @@ -0,0 +1,43 @@ +#if defined(__aarch64__) && defined(__linux__) + +#include "sanitizer_common/sanitizer_asm.h" + +ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA) + +.comm _ZN14__interception10real_vforkE,8,8 +.globl ASM_WRAPPER_NAME(vfork) +ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork)) +ASM_WRAPPER_NAME(vfork): + // Save x30 in the off-stack spill area. + stp xzr, x30, [sp, #-16]! + bl COMMON_INTERCEPTOR_SPILL_AREA + ldp xzr, x30, [sp], 16 + str x30, [x0] + + // Call real vfork. This may return twice. User code that runs between the first and the second return + // may clobber the stack frame of the interceptor; that's why it does not have a frame. + adrp x0, _ZN14__interception10real_vforkE + ldr x0, [x0, :lo12:_ZN14__interception10real_vforkE] + blr x0 + + stp x0, xzr, [sp, #-16]! + cmp x0, #0 + b.eq .L_exit + + // x0 != 0 => parent process. Clear stack shadow. + add x0, sp, #16 + bl COMMON_INTERCEPTOR_HANDLE_VFORK + +.L_exit: + // Restore x30. + bl COMMON_INTERCEPTOR_SPILL_AREA + ldr x30, [x0] + ldp x0, xzr, [sp], 16 + + ret +ASM_SIZE(vfork) + +.weak vfork +.set vfork, ASM_WRAPPER_NAME(vfork) + +#endif diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_arm.inc.S b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_arm.inc.S new file mode 100644 index 00000000000..780a9d46e26 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_arm.inc.S @@ -0,0 +1,49 @@ +#if defined(__arm__) && defined(__linux__) + +#include "sanitizer_common/sanitizer_asm.h" + +ASM_HIDDEN(COMMON_INTERCEPTOR_SPILL_AREA) + +.comm _ZN14__interception10real_vforkE,4,4 +.globl ASM_WRAPPER_NAME(vfork) +ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork)) +ASM_WRAPPER_NAME(vfork): + // Save LR in the off-stack spill area. + push {r4, lr} + bl COMMON_INTERCEPTOR_SPILL_AREA + pop {r4, lr} + str lr, [r0] + + // Call real vfork. This may return twice. User code that runs between the first and the second return + // may clobber the stack frame of the interceptor; that's why it does not have a frame. + ldr r0, .LCPI0_0 +.LPC0_0: + ldr r0, [pc, r0] + mov lr, pc + bx r0 + + push {r0, r4} + cmp r0, #0 + beq .L_exit + + // r0 != 0 => parent process. Clear stack shadow. + add r0, sp, #8 + bl COMMON_INTERCEPTOR_HANDLE_VFORK + +.L_exit: + // Restore LR. + bl COMMON_INTERCEPTOR_SPILL_AREA + ldr lr, [r0] + pop {r0, r4} + + mov pc, lr + +.LCPI0_0: + .long _ZN14__interception10real_vforkE - (.LPC0_0+8) + +ASM_SIZE(vfork) + +.weak vfork +.set vfork, ASM_WRAPPER_NAME(vfork) + +#endif diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S new file mode 100644 index 00000000000..ed693819c6d --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_i386.inc.S @@ -0,0 +1,63 @@ +#if defined(__i386__) && defined(__linux__) + +#include "sanitizer_common/sanitizer_asm.h" + +.comm _ZN14__interception10real_vforkE,4,4 +.globl ASM_WRAPPER_NAME(vfork) +ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork)) +ASM_WRAPPER_NAME(vfork): + // Store return address in the spill area and tear down the stack frame. + sub $12, %esp + call COMMON_INTERCEPTOR_SPILL_AREA + mov 12(%esp), %ecx + mov %ecx, (%eax) + add $16, %esp + + call .L0$pb +.L0$pb: + pop %eax +.Ltmp0: + add $_GLOBAL_OFFSET_TABLE_+(.Ltmp0-.L0$pb), %eax + call *_ZN14__interception10real_vforkE@GOTOFF(%eax) + + // Restore the stack frame. + // 12(%esp) return address + // 8(%esp) spill %ebx + // 4(%esp) spill REAL(vfork) return value + // (%esp) call frame (arg0) for __*_handle_vfork + sub $16, %esp + mov %ebx, 8(%esp) + mov %eax, 4(%esp) + + // Form GOT address in %ebx. + call .L1$pb +.L1$pb: + pop %ebx +.Ltmp1: + add $_GLOBAL_OFFSET_TABLE_+(.Ltmp1-.L1$pb), %ebx + + // Restore original return address. + call COMMON_INTERCEPTOR_SPILL_AREA + mov (%eax), %ecx + mov %ecx, 12(%esp) + mov 4(%esp), %eax + + // Call handle_vfork in the parent process (%rax != 0). + test %eax, %eax + je .L_exit + + lea 16(%esp), %ecx + mov %ecx, (%esp) + call COMMON_INTERCEPTOR_HANDLE_VFORK@PLT + +.L_exit: + mov 4(%esp), %eax + mov 8(%esp), %ebx + add $12, %esp + ret +ASM_SIZE(vfork) + +.weak vfork +.set vfork, ASM_WRAPPER_NAME(vfork) + +#endif diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S new file mode 100644 index 00000000000..8147cdd0924 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_vfork_x86_64.inc.S @@ -0,0 +1,41 @@ +#if defined(__x86_64__) && defined(__linux__) + +#include "sanitizer_common/sanitizer_asm.h" + +.comm _ZN14__interception10real_vforkE,8,8 +.globl ASM_WRAPPER_NAME(vfork) +ASM_TYPE_FUNCTION(ASM_WRAPPER_NAME(vfork)) +ASM_WRAPPER_NAME(vfork): + // Store return address in the spill area and tear down the stack frame. + push %rcx + call COMMON_INTERCEPTOR_SPILL_AREA + pop %rcx + pop %rdi + mov %rdi, (%rax) + + call *_ZN14__interception10real_vforkE(%rip) + + // Restore return address from the spill area. + push %rcx + push %rax + call COMMON_INTERCEPTOR_SPILL_AREA + mov (%rax), %rdx + mov %rdx, 8(%rsp) + mov (%rsp), %rax + + // Call handle_vfork in the parent process (%rax != 0). + test %rax, %rax + je .L_exit + + lea 16(%rsp), %rdi + call COMMON_INTERCEPTOR_HANDLE_VFORK@PLT + +.L_exit: + pop %rax + ret +ASM_SIZE(vfork) + +.weak vfork +.set vfork, ASM_WRAPPER_NAME(vfork) + +#endif diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interface.inc b/libsanitizer/sanitizer_common/sanitizer_common_interface.inc index 89d47bda7df..c72554973b0 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_interface.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_interface.inc @@ -1,7 +1,8 @@ //===-- sanitizer_common_interface.inc ------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // Sanitizer Common interface list. diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interface_posix.inc b/libsanitizer/sanitizer_common/sanitizer_common_interface_posix.inc index d3b72a8eeb7..38f9531148d 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_interface_posix.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_interface_posix.inc @@ -1,7 +1,8 @@ //===-- sanitizer_common_interface_posix.inc ------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // Sanitizer Common interface list only available for Posix systems. diff --git a/libsanitizer/sanitizer_common/sanitizer_common_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_common_libcdep.cpp similarity index 92% rename from libsanitizer/sanitizer_common/sanitizer_common_libcdep.cc rename to libsanitizer/sanitizer_common/sanitizer_common_libcdep.cpp index 6a63650c81b..27d6a177760 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_common_libcdep.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_common_libcdep.cc ---------------------------------------===// +//===-- sanitizer_common_libcdep.cpp --------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -23,7 +24,7 @@ void SetSoftRssLimitExceededCallback(void (*Callback)(bool exceeded)) { SoftRssLimitExceededCallback = Callback; } -#if SANITIZER_LINUX && !SANITIZER_GO +#if (SANITIZER_LINUX || SANITIZER_NETBSD) && !SANITIZER_GO // Weak default implementation for when sanitizer_stackdepot is not linked in. SANITIZER_WEAK_ATTRIBUTE StackDepotStats *StackDepotGetStats() { return nullptr; @@ -112,7 +113,7 @@ void WriteToSyslog(const char *msg) { } void MaybeStartBackgroudThread() { -#if SANITIZER_LINUX && \ +#if (SANITIZER_LINUX || SANITIZER_NETBSD) && \ !SANITIZER_GO // Need to implement/test on other platforms. // Start the background thread if one of the rss limits is given. if (!common_flags()->hard_rss_limit_mb && diff --git a/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cc b/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cpp similarity index 76% rename from libsanitizer/sanitizer_common/sanitizer_common_nolibc.cc rename to libsanitizer/sanitizer_common/sanitizer_common_nolibc.cpp index 7f92bdcec24..3b278e017eb 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cc +++ b/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_common_nolibc.cc ----------------------------------------===// +//===-- sanitizer_common_nolibc.cpp ---------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc b/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc index 6fd5ef74274..31ff48cfd2c 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_syscalls.inc @@ -1,7 +1,8 @@ //===-- sanitizer_common_syscalls.inc ---------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -2872,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/libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cc b/libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cpp similarity index 95% rename from libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cc rename to libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cpp index 8426aad432a..5451d1e758b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cc +++ b/libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_coverage_fuchsia.cc -------------------------------------===// +//===-- sanitizer_coverage_fuchsia.cpp ------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -29,6 +30,7 @@ #include "sanitizer_atomic.h" #include "sanitizer_common.h" #include "sanitizer_internal_defs.h" +#include "sanitizer_symbolizer_fuchsia.h" #include #include @@ -99,7 +101,7 @@ class TracePcGuardController final { // uses the `dumpfile` symbolizer markup element to highlight the // dump. See the explanation for this in: // https://fuchsia.googlesource.com/zircon/+/master/docs/symbolizer_markup.md - Printf("SanitizerCoverage: {{{dumpfile:%s:%s}}} with up to %u PCs\n", + Printf("SanitizerCoverage: " FORMAT_DUMPFILE " with up to %u PCs\n", kSancovSinkName, vmo_name_, next_index_ - 1); } } @@ -130,7 +132,7 @@ class TracePcGuardController final { // The first sample goes at [1] to reserve [0] for the magic number. next_index_ = 1 + num_guards; - zx_status_t status = _zx_vmo_create(DataSize(), 0, &vmo_); + zx_status_t status = _zx_vmo_create(DataSize(), ZX_VMO_RESIZABLE, &vmo_); CHECK_EQ(status, ZX_OK); // Give the VMO a name including our process KOID so it's easy to spot. diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_interface.inc b/libsanitizer/sanitizer_common/sanitizer_coverage_interface.inc index fb78cc00f70..7beeff7e8af 100644 --- a/libsanitizer/sanitizer_common/sanitizer_coverage_interface.inc +++ b/libsanitizer/sanitizer_common/sanitizer_coverage_interface.inc @@ -1,7 +1,8 @@ //===-- sanitizer_coverage_interface.inc ----------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // Sanitizer Coverage interface list. diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cc b/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cpp similarity index 96% rename from libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cc rename to libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cpp index 84db6474ab5..ad137f936ff 100644 --- a/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cc +++ b/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_coverage_libcdep_new.cc ---------------------------------===// +//===-- sanitizer_coverage_libcdep_new.cpp --------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // Sanitizer Coverage Controller for Trace PC Guard. diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_win_dll_thunk.cc b/libsanitizer/sanitizer_common/sanitizer_coverage_win_dll_thunk.cpp similarity index 74% rename from libsanitizer/sanitizer_common/sanitizer_coverage_win_dll_thunk.cc rename to libsanitizer/sanitizer_common/sanitizer_coverage_win_dll_thunk.cpp index 5aea1203dbf..d0bf8a45564 100644 --- a/libsanitizer/sanitizer_common/sanitizer_coverage_win_dll_thunk.cc +++ b/libsanitizer/sanitizer_common/sanitizer_coverage_win_dll_thunk.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_coverage_win_dll_thunk.cc -------------------------------===// +//===-- sanitizer_coverage_win_dll_thunk.cpp ------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cc b/libsanitizer/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cpp similarity index 59% rename from libsanitizer/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cc rename to libsanitizer/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cpp index 939f395071b..0bdf0c5aed4 100644 --- a/libsanitizer/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cc +++ b/libsanitizer/sanitizer_common/sanitizer_coverage_win_dynamic_runtime_thunk.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_coverage_win_dynamic_runtime_thunk.cc -------------------===// +//===-- sanitizer_coverage_win_dynamic_runtime_thunk.cpp ------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -17,3 +18,9 @@ #define INTERFACE_WEAK_FUNCTION(Name) WIN_WEAK_IMPORT_DEF(Name) #include "sanitizer_coverage_interface.inc" #endif // SANITIZER_DYNAMIC_RUNTIME_THUNK + +namespace __sanitizer { +// Add one, otherwise unused, external symbol to this object file so that the +// Visual C++ linker includes it and reads the .drective section. +void ForceWholeArchiveIncludeForSanCov() {} +} diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_win_sections.cc b/libsanitizer/sanitizer_common/sanitizer_coverage_win_sections.cpp similarity index 57% rename from libsanitizer/sanitizer_common/sanitizer_coverage_win_sections.cc rename to libsanitizer/sanitizer_common/sanitizer_coverage_win_sections.cpp index 12832fcc90e..40184bbb913 100644 --- a/libsanitizer/sanitizer_common/sanitizer_coverage_win_sections.cc +++ b/libsanitizer/sanitizer_common/sanitizer_coverage_win_sections.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_coverage_win_sections.cc --------------------------------===// +//===-- sanitizer_coverage_win_sections.cpp -------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -25,35 +26,40 @@ #include "sanitizer_platform.h" #if SANITIZER_WINDOWS #include -extern "C" { -// The Guard array and counter array should both be merged into the .data -// section to reduce the number of PE sections However, because PCTable is -// constant it should be merged with the .rdata section. -#pragma section(".SCOV$GA", read, write) // NOLINT -// Use align(1) to avoid adding any padding that will mess up clients trying to -// determine the start and end of the array. -__declspec(allocate(".SCOV$GA")) __declspec(align(1)) uint64_t - __start___sancov_guards = 0; -#pragma section(".SCOV$GZ", read, write) // NOLINT -__declspec(allocate(".SCOV$GZ")) __declspec(align(1)) uint64_t - __stop___sancov_guards = 0; +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 -__declspec(allocate(".SCOV$CA")) __declspec(align(1)) uint64_t - __start___sancov_cntrs = 0; +__declspec(allocate(".SCOV$CA")) uint64_t __start___sancov_cntrs = 0; + +// Even though we said not to align __stop__sancov_cntrs (using the "align" +// declspec), MSVC's linker may try to align the section, .SCOV$CZ, containing +// it. This can cause a mismatch between the number of PCs and counters since +// each PCTable element is 8 bytes (unlike counters which are 1 byte) so no +// 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 -__declspec(allocate(".SCOV$CZ")) __declspec(align(1)) uint64_t +__declspec(allocate(".SCOV$CZ")) __declspec(align(1)) uint8_t __stop___sancov_cntrs = 0; +#pragma section(".SCOV$GA", read, write) // NOLINT +__declspec(allocate(".SCOV$GA")) uint64_t __start___sancov_guards = 0; +#pragma section(".SCOV$GZ", read, write) // NOLINT +__declspec(allocate(".SCOV$GZ")) __declspec(align(1)) uint8_t + __stop___sancov_guards = 0; + +// The guard array and counter array should both be merged into the .data +// section to reduce the number of PE sections. However, because PCTable is +// constant it should be merged with the .rdata section. #pragma comment(linker, "/MERGE:.SCOV=.data") -// Use uint64_t so there won't be any issues if the linker tries to word align -// the pc array. #pragma section(".SCOVP$A", read) // NOLINT -__declspec(allocate(".SCOVP$A")) __declspec(align(1)) uint64_t - __start___sancov_pcs = 0; +__declspec(allocate(".SCOVP$A")) uint64_t __start___sancov_pcs = 0; #pragma section(".SCOVP$Z", read) // NOLINT -__declspec(allocate(".SCOVP$Z")) __declspec(align(1)) uint64_t +__declspec(allocate(".SCOVP$Z")) __declspec(align(1)) uint8_t __stop___sancov_pcs = 0; #pragma comment(linker, "/MERGE:.SCOVP=.rdata") diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_win_weak_interception.cc b/libsanitizer/sanitizer_common/sanitizer_coverage_win_weak_interception.cpp similarity index 77% rename from libsanitizer/sanitizer_common/sanitizer_coverage_win_weak_interception.cc rename to libsanitizer/sanitizer_common/sanitizer_coverage_win_weak_interception.cpp index 64718dfc507..55263981705 100644 --- a/libsanitizer/sanitizer_common/sanitizer_coverage_win_weak_interception.cc +++ b/libsanitizer/sanitizer_common/sanitizer_coverage_win_weak_interception.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_coverage_win_weak_interception.cc -----------------------===// +//===-- sanitizer_coverage_win_weak_interception.cpp ----------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 module should be included in Sanitizer Coverage when it implemented as a diff --git a/libsanitizer/sanitizer_common/sanitizer_dbghelp.h b/libsanitizer/sanitizer_common/sanitizer_dbghelp.h index bad17a91eb8..00a53998006 100644 --- a/libsanitizer/sanitizer_common/sanitizer_dbghelp.h +++ b/libsanitizer/sanitizer_common/sanitizer_dbghelp.h @@ -1,7 +1,8 @@ //===-- sanitizer_dbghelp.h ------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector.h b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector.h index 5c8317554ad..b80cff460ed 100644 --- a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector.h +++ b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector.h @@ -1,7 +1,8 @@ //===-- sanitizer_deadlock_detector.h ---------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -24,8 +25,8 @@ #ifndef SANITIZER_DEADLOCK_DETECTOR_H #define SANITIZER_DEADLOCK_DETECTOR_H -#include "sanitizer_common.h" #include "sanitizer_bvgraph.h" +#include "sanitizer_common.h" namespace __sanitizer { @@ -56,7 +57,6 @@ class DeadlockDetectorTLS { // Returns true if this is the first (non-recursive) acquisition of this lock. bool addLock(uptr lock_id, uptr current_epoch, u32 stk) { - // Printf("addLock: %zx %zx stk %u\n", lock_id, current_epoch, stk); CHECK_EQ(epoch_, current_epoch); if (!bv_.setBit(lock_id)) { // The lock is already held by this thread, it must be recursive. @@ -82,7 +82,6 @@ class DeadlockDetectorTLS { } } } - // Printf("remLock: %zx %zx\n", lock_id, epoch_); if (!bv_.clearBit(lock_id)) return; // probably addLock happened before flush if (n_all_locks_) { @@ -156,7 +155,6 @@ class DeadlockDetector { if (!available_nodes_.empty()) return getAvailableNode(data); if (!recycled_nodes_.empty()) { - // Printf("recycling: n_edges_ %zd\n", n_edges_); for (sptr i = n_edges_ - 1; i >= 0; i--) { if (recycled_nodes_.getBit(edges_[i].from) || recycled_nodes_.getBit(edges_[i].to)) { @@ -253,8 +251,6 @@ class DeadlockDetector { unique_tid}; edges_[n_edges_++] = e; } - // Printf("Edge%zd: %u %zd=>%zd in T%d\n", - // n_edges_, stk, added_edges[i], cur_idx, unique_tid); } return n_added_edges; } diff --git a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector1.cc b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector1.cpp similarity index 95% rename from libsanitizer/sanitizer_common/sanitizer_deadlock_detector1.cc rename to libsanitizer/sanitizer_common/sanitizer_deadlock_detector1.cpp index e2aedc24da9..d4a325bea4b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector1.cc +++ b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector1.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_deadlock_detector1.cc -----------------------------------===// +//===-- sanitizer_deadlock_detector1.cpp ----------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cc b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cpp similarity index 97% rename from libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cc rename to libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cpp index fb4785317f0..4026739d4e5 100644 --- a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cc +++ b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_deadlock_detector2.cc -----------------------------------===// +//===-- sanitizer_deadlock_detector2.cpp ----------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector_interface.h b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector_interface.h index f8da20612db..a4722b080eb 100644 --- a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector_interface.h +++ b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector_interface.h @@ -1,7 +1,8 @@ //===-- sanitizer_deadlock_detector_interface.h -----------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_errno.cc b/libsanitizer/sanitizer_common/sanitizer_errno.cpp similarity index 76% rename from libsanitizer/sanitizer_common/sanitizer_errno.cc rename to libsanitizer/sanitizer_common/sanitizer_errno.cpp index b65f0e7ddf1..cbadf4d924a 100644 --- a/libsanitizer/sanitizer_common/sanitizer_errno.cc +++ b/libsanitizer/sanitizer_common/sanitizer_errno.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_errno.cc --------------------------------------*- C++ -*-===// +//===-- sanitizer_errno.cpp -------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_errno.h b/libsanitizer/sanitizer_common/sanitizer_errno.h index d67cc24da1a..584e66e4a86 100644 --- a/libsanitizer/sanitizer_common/sanitizer_errno.h +++ b/libsanitizer/sanitizer_common/sanitizer_errno.h @@ -1,7 +1,8 @@ //===-- sanitizer_errno.h ---------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_errno_codes.h b/libsanitizer/sanitizer_common/sanitizer_errno_codes.h index 709f43b7689..f388d0d3646 100644 --- a/libsanitizer/sanitizer_common/sanitizer_errno_codes.h +++ b/libsanitizer/sanitizer_common/sanitizer_errno_codes.h @@ -1,7 +1,8 @@ //===-- sanitizer_errno_codes.h ---------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_file.cc b/libsanitizer/sanitizer_common/sanitizer_file.cpp similarity index 94% rename from libsanitizer/sanitizer_common/sanitizer_file.cc rename to libsanitizer/sanitizer_common/sanitizer_file.cpp index 61fcc9f90d7..c8c0b33cd6c 100644 --- a/libsanitizer/sanitizer_common/sanitizer_file.cc +++ b/libsanitizer/sanitizer_common/sanitizer_file.cpp @@ -1,13 +1,14 @@ -//===-- sanitizer_file.cc ------------------------------------------------===// +//===-- sanitizer_file.cpp -----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 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. // //===---------------------------------------------------------------------===// diff --git a/libsanitizer/sanitizer_common/sanitizer_file.h b/libsanitizer/sanitizer_common/sanitizer_file.h index 3f9e8ab2849..4a78a0e0ac8 100644 --- a/libsanitizer/sanitizer_common/sanitizer_file.h +++ b/libsanitizer/sanitizer_common/sanitizer_file.h @@ -1,7 +1,8 @@ //===-- sanitizer_file.h ---------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===---------------------------------------------------------------------===// // @@ -64,9 +65,6 @@ bool ReadFromFile(fd_t fd, void *buff, uptr buff_size, bool WriteToFile(fd_t fd, const void *buff, uptr buff_size, uptr *bytes_written = nullptr, error_t *error_p = nullptr); -bool RenameFile(const char *oldpath, const char *newpath, - error_t *error_p = nullptr); - // Scoped file handle closer. struct FileCloser { explicit FileCloser(fd_t fd) : fd(fd) {} diff --git a/libsanitizer/sanitizer_common/sanitizer_flag_parser.cc b/libsanitizer/sanitizer_common/sanitizer_flag_parser.cpp similarity index 81% rename from libsanitizer/sanitizer_common/sanitizer_flag_parser.cc rename to libsanitizer/sanitizer_common/sanitizer_flag_parser.cpp index 1fc6b2edb0c..4831814b6df 100644 --- a/libsanitizer/sanitizer_common/sanitizer_flag_parser.cc +++ b/libsanitizer/sanitizer_common/sanitizer_flag_parser.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_flag_parser.cc ------------------------------------------===// +//===-- sanitizer_flag_parser.cpp -----------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -61,7 +62,7 @@ void FlagParser::PrintFlagDescriptions() { } void FlagParser::fatal_error(const char *err) { - Printf("ERROR: %s\n", err); + Printf("%s: ERROR: %s\n", SanitizerToolName, err); Die(); } @@ -74,10 +75,17 @@ void FlagParser::skip_whitespace() { while (is_space(buf_[pos_])) ++pos_; } -void FlagParser::parse_flag() { +void FlagParser::parse_flag(const char *env_option_name) { uptr name_start = pos_; while (buf_[pos_] != 0 && buf_[pos_] != '=' && !is_space(buf_[pos_])) ++pos_; - if (buf_[pos_] != '=') fatal_error("expected '='"); + if (buf_[pos_] != '=') { + if (env_option_name) { + Printf("%s: ERROR: expected '=' in %s\n", SanitizerToolName, + env_option_name); + Die(); + } else + fatal_error("expected '='"); + } char *name = ll_strndup(buf_ + name_start, pos_ - name_start); uptr value_start = ++pos_; @@ -99,11 +107,11 @@ void FlagParser::parse_flag() { if (!res) fatal_error("Flag parsing failed."); } -void FlagParser::parse_flags() { +void FlagParser::parse_flags(const char *env_option_name) { while (true) { skip_whitespace(); if (buf_[pos_] == 0) break; - parse_flag(); + parse_flag(env_option_name); } // Do a sanity check for certain flags. @@ -111,7 +119,13 @@ void FlagParser::parse_flags() { common_flags_dont_use.malloc_context_size = 1; } -void FlagParser::ParseString(const char *s) { +void FlagParser::ParseStringFromEnv(const char *env_name) { + const char *env = GetEnv(env_name); + VPrintf(1, "%s: %s\n", env_name, env ? env : ""); + ParseString(env, env_name); +} + +void FlagParser::ParseString(const char *s, const char *env_option_name) { if (!s) return; // Backup current parser state to allow nested ParseString() calls. const char *old_buf_ = buf_; @@ -119,7 +133,7 @@ void FlagParser::ParseString(const char *s) { buf_ = s; pos_ = 0; - parse_flags(); + parse_flags(env_option_name); buf_ = old_buf_; pos_ = old_pos_; @@ -138,7 +152,7 @@ bool FlagParser::ParseFile(const char *path, bool ignore_missing) { Printf("Failed to read options from '%s': error %d\n", path, err); return false; } - ParseString(data); + ParseString(data, path); UnmapOrDie(data, data_mapped_size); return true; } diff --git a/libsanitizer/sanitizer_common/sanitizer_flag_parser.h b/libsanitizer/sanitizer_common/sanitizer_flag_parser.h index 6bf3fedf2fd..8e12700bbe8 100644 --- a/libsanitizer/sanitizer_common/sanitizer_flag_parser.h +++ b/libsanitizer/sanitizer_common/sanitizer_flag_parser.h @@ -1,7 +1,8 @@ //===-- sanitizer_flag_parser.h ---------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -21,6 +22,9 @@ namespace __sanitizer { class FlagHandlerBase { public: virtual bool Parse(const char *value) { return false; } + + protected: + ~FlagHandlerBase() {}; }; template @@ -95,6 +99,15 @@ inline bool FlagHandler::Parse(const char *value) { return ok; } +template <> +inline bool FlagHandler::Parse(const char *value) { + const char *value_end; + *t_ = internal_simple_strtoll(value, &value_end, 10); + bool ok = *value_end == 0; + if (!ok) Printf("ERROR: Invalid value for s64 option: '%s'\n", value); + return ok; +} + class FlagParser { static const int kMaxFlags = 200; struct Flag { @@ -111,7 +124,8 @@ class FlagParser { FlagParser(); void RegisterHandler(const char *name, FlagHandlerBase *handler, const char *desc); - void ParseString(const char *s); + void ParseString(const char *s, const char *env_name = 0); + void ParseStringFromEnv(const char *env_name); bool ParseFile(const char *path, bool ignore_missing); void PrintFlagDescriptions(); @@ -121,8 +135,8 @@ class FlagParser { void fatal_error(const char *err); bool is_space(char c); void skip_whitespace(); - void parse_flags(); - void parse_flag(); + void parse_flags(const char *env_option_name); + void parse_flag(const char *env_option_name); bool run_handler(const char *name, const char *value); char *ll_strndup(const char *s, uptr n); }; diff --git a/libsanitizer/sanitizer_common/sanitizer_flags.cc b/libsanitizer/sanitizer_common/sanitizer_flags.cpp similarity index 92% rename from libsanitizer/sanitizer_common/sanitizer_flags.cc rename to libsanitizer/sanitizer_common/sanitizer_flags.cpp index cbd00026c1b..acc7ed39cb0 100644 --- a/libsanitizer/sanitizer_common/sanitizer_flags.cc +++ b/libsanitizer/sanitizer_common/sanitizer_flags.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_flags.cc ------------------------------------------------===// +//===-- sanitizer_flags.cpp -----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_flags.h b/libsanitizer/sanitizer_common/sanitizer_flags.h index 2e3739e915d..8f5e987da3f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_flags.h +++ b/libsanitizer/sanitizer_common/sanitizer_flags.h @@ -1,7 +1,8 @@ //===-- sanitizer_flags.h ---------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_flags.inc b/libsanitizer/sanitizer_common/sanitizer_flags.inc index a62dbebb575..7d592bdcb61 100644 --- a/libsanitizer/sanitizer_common/sanitizer_flags.inc +++ b/libsanitizer/sanitizer_common/sanitizer_flags.inc @@ -1,7 +1,8 @@ //===-- sanitizer_flags.h ---------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -101,7 +102,7 @@ COMMON_FLAG(bool, allow_user_segv_handler, true, "handle_*=1 will be upgraded to handle_*=2.") COMMON_FLAG(bool, use_sigaltstack, true, "If set, uses alternate stack for signal handling.") -COMMON_FLAG(bool, detect_deadlocks, false, +COMMON_FLAG(bool, detect_deadlocks, true, "If set, deadlock detection is enabled.") COMMON_FLAG( uptr, clear_shadow_mmap_threshold, 64 * 1024, @@ -217,9 +218,9 @@ COMMON_FLAG(bool, intercept_stat, true, COMMON_FLAG(bool, intercept_send, true, "If set, uses custom wrappers for send* functions " "to find more errors.") -COMMON_FLAG(bool, decorate_proc_maps, false, "If set, decorate sanitizer " - "mappings in /proc/self/maps with " - "user-readable names") +COMMON_FLAG(bool, decorate_proc_maps, (bool)SANITIZER_ANDROID, + "If set, decorate sanitizer mappings in /proc/self/maps with " + "user-readable names") COMMON_FLAG(int, exitcode, 1, "Override the program exit status if the tool " "found an error") COMMON_FLAG( @@ -241,3 +242,6 @@ COMMON_FLAG(bool, dump_registers, true, COMMON_FLAG(bool, detect_write_exec, false, "If true, triggers warning when writable-executable pages requests " "are being made") +COMMON_FLAG(bool, test_only_emulate_no_memorymap, false, + "TEST ONLY fail to read memory mappings to emulate sanitized " + "\"init\"") diff --git a/libsanitizer/sanitizer_common/sanitizer_freebsd.h b/libsanitizer/sanitizer_common/sanitizer_freebsd.h index 47bb1313e6f..64cb21f1c3d 100644 --- a/libsanitizer/sanitizer_common/sanitizer_freebsd.h +++ b/libsanitizer/sanitizer_common/sanitizer_freebsd.h @@ -1,7 +1,8 @@ //===-- sanitizer_freebsd.h -------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_fuchsia.cc b/libsanitizer/sanitizer_common/sanitizer_fuchsia.cpp similarity index 93% rename from libsanitizer/sanitizer_common/sanitizer_fuchsia.cc rename to libsanitizer/sanitizer_common/sanitizer_fuchsia.cpp index 6602f97b40b..3dc6863a03a 100644 --- a/libsanitizer/sanitizer_common/sanitizer_fuchsia.cc +++ b/libsanitizer/sanitizer_common/sanitizer_fuchsia.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_fuchsia.cc ----------------------------------------------===// +//===-- sanitizer_fuchsia.cpp ---------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -45,9 +46,14 @@ unsigned int internal_sleep(unsigned int seconds) { return 0; } -u64 NanoTime() { return _zx_clock_get(ZX_CLOCK_UTC); } +u64 NanoTime() { + zx_time_t time; + zx_status_t status = _zx_clock_get(ZX_CLOCK_UTC, &time); + CHECK_EQ(status, ZX_OK); + return time; +} -u64 MonotonicNanoTime() { return _zx_clock_get(ZX_CLOCK_MONOTONIC); } +u64 MonotonicNanoTime() { return _zx_clock_get_monotonic(); } uptr internal_getpid() { zx_info_handle_basic_t info; @@ -84,8 +90,10 @@ void GetThreadStackTopAndBottom(bool, uptr *stack_top, uptr *stack_bottom) { *stack_top = *stack_bottom + size; } +void InitializePlatformEarly() {} void MaybeReexec() {} void CheckASLR() {} +void CheckMPROTECT() {} void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {} void DisableCoreDumperIfNecessary() {} void InstallDeadlySignalHandlers(SignalHandlerType handler) {} @@ -117,8 +125,9 @@ void BlockingMutex::Lock() { if (atomic_exchange(m, MtxLocked, memory_order_acquire) == MtxUnlocked) return; while (atomic_exchange(m, MtxSleeping, memory_order_acquire) != MtxUnlocked) { - zx_status_t status = _zx_futex_wait(reinterpret_cast(m), - MtxSleeping, ZX_TIME_INFINITE); + zx_status_t status = + _zx_futex_wait(reinterpret_cast(m), MtxSleeping, + ZX_HANDLE_INVALID, ZX_TIME_INFINITE); if (status != ZX_ERR_BAD_STATE) // Normal race. CHECK_EQ(status, ZX_OK); } @@ -205,10 +214,10 @@ uptr ReservedAddressRange::Init(uptr init_size, const char *name, uintptr_t base; zx_handle_t vmar; zx_status_t status = - _zx_vmar_allocate_old(_zx_vmar_root_self(), 0, init_size, - ZX_VM_FLAG_CAN_MAP_READ | ZX_VM_FLAG_CAN_MAP_WRITE | - ZX_VM_FLAG_CAN_MAP_SPECIFIC, - &vmar, &base); + _zx_vmar_allocate( + _zx_vmar_root_self(), + ZX_VM_CAN_MAP_READ | ZX_VM_CAN_MAP_WRITE | ZX_VM_CAN_MAP_SPECIFIC, + 0, init_size, &vmar, &base); if (status != ZX_OK) ReportMmapFailureAndDie(init_size, name, "zx_vmar_allocate", status); base_ = reinterpret_cast(base); @@ -248,12 +257,14 @@ static uptr DoMmapFixedOrDie(zx_handle_t vmar, uptr fixed_addr, uptr map_size, return addr; } -uptr ReservedAddressRange::Map(uptr fixed_addr, uptr map_size) { +uptr ReservedAddressRange::Map(uptr fixed_addr, uptr map_size, + const char *name) { return DoMmapFixedOrDie(os_handle_, fixed_addr, map_size, base_, name_, false); } -uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr map_size) { +uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr map_size, + const char *name) { return DoMmapFixedOrDie(os_handle_, fixed_addr, map_size, base_, name_, true); } @@ -449,6 +460,7 @@ char **StoredArgv; char **StoredEnviron; char **GetArgv() { return StoredArgv; } +char **GetEnviron() { return StoredEnviron; } const char *GetEnv(const char *name) { if (StoredEnviron) { diff --git a/libsanitizer/sanitizer_common/sanitizer_fuchsia.h b/libsanitizer/sanitizer_common/sanitizer_fuchsia.h index 59b679d6c7f..5a2ad32b411 100644 --- a/libsanitizer/sanitizer_common/sanitizer_fuchsia.h +++ b/libsanitizer/sanitizer_common/sanitizer_fuchsia.h @@ -1,7 +1,8 @@ //===-- sanitizer_fuchsia.h ------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===---------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_getauxval.h b/libsanitizer/sanitizer_common/sanitizer_getauxval.h index a2868614cfc..cbd1af12c04 100644 --- a/libsanitizer/sanitizer_common/sanitizer_getauxval.h +++ b/libsanitizer/sanitizer_common/sanitizer_getauxval.h @@ -1,7 +1,8 @@ //===-- sanitizer_getauxval.h -----------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_hash.h b/libsanitizer/sanitizer_common/sanitizer_hash.h new file mode 100644 index 00000000000..3d97dcc5d28 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_hash.h @@ -0,0 +1,43 @@ +//===-- sanitizer_common.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 implements a simple hash function. +//===----------------------------------------------------------------------===// + +#ifndef SANITIZER_HASH_H +#define SANITIZER_HASH_H + +#include "sanitizer_internal_defs.h" + +namespace __sanitizer { +class MurMur2HashBuilder { + static const u32 m = 0x5bd1e995; + static const u32 seed = 0x9747b28c; + static const u32 r = 24; + u32 h; + + public: + explicit MurMur2HashBuilder(u32 init = 0) { h = seed ^ init; } + void add(u32 k) { + k *= m; + k ^= k >> r; + k *= m; + h *= m; + h ^= k; + } + u32 get() { + u32 x = h; + x ^= x >> 13; + x *= m; + x ^= x >> 15; + return x; + } +}; +} //namespace __sanitizer + +#endif // SANITIZER_HASH_H diff --git a/libsanitizer/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc b/libsanitizer/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc index b42e6314434..1ec73827b8b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc +++ b/libsanitizer/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc @@ -1,7 +1,8 @@ //===-- sanitizer_interceptors_ioctl_netbsd.inc -----------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -23,7 +24,7 @@ struct ioctl_desc { const char *name; }; -const unsigned ioctl_table_max = 1198; +const unsigned ioctl_table_max = 1236; static ioctl_desc ioctl_table[ioctl_table_max]; static unsigned ioctl_table_size = 0; @@ -286,6 +287,8 @@ static void ioctl_table_fill() { _(MLX_GET_CINFO, WRITE, struct_mlx_cinfo_sz); /* Entries from file: dev/ic/nvmeio.h */ _(NVME_PASSTHROUGH_CMD, READWRITE, struct_nvme_pt_command_sz); + /* Entries from file: dev/ic/qemufwcfgio.h */ + _(FWCFGIO_SET_INDEX, READ, sizeof(u16)); /* Entries from file: dev/ir/irdaio.h */ _(IRDA_RESET_PARAMS, NONE, 0); _(IRDA_SET_PARAMS, READ, struct_irda_params_sz); @@ -294,9 +297,6 @@ static void ioctl_table_fill() { _(IRFRAMETTY_GET_DEVICE, WRITE, sizeof(unsigned int)); _(IRFRAMETTY_GET_DONGLE, WRITE, sizeof(unsigned int)); _(IRFRAMETTY_SET_DONGLE, READ, sizeof(unsigned int)); - /* Entries from file: dev/isa/satlinkio.h */ - _(SATIORESET, NONE, 0); - _(SATIOGID, WRITE, struct_satlink_id_sz); /* Entries from file: dev/isa/isvio.h */ _(ISV_CMD, READWRITE, struct_isv_cmd_sz); /* Entries from file: dev/isa/wtreg.h */ @@ -645,6 +645,30 @@ static void ioctl_table_fill() { _(SPKRTUNE, NONE, 0); _(SPKRGETVOL, WRITE, sizeof(unsigned int)); _(SPKRSETVOL, READ, sizeof(unsigned int)); +#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); + _(NVMM_IOC_MACHINE_DESTROY, READ, struct_nvmm_ioc_machine_destroy_sz); + _(NVMM_IOC_MACHINE_CONFIGURE, READ, struct_nvmm_ioc_machine_configure_sz); + _(NVMM_IOC_VCPU_CREATE, READ, struct_nvmm_ioc_vcpu_create_sz); + _(NVMM_IOC_VCPU_DESTROY, READ, struct_nvmm_ioc_vcpu_destroy_sz); + _(NVMM_IOC_VCPU_SETSTATE, READ, struct_nvmm_ioc_vcpu_setstate_sz); + _(NVMM_IOC_VCPU_GETSTATE, READ, struct_nvmm_ioc_vcpu_getstate_sz); + _(NVMM_IOC_VCPU_INJECT, READ, struct_nvmm_ioc_vcpu_inject_sz); + _(NVMM_IOC_VCPU_RUN, READWRITE, struct_nvmm_ioc_vcpu_run_sz); + _(NVMM_IOC_GPA_MAP, READ, struct_nvmm_ioc_gpa_map_sz); + _(NVMM_IOC_GPA_UNMAP, READ, struct_nvmm_ioc_gpa_unmap_sz); + _(NVMM_IOC_HVA_MAP, READ, struct_nvmm_ioc_hva_map_sz); + _(NVMM_IOC_HVA_UNMAP, READ, struct_nvmm_ioc_hva_unmap_sz); + _(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); /* Entries from file: net/bpf.h */ _(BIOCGBLEN, WRITE, sizeof(unsigned int)); _(BIOCSBLEN, READWRITE, sizeof(unsigned int)); @@ -664,20 +688,12 @@ static void ioctl_table_fill() { _(BIOCSHDRCMPLT, READ, sizeof(unsigned int)); _(BIOCSDLT, READ, sizeof(unsigned int)); _(BIOCGDLTLIST, READWRITE, struct_bpf_dltlist_sz); - _(BIOCGSEESENT, WRITE, sizeof(unsigned int)); - _(BIOCSSEESENT, READ, sizeof(unsigned int)); + _(BIOCGDIRECTION, WRITE, sizeof(unsigned int)); + _(BIOCSDIRECTION, READ, sizeof(unsigned int)); _(BIOCSRTIMEOUT, READ, struct_timeval_sz); _(BIOCGRTIMEOUT, WRITE, struct_timeval_sz); _(BIOCGFEEDBACK, WRITE, sizeof(unsigned int)); _(BIOCSFEEDBACK, READ, sizeof(unsigned int)); - /* Entries from file: net/if_atm.h */ - _(SIOCRAWATM, READWRITE, sizeof(int)); - _(SIOCATMENA, READWRITE, struct_atm_pseudoioctl_sz); - _(SIOCATMDIS, READWRITE, struct_atm_pseudoioctl_sz); - _(SIOCSPVCTX, READWRITE, struct_pvctxreq_sz); - _(SIOCGPVCTX, READWRITE, struct_pvctxreq_sz); - _(SIOCSPVCSIF, READWRITE, struct_ifreq_sz); - _(SIOCGPVCSIF, READWRITE, struct_ifreq_sz); /* Entries from file: net/if_gre.h */ _(GRESADDRS, READ, struct_ifreq_sz); _(GRESADDRD, READ, struct_ifreq_sz); @@ -713,12 +729,12 @@ static void ioctl_table_fill() { /* Entries from file: net/npf.h */ _(IOC_NPF_VERSION, WRITE, sizeof(int)); _(IOC_NPF_SWITCH, READ, sizeof(int)); - _(IOC_NPF_LOAD, READWRITE, struct_plistref_sz); + _(IOC_NPF_LOAD, READWRITE, struct_nvlist_ref_sz); _(IOC_NPF_TABLE, READ, struct_npf_ioctl_table_sz); _(IOC_NPF_STATS, READ, sizeof(uptr)); - _(IOC_NPF_SAVE, WRITE, struct_plistref_sz); - _(IOC_NPF_RULE, READWRITE, struct_plistref_sz); - _(IOC_NPF_CONN_LOOKUP, READWRITE, struct_plistref_sz); + _(IOC_NPF_SAVE, WRITE, struct_nvlist_ref_sz); + _(IOC_NPF_RULE, READWRITE, struct_nvlist_ref_sz); + _(IOC_NPF_CONN_LOOKUP, READWRITE, struct_nvlist_ref_sz); /* Entries from file: net/if_pppoe.h */ _(PPPOESETPARMS, READ, struct_pppoediscparms_sz); _(PPPOEGETPARMS, READWRITE, struct_pppoediscparms_sz); @@ -841,6 +857,9 @@ static void ioctl_table_fill() { _(SIOCGNATS, READWRITE, struct_ipfobj_sz); _(SIOCGNATL, READWRITE, struct_ipfobj_sz); _(SIOCPURGENAT, READWRITE, struct_ipfobj_sz); + /* Entries from file: netinet/sctp_uio.h */ + _(SIOCCONNECTX, READWRITE, struct_sctp_connectx_addrs_sz); + _(SIOCCONNECTXDEL, READWRITE, struct_sctp_connectx_addrs_sz); /* Entries from file: netinet6/in6_var.h */ _(SIOCSIFINFO_FLAGS, READWRITE, struct_in6_ndireq_sz); _(SIOCAADDRCTL_POLICY, READ, struct_in6_addrpolicy_sz); @@ -880,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); @@ -970,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); @@ -1000,6 +1023,8 @@ static void ioctl_table_fill() { /* Entries from file: sys/filio.h */ _(FIOCLEX, NONE, 0); _(FIONCLEX, NONE, 0); + _(FIOSEEKDATA, READWRITE, sizeof(uptr)); + _(FIOSEEKHOLE, READWRITE, sizeof(uptr)); _(FIONREAD, WRITE, sizeof(int)); _(FIONBIO, READ, sizeof(int)); _(FIOASYNC, READ, sizeof(int)); @@ -1093,7 +1118,6 @@ static void ioctl_table_fill() { /* Entries from file: sys/power.h */ _(POWER_EVENT_RECVDICT, READWRITE, struct_plistref_sz); _(POWER_IOC_GET_TYPE, WRITE, struct_power_type_sz); - _(POWER_IOC_GET_TYPE_WITH_LOSSAGE, WRITE, sizeof(uptr)); /* Entries from file: sys/radioio.h */ _(RIOCGINFO, WRITE, struct_radio_info_sz); _(RIOCSINFO, READWRITE, struct_radio_info_sz); @@ -1131,6 +1155,7 @@ static void ioctl_table_fill() { _(SIOCATMARK, WRITE, sizeof(int)); _(SIOCSPGRP, READ, sizeof(int)); _(SIOCGPGRP, WRITE, sizeof(int)); + _(SIOCPEELOFF, READWRITE, sizeof(int)); _(SIOCADDRT, READ, struct_ortentry_sz); _(SIOCDELRT, READ, struct_ortentry_sz); _(SIOCSIFADDR, READ, struct_ifreq_sz); @@ -1188,6 +1213,12 @@ static void ioctl_table_fill() { _(SIOCSLINKSTR, READ, struct_ifdrv_sz); _(SIOCGETHERCAP, READWRITE, struct_eccapreq_sz); _(SIOCGIFINDEX, READWRITE, struct_ifreq_sz); + _(SIOCSETHERCAP, READ, struct_eccapreq_sz); + _(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); _(SIOCSETPFSYNC, READ, struct_ifreq_sz); _(SIOCGETPFSYNC, READWRITE, struct_ifreq_sz); /* Entries from file: sys/timepps.h */ @@ -1314,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); diff --git a/libsanitizer/sanitizer_common/sanitizer_interface_internal.h b/libsanitizer/sanitizer_common/sanitizer_interface_internal.h index 6597efa2def..c110eff130f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_interface_internal.h +++ b/libsanitizer/sanitizer_common/sanitizer_interface_internal.h @@ -1,7 +1,8 @@ //===-- sanitizer_interface_internal.h --------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h index 26bea8bed91..e0c6506bed5 100644 --- a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h +++ b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h @@ -1,7 +1,8 @@ //===-- sanitizer_internal_defs.h -------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -195,7 +196,9 @@ typedef u64 tid_t; // This header should NOT include any other headers to avoid portability issues. // Common defs. +#ifndef INLINE #define INLINE inline +#endif #define INTERFACE_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE #define SANITIZER_WEAK_DEFAULT_IMPL \ extern "C" SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE NOINLINE @@ -419,7 +422,6 @@ inline void Trap() { namespace __asan { using namespace __sanitizer; } // NOLINT namespace __dsan { using namespace __sanitizer; } // NOLINT namespace __dfsan { using namespace __sanitizer; } // NOLINT -namespace __esan { using namespace __sanitizer; } // NOLINT namespace __lsan { using namespace __sanitizer; } // NOLINT namespace __msan { using namespace __sanitizer; } // NOLINT namespace __hwasan { using namespace __sanitizer; } // NOLINT diff --git a/libsanitizer/sanitizer_common/sanitizer_lfstack.h b/libsanitizer/sanitizer_common/sanitizer_lfstack.h index 8bd0e91c400..af2ca55ec3f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_lfstack.h +++ b/libsanitizer/sanitizer_common/sanitizer_lfstack.h @@ -1,7 +1,8 @@ //===-- sanitizer_lfstack.h -=-----------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_libc.cc b/libsanitizer/sanitizer_common/sanitizer_libc.cpp similarity index 96% rename from libsanitizer/sanitizer_common/sanitizer_libc.cc rename to libsanitizer/sanitizer_common/sanitizer_libc.cpp index 94fa69b6a2d..5c9d3a80c13 100644 --- a/libsanitizer/sanitizer_common/sanitizer_libc.cc +++ b/libsanitizer/sanitizer_common/sanitizer_libc.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_libc.cc -------------------------------------------------===// +//===-- sanitizer_libc.cpp ------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_libc.h b/libsanitizer/sanitizer_common/sanitizer_libc.h index 4bc6791be56..3d5db35d68b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_libc.h +++ b/libsanitizer/sanitizer_common/sanitizer_libc.h @@ -1,7 +1,8 @@ //===-- sanitizer_libc.h ----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_libignore.cc b/libsanitizer/sanitizer_common/sanitizer_libignore.cpp similarity index 93% rename from libsanitizer/sanitizer_common/sanitizer_libignore.cc rename to libsanitizer/sanitizer_common/sanitizer_libignore.cpp index 0a551490b7f..eb9bb765013 100644 --- a/libsanitizer/sanitizer_common/sanitizer_libignore.cc +++ b/libsanitizer/sanitizer_common/sanitizer_libignore.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_libignore.cc --------------------------------------------===// +//===-- sanitizer_libignore.cpp -------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// diff --git a/libsanitizer/sanitizer_common/sanitizer_libignore.h b/libsanitizer/sanitizer_common/sanitizer_libignore.h index b2884fa3c91..256f685979f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_libignore.h +++ b/libsanitizer/sanitizer_common/sanitizer_libignore.h @@ -1,7 +1,8 @@ //===-- sanitizer_libignore.h -----------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.cc b/libsanitizer/sanitizer_common/sanitizer_linux.cpp similarity index 96% rename from libsanitizer/sanitizer_common/sanitizer_linux.cc rename to libsanitizer/sanitizer_common/sanitizer_linux.cpp index dc1e9849679..1ed6af33fb8 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux.cc +++ b/libsanitizer/sanitizer_common/sanitizer_linux.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_linux.cc ------------------------------------------------===// +//===-- sanitizer_linux.cpp -----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -127,12 +128,6 @@ const int FUTEX_WAKE_PRIVATE = FUTEX_WAKE | FUTEX_PRIVATE_FLAG; # define SANITIZER_LINUX_USES_64BIT_SYSCALLS 0 #endif -#if defined(__x86_64__) || SANITIZER_MIPS64 -extern "C" { -extern void internal_sigreturn(); -} -#endif - // Note : FreeBSD had implemented both // Linux and OpenBSD apis, available from // future 12.x version most likely @@ -379,6 +374,10 @@ uptr internal_filesize(fd_t fd) { return (uptr)st.st_size; } +uptr internal_dup(int oldfd) { + return internal_syscall(SYSCALL(dup), oldfd); +} + uptr internal_dup2(int oldfd, int newfd) { #if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS return internal_syscall(SYSCALL(dup3), oldfd, newfd, 0); @@ -431,7 +430,7 @@ void internal__exit(int exitcode) { unsigned int internal_sleep(unsigned int seconds) { struct timespec ts; - ts.tv_sec = 1; + ts.tv_sec = seconds; ts.tv_nsec = 0; int res = internal_syscall(SYSCALL(nanosleep), &ts, &ts); if (res) return ts.tv_sec; @@ -447,6 +446,8 @@ uptr internal_execve(const char *filename, char *const argv[], // ----------------- sanitizer_common.h bool FileExists(const char *filename) { + if (ShouldMockFailureToOpen(filename)) + return false; struct stat st; #if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS if (internal_syscall(SYSCALL(newfstatat), AT_FDCWD, filename, &st, 0)) @@ -621,33 +622,13 @@ char **GetArgv() { return argv; } -void ReExec() { +char **GetEnviron() { char **argv, **envp; - const char *pathname = "/proc/self/exe"; - -#if SANITIZER_NETBSD - static const int name[] = { - CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME, - }; - char path[400]; - uptr len; - - len = sizeof(path); - if (internal_sysctl(name, ARRAY_SIZE(name), path, &len, NULL, 0) != -1) - pathname = path; -#elif SANITIZER_SOLARIS - pathname = getexecname(); - CHECK_NE(pathname, NULL); -#endif - GetArgsAndEnv(&argv, &envp); - uptr rv = internal_execve(pathname, argv, envp); - int rverrno; - CHECK_EQ(internal_iserror(rv, &rverrno), true); - Printf("execve failed, errno %d\n", rverrno); - Die(); + return envp; } -#endif + +#endif // !SANITIZER_OPENBSD #if !SANITIZER_SOLARIS enum MutexState { @@ -790,14 +771,19 @@ int internal_sysctl(const int *name, unsigned int namelen, void *oldp, return sysctl(name, namelen, oldp, (size_t *)oldlenp, (void *)newp, (size_t)newlen); #else - return sysctl(name, namelen, oldp, (size_t *)oldlenp, newp, (size_t)newlen); + return internal_syscall(SYSCALL(__sysctl), name, namelen, oldp, + (size_t *)oldlenp, newp, (size_t)newlen); #endif } #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 @@ -849,24 +835,6 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) { } return result; } - -// Invokes sigaction via a raw syscall with a restorer, but does not support -// all platforms yet. -// We disable for Go simply because we have not yet added to buildgo.sh. -#if (defined(__x86_64__) || SANITIZER_MIPS64) && !SANITIZER_GO -int internal_sigaction_syscall(int signum, const void *act, void *oldact) { - if (act == nullptr) - return internal_sigaction_norestorer(signum, act, oldact); - __sanitizer_sigaction u_adjust; - internal_memcpy(&u_adjust, act, sizeof(u_adjust)); -#if !SANITIZER_ANDROID || !SANITIZER_MIPS32 - if (u_adjust.sa_restorer == nullptr) { - u_adjust.sa_restorer = internal_sigreturn; - } -#endif - return internal_sigaction_norestorer(signum, (const void *)&u_adjust, oldact); -} -#endif // defined(__x86_64__) && !SANITIZER_GO #endif // SANITIZER_LINUX uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set, @@ -1021,6 +989,8 @@ static uptr GetKernelAreaSize() { // Firstly check if there are writable segments // mapped to top gigabyte (e.g. stack). MemoryMappingLayout proc_maps(/*cache_enabled*/true); + if (proc_maps.Error()) + return 0; MemoryMappedSegment segment; while (proc_maps.Next(&segment)) { if ((segment.end >= 3 * gbyte) && segment.IsWritable()) return 0; @@ -1064,7 +1034,7 @@ uptr GetMaxVirtualAddress() { return (1ULL << 40) - 1; // 0x000000ffffffffffUL; # elif defined(__s390x__) return (1ULL << 53) - 1; // 0x001fffffffffffffUL; -# elif defined(__sparc__) +#elif defined(__sparc__) return ~(uptr)0; # else return (1ULL << 47) - 1; // 0x00007fffffffffffUL; @@ -1088,18 +1058,25 @@ uptr GetMaxUserVirtualAddress() { return addr; } +#if !SANITIZER_ANDROID uptr GetPageSize() { -// Android post-M sysconf(_SC_PAGESIZE) crashes if called from .preinit_array. -#if SANITIZER_ANDROID - return 4096; -#elif SANITIZER_LINUX && (defined(__x86_64__) || defined(__i386__)) +#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__i386__)) return EXEC_PAGESIZE; #elif SANITIZER_USE_GETAUXVAL return getauxval(AT_PAGESZ); +#elif SANITIZER_FREEBSD || SANITIZER_NETBSD +// Use sysctl as sysconf can trigger interceptors internally. + int pz = 0; + uptr pzl = sizeof(pz); + int mib[2] = {CTL_HW, HW_PAGESIZE}; + int rv = internal_sysctl(mib, 2, &pz, &pzl, nullptr, 0); + CHECK_EQ(rv, 0); + return (uptr)pz; #else return sysconf(_SC_PAGESIZE); // EXEC_PAGESIZE may not be trustworthy. #endif } +#endif // !SANITIZER_ANDROID #if !SANITIZER_OPENBSD uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { @@ -1853,17 +1830,17 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { #elif defined(__sparc__) // Decode the instruction to determine the access type. // From OpenSolaris $SRC/uts/sun4/os/trap.c (get_accesstype). -# if SANITIZER_SOLARIS +#if SANITIZER_SOLARIS uptr pc = ucontext->uc_mcontext.gregs[REG_PC]; -# else +#else // Historical BSDism here. struct sigcontext *scontext = (struct sigcontext *)context; -# if defined(__arch64__) +#if defined(__arch64__) uptr pc = scontext->sigc_regs.tpc; -# else +#else uptr pc = scontext->si_regs.pc; -# endif -# endif +#endif +#endif u32 instr = *(u32 *)pc; return (instr >> 21) & 1 ? WRITE: READ; #else @@ -1954,27 +1931,27 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { // pointer, but GCC always uses r31 when we need a frame pointer. *bp = ucontext->uc_mcontext.regs->gpr[PT_R31]; #elif defined(__sparc__) -# if defined(__arch64__) || defined(__sparcv9) -# define STACK_BIAS 2047 -# else -# define STACK_BIAS 0 +#if defined(__arch64__) || defined(__sparcv9) +#define STACK_BIAS 2047 +#else +#define STACK_BIAS 0 # endif # if SANITIZER_SOLARIS - ucontext_t *ucontext = (ucontext_t*)context; + ucontext_t *ucontext = (ucontext_t *)context; *pc = ucontext->uc_mcontext.gregs[REG_PC]; *sp = ucontext->uc_mcontext.gregs[REG_O6] + STACK_BIAS; -# else +#else // Historical BSDism here. struct sigcontext *scontext = (struct sigcontext *)context; -# if defined(__arch64__) +#if defined(__arch64__) *pc = scontext->sigc_regs.tpc; *sp = scontext->sigc_regs.u_regs[14] + STACK_BIAS; -# else +#else *pc = scontext->si_regs.pc; *sp = scontext->si_regs.u_regs[14]; -# endif +#endif # endif - *bp = (uptr) ((uhwptr *) *sp)[14] + STACK_BIAS; + *bp = (uptr)((uhwptr *)*sp)[14] + STACK_BIAS; #elif defined(__mips__) ucontext_t *ucontext = (ucontext_t*)context; *pc = ucontext->uc_mcontext.pc; @@ -1996,6 +1973,10 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { void SignalContext::InitPcSpBp() { GetPcSpBp(context, &pc, &sp, &bp); } +void InitializePlatformEarly() { + // Do nothing. +} + void MaybeReexec() { // No need to re-exec on Linux. } @@ -2035,6 +2016,30 @@ void CheckASLR() { #endif } +void CheckMPROTECT() { +#if SANITIZER_NETBSD + int mib[3]; + int paxflags; + uptr len = sizeof(paxflags); + + mib[0] = CTL_PROC; + mib[1] = internal_getpid(); + mib[2] = PROC_PID_PAXFLAGS; + + if (UNLIKELY(internal_sysctl(mib, 3, &paxflags, &len, NULL, 0) == -1)) { + Printf("sysctl failed\n"); + Die(); + } + + if (UNLIKELY(paxflags & CTL_PROC_PAXFLAGS_MPROTECT)) { + Printf("This sanitizer is not compatible with enabled MPROTECT\n"); + Die(); + } +#else + // Do nothing +#endif +} + void PrintModuleMap() { } void CheckNoDeepBind(const char *filename, int flag) { diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.h b/libsanitizer/sanitizer_common/sanitizer_linux.h index e1f606fd5f6..c28347ad963 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux.h +++ b/libsanitizer/sanitizer_common/sanitizer_linux.h @@ -1,7 +1,8 @@ //===-- sanitizer_linux.h ---------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -16,6 +17,7 @@ SANITIZER_OPENBSD || SANITIZER_SOLARIS #include "sanitizer_common.h" #include "sanitizer_internal_defs.h" +#include "sanitizer_platform_limits_freebsd.h" #include "sanitizer_platform_limits_netbsd.h" #include "sanitizer_platform_limits_openbsd.h" #include "sanitizer_platform_limits_posix.h" @@ -56,10 +58,6 @@ uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5); // (like the process-wide error reporting SEGV handler) must use // internal_sigaction instead. int internal_sigaction_norestorer(int signum, const void *act, void *oldact); -#if (defined(__x86_64__) || SANITIZER_MIPS64) && !SANITIZER_GO -// Uses a raw system call to avoid interceptors. -int internal_sigaction_syscall(int signum, const void *act, void *oldact); -#endif void internal_sigdelset(__sanitizer_sigset_t *set, int signum); #if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) \ || defined(__powerpc64__) || defined(__s390__) || defined(__i386__) \ @@ -69,6 +67,9 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, #endif #elif SANITIZER_FREEBSD void internal_sigdelset(__sanitizer_sigset_t *set, int signum); +#elif SANITIZER_NETBSD +void internal_sigdelset(__sanitizer_sigset_t *set, int signum); +uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg); #endif // SANITIZER_LINUX // This class reads thread IDs from /proc//task using only syscalls. @@ -103,6 +104,17 @@ bool LibraryNameIs(const char *full_name, const char *base_name); // Call cb for each region mapped by map. void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr)); +// Releases memory pages entirely within the [beg, end] address range. +// The pages no longer count toward RSS; reads are guaranteed to return 0. +// Requires (but does not verify!) that pages are MAP_PRIVATE. +INLINE void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) { + // man madvise on Linux promises zero-fill for anonymous private pages. + // Testing shows the same behaviour for private (but not anonymous) mappings + // of shm_open() files, as long as the underlying file is untouched. + CHECK(SANITIZER_LINUX); + ReleaseMemoryPagesToOS(beg, end); +} + #if SANITIZER_ANDROID #if defined(__aarch64__) @@ -131,13 +143,13 @@ void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr)); #error "Unsupported architecture." #endif -// The Android Bionic team has allocated a TLS slot for TSan starting with N, -// given that Android currently doesn't support ELF TLS. It is used to store -// Sanitizers thread specific data. -static const int TLS_SLOT_TSAN = 8; +// The Android Bionic team has allocated a TLS slot for sanitizers starting +// with Q, given that Android currently doesn't support ELF TLS. It is used to +// store sanitizer thread specific data. +static const int TLS_SLOT_SANITIZER = 6; ALWAYS_INLINE uptr *get_android_tls_ptr() { - return reinterpret_cast(&__get_tls()[TLS_SLOT_TSAN]); + return reinterpret_cast(&__get_tls()[TLS_SLOT_SANITIZER]); } #endif // SANITIZER_ANDROID diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp similarity index 94% rename from libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc rename to libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp index 28360f5656a..1f584a2add6 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_linux_libcdep.cc ----------------------------------------===// +//===-- sanitizer_linux_libcdep.cpp ---------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -21,6 +22,7 @@ #include "sanitizer_file.h" #include "sanitizer_flags.h" #include "sanitizer_freebsd.h" +#include "sanitizer_getauxval.h" #include "sanitizer_linux.h" #include "sanitizer_placement_new.h" #include "sanitizer_procmaps.h" @@ -50,6 +52,7 @@ #endif #if SANITIZER_SOLARIS +#include #include #endif @@ -97,6 +100,10 @@ void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top, // Find the mapping that contains a stack variable. MemoryMappingLayout proc_maps(/*cache_enabled*/true); + if (proc_maps.Error()) { + *stack_top = *stack_bottom = 0; + return; + } MemoryMappedSegment segment; uptr prev_end = 0; while (proc_maps.Next(&segment)) { @@ -694,13 +701,9 @@ u32 GetNumberOfCPUs() { #elif SANITIZER_SOLARIS return sysconf(_SC_NPROCESSORS_ONLN); #else -#if defined(CPU_COUNT) cpu_set_t CPUs; CHECK_EQ(sched_getaffinity(0, sizeof(cpu_set_t), &CPUs), 0); return CPU_COUNT(&CPUs); -#else - return 1; -#endif #endif } @@ -808,6 +811,40 @@ u64 MonotonicNanoTime() { } #endif // SANITIZER_LINUX && !SANITIZER_GO +#if !SANITIZER_OPENBSD +void ReExec() { + const char *pathname = "/proc/self/exe"; + +#if SANITIZER_NETBSD + static const int name[] = { + CTL_KERN, + KERN_PROC_ARGS, + -1, + KERN_PROC_PATHNAME, + }; + char path[400]; + uptr len; + + len = sizeof(path); + if (internal_sysctl(name, ARRAY_SIZE(name), path, &len, NULL, 0) != -1) + pathname = path; +#elif SANITIZER_SOLARIS + pathname = getexecname(); + CHECK_NE(pathname, NULL); +#elif SANITIZER_USE_GETAUXVAL + // Calling execve with /proc/self/exe sets that as $EXEC_ORIGIN. Binaries that + // rely on that will fail to load shared libraries. Query AT_EXECFN instead. + pathname = reinterpret_cast(getauxval(AT_EXECFN)); +#endif + + uptr rv = internal_execve(pathname, GetArgv(), GetEnviron()); + int rverrno; + CHECK_EQ(internal_iserror(rv, &rverrno), true); + Printf("execve failed, errno %d\n", rverrno); + Die(); +} +#endif // !SANITIZER_OPENBSD + } // namespace __sanitizer #endif diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_mips64.S b/libsanitizer/sanitizer_common/sanitizer_linux_mips64.S deleted file mode 100644 index 8729642aa65..00000000000 --- a/libsanitizer/sanitizer_common/sanitizer_linux_mips64.S +++ /dev/null @@ -1,23 +0,0 @@ -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. - -// Avoid being marked as needing an executable stack: -#if defined(__linux__) && defined(__ELF__) -.section .note.GNU-stack,"",%progbits -#endif - -// Further contents are mips64 only: -#if defined(__linux__) && defined(__mips64) - -.section .text -.set noreorder -.globl internal_sigreturn -.type internal_sigreturn, @function -internal_sigreturn: - - li $v0,5211 // #5211 is for SYS_rt_sigreturn - syscall - -.size internal_sigreturn, .-internal_sigreturn - -#endif // defined(__linux__) && defined(__mips64) diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_s390.cc b/libsanitizer/sanitizer_common/sanitizer_linux_s390.cpp similarity index 96% rename from libsanitizer/sanitizer_common/sanitizer_linux_s390.cc rename to libsanitizer/sanitizer_common/sanitizer_linux_s390.cpp index e55ffe00cfb..41e187eaf8d 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux_s390.cc +++ b/libsanitizer/sanitizer_common/sanitizer_linux_s390.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_linux_s390.cc -------------------------------------------===// +//===-- sanitizer_linux_s390.cpp ------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_x86_64.S b/libsanitizer/sanitizer_common/sanitizer_linux_x86_64.S deleted file mode 100644 index 8ff909542b6..00000000000 --- a/libsanitizer/sanitizer_common/sanitizer_linux_x86_64.S +++ /dev/null @@ -1,25 +0,0 @@ -// This file is dual licensed under the MIT and the University of Illinois Open -// Source Licenses. See LICENSE.TXT for details. - -// Avoid being marked as needing an executable stack: -#if defined(__linux__) && defined(__ELF__) -.section .note.GNU-stack,"",%progbits -#endif - -// Further contents are x86_64-only: -#if defined(__linux__) && defined(__x86_64__) - -#include "../builtins/assembly.h" - -// If the "naked" function attribute were supported for x86 we could -// do this via inline asm. -.text -.balign 4 -DEFINE_COMPILERRT_FUNCTION(internal_sigreturn) - mov $0xf, %eax // 0xf == SYS_rt_sigreturn - mov %rcx, %r10 - syscall - ret // Won't normally reach here. -END_COMPILERRT_FUNCTION(internal_sigreturn) - -#endif // defined(__linux__) && defined(__x86_64__) diff --git a/libsanitizer/sanitizer_common/sanitizer_list.h b/libsanitizer/sanitizer_common/sanitizer_list.h index d7e8b501a6e..f0b925945e6 100644 --- a/libsanitizer/sanitizer_common/sanitizer_list.h +++ b/libsanitizer/sanitizer_common/sanitizer_list.h @@ -1,7 +1,8 @@ //===-- sanitizer_list.h ----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_local_address_space_view.h b/libsanitizer/sanitizer_common/sanitizer_local_address_space_view.h new file mode 100644 index 00000000000..5d1b5264b5e --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_local_address_space_view.h @@ -0,0 +1,76 @@ +//===-- sanitizer_local_address_space_view.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 +// +//===----------------------------------------------------------------------===// +// +// `LocalAddressSpaceView` provides the local (i.e. target and current address +// space are the same) implementation of the `AddressSpaveView` interface which +// provides a simple interface to load memory from another process (i.e. +// out-of-process) +// +// The `AddressSpaceView` interface requires that the type can be used as a +// template parameter to objects that wish to be able to operate in an +// out-of-process manner. In normal usage, objects are in-process and are thus +// instantiated with the `LocalAddressSpaceView` type. This type is used to +// load any pointers in instance methods. This implementation is effectively +// a no-op. When an object is to be used in an out-of-process manner it is +// instansiated with the `RemoteAddressSpaceView` type. +// +// By making `AddressSpaceView` a template parameter of an object, it can +// change its implementation at compile time which has no run time overhead. +// This also allows unifying in-process and out-of-process code which avoids +// code duplication. +// +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_LOCAL_ADDRES_SPACE_VIEW_H +#define SANITIZER_LOCAL_ADDRES_SPACE_VIEW_H + +namespace __sanitizer { +struct LocalAddressSpaceView { + // Load memory `sizeof(T) * num_elements` bytes of memory from the target + // process (always local for this implementation) starting at address + // `target_address`. The local copy of this memory is returned as a pointer. + // The caller should not write to this memory. The behaviour when doing so is + // undefined. Callers should use `LoadWritable()` to get access to memory + // that is writable. + // + // The lifetime of loaded memory is implementation defined. + template + static const T *Load(const T *target_address, uptr num_elements = 1) { + // The target address space is the local address space so + // nothing needs to be copied. Just return the pointer. + return target_address; + } + + // Load memory `sizeof(T) * num_elements` bytes of memory from the target + // process (always local for this implementation) starting at address + // `target_address`. The local copy of this memory is returned as a pointer. + // The memory returned may be written to. + // + // Writes made to the returned memory will be visible in the memory returned + // by subsequent `Load()` or `LoadWritable()` calls provided the + // `target_address` parameter is the same. It is not guaranteed that the + // memory returned by previous calls to `Load()` will contain any performed + // writes. If two or more overlapping regions of memory are loaded via + // separate calls to `LoadWritable()`, it is implementation defined whether + // writes made to the region returned by one call are visible in the regions + // returned by other calls. + // + // Given the above it is recommended to load the largest possible object + // that requires modification (e.g. a class) rather than individual fields + // from a class to avoid issues with overlapping writable regions. + // + // The lifetime of loaded memory is implementation defined. + template + static T *LoadWritable(T *target_address, uptr num_elements = 1) { + // The target address space is the local address space so + // nothing needs to be copied. Just return the pointer. + return target_address; + } +}; +} // namespace __sanitizer + +#endif diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.cc b/libsanitizer/sanitizer_common/sanitizer_mac.cpp similarity index 92% rename from libsanitizer/sanitizer_common/sanitizer_mac.cc rename to libsanitizer/sanitizer_common/sanitizer_mac.cpp index 28b2906e226..bd6301aebad 100644 --- a/libsanitizer/sanitizer_common/sanitizer_mac.cc +++ b/libsanitizer/sanitizer_common/sanitizer_mac.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_mac.cc --------------------------------------------------===// +//===-- sanitizer_mac.cpp -------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -35,7 +36,7 @@ extern char **environ; #endif -#if defined(__has_include) && __has_include() && defined(__BLOCKS__) +#if defined(__has_include) && __has_include() #define SANITIZER_OS_TRACE 1 #include #else @@ -106,9 +107,20 @@ extern "C" int __munmap(void *, size_t) SANITIZER_WEAK_ATTRIBUTE; #define VM_MEMORY_SANITIZER 99 #endif +// XNU on Darwin provides a mmap flag that optimizes allocation/deallocation of +// giant memory regions (i.e. shadow memory regions). +#define kXnuFastMmapFd 0x4 +static size_t kXnuFastMmapThreshold = 2 << 30; // 2 GB +static bool use_xnu_fast_mmap = false; + uptr internal_mmap(void *addr, size_t length, int prot, int flags, int fd, u64 offset) { - if (fd == -1) fd = VM_MAKE_TAG(VM_MEMORY_SANITIZER); + if (fd == -1) { + fd = VM_MAKE_TAG(VM_MEMORY_SANITIZER); + if (length >= kXnuFastMmapThreshold) { + if (use_xnu_fast_mmap) fd |= kXnuFastMmapFd; + } + } if (&__mmap) return (uptr)__mmap(addr, length, prot, flags, fd, offset); return (uptr)mmap(addr, length, prot, flags, fd, offset); } @@ -161,6 +173,10 @@ uptr internal_filesize(fd_t fd) { return (uptr)st.st_size; } +uptr internal_dup(int oldfd) { + return dup(oldfd); +} + uptr internal_dup2(int oldfd, int newfd) { return dup2(oldfd, newfd); } @@ -223,25 +239,25 @@ int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp, (size_t)newlen); } -int internal_forkpty(int *amaster) { - int master, slave; - if (openpty(&master, &slave, nullptr, nullptr, nullptr) == -1) return -1; +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(master); - close(slave); + close(parent); + close(worker); return -1; } if (pid == 0) { - close(master); - if (login_tty(slave) != 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 { - *amaster = master; - close(slave); + *aparent = parent; + close(worker); } return pid; } @@ -265,6 +281,8 @@ uptr internal_waitpid(int pid, int *status, int options) { // ----------------- sanitizer_common.h bool FileExists(const char *filename) { + if (ShouldMockFailureToOpen(filename)) + return false; struct stat st; if (stat(filename, &st)) return false; @@ -360,6 +378,10 @@ void CheckASLR() { // Do nothing } +void CheckMPROTECT() { + // Do nothing +} + uptr GetPageSize() { return sysconf(_SC_PAGESIZE); } @@ -512,27 +534,35 @@ MacosVersion GetMacosVersionInternal() { CHECK_NE(internal_sysctl(mib, 2, 0, &len, 0, 0), -1); CHECK_LT(len, maxlen); CHECK_NE(internal_sysctl(mib, 2, version, &len, 0, 0), -1); - switch (version[0]) { - case '9': return MACOS_VERSION_LEOPARD; - case '1': { - switch (version[1]) { - case '0': return MACOS_VERSION_SNOW_LEOPARD; - case '1': return MACOS_VERSION_LION; - case '2': return MACOS_VERSION_MOUNTAIN_LION; - case '3': return MACOS_VERSION_MAVERICKS; - case '4': return MACOS_VERSION_YOSEMITE; - case '5': return MACOS_VERSION_EL_CAPITAN; - case '6': return MACOS_VERSION_SIERRA; - case '7': return MACOS_VERSION_HIGH_SIERRA; - case '8': return MACOS_VERSION_MOJAVE; - default: - if (IsDigit(version[1])) - return MACOS_VERSION_UNKNOWN_NEWER; - else - return MACOS_VERSION_UNKNOWN; - } - } - default: return MACOS_VERSION_UNKNOWN; + + // Expect .(.) + CHECK_GE(len, 3); + const char *p = version; + int major = internal_simple_strtoll(p, &p, /*base=*/10); + if (*p != '.') return MACOS_VERSION_UNKNOWN; + p += 1; + int minor = internal_simple_strtoll(p, &p, /*base=*/10); + if (*p != '.') return MACOS_VERSION_UNKNOWN; + + switch (major) { + case 9: return MACOS_VERSION_LEOPARD; + case 10: return MACOS_VERSION_SNOW_LEOPARD; + case 11: return MACOS_VERSION_LION; + case 12: return MACOS_VERSION_MOUNTAIN_LION; + case 13: return MACOS_VERSION_MAVERICKS; + case 14: return MACOS_VERSION_YOSEMITE; + case 15: return MACOS_VERSION_EL_CAPITAN; + case 16: return MACOS_VERSION_SIERRA; + case 17: + // Not a typo, 17.5 Darwin Kernel Version maps to High Sierra 10.13.4. + if (minor >= 5) + return MACOS_VERSION_HIGH_SIERRA_DOT_RELEASE_4; + return MACOS_VERSION_HIGH_SIERRA; + case 18: return MACOS_VERSION_MOJAVE; + case 19: return MACOS_VERSION_CATALINA; + default: + if (major < 9) return MACOS_VERSION_UNKNOWN; + return MACOS_VERSION_UNKNOWN_NEWER; } } @@ -675,6 +705,16 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { void SignalContext::InitPcSpBp() { GetPcSpBp(context, &pc, &sp, &bp); } +void InitializePlatformEarly() { + // Only use xnu_fast_mmap when on x86_64 and the OS supports it. + use_xnu_fast_mmap = +#if defined(__x86_64__) + GetMacosVersion() >= MACOS_VERSION_HIGH_SIERRA_DOT_RELEASE_4; +#else + false; +#endif +} + #if !SANITIZER_GO static const char kDyldInsertLibraries[] = "DYLD_INSERT_LIBRARIES"; LowLevelAllocator allocator_for_env; @@ -872,7 +912,7 @@ char **GetArgv() { return *_NSGetArgv(); } -#if defined(__aarch64__) && SANITIZER_IOS && !SANITIZER_IOSSIM +#if SANITIZER_IOS // The task_vm_info struct is normally provided by the macOS SDK, but we need // fields only available in 10.12+. Declare the struct manually to be able to // build against older SDKs. @@ -903,33 +943,37 @@ struct __sanitizer_task_vm_info { #define __SANITIZER_TASK_VM_INFO_COUNT ((mach_msg_type_number_t) \ (sizeof(__sanitizer_task_vm_info) / sizeof(natural_t))) -uptr GetTaskInfoMaxAddress() { +static uptr GetTaskInfoMaxAddress() { __sanitizer_task_vm_info vm_info = {} /* zero initialize */; mach_msg_type_number_t count = __SANITIZER_TASK_VM_INFO_COUNT; int err = task_info(mach_task_self(), TASK_VM_INFO, (int *)&vm_info, &count); - if (err == 0 && vm_info.max_address != 0) { - return vm_info.max_address - 1; - } else { - // xnu cannot provide vm address limit - return 0x200000000 - 1; - } + return err ? 0 : vm_info.max_address; } -#endif uptr GetMaxUserVirtualAddress() { -#if SANITIZER_WORDSIZE == 64 -# if defined(__aarch64__) && SANITIZER_IOS && !SANITIZER_IOSSIM - // Get the maximum VM address static uptr max_vm = GetTaskInfoMaxAddress(); - CHECK(max_vm); - return max_vm; + if (max_vm != 0) + return max_vm - 1; + + // xnu cannot provide vm address limit +# if SANITIZER_WORDSIZE == 32 + return 0xffe00000 - 1; # else - return (1ULL << 47) - 1; // 0x00007fffffffffffUL; + return 0x200000000 - 1; # endif -#else // SANITIZER_WORDSIZE == 32 +} + +#else // !SANITIZER_IOS + +uptr GetMaxUserVirtualAddress() { +# if SANITIZER_WORDSIZE == 64 + return (1ULL << 47) - 1; // 0x00007fffffffffffUL; +# else // SANITIZER_WORDSIZE == 32 + static_assert(SANITIZER_WORDSIZE == 32, "Wrong wordsize"); return (1ULL << 32) - 1; // 0xffffffff; -#endif // SANITIZER_WORDSIZE +# endif } +#endif uptr GetMaxVirtualAddress() { return GetMaxUserVirtualAddress(); diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.h b/libsanitizer/sanitizer_common/sanitizer_mac.h index 8e7a4a24525..2257883084e 100644 --- a/libsanitizer/sanitizer_common/sanitizer_mac.h +++ b/libsanitizer/sanitizer_common/sanitizer_mac.h @@ -1,7 +1,8 @@ //===-- sanitizer_mac.h -----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -41,7 +42,9 @@ enum MacosVersion { MACOS_VERSION_EL_CAPITAN, MACOS_VERSION_SIERRA, MACOS_VERSION_HIGH_SIERRA, + MACOS_VERSION_HIGH_SIERRA_DOT_RELEASE_4, MACOS_VERSION_MOJAVE, + MACOS_VERSION_CATALINA, MACOS_VERSION_UNKNOWN_NEWER }; diff --git a/libsanitizer/sanitizer_common/sanitizer_mac_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_mac_libcdep.cpp similarity index 72% rename from libsanitizer/sanitizer_common/sanitizer_mac_libcdep.cc rename to libsanitizer/sanitizer_common/sanitizer_mac_libcdep.cpp index a0d5c3f8f55..ac7e328946b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_mac_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_mac_libcdep.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_mac_libcdep.cc ------------------------------------------===// +//===-- sanitizer_mac_libcdep.cpp -----------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_malloc_mac.inc b/libsanitizer/sanitizer_common/sanitizer_malloc_mac.inc index 8887f5d5ca4..11adbe5c25b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_malloc_mac.inc +++ b/libsanitizer/sanitizer_common/sanitizer_malloc_mac.inc @@ -1,7 +1,8 @@ //===-- sanitizer_malloc_mac.inc --------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -28,9 +29,29 @@ // https://github.com/gperftools/gperftools. namespace __sanitizer { + extern malloc_zone_t sanitizer_zone; + +struct sanitizer_malloc_introspection_t : public malloc_introspection_t { + // IMPORTANT: Do not change the order, alignment, or types of these fields to + // maintain binary compatibility. You should only add fields to this struct. + + // Used to track changes to the allocator that will affect + // zone enumeration. + u64 allocator_enumeration_version; + uptr allocator_ptr; + uptr allocator_size; +}; + +u64 GetMallocZoneAllocatorEnumerationVersion() { + // This represents the current allocator ABI version. + // This field should be incremented every time the Allocator + // ABI changes in a way that breaks allocator enumeration. + return 0; } +} // namespace __sanitizer + INTERCEPTOR(malloc_zone_t *, malloc_create_zone, vm_size_t start_size, unsigned zone_flags) { COMMON_MALLOC_ENTER(); @@ -70,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 @@ -205,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" @@ -245,6 +275,13 @@ void *__sanitizer_mz_memalign(malloc_zone_t *zone, size_t align, size_t size) { return p; } +// This public API exists purely for testing purposes. +extern "C" +SANITIZER_INTERFACE_ATTRIBUTE +malloc_zone_t* __sanitizer_mz_default_zone() { + return &sanitizer_zone; +} + // This function is currently unused, and we build with -Werror. #if 0 void __sanitizer_mz_free_definite_size( @@ -254,13 +291,48 @@ void __sanitizer_mz_free_definite_size( } #endif -kern_return_t mi_enumerator(task_t task, void *, - unsigned type_mask, vm_address_t zone_address, - memory_reader_t reader, +#ifndef COMMON_MALLOC_HAS_ZONE_ENUMERATOR +#error "COMMON_MALLOC_HAS_ZONE_ENUMERATOR must be defined" +#endif +static_assert((COMMON_MALLOC_HAS_ZONE_ENUMERATOR) == 0 || + (COMMON_MALLOC_HAS_ZONE_ENUMERATOR) == 1, + "COMMON_MALLOC_HAS_ZONE_ENUMERATOR must be 0 or 1"); + +#if COMMON_MALLOC_HAS_ZONE_ENUMERATOR +// Forward declare and expect the implementation to provided by +// includer. +kern_return_t mi_enumerator(task_t task, void *, unsigned type_mask, + vm_address_t zone_address, memory_reader_t reader, + vm_range_recorder_t recorder); +#else +// Provide stub implementation that fails. +kern_return_t mi_enumerator(task_t task, void *, unsigned type_mask, + vm_address_t zone_address, memory_reader_t reader, vm_range_recorder_t recorder) { - // Should enumerate all the pointers we have. Seems like a lot of work. + // Not supported. return KERN_FAILURE; } +#endif + +#ifndef COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT +#error "COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT must be defined" +#endif +static_assert((COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT) == 0 || + (COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT) == 1, + "COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT must be 0 or 1"); +#if COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT +// Forward declare and expect the implementation to provided by +// includer. +void mi_extra_init( + sanitizer_malloc_introspection_t *mi); +#else +void mi_extra_init( + sanitizer_malloc_introspection_t *mi) { + // Just zero initialize the fields. + mi->allocator_ptr = 0; + mi->allocator_size = 0; +} +#endif size_t mi_good_size(malloc_zone_t *zone, size_t size) { // I think it's always safe to return size, but we maybe could do better. @@ -300,8 +372,8 @@ boolean_t mi_zone_locked(malloc_zone_t *zone) { namespace COMMON_MALLOC_NAMESPACE { -void ReplaceSystemMalloc() { - static malloc_introspection_t sanitizer_zone_introspection; +void InitMallocZoneFields() { + static sanitizer_malloc_introspection_t sanitizer_zone_introspection; // Ok to use internal_memset, these places are not performance-critical. internal_memset(&sanitizer_zone_introspection, 0, sizeof(sanitizer_zone_introspection)); @@ -316,6 +388,13 @@ void ReplaceSystemMalloc() { sanitizer_zone_introspection.statistics = &mi_statistics; sanitizer_zone_introspection.zone_locked = &mi_zone_locked; + // Set current allocator enumeration version. + sanitizer_zone_introspection.allocator_enumeration_version = + GetMallocZoneAllocatorEnumerationVersion(); + + // Perform any sanitizer specific initialization. + mi_extra_init(&sanitizer_zone_introspection); + internal_memset(&sanitizer_zone, 0, sizeof(malloc_zone_t)); // Use version 6 for OSX >= 10.6. @@ -333,6 +412,10 @@ void ReplaceSystemMalloc() { sanitizer_zone.free_definite_size = 0; sanitizer_zone.memalign = &__sanitizer_mz_memalign; sanitizer_zone.introspect = &sanitizer_zone_introspection; +} + +void ReplaceSystemMalloc() { + InitMallocZoneFields(); // Register the zone. malloc_zone_register(&sanitizer_zone); diff --git a/libsanitizer/sanitizer_common/sanitizer_mutex.h b/libsanitizer/sanitizer_common/sanitizer_mutex.h index 2b7f7d24f2e..40a65914299 100644 --- a/libsanitizer/sanitizer_common/sanitizer_mutex.h +++ b/libsanitizer/sanitizer_common/sanitizer_mutex.h @@ -1,7 +1,8 @@ //===-- sanitizer_mutex.h ---------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_netbsd.cc b/libsanitizer/sanitizer_common/sanitizer_netbsd.cpp similarity index 90% rename from libsanitizer/sanitizer_common/sanitizer_netbsd.cc rename to libsanitizer/sanitizer_common/sanitizer_netbsd.cpp index d0df94d1f95..4e74f6a3b51 100644 --- a/libsanitizer/sanitizer_common/sanitizer_netbsd.cc +++ b/libsanitizer/sanitizer_common/sanitizer_netbsd.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_netbsd.cc -----------------------------------------------===// +//===-- sanitizer_netbsd.cpp ----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -167,6 +168,11 @@ uptr internal_filesize(fd_t fd) { return (uptr)st.st_size; } +uptr internal_dup(int oldfd) { + DEFINE__REAL(int, dup, int a); + return _REAL(dup, oldfd); +} + uptr internal_dup2(int oldfd, int newfd) { DEFINE__REAL(int, dup2, int a, int b); return _REAL(dup2, oldfd, newfd); @@ -200,7 +206,7 @@ void internal__exit(int exitcode) { unsigned int internal_sleep(unsigned int seconds) { struct timespec ts; - ts.tv_sec = 1; + ts.tv_sec = seconds; ts.tv_nsec = 0; CHECK(&_sys___nanosleep50); int res = _sys___nanosleep50(&ts, &ts); @@ -239,10 +245,9 @@ uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) { return _REAL(__clock_gettime50, clk_id, tp); } -uptr internal_ptrace(int request, int pid, void *addr, void *data) { - Printf("internal_ptrace not implemented for NetBSD"); - Die(); - return 0; +uptr internal_ptrace(int request, int pid, void *addr, int data) { + DEFINE__REAL(int, ptrace, int a, int b, void *c, int d); + return _REAL(ptrace, request, pid, addr, data); } uptr internal_waitpid(int pid, int *status, int options) { @@ -316,11 +321,16 @@ void internal_sigemptyset(__sanitizer_sigset_t *set) { (void)_REAL(__sigemptyset14, set); } -uptr intrnal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, - int *parent_tidptr, void *newtls, int *child_tidptr) { - Printf("internal_clone not implemented for NetBSD"); - Die(); - return 0; +void internal_sigdelset(__sanitizer_sigset_t *set, int signo) { + DEFINE__REAL(int, __sigdelset14, const void *a, int b); + (void)_REAL(__sigdelset14, set, signo); +} + +uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, + void *arg) { + DEFINE__REAL(int, clone, int (*a)(void *b), void *c, int d, void *e); + + return _REAL(clone, fn, child_stack, flags, arg); } } // namespace __sanitizer diff --git a/libsanitizer/sanitizer_common/sanitizer_openbsd.cc b/libsanitizer/sanitizer_common/sanitizer_openbsd.cpp similarity index 88% rename from libsanitizer/sanitizer_common/sanitizer_openbsd.cc rename to libsanitizer/sanitizer_common/sanitizer_openbsd.cpp index 6ff8b0d10a9..ed2d8edeb7a 100644 --- a/libsanitizer/sanitizer_common/sanitizer_openbsd.cc +++ b/libsanitizer/sanitizer_common/sanitizer_openbsd.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_openbsd.cc ----------------------------------------------===// +//===-- sanitizer_openbsd.cpp ---------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -99,6 +100,12 @@ char **GetArgv() { return argv; } +char **GetEnviron() { + char **argv, **envp; + GetArgsAndEnv(&argv, &envp); + return envp; +} + void ReExec() { UNIMPLEMENTED(); } diff --git a/libsanitizer/sanitizer_common/sanitizer_persistent_allocator.cc b/libsanitizer/sanitizer_common/sanitizer_persistent_allocator.cpp similarity index 61% rename from libsanitizer/sanitizer_common/sanitizer_persistent_allocator.cc rename to libsanitizer/sanitizer_common/sanitizer_persistent_allocator.cpp index b989ed0c90f..1ca0375b8a5 100644 --- a/libsanitizer/sanitizer_common/sanitizer_persistent_allocator.cc +++ b/libsanitizer/sanitizer_common/sanitizer_persistent_allocator.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_persistent_allocator.cc -----------------------*- C++ -*-===// +//===-- sanitizer_persistent_allocator.cpp ----------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_persistent_allocator.h b/libsanitizer/sanitizer_common/sanitizer_persistent_allocator.h index 71185033eff..de4fb6ebc3c 100644 --- a/libsanitizer/sanitizer_common/sanitizer_persistent_allocator.h +++ b/libsanitizer/sanitizer_common/sanitizer_persistent_allocator.h @@ -1,7 +1,8 @@ //===-- sanitizer_persistent_allocator.h ------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_placement_new.h b/libsanitizer/sanitizer_common/sanitizer_placement_new.h index 7231e96878d..1ceb8b90926 100644 --- a/libsanitizer/sanitizer_common/sanitizer_placement_new.h +++ b/libsanitizer/sanitizer_common/sanitizer_placement_new.h @@ -1,7 +1,8 @@ //===-- sanitizer_placement_new.h -------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_platform.h b/libsanitizer/sanitizer_common/sanitizer_platform.h index cc72d528713..b45c975358d 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform.h @@ -1,7 +1,8 @@ //===-- sanitizer_platform.h ------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -240,7 +241,7 @@ # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 48) # endif #elif defined(__sparc__) -# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 52) +#define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 52) #else # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47) #endif @@ -249,9 +250,9 @@ // The SPARC64 Linux port implements this to split the VMA space into two // non-contiguous halves with a huge hole in the middle. #if defined(__sparc__) && SANITIZER_WORDSIZE == 64 -# define SANITIZER_SIGN_EXTENDED_ADDRESSES 1 +#define SANITIZER_SIGN_EXTENDED_ADDRESSES 1 #else -# define SANITIZER_SIGN_EXTENDED_ADDRESSES 0 +#define SANITIZER_SIGN_EXTENDED_ADDRESSES 0 #endif // The AArch64 linux port uses the canonical syscall set as mandated by @@ -284,12 +285,6 @@ # define SANITIZER_POINTER_FORMAT_LENGTH FIRST_32_SECOND_64(8, 12) #endif -// Assume obsolete RPC headers are available by default -#if !defined(HAVE_RPC_XDR_H) && !defined(HAVE_TIRPC_RPC_XDR_H) -# define HAVE_RPC_XDR_H (SANITIZER_LINUX && !SANITIZER_ANDROID) -# define HAVE_TIRPC_RPC_XDR_H 0 -#endif - /// \macro MSC_PREREQ /// \brief Is the compiler MSVC of at least the specified version? /// The common \param version values to check for are: @@ -351,4 +346,13 @@ #define SANITIZER_SYMBOLIZER_MARKUP 0 #endif +// Enable ability to support sanitizer initialization that is +// compatible with the sanitizer library being loaded via +// `dlopen()`. +#if SANITIZER_MAC +#define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 1 +#else +#define SANITIZER_SUPPORTS_INIT_FOR_DLOPEN 0 +#endif + #endif // SANITIZER_PLATFORM_H diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h index d6fc2b9ce23..e7becbb0e20 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h @@ -1,7 +1,8 @@ //===-- sanitizer_platform_interceptors.h -----------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -31,8 +32,9 @@ #endif #if SI_POSIX +# include "sanitizer_platform_limits_freebsd.h" # include "sanitizer_platform_limits_netbsd.h" -#include "sanitizer_platform_limits_openbsd.h" +# include "sanitizer_platform_limits_openbsd.h" # include "sanitizer_platform_limits_posix.h" # include "sanitizer_platform_limits_solaris.h" #endif @@ -140,6 +142,9 @@ #define SANITIZER_INTERCEPT_MEMMOVE 1 #define SANITIZER_INTERCEPT_MEMCPY 1 #define SANITIZER_INTERCEPT_MEMCMP SI_NOT_FUCHSIA +#define SANITIZER_INTERCEPT_BCMP \ + SANITIZER_INTERCEPT_MEMCMP && \ + ((SI_POSIX && _GNU_SOURCE) || SI_NETBSD || SI_OPENBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT_STRNDUP SI_POSIX #define SANITIZER_INTERCEPT___STRNDUP SI_LINUX_NOT_FREEBSD #if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ @@ -205,9 +210,13 @@ #define SANITIZER_INTERCEPT_GETPWENT \ (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \ SI_SOLARIS) +#define SANITIZER_INTERCEPT_FGETGRENT_R \ + (SI_FREEBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_FGETPWENT SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_GETPWENT_R \ (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) +#define SANITIZER_INTERCEPT_FGETPWENT_R \ + (SI_FREEBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_SETPWENT \ (SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_CLOCK_GETTIME \ @@ -274,6 +283,9 @@ #define SANITIZER_INTERCEPT_WCRTOMB \ (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \ SI_SOLARIS) +#define SANITIZER_INTERCEPT_WCTOMB \ + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \ + SI_SOLARIS) #define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_REALPATH SI_POSIX #define SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME \ @@ -302,6 +314,7 @@ (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_SIGPENDING SI_POSIX #define SANITIZER_INTERCEPT_SIGPROCMASK SI_POSIX +#define SANITIZER_INTERCEPT_PTHREAD_SIGMASK SI_POSIX #define SANITIZER_INTERCEPT_BACKTRACE \ (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_GETMNTENT SI_LINUX @@ -350,11 +363,14 @@ #define SANITIZER_INTERCEPT_THR_EXIT SI_FREEBSD #define SANITIZER_INTERCEPT_TMPNAM SI_POSIX #define SANITIZER_INTERCEPT_TMPNAM_R SI_LINUX_NOT_ANDROID || SI_SOLARIS +#define SANITIZER_INTERCEPT_TTYNAME SI_POSIX #define SANITIZER_INTERCEPT_TTYNAME_R SI_POSIX #define SANITIZER_INTERCEPT_TEMPNAM SI_POSIX #define SANITIZER_INTERCEPT_SINCOS SI_LINUX || SI_SOLARIS #define SANITIZER_INTERCEPT_REMQUO SI_POSIX +#define SANITIZER_INTERCEPT_REMQUOL (SI_POSIX && !SI_NETBSD) #define SANITIZER_INTERCEPT_LGAMMA SI_POSIX +#define SANITIZER_INTERCEPT_LGAMMAL (SI_POSIX && !SI_NETBSD) #define SANITIZER_INTERCEPT_LGAMMA_R (SI_FREEBSD || SI_LINUX || SI_SOLARIS) #define SANITIZER_INTERCEPT_LGAMMAL_R SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_DRAND48_R SI_LINUX_NOT_ANDROID @@ -378,7 +394,7 @@ #define SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP \ (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_GETNAME_NP \ - (SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) + (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_TLS_GET_ADDR \ (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) @@ -398,7 +414,8 @@ #else #define SANITIZER_INTERCEPT_AEABI_MEM 0 #endif -#define SANITIZER_INTERCEPT___BZERO SI_MAC +#define SANITIZER_INTERCEPT___BZERO SI_MAC || SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_BZERO SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_FTIME \ (!SI_FREEBSD && !SI_NETBSD && !SI_OPENBSD && SI_POSIX) #define SANITIZER_INTERCEPT_XDR SI_LINUX_NOT_ANDROID || SI_SOLARIS @@ -470,10 +487,12 @@ #define SANITIZER_INTERCEPT_CFREE \ (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA && \ 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_MCHECK_MPROBE SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_WCSCAT SI_POSIX +#define SANITIZER_INTERCEPT_WCSDUP SI_POSIX #define SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION (!SI_WINDOWS && SI_NOT_FUCHSIA) #define SANITIZER_INTERCEPT_BSD_SIGNAL SI_ANDROID @@ -508,5 +527,45 @@ #define SANITIZER_INTERCEPT_TTYENT SI_NETBSD #define SANITIZER_INTERCEPT_PROTOENT SI_NETBSD #define SANITIZER_INTERCEPT_NETENT SI_NETBSD +#define SANITIZER_INTERCEPT_SETVBUF (SI_NETBSD || SI_FREEBSD || \ + SI_LINUX || SI_MAC) +#define SANITIZER_INTERCEPT_GETMNTINFO (SI_NETBSD || SI_FREEBSD || SI_MAC) +#define SANITIZER_INTERCEPT_MI_VECTOR_HASH SI_NETBSD +#define SANITIZER_INTERCEPT_GETVFSSTAT SI_NETBSD +#define SANITIZER_INTERCEPT_REGEX (SI_NETBSD || SI_FREEBSD || SI_LINUX) +#define SANITIZER_INTERCEPT_REGEXSUB SI_NETBSD +#define SANITIZER_INTERCEPT_FTS (SI_NETBSD || SI_FREEBSD) +#define SANITIZER_INTERCEPT_SYSCTL (SI_NETBSD || SI_FREEBSD || SI_MAC) +#define SANITIZER_INTERCEPT_ASYSCTL SI_NETBSD +#define SANITIZER_INTERCEPT_SYSCTLGETMIBINFO SI_NETBSD +#define SANITIZER_INTERCEPT_NL_LANGINFO (SI_NETBSD || SI_FREEBSD || SI_MAC) +#define SANITIZER_INTERCEPT_MODCTL SI_NETBSD +#define SANITIZER_INTERCEPT_CAPSICUM SI_FREEBSD +#define SANITIZER_INTERCEPT_STRTONUM (SI_NETBSD || SI_FREEBSD) +#define SANITIZER_INTERCEPT_FPARSELN SI_NETBSD +#define SANITIZER_INTERCEPT_STATVFS1 SI_NETBSD +#define SANITIZER_INTERCEPT_STRTOI SI_NETBSD +#define SANITIZER_INTERCEPT_CAPSICUM SI_FREEBSD +#define SANITIZER_INTERCEPT_SHA1 SI_NETBSD +#define SANITIZER_INTERCEPT_MD4 SI_NETBSD +#define SANITIZER_INTERCEPT_RMD160 SI_NETBSD +#define SANITIZER_INTERCEPT_MD5 SI_NETBSD +#define SANITIZER_INTERCEPT_FSEEK (SI_NETBSD || SI_FREEBSD) +#define SANITIZER_INTERCEPT_MD2 SI_NETBSD +#define SANITIZER_INTERCEPT_SHA2 SI_NETBSD +#define SANITIZER_INTERCEPT_CDB SI_NETBSD +#define SANITIZER_INTERCEPT_VIS (SI_NETBSD || SI_FREEBSD) +#define SANITIZER_INTERCEPT_POPEN SI_POSIX +#define SANITIZER_INTERCEPT_POPENVE SI_NETBSD +#define SANITIZER_INTERCEPT_PCLOSE SI_POSIX +#define SANITIZER_INTERCEPT_FUNOPEN (SI_NETBSD || SI_FREEBSD) +#define SANITIZER_INTERCEPT_FUNOPEN2 SI_NETBSD +#define SANITIZER_INTERCEPT_GETFSENT (SI_FREEBSD || SI_NETBSD || SI_MAC) +#define SANITIZER_INTERCEPT_ARC4RANDOM (SI_FREEBSD || SI_NETBSD) +#define SANITIZER_INTERCEPT_FDEVNAME SI_FREEBSD +#define SANITIZER_INTERCEPT_GETUSERSHELL (SI_POSIX && !SI_ANDROID) +#define SANITIZER_INTERCEPT_SL_INIT (SI_FREEBSD || SI_NETBSD) + +#define SANITIZER_INTERCEPT_GETRANDOM SI_LINUX #endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.cpp b/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.cpp new file mode 100644 index 00000000000..2d1bb1a12da --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.cpp @@ -0,0 +1,525 @@ +//===-- 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. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of Sanitizer common code. +// +// Sizes and layouts of platform-specific FreeBSD data structures. +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" + +#if SANITIZER_FREEBSD + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +#define _KERNEL // to declare 'shminfo' structure +# include +#undef _KERNEL + +#undef INLINE // to avoid clashes with sanitizers' definitions + +#undef IOC_DIRMASK + +# include +# include +# include + +#include +#include +#include + +// Include these after system headers to avoid name clashes and ambiguities. +#include "sanitizer_internal_defs.h" +#include "sanitizer_platform_limits_freebsd.h" + +namespace __sanitizer { + unsigned struct_cap_rights_sz = sizeof(cap_rights_t); + unsigned struct_utsname_sz = sizeof(struct utsname); + unsigned struct_stat_sz = sizeof(struct stat); + unsigned struct_rusage_sz = sizeof(struct rusage); + unsigned struct_tm_sz = sizeof(struct tm); + unsigned struct_passwd_sz = sizeof(struct passwd); + unsigned struct_group_sz = sizeof(struct group); + unsigned siginfo_t_sz = sizeof(siginfo_t); + unsigned struct_sigaction_sz = sizeof(struct sigaction); + unsigned struct_itimerval_sz = sizeof(struct itimerval); + unsigned pthread_t_sz = sizeof(pthread_t); + unsigned pthread_mutex_t_sz = sizeof(pthread_mutex_t); + unsigned pthread_cond_t_sz = sizeof(pthread_cond_t); + unsigned pid_t_sz = sizeof(pid_t); + unsigned timeval_sz = sizeof(timeval); + unsigned uid_t_sz = sizeof(uid_t); + unsigned gid_t_sz = sizeof(gid_t); + unsigned fpos_t_sz = sizeof(fpos_t); + unsigned mbstate_t_sz = sizeof(mbstate_t); + unsigned sigset_t_sz = sizeof(sigset_t); + unsigned struct_timezone_sz = sizeof(struct timezone); + unsigned struct_tms_sz = sizeof(struct tms); + unsigned struct_sigevent_sz = sizeof(struct sigevent); + unsigned struct_sched_param_sz = sizeof(struct sched_param); + unsigned struct_statfs_sz = sizeof(struct statfs); + unsigned struct_sockaddr_sz = sizeof(struct sockaddr); + unsigned ucontext_t_sz = sizeof(ucontext_t); + unsigned struct_rlimit_sz = sizeof(struct rlimit); + unsigned struct_timespec_sz = sizeof(struct timespec); + unsigned struct_utimbuf_sz = sizeof(struct utimbuf); + unsigned struct_itimerspec_sz = sizeof(struct itimerspec); + unsigned struct_timeb_sz = sizeof(struct timeb); + unsigned struct_msqid_ds_sz = sizeof(struct msqid_ds); + unsigned struct_mq_attr_sz = sizeof(struct mq_attr); + unsigned struct_statvfs_sz = sizeof(struct statvfs); + unsigned struct_shminfo_sz = sizeof(struct shminfo); + unsigned struct_shm_info_sz = sizeof(struct shm_info); + unsigned struct_regmatch_sz = sizeof(regmatch_t); + unsigned struct_regex_sz = sizeof(regex_t); + unsigned struct_fstab_sz = sizeof(struct fstab); + unsigned struct_FTS_sz = sizeof(FTS); + unsigned struct_FTSENT_sz = sizeof(FTSENT); + unsigned struct_StringList_sz = sizeof(StringList); + + const uptr sig_ign = (uptr)SIG_IGN; + const uptr sig_dfl = (uptr)SIG_DFL; + const uptr sig_err = (uptr)SIG_ERR; + const uptr sa_siginfo = (uptr)SA_SIGINFO; + + int shmctl_ipc_stat = (int)IPC_STAT; + int shmctl_ipc_info = (int)IPC_INFO; + int shmctl_shm_info = (int)SHM_INFO; + int shmctl_shm_stat = (int)SHM_STAT; + unsigned struct_utmpx_sz = sizeof(struct utmpx); + + int map_fixed = MAP_FIXED; + + int af_inet = (int)AF_INET; + int af_inet6 = (int)AF_INET6; + + uptr __sanitizer_in_addr_sz(int af) { + if (af == AF_INET) + return sizeof(struct in_addr); + else if (af == AF_INET6) + return sizeof(struct in6_addr); + else + return 0; + } + + unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); + int glob_nomatch = GLOB_NOMATCH; + int glob_altdirfunc = GLOB_ALTDIRFUNC; + + unsigned path_max = PATH_MAX; + + // ioctl arguments + unsigned struct_ifreq_sz = sizeof(struct ifreq); + unsigned struct_termios_sz = sizeof(struct termios); + unsigned struct_winsize_sz = sizeof(struct winsize); +#if SOUND_VERSION >= 0x040000 + unsigned struct_copr_buffer_sz = 0; + unsigned struct_copr_debug_buf_sz = 0; + unsigned struct_copr_msg_sz = 0; +#else + unsigned struct_copr_buffer_sz = sizeof(struct copr_buffer); + unsigned struct_copr_debug_buf_sz = sizeof(struct copr_debug_buf); + unsigned struct_copr_msg_sz = sizeof(struct copr_msg); +#endif + unsigned struct_midi_info_sz = sizeof(struct midi_info); + unsigned struct_mtget_sz = sizeof(struct mtget); + unsigned struct_mtop_sz = sizeof(struct mtop); + unsigned struct_sbi_instrument_sz = sizeof(struct sbi_instrument); + unsigned struct_seq_event_rec_sz = sizeof(struct seq_event_rec); + unsigned struct_synth_info_sz = sizeof(struct synth_info); + unsigned struct_audio_buf_info_sz = sizeof(struct audio_buf_info); + unsigned struct_ppp_stats_sz = sizeof(struct ppp_stats); + unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req); + unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req); + const unsigned long __sanitizer_bufsiz = BUFSIZ; + + const unsigned IOCTL_NOT_PRESENT = 0; + + unsigned IOCTL_FIOASYNC = FIOASYNC; + unsigned IOCTL_FIOCLEX = FIOCLEX; + unsigned IOCTL_FIOGETOWN = FIOGETOWN; + unsigned IOCTL_FIONBIO = FIONBIO; + unsigned IOCTL_FIONCLEX = FIONCLEX; + unsigned IOCTL_FIOSETOWN = FIOSETOWN; + unsigned IOCTL_SIOCADDMULTI = SIOCADDMULTI; + unsigned IOCTL_SIOCATMARK = SIOCATMARK; + unsigned IOCTL_SIOCDELMULTI = SIOCDELMULTI; + unsigned IOCTL_SIOCGIFADDR = SIOCGIFADDR; + unsigned IOCTL_SIOCGIFBRDADDR = SIOCGIFBRDADDR; + unsigned IOCTL_SIOCGIFCONF = SIOCGIFCONF; + unsigned IOCTL_SIOCGIFDSTADDR = SIOCGIFDSTADDR; + unsigned IOCTL_SIOCGIFFLAGS = SIOCGIFFLAGS; + unsigned IOCTL_SIOCGIFMETRIC = SIOCGIFMETRIC; + unsigned IOCTL_SIOCGIFMTU = SIOCGIFMTU; + unsigned IOCTL_SIOCGIFNETMASK = SIOCGIFNETMASK; + unsigned IOCTL_SIOCGPGRP = SIOCGPGRP; + unsigned IOCTL_SIOCSIFADDR = SIOCSIFADDR; + unsigned IOCTL_SIOCSIFBRDADDR = SIOCSIFBRDADDR; + unsigned IOCTL_SIOCSIFDSTADDR = SIOCSIFDSTADDR; + unsigned IOCTL_SIOCSIFFLAGS = SIOCSIFFLAGS; + unsigned IOCTL_SIOCSIFMETRIC = SIOCSIFMETRIC; + unsigned IOCTL_SIOCSIFMTU = SIOCSIFMTU; + unsigned IOCTL_SIOCSIFNETMASK = SIOCSIFNETMASK; + unsigned IOCTL_SIOCSPGRP = SIOCSPGRP; + unsigned IOCTL_TIOCCONS = TIOCCONS; + unsigned IOCTL_TIOCEXCL = TIOCEXCL; + unsigned IOCTL_TIOCGETD = TIOCGETD; + unsigned IOCTL_TIOCGPGRP = TIOCGPGRP; + unsigned IOCTL_TIOCGWINSZ = TIOCGWINSZ; + unsigned IOCTL_TIOCMBIC = TIOCMBIC; + unsigned IOCTL_TIOCMBIS = TIOCMBIS; + unsigned IOCTL_TIOCMGET = TIOCMGET; + unsigned IOCTL_TIOCMSET = TIOCMSET; + unsigned IOCTL_TIOCNOTTY = TIOCNOTTY; + unsigned IOCTL_TIOCNXCL = TIOCNXCL; + unsigned IOCTL_TIOCOUTQ = TIOCOUTQ; + unsigned IOCTL_TIOCPKT = TIOCPKT; + unsigned IOCTL_TIOCSCTTY = TIOCSCTTY; + unsigned IOCTL_TIOCSETD = TIOCSETD; + unsigned IOCTL_TIOCSPGRP = TIOCSPGRP; + unsigned IOCTL_TIOCSTI = TIOCSTI; + unsigned IOCTL_TIOCSWINSZ = TIOCSWINSZ; + unsigned IOCTL_SIOCGETSGCNT = SIOCGETSGCNT; + unsigned IOCTL_SIOCGETVIFCNT = SIOCGETVIFCNT; + unsigned IOCTL_MTIOCGET = MTIOCGET; + unsigned IOCTL_MTIOCTOP = MTIOCTOP; + unsigned IOCTL_SNDCTL_DSP_GETBLKSIZE = SNDCTL_DSP_GETBLKSIZE; + unsigned IOCTL_SNDCTL_DSP_GETFMTS = SNDCTL_DSP_GETFMTS; + unsigned IOCTL_SNDCTL_DSP_NONBLOCK = SNDCTL_DSP_NONBLOCK; + unsigned IOCTL_SNDCTL_DSP_POST = SNDCTL_DSP_POST; + unsigned IOCTL_SNDCTL_DSP_RESET = SNDCTL_DSP_RESET; + unsigned IOCTL_SNDCTL_DSP_SETFMT = SNDCTL_DSP_SETFMT; + unsigned IOCTL_SNDCTL_DSP_SETFRAGMENT = SNDCTL_DSP_SETFRAGMENT; + unsigned IOCTL_SNDCTL_DSP_SPEED = SNDCTL_DSP_SPEED; + unsigned IOCTL_SNDCTL_DSP_STEREO = SNDCTL_DSP_STEREO; + unsigned IOCTL_SNDCTL_DSP_SUBDIVIDE = SNDCTL_DSP_SUBDIVIDE; + unsigned IOCTL_SNDCTL_DSP_SYNC = SNDCTL_DSP_SYNC; + unsigned IOCTL_SNDCTL_FM_4OP_ENABLE = SNDCTL_FM_4OP_ENABLE; + unsigned IOCTL_SNDCTL_FM_LOAD_INSTR = SNDCTL_FM_LOAD_INSTR; + unsigned IOCTL_SNDCTL_MIDI_INFO = SNDCTL_MIDI_INFO; + unsigned IOCTL_SNDCTL_MIDI_PRETIME = SNDCTL_MIDI_PRETIME; + unsigned IOCTL_SNDCTL_SEQ_CTRLRATE = SNDCTL_SEQ_CTRLRATE; + unsigned IOCTL_SNDCTL_SEQ_GETINCOUNT = SNDCTL_SEQ_GETINCOUNT; + unsigned IOCTL_SNDCTL_SEQ_GETOUTCOUNT = SNDCTL_SEQ_GETOUTCOUNT; + unsigned IOCTL_SNDCTL_SEQ_NRMIDIS = SNDCTL_SEQ_NRMIDIS; + unsigned IOCTL_SNDCTL_SEQ_NRSYNTHS = SNDCTL_SEQ_NRSYNTHS; + unsigned IOCTL_SNDCTL_SEQ_OUTOFBAND = SNDCTL_SEQ_OUTOFBAND; + unsigned IOCTL_SNDCTL_SEQ_PANIC = SNDCTL_SEQ_PANIC; + unsigned IOCTL_SNDCTL_SEQ_PERCMODE = SNDCTL_SEQ_PERCMODE; + unsigned IOCTL_SNDCTL_SEQ_RESET = SNDCTL_SEQ_RESET; + unsigned IOCTL_SNDCTL_SEQ_RESETSAMPLES = SNDCTL_SEQ_RESETSAMPLES; + unsigned IOCTL_SNDCTL_SEQ_SYNC = SNDCTL_SEQ_SYNC; + unsigned IOCTL_SNDCTL_SEQ_TESTMIDI = SNDCTL_SEQ_TESTMIDI; + unsigned IOCTL_SNDCTL_SEQ_THRESHOLD = SNDCTL_SEQ_THRESHOLD; + unsigned IOCTL_SNDCTL_SYNTH_INFO = SNDCTL_SYNTH_INFO; + unsigned IOCTL_SNDCTL_SYNTH_MEMAVL = SNDCTL_SYNTH_MEMAVL; + unsigned IOCTL_SNDCTL_TMR_CONTINUE = SNDCTL_TMR_CONTINUE; + unsigned IOCTL_SNDCTL_TMR_METRONOME = SNDCTL_TMR_METRONOME; + unsigned IOCTL_SNDCTL_TMR_SELECT = SNDCTL_TMR_SELECT; + unsigned IOCTL_SNDCTL_TMR_SOURCE = SNDCTL_TMR_SOURCE; + unsigned IOCTL_SNDCTL_TMR_START = SNDCTL_TMR_START; + unsigned IOCTL_SNDCTL_TMR_STOP = SNDCTL_TMR_STOP; + unsigned IOCTL_SNDCTL_TMR_TEMPO = SNDCTL_TMR_TEMPO; + unsigned IOCTL_SNDCTL_TMR_TIMEBASE = SNDCTL_TMR_TIMEBASE; + unsigned IOCTL_SOUND_MIXER_READ_ALTPCM = SOUND_MIXER_READ_ALTPCM; + unsigned IOCTL_SOUND_MIXER_READ_BASS = SOUND_MIXER_READ_BASS; + unsigned IOCTL_SOUND_MIXER_READ_CAPS = SOUND_MIXER_READ_CAPS; + unsigned IOCTL_SOUND_MIXER_READ_CD = SOUND_MIXER_READ_CD; + unsigned IOCTL_SOUND_MIXER_READ_DEVMASK = SOUND_MIXER_READ_DEVMASK; + unsigned IOCTL_SOUND_MIXER_READ_ENHANCE = SOUND_MIXER_READ_ENHANCE; + unsigned IOCTL_SOUND_MIXER_READ_IGAIN = SOUND_MIXER_READ_IGAIN; + unsigned IOCTL_SOUND_MIXER_READ_IMIX = SOUND_MIXER_READ_IMIX; + unsigned IOCTL_SOUND_MIXER_READ_LINE = SOUND_MIXER_READ_LINE; + unsigned IOCTL_SOUND_MIXER_READ_LINE1 = SOUND_MIXER_READ_LINE1; + unsigned IOCTL_SOUND_MIXER_READ_LINE2 = SOUND_MIXER_READ_LINE2; + unsigned IOCTL_SOUND_MIXER_READ_LINE3 = SOUND_MIXER_READ_LINE3; + unsigned IOCTL_SOUND_MIXER_READ_LOUD = SOUND_MIXER_READ_LOUD; + unsigned IOCTL_SOUND_MIXER_READ_MIC = SOUND_MIXER_READ_MIC; + unsigned IOCTL_SOUND_MIXER_READ_MUTE = SOUND_MIXER_READ_MUTE; + unsigned IOCTL_SOUND_MIXER_READ_OGAIN = SOUND_MIXER_READ_OGAIN; + unsigned IOCTL_SOUND_MIXER_READ_PCM = SOUND_MIXER_READ_PCM; + unsigned IOCTL_SOUND_MIXER_READ_RECLEV = SOUND_MIXER_READ_RECLEV; + unsigned IOCTL_SOUND_MIXER_READ_RECMASK = SOUND_MIXER_READ_RECMASK; + unsigned IOCTL_SOUND_MIXER_READ_RECSRC = SOUND_MIXER_READ_RECSRC; + unsigned IOCTL_SOUND_MIXER_READ_SPEAKER = SOUND_MIXER_READ_SPEAKER; + unsigned IOCTL_SOUND_MIXER_READ_STEREODEVS = SOUND_MIXER_READ_STEREODEVS; + unsigned IOCTL_SOUND_MIXER_READ_SYNTH = SOUND_MIXER_READ_SYNTH; + unsigned IOCTL_SOUND_MIXER_READ_TREBLE = SOUND_MIXER_READ_TREBLE; + unsigned IOCTL_SOUND_MIXER_READ_VOLUME = SOUND_MIXER_READ_VOLUME; + unsigned IOCTL_SOUND_MIXER_WRITE_ALTPCM = SOUND_MIXER_WRITE_ALTPCM; + unsigned IOCTL_SOUND_MIXER_WRITE_BASS = SOUND_MIXER_WRITE_BASS; + unsigned IOCTL_SOUND_MIXER_WRITE_CD = SOUND_MIXER_WRITE_CD; + unsigned IOCTL_SOUND_MIXER_WRITE_ENHANCE = SOUND_MIXER_WRITE_ENHANCE; + unsigned IOCTL_SOUND_MIXER_WRITE_IGAIN = SOUND_MIXER_WRITE_IGAIN; + unsigned IOCTL_SOUND_MIXER_WRITE_IMIX = SOUND_MIXER_WRITE_IMIX; + unsigned IOCTL_SOUND_MIXER_WRITE_LINE = SOUND_MIXER_WRITE_LINE; + unsigned IOCTL_SOUND_MIXER_WRITE_LINE1 = SOUND_MIXER_WRITE_LINE1; + unsigned IOCTL_SOUND_MIXER_WRITE_LINE2 = SOUND_MIXER_WRITE_LINE2; + unsigned IOCTL_SOUND_MIXER_WRITE_LINE3 = SOUND_MIXER_WRITE_LINE3; + unsigned IOCTL_SOUND_MIXER_WRITE_LOUD = SOUND_MIXER_WRITE_LOUD; + unsigned IOCTL_SOUND_MIXER_WRITE_MIC = SOUND_MIXER_WRITE_MIC; + unsigned IOCTL_SOUND_MIXER_WRITE_MUTE = SOUND_MIXER_WRITE_MUTE; + unsigned IOCTL_SOUND_MIXER_WRITE_OGAIN = SOUND_MIXER_WRITE_OGAIN; + unsigned IOCTL_SOUND_MIXER_WRITE_PCM = SOUND_MIXER_WRITE_PCM; + unsigned IOCTL_SOUND_MIXER_WRITE_RECLEV = SOUND_MIXER_WRITE_RECLEV; + unsigned IOCTL_SOUND_MIXER_WRITE_RECSRC = SOUND_MIXER_WRITE_RECSRC; + unsigned IOCTL_SOUND_MIXER_WRITE_SPEAKER = SOUND_MIXER_WRITE_SPEAKER; + unsigned IOCTL_SOUND_MIXER_WRITE_SYNTH = SOUND_MIXER_WRITE_SYNTH; + unsigned IOCTL_SOUND_MIXER_WRITE_TREBLE = SOUND_MIXER_WRITE_TREBLE; + unsigned IOCTL_SOUND_MIXER_WRITE_VOLUME = SOUND_MIXER_WRITE_VOLUME; + unsigned IOCTL_VT_ACTIVATE = VT_ACTIVATE; + unsigned IOCTL_VT_GETMODE = VT_GETMODE; + unsigned IOCTL_VT_OPENQRY = VT_OPENQRY; + unsigned IOCTL_VT_RELDISP = VT_RELDISP; + unsigned IOCTL_VT_SETMODE = VT_SETMODE; + unsigned IOCTL_VT_WAITACTIVE = VT_WAITACTIVE; + unsigned IOCTL_GIO_SCRNMAP = GIO_SCRNMAP; + unsigned IOCTL_KDDISABIO = KDDISABIO; + unsigned IOCTL_KDENABIO = KDENABIO; + unsigned IOCTL_KDGETLED = KDGETLED; + unsigned IOCTL_KDGETMODE = KDGETMODE; + unsigned IOCTL_KDGKBMODE = KDGKBMODE; + unsigned IOCTL_KDGKBTYPE = KDGKBTYPE; + unsigned IOCTL_KDMKTONE = KDMKTONE; + unsigned IOCTL_KDSETLED = KDSETLED; + unsigned IOCTL_KDSETMODE = KDSETMODE; + unsigned IOCTL_KDSKBMODE = KDSKBMODE; + unsigned IOCTL_KIOCSOUND = KIOCSOUND; + unsigned IOCTL_PIO_SCRNMAP = PIO_SCRNMAP; + unsigned IOCTL_SNDCTL_DSP_GETISPACE = SNDCTL_DSP_GETISPACE; + + const int si_SEGV_MAPERR = SEGV_MAPERR; + const int si_SEGV_ACCERR = SEGV_ACCERR; + const int unvis_valid = UNVIS_VALID; + const int unvis_validpush = UNVIS_VALIDPUSH; +} // namespace __sanitizer + +using namespace __sanitizer; + +COMPILER_CHECK(sizeof(__sanitizer_pthread_attr_t) >= sizeof(pthread_attr_t)); + +COMPILER_CHECK(sizeof(socklen_t) == sizeof(unsigned)); +CHECK_TYPE_SIZE(pthread_key_t); + +// There are more undocumented fields in dl_phdr_info that we are not interested +// in. +COMPILER_CHECK(sizeof(__sanitizer_dl_phdr_info) <= sizeof(dl_phdr_info)); +CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_addr); +CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_name); +CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phdr); +CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phnum); + +CHECK_TYPE_SIZE(glob_t); +CHECK_SIZE_AND_OFFSET(glob_t, gl_pathc); +CHECK_SIZE_AND_OFFSET(glob_t, gl_pathv); +CHECK_SIZE_AND_OFFSET(glob_t, gl_offs); +CHECK_SIZE_AND_OFFSET(glob_t, gl_flags); +CHECK_SIZE_AND_OFFSET(glob_t, gl_closedir); +CHECK_SIZE_AND_OFFSET(glob_t, gl_readdir); +CHECK_SIZE_AND_OFFSET(glob_t, gl_opendir); +CHECK_SIZE_AND_OFFSET(glob_t, gl_lstat); +CHECK_SIZE_AND_OFFSET(glob_t, gl_stat); + +CHECK_TYPE_SIZE(addrinfo); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_flags); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_family); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_socktype); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_protocol); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_protocol); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_addrlen); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_canonname); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_addr); + +CHECK_TYPE_SIZE(hostent); +CHECK_SIZE_AND_OFFSET(hostent, h_name); +CHECK_SIZE_AND_OFFSET(hostent, h_aliases); +CHECK_SIZE_AND_OFFSET(hostent, h_addrtype); +CHECK_SIZE_AND_OFFSET(hostent, h_length); +CHECK_SIZE_AND_OFFSET(hostent, h_addr_list); + +CHECK_TYPE_SIZE(iovec); +CHECK_SIZE_AND_OFFSET(iovec, iov_base); +CHECK_SIZE_AND_OFFSET(iovec, iov_len); + +CHECK_TYPE_SIZE(msghdr); +CHECK_SIZE_AND_OFFSET(msghdr, msg_name); +CHECK_SIZE_AND_OFFSET(msghdr, msg_namelen); +CHECK_SIZE_AND_OFFSET(msghdr, msg_iov); +CHECK_SIZE_AND_OFFSET(msghdr, msg_iovlen); +CHECK_SIZE_AND_OFFSET(msghdr, msg_control); +CHECK_SIZE_AND_OFFSET(msghdr, msg_controllen); +CHECK_SIZE_AND_OFFSET(msghdr, msg_flags); + +CHECK_TYPE_SIZE(cmsghdr); +CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_len); +CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_level); +CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_type); + +COMPILER_CHECK(sizeof(__sanitizer_dirent) <= sizeof(dirent)); +CHECK_SIZE_AND_OFFSET(dirent, d_ino); +CHECK_SIZE_AND_OFFSET(dirent, d_reclen); + +CHECK_TYPE_SIZE(ifconf); +CHECK_SIZE_AND_OFFSET(ifconf, ifc_len); +CHECK_SIZE_AND_OFFSET(ifconf, ifc_ifcu); + +CHECK_TYPE_SIZE(pollfd); +CHECK_SIZE_AND_OFFSET(pollfd, fd); +CHECK_SIZE_AND_OFFSET(pollfd, events); +CHECK_SIZE_AND_OFFSET(pollfd, revents); + +CHECK_TYPE_SIZE(nfds_t); + +CHECK_TYPE_SIZE(sigset_t); + +COMPILER_CHECK(sizeof(__sanitizer_sigaction) == sizeof(struct sigaction)); +// Can't write checks for sa_handler and sa_sigaction due to them being +// preprocessor macros. +CHECK_STRUCT_SIZE_AND_OFFSET(sigaction, sa_mask); + +CHECK_TYPE_SIZE(wordexp_t); +CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordc); +CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordv); +CHECK_SIZE_AND_OFFSET(wordexp_t, we_offs); + +CHECK_TYPE_SIZE(tm); +CHECK_SIZE_AND_OFFSET(tm, tm_sec); +CHECK_SIZE_AND_OFFSET(tm, tm_min); +CHECK_SIZE_AND_OFFSET(tm, tm_hour); +CHECK_SIZE_AND_OFFSET(tm, tm_mday); +CHECK_SIZE_AND_OFFSET(tm, tm_mon); +CHECK_SIZE_AND_OFFSET(tm, tm_year); +CHECK_SIZE_AND_OFFSET(tm, tm_wday); +CHECK_SIZE_AND_OFFSET(tm, tm_yday); +CHECK_SIZE_AND_OFFSET(tm, tm_isdst); +CHECK_SIZE_AND_OFFSET(tm, tm_gmtoff); +CHECK_SIZE_AND_OFFSET(tm, tm_zone); + +CHECK_TYPE_SIZE(ether_addr); + +CHECK_TYPE_SIZE(ipc_perm); +CHECK_SIZE_AND_OFFSET(ipc_perm, key); +CHECK_SIZE_AND_OFFSET(ipc_perm, seq); +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); + +CHECK_TYPE_SIZE(shmid_ds); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_perm); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_segsz); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_atime); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_dtime); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_ctime); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_cpid); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_lpid); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_nattch); + +CHECK_TYPE_SIZE(clock_t); + +CHECK_TYPE_SIZE(ifaddrs); +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_next); +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name); +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_addr); +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_netmask); +#undef ifa_dstaddr +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_dstaddr); +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_data); + +CHECK_TYPE_SIZE(timeb); +CHECK_SIZE_AND_OFFSET(timeb, time); +CHECK_SIZE_AND_OFFSET(timeb, millitm); +CHECK_SIZE_AND_OFFSET(timeb, timezone); +CHECK_SIZE_AND_OFFSET(timeb, dstflag); + +CHECK_TYPE_SIZE(passwd); +CHECK_SIZE_AND_OFFSET(passwd, pw_name); +CHECK_SIZE_AND_OFFSET(passwd, pw_passwd); +CHECK_SIZE_AND_OFFSET(passwd, pw_uid); +CHECK_SIZE_AND_OFFSET(passwd, pw_gid); +CHECK_SIZE_AND_OFFSET(passwd, pw_dir); +CHECK_SIZE_AND_OFFSET(passwd, pw_shell); + +CHECK_SIZE_AND_OFFSET(passwd, pw_gecos); + +CHECK_TYPE_SIZE(group); +CHECK_SIZE_AND_OFFSET(group, gr_name); +CHECK_SIZE_AND_OFFSET(group, gr_passwd); +CHECK_SIZE_AND_OFFSET(group, gr_gid); +CHECK_SIZE_AND_OFFSET(group, gr_mem); + +#if HAVE_RPC_XDR_H +CHECK_TYPE_SIZE(XDR); +CHECK_SIZE_AND_OFFSET(XDR, x_op); +CHECK_SIZE_AND_OFFSET(XDR, x_ops); +CHECK_SIZE_AND_OFFSET(XDR, x_public); +CHECK_SIZE_AND_OFFSET(XDR, x_private); +CHECK_SIZE_AND_OFFSET(XDR, x_base); +CHECK_SIZE_AND_OFFSET(XDR, x_handy); +COMPILER_CHECK(__sanitizer_XDR_ENCODE == XDR_ENCODE); +COMPILER_CHECK(__sanitizer_XDR_DECODE == XDR_DECODE); +COMPILER_CHECK(__sanitizer_XDR_FREE == XDR_FREE); +#endif + +CHECK_TYPE_SIZE(sem_t); + +COMPILER_CHECK(sizeof(__sanitizer_cap_rights_t) >= sizeof(cap_rights_t)); +#endif // SANITIZER_FREEBSD diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.h new file mode 100644 index 00000000000..46307c6c434 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_freebsd.h @@ -0,0 +1,656 @@ +//===-- sanitizer_platform_limits_freebsd.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. +// +// Sizes and layouts of platform-specific FreeBSD data structures. +//===----------------------------------------------------------------------===// + +#ifndef SANITIZER_PLATFORM_LIMITS_FREEBSD_H +#define SANITIZER_PLATFORM_LIMITS_FREEBSD_H + +#if SANITIZER_FREEBSD + +#include "sanitizer_internal_defs.h" +#include "sanitizer_platform.h" + +#include "sanitizer_platform_limits_posix.h" + +// FreeBSD's dlopen() returns a pointer to an Obj_Entry structure that +// incorporates the map structure. +# define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ + ((link_map*)((handle) == nullptr ? nullptr : ((char*)(handle) + 560))) +// Get sys/_types.h, because that tells us whether 64-bit inodes are +// used in struct dirent below. +#include + +namespace __sanitizer { + extern unsigned struct_utsname_sz; + extern unsigned struct_stat_sz; +#if defined(__powerpc64__) + const unsigned struct___old_kernel_stat_sz = 0; +#else + 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; +#else + 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 { +#if defined(__INO64) + unsigned long long d_fileno; + unsigned long long d_off; +#else + unsigned int d_fileno; +#endif + 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; + +#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; +#endif + 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; +#else + 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 .cpp. + 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; + }; + +#define IOC_NRBITS 8 +#define IOC_TYPEBITS 8 +#if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__) +#define IOC_SIZEBITS 13 +#define IOC_DIRBITS 3 +#define IOC_NONE 1U +#define IOC_WRITE 4U +#define IOC_READ 2U +#else +#define IOC_SIZEBITS 14 +#define IOC_DIRBITS 2 +#define IOC_NONE 0U +#define IOC_WRITE 1U +#define IOC_READ 2U +#endif +#define IOC_NRMASK ((1 << IOC_NRBITS) - 1) +#define IOC_TYPEMASK ((1 << IOC_TYPEBITS) - 1) +#define IOC_SIZEMASK ((1 << IOC_SIZEBITS) - 1) +#if defined(IOC_DIRMASK) +#undef IOC_DIRMASK +#endif +#define IOC_DIRMASK ((1 << IOC_DIRBITS) - 1) +#define IOC_NRSHIFT 0 +#define IOC_TYPESHIFT (IOC_NRSHIFT + IOC_NRBITS) +#define IOC_SIZESHIFT (IOC_TYPESHIFT + IOC_TYPEBITS) +#define IOC_DIRSHIFT (IOC_SIZESHIFT + IOC_SIZEBITS) +#define EVIOC_EV_MAX 0x1f +#define EVIOC_ABS_MAX 0x3f + +#define IOC_DIR(nr) (((nr) >> IOC_DIRSHIFT) & IOC_DIRMASK) +#define IOC_TYPE(nr) (((nr) >> IOC_TYPESHIFT) & IOC_TYPEMASK) +#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; +} // 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) == \ + 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) == \ + offsetof(struct CLASS, MEMBER)) + +#define SIGACTION_SYMNAME sigaction + +#endif + +#endif // SANITIZER_FREEBSD diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp similarity index 86% rename from libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc rename to libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp index 3a906538129..842bc789f47 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_platform_limits_linux.cc --------------------------------===// +//===-- sanitizer_platform_limits_linux.cpp -------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -12,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 @@ -25,12 +26,9 @@ // With old kernels (and even new kernels on powerpc) asm/stat.h uses types that // are not defined anywhere in userspace headers. Fake them. This seems to work -// fine with newer headers, too. Beware that with , struct stat -// takes the form of struct stat64 on 32-bit platforms if _FILE_OFFSET_BITS=64. -// Also, for some platforms (e.g. mips) there are additional members in the -// struct stat:s. +// fine with newer headers, too. #include -#if defined(__x86_64__) +#if defined(__x86_64__) || defined(__mips__) #include #else #define ino_t __kernel_ino_t diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cpp similarity index 92% rename from libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cc rename to libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cpp index 8e74727c999..f01de6c995e 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cc +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_platform_limits_netbsd.cc -------------------------------===// +//===-- sanitizer_platform_limits_netbsd.cpp ------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -13,9 +14,82 @@ #include "sanitizer_platform.h" #if SANITIZER_NETBSD + +#define _KMEMUSER +#define RAY_DO_SIGLEV + +// clang-format off #include #include - +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include #include @@ -45,47 +119,39 @@ #include #include #include +#include #include #include #include -#include #include #include #include #include - #include #include - #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include #include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#define RAY_DO_SIGLEV +#include +#include +#include +#include +#include #include #include #include @@ -95,10 +161,13 @@ #include #include #include +#include #include +#include #include #include #include +#include #include #include #include @@ -113,86 +182,30 @@ #include #include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include #include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -//#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include #include #include #include @@ -200,8 +213,19 @@ #include #include #include +#include #include #include +#include +#include +#include +#include +#include + +#if defined(__x86_64__) +#include +#endif +// clang-format on // Include these after system headers to avoid name clashes and ambiguities. #include "sanitizer_internal_defs.h" @@ -236,6 +260,11 @@ unsigned struct_rlimit_sz = sizeof(struct rlimit); unsigned struct_timespec_sz = sizeof(struct timespec); unsigned struct_sembuf_sz = sizeof(struct sembuf); unsigned struct_kevent_sz = sizeof(struct kevent); +unsigned struct_FTS_sz = sizeof(FTS); +unsigned struct_FTSENT_sz = sizeof(FTSENT); +unsigned struct_regex_sz = sizeof(regex_t); +unsigned struct_regmatch_sz = sizeof(regmatch_t); +unsigned struct_fstab_sz = sizeof(struct fstab); unsigned struct_utimbuf_sz = sizeof(struct utimbuf); unsigned struct_itimerspec_sz = sizeof(struct itimerspec); unsigned struct_timex_sz = sizeof(struct timex); @@ -249,6 +278,8 @@ const uptr sig_dfl = (uptr)SIG_DFL; const uptr sig_err = (uptr)SIG_ERR; const uptr sa_siginfo = (uptr)SA_SIGINFO; +const unsigned long __sanitizer_bufsiz = BUFSIZ; + int ptrace_pt_io = PT_IO; int ptrace_pt_lwpinfo = PT_LWPINFO; int ptrace_pt_set_event_mask = PT_SET_EVENT_MASK; @@ -337,6 +368,14 @@ unsigned path_max = PATH_MAX; int struct_ttyent_sz = sizeof(struct ttyent); +struct __sanitizer_nvlist_ref_t { + void *buf; + uptr len; + int flags; +}; + +typedef __sanitizer_nvlist_ref_t nvlist_ref_t; + // ioctl arguments unsigned struct_altqreq_sz = sizeof(altqreq); unsigned struct_amr_user_ioctl_sz = sizeof(amr_user_ioctl); @@ -348,7 +387,6 @@ unsigned struct_atabusiodetach_args_sz = sizeof(atabusiodetach_args); unsigned struct_atabusioscan_args_sz = sizeof(atabusioscan_args); unsigned struct_ath_diag_sz = sizeof(ath_diag); unsigned struct_atm_flowmap_sz = sizeof(atm_flowmap); -unsigned struct_atm_pseudoioctl_sz = sizeof(atm_pseudoioctl); unsigned struct_audio_buf_info_sz = sizeof(audio_buf_info); unsigned struct_audio_device_sz = sizeof(audio_device); unsigned struct_audio_encoding_sz = sizeof(audio_encoding); @@ -594,7 +632,6 @@ unsigned struct_priq_delete_filter_sz = sizeof(priq_delete_filter); unsigned struct_priq_interface_sz = sizeof(priq_interface); unsigned struct_priq_modify_class_sz = sizeof(priq_modify_class); unsigned struct_ptmget_sz = sizeof(ptmget); -unsigned struct_pvctxreq_sz = sizeof(pvctxreq); unsigned struct_radio_info_sz = sizeof(radio_info); unsigned struct_red_conf_sz = sizeof(red_conf); unsigned struct_red_interface_sz = sizeof(red_interface); @@ -606,7 +643,6 @@ unsigned struct_rf_recon_req_sz = sizeof(rf_recon_req); unsigned struct_rio_conf_sz = sizeof(rio_conf); unsigned struct_rio_interface_sz = sizeof(rio_interface); unsigned struct_rio_stats_sz = sizeof(rio_stats); -unsigned struct_satlink_id_sz = sizeof(satlink_id); unsigned struct_scan_io_sz = sizeof(scan_io); unsigned struct_scbusaccel_args_sz = sizeof(scbusaccel_args); unsigned struct_scbusiodetach_args_sz = sizeof(scbusiodetach_args); @@ -654,6 +690,29 @@ 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); unsigned struct_usb_device_info_old_sz = sizeof(usb_device_info_old); unsigned struct_usb_device_info_sz = sizeof(usb_device_info); unsigned struct_usb_device_stats_sz = sizeof(usb_device_stats); @@ -693,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); @@ -778,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); @@ -795,6 +858,8 @@ unsigned struct_RF_SparetWait_sz = sizeof(RF_SparetWait_t); unsigned struct_RF_ComponentLabel_sz = sizeof(RF_ComponentLabel_t); unsigned struct_RF_SingleComponent_sz = sizeof(RF_SingleComponent_t); unsigned struct_RF_ProgressInfo_sz = sizeof(RF_ProgressInfo_t); +unsigned struct_nvlist_ref_sz = sizeof(struct __sanitizer_nvlist_ref_t); +unsigned struct_StringList_sz = sizeof(StringList); const unsigned IOCTL_NOT_PRESENT = 0; @@ -1059,6 +1124,7 @@ unsigned IOCTL_MLX_REBUILDSTAT = MLX_REBUILDSTAT; unsigned IOCTL_MLX_GET_SYSDRIVE = MLX_GET_SYSDRIVE; unsigned IOCTL_MLX_GET_CINFO = MLX_GET_CINFO; unsigned IOCTL_NVME_PASSTHROUGH_CMD = NVME_PASSTHROUGH_CMD; +unsigned IOCTL_FWCFGIO_SET_INDEX = FWCFGIO_SET_INDEX; unsigned IOCTL_IRDA_RESET_PARAMS = IRDA_RESET_PARAMS; unsigned IOCTL_IRDA_SET_PARAMS = IRDA_SET_PARAMS; unsigned IOCTL_IRDA_GET_SPEEDMASK = IRDA_GET_SPEEDMASK; @@ -1066,9 +1132,6 @@ unsigned IOCTL_IRDA_GET_TURNAROUNDMASK = IRDA_GET_TURNAROUNDMASK; unsigned IOCTL_IRFRAMETTY_GET_DEVICE = IRFRAMETTY_GET_DEVICE; unsigned IOCTL_IRFRAMETTY_GET_DONGLE = IRFRAMETTY_GET_DONGLE; unsigned IOCTL_IRFRAMETTY_SET_DONGLE = IRFRAMETTY_SET_DONGLE; -unsigned IOCTL_SATIORESET = SATIORESET; -unsigned IOCTL_SATIOGID = SATIOGID; -unsigned IOCTL_SATIOSBUFSIZE = SATIOSBUFSIZE; unsigned IOCTL_ISV_CMD = ISV_CMD; unsigned IOCTL_WTQICMD = WTQICMD; unsigned IOCTL_ISCSI_GET_VERSION = ISCSI_GET_VERSION; @@ -1388,6 +1451,27 @@ unsigned IOCTL_SPKRTONE = SPKRTONE; unsigned IOCTL_SPKRTUNE = SPKRTUNE; unsigned IOCTL_SPKRGETVOL = SPKRGETVOL; unsigned IOCTL_SPKRSETVOL = SPKRSETVOL; +#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; +unsigned IOCTL_NVMM_IOC_MACHINE_CONFIGURE = NVMM_IOC_MACHINE_CONFIGURE; +unsigned IOCTL_NVMM_IOC_VCPU_CREATE = NVMM_IOC_VCPU_CREATE; +unsigned IOCTL_NVMM_IOC_VCPU_DESTROY = NVMM_IOC_VCPU_DESTROY; +unsigned IOCTL_NVMM_IOC_VCPU_SETSTATE = NVMM_IOC_VCPU_SETSTATE; +unsigned IOCTL_NVMM_IOC_VCPU_GETSTATE = NVMM_IOC_VCPU_GETSTATE; +unsigned IOCTL_NVMM_IOC_VCPU_INJECT = NVMM_IOC_VCPU_INJECT; +unsigned IOCTL_NVMM_IOC_VCPU_RUN = NVMM_IOC_VCPU_RUN; +unsigned IOCTL_NVMM_IOC_GPA_MAP = NVMM_IOC_GPA_MAP; +unsigned IOCTL_NVMM_IOC_GPA_UNMAP = NVMM_IOC_GPA_UNMAP; +unsigned IOCTL_NVMM_IOC_HVA_MAP = NVMM_IOC_HVA_MAP; +unsigned IOCTL_NVMM_IOC_HVA_UNMAP = NVMM_IOC_HVA_UNMAP; +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; unsigned IOCTL_BIOCSBLEN = BIOCSBLEN; unsigned IOCTL_BIOCSETF = BIOCSETF; @@ -1406,19 +1490,12 @@ unsigned IOCTL_BIOCGHDRCMPLT = BIOCGHDRCMPLT; unsigned IOCTL_BIOCSHDRCMPLT = BIOCSHDRCMPLT; unsigned IOCTL_BIOCSDLT = BIOCSDLT; unsigned IOCTL_BIOCGDLTLIST = BIOCGDLTLIST; -unsigned IOCTL_BIOCGSEESENT = BIOCGSEESENT; -unsigned IOCTL_BIOCSSEESENT = BIOCSSEESENT; +unsigned IOCTL_BIOCGDIRECTION = BIOCGDIRECTION; +unsigned IOCTL_BIOCSDIRECTION = BIOCSDIRECTION; unsigned IOCTL_BIOCSRTIMEOUT = BIOCSRTIMEOUT; unsigned IOCTL_BIOCGRTIMEOUT = BIOCGRTIMEOUT; unsigned IOCTL_BIOCGFEEDBACK = BIOCGFEEDBACK; unsigned IOCTL_BIOCSFEEDBACK = BIOCSFEEDBACK; -unsigned IOCTL_SIOCRAWATM = SIOCRAWATM; -unsigned IOCTL_SIOCATMENA = SIOCATMENA; -unsigned IOCTL_SIOCATMDIS = SIOCATMDIS; -unsigned IOCTL_SIOCSPVCTX = SIOCSPVCTX; -unsigned IOCTL_SIOCGPVCTX = SIOCGPVCTX; -unsigned IOCTL_SIOCSPVCSIF = SIOCSPVCSIF; -unsigned IOCTL_SIOCGPVCSIF = SIOCGPVCSIF; unsigned IOCTL_GRESADDRS = GRESADDRS; unsigned IOCTL_GRESADDRD = GRESADDRD; unsigned IOCTL_GREGADDRS = GREGADDRS; @@ -1573,6 +1650,8 @@ unsigned IOCTL_SIOCRMNAT = SIOCRMNAT; unsigned IOCTL_SIOCGNATS = SIOCGNATS; unsigned IOCTL_SIOCGNATL = SIOCGNATL; unsigned IOCTL_SIOCPURGENAT = SIOCPURGENAT; +unsigned IOCTL_SIOCCONNECTX = SIOCCONNECTX; +unsigned IOCTL_SIOCCONNECTXDEL = SIOCCONNECTXDEL; unsigned IOCTL_SIOCSIFINFO_FLAGS = SIOCSIFINFO_FLAGS; unsigned IOCTL_SIOCAADDRCTL_POLICY = SIOCAADDRCTL_POLICY; unsigned IOCTL_SIOCDADDRCTL_POLICY = SIOCDADDRCTL_POLICY; @@ -1608,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; @@ -1693,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; @@ -1717,6 +1800,8 @@ unsigned IOCTL_FDIOCGETFORMAT = FDIOCGETFORMAT; unsigned IOCTL_FDIOCFORMAT_TRACK = FDIOCFORMAT_TRACK; unsigned IOCTL_FIOCLEX = FIOCLEX; unsigned IOCTL_FIONCLEX = FIONCLEX; +unsigned IOCTL_FIOSEEKDATA = FIOSEEKDATA; +unsigned IOCTL_FIOSEEKHOLE = FIOSEEKHOLE; unsigned IOCTL_FIONREAD = FIONREAD; unsigned IOCTL_FIONBIO = FIONBIO; unsigned IOCTL_FIOASYNC = FIOASYNC; @@ -1802,8 +1887,6 @@ unsigned IOCTL_MTIOCSLOCATE = MTIOCSLOCATE; unsigned IOCTL_MTIOCHLOCATE = MTIOCHLOCATE; unsigned IOCTL_POWER_EVENT_RECVDICT = POWER_EVENT_RECVDICT; unsigned IOCTL_POWER_IOC_GET_TYPE = POWER_IOC_GET_TYPE; -unsigned IOCTL_POWER_IOC_GET_TYPE_WITH_LOSSAGE = - POWER_IOC_GET_TYPE_WITH_LOSSAGE; unsigned IOCTL_RIOCGINFO = RIOCGINFO; unsigned IOCTL_RIOCSINFO = RIOCSINFO; unsigned IOCTL_RIOCSSRCH = RIOCSSRCH; @@ -1838,6 +1921,7 @@ unsigned IOCTL_SIOCGLOWAT = SIOCGLOWAT; unsigned IOCTL_SIOCATMARK = SIOCATMARK; unsigned IOCTL_SIOCSPGRP = SIOCSPGRP; unsigned IOCTL_SIOCGPGRP = SIOCGPGRP; +unsigned IOCTL_SIOCPEELOFF = SIOCPEELOFF; unsigned IOCTL_SIOCADDRT = SIOCADDRT; unsigned IOCTL_SIOCDELRT = SIOCDELRT; unsigned IOCTL_SIOCSIFADDR = SIOCSIFADDR; @@ -1895,6 +1979,12 @@ unsigned IOCTL_SIOCGLINKSTR = SIOCGLINKSTR; 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; unsigned IOCTL_SIOCSETPFSYNC = SIOCSETPFSYNC; unsigned IOCTL_SIOCGETPFSYNC = SIOCGETPFSYNC; unsigned IOCTL_PPS_IOC_CREATE = PPS_IOC_CREATE; @@ -2016,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; @@ -2061,6 +2164,44 @@ unsigned IOCTL_SNDCTL_DSP_SILENCE = SNDCTL_DSP_SILENCE; const int si_SEGV_MAPERR = SEGV_MAPERR; const int si_SEGV_ACCERR = SEGV_ACCERR; + +const int modctl_load = MODCTL_LOAD; +const int modctl_unload = MODCTL_UNLOAD; +const int modctl_stat = MODCTL_STAT; +const int modctl_exists = MODCTL_EXISTS; + +const unsigned SHA1_CTX_sz = sizeof(SHA1_CTX); +const unsigned SHA1_return_length = SHA1_DIGEST_STRING_LENGTH; + +const unsigned MD4_CTX_sz = sizeof(MD4_CTX); +const unsigned MD4_return_length = MD4_DIGEST_STRING_LENGTH; + +const unsigned RMD160_CTX_sz = sizeof(RMD160_CTX); +const unsigned RMD160_return_length = RMD160_DIGEST_STRING_LENGTH; + +const unsigned MD5_CTX_sz = sizeof(MD5_CTX); +const unsigned MD5_return_length = MD5_DIGEST_STRING_LENGTH; + +const unsigned fpos_t_sz = sizeof(fpos_t); + +const unsigned MD2_CTX_sz = sizeof(MD2_CTX); +const unsigned MD2_return_length = MD2_DIGEST_STRING_LENGTH; + +#define SHA2_CONST(LEN) \ + const unsigned SHA##LEN##_CTX_sz = sizeof(SHA##LEN##_CTX); \ + const unsigned SHA##LEN##_return_length = SHA##LEN##_DIGEST_STRING_LENGTH; \ + const unsigned SHA##LEN##_block_length = SHA##LEN##_BLOCK_LENGTH; \ + const unsigned SHA##LEN##_digest_length = SHA##LEN##_DIGEST_LENGTH + +SHA2_CONST(224); +SHA2_CONST(256); +SHA2_CONST(384); +SHA2_CONST(512); + +#undef SHA2_CONST + +const int unvis_valid = UNVIS_VALID; +const int unvis_validpush = UNVIS_VALIDPUSH; } // namespace __sanitizer using namespace __sanitizer; @@ -2151,6 +2292,29 @@ CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordc); CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordv); CHECK_SIZE_AND_OFFSET(wordexp_t, we_offs); +COMPILER_CHECK(sizeof(__sanitizer_FILE) <= sizeof(FILE)); +CHECK_SIZE_AND_OFFSET(FILE, _p); +CHECK_SIZE_AND_OFFSET(FILE, _r); +CHECK_SIZE_AND_OFFSET(FILE, _w); +CHECK_SIZE_AND_OFFSET(FILE, _flags); +CHECK_SIZE_AND_OFFSET(FILE, _file); +CHECK_SIZE_AND_OFFSET(FILE, _bf); +CHECK_SIZE_AND_OFFSET(FILE, _lbfsize); +CHECK_SIZE_AND_OFFSET(FILE, _cookie); +CHECK_SIZE_AND_OFFSET(FILE, _close); +CHECK_SIZE_AND_OFFSET(FILE, _read); +CHECK_SIZE_AND_OFFSET(FILE, _seek); +CHECK_SIZE_AND_OFFSET(FILE, _write); +CHECK_SIZE_AND_OFFSET(FILE, _ext); +CHECK_SIZE_AND_OFFSET(FILE, _up); +CHECK_SIZE_AND_OFFSET(FILE, _ur); +CHECK_SIZE_AND_OFFSET(FILE, _ubuf); +CHECK_SIZE_AND_OFFSET(FILE, _nbuf); +CHECK_SIZE_AND_OFFSET(FILE, _flush); +CHECK_SIZE_AND_OFFSET(FILE, _lb_unused); +CHECK_SIZE_AND_OFFSET(FILE, _blksize); +CHECK_SIZE_AND_OFFSET(FILE, _offset); + CHECK_TYPE_SIZE(tm); CHECK_SIZE_AND_OFFSET(tm, tm_sec); CHECK_SIZE_AND_OFFSET(tm, tm_min); @@ -2222,4 +2386,10 @@ CHECK_SIZE_AND_OFFSET(group, gr_passwd); CHECK_SIZE_AND_OFFSET(group, gr_gid); CHECK_SIZE_AND_OFFSET(group, gr_mem); +CHECK_TYPE_SIZE(modctl_load_t); +CHECK_SIZE_AND_OFFSET(modctl_load_t, ml_filename); +CHECK_SIZE_AND_OFFSET(modctl_load_t, ml_flags); +CHECK_SIZE_AND_OFFSET(modctl_load_t, ml_props); +CHECK_SIZE_AND_OFFSET(modctl_load_t, ml_propslen); + #endif // SANITIZER_NETBSD diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.h index eddfc124f07..4fb3b8c0e06 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.h @@ -1,7 +1,8 @@ //===-- sanitizer_platform_limits_netbsd.h --------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -23,10 +24,10 @@ #if defined(__x86_64__) #define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ - _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 312) + _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 264) #elif defined(__i386__) #define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ - _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 164) + _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 136) #endif namespace __sanitizer { @@ -58,6 +59,29 @@ extern unsigned struct_timespec_sz; extern unsigned struct_sembuf_sz; extern unsigned struct_kevent_sz; +extern unsigned struct_FTS_sz; +extern unsigned struct_FTSENT_sz; + +extern unsigned struct_regex_sz; +extern unsigned struct_regmatch_sz; + +extern unsigned struct_fstab_sz; + +struct __sanitizer_regmatch { + OFF_T rm_so; + OFF_T rm_eo; +}; + +typedef struct __sanitizer_modctl_load { + const char *ml_filename; + int ml_flags; + const char *ml_props; + uptr ml_propslen; +} __sanitizer_modctl_load_t; +extern const int modctl_load; +extern const int modctl_unload; +extern const int modctl_stat; +extern const int modctl_exists; union __sanitizer_sigval { int sival_int; @@ -423,8 +447,36 @@ struct __sanitizer_wordexp_t { uptr we_nbytes; }; -typedef char __sanitizer_FILE; -#define SANITIZER_HAS_STRUCT_FILE 0 +struct __sanitizer_FILE { + unsigned char *_p; + int _r; + int _w; + unsigned short _flags; + short _file; + struct { + unsigned char *_base; + int _size; + } _bf; + int _lbfsize; + void *_cookie; + int (*_close)(void *ptr); + u64 (*_read)(void *, void *, uptr); + u64 (*_seek)(void *, u64, int); + uptr (*_write)(void *, const void *, uptr); + struct { + unsigned char *_base; + int _size; + } _ext; + unsigned char *_up; + int _ur; + unsigned char _ubuf[3]; + unsigned char _nbuf[1]; + int (*_flush)(void *ptr); + char _lb_unused[sizeof(uptr)]; + int _blksize; + u64 _offset; +}; +#define SANITIZER_HAS_STRUCT_FILE 1 extern int shmctl_ipc_stat; @@ -458,6 +510,8 @@ struct __sanitizer_ttyent { char *ty_class; }; +extern const unsigned long __sanitizer_bufsiz; + #define IOC_NRBITS 8 #define IOC_TYPEBITS 8 #define IOC_SIZEBITS 14 @@ -494,7 +548,6 @@ extern unsigned struct_atabusiodetach_args_sz; extern unsigned struct_atabusioscan_args_sz; extern unsigned struct_ath_diag_sz; extern unsigned struct_atm_flowmap_sz; -extern unsigned struct_atm_pseudoioctl_sz; extern unsigned struct_audio_buf_info_sz; extern unsigned struct_audio_device_sz; extern unsigned struct_audio_encoding_sz; @@ -749,7 +802,6 @@ extern unsigned struct_rf_recon_req_sz; extern unsigned struct_rio_conf_sz; extern unsigned struct_rio_interface_sz; extern unsigned struct_rio_stats_sz; -extern unsigned struct_satlink_id_sz; extern unsigned struct_scan_io_sz; extern unsigned struct_scbusaccel_args_sz; extern unsigned struct_scbusiodetach_args_sz; @@ -797,6 +849,28 @@ 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; extern unsigned struct_usb_device_info_old_sz; extern unsigned struct_usb_device_info_sz; extern unsigned struct_usb_device_stats_sz; @@ -836,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; @@ -914,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; @@ -931,6 +1009,8 @@ extern unsigned struct_RF_SparetWait_sz; extern unsigned struct_RF_ComponentLabel_sz; extern unsigned struct_RF_SingleComponent_sz; extern unsigned struct_RF_ProgressInfo_sz; +extern unsigned struct_nvlist_ref_sz; +extern unsigned struct_StringList_sz; // A special value to mark ioctls that are not present on the target platform, @@ -1199,6 +1279,7 @@ extern unsigned IOCTL_MLX_REBUILDSTAT; extern unsigned IOCTL_MLX_GET_SYSDRIVE; extern unsigned IOCTL_MLX_GET_CINFO; extern unsigned IOCTL_NVME_PASSTHROUGH_CMD; +extern unsigned IOCTL_FWCFGIO_SET_INDEX; extern unsigned IOCTL_IRDA_RESET_PARAMS; extern unsigned IOCTL_IRDA_SET_PARAMS; extern unsigned IOCTL_IRDA_GET_SPEEDMASK; @@ -1206,9 +1287,6 @@ extern unsigned IOCTL_IRDA_GET_TURNAROUNDMASK; extern unsigned IOCTL_IRFRAMETTY_GET_DEVICE; extern unsigned IOCTL_IRFRAMETTY_GET_DONGLE; extern unsigned IOCTL_IRFRAMETTY_SET_DONGLE; -extern unsigned IOCTL_SATIORESET; -extern unsigned IOCTL_SATIOGID; -extern unsigned IOCTL_SATIOSBUFSIZE; extern unsigned IOCTL_ISV_CMD; extern unsigned IOCTL_WTQICMD; extern unsigned IOCTL_ISCSI_GET_VERSION; @@ -1520,6 +1598,25 @@ extern unsigned IOCTL_SPKRTONE; extern unsigned IOCTL_SPKRTUNE; extern unsigned IOCTL_SPKRGETVOL; extern unsigned IOCTL_SPKRSETVOL; +#if defined(__x86_64__) +extern unsigned IOCTL_NVMM_IOC_CAPABILITY; +extern unsigned IOCTL_NVMM_IOC_MACHINE_CREATE; +extern unsigned IOCTL_NVMM_IOC_MACHINE_DESTROY; +extern unsigned IOCTL_NVMM_IOC_MACHINE_CONFIGURE; +extern unsigned IOCTL_NVMM_IOC_VCPU_CREATE; +extern unsigned IOCTL_NVMM_IOC_VCPU_DESTROY; +extern unsigned IOCTL_NVMM_IOC_VCPU_SETSTATE; +extern unsigned IOCTL_NVMM_IOC_VCPU_GETSTATE; +extern unsigned IOCTL_NVMM_IOC_VCPU_INJECT; +extern unsigned IOCTL_NVMM_IOC_VCPU_RUN; +extern unsigned IOCTL_NVMM_IOC_GPA_MAP; +extern unsigned IOCTL_NVMM_IOC_GPA_UNMAP; +extern unsigned IOCTL_NVMM_IOC_HVA_MAP; +extern unsigned IOCTL_NVMM_IOC_HVA_UNMAP; +extern unsigned IOCTL_NVMM_IOC_CTL; +#endif +extern unsigned IOCTL_AUTOFSREQUEST; +extern unsigned IOCTL_AUTOFSDONE; extern unsigned IOCTL_BIOCGBLEN; extern unsigned IOCTL_BIOCSBLEN; extern unsigned IOCTL_BIOCSETF; @@ -1538,19 +1635,12 @@ extern unsigned IOCTL_BIOCGHDRCMPLT; extern unsigned IOCTL_BIOCSHDRCMPLT; extern unsigned IOCTL_BIOCSDLT; extern unsigned IOCTL_BIOCGDLTLIST; -extern unsigned IOCTL_BIOCGSEESENT; -extern unsigned IOCTL_BIOCSSEESENT; +extern unsigned IOCTL_BIOCGDIRECTION; +extern unsigned IOCTL_BIOCSDIRECTION; extern unsigned IOCTL_BIOCSRTIMEOUT; extern unsigned IOCTL_BIOCGRTIMEOUT; extern unsigned IOCTL_BIOCGFEEDBACK; extern unsigned IOCTL_BIOCSFEEDBACK; -extern unsigned IOCTL_SIOCRAWATM; -extern unsigned IOCTL_SIOCATMENA; -extern unsigned IOCTL_SIOCATMDIS; -extern unsigned IOCTL_SIOCSPVCTX; -extern unsigned IOCTL_SIOCGPVCTX; -extern unsigned IOCTL_SIOCSPVCSIF; -extern unsigned IOCTL_SIOCGPVCSIF; extern unsigned IOCTL_GRESADDRS; extern unsigned IOCTL_GRESADDRD; extern unsigned IOCTL_GREGADDRS; @@ -1705,6 +1795,8 @@ extern unsigned IOCTL_SIOCRMNAT; extern unsigned IOCTL_SIOCGNATS; extern unsigned IOCTL_SIOCGNATL; extern unsigned IOCTL_SIOCPURGENAT; +extern unsigned IOCTL_SIOCCONNECTX; +extern unsigned IOCTL_SIOCCONNECTXDEL; extern unsigned IOCTL_SIOCSIFINFO_FLAGS; extern unsigned IOCTL_SIOCAADDRCTL_POLICY; extern unsigned IOCTL_SIOCDADDRCTL_POLICY; @@ -1740,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; @@ -1825,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; @@ -1849,6 +1945,8 @@ extern unsigned IOCTL_FDIOCGETFORMAT; extern unsigned IOCTL_FDIOCFORMAT_TRACK; extern unsigned IOCTL_FIOCLEX; extern unsigned IOCTL_FIONCLEX; +extern unsigned IOCTL_FIOSEEKDATA; +extern unsigned IOCTL_FIOSEEKHOLE; extern unsigned IOCTL_FIONREAD; extern unsigned IOCTL_FIONBIO; extern unsigned IOCTL_FIOASYNC; @@ -1924,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; @@ -1934,7 +2034,6 @@ extern unsigned IOCTL_MTIOCSLOCATE; extern unsigned IOCTL_MTIOCHLOCATE; extern unsigned IOCTL_POWER_EVENT_RECVDICT; extern unsigned IOCTL_POWER_IOC_GET_TYPE; -extern unsigned IOCTL_POWER_IOC_GET_TYPE_WITH_LOSSAGE; extern unsigned IOCTL_RIOCGINFO; extern unsigned IOCTL_RIOCSINFO; extern unsigned IOCTL_RIOCSSRCH; @@ -1969,6 +2068,7 @@ extern unsigned IOCTL_SIOCGLOWAT; extern unsigned IOCTL_SIOCATMARK; extern unsigned IOCTL_SIOCSPGRP; extern unsigned IOCTL_SIOCGPGRP; +extern unsigned IOCTL_SIOCPEELOFF; extern unsigned IOCTL_SIOCADDRT; extern unsigned IOCTL_SIOCDELRT; extern unsigned IOCTL_SIOCSIFADDR; @@ -2026,6 +2126,12 @@ extern unsigned IOCTL_SIOCGLINKSTR; 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; extern unsigned IOCTL_SIOCSETPFSYNC; extern unsigned IOCTL_SIOCGETPFSYNC; extern unsigned IOCTL_PPS_IOC_CREATE; @@ -2147,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; @@ -2192,6 +2311,74 @@ extern unsigned IOCTL_SNDCTL_DSP_SILENCE; extern const int si_SEGV_MAPERR; extern const int si_SEGV_ACCERR; + +extern const unsigned SHA1_CTX_sz; +extern const unsigned SHA1_return_length; + +extern const unsigned MD4_CTX_sz; +extern const unsigned MD4_return_length; + +extern const unsigned RMD160_CTX_sz; +extern const unsigned RMD160_return_length; + +extern const unsigned MD5_CTX_sz; +extern const unsigned MD5_return_length; + +extern const unsigned fpos_t_sz; + +extern const unsigned MD2_CTX_sz; +extern const unsigned MD2_return_length; + +#define SHA2_EXTERN(LEN) \ + extern const unsigned SHA##LEN##_CTX_sz; \ + extern const unsigned SHA##LEN##_return_length; \ + extern const unsigned SHA##LEN##_block_length; \ + extern const unsigned SHA##LEN##_digest_length + +SHA2_EXTERN(224); +SHA2_EXTERN(256); +SHA2_EXTERN(384); +SHA2_EXTERN(512); + +#undef SHA2_EXTERN + +extern const int unvis_valid; +extern const int unvis_validpush; + +struct __sanitizer_cdbr { + void (*unmap)(void *, void *, uptr); + void *cookie; + u8 *mmap_base; + uptr mmap_size; + + u8 *hash_base; + u8 *offset_base; + u8 *data_base; + + u32 data_size; + u32 entries; + u32 entries_index; + u32 seed; + + u8 offset_size; + u8 index_size; + + u32 entries_m; + u32 entries_index_m; + u8 entries_s1, entries_s2; + u8 entries_index_s1, entries_index_s2; +}; + +struct __sanitizer_cdbw { + uptr data_counter; + uptr data_allocated; + uptr data_size; + uptr *data_len; + void **data_ptr; + uptr hash_size; + void *hash; + uptr key_counter; +}; } // namespace __sanitizer #define CHECK_TYPE_SIZE(TYPE) \ diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cpp similarity index 97% rename from libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cc rename to libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cpp index e114ff42f70..12515626ce5 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cc +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_platform_limits_openbsd.cc ------------------------------===// +//===-- sanitizer_platform_limits_openbsd.cpp -----------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h index 8f21de75228..6d8b062716b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h @@ -1,7 +1,8 @@ //===-- sanitizer_platform_limits_openbsd.h -------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp similarity index 96% rename from libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc rename to libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp index 6cd4a5bac8b..7f1132c461e 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_platform_limits_posix.cc --------------------------------===// +//===-- sanitizer_platform_limits_posix.cpp -------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -12,7 +13,7 @@ #include "sanitizer_platform.h" -#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_MAC +#if SANITIZER_LINUX || SANITIZER_MAC // Tests in this file assume that off_t-dependent data structures match the // libc ABI. For example, struct dirent here is what readdir() function (as // exported from libc) returns, and not the user-facing "dirent", which @@ -43,7 +44,8 @@ #include #include #include -#if !SANITIZER_MAC && !SANITIZER_FREEBSD +#include +#if !SANITIZER_MAC #include #endif @@ -52,6 +54,7 @@ #endif #if !SANITIZER_ANDROID +#include #include #include #include @@ -76,43 +79,11 @@ #include #endif -#if SANITIZER_FREEBSD -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include -# include - -#define _KERNEL // to declare 'shminfo' structure -# include -#undef _KERNEL - -#undef INLINE // to avoid clashes with sanitizers' definitions -#endif - -#if SANITIZER_FREEBSD || SANITIZER_IOS +#if SANITIZER_IOS #undef IOC_DIRMASK #endif -#if SANITIZER_LINUX || SANITIZER_FREEBSD +#if SANITIZER_LINUX # include # include # if defined(__mips64) || defined(__aarch64__) || defined(__arm__) @@ -144,8 +115,6 @@ typedef struct user_fpregs elf_fpregset_t; #include #if HAVE_RPC_XDR_H # include -#elif HAVE_TIRPC_RPC_XDR_H -# include #endif #include #include @@ -196,9 +165,9 @@ typedef struct user_fpregs elf_fpregset_t; namespace __sanitizer { unsigned struct_utsname_sz = sizeof(struct utsname); unsigned struct_stat_sz = sizeof(struct stat); -#if !SANITIZER_IOS && !SANITIZER_FREEBSD +#if !SANITIZER_IOS unsigned struct_stat64_sz = sizeof(struct stat64); -#endif // !SANITIZER_IOS && !SANITIZER_FREEBSD +#endif // !SANITIZER_IOS unsigned struct_rusage_sz = sizeof(struct rusage); unsigned struct_tm_sz = sizeof(struct tm); unsigned struct_passwd_sz = sizeof(struct passwd); @@ -219,13 +188,15 @@ namespace __sanitizer { unsigned struct_tms_sz = sizeof(struct tms); unsigned struct_sigevent_sz = sizeof(struct sigevent); unsigned struct_sched_param_sz = sizeof(struct sched_param); - + unsigned struct_regex_sz = sizeof(regex_t); + unsigned struct_regmatch_sz = sizeof(regmatch_t); #if SANITIZER_MAC && !SANITIZER_IOS unsigned struct_statfs64_sz = sizeof(struct statfs64); #endif // SANITIZER_MAC && !SANITIZER_IOS #if !SANITIZER_ANDROID + unsigned struct_fstab_sz = sizeof(struct fstab); unsigned struct_statfs_sz = sizeof(struct statfs); unsigned struct_sockaddr_sz = sizeof(struct sockaddr); unsigned ucontext_t_sz = sizeof(ucontext_t); @@ -242,12 +213,12 @@ namespace __sanitizer { unsigned struct_oldold_utsname_sz = sizeof(struct oldold_utsname); #endif // SANITIZER_LINUX -#if SANITIZER_LINUX || SANITIZER_FREEBSD +#if SANITIZER_LINUX unsigned struct_rlimit_sz = sizeof(struct rlimit); unsigned struct_timespec_sz = sizeof(struct timespec); unsigned struct_utimbuf_sz = sizeof(struct utimbuf); unsigned struct_itimerspec_sz = sizeof(struct itimerspec); -#endif // SANITIZER_LINUX || SANITIZER_FREEBSD +#endif // SANITIZER_LINUX #if SANITIZER_LINUX && !SANITIZER_ANDROID // Use pre-computed size of struct ustat to avoid which @@ -267,12 +238,12 @@ namespace __sanitizer { unsigned struct_statvfs64_sz = sizeof(struct statvfs64); #endif // SANITIZER_LINUX && !SANITIZER_ANDROID -#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned struct_timex_sz = sizeof(struct timex); unsigned struct_msqid_ds_sz = sizeof(struct msqid_ds); unsigned struct_mq_attr_sz = sizeof(struct mq_attr); unsigned struct_statvfs_sz = sizeof(struct statvfs); -#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID +#endif // SANITIZER_LINUX && !SANITIZER_ANDROID const uptr sig_ign = (uptr)SIG_IGN; const uptr sig_dfl = (uptr)SIG_DFL; @@ -284,7 +255,7 @@ namespace __sanitizer { #endif -#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned struct_shminfo_sz = sizeof(struct shminfo); unsigned struct_shm_info_sz = sizeof(struct shm_info); int shmctl_ipc_stat = (int)IPC_STAT; @@ -320,7 +291,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(ElfW(Phdr)); unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); #endif -#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID int glob_nomatch = GLOB_NOMATCH; int glob_altdirfunc = GLOB_ALTDIRFUNC; #endif @@ -445,7 +416,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned struct_vt_stat_sz = sizeof(struct vt_stat); #endif // SANITIZER_LINUX -#if SANITIZER_LINUX || SANITIZER_FREEBSD +#if SANITIZER_LINUX #if SOUND_VERSION >= 0x040000 unsigned struct_copr_buffer_sz = 0; unsigned struct_copr_debug_buf_sz = 0; @@ -462,7 +433,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned struct_seq_event_rec_sz = sizeof(struct seq_event_rec); unsigned struct_synth_info_sz = sizeof(struct synth_info); unsigned struct_vt_mode_sz = sizeof(struct vt_mode); -#endif // SANITIZER_LINUX || SANITIZER_FREEBSD +#endif // SANITIZER_LINUX #if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned struct_ax25_parms_struct_sz = sizeof(struct ax25_parms_struct); @@ -489,7 +460,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned struct_unimapinit_sz = sizeof(struct unimapinit); #endif // SANITIZER_LINUX && !SANITIZER_ANDROID -#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned struct_audio_buf_info_sz = sizeof(struct audio_buf_info); unsigned struct_ppp_stats_sz = sizeof(struct ppp_stats); #endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID @@ -499,6 +470,8 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req); #endif + const unsigned long __sanitizer_bufsiz = BUFSIZ; + const unsigned IOCTL_NOT_PRESENT = 0; unsigned IOCTL_FIOASYNC = FIOASYNC; @@ -545,7 +518,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned IOCTL_TIOCSPGRP = TIOCSPGRP; unsigned IOCTL_TIOCSTI = TIOCSTI; unsigned IOCTL_TIOCSWINSZ = TIOCSWINSZ; -#if ((SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID) +#if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned IOCTL_SIOCGETSGCNT = SIOCGETSGCNT; unsigned IOCTL_SIOCGETVIFCNT = SIOCGETVIFCNT; #endif @@ -735,9 +708,6 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned IOCTL_VT_RESIZE = VT_RESIZE; unsigned IOCTL_VT_RESIZEX = VT_RESIZEX; unsigned IOCTL_VT_SENDSIG = VT_SENDSIG; -#endif // SANITIZER_LINUX - -#if SANITIZER_LINUX || SANITIZER_FREEBSD unsigned IOCTL_MTIOCGET = MTIOCGET; unsigned IOCTL_MTIOCTOP = MTIOCTOP; unsigned IOCTL_SNDCTL_DSP_GETBLKSIZE = SNDCTL_DSP_GETBLKSIZE; @@ -830,7 +800,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned IOCTL_VT_RELDISP = VT_RELDISP; unsigned IOCTL_VT_SETMODE = VT_SETMODE; unsigned IOCTL_VT_WAITACTIVE = VT_WAITACTIVE; -#endif // SANITIZER_LINUX || SANITIZER_FREEBSD +#endif // SANITIZER_LINUX #if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned IOCTL_CYGETDEFTHRESH = CYGETDEFTHRESH; @@ -923,7 +893,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned IOCTL_TIOCSSERIAL = TIOCSSERIAL; #endif // SANITIZER_LINUX && !SANITIZER_ANDROID -#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned IOCTL_GIO_SCRNMAP = GIO_SCRNMAP; unsigned IOCTL_KDDISABIO = KDDISABIO; unsigned IOCTL_KDENABIO = KDENABIO; @@ -1241,7 +1211,7 @@ CHECK_SIZE_AND_OFFSET(group, gr_passwd); CHECK_SIZE_AND_OFFSET(group, gr_gid); CHECK_SIZE_AND_OFFSET(group, gr_mem); -#if HAVE_RPC_XDR_H || HAVE_TIRPC_RPC_XDR_H +#if HAVE_RPC_XDR_H CHECK_TYPE_SIZE(XDR); CHECK_SIZE_AND_OFFSET(XDR, x_op); CHECK_SIZE_AND_OFFSET(XDR, x_ops); diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h index 73af92af1e8..ef90a2592cf 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h @@ -1,7 +1,8 @@ //===-- sanitizer_platform_limits_posix.h ---------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -13,22 +14,12 @@ #ifndef SANITIZER_PLATFORM_LIMITS_POSIX_H #define SANITIZER_PLATFORM_LIMITS_POSIX_H -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC +#if SANITIZER_LINUX || SANITIZER_MAC #include "sanitizer_internal_defs.h" #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD -// FreeBSD's dlopen() returns a pointer to an Obj_Entry structure that -// incorporates the map structure. -# define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ - ((link_map*)((handle) == nullptr ? nullptr : ((char*)(handle) + 560))) -// Get sys/_types.h, because that tells us whether 64-bit inodes are -// used in struct dirent below. -#include -#else # define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) ((link_map*)(handle)) -#endif // !SANITIZER_FREEBSD #ifndef __GLIBC_PREREQ #define __GLIBC_PREREQ(x, y) 0 @@ -37,7 +28,7 @@ namespace __sanitizer { extern unsigned struct_utsname_sz; extern unsigned struct_stat_sz; -#if !SANITIZER_FREEBSD && !SANITIZER_IOS +#if !SANITIZER_IOS extern unsigned struct_stat64_sz; #endif extern unsigned struct_rusage_sz; @@ -57,8 +48,11 @@ namespace __sanitizer { extern unsigned struct_sigevent_sz; extern unsigned struct_sched_param_sz; extern unsigned struct_statfs64_sz; + extern unsigned struct_regex_sz; + extern unsigned struct_regmatch_sz; #if !SANITIZER_ANDROID + extern unsigned struct_fstab_sz; extern unsigned struct_statfs_sz; extern unsigned struct_sockaddr_sz; extern unsigned ucontext_t_sz; @@ -87,7 +81,7 @@ namespace __sanitizer { #elif defined(__mips__) const unsigned struct_kernel_stat_sz = SANITIZER_ANDROID ? FIRST_32_SECOND_64(104, 128) : - FIRST_32_SECOND_64(144, 216); + 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; @@ -121,7 +115,7 @@ namespace __sanitizer { const unsigned struct_kexec_segment_sz = 4 * sizeof(unsigned long); #endif // SANITIZER_LINUX -#if SANITIZER_LINUX || SANITIZER_FREEBSD +#if SANITIZER_LINUX #if defined(__powerpc64__) || defined(__s390__) const unsigned struct___old_kernel_stat_sz = 0; @@ -178,11 +172,9 @@ namespace __sanitizer { int data; #elif SANITIZER_LINUX uptr data[4]; -#elif SANITIZER_FREEBSD - u32 data[4]; #endif }; -#endif // SANITIZER_LINUX || SANITIZER_FREEBSD +#endif // SANITIZER_LINUX #if SANITIZER_ANDROID struct __sanitizer_struct_mallinfo { @@ -304,35 +296,14 @@ namespace __sanitizer { #endif #endif }; -#elif SANITIZER_FREEBSD - 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; - }; #endif -#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID +#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; -#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID +#endif // SANITIZER_LINUX && !SANITIZER_ANDROID struct __sanitizer_iovec { void *iov_base; @@ -382,7 +353,7 @@ namespace __sanitizer { char *pw_passwd; int pw_uid; int pw_gid; -#if SANITIZER_MAC || SANITIZER_FREEBSD +#if SANITIZER_MAC long pw_change; char *pw_class; #endif @@ -391,11 +362,8 @@ namespace __sanitizer { #endif char *pw_dir; char *pw_shell; -#if SANITIZER_MAC || SANITIZER_FREEBSD +#if SANITIZER_MAC long pw_expire; -#endif -#if SANITIZER_FREEBSD - int pw_fields; #endif }; @@ -466,7 +434,7 @@ namespace __sanitizer { }; #endif -#if SANITIZER_MAC || SANITIZER_FREEBSD +#if SANITIZER_MAC struct __sanitizer_msghdr { void *msg_name; unsigned msg_namelen; @@ -512,17 +480,6 @@ namespace __sanitizer { unsigned short d_reclen; // more fields that we don't care about }; -#elif SANITIZER_FREEBSD - struct __sanitizer_dirent { -#if defined(__INO64) - unsigned long long d_fileno; - unsigned long long d_off; -#else - unsigned int d_fileno; -#endif - 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; @@ -548,20 +505,17 @@ namespace __sanitizer { }; #endif -// 'clock_t' is 32 bits wide on x64 FreeBSD -#if SANITIZER_FREEBSD - typedef int __sanitizer_clock_t; -#elif defined(__x86_64__) && !defined(_LP64) +#if defined(__x86_64__) && !defined(_LP64) typedef long long __sanitizer_clock_t; #else typedef long __sanitizer_clock_t; #endif -#if SANITIZER_LINUX || SANITIZER_FREEBSD +#if SANITIZER_LINUX typedef int __sanitizer_clockid_t; #endif -#if SANITIZER_LINUX || SANITIZER_FREEBSD +#if SANITIZER_LINUX #if defined(_LP64) || defined(__x86_64__) || defined(__powerpc__)\ || defined(__mips__) typedef unsigned __sanitizer___kernel_uid_t; @@ -591,7 +545,7 @@ namespace __sanitizer { #endif // This thing depends on the platform. We are only interested in the upper - // limit. Verified with a compiler assert in .cc. + // limit. Verified with a compiler assert in .cpp. const int pthread_attr_t_max_sz = 128; union __sanitizer_pthread_attr_t { char size[pthread_attr_t_max_sz]; // NOLINT @@ -611,11 +565,6 @@ namespace __sanitizer { // The size is determined by looking at sizeof of real sigset_t on linux. uptr val[128 / sizeof(uptr)]; }; -#elif SANITIZER_FREEBSD - struct __sanitizer_sigset_t { - // uint32_t * 4 - unsigned int __bits[4]; - }; #endif struct __sanitizer_siginfo { @@ -705,9 +654,7 @@ namespace __sanitizer { }; #endif // !SANITIZER_ANDROID -#if SANITIZER_FREEBSD - typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t; -#elif defined(__mips__) +#if defined(__mips__) struct __sanitizer_kernel_sigset_t { uptr sig[2]; }; @@ -753,7 +700,7 @@ namespace __sanitizer { extern int af_inet6; uptr __sanitizer_in_addr_sz(int af); -#if SANITIZER_LINUX || SANITIZER_FREEBSD +#if SANITIZER_LINUX struct __sanitizer_dl_phdr_info { uptr dlpi_addr; const char *dlpi_name; @@ -769,7 +716,7 @@ namespace __sanitizer { int ai_family; int ai_socktype; int ai_protocol; -#if SANITIZER_ANDROID || SANITIZER_MAC || SANITIZER_FREEBSD +#if SANITIZER_ANDROID || SANITIZER_MAC unsigned ai_addrlen; char *ai_canonname; void *ai_addr; @@ -795,7 +742,7 @@ namespace __sanitizer { short revents; }; -#if SANITIZER_ANDROID || SANITIZER_MAC || SANITIZER_FREEBSD +#if SANITIZER_ANDROID || SANITIZER_MAC typedef unsigned __sanitizer_nfds_t; #else typedef unsigned long __sanitizer_nfds_t; @@ -815,23 +762,9 @@ namespace __sanitizer { int (*gl_lstat)(const char *, void *); int (*gl_stat)(const char *, void *); }; -# elif SANITIZER_FREEBSD - 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* */); - }; -# endif // SANITIZER_FREEBSD +# endif // SANITIZER_LINUX -# if SANITIZER_LINUX || SANITIZER_FREEBSD +# if SANITIZER_LINUX extern int glob_nomatch; extern int glob_altdirfunc; # endif @@ -843,10 +776,6 @@ namespace __sanitizer { uptr we_wordc; char **we_wordv; uptr we_offs; -#if SANITIZER_FREEBSD - char *we_strings; - uptr we_nbytes; -#endif }; #if SANITIZER_LINUX && !SANITIZER_ANDROID @@ -900,7 +829,7 @@ namespace __sanitizer { extern int ptrace_geteventmsg; #endif -#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID extern unsigned struct_shminfo_sz; extern unsigned struct_shm_info_sz; extern int shmctl_ipc_stat; @@ -1037,7 +966,7 @@ struct __sanitizer_cookie_io_functions_t { extern unsigned struct_vt_stat_sz; #endif // SANITIZER_LINUX -#if SANITIZER_LINUX || SANITIZER_FREEBSD +#if SANITIZER_LINUX extern unsigned struct_copr_buffer_sz; extern unsigned struct_copr_debug_buf_sz; extern unsigned struct_copr_msg_sz; @@ -1049,7 +978,7 @@ struct __sanitizer_cookie_io_functions_t { extern unsigned struct_seq_event_rec_sz; extern unsigned struct_synth_info_sz; extern unsigned struct_vt_mode_sz; -#endif // SANITIZER_LINUX || SANITIZER_FREEBSD +#endif // SANITIZER_LINUX #if SANITIZER_LINUX && !SANITIZER_ANDROID extern unsigned struct_ax25_parms_struct_sz; @@ -1071,7 +1000,9 @@ struct __sanitizer_cookie_io_functions_t { extern unsigned struct_unimapinit_sz; #endif // SANITIZER_LINUX && !SANITIZER_ANDROID -#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID + extern const unsigned long __sanitizer_bufsiz; + +#if SANITIZER_LINUX && !SANITIZER_ANDROID extern unsigned struct_audio_buf_info_sz; extern unsigned struct_ppp_stats_sz; #endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID @@ -1131,7 +1062,7 @@ struct __sanitizer_cookie_io_functions_t { extern unsigned IOCTL_TIOCSPGRP; extern unsigned IOCTL_TIOCSTI; extern unsigned IOCTL_TIOCSWINSZ; -#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID +#if SANITIZER_LINUX && !SANITIZER_ANDROID extern unsigned IOCTL_SIOCGETSGCNT; extern unsigned IOCTL_SIOCGETVIFCNT; #endif @@ -1293,8 +1224,6 @@ struct __sanitizer_cookie_io_functions_t { extern unsigned IOCTL_VT_RESIZE; extern unsigned IOCTL_VT_RESIZEX; extern unsigned IOCTL_VT_SENDSIG; -#endif // SANITIZER_LINUX -#if SANITIZER_LINUX || SANITIZER_FREEBSD extern unsigned IOCTL_MTIOCGET; extern unsigned IOCTL_MTIOCTOP; extern unsigned IOCTL_SIOCADDRT; @@ -1395,7 +1324,7 @@ struct __sanitizer_cookie_io_functions_t { extern unsigned IOCTL_VT_RELDISP; extern unsigned IOCTL_VT_SETMODE; extern unsigned IOCTL_VT_WAITACTIVE; -#endif // SANITIZER_LINUX || SANITIZER_FREEBSD +#endif // SANITIZER_LINUX #if SANITIZER_LINUX && !SANITIZER_ANDROID extern unsigned IOCTL_CYGETDEFTHRESH; @@ -1482,9 +1411,6 @@ struct __sanitizer_cookie_io_functions_t { extern unsigned IOCTL_TIOCSERGETMULTI; extern unsigned IOCTL_TIOCSERSETMULTI; extern unsigned IOCTL_TIOCSSERIAL; -#endif // SANITIZER_LINUX && !SANITIZER_ANDROID - -#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID extern unsigned IOCTL_GIO_SCRNMAP; extern unsigned IOCTL_KDDISABIO; extern unsigned IOCTL_KDENABIO; @@ -1523,6 +1449,6 @@ struct __sanitizer_cookie_io_functions_t { #define SIGACTION_SYMNAME sigaction -#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC +#endif // SANITIZER_LINUX || SANITIZER_MAC #endif diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cpp similarity index 97% rename from libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cc rename to libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cpp index 00b0ffcff59..9717d98ebf1 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cc +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_platform_limits_solaris.cc ------------------------------===// +//===-- sanitizer_platform_limits_solaris.cpp -----------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.h index 97788d61d62..ed3b7a04dff 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.h @@ -1,7 +1,8 @@ //===-- sanitizer_platform_limits_solaris.h -------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -235,7 +236,7 @@ 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. +// limit. Verified with a compiler assert in .cpp. const int pthread_attr_t_max_sz = 128; union __sanitizer_pthread_attr_t { char size[pthread_attr_t_max_sz]; // NOLINT diff --git a/libsanitizer/sanitizer_common/sanitizer_posix.cc b/libsanitizer/sanitizer_common/sanitizer_posix.cpp similarity index 72% rename from libsanitizer/sanitizer_common/sanitizer_posix.cc rename to libsanitizer/sanitizer_common/sanitizer_posix.cpp index 71994bac840..002bcb1eda4 100644 --- a/libsanitizer/sanitizer_common/sanitizer_posix.cc +++ b/libsanitizer/sanitizer_common/sanitizer_posix.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_posix.cc ------------------------------------------------===// +//===-- sanitizer_posix.cpp -----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -16,6 +17,7 @@ #include "sanitizer_common.h" #include "sanitizer_file.h" +#include "sanitizer_flags.h" #include "sanitizer_libc.h" #include "sanitizer_posix.h" #include "sanitizer_procmaps.h" @@ -41,9 +43,8 @@ uptr GetMmapGranularity() { void *MmapOrDie(uptr size, const char *mem_type, bool raw_report) { size = RoundUpTo(size, GetPageSizeCached()); - uptr res = internal_mmap(nullptr, size, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); + uptr res = MmapNamed(nullptr, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, mem_type); int reserrno; if (UNLIKELY(internal_iserror(res, &reserrno))) ReportMmapFailureAndDie(size, mem_type, "allocate", reserrno, raw_report); @@ -64,9 +65,8 @@ void UnmapOrDie(void *addr, uptr size) { void *MmapOrDieOnFatalError(uptr size, const char *mem_type) { size = RoundUpTo(size, GetPageSizeCached()); - uptr res = internal_mmap(nullptr, size, - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON, -1, 0); + uptr res = MmapNamed(nullptr, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON, mem_type); int reserrno; if (UNLIKELY(internal_iserror(res, &reserrno))) { if (reserrno == ENOMEM) @@ -101,12 +101,9 @@ void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment, } void *MmapNoReserveOrDie(uptr size, const char *mem_type) { - uptr PageSize = GetPageSizeCached(); - uptr p = internal_mmap(nullptr, - RoundUpTo(size, PageSize), - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, - -1, 0); + size = RoundUpTo(size, GetPageSizeCached()); + uptr p = MmapNamed(nullptr, size, PROT_READ | PROT_WRITE, + MAP_PRIVATE | MAP_ANON | MAP_NORESERVE, mem_type); int reserrno; if (UNLIKELY(internal_iserror(p, &reserrno))) ReportMmapFailureAndDie(size, mem_type, "allocate noreserve", reserrno); @@ -114,13 +111,12 @@ void *MmapNoReserveOrDie(uptr size, const char *mem_type) { return (void *)p; } -void *MmapFixedImpl(uptr fixed_addr, uptr size, bool tolerate_enomem) { - uptr PageSize = GetPageSizeCached(); - uptr p = internal_mmap((void*)(fixed_addr & ~(PageSize - 1)), - RoundUpTo(size, PageSize), - PROT_READ | PROT_WRITE, - MAP_PRIVATE | MAP_ANON | MAP_FIXED, - -1, 0); +static void *MmapFixedImpl(uptr fixed_addr, uptr size, bool tolerate_enomem, + 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_ANON | MAP_FIXED, name); int reserrno; if (UNLIKELY(internal_iserror(p, &reserrno))) { if (tolerate_enomem && reserrno == ENOMEM) @@ -134,12 +130,12 @@ void *MmapFixedImpl(uptr fixed_addr, uptr size, bool tolerate_enomem) { return (void *)p; } -void *MmapFixedOrDie(uptr fixed_addr, uptr size) { - return MmapFixedImpl(fixed_addr, size, false /*tolerate_enomem*/); +void *MmapFixedOrDie(uptr fixed_addr, uptr size, const char *name) { + return MmapFixedImpl(fixed_addr, size, false /*tolerate_enomem*/, name); } -void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size) { - return MmapFixedImpl(fixed_addr, size, true /*tolerate_enomem*/); +void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size, const char *name) { + return MmapFixedImpl(fixed_addr, size, true /*tolerate_enomem*/, name); } bool MprotectNoAccess(uptr addr, uptr size) { @@ -155,6 +151,8 @@ void MprotectMallocZones(void *addr, int prot) {} #endif fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *errno_p) { + if (ShouldMockFailureToOpen(filename)) + return kInvalidFd; int flags; switch (mode) { case RdOnly: flags = O_RDONLY; break; @@ -164,7 +162,7 @@ fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *errno_p) { fd_t res = internal_open(filename, flags, 0660); if (internal_iserror(res, errno_p)) return kInvalidFd; - return res; + return ReserveStandardFds(res); } void CloseFile(fd_t fd) { @@ -191,11 +189,6 @@ bool WriteToFile(fd_t fd, const void *buff, uptr buff_size, uptr *bytes_written, return true; } -bool RenameFile(const char *oldpath, const char *newpath, error_t *error_p) { - uptr res = internal_rename(oldpath, newpath); - return !internal_iserror(res, error_p); -} - void *MapFileToMemory(const char *file_name, uptr *buff_size) { fd_t fd = OpenFile(file_name, RdOnly); CHECK(fd != kInvalidFd); @@ -233,6 +226,8 @@ static inline bool IntervalsAreSeparate(uptr start1, uptr end1, // memory). bool MemoryRangeIsAvailable(uptr range_start, uptr range_end) { MemoryMappingLayout proc_maps(/*cache_enabled*/true); + if (proc_maps.Error()) + return true; // and hope for the best MemoryMappedSegment segment; while (proc_maps.Next(&segment)) { if (segment.start == segment.end) continue; // Empty range. @@ -272,13 +267,8 @@ bool IsAbsolutePath(const char *path) { void ReportFile::Write(const char *buffer, uptr length) { SpinMutexLock l(mu); - static const char *kWriteError = - "ReportFile::Write() can't output requested buffer!\n"; ReopenIfNecessary(); - if (length != internal_write(fd, buffer, length)) { - internal_write(fd, kWriteError, internal_strlen(kWriteError)); - Die(); - } + internal_write(fd, buffer, length); } bool GetCodeRangeForFile(const char *module, uptr *start, uptr *end) { @@ -326,6 +316,73 @@ const char *SignalContext::Describe() const { return "UNKNOWN SIGNAL"; } +fd_t ReserveStandardFds(fd_t fd) { + CHECK_GE(fd, 0); + if (fd > 2) + return fd; + bool used[3]; + internal_memset(used, 0, sizeof(used)); + while (fd <= 2) { + used[fd] = true; + fd = internal_dup(fd); + } + for (int i = 0; i <= 2; ++i) + if (used[i]) + internal_close(i); + return fd; +} + +bool ShouldMockFailureToOpen(const char *path) { + return common_flags()->test_only_emulate_no_memorymap && + internal_strncmp(path, "/proc/", 6) == 0; +} + +#if SANITIZER_LINUX && !SANITIZER_ANDROID && !SANITIZER_GO +int GetNamedMappingFd(const char *name, uptr size, int *flags) { + if (!common_flags()->decorate_proc_maps || !name) + return -1; + char shmname[200]; + CHECK(internal_strlen(name) < sizeof(shmname) - 10); + internal_snprintf(shmname, sizeof(shmname), "/dev/shm/%zu [%s]", + internal_getpid(), name); + int fd = ReserveStandardFds( + internal_open(shmname, O_RDWR | O_CREAT | O_TRUNC | O_CLOEXEC, S_IRWXU)); + CHECK_GE(fd, 0); + int res = internal_ftruncate(fd, size); + CHECK_EQ(0, res); + res = internal_unlink(shmname); + CHECK_EQ(0, res); + *flags &= ~(MAP_ANON | MAP_ANONYMOUS); + return fd; +} +#else +int GetNamedMappingFd(const char *name, uptr size, int *flags) { + return -1; +} +#endif + +#if SANITIZER_ANDROID +#define PR_SET_VMA 0x53564d41 +#define PR_SET_VMA_ANON_NAME 0 +void DecorateMapping(uptr addr, uptr size, const char *name) { + if (!common_flags()->decorate_proc_maps || !name) + return; + internal_prctl(PR_SET_VMA, PR_SET_VMA_ANON_NAME, addr, size, (uptr)name); +} +#else +void DecorateMapping(uptr addr, uptr size, const char *name) { +} +#endif + +uptr MmapNamed(void *addr, uptr length, int prot, int flags, const char *name) { + int fd = GetNamedMappingFd(name, length, &flags); + uptr res = internal_mmap(addr, length, prot, flags, fd, 0); + if (!internal_iserror(res)) + DecorateMapping(res, length, name); + return res; +} + + } // namespace __sanitizer #endif // SANITIZER_POSIX diff --git a/libsanitizer/sanitizer_common/sanitizer_posix.h b/libsanitizer/sanitizer_common/sanitizer_posix.h index a013f354eec..6cf5ce75b12 100644 --- a/libsanitizer/sanitizer_common/sanitizer_posix.h +++ b/libsanitizer/sanitizer_common/sanitizer_posix.h @@ -1,7 +1,8 @@ //===-- sanitizer_posix.h -------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -14,6 +15,7 @@ // ----------- ATTENTION ------------- // This header should NOT include any other headers from sanitizer runtime. #include "sanitizer_internal_defs.h" +#include "sanitizer_platform_limits_freebsd.h" #include "sanitizer_platform_limits_netbsd.h" #include "sanitizer_platform_limits_openbsd.h" #include "sanitizer_platform_limits_posix.h" @@ -46,13 +48,18 @@ uptr internal_filesize(fd_t fd); // -1 on error. uptr internal_stat(const char *path, void *buf); uptr internal_lstat(const char *path, void *buf); uptr internal_fstat(fd_t fd, void *buf); +uptr internal_dup(int oldfd); uptr internal_dup2(int oldfd, int newfd); uptr internal_readlink(const char *path, char *buf, uptr bufsize); uptr internal_unlink(const char *path); uptr internal_rename(const char *oldpath, const char *newpath); uptr internal_lseek(fd_t fd, OFF_T offset, int whence); +#if SANITIZER_NETBSD +uptr internal_ptrace(int request, int pid, void *addr, int data); +#else uptr internal_ptrace(int request, int pid, void *addr, void *data); +#endif uptr internal_waitpid(int pid, int *status, int options); int internal_fork(); @@ -96,6 +103,23 @@ uptr internal_execve(const char *filename, char *const argv[], bool IsStateDetached(int state); +// Move the fd out of {0, 1, 2} range. +fd_t ReserveStandardFds(fd_t fd); + +bool ShouldMockFailureToOpen(const char *path); + +// Create a non-file mapping with a given /proc/self/maps name. +uptr MmapNamed(void *addr, uptr length, int prot, int flags, const char *name); + +// Platforms should implement at most one of these. +// 1. Provide a pre-decorated file descriptor to use instead of an anonymous +// mapping. +int GetNamedMappingFd(const char *name, uptr size, int *flags); +// 2. Add name to an existing anonymous mapping. The caller must keep *name +// alive at least as long as the mapping exists. +void DecorateMapping(uptr addr, uptr size, const char *name); + + } // namespace __sanitizer #endif // SANITIZER_POSIX_H diff --git a/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp similarity index 85% rename from libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cc rename to libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp index d2fd76a6d36..1bbbf8a675f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_posix_libcdep.cc ----------------------------------------===// +//===-- sanitizer_posix_libcdep.cpp ---------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -67,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 } @@ -92,10 +94,12 @@ static rlim_t getlim(int res) { } static void setlim(int res, rlim_t lim) { - // The following magic is to prevent clang from replacing it with memset. - volatile struct rlimit rlim; + struct rlimit rlim; + if (getrlimit(res, const_cast(&rlim))) { + Report("ERROR: %s getrlimit() failed %d\n", SanitizerToolName, errno); + Die(); + } rlim.rlim_cur = lim; - rlim.rlim_max = lim; if (setrlimit(res, const_cast(&rlim))) { Report("ERROR: %s setrlimit() failed %d\n", SanitizerToolName, errno); Die(); @@ -113,10 +117,6 @@ bool StackSizeIsUnlimited() { return (stack_size == RLIM_INFINITY); } -uptr GetStackSizeLimitInBytes() { - return (uptr)getlim(RLIMIT_STACK); -} - void SetStackSizeLimitInBytes(uptr limit) { setlim(RLIMIT_STACK, (rlim_t)limit); CHECK(!StackSizeIsUnlimited()); @@ -304,37 +304,11 @@ void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args) { MemoryMappingLayout::CacheMemoryMappings(); } -#if SANITIZER_ANDROID || SANITIZER_GO -int GetNamedMappingFd(const char *name, uptr size) { - return -1; -} -#else -int GetNamedMappingFd(const char *name, uptr size) { - if (!common_flags()->decorate_proc_maps) - return -1; - char shmname[200]; - CHECK(internal_strlen(name) < sizeof(shmname) - 10); - internal_snprintf(shmname, sizeof(shmname), "%zu [%s]", internal_getpid(), - name); - int fd = shm_open(shmname, O_RDWR | O_CREAT | O_TRUNC, S_IRWXU); - CHECK_GE(fd, 0); - int res = internal_ftruncate(fd, size); - CHECK_EQ(0, res); - res = shm_unlink(shmname); - CHECK_EQ(0, res); - return fd; -} -#endif - bool MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) { - int fd = name ? GetNamedMappingFd(name, size) : -1; - unsigned flags = MAP_PRIVATE | MAP_FIXED | MAP_NORESERVE; - if (fd == -1) flags |= MAP_ANON; - - uptr PageSize = GetPageSizeCached(); - uptr p = internal_mmap((void *)(fixed_addr & ~(PageSize - 1)), - RoundUpTo(size, PageSize), PROT_READ | PROT_WRITE, - flags, fd, 0); + 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); int reserrno; if (internal_iserror(p, &reserrno)) { Report("ERROR: %s failed to " @@ -347,12 +321,8 @@ bool MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) { } uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) { - // We don't pass `name` along because, when you enable `decorate_proc_maps` - // AND actually use a named mapping AND are using a sanitizer intercepting - // `open` (e.g. TSAN, ESAN), then you'll get a failure during initialization. - // TODO(flowerhack): Fix the implementation of GetNamedMappingFd to solve - // this problem. - base_ = fixed_addr ? MmapFixedNoAccess(fixed_addr, size) : MmapNoAccess(size); + base_ = fixed_addr ? MmapFixedNoAccess(fixed_addr, size, name) + : MmapNoAccess(size); size_ = size; name_ = name; (void)os_handle_; // unsupported @@ -361,12 +331,14 @@ uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) { // Uses fixed_addr for now. // Will use offset instead once we've implemented this function for real. -uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size) { - return reinterpret_cast(MmapFixedOrDieOnFatalError(fixed_addr, size)); +uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size, const char *name) { + return reinterpret_cast( + MmapFixedOrDieOnFatalError(fixed_addr, size, name)); } -uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr size) { - return reinterpret_cast(MmapFixedOrDie(fixed_addr, size)); +uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr size, + const char *name) { + return reinterpret_cast(MmapFixedOrDie(fixed_addr, size, name)); } void ReservedAddressRange::Unmap(uptr addr, uptr size) { @@ -381,12 +353,9 @@ void ReservedAddressRange::Unmap(uptr addr, uptr size) { } void *MmapFixedNoAccess(uptr fixed_addr, uptr size, const char *name) { - int fd = name ? GetNamedMappingFd(name, size) : -1; - unsigned flags = MAP_PRIVATE | MAP_FIXED | MAP_NORESERVE; - if (fd == -1) flags |= MAP_ANON; - - return (void *)internal_mmap((void *)fixed_addr, size, PROT_NONE, flags, fd, - 0); + return (void *)MmapNamed((void *)fixed_addr, size, PROT_NONE, + MAP_PRIVATE | MAP_FIXED | MAP_NORESERVE | MAP_ANON, + name); } void *MmapNoAccess(uptr size) { diff --git a/libsanitizer/sanitizer_common/sanitizer_printf.cc b/libsanitizer/sanitizer_common/sanitizer_printf.cpp similarity index 97% rename from libsanitizer/sanitizer_common/sanitizer_printf.cc rename to libsanitizer/sanitizer_common/sanitizer_printf.cpp index 5da8c5f189d..9d1c544786d 100644 --- a/libsanitizer/sanitizer_common/sanitizer_printf.cc +++ b/libsanitizer/sanitizer_common/sanitizer_printf.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_printf.cc -----------------------------------------------===// +//===-- sanitizer_printf.cpp ----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps.h b/libsanitizer/sanitizer_common/sanitizer_procmaps.h index 606b2921443..052027111ce 100644 --- a/libsanitizer/sanitizer_common/sanitizer_procmaps.h +++ b/libsanitizer/sanitizer_common/sanitizer_procmaps.h @@ -1,7 +1,8 @@ //===-- sanitizer_procmaps.h ------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -68,6 +69,7 @@ class MemoryMappingLayout { explicit MemoryMappingLayout(bool cache_enabled); ~MemoryMappingLayout(); bool Next(MemoryMappedSegment *segment); + bool Error() const; void Reset(); // In some cases, e.g. when running under a sandbox on Linux, ASan is unable // to obtain the memory mappings. It should fall back to pre-cached data diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cc b/libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cpp similarity index 92% rename from libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cc rename to libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cpp index b7887d9e4d3..02ff7c0e91a 100644 --- a/libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cc +++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_procmaps_bsd.cc -----------------------------------------===// +//===-- sanitizer_procmaps_bsd.cpp ----------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -97,6 +98,7 @@ void ReadProcMaps(ProcSelfMapsBuff *proc_maps) { } bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { + CHECK(!Error()); // can not fail char *last = data_.proc_self_maps.data + data_.proc_self_maps.len; if (data_.current >= last) return false; diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_common.cc b/libsanitizer/sanitizer_common/sanitizer_procmaps_common.cpp similarity index 93% rename from libsanitizer/sanitizer_common/sanitizer_procmaps_common.cc rename to libsanitizer/sanitizer_common/sanitizer_procmaps_common.cpp index 24cf9f8b00d..e0cb47f8ca9 100644 --- a/libsanitizer/sanitizer_common/sanitizer_procmaps_common.cc +++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_common.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_procmaps_common.cc --------------------------------------===// +//===-- sanitizer_procmaps_common.cpp -------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -78,12 +79,14 @@ MemoryMappingLayout::MemoryMappingLayout(bool cache_enabled) { ReadProcMaps(&data_.proc_self_maps); if (cache_enabled && data_.proc_self_maps.mmaped_size == 0) LoadFromCache(); - CHECK_GT(data_.proc_self_maps.mmaped_size, 0); - CHECK_GT(data_.proc_self_maps.len, 0); Reset(); } +bool MemoryMappingLayout::Error() const { + return data_.current == nullptr; +} + MemoryMappingLayout::~MemoryMappingLayout() { // Only unmap the buffer if it is different from the cached one. Otherwise // it will be unmapped when the cache is refreshed. diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_linux.cc b/libsanitizer/sanitizer_common/sanitizer_procmaps_linux.cpp similarity index 89% rename from libsanitizer/sanitizer_common/sanitizer_procmaps_linux.cc rename to libsanitizer/sanitizer_common/sanitizer_procmaps_linux.cpp index f9092f4832e..c7af57355b9 100644 --- a/libsanitizer/sanitizer_common/sanitizer_procmaps_linux.cc +++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_linux.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_procmaps_linux.cc ---------------------------------------===// +//===-- sanitizer_procmaps_linux.cpp --------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -29,6 +30,7 @@ static bool IsOneOf(char c, char c1, char c2) { } bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { + if (Error()) return false; // simulate empty maps char *last = data_.proc_self_maps.data + data_.proc_self_maps.len; if (data_.current >= last) return false; char *next_line = diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cc b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp similarity index 97% rename from libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cc rename to libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp index b0e68fde762..ea72a57bf3c 100644 --- a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cc +++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_procmaps_mac.cc -----------------------------------------===// +//===-- sanitizer_procmaps_mac.cpp ----------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -86,6 +87,10 @@ MemoryMappingLayout::MemoryMappingLayout(bool cache_enabled) { MemoryMappingLayout::~MemoryMappingLayout() { } +bool MemoryMappingLayout::Error() const { + return false; +} + // More information about Mach-O headers can be found in mach-o/loader.h // Each Mach-O image has a header (mach_header or mach_header_64) starting with // a magic number, and a list of linker load commands directly following the diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_solaris.cc b/libsanitizer/sanitizer_common/sanitizer_procmaps_solaris.cpp similarity index 67% rename from libsanitizer/sanitizer_common/sanitizer_procmaps_solaris.cc rename to libsanitizer/sanitizer_common/sanitizer_procmaps_solaris.cpp index 9e5e37e6b9d..8793423a601 100644 --- a/libsanitizer/sanitizer_common/sanitizer_procmaps_solaris.cc +++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_solaris.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_procmaps_solaris.cc -------------------------------------===// +//===-- sanitizer_procmaps_solaris.cpp ------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -21,11 +22,16 @@ namespace __sanitizer { void ReadProcMaps(ProcSelfMapsBuff *proc_maps) { - ReadFileToBuffer("/proc/self/xmap", &proc_maps->data, &proc_maps->mmaped_size, - &proc_maps->len); + if (!ReadFileToBuffer("/proc/self/xmap", &proc_maps->data, + &proc_maps->mmaped_size, &proc_maps->len)) { + proc_maps->data = nullptr; + proc_maps->mmaped_size = 0; + proc_maps->len = 0; + } } bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { + if (Error()) return false; // simulate empty maps char *last = data_.proc_self_maps.data + data_.proc_self_maps.len; if (data_.current >= last) return false; @@ -44,9 +50,11 @@ bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { segment->protection |= kProtectionExecute; if (segment->filename != NULL && segment->filename_size > 0) { - internal_snprintf(segment->filename, - Min(segment->filename_size, (uptr)PATH_MAX), "%s", + char proc_path[PATH_MAX + 1]; + + internal_snprintf(proc_path, sizeof(proc_path), "/proc/self/path/%s", xmapentry->pr_mapname); + internal_readlink(proc_path, segment->filename, segment->filename_size); } data_.current += sizeof(prxmap_t); diff --git a/libsanitizer/sanitizer_common/sanitizer_quarantine.h b/libsanitizer/sanitizer_common/sanitizer_quarantine.h index 0ebe97d1e40..992f23152c6 100644 --- a/libsanitizer/sanitizer_common/sanitizer_quarantine.h +++ b/libsanitizer/sanitizer_common/sanitizer_quarantine.h @@ -1,7 +1,8 @@ //===-- sanitizer_quarantine.h ----------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_report_decorator.h b/libsanitizer/sanitizer_common/sanitizer_report_decorator.h index b46a02844df..d276c2cdd84 100644 --- a/libsanitizer/sanitizer_common/sanitizer_report_decorator.h +++ b/libsanitizer/sanitizer_common/sanitizer_report_decorator.h @@ -1,7 +1,8 @@ //===-- sanitizer_report_decorator.h ----------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_ring_buffer.h b/libsanitizer/sanitizer_common/sanitizer_ring_buffer.h index 39ee6315a70..2a46e933b75 100644 --- a/libsanitizer/sanitizer_common/sanitizer_ring_buffer.h +++ b/libsanitizer/sanitizer_common/sanitizer_ring_buffer.h @@ -1,7 +1,8 @@ //===-- sanitizer_ring_buffer.h ---------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -138,7 +139,7 @@ class CompactRingBuffer { SetNext(next); } - T operator[](uptr Idx) const { + const T &operator[](uptr Idx) const { CHECK_LT(Idx, size()); const T *Begin = (const T *)StartOfStorage(); sptr StorageIdx = Next() - Begin; diff --git a/libsanitizer/sanitizer_common/sanitizer_rtems.cc b/libsanitizer/sanitizer_common/sanitizer_rtems.cpp similarity index 95% rename from libsanitizer/sanitizer_common/sanitizer_rtems.cc rename to libsanitizer/sanitizer_common/sanitizer_rtems.cpp index 2792c59da60..0d2576c00ab 100644 --- a/libsanitizer/sanitizer_common/sanitizer_rtems.cc +++ b/libsanitizer/sanitizer_common/sanitizer_rtems.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_rtems.cc ------------------------------------------------===// +//===-- sanitizer_rtems.cpp -----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -93,8 +94,10 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, *tls_addr = *tls_size = 0; } +void InitializePlatformEarly() {} void MaybeReexec() {} void CheckASLR() {} +void CheckMPROTECT() {} void DisableCoreDumperIfNecessary() {} void InstallDeadlySignalHandlers(SignalHandlerType handler) {} void SetAlternateSignalStack() {} @@ -224,11 +227,6 @@ bool WriteToFile(fd_t fd, const void *buff, uptr buff_size, uptr *bytes_written, return true; } -bool RenameFile(const char *oldpath, const char *newpath, error_t *error_p) { - uptr res = rename(oldpath, newpath); - return !internal_iserror(res, error_p); -} - void ReleaseMemoryPagesToOS(uptr beg, uptr end) {} void DumpProcessMap() {} @@ -238,6 +236,7 @@ bool IsAccessibleMemoryRange(uptr beg, uptr size) { } char **GetArgv() { return nullptr; } +char **GetEnviron() { return nullptr; } const char *GetEnv(const char *name) { return getenv(name); diff --git a/libsanitizer/sanitizer_common/sanitizer_rtems.h b/libsanitizer/sanitizer_common/sanitizer_rtems.h index dc64bbc00df..e8adfd500df 100644 --- a/libsanitizer/sanitizer_common/sanitizer_rtems.h +++ b/libsanitizer/sanitizer_common/sanitizer_rtems.h @@ -1,7 +1,8 @@ //===-- sanitizer_rtems.h ---------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_signal_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_signal_interceptors.inc index 7ec63396d79..68d9eb65968 100644 --- a/libsanitizer/sanitizer_common/sanitizer_signal_interceptors.inc +++ b/libsanitizer/sanitizer_common/sanitizer_signal_interceptors.inc @@ -1,7 +1,8 @@ //===-- sanitizer_signal_interceptors.inc -----------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_solaris.cc b/libsanitizer/sanitizer_common/sanitizer_solaris.cpp similarity index 94% rename from libsanitizer/sanitizer_common/sanitizer_solaris.cc rename to libsanitizer/sanitizer_common/sanitizer_solaris.cpp index 9d0c3d93d44..035f2d0ca29 100644 --- a/libsanitizer/sanitizer_common/sanitizer_solaris.cc +++ b/libsanitizer/sanitizer_common/sanitizer_solaris.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_solaris.cc ----------------------------------------------===// +//===-- sanitizer_solaris.cpp ---------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -87,11 +88,6 @@ uptr internal_open(const char *filename, int flags, u32 mode) { return _REAL64(open)(filename, flags, mode); } -uptr OpenFile(const char *filename, bool write) { - return internal_open(filename, - write ? O_WRONLY | O_CREAT : O_RDONLY, 0660); -} - DECLARE__REAL_AND_INTERNAL(uptr, read, fd_t fd, void *buf, uptr count) { return _REAL(read)(fd, buf, count); } @@ -124,6 +120,10 @@ uptr internal_filesize(fd_t fd) { return (uptr)st.st_size; } +DECLARE__REAL_AND_INTERNAL(uptr, dup, int oldfd) { + return _REAL(dup)(oldfd); +} + DECLARE__REAL_AND_INTERNAL(uptr, dup2, int oldfd, int newfd) { return _REAL(dup2)(oldfd, newfd); } diff --git a/libsanitizer/sanitizer_common/sanitizer_stackdepot.cc b/libsanitizer/sanitizer_common/sanitizer_stackdepot.cpp similarity index 87% rename from libsanitizer/sanitizer_common/sanitizer_stackdepot.cc rename to libsanitizer/sanitizer_common/sanitizer_stackdepot.cpp index d48f7d27689..30073a96cee 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stackdepot.cc +++ b/libsanitizer/sanitizer_common/sanitizer_stackdepot.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_stackdepot.cc -------------------------------------------===// +//===-- sanitizer_stackdepot.cpp ------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -12,6 +13,7 @@ #include "sanitizer_stackdepot.h" #include "sanitizer_common.h" +#include "sanitizer_hash.h" #include "sanitizer_stackdepotbase.h" namespace __sanitizer { @@ -24,7 +26,7 @@ struct StackDepotNode { u32 tag; uptr stack[1]; // [size] - static const u32 kTabSizeLog = 20; + static const u32 kTabSizeLog = SANITIZER_ANDROID ? 16 : 20; // Lower kTabSizeLog bits are equal for all items in one bucket. // We use these bits to store the per-stack use counter. static const u32 kUseCountBits = kTabSizeLog; @@ -48,23 +50,9 @@ struct StackDepotNode { return sizeof(StackDepotNode) + (args.size - 1) * sizeof(uptr); } static u32 hash(const args_type &args) { - // murmur2 - const u32 m = 0x5bd1e995; - const u32 seed = 0x9747b28c; - const u32 r = 24; - u32 h = seed ^ (args.size * sizeof(uptr)); - for (uptr i = 0; i < args.size; i++) { - u32 k = args.trace[i]; - k *= m; - k ^= k >> r; - k *= m; - h *= m; - h ^= k; - } - h ^= h >> 13; - h *= m; - h ^= h >> 15; - return h; + MurMur2HashBuilder H(args.size * sizeof(uptr)); + for (uptr i = 0; i < args.size; i++) H.add(args.trace[i]); + return H.get(); } static bool is_valid(const args_type &args) { return args.size > 0 && args.trace; diff --git a/libsanitizer/sanitizer_common/sanitizer_stackdepot.h b/libsanitizer/sanitizer_common/sanitizer_stackdepot.h index dfb5349de9f..bf29cb9a006 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stackdepot.h +++ b/libsanitizer/sanitizer_common/sanitizer_stackdepot.h @@ -1,7 +1,8 @@ //===-- sanitizer_stackdepot.h ----------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -30,7 +31,7 @@ struct StackDepotHandle { void inc_use_count_unsafe(); }; -const int kStackDepotMaxUseCount = 1U << 20; +const int kStackDepotMaxUseCount = 1U << (SANITIZER_ANDROID ? 16 : 20); StackDepotStats *StackDepotGetStats(); u32 StackDepotPut(StackTrace stack); diff --git a/libsanitizer/sanitizer_common/sanitizer_stackdepotbase.h b/libsanitizer/sanitizer_common/sanitizer_stackdepotbase.h index ab4932823a3..ef1b4f7f705 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stackdepotbase.h +++ b/libsanitizer/sanitizer_common/sanitizer_stackdepotbase.h @@ -1,7 +1,8 @@ //===-- sanitizer_stackdepotbase.h ------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp similarity index 82% rename from libsanitizer/sanitizer_common/sanitizer_stacktrace.cc rename to libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp index f1c514d4952..ef14fb704ee 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_stacktrace.cc -------------------------------------------===// +//===-- sanitizer_stacktrace.cpp ------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -47,6 +48,7 @@ void BufferedStackTrace::Init(const uptr *pcs, uptr cnt, uptr extra_top_pc) { static inline uhwptr *GetCanonicFrame(uptr bp, uptr stack_top, uptr stack_bottom) { + CHECK_GT(stack_top, stack_bottom); #ifdef __arm__ if (!IsValidFrame(bp, stack_top, stack_bottom)) return 0; uhwptr *bp_prev = (uhwptr *)bp; @@ -58,17 +60,18 @@ static inline uhwptr *GetCanonicFrame(uptr bp, // Nope, this does not look right either. This means the frame after next does // not have a valid frame pointer, but we can still extract the caller PC. // Unfortunately, there is no way to decide between GCC and LLVM frame - // layouts. Assume GCC. - return bp_prev - 1; + // layouts. Assume LLVM. + return bp_prev; #else return (uhwptr*)bp; #endif } -void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top, - uptr stack_bottom, u32 max_depth) { - const uptr kPageSize = GetPageSizeCached(); +void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top, + uptr stack_bottom, u32 max_depth) { + // TODO(yln): add arg sanity check for stack_top/stack_bottom CHECK_GE(max_depth, 2); + const uptr kPageSize = GetPageSizeCached(); trace_buffer[0] = pc; size = 1; if (stack_top < 4096) return; // Sanity check for stack top. @@ -81,21 +84,14 @@ void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top, IsAligned((uptr)frame, sizeof(*frame)) && size < max_depth) { #ifdef __powerpc__ - // PowerPC ABIs specify that the return address is saved on the - // *caller's* stack frame. Thus we must dereference the back chain - // to find the caller frame before extracting it. + // PowerPC ABIs specify that the return address is saved at offset + // 16 of the *caller's* stack frame. Thus we must dereference the + // back chain to find the caller frame before extracting it. uhwptr *caller_frame = (uhwptr*)frame[0]; if (!IsValidFrame((uptr)caller_frame, stack_top, bottom) || !IsAligned((uptr)caller_frame, sizeof(uhwptr))) break; - // For most ABIs the offset where the return address is saved is two - // register sizes. The exception is the SVR4 ABI, which uses an - // offset of only one register size. -#ifdef _CALL_SYSV - uhwptr pc1 = caller_frame[1]; -#else uhwptr pc1 = caller_frame[2]; -#endif #elif defined(__s390__) uhwptr pc1 = frame[14]; #else diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.h b/libsanitizer/sanitizer_common/sanitizer_stacktrace.h index 039b5d96dc2..f1f29e9f32e 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.h +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.h @@ -1,7 +1,8 @@ //===-- sanitizer_stacktrace.h ----------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -15,6 +16,8 @@ namespace __sanitizer { +struct BufferedStackTrace; + static const u32 kStackTraceMax = 256; #if SANITIZER_LINUX && defined(__mips__) @@ -57,7 +60,7 @@ struct StackTrace { static bool WillUseFastUnwind(bool request_fast_unwind) { if (!SANITIZER_CAN_FAST_UNWIND) return false; - else if (!SANITIZER_CAN_SLOW_UNWIND) + if (!SANITIZER_CAN_SLOW_UNWIND) return true; return request_fast_unwind; } @@ -95,6 +98,23 @@ struct BufferedStackTrace : public StackTrace { BufferedStackTrace() : StackTrace(trace_buffer, 0), top_frame_bp(0) {} void Init(const uptr *pcs, uptr cnt, uptr extra_top_pc = 0); + + // Get the stack trace with the given pc and bp. + // The pc will be in the position 0 of the resulting stack trace. + // The bp may refer to the current frame or to the caller's frame. + void Unwind(uptr pc, uptr bp, void *context, bool request_fast, + u32 max_depth = kStackTraceMax) { + top_frame_bp = (max_depth > 0) ? bp : 0; + // Small max_depth optimization + if (max_depth <= 1) { + if (max_depth == 1) + trace_buffer[0] = pc; + size = max_depth; + return; + } + UnwindImpl(pc, bp, context, request_fast, max_depth); + } + void Unwind(u32 max_depth, uptr pc, uptr bp, void *context, uptr stack_top, uptr stack_bottom, bool request_fast_unwind); @@ -104,16 +124,23 @@ struct BufferedStackTrace : public StackTrace { } private: - void FastUnwindStack(uptr pc, uptr bp, uptr stack_top, uptr stack_bottom, - u32 max_depth); - void SlowUnwindStack(uptr pc, u32 max_depth); - void SlowUnwindStackWithContext(uptr pc, void *context, - u32 max_depth); + // Every runtime defines its own implementation of this method + void UnwindImpl(uptr pc, uptr bp, void *context, bool request_fast, + u32 max_depth); + + // UnwindFast/Slow have platform-specific implementations + void UnwindFast(uptr pc, uptr bp, uptr stack_top, uptr stack_bottom, + u32 max_depth); + void UnwindSlow(uptr pc, u32 max_depth); + void UnwindSlow(uptr pc, void *context, u32 max_depth); + void PopStackFrames(uptr count); uptr LocatePcInTrace(uptr pc); BufferedStackTrace(const BufferedStackTrace &) = delete; void operator=(const BufferedStackTrace &) = delete; + + friend class FastUnwindTest; }; // Check if given pointer points into allocated stack area. @@ -125,21 +152,23 @@ static inline bool IsValidFrame(uptr frame, uptr stack_top, uptr stack_bottom) { // Use this macro if you want to print stack trace with the caller // of the current function in the top frame. -#define GET_CALLER_PC_BP_SP \ - uptr bp = GET_CURRENT_FRAME(); \ - uptr pc = GET_CALLER_PC(); \ - uptr local_stack; \ - uptr sp = (uptr)&local_stack - #define GET_CALLER_PC_BP \ uptr bp = GET_CURRENT_FRAME(); \ uptr pc = GET_CALLER_PC(); +#define GET_CALLER_PC_BP_SP \ + GET_CALLER_PC_BP; \ + uptr local_stack; \ + uptr sp = (uptr)&local_stack + // Use this macro if you want to print stack trace with the current // function in the top frame. -#define GET_CURRENT_PC_BP_SP \ +#define GET_CURRENT_PC_BP \ uptr bp = GET_CURRENT_FRAME(); \ - uptr pc = StackTrace::GetCurrentPc(); \ + uptr pc = StackTrace::GetCurrentPc() + +#define GET_CURRENT_PC_BP_SP \ + GET_CURRENT_PC_BP; \ uptr local_stack; \ uptr sp = (uptr)&local_stack diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cpp similarity index 90% rename from libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cc rename to libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cpp index ff085519e52..2c08274f35c 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_stacktrace_libcdep.cc -----------------------------------===// +//===-- sanitizer_stacktrace_libcdep.cpp ----------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -56,6 +57,8 @@ void StackTrace::Print() const { void BufferedStackTrace::Unwind(u32 max_depth, uptr pc, uptr bp, void *context, uptr stack_top, uptr stack_bottom, bool request_fast_unwind) { + // Ensures all call sites get what they requested. + CHECK_EQ(request_fast_unwind, WillUseFastUnwind(request_fast_unwind)); top_frame_bp = (max_depth > 0) ? bp : 0; // Avoid doing any work for small max_depth. if (max_depth == 0) { @@ -70,14 +73,14 @@ void BufferedStackTrace::Unwind(u32 max_depth, uptr pc, uptr bp, void *context, if (!WillUseFastUnwind(request_fast_unwind)) { #if SANITIZER_CAN_SLOW_UNWIND if (context) - SlowUnwindStackWithContext(pc, context, max_depth); + UnwindSlow(pc, context, max_depth); else - SlowUnwindStack(pc, max_depth); + UnwindSlow(pc, max_depth); #else UNREACHABLE("slow unwind requested but not available"); #endif } else { - FastUnwindStack(pc, bp, stack_top, stack_bottom, max_depth); + UnwindFast(pc, bp, stack_top, stack_bottom, max_depth); } } diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cpp similarity index 95% rename from libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cc rename to libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cpp index 7e21c4b883f..150ff475316 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cc +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_common.cc -----------------------------------------------===// +//===-- sanitizer_common.cpp ----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -15,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) { @@ -96,6 +97,8 @@ static const char *DemangleFunctionName(const char *function) { return "pthread_equal"; if (!internal_strcmp(function, "__libc_thr_curcpu")) return "pthread_curcpu_np"; + if (!internal_strcmp(function, "__libc_thr_sigsetmask")) + return "pthread_sigmask"; #endif return function; diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.h b/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.h index cf3cd4292dd..f7f7629f773 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.h +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.h @@ -1,7 +1,8 @@ //===-- sanitizer_stacktrace_printer.h --------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cpp similarity index 74% rename from libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cc rename to libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cpp index bd04d0f715b..34190fb1bbb 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cc +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_stacktrace_sparc.cc -------------------------------------===// +//===-- sanitizer_stacktrace_sparc.cpp ------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -24,10 +25,11 @@ namespace __sanitizer { -void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top, - uptr stack_bottom, u32 max_depth) { - const uptr kPageSize = GetPageSizeCached(); +void BufferedStackTrace::UnwindFast(uptr pc, uptr bp, uptr stack_top, + uptr stack_bottom, u32 max_depth) { + // TODO(yln): add arg sanity check for stack_top/stack_bottom CHECK_GE(max_depth, 2); + const uptr kPageSize = GetPageSizeCached(); #if defined(__GNUC__) // __builtin_return_address returns the address of the call instruction // on the SPARC and not the return address, so we need to compensate. @@ -50,11 +52,9 @@ void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top, uptr prev_bp = GET_CURRENT_FRAME(); uptr next_bp = prev_bp; unsigned int i = 0; - while (next_bp != bp && - IsAligned(next_bp, sizeof(uhwptr)) && - i++ < 8) { + while (next_bp != bp && IsAligned(next_bp, sizeof(uhwptr)) && i++ < 8) { prev_bp = next_bp; - next_bp = (uptr) ((uhwptr *) next_bp)[14] + STACK_BIAS; + next_bp = (uptr)((uhwptr *)next_bp)[14] + STACK_BIAS; } if (next_bp == bp) bp = prev_bp; @@ -62,8 +62,7 @@ void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top, // Goes up as we walk the stack. uptr bottom = stack_bottom; // Avoid infinite loop when frame == frame[0] by using frame > prev_frame. - while (IsValidFrame(bp, stack_top, bottom) && - IsAligned(bp, sizeof(uhwptr)) && + while (IsValidFrame(bp, stack_top, bottom) && IsAligned(bp, sizeof(uhwptr)) && size < max_depth) { uhwptr pc1 = ((uhwptr *)bp)[15]; // Let's assume that any pointer in the 0th page is invalid and @@ -74,10 +73,10 @@ void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top, if (pc1 != pc) { // %o7 contains the address of the call instruction and not the // return address, so we need to compensate. - trace_buffer[size++] = GetNextInstructionPc((uptr) pc1); + trace_buffer[size++] = GetNextInstructionPc((uptr)pc1); } bottom = bp; - bp = (uptr) ((uhwptr *) bp)[14] + STACK_BIAS; + bp = (uptr)((uhwptr *)bp)[14] + STACK_BIAS; } } diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld.h b/libsanitizer/sanitizer_common/sanitizer_stoptheworld.h index 8c3d2c05557..4e424005714 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld.h +++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld.h @@ -1,7 +1,8 @@ //===-- sanitizer_stoptheworld.h --------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp similarity index 98% rename from libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc rename to libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp index 635c5732d84..b520dc8daca 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_stoptheworld_linux_libcdep.cc ---------------------------===// +//===-- sanitizer_stoptheworld_linux_libcdep.cpp --------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_mac.cc b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_mac.cpp similarity index 94% rename from libsanitizer/sanitizer_common/sanitizer_stoptheworld_mac.cc rename to libsanitizer/sanitizer_common/sanitizer_stoptheworld_mac.cpp index 6282694fa8c..9dffd21ecb7 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_mac.cc +++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_mac.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_stoptheworld_mac.cc -------------------------------------===// +//===-- sanitizer_stoptheworld_mac.cpp ------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp new file mode 100644 index 00000000000..5690d75097f --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_netbsd_libcdep.cpp @@ -0,0 +1,356 @@ +//===-- 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. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// See sanitizer_stoptheworld.h for details. +// This implementation was inspired by Markus Gutschke's linuxthreads.cc. +// +// This is a NetBSD variation of Linux stoptheworld implementation +// See sanitizer_stoptheworld_linux_libcdep.cpp for code comments. +// +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" + +#if SANITIZER_NETBSD + +#include "sanitizer_stoptheworld.h" + +#include "sanitizer_atomic.h" +#include "sanitizer_platform_limits_posix.h" + +#include + +#include +#include +#include + +#include + +#include +#include +#include +#include +#include + +#define internal_sigaction_norestorer internal_sigaction + +#include "sanitizer_common.h" +#include "sanitizer_flags.h" +#include "sanitizer_libc.h" +#include "sanitizer_linux.h" +#include "sanitizer_mutex.h" +#include "sanitizer_placement_new.h" + +namespace __sanitizer { + +class SuspendedThreadsListNetBSD : public SuspendedThreadsList { + public: + SuspendedThreadsListNetBSD() { thread_ids_.reserve(1024); } + + tid_t GetThreadID(uptr index) const; + uptr ThreadCount() const; + bool ContainsTid(tid_t thread_id) const; + void Append(tid_t tid); + + PtraceRegistersStatus GetRegistersAndSP(uptr index, uptr *buffer, + uptr *sp) const; + uptr RegisterCount() const; + + private: + InternalMmapVector thread_ids_; +}; + +struct TracerThreadArgument { + StopTheWorldCallback callback; + void *callback_argument; + BlockingMutex mutex; + atomic_uintptr_t done; + uptr parent_pid; +}; + +class ThreadSuspender { + public: + explicit ThreadSuspender(pid_t pid, TracerThreadArgument *arg) + : arg(arg), pid_(pid) { + CHECK_GE(pid, 0); + } + bool SuspendAllThreads(); + void ResumeAllThreads(); + void KillAllThreads(); + SuspendedThreadsListNetBSD &suspended_threads_list() { + return suspended_threads_list_; + } + TracerThreadArgument *arg; + + private: + SuspendedThreadsListNetBSD suspended_threads_list_; + pid_t pid_; +}; + +void ThreadSuspender::ResumeAllThreads() { + int pterrno; + if (!internal_iserror(internal_ptrace(PT_DETACH, pid_, (void *)(uptr)1, 0), + &pterrno)) { + VReport(2, "Detached from process %d.\n", pid_); + } else { + VReport(1, "Could not detach from process %d (errno %d).\n", pid_, pterrno); + } +} + +void ThreadSuspender::KillAllThreads() { + internal_ptrace(PT_KILL, pid_, nullptr, 0); +} + +bool ThreadSuspender::SuspendAllThreads() { + int pterrno; + if (internal_iserror(internal_ptrace(PT_ATTACH, pid_, nullptr, 0), + &pterrno)) { + Printf("Could not attach to process %d (errno %d).\n", pid_, pterrno); + return false; + } + + int status; + uptr waitpid_status; + HANDLE_EINTR(waitpid_status, internal_waitpid(pid_, &status, 0)); + + VReport(2, "Attached to process %d.\n", pid_); + + struct ptrace_lwpinfo pl; + int val; + pl.pl_lwpid = 0; + while ((val = ptrace(PT_LWPINFO, pid_, (void *)&pl, sizeof(pl))) != -1 && + pl.pl_lwpid != 0) { + suspended_threads_list_.Append(pl.pl_lwpid); + VReport(2, "Appended thread %d in process %d.\n", pl.pl_lwpid, pid_); + } + return true; +} + +// Pointer to the ThreadSuspender instance for use in signal handler. +static ThreadSuspender *thread_suspender_instance = nullptr; + +// Synchronous signals that should not be blocked. +static const int kSyncSignals[] = {SIGABRT, SIGILL, SIGFPE, SIGSEGV, + SIGBUS, SIGXCPU, SIGXFSZ}; + +static void TracerThreadDieCallback() { + ThreadSuspender *inst = thread_suspender_instance; + if (inst && stoptheworld_tracer_pid == internal_getpid()) { + inst->KillAllThreads(); + thread_suspender_instance = nullptr; + } +} + +// Signal handler to wake up suspended threads when the tracer thread dies. +static void TracerThreadSignalHandler(int signum, __sanitizer_siginfo *siginfo, + void *uctx) { + SignalContext ctx(siginfo, uctx); + Printf("Tracer caught signal %d: addr=0x%zx pc=0x%zx sp=0x%zx\n", signum, + ctx.addr, ctx.pc, ctx.sp); + ThreadSuspender *inst = thread_suspender_instance; + if (inst) { + if (signum == SIGABRT) + inst->KillAllThreads(); + else + inst->ResumeAllThreads(); + RAW_CHECK(RemoveDieCallback(TracerThreadDieCallback)); + thread_suspender_instance = nullptr; + atomic_store(&inst->arg->done, 1, memory_order_relaxed); + } + internal__exit((signum == SIGABRT) ? 1 : 2); +} + +// Size of alternative stack for signal handlers in the tracer thread. +static const int kHandlerStackSize = 8192; + +// This function will be run as a cloned task. +static int TracerThread(void *argument) { + TracerThreadArgument *tracer_thread_argument = + (TracerThreadArgument *)argument; + + // Check if parent is already dead. + if (internal_getppid() != tracer_thread_argument->parent_pid) + internal__exit(4); + + // Wait for the parent thread to finish preparations. + tracer_thread_argument->mutex.Lock(); + tracer_thread_argument->mutex.Unlock(); + + RAW_CHECK(AddDieCallback(TracerThreadDieCallback)); + + ThreadSuspender thread_suspender(internal_getppid(), tracer_thread_argument); + // Global pointer for the signal handler. + thread_suspender_instance = &thread_suspender; + + // Alternate stack for signal handling. + InternalMmapVector handler_stack_memory(kHandlerStackSize); + stack_t handler_stack; + internal_memset(&handler_stack, 0, sizeof(handler_stack)); + handler_stack.ss_sp = handler_stack_memory.data(); + handler_stack.ss_size = kHandlerStackSize; + internal_sigaltstack(&handler_stack, nullptr); + + // Install our handler for synchronous signals. Other signals should be + // blocked by the mask we inherited from the parent thread. + for (uptr i = 0; i < ARRAY_SIZE(kSyncSignals); i++) { + __sanitizer_sigaction act; + internal_memset(&act, 0, sizeof(act)); + act.sigaction = TracerThreadSignalHandler; + act.sa_flags = SA_ONSTACK | SA_SIGINFO; + internal_sigaction_norestorer(kSyncSignals[i], &act, 0); + } + + int exit_code = 0; + if (!thread_suspender.SuspendAllThreads()) { + VReport(1, "Failed suspending threads.\n"); + exit_code = 3; + } else { + tracer_thread_argument->callback(thread_suspender.suspended_threads_list(), + tracer_thread_argument->callback_argument); + thread_suspender.ResumeAllThreads(); + exit_code = 0; + } + RAW_CHECK(RemoveDieCallback(TracerThreadDieCallback)); + thread_suspender_instance = nullptr; + atomic_store(&tracer_thread_argument->done, 1, memory_order_relaxed); + return exit_code; +} + +class ScopedStackSpaceWithGuard { + public: + explicit ScopedStackSpaceWithGuard(uptr stack_size) { + stack_size_ = stack_size; + guard_size_ = GetPageSizeCached(); + // FIXME: Omitting MAP_STACK here works in current kernels but might break + // in the future. + guard_start_ = + (uptr)MmapOrDie(stack_size_ + guard_size_, "ScopedStackWithGuard"); + CHECK(MprotectNoAccess((uptr)guard_start_, guard_size_)); + } + ~ScopedStackSpaceWithGuard() { + UnmapOrDie((void *)guard_start_, stack_size_ + guard_size_); + } + void *Bottom() const { + return (void *)(guard_start_ + stack_size_ + guard_size_); + } + + private: + uptr stack_size_; + uptr guard_size_; + uptr guard_start_; +}; + +static __sanitizer_sigset_t blocked_sigset; +static __sanitizer_sigset_t old_sigset; + +struct ScopedSetTracerPID { + explicit ScopedSetTracerPID(uptr tracer_pid) { + stoptheworld_tracer_pid = tracer_pid; + stoptheworld_tracer_ppid = internal_getpid(); + } + ~ScopedSetTracerPID() { + stoptheworld_tracer_pid = 0; + stoptheworld_tracer_ppid = 0; + } +}; + +void StopTheWorld(StopTheWorldCallback callback, void *argument) { + // Prepare the arguments for TracerThread. + struct TracerThreadArgument tracer_thread_argument; + tracer_thread_argument.callback = callback; + tracer_thread_argument.callback_argument = argument; + tracer_thread_argument.parent_pid = internal_getpid(); + atomic_store(&tracer_thread_argument.done, 0, memory_order_relaxed); + const uptr kTracerStackSize = 2 * 1024 * 1024; + ScopedStackSpaceWithGuard tracer_stack(kTracerStackSize); + + tracer_thread_argument.mutex.Lock(); + + internal_sigfillset(&blocked_sigset); + for (uptr i = 0; i < ARRAY_SIZE(kSyncSignals); i++) + internal_sigdelset(&blocked_sigset, kSyncSignals[i]); + int rv = internal_sigprocmask(SIG_BLOCK, &blocked_sigset, &old_sigset); + CHECK_EQ(rv, 0); + uptr tracer_pid = internal_clone(TracerThread, tracer_stack.Bottom(), + CLONE_VM | CLONE_FS | CLONE_FILES, + &tracer_thread_argument); + internal_sigprocmask(SIG_SETMASK, &old_sigset, 0); + int local_errno = 0; + if (internal_iserror(tracer_pid, &local_errno)) { + VReport(1, "Failed spawning a tracer thread (errno %d).\n", local_errno); + tracer_thread_argument.mutex.Unlock(); + } else { + ScopedSetTracerPID scoped_set_tracer_pid(tracer_pid); + + tracer_thread_argument.mutex.Unlock(); + + while (atomic_load(&tracer_thread_argument.done, memory_order_relaxed) == 0) + sched_yield(); + + for (;;) { + uptr waitpid_status = internal_waitpid(tracer_pid, nullptr, __WALL); + if (!internal_iserror(waitpid_status, &local_errno)) + break; + if (local_errno == EINTR) + continue; + VReport(1, "Waiting on the tracer thread failed (errno %d).\n", + local_errno); + break; + } + } +} + +tid_t SuspendedThreadsListNetBSD::GetThreadID(uptr index) const { + CHECK_LT(index, thread_ids_.size()); + return thread_ids_[index]; +} + +uptr SuspendedThreadsListNetBSD::ThreadCount() const { + return thread_ids_.size(); +} + +bool SuspendedThreadsListNetBSD::ContainsTid(tid_t thread_id) const { + for (uptr i = 0; i < thread_ids_.size(); i++) { + if (thread_ids_[i] == thread_id) + return true; + } + return false; +} + +void SuspendedThreadsListNetBSD::Append(tid_t tid) { + thread_ids_.push_back(tid); +} + +PtraceRegistersStatus SuspendedThreadsListNetBSD::GetRegistersAndSP( + uptr index, uptr *buffer, uptr *sp) const { + lwpid_t tid = GetThreadID(index); + pid_t ppid = internal_getppid(); + struct reg regs; + int pterrno; + bool isErr = + internal_iserror(internal_ptrace(PT_GETREGS, ppid, ®s, tid), &pterrno); + if (isErr) { + VReport(1, + "Could not get registers from process %d thread %d (errno %d).\n", + ppid, tid, pterrno); + return pterrno == ESRCH ? REGISTERS_UNAVAILABLE_FATAL + : REGISTERS_UNAVAILABLE; + } + + *sp = PTRACE_REG_SP(®s); + internal_memcpy(buffer, ®s, sizeof(regs)); + + return REGISTERS_AVAILABLE; +} + +uptr SuspendedThreadsListNetBSD::RegisterCount() const { + return sizeof(struct reg) / sizeof(uptr); +} +} // namespace __sanitizer + +#endif diff --git a/libsanitizer/sanitizer_common/sanitizer_suppressions.cc b/libsanitizer/sanitizer_common/sanitizer_suppressions.cpp similarity index 84% rename from libsanitizer/sanitizer_common/sanitizer_suppressions.cc rename to libsanitizer/sanitizer_common/sanitizer_suppressions.cpp index 6c682a1fb62..44c83a66c5f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_suppressions.cc +++ b/libsanitizer/sanitizer_common/sanitizer_suppressions.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_suppressions.cc -----------------------------------------===// +//===-- sanitizer_suppressions.cpp ----------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -29,6 +30,7 @@ SuppressionContext::SuppressionContext(const char *suppression_types[], internal_memset(has_suppression_type_, 0, suppression_types_num_); } +#if !SANITIZER_FUCHSIA static bool GetPathAssumingFileIsRelativeToExec(const char *file_path, /*out*/char *new_file_path, uptr new_file_path_size) { @@ -45,20 +47,30 @@ static bool GetPathAssumingFileIsRelativeToExec(const char *file_path, return false; } +static const char *FindFile(const char *file_path, + /*out*/char *new_file_path, + uptr new_file_path_size) { + // If we cannot find the file, check if its location is relative to + // the location of the executable. + if (!FileExists(file_path) && !IsAbsolutePath(file_path) && + GetPathAssumingFileIsRelativeToExec(file_path, new_file_path, + new_file_path_size)) { + return new_file_path; + } + return file_path; +} +#else +static const char *FindFile(const char *file_path, char *, uptr) { + return file_path; +} +#endif + void SuppressionContext::ParseFromFile(const char *filename) { if (filename[0] == '\0') return; -#if !SANITIZER_FUCHSIA - // If we cannot find the file, check if its location is relative to - // the location of the executable. InternalScopedString new_file_path(kMaxPathLength); - if (!FileExists(filename) && !IsAbsolutePath(filename) && - GetPathAssumingFileIsRelativeToExec(filename, new_file_path.data(), - new_file_path.size())) { - filename = new_file_path.data(); - } -#endif // !SANITIZER_FUCHSIA + filename = FindFile(filename, new_file_path.data(), new_file_path.size()); // Read the file. VPrintf(1, "%s: reading suppressions file at %s\n", @@ -92,7 +104,7 @@ bool SuppressionContext::Match(const char *str, const char *type, } static const char *StripPrefix(const char *str, const char *prefix) { - while (str && *str == *prefix) { + while (*str && *str == *prefix) { str++; prefix++; } diff --git a/libsanitizer/sanitizer_common/sanitizer_suppressions.h b/libsanitizer/sanitizer_common/sanitizer_suppressions.h index ed6d7baae84..f9da7af7e6a 100644 --- a/libsanitizer/sanitizer_common/sanitizer_suppressions.h +++ b/libsanitizer/sanitizer_common/sanitizer_suppressions.h @@ -1,7 +1,8 @@ //===-- sanitizer_suppressions.h --------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer.cpp similarity index 86% rename from libsanitizer/sanitizer_common/sanitizer_symbolizer.cc rename to libsanitizer/sanitizer_common/sanitizer_symbolizer.cpp index 9d3e0115eb2..ce2ece5f4d5 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer.cc +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_symbolizer.cc -------------------------------------------===// +//===-- sanitizer_symbolizer.cpp ------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -65,6 +66,16 @@ void DataInfo::Clear() { internal_memset(this, 0, sizeof(DataInfo)); } +void FrameInfo::Clear() { + InternalFree(module); + for (LocalInfo &local : locals) { + InternalFree(local.function_name); + InternalFree(local.name); + InternalFree(local.decl_file); + } + locals.clear(); +} + Symbolizer *Symbolizer::symbolizer_; StaticSpinMutex Symbolizer::init_mu_; LowLevelAllocator Symbolizer::symbolizer_allocator_; diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer.h index ef2fb4a0af3..51648e2d0e8 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer.h +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer.h @@ -1,7 +1,8 @@ //===-- sanitizer_symbolizer.h ----------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -19,6 +20,7 @@ #include "sanitizer_common.h" #include "sanitizer_mutex.h" +#include "sanitizer_vector.h" namespace __sanitizer { @@ -76,6 +78,32 @@ struct DataInfo { void Clear(); }; +struct LocalInfo { + char *function_name = nullptr; + char *name = nullptr; + char *decl_file = nullptr; + unsigned decl_line = 0; + + bool has_frame_offset = false; + bool has_size = false; + bool has_tag_offset = false; + + sptr frame_offset; + uptr size; + uptr tag_offset; + + void Clear(); +}; + +struct FrameInfo { + char *module; + uptr module_offset; + ModuleArch module_arch; + + InternalMmapVector locals; + void Clear(); +}; + class SymbolizerTool; class Symbolizer final { @@ -88,6 +116,7 @@ class Symbolizer final { // all inlined functions, if necessary). SymbolizedStack *SymbolizePC(uptr address); bool SymbolizeData(uptr address, DataInfo *info); + bool SymbolizeFrame(uptr address, FrameInfo *info); // The module names Symbolizer returns are stable and unique for every given // module. It is safe to store and compare them as pointers. diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_fuchsia.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer_fuchsia.h index 2f680752255..c4061e38c6a 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_fuchsia.h +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_fuchsia.h @@ -1,7 +1,8 @@ //===-- sanitizer_symbolizer_fuchsia.h -----------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -33,6 +34,9 @@ constexpr const char *kFormatData = "{{{data:%p}}}"; // One frame in a backtrace (printed on a line by itself). constexpr const char *kFormatFrame = "{{{bt:%u:%p}}}"; +// Dump trigger element. +#define FORMAT_DUMPFILE "{{{dumpfile:%s:%s}}}" + } // namespace __sanitizer #endif // SANITIZER_SYMBOLIZER_FUCHSIA_H diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h index eae7509576e..3031f28a20e 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_internal.h @@ -1,7 +1,8 @@ //===-- sanitizer_symbolizer_internal.h -------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -14,6 +15,7 @@ #include "sanitizer_symbolizer.h" #include "sanitizer_file.h" +#include "sanitizer_vector.h" namespace __sanitizer { @@ -57,6 +59,10 @@ class SymbolizerTool { UNIMPLEMENTED(); } + virtual bool SymbolizeFrame(uptr addr, FrameInfo *info) { + return false; + } + virtual void Flush() {} // Return nullptr to fallback to the default platform-specific demangler. @@ -74,26 +80,27 @@ class SymbolizerProcess { 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_; @@ -119,12 +126,13 @@ class LLVMSymbolizer : public SymbolizerTool { explicit LLVMSymbolizer(const char *path, LowLevelAllocator *allocator); bool SymbolizePC(uptr addr, SymbolizedStack *stack) override; - bool SymbolizeData(uptr addr, DataInfo *info) override; + bool SymbolizeFrame(uptr addr, FrameInfo *info) override; private: - const char *FormatAndSendCommand(bool is_data, const char *module_name, - uptr module_offset, ModuleArch arch); + const char *FormatAndSendCommand(const char *command_prefix, + const char *module_name, uptr module_offset, + ModuleArch arch); LLVMSymbolizerProcess *symbolizer_process_; static const uptr kBufferSize = 16 * 1024; diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cpp similarity index 95% rename from libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc rename to libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cpp index eebc30b124d..27ed222745e 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cc +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_symbolizer_libbacktrace.cc ------------------------------===// +//===-- sanitizer_symbolizer_libbacktrace.cpp -----------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.h index ab1d6f99163..e2a0f71420f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.h +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libbacktrace.h @@ -1,7 +1,8 @@ //===-- sanitizer_symbolizer_libbacktrace.h ---------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp similarity index 85% rename from libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cc rename to libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp index 9e57bb62485..742b9748c98 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_symbolizer_libcdep.cc -----------------------------------===// +//===-- sanitizer_symbolizer_libcdep.cpp ----------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -24,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) { @@ -57,6 +58,16 @@ const char *ExtractUptr(const char *str, const char *delims, uptr *result) { return ret; } +const char *ExtractSptr(const char *str, const char *delims, sptr *result) { + char *buff; + const char *ret = ExtractToken(str, delims, &buff); + if (buff != 0) { + *result = (sptr)internal_atoll(buff); + } + InternalFree(buff); + return ret; +} + const char *ExtractTokenUpToDelimiter(const char *str, const char *delimiter, char **result) { const char *found_delimiter = internal_strstr(str, delimiter); @@ -111,6 +122,22 @@ bool Symbolizer::SymbolizeData(uptr addr, DataInfo *info) { return true; } +bool Symbolizer::SymbolizeFrame(uptr addr, FrameInfo *info) { + BlockingMutexLock l(&mu_); + const char *module_name; + if (!FindModuleNameAndOffsetForAddress( + addr, &module_name, &info->module_offset, &info->module_arch)) + return false; + info->module = internal_strdup(module_name); + for (auto &tool : tools_) { + SymbolizerScope sym_scope(this); + if (tool.SymbolizeFrame(addr, info)) { + return true; + } + } + return true; +} + bool Symbolizer::GetModuleNameAndOffsetForPC(uptr pc, const char **module_name, uptr *module_address) { BlockingMutexLock l(&mu_); @@ -342,10 +369,38 @@ void ParseSymbolizeDataOutput(const char *str, DataInfo *info) { str = ExtractUptr(str, "\n", &info->size); } +static void ParseSymbolizeFrameOutput(const char *str, + InternalMmapVector *locals) { + if (internal_strncmp(str, "??", 2) == 0) + return; + + while (*str) { + LocalInfo local; + str = ExtractToken(str, "\n", &local.function_name); + str = ExtractToken(str, "\n", &local.name); + + AddressInfo addr; + str = ParseFileLineInfo(&addr, str); + local.decl_file = addr.file; + local.decl_line = addr.line; + + local.has_frame_offset = internal_strncmp(str, "??", 2) != 0; + str = ExtractSptr(str, " ", &local.frame_offset); + + local.has_size = internal_strncmp(str, "??", 2) != 0; + str = ExtractUptr(str, " ", &local.size); + + local.has_tag_offset = internal_strncmp(str, "??", 2) != 0; + str = ExtractUptr(str, "\n", &local.tag_offset); + + locals->push_back(local); + } +} + bool LLVMSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) { AddressInfo *info = &stack->info; const char *buf = FormatAndSendCommand( - /*is_data*/ false, info->module, info->module_offset, info->module_arch); + "CODE", info->module, info->module_offset, info->module_arch); if (buf) { ParseSymbolizePCOutput(buf, stack); return true; @@ -355,7 +410,7 @@ bool LLVMSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) { bool LLVMSymbolizer::SymbolizeData(uptr addr, DataInfo *info) { const char *buf = FormatAndSendCommand( - /*is_data*/ true, info->module, info->module_offset, info->module_arch); + "DATA", info->module, info->module_offset, info->module_arch); if (buf) { ParseSymbolizeDataOutput(buf, info); info->start += (addr - info->module_offset); // Add the base address. @@ -364,22 +419,31 @@ bool LLVMSymbolizer::SymbolizeData(uptr addr, DataInfo *info) { return false; } -const char *LLVMSymbolizer::FormatAndSendCommand(bool is_data, +bool LLVMSymbolizer::SymbolizeFrame(uptr addr, FrameInfo *info) { + const char *buf = FormatAndSendCommand( + "FRAME", info->module, info->module_offset, info->module_arch); + if (buf) { + ParseSymbolizeFrameOutput(buf, &info->locals); + return true; + } + return false; +} + +const char *LLVMSymbolizer::FormatAndSendCommand(const char *command_prefix, const char *module_name, uptr module_offset, ModuleArch arch) { CHECK(module_name); - const char *is_data_str = is_data ? "DATA " : ""; if (arch == kModuleArchUnknown) { - if (internal_snprintf(buffer_, kBufferSize, "%s\"%s\" 0x%zx\n", is_data_str, - module_name, + if (internal_snprintf(buffer_, kBufferSize, "%s \"%s\" 0x%zx\n", + command_prefix, module_name, module_offset) >= static_cast(kBufferSize)) { Report("WARNING: Command buffer too small"); return nullptr; } } else { - if (internal_snprintf(buffer_, kBufferSize, "%s\"%s:%s\" 0x%zx\n", - is_data_str, module_name, ModuleArchToString(arch), + if (internal_snprintf(buffer_, kBufferSize, "%s \"%s:%s\" 0x%zx\n", + command_prefix, module_name, ModuleArchToString(arch), module_offset) >= static_cast(kBufferSize)) { Report("WARNING: Command buffer too small"); return nullptr; diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cpp similarity index 92% rename from libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cc rename to libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cpp index 249ccdf8377..7bc4b0ce025 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cc +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_symbolizer_mac.cc ---------------------------------------===// +//===-- sanitizer_symbolizer_mac.cpp --------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -56,6 +57,11 @@ class AtosSymbolizerProcess : public SymbolizerProcess { } private: + virtual 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/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.h index 240c538d93d..68521375e64 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.h +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_mac.h @@ -1,7 +1,8 @@ //===-- sanitizer_symbolizer_mac.h ------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_markup.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_markup.cpp similarity index 91% rename from libsanitizer/sanitizer_common/sanitizer_symbolizer_markup.cc rename to libsanitizer/sanitizer_common/sanitizer_symbolizer_markup.cpp index 3897aab0b9a..57b4d0c9d96 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_markup.cc +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_markup.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_symbolizer_markup.cc ------------------------------------===// +//===-- sanitizer_symbolizer_markup.cpp -----------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -116,7 +117,7 @@ _Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) { : _URC_NO_REASON); } -void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) { +void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) { CHECK_GE(max_depth, 2); size = 0; UnwindTraceArg arg = {this, Min(max_depth + 1, kStackTraceMax)}; @@ -131,9 +132,9 @@ void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) { trace_buffer[0] = pc; } -void BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context, - u32 max_depth) { - CHECK_NE(context, nullptr); +void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) { + CHECK(context); + CHECK_GE(max_depth, 2); UNREACHABLE("signal context doesn't exist"); } #endif // SANITIZER_CAN_SLOW_UNWIND diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp similarity index 98% rename from libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc rename to libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp index 750e89e2960..43e6a6d2dbf 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_symbolizer_posix_libcdep.cc -----------------------------===// +//===-- sanitizer_symbolizer_posix_libcdep.cpp ----------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cpp similarity index 95% rename from libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cc rename to libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cpp index 1157724125e..a8b449b030e 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cc +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_symbolizer_report.cc ------------------------------------===// +//===-- sanitizer_symbolizer_report.cpp -----------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// @@ -102,9 +103,11 @@ void ReportMmapWriteExec(int prot) { GET_CALLER_PC_BP_SP; (void)sp; bool fast = common_flags()->fast_unwind_on_fatal; - if (fast) + if (StackTrace::WillUseFastUnwind(fast)) { GetThreadStackTopAndBottom(false, &top, &bottom); - stack->Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, fast); + stack->Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, true); + } else + stack->Unwind(kStackTraceMax, pc, 0, nullptr, 0, 0, false); Printf("%s", d.Warning()); Report("WARNING: %s: writable-executable page usage\n", SanitizerToolName); diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_rtems.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer_rtems.h index 2afd01ed9f7..3371092e068 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_rtems.h +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_rtems.h @@ -1,7 +1,8 @@ //===-- sanitizer_symbolizer_rtems.h -----------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cpp similarity index 97% rename from libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cc rename to libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cpp index 3b455125c7a..2808779156e 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cc +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_symbolizer_win.cc ---------------------------------------===// +//===-- sanitizer_symbolizer_win.cpp --------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -34,6 +35,9 @@ namespace { class WinSymbolizerTool : public SymbolizerTool { public: + // The constructor is provided to avoid synthesized memsets. + WinSymbolizerTool() {} + bool SymbolizePC(uptr addr, SymbolizedStack *stack) override; bool SymbolizeData(uptr addr, DataInfo *info) override { return false; diff --git a/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc b/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc index 0c3b7f97045..a43ce3efab1 100644 --- a/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc +++ b/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc @@ -1,7 +1,8 @@ //===-- sanitizer_syscall_generic.inc ---------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_syscall_linux_aarch64.inc b/libsanitizer/sanitizer_common/sanitizer_syscall_linux_aarch64.inc index 64d6322651a..56c5e99220c 100644 --- a/libsanitizer/sanitizer_common/sanitizer_syscall_linux_aarch64.inc +++ b/libsanitizer/sanitizer_common/sanitizer_syscall_linux_aarch64.inc @@ -1,7 +1,8 @@ //===-- sanitizer_syscall_linux_aarch64.inc --------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_syscall_linux_arm.inc b/libsanitizer/sanitizer_common/sanitizer_syscall_linux_arm.inc index 71ac0d52d0c..121a9445b41 100644 --- a/libsanitizer/sanitizer_common/sanitizer_syscall_linux_arm.inc +++ b/libsanitizer/sanitizer_common/sanitizer_syscall_linux_arm.inc @@ -1,7 +1,8 @@ //===-- sanitizer_syscall_linux_arm.inc -------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_syscall_linux_x86_64.inc b/libsanitizer/sanitizer_common/sanitizer_syscall_linux_x86_64.inc index b610d66be4f..67e8686d12c 100644 --- a/libsanitizer/sanitizer_common/sanitizer_syscall_linux_x86_64.inc +++ b/libsanitizer/sanitizer_common/sanitizer_syscall_linux_x86_64.inc @@ -1,7 +1,8 @@ //===-- sanitizer_syscall_linux_x86_64.inc ----------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_syscalls_netbsd.inc b/libsanitizer/sanitizer_common/sanitizer_syscalls_netbsd.inc index 4fd4d06a0d1..21b52166963 100644 --- a/libsanitizer/sanitizer_common/sanitizer_syscalls_netbsd.inc +++ b/libsanitizer/sanitizer_common/sanitizer_syscalls_netbsd.inc @@ -1,7 +1,8 @@ //===-- sanitizer_syscalls_netbsd.inc ---------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -41,8 +42,8 @@ // DO NOT EDIT! THIS FILE HAS BEEN GENERATED! // // Generated with: generate_netbsd_syscalls.awk -// Generated date: 2018-03-03 -// Generated from: syscalls.master,v 1.291 2018/01/06 16:41:23 kamil Exp +// Generated date: 2018-10-30 +// Generated from: syscalls.master,v 1.293 2018/07/31 13:00:13 rjs Exp // //===----------------------------------------------------------------------===// @@ -1452,7 +1453,15 @@ PRE_SYSCALL(fpathconf)(long long fd_, long long name_) { /* Nothing to do */ } POST_SYSCALL(fpathconf)(long long res, long long fd_, long long name_) { /* Nothing to do */ } -/* syscall 193 has been skipped */ +PRE_SYSCALL(getsockopt2) +(long long s_, long long level_, long long name_, void *val_, void *avalsize_) { + /* TODO */ +} +POST_SYSCALL(getsockopt2) +(long long res, long long s_, long long level_, long long name_, void *val_, + void *avalsize_) { + /* TODO */ +} PRE_SYSCALL(getrlimit)(long long which_, void *rlp_) { PRE_WRITE(rlp_, struct_rlimit_sz); } @@ -2339,20 +2348,8 @@ POST_SYSCALL(__sigaction_sigtramp) PRE_READ(nsa_, sizeof(__sanitizer_sigaction)); } } -PRE_SYSCALL(pmc_get_info)(long long ctr_, long long op_, void *args_) { - /* TODO */ -} -POST_SYSCALL(pmc_get_info) -(long long res, long long ctr_, long long op_, void *args_) { - /* TODO */ -} -PRE_SYSCALL(pmc_control)(long long ctr_, long long op_, void *args_) { - /* TODO */ -} -POST_SYSCALL(pmc_control) -(long long res, long long ctr_, long long op_, void *args_) { - /* TODO */ -} +/* syscall 341 has been skipped */ +/* syscall 342 has been skipped */ PRE_SYSCALL(rasctl)(void *addr_, long long len_, long long op_) { /* Nothing to do */ } @@ -3693,18 +3690,18 @@ POST_SYSCALL(recvmmsg) PRE_SYSCALL(sendmmsg) (long long s_, void *mmsg_, long long vlen_, long long flags_) { struct __sanitizer_mmsghdr *mmsg = (struct __sanitizer_mmsghdr *)mmsg_; - unsigned int vlen = (vlen_ > 1024 ? 1024 : vlen_); if (mmsg) { - PRE_READ(mmsg, sizeof(struct __sanitizer_mmsghdr) * vlen); + PRE_READ(mmsg, sizeof(struct __sanitizer_mmsghdr) * + (vlen_ > 1024 ? 1024 : vlen_)); } } POST_SYSCALL(sendmmsg) (long long res, long long s_, void *mmsg_, long long vlen_, long long flags_) { struct __sanitizer_mmsghdr *mmsg = (struct __sanitizer_mmsghdr *)mmsg_; - unsigned int vlen = (vlen_ > 1024 ? 1024 : vlen_); if (res >= 0) { if (mmsg) { - POST_READ(mmsg, sizeof(struct __sanitizer_mmsghdr) * vlen); + POST_READ(mmsg, sizeof(struct __sanitizer_mmsghdr) * + (vlen_ > 1024 ? 1024 : vlen_)); } } } diff --git a/libsanitizer/sanitizer_common/sanitizer_termination.cc b/libsanitizer/sanitizer_common/sanitizer_termination.cpp similarity index 90% rename from libsanitizer/sanitizer_common/sanitizer_termination.cc rename to libsanitizer/sanitizer_common/sanitizer_termination.cpp index 79754fa1dbf..e588c93b994 100644 --- a/libsanitizer/sanitizer_common/sanitizer_termination.cc +++ b/libsanitizer/sanitizer_common/sanitizer_termination.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_termination.cc --------------------------------*- C++ -*-===// +//===-- sanitizer_termination.cpp -------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// /// diff --git a/libsanitizer/sanitizer_common/sanitizer_thread_registry.cc b/libsanitizer/sanitizer_common/sanitizer_thread_registry.cpp similarity index 91% rename from libsanitizer/sanitizer_common/sanitizer_thread_registry.cc rename to libsanitizer/sanitizer_common/sanitizer_thread_registry.cpp index 0ab1ec360ee..f2c6f279931 100644 --- a/libsanitizer/sanitizer_common/sanitizer_thread_registry.cc +++ b/libsanitizer/sanitizer_common/sanitizer_thread_registry.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_thread_registry.cc --------------------------------------===// +//===-- sanitizer_thread_registry.cpp -------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -16,8 +17,8 @@ namespace __sanitizer { ThreadContextBase::ThreadContextBase(u32 tid) : tid(tid), unique_id(0), reuse_count(), os_id(0), user_id(0), - status(ThreadStatusInvalid), - detached(false), workerthread(false), parent_tid(0), next(0) { + status(ThreadStatusInvalid), detached(false), + thread_type(ThreadType::Regular), parent_tid(0), next(0) { name[0] = '\0'; atomic_store(&thread_destroyed, 0, memory_order_release); } @@ -69,11 +70,11 @@ void ThreadContextBase::SetFinished() { OnFinished(); } -void ThreadContextBase::SetStarted(tid_t _os_id, bool _workerthread, +void ThreadContextBase::SetStarted(tid_t _os_id, ThreadType _thread_type, void *arg) { status = ThreadStatusRunning; os_id = _os_id; - workerthread = _workerthread; + thread_type = _thread_type; OnStarted(arg); } @@ -301,7 +302,7 @@ void ThreadRegistry::FinishThread(u32 tid) { tctx->SetDestroyed(); } -void ThreadRegistry::StartThread(u32 tid, tid_t os_id, bool workerthread, +void ThreadRegistry::StartThread(u32 tid, tid_t os_id, ThreadType thread_type, void *arg) { BlockingMutexLock l(&mtx_); running_threads_++; @@ -309,7 +310,7 @@ void ThreadRegistry::StartThread(u32 tid, tid_t os_id, bool workerthread, ThreadContextBase *tctx = threads_[tid]; CHECK_NE(tctx, 0); CHECK_EQ(ThreadStatusCreated, tctx->status); - tctx->SetStarted(os_id, workerthread, arg); + tctx->SetStarted(os_id, thread_type, arg); } void ThreadRegistry::QuarantinePush(ThreadContextBase *tctx) { @@ -336,4 +337,15 @@ ThreadContextBase *ThreadRegistry::QuarantinePop() { return tctx; } +void ThreadRegistry::SetThreadUserId(u32 tid, uptr user_id) { + BlockingMutexLock l(&mtx_); + CHECK_LT(tid, n_contexts_); + ThreadContextBase *tctx = threads_[tid]; + CHECK_NE(tctx, 0); + CHECK_NE(tctx->status, ThreadStatusInvalid); + CHECK_NE(tctx->status, ThreadStatusDead); + CHECK_EQ(tctx->user_id, 0); + tctx->user_id = user_id; +} + } // namespace __sanitizer diff --git a/libsanitizer/sanitizer_common/sanitizer_thread_registry.h b/libsanitizer/sanitizer_common/sanitizer_thread_registry.h index 7dba28c388f..493aa988f7e 100644 --- a/libsanitizer/sanitizer_common/sanitizer_thread_registry.h +++ b/libsanitizer/sanitizer_common/sanitizer_thread_registry.h @@ -1,7 +1,8 @@ //===-- sanitizer_thread_registry.h -----------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -27,6 +28,12 @@ enum ThreadStatus { ThreadStatusDead // Joined, but some info is still available. }; +enum class ThreadType { + Regular, // Normal thread + Worker, // macOS Grand Central Dispatch (GCD) worker thread + Fiber, // Fiber +}; + // Generic thread context. Specific sanitizer tools may inherit from it. // If thread is dead, context may optionally be reused for a new thread. class ThreadContextBase { @@ -43,7 +50,7 @@ class ThreadContextBase { ThreadStatus status; bool detached; - bool workerthread; + ThreadType thread_type; u32 parent_tid; ThreadContextBase *next; // For storing thread contexts in a list. @@ -55,7 +62,7 @@ class ThreadContextBase { void SetDead(); void SetJoined(void *arg); void SetFinished(); - void SetStarted(tid_t _os_id, bool _workerthread, void *arg); + void SetStarted(tid_t _os_id, ThreadType _thread_type, void *arg); void SetCreated(uptr _user_id, u64 _unique_id, bool _detached, u32 _parent_tid, void *arg); void Reset(); @@ -119,7 +126,8 @@ class ThreadRegistry { void DetachThread(u32 tid, void *arg); void JoinThread(u32 tid, void *arg); void FinishThread(u32 tid); - void StartThread(u32 tid, tid_t os_id, bool workerthread, void *arg); + void StartThread(u32 tid, tid_t os_id, ThreadType thread_type, void *arg); + void SetThreadUserId(u32 tid, uptr user_id); private: const ThreadContextFactory context_factory_; diff --git a/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cc b/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cpp similarity index 95% rename from libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cc rename to libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cpp index f1482c2a53b..9ca898a306a 100644 --- a/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cc +++ b/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_tls_get_addr.cc -----------------------------------------===// +//===-- sanitizer_tls_get_addr.cpp ----------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.h b/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.h index 19c8472c481..c7cd5a8bffc 100644 --- a/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.h +++ b/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.h @@ -1,7 +1,8 @@ //===-- sanitizer_tls_get_addr.h --------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -41,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/libsanitizer/sanitizer_common/sanitizer_type_traits.cpp b/libsanitizer/sanitizer_common/sanitizer_type_traits.cpp new file mode 100644 index 00000000000..5ee37d7376f --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_type_traits.cpp @@ -0,0 +1,20 @@ +//===-- 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. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Implements a subset of C++ type traits. This is so we can avoid depending +// on system C++ headers. +// +//===----------------------------------------------------------------------===// +#include "sanitizer_type_traits.h" + +namespace __sanitizer { + +const bool true_type::value; +const bool false_type::value; + +} // namespace __sanitizer diff --git a/libsanitizer/sanitizer_common/sanitizer_type_traits.h b/libsanitizer/sanitizer_common/sanitizer_type_traits.h new file mode 100644 index 00000000000..2a58d9874d2 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_type_traits.h @@ -0,0 +1,62 @@ +//===-- sanitizer_type_traits.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 +// +//===----------------------------------------------------------------------===// +// +// Implements a subset of C++ type traits. This is so we can avoid depending +// on system C++ headers. +// +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_TYPE_TRAITS_H +#define SANITIZER_TYPE_TRAITS_H + +namespace __sanitizer { + +struct true_type { + static const bool value = true; +}; + +struct false_type { + static const bool value = false; +}; + +// is_same +// +// Type trait to compare if types are the same. +// E.g. +// +// ``` +// is_same::value - True +// is_same::value - False +// ``` +template +struct is_same : public false_type {}; + +template +struct is_same : public true_type {}; + +// conditional +// +// Defines type as T if B is true or as F otherwise. +// E.g. the following is true +// +// ``` +// is_same::type>::value +// is_same::type>::value +// ``` +template +struct conditional { + using type = T; +}; + +template +struct conditional { + using type = F; +}; + +} // namespace __sanitizer + +#endif diff --git a/libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp similarity index 90% rename from libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cc rename to libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp index 44f12c408b9..1a43759e38a 100644 --- a/libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_unwind_linux_libcdep.cc ---------------------------------===// +//===-- sanitizer_unwind_linux_libcdep.cpp --------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -26,7 +27,7 @@ namespace __sanitizer { -//------------------------- SlowUnwindStack ----------------------------------- +//---------------------------- UnwindSlow -------------------------------------- typedef struct { uptr absolute_pc; @@ -95,7 +96,7 @@ uptr Unwind_GetIP(struct _Unwind_Context *ctx) { // Clear the Thumb bit. return val & ~(uptr)1; #else - return _Unwind_GetIP(ctx); + return (uptr)_Unwind_GetIP(ctx); #endif } @@ -118,7 +119,7 @@ _Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) { return UNWIND_CONTINUE; } -void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) { +void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) { CHECK_GE(max_depth, 2); size = 0; UnwindTraceArg arg = {this, Min(max_depth + 1, kStackTraceMax)}; @@ -143,11 +144,11 @@ void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) { #endif } -void BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context, - u32 max_depth) { +void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) { + CHECK(context); CHECK_GE(max_depth, 2); if (!unwind_backtrace_signal_arch) { - SlowUnwindStack(pc, max_depth); + UnwindSlow(pc, max_depth); return; } diff --git a/libsanitizer/sanitizer_common/sanitizer_unwind_win.cc b/libsanitizer/sanitizer_common/sanitizer_unwind_win.cpp similarity index 81% rename from libsanitizer/sanitizer_common/sanitizer_unwind_win.cc rename to libsanitizer/sanitizer_common/sanitizer_unwind_win.cpp index 8ea62faee52..8e06940685d 100644 --- a/libsanitizer/sanitizer_common/sanitizer_unwind_win.cc +++ b/libsanitizer/sanitizer_common/sanitizer_unwind_win.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_unwind_win.cc -------------------------------------------===// +//===-- sanitizer_unwind_win.cpp ------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -23,7 +24,7 @@ using namespace __sanitizer; #if !SANITIZER_GO -void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) { +void BufferedStackTrace::UnwindSlow(uptr pc, u32 max_depth) { CHECK_GE(max_depth, 2); // FIXME: CaptureStackBackTrace might be too slow for us. // FIXME: Compare with StackWalk64. @@ -38,8 +39,9 @@ void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) { PopStackFrames(pc_location); } -void BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context, - u32 max_depth) { +void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) { + CHECK(context); + CHECK_GE(max_depth, 2); CONTEXT ctx = *(CONTEXT *)context; STACKFRAME64 stack_frame; memset(&stack_frame, 0, sizeof(stack_frame)); diff --git a/libsanitizer/sanitizer_common/sanitizer_vector.h b/libsanitizer/sanitizer_common/sanitizer_vector.h index ad6510bbe46..4b9ae7db4c1 100644 --- a/libsanitizer/sanitizer_common/sanitizer_vector.h +++ b/libsanitizer/sanitizer_common/sanitizer_vector.h @@ -1,7 +1,8 @@ //===-- sanitizer_vector.h -------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_win.cc b/libsanitizer/sanitizer_common/sanitizer_win.cpp similarity index 92% rename from libsanitizer/sanitizer_common/sanitizer_win.cc rename to libsanitizer/sanitizer_common/sanitizer_win.cpp index ebc6c503036..c98e3d42f43 100644 --- a/libsanitizer/sanitizer_common/sanitizer_win.cc +++ b/libsanitizer/sanitizer_common/sanitizer_win.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_win.cc --------------------------------------------------===// +//===-- sanitizer_win.cpp -------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -30,6 +31,18 @@ #if defined(PSAPI_VERSION) && PSAPI_VERSION == 1 #pragma comment(lib, "psapi") #endif +#if SANITIZER_WIN_TRACE +#include +// Windows trace logging provider init +#pragma comment(lib, "advapi32.lib") +TRACELOGGING_DECLARE_PROVIDER(g_asan_provider); +// GUID must be the same in utils/AddressSanitizerLoggingProvider.wprp +TRACELOGGING_DEFINE_PROVIDER(g_asan_provider, "AddressSanitizerLoggingProvider", + (0x6c6c766d, 0x3846, 0x4e6a, 0xa4, 0xfb, 0x5b, + 0x53, 0x0b, 0xd0, 0xf3, 0xfa)); +#else +#define TraceLoggingUnregister(x) +#endif // A macro to tell the compiler that this part of the code cannot be reached, // if the compiler supports this feature. Since we're using this in @@ -228,7 +241,7 @@ bool MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) { // Memory space mapped by 'MmapFixedOrDie' must have been reserved by // 'MmapFixedNoAccess'. -void *MmapFixedOrDie(uptr fixed_addr, uptr size) { +void *MmapFixedOrDie(uptr fixed_addr, uptr size, const char *name) { void *p = VirtualAlloc((LPVOID)fixed_addr, size, MEM_COMMIT, PAGE_READWRITE); if (p == 0) { @@ -242,11 +255,12 @@ void *MmapFixedOrDie(uptr fixed_addr, uptr size) { // Uses fixed_addr for now. // Will use offset instead once we've implemented this function for real. -uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size) { +uptr ReservedAddressRange::Map(uptr fixed_addr, uptr size, const char *name) { return reinterpret_cast(MmapFixedOrDieOnFatalError(fixed_addr, size)); } -uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr size) { +uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr size, + const char *name) { return reinterpret_cast(MmapFixedOrDie(fixed_addr, size)); } @@ -259,7 +273,7 @@ void ReservedAddressRange::Unmap(uptr addr, uptr size) { UnmapOrDie(reinterpret_cast(addr), size); } -void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size) { +void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size, const char *name) { void *p = VirtualAlloc((LPVOID)fixed_addr, size, MEM_COMMIT, PAGE_READWRITE); if (p == 0) { @@ -315,9 +329,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) { @@ -485,8 +498,14 @@ bool IsPathSeparator(const char c) { return c == '\\' || c == '/'; } +static bool IsAlpha(char c) { + c = ToLower(c); + return c >= 'a' && c <= 'z'; +} + bool IsAbsolutePath(const char *path) { - UNIMPLEMENTED(); + return path != nullptr && IsAlpha(path[0]) && path[1] == ':' && + IsPathSeparator(path[2]); } void SleepForSeconds(int seconds) { @@ -644,6 +663,7 @@ int Atexit(void (*function)(void)) { } static int RunAtexit() { + TraceLoggingUnregister(g_asan_provider); int ret = 0; for (uptr i = 0; i < atexit_functions.size(); ++i) { ret |= atexit(atexit_functions[i]); @@ -735,16 +755,13 @@ bool WriteToFile(fd_t fd, const void *buff, uptr buff_size, uptr *bytes_written, } } -bool RenameFile(const char *oldpath, const char *newpath, error_t *error_p) { - UNIMPLEMENTED(); -} - uptr internal_sched_yield() { Sleep(0); return 0; } void internal__exit(int exitcode) { + TraceLoggingUnregister(g_asan_provider); // ExitProcess runs some finalizers, so use TerminateProcess to avoid that. // The debugger doesn't stop on TerminateProcess like it does on ExitProcess, // so add our own breakpoint here. @@ -1006,6 +1023,10 @@ void CheckVMASize() { // Do nothing. } +void InitializePlatformEarly() { + // Do nothing. +} + void MaybeReexec() { // No need to re-exec on Windows. } @@ -1014,17 +1035,26 @@ void CheckASLR() { // Do nothing } +void CheckMPROTECT() { + // Do nothing +} + char **GetArgv() { // FIXME: Actually implement this function. return 0; } +char **GetEnviron() { + // FIXME: Actually implement this function. + return 0; +} + pid_t StartSubprocess(const char *program, const char *const argv[], fd_t stdin_fd, fd_t stdout_fd, fd_t stderr_fd) { // 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; } @@ -1053,6 +1083,32 @@ u32 GetNumberOfCPUs() { return sysinfo.dwNumberOfProcessors; } +#if SANITIZER_WIN_TRACE +// TODO(mcgov): Rename this project-wide to PlatformLogInit +void AndroidLogInit(void) { + HRESULT hr = TraceLoggingRegister(g_asan_provider); + if (!SUCCEEDED(hr)) + return; +} + +void SetAbortMessage(const char *) {} + +void LogFullErrorReport(const char *buffer) { + if (common_flags()->log_to_syslog) { + InternalMmapVector filename; + DWORD filename_length = 0; + do { + filename.resize(filename.size() + 0x100); + filename_length = + GetModuleFileNameW(NULL, filename.begin(), filename.size()); + } while (filename_length >= filename.size()); + TraceLoggingWrite(g_asan_provider, "AsanReportEvent", + TraceLoggingValue(filename.begin(), "ExecutableName"), + TraceLoggingValue(buffer, "AsanReportContents")); + } +} +#endif // SANITIZER_WIN_TRACE + } // namespace __sanitizer #endif // _WIN32 diff --git a/libsanitizer/sanitizer_common/sanitizer_win.h b/libsanitizer/sanitizer_common/sanitizer_win.h index c2d53a46fed..ff8939ca5e8 100644 --- a/libsanitizer/sanitizer_common/sanitizer_win.h +++ b/libsanitizer/sanitizer_common/sanitizer_win.h @@ -1,7 +1,8 @@ //===-- sanitizer_win.h -----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_win_defs.h b/libsanitizer/sanitizer_common/sanitizer_win_defs.h index 1b1a86c4719..bcd94a08dc4 100644 --- a/libsanitizer/sanitizer_common/sanitizer_win_defs.h +++ b/libsanitizer/sanitizer_common/sanitizer_win_defs.h @@ -1,7 +1,8 @@ //===-- sanitizer_win_defs.h ------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.cc b/libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.cpp similarity index 92% rename from libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.cc rename to libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.cpp index 6577a3606d1..aa0eb4d43a4 100644 --- a/libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.cc +++ b/libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_win_dll_thunk.cc ----------------------------------------===// +//===-- sanitizer_win_dll_thunk.cpp ---------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 defines a family of thunks that should be statically linked into diff --git a/libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.h b/libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.h index 5a475e0798e..48c73c4c98a 100644 --- a/libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.h +++ b/libsanitizer/sanitizer_common/sanitizer_win_dll_thunk.h @@ -1,7 +1,8 @@ //===-- sanitizer_win_dll_thunk.h -----------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 header provide helper macros to delegate calls to the shared runtime diff --git a/libsanitizer/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cc b/libsanitizer/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cpp similarity index 58% rename from libsanitizer/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cc rename to libsanitizer/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cpp index f3b3037b276..87c032c6e61 100644 --- a/libsanitizer/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cc +++ b/libsanitizer/sanitizer_common/sanitizer_win_dynamic_runtime_thunk.cpp @@ -1,7 +1,8 @@ -//===-- santizer_win_dynamic_runtime_thunk.cc -----------------------------===// +//===-- santizer_win_dynamic_runtime_thunk.cpp ----------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -17,3 +18,9 @@ #define INTERFACE_WEAK_FUNCTION(Name) WIN_WEAK_IMPORT_DEF(Name) #include "sanitizer_common_interface.inc" #endif // SANITIZER_DYNAMIC_RUNTIME_THUNK + +namespace __sanitizer { +// Add one, otherwise unused, external symbol to this object file so that the +// Visual C++ linker includes it and reads the .drective section. +void ForceWholeArchiveIncludeForSanitizerCommon() {} +} diff --git a/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.cc b/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.cpp similarity index 92% rename from libsanitizer/sanitizer_common/sanitizer_win_weak_interception.cc rename to libsanitizer/sanitizer_common/sanitizer_win_weak_interception.cpp index 3ee428b4723..a6f34c27788 100644 --- a/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.cc +++ b/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.cpp @@ -1,7 +1,8 @@ -//===-- sanitizer_win_weak_interception.cc --------------------------------===// +//===-- sanitizer_win_weak_interception.cpp -------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 module should be included in the sanitizer when it is implemented as a diff --git a/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.h b/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.h index 873f9b822ab..5e4d8b8def3 100644 --- a/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.h +++ b/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.h @@ -1,7 +1,8 @@ //===-- sanitizer_win_weak_interception.h ---------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 header provide helper macros to delegate calls of weak functions to the diff --git a/libsanitizer/tsan/Makefile.am b/libsanitizer/tsan/Makefile.am index 753cb8f4fc1..1ca9b68a3c5 100644 --- a/libsanitizer/tsan/Makefile.am +++ b/libsanitizer/tsan/Makefile.am @@ -14,40 +14,39 @@ toolexeclib_LTLIBRARIES = libtsan.la nodist_toolexeclib_HEADERS = libtsan_preinit.o tsan_files = \ - tsan_clock.cc \ - tsan_debugging.cc \ - tsan_external.cc \ - tsan_fd.cc \ - tsan_flags.cc \ - tsan_ignoreset.cc \ - tsan_interceptors.cc \ - tsan_interceptors_mac.cc \ - tsan_interface_ann.cc \ - tsan_interface_atomic.cc \ - tsan_interface.cc \ - tsan_interface_java.cc \ - tsan_libdispatch_mac.cc \ - tsan_malloc_mac.cc \ - tsan_md5.cc \ - tsan_mman.cc \ - tsan_mutex.cc \ - tsan_mutexset.cc \ - tsan_new_delete.cc \ - tsan_platform_linux.cc \ - tsan_platform_mac.cc \ - tsan_platform_posix.cc \ - tsan_platform_windows.cc \ - tsan_report.cc \ - tsan_rtl.cc \ - tsan_rtl_mutex.cc \ - tsan_rtl_proc.cc \ - tsan_rtl_report.cc \ - tsan_rtl_thread.cc \ - tsan_stack_trace.cc \ - tsan_stat.cc \ - tsan_suppressions.cc \ - tsan_symbolize.cc \ - tsan_sync.cc + tsan_clock.cpp \ + tsan_debugging.cpp \ + tsan_external.cpp \ + tsan_fd.cpp \ + tsan_flags.cpp \ + tsan_ignoreset.cpp \ + tsan_interceptors.cpp \ + tsan_interceptors_mac.cpp \ + tsan_interface_ann.cpp \ + tsan_interface_atomic.cpp \ + tsan_interface.cpp \ + tsan_interface_java.cpp \ + tsan_malloc_mac.cpp \ + tsan_md5.cpp \ + tsan_mman.cpp \ + tsan_mutex.cpp \ + tsan_mutexset.cpp \ + tsan_new_delete.cpp \ + tsan_platform_linux.cpp \ + tsan_platform_mac.cpp \ + tsan_platform_posix.cpp \ + tsan_platform_windows.cpp \ + tsan_report.cpp \ + tsan_rtl.cpp \ + tsan_rtl_mutex.cpp \ + tsan_rtl_proc.cpp \ + tsan_rtl_report.cpp \ + tsan_rtl_thread.cpp \ + tsan_stack_trace.cpp \ + tsan_stat.cpp \ + tsan_suppressions.cpp \ + tsan_symbolize.cpp \ + tsan_sync.cpp libtsan_la_SOURCES = $(tsan_files) EXTRA_libtsan_la_SOURCES = tsan_rtl_amd64.S tsan_rtl_aarch64.S tsan_rtl_mips64.S tsan_rtl_ppc64.S diff --git a/libsanitizer/tsan/Makefile.in b/libsanitizer/tsan/Makefile.in index cb4f0f9fef0..9471b97c0fd 100644 --- a/libsanitizer/tsan/Makefile.in +++ b/libsanitizer/tsan/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -148,10 +148,9 @@ am__objects_1 = tsan_clock.lo tsan_debugging.lo tsan_external.lo \ tsan_fd.lo tsan_flags.lo tsan_ignoreset.lo \ tsan_interceptors.lo tsan_interceptors_mac.lo \ tsan_interface_ann.lo tsan_interface_atomic.lo \ - tsan_interface.lo tsan_interface_java.lo \ - tsan_libdispatch_mac.lo tsan_malloc_mac.lo tsan_md5.lo \ - tsan_mman.lo tsan_mutex.lo tsan_mutexset.lo tsan_new_delete.lo \ - tsan_platform_linux.lo tsan_platform_mac.lo \ + tsan_interface.lo tsan_interface_java.lo tsan_malloc_mac.lo \ + tsan_md5.lo tsan_mman.lo tsan_mutex.lo tsan_mutexset.lo \ + tsan_new_delete.lo tsan_platform_linux.lo tsan_platform_mac.lo \ tsan_platform_posix.lo tsan_platform_windows.lo tsan_report.lo \ tsan_rtl.lo tsan_rtl_mutex.lo tsan_rtl_proc.lo \ tsan_rtl_report.lo tsan_rtl_thread.lo tsan_stack_trace.lo \ @@ -180,11 +179,37 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/../depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/tsan_clock.Plo \ + ./$(DEPDIR)/tsan_debugging.Plo ./$(DEPDIR)/tsan_external.Plo \ + ./$(DEPDIR)/tsan_fd.Plo ./$(DEPDIR)/tsan_flags.Plo \ + ./$(DEPDIR)/tsan_ignoreset.Plo \ + ./$(DEPDIR)/tsan_interceptors.Plo \ + ./$(DEPDIR)/tsan_interceptors_mac.Plo \ + ./$(DEPDIR)/tsan_interface.Plo \ + ./$(DEPDIR)/tsan_interface_ann.Plo \ + ./$(DEPDIR)/tsan_interface_atomic.Plo \ + ./$(DEPDIR)/tsan_interface_java.Plo \ + ./$(DEPDIR)/tsan_malloc_mac.Plo ./$(DEPDIR)/tsan_md5.Plo \ + ./$(DEPDIR)/tsan_mman.Plo ./$(DEPDIR)/tsan_mutex.Plo \ + ./$(DEPDIR)/tsan_mutexset.Plo ./$(DEPDIR)/tsan_new_delete.Plo \ + ./$(DEPDIR)/tsan_platform_linux.Plo \ + ./$(DEPDIR)/tsan_platform_mac.Plo \ + ./$(DEPDIR)/tsan_platform_posix.Plo \ + ./$(DEPDIR)/tsan_platform_windows.Plo \ + ./$(DEPDIR)/tsan_report.Plo ./$(DEPDIR)/tsan_rtl.Plo \ + ./$(DEPDIR)/tsan_rtl_aarch64.Plo \ + ./$(DEPDIR)/tsan_rtl_amd64.Plo ./$(DEPDIR)/tsan_rtl_mips64.Plo \ + ./$(DEPDIR)/tsan_rtl_mutex.Plo ./$(DEPDIR)/tsan_rtl_ppc64.Plo \ + ./$(DEPDIR)/tsan_rtl_proc.Plo ./$(DEPDIR)/tsan_rtl_report.Plo \ + ./$(DEPDIR)/tsan_rtl_thread.Plo \ + ./$(DEPDIR)/tsan_stack_trace.Plo ./$(DEPDIR)/tsan_stat.Plo \ + ./$(DEPDIR)/tsan_suppressions.Plo \ + ./$(DEPDIR)/tsan_symbolize.Plo ./$(DEPDIR)/tsan_sync.Plo am__mv = mv -f CPPASCOMPILE = $(CCAS) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CCASFLAGS) $(CCASFLAGS) -LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ +LTCPPASCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ $(LIBTOOLFLAGS) --mode=compile $(CCAS) $(DEFS) \ $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ $(AM_CCASFLAGS) $(CCASFLAGS) @@ -416,40 +441,39 @@ ACLOCAL_AMFLAGS = -I m4 toolexeclib_LTLIBRARIES = libtsan.la nodist_toolexeclib_HEADERS = libtsan_preinit.o tsan_files = \ - tsan_clock.cc \ - tsan_debugging.cc \ - tsan_external.cc \ - tsan_fd.cc \ - tsan_flags.cc \ - tsan_ignoreset.cc \ - tsan_interceptors.cc \ - tsan_interceptors_mac.cc \ - tsan_interface_ann.cc \ - tsan_interface_atomic.cc \ - tsan_interface.cc \ - tsan_interface_java.cc \ - tsan_libdispatch_mac.cc \ - tsan_malloc_mac.cc \ - tsan_md5.cc \ - tsan_mman.cc \ - tsan_mutex.cc \ - tsan_mutexset.cc \ - tsan_new_delete.cc \ - tsan_platform_linux.cc \ - tsan_platform_mac.cc \ - tsan_platform_posix.cc \ - tsan_platform_windows.cc \ - tsan_report.cc \ - tsan_rtl.cc \ - tsan_rtl_mutex.cc \ - tsan_rtl_proc.cc \ - tsan_rtl_report.cc \ - tsan_rtl_thread.cc \ - tsan_stack_trace.cc \ - tsan_stat.cc \ - tsan_suppressions.cc \ - tsan_symbolize.cc \ - tsan_sync.cc + tsan_clock.cpp \ + tsan_debugging.cpp \ + tsan_external.cpp \ + tsan_fd.cpp \ + tsan_flags.cpp \ + tsan_ignoreset.cpp \ + tsan_interceptors.cpp \ + tsan_interceptors_mac.cpp \ + tsan_interface_ann.cpp \ + tsan_interface_atomic.cpp \ + tsan_interface.cpp \ + tsan_interface_java.cpp \ + tsan_malloc_mac.cpp \ + tsan_md5.cpp \ + tsan_mman.cpp \ + tsan_mutex.cpp \ + tsan_mutexset.cpp \ + tsan_new_delete.cpp \ + tsan_platform_linux.cpp \ + tsan_platform_mac.cpp \ + tsan_platform_posix.cpp \ + tsan_platform_windows.cpp \ + tsan_report.cpp \ + tsan_rtl.cpp \ + tsan_rtl_mutex.cpp \ + tsan_rtl_proc.cpp \ + tsan_rtl_report.cpp \ + tsan_rtl_thread.cpp \ + tsan_stack_trace.cpp \ + tsan_stat.cpp \ + tsan_suppressions.cpp \ + tsan_symbolize.cpp \ + tsan_sync.cpp libtsan_la_SOURCES = $(tsan_files) EXTRA_libtsan_la_SOURCES = tsan_rtl_amd64.S tsan_rtl_aarch64.S tsan_rtl_mips64.S tsan_rtl_ppc64.S @@ -506,7 +530,7 @@ MAKEOVERRIDES = all: all-am .SUFFIXES: -.SUFFIXES: .S .cc .lo .o .obj +.SUFFIXES: .S .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -524,8 +548,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -581,44 +605,49 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_clock.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_debugging.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_external.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_fd.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_flags.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_ignoreset.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_interceptors.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_interceptors_mac.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_interface.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_interface_ann.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_interface_atomic.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_interface_java.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_libdispatch_mac.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_malloc_mac.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_md5.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_mman.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_mutex.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_mutexset.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_new_delete.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_platform_linux.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_platform_mac.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_platform_posix.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_platform_windows.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_report.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_aarch64.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_amd64.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_mips64.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_mutex.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_ppc64.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_proc.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_report.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_thread.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_stack_trace.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_stat.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_suppressions.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_symbolize.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_sync.Plo@am__quote@ +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_clock.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_debugging.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_external.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_fd.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_flags.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_ignoreset.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_interceptors.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_interceptors_mac.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_interface.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_interface_ann.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_interface_atomic.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_interface_java.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_malloc_mac.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_md5.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_mman.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_mutex.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_mutexset.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_new_delete.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_platform_linux.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_platform_mac.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_platform_posix.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_platform_windows.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_report.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_aarch64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_amd64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_mips64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_mutex.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_ppc64.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_proc.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_report.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_rtl_thread.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_stack_trace.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_stat.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_suppressions.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_symbolize.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/tsan_sync.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) .S.o: @am__fastdepCCAS_TRUE@ $(AM_V_CPPAS)$(CPPASCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @@ -641,21 +670,21 @@ distclean-compile: @AMDEP_TRUE@@am__fastdepCCAS_FALSE@ DEPDIR=$(DEPDIR) $(CCASDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCCAS_FALSE@ $(AM_V_CPPAS@am__nodep@)$(LTCPPASCOMPILE) -c -o $@ $< -.cc.o: +.cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< -.cc.obj: +.cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` -.cc.lo: +.cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @@ -783,7 +812,43 @@ clean-am: clean-generic clean-libtool clean-toolexeclibLTLIBRARIES \ mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/tsan_clock.Plo + -rm -f ./$(DEPDIR)/tsan_debugging.Plo + -rm -f ./$(DEPDIR)/tsan_external.Plo + -rm -f ./$(DEPDIR)/tsan_fd.Plo + -rm -f ./$(DEPDIR)/tsan_flags.Plo + -rm -f ./$(DEPDIR)/tsan_ignoreset.Plo + -rm -f ./$(DEPDIR)/tsan_interceptors.Plo + -rm -f ./$(DEPDIR)/tsan_interceptors_mac.Plo + -rm -f ./$(DEPDIR)/tsan_interface.Plo + -rm -f ./$(DEPDIR)/tsan_interface_ann.Plo + -rm -f ./$(DEPDIR)/tsan_interface_atomic.Plo + -rm -f ./$(DEPDIR)/tsan_interface_java.Plo + -rm -f ./$(DEPDIR)/tsan_malloc_mac.Plo + -rm -f ./$(DEPDIR)/tsan_md5.Plo + -rm -f ./$(DEPDIR)/tsan_mman.Plo + -rm -f ./$(DEPDIR)/tsan_mutex.Plo + -rm -f ./$(DEPDIR)/tsan_mutexset.Plo + -rm -f ./$(DEPDIR)/tsan_new_delete.Plo + -rm -f ./$(DEPDIR)/tsan_platform_linux.Plo + -rm -f ./$(DEPDIR)/tsan_platform_mac.Plo + -rm -f ./$(DEPDIR)/tsan_platform_posix.Plo + -rm -f ./$(DEPDIR)/tsan_platform_windows.Plo + -rm -f ./$(DEPDIR)/tsan_report.Plo + -rm -f ./$(DEPDIR)/tsan_rtl.Plo + -rm -f ./$(DEPDIR)/tsan_rtl_aarch64.Plo + -rm -f ./$(DEPDIR)/tsan_rtl_amd64.Plo + -rm -f ./$(DEPDIR)/tsan_rtl_mips64.Plo + -rm -f ./$(DEPDIR)/tsan_rtl_mutex.Plo + -rm -f ./$(DEPDIR)/tsan_rtl_ppc64.Plo + -rm -f ./$(DEPDIR)/tsan_rtl_proc.Plo + -rm -f ./$(DEPDIR)/tsan_rtl_report.Plo + -rm -f ./$(DEPDIR)/tsan_rtl_thread.Plo + -rm -f ./$(DEPDIR)/tsan_stack_trace.Plo + -rm -f ./$(DEPDIR)/tsan_stat.Plo + -rm -f ./$(DEPDIR)/tsan_suppressions.Plo + -rm -f ./$(DEPDIR)/tsan_symbolize.Plo + -rm -f ./$(DEPDIR)/tsan_sync.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -830,7 +895,43 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/tsan_clock.Plo + -rm -f ./$(DEPDIR)/tsan_debugging.Plo + -rm -f ./$(DEPDIR)/tsan_external.Plo + -rm -f ./$(DEPDIR)/tsan_fd.Plo + -rm -f ./$(DEPDIR)/tsan_flags.Plo + -rm -f ./$(DEPDIR)/tsan_ignoreset.Plo + -rm -f ./$(DEPDIR)/tsan_interceptors.Plo + -rm -f ./$(DEPDIR)/tsan_interceptors_mac.Plo + -rm -f ./$(DEPDIR)/tsan_interface.Plo + -rm -f ./$(DEPDIR)/tsan_interface_ann.Plo + -rm -f ./$(DEPDIR)/tsan_interface_atomic.Plo + -rm -f ./$(DEPDIR)/tsan_interface_java.Plo + -rm -f ./$(DEPDIR)/tsan_malloc_mac.Plo + -rm -f ./$(DEPDIR)/tsan_md5.Plo + -rm -f ./$(DEPDIR)/tsan_mman.Plo + -rm -f ./$(DEPDIR)/tsan_mutex.Plo + -rm -f ./$(DEPDIR)/tsan_mutexset.Plo + -rm -f ./$(DEPDIR)/tsan_new_delete.Plo + -rm -f ./$(DEPDIR)/tsan_platform_linux.Plo + -rm -f ./$(DEPDIR)/tsan_platform_mac.Plo + -rm -f ./$(DEPDIR)/tsan_platform_posix.Plo + -rm -f ./$(DEPDIR)/tsan_platform_windows.Plo + -rm -f ./$(DEPDIR)/tsan_report.Plo + -rm -f ./$(DEPDIR)/tsan_rtl.Plo + -rm -f ./$(DEPDIR)/tsan_rtl_aarch64.Plo + -rm -f ./$(DEPDIR)/tsan_rtl_amd64.Plo + -rm -f ./$(DEPDIR)/tsan_rtl_mips64.Plo + -rm -f ./$(DEPDIR)/tsan_rtl_mutex.Plo + -rm -f ./$(DEPDIR)/tsan_rtl_ppc64.Plo + -rm -f ./$(DEPDIR)/tsan_rtl_proc.Plo + -rm -f ./$(DEPDIR)/tsan_rtl_report.Plo + -rm -f ./$(DEPDIR)/tsan_rtl_thread.Plo + -rm -f ./$(DEPDIR)/tsan_stack_trace.Plo + -rm -f ./$(DEPDIR)/tsan_stat.Plo + -rm -f ./$(DEPDIR)/tsan_suppressions.Plo + -rm -f ./$(DEPDIR)/tsan_symbolize.Plo + -rm -f ./$(DEPDIR)/tsan_sync.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -852,20 +953,21 @@ uninstall-am: uninstall-nodist_toolexeclibHEADERS \ .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-toolexeclibLTLIBRARIES cscopelist-am ctags \ - ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags dvi dvi-am html html-am info \ - info-am install install-am install-data install-data-am \ - install-dvi install-dvi-am install-exec install-exec-am \ - install-html install-html-am install-info install-info-am \ - install-man install-nodist_toolexeclibHEADERS install-pdf \ - install-pdf-am install-ps install-ps-am install-strip \ - install-toolexeclibLTLIBRARIES installcheck installcheck-am \ - installdirs maintainer-clean maintainer-clean-generic \ - mostlyclean mostlyclean-compile mostlyclean-generic \ - mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ - uninstall-am uninstall-nodist_toolexeclibHEADERS \ +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-toolexeclibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags dvi dvi-am \ + html html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-nodist_toolexeclibHEADERS \ + install-pdf install-pdf-am install-ps install-ps-am \ + install-strip install-toolexeclibLTLIBRARIES installcheck \ + installcheck-am installdirs maintainer-clean \ + maintainer-clean-generic mostlyclean mostlyclean-compile \ + mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ + tags tags-am uninstall uninstall-am \ + uninstall-nodist_toolexeclibHEADERS \ uninstall-toolexeclibLTLIBRARIES .PRECIOUS: Makefile diff --git a/libsanitizer/tsan/tsan_clock.cc b/libsanitizer/tsan/tsan_clock.cpp similarity index 98% rename from libsanitizer/tsan/tsan_clock.cc rename to libsanitizer/tsan/tsan_clock.cpp index c2b5b582ca3..4b7aa0653da 100644 --- a/libsanitizer/tsan/tsan_clock.cc +++ b/libsanitizer/tsan/tsan_clock.cpp @@ -1,7 +1,8 @@ -//===-- tsan_clock.cc -----------------------------------------------------===// +//===-- tsan_clock.cpp ----------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -39,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/libsanitizer/tsan/tsan_clock.h b/libsanitizer/tsan/tsan_clock.h index c8eb8ee2d1a..6a1d15a2a16 100644 --- a/libsanitizer/tsan/tsan_clock.h +++ b/libsanitizer/tsan/tsan_clock.h @@ -1,7 +1,8 @@ //===-- tsan_clock.h --------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_debugging.cc b/libsanitizer/tsan/tsan_debugging.cpp similarity index 82% rename from libsanitizer/tsan/tsan_debugging.cc rename to libsanitizer/tsan/tsan_debugging.cpp index 722b6c1b470..d3d6255090b 100644 --- a/libsanitizer/tsan/tsan_debugging.cc +++ b/libsanitizer/tsan/tsan_debugging.cpp @@ -1,7 +1,8 @@ -//===-- tsan_debugging.cc -------------------------------------------------===// +//===-- tsan_debugging.cpp ------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -18,31 +19,37 @@ using namespace __tsan; static const char *ReportTypeDescription(ReportType typ) { - if (typ == ReportTypeRace) return "data-race"; - if (typ == ReportTypeVptrRace) return "data-race-vptr"; - if (typ == ReportTypeUseAfterFree) return "heap-use-after-free"; - if (typ == ReportTypeVptrUseAfterFree) return "heap-use-after-free-vptr"; - if (typ == ReportTypeExternalRace) return "external-race"; - if (typ == ReportTypeThreadLeak) return "thread-leak"; - if (typ == ReportTypeMutexDestroyLocked) return "locked-mutex-destroy"; - if (typ == ReportTypeMutexDoubleLock) return "mutex-double-lock"; - if (typ == ReportTypeMutexInvalidAccess) return "mutex-invalid-access"; - if (typ == ReportTypeMutexBadUnlock) return "mutex-bad-unlock"; - if (typ == ReportTypeMutexBadReadLock) return "mutex-bad-read-lock"; - if (typ == ReportTypeMutexBadReadUnlock) return "mutex-bad-read-unlock"; - if (typ == ReportTypeSignalUnsafe) return "signal-unsafe-call"; - if (typ == ReportTypeErrnoInSignal) return "errno-in-signal-handler"; - if (typ == ReportTypeDeadlock) return "lock-order-inversion"; - return ""; + switch (typ) { + case ReportTypeRace: return "data-race"; + case ReportTypeVptrRace: return "data-race-vptr"; + case ReportTypeUseAfterFree: return "heap-use-after-free"; + case ReportTypeVptrUseAfterFree: return "heap-use-after-free-vptr"; + case ReportTypeExternalRace: return "external-race"; + case ReportTypeThreadLeak: return "thread-leak"; + case ReportTypeMutexDestroyLocked: return "locked-mutex-destroy"; + case ReportTypeMutexDoubleLock: return "mutex-double-lock"; + case ReportTypeMutexInvalidAccess: return "mutex-invalid-access"; + case ReportTypeMutexBadUnlock: return "mutex-bad-unlock"; + case ReportTypeMutexBadReadLock: return "mutex-bad-read-lock"; + case ReportTypeMutexBadReadUnlock: return "mutex-bad-read-unlock"; + case ReportTypeSignalUnsafe: return "signal-unsafe-call"; + case ReportTypeErrnoInSignal: return "errno-in-signal-handler"; + case ReportTypeDeadlock: return "lock-order-inversion"; + // No default case so compiler warns us if we miss one + } + UNREACHABLE("missing case"); } static const char *ReportLocationTypeDescription(ReportLocationType typ) { - if (typ == ReportLocationGlobal) return "global"; - if (typ == ReportLocationHeap) return "heap"; - if (typ == ReportLocationStack) return "stack"; - if (typ == ReportLocationTLS) return "tls"; - if (typ == ReportLocationFD) return "fd"; - return ""; + switch (typ) { + case ReportLocationGlobal: return "global"; + case ReportLocationHeap: return "heap"; + case ReportLocationStack: return "stack"; + case ReportLocationTLS: return "tls"; + case ReportLocationFD: return "fd"; + // No default case so compiler warns us if we miss one + } + UNREACHABLE("missing case"); } static void CopyTrace(SymbolizedStack *first_frame, void **trace, diff --git a/libsanitizer/tsan/tsan_defs.h b/libsanitizer/tsan/tsan_defs.h index 2c7eda69f92..293d7deccc3 100644 --- a/libsanitizer/tsan/tsan_defs.h +++ b/libsanitizer/tsan/tsan_defs.h @@ -1,7 +1,8 @@ //===-- tsan_defs.h ---------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_dense_alloc.h b/libsanitizer/tsan/tsan_dense_alloc.h index 197b96fdeed..64fc50e95c2 100644 --- a/libsanitizer/tsan/tsan_dense_alloc.h +++ b/libsanitizer/tsan/tsan_dense_alloc.h @@ -1,7 +1,8 @@ //===-- tsan_dense_alloc.h --------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_dispatch_defs.h b/libsanitizer/tsan/tsan_dispatch_defs.h new file mode 100644 index 00000000000..6f1d1f75f60 --- /dev/null +++ b/libsanitizer/tsan/tsan_dispatch_defs.h @@ -0,0 +1,66 @@ +//===-- tsan_dispatch_defs.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 ThreadSanitizer (TSan), a race detector. +// +//===----------------------------------------------------------------------===// +#ifndef TSAN_DISPATCH_DEFS_H +#define TSAN_DISPATCH_DEFS_H + +#include "sanitizer_common/sanitizer_internal_defs.h" + +typedef struct dispatch_object_s {} *dispatch_object_t; + +#define DISPATCH_DECL(name) \ + typedef struct name##_s : public dispatch_object_s {} *name##_t + +DISPATCH_DECL(dispatch_queue); +DISPATCH_DECL(dispatch_source); +DISPATCH_DECL(dispatch_group); +DISPATCH_DECL(dispatch_data); +DISPATCH_DECL(dispatch_semaphore); +DISPATCH_DECL(dispatch_io); + +typedef void (*dispatch_function_t)(void *arg); +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 __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 + +extern "C" { +void *dispatch_get_context(dispatch_object_t object); +void dispatch_retain(dispatch_object_t object); +void dispatch_release(dispatch_object_t object); + +extern const dispatch_block_t _dispatch_data_destructor_free; +extern const dispatch_block_t _dispatch_data_destructor_munmap; +} // extern "C" + +#define DISPATCH_DATA_DESTRUCTOR_DEFAULT nullptr +#define DISPATCH_DATA_DESTRUCTOR_FREE _dispatch_data_destructor_free +#define DISPATCH_DATA_DESTRUCTOR_MUNMAP _dispatch_data_destructor_munmap + +#if __has_attribute(noescape) + #define DISPATCH_NOESCAPE __attribute__((__noescape__)) +#else + #define DISPATCH_NOESCAPE +#endif + +// Data types used in dispatch APIs +typedef unsigned long size_t; // NOLINT +typedef unsigned long uintptr_t; // NOLINT +typedef __sanitizer::s64 off_t; +typedef __sanitizer::u16 mode_t; +typedef long long_t; // NOLINT + +#endif // TSAN_DISPATCH_DEFS_H diff --git a/libsanitizer/tsan/tsan_external.cc b/libsanitizer/tsan/tsan_external.cpp similarity index 93% rename from libsanitizer/tsan/tsan_external.cc rename to libsanitizer/tsan/tsan_external.cpp index 3dddc3a4f64..efc1013087c 100644 --- a/libsanitizer/tsan/tsan_external.cc +++ b/libsanitizer/tsan/tsan_external.cpp @@ -1,7 +1,8 @@ -//===-- tsan_external.cc --------------------------------------------------===// +//===-- tsan_external.cpp -------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_fd.cc b/libsanitizer/tsan/tsan_fd.cpp similarity index 97% rename from libsanitizer/tsan/tsan_fd.cc rename to libsanitizer/tsan/tsan_fd.cpp index effa35ddeb5..db01d809531 100644 --- a/libsanitizer/tsan/tsan_fd.cc +++ b/libsanitizer/tsan/tsan_fd.cpp @@ -1,7 +1,8 @@ -//===-- tsan_fd.cc --------------------------------------------------------===// +//===-- tsan_fd.cpp -------------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_fd.h b/libsanitizer/tsan/tsan_fd.h index 4d9236c9903..ce4f2f73bac 100644 --- a/libsanitizer/tsan/tsan_fd.h +++ b/libsanitizer/tsan/tsan_fd.h @@ -1,7 +1,8 @@ //===-- tsan_fd.h -----------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_flags.cc b/libsanitizer/tsan/tsan_flags.cpp similarity index 86% rename from libsanitizer/tsan/tsan_flags.cc rename to libsanitizer/tsan/tsan_flags.cpp index 4217691658e..44bf325cd35 100644 --- a/libsanitizer/tsan/tsan_flags.cc +++ b/libsanitizer/tsan/tsan_flags.cpp @@ -1,7 +1,8 @@ -//===-- tsan_flags.cc -----------------------------------------------------===// +//===-- tsan_flags.cpp ----------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -48,7 +49,7 @@ void RegisterTsanFlags(FlagParser *parser, Flags *f) { &f->second_deadlock_stack); } -void InitializeFlags(Flags *f, const char *env) { +void InitializeFlags(Flags *f, const char *env, const char *env_option_name) { SetCommonFlagsDefaults(); { // Override some common flags defaults. @@ -59,8 +60,7 @@ void InitializeFlags(Flags *f, const char *env) { // Does not work as expected for Go: runtime handles SIGABRT and crashes. cf.abort_on_error = false; // Go does not have mutexes. - } else { - cf.detect_deadlocks = true; + cf.detect_deadlocks = false; } cf.print_suppressions = false; cf.stack_trace_format = " #%n %f %S %M"; @@ -91,9 +91,9 @@ void InitializeFlags(Flags *f, const char *env) { ubsan_parser.ParseString(ubsan_default_options); #endif // Override from command line. - parser.ParseString(env); + parser.ParseString(env, env_option_name); #if TSAN_CONTAINS_UBSAN - ubsan_parser.ParseString(GetEnv("UBSAN_OPTIONS")); + ubsan_parser.ParseStringFromEnv("UBSAN_OPTIONS"); #endif // Sanity check. diff --git a/libsanitizer/tsan/tsan_flags.h b/libsanitizer/tsan/tsan_flags.h index 35b0efc1c6b..da27d5b992b 100644 --- a/libsanitizer/tsan/tsan_flags.h +++ b/libsanitizer/tsan/tsan_flags.h @@ -1,7 +1,8 @@ //===-- tsan_flags.h --------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -26,7 +27,8 @@ struct Flags : DDFlags { void ParseFromString(const char *str); }; -void InitializeFlags(Flags *flags, const char *env); +void InitializeFlags(Flags *flags, const char *env, + const char *env_option_name = nullptr); } // namespace __tsan #endif // TSAN_FLAGS_H diff --git a/libsanitizer/tsan/tsan_flags.inc b/libsanitizer/tsan/tsan_flags.inc index e9873f16ce4..bfb74b696e6 100644 --- a/libsanitizer/tsan/tsan_flags.inc +++ b/libsanitizer/tsan/tsan_flags.inc @@ -1,7 +1,8 @@ //===-- tsan_flags.inc ------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -75,8 +76,6 @@ TSAN_FLAG(int, io_sync, 1, TSAN_FLAG(bool, die_after_fork, true, "Die after multi-threaded fork if the child creates new threads.") TSAN_FLAG(const char *, suppressions, "", "Suppressions file name.") -TSAN_FLAG(bool, ignore_interceptors_accesses, false, - "Ignore reads and writes from all interceptors.") TSAN_FLAG(bool, ignore_noninstrumented_modules, SANITIZER_MAC ? true : false, "Interceptors should only detect races when called from instrumented " "modules.") diff --git a/libsanitizer/tsan/tsan_ignoreset.cc b/libsanitizer/tsan/tsan_ignoreset.cpp similarity index 75% rename from libsanitizer/tsan/tsan_ignoreset.cc rename to libsanitizer/tsan/tsan_ignoreset.cpp index f0aec42eb61..f6e41f66861 100644 --- a/libsanitizer/tsan/tsan_ignoreset.cc +++ b/libsanitizer/tsan/tsan_ignoreset.cpp @@ -1,7 +1,8 @@ -//===-- tsan_ignoreset.cc -------------------------------------------------===// +//===-- tsan_ignoreset.cpp ------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_ignoreset.h b/libsanitizer/tsan/tsan_ignoreset.h index 5a250b75af5..3e318bd674d 100644 --- a/libsanitizer/tsan/tsan_ignoreset.h +++ b/libsanitizer/tsan/tsan_ignoreset.h @@ -1,7 +1,8 @@ //===-- tsan_ignoreset.h ----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_interceptors.cc b/libsanitizer/tsan/tsan_interceptors.cpp similarity index 95% rename from libsanitizer/tsan/tsan_interceptors.cc rename to libsanitizer/tsan/tsan_interceptors.cpp index 069df5951d8..9e1b9ed77be 100644 --- a/libsanitizer/tsan/tsan_interceptors.cc +++ b/libsanitizer/tsan/tsan_interceptors.cpp @@ -1,7 +1,8 @@ -//===-- tsan_interceptors.cc ----------------------------------------------===// +//===-- tsan_interceptors.cpp ---------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -40,17 +41,15 @@ using namespace __tsan; // NOLINT #if SANITIZER_NETBSD #define dirfd(dirp) (*(int *)(dirp)) -#define fileno_unlocked fileno +#define fileno_unlocked(fp) \ + (((__sanitizer_FILE*)fp)->_file == -1 ? -1 : \ + (int)(unsigned short)(((__sanitizer_FILE*)fp)->_file)) // NOLINT -#if _LP64 -#define __sF_size 152 -#else -#define __sF_size 88 -#endif - -#define stdout ((char*)&__sF + (__sF_size * 1)) -#define stderr ((char*)&__sF + (__sF_size * 2)) +#define stdout ((__sanitizer_FILE*)&__sF[1]) +#define stderr ((__sanitizer_FILE*)&__sF[2]) +#define nanosleep __nanosleep50 +#define vfork __vfork14 #endif #if SANITIZER_ANDROID @@ -92,8 +91,8 @@ DECLARE_REAL_AND_INTERCEPTOR(void *, malloc, uptr size) DECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr) extern "C" void *pthread_self(); extern "C" void _exit(int status); -extern "C" int fileno_unlocked(void *stream); #if !SANITIZER_NETBSD +extern "C" int fileno_unlocked(void *stream); extern "C" int dirfd(void *dirp); #endif #if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_NETBSD @@ -154,7 +153,7 @@ const int SIG_SETMASK = 2; #endif #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED \ - (!cur_thread()->is_inited) + (cur_thread_init(), !cur_thread()->is_inited) namespace __tsan { struct SignalDesc { @@ -224,6 +223,16 @@ void InitializeLibIgnore() { libignore()->OnLibraryLoaded(0); } +// The following two hooks can be used by for cooperative scheduling when +// locking. +#ifdef TSAN_EXTERNAL_HOOKS +void OnPotentiallyBlockingRegionBegin(); +void OnPotentiallyBlockingRegionEnd(); +#else +SANITIZER_WEAK_CXX_DEFAULT_IMPL void OnPotentiallyBlockingRegionBegin() {} +SANITIZER_WEAK_CXX_DEFAULT_IMPL void OnPotentiallyBlockingRegionEnd() {} +#endif + } // namespace __tsan static ThreadSignalContext *SigCtx(ThreadState *thr) { @@ -244,8 +253,7 @@ ScopedInterceptor::ScopedInterceptor(ThreadState *thr, const char *fname, if (!thr_->ignore_interceptors) FuncEntry(thr, pc); DPrintf("#%d: intercept %s()\n", thr_->tid, fname); ignoring_ = - !thr_->in_ignored_lib && (flags()->ignore_interceptors_accesses || - libignore()->IsIgnored(pc, &in_ignored_lib_)); + !thr_->in_ignored_lib && libignore()->IsIgnored(pc, &in_ignored_lib_); EnableIgnores(); } @@ -390,7 +398,7 @@ static int setup_at_exit_wrapper(ThreadState *thr, uptr pc, void(*f)(), #if !SANITIZER_ANDROID TSAN_INTERCEPTOR(int, atexit, void (*f)()) { - if (UNLIKELY(cur_thread()->in_symbolizer)) + if (in_symbolizer()) return 0; // We want to setup the atexit callback even if we are in ignored lib // or after fork. @@ -400,7 +408,7 @@ TSAN_INTERCEPTOR(int, atexit, void (*f)()) { #endif TSAN_INTERCEPTOR(int, __cxa_atexit, void (*f)(void *a), void *arg, void *dso) { - if (UNLIKELY(cur_thread()->in_symbolizer)) + if (in_symbolizer()) return 0; SCOPED_TSAN_INTERCEPTOR(__cxa_atexit, f, arg, dso); return setup_at_exit_wrapper(thr, pc, (void(*)())f, arg, dso); @@ -446,7 +454,7 @@ static void on_exit_wrapper(int status, void *arg) { } TSAN_INTERCEPTOR(int, on_exit, void(*f)(int, void*), void *arg) { - if (UNLIKELY(cur_thread()->in_symbolizer)) + if (in_symbolizer()) return 0; SCOPED_TSAN_INTERCEPTOR(on_exit, f, arg); AtExitCtx *ctx = (AtExitCtx*)InternalAlloc(sizeof(AtExitCtx)); @@ -478,7 +486,7 @@ static void JmpBufGarbageCollect(ThreadState *thr, uptr sp) { } } -static void SetJmp(ThreadState *thr, uptr sp, uptr mangled_sp) { +static void SetJmp(ThreadState *thr, uptr sp) { if (!thr->is_inited) // called from libc guts during bootstrap return; // Cleanup old bufs. @@ -486,7 +494,6 @@ static void SetJmp(ThreadState *thr, uptr sp, uptr mangled_sp) { // Remember the buf. JmpBuf *buf = thr->jmp_bufs.PushBack(); buf->sp = sp; - buf->mangled_sp = mangled_sp; buf->shadow_stack_pos = thr->shadow_stack_pos; ThreadSignalContext *sctx = SigCtx(thr); buf->int_signal_send = sctx ? sctx->int_signal_send : 0; @@ -498,32 +505,11 @@ static void SetJmp(ThreadState *thr, uptr sp, uptr mangled_sp) { } static void LongJmp(ThreadState *thr, uptr *env) { -#ifdef __powerpc__ - uptr mangled_sp = env[0]; -#elif SANITIZER_FREEBSD - uptr mangled_sp = env[2]; -#elif SANITIZER_NETBSD - uptr mangled_sp = env[6]; -#elif SANITIZER_MAC -# ifdef __aarch64__ - uptr mangled_sp = - (GetMacosVersion() >= MACOS_VERSION_MOJAVE) ? env[12] : env[13]; -# else - uptr mangled_sp = env[2]; -# endif -#elif SANITIZER_LINUX -# ifdef __aarch64__ - uptr mangled_sp = env[13]; -# elif defined(__mips64) - uptr mangled_sp = env[1]; -# else - uptr mangled_sp = env[6]; -# endif -#endif - // Find the saved buf by mangled_sp. + uptr sp = ExtractLongJmpSp(env); + // Find the saved buf with matching sp. for (uptr i = 0; i < thr->jmp_bufs.Size(); i++) { JmpBuf *buf = &thr->jmp_bufs[i]; - if (buf->mangled_sp == mangled_sp) { + if (buf->sp == sp) { CHECK_GE(thr->shadow_stack_pos, buf->shadow_stack_pos); // Unwind the stack. while (thr->shadow_stack_pos > buf->shadow_stack_pos) @@ -545,8 +531,9 @@ static void LongJmp(ThreadState *thr, uptr *env) { } // FIXME: put everything below into a common extern "C" block? -extern "C" void __tsan_setjmp(uptr sp, uptr mangled_sp) { - SetJmp(cur_thread(), sp, mangled_sp); +extern "C" void __tsan_setjmp(uptr sp) { + cur_thread_init(); + SetJmp(cur_thread(), sp); } #if SANITIZER_MAC @@ -656,7 +643,7 @@ TSAN_INTERCEPTOR(void, _longjmp, uptr *env, int val) { #if !SANITIZER_MAC TSAN_INTERCEPTOR(void*, malloc, uptr size) { - if (UNLIKELY(cur_thread()->in_symbolizer)) + if (in_symbolizer()) return InternalAlloc(size); void *p = 0; { @@ -673,7 +660,7 @@ TSAN_INTERCEPTOR(void*, __libc_memalign, uptr align, uptr sz) { } TSAN_INTERCEPTOR(void*, calloc, uptr size, uptr n) { - if (UNLIKELY(cur_thread()->in_symbolizer)) + if (in_symbolizer()) return InternalCalloc(size, n); void *p = 0; { @@ -685,7 +672,7 @@ TSAN_INTERCEPTOR(void*, calloc, uptr size, uptr n) { } TSAN_INTERCEPTOR(void*, realloc, void *p, uptr size) { - if (UNLIKELY(cur_thread()->in_symbolizer)) + if (in_symbolizer()) return InternalRealloc(p, size); if (p) invoke_free_hook(p); @@ -697,10 +684,23 @@ TSAN_INTERCEPTOR(void*, realloc, void *p, uptr size) { return p; } +TSAN_INTERCEPTOR(void*, reallocarray, void *p, uptr size, uptr n) { + if (in_symbolizer()) + return InternalReallocArray(p, size, n); + if (p) + invoke_free_hook(p); + { + SCOPED_INTERCEPTOR_RAW(reallocarray, p, size, n); + p = user_reallocarray(thr, pc, p, size, n); + } + invoke_malloc_hook(p, size); + return p; +} + TSAN_INTERCEPTOR(void, free, void *p) { if (p == 0) return; - if (UNLIKELY(cur_thread()->in_symbolizer)) + if (in_symbolizer()) return InternalFree(p); invoke_free_hook(p); SCOPED_INTERCEPTOR_RAW(free, p); @@ -710,7 +710,7 @@ TSAN_INTERCEPTOR(void, free, void *p) { TSAN_INTERCEPTOR(void, cfree, void *p) { if (p == 0) return; - if (UNLIKELY(cur_thread()->in_symbolizer)) + if (in_symbolizer()) return InternalFree(p); invoke_free_hook(p); SCOPED_INTERCEPTOR_RAW(cfree, p); @@ -799,14 +799,14 @@ TSAN_INTERCEPTOR(void*, memalign, uptr align, uptr sz) { #if !SANITIZER_MAC TSAN_INTERCEPTOR(void*, aligned_alloc, uptr align, uptr sz) { - if (UNLIKELY(cur_thread()->in_symbolizer)) + if (in_symbolizer()) return InternalAlloc(sz, nullptr, align); SCOPED_INTERCEPTOR_RAW(aligned_alloc, align, sz); return user_aligned_alloc(thr, pc, align, sz); } TSAN_INTERCEPTOR(void*, valloc, uptr sz) { - if (UNLIKELY(cur_thread()->in_symbolizer)) + if (in_symbolizer()) return InternalAlloc(sz, nullptr, GetPageSizeCached()); SCOPED_INTERCEPTOR_RAW(valloc, sz); return user_valloc(thr, pc, sz); @@ -815,7 +815,7 @@ TSAN_INTERCEPTOR(void*, valloc, uptr sz) { #if SANITIZER_LINUX TSAN_INTERCEPTOR(void*, pvalloc, uptr sz) { - if (UNLIKELY(cur_thread()->in_symbolizer)) { + if (in_symbolizer()) { uptr PageSize = GetPageSizeCached(); sz = sz ? RoundUpTo(sz, PageSize) : PageSize; return InternalAlloc(sz, nullptr, PageSize); @@ -830,7 +830,7 @@ TSAN_INTERCEPTOR(void*, pvalloc, uptr sz) { #if !SANITIZER_MAC TSAN_INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr sz) { - if (UNLIKELY(cur_thread()->in_symbolizer)) { + if (in_symbolizer()) { void *p = InternalAlloc(sz, nullptr, align); if (!p) return errno_ENOMEM; @@ -862,6 +862,8 @@ TSAN_INTERCEPTOR(int, posix_memalign, void **memptr, uptr align, uptr sz) { // Used in thread-safe function static initialization. STDCXX_INTERCEPTOR(int, __cxa_guard_acquire, atomic_uint32_t *g) { SCOPED_INTERCEPTOR_RAW(__cxa_guard_acquire, g); + OnPotentiallyBlockingRegionBegin(); + auto on_exit = at_scope_exit(&OnPotentiallyBlockingRegionEnd); for (;;) { u32 cmp = atomic_load(g, memory_order_acquire); if (cmp == 0) { @@ -932,6 +934,7 @@ extern "C" void *__tsan_thread_start_func(void *arg) { void *param = p->param; int tid = 0; { + cur_thread_init(); ThreadState *thr = cur_thread(); // Thread-local state is not initialized yet. ScopedIgnoreInterceptors ignore; @@ -948,7 +951,7 @@ extern "C" void *__tsan_thread_start_func(void *arg) { internal_sched_yield(); Processor *proc = ProcCreate(); ProcWire(proc, thr); - ThreadStart(thr, tid, GetTid(), /*workerthread*/ false); + ThreadStart(thr, tid, GetTid(), ThreadType::Regular); atomic_store(&p->tid, 0, memory_order_release); } void *res = callback(param); @@ -1040,6 +1043,45 @@ TSAN_INTERCEPTOR(int, pthread_detach, void *th) { return res; } +TSAN_INTERCEPTOR(void, pthread_exit, void *retval) { + { + SCOPED_INTERCEPTOR_RAW(pthread_exit, retval); +#if !SANITIZER_MAC && !SANITIZER_ANDROID + CHECK_EQ(thr, &cur_thread_placeholder); +#endif + } + REAL(pthread_exit)(retval); +} + +#if SANITIZER_LINUX +TSAN_INTERCEPTOR(int, pthread_tryjoin_np, void *th, void **ret) { + SCOPED_TSAN_INTERCEPTOR(pthread_tryjoin_np, th, ret); + int tid = ThreadTid(thr, pc, (uptr)th); + ThreadIgnoreBegin(thr, pc); + int res = REAL(pthread_tryjoin_np)(th, ret); + ThreadIgnoreEnd(thr, pc); + if (res == 0) + ThreadJoin(thr, pc, tid); + else + ThreadNotJoined(thr, pc, tid, (uptr)th); + return res; +} + +TSAN_INTERCEPTOR(int, pthread_timedjoin_np, void *th, void **ret, + const struct timespec *abstime) { + SCOPED_TSAN_INTERCEPTOR(pthread_timedjoin_np, th, ret, abstime); + int tid = ThreadTid(thr, pc, (uptr)th); + ThreadIgnoreBegin(thr, pc); + int res = BLOCK_REAL(pthread_timedjoin_np)(th, ret, abstime); + ThreadIgnoreEnd(thr, pc); + if (res == 0) + ThreadJoin(thr, pc, tid); + else + ThreadNotJoined(thr, pc, tid, (uptr)th); + return res; +} +#endif + // Problem: // NPTL implementation of pthread_cond has 2 versions (2.2.5 and 2.3.2). // pthread_cond_t has different size in the different versions. @@ -1115,7 +1157,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); @@ -1935,6 +1977,7 @@ static bool is_sync_signal(ThreadSignalContext *sctx, int sig) { void ALWAYS_INLINE rtl_generic_sighandler(bool sigact, int sig, __sanitizer_siginfo *info, void *ctx) { + cur_thread_init(); ThreadState *thr = cur_thread(); ThreadSignalContext *sctx = SigCtx(thr); if (sig < 0 || sig >= kSigCount) { @@ -2051,7 +2094,7 @@ TSAN_INTERCEPTOR(int, getaddrinfo, void *node, void *service, } TSAN_INTERCEPTOR(int, fork, int fake) { - if (UNLIKELY(cur_thread()->in_symbolizer)) + if (in_symbolizer()) return REAL(fork)(fake); SCOPED_INTERCEPTOR_RAW(fork, fake); ForkBefore(thr, pc); @@ -2164,23 +2207,12 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc, #include "sanitizer_common/sanitizer_platform_interceptors.h" // Causes interceptor recursion (getaddrinfo() and fopen()) #undef SANITIZER_INTERCEPT_GETADDRINFO -// There interceptors do not seem to be strictly necessary for tsan. -// But we see cases where the interceptors consume 70% of execution time. -// Memory blocks passed to fgetgrent_r are "written to" by tsan several times. -// First, there is some recursion (getgrnam_r calls fgetgrent_r), and each -// function "writes to" the buffer. Then, the same memory is "written to" -// twice, first as buf and then as pwbufp (both of them refer to the same -// addresses). -#undef SANITIZER_INTERCEPT_GETPWENT -#undef SANITIZER_INTERCEPT_GETPWENT_R -#undef SANITIZER_INTERCEPT_FGETPWENT -#undef SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS -#undef SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS // We define our own. #if SANITIZER_INTERCEPT_TLS_GET_ADDR #define NEED_TLS_GET_ADDR #endif #undef SANITIZER_INTERCEPT_TLS_GET_ADDR +#undef SANITIZER_INTERCEPT_PTHREAD_SIGMASK #define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name) #define COMMON_INTERCEPT_FUNCTION_VER(name, ver) \ @@ -2209,7 +2241,8 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc, (void) ctx; #define COMMON_INTERCEPTOR_FILE_OPEN(ctx, file, path) \ - Acquire(thr, pc, File2addr(path)); \ + if (path) \ + Acquire(thr, pc, File2addr(path)); \ if (file) { \ int fd = fileno_unlocked(file); \ if (fd >= 0) FdFileCreate(thr, pc, fd); \ @@ -2558,6 +2591,8 @@ TSAN_INTERCEPTOR_NETBSD_ALIAS(int, rwlock_wrlock, void *m) TSAN_INTERCEPTOR_NETBSD_ALIAS(int, rwlock_trywrlock, void *m) TSAN_INTERCEPTOR_NETBSD_ALIAS(int, rwlock_unlock, void *m) TSAN_INTERCEPTOR_NETBSD_ALIAS_THR(int, once, void *o, void (*f)()) +TSAN_INTERCEPTOR_NETBSD_ALIAS_THR2(int, sigsetmask, sigmask, int a, void *b, + void *c) namespace __tsan { @@ -2577,6 +2612,9 @@ static void unreachable() { } #endif +// Define default implementation since interception of libdispatch is optional. +SANITIZER_WEAK_ATTRIBUTE void InitializeLibdispatchInterceptors() {} + void InitializeInterceptors() { #if !SANITIZER_MAC // We need to setup it early, because functions like dlsym() can call it. @@ -2594,18 +2632,18 @@ void InitializeInterceptors() { InitializeCommonInterceptors(); InitializeSignalInterceptors(); + InitializeLibdispatchInterceptors(); #if !SANITIZER_MAC // We can not use TSAN_INTERCEPT to get setjmp addr, // because it does &setjmp and setjmp is not present in some versions of libc. - using __interception::GetRealFunctionAddress; - GetRealFunctionAddress(TSAN_STRING_SETJMP, - (uptr*)&REAL(setjmp_symname), 0, 0); - GetRealFunctionAddress("_setjmp", (uptr*)&REAL(_setjmp), 0, 0); - GetRealFunctionAddress(TSAN_STRING_SIGSETJMP, - (uptr*)&REAL(sigsetjmp_symname), 0, 0); + using __interception::InterceptFunction; + InterceptFunction(TSAN_STRING_SETJMP, (uptr*)&REAL(setjmp_symname), 0, 0); + InterceptFunction("_setjmp", (uptr*)&REAL(_setjmp), 0, 0); + InterceptFunction(TSAN_STRING_SIGSETJMP, (uptr*)&REAL(sigsetjmp_symname), 0, + 0); #if !SANITIZER_NETBSD - GetRealFunctionAddress("__sigsetjmp", (uptr*)&REAL(__sigsetjmp), 0, 0); + InterceptFunction("__sigsetjmp", (uptr*)&REAL(__sigsetjmp), 0, 0); #endif #endif @@ -2619,6 +2657,7 @@ void InitializeInterceptors() { TSAN_INTERCEPT(__libc_memalign); TSAN_INTERCEPT(calloc); TSAN_INTERCEPT(realloc); + TSAN_INTERCEPT(reallocarray); TSAN_INTERCEPT(free); TSAN_INTERCEPT(cfree); TSAN_INTERCEPT(munmap); @@ -2634,6 +2673,11 @@ void InitializeInterceptors() { TSAN_INTERCEPT(pthread_create); TSAN_INTERCEPT(pthread_join); TSAN_INTERCEPT(pthread_detach); + TSAN_INTERCEPT(pthread_exit); + #if SANITIZER_LINUX + TSAN_INTERCEPT(pthread_tryjoin_np); + TSAN_INTERCEPT(pthread_timedjoin_np); + #endif TSAN_INTERCEPT_VER(pthread_cond_init, PTHREAD_ABI_BASE); TSAN_INTERCEPT_VER(pthread_cond_signal, PTHREAD_ABI_BASE); @@ -2767,6 +2811,7 @@ void InitializeInterceptors() { TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(rwlock_trywrlock); TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(rwlock_unlock); TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS_THR(once); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS_THR(sigsetmask); FdInit(); } diff --git a/libsanitizer/tsan/tsan_interceptors.h b/libsanitizer/tsan/tsan_interceptors.h index 959a39465e3..88d1edd775d 100644 --- a/libsanitizer/tsan/tsan_interceptors.h +++ b/libsanitizer/tsan/tsan_interceptors.h @@ -21,9 +21,17 @@ class ScopedInterceptor { LibIgnore *libignore(); +#if !SANITIZER_GO +INLINE bool in_symbolizer() { + cur_thread_init(); + return UNLIKELY(cur_thread()->in_symbolizer); +} +#endif + } // namespace __tsan #define SCOPED_INTERCEPTOR_RAW(func, ...) \ + cur_thread_init(); \ ThreadState *thr = cur_thread(); \ const uptr caller_pc = GET_CALLER_PC(); \ ScopedInterceptor si(thr, #func, caller_pc); \ @@ -56,9 +64,13 @@ LibIgnore *libignore(); # define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR(ret, func, ...) \ TSAN_INTERCEPTOR(ret, __libc_thr_##func, __VA_ARGS__) \ ALIAS(WRAPPER_NAME(pthread_##func)); +# define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR2(ret, func, func2, ...) \ + TSAN_INTERCEPTOR(ret, __libc_thr_##func, __VA_ARGS__) \ + ALIAS(WRAPPER_NAME(pthread_##func2)); #else # define TSAN_INTERCEPTOR_NETBSD_ALIAS(ret, func, ...) # define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR(ret, func, ...) +# define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR2(ret, func, func2, ...) #endif #endif // TSAN_INTERCEPTORS_H diff --git a/libsanitizer/tsan/tsan_interceptors_mac.cc b/libsanitizer/tsan/tsan_interceptors_mac.cpp similarity index 82% rename from libsanitizer/tsan/tsan_interceptors_mac.cc rename to libsanitizer/tsan/tsan_interceptors_mac.cpp index 1df6ac27f49..c2083f8cde9 100644 --- a/libsanitizer/tsan/tsan_interceptors_mac.cc +++ b/libsanitizer/tsan/tsan_interceptors_mac.cpp @@ -1,7 +1,8 @@ -//===-- tsan_interceptors_mac.cc ------------------------------------------===// +//===-- tsan_interceptors_mac.cpp -----------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -17,8 +18,12 @@ #include "tsan_interceptors.h" #include "tsan_interface.h" #include "tsan_interface_ann.h" +#include "sanitizer_common/sanitizer_addrhashmap.h" +#include #include +#include +#include #if defined(__has_include) && __has_include() #include @@ -26,6 +31,11 @@ typedef long long_t; // NOLINT +extern "C" { +int getcontext(ucontext_t *ucp) __attribute__((returns_twice)); +int setcontext(const ucontext_t *ucp); +} + namespace __tsan { // The non-barrier versions of OSAtomic* functions are semantically mo_relaxed, @@ -292,41 +302,87 @@ TSAN_INTERCEPTOR(void, xpc_connection_cancel, xpc_connection_t connection) { #endif // #if defined(__has_include) && __has_include() -// Is the Obj-C object a tagged pointer (i.e. isn't really a valid pointer and -// contains data in the pointers bits instead)? -static bool IsTaggedObjCPointer(void *obj) { +// Determines whether the Obj-C object pointer is a tagged pointer. Tagged +// pointers encode the object data directly in their pointer bits and do not +// have an associated memory allocation. The Obj-C runtime uses tagged pointers +// to transparently optimize small objects. +static bool IsTaggedObjCPointer(id obj) { const uptr kPossibleTaggedBits = 0x8000000000000001ull; return ((uptr)obj & kPossibleTaggedBits) != 0; } -// Return an address on which we can synchronize (Acquire and Release) for a -// Obj-C tagged pointer (which is not a valid pointer). Ideally should be a -// derived address from 'obj', but for now just return the same global address. -// TODO(kubamracek): Return different address for different pointers. -static uptr SyncAddressForTaggedPointer(void *obj) { - (void)obj; - static u64 addr; - return (uptr)&addr; +// Returns an address which can be used to inform TSan about synchronization +// points (MutexLock/Unlock). The TSan infrastructure expects this to be a valid +// address in the process space. We do a small allocation here to obtain a +// stable address (the array backing the hash map can change). The memory is +// never free'd (leaked) and allocation and locking are slow, but this code only +// runs for @synchronized with tagged pointers, which is very rare. +static uptr GetOrCreateSyncAddress(uptr addr, ThreadState *thr, uptr pc) { + typedef AddrHashMap Map; + static Map Addresses; + Map::Handle h(&Addresses, addr); + if (h.created()) { + ThreadIgnoreBegin(thr, pc); + *h = (uptr) user_alloc(thr, pc, /*size=*/1); + ThreadIgnoreEnd(thr, pc); + } + return *h; } -// Address on which we can synchronize for an Objective-C object. Supports -// tagged pointers. -static uptr SyncAddressForObjCObject(void *obj) { - if (IsTaggedObjCPointer(obj)) return SyncAddressForTaggedPointer(obj); +// Returns an address on which we can synchronize given an Obj-C object pointer. +// For normal object pointers, this is just the address of the object in memory. +// Tagged pointers are not backed by an actual memory allocation, so we need to +// synthesize a valid address. +static uptr SyncAddressForObjCObject(id obj, ThreadState *thr, uptr pc) { + if (IsTaggedObjCPointer(obj)) + return GetOrCreateSyncAddress((uptr)obj, thr, pc); return (uptr)obj; } -TSAN_INTERCEPTOR(int, objc_sync_enter, void *obj) { +TSAN_INTERCEPTOR(int, objc_sync_enter, id obj) { SCOPED_TSAN_INTERCEPTOR(objc_sync_enter, obj); + if (!obj) return REAL(objc_sync_enter)(obj); + uptr addr = SyncAddressForObjCObject(obj, thr, pc); + MutexPreLock(thr, pc, addr, MutexFlagWriteReentrant); int result = REAL(objc_sync_enter)(obj); - if (obj) Acquire(thr, pc, SyncAddressForObjCObject(obj)); + CHECK_EQ(result, OBJC_SYNC_SUCCESS); + MutexPostLock(thr, pc, addr, MutexFlagWriteReentrant); return result; } -TSAN_INTERCEPTOR(int, objc_sync_exit, void *obj) { - SCOPED_TSAN_INTERCEPTOR(objc_sync_enter, obj); - if (obj) Release(thr, pc, SyncAddressForObjCObject(obj)); - return REAL(objc_sync_exit)(obj); +TSAN_INTERCEPTOR(int, objc_sync_exit, id obj) { + SCOPED_TSAN_INTERCEPTOR(objc_sync_exit, obj); + if (!obj) return REAL(objc_sync_exit)(obj); + uptr addr = SyncAddressForObjCObject(obj, thr, pc); + MutexUnlock(thr, pc, addr); + int result = REAL(objc_sync_exit)(obj); + if (result != OBJC_SYNC_SUCCESS) MutexInvalidAccess(thr, pc, addr); + return result; +} + +TSAN_INTERCEPTOR(int, swapcontext, ucontext_t *oucp, const ucontext_t *ucp) { + { + SCOPED_INTERCEPTOR_RAW(swapcontext, oucp, ucp); + } + // Bacause of swapcontext() semantics we have no option but to copy its + // impementation here + if (!oucp || !ucp) { + errno = EINVAL; + return -1; + } + ThreadState *thr = cur_thread(); + const int UCF_SWAPPED = 0x80000000; + oucp->uc_onstack &= ~UCF_SWAPPED; + thr->ignore_interceptors++; + int ret = getcontext(oucp); + if (!(oucp->uc_onstack & UCF_SWAPPED)) { + thr->ignore_interceptors--; + if (!ret) { + oucp->uc_onstack |= UCF_SWAPPED; + ret = setcontext(ucp); + } + } + return ret; } // On macOS, libc++ is always linked dynamically, so intercepting works the diff --git a/libsanitizer/tsan/tsan_interface.cc b/libsanitizer/tsan/tsan_interface.cpp similarity index 78% rename from libsanitizer/tsan/tsan_interface.cc rename to libsanitizer/tsan/tsan_interface.cpp index d98ff15f562..845d8c8520c 100644 --- a/libsanitizer/tsan/tsan_interface.cc +++ b/libsanitizer/tsan/tsan_interface.cpp @@ -1,7 +1,8 @@ -//===-- tsan_interface.cc -------------------------------------------------===// +//===-- tsan_interface.cpp ------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -23,6 +24,7 @@ typedef u32 uint32_t; typedef u64 uint64_t; void __tsan_init() { + cur_thread_init(); Initialize(cur_thread()); } @@ -122,6 +124,31 @@ void __sanitizer_unaligned_store64(uu64 *addr, u64 v) { __tsan_unaligned_write8(addr); *addr = v; } + +SANITIZER_INTERFACE_ATTRIBUTE +void *__tsan_get_current_fiber() { + return cur_thread(); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void *__tsan_create_fiber(unsigned flags) { + return FiberCreate(cur_thread(), CALLERPC, flags); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void __tsan_destroy_fiber(void *fiber) { + FiberDestroy(cur_thread(), CALLERPC, static_cast(fiber)); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void __tsan_switch_to_fiber(void *fiber, unsigned flags) { + FiberSwitch(cur_thread(), CALLERPC, static_cast(fiber), flags); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void __tsan_set_fiber_name(void *fiber, const char *name) { + ThreadSetName(static_cast(fiber), name); +} } // extern "C" void __tsan_acquire(void *addr) { diff --git a/libsanitizer/tsan/tsan_interface.h b/libsanitizer/tsan/tsan_interface.h index bb097b9554b..fac57809aa2 100644 --- a/libsanitizer/tsan/tsan_interface.h +++ b/libsanitizer/tsan/tsan_interface.h @@ -1,7 +1,8 @@ //===-- tsan_interface.h ----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -198,7 +199,7 @@ __extension__ typedef __int128 a128; #endif // Part of ABI, do not change. -// http://llvm.org/viewvc/llvm-project/libcxx/trunk/include/atomic?view=markup +// https://github.com/llvm/llvm-project/blob/master/libcxx/include/atomic typedef enum { mo_relaxed, mo_consume, diff --git a/libsanitizer/tsan/tsan_interface_ann.cc b/libsanitizer/tsan/tsan_interface_ann.cpp similarity index 98% rename from libsanitizer/tsan/tsan_interface_ann.cc rename to libsanitizer/tsan/tsan_interface_ann.cpp index 3e2b7c83c3a..288485c17fa 100644 --- a/libsanitizer/tsan/tsan_interface_ann.cc +++ b/libsanitizer/tsan/tsan_interface_ann.cpp @@ -1,7 +1,8 @@ -//===-- tsan_interface_ann.cc ---------------------------------------------===// +//===-- tsan_interface_ann.cpp --------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_interface_ann.h b/libsanitizer/tsan/tsan_interface_ann.h index 45c18352e69..458d61f5335 100644 --- a/libsanitizer/tsan/tsan_interface_ann.h +++ b/libsanitizer/tsan/tsan_interface_ann.h @@ -1,7 +1,8 @@ //===-- tsan_interface_ann.h ------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_interface_atomic.cc b/libsanitizer/tsan/tsan_interface_atomic.cpp similarity index 98% rename from libsanitizer/tsan/tsan_interface_atomic.cc rename to libsanitizer/tsan/tsan_interface_atomic.cpp index c175d614764..730a8e63f74 100644 --- a/libsanitizer/tsan/tsan_interface_atomic.cc +++ b/libsanitizer/tsan/tsan_interface_atomic.cpp @@ -1,7 +1,8 @@ -//===-- tsan_interface_atomic.cc ------------------------------------------===// +//===-- tsan_interface_atomic.cpp -----------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -473,7 +474,7 @@ static morder convert_morder(morder mo) { #define SCOPED_ATOMIC(func, ...) \ ThreadState *const thr = cur_thread(); \ - if (thr->ignore_sync || thr->ignore_interceptors) { \ + if (UNLIKELY(thr->ignore_sync || thr->ignore_interceptors)) { \ ProcessPendingSignals(thr); \ return NoTsanAtomic##func(__VA_ARGS__); \ } \ diff --git a/libsanitizer/tsan/tsan_interface_inl.h b/libsanitizer/tsan/tsan_interface_inl.h index bf70cdce34b..bf4a1658625 100644 --- a/libsanitizer/tsan/tsan_interface_inl.h +++ b/libsanitizer/tsan/tsan_interface_inl.h @@ -1,7 +1,8 @@ //===-- tsan_interface_inl.h ------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_interface_java.cc b/libsanitizer/tsan/tsan_interface_java.cpp similarity index 96% rename from libsanitizer/tsan/tsan_interface_java.cc rename to libsanitizer/tsan/tsan_interface_java.cpp index d3f35a9bc82..7d3d32fdbe0 100644 --- a/libsanitizer/tsan/tsan_interface_java.cc +++ b/libsanitizer/tsan/tsan_interface_java.cpp @@ -1,7 +1,8 @@ -//===-- tsan_interface_java.cc --------------------------------------------===// +//===-- tsan_interface_java.cpp -------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_interface_java.h b/libsanitizer/tsan/tsan_interface_java.h index 2dd49f05c68..93e67bd10b1 100644 --- a/libsanitizer/tsan/tsan_interface_java.h +++ b/libsanitizer/tsan/tsan_interface_java.h @@ -1,7 +1,8 @@ //===-- tsan_interface_java.h -----------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -17,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 diff --git a/libsanitizer/tsan/tsan_libdispatch_mac.cc b/libsanitizer/tsan/tsan_libdispatch.cpp similarity index 82% rename from libsanitizer/tsan/tsan_libdispatch_mac.cc rename to libsanitizer/tsan/tsan_libdispatch.cpp index f7e08d46fbb..5e86ddc4e12 100644 --- a/libsanitizer/tsan/tsan_libdispatch_mac.cc +++ b/libsanitizer/tsan/tsan_libdispatch.cpp @@ -1,36 +1,25 @@ -//===-- tsan_libdispatch_mac.cc -------------------------------------------===// +//===-- tsan_libdispatch.cpp ----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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. // -// Mac-specific libdispatch (GCD) support. +// Support for intercepting libdispatch (GCD). //===----------------------------------------------------------------------===// -#include "sanitizer_common/sanitizer_platform.h" -#if SANITIZER_MAC - #include "sanitizer_common/sanitizer_common.h" #include "interception/interception.h" #include "tsan_interceptors.h" -#include "tsan_platform.h" #include "tsan_rtl.h" -#include -#include -#include - -// DISPATCH_NOESCAPE is not defined prior to XCode 8. -#ifndef DISPATCH_NOESCAPE -#define DISPATCH_NOESCAPE -#endif - -typedef long long_t; // NOLINT +#include "tsan_dispatch_defs.h" namespace __tsan { + typedef u16 uint16_t; typedef struct { dispatch_queue_t queue; @@ -40,7 +29,7 @@ typedef struct { bool submitted_synchronously; bool is_barrier_block; uptr non_queue_sync_object; -} tsan_block_context_t; +} block_context_t; // The offsets of different fields of the dispatch_queue_t structure, exported // by libdispatch.dylib. @@ -84,13 +73,11 @@ static dispatch_queue_t GetTargetQueueFromSource(dispatch_source_t source) { return tq; } -static tsan_block_context_t *AllocContext(ThreadState *thr, uptr pc, - dispatch_queue_t queue, - void *orig_context, - dispatch_function_t orig_work) { - tsan_block_context_t *new_context = - (tsan_block_context_t *)user_alloc_internal(thr, pc, - sizeof(tsan_block_context_t)); +static block_context_t *AllocContext(ThreadState *thr, uptr pc, + dispatch_queue_t queue, void *orig_context, + dispatch_function_t orig_work) { + block_context_t *new_context = + (block_context_t *)user_alloc_internal(thr, pc, sizeof(block_context_t)); new_context->queue = queue; new_context->orig_context = orig_context; new_context->orig_work = orig_work; @@ -109,7 +96,7 @@ static tsan_block_context_t *AllocContext(ThreadState *thr, uptr pc, bool serial_task = context->is_barrier_block || is_queue_serial static void dispatch_sync_pre_execute(ThreadState *thr, uptr pc, - tsan_block_context_t *context) { + block_context_t *context) { uptr submit_sync = (uptr)context; Acquire(thr, pc, submit_sync); @@ -124,7 +111,7 @@ static void dispatch_sync_pre_execute(ThreadState *thr, uptr pc, } static void dispatch_sync_post_execute(ThreadState *thr, uptr pc, - tsan_block_context_t *context) { + block_context_t *context) { uptr submit_sync = (uptr)context; if (context->submitted_synchronously) Release(thr, pc, submit_sync); @@ -140,7 +127,7 @@ static void dispatch_sync_post_execute(ThreadState *thr, uptr pc, static void dispatch_callback_wrap(void *param) { SCOPED_INTERCEPTOR_RAW(dispatch_callback_wrap); - tsan_block_context_t *context = (tsan_block_context_t *)param; + block_context_t *context = (block_context_t *)param; dispatch_sync_pre_execute(thr, pc, context); @@ -164,13 +151,13 @@ static void invoke_and_release_block(void *param) { Block_release(block); } -#define DISPATCH_INTERCEPT_B(name, barrier) \ +#define DISPATCH_INTERCEPT_ASYNC_B(name, barrier) \ TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, dispatch_block_t block) { \ SCOPED_TSAN_INTERCEPTOR(name, q, block); \ SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); \ dispatch_block_t heap_block = Block_copy(block); \ SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END(); \ - tsan_block_context_t *new_context = \ + block_context_t *new_context = \ AllocContext(thr, pc, q, heap_block, &invoke_and_release_block); \ new_context->is_barrier_block = barrier; \ Release(thr, pc, (uptr)new_context); \ @@ -183,7 +170,7 @@ static void invoke_and_release_block(void *param) { TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, \ DISPATCH_NOESCAPE dispatch_block_t block) { \ SCOPED_TSAN_INTERCEPTOR(name, q, block); \ - tsan_block_context_t new_context = { \ + block_context_t new_context = { \ q, block, &invoke_block, false, true, barrier, 0}; \ Release(thr, pc, (uptr)&new_context); \ SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); \ @@ -192,11 +179,11 @@ static void invoke_and_release_block(void *param) { Acquire(thr, pc, (uptr)&new_context); \ } -#define DISPATCH_INTERCEPT_F(name, barrier) \ +#define DISPATCH_INTERCEPT_ASYNC_F(name, barrier) \ TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, void *context, \ dispatch_function_t work) { \ SCOPED_TSAN_INTERCEPTOR(name, q, context, work); \ - tsan_block_context_t *new_context = \ + block_context_t *new_context = \ AllocContext(thr, pc, q, context, work); \ new_context->is_barrier_block = barrier; \ Release(thr, pc, (uptr)new_context); \ @@ -209,7 +196,7 @@ static void invoke_and_release_block(void *param) { TSAN_INTERCEPTOR(void, name, dispatch_queue_t q, void *context, \ dispatch_function_t work) { \ SCOPED_TSAN_INTERCEPTOR(name, q, context, work); \ - tsan_block_context_t new_context = { \ + block_context_t new_context = { \ q, context, work, false, true, barrier, 0}; \ Release(thr, pc, (uptr)&new_context); \ SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); \ @@ -218,18 +205,21 @@ static void invoke_and_release_block(void *param) { Acquire(thr, pc, (uptr)&new_context); \ } +#define DISPATCH_INTERCEPT(name, barrier) \ + DISPATCH_INTERCEPT_ASYNC_F(name##_async_f, barrier) \ + DISPATCH_INTERCEPT_ASYNC_B(name##_async, barrier) \ + DISPATCH_INTERCEPT_SYNC_F(name##_sync_f, barrier) \ + DISPATCH_INTERCEPT_SYNC_B(name##_sync, barrier) + // We wrap dispatch_async, dispatch_sync and friends where we allocate a new // context, which is used to synchronize (we release the context before // submitting, and the callback acquires it before executing the original // callback). -DISPATCH_INTERCEPT_B(dispatch_async, false) -DISPATCH_INTERCEPT_B(dispatch_barrier_async, true) -DISPATCH_INTERCEPT_F(dispatch_async_f, false) -DISPATCH_INTERCEPT_F(dispatch_barrier_async_f, true) -DISPATCH_INTERCEPT_SYNC_B(dispatch_sync, false) -DISPATCH_INTERCEPT_SYNC_B(dispatch_barrier_sync, true) -DISPATCH_INTERCEPT_SYNC_F(dispatch_sync_f, false) -DISPATCH_INTERCEPT_SYNC_F(dispatch_barrier_sync_f, true) +DISPATCH_INTERCEPT(dispatch, false) +DISPATCH_INTERCEPT(dispatch_barrier, true) + +DECLARE_REAL(void, dispatch_after_f, dispatch_time_t when, + dispatch_queue_t queue, void *context, dispatch_function_t work) TSAN_INTERCEPTOR(void, dispatch_after, dispatch_time_t when, dispatch_queue_t queue, dispatch_block_t block) { @@ -237,7 +227,7 @@ TSAN_INTERCEPTOR(void, dispatch_after, dispatch_time_t when, SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); dispatch_block_t heap_block = Block_copy(block); SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END(); - tsan_block_context_t *new_context = + block_context_t *new_context = AllocContext(thr, pc, queue, heap_block, &invoke_and_release_block); Release(thr, pc, (uptr)new_context); SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); @@ -322,9 +312,12 @@ TSAN_INTERCEPTOR(long_t, dispatch_group_wait, dispatch_group_t group, return result; } +// Used, but not intercepted. +extern "C" void dispatch_group_enter(dispatch_group_t group); + TSAN_INTERCEPTOR(void, dispatch_group_leave, dispatch_group_t group) { SCOPED_TSAN_INTERCEPTOR(dispatch_group_leave, group); - // Acquired in the group noticifaction callback in dispatch_group_notify[_f]. + // Acquired in the group notification callback in dispatch_group_notify[_f]. Release(thr, pc, (uptr)group); REAL(dispatch_group_leave)(group); } @@ -334,10 +327,10 @@ TSAN_INTERCEPTOR(void, dispatch_group_async, dispatch_group_t group, SCOPED_TSAN_INTERCEPTOR(dispatch_group_async, group, queue, block); dispatch_retain(group); dispatch_group_enter(group); - __block dispatch_block_t block_copy = (dispatch_block_t)_Block_copy(block); + __block dispatch_block_t block_copy = (dispatch_block_t)Block_copy(block); WRAP(dispatch_async)(queue, ^(void) { block_copy(); - _Block_release(block_copy); + Block_release(block_copy); WRAP(dispatch_group_leave)(group); dispatch_release(group); }); @@ -356,6 +349,9 @@ TSAN_INTERCEPTOR(void, dispatch_group_async_f, dispatch_group_t group, }); } +DECLARE_REAL(void, dispatch_group_notify_f, dispatch_group_t group, + dispatch_queue_t q, void *context, dispatch_function_t work) + TSAN_INTERCEPTOR(void, dispatch_group_notify, dispatch_group_t group, dispatch_queue_t q, dispatch_block_t block) { SCOPED_TSAN_INTERCEPTOR(dispatch_group_notify, group, q, block); @@ -375,7 +371,7 @@ TSAN_INTERCEPTOR(void, dispatch_group_notify, dispatch_group_t group, block(); }); SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END(); - tsan_block_context_t *new_context = + block_context_t *new_context = AllocContext(thr, pc, q, heap_block, &invoke_and_release_block); new_context->is_barrier_block = true; Release(thr, pc, (uptr)new_context); @@ -393,7 +389,7 @@ TSAN_INTERCEPTOR(void, dispatch_source_set_event_handler, if (handler == nullptr) return REAL(dispatch_source_set_event_handler)(source, nullptr); dispatch_queue_t q = GetTargetQueueFromSource(source); - __block tsan_block_context_t new_context = { + __block block_context_t new_context = { q, handler, &invoke_block, false, false, false, 0 }; dispatch_block_t new_handler = Block_copy(^(void) { new_context.orig_context = handler; // To explicitly capture "handler". @@ -422,7 +418,7 @@ TSAN_INTERCEPTOR(void, dispatch_source_set_cancel_handler, if (handler == nullptr) return REAL(dispatch_source_set_cancel_handler)(source, nullptr); dispatch_queue_t q = GetTargetQueueFromSource(source); - __block tsan_block_context_t new_context = { + __block block_context_t new_context = { q, handler, &invoke_block, false, false, false, 0}; dispatch_block_t new_handler = Block_copy(^(void) { new_context.orig_context = handler; // To explicitly capture "handler". @@ -453,7 +449,7 @@ TSAN_INTERCEPTOR(void, dispatch_source_set_registration_handler, if (handler == nullptr) return REAL(dispatch_source_set_registration_handler)(source, nullptr); dispatch_queue_t q = GetTargetQueueFromSource(source); - __block tsan_block_context_t new_context = { + __block block_context_t new_context = { q, handler, &invoke_block, false, false, false, 0}; dispatch_block_t new_handler = Block_copy(^(void) { new_context.orig_context = handler; // To explicitly capture "handler". @@ -482,34 +478,54 @@ TSAN_INTERCEPTOR(void, dispatch_apply, size_t iterations, DISPATCH_NOESCAPE void (^block)(size_t)) { SCOPED_TSAN_INTERCEPTOR(dispatch_apply, iterations, queue, block); - void *parent_to_child_sync = nullptr; - uptr parent_to_child_sync_uptr = (uptr)&parent_to_child_sync; - void *child_to_parent_sync = nullptr; - uptr child_to_parent_sync_uptr = (uptr)&child_to_parent_sync; + u8 sync1, sync2; + uptr parent_to_child_sync = (uptr)&sync1; + uptr child_to_parent_sync = (uptr)&sync2; - Release(thr, pc, parent_to_child_sync_uptr); + Release(thr, pc, parent_to_child_sync); void (^new_block)(size_t) = ^(size_t iteration) { SCOPED_INTERCEPTOR_RAW(dispatch_apply); - Acquire(thr, pc, parent_to_child_sync_uptr); + Acquire(thr, pc, parent_to_child_sync); SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); block(iteration); SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END(); - Release(thr, pc, child_to_parent_sync_uptr); + Release(thr, pc, child_to_parent_sync); }; SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); REAL(dispatch_apply)(iterations, queue, new_block); SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END(); - Acquire(thr, pc, child_to_parent_sync_uptr); + Acquire(thr, pc, child_to_parent_sync); +} + +static void invoke_block_iteration(void *param, size_t iteration) { + auto block = (void (^)(size_t)) param; + block(iteration); } TSAN_INTERCEPTOR(void, dispatch_apply_f, size_t iterations, dispatch_queue_t queue, void *context, void (*work)(void *, size_t)) { SCOPED_TSAN_INTERCEPTOR(dispatch_apply_f, iterations, queue, context, work); + + // Unfortunately, we cannot delegate to dispatch_apply, since libdispatch + // implements dispatch_apply in terms of dispatch_apply_f. + u8 sync1, sync2; + uptr parent_to_child_sync = (uptr)&sync1; + uptr child_to_parent_sync = (uptr)&sync2; + + Release(thr, pc, parent_to_child_sync); void (^new_block)(size_t) = ^(size_t iteration) { + SCOPED_INTERCEPTOR_RAW(dispatch_apply_f); + Acquire(thr, pc, parent_to_child_sync); + SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); work(context, iteration); + SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END(); + Release(thr, pc, child_to_parent_sync); }; - WRAP(dispatch_apply)(iterations, queue, new_block); + SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); + REAL(dispatch_apply_f)(iterations, queue, new_block, invoke_block_iteration); + SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END(); + Acquire(thr, pc, child_to_parent_sync); } DECLARE_REAL_AND_INTERCEPTOR(void, free, void *ptr) @@ -529,7 +545,7 @@ TSAN_INTERCEPTOR(dispatch_data_t, dispatch_data_create, const void *buffer, SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); dispatch_block_t heap_block = Block_copy(destructor); SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_END(); - tsan_block_context_t *new_context = + block_context_t *new_context = AllocContext(thr, pc, q, heap_block, &invoke_and_release_block); uptr submit_sync = (uptr)new_context; Release(thr, pc, submit_sync); @@ -544,7 +560,7 @@ typedef void (^cleanup_handler_t)(int error); TSAN_INTERCEPTOR(void, dispatch_read, dispatch_fd_t fd, size_t length, dispatch_queue_t q, fd_handler_t h) { SCOPED_TSAN_INTERCEPTOR(dispatch_read, fd, length, q, h); - __block tsan_block_context_t new_context = { + __block block_context_t new_context = { q, nullptr, &invoke_block, false, false, false, 0}; fd_handler_t new_h = Block_copy(^(dispatch_data_t data, int error) { new_context.orig_context = ^(void) { @@ -561,7 +577,7 @@ TSAN_INTERCEPTOR(void, dispatch_read, dispatch_fd_t fd, size_t length, TSAN_INTERCEPTOR(void, dispatch_write, dispatch_fd_t fd, dispatch_data_t data, dispatch_queue_t q, fd_handler_t h) { SCOPED_TSAN_INTERCEPTOR(dispatch_write, fd, data, q, h); - __block tsan_block_context_t new_context = { + __block block_context_t new_context = { q, nullptr, &invoke_block, false, false, false, 0}; fd_handler_t new_h = Block_copy(^(dispatch_data_t data, int error) { new_context.orig_context = ^(void) { @@ -578,7 +594,7 @@ TSAN_INTERCEPTOR(void, dispatch_write, dispatch_fd_t fd, dispatch_data_t data, TSAN_INTERCEPTOR(void, dispatch_io_read, dispatch_io_t channel, off_t offset, size_t length, dispatch_queue_t q, dispatch_io_handler_t h) { SCOPED_TSAN_INTERCEPTOR(dispatch_io_read, channel, offset, length, q, h); - __block tsan_block_context_t new_context = { + __block block_context_t new_context = { q, nullptr, &invoke_block, false, false, false, 0}; dispatch_io_handler_t new_h = Block_copy(^(bool done, dispatch_data_t data, int error) { @@ -597,7 +613,7 @@ TSAN_INTERCEPTOR(void, dispatch_io_write, dispatch_io_t channel, off_t offset, dispatch_data_t data, dispatch_queue_t q, dispatch_io_handler_t h) { SCOPED_TSAN_INTERCEPTOR(dispatch_io_write, channel, offset, data, q, h); - __block tsan_block_context_t new_context = { + __block block_context_t new_context = { q, nullptr, &invoke_block, false, false, false, 0}; dispatch_io_handler_t new_h = Block_copy(^(bool done, dispatch_data_t data, int error) { @@ -615,7 +631,7 @@ TSAN_INTERCEPTOR(void, dispatch_io_write, dispatch_io_t channel, off_t offset, TSAN_INTERCEPTOR(void, dispatch_io_barrier, dispatch_io_t channel, dispatch_block_t barrier) { SCOPED_TSAN_INTERCEPTOR(dispatch_io_barrier, channel, barrier); - __block tsan_block_context_t new_context = { + __block block_context_t new_context = { nullptr, nullptr, &invoke_block, false, false, false, 0}; new_context.non_queue_sync_object = (uptr)channel; new_context.is_barrier_block = true; @@ -635,7 +651,7 @@ TSAN_INTERCEPTOR(dispatch_io_t, dispatch_io_create, dispatch_io_type_t type, dispatch_fd_t fd, dispatch_queue_t q, cleanup_handler_t h) { SCOPED_TSAN_INTERCEPTOR(dispatch_io_create, type, fd, q, h); __block dispatch_io_t new_channel = nullptr; - __block tsan_block_context_t new_context = { + __block block_context_t new_context = { q, nullptr, &invoke_block, false, false, false, 0}; cleanup_handler_t new_h = Block_copy(^(int error) { { @@ -660,7 +676,7 @@ TSAN_INTERCEPTOR(dispatch_io_t, dispatch_io_create_with_path, SCOPED_TSAN_INTERCEPTOR(dispatch_io_create_with_path, type, path, oflag, mode, q, h); __block dispatch_io_t new_channel = nullptr; - __block tsan_block_context_t new_context = { + __block block_context_t new_context = { q, nullptr, &invoke_block, false, false, false, 0}; cleanup_handler_t new_h = Block_copy(^(int error) { { @@ -685,7 +701,7 @@ TSAN_INTERCEPTOR(dispatch_io_t, dispatch_io_create_with_io, cleanup_handler_t h) { SCOPED_TSAN_INTERCEPTOR(dispatch_io_create_with_io, type, io, q, h); __block dispatch_io_t new_channel = nullptr; - __block tsan_block_context_t new_context = { + __block block_context_t new_context = { q, nullptr, &invoke_block, false, false, false, 0}; cleanup_handler_t new_h = Block_copy(^(int error) { { @@ -720,6 +736,46 @@ TSAN_INTERCEPTOR(void, dispatch_resume, dispatch_object_t o) { return REAL(dispatch_resume)(o); } -} // namespace __tsan +void InitializeLibdispatchInterceptors() { + INTERCEPT_FUNCTION(dispatch_async); + INTERCEPT_FUNCTION(dispatch_async_f); + INTERCEPT_FUNCTION(dispatch_sync); + INTERCEPT_FUNCTION(dispatch_sync_f); + INTERCEPT_FUNCTION(dispatch_barrier_async); + INTERCEPT_FUNCTION(dispatch_barrier_async_f); + INTERCEPT_FUNCTION(dispatch_barrier_sync); + INTERCEPT_FUNCTION(dispatch_barrier_sync_f); + INTERCEPT_FUNCTION(dispatch_after); + INTERCEPT_FUNCTION(dispatch_after_f); + INTERCEPT_FUNCTION(dispatch_once); + INTERCEPT_FUNCTION(dispatch_once_f); + INTERCEPT_FUNCTION(dispatch_semaphore_signal); + INTERCEPT_FUNCTION(dispatch_semaphore_wait); + INTERCEPT_FUNCTION(dispatch_group_wait); + INTERCEPT_FUNCTION(dispatch_group_leave); + INTERCEPT_FUNCTION(dispatch_group_async); + INTERCEPT_FUNCTION(dispatch_group_async_f); + INTERCEPT_FUNCTION(dispatch_group_notify); + INTERCEPT_FUNCTION(dispatch_group_notify_f); + INTERCEPT_FUNCTION(dispatch_source_set_event_handler); + INTERCEPT_FUNCTION(dispatch_source_set_event_handler_f); + INTERCEPT_FUNCTION(dispatch_source_set_cancel_handler); + INTERCEPT_FUNCTION(dispatch_source_set_cancel_handler_f); + INTERCEPT_FUNCTION(dispatch_source_set_registration_handler); + INTERCEPT_FUNCTION(dispatch_source_set_registration_handler_f); + INTERCEPT_FUNCTION(dispatch_apply); + INTERCEPT_FUNCTION(dispatch_apply_f); + INTERCEPT_FUNCTION(dispatch_data_create); + INTERCEPT_FUNCTION(dispatch_read); + INTERCEPT_FUNCTION(dispatch_write); + INTERCEPT_FUNCTION(dispatch_io_read); + INTERCEPT_FUNCTION(dispatch_io_write); + INTERCEPT_FUNCTION(dispatch_io_barrier); + INTERCEPT_FUNCTION(dispatch_io_create); + INTERCEPT_FUNCTION(dispatch_io_create_with_path); + INTERCEPT_FUNCTION(dispatch_io_create_with_io); + INTERCEPT_FUNCTION(dispatch_io_close); + INTERCEPT_FUNCTION(dispatch_resume); +} -#endif // SANITIZER_MAC +} // namespace __tsan diff --git a/libsanitizer/tsan/tsan_malloc_mac.cc b/libsanitizer/tsan/tsan_malloc_mac.cpp similarity index 78% rename from libsanitizer/tsan/tsan_malloc_mac.cc rename to libsanitizer/tsan/tsan_malloc_mac.cpp index 618fa2d6702..0e861bf1f96 100644 --- a/libsanitizer/tsan/tsan_malloc_mac.cc +++ b/libsanitizer/tsan/tsan_malloc_mac.cpp @@ -1,7 +1,8 @@ -//===-- tsan_malloc_mac.cc ------------------------------------------------===// +//===-- tsan_malloc_mac.cpp -----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -27,19 +28,19 @@ using namespace __tsan; void *p = \ user_memalign(cur_thread(), StackTrace::GetCurrentPc(), alignment, size) #define COMMON_MALLOC_MALLOC(size) \ - if (cur_thread()->in_symbolizer) return InternalAlloc(size); \ + if (in_symbolizer()) return InternalAlloc(size); \ SCOPED_INTERCEPTOR_RAW(malloc, size); \ void *p = user_alloc(thr, pc, size) #define COMMON_MALLOC_REALLOC(ptr, size) \ - if (cur_thread()->in_symbolizer) return InternalRealloc(ptr, size); \ + if (in_symbolizer()) return InternalRealloc(ptr, size); \ SCOPED_INTERCEPTOR_RAW(realloc, ptr, size); \ void *p = user_realloc(thr, pc, ptr, size) #define COMMON_MALLOC_CALLOC(count, size) \ - if (cur_thread()->in_symbolizer) return InternalCalloc(count, size); \ + if (in_symbolizer()) return InternalCalloc(count, size); \ SCOPED_INTERCEPTOR_RAW(calloc, size, count); \ void *p = user_calloc(thr, pc, size, count) #define COMMON_MALLOC_POSIX_MEMALIGN(memptr, alignment, size) \ - if (cur_thread()->in_symbolizer) { \ + if (in_symbolizer()) { \ void *p = InternalAlloc(size, nullptr, alignment); \ if (!p) return errno_ENOMEM; \ *memptr = p; \ @@ -48,12 +49,12 @@ using namespace __tsan; SCOPED_INTERCEPTOR_RAW(posix_memalign, memptr, alignment, size); \ int res = user_posix_memalign(thr, pc, memptr, alignment, size); #define COMMON_MALLOC_VALLOC(size) \ - if (cur_thread()->in_symbolizer) \ + if (in_symbolizer()) \ return InternalAlloc(size, nullptr, GetPageSizeCached()); \ SCOPED_INTERCEPTOR_RAW(valloc, size); \ void *p = user_valloc(thr, pc, size) #define COMMON_MALLOC_FREE(ptr) \ - if (cur_thread()->in_symbolizer) return InternalFree(ptr); \ + if (in_symbolizer()) return InternalFree(ptr); \ SCOPED_INTERCEPTOR_RAW(free, ptr); \ user_free(thr, pc, ptr) #define COMMON_MALLOC_SIZE(ptr) uptr size = user_alloc_usable_size(ptr); @@ -62,6 +63,8 @@ using namespace __tsan; (void)zone_name; \ Report("mz_realloc(%p) -- attempting to realloc unallocated memory.\n", ptr); #define COMMON_MALLOC_NAMESPACE __tsan +#define COMMON_MALLOC_HAS_ZONE_ENUMERATOR 0 +#define COMMON_MALLOC_HAS_EXTRA_INTROSPECTION_INIT 0 #include "sanitizer_common/sanitizer_malloc_mac.inc" diff --git a/libsanitizer/tsan/tsan_md5.cc b/libsanitizer/tsan/tsan_md5.cpp similarity index 95% rename from libsanitizer/tsan/tsan_md5.cc rename to libsanitizer/tsan/tsan_md5.cpp index f299dfc59b6..d146e1cc35f 100644 --- a/libsanitizer/tsan/tsan_md5.cc +++ b/libsanitizer/tsan/tsan_md5.cpp @@ -1,7 +1,8 @@ -//===-- tsan_md5.cc -------------------------------------------------------===// +//===-- tsan_md5.cpp ------------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -137,6 +138,14 @@ static const void *body(MD5_CTX *ctx, const void *data, ulong_t size) { return ptr; } +#undef F +#undef G +#undef H +#undef I +#undef STEP +#undef SET +#undef GET + void MD5_Init(MD5_CTX *ctx) { ctx->a = 0x67452301; ctx->b = 0xefcdab89; diff --git a/libsanitizer/tsan/tsan_mman.cc b/libsanitizer/tsan/tsan_mman.cpp similarity index 94% rename from libsanitizer/tsan/tsan_mman.cc rename to libsanitizer/tsan/tsan_mman.cpp index 76d12a43b27..1b2c0549d39 100644 --- a/libsanitizer/tsan/tsan_mman.cc +++ b/libsanitizer/tsan/tsan_mman.cpp @@ -1,7 +1,8 @@ -//===-- tsan_mman.cc ------------------------------------------------------===// +//===-- tsan_mman.cpp -----------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -200,6 +201,16 @@ void *user_calloc(ThreadState *thr, uptr pc, uptr size, uptr n) { return SetErrnoOnNull(p); } +void *user_reallocarray(ThreadState *thr, uptr pc, void *p, uptr size, uptr n) { + if (UNLIKELY(CheckForCallocOverflow(size, n))) { + if (AllocatorMayReturnNull()) + return SetErrnoOnNull(nullptr); + GET_STACK_TRACE_FATAL(thr, pc); + ReportReallocArrayOverflow(size, n, &stack); + } + return user_realloc(thr, pc, p, size * n); +} + void OnUserAlloc(ThreadState *thr, uptr pc, uptr p, uptr sz, bool write) { DPrintf("#%d: alloc(%zu) = %p\n", thr->tid, sz, p); ctx->metamap.AllocBlock(thr, pc, p, sz); diff --git a/libsanitizer/tsan/tsan_mman.h b/libsanitizer/tsan/tsan_mman.h index 3443cb0d8f9..467aabdf2b9 100644 --- a/libsanitizer/tsan/tsan_mman.h +++ b/libsanitizer/tsan/tsan_mman.h @@ -1,7 +1,8 @@ //===-- tsan_mman.h ---------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -33,6 +34,7 @@ void user_free(ThreadState *thr, uptr pc, void *p, bool signal = true); void *user_alloc(ThreadState *thr, uptr pc, uptr sz); void *user_calloc(ThreadState *thr, uptr pc, uptr sz, uptr n); void *user_realloc(ThreadState *thr, uptr pc, void *p, uptr sz); +void *user_reallocarray(ThreadState *thr, uptr pc, void *p, uptr sz, uptr n); void *user_memalign(ThreadState *thr, uptr pc, uptr align, uptr sz); int user_posix_memalign(ThreadState *thr, uptr pc, void **memptr, uptr align, uptr sz); diff --git a/libsanitizer/tsan/tsan_mutex.cc b/libsanitizer/tsan/tsan_mutex.cpp similarity index 96% rename from libsanitizer/tsan/tsan_mutex.cc rename to libsanitizer/tsan/tsan_mutex.cpp index 9b105cf201b..7a0918f2a2c 100644 --- a/libsanitizer/tsan/tsan_mutex.cc +++ b/libsanitizer/tsan/tsan_mutex.cpp @@ -1,7 +1,8 @@ -//===-- tsan_mutex.cc -----------------------------------------------------===// +//===-- tsan_mutex.cpp ----------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_mutex.h b/libsanitizer/tsan/tsan_mutex.h index bd1000f0b29..80fdc6ed57b 100644 --- a/libsanitizer/tsan/tsan_mutex.h +++ b/libsanitizer/tsan/tsan_mutex.h @@ -1,7 +1,8 @@ //===-- tsan_mutex.h --------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_mutexset.cc b/libsanitizer/tsan/tsan_mutexset.cpp similarity index 87% rename from libsanitizer/tsan/tsan_mutexset.cc rename to libsanitizer/tsan/tsan_mutexset.cpp index 3ebae3a57bc..813fa3bca93 100644 --- a/libsanitizer/tsan/tsan_mutexset.cc +++ b/libsanitizer/tsan/tsan_mutexset.cpp @@ -1,7 +1,8 @@ -//===-- tsan_mutexset.cc --------------------------------------------------===// +//===-- tsan_mutexset.cpp -------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_mutexset.h b/libsanitizer/tsan/tsan_mutexset.h index b2c60b9a826..d63881f4029 100644 --- a/libsanitizer/tsan/tsan_mutexset.h +++ b/libsanitizer/tsan/tsan_mutexset.h @@ -1,7 +1,8 @@ //===-- tsan_mutexset.h -----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_new_delete.cc b/libsanitizer/tsan/tsan_new_delete.cpp similarity index 95% rename from libsanitizer/tsan/tsan_new_delete.cc rename to libsanitizer/tsan/tsan_new_delete.cpp index 1346aa7a4e6..3ed3c847a9a 100644 --- a/libsanitizer/tsan/tsan_new_delete.cc +++ b/libsanitizer/tsan/tsan_new_delete.cpp @@ -1,7 +1,8 @@ -//===-- tsan_new_delete.cc ----------------------------------------------===// +//===-- tsan_new_delete.cpp ---------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -28,7 +29,7 @@ DECLARE_REAL(void, free, void *ptr) // TODO(alekseys): throw std::bad_alloc instead of dying on OOM. #define OPERATOR_NEW_BODY(mangled_name, nothrow) \ - if (cur_thread()->in_symbolizer) \ + if (in_symbolizer()) \ return InternalAlloc(size); \ void *p = 0; \ { \ @@ -43,7 +44,7 @@ DECLARE_REAL(void, free, void *ptr) return p; #define OPERATOR_NEW_BODY_ALIGN(mangled_name, nothrow) \ - if (cur_thread()->in_symbolizer) \ + if (in_symbolizer()) \ return InternalAlloc(size, nullptr, (uptr)align); \ void *p = 0; \ { \ @@ -113,7 +114,7 @@ void *operator new[](__sanitizer::uptr size, std::align_val_t align, #define OPERATOR_DELETE_BODY(mangled_name) \ if (ptr == 0) return; \ - if (cur_thread()->in_symbolizer) \ + if (in_symbolizer()) \ return InternalFree(ptr); \ invoke_free_hook(ptr); \ SCOPED_INTERCEPTOR_RAW(mangled_name, ptr); \ diff --git a/libsanitizer/tsan/tsan_platform.h b/libsanitizer/tsan/tsan_platform.h index 871df468b65..0d106c4147c 100644 --- a/libsanitizer/tsan/tsan_platform.h +++ b/libsanitizer/tsan/tsan_platform.h @@ -1,7 +1,8 @@ //===-- tsan_platform.h -----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -1010,6 +1011,7 @@ void FlushShadowMemory(); void WriteMemoryProfile(char *buf, uptr buf_size, uptr nthread, uptr nlive); int ExtractResolvFDs(void *state, int *fds, int nfd); int ExtractRecvmsgFDs(void *msg, int *fds, int nfd); +uptr ExtractLongJmpSp(uptr *env); void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size); int call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m, diff --git a/libsanitizer/tsan/tsan_platform_linux.cc b/libsanitizer/tsan/tsan_platform_linux.cpp similarity index 82% rename from libsanitizer/tsan/tsan_platform_linux.cc rename to libsanitizer/tsan/tsan_platform_linux.cpp index 9b4dea20659..33fa586ca1b 100644 --- a/libsanitizer/tsan/tsan_platform_linux.cc +++ b/libsanitizer/tsan/tsan_platform_linux.cpp @@ -1,7 +1,8 @@ -//===-- tsan_platform_linux.cc --------------------------------------------===// +//===-- tsan_platform_linux.cpp -------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -66,12 +67,25 @@ extern "C" void *__libc_stack_end; void *__libc_stack_end = 0; #endif -#if SANITIZER_LINUX && defined(__aarch64__) -void InitializeGuardPtr() __attribute__((visibility("hidden"))); +#if SANITIZER_LINUX && defined(__aarch64__) && !SANITIZER_GO +# define INIT_LONGJMP_XOR_KEY 1 +#else +# define INIT_LONGJMP_XOR_KEY 0 +#endif + +#if INIT_LONGJMP_XOR_KEY +#include "interception/interception.h" +// Must be declared outside of other namespaces. +DECLARE_REAL(int, _setjmp, void *env) #endif namespace __tsan { +#if INIT_LONGJMP_XOR_KEY +static void InitializeLongjmpXorKey(); +static uptr longjmp_xor_key; +#endif + #ifdef TSAN_RUNTIME_VMA // Runtime detected VMA size. uptr vmaSize; @@ -247,7 +261,8 @@ void InitializePlatform() { // Go maps shadow memory lazily and works fine with limited address space. // Unlimited stack is not a problem as well, because the executable // is not compiled with -pie. - if (!SANITIZER_GO) { +#if !SANITIZER_GO + { bool reexec = false; // TSan doesn't play well with unlimited stack size (as stack // overlaps with shadow memory). If we detect unlimited stack size, @@ -282,17 +297,16 @@ void InitializePlatform() { CHECK_NE(personality(old_personality | ADDR_NO_RANDOMIZE), -1); reexec = true; } - // Initialize the guard pointer used in {sig}{set,long}jump. - InitializeGuardPtr(); + // Initialize the xor key used in {sig}{set,long}jump. + InitializeLongjmpXorKey(); #endif if (reexec) ReExec(); } -#if !SANITIZER_GO CheckAndProtect(); InitTlsSize(); -#endif +#endif // !SANITIZER_GO } #if !SANITIZER_GO @@ -333,6 +347,83 @@ int ExtractRecvmsgFDs(void *msgp, int *fds, int nfd) { return res; } +// Reverse operation of libc stack pointer mangling +static uptr UnmangleLongJmpSp(uptr mangled_sp) { +#if defined(__x86_64__) +# if SANITIZER_LINUX + // Reverse of: + // xor %fs:0x30, %rsi + // rol $0x11, %rsi + uptr sp; + asm("ror $0x11, %0 \n" + "xor %%fs:0x30, %0 \n" + : "=r" (sp) + : "0" (mangled_sp)); + return sp; +# else + return mangled_sp; +# endif +#elif defined(__aarch64__) +# if SANITIZER_LINUX + return mangled_sp ^ longjmp_xor_key; +# else + return mangled_sp; +# endif +#elif defined(__powerpc64__) + // Reverse of: + // ld r4, -28696(r13) + // xor r4, r3, r4 + uptr xor_key; + asm("ld %0, -28696(%%r13)" : "=r" (xor_key)); + return mangled_sp ^ xor_key; +#elif defined(__mips__) + return mangled_sp; +#else + #error "Unknown platform" +#endif +} + +#ifdef __powerpc__ +# define LONG_JMP_SP_ENV_SLOT 0 +#elif SANITIZER_FREEBSD +# define LONG_JMP_SP_ENV_SLOT 2 +#elif SANITIZER_NETBSD +# define LONG_JMP_SP_ENV_SLOT 6 +#elif SANITIZER_LINUX +# ifdef __aarch64__ +# define LONG_JMP_SP_ENV_SLOT 13 +# elif defined(__mips64) +# define LONG_JMP_SP_ENV_SLOT 1 +# else +# define LONG_JMP_SP_ENV_SLOT 6 +# endif +#endif + +uptr ExtractLongJmpSp(uptr *env) { + uptr mangled_sp = env[LONG_JMP_SP_ENV_SLOT]; + return UnmangleLongJmpSp(mangled_sp); +} + +#if INIT_LONGJMP_XOR_KEY +// GLIBC mangles the function pointers in jmp_buf (used in {set,long}*jmp +// functions) by XORing them with a random key. For AArch64 it is a global +// variable rather than a TCB one (as for x86_64/powerpc). We obtain the key by +// issuing a setjmp and XORing the SP pointer values to derive the key. +static void InitializeLongjmpXorKey() { + // 1. Call REAL(setjmp), which stores the mangled SP in env. + jmp_buf env; + REAL(_setjmp)(env); + + // 2. Retrieve vanilla/mangled SP. + uptr sp; + asm("mov %0, sp" : "=r" (sp)); + uptr mangled_sp = ((uptr *)&env)[LONG_JMP_SP_ENV_SLOT]; + + // 3. xor SPs to obtain key. + longjmp_xor_key = mangled_sp ^ sp; +} +#endif + void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size) { // Check that the thr object is in tls; const uptr thr_beg = (uptr)thr; @@ -360,7 +451,7 @@ int call_pthread_cancel_with_cleanup(int(*fn)(void *c, void *m, pthread_cleanup_pop(0); return res; } -#endif +#endif // !SANITIZER_GO #if !SANITIZER_GO void ReplaceSystemMalloc() { } @@ -400,6 +491,10 @@ ThreadState *cur_thread() { return thr; } +void set_cur_thread(ThreadState *thr) { + *get_android_tls_ptr() = reinterpret_cast(thr); +} + void cur_thread_finalize() { __sanitizer_sigset_t emptyset; internal_sigfillset(&emptyset); diff --git a/libsanitizer/tsan/tsan_platform_mac.cc b/libsanitizer/tsan/tsan_platform_mac.cpp similarity index 85% rename from libsanitizer/tsan/tsan_platform_mac.cc rename to libsanitizer/tsan/tsan_platform_mac.cpp index 14395ba614a..326ca8532e5 100644 --- a/libsanitizer/tsan/tsan_platform_mac.cc +++ b/libsanitizer/tsan/tsan_platform_mac.cpp @@ -1,7 +1,8 @@ -//===-- tsan_platform_mac.cc ----------------------------------------------===// +//===-- tsan_platform_mac.cpp ---------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -72,22 +73,22 @@ static void *SignalSafeGetOrAllocate(uptr *dst, uptr size) { // shadow memory is set up. static uptr main_thread_identity = 0; ALIGNED(64) static char main_thread_state[sizeof(ThreadState)]; +static ThreadState *main_thread_state_loc = (ThreadState *)main_thread_state; -ThreadState **cur_thread_location() { - ThreadState **thread_identity = (ThreadState **)pthread_self(); - return ((uptr)thread_identity == main_thread_identity) ? nullptr - : thread_identity; +static ThreadState **cur_thread_location() { + uptr thread_identity = (uptr)pthread_self(); + if (thread_identity == main_thread_identity || main_thread_identity == 0) + return &main_thread_state_loc; + return (ThreadState **)MemToShadow(thread_identity); } ThreadState *cur_thread() { - ThreadState **thr_state_loc = cur_thread_location(); - if (thr_state_loc == nullptr || main_thread_identity == 0) { - return (ThreadState *)&main_thread_state; - } - ThreadState **fake_tls = (ThreadState **)MemToShadow((uptr)thr_state_loc); - ThreadState *thr = (ThreadState *)SignalSafeGetOrAllocate( - (uptr *)fake_tls, sizeof(ThreadState)); - return thr; + return (ThreadState *)SignalSafeGetOrAllocate( + (uptr *)cur_thread_location(), sizeof(ThreadState)); +} + +void set_cur_thread(ThreadState *thr) { + *cur_thread_location() = thr; } // TODO(kuba.brecka): This is not async-signal-safe. In particular, we call @@ -95,14 +96,13 @@ ThreadState *cur_thread() { // handler will try to access the unmapped ThreadState. void cur_thread_finalize() { ThreadState **thr_state_loc = cur_thread_location(); - if (thr_state_loc == nullptr) { + if (thr_state_loc == &main_thread_state_loc) { // Calling dispatch_main() or xpc_main() actually invokes pthread_exit to // exit the main thread. Let's keep the main thread's ThreadState. return; } - ThreadState **fake_tls = (ThreadState **)MemToShadow((uptr)thr_state_loc); - internal_munmap(*fake_tls, sizeof(ThreadState)); - *fake_tls = nullptr; + internal_munmap(*thr_state_loc, sizeof(ThreadState)); + *thr_state_loc = nullptr; } #endif @@ -211,7 +211,7 @@ static void my_pthread_introspection_hook(unsigned int event, pthread_t thread, ThreadState *parent_thread_state = nullptr; // No parent. int tid = ThreadCreate(parent_thread_state, 0, (uptr)thread, true); CHECK_NE(tid, 0); - ThreadStart(thr, tid, GetTid(), /*workerthread*/ true); + ThreadStart(thr, tid, GetTid(), ThreadType::Worker); } } else if (event == PTHREAD_INTROSPECTION_THREAD_TERMINATE) { if (thread == pthread_self()) { @@ -238,8 +238,7 @@ void InitializePlatformEarly() { #endif } -static const uptr kPthreadSetjmpXorKeySlot = 0x7; -extern "C" uptr __tsan_darwin_setjmp_xor_key = 0; +static uptr longjmp_xor_key = 0; void InitializePlatform() { DisableCoreDumperIfNecessary(); @@ -254,21 +253,35 @@ void InitializePlatform() { #endif if (GetMacosVersion() >= MACOS_VERSION_MOJAVE) { - __tsan_darwin_setjmp_xor_key = - (uptr)pthread_getspecific(kPthreadSetjmpXorKeySlot); + // Libsystem currently uses a process-global key; this might change. + const unsigned kTLSLongjmpXorKeySlot = 0x7; + longjmp_xor_key = (uptr)pthread_getspecific(kTLSLongjmpXorKeySlot); } } +#ifdef __aarch64__ +# define LONG_JMP_SP_ENV_SLOT \ + ((GetMacosVersion() >= MACOS_VERSION_MOJAVE) ? 12 : 13) +#else +# define LONG_JMP_SP_ENV_SLOT 2 +#endif + +uptr ExtractLongJmpSp(uptr *env) { + uptr mangled_sp = env[LONG_JMP_SP_ENV_SLOT]; + uptr sp = mangled_sp ^ longjmp_xor_key; + return sp; +} + #if !SANITIZER_GO void ImitateTlsWrite(ThreadState *thr, uptr tls_addr, uptr tls_size) { // The pointer to the ThreadState object is stored in the shadow memory // of the tls. uptr tls_end = tls_addr + tls_size; - ThreadState **thr_state_loc = cur_thread_location(); - if (thr_state_loc == nullptr) { + uptr thread_identity = (uptr)pthread_self(); + if (thread_identity == main_thread_identity) { MemoryRangeImitateWrite(thr, /*pc=*/2, tls_addr, tls_size); } else { - uptr thr_state_start = (uptr)thr_state_loc; + uptr thr_state_start = thread_identity; uptr thr_state_end = thr_state_start + sizeof(uptr); CHECK_GE(thr_state_start, tls_addr); CHECK_LE(thr_state_start, tls_addr + tls_size); diff --git a/libsanitizer/tsan/tsan_platform_posix.cc b/libsanitizer/tsan/tsan_platform_posix.cpp similarity index 91% rename from libsanitizer/tsan/tsan_platform_posix.cc rename to libsanitizer/tsan/tsan_platform_posix.cpp index df9b6d41828..1a0faee0252 100644 --- a/libsanitizer/tsan/tsan_platform_posix.cc +++ b/libsanitizer/tsan/tsan_platform_posix.cpp @@ -1,7 +1,8 @@ -//===-- tsan_platform_posix.cc --------------------------------------------===// +//===-- tsan_platform_posix.cpp -------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -29,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/libsanitizer/tsan/tsan_platform_windows.cc b/libsanitizer/tsan/tsan_platform_windows.cpp similarity index 71% rename from libsanitizer/tsan/tsan_platform_windows.cc rename to libsanitizer/tsan/tsan_platform_windows.cpp index 76883caabf1..19437879a41 100644 --- a/libsanitizer/tsan/tsan_platform_windows.cc +++ b/libsanitizer/tsan/tsan_platform_windows.cpp @@ -1,7 +1,8 @@ -//===-- tsan_platform_windows.cc ------------------------------------------===// +//===-- tsan_platform_windows.cpp -----------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_preinit.cc b/libsanitizer/tsan/tsan_preinit.cpp similarity index 74% rename from libsanitizer/tsan/tsan_preinit.cc rename to libsanitizer/tsan/tsan_preinit.cpp index d5d1659c09b..205bdbf93b2 100644 --- a/libsanitizer/tsan/tsan_preinit.cc +++ b/libsanitizer/tsan/tsan_preinit.cpp @@ -1,7 +1,8 @@ -//===-- tsan_preinit.cc ---------------------------------------------------===// +//===-- tsan_preinit.cpp --------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_report.cc b/libsanitizer/tsan/tsan_report.cpp similarity index 88% rename from libsanitizer/tsan/tsan_report.cc rename to libsanitizer/tsan/tsan_report.cpp index 4dffc342a92..655aa5f9123 100644 --- a/libsanitizer/tsan/tsan_report.cc +++ b/libsanitizer/tsan/tsan_report.cpp @@ -1,7 +1,8 @@ -//===-- tsan_report.cc ----------------------------------------------------===// +//===-- tsan_report.cpp ---------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -75,39 +76,42 @@ const char *thread_name(char *buf, int tid) { } static const char *ReportTypeString(ReportType typ, uptr tag) { - if (typ == ReportTypeRace) - return "data race"; - if (typ == ReportTypeVptrRace) - return "data race on vptr (ctor/dtor vs virtual call)"; - if (typ == ReportTypeUseAfterFree) - return "heap-use-after-free"; - if (typ == ReportTypeVptrUseAfterFree) - return "heap-use-after-free (virtual call vs free)"; - if (typ == ReportTypeExternalRace) { - const char *str = GetReportHeaderFromTag(tag); - return str ? str : "race on external object"; + switch (typ) { + case ReportTypeRace: + return "data race"; + case ReportTypeVptrRace: + return "data race on vptr (ctor/dtor vs virtual call)"; + case ReportTypeUseAfterFree: + return "heap-use-after-free"; + case ReportTypeVptrUseAfterFree: + return "heap-use-after-free (virtual call vs free)"; + case ReportTypeExternalRace: { + const char *str = GetReportHeaderFromTag(tag); + return str ? str : "race on external object"; + } + case ReportTypeThreadLeak: + return "thread leak"; + case ReportTypeMutexDestroyLocked: + return "destroy of a locked mutex"; + case ReportTypeMutexDoubleLock: + return "double lock of a mutex"; + case ReportTypeMutexInvalidAccess: + return "use of an invalid mutex (e.g. uninitialized or destroyed)"; + case ReportTypeMutexBadUnlock: + return "unlock of an unlocked mutex (or by a wrong thread)"; + case ReportTypeMutexBadReadLock: + return "read lock of a write locked mutex"; + case ReportTypeMutexBadReadUnlock: + return "read unlock of a write locked mutex"; + case ReportTypeSignalUnsafe: + return "signal-unsafe call inside of a signal"; + case ReportTypeErrnoInSignal: + return "signal handler spoils errno"; + case ReportTypeDeadlock: + return "lock-order-inversion (potential deadlock)"; + // No default case so compiler warns us if we miss one } - if (typ == ReportTypeThreadLeak) - return "thread leak"; - if (typ == ReportTypeMutexDestroyLocked) - return "destroy of a locked mutex"; - if (typ == ReportTypeMutexDoubleLock) - return "double lock of a mutex"; - if (typ == ReportTypeMutexInvalidAccess) - return "use of an invalid mutex (e.g. uninitialized or destroyed)"; - if (typ == ReportTypeMutexBadUnlock) - return "unlock of an unlocked mutex (or by a wrong thread)"; - if (typ == ReportTypeMutexBadReadLock) - return "read lock of a write locked mutex"; - if (typ == ReportTypeMutexBadReadUnlock) - return "read unlock of a write locked mutex"; - if (typ == ReportTypeSignalUnsafe) - return "signal-unsafe call inside of a signal"; - if (typ == ReportTypeErrnoInSignal) - return "signal handler spoils errno"; - if (typ == ReportTypeDeadlock) - return "lock-order-inversion (potential deadlock)"; - return ""; + UNREACHABLE("missing case"); } #if SANITIZER_MAC @@ -253,7 +257,7 @@ static void PrintThread(const ReportThread *rt) { Printf(" '%s'", rt->name); char thrbuf[kThreadBufSize]; const char *thread_status = rt->running ? "running" : "finished"; - if (rt->workerthread) { + if (rt->thread_type == ThreadType::Worker) { Printf(" (tid=%zu, %s) is a GCD worker thread\n", rt->os_id, thread_status); Printf("\n"); Printf("%s", d.Default()); @@ -294,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.cpp") || internal_strstr(file, "sanitizer_common_interceptors.inc") || internal_strstr(file, "tsan_interface_"))) return true; diff --git a/libsanitizer/tsan/tsan_report.h b/libsanitizer/tsan/tsan_report.h index 8e96e975804..b4e4d898937 100644 --- a/libsanitizer/tsan/tsan_report.h +++ b/libsanitizer/tsan/tsan_report.h @@ -1,7 +1,8 @@ //===-- tsan_report.h -------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -12,6 +13,7 @@ #define TSAN_REPORT_H #include "sanitizer_common/sanitizer_symbolizer.h" +#include "sanitizer_common/sanitizer_thread_registry.h" #include "sanitizer_common/sanitizer_vector.h" #include "tsan_defs.h" @@ -90,7 +92,7 @@ struct ReportThread { int id; tid_t os_id; bool running; - bool workerthread; + ThreadType thread_type; char *name; u32 parent_tid; ReportStack *stack; diff --git a/libsanitizer/tsan/tsan_rtl.cc b/libsanitizer/tsan/tsan_rtl.cpp similarity index 96% rename from libsanitizer/tsan/tsan_rtl.cc rename to libsanitizer/tsan/tsan_rtl.cpp index bd0892d0de5..1ac3907094b 100644 --- a/libsanitizer/tsan/tsan_rtl.cc +++ b/libsanitizer/tsan/tsan_rtl.cpp @@ -1,7 +1,8 @@ -//===-- tsan_rtl.cc -------------------------------------------------------===// +//===-- tsan_rtl.cpp ------------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -148,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; @@ -327,11 +329,8 @@ static void CheckShadowMapping() { #if !SANITIZER_GO static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { - uptr top = 0; - uptr bottom = 0; - bool fast = common_flags()->fast_unwind_on_fatal; - if (fast) GetThreadStackTopAndBottom(false, &top, &bottom); - stack->Unwind(kStackTraceMax, sig.pc, sig.bp, sig.context, top, bottom, fast); + stack->Unwind(sig.pc, sig.bp, sig.context, + common_flags()->fast_unwind_on_fatal); } static void TsanOnDeadlySignal(int signo, void *siginfo, void *context) { @@ -352,12 +351,15 @@ void Initialize(ThreadState *thr) { SetCheckFailedCallback(TsanCheckFailed); ctx = new(ctx_placeholder) Context; - const char *options = GetEnv(SANITIZER_GO ? "GORACE" : "TSAN_OPTIONS"); + const char *env_name = SANITIZER_GO ? "GORACE" : "TSAN_OPTIONS"; + const char *options = GetEnv(env_name); CacheBinaryName(); CheckASLR(); - InitializeFlags(&ctx->flags, options); + InitializeFlags(&ctx->flags, options, env_name); AvoidCVE_2016_2143(); - InitializePlatformEarly(); + __sanitizer::InitializePlatformEarly(); + __tsan::InitializePlatformEarly(); + #if !SANITIZER_GO // Re-exec ourselves if we need to set additional env or command line args. MaybeReexec(); @@ -393,7 +395,7 @@ void Initialize(ThreadState *thr) { // Initialize thread 0. int tid = ThreadCreate(thr, 0, 0, true); CHECK_EQ(tid, 0); - ThreadStart(thr, tid, GetTid(), /*workerthread*/ false); + ThreadStart(thr, tid, GetTid(), ThreadType::Regular); #if TSAN_CONTAINS_UBSAN __ubsan::InitAsPlugin(); #endif @@ -638,6 +640,7 @@ void MemoryAccessImpl1(ThreadState *thr, uptr addr, // __m128i _mm_move_epi64(__m128i*); // _mm_storel_epi64(u64*, __m128i); u64 store_word = cur.raw(); + bool stored = false; // scan all the shadow values and dispatch to 4 categories: // same, replace, candidate and race (see comments below). @@ -662,16 +665,28 @@ void MemoryAccessImpl1(ThreadState *thr, uptr addr, int idx = 0; #include "tsan_update_shadow_word_inl.h" idx = 1; + if (stored) { +#include "tsan_update_shadow_word_inl.h" + } else { #include "tsan_update_shadow_word_inl.h" + } idx = 2; + if (stored) { +#include "tsan_update_shadow_word_inl.h" + } else { #include "tsan_update_shadow_word_inl.h" + } idx = 3; + if (stored) { #include "tsan_update_shadow_word_inl.h" + } else { +#include "tsan_update_shadow_word_inl.h" + } #endif // we did not find any races and had already stored // the current access info, so we are done - if (LIKELY(store_word == 0)) + if (LIKELY(stored)) return; // choose a random candidate slot and replace it StoreShadow(shadow_mem + (cur.epoch() % kShadowCnt), store_word); @@ -811,7 +826,7 @@ void MemoryAccess(ThreadState *thr, uptr pc, uptr addr, } #endif - if (!SANITIZER_GO && *shadow_mem == kShadowRodata) { + if (!SANITIZER_GO && !kAccessIsWrite && *shadow_mem == kShadowRodata) { // Access to .rodata section, no races here. // Measurements show that it can be 10-20% of all memory accesses. StatInc(thr, StatMop); @@ -822,7 +837,7 @@ void MemoryAccess(ThreadState *thr, uptr pc, uptr addr, } FastState fast_state = thr->fast_state; - if (fast_state.GetIgnoreBit()) { + if (UNLIKELY(fast_state.GetIgnoreBit())) { StatInc(thr, StatMop); StatInc(thr, kAccessIsWrite ? StatMopWrite : StatMopRead); StatInc(thr, (StatType)(StatMop1 + kAccessSizeLog)); @@ -855,7 +870,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, diff --git a/libsanitizer/tsan/tsan_rtl.h b/libsanitizer/tsan/tsan_rtl.h index f97b583c48b..3a8231bda9a 100644 --- a/libsanitizer/tsan/tsan_rtl.h +++ b/libsanitizer/tsan/tsan_rtl.h @@ -1,7 +1,8 @@ //===-- tsan_rtl.h ----------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -54,18 +55,14 @@ namespace __tsan { #if !SANITIZER_GO struct MapUnmapCallback; #if defined(__mips64) || defined(__aarch64__) || defined(__powerpc__) -static const uptr kAllocatorRegionSizeLog = 20; -static const uptr kAllocatorNumRegions = - SANITIZER_MMAP_RANGE_SIZE >> kAllocatorRegionSizeLog; -typedef TwoLevelByteMap<(kAllocatorNumRegions >> 12), 1 << 12, - MapUnmapCallback> ByteMap; + struct AP32 { static const uptr kSpaceBeg = 0; static const u64 kSpaceSize = SANITIZER_MMAP_RANGE_SIZE; static const uptr kMetadataSize = 0; typedef __sanitizer::CompactSizeClassMap SizeClassMap; - static const uptr kRegionSizeLog = kAllocatorRegionSizeLog; - typedef __tsan::ByteMap ByteMap; + static const uptr kRegionSizeLog = 20; + using AddressSpaceView = LocalAddressSpaceView; typedef __tsan::MapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; }; @@ -78,13 +75,12 @@ struct AP64 { // Allocator64 parameters. Deliberately using a short name. typedef DefaultSizeClassMap SizeClassMap; typedef __tsan::MapUnmapCallback MapUnmapCallback; static const uptr kFlags = 0; + using AddressSpaceView = LocalAddressSpaceView; }; typedef SizeClassAllocator64 PrimaryAllocator; #endif -typedef SizeClassAllocatorLocalCache AllocatorCache; -typedef LargeMmapAllocator SecondaryAllocator; -typedef CombinedAllocator Allocator; +typedef CombinedAllocator Allocator; +typedef Allocator::AllocatorCache AllocatorCache; Allocator *allocator(); #endif @@ -329,7 +325,6 @@ struct ThreadSignalContext; struct JmpBuf { uptr sp; - uptr mangled_sp; int int_signal_send; bool in_blocking_func; uptr in_signal_handler; @@ -381,6 +376,9 @@ struct ThreadState { // taken by epoch between synchs. // This way we can save one load from tls. u64 fast_synch_epoch; + // Technically `current` should be a separate THREADLOCAL variable; + // but it is placed here in order to share cache line with previous fields. + ThreadState* current; // This is a slow path flag. On fast path, fast_state.GetIgnoreBit() is read. // We do not distinguish beteween ignoring reads and writes // for better performance. @@ -458,12 +456,22 @@ struct ThreadState { #if !SANITIZER_GO #if SANITIZER_MAC || SANITIZER_ANDROID ThreadState *cur_thread(); +void set_cur_thread(ThreadState *thr); void cur_thread_finalize(); +INLINE void cur_thread_init() { } #else __attribute__((tls_model("initial-exec"))) extern THREADLOCAL char cur_thread_placeholder[]; INLINE ThreadState *cur_thread() { - return reinterpret_cast(&cur_thread_placeholder); + return reinterpret_cast(cur_thread_placeholder)->current; +} +INLINE void cur_thread_init() { + ThreadState *thr = reinterpret_cast(cur_thread_placeholder); + if (UNLIKELY(!thr->current)) + thr->current = thr; +} +INLINE void set_cur_thread(ThreadState *thr) { + reinterpret_cast(cur_thread_placeholder)->current = thr; } INLINE void cur_thread_finalize() { } #endif // SANITIZER_MAC || SANITIZER_ANDROID @@ -761,7 +769,8 @@ void FuncEntry(ThreadState *thr, uptr pc); void FuncExit(ThreadState *thr); int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached); -void ThreadStart(ThreadState *thr, int tid, tid_t os_id, bool workerthread); +void ThreadStart(ThreadState *thr, int tid, tid_t os_id, + ThreadType thread_type); void ThreadFinish(ThreadState *thr); int ThreadTid(ThreadState *thr, uptr pc, uptr uid); void ThreadJoin(ThreadState *thr, uptr pc, int tid); @@ -770,6 +779,7 @@ void ThreadFinalize(ThreadState *thr); void ThreadSetName(ThreadState *thr, const char *name); int ThreadCount(ThreadState *thr); void ProcessPendingSignals(ThreadState *thr); +void ThreadNotJoined(ThreadState *thr, uptr pc, int tid, uptr uid); Processor *ProcCreate(); void ProcDestroy(Processor *proc); @@ -863,6 +873,16 @@ uptr ALWAYS_INLINE HeapEnd() { } #endif +ThreadState *FiberCreate(ThreadState *thr, uptr pc, unsigned flags); +void FiberDestroy(ThreadState *thr, uptr pc, ThreadState *fiber); +void FiberSwitch(ThreadState *thr, uptr pc, ThreadState *fiber, unsigned flags); + +// These need to match __tsan_switch_to_fiber_* flags defined in +// tsan_interface.h. See documentation there as well. +enum FiberSwitchFlags { + FiberSwitchFlagNoSync = 1 << 0, // __tsan_switch_to_fiber_no_sync +}; + } // namespace __tsan #endif // TSAN_RTL_H diff --git a/libsanitizer/tsan/tsan_rtl_aarch64.S b/libsanitizer/tsan/tsan_rtl_aarch64.S index 3d02bf22f8a..e0b4c71dfed 100644 --- a/libsanitizer/tsan/tsan_rtl_aarch64.S +++ b/libsanitizer/tsan/tsan_rtl_aarch64.S @@ -3,14 +3,6 @@ #include "sanitizer_common/sanitizer_asm.h" -#if !defined(__APPLE__) -.section .bss -.type __tsan_pointer_chk_guard, %object -ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__tsan_pointer_chk_guard)) -__tsan_pointer_chk_guard: -.zero 8 -#endif - #if defined(__APPLE__) .align 2 @@ -40,57 +32,6 @@ _sigsetjmp$non_lazy_ptr: .align 3 #endif -#if !defined(__APPLE__) -// GLIBC mangles the function pointers in jmp_buf (used in {set,long}*jmp -// functions) by XORing them with a random guard pointer. For AArch64 it is a -// global variable rather than a TCB one (as for x86_64/powerpc) and althought -// its value is exported by the loader, it lies within a private GLIBC -// namespace (meaning it should be only used by GLIBC itself and the ABI is -// not stable). So InitializeGuardPtr obtains the pointer guard value by -// issuing a setjmp and checking the resulting pointers values against the -// original ones. -ASM_HIDDEN(_Z18InitializeGuardPtrv) -.global _Z18InitializeGuardPtrv -ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_Z18InitializeGuardPtrv)) -_Z18InitializeGuardPtrv: - CFI_STARTPROC - // Allocates a jmp_buf for the setjmp call. - stp x29, x30, [sp, -336]! - CFI_DEF_CFA_OFFSET (336) - CFI_OFFSET (29, -336) - CFI_OFFSET (30, -328) - add x29, sp, 0 - CFI_DEF_CFA_REGISTER (29) - add x0, x29, 24 - - // Call libc setjmp that mangle the stack pointer value - adrp x1, :got:_ZN14__interception12real__setjmpE - ldr x1, [x1, #:got_lo12:_ZN14__interception12real__setjmpE] - ldr x1, [x1] - blr x1 - - // glibc setjmp mangles both the frame pointer (FP, pc+4 on blr) and the - // stack pointer (SP). FP will be placed on ((uintptr*)jmp_buf)[11] and - // SP at ((uintptr*)jmp_buf)[13]. - // The mangle operation is just 'value' xor 'pointer guard value' and - // if we know the original value (SP) and the expected one, we can derive - // the guard pointer value. - mov x0, sp - - // Loads the mangled SP pointer. - ldr x1, [x29, 128] - eor x0, x0, x1 - adrp x2, __tsan_pointer_chk_guard - str x0, [x2, #:lo12:__tsan_pointer_chk_guard] - ldp x29, x30, [sp], 336 - CFI_RESTORE (30) - CFI_RESTORE (19) - CFI_DEF_CFA (31, 0) - ret - CFI_ENDPROC -ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_Z18InitializeGuardPtrv)) -#endif - ASM_HIDDEN(__tsan_setjmp) .comm _ZN14__interception11real_setjmpE,8,8 .globl ASM_SYMBOL_INTERCEPTOR(setjmp) @@ -98,7 +39,7 @@ ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(setjmp)) ASM_SYMBOL_INTERCEPTOR(setjmp): CFI_STARTPROC - // save env parameters for function call + // Save frame/link register stp x29, x30, [sp, -32]! CFI_DEF_CFA_OFFSET (32) CFI_OFFSET (29, -32) @@ -108,33 +49,24 @@ ASM_SYMBOL_INTERCEPTOR(setjmp): add x29, sp, 0 CFI_DEF_CFA_REGISTER (29) - // Save jmp_buf - str x19, [sp, 16] - CFI_OFFSET (19, -16) - mov x19, x0 + // Save env parameter + str x0, [sp, 16] + CFI_OFFSET (0, -16) -#if !defined(__APPLE__) - // SP pointer mangling (see glibc setjmp) - adrp x2, __tsan_pointer_chk_guard - ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard] - add x0, x29, 32 - eor x1, x2, x0 -#else - adrp x2, ___tsan_darwin_setjmp_xor_key@page - ldr x2, [x2, ___tsan_darwin_setjmp_xor_key@pageoff] + // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` add x0, x29, 32 - eor x1, x2, x0 -#endif // call tsan interceptor bl ASM_SYMBOL(__tsan_setjmp) - // restore env parameter - mov x0, x19 - ldr x19, [sp, 16] + // Restore env parameter + ldr x0, [sp, 16] + CFI_RESTORE (0) + + // Restore frame/link register ldp x29, x30, [sp], 32 + CFI_RESTORE (29) CFI_RESTORE (30) - CFI_RESTORE (19) CFI_DEF_CFA (31, 0) // tail jump to libc setjmp @@ -158,7 +90,7 @@ ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_setjmp)) ASM_SYMBOL_INTERCEPTOR(_setjmp): CFI_STARTPROC - // save env parameters for function call + // Save frame/link register stp x29, x30, [sp, -32]! CFI_DEF_CFA_OFFSET (32) CFI_OFFSET (29, -32) @@ -168,33 +100,24 @@ ASM_SYMBOL_INTERCEPTOR(_setjmp): add x29, sp, 0 CFI_DEF_CFA_REGISTER (29) - // Save jmp_buf - str x19, [sp, 16] - CFI_OFFSET (19, -16) - mov x19, x0 + // Save env parameter + str x0, [sp, 16] + CFI_OFFSET (0, -16) -#if !defined(__APPLE__) - // SP pointer mangling (see glibc setjmp) - adrp x2, __tsan_pointer_chk_guard - ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard] + // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` add x0, x29, 32 - eor x1, x2, x0 -#else - adrp x2, ___tsan_darwin_setjmp_xor_key@page - ldr x2, [x2, ___tsan_darwin_setjmp_xor_key@pageoff] - add x0, x29, 32 - eor x1, x2, x0 -#endif // call tsan interceptor bl ASM_SYMBOL(__tsan_setjmp) - // Restore jmp_buf parameter - mov x0, x19 - ldr x19, [sp, 16] + // Restore env parameter + ldr x0, [sp, 16] + CFI_RESTORE (0) + + // Restore frame/link register ldp x29, x30, [sp], 32 + CFI_RESTORE (29) CFI_RESTORE (30) - CFI_RESTORE (19) CFI_DEF_CFA (31, 0) // tail jump to libc setjmp @@ -218,7 +141,7 @@ ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(sigsetjmp)) ASM_SYMBOL_INTERCEPTOR(sigsetjmp): CFI_STARTPROC - // save env parameters for function call + // Save frame/link register stp x29, x30, [sp, -32]! CFI_DEF_CFA_OFFSET (32) CFI_OFFSET (29, -32) @@ -228,38 +151,26 @@ ASM_SYMBOL_INTERCEPTOR(sigsetjmp): add x29, sp, 0 CFI_DEF_CFA_REGISTER (29) - // Save jmp_buf and savesigs - stp x19, x20, [sp, 16] - CFI_OFFSET (19, -16) - CFI_OFFSET (20, -8) - mov w20, w1 - mov x19, x0 + // Save env and savesigs parameter + stp x0, x1, [sp, 16] + CFI_OFFSET (0, -16) + CFI_OFFSET (1, -8) -#if !defined(__APPLE__) - // SP pointer mangling (see glibc setjmp) - adrp x2, __tsan_pointer_chk_guard - ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard] - add x0, x29, 32 - eor x1, x2, x0 -#else - adrp x2, ___tsan_darwin_setjmp_xor_key@page - ldr x2, [x2, ___tsan_darwin_setjmp_xor_key@pageoff] + // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` add x0, x29, 32 - eor x1, x2, x0 -#endif // call tsan interceptor bl ASM_SYMBOL(__tsan_setjmp) - // restore env parameter - mov w1, w20 - mov x0, x19 - ldp x19, x20, [sp, 16] + // Restore env and savesigs parameter + ldp x0, x1, [sp, 16] + CFI_RESTORE (0) + CFI_RESTORE (1) + + // Restore frame/link register ldp x29, x30, [sp], 32 - CFI_RESTORE (30) CFI_RESTORE (29) - CFI_RESTORE (19) - CFI_RESTORE (20) + CFI_RESTORE (30) CFI_DEF_CFA (31, 0) // tail jump to libc sigsetjmp @@ -283,7 +194,7 @@ ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)) ASM_SYMBOL_INTERCEPTOR(__sigsetjmp): CFI_STARTPROC - // save env parameters for function call + // Save frame/link register stp x29, x30, [sp, -32]! CFI_DEF_CFA_OFFSET (32) CFI_OFFSET (29, -32) @@ -293,32 +204,26 @@ ASM_SYMBOL_INTERCEPTOR(__sigsetjmp): add x29, sp, 0 CFI_DEF_CFA_REGISTER (29) - // Save jmp_buf and savesigs - stp x19, x20, [sp, 16] - CFI_OFFSET (19, -16) - CFI_OFFSET (20, -8) - mov w20, w1 - mov x19, x0 + // Save env and savesigs parameter + stp x0, x1, [sp, 16] + CFI_OFFSET (0, -16) + CFI_OFFSET (1, -8) -#if !defined(__APPLE__) - // SP pointer mangling (see glibc setjmp) - adrp x2, __tsan_pointer_chk_guard - ldr x2, [x2, #:lo12:__tsan_pointer_chk_guard] + // Obtain SP, first argument to `void __tsan_setjmp(uptr sp)` add x0, x29, 32 - eor x1, x2, x0 -#endif // call tsan interceptor bl ASM_SYMBOL(__tsan_setjmp) - mov w1, w20 - mov x0, x19 - ldp x19, x20, [sp, 16] + // Restore env and savesigs parameter + ldp x0, x1, [sp, 16] + CFI_RESTORE (0) + CFI_RESTORE (1) + + // Restore frame/link register ldp x29, x30, [sp], 32 - CFI_RESTORE (30) CFI_RESTORE (29) - CFI_RESTORE (19) - CFI_RESTORE (20) + CFI_RESTORE (30) CFI_DEF_CFA (31, 0) // tail jump to libc __sigsetjmp @@ -335,9 +240,6 @@ ASM_SYMBOL_INTERCEPTOR(__sigsetjmp): ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)) #endif -#if defined(__linux__) -/* We do not need executable stack. */ -.section .note.GNU-stack,"",@progbits -#endif +NO_EXEC_STACK_DIRECTIVE #endif diff --git a/libsanitizer/tsan/tsan_rtl_amd64.S b/libsanitizer/tsan/tsan_rtl_amd64.S index 34ef51c2a72..5913aa360c5 100644 --- a/libsanitizer/tsan/tsan_rtl_amd64.S +++ b/libsanitizer/tsan/tsan_rtl_amd64.S @@ -189,19 +189,11 @@ ASM_SYMBOL_INTERCEPTOR(setjmp): push %rdi CFI_ADJUST_CFA_OFFSET(8) CFI_REL_OFFSET(%rdi, 0) - // obtain %rsp + // obtain SP, store in %rdi, first argument to `void __tsan_setjmp(uptr sp)` #if defined(__FreeBSD__) || defined(__NetBSD__) lea 8(%rsp), %rdi - mov %rdi, %rsi -#elif defined(__APPLE__) +#elif defined(__linux__) || defined(__APPLE__) lea 16(%rsp), %rdi - mov %rdi, %rsi - xorq ___tsan_darwin_setjmp_xor_key(%rip), %rsi -#elif defined(__linux__) - lea 16(%rsp), %rdi - mov %rdi, %rsi - xor %fs:0x30, %rsi // magic mangling of rsp (see libc setjmp) - rol $0x11, %rsi #else # error "Unknown platform" #endif @@ -238,19 +230,11 @@ ASM_SYMBOL_INTERCEPTOR(_setjmp): push %rdi CFI_ADJUST_CFA_OFFSET(8) CFI_REL_OFFSET(%rdi, 0) - // obtain %rsp + // obtain SP, store in %rdi, first argument to `void __tsan_setjmp(uptr sp)` #if defined(__FreeBSD__) || defined(__NetBSD__) lea 8(%rsp), %rdi - mov %rdi, %rsi -#elif defined(__APPLE__) - lea 16(%rsp), %rdi - mov %rdi, %rsi - xorq ___tsan_darwin_setjmp_xor_key(%rip), %rsi -#elif defined(__linux__) +#elif defined(__linux__) || defined(__APPLE__) lea 16(%rsp), %rdi - mov %rdi, %rsi - xor %fs:0x30, %rsi // magic mangling of rsp (see libc setjmp) - rol $0x11, %rsi #else # error "Unknown platform" #endif @@ -294,19 +278,11 @@ ASM_SYMBOL_INTERCEPTOR(sigsetjmp): // align stack frame sub $8, %rsp CFI_ADJUST_CFA_OFFSET(8) - // obtain %rsp + // obtain SP, store in %rdi, first argument to `void __tsan_setjmp(uptr sp)` #if defined(__FreeBSD__) || defined(__NetBSD__) lea 24(%rsp), %rdi - mov %rdi, %rsi -#elif defined(__APPLE__) +#elif defined(__linux__) || defined(__APPLE__) lea 32(%rsp), %rdi - mov %rdi, %rsi - xorq ___tsan_darwin_setjmp_xor_key(%rip), %rsi -#elif defined(__linux__) - lea 32(%rsp), %rdi - mov %rdi, %rsi - xor %fs:0x30, %rsi // magic mangling of rsp (see libc setjmp) - rol $0x11, %rsi #else # error "Unknown platform" #endif @@ -358,15 +334,11 @@ ASM_SYMBOL_INTERCEPTOR(__sigsetjmp): // align stack frame sub $8, %rsp CFI_ADJUST_CFA_OFFSET(8) - // obtain %rsp + // obtain SP, store in %rdi, first argument to `void __tsan_setjmp(uptr sp)` #if defined(__FreeBSD__) lea 24(%rsp), %rdi - mov %rdi, %rsi #else lea 32(%rsp), %rdi - mov %rdi, %rsi - xor %fs:0x30, %rsi // magic mangling of rsp (see libc setjmp) - rol $0x11, %rsi #endif // call tsan interceptor call ASM_SYMBOL(__tsan_setjmp) @@ -389,10 +361,6 @@ ASM_SYMBOL_INTERCEPTOR(__sigsetjmp): ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)) #endif // !defined(__APPLE__) && !defined(__NetBSD__) -#if defined(__FreeBSD__) || defined(__linux__) -/* We do not need executable stack. */ -/* This note is not needed on NetBSD. */ -.section .note.GNU-stack,"",@progbits -#endif +NO_EXEC_STACK_DIRECTIVE #endif diff --git a/libsanitizer/tsan/tsan_rtl_mutex.cc b/libsanitizer/tsan/tsan_rtl_mutex.cpp similarity index 98% rename from libsanitizer/tsan/tsan_rtl_mutex.cc rename to libsanitizer/tsan/tsan_rtl_mutex.cpp index 6981f98dcb9..ce6e7cb2c4e 100644 --- a/libsanitizer/tsan/tsan_rtl_mutex.cc +++ b/libsanitizer/tsan/tsan_rtl_mutex.cpp @@ -1,7 +1,8 @@ -//===-- tsan_rtl_mutex.cc -------------------------------------------------===// +//===-- tsan_rtl_mutex.cpp ------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_rtl_ppc64.S b/libsanitizer/tsan/tsan_rtl_ppc64.S index 9e533a71a9c..8285e21aa1e 100644 --- a/libsanitizer/tsan/tsan_rtl_ppc64.S +++ b/libsanitizer/tsan/tsan_rtl_ppc64.S @@ -1,6 +1,5 @@ #include "tsan_ppc_regs.h" - .machine altivec .section .text .hidden __tsan_setjmp .globl _setjmp diff --git a/libsanitizer/tsan/tsan_rtl_proc.cc b/libsanitizer/tsan/tsan_rtl_proc.cpp similarity index 84% rename from libsanitizer/tsan/tsan_rtl_proc.cc rename to libsanitizer/tsan/tsan_rtl_proc.cpp index 1b0a9b38938..def61cca14d 100644 --- a/libsanitizer/tsan/tsan_rtl_proc.cc +++ b/libsanitizer/tsan/tsan_rtl_proc.cpp @@ -1,7 +1,8 @@ -//===-- tsan_rtl_proc.cc ------------------------------------------------===// +//===-- tsan_rtl_proc.cpp -----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_rtl_report.cc b/libsanitizer/tsan/tsan_rtl_report.cpp similarity index 98% rename from libsanitizer/tsan/tsan_rtl_report.cc rename to libsanitizer/tsan/tsan_rtl_report.cpp index 18b6cf7fd50..47b8bf77dca 100644 --- a/libsanitizer/tsan/tsan_rtl_report.cc +++ b/libsanitizer/tsan/tsan_rtl_report.cpp @@ -1,7 +1,8 @@ -//===-- tsan_rtl_report.cc ------------------------------------------------===// +//===-- tsan_rtl_report.cpp -----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -200,7 +201,7 @@ void ScopedReportBase::AddThread(const ThreadContext *tctx, bool suppressable) { rt->running = (tctx->status == ThreadStatusRunning); rt->name = internal_strdup(tctx->name); rt->parent_tid = tctx->parent_tid; - rt->workerthread = tctx->workerthread; + rt->thread_type = tctx->thread_type; rt->stack = 0; rt->stack = SymbolizeStackId(tctx->creation_stack_id); if (rt->stack) @@ -649,7 +650,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]); @@ -728,10 +729,12 @@ void PrintCurrentStack(ThreadState *thr, uptr pc) { ALWAYS_INLINE void PrintCurrentStackSlow(uptr pc) { #if !SANITIZER_GO + uptr bp = GET_CURRENT_FRAME(); BufferedStackTrace *ptrace = new(internal_alloc(MBlockStackTrace, sizeof(BufferedStackTrace))) BufferedStackTrace(); - ptrace->Unwind(kStackTraceMax, pc, 0, 0, 0, 0, false); + ptrace->Unwind(pc, bp, nullptr, false); + for (uptr i = 0; i < ptrace->size / 2; i++) { uptr tmp = ptrace->trace_buffer[i]; ptrace->trace_buffer[i] = ptrace->trace_buffer[ptrace->size - i - 1]; diff --git a/libsanitizer/tsan/tsan_rtl_thread.cc b/libsanitizer/tsan/tsan_rtl_thread.cpp similarity index 86% rename from libsanitizer/tsan/tsan_rtl_thread.cc rename to libsanitizer/tsan/tsan_rtl_thread.cpp index 7a731c4006a..0ac1ee99c47 100644 --- a/libsanitizer/tsan/tsan_rtl_thread.cc +++ b/libsanitizer/tsan/tsan_rtl_thread.cpp @@ -1,7 +1,8 @@ -//===-- tsan_rtl_thread.cc ------------------------------------------------===// +//===-- tsan_rtl_thread.cpp -----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -238,13 +239,15 @@ int ThreadCreate(ThreadState *thr, uptr pc, uptr uid, bool detached) { return tid; } -void ThreadStart(ThreadState *thr, int tid, tid_t os_id, bool workerthread) { +void ThreadStart(ThreadState *thr, int tid, tid_t os_id, + ThreadType thread_type) { uptr stk_addr = 0; uptr stk_size = 0; uptr tls_addr = 0; uptr tls_size = 0; #if !SANITIZER_GO - GetThreadStackAndTls(tid == 0, &stk_addr, &stk_size, &tls_addr, &tls_size); + if (thread_type != ThreadType::Fiber) + GetThreadStackAndTls(tid == 0, &stk_addr, &stk_size, &tls_addr, &tls_size); if (tid) { if (stk_addr && stk_size) @@ -256,7 +259,7 @@ void ThreadStart(ThreadState *thr, int tid, tid_t os_id, bool workerthread) { ThreadRegistry *tr = ctx->thread_registry; OnStartedArgs args = { thr, stk_addr, stk_size, tls_addr, tls_size }; - tr->StartThread(tid, os_id, workerthread, &args); + tr->StartThread(tid, os_id, thread_type, &args); tr->Lock(); thr->tctx = (ThreadContext*)tr->GetThreadLocked(tid); @@ -310,6 +313,12 @@ void ThreadDetach(ThreadState *thr, uptr pc, int tid) { ctx->thread_registry->DetachThread(tid, thr); } +void ThreadNotJoined(ThreadState *thr, uptr pc, int tid, uptr uid) { + CHECK_GT(tid, 0); + CHECK_LT(tid, kMaxTid); + ctx->thread_registry->SetThreadUserId(tid, uid); +} + void ThreadSetName(ThreadState *thr, const char *name) { ctx->thread_registry->SetThreadName(thr->tid, name); } @@ -396,4 +405,40 @@ void MemoryAccessRange(ThreadState *thr, uptr pc, uptr addr, } } +#if !SANITIZER_GO +void FiberSwitchImpl(ThreadState *from, ThreadState *to) { + Processor *proc = from->proc(); + ProcUnwire(proc, from); + ProcWire(proc, to); + set_cur_thread(to); +} + +ThreadState *FiberCreate(ThreadState *thr, uptr pc, unsigned flags) { + void *mem = internal_alloc(MBlockThreadContex, sizeof(ThreadState)); + ThreadState *fiber = static_cast(mem); + internal_memset(fiber, 0, sizeof(*fiber)); + int tid = ThreadCreate(thr, pc, 0, true); + FiberSwitchImpl(thr, fiber); + ThreadStart(fiber, tid, 0, ThreadType::Fiber); + FiberSwitchImpl(fiber, thr); + return fiber; +} + +void FiberDestroy(ThreadState *thr, uptr pc, ThreadState *fiber) { + FiberSwitchImpl(thr, fiber); + ThreadFinish(fiber); + FiberSwitchImpl(fiber, thr); + internal_free(fiber); +} + +void FiberSwitch(ThreadState *thr, uptr pc, + ThreadState *fiber, unsigned flags) { + if (!(flags & FiberSwitchFlagNoSync)) + Release(thr, pc, (uptr)fiber); + FiberSwitchImpl(thr, fiber); + if (!(flags & FiberSwitchFlagNoSync)) + Acquire(fiber, pc, (uptr)fiber); +} +#endif + } // namespace __tsan diff --git a/libsanitizer/tsan/tsan_stack_trace.cc b/libsanitizer/tsan/tsan_stack_trace.cpp similarity index 64% rename from libsanitizer/tsan/tsan_stack_trace.cc rename to libsanitizer/tsan/tsan_stack_trace.cpp index 4ddec965f32..403a21ae4ae 100644 --- a/libsanitizer/tsan/tsan_stack_trace.cc +++ b/libsanitizer/tsan/tsan_stack_trace.cpp @@ -1,7 +1,8 @@ -//===-- tsan_stack_trace.cc -----------------------------------------------===// +//===-- tsan_stack_trace.cpp ----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -47,3 +48,16 @@ void VarSizeStackTrace::ReverseOrder() { } } // namespace __tsan + +#if !SANITIZER_GO +void __sanitizer::BufferedStackTrace::UnwindImpl( + uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) { + uptr top = 0; + uptr bottom = 0; + if (StackTrace::WillUseFastUnwind(request_fast)) { + GetThreadStackTopAndBottom(false, &top, &bottom); + Unwind(max_depth, pc, bp, nullptr, top, bottom, true); + } else + Unwind(max_depth, pc, 0, context, 0, 0, false); +} +#endif // SANITIZER_GO diff --git a/libsanitizer/tsan/tsan_stack_trace.h b/libsanitizer/tsan/tsan_stack_trace.h index bc4468f4405..3eb8ce156e8 100644 --- a/libsanitizer/tsan/tsan_stack_trace.h +++ b/libsanitizer/tsan/tsan_stack_trace.h @@ -1,7 +1,8 @@ //===-- tsan_stack_trace.h --------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_stat.cc b/libsanitizer/tsan/tsan_stat.cpp similarity index 97% rename from libsanitizer/tsan/tsan_stat.cc rename to libsanitizer/tsan/tsan_stat.cpp index decb7a20b84..78f3cce9138 100644 --- a/libsanitizer/tsan/tsan_stat.cc +++ b/libsanitizer/tsan/tsan_stat.cpp @@ -1,7 +1,8 @@ -//===-- tsan_stat.cc ------------------------------------------------------===// +//===-- tsan_stat.cpp -----------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_stat.h b/libsanitizer/tsan/tsan_stat.h index c4859df52b0..94e18bc66df 100644 --- a/libsanitizer/tsan/tsan_stat.h +++ b/libsanitizer/tsan/tsan_stat.h @@ -1,7 +1,8 @@ //===-- tsan_stat.h ---------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_suppressions.cc b/libsanitizer/tsan/tsan_suppressions.cpp similarity index 77% rename from libsanitizer/tsan/tsan_suppressions.cc rename to libsanitizer/tsan/tsan_suppressions.cpp index d48148fed5c..6bf6720210a 100644 --- a/libsanitizer/tsan/tsan_suppressions.cc +++ b/libsanitizer/tsan/tsan_suppressions.cpp @@ -1,7 +1,8 @@ -//===-- tsan_suppressions.cc ----------------------------------------------===// +//===-- tsan_suppressions.cpp ---------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -64,38 +65,30 @@ SuppressionContext *Suppressions() { } static const char *conv(ReportType typ) { - if (typ == ReportTypeRace) - return kSuppressionRace; - else if (typ == ReportTypeVptrRace) - return kSuppressionRace; - else if (typ == ReportTypeUseAfterFree) - return kSuppressionRace; - else if (typ == ReportTypeVptrUseAfterFree) - return kSuppressionRace; - else if (typ == ReportTypeExternalRace) - return kSuppressionRace; - else if (typ == ReportTypeThreadLeak) - return kSuppressionThread; - else if (typ == ReportTypeMutexDestroyLocked) - return kSuppressionMutex; - else if (typ == ReportTypeMutexDoubleLock) - return kSuppressionMutex; - else if (typ == ReportTypeMutexInvalidAccess) - return kSuppressionMutex; - else if (typ == ReportTypeMutexBadUnlock) - return kSuppressionMutex; - else if (typ == ReportTypeMutexBadReadLock) - return kSuppressionMutex; - else if (typ == ReportTypeMutexBadReadUnlock) - return kSuppressionMutex; - else if (typ == ReportTypeSignalUnsafe) - return kSuppressionSignal; - else if (typ == ReportTypeErrnoInSignal) - return kSuppressionNone; - else if (typ == ReportTypeDeadlock) - return kSuppressionDeadlock; - Printf("ThreadSanitizer: unknown report type %d\n", typ); - Die(); + switch (typ) { + case ReportTypeRace: + case ReportTypeVptrRace: + case ReportTypeUseAfterFree: + case ReportTypeVptrUseAfterFree: + case ReportTypeExternalRace: + return kSuppressionRace; + case ReportTypeThreadLeak: + return kSuppressionThread; + case ReportTypeMutexDestroyLocked: + case ReportTypeMutexDoubleLock: + case ReportTypeMutexInvalidAccess: + case ReportTypeMutexBadUnlock: + case ReportTypeMutexBadReadLock: + case ReportTypeMutexBadReadUnlock: + return kSuppressionMutex; + case ReportTypeSignalUnsafe: + case ReportTypeErrnoInSignal: + return kSuppressionSignal; + case ReportTypeDeadlock: + return kSuppressionDeadlock; + // No default case so compiler warns us if we miss one + } + UNREACHABLE("missing case"); } static uptr IsSuppressed(const char *stype, const AddressInfo &info, diff --git a/libsanitizer/tsan/tsan_suppressions.h b/libsanitizer/tsan/tsan_suppressions.h index 58951975075..f430aeb6c4c 100644 --- a/libsanitizer/tsan/tsan_suppressions.h +++ b/libsanitizer/tsan/tsan_suppressions.h @@ -1,7 +1,8 @@ //===-- tsan_suppressions.h -------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_symbolize.cc b/libsanitizer/tsan/tsan_symbolize.cpp similarity index 93% rename from libsanitizer/tsan/tsan_symbolize.cc rename to libsanitizer/tsan/tsan_symbolize.cpp index 074006be70d..6478f3a754a 100644 --- a/libsanitizer/tsan/tsan_symbolize.cc +++ b/libsanitizer/tsan/tsan_symbolize.cpp @@ -1,7 +1,8 @@ -//===-- tsan_symbolize.cc -------------------------------------------------===// +//===-- tsan_symbolize.cpp ------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_symbolize.h b/libsanitizer/tsan/tsan_symbolize.h index a859f6318b0..7adaa04dc27 100644 --- a/libsanitizer/tsan/tsan_symbolize.h +++ b/libsanitizer/tsan/tsan_symbolize.h @@ -1,7 +1,8 @@ //===-- tsan_symbolize.h ----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_sync.cc b/libsanitizer/tsan/tsan_sync.cpp similarity index 96% rename from libsanitizer/tsan/tsan_sync.cc rename to libsanitizer/tsan/tsan_sync.cpp index 10ae446e58b..7f686dc5fcd 100644 --- a/libsanitizer/tsan/tsan_sync.cc +++ b/libsanitizer/tsan/tsan_sync.cpp @@ -1,7 +1,8 @@ -//===-- tsan_sync.cc ------------------------------------------------------===// +//===-- tsan_sync.cpp -----------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_sync.h b/libsanitizer/tsan/tsan_sync.h index a4409fe49ae..47f2739d8de 100644 --- a/libsanitizer/tsan/tsan_sync.h +++ b/libsanitizer/tsan/tsan_sync.h @@ -1,7 +1,8 @@ //===-- tsan_sync.h ---------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_trace.h b/libsanitizer/tsan/tsan_trace.h index 5cc3f8f3498..fbd0f72db6e 100644 --- a/libsanitizer/tsan/tsan_trace.h +++ b/libsanitizer/tsan/tsan_trace.h @@ -1,7 +1,8 @@ //===-- tsan_trace.h --------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/tsan/tsan_update_shadow_word_inl.h b/libsanitizer/tsan/tsan_update_shadow_word_inl.h index 2ea74283818..056c3aa2032 100644 --- a/libsanitizer/tsan/tsan_update_shadow_word_inl.h +++ b/libsanitizer/tsan/tsan_update_shadow_word_inl.h @@ -1,7 +1,8 @@ //===-- tsan_update_shadow_word_inl.h ---------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -16,31 +17,35 @@ do { const unsigned kAccessSize = 1 << kAccessSizeLog; u64 *sp = &shadow_mem[idx]; old = LoadShadow(sp); - if (old.IsZero()) { + if (LIKELY(old.IsZero())) { StatInc(thr, StatShadowZero); - if (store_word) + if (!stored) { StoreIfNotYetStored(sp, &store_word); - // The above StoreIfNotYetStored could be done unconditionally - // and it even shows 4% gain on synthetic benchmarks (r4307). + stored = true; + } break; } // is the memory access equal to the previous? - if (Shadow::Addr0AndSizeAreEqual(cur, old)) { + if (LIKELY(Shadow::Addr0AndSizeAreEqual(cur, old))) { StatInc(thr, StatShadowSameSize); // same thread? - if (Shadow::TidsAreEqual(old, cur)) { + if (LIKELY(Shadow::TidsAreEqual(old, cur))) { StatInc(thr, StatShadowSameThread); - if (old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic)) + if (LIKELY(old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic))) { StoreIfNotYetStored(sp, &store_word); + stored = true; + } break; } StatInc(thr, StatShadowAnotherThread); if (HappensBefore(old, thr)) { - if (old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic)) + if (old.IsRWWeakerOrEqual(kAccessIsWrite, kIsAtomic)) { StoreIfNotYetStored(sp, &store_word); + stored = true; + } break; } - if (old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic)) + if (LIKELY(old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic))) break; goto RACE; } @@ -54,7 +59,7 @@ do { StatInc(thr, StatShadowAnotherThread); if (old.IsBothReadsOrAtomic(kAccessIsWrite, kIsAtomic)) break; - if (HappensBefore(old, thr)) + if (LIKELY(HappensBefore(old, thr))) break; goto RACE; } diff --git a/libsanitizer/ubsan/Makefile.am b/libsanitizer/ubsan/Makefile.am index 1f924f8120a..46021d6c8fa 100644 --- a/libsanitizer/ubsan/Makefile.am +++ b/libsanitizer/ubsan/Makefile.am @@ -13,16 +13,16 @@ ACLOCAL_AMFLAGS = -I m4 toolexeclib_LTLIBRARIES = libubsan.la ubsan_plugin_files = \ - ubsan_diag.cc \ - ubsan_flags.cc \ - ubsan_handlers.cc \ - ubsan_handlers_cxx.cc \ - ubsan_init.cc \ - ubsan_monitor.cc \ - ubsan_type_hash.cc \ - ubsan_type_hash_itanium.cc \ - ubsan_type_hash_win.cc \ - ubsan_value.cc + ubsan_diag.cpp \ + ubsan_flags.cpp \ + ubsan_handlers.cpp \ + ubsan_handlers_cxx.cpp \ + ubsan_init.cpp \ + ubsan_monitor.cpp \ + ubsan_type_hash.cpp \ + ubsan_type_hash_itanium.cpp \ + ubsan_type_hash_win.cpp \ + ubsan_value.cpp ubsan_files = $(ubsan_plugin_files) diff --git a/libsanitizer/ubsan/Makefile.in b/libsanitizer/ubsan/Makefile.in index b1ba31a50e6..9092f17b609 100644 --- a/libsanitizer/ubsan/Makefile.in +++ b/libsanitizer/ubsan/Makefile.in @@ -1,7 +1,7 @@ -# Makefile.in generated by automake 1.15.1 from Makefile.am. +# Makefile.in generated by automake 1.16.1 from Makefile.am. # @configure_input@ -# Copyright (C) 1994-2017 Free Software Foundation, Inc. +# Copyright (C) 1994-2018 Free Software Foundation, Inc. # This Makefile.in is free software; the Free Software Foundation # gives unlimited permission to copy and/or distribute it, @@ -173,7 +173,14 @@ am__v_at_0 = @ am__v_at_1 = DEFAULT_INCLUDES = -I.@am__isrc@ -I$(top_builddir) depcomp = $(SHELL) $(top_srcdir)/../depcomp -am__depfiles_maybe = depfiles +am__maybe_remake_depfiles = depfiles +am__depfiles_remade = ./$(DEPDIR)/ubsan_diag.Plo \ + ./$(DEPDIR)/ubsan_flags.Plo ./$(DEPDIR)/ubsan_handlers.Plo \ + ./$(DEPDIR)/ubsan_handlers_cxx.Plo ./$(DEPDIR)/ubsan_init.Plo \ + ./$(DEPDIR)/ubsan_monitor.Plo ./$(DEPDIR)/ubsan_type_hash.Plo \ + ./$(DEPDIR)/ubsan_type_hash_itanium.Plo \ + ./$(DEPDIR)/ubsan_type_hash_win.Plo \ + ./$(DEPDIR)/ubsan_value.Plo am__mv = mv -f CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) @@ -379,16 +386,16 @@ AM_CXXFLAGS = -Wall -W -Wno-unused-parameter -Wwrite-strings -pedantic \ ACLOCAL_AMFLAGS = -I m4 toolexeclib_LTLIBRARIES = libubsan.la ubsan_plugin_files = \ - ubsan_diag.cc \ - ubsan_flags.cc \ - ubsan_handlers.cc \ - ubsan_handlers_cxx.cc \ - ubsan_init.cc \ - ubsan_monitor.cc \ - ubsan_type_hash.cc \ - ubsan_type_hash_itanium.cc \ - ubsan_type_hash_win.cc \ - ubsan_value.cc + ubsan_diag.cpp \ + ubsan_flags.cpp \ + ubsan_handlers.cpp \ + ubsan_handlers_cxx.cpp \ + ubsan_init.cpp \ + ubsan_monitor.cpp \ + ubsan_type_hash.cpp \ + ubsan_type_hash_itanium.cpp \ + ubsan_type_hash_win.cpp \ + ubsan_value.cpp ubsan_files = $(ubsan_plugin_files) libubsan_la_SOURCES = $(ubsan_files) @@ -439,7 +446,7 @@ MAKEOVERRIDES = all: all-am .SUFFIXES: -.SUFFIXES: .cc .lo .o .obj +.SUFFIXES: .cpp .lo .o .obj $(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am $(am__configure_deps) @for dep in $?; do \ case '$(am__configure_deps)' in \ @@ -457,8 +464,8 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status *config.status*) \ cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh;; \ *) \ - echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe)'; \ - cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__depfiles_maybe);; \ + echo ' cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles)'; \ + cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@ $(am__maybe_remake_depfiles);; \ esac; $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES) @@ -514,32 +521,38 @@ mostlyclean-compile: distclean-compile: -rm -f *.tab.c -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_diag.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_flags.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_handlers.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_handlers_cxx.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_init.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_monitor.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_type_hash.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_type_hash_itanium.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_type_hash_win.Plo@am__quote@ -@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_value.Plo@am__quote@ - -.cc.o: +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_diag.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_flags.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_handlers.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_handlers_cxx.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_init.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_monitor.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_type_hash.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_type_hash_itanium.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_type_hash_win.Plo@am__quote@ # am--include-marker +@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/ubsan_value.Plo@am__quote@ # am--include-marker + +$(am__depfiles_remade): + @$(MKDIR_P) $(@D) + @echo '# dummy' >$@-t && $(am__mv) $@-t $@ + +am--depfiles: $(am__depfiles_remade) + +.cpp.o: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ $< -.cc.obj: +.cpp.obj: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(CXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ `$(CYGPATH_W) '$<'` @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Po @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=no @AMDEPBACKSLASH@ @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` -.cc.lo: +.cpp.lo: @am__fastdepCXX_TRUE@ $(AM_V_CXX)$(LTCXXCOMPILE) -MT $@ -MD -MP -MF $(DEPDIR)/$*.Tpo -c -o $@ $< @am__fastdepCXX_TRUE@ $(AM_V_at)$(am__mv) $(DEPDIR)/$*.Tpo $(DEPDIR)/$*.Plo @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ @@ -646,7 +659,16 @@ clean-am: clean-generic clean-libtool clean-toolexeclibLTLIBRARIES \ mostlyclean-am distclean: distclean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/ubsan_diag.Plo + -rm -f ./$(DEPDIR)/ubsan_flags.Plo + -rm -f ./$(DEPDIR)/ubsan_handlers.Plo + -rm -f ./$(DEPDIR)/ubsan_handlers_cxx.Plo + -rm -f ./$(DEPDIR)/ubsan_init.Plo + -rm -f ./$(DEPDIR)/ubsan_monitor.Plo + -rm -f ./$(DEPDIR)/ubsan_type_hash.Plo + -rm -f ./$(DEPDIR)/ubsan_type_hash_itanium.Plo + -rm -f ./$(DEPDIR)/ubsan_type_hash_win.Plo + -rm -f ./$(DEPDIR)/ubsan_value.Plo -rm -f Makefile distclean-am: clean-am distclean-compile distclean-generic \ distclean-tags @@ -692,7 +714,16 @@ install-ps-am: installcheck-am: maintainer-clean: maintainer-clean-am - -rm -rf ./$(DEPDIR) + -rm -f ./$(DEPDIR)/ubsan_diag.Plo + -rm -f ./$(DEPDIR)/ubsan_flags.Plo + -rm -f ./$(DEPDIR)/ubsan_handlers.Plo + -rm -f ./$(DEPDIR)/ubsan_handlers_cxx.Plo + -rm -f ./$(DEPDIR)/ubsan_init.Plo + -rm -f ./$(DEPDIR)/ubsan_monitor.Plo + -rm -f ./$(DEPDIR)/ubsan_type_hash.Plo + -rm -f ./$(DEPDIR)/ubsan_type_hash_itanium.Plo + -rm -f ./$(DEPDIR)/ubsan_type_hash_win.Plo + -rm -f ./$(DEPDIR)/ubsan_value.Plo -rm -f Makefile maintainer-clean-am: distclean-am maintainer-clean-generic @@ -713,20 +744,20 @@ uninstall-am: uninstall-toolexeclibLTLIBRARIES .MAKE: install-am install-strip -.PHONY: CTAGS GTAGS TAGS all all-am check check-am clean clean-generic \ - clean-libtool clean-toolexeclibLTLIBRARIES cscopelist-am ctags \ - ctags-am distclean distclean-compile distclean-generic \ - distclean-libtool distclean-tags dvi dvi-am html html-am info \ - info-am install install-am install-data install-data-am \ - install-dvi install-dvi-am install-exec install-exec-am \ - install-html install-html-am install-info install-info-am \ - install-man install-pdf install-pdf-am install-ps \ - install-ps-am install-strip install-toolexeclibLTLIBRARIES \ - installcheck installcheck-am installdirs maintainer-clean \ - maintainer-clean-generic mostlyclean mostlyclean-compile \ - mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ - tags tags-am uninstall uninstall-am \ - uninstall-toolexeclibLTLIBRARIES +.PHONY: CTAGS GTAGS TAGS all all-am am--depfiles check check-am clean \ + clean-generic clean-libtool clean-toolexeclibLTLIBRARIES \ + cscopelist-am ctags ctags-am distclean distclean-compile \ + distclean-generic distclean-libtool distclean-tags dvi dvi-am \ + html html-am info info-am install install-am install-data \ + install-data-am install-dvi install-dvi-am install-exec \ + install-exec-am install-html install-html-am install-info \ + install-info-am install-man install-pdf install-pdf-am \ + install-ps install-ps-am install-strip \ + install-toolexeclibLTLIBRARIES installcheck installcheck-am \ + installdirs maintainer-clean maintainer-clean-generic \ + mostlyclean mostlyclean-compile mostlyclean-generic \ + mostlyclean-libtool pdf pdf-am ps ps-am tags tags-am uninstall \ + uninstall-am uninstall-toolexeclibLTLIBRARIES .PRECIOUS: Makefile diff --git a/libsanitizer/ubsan/ubsan_checks.inc b/libsanitizer/ubsan/ubsan_checks.inc index dbe5550a9e4..7e7216c5b4a 100644 --- a/libsanitizer/ubsan/ubsan_checks.inc +++ b/libsanitizer/ubsan/ubsan_checks.inc @@ -1,7 +1,8 @@ //===-- ubsan_checks.inc ----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -19,6 +20,7 @@ UBSAN_CHECK(GenericUB, "undefined-behavior", "undefined") UBSAN_CHECK(NullPointerUse, "null-pointer-use", "null") UBSAN_CHECK(PointerOverflow, "pointer-overflow", "pointer-overflow") UBSAN_CHECK(MisalignedPointerUse, "misaligned-pointer-use", "alignment") +UBSAN_CHECK(AlignmentAssumption, "alignment-assumption", "alignment") UBSAN_CHECK(InsufficientObjectSize, "insufficient-object-size", "object-size") UBSAN_CHECK(SignedIntegerOverflow, "signed-integer-overflow", "signed-integer-overflow") @@ -34,6 +36,12 @@ UBSAN_CHECK(ImplicitUnsignedIntegerTruncation, UBSAN_CHECK(ImplicitSignedIntegerTruncation, "implicit-signed-integer-truncation", "implicit-signed-integer-truncation") +UBSAN_CHECK(ImplicitIntegerSignChange, + "implicit-integer-sign-change", + "implicit-integer-sign-change") +UBSAN_CHECK(ImplicitSignedIntegerTruncationOrSignChange, + "implicit-signed-integer-truncation-or-sign-change", + "implicit-signed-integer-truncation,implicit-integer-sign-change") UBSAN_CHECK(InvalidShiftBase, "invalid-shift-base", "shift-base") UBSAN_CHECK(InvalidShiftExponent, "invalid-shift-exponent", "shift-exponent") UBSAN_CHECK(OutOfBoundsIndex, "out-of-bounds-index", "bounds") diff --git a/libsanitizer/ubsan/ubsan_diag.cc b/libsanitizer/ubsan/ubsan_diag.cpp similarity index 93% rename from libsanitizer/ubsan/ubsan_diag.cc rename to libsanitizer/ubsan/ubsan_diag.cpp index cdf15b70e26..c8f7960db42 100644 --- a/libsanitizer/ubsan/ubsan_diag.cc +++ b/libsanitizer/ubsan/ubsan_diag.cpp @@ -1,7 +1,8 @@ -//===-- ubsan_diag.cc -----------------------------------------------------===// +//===-- ubsan_diag.cpp ----------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -25,13 +26,21 @@ using namespace __ubsan; -void __ubsan::GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, - uptr bp, void *context, bool fast) { +// UBSan is combined with runtimes that already provide this functionality +// (e.g., ASan) as well as runtimes that lack it (e.g., scudo). Tried to use +// weak linkage to resolve this issue which is not portable and breaks on +// Windows. +// TODO(yln): This is a temporary workaround. GetStackTrace functions will be +// removed in the future. +void ubsan_GetStackTrace(BufferedStackTrace *stack, uptr max_depth, + uptr pc, uptr bp, void *context, bool fast) { uptr top = 0; uptr bottom = 0; - if (fast) + if (StackTrace::WillUseFastUnwind(fast)) { GetThreadStackTopAndBottom(false, &top, &bottom); - stack->Unwind(max_depth, pc, bp, context, top, bottom, fast); + stack->Unwind(max_depth, pc, bp, nullptr, top, bottom, true); + } else + stack->Unwind(max_depth, pc, bp, context, 0, 0, false); } static void MaybePrintStackTrace(uptr pc, uptr bp) { @@ -41,7 +50,7 @@ static void MaybePrintStackTrace(uptr pc, uptr bp) { return; BufferedStackTrace stack; - GetStackTrace(&stack, kStackTraceMax, pc, bp, nullptr, + ubsan_GetStackTrace(&stack, kStackTraceMax, pc, bp, nullptr, common_flags()->fast_unwind_on_fatal); stack.Print(); } diff --git a/libsanitizer/ubsan/ubsan_diag.h b/libsanitizer/ubsan/ubsan_diag.h index 429a9ecd69d..b444e971b22 100644 --- a/libsanitizer/ubsan/ubsan_diag.h +++ b/libsanitizer/ubsan/ubsan_diag.h @@ -1,7 +1,8 @@ //===-- ubsan_diag.h --------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -233,9 +234,6 @@ bool ignoreReport(SourceLocation SLoc, ReportOptions Opts, ErrorType ET); GET_CALLER_PC_BP; \ ReportOptions Opts = {unrecoverable_handler, pc, bp} -void GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, uptr bp, - void *context, bool fast); - /// \brief Instantiate this class before printing diagnostics in the error /// report. This class ensures that reports from different threads and from /// different sanitizers won't be mixed. diff --git a/libsanitizer/ubsan/ubsan_diag_standalone.cc b/libsanitizer/ubsan/ubsan_diag_standalone.cc deleted file mode 100644 index ddc1be7018c..00000000000 --- a/libsanitizer/ubsan/ubsan_diag_standalone.cc +++ /dev/null @@ -1,36 +0,0 @@ -//===-- ubsan_diag_standalone.cc ------------------------------------------===// -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. -// -//===----------------------------------------------------------------------===// -// -// Diagnostic reporting for the standalone UBSan runtime. -// -//===----------------------------------------------------------------------===// - -#include "ubsan_platform.h" -#if CAN_SANITIZE_UB -#include "ubsan_diag.h" - -using namespace __ubsan; - -extern "C" { -SANITIZER_INTERFACE_ATTRIBUTE -void __sanitizer_print_stack_trace() { - uptr top = 0; - uptr bottom = 0; - bool request_fast_unwind = common_flags()->fast_unwind_on_fatal; - if (request_fast_unwind) - __sanitizer::GetThreadStackTopAndBottom(false, &top, &bottom); - - GET_CURRENT_PC_BP_SP; - (void)sp; - BufferedStackTrace stack; - stack.Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, - request_fast_unwind); - stack.Print(); -} -} // extern "C" - -#endif // CAN_SANITIZE_UB diff --git a/libsanitizer/ubsan/ubsan_diag_standalone.cpp b/libsanitizer/ubsan/ubsan_diag_standalone.cpp new file mode 100644 index 00000000000..300179adae2 --- /dev/null +++ b/libsanitizer/ubsan/ubsan_diag_standalone.cpp @@ -0,0 +1,40 @@ +//===-- 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. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Diagnostic reporting for the standalone UBSan runtime. +// +//===----------------------------------------------------------------------===// + +#include "ubsan_platform.h" +#if CAN_SANITIZE_UB +#include "ubsan_diag.h" + +using namespace __ubsan; + +void __sanitizer::BufferedStackTrace::UnwindImpl( + uptr pc, uptr bp, void *context, bool request_fast, u32 max_depth) { + uptr top = 0; + uptr bottom = 0; + if (StackTrace::WillUseFastUnwind(request_fast)) { + GetThreadStackTopAndBottom(false, &top, &bottom); + Unwind(max_depth, pc, bp, nullptr, top, bottom, true); + } else + Unwind(max_depth, pc, bp, context, 0, 0, false); +} + +extern "C" { +SANITIZER_INTERFACE_ATTRIBUTE +void __sanitizer_print_stack_trace() { + GET_CURRENT_PC_BP; + BufferedStackTrace stack; + stack.Unwind(pc, bp, nullptr, common_flags()->fast_unwind_on_fatal); + stack.Print(); +} +} // extern "C" + +#endif // CAN_SANITIZE_UB diff --git a/libsanitizer/ubsan/ubsan_flags.cc b/libsanitizer/ubsan/ubsan_flags.cpp similarity index 86% rename from libsanitizer/ubsan/ubsan_flags.cc rename to libsanitizer/ubsan/ubsan_flags.cpp index a7ecc755e46..80de2a6d101 100644 --- a/libsanitizer/ubsan/ubsan_flags.cc +++ b/libsanitizer/ubsan/ubsan_flags.cpp @@ -1,7 +1,8 @@ -//===-- ubsan_flags.cc ----------------------------------------------------===// +//===-- ubsan_flags.cpp ---------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -68,7 +69,7 @@ void InitializeFlags() { // Override from user-specified string. parser.ParseString(MaybeCallUbsanDefaultOptions()); // Override from environment variable. - parser.ParseString(GetFlag("UBSAN_OPTIONS")); + parser.ParseStringFromEnv("UBSAN_OPTIONS"); InitializeCommonFlags(); if (Verbosity()) ReportUnrecognizedFlags(); diff --git a/libsanitizer/ubsan/ubsan_flags.h b/libsanitizer/ubsan/ubsan_flags.h index 2604b6b00cc..daa0d7c701e 100644 --- a/libsanitizer/ubsan/ubsan_flags.h +++ b/libsanitizer/ubsan/ubsan_flags.h @@ -1,7 +1,8 @@ //===-- ubsan_flags.h -------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/ubsan/ubsan_flags.inc b/libsanitizer/ubsan/ubsan_flags.inc index 438ea0b81be..a4d0e6109e3 100644 --- a/libsanitizer/ubsan/ubsan_flags.inc +++ b/libsanitizer/ubsan/ubsan_flags.inc @@ -1,7 +1,8 @@ //===-- ubsan_flags.inc -----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -23,5 +24,5 @@ UBSAN_FLAG(const char *, suppressions, "", "Suppressions file name.") UBSAN_FLAG(bool, report_error_type, false, "Print specific error type instead of 'undefined-behavior' in summary.") UBSAN_FLAG(bool, silence_unsigned_overflow, false, - "Do not print error reports for unsigned integer overflow. " - "Used to provide fuzzing signal without blowing up logs.") + "Do not print non-fatal error reports for unsigned integer overflow. " + "Used to provide fuzzing signal without blowing up logs.") diff --git a/libsanitizer/ubsan/ubsan_handlers.cc b/libsanitizer/ubsan/ubsan_handlers.cpp similarity index 90% rename from libsanitizer/ubsan/ubsan_handlers.cc rename to libsanitizer/ubsan/ubsan_handlers.cpp index f67b9e30fb9..e832581f9dc 100644 --- a/libsanitizer/ubsan/ubsan_handlers.cc +++ b/libsanitizer/ubsan/ubsan_handlers.cpp @@ -1,7 +1,8 @@ -//===-- ubsan_handlers.cc -------------------------------------------------===// +//===-- ubsan_handlers.cpp ------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -104,6 +105,62 @@ void __ubsan::__ubsan_handle_type_mismatch_v1_abort(TypeMismatchData *Data, Die(); } +static void handleAlignmentAssumptionImpl(AlignmentAssumptionData *Data, + ValueHandle Pointer, + ValueHandle Alignment, + ValueHandle Offset, + ReportOptions Opts) { + Location Loc = Data->Loc.acquire(); + SourceLocation AssumptionLoc = Data->AssumptionLoc.acquire(); + + ErrorType ET = ErrorType::AlignmentAssumption; + + if (ignoreReport(Loc.getSourceLocation(), Opts, ET)) + return; + + ScopedReport R(Opts, Loc, ET); + + uptr RealPointer = Pointer - Offset; + uptr LSB = LeastSignificantSetBitIndex(RealPointer); + uptr ActualAlignment = uptr(1) << LSB; + + uptr Mask = Alignment - 1; + uptr MisAlignmentOffset = RealPointer & Mask; + + if (!Offset) { + Diag(Loc, DL_Error, ET, + "assumption of %0 byte alignment for pointer of type %1 failed") + << Alignment << Data->Type; + } else { + Diag(Loc, DL_Error, ET, + "assumption of %0 byte alignment (with offset of %1 byte) for pointer " + "of type %2 failed") + << Alignment << Offset << Data->Type; + } + + if (!AssumptionLoc.isInvalid()) + Diag(AssumptionLoc, DL_Note, ET, "alignment assumption was specified here"); + + Diag(RealPointer, DL_Note, ET, + "%0address is %1 aligned, misalignment offset is %2 bytes") + << (Offset ? "offset " : "") << ActualAlignment << MisAlignmentOffset; +} + +void __ubsan::__ubsan_handle_alignment_assumption(AlignmentAssumptionData *Data, + ValueHandle Pointer, + ValueHandle Alignment, + ValueHandle Offset) { + GET_REPORT_OPTIONS(false); + handleAlignmentAssumptionImpl(Data, Pointer, Alignment, Offset, Opts); +} +void __ubsan::__ubsan_handle_alignment_assumption_abort( + AlignmentAssumptionData *Data, ValueHandle Pointer, ValueHandle Alignment, + ValueHandle Offset) { + GET_REPORT_OPTIONS(true); + handleAlignmentAssumptionImpl(Data, Pointer, Alignment, Offset, Opts); + Die(); +} + /// \brief Common diagnostic emission for various forms of integer overflow. template static void handleIntegerOverflowImpl(OverflowData *Data, ValueHandle LHS, @@ -117,7 +174,9 @@ static void handleIntegerOverflowImpl(OverflowData *Data, ValueHandle LHS, if (ignoreReport(Loc, Opts, ET)) return; - if (!IsSigned && flags()->silence_unsigned_overflow) + // If this is an unsigned overflow in non-fatal mode, potentially ignore it. + if (!IsSigned && !Opts.FromUnrecoverableHandler && + flags()->silence_unsigned_overflow) return; ScopedReport R(Opts, Loc, ET); @@ -479,6 +538,12 @@ static void handleImplicitConversion(ImplicitConversionData *Data, case ICCK_SignedIntegerTruncation: ET = ErrorType::ImplicitSignedIntegerTruncation; break; + case ICCK_IntegerSignChange: + ET = ErrorType::ImplicitIntegerSignChange; + break; + case ICCK_SignedIntegerTruncationOrSignChange: + ET = ErrorType::ImplicitSignedIntegerTruncationOrSignChange; + break; } if (ignoreReport(Loc, Opts, ET)) @@ -533,42 +598,6 @@ void __ubsan::__ubsan_handle_invalid_builtin_abort(InvalidBuiltinData *Data) { Die(); } -static void handleFunctionTypeMismatch(FunctionTypeMismatchData *Data, - ValueHandle Function, - ReportOptions Opts) { - SourceLocation CallLoc = Data->Loc.acquire(); - ErrorType ET = ErrorType::FunctionTypeMismatch; - - if (ignoreReport(CallLoc, Opts, ET)) - return; - - ScopedReport R(Opts, CallLoc, ET); - - SymbolizedStackHolder FLoc(getSymbolizedLocation(Function)); - const char *FName = FLoc.get()->info.function; - if (!FName) - FName = "(unknown)"; - - Diag(CallLoc, DL_Error, ET, - "call to function %0 through pointer to incorrect function type %1") - << FName << Data->Type; - Diag(FLoc, DL_Note, ET, "%0 defined here") << FName; -} - -void -__ubsan::__ubsan_handle_function_type_mismatch(FunctionTypeMismatchData *Data, - ValueHandle Function) { - GET_REPORT_OPTIONS(false); - handleFunctionTypeMismatch(Data, Function, Opts); -} - -void __ubsan::__ubsan_handle_function_type_mismatch_abort( - FunctionTypeMismatchData *Data, ValueHandle Function) { - GET_REPORT_OPTIONS(true); - handleFunctionTypeMismatch(Data, Function, Opts); - Die(); -} - static void handleNonNullReturn(NonNullReturnData *Data, SourceLocation *LocPtr, ReportOptions Opts, bool IsAttr) { if (!LocPtr) @@ -771,21 +800,6 @@ void __ubsan_handle_cfi_bad_type(CFICheckFailData *Data, ValueHandle Vtable, } // namespace __ubsan -void __ubsan::__ubsan_handle_cfi_bad_icall(CFIBadIcallData *CallData, - ValueHandle Function) { - GET_REPORT_OPTIONS(false); - CFICheckFailData Data = {CFITCK_ICall, CallData->Loc, CallData->Type}; - handleCFIBadIcall(&Data, Function, Opts); -} - -void __ubsan::__ubsan_handle_cfi_bad_icall_abort(CFIBadIcallData *CallData, - ValueHandle Function) { - GET_REPORT_OPTIONS(true); - CFICheckFailData Data = {CFITCK_ICall, CallData->Loc, CallData->Type}; - handleCFIBadIcall(&Data, Function, Opts); - Die(); -} - void __ubsan::__ubsan_handle_cfi_check_fail(CFICheckFailData *Data, ValueHandle Value, uptr ValidVtable) { diff --git a/libsanitizer/ubsan/ubsan_handlers.h b/libsanitizer/ubsan/ubsan_handlers.h index 87e3c3439b6..22ca9642238 100644 --- a/libsanitizer/ubsan/ubsan_handlers.h +++ b/libsanitizer/ubsan/ubsan_handlers.h @@ -1,7 +1,8 @@ //===-- ubsan_handlers.h ----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -37,6 +38,17 @@ struct TypeMismatchData { /// type. RECOVERABLE(type_mismatch_v1, TypeMismatchData *Data, ValueHandle Pointer) +struct AlignmentAssumptionData { + SourceLocation Loc; + SourceLocation AssumptionLoc; + const TypeDescriptor &Type; +}; + +/// \brief Handle a runtime alignment assumption check failure, +/// caused by a misaligned pointer. +RECOVERABLE(alignment_assumption, AlignmentAssumptionData *Data, + ValueHandle Pointer, ValueHandle Alignment, ValueHandle Offset) + struct OverflowData { SourceLocation Loc; const TypeDescriptor &Type; @@ -126,6 +138,8 @@ enum ImplicitConversionCheckKind : unsigned char { ICCK_IntegerTruncation = 0, // Legacy, was only used by clang 7. ICCK_UnsignedIntegerTruncation = 1, ICCK_SignedIntegerTruncation = 2, + ICCK_IntegerSignChange = 3, + ICCK_SignedIntegerTruncationOrSignChange = 4, }; struct ImplicitConversionData { @@ -154,15 +168,6 @@ struct InvalidBuiltinData { /// Handle a builtin called in an invalid way. RECOVERABLE(invalid_builtin, InvalidBuiltinData *Data) -struct FunctionTypeMismatchData { - SourceLocation Loc; - const TypeDescriptor &Type; -}; - -RECOVERABLE(function_type_mismatch, - FunctionTypeMismatchData *Data, - ValueHandle Val) - struct NonNullReturnData { SourceLocation AttrLoc; }; @@ -202,20 +207,12 @@ enum CFITypeCheckKind : unsigned char { CFITCK_VMFCall, }; -struct CFIBadIcallData { - SourceLocation Loc; - const TypeDescriptor &Type; -}; - struct CFICheckFailData { CFITypeCheckKind CheckKind; SourceLocation Loc; const TypeDescriptor &Type; }; -/// \brief Handle control flow integrity failure for indirect function calls. -RECOVERABLE(cfi_bad_icall, CFIBadIcallData *Data, ValueHandle Function) - /// \brief Handle control flow integrity failures. RECOVERABLE(cfi_check_fail, CFICheckFailData *Data, ValueHandle Function, uptr VtableIsValid) diff --git a/libsanitizer/ubsan/ubsan_handlers_cxx.cc b/libsanitizer/ubsan/ubsan_handlers_cxx.cpp similarity index 74% rename from libsanitizer/ubsan/ubsan_handlers_cxx.cc rename to libsanitizer/ubsan/ubsan_handlers_cxx.cpp index 912617010a8..2a6d558de03 100644 --- a/libsanitizer/ubsan/ubsan_handlers_cxx.cc +++ b/libsanitizer/ubsan/ubsan_handlers_cxx.cpp @@ -1,7 +1,8 @@ -//===-- ubsan_handlers_cxx.cc ---------------------------------------------===// +//===-- ubsan_handlers_cxx.cpp --------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -155,6 +156,50 @@ void __ubsan_handle_cfi_bad_type(CFICheckFailData *Data, ValueHandle Vtable, Diag(Loc, DL_Note, ET, "check failed in %0, vtable located in %1") << SrcModule << DstModule; } + +static bool handleFunctionTypeMismatch(FunctionTypeMismatchData *Data, + ValueHandle Function, + ValueHandle calleeRTTI, + ValueHandle fnRTTI, ReportOptions Opts) { + if (checkTypeInfoEquality(reinterpret_cast(calleeRTTI), + reinterpret_cast(fnRTTI))) + return false; + + SourceLocation CallLoc = Data->Loc.acquire(); + ErrorType ET = ErrorType::FunctionTypeMismatch; + + if (ignoreReport(CallLoc, Opts, ET)) + return true; + + ScopedReport R(Opts, CallLoc, ET); + + SymbolizedStackHolder FLoc(getSymbolizedLocation(Function)); + const char *FName = FLoc.get()->info.function; + if (!FName) + FName = "(unknown)"; + + Diag(CallLoc, DL_Error, ET, + "call to function %0 through pointer to incorrect function type %1") + << FName << Data->Type; + Diag(FLoc, DL_Note, ET, "%0 defined here") << FName; + return true; +} + +void __ubsan_handle_function_type_mismatch_v1(FunctionTypeMismatchData *Data, + ValueHandle Function, + ValueHandle calleeRTTI, + ValueHandle fnRTTI) { + GET_REPORT_OPTIONS(false); + handleFunctionTypeMismatch(Data, Function, calleeRTTI, fnRTTI, Opts); +} + +void __ubsan_handle_function_type_mismatch_v1_abort( + FunctionTypeMismatchData *Data, ValueHandle Function, + ValueHandle calleeRTTI, ValueHandle fnRTTI) { + GET_REPORT_OPTIONS(true); + if (handleFunctionTypeMismatch(Data, Function, calleeRTTI, fnRTTI, Opts)) + Die(); +} } // namespace __ubsan #endif // CAN_SANITIZE_UB diff --git a/libsanitizer/ubsan/ubsan_handlers_cxx.h b/libsanitizer/ubsan/ubsan_handlers_cxx.h index 37382359b1e..f7b9fc54f47 100644 --- a/libsanitizer/ubsan/ubsan_handlers_cxx.h +++ b/libsanitizer/ubsan/ubsan_handlers_cxx.h @@ -1,7 +1,8 @@ //===-- ubsan_handlers_cxx.h ------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -32,6 +33,22 @@ void __ubsan_handle_dynamic_type_cache_miss( extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __ubsan_handle_dynamic_type_cache_miss_abort( DynamicTypeCacheMissData *Data, ValueHandle Pointer, ValueHandle Hash); + +struct FunctionTypeMismatchData { + SourceLocation Loc; + const TypeDescriptor &Type; +}; + +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void +__ubsan_handle_function_type_mismatch_v1(FunctionTypeMismatchData *Data, + ValueHandle Val, + ValueHandle calleeRTTI, + ValueHandle fnRTTI); +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void +__ubsan_handle_function_type_mismatch_v1_abort(FunctionTypeMismatchData *Data, + ValueHandle Val, + ValueHandle calleeRTTI, + ValueHandle fnRTTI); } #endif // UBSAN_HANDLERS_H diff --git a/libsanitizer/ubsan/ubsan_init.cc b/libsanitizer/ubsan/ubsan_init.cpp similarity index 84% rename from libsanitizer/ubsan/ubsan_init.cc rename to libsanitizer/ubsan/ubsan_init.cpp index 9ae17f59ea1..1a3b7d37267 100644 --- a/libsanitizer/ubsan/ubsan_init.cc +++ b/libsanitizer/ubsan/ubsan_init.cpp @@ -1,7 +1,8 @@ -//===-- ubsan_init.cc -----------------------------------------------------===// +//===-- ubsan_init.cpp ----------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/ubsan/ubsan_init.h b/libsanitizer/ubsan/ubsan_init.h index 73bd3f3580f..0510385b13d 100644 --- a/libsanitizer/ubsan/ubsan_init.h +++ b/libsanitizer/ubsan/ubsan_init.h @@ -1,7 +1,8 @@ //===-- ubsan_init.h --------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/ubsan/ubsan_init_standalone.cc b/libsanitizer/ubsan/ubsan_init_standalone.cpp similarity index 72% rename from libsanitizer/ubsan/ubsan_init_standalone.cc rename to libsanitizer/ubsan/ubsan_init_standalone.cpp index 67223bea629..91c3f57b424 100644 --- a/libsanitizer/ubsan/ubsan_init_standalone.cc +++ b/libsanitizer/ubsan/ubsan_init_standalone.cpp @@ -1,7 +1,8 @@ -//===-- ubsan_init_standalone.cc ------------------------------------------===// +//===-- ubsan_init_standalone.cpp -----------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/ubsan/ubsan_init_standalone_preinit.cc b/libsanitizer/ubsan/ubsan_init_standalone_preinit.cpp similarity index 75% rename from libsanitizer/ubsan/ubsan_init_standalone_preinit.cc rename to libsanitizer/ubsan/ubsan_init_standalone_preinit.cpp index fd26b49e4e7..fabbf919a40 100644 --- a/libsanitizer/ubsan/ubsan_init_standalone_preinit.cc +++ b/libsanitizer/ubsan/ubsan_init_standalone_preinit.cpp @@ -1,7 +1,8 @@ -//===-- ubsan_init_standalone_preinit.cc ---------------------------------===// +//===-- ubsan_init_standalone_preinit.cpp --------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/ubsan/ubsan_interface.inc b/libsanitizer/ubsan/ubsan_interface.inc index ef0842d9339..1e44bc2171d 100644 --- a/libsanitizer/ubsan/ubsan_interface.inc +++ b/libsanitizer/ubsan/ubsan_interface.inc @@ -1,13 +1,16 @@ //===-- ubsan_interface.inc -----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // Ubsan interface list. //===----------------------------------------------------------------------===// INTERFACE_FUNCTION(__ubsan_handle_add_overflow) INTERFACE_FUNCTION(__ubsan_handle_add_overflow_abort) +INTERFACE_FUNCTION(__ubsan_handle_alignment_assumption) +INTERFACE_FUNCTION(__ubsan_handle_alignment_assumption_abort) INTERFACE_FUNCTION(__ubsan_handle_builtin_unreachable) INTERFACE_FUNCTION(__ubsan_handle_cfi_bad_type) INTERFACE_FUNCTION(__ubsan_handle_cfi_check_fail) @@ -18,8 +21,8 @@ INTERFACE_FUNCTION(__ubsan_handle_dynamic_type_cache_miss) INTERFACE_FUNCTION(__ubsan_handle_dynamic_type_cache_miss_abort) INTERFACE_FUNCTION(__ubsan_handle_float_cast_overflow) INTERFACE_FUNCTION(__ubsan_handle_float_cast_overflow_abort) -INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch) -INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_abort) +INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_v1) +INTERFACE_FUNCTION(__ubsan_handle_function_type_mismatch_v1_abort) INTERFACE_FUNCTION(__ubsan_handle_implicit_conversion) INTERFACE_FUNCTION(__ubsan_handle_implicit_conversion_abort) INTERFACE_FUNCTION(__ubsan_handle_invalid_builtin) diff --git a/libsanitizer/ubsan/ubsan_monitor.cc b/libsanitizer/ubsan/ubsan_monitor.cpp similarity index 90% rename from libsanitizer/ubsan/ubsan_monitor.cc rename to libsanitizer/ubsan/ubsan_monitor.cpp index 81180a63917..d064e95f76f 100644 --- a/libsanitizer/ubsan/ubsan_monitor.cc +++ b/libsanitizer/ubsan/ubsan_monitor.cpp @@ -1,7 +1,8 @@ -//===-- ubsan_monitor.cc ----------------------------------------*- C++ -*-===// +//===-- ubsan_monitor.cpp ---------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/ubsan/ubsan_monitor.h b/libsanitizer/ubsan/ubsan_monitor.h index 632bd256e7e..3bfd7be8916 100644 --- a/libsanitizer/ubsan/ubsan_monitor.h +++ b/libsanitizer/ubsan/ubsan_monitor.h @@ -1,7 +1,8 @@ //===-- ubsan_monitor.h -----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/ubsan/ubsan_platform.h b/libsanitizer/ubsan/ubsan_platform.h index 67c4e079724..71d7fb18c9b 100644 --- a/libsanitizer/ubsan/ubsan_platform.h +++ b/libsanitizer/ubsan/ubsan_platform.h @@ -1,7 +1,8 @@ //===-- ubsan_platform.h ----------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -11,7 +12,6 @@ #ifndef UBSAN_PLATFORM_H #define UBSAN_PLATFORM_H -#ifndef CAN_SANITIZE_UB // Other platforms should be easy to add, and probably work as-is. #if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \ defined(__NetBSD__) || defined(__OpenBSD__) || \ @@ -21,6 +21,5 @@ #else # define CAN_SANITIZE_UB 0 #endif -#endif //CAN_SANITIZE_UB #endif diff --git a/libsanitizer/ubsan/ubsan_signals_standalone.cc b/libsanitizer/ubsan/ubsan_signals_standalone.cpp similarity index 77% rename from libsanitizer/ubsan/ubsan_signals_standalone.cc rename to libsanitizer/ubsan/ubsan_signals_standalone.cpp index 5e77c60b1db..627b3c4d89b 100644 --- a/libsanitizer/ubsan/ubsan_signals_standalone.cc +++ b/libsanitizer/ubsan/ubsan_signals_standalone.cpp @@ -1,10 +1,8 @@ -//=-- ubsan_signals_standalone.cc -//------------------------------------------------===// +//=-- ubsan_signals_standalone.cpp ----------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -39,11 +37,15 @@ void InitializeDeadlySignals() {} #define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name) #include "sanitizer_common/sanitizer_signal_interceptors.inc" +// TODO(yln): Temporary workaround. Will be removed. +void ubsan_GetStackTrace(BufferedStackTrace *stack, uptr max_depth, + uptr pc, uptr bp, void *context, bool fast); + namespace __ubsan { static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { - GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context, + ubsan_GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context, common_flags()->fast_unwind_on_fatal); } diff --git a/libsanitizer/ubsan/ubsan_signals_standalone.h b/libsanitizer/ubsan/ubsan_signals_standalone.h index b29c29482ec..128eff266fb 100644 --- a/libsanitizer/ubsan/ubsan_signals_standalone.h +++ b/libsanitizer/ubsan/ubsan_signals_standalone.h @@ -1,10 +1,9 @@ //=-- ubsan_signals_standalone.h //------------------------------------------------===// // -// The LLVM Compiler Infrastructure -// -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/ubsan/ubsan_type_hash.cc b/libsanitizer/ubsan/ubsan_type_hash.cpp similarity index 76% rename from libsanitizer/ubsan/ubsan_type_hash.cc rename to libsanitizer/ubsan/ubsan_type_hash.cpp index 65160aa4aba..8f4b9aee50b 100644 --- a/libsanitizer/ubsan/ubsan_type_hash.cc +++ b/libsanitizer/ubsan/ubsan_type_hash.cpp @@ -1,7 +1,8 @@ -//===-- ubsan_type_hash.cc ------------------------------------------------===// +//===-- ubsan_type_hash.cpp -----------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -10,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/libsanitizer/ubsan/ubsan_type_hash.h b/libsanitizer/ubsan/ubsan_type_hash.h index 610fcb44ea7..e42884b765a 100644 --- a/libsanitizer/ubsan/ubsan_type_hash.h +++ b/libsanitizer/ubsan/ubsan_type_hash.h @@ -1,7 +1,8 @@ //===-- ubsan_type_hash.h ---------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -63,6 +64,10 @@ const int VptrMaxOffsetToTop = 1<<20; extern "C" SANITIZER_INTERFACE_ATTRIBUTE HashValue __ubsan_vptr_type_cache[VptrTypeCacheSize]; +/// \brief Do whatever is required by the ABI to check for std::type_info +/// equivalence beyond simple pointer comparison. +bool checkTypeInfoEquality(const void *TypeInfo1, const void *TypeInfo2); + } // namespace __ubsan #endif // UBSAN_TYPE_HASH_H diff --git a/libsanitizer/ubsan/ubsan_type_hash_itanium.cc b/libsanitizer/ubsan/ubsan_type_hash_itanium.cpp similarity index 92% rename from libsanitizer/ubsan/ubsan_type_hash_itanium.cc rename to libsanitizer/ubsan/ubsan_type_hash_itanium.cpp index bff78887396..97846d4dd43 100644 --- a/libsanitizer/ubsan/ubsan_type_hash_itanium.cc +++ b/libsanitizer/ubsan/ubsan_type_hash_itanium.cpp @@ -1,7 +1,8 @@ -//===-- ubsan_type_hash_itanium.cc ----------------------------------------===// +//===-- ubsan_type_hash_itanium.cpp ---------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -116,9 +117,7 @@ static bool isDerivedFromAtOffset(const abi::__class_type_info *Derived, const abi::__class_type_info *Base, sptr Offset) { if (Derived->__type_name == Base->__type_name || - (SANITIZER_NON_UNIQUE_TYPEINFO && - Derived->__type_name[0] != '*' && - !internal_strcmp(Derived->__type_name, Base->__type_name))) + __ubsan::checkTypeInfoEquality(Derived, Base)) return Offset == 0; if (const abi::__si_class_type_info *SI = @@ -257,4 +256,13 @@ __ubsan::getDynamicTypeInfoFromVtable(void *VtablePtr) { ObjectType ? ObjectType->__type_name : ""); } +bool __ubsan::checkTypeInfoEquality(const void *TypeInfo1, + const void *TypeInfo2) { + auto TI1 = static_cast(TypeInfo1); + auto TI2 = static_cast(TypeInfo2); + return SANITIZER_NON_UNIQUE_TYPEINFO && TI1->__type_name[0] != '*' && + TI2->__type_name[0] != '*' && + !internal_strcmp(TI1->__type_name, TI2->__type_name); +} + #endif // CAN_SANITIZE_UB && !SANITIZER_WINDOWS diff --git a/libsanitizer/ubsan/ubsan_type_hash_win.cc b/libsanitizer/ubsan/ubsan_type_hash_win.cpp similarity index 87% rename from libsanitizer/ubsan/ubsan_type_hash_win.cc rename to libsanitizer/ubsan/ubsan_type_hash_win.cpp index a2eb1a71cb9..45dcb758ec4 100644 --- a/libsanitizer/ubsan/ubsan_type_hash_win.cc +++ b/libsanitizer/ubsan/ubsan_type_hash_win.cpp @@ -1,7 +1,8 @@ -//===-- ubsan_type_hash_win.cc --------------------------------------------===// +//===-- ubsan_type_hash_win.cpp -------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // @@ -76,4 +77,8 @@ __ubsan::getDynamicTypeInfoFromVtable(void *VtablePtr) { ""); } +bool __ubsan::checkTypeInfoEquality(const void *, const void *) { + return false; +} + #endif // CAN_SANITIZE_UB && SANITIZER_WINDOWS diff --git a/libsanitizer/ubsan/ubsan_value.cc b/libsanitizer/ubsan/ubsan_value.cpp similarity index 92% rename from libsanitizer/ubsan/ubsan_value.cc rename to libsanitizer/ubsan/ubsan_value.cpp index 3e158f92e07..60f0b5c9934 100644 --- a/libsanitizer/ubsan/ubsan_value.cc +++ b/libsanitizer/ubsan/ubsan_value.cpp @@ -1,7 +1,8 @@ -//===-- ubsan_value.cc ----------------------------------------------------===// +//===-- ubsan_value.cpp ---------------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/ubsan/ubsan_value.h b/libsanitizer/ubsan/ubsan_value.h index cca1ac85b77..a216e3a147e 100644 --- a/libsanitizer/ubsan/ubsan_value.h +++ b/libsanitizer/ubsan/ubsan_value.h @@ -1,7 +1,8 @@ //===-- ubsan_value.h -------------------------------------------*- C++ -*-===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/ubsan/ubsan_win_dll_thunk.cc b/libsanitizer/ubsan/ubsan_win_dll_thunk.cpp similarity index 74% rename from libsanitizer/ubsan/ubsan_win_dll_thunk.cc rename to libsanitizer/ubsan/ubsan_win_dll_thunk.cpp index 1091ac0351a..5ac7fc3e08e 100644 --- a/libsanitizer/ubsan/ubsan_win_dll_thunk.cc +++ b/libsanitizer/ubsan/ubsan_win_dll_thunk.cpp @@ -1,7 +1,8 @@ -//===-- ubsan_win_dll_thunk.cc --------------------------------------------===// +//===-- ubsan_win_dll_thunk.cpp -------------------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/ubsan/ubsan_win_dynamic_runtime_thunk.cc b/libsanitizer/ubsan/ubsan_win_dynamic_runtime_thunk.cpp similarity index 72% rename from libsanitizer/ubsan/ubsan_win_dynamic_runtime_thunk.cc rename to libsanitizer/ubsan/ubsan_win_dynamic_runtime_thunk.cpp index 6ab5ae388a3..00722b4033a 100644 --- a/libsanitizer/ubsan/ubsan_win_dynamic_runtime_thunk.cc +++ b/libsanitizer/ubsan/ubsan_win_dynamic_runtime_thunk.cpp @@ -1,7 +1,8 @@ -//===-- ubsan_win_dynamic_runtime_thunk.cc --------------------------------===// +//===-- ubsan_win_dynamic_runtime_thunk.cpp -------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 // //===----------------------------------------------------------------------===// // diff --git a/libsanitizer/ubsan/ubsan_win_weak_interception.cc b/libsanitizer/ubsan/ubsan_win_weak_interception.cpp similarity index 77% rename from libsanitizer/ubsan/ubsan_win_weak_interception.cc rename to libsanitizer/ubsan/ubsan_win_weak_interception.cpp index 9f0a8f1d38a..01db0c0ce78 100644 --- a/libsanitizer/ubsan/ubsan_win_weak_interception.cc +++ b/libsanitizer/ubsan/ubsan_win_weak_interception.cpp @@ -1,7 +1,8 @@ -//===-- ubsan_win_weak_interception.cc ------------------------------------===// +//===-- ubsan_win_weak_interception.cpp -----------------------------------===// // -// This file is distributed under the University of Illinois Open Source -// License. See LICENSE.TXT for details. +// 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 module should be included in Ubsan when it is implemented as a shared -- 2.30.2