From eac975312214dccb9d425b3e8d0b93e85c11ddf4 Mon Sep 17 00:00:00 2001 From: Martin Liska Date: Wed, 31 Oct 2018 12:14:23 +0100 Subject: [PATCH] backport: All source files: Merge from upstream 345033. Merge from upstream 345033. 2018-10-31 Martin Liska * All source files: Merge from upstream 345033. From-SVN: r265665 --- libsanitizer/ChangeLog | 4 + libsanitizer/MERGE | 2 +- libsanitizer/asan/asan_activation.cc | 7 +- libsanitizer/asan/asan_allocator.cc | 166 +- libsanitizer/asan/asan_allocator.h | 9 +- libsanitizer/asan/asan_debugging.cc | 3 +- libsanitizer/asan/asan_descriptions.cc | 71 +- libsanitizer/asan/asan_descriptions.h | 18 +- libsanitizer/asan/asan_errors.cc | 204 +- libsanitizer/asan/asan_errors.h | 281 +- libsanitizer/asan/asan_fake_stack.cc | 4 +- libsanitizer/asan/asan_flags.cc | 12 +- libsanitizer/asan/asan_flags.inc | 3 +- libsanitizer/asan/asan_fuchsia.cc | 2 +- libsanitizer/asan/asan_globals.cc | 30 +- libsanitizer/asan/asan_globals_win.cc | 6 +- libsanitizer/asan/asan_init_version.h | 7 + libsanitizer/asan/asan_interceptors.cc | 59 +- libsanitizer/asan/asan_interceptors.h | 28 +- .../asan/asan_interceptors_memintrinsics.cc | 16 +- .../asan/asan_interceptors_memintrinsics.h | 25 +- libsanitizer/asan/asan_internal.h | 7 +- libsanitizer/asan/asan_linux.cc | 73 +- libsanitizer/asan/asan_lock.h | 1 - libsanitizer/asan/asan_mac.cc | 28 +- libsanitizer/asan/asan_malloc_linux.cc | 81 +- libsanitizer/asan/asan_malloc_local.h | 42 + libsanitizer/asan/asan_malloc_mac.cc | 3 + libsanitizer/asan/asan_malloc_win.cc | 15 +- libsanitizer/asan/asan_mapping.h | 142 +- libsanitizer/asan/asan_mapping_myriad.h | 84 + libsanitizer/asan/asan_memory_profile.cc | 12 +- libsanitizer/asan/asan_new_delete.cc | 128 +- libsanitizer/asan/asan_poisoning.cc | 13 +- libsanitizer/asan/asan_poisoning.h | 5 +- libsanitizer/asan/asan_posix.cc | 1 - libsanitizer/asan/asan_premap_shadow.cc | 77 + libsanitizer/asan/asan_premap_shadow.h | 28 + libsanitizer/asan/asan_report.cc | 73 +- libsanitizer/asan/asan_report.h | 19 +- libsanitizer/asan/asan_rtems.cc | 251 + libsanitizer/asan/asan_rtl.cc | 45 +- libsanitizer/asan/asan_shadow_setup.cc | 18 +- libsanitizer/asan/asan_stack.h | 48 +- libsanitizer/asan/asan_thread.cc | 30 +- libsanitizer/asan/asan_win.cc | 17 +- libsanitizer/asan/asan_win_dll_thunk.cc | 2 +- .../include/sanitizer/allocator_interface.h | 14 +- .../include/sanitizer/asan_interface.h | 24 +- .../include/sanitizer/common_interface_defs.h | 13 +- .../include/sanitizer/coverage_interface.h | 4 +- .../include/sanitizer/esan_interface.h | 4 +- .../include/sanitizer/hwasan_interface.h | 82 + .../include/sanitizer/lsan_interface.h | 14 +- .../include/sanitizer/msan_interface.h | 16 +- .../include/sanitizer/netbsd_syscall_hooks.h | 4732 +++++++++++++++++ .../include/sanitizer/scudo_interface.h | 37 + .../include/sanitizer/tsan_interface.h | 6 + libsanitizer/interception/interception.h | 57 +- .../interception/interception_linux.cc | 24 +- .../interception/interception_linux.h | 13 +- libsanitizer/interception/interception_mac.cc | 5 +- libsanitizer/interception/interception_mac.h | 4 +- .../interception/interception_type_test.cc | 9 +- libsanitizer/interception/interception_win.cc | 19 +- libsanitizer/interception/interception_win.h | 4 +- libsanitizer/lsan/lsan.cc | 9 +- libsanitizer/lsan/lsan.h | 12 +- libsanitizer/lsan/lsan_allocator.cc | 74 +- libsanitizer/lsan/lsan_allocator.h | 15 +- libsanitizer/lsan/lsan_common.cc | 48 +- libsanitizer/lsan/lsan_common.h | 13 +- libsanitizer/lsan/lsan_common_linux.cc | 20 +- libsanitizer/lsan/lsan_common_mac.cc | 11 +- libsanitizer/lsan/lsan_interceptors.cc | 70 +- libsanitizer/lsan/lsan_malloc_mac.cc | 3 + libsanitizer/lsan/lsan_thread.cc | 5 + libsanitizer/sanitizer_common/sancov_begin.S | 5 + libsanitizer/sanitizer_common/sancov_end.S | 5 + .../sanitizer_common/sanitizer_allocator.cc | 73 +- .../sanitizer_common/sanitizer_allocator.h | 38 +- .../sanitizer_allocator_bytemap.h | 4 +- .../sanitizer_allocator_checks.h | 8 +- .../sanitizer_allocator_combined.h | 16 +- .../sanitizer_allocator_interface.h | 3 + .../sanitizer_allocator_internal.h | 16 +- .../sanitizer_allocator_local_cache.h | 93 +- .../sanitizer_allocator_primary32.h | 120 +- .../sanitizer_allocator_primary64.h | 197 +- .../sanitizer_allocator_report.cc | 123 + .../sanitizer_allocator_report.h | 36 + .../sanitizer_allocator_secondary.h | 84 +- .../sanitizer_allocator_size_class_map.h | 36 +- .../sanitizer_allocator_stats.h | 2 +- libsanitizer/sanitizer_common/sanitizer_asm.h | 8 +- .../sanitizer_common/sanitizer_atomic_clang.h | 17 +- .../sanitizer_atomic_clang_mips.h | 115 + .../sanitizer_atomic_clang_other.h | 65 +- .../sanitizer_atomic_clang_x86.h | 6 +- .../sanitizer_common/sanitizer_bitvector.h | 4 +- .../sanitizer_common/sanitizer_bvgraph.h | 2 +- .../sanitizer_common/sanitizer_common.cc | 43 +- .../sanitizer_common/sanitizer_common.h | 248 +- .../sanitizer_common_interceptors.inc | 1086 +++- .../sanitizer_common_interceptors_ioctl.inc | 8 +- .../sanitizer_common_interface.inc | 2 + .../sanitizer_common_libcdep.cc | 274 +- .../sanitizer_common_nolibc.cc | 1 - .../sanitizer_coverage_fuchsia.cc | 20 +- .../sanitizer_coverage_libcdep_new.cc | 3 +- .../sanitizer_coverage_win_sections.cc | 53 +- .../sanitizer_deadlock_detector2.cc | 8 +- .../sanitizer_common/sanitizer_errno.h | 5 +- .../sanitizer_common/sanitizer_file.cc | 59 +- .../sanitizer_common/sanitizer_flag_parser.h | 4 +- .../sanitizer_common/sanitizer_flags.cc | 8 - .../sanitizer_common/sanitizer_flags.inc | 23 +- .../sanitizer_common/sanitizer_fuchsia.cc | 276 +- .../sanitizer_common/sanitizer_getauxval.h | 46 + .../sanitizer_interceptors_ioctl_netbsd.inc | 1487 ++++++ .../sanitizer_interface_internal.h | 6 + .../sanitizer_internal_defs.h | 48 +- .../sanitizer_common/sanitizer_libc.cc | 39 +- .../sanitizer_common/sanitizer_libc.h | 7 +- .../sanitizer_common/sanitizer_libignore.cc | 7 +- .../sanitizer_common/sanitizer_libignore.h | 8 +- .../sanitizer_common/sanitizer_linux.cc | 684 ++- .../sanitizer_common/sanitizer_linux.h | 36 +- .../sanitizer_linux_libcdep.cc | 489 +- .../sanitizer_common/sanitizer_linux_s390.cc | 2 +- .../sanitizer_common/sanitizer_linux_x86_64.S | 2 - .../sanitizer_common/sanitizer_mac.cc | 124 +- libsanitizer/sanitizer_common/sanitizer_mac.h | 6 +- .../sanitizer_common/sanitizer_mac_libcdep.cc | 2 +- .../sanitizer_common/sanitizer_malloc_mac.inc | 35 +- .../sanitizer_common/sanitizer_mutex.h | 11 +- .../sanitizer_common/sanitizer_netbsd.cc | 328 ++ .../sanitizer_common/sanitizer_openbsd.cc | 108 + .../sanitizer_common/sanitizer_platform.h | 67 +- .../sanitizer_platform_interceptors.h | 307 +- .../sanitizer_platform_limits_linux.cc | 7 +- .../sanitizer_platform_limits_netbsd.cc | 1952 ++++++- .../sanitizer_platform_limits_netbsd.h | 2000 ++++++- .../sanitizer_platform_limits_openbsd.cc | 277 + .../sanitizer_platform_limits_openbsd.h | 380 ++ .../sanitizer_platform_limits_posix.cc | 23 +- .../sanitizer_platform_limits_posix.h | 74 +- .../sanitizer_platform_limits_solaris.cc | 364 ++ .../sanitizer_platform_limits_solaris.h | 495 ++ .../sanitizer_common/sanitizer_posix.cc | 7 +- .../sanitizer_common/sanitizer_posix.h | 7 + .../sanitizer_posix_libcdep.cc | 83 +- .../sanitizer_common/sanitizer_printf.cc | 38 +- .../sanitizer_common/sanitizer_procmaps.h | 6 +- ...s_freebsd.cc => sanitizer_procmaps_bsd.cc} | 70 +- .../sanitizer_procmaps_common.cc | 55 +- .../sanitizer_procmaps_linux.cc | 8 +- .../sanitizer_procmaps_mac.cc | 19 +- .../sanitizer_procmaps_solaris.cc | 57 + .../sanitizer_common/sanitizer_quarantine.h | 40 +- .../sanitizer_report_decorator.h | 5 +- .../sanitizer_common/sanitizer_ring_buffer.h | 160 + .../sanitizer_common/sanitizer_rtems.cc | 280 + .../sanitizer_common/sanitizer_rtems.h | 19 + .../sanitizer_signal_interceptors.inc | 46 +- .../sanitizer_common/sanitizer_solaris.cc | 219 + .../sanitizer_common/sanitizer_stackdepot.cc | 6 +- .../sanitizer_common/sanitizer_stacktrace.cc | 25 +- .../sanitizer_common/sanitizer_stacktrace.h | 13 +- .../sanitizer_stacktrace_libcdep.cc | 24 +- .../sanitizer_stacktrace_printer.cc | 87 +- .../sanitizer_stacktrace_sparc.cc | 56 + .../sanitizer_stoptheworld_linux_libcdep.cc | 55 +- .../sanitizer_suppressions.cc | 2 +- .../sanitizer_common/sanitizer_symbolizer.h | 7 +- .../sanitizer_symbolizer_fuchsia.h | 38 + .../sanitizer_symbolizer_libcdep.cc | 11 +- ...hsia.cc => sanitizer_symbolizer_markup.cc} | 78 +- .../sanitizer_symbolizer_posix_libcdep.cc | 8 +- .../sanitizer_symbolizer_report.cc | 280 + .../sanitizer_symbolizer_rtems.h | 39 + .../sanitizer_symbolizer_win.cc | 4 - .../sanitizer_syscall_generic.inc | 33 +- .../sanitizer_syscall_linux_arm.inc | 136 + .../sanitizer_syscalls_netbsd.inc | 3784 +++++++++++++ .../sanitizer_common/sanitizer_termination.cc | 9 + .../sanitizer_thread_registry.cc | 40 +- .../sanitizer_thread_registry.h | 5 + .../sanitizer_tls_get_addr.cc | 3 +- .../sanitizer_unwind_linux_libcdep.cc | 10 +- .../sanitizer_common/sanitizer_unwind_win.cc | 73 + .../sanitizer_vector.h} | 36 +- .../sanitizer_common/sanitizer_win.cc | 178 +- .../sanitizer_common/sanitizer_win_defs.h | 20 +- .../sanitizer_win_weak_interception.cc | 2 +- libsanitizer/tsan/tsan_debugging.cc | 7 + libsanitizer/tsan/tsan_interceptors.cc | 605 ++- libsanitizer/tsan/tsan_interceptors.h | 12 + libsanitizer/tsan/tsan_interceptors_mac.cc | 57 +- libsanitizer/tsan/tsan_interface.h | 13 + libsanitizer/tsan/tsan_interface_ann.cc | 6 +- libsanitizer/tsan/tsan_libdispatch_mac.cc | 14 +- libsanitizer/tsan/tsan_malloc_mac.cc | 10 + libsanitizer/tsan/tsan_mman.cc | 50 +- libsanitizer/tsan/tsan_new_delete.cc | 107 +- libsanitizer/tsan/tsan_platform.h | 171 +- libsanitizer/tsan/tsan_platform_linux.cc | 34 +- libsanitizer/tsan/tsan_platform_mac.cc | 10 +- libsanitizer/tsan/tsan_platform_posix.cc | 59 +- libsanitizer/tsan/tsan_report.cc | 14 +- libsanitizer/tsan/tsan_report.h | 2 +- libsanitizer/tsan/tsan_rtl.cc | 77 +- libsanitizer/tsan/tsan_rtl.h | 32 +- libsanitizer/tsan/tsan_rtl_aarch64.S | 62 +- libsanitizer/tsan/tsan_rtl_amd64.S | 114 +- libsanitizer/tsan/tsan_rtl_mutex.cc | 10 +- libsanitizer/tsan/tsan_rtl_report.cc | 49 +- libsanitizer/tsan/tsan_rtl_thread.cc | 2 +- libsanitizer/tsan/tsan_stack_trace.cc | 5 + libsanitizer/tsan/tsan_stack_trace.h | 4 + libsanitizer/tsan/tsan_suppressions.cc | 2 +- libsanitizer/tsan/tsan_symbolize.cc | 41 + libsanitizer/tsan/tsan_sync.cc | 3 +- libsanitizer/tsan/tsan_sync.h | 4 +- libsanitizer/ubsan/ubsan_checks.inc | 6 + libsanitizer/ubsan/ubsan_diag.cc | 17 +- libsanitizer/ubsan/ubsan_diag.h | 27 +- libsanitizer/ubsan/ubsan_flags.cc | 15 +- libsanitizer/ubsan/ubsan_flags.inc | 3 + libsanitizer/ubsan/ubsan_handlers.cc | 185 +- libsanitizer/ubsan/ubsan_handlers.h | 21 + libsanitizer/ubsan/ubsan_handlers_cxx.cc | 48 +- .../ubsan/ubsan_init_standalone_preinit.cc | 3 +- libsanitizer/ubsan/ubsan_interface.inc | 4 + libsanitizer/ubsan/ubsan_monitor.cc | 74 + libsanitizer/ubsan/ubsan_monitor.h | 47 + libsanitizer/ubsan/ubsan_platform.h | 13 +- .../ubsan/ubsan_signals_standalone.cc | 30 +- libsanitizer/ubsan/ubsan_signals_standalone.h | 2 + .../ubsan/ubsan_win_weak_interception.cc | 1 + 240 files changed, 25041 insertions(+), 3391 deletions(-) create mode 100644 libsanitizer/asan/asan_malloc_local.h create mode 100644 libsanitizer/asan/asan_mapping_myriad.h create mode 100644 libsanitizer/asan/asan_premap_shadow.cc create mode 100644 libsanitizer/asan/asan_premap_shadow.h create mode 100644 libsanitizer/asan/asan_rtems.cc create mode 100644 libsanitizer/include/sanitizer/hwasan_interface.h create mode 100644 libsanitizer/include/sanitizer/netbsd_syscall_hooks.h create mode 100644 libsanitizer/include/sanitizer/scudo_interface.h create mode 100644 libsanitizer/sanitizer_common/sancov_begin.S create mode 100644 libsanitizer/sanitizer_common/sancov_end.S create mode 100644 libsanitizer/sanitizer_common/sanitizer_allocator_report.cc create mode 100644 libsanitizer/sanitizer_common/sanitizer_allocator_report.h create mode 100644 libsanitizer/sanitizer_common/sanitizer_atomic_clang_mips.h create mode 100644 libsanitizer/sanitizer_common/sanitizer_getauxval.h create mode 100644 libsanitizer/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc create mode 100644 libsanitizer/sanitizer_common/sanitizer_netbsd.cc create mode 100644 libsanitizer/sanitizer_common/sanitizer_openbsd.cc create mode 100644 libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cc create mode 100644 libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h create mode 100644 libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cc create mode 100644 libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.h rename libsanitizer/sanitizer_common/{sanitizer_procmaps_freebsd.cc => sanitizer_procmaps_bsd.cc} (57%) create mode 100644 libsanitizer/sanitizer_common/sanitizer_procmaps_solaris.cc create mode 100644 libsanitizer/sanitizer_common/sanitizer_ring_buffer.h create mode 100644 libsanitizer/sanitizer_common/sanitizer_rtems.cc create mode 100644 libsanitizer/sanitizer_common/sanitizer_rtems.h create mode 100644 libsanitizer/sanitizer_common/sanitizer_solaris.cc create mode 100644 libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cc create mode 100644 libsanitizer/sanitizer_common/sanitizer_symbolizer_fuchsia.h rename libsanitizer/sanitizer_common/{sanitizer_symbolizer_fuchsia.cc => sanitizer_symbolizer_markup.cc} (61%) create mode 100644 libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cc create mode 100644 libsanitizer/sanitizer_common/sanitizer_symbolizer_rtems.h create mode 100644 libsanitizer/sanitizer_common/sanitizer_syscall_linux_arm.inc create mode 100644 libsanitizer/sanitizer_common/sanitizer_syscalls_netbsd.inc create mode 100644 libsanitizer/sanitizer_common/sanitizer_unwind_win.cc rename libsanitizer/{tsan/tsan_vector.h => sanitizer_common/sanitizer_vector.h} (75%) create mode 100644 libsanitizer/ubsan/ubsan_monitor.cc create mode 100644 libsanitizer/ubsan/ubsan_monitor.h diff --git a/libsanitizer/ChangeLog b/libsanitizer/ChangeLog index d93e7db9ee1..b8f0bfddc73 100644 --- a/libsanitizer/ChangeLog +++ b/libsanitizer/ChangeLog @@ -1,3 +1,7 @@ +2018-10-31 Martin Liska + + * All source files: Merge from upstream 345033. + 2018-10-31 Martin Liska * HOWTO_MERGE: Enhance documentation. diff --git a/libsanitizer/MERGE b/libsanitizer/MERGE index c92f826445e..8f02e230649 100644 --- a/libsanitizer/MERGE +++ b/libsanitizer/MERGE @@ -1,4 +1,4 @@ -315899 +345033 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/asan/asan_activation.cc b/libsanitizer/asan/asan_activation.cc index 599e56b9e3f..6f69f700c06 100644 --- a/libsanitizer/asan/asan_activation.cc +++ b/libsanitizer/asan/asan_activation.cc @@ -14,8 +14,10 @@ #include "asan_allocator.h" #include "asan_flags.h" #include "asan_internal.h" +#include "asan_mapping.h" #include "asan_poisoning.h" #include "asan_stack.h" +#include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_flags.h" namespace __asan { @@ -108,8 +110,9 @@ void AsanDeactivate() { AllocatorOptions disabled = asan_deactivated_flags.allocator_options; disabled.quarantine_size_mb = 0; disabled.thread_local_quarantine_size_kb = 0; - disabled.min_redzone = 16; // Redzone must be at least 16 bytes long. - disabled.max_redzone = 16; + // Redzone must be at least Max(16, granularity) bytes long. + disabled.min_redzone = Max(16, (int)SHADOW_GRANULARITY); + disabled.max_redzone = disabled.min_redzone; disabled.alloc_dealloc_mismatch = false; disabled.may_return_null = true; ReInitializeAllocator(disabled); diff --git a/libsanitizer/asan/asan_allocator.cc b/libsanitizer/asan/asan_allocator.cc index 1b465469c75..c2b31a543e7 100644 --- a/libsanitizer/asan/asan_allocator.cc +++ b/libsanitizer/asan/asan_allocator.cc @@ -82,7 +82,10 @@ struct ChunkHeader { // This field is used for small sizes. For large sizes it is equal to // SizeClassMap::kMaxSize and the actual size is stored in the // SecondaryAllocator's metadata. - u32 user_requested_size; + u32 user_requested_size : 29; + // align < 8 -> 0 + // else -> log2(min(align, 512)) - 2 + u32 user_requested_alignment_log : 3; u32 alloc_context_id; }; @@ -129,8 +132,9 @@ struct AsanChunk: ChunkBase { }; struct QuarantineCallback { - explicit QuarantineCallback(AllocatorCache *cache) - : cache_(cache) { + QuarantineCallback(AllocatorCache *cache, BufferedStackTrace *stack) + : cache_(cache), + stack_(stack) { } void Recycle(AsanChunk *m) { @@ -163,7 +167,7 @@ struct QuarantineCallback { void *res = get_allocator().Allocate(cache_, size, 1); // TODO(alekseys): Consider making quarantine OOM-friendly. if (UNLIKELY(!res)) - return DieOnFailure::OnOOM(); + ReportOutOfMemory(size, stack_); return res; } @@ -171,7 +175,9 @@ struct QuarantineCallback { get_allocator().Deallocate(cache_, p); } - AllocatorCache *cache_; + private: + AllocatorCache* const cache_; + BufferedStackTrace* const stack_; }; typedef Quarantine AsanQuarantine; @@ -269,9 +275,9 @@ struct Allocator { atomic_store(&max_redzone, options.max_redzone, memory_order_release); } - void Initialize(const AllocatorOptions &options) { + void InitLinkerInitialized(const AllocatorOptions &options) { SetAllocatorMayReturnNull(options.may_return_null); - allocator.Init(options.release_to_os_interval_ms); + allocator.InitLinkerInitialized(options.release_to_os_interval_ms); SharedInitCode(options); } @@ -349,6 +355,20 @@ struct Allocator { return Min(Max(rz_log, RZSize2Log(min_rz)), RZSize2Log(max_rz)); } + static uptr ComputeUserRequestedAlignmentLog(uptr user_requested_alignment) { + if (user_requested_alignment < 8) + return 0; + if (user_requested_alignment > 512) + user_requested_alignment = 512; + return Log2(user_requested_alignment) - 2; + } + + static uptr ComputeUserAlignment(uptr user_requested_alignment_log) { + if (user_requested_alignment_log == 0) + return 0; + return 1LL << (user_requested_alignment_log + 2); + } + // We have an address between two chunks, and we want to report just one. AsanChunk *ChooseChunk(uptr addr, AsanChunk *left_chunk, AsanChunk *right_chunk) { @@ -378,11 +398,16 @@ struct Allocator { AllocType alloc_type, bool can_fill) { if (UNLIKELY(!asan_inited)) AsanInitFromRtl(); - if (RssLimitExceeded()) - return AsanAllocator::FailureHandler::OnOOM(); + if (RssLimitExceeded()) { + if (AllocatorMayReturnNull()) + return nullptr; + ReportRssLimitExceeded(stack); + } Flags &fl = *flags(); CHECK(stack); const uptr min_alignment = SHADOW_GRANULARITY; + const uptr user_requested_alignment_log = + ComputeUserRequestedAlignmentLog(alignment); if (alignment < min_alignment) alignment = min_alignment; if (size == 0) { @@ -410,9 +435,13 @@ struct Allocator { } CHECK(IsAligned(needed_size, min_alignment)); if (size > kMaxAllowedMallocSize || needed_size > kMaxAllowedMallocSize) { - Report("WARNING: AddressSanitizer failed to allocate 0x%zx bytes\n", - (void*)size); - return AsanAllocator::FailureHandler::OnBadRequest(); + if (AllocatorMayReturnNull()) { + Report("WARNING: AddressSanitizer failed to allocate 0x%zx bytes\n", + (void*)size); + return nullptr; + } + ReportAllocationSizeTooBig(size, needed_size, kMaxAllowedMallocSize, + stack); } AsanThread *t = GetCurrentThread(); @@ -425,8 +454,12 @@ struct Allocator { AllocatorCache *cache = &fallback_allocator_cache; allocated = allocator.Allocate(cache, needed_size, 8); } - if (!allocated) - return nullptr; + if (UNLIKELY(!allocated)) { + SetAllocatorOutOfMemory(); + if (AllocatorMayReturnNull()) + return nullptr; + ReportOutOfMemory(size, stack); + } if (*(u8 *)MEM_TO_SHADOW((uptr)allocated) == 0 && CanPoisonMemory()) { // Heap poisoning is enabled, but the allocator provides an unpoisoned @@ -470,6 +503,7 @@ struct Allocator { meta[0] = size; meta[1] = chunk_beg; } + m->user_requested_alignment_log = user_requested_alignment_log; m->alloc_context_id = StackDepotPut(*stack); @@ -561,18 +595,18 @@ struct Allocator { if (t) { AsanThreadLocalMallocStorage *ms = &t->malloc_storage(); AllocatorCache *ac = GetAllocatorCache(ms); - quarantine.Put(GetQuarantineCache(ms), QuarantineCallback(ac), m, - m->UsedSize()); + quarantine.Put(GetQuarantineCache(ms), QuarantineCallback(ac, stack), m, + m->UsedSize()); } else { SpinMutexLock l(&fallback_mutex); AllocatorCache *ac = &fallback_allocator_cache; - quarantine.Put(&fallback_quarantine_cache, QuarantineCallback(ac), m, - m->UsedSize()); + quarantine.Put(&fallback_quarantine_cache, QuarantineCallback(ac, stack), + m, m->UsedSize()); } } - void Deallocate(void *ptr, uptr delete_size, BufferedStackTrace *stack, - AllocType alloc_type) { + void Deallocate(void *ptr, uptr delete_size, uptr delete_alignment, + BufferedStackTrace *stack, AllocType alloc_type) { uptr p = reinterpret_cast(ptr); if (p == 0) return; @@ -599,11 +633,14 @@ struct Allocator { ReportAllocTypeMismatch((uptr)ptr, stack, (AllocType)m->alloc_type, (AllocType)alloc_type); } - } - - if (delete_size && flags()->new_delete_type_mismatch && - delete_size != m->UsedSize()) { - ReportNewDeleteSizeMismatch(p, delete_size, stack); + } else { + if (flags()->new_delete_type_mismatch && + (alloc_type == FROM_NEW || alloc_type == FROM_NEW_BR) && + ((delete_size && delete_size != m->UsedSize()) || + ComputeUserRequestedAlignmentLog(delete_alignment) != + m->user_requested_alignment_log)) { + ReportNewDeleteTypeMismatch(p, delete_size, delete_alignment, stack); + } } QuarantineChunk(m, ptr, stack); @@ -629,14 +666,17 @@ struct Allocator { // If realloc() races with free(), we may start copying freed memory. // However, we will report racy double-free later anyway. REAL(memcpy)(new_ptr, old_ptr, memcpy_size); - Deallocate(old_ptr, 0, stack, FROM_MALLOC); + Deallocate(old_ptr, 0, 0, stack, FROM_MALLOC); } return new_ptr; } void *Calloc(uptr nmemb, uptr size, BufferedStackTrace *stack) { - if (CheckForCallocOverflow(size, nmemb)) - return AsanAllocator::FailureHandler::OnBadRequest(); + if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) { + if (AllocatorMayReturnNull()) + return nullptr; + ReportCallocOverflow(nmemb, size, stack); + } void *ptr = Allocate(nmemb * size, 8, stack, FROM_MALLOC, false); // If the memory comes from the secondary allocator no need to clear it // as it comes directly from mmap. @@ -652,9 +692,9 @@ struct Allocator { ReportFreeNotMalloced((uptr)ptr, stack); } - void CommitBack(AsanThreadLocalMallocStorage *ms) { + void CommitBack(AsanThreadLocalMallocStorage *ms, BufferedStackTrace *stack) { AllocatorCache *ac = GetAllocatorCache(ms); - quarantine.Drain(GetQuarantineCache(ms), QuarantineCallback(ac)); + quarantine.Drain(GetQuarantineCache(ms), QuarantineCallback(ac, stack)); allocator.SwallowCache(ac); } @@ -714,6 +754,24 @@ struct Allocator { return AsanChunkView(m1); } + void Purge(BufferedStackTrace *stack) { + AsanThread *t = GetCurrentThread(); + if (t) { + AsanThreadLocalMallocStorage *ms = &t->malloc_storage(); + quarantine.DrainAndRecycle(GetQuarantineCache(ms), + QuarantineCallback(GetAllocatorCache(ms), + stack)); + } + { + SpinMutexLock l(&fallback_mutex); + quarantine.DrainAndRecycle(&fallback_quarantine_cache, + QuarantineCallback(&fallback_allocator_cache, + stack)); + } + + allocator.ForceReleaseToOS(); + } + void PrintStats() { allocator.PrintStats(); quarantine.PrintStats(); @@ -748,6 +806,9 @@ bool AsanChunkView::IsQuarantined() const { uptr AsanChunkView::Beg() const { return chunk_->Beg(); } uptr AsanChunkView::End() const { return Beg() + UsedSize(); } uptr AsanChunkView::UsedSize() const { return chunk_->UsedSize(); } +u32 AsanChunkView::UserRequestedAlignment() const { + return Allocator::ComputeUserAlignment(chunk_->user_requested_alignment_log); +} uptr AsanChunkView::AllocTid() const { return chunk_->alloc_tid; } uptr AsanChunkView::FreeTid() const { return chunk_->free_tid; } AllocType AsanChunkView::GetAllocType() const { @@ -773,7 +834,7 @@ StackTrace AsanChunkView::GetFreeStack() const { } void InitializeAllocator(const AllocatorOptions &options) { - instance.Initialize(options); + instance.InitLinkerInitialized(options); } void ReInitializeAllocator(const AllocatorOptions &options) { @@ -792,7 +853,8 @@ AsanChunkView FindHeapChunkByAllocBeg(uptr addr) { } void AsanThreadLocalMallocStorage::CommitBack() { - instance.CommitBack(this); + GET_STACK_TRACE_MALLOC; + instance.CommitBack(this, &stack); } void PrintInternalAllocatorStats() { @@ -800,12 +862,12 @@ void PrintInternalAllocatorStats() { } void asan_free(void *ptr, BufferedStackTrace *stack, AllocType alloc_type) { - instance.Deallocate(ptr, 0, stack, alloc_type); + instance.Deallocate(ptr, 0, 0, stack, alloc_type); } -void asan_sized_free(void *ptr, uptr size, BufferedStackTrace *stack, - AllocType alloc_type) { - instance.Deallocate(ptr, size, stack, alloc_type); +void asan_delete(void *ptr, uptr size, uptr alignment, + BufferedStackTrace *stack, AllocType alloc_type) { + instance.Deallocate(ptr, size, alignment, stack, alloc_type); } void *asan_malloc(uptr size, BufferedStackTrace *stack) { @@ -821,7 +883,7 @@ void *asan_realloc(void *p, uptr size, BufferedStackTrace *stack) { return SetErrnoOnNull(instance.Allocate(size, 8, stack, FROM_MALLOC, true)); if (size == 0) { if (flags()->allocator_frees_and_returns_null_on_realloc_zero) { - instance.Deallocate(p, 0, stack, FROM_MALLOC); + instance.Deallocate(p, 0, 0, stack, FROM_MALLOC); return nullptr; } // Allocate a size of 1 if we shouldn't free() on Realloc to 0 @@ -839,7 +901,9 @@ void *asan_pvalloc(uptr size, BufferedStackTrace *stack) { uptr PageSize = GetPageSizeCached(); if (UNLIKELY(CheckForPvallocOverflow(size, PageSize))) { errno = errno_ENOMEM; - return AsanAllocator::FailureHandler::OnBadRequest(); + if (AllocatorMayReturnNull()) + return nullptr; + ReportPvallocOverflow(size, stack); } // pvalloc(0) should allocate one page. size = size ? RoundUpTo(size, PageSize) : PageSize; @@ -851,20 +915,35 @@ void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack, AllocType alloc_type) { if (UNLIKELY(!IsPowerOfTwo(alignment))) { errno = errno_EINVAL; - return AsanAllocator::FailureHandler::OnBadRequest(); + if (AllocatorMayReturnNull()) + return nullptr; + ReportInvalidAllocationAlignment(alignment, stack); } return SetErrnoOnNull( instance.Allocate(size, alignment, stack, alloc_type, true)); } +void *asan_aligned_alloc(uptr alignment, uptr size, BufferedStackTrace *stack) { + if (UNLIKELY(!CheckAlignedAllocAlignmentAndSize(alignment, size))) { + errno = errno_EINVAL; + if (AllocatorMayReturnNull()) + return nullptr; + ReportInvalidAlignedAllocAlignment(size, alignment, stack); + } + return SetErrnoOnNull( + instance.Allocate(size, alignment, stack, FROM_MALLOC, true)); +} + int asan_posix_memalign(void **memptr, uptr alignment, uptr size, BufferedStackTrace *stack) { if (UNLIKELY(!CheckPosixMemalignAlignment(alignment))) { - AsanAllocator::FailureHandler::OnBadRequest(); - return errno_EINVAL; + if (AllocatorMayReturnNull()) + return errno_EINVAL; + ReportInvalidPosixMemalignAlignment(alignment, stack); } void *ptr = instance.Allocate(size, alignment, stack, FROM_MALLOC, true); if (UNLIKELY(!ptr)) + // OOM error is already taken care of by Allocate. return errno_ENOMEM; CHECK(IsAligned((uptr)ptr, alignment)); *memptr = ptr; @@ -1009,6 +1088,11 @@ uptr __sanitizer_get_allocated_size(const void *p) { return allocated_size; } +void __sanitizer_purge_allocator() { + GET_STACK_TRACE_MALLOC; + instance.Purge(&stack); +} + #if !SANITIZER_SUPPORTS_WEAK_HOOKS // Provide default (no-op) implementation of malloc hooks. SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_malloc_hook, diff --git a/libsanitizer/asan/asan_allocator.h b/libsanitizer/asan/asan_allocator.h index 287ff304fbb..c49bd811181 100644 --- a/libsanitizer/asan/asan_allocator.h +++ b/libsanitizer/asan/asan_allocator.h @@ -56,6 +56,7 @@ class AsanChunkView { uptr Beg() const; // First byte of user memory. uptr End() const; // Last byte of user memory. uptr UsedSize() const; // Size requested by the user. + u32 UserRequestedAlignment() const; // Originally requested alignment. uptr AllocTid() const; uptr FreeTid() const; bool Eq(const AsanChunkView &c) const { return chunk_ == c.chunk_; } @@ -126,7 +127,8 @@ const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x20000000000ULL; // 2T. typedef DefaultSizeClassMap SizeClassMap; # elif defined(__aarch64__) && SANITIZER_ANDROID -const uptr kAllocatorSpace = 0x3000000000ULL; +// Android needs to support 39, 42 and 48 bit VMA. +const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x2000000000ULL; // 128G. typedef VeryCompactSizeClassMap SizeClassMap; # elif defined(__aarch64__) @@ -195,8 +197,8 @@ struct AsanThreadLocalMallocStorage { void *asan_memalign(uptr alignment, uptr size, BufferedStackTrace *stack, AllocType alloc_type); void asan_free(void *ptr, BufferedStackTrace *stack, AllocType alloc_type); -void asan_sized_free(void *ptr, uptr size, BufferedStackTrace *stack, - AllocType alloc_type); +void asan_delete(void *ptr, uptr size, uptr alignment, + BufferedStackTrace *stack, AllocType alloc_type); void *asan_malloc(uptr size, BufferedStackTrace *stack); void *asan_calloc(uptr nmemb, uptr size, BufferedStackTrace *stack); @@ -204,6 +206,7 @@ void *asan_realloc(void *p, uptr size, BufferedStackTrace *stack); void *asan_valloc(uptr size, BufferedStackTrace *stack); void *asan_pvalloc(uptr size, BufferedStackTrace *stack); +void *asan_aligned_alloc(uptr alignment, uptr size, BufferedStackTrace *stack); int asan_posix_memalign(void **memptr, uptr alignment, uptr size, BufferedStackTrace *stack); uptr asan_malloc_usable_size(const void *ptr, uptr pc, uptr bp); diff --git a/libsanitizer/asan/asan_debugging.cc b/libsanitizer/asan/asan_debugging.cc index 1c8d0df8f6e..075af3375cd 100644 --- a/libsanitizer/asan/asan_debugging.cc +++ b/libsanitizer/asan/asan_debugging.cc @@ -25,7 +25,8 @@ using namespace __asan; static void FindInfoForStackVar(uptr addr, const char *frame_descr, uptr offset, char *name, uptr name_size, uptr ®ion_address, uptr ®ion_size) { - InternalMmapVector vars(16); + InternalMmapVector vars; + vars.reserve(16); if (!ParseFrameDescription(frame_descr, &vars)) { return; } diff --git a/libsanitizer/asan/asan_descriptions.cc b/libsanitizer/asan/asan_descriptions.cc index c856a653742..99f226da899 100644 --- a/libsanitizer/asan/asan_descriptions.cc +++ b/libsanitizer/asan/asan_descriptions.cc @@ -18,23 +18,25 @@ namespace __asan { -// Return " (thread_name) " or an empty string if the name is empty. -const char *ThreadNameWithParenthesis(AsanThreadContext *t, char buff[], - uptr buff_len) { - const char *name = t->name; - if (name[0] == '\0') return ""; - buff[0] = 0; - internal_strncat(buff, " (", 3); - internal_strncat(buff, name, buff_len - 4); - internal_strncat(buff, ")", 2); - return buff; +AsanThreadIdAndName::AsanThreadIdAndName(AsanThreadContext *t) { + Init(t->tid, t->name); } -const char *ThreadNameWithParenthesis(u32 tid, char buff[], uptr buff_len) { - if (tid == kInvalidTid) return ""; - asanThreadRegistry().CheckLocked(); - AsanThreadContext *t = GetThreadContextByTidLocked(tid); - return ThreadNameWithParenthesis(t, buff, buff_len); +AsanThreadIdAndName::AsanThreadIdAndName(u32 tid) { + if (tid == kInvalidTid) { + Init(tid, ""); + } else { + asanThreadRegistry().CheckLocked(); + AsanThreadContext *t = GetThreadContextByTidLocked(tid); + Init(tid, t->name); + } +} + +void AsanThreadIdAndName::Init(u32 tid, const char *tname) { + int len = internal_snprintf(name, sizeof(name), "T%d", tid); + CHECK(((unsigned int)len) < sizeof(name)); + if (tname[0] != '\0') + internal_snprintf(&name[len], sizeof(name) - len, " (%s)", tname); } void DescribeThread(AsanThreadContext *context) { @@ -45,18 +47,15 @@ void DescribeThread(AsanThreadContext *context) { return; } context->announced = true; - char tname[128]; InternalScopedString str(1024); - str.append("Thread T%d%s", context->tid, - ThreadNameWithParenthesis(context->tid, tname, sizeof(tname))); + str.append("Thread %s", AsanThreadIdAndName(context).c_str()); if (context->parent_tid == kInvalidTid) { str.append(" created by unknown thread\n"); Printf("%s", str.data()); return; } - str.append( - " created by T%d%s here:\n", context->parent_tid, - ThreadNameWithParenthesis(context->parent_tid, tname, sizeof(tname))); + str.append(" created by %s here:\n", + AsanThreadIdAndName(context->parent_tid).c_str()); Printf("%s", str.data()); StackDepotGet(context->stack_id).Print(); // Recursively described parent thread if needed. @@ -120,6 +119,7 @@ static void GetAccessToHeapChunkInformation(ChunkAccess *descr, } descr->chunk_begin = chunk.Beg(); descr->chunk_size = chunk.UsedSize(); + descr->user_requested_alignment = chunk.UserRequestedAlignment(); descr->alloc_type = chunk.GetAllocType(); } @@ -355,10 +355,9 @@ bool GlobalAddressDescription::PointsInsideTheSameVariable( void StackAddressDescription::Print() const { Decorator d; - char tname[128]; Printf("%s", d.Location()); - Printf("Address %p is located in stack of thread T%d%s", addr, tid, - ThreadNameWithParenthesis(tid, tname, sizeof(tname))); + Printf("Address %p is located in stack of thread %s", addr, + AsanThreadIdAndName(tid).c_str()); if (!frame_descr) { Printf("%s\n", d.Default()); @@ -377,7 +376,8 @@ void StackAddressDescription::Print() const { StackTrace alloca_stack(&frame_pc, 1); alloca_stack.Print(); - InternalMmapVector vars(16); + InternalMmapVector vars; + vars.reserve(16); if (!ParseFrameDescription(frame_descr, &vars)) { Printf( "AddressSanitizer can't parse the stack frame " @@ -399,7 +399,7 @@ void StackAddressDescription::Print() const { } Printf( "HINT: this may be a false positive if your program uses " - "some custom stack unwind mechanism or swapcontext\n"); + "some custom stack unwind mechanism, swapcontext or vfork\n"); if (SANITIZER_WINDOWS) Printf(" (longjmp, SEH and C++ exceptions *are* supported)\n"); else @@ -415,26 +415,19 @@ void HeapAddressDescription::Print() const { AsanThreadContext *alloc_thread = GetThreadContextByTidLocked(alloc_tid); StackTrace alloc_stack = GetStackTraceFromId(alloc_stack_id); - char tname[128]; Decorator d; AsanThreadContext *free_thread = nullptr; if (free_tid != kInvalidTid) { free_thread = GetThreadContextByTidLocked(free_tid); - Printf("%sfreed by thread T%d%s here:%s\n", d.Allocation(), - free_thread->tid, - ThreadNameWithParenthesis(free_thread, tname, sizeof(tname)), - d.Default()); + Printf("%sfreed by thread %s here:%s\n", d.Allocation(), + AsanThreadIdAndName(free_thread).c_str(), d.Default()); StackTrace free_stack = GetStackTraceFromId(free_stack_id); free_stack.Print(); - Printf("%spreviously allocated by thread T%d%s here:%s\n", d.Allocation(), - alloc_thread->tid, - ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)), - d.Default()); + Printf("%spreviously allocated by thread %s here:%s\n", d.Allocation(), + AsanThreadIdAndName(alloc_thread).c_str(), d.Default()); } else { - Printf("%sallocated by thread T%d%s here:%s\n", d.Allocation(), - alloc_thread->tid, - ThreadNameWithParenthesis(alloc_thread, tname, sizeof(tname)), - d.Default()); + Printf("%sallocated by thread %s here:%s\n", d.Allocation(), + AsanThreadIdAndName(alloc_thread).c_str(), d.Default()); } alloc_stack.Print(); DescribeThread(GetCurrentThread()); diff --git a/libsanitizer/asan/asan_descriptions.h b/libsanitizer/asan/asan_descriptions.h index 12d9ac5f70b..43d0cbfeff3 100644 --- a/libsanitizer/asan/asan_descriptions.h +++ b/libsanitizer/asan/asan_descriptions.h @@ -24,9 +24,20 @@ void DescribeThread(AsanThreadContext *context); static inline void DescribeThread(AsanThread *t) { if (t) DescribeThread(t->context()); } -const char *ThreadNameWithParenthesis(AsanThreadContext *t, char buff[], - uptr buff_len); -const char *ThreadNameWithParenthesis(u32 tid, char buff[], uptr buff_len); + +class AsanThreadIdAndName { + public: + explicit AsanThreadIdAndName(AsanThreadContext *t); + explicit AsanThreadIdAndName(u32 tid); + + // Contains "T%tid (%name)" or "T%tid" if the name is empty. + const char *c_str() const { return &name[0]; } + + private: + void Init(u32 tid, const char *tname); + + char name[128]; +}; class Decorator : public __sanitizer::SanitizerCommonDecorator { public: @@ -100,6 +111,7 @@ struct ChunkAccess { sptr offset; uptr chunk_begin; uptr chunk_size; + u32 user_requested_alignment : 12; u32 access_type : 2; u32 alloc_type : 2; }; diff --git a/libsanitizer/asan/asan_errors.cc b/libsanitizer/asan/asan_errors.cc index b469b16f004..b9d02a74a0d 100644 --- a/libsanitizer/asan/asan_errors.cc +++ b/libsanitizer/asan/asan_errors.cc @@ -11,7 +11,6 @@ //===----------------------------------------------------------------------===// #include "asan_errors.h" -#include #include "asan_descriptions.h" #include "asan_mapping.h" #include "asan_report.h" @@ -35,8 +34,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(); - GetStackTraceWithPcBpAndContext(stack, kStackTraceMax, sig.pc, sig.bp, - sig.context, fast); + GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context, fast); } void ErrorDeadlySignal::Print() { @@ -45,13 +43,11 @@ void ErrorDeadlySignal::Print() { void ErrorDoubleFree::Print() { Decorator d; - Printf("%s", d.Warning()); - char tname[128]; + Printf("%s", d.Error()); Report( - "ERROR: AddressSanitizer: attempting %s on %p in " - "thread T%d%s:\n", - scariness.GetDescription(), addr_description.addr, tid, - ThreadNameWithParenthesis(tid, tname, sizeof(tname))); + "ERROR: AddressSanitizer: attempting %s on %p in thread %s:\n", + scariness.GetDescription(), addr_description.addr, + AsanThreadIdAndName(tid).c_str()); Printf("%s", d.Default()); scariness.Print(); GET_STACK_TRACE_FATAL(second_free_stack->trace[0], @@ -61,20 +57,36 @@ void ErrorDoubleFree::Print() { ReportErrorSummary(scariness.GetDescription(), &stack); } -void ErrorNewDeleteSizeMismatch::Print() { +void ErrorNewDeleteTypeMismatch::Print() { Decorator d; - Printf("%s", d.Warning()); - char tname[128]; + Printf("%s", d.Error()); Report( - "ERROR: AddressSanitizer: %s on %p in thread " - "T%d%s:\n", - scariness.GetDescription(), addr_description.addr, tid, - ThreadNameWithParenthesis(tid, tname, sizeof(tname))); + "ERROR: AddressSanitizer: %s on %p in thread %s:\n", + scariness.GetDescription(), addr_description.addr, + AsanThreadIdAndName(tid).c_str()); Printf("%s object passed to delete has wrong type:\n", d.Default()); - Printf( - " size of the allocated type: %zd bytes;\n" - " size of the deallocated type: %zd bytes.\n", - addr_description.chunk_access.chunk_size, delete_size); + if (delete_size != 0) { + Printf( + " size of the allocated type: %zd bytes;\n" + " size of the deallocated type: %zd bytes.\n", + addr_description.chunk_access.chunk_size, delete_size); + } + const uptr user_alignment = + addr_description.chunk_access.user_requested_alignment; + if (delete_alignment != user_alignment) { + char user_alignment_str[32]; + char delete_alignment_str[32]; + internal_snprintf(user_alignment_str, sizeof(user_alignment_str), + "%zd bytes", user_alignment); + internal_snprintf(delete_alignment_str, sizeof(delete_alignment_str), + "%zd bytes", delete_alignment); + static const char *kDefaultAlignment = "default-aligned"; + Printf( + " alignment of the allocated type: %s;\n" + " alignment of the deallocated type: %s.\n", + user_alignment > 0 ? user_alignment_str : kDefaultAlignment, + delete_alignment > 0 ? delete_alignment_str : kDefaultAlignment); + } CHECK_GT(free_stack->size, 0); scariness.Print(); GET_STACK_TRACE_FATAL(free_stack->trace[0], free_stack->top_frame_bp); @@ -88,13 +100,11 @@ void ErrorNewDeleteSizeMismatch::Print() { void ErrorFreeNotMalloced::Print() { Decorator d; - Printf("%s", d.Warning()); - char tname[128]; + Printf("%s", d.Error()); Report( "ERROR: AddressSanitizer: attempting free on address " - "which was not malloc()-ed: %p in thread T%d%s\n", - addr_description.Address(), tid, - ThreadNameWithParenthesis(tid, tname, sizeof(tname))); + "which was not malloc()-ed: %p in thread %s\n", + addr_description.Address(), AsanThreadIdAndName(tid).c_str()); Printf("%s", d.Default()); CHECK_GT(free_stack->size, 0); scariness.Print(); @@ -111,7 +121,7 @@ void ErrorAllocTypeMismatch::Print() { "operator delete []"}; CHECK_NE(alloc_type, dealloc_type); Decorator d; - Printf("%s", d.Warning()); + Printf("%s", d.Error()); Report("ERROR: AddressSanitizer: %s (%s vs %s) on %p\n", scariness.GetDescription(), alloc_names[alloc_type], dealloc_names[dealloc_type], @@ -130,7 +140,7 @@ void ErrorAllocTypeMismatch::Print() { void ErrorMallocUsableSizeNotOwned::Print() { Decorator d; - Printf("%s", d.Warning()); + Printf("%s", d.Error()); Report( "ERROR: AddressSanitizer: attempting to call malloc_usable_size() for " "pointer which is not owned: %p\n", @@ -143,7 +153,7 @@ void ErrorMallocUsableSizeNotOwned::Print() { void ErrorSanitizerGetAllocatedSizeNotOwned::Print() { Decorator d; - Printf("%s", d.Warning()); + Printf("%s", d.Error()); Report( "ERROR: AddressSanitizer: attempting to call " "__sanitizer_get_allocated_size() for pointer which is not owned: %p\n", @@ -154,11 +164,123 @@ void ErrorSanitizerGetAllocatedSizeNotOwned::Print() { ReportErrorSummary(scariness.GetDescription(), stack); } +void ErrorCallocOverflow::Print() { + Decorator d; + Printf("%s", d.Error()); + Report( + "ERROR: AddressSanitizer: calloc 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()); + Report( + "ERROR: AddressSanitizer: pvalloc parameters overflow: size 0x%zx " + "rounded up to system page size 0x%zx cannot be represented in type " + "size_t (thread %s)\n", + size, GetPageSizeCached(), AsanThreadIdAndName(tid).c_str()); + Printf("%s", d.Default()); + stack->Print(); + PrintHintAllocatorCannotReturnNull(); + ReportErrorSummary(scariness.GetDescription(), stack); +} + +void ErrorInvalidAllocationAlignment::Print() { + Decorator d; + Printf("%s", d.Error()); + Report( + "ERROR: AddressSanitizer: invalid allocation alignment: %zd, " + "alignment must be a power of two (thread %s)\n", + alignment, AsanThreadIdAndName(tid).c_str()); + Printf("%s", d.Default()); + stack->Print(); + PrintHintAllocatorCannotReturnNull(); + ReportErrorSummary(scariness.GetDescription(), stack); +} + +void ErrorInvalidAlignedAllocAlignment::Print() { + Decorator d; + Printf("%s", d.Error()); +#if SANITIZER_POSIX + Report("ERROR: AddressSanitizer: invalid alignment requested in " + "aligned_alloc: %zd, alignment must be a power of two and the " + "requested size 0x%zx must be a multiple of alignment " + "(thread %s)\n", alignment, size, AsanThreadIdAndName(tid).c_str()); +#else + Report("ERROR: AddressSanitizer: invalid alignment requested in " + "aligned_alloc: %zd, the requested size 0x%zx must be a multiple of " + "alignment (thread %s)\n", alignment, size, + AsanThreadIdAndName(tid).c_str()); +#endif + Printf("%s", d.Default()); + stack->Print(); + PrintHintAllocatorCannotReturnNull(); + ReportErrorSummary(scariness.GetDescription(), stack); +} + +void ErrorInvalidPosixMemalignAlignment::Print() { + Decorator d; + Printf("%s", d.Error()); + Report( + "ERROR: AddressSanitizer: invalid alignment requested in posix_memalign: " + "%zd, alignment must be a power of two and a multiple of sizeof(void*) " + "== %zd (thread %s)\n", + alignment, sizeof(void*), AsanThreadIdAndName(tid).c_str()); // NOLINT + Printf("%s", d.Default()); + stack->Print(); + PrintHintAllocatorCannotReturnNull(); + ReportErrorSummary(scariness.GetDescription(), stack); +} + +void ErrorAllocationSizeTooBig::Print() { + Decorator d; + Printf("%s", d.Error()); + Report( + "ERROR: AddressSanitizer: requested allocation size 0x%zx (0x%zx after " + "adjustments for alignment, red zones etc.) exceeds maximum supported " + "size of 0x%zx (thread %s)\n", + user_size, total_size, max_size, AsanThreadIdAndName(tid).c_str()); + Printf("%s", d.Default()); + stack->Print(); + PrintHintAllocatorCannotReturnNull(); + ReportErrorSummary(scariness.GetDescription(), stack); +} + +void ErrorRssLimitExceeded::Print() { + Decorator d; + Printf("%s", d.Error()); + Report( + "ERROR: AddressSanitizer: specified RSS limit exceeded, currently set to " + "soft_rss_limit_mb=%zd\n", common_flags()->soft_rss_limit_mb); + Printf("%s", d.Default()); + stack->Print(); + PrintHintAllocatorCannotReturnNull(); + ReportErrorSummary(scariness.GetDescription(), stack); +} + +void ErrorOutOfMemory::Print() { + Decorator d; + Printf("%s", d.Error()); + Report( + "ERROR: AddressSanitizer: allocator is out of memory trying to allocate " + "0x%zx bytes\n", requested_size); + Printf("%s", d.Default()); + stack->Print(); + PrintHintAllocatorCannotReturnNull(); + ReportErrorSummary(scariness.GetDescription(), stack); +} + void ErrorStringFunctionMemoryRangesOverlap::Print() { Decorator d; char bug_type[100]; internal_snprintf(bug_type, sizeof(bug_type), "%s-param-overlap", function); - Printf("%s", d.Warning()); + Printf("%s", d.Error()); Report( "ERROR: AddressSanitizer: %s: memory ranges [%p,%p) and [%p, %p) " "overlap\n", @@ -175,7 +297,7 @@ void ErrorStringFunctionMemoryRangesOverlap::Print() { void ErrorStringFunctionSizeOverflow::Print() { Decorator d; - Printf("%s", d.Warning()); + Printf("%s", d.Error()); Report("ERROR: AddressSanitizer: %s: (size=%zd)\n", scariness.GetDescription(), size); Printf("%s", d.Default()); @@ -203,7 +325,7 @@ void ErrorBadParamsToAnnotateContiguousContainer::Print() { void ErrorODRViolation::Print() { Decorator d; - Printf("%s", d.Warning()); + Printf("%s", d.Error()); Report("ERROR: AddressSanitizer: %s (%p):\n", scariness.GetDescription(), global1.beg); Printf("%s", d.Default()); @@ -232,7 +354,7 @@ void ErrorODRViolation::Print() { void ErrorInvalidPointerPair::Print() { Decorator d; - Printf("%s", d.Warning()); + Printf("%s", d.Error()); Report("ERROR: AddressSanitizer: %s: %p %p\n", scariness.GetDescription(), addr1_description.Address(), addr2_description.Address()); Printf("%s", d.Default()); @@ -396,6 +518,7 @@ static void PrintLegend(InternalScopedString *str) { PrintShadowByte(str, " ASan internal: ", kAsanInternalHeapMagic); PrintShadowByte(str, " Left alloca redzone: ", kAsanAllocaLeftMagic); PrintShadowByte(str, " Right alloca redzone: ", kAsanAllocaRightMagic); + PrintShadowByte(str, " Shadow gap: ", kAsanShadowGap); } static void PrintShadowBytes(InternalScopedString *str, const char *before, @@ -420,9 +543,14 @@ static void PrintShadowMemoryForAddress(uptr addr) { InternalScopedString str(4096 * 8); str.append("Shadow bytes around the buggy address:\n"); for (int i = -5; i <= 5; i++) { + uptr row_shadow_addr = aligned_shadow + i * n_bytes_per_row; + // Skip rows that would be outside the shadow range. This can happen when + // the user address is near the bottom, top, or shadow gap of the address + // space. + if (!AddrIsInShadow(row_shadow_addr)) continue; const char *prefix = (i == 0) ? "=>" : " "; - PrintShadowBytes(&str, prefix, (u8 *)(aligned_shadow + i * n_bytes_per_row), - (u8 *)shadow_addr, n_bytes_per_row); + PrintShadowBytes(&str, prefix, (u8 *)row_shadow_addr, (u8 *)shadow_addr, + n_bytes_per_row); } if (flags()->print_legend) PrintLegend(&str); Printf("%s", str.data()); @@ -430,17 +558,15 @@ static void PrintShadowMemoryForAddress(uptr addr) { void ErrorGeneric::Print() { Decorator d; - Printf("%s", d.Warning()); + Printf("%s", d.Error()); uptr addr = addr_description.Address(); Report("ERROR: AddressSanitizer: %s on address %p at pc %p bp %p sp %p\n", bug_descr, (void *)addr, pc, bp, sp); Printf("%s", d.Default()); - char tname[128]; - Printf("%s%s of size %zu at %p thread T%d%s%s\n", d.Access(), + Printf("%s%s of size %zu at %p thread %s%s\n", d.Access(), access_size ? (is_write ? "WRITE" : "READ") : "ACCESS", access_size, - (void *)addr, tid, - ThreadNameWithParenthesis(tid, tname, sizeof(tname)), d.Default()); + (void *)addr, AsanThreadIdAndName(tid).c_str(), d.Default()); scariness.Print(); GET_STACK_TRACE_FATAL(pc, bp); diff --git a/libsanitizer/asan/asan_errors.h b/libsanitizer/asan/asan_errors.h index ea8fd01e287..5ed15dc9817 100644 --- a/libsanitizer/asan/asan_errors.h +++ b/libsanitizer/asan/asan_errors.h @@ -18,20 +18,30 @@ namespace __asan { +// (*) VS2013 does not implement unrestricted unions, so we need a trivial +// default constructor explicitly defined for each particular error. + +// None of the error classes own the stack traces mentioned in them. + struct ErrorBase { - ErrorBase() = default; - explicit ErrorBase(u32 tid_) : tid(tid_) {} ScarinessScoreBase scariness; u32 tid; + + ErrorBase() = default; // (*) + explicit ErrorBase(u32 tid_) : tid(tid_) {} + ErrorBase(u32 tid_, int initial_score, const char *reason) : tid(tid_) { + scariness.Clear(); + scariness.Scare(initial_score, reason); + } }; struct ErrorDeadlySignal : ErrorBase { SignalContext signal; - // VS2013 doesn't implement unrestricted unions, so we need a trivial default - // constructor - ErrorDeadlySignal() = default; + + ErrorDeadlySignal() = default; // (*) ErrorDeadlySignal(u32 tid, const SignalContext &sig) - : ErrorBase(tid), signal(sig) { + : ErrorBase(tid), + signal(sig) { scariness.Clear(); if (signal.IsStackOverflow()) { scariness.Scare(10, "stack-overflow"); @@ -53,123 +63,206 @@ struct ErrorDeadlySignal : ErrorBase { }; struct ErrorDoubleFree : ErrorBase { - // ErrorDoubleFree doesn't own the stack trace. const BufferedStackTrace *second_free_stack; HeapAddressDescription addr_description; - // VS2013 doesn't implement unrestricted unions, so we need a trivial default - // constructor - ErrorDoubleFree() = default; + + ErrorDoubleFree() = default; // (*) ErrorDoubleFree(u32 tid, BufferedStackTrace *stack, uptr addr) - : ErrorBase(tid), second_free_stack(stack) { + : ErrorBase(tid, 42, "double-free"), + second_free_stack(stack) { CHECK_GT(second_free_stack->size, 0); GetHeapAddressInformation(addr, 1, &addr_description); - scariness.Clear(); - scariness.Scare(42, "double-free"); } void Print(); }; -struct ErrorNewDeleteSizeMismatch : ErrorBase { - // ErrorNewDeleteSizeMismatch doesn't own the stack trace. +struct ErrorNewDeleteTypeMismatch : ErrorBase { const BufferedStackTrace *free_stack; HeapAddressDescription addr_description; uptr delete_size; - // VS2013 doesn't implement unrestricted unions, so we need a trivial default - // constructor - ErrorNewDeleteSizeMismatch() = default; - ErrorNewDeleteSizeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr, - uptr delete_size_) - : ErrorBase(tid), free_stack(stack), delete_size(delete_size_) { + uptr delete_alignment; + + ErrorNewDeleteTypeMismatch() = default; // (*) + ErrorNewDeleteTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr, + uptr delete_size_, uptr delete_alignment_) + : ErrorBase(tid, 10, "new-delete-type-mismatch"), + free_stack(stack), + delete_size(delete_size_), + delete_alignment(delete_alignment_) { GetHeapAddressInformation(addr, 1, &addr_description); - scariness.Clear(); - scariness.Scare(10, "new-delete-type-mismatch"); } void Print(); }; struct ErrorFreeNotMalloced : ErrorBase { - // ErrorFreeNotMalloced doesn't own the stack trace. const BufferedStackTrace *free_stack; AddressDescription addr_description; - // VS2013 doesn't implement unrestricted unions, so we need a trivial default - // constructor - ErrorFreeNotMalloced() = default; + + ErrorFreeNotMalloced() = default; // (*) ErrorFreeNotMalloced(u32 tid, BufferedStackTrace *stack, uptr addr) - : ErrorBase(tid), + : ErrorBase(tid, 40, "bad-free"), free_stack(stack), - addr_description(addr, /*shouldLockThreadRegistry=*/false) { - scariness.Clear(); - scariness.Scare(40, "bad-free"); - } + addr_description(addr, /*shouldLockThreadRegistry=*/false) {} void Print(); }; struct ErrorAllocTypeMismatch : ErrorBase { - // ErrorAllocTypeMismatch doesn't own the stack trace. const BufferedStackTrace *dealloc_stack; HeapAddressDescription addr_description; AllocType alloc_type, dealloc_type; - // VS2013 doesn't implement unrestricted unions, so we need a trivial default - // constructor - ErrorAllocTypeMismatch() = default; + + ErrorAllocTypeMismatch() = default; // (*) ErrorAllocTypeMismatch(u32 tid, BufferedStackTrace *stack, uptr addr, AllocType alloc_type_, AllocType dealloc_type_) - : ErrorBase(tid), + : ErrorBase(tid, 10, "alloc-dealloc-mismatch"), dealloc_stack(stack), alloc_type(alloc_type_), dealloc_type(dealloc_type_) { GetHeapAddressInformation(addr, 1, &addr_description); - scariness.Clear(); - scariness.Scare(10, "alloc-dealloc-mismatch"); }; void Print(); }; struct ErrorMallocUsableSizeNotOwned : ErrorBase { - // ErrorMallocUsableSizeNotOwned doesn't own the stack trace. const BufferedStackTrace *stack; AddressDescription addr_description; - // VS2013 doesn't implement unrestricted unions, so we need a trivial default - // constructor - ErrorMallocUsableSizeNotOwned() = default; + + ErrorMallocUsableSizeNotOwned() = default; // (*) ErrorMallocUsableSizeNotOwned(u32 tid, BufferedStackTrace *stack_, uptr addr) - : ErrorBase(tid), + : ErrorBase(tid, 10, "bad-malloc_usable_size"), stack(stack_), - addr_description(addr, /*shouldLockThreadRegistry=*/false) { - scariness.Clear(); - scariness.Scare(10, "bad-malloc_usable_size"); - } + addr_description(addr, /*shouldLockThreadRegistry=*/false) {} void Print(); }; struct ErrorSanitizerGetAllocatedSizeNotOwned : ErrorBase { - // ErrorSanitizerGetAllocatedSizeNotOwned doesn't own the stack trace. const BufferedStackTrace *stack; AddressDescription addr_description; - // VS2013 doesn't implement unrestricted unions, so we need a trivial default - // constructor - ErrorSanitizerGetAllocatedSizeNotOwned() = default; + + ErrorSanitizerGetAllocatedSizeNotOwned() = default; // (*) ErrorSanitizerGetAllocatedSizeNotOwned(u32 tid, BufferedStackTrace *stack_, uptr addr) - : ErrorBase(tid), + : ErrorBase(tid, 10, "bad-__sanitizer_get_allocated_size"), stack(stack_), - addr_description(addr, /*shouldLockThreadRegistry=*/false) { - scariness.Clear(); - scariness.Scare(10, "bad-__sanitizer_get_allocated_size"); - } + addr_description(addr, /*shouldLockThreadRegistry=*/false) {} + void Print(); +}; + +struct ErrorCallocOverflow : ErrorBase { + const BufferedStackTrace *stack; + uptr count; + uptr size; + + ErrorCallocOverflow() = default; // (*) + ErrorCallocOverflow(u32 tid, BufferedStackTrace *stack_, uptr count_, + uptr size_) + : ErrorBase(tid, 10, "calloc-overflow"), + stack(stack_), + count(count_), + size(size_) {} + void Print(); +}; + +struct ErrorPvallocOverflow : ErrorBase { + const BufferedStackTrace *stack; + uptr size; + + ErrorPvallocOverflow() = default; // (*) + ErrorPvallocOverflow(u32 tid, BufferedStackTrace *stack_, uptr size_) + : ErrorBase(tid, 10, "pvalloc-overflow"), + stack(stack_), + size(size_) {} + void Print(); +}; + +struct ErrorInvalidAllocationAlignment : ErrorBase { + const BufferedStackTrace *stack; + uptr alignment; + + ErrorInvalidAllocationAlignment() = default; // (*) + ErrorInvalidAllocationAlignment(u32 tid, BufferedStackTrace *stack_, + uptr alignment_) + : ErrorBase(tid, 10, "invalid-allocation-alignment"), + stack(stack_), + alignment(alignment_) {} + void Print(); +}; + +struct ErrorInvalidAlignedAllocAlignment : ErrorBase { + const BufferedStackTrace *stack; + uptr size; + uptr alignment; + + ErrorInvalidAlignedAllocAlignment() = default; // (*) + ErrorInvalidAlignedAllocAlignment(u32 tid, BufferedStackTrace *stack_, + uptr size_, uptr alignment_) + : ErrorBase(tid, 10, "invalid-aligned-alloc-alignment"), + stack(stack_), + size(size_), + alignment(alignment_) {} + void Print(); +}; + +struct ErrorInvalidPosixMemalignAlignment : ErrorBase { + const BufferedStackTrace *stack; + uptr alignment; + + ErrorInvalidPosixMemalignAlignment() = default; // (*) + ErrorInvalidPosixMemalignAlignment(u32 tid, BufferedStackTrace *stack_, + uptr alignment_) + : ErrorBase(tid, 10, "invalid-posix-memalign-alignment"), + stack(stack_), + alignment(alignment_) {} + void Print(); +}; + +struct ErrorAllocationSizeTooBig : ErrorBase { + const BufferedStackTrace *stack; + uptr user_size; + uptr total_size; + uptr max_size; + + ErrorAllocationSizeTooBig() = default; // (*) + ErrorAllocationSizeTooBig(u32 tid, BufferedStackTrace *stack_, + uptr user_size_, uptr total_size_, uptr max_size_) + : ErrorBase(tid, 10, "allocation-size-too-big"), + stack(stack_), + user_size(user_size_), + total_size(total_size_), + max_size(max_size_) {} + void Print(); +}; + +struct ErrorRssLimitExceeded : ErrorBase { + const BufferedStackTrace *stack; + + ErrorRssLimitExceeded() = default; // (*) + ErrorRssLimitExceeded(u32 tid, BufferedStackTrace *stack_) + : ErrorBase(tid, 10, "rss-limit-exceeded"), + stack(stack_) {} + void Print(); +}; + +struct ErrorOutOfMemory : ErrorBase { + const BufferedStackTrace *stack; + uptr requested_size; + + ErrorOutOfMemory() = default; // (*) + ErrorOutOfMemory(u32 tid, BufferedStackTrace *stack_, uptr requested_size_) + : ErrorBase(tid, 10, "out-of-memory"), + stack(stack_), + requested_size(requested_size_) {} void Print(); }; struct ErrorStringFunctionMemoryRangesOverlap : ErrorBase { - // ErrorStringFunctionMemoryRangesOverlap doesn't own the stack trace. const BufferedStackTrace *stack; uptr length1, length2; AddressDescription addr1_description; AddressDescription addr2_description; const char *function; - // VS2013 doesn't implement unrestricted unions, so we need a trivial default - // constructor - ErrorStringFunctionMemoryRangesOverlap() = default; + + ErrorStringFunctionMemoryRangesOverlap() = default; // (*) ErrorStringFunctionMemoryRangesOverlap(u32 tid, BufferedStackTrace *stack_, uptr addr1, uptr length1_, uptr addr2, uptr length2_, const char *function_) @@ -189,65 +282,51 @@ struct ErrorStringFunctionMemoryRangesOverlap : ErrorBase { }; struct ErrorStringFunctionSizeOverflow : ErrorBase { - // ErrorStringFunctionSizeOverflow doesn't own the stack trace. const BufferedStackTrace *stack; AddressDescription addr_description; uptr size; - // VS2013 doesn't implement unrestricted unions, so we need a trivial default - // constructor - ErrorStringFunctionSizeOverflow() = default; + + ErrorStringFunctionSizeOverflow() = default; // (*) ErrorStringFunctionSizeOverflow(u32 tid, BufferedStackTrace *stack_, uptr addr, uptr size_) - : ErrorBase(tid), + : ErrorBase(tid, 10, "negative-size-param"), stack(stack_), addr_description(addr, /*shouldLockThreadRegistry=*/false), - size(size_) { - scariness.Clear(); - scariness.Scare(10, "negative-size-param"); - } + size(size_) {} void Print(); }; struct ErrorBadParamsToAnnotateContiguousContainer : ErrorBase { - // ErrorBadParamsToAnnotateContiguousContainer doesn't own the stack trace. const BufferedStackTrace *stack; uptr beg, end, old_mid, new_mid; - // VS2013 doesn't implement unrestricted unions, so we need a trivial default - // constructor - ErrorBadParamsToAnnotateContiguousContainer() = default; + + ErrorBadParamsToAnnotateContiguousContainer() = default; // (*) // PS4: Do we want an AddressDescription for beg? ErrorBadParamsToAnnotateContiguousContainer(u32 tid, BufferedStackTrace *stack_, uptr beg_, uptr end_, uptr old_mid_, uptr new_mid_) - : ErrorBase(tid), + : ErrorBase(tid, 10, "bad-__sanitizer_annotate_contiguous_container"), stack(stack_), beg(beg_), end(end_), old_mid(old_mid_), - new_mid(new_mid_) { - scariness.Clear(); - scariness.Scare(10, "bad-__sanitizer_annotate_contiguous_container"); - } + new_mid(new_mid_) {} void Print(); }; struct ErrorODRViolation : ErrorBase { __asan_global global1, global2; u32 stack_id1, stack_id2; - // VS2013 doesn't implement unrestricted unions, so we need a trivial default - // constructor - ErrorODRViolation() = default; + + ErrorODRViolation() = default; // (*) ErrorODRViolation(u32 tid, const __asan_global *g1, u32 stack_id1_, const __asan_global *g2, u32 stack_id2_) - : ErrorBase(tid), + : ErrorBase(tid, 10, "odr-violation"), global1(*g1), global2(*g2), stack_id1(stack_id1_), - stack_id2(stack_id2_) { - scariness.Clear(); - scariness.Scare(10, "odr-violation"); - } + stack_id2(stack_id2_) {} void Print(); }; @@ -255,20 +334,16 @@ struct ErrorInvalidPointerPair : ErrorBase { uptr pc, bp, sp; AddressDescription addr1_description; AddressDescription addr2_description; - // VS2013 doesn't implement unrestricted unions, so we need a trivial default - // constructor - ErrorInvalidPointerPair() = default; + + ErrorInvalidPointerPair() = default; // (*) ErrorInvalidPointerPair(u32 tid, uptr pc_, uptr bp_, uptr sp_, uptr p1, uptr p2) - : ErrorBase(tid), + : ErrorBase(tid, 10, "invalid-pointer-pair"), pc(pc_), bp(bp_), sp(sp_), addr1_description(p1, 1, /*shouldLockThreadRegistry=*/false), - addr2_description(p2, 1, /*shouldLockThreadRegistry=*/false) { - scariness.Clear(); - scariness.Scare(10, "invalid-pointer-pair"); - } + addr2_description(p2, 1, /*shouldLockThreadRegistry=*/false) {} void Print(); }; @@ -279,9 +354,8 @@ struct ErrorGeneric : ErrorBase { const char *bug_descr; bool is_write; u8 shadow_val; - // VS2013 doesn't implement unrestricted unions, so we need a trivial default - // constructor - ErrorGeneric() = default; + + ErrorGeneric() = default; // (*) ErrorGeneric(u32 tid, uptr addr, uptr pc_, uptr bp_, uptr sp_, bool is_write_, uptr access_size_); void Print(); @@ -291,11 +365,19 @@ struct ErrorGeneric : ErrorBase { #define ASAN_FOR_EACH_ERROR_KIND(macro) \ macro(DeadlySignal) \ macro(DoubleFree) \ - macro(NewDeleteSizeMismatch) \ + macro(NewDeleteTypeMismatch) \ macro(FreeNotMalloced) \ macro(AllocTypeMismatch) \ macro(MallocUsableSizeNotOwned) \ macro(SanitizerGetAllocatedSizeNotOwned) \ + macro(CallocOverflow) \ + macro(PvallocOverflow) \ + macro(InvalidAllocationAlignment) \ + macro(InvalidAlignedAllocAlignment) \ + macro(InvalidPosixMemalignAlignment) \ + macro(AllocationSizeTooBig) \ + macro(RssLimitExceeded) \ + macro(OutOfMemory) \ macro(StringFunctionMemoryRangesOverlap) \ macro(StringFunctionSizeOverflow) \ macro(BadParamsToAnnotateContiguousContainer) \ @@ -330,6 +412,7 @@ struct ErrorDescription { }; ErrorDescription() { internal_memset(this, 0, sizeof(*this)); } + explicit ErrorDescription(LinkerInitialized) {} ASAN_FOR_EACH_ERROR_KIND(ASAN_ERROR_DESCRIPTION_CONSTRUCTOR) bool IsValid() { return kind != kErrorKindInvalid; } diff --git a/libsanitizer/asan/asan_fake_stack.cc b/libsanitizer/asan/asan_fake_stack.cc index 3140f9a2aeb..f4a5bb75c28 100644 --- a/libsanitizer/asan/asan_fake_stack.cc +++ b/libsanitizer/asan/asan_fake_stack.cc @@ -26,9 +26,9 @@ static const u64 kAllocaRedzoneMask = 31UL; // For small size classes inline PoisonShadow for better performance. ALWAYS_INLINE void SetShadow(uptr ptr, uptr size, uptr class_id, u64 magic) { - CHECK_EQ(SHADOW_SCALE, 3); // This code expects SHADOW_SCALE=3. u64 *shadow = reinterpret_cast(MemToShadow(ptr)); - if (class_id <= 6) { + if (SHADOW_SCALE == 3 && class_id <= 6) { + // This code expects SHADOW_SCALE=3. for (uptr i = 0; i < (((uptr)1) << class_id); i++) { shadow[i] = magic; // Make sure this does not become memset. diff --git a/libsanitizer/asan/asan_flags.cc b/libsanitizer/asan/asan_flags.cc index 0c83dac6747..522fce30f05 100644 --- a/libsanitizer/asan/asan_flags.cc +++ b/libsanitizer/asan/asan_flags.cc @@ -31,10 +31,7 @@ static const char *MaybeCallAsanDefaultOptions() { static const char *MaybeUseAsanDefaultOptionsCompileDefinition() { #ifdef ASAN_DEFAULT_OPTIONS -// Stringize the macro value. -# define ASAN_STRINGIZE(x) #x -# define ASAN_STRINGIZE_OPTIONS(options) ASAN_STRINGIZE(options) - return ASAN_STRINGIZE_OPTIONS(ASAN_DEFAULT_OPTIONS); + return SANITIZER_STRINGIFY(ASAN_DEFAULT_OPTIONS); #else return ""; #endif @@ -146,6 +143,9 @@ void InitializeFlags() { SanitizerToolName); Die(); } + // Ensure that redzone is at least SHADOW_GRANULARITY. + if (f->redzone < (int)SHADOW_GRANULARITY) + f->redzone = SHADOW_GRANULARITY; // Make "strict_init_order" imply "check_initialization_order". // TODO(samsonov): Use a single runtime flag for an init-order checker. if (f->strict_init_order) { @@ -158,6 +158,10 @@ void InitializeFlags() { CHECK_LE(f->max_redzone, 2048); CHECK(IsPowerOfTwo(f->redzone)); CHECK(IsPowerOfTwo(f->max_redzone)); + if (SANITIZER_RTEMS) { + CHECK(!f->unmap_shadow_on_exit); + CHECK(!f->protect_shadow_gap); + } // quarantine_size is deprecated but we still honor it. // quarantine_size can not be used together with quarantine_size_mb. diff --git a/libsanitizer/asan/asan_flags.inc b/libsanitizer/asan/asan_flags.inc index b4253e02524..9cd1f60db60 100644 --- a/libsanitizer/asan/asan_flags.inc +++ b/libsanitizer/asan/asan_flags.inc @@ -86,7 +86,8 @@ ASAN_FLAG(bool, check_malloc_usable_size, true, "295.*.") ASAN_FLAG(bool, unmap_shadow_on_exit, false, "If set, explicitly unmaps the (huge) shadow at exit.") -ASAN_FLAG(bool, protect_shadow_gap, true, "If set, mprotect the shadow gap") +ASAN_FLAG(bool, protect_shadow_gap, !SANITIZER_RTEMS, + "If set, mprotect the shadow gap") ASAN_FLAG(bool, print_stats, false, "Print various statistics after printing an error message or if " "atexit=1.") diff --git a/libsanitizer/asan/asan_fuchsia.cc b/libsanitizer/asan/asan_fuchsia.cc index 6b1b48921ef..f8207ecccd1 100644 --- a/libsanitizer/asan/asan_fuchsia.cc +++ b/libsanitizer/asan/asan_fuchsia.cc @@ -26,7 +26,7 @@ namespace __asan { // The system already set up the shadow memory for us. -// __sanitizer::GetMaxVirtualAddress has already been called by +// __sanitizer::GetMaxUserVirtualAddress has already been called by // AsanInitInternal->InitializeHighMemEnd (asan_rtl.cc). // Just do some additional sanity checks here. void InitializeShadowMemory() { diff --git a/libsanitizer/asan/asan_globals.cc b/libsanitizer/asan/asan_globals.cc index c33b0ac7561..34963156346 100644 --- a/libsanitizer/asan/asan_globals.cc +++ b/libsanitizer/asan/asan_globals.cc @@ -147,6 +147,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 @@ -194,6 +211,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); @@ -203,8 +222,9 @@ static void RegisterGlobal(const Global *g) { list_of_all_globals = l; if (g->has_dynamic_init) { if (!dynamic_init_globals) { - dynamic_init_globals = new(allocator_for_globals) - VectorOfGlobals(kDynamicInitGlobalsInitialCapacity); + dynamic_init_globals = + new (allocator_for_globals) VectorOfGlobals; // NOLINT + dynamic_init_globals->reserve(kDynamicInitGlobalsInitialCapacity); } DynInitGlobal dyn_global = { *g, false }; dynamic_init_globals->push_back(dyn_global); @@ -337,9 +357,11 @@ void __asan_register_globals(__asan_global *globals, uptr n) { GET_STACK_TRACE_MALLOC; u32 stack_id = StackDepotPut(stack); BlockingMutexLock lock(&mu_for_globals); - if (!global_registration_site_vector) + if (!global_registration_site_vector) { global_registration_site_vector = - new(allocator_for_globals) GlobalRegistrationSiteVector(128); + new (allocator_for_globals) GlobalRegistrationSiteVector; // NOLINT + global_registration_site_vector->reserve(128); + } GlobalRegistrationSite site = {stack_id, &globals[0], &globals[n - 1]}; global_registration_site_vector->push_back(site); if (flags()->report_globals >= 2) { diff --git a/libsanitizer/asan/asan_globals_win.cc b/libsanitizer/asan/asan_globals_win.cc index 118c0ac991c..a78bc878f9c 100644 --- a/libsanitizer/asan/asan_globals_win.cc +++ b/libsanitizer/asan/asan_globals_win.cc @@ -17,9 +17,9 @@ namespace __asan { #pragma section(".ASAN$GA", read, write) // NOLINT #pragma section(".ASAN$GZ", read, write) // NOLINT extern "C" __declspec(allocate(".ASAN$GA")) -__asan_global __asan_globals_start = {}; + ALIGNED(sizeof(__asan_global)) __asan_global __asan_globals_start = {}; extern "C" __declspec(allocate(".ASAN$GZ")) -__asan_global __asan_globals_end = {}; + ALIGNED(sizeof(__asan_global)) __asan_global __asan_globals_end = {}; #pragma comment(linker, "/merge:.ASAN=.data") static void call_on_globals(void (*hook)(__asan_global *, uptr)) { @@ -27,7 +27,7 @@ static void call_on_globals(void (*hook)(__asan_global *, uptr)) { __asan_global *end = &__asan_globals_end; uptr bytediff = (uptr)end - (uptr)start; if (bytediff % sizeof(__asan_global) != 0) { -#ifdef SANITIZER_DLL_THUNK +#if defined(SANITIZER_DLL_THUNK) || defined(SANITIZER_DYNAMIC_RUNTIME_THUNK) __debugbreak(); #else CHECK("corrupt asan global array"); diff --git a/libsanitizer/asan/asan_init_version.h b/libsanitizer/asan/asan_init_version.h index 51e8324fc13..7833133938d 100644 --- a/libsanitizer/asan/asan_init_version.h +++ b/libsanitizer/asan/asan_init_version.h @@ -13,6 +13,8 @@ #ifndef ASAN_INIT_VERSION_H #define ASAN_INIT_VERSION_H +#include "sanitizer_common/sanitizer_platform.h" + extern "C" { // Every time the ASan ABI changes we also change the version number in the // __asan_init function name. Objects built with incompatible ASan ABI @@ -30,7 +32,12 @@ extern "C" { // v6=>v7: added 'odr_indicator' to __asan_global // v7=>v8: added '__asan_(un)register_image_globals' functions for dead // stripping support on Mach-O platforms +#if SANITIZER_WORDSIZE == 32 && SANITIZER_ANDROID + // v8=>v9: 32-bit Android switched to dynamic shadow + #define __asan_version_mismatch_check __asan_version_mismatch_check_v9 +#else #define __asan_version_mismatch_check __asan_version_mismatch_check_v8 +#endif } #endif // ASAN_INIT_VERSION_H diff --git a/libsanitizer/asan/asan_interceptors.cc b/libsanitizer/asan/asan_interceptors.cc index 552cf9347af..fc9818bee8a 100644 --- a/libsanitizer/asan/asan_interceptors.cc +++ b/libsanitizer/asan/asan_interceptors.cc @@ -22,15 +22,20 @@ #include "lsan/lsan_common.h" #include "sanitizer_common/sanitizer_libc.h" -// There is no general interception at all on Fuchsia. +// There is no general interception at all on Fuchsia and RTEMS. // Only the functions in asan_interceptors_memintrinsics.cc are // really defined to replace libc functions. -#if !SANITIZER_FUCHSIA +#if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS #if SANITIZER_POSIX #include "sanitizer_common/sanitizer_posix.h" #endif +#if ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION || \ + ASAN_INTERCEPT__SJLJ_UNWIND_RAISEEXCEPTION +#include +#endif + #if defined(__i386) && SANITIZER_LINUX #define ASAN_PTHREAD_CREATE_VERSION "GLIBC_2.1" #elif defined(__mips__) && SANITIZER_LINUX @@ -176,6 +181,7 @@ DECLARE_REAL_AND_INTERCEPTOR(void, free, void *) (void)(s); \ } while (false) #include "sanitizer_common/sanitizer_common_syscalls.inc" +#include "sanitizer_common/sanitizer_syscalls_netbsd.inc" struct ThreadStartParam { atomic_uintptr_t t; @@ -324,6 +330,32 @@ INTERCEPTOR(void, __cxa_throw, void *a, void *b, void *c) { } #endif +#if ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION +INTERCEPTOR(void, __cxa_rethrow_primary_exception, void *a) { + CHECK(REAL(__cxa_rethrow_primary_exception)); + __asan_handle_no_return(); + REAL(__cxa_rethrow_primary_exception)(a); +} +#endif + +#if ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION +INTERCEPTOR(_Unwind_Reason_Code, _Unwind_RaiseException, + _Unwind_Exception *object) { + CHECK(REAL(_Unwind_RaiseException)); + __asan_handle_no_return(); + return REAL(_Unwind_RaiseException)(object); +} +#endif + +#if ASAN_INTERCEPT__SJLJ_UNWIND_RAISEEXCEPTION +INTERCEPTOR(_Unwind_Reason_Code, _Unwind_SjLj_RaiseException, + _Unwind_Exception *object) { + CHECK(REAL(_Unwind_SjLj_RaiseException)); + __asan_handle_no_return(); + return REAL(_Unwind_SjLj_RaiseException)(object); +} +#endif + #if ASAN_INTERCEPT_INDEX # if ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX INTERCEPTOR(char*, index, const char *string, int c) @@ -546,14 +578,6 @@ INTERCEPTOR(int, __cxa_atexit, void (*func)(void *), void *arg, } #endif // ASAN_INTERCEPT___CXA_ATEXIT -#if ASAN_INTERCEPT_FORK -INTERCEPTOR(int, fork, void) { - ENSURE_ASAN_INITED(); - int pid = REAL(fork)(); - return pid; -} -#endif // ASAN_INTERCEPT_FORK - // ---------------------- InitializeAsanInterceptors ---------------- {{{1 namespace __asan { void InitializeAsanInterceptors() { @@ -604,6 +628,17 @@ void InitializeAsanInterceptors() { #if ASAN_INTERCEPT___CXA_THROW ASAN_INTERCEPT_FUNC(__cxa_throw); #endif +#if ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION + ASAN_INTERCEPT_FUNC(__cxa_rethrow_primary_exception); +#endif + // Indirectly intercept std::rethrow_exception. +#if ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION + INTERCEPT_FUNCTION(_Unwind_RaiseException); +#endif + // Indirectly intercept std::rethrow_exception. +#if ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION + INTERCEPT_FUNCTION(_Unwind_SjLj_RaiseException); +#endif // Intercept threading-related functions #if ASAN_INTERCEPT_PTHREAD_CREATE @@ -620,10 +655,6 @@ void InitializeAsanInterceptors() { ASAN_INTERCEPT_FUNC(__cxa_atexit); #endif -#if ASAN_INTERCEPT_FORK - ASAN_INTERCEPT_FUNC(fork); -#endif - InitializePlatformInterceptors(); VReport(1, "AddressSanitizer: libc interceptors initialized\n"); diff --git a/libsanitizer/asan/asan_interceptors.h b/libsanitizer/asan/asan_interceptors.h index e20d1af15a6..b599ebb0ba9 100644 --- a/libsanitizer/asan/asan_interceptors.h +++ b/libsanitizer/asan/asan_interceptors.h @@ -32,10 +32,10 @@ void InitializePlatformInterceptors(); } // namespace __asan -// There is no general interception at all on Fuchsia. +// There is no general interception at all on Fuchsia and RTEMS. // Only the functions in asan_interceptors_memintrinsics.h are // really defined to replace libc functions. -#if !SANITIZER_FUCHSIA +#if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS // Use macro to describe if specific function should be // intercepted on a given platform. @@ -44,22 +44,21 @@ void InitializePlatformInterceptors(); # define ASAN_INTERCEPT__LONGJMP 1 # define ASAN_INTERCEPT_INDEX 1 # define ASAN_INTERCEPT_PTHREAD_CREATE 1 -# define ASAN_INTERCEPT_FORK 1 #else # define ASAN_INTERCEPT_ATOLL_AND_STRTOLL 0 # define ASAN_INTERCEPT__LONGJMP 0 # define ASAN_INTERCEPT_INDEX 0 # define ASAN_INTERCEPT_PTHREAD_CREATE 0 -# define ASAN_INTERCEPT_FORK 0 #endif -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS # define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 1 #else # define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 0 #endif -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_SOLARIS # define ASAN_INTERCEPT_SWAPCONTEXT 1 #else # define ASAN_INTERCEPT_SWAPCONTEXT 0 @@ -77,12 +76,20 @@ void InitializePlatformInterceptors(); # define ASAN_INTERCEPT___LONGJMP_CHK 0 #endif -// Android bug: https://code.google.com/p/android/issues/detail?id=61799 -#if ASAN_HAS_EXCEPTIONS && !SANITIZER_WINDOWS && \ - !(SANITIZER_ANDROID && defined(__i386)) +#if ASAN_HAS_EXCEPTIONS && !SANITIZER_WINDOWS && !SANITIZER_SOLARIS && \ + !SANITIZER_NETBSD # define ASAN_INTERCEPT___CXA_THROW 1 +# 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 +# define ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION 1 +# endif #else # define ASAN_INTERCEPT___CXA_THROW 0 +# define ASAN_INTERCEPT___CXA_RETHROW_PRIMARY_EXCEPTION 0 +# define ASAN_INTERCEPT__UNWIND_RAISEEXCEPTION 0 +# define ASAN_INTERCEPT__UNWIND_SJLJ_RAISEEXCEPTION 0 #endif #if !SANITIZER_WINDOWS @@ -103,9 +110,6 @@ DECLARE_REAL(SIZE_T, strlen, const char *s) DECLARE_REAL(char*, strncpy, char *to, const char *from, uptr size) DECLARE_REAL(uptr, strnlen, const char *s, uptr maxlen) DECLARE_REAL(char*, strstr, const char *s1, const char *s2) -struct sigaction; -DECLARE_REAL(int, sigaction, int signum, const struct sigaction *act, - struct sigaction *oldact) #if !SANITIZER_MAC #define ASAN_INTERCEPT_FUNC(name) \ diff --git a/libsanitizer/asan/asan_interceptors_memintrinsics.cc b/libsanitizer/asan/asan_interceptors_memintrinsics.cc index 16de54cfeef..b0c06a04cac 100644 --- a/libsanitizer/asan/asan_interceptors_memintrinsics.cc +++ b/libsanitizer/asan/asan_interceptors_memintrinsics.cc @@ -29,14 +29,14 @@ void *__asan_memmove(void *to, const void *from, uptr size) { ASAN_MEMMOVE_IMPL(nullptr, to, from, size); } -#if SANITIZER_FUCHSIA +#if SANITIZER_FUCHSIA || SANITIZER_RTEMS -// Fuchsia doesn't use sanitizer_common_interceptors.inc, but the only -// things there it wants are these three. Just define them as aliases -// here rather than repeating the contents. +// Fuchsia and RTEMS don't use sanitizer_common_interceptors.inc, but +// the only things there it wants are these three. Just define them +// as aliases here rather than repeating the contents. -decltype(memcpy) memcpy[[gnu::alias("__asan_memcpy")]]; -decltype(memmove) memmove[[gnu::alias("__asan_memmove")]]; -decltype(memset) memset[[gnu::alias("__asan_memset")]]; +extern "C" decltype(__asan_memcpy) memcpy[[gnu::alias("__asan_memcpy")]]; +extern "C" decltype(__asan_memmove) memmove[[gnu::alias("__asan_memmove")]]; +extern "C" decltype(__asan_memset) memset[[gnu::alias("__asan_memset")]]; -#endif // SANITIZER_FUCHSIA +#endif // SANITIZER_FUCHSIA || SANITIZER_RTEMS diff --git a/libsanitizer/asan/asan_interceptors_memintrinsics.h b/libsanitizer/asan/asan_interceptors_memintrinsics.h index 1dc4d64c7fa..faf8119c937 100644 --- a/libsanitizer/asan/asan_interceptors_memintrinsics.h +++ b/libsanitizer/asan/asan_interceptors_memintrinsics.h @@ -131,15 +131,22 @@ static inline bool RangesOverlap(const char *offset1, uptr length1, const char *offset2, uptr length2) { return !((offset1 + length1 <= offset2) || (offset2 + length2 <= offset1)); } -#define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) do { \ - const char *offset1 = (const char*)_offset1; \ - const char *offset2 = (const char*)_offset2; \ - if (RangesOverlap(offset1, length1, offset2, length2)) { \ - GET_STACK_TRACE_FATAL_HERE; \ - ReportStringFunctionMemoryRangesOverlap(name, offset1, length1, \ - offset2, length2, &stack); \ - } \ -} while (0) +#define CHECK_RANGES_OVERLAP(name, _offset1, length1, _offset2, length2) \ + do { \ + const char *offset1 = (const char *)_offset1; \ + const char *offset2 = (const char *)_offset2; \ + if (RangesOverlap(offset1, length1, offset2, length2)) { \ + GET_STACK_TRACE_FATAL_HERE; \ + bool suppressed = IsInterceptorSuppressed(name); \ + if (!suppressed && HaveStackTraceBasedSuppressions()) { \ + suppressed = IsStackTraceSuppressed(&stack); \ + } \ + if (!suppressed) { \ + ReportStringFunctionMemoryRangesOverlap(name, offset1, length1, \ + offset2, length2, &stack); \ + } \ + } \ + } while (0) } // namespace __asan diff --git a/libsanitizer/asan/asan_internal.h b/libsanitizer/asan/asan_internal.h index a3fe755f523..7c239895e39 100644 --- a/libsanitizer/asan/asan_internal.h +++ b/libsanitizer/asan/asan_internal.h @@ -34,7 +34,7 @@ // If set, values like allocator chunk size, as well as defaults for some flags // will be changed towards less memory overhead. #ifndef ASAN_LOW_MEMORY -# if SANITIZER_IOS || SANITIZER_ANDROID +# if SANITIZER_IOS || SANITIZER_ANDROID || SANITIZER_RTEMS # define ASAN_LOW_MEMORY 1 # else # define ASAN_LOW_MEMORY 0 @@ -76,7 +76,7 @@ void InitializeShadowMemory(); // asan_malloc_linux.cc / asan_malloc_mac.cc void ReplaceSystemMalloc(); -// asan_linux.cc / asan_mac.cc / asan_win.cc +// asan_linux.cc / asan_mac.cc / asan_rtems.cc / asan_win.cc uptr FindDynamicShadowStart(); void *AsanDoesNotSupportStaticLinkage(); void AsanCheckDynamicRTPrereqs(); @@ -145,6 +145,9 @@ const int kAsanArrayCookieMagic = 0xac; const int kAsanIntraObjectRedzone = 0xbb; const int kAsanAllocaLeftMagic = 0xca; const int kAsanAllocaRightMagic = 0xcb; +// Used to populate the shadow gap for systems without memory +// protection there (i.e. Myriad). +const int kAsanShadowGap = 0xcc; static const uptr kCurrentStackFrameMagic = 0x41B58AB3; static const uptr kRetiredStackFrameMagic = 0x45E0360E; diff --git a/libsanitizer/asan/asan_linux.cc b/libsanitizer/asan/asan_linux.cc index a43243e3b43..d92d0596b7c 100644 --- a/libsanitizer/asan/asan_linux.cc +++ b/libsanitizer/asan/asan_linux.cc @@ -11,10 +11,12 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS #include "asan_interceptors.h" #include "asan_internal.h" +#include "asan_premap_shadow.h" #include "asan_thread.h" #include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_freebsd.h" @@ -28,6 +30,7 @@ #include #include #include +#include #include #include #include @@ -37,7 +40,11 @@ #include #endif -#if SANITIZER_ANDROID || SANITIZER_FREEBSD +#if SANITIZER_SOLARIS +#include +#endif + +#if SANITIZER_ANDROID || SANITIZER_FREEBSD || SANITIZER_SOLARIS #include extern "C" void* _DYNAMIC; #elif SANITIZER_NETBSD @@ -79,9 +86,51 @@ void *AsanDoesNotSupportStaticLinkage() { return &_DYNAMIC; // defined in link.h } +static void UnmapFromTo(uptr from, uptr to) { + CHECK(to >= from); + if (to == from) return; + uptr res = internal_munmap(reinterpret_cast(from), to - from); + if (UNLIKELY(internal_iserror(res))) { + Report( + "ERROR: AddresSanitizer failed to unmap 0x%zx (%zd) bytes at address " + "%p\n", + to - from, to - from, from); + CHECK("unable to unmap" && 0); + } +} + +#if ASAN_PREMAP_SHADOW +uptr FindPremappedShadowStart() { + uptr granularity = GetMmapGranularity(); + uptr shadow_start = reinterpret_cast(&__asan_shadow); + uptr premap_shadow_size = PremapShadowSize(); + uptr shadow_size = RoundUpTo(kHighShadowEnd, granularity); + // We may have mapped too much. Release extra memory. + UnmapFromTo(shadow_start + shadow_size, shadow_start + premap_shadow_size); + return shadow_start; +} +#endif + uptr FindDynamicShadowStart() { - UNREACHABLE("FindDynamicShadowStart is not available"); - return 0; +#if ASAN_PREMAP_SHADOW + if (!PremapShadowFailed()) + return FindPremappedShadowStart(); +#endif + + uptr granularity = GetMmapGranularity(); + uptr alignment = granularity * 8; + uptr left_padding = granularity; + uptr shadow_size = RoundUpTo(kHighShadowEnd, granularity); + uptr map_size = shadow_size + left_padding + alignment; + + uptr map_start = (uptr)MmapNoAccess(map_size); + CHECK_NE(map_start, ~(uptr)0); + + uptr shadow_start = RoundUpTo(map_start + left_padding, alignment); + UnmapFromTo(map_start, shadow_start - left_padding); + UnmapFromTo(shadow_start + shadow_size, map_start + map_size); + + return shadow_start; } void AsanApplyToGlobals(globals_op_fptr op, const void *needle) { @@ -95,6 +144,9 @@ void AsanCheckIncompatibleRT() {} #else static int FindFirstDSOCallback(struct dl_phdr_info *info, size_t size, void *data) { + VReport(2, "info->dlpi_name = %s\tinfo->dlpi_addr = %p\n", + info->dlpi_name, info->dlpi_addr); + // Continue until the first dynamic library is found if (!info->dlpi_name || info->dlpi_name[0] == 0) return 0; @@ -103,7 +155,7 @@ static int FindFirstDSOCallback(struct dl_phdr_info *info, size_t size, if (internal_strncmp(info->dlpi_name, "linux-", sizeof("linux-") - 1) == 0) return 0; -#if SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_NETBSD // Ignore first entry (the main program) char **p = (char **)data; if (!(*p)) { @@ -112,6 +164,12 @@ static int FindFirstDSOCallback(struct dl_phdr_info *info, size_t size, } #endif +#if SANITIZER_SOLARIS + // Ignore executable on Solaris + if (info->dlpi_addr == 0) + return 0; +#endif + *(const char **)data = info->dlpi_name; return 1; } @@ -155,7 +213,7 @@ void AsanCheckIncompatibleRT() { // the functions in dynamic ASan runtime instead of the functions in // system libraries, causing crashes later in ASan initialization. MemoryMappingLayout proc_maps(/*cache_enabled*/true); - char filename[128]; + char filename[PATH_MAX]; MemoryMappedSegment segment(filename, sizeof(filename)); while (proc_maps.Next(&segment)) { if (IsDynamicRTName(segment.filename)) { @@ -190,4 +248,5 @@ void *AsanDlSymNext(const char *sym) { } // namespace __asan -#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || + // SANITIZER_SOLARIS diff --git a/libsanitizer/asan/asan_lock.h b/libsanitizer/asan/asan_lock.h index 8b137891791..e69de29bb2d 100644 --- a/libsanitizer/asan/asan_lock.h +++ b/libsanitizer/asan/asan_lock.h @@ -1 +0,0 @@ - diff --git a/libsanitizer/asan/asan_mac.cc b/libsanitizer/asan/asan_mac.cc index 45c66d8645c..89a3db4c2fb 100644 --- a/libsanitizer/asan/asan_mac.cc +++ b/libsanitizer/asan/asan_mac.cc @@ -60,16 +60,36 @@ uptr FindDynamicShadowStart() { uptr space_size = kHighShadowEnd + left_padding; uptr largest_gap_found = 0; - uptr shadow_start = FindAvailableMemoryRange(space_size, alignment, - granularity, &largest_gap_found); + uptr max_occupied_addr = 0; + VReport(2, "FindDynamicShadowStart, space_size = %p\n", space_size); + uptr shadow_start = + FindAvailableMemoryRange(space_size, alignment, granularity, + &largest_gap_found, &max_occupied_addr); // If the shadow doesn't fit, restrict the address space to make it fit. if (shadow_start == 0) { + VReport( + 2, + "Shadow doesn't fit, largest_gap_found = %p, max_occupied_addr = %p\n", + largest_gap_found, max_occupied_addr); uptr new_max_vm = RoundDownTo(largest_gap_found << SHADOW_SCALE, alignment); + if (new_max_vm < max_occupied_addr) { + Report("Unable to find a memory range for dynamic shadow.\n"); + Report( + "space_size = %p, largest_gap_found = %p, max_occupied_addr = %p, " + "new_max_vm = %p\n", + space_size, largest_gap_found, max_occupied_addr, new_max_vm); + CHECK(0 && "cannot place shadow"); + } RestrictMemoryToMaxAddress(new_max_vm); kHighMemEnd = new_max_vm - 1; space_size = kHighShadowEnd + left_padding; - shadow_start = - FindAvailableMemoryRange(space_size, alignment, granularity, nullptr); + VReport(2, "FindDynamicShadowStart, space_size = %p\n", space_size); + shadow_start = FindAvailableMemoryRange(space_size, alignment, granularity, + nullptr, nullptr); + if (shadow_start == 0) { + Report("Unable to find a memory range after restricting VM.\n"); + CHECK(0 && "cannot place shadow after restricting vm"); + } } CHECK_NE((uptr)0, shadow_start); CHECK(IsAligned(shadow_start, alignment)); diff --git a/libsanitizer/asan/asan_malloc_linux.cc b/libsanitizer/asan/asan_malloc_linux.cc index 19f45fc3cee..a6e692759ce 100644 --- a/libsanitizer/asan/asan_malloc_linux.cc +++ b/libsanitizer/asan/asan_malloc_linux.cc @@ -14,19 +14,23 @@ #include "sanitizer_common/sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX || \ - SANITIZER_NETBSD + SANITIZER_NETBSD || SANITIZER_RTEMS || SANITIZER_SOLARIS +#include "sanitizer_common/sanitizer_allocator_checks.h" +#include "sanitizer_common/sanitizer_errno.h" #include "sanitizer_common/sanitizer_tls_get_addr.h" #include "asan_allocator.h" #include "asan_interceptors.h" #include "asan_internal.h" +#include "asan_malloc_local.h" #include "asan_stack.h" // ---------------------- Replacement functions ---------------- {{{1 using namespace __asan; // NOLINT static uptr allocated_for_dlsym; -static const uptr kDlsymAllocPoolSize = 1024; +static uptr last_dlsym_alloc_size_in_words; +static const uptr kDlsymAllocPoolSize = SANITIZER_RTEMS ? 4096 : 1024; static uptr alloc_memory_for_dlsym[kDlsymAllocPoolSize]; static INLINE bool IsInDlsymAllocPool(const void *ptr) { @@ -37,21 +41,73 @@ static INLINE bool IsInDlsymAllocPool(const void *ptr) { static void *AllocateFromLocalPool(uptr size_in_bytes) { uptr size_in_words = RoundUpTo(size_in_bytes, kWordSize) / kWordSize; void *mem = (void*)&alloc_memory_for_dlsym[allocated_for_dlsym]; + last_dlsym_alloc_size_in_words = size_in_words; allocated_for_dlsym += size_in_words; CHECK_LT(allocated_for_dlsym, kDlsymAllocPoolSize); return mem; } +static void DeallocateFromLocalPool(const void *ptr) { + // Hack: since glibc 2.27 dlsym no longer uses stack-allocated memory to store + // error messages and instead uses malloc followed by free. To avoid pool + // exhaustion due to long object filenames, handle that special case here. + uptr prev_offset = allocated_for_dlsym - last_dlsym_alloc_size_in_words; + void *prev_mem = (void*)&alloc_memory_for_dlsym[prev_offset]; + if (prev_mem == ptr) { + REAL(memset)(prev_mem, 0, last_dlsym_alloc_size_in_words * kWordSize); + allocated_for_dlsym = prev_offset; + last_dlsym_alloc_size_in_words = 0; + } +} + +static int PosixMemalignFromLocalPool(void **memptr, uptr alignment, + uptr size_in_bytes) { + if (UNLIKELY(!CheckPosixMemalignAlignment(alignment))) + return errno_EINVAL; + + CHECK(alignment >= kWordSize); + + uptr addr = (uptr)&alloc_memory_for_dlsym[allocated_for_dlsym]; + uptr aligned_addr = RoundUpTo(addr, alignment); + uptr aligned_size = RoundUpTo(size_in_bytes, kWordSize); + + uptr *end_mem = (uptr*)(aligned_addr + aligned_size); + uptr allocated = end_mem - alloc_memory_for_dlsym; + if (allocated >= kDlsymAllocPoolSize) + return errno_ENOMEM; + + allocated_for_dlsym = allocated; + *memptr = (void*)aligned_addr; + return 0; +} + +#if SANITIZER_RTEMS +void* MemalignFromLocalPool(uptr alignment, uptr size) { + void *ptr = nullptr; + alignment = Max(alignment, kWordSize); + PosixMemalignFromLocalPool(&ptr, alignment, size); + return ptr; +} + +bool IsFromLocalPool(const void *ptr) { + return IsInDlsymAllocPool(ptr); +} +#endif + static INLINE bool MaybeInDlsym() { // Fuchsia doesn't use dlsym-based interceptors. return !SANITIZER_FUCHSIA && asan_init_is_running; } +static INLINE bool UseLocalPool() { + return EarlyMalloc() || MaybeInDlsym(); +} + static void *ReallocFromLocalPool(void *ptr, uptr size) { const uptr offset = (uptr)ptr - (uptr)alloc_memory_for_dlsym; const uptr copy_size = Min(size, kDlsymAllocPoolSize - offset); void *new_ptr; - if (UNLIKELY(MaybeInDlsym())) { + if (UNLIKELY(UseLocalPool())) { new_ptr = AllocateFromLocalPool(size); } else { ENSURE_ASAN_INITED(); @@ -64,8 +120,10 @@ static void *ReallocFromLocalPool(void *ptr, uptr size) { INTERCEPTOR(void, free, void *ptr) { GET_STACK_TRACE_FREE; - if (UNLIKELY(IsInDlsymAllocPool(ptr))) + if (UNLIKELY(IsInDlsymAllocPool(ptr))) { + DeallocateFromLocalPool(ptr); return; + } asan_free(ptr, &stack, FROM_MALLOC); } @@ -79,7 +137,7 @@ INTERCEPTOR(void, cfree, void *ptr) { #endif // SANITIZER_INTERCEPT_CFREE INTERCEPTOR(void*, malloc, uptr size) { - if (UNLIKELY(MaybeInDlsym())) + if (UNLIKELY(UseLocalPool())) // Hack: dlsym calls malloc before REAL(malloc) is retrieved from dlsym. return AllocateFromLocalPool(size); ENSURE_ASAN_INITED(); @@ -88,7 +146,7 @@ INTERCEPTOR(void*, malloc, uptr size) { } INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) { - if (UNLIKELY(MaybeInDlsym())) + if (UNLIKELY(UseLocalPool())) // Hack: dlsym calls calloc before REAL(calloc) is retrieved from dlsym. return AllocateFromLocalPool(nmemb * size); ENSURE_ASAN_INITED(); @@ -99,7 +157,7 @@ INTERCEPTOR(void*, calloc, uptr nmemb, uptr size) { INTERCEPTOR(void*, realloc, void *ptr, uptr size) { if (UNLIKELY(IsInDlsymAllocPool(ptr))) return ReallocFromLocalPool(ptr, size); - if (UNLIKELY(MaybeInDlsym())) + if (UNLIKELY(UseLocalPool())) return AllocateFromLocalPool(size); ENSURE_ASAN_INITED(); GET_STACK_TRACE_MALLOC; @@ -120,10 +178,12 @@ INTERCEPTOR(void*, __libc_memalign, uptr boundary, uptr size) { } #endif // SANITIZER_INTERCEPT_MEMALIGN +#if SANITIZER_INTERCEPT_ALIGNED_ALLOC INTERCEPTOR(void*, aligned_alloc, uptr boundary, uptr size) { GET_STACK_TRACE_MALLOC; - return asan_memalign(boundary, size, &stack, FROM_MALLOC); + return asan_aligned_alloc(boundary, size, &stack); } +#endif // SANITIZER_INTERCEPT_ALIGNED_ALLOC INTERCEPTOR(uptr, malloc_usable_size, void *ptr) { GET_CURRENT_PC_BP_SP; @@ -152,8 +212,9 @@ INTERCEPTOR(int, mallopt, int cmd, int value) { #endif // SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) { + if (UNLIKELY(UseLocalPool())) + return PosixMemalignFromLocalPool(memptr, alignment, size); GET_STACK_TRACE_MALLOC; - // Printf("posix_memalign: %zx %zu\n", alignment, size); return asan_posix_memalign(memptr, alignment, size, &stack); } @@ -234,4 +295,4 @@ void ReplaceSystemMalloc() { #endif // SANITIZER_ANDROID #endif // SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX || - // SANITIZER_NETBSD + // SANITIZER_NETBSD || SANITIZER_SOLARIS diff --git a/libsanitizer/asan/asan_malloc_local.h b/libsanitizer/asan/asan_malloc_local.h new file mode 100644 index 00000000000..354189315fb --- /dev/null +++ b/libsanitizer/asan/asan_malloc_local.h @@ -0,0 +1,42 @@ +//===-- asan_malloc_local.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 AddressSanitizer, an address sanity checker. +// +// Provide interfaces to check for and handle local pool memory allocation. +//===----------------------------------------------------------------------===// + +#ifndef ASAN_MALLOC_LOCAL_H +#define ASAN_MALLOC_LOCAL_H + +#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); +} + +void* MemalignFromLocalPool(uptr alignment, uptr size); + +#if SANITIZER_RTEMS + +bool IsFromLocalPool(const void *ptr); + +#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 IS_FROM_LOCAL_POOL(ptr) 0 + +#endif // SANITIZER_RTEMS + +#endif // ASAN_MALLOC_LOCAL_H diff --git a/libsanitizer/asan/asan_malloc_mac.cc b/libsanitizer/asan/asan_malloc_mac.cc index 1ca665d84c5..e34884be85b 100644 --- a/libsanitizer/asan/asan_malloc_mac.cc +++ b/libsanitizer/asan/asan_malloc_mac.cc @@ -36,6 +36,9 @@ using namespace __asan; #define COMMON_MALLOC_CALLOC(count, size) \ GET_STACK_TRACE_MALLOC; \ void *p = asan_calloc(count, size, &stack); +#define COMMON_MALLOC_POSIX_MEMALIGN(memptr, alignment, size) \ + GET_STACK_TRACE_MALLOC; \ + int res = asan_posix_memalign(memptr, alignment, size, &stack); #define COMMON_MALLOC_VALLOC(size) \ GET_STACK_TRACE_MALLOC; \ void *p = asan_memalign(GetPageSizeCached(), size, &stack, FROM_MALLOC); diff --git a/libsanitizer/asan/asan_malloc_win.cc b/libsanitizer/asan/asan_malloc_win.cc index 017481d0b81..24518603792 100644 --- a/libsanitizer/asan/asan_malloc_win.cc +++ b/libsanitizer/asan/asan_malloc_win.cc @@ -12,8 +12,17 @@ #include "sanitizer_common/sanitizer_platform.h" #if SANITIZER_WINDOWS -#define WIN32_LEAN_AND_MEAN -#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; + +#define HEAP_ZERO_MEMORY 0x00000008 +#define HEAP_REALLOC_IN_PLACE_ONLY 0x00000010 + #include "asan_allocator.h" #include "asan_interceptors.h" @@ -123,7 +132,7 @@ void *_recalloc_base(void *p, size_t n, size_t elem_size) { } ALLOCATION_FUNCTION_ATTRIBUTE -size_t _msize(const void *ptr) { +size_t _msize(void *ptr) { GET_CURRENT_PC_BP_SP; (void)sp; return asan_malloc_usable_size(ptr, pc, bp); diff --git a/libsanitizer/asan/asan_mapping.h b/libsanitizer/asan/asan_mapping.h index 5496df66deb..3f35a191a92 100644 --- a/libsanitizer/asan/asan_mapping.h +++ b/libsanitizer/asan/asan_mapping.h @@ -120,6 +120,13 @@ // || `[0x400000000000, 0x47ffffffffff]` || LowShadow || // || `[0x000000000000, 0x3fffffffffff]` || LowMem || // +// Shadow mapping on NetBSD/i386 with SHADOW_OFFSET == 0x40000000: +// || `[0x60000000, 0xfffff000]` || HighMem || +// || `[0x4c000000, 0x5fffffff]` || HighShadow || +// || `[0x48000000, 0x4bffffff]` || ShadowGap || +// || `[0x40000000, 0x47ffffff]` || LowShadow || +// || `[0x00000000, 0x3fffffff]` || LowMem || +// // Default Windows/i386 mapping: // (the exact location of HighShadow/HighMem may vary depending // on WoW64, /LARGEADDRESSAWARE, etc). @@ -128,12 +135,23 @@ // || `[0x36000000, 0x39ffffff]` || ShadowGap || // || `[0x30000000, 0x35ffffff]` || LowShadow || // || `[0x00000000, 0x2fffffff]` || LowMem || - -static const u64 kDefaultShadowScale = 3; +// +// Shadow mapping on Myriad2 (for shadow scale 5): +// || `[0x9ff80000, 0x9fffffff]` || ShadowGap || +// || `[0x9f000000, 0x9ff7ffff]` || LowShadow || +// || `[0x80000000, 0x9effffff]` || LowMem || +// || `[0x00000000, 0x7fffffff]` || Ignored || + +#if defined(ASAN_SHADOW_SCALE) +static const u64 kDefaultShadowScale = ASAN_SHADOW_SCALE; +#else +static const u64 kDefaultShadowScale = SANITIZER_MYRIAD2 ? 5 : 3; +#endif static const u64 kDefaultShadowSentinel = ~(uptr)0; static const u64 kDefaultShadowOffset32 = 1ULL << 29; // 0x20000000 static const u64 kDefaultShadowOffset64 = 1ULL << 44; -static const u64 kDefaultShort64bitShadowOffset = 0x7FFF8000; // < 2G. +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; @@ -141,24 +159,36 @@ 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 kFreeBSD_ShadowOffset32 = 1ULL << 30; // 0x40000000 static const u64 kFreeBSD_ShadowOffset64 = 1ULL << 46; // 0x400000000000 +static const u64 kNetBSD_ShadowOffset32 = 1ULL << 30; // 0x40000000 static const u64 kNetBSD_ShadowOffset64 = 1ULL << 46; // 0x400000000000 static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000 +static const u64 kMyriadMemoryOffset32 = 0x80000000ULL; +static const u64 kMyriadMemorySize32 = 0x20000000ULL; +static const u64 kMyriadMemoryEnd32 = + kMyriadMemoryOffset32 + kMyriadMemorySize32 - 1; +static const u64 kMyriadShadowOffset32 = + (kMyriadMemoryOffset32 + kMyriadMemorySize32 - + (kMyriadMemorySize32 >> kDefaultShadowScale)); +static const u64 kMyriadCacheBitMask32 = 0x40000000ULL; + #define SHADOW_SCALE kDefaultShadowScale #if SANITIZER_FUCHSIA # define SHADOW_OFFSET (0) #elif SANITIZER_WORDSIZE == 32 # if SANITIZER_ANDROID -# define SHADOW_OFFSET (0) +# define SHADOW_OFFSET __asan_shadow_memory_dynamic_address # elif defined(__mips__) # define SHADOW_OFFSET kMIPS32_ShadowOffset32 # elif SANITIZER_FREEBSD # define SHADOW_OFFSET kFreeBSD_ShadowOffset32 +# elif SANITIZER_NETBSD +# define SHADOW_OFFSET kNetBSD_ShadowOffset32 # elif SANITIZER_WINDOWS # define SHADOW_OFFSET kWindowsShadowOffset32 # elif SANITIZER_IOS @@ -167,6 +197,8 @@ static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000 # else # define SHADOW_OFFSET kIosShadowOffset32 # endif +# elif SANITIZER_MYRIAD2 +# define SHADOW_OFFSET kMyriadShadowOffset32 # else # define SHADOW_OFFSET kDefaultShadowOffset32 # endif @@ -198,7 +230,46 @@ static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000 # endif #endif +#if SANITIZER_ANDROID && defined(__arm__) +# define ASAN_PREMAP_SHADOW 1 +#else +# define ASAN_PREMAP_SHADOW 0 +#endif + #define SHADOW_GRANULARITY (1ULL << SHADOW_SCALE) + +#define DO_ASAN_MAPPING_PROFILE 0 // Set to 1 to profile the functions below. + +#if DO_ASAN_MAPPING_PROFILE +# define PROFILE_ASAN_MAPPING() AsanMappingProfile[__LINE__]++; +#else +# define PROFILE_ASAN_MAPPING() +#endif + +// If 1, all shadow boundaries are constants. +// Don't set to 1 other than for testing. +#define ASAN_FIXED_MAPPING 0 + +namespace __asan { + +extern uptr AsanMappingProfile[]; + +#if ASAN_FIXED_MAPPING +// Fixed mapping for 64-bit Linux. Mostly used for performance comparison +// with non-fixed mapping. As of r175253 (Feb 2013) the performance +// difference between fixed and non-fixed mapping is below the noise level. +static uptr kHighMemEnd = 0x7fffffffffffULL; +static uptr kMidMemBeg = 0x3000000000ULL; +static uptr kMidMemEnd = 0x4fffffffffULL; +#else +extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init. +#endif + +} // namespace __asan + +#if SANITIZER_MYRIAD2 +#include "asan_mapping_myriad.h" +#else #define MEM_TO_SHADOW(mem) (((mem) >> SHADOW_SCALE) + (SHADOW_OFFSET)) #define kLowMemBeg 0 @@ -230,36 +301,11 @@ static const u64 kWindowsShadowOffset32 = 3ULL << 28; // 0x30000000 #define kShadowGap3Beg (kMidMemBeg ? kMidMemEnd + 1 : 0) #define kShadowGap3End (kMidMemBeg ? kHighShadowBeg - 1 : 0) -#define DO_ASAN_MAPPING_PROFILE 0 // Set to 1 to profile the functions below. - -#if DO_ASAN_MAPPING_PROFILE -# define PROFILE_ASAN_MAPPING() AsanMappingProfile[__LINE__]++; -#else -# define PROFILE_ASAN_MAPPING() -#endif - -// If 1, all shadow boundaries are constants. -// Don't set to 1 other than for testing. -#define ASAN_FIXED_MAPPING 0 - namespace __asan { -extern uptr AsanMappingProfile[]; - -#if ASAN_FIXED_MAPPING -// Fixed mapping for 64-bit Linux. Mostly used for performance comparison -// with non-fixed mapping. As of r175253 (Feb 2013) the performance -// difference between fixed and non-fixed mapping is below the noise level. -static uptr kHighMemEnd = 0x7fffffffffffULL; -static uptr kMidMemBeg = 0x3000000000ULL; -static uptr kMidMemEnd = 0x4fffffffffULL; -#else -extern uptr kHighMemEnd, kMidMemBeg, kMidMemEnd; // Initialized in __asan_init. -#endif - static inline bool AddrIsInLowMem(uptr a) { PROFILE_ASAN_MAPPING(); - return a < kLowMemEnd; + return a <= kLowMemEnd; } static inline bool AddrIsInLowShadow(uptr a) { @@ -267,14 +313,24 @@ static inline bool AddrIsInLowShadow(uptr a) { return a >= kLowShadowBeg && a <= kLowShadowEnd; } +static inline bool AddrIsInMidMem(uptr a) { + PROFILE_ASAN_MAPPING(); + return kMidMemBeg && a >= kMidMemBeg && a <= kMidMemEnd; +} + +static inline bool AddrIsInMidShadow(uptr a) { + PROFILE_ASAN_MAPPING(); + return kMidMemBeg && a >= kMidShadowBeg && a <= kMidShadowEnd; +} + static inline bool AddrIsInHighMem(uptr a) { PROFILE_ASAN_MAPPING(); - return a >= kHighMemBeg && a <= kHighMemEnd; + return kHighMemBeg && a >= kHighMemBeg && a <= kHighMemEnd; } -static inline bool AddrIsInMidMem(uptr a) { +static inline bool AddrIsInHighShadow(uptr a) { PROFILE_ASAN_MAPPING(); - return kMidMemBeg && a >= kMidMemBeg && a <= kMidMemEnd; + return kHighMemBeg && a >= kHighShadowBeg && a <= kHighShadowEnd; } static inline bool AddrIsInShadowGap(uptr a) { @@ -292,6 +348,12 @@ static inline bool AddrIsInShadowGap(uptr a) { return a >= kShadowGapBeg && a <= kShadowGapEnd; } +} // namespace __asan + +#endif // SANITIZER_MYRIAD2 + +namespace __asan { + static inline bool AddrIsInMem(uptr a) { PROFILE_ASAN_MAPPING(); return AddrIsInLowMem(a) || AddrIsInMidMem(a) || AddrIsInHighMem(a) || @@ -304,16 +366,6 @@ static inline uptr MemToShadow(uptr p) { return MEM_TO_SHADOW(p); } -static inline bool AddrIsInHighShadow(uptr a) { - PROFILE_ASAN_MAPPING(); - return a >= kHighShadowBeg && a <= kHighMemEnd; -} - -static inline bool AddrIsInMidShadow(uptr a) { - PROFILE_ASAN_MAPPING(); - return kMidMemBeg && a >= kMidShadowBeg && a <= kMidMemEnd; -} - static inline bool AddrIsInShadow(uptr a) { PROFILE_ASAN_MAPPING(); return AddrIsInLowShadow(a) || AddrIsInMidShadow(a) || AddrIsInHighShadow(a); @@ -326,6 +378,8 @@ static inline bool AddrIsAlignedByGranularity(uptr a) { static inline bool AddressIsPoisoned(uptr a) { PROFILE_ASAN_MAPPING(); + if (SANITIZER_MYRIAD2 && !AddrIsInMem(a) && !AddrIsInShadow(a)) + return false; const uptr kAccessSize = 1; u8 *shadow_address = (u8*)MEM_TO_SHADOW(a); s8 shadow_value = *shadow_address; diff --git a/libsanitizer/asan/asan_mapping_myriad.h b/libsanitizer/asan/asan_mapping_myriad.h new file mode 100644 index 00000000000..fa8d4fe0270 --- /dev/null +++ b/libsanitizer/asan/asan_mapping_myriad.h @@ -0,0 +1,84 @@ +//===-- asan_mapping_myriad.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 AddressSanitizer, an address sanity checker. +// +// Myriad-specific definitions for ASan memory mapping. +//===----------------------------------------------------------------------===// +#ifndef ASAN_MAPPING_MYRIAD_H +#define ASAN_MAPPING_MYRIAD_H + +#define RAW_ADDR(mem) ((mem) & ~kMyriadCacheBitMask32) +#define MEM_TO_SHADOW(mem) \ + (((RAW_ADDR(mem) - kLowMemBeg) >> SHADOW_SCALE) + (SHADOW_OFFSET)) + +#define kLowMemBeg kMyriadMemoryOffset32 +#define kLowMemEnd (SHADOW_OFFSET - 1) + +#define kLowShadowBeg SHADOW_OFFSET +#define kLowShadowEnd MEM_TO_SHADOW(kLowMemEnd) + +#define kHighMemBeg 0 + +#define kHighShadowBeg 0 +#define kHighShadowEnd 0 + +#define kMidShadowBeg 0 +#define kMidShadowEnd 0 + +#define kShadowGapBeg (kLowShadowEnd + 1) +#define kShadowGapEnd kMyriadMemoryEnd32 + +#define kShadowGap2Beg 0 +#define kShadowGap2End 0 + +#define kShadowGap3Beg 0 +#define kShadowGap3End 0 + +namespace __asan { + +static inline bool AddrIsInLowMem(uptr a) { + PROFILE_ASAN_MAPPING(); + a = RAW_ADDR(a); + return a >= kLowMemBeg && a <= kLowMemEnd; +} + +static inline bool AddrIsInLowShadow(uptr a) { + PROFILE_ASAN_MAPPING(); + a = RAW_ADDR(a); + return a >= kLowShadowBeg && a <= kLowShadowEnd; +} + +static inline bool AddrIsInMidMem(uptr a) { + PROFILE_ASAN_MAPPING(); + return false; +} + +static inline bool AddrIsInMidShadow(uptr a) { + PROFILE_ASAN_MAPPING(); + return false; +} + +static inline bool AddrIsInHighMem(uptr a) { + PROFILE_ASAN_MAPPING(); + return false; +} + +static inline bool AddrIsInHighShadow(uptr a) { + PROFILE_ASAN_MAPPING(); + return false; +} + +static inline bool AddrIsInShadowGap(uptr a) { + PROFILE_ASAN_MAPPING(); + a = RAW_ADDR(a); + return a >= kShadowGapBeg && a <= kShadowGapEnd; +} + +} // namespace __asan + +#endif // ASAN_MAPPING_MYRIAD_H diff --git a/libsanitizer/asan/asan_memory_profile.cc b/libsanitizer/asan/asan_memory_profile.cc index 42d07c705f1..23183bda79b 100644 --- a/libsanitizer/asan/asan_memory_profile.cc +++ b/libsanitizer/asan/asan_memory_profile.cc @@ -29,9 +29,9 @@ struct AllocationSite { class HeapProfile { public: - HeapProfile() : allocations_(1024) {} + HeapProfile() { allocations_.reserve(1024); } - void ProcessChunk(const AsanChunkView& cv) { + void ProcessChunk(const AsanChunkView &cv) { if (cv.IsAllocated()) { total_allocated_user_size_ += cv.UsedSize(); total_allocated_count_++; @@ -47,10 +47,10 @@ class HeapProfile { } void Print(uptr top_percent, uptr max_number_of_contexts) { - InternalSort(&allocations_, allocations_.size(), - [](const AllocationSite &a, const AllocationSite &b) { - return a.total_size > b.total_size; - }); + Sort(allocations_.data(), allocations_.size(), + [](const AllocationSite &a, const AllocationSite &b) { + return a.total_size > b.total_size; + }); CHECK(total_allocated_user_size_); uptr total_shown = 0; Printf("Live Heap Allocations: %zd bytes in %zd chunks; quarantined: " diff --git a/libsanitizer/asan/asan_new_delete.cc b/libsanitizer/asan/asan_new_delete.cc index e95b5287191..7e194e2229c 100644 --- a/libsanitizer/asan/asan_new_delete.cc +++ b/libsanitizer/asan/asan_new_delete.cc @@ -12,6 +12,8 @@ #include "asan_allocator.h" #include "asan_internal.h" +#include "asan_malloc_local.h" +#include "asan_report.h" #include "asan_stack.h" #include "interception/interception.h" @@ -22,7 +24,7 @@ // anyway by passing extra -export flags to the linker, which is exactly that // dllexport would normally do. We need to export them in order to make the // VS2015 dynamic CRT (MD) work. -#if SANITIZER_WINDOWS +#if SANITIZER_WINDOWS && defined(_MSC_VER) #define CXX_OPERATOR_ATTRIBUTE #define COMMENT_EXPORT(sym) __pragma(comment(linker, "/export:" sym)) #ifdef _WIN64 @@ -65,16 +67,28 @@ struct nothrow_t {}; enum class align_val_t: size_t {}; } // namespace std -// TODO(alekseys): throw std::bad_alloc instead of dying on OOM. +// 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)) DieOnFailure::OnOOM();\ + 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)) DieOnFailure::OnOOM();\ + if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\ return res; // On OS X it's not enough to just provide our own 'operator new' and @@ -123,77 +137,73 @@ INTERCEPTOR(void *, _ZnwmRKSt9nothrow_t, size_t size, std::nothrow_t const&) { INTERCEPTOR(void *, _ZnamRKSt9nothrow_t, size_t size, std::nothrow_t const&) { OPERATOR_NEW_BODY(FROM_NEW_BR, true /*nothrow*/); } -#endif +#endif // !SANITIZER_MAC #define OPERATOR_DELETE_BODY(type) \ + if (IS_FROM_LOCAL_POOL(ptr)) return;\ + GET_STACK_TRACE_FREE;\ + asan_delete(ptr, 0, 0, &stack, type); + +#define OPERATOR_DELETE_BODY_SIZE(type) \ + if (IS_FROM_LOCAL_POOL(ptr)) return;\ + GET_STACK_TRACE_FREE;\ + asan_delete(ptr, size, 0, &stack, type); + +#define OPERATOR_DELETE_BODY_ALIGN(type) \ + if (IS_FROM_LOCAL_POOL(ptr)) return;\ + GET_STACK_TRACE_FREE;\ + asan_delete(ptr, 0, static_cast(align), &stack, type); + +#define OPERATOR_DELETE_BODY_SIZE_ALIGN(type) \ + if (IS_FROM_LOCAL_POOL(ptr)) return;\ GET_STACK_TRACE_FREE;\ - asan_free(ptr, &stack, type); + asan_delete(ptr, size, static_cast(align), &stack, type); #if !SANITIZER_MAC CXX_OPERATOR_ATTRIBUTE -void operator delete(void *ptr) NOEXCEPT { - OPERATOR_DELETE_BODY(FROM_NEW); -} +void operator delete(void *ptr) NOEXCEPT +{ OPERATOR_DELETE_BODY(FROM_NEW); } CXX_OPERATOR_ATTRIBUTE -void operator delete[](void *ptr) NOEXCEPT { - OPERATOR_DELETE_BODY(FROM_NEW_BR); -} +void operator delete[](void *ptr) NOEXCEPT +{ OPERATOR_DELETE_BODY(FROM_NEW_BR); } CXX_OPERATOR_ATTRIBUTE -void operator delete(void *ptr, std::nothrow_t const&) { - OPERATOR_DELETE_BODY(FROM_NEW); -} +void operator delete(void *ptr, std::nothrow_t const&) +{ OPERATOR_DELETE_BODY(FROM_NEW); } CXX_OPERATOR_ATTRIBUTE -void operator delete[](void *ptr, std::nothrow_t const&) { - OPERATOR_DELETE_BODY(FROM_NEW_BR); -} +void operator delete[](void *ptr, std::nothrow_t const&) +{ OPERATOR_DELETE_BODY(FROM_NEW_BR); } CXX_OPERATOR_ATTRIBUTE -void operator delete(void *ptr, size_t size) NOEXCEPT { - GET_STACK_TRACE_FREE; - asan_sized_free(ptr, size, &stack, FROM_NEW); -} +void operator delete(void *ptr, size_t size) NOEXCEPT +{ OPERATOR_DELETE_BODY_SIZE(FROM_NEW); } CXX_OPERATOR_ATTRIBUTE -void operator delete[](void *ptr, size_t size) NOEXCEPT { - GET_STACK_TRACE_FREE; - asan_sized_free(ptr, size, &stack, FROM_NEW_BR); -} +void operator delete[](void *ptr, size_t size) NOEXCEPT +{ OPERATOR_DELETE_BODY_SIZE(FROM_NEW_BR); } CXX_OPERATOR_ATTRIBUTE -void operator delete(void *ptr, std::align_val_t) NOEXCEPT { - OPERATOR_DELETE_BODY(FROM_NEW); -} +void operator delete(void *ptr, std::align_val_t align) NOEXCEPT +{ OPERATOR_DELETE_BODY_ALIGN(FROM_NEW); } CXX_OPERATOR_ATTRIBUTE -void operator delete[](void *ptr, std::align_val_t) NOEXCEPT { - OPERATOR_DELETE_BODY(FROM_NEW_BR); -} +void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT +{ OPERATOR_DELETE_BODY_ALIGN(FROM_NEW_BR); } CXX_OPERATOR_ATTRIBUTE -void operator delete(void *ptr, std::align_val_t, std::nothrow_t const&) { - OPERATOR_DELETE_BODY(FROM_NEW); -} +void operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&) +{ OPERATOR_DELETE_BODY_ALIGN(FROM_NEW); } CXX_OPERATOR_ATTRIBUTE -void operator delete[](void *ptr, std::align_val_t, std::nothrow_t const&) { - OPERATOR_DELETE_BODY(FROM_NEW_BR); -} +void operator delete[](void *ptr, std::align_val_t align, std::nothrow_t const&) +{ OPERATOR_DELETE_BODY_ALIGN(FROM_NEW_BR); } CXX_OPERATOR_ATTRIBUTE -void operator delete(void *ptr, size_t size, std::align_val_t) NOEXCEPT { - GET_STACK_TRACE_FREE; - asan_sized_free(ptr, size, &stack, FROM_NEW); -} +void operator delete(void *ptr, size_t size, std::align_val_t align) NOEXCEPT +{ OPERATOR_DELETE_BODY_SIZE_ALIGN(FROM_NEW); } CXX_OPERATOR_ATTRIBUTE -void operator delete[](void *ptr, size_t size, std::align_val_t) NOEXCEPT { - GET_STACK_TRACE_FREE; - asan_sized_free(ptr, size, &stack, FROM_NEW_BR); -} +void operator delete[](void *ptr, size_t size, std::align_val_t align) NOEXCEPT +{ OPERATOR_DELETE_BODY_SIZE_ALIGN(FROM_NEW_BR); } #else // SANITIZER_MAC -INTERCEPTOR(void, _ZdlPv, void *ptr) { - OPERATOR_DELETE_BODY(FROM_NEW); -} -INTERCEPTOR(void, _ZdaPv, void *ptr) { - OPERATOR_DELETE_BODY(FROM_NEW_BR); -} -INTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) { - OPERATOR_DELETE_BODY(FROM_NEW); -} -INTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) { - OPERATOR_DELETE_BODY(FROM_NEW_BR); -} -#endif +INTERCEPTOR(void, _ZdlPv, void *ptr) +{ OPERATOR_DELETE_BODY(FROM_NEW); } +INTERCEPTOR(void, _ZdaPv, void *ptr) +{ OPERATOR_DELETE_BODY(FROM_NEW_BR); } +INTERCEPTOR(void, _ZdlPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) +{ OPERATOR_DELETE_BODY(FROM_NEW); } +INTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) +{ OPERATOR_DELETE_BODY(FROM_NEW_BR); } +#endif // !SANITIZER_MAC diff --git a/libsanitizer/asan/asan_poisoning.cc b/libsanitizer/asan/asan_poisoning.cc index 1343dfbd39e..35409baf612 100644 --- a/libsanitizer/asan/asan_poisoning.cc +++ b/libsanitizer/asan/asan_poisoning.cc @@ -30,7 +30,7 @@ bool CanPoisonMemory() { } void PoisonShadow(uptr addr, uptr size, u8 value) { - if (!CanPoisonMemory()) return; + if (value && !CanPoisonMemory()) return; CHECK(AddrIsAlignedByGranularity(addr)); CHECK(AddrIsInMem(addr)); CHECK(AddrIsAlignedByGranularity(addr + size)); @@ -180,8 +180,15 @@ int __asan_address_is_poisoned(void const volatile *addr) { uptr __asan_region_is_poisoned(uptr beg, uptr size) { if (!size) return 0; uptr end = beg + size; - if (!AddrIsInMem(beg)) return beg; - if (!AddrIsInMem(end)) return end; + if (SANITIZER_MYRIAD2) { + // On Myriad, address not in DRAM range need to be treated as + // unpoisoned. + if (!AddrIsInMem(beg) && !AddrIsInShadow(beg)) return 0; + if (!AddrIsInMem(end) && !AddrIsInShadow(end)) return 0; + } else { + if (!AddrIsInMem(beg)) return beg; + if (!AddrIsInMem(end)) return end; + } CHECK_LT(beg, end); uptr aligned_b = RoundUpTo(beg, SHADOW_GRANULARITY); uptr aligned_e = RoundDownTo(end, SHADOW_GRANULARITY); diff --git a/libsanitizer/asan/asan_poisoning.h b/libsanitizer/asan/asan_poisoning.h index 942e74174c2..7e8c5886831 100644 --- a/libsanitizer/asan/asan_poisoning.h +++ b/libsanitizer/asan/asan_poisoning.h @@ -36,7 +36,7 @@ void PoisonShadowPartialRightRedzone(uptr addr, // performance-critical code with care. ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size, u8 value) { - DCHECK(CanPoisonMemory()); + DCHECK(!value || CanPoisonMemory()); uptr shadow_beg = MEM_TO_SHADOW(aligned_beg); uptr shadow_end = MEM_TO_SHADOW( aligned_beg + aligned_size - SHADOW_GRANULARITY) + 1; @@ -49,6 +49,9 @@ ALWAYS_INLINE void FastPoisonShadow(uptr aligned_beg, uptr aligned_size, // 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 || shadow_end - shadow_beg < common_flags()->clear_shadow_mmap_threshold) { REAL(memset)((void*)shadow_beg, value, shadow_end - shadow_beg); } else { diff --git a/libsanitizer/asan/asan_posix.cc b/libsanitizer/asan/asan_posix.cc index e113c02a8cc..d765dc79c51 100644 --- a/libsanitizer/asan/asan_posix.cc +++ b/libsanitizer/asan/asan_posix.cc @@ -23,7 +23,6 @@ #include "sanitizer_common/sanitizer_procmaps.h" #include -#include #include #include #include diff --git a/libsanitizer/asan/asan_premap_shadow.cc b/libsanitizer/asan/asan_premap_shadow.cc new file mode 100644 index 00000000000..4273ae5e389 --- /dev/null +++ b/libsanitizer/asan/asan_premap_shadow.cc @@ -0,0 +1,77 @@ +//===-- asan_premap_shadow.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. +// +// Reserve shadow memory with an ifunc resolver. +//===----------------------------------------------------------------------===// + +#include "asan_mapping.h" + +#if ASAN_PREMAP_SHADOW + +#include "asan_premap_shadow.h" +#include "sanitizer_common/sanitizer_posix.h" + +namespace __asan { + +// The code in this file needs to run in an unrelocated binary. It may not +// access any external symbol, including its own non-hidden globals. + +// Conservative upper limit. +uptr PremapShadowSize() { + uptr granularity = GetMmapGranularity(); + return RoundUpTo(GetMaxVirtualAddress() >> SHADOW_SCALE, granularity); +} + +// Returns an address aligned to 8 pages, such that one page on the left and +// PremapShadowSize() bytes on the right of it are mapped r/o. +uptr PremapShadow() { + uptr granularity = GetMmapGranularity(); + uptr alignment = granularity * 8; + uptr left_padding = granularity; + uptr shadow_size = PremapShadowSize(); + uptr map_size = shadow_size + left_padding + alignment; + + uptr map_start = (uptr)MmapNoAccess(map_size); + CHECK_NE(map_start, ~(uptr)0); + + uptr shadow_start = RoundUpTo(map_start + left_padding, alignment); + uptr shadow_end = shadow_start + shadow_size; + internal_munmap(reinterpret_cast(map_start), + shadow_start - left_padding - map_start); + internal_munmap(reinterpret_cast(shadow_end), + map_start + map_size - shadow_end); + return shadow_start; +} + +bool PremapShadowFailed() { + uptr shadow = reinterpret_cast(&__asan_shadow); + uptr resolver = reinterpret_cast(&__asan_premap_shadow); + // shadow == resolver is how Android KitKat and older handles ifunc. + // shadow == 0 just in case. + if (shadow == 0 || shadow == resolver) + return true; + return false; +} +} // namespace __asan + +extern "C" { +decltype(__asan_shadow)* __asan_premap_shadow() { + // The resolver may be called multiple times. Map the shadow just once. + static uptr premapped_shadow = 0; + if (!premapped_shadow) premapped_shadow = __asan::PremapShadow(); + return reinterpret_cast(premapped_shadow); +} + +// __asan_shadow is a "function" that has the same address as the first byte of +// the shadow mapping. +INTERFACE_ATTRIBUTE __attribute__((ifunc("__asan_premap_shadow"))) void +__asan_shadow(); +} + +#endif // ASAN_PREMAP_SHADOW diff --git a/libsanitizer/asan/asan_premap_shadow.h b/libsanitizer/asan/asan_premap_shadow.h new file mode 100644 index 00000000000..345b56ea6a6 --- /dev/null +++ b/libsanitizer/asan/asan_premap_shadow.h @@ -0,0 +1,28 @@ +//===-- asan_mapping.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 AddressSanitizer, an address sanity checker. +// +// Premap shadow range with an ifunc resolver. +//===----------------------------------------------------------------------===// + + +#ifndef ASAN_PREMAP_SHADOW_H +#define ASAN_PREMAP_SHADOW_H + +#if ASAN_PREMAP_SHADOW +namespace __asan { +// Conservative upper limit. +uptr PremapShadowSize(); +bool PremapShadowFailed(); +} +#endif + +extern "C" INTERFACE_ATTRIBUTE void __asan_shadow(); +extern "C" decltype(__asan_shadow)* __asan_premap_shadow(); + +#endif // ASAN_PREMAP_SHADOW_H diff --git a/libsanitizer/asan/asan_report.cc b/libsanitizer/asan/asan_report.cc index 434aa734c8f..787b6890a34 100644 --- a/libsanitizer/asan/asan_report.cc +++ b/libsanitizer/asan/asan_report.cc @@ -82,7 +82,7 @@ static void PrintZoneForPointer(uptr ptr, uptr zone_ptr, bool ParseFrameDescription(const char *frame_descr, InternalMmapVector *vars) { CHECK(frame_descr); - char *p; + const char *p; // This string is created by the compiler and has the following form: // "n alloc_1 alloc_2 ... alloc_n" // where alloc_i looks like "offset size len ObjectName" @@ -132,6 +132,10 @@ class ScopedInErrorReport { } ~ScopedInErrorReport() { + if (halt_on_error_ && !__sanitizer_acquire_crash_state()) { + asanThreadRegistry().Unlock(); + return; + } ASAN_ON_ERROR(); if (current_error_.IsValid()) current_error_.Print(); @@ -150,7 +154,7 @@ class ScopedInErrorReport { // Copy the message buffer so that we could start logging without holding a // lock that gets aquired during printing. - InternalScopedBuffer buffer_copy(kErrorMessageBufferSize); + InternalMmapVector buffer_copy(kErrorMessageBufferSize); { BlockingMutexLock l(&error_message_buf_mutex); internal_memcpy(buffer_copy.data(), @@ -200,7 +204,7 @@ class ScopedInErrorReport { bool halt_on_error_; }; -ErrorDescription ScopedInErrorReport::current_error_; +ErrorDescription ScopedInErrorReport::current_error_(LINKER_INITIALIZED); void ReportDeadlySignal(const SignalContext &sig) { ScopedInErrorReport in_report(/*fatal*/ true); @@ -214,11 +218,12 @@ void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack) { in_report.ReportError(error); } -void ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size, +void ReportNewDeleteTypeMismatch(uptr addr, uptr delete_size, + uptr delete_alignment, BufferedStackTrace *free_stack) { ScopedInErrorReport in_report; - ErrorNewDeleteSizeMismatch error(GetCurrentTidOrInvalid(), free_stack, addr, - delete_size); + ErrorNewDeleteTypeMismatch error(GetCurrentTidOrInvalid(), free_stack, addr, + delete_size, delete_alignment); in_report.ReportError(error); } @@ -251,6 +256,62 @@ void ReportSanitizerGetAllocatedSizeNotOwned(uptr addr, in_report.ReportError(error); } +void ReportCallocOverflow(uptr count, uptr size, BufferedStackTrace *stack) { + ScopedInErrorReport in_report(/*fatal*/ true); + ErrorCallocOverflow 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); + in_report.ReportError(error); +} + +void ReportInvalidAllocationAlignment(uptr alignment, + BufferedStackTrace *stack) { + ScopedInErrorReport in_report(/*fatal*/ true); + ErrorInvalidAllocationAlignment error(GetCurrentTidOrInvalid(), stack, + alignment); + in_report.ReportError(error); +} + +void ReportInvalidAlignedAllocAlignment(uptr size, uptr alignment, + BufferedStackTrace *stack) { + ScopedInErrorReport in_report(/*fatal*/ true); + ErrorInvalidAlignedAllocAlignment error(GetCurrentTidOrInvalid(), stack, + size, alignment); + in_report.ReportError(error); +} + +void ReportInvalidPosixMemalignAlignment(uptr alignment, + BufferedStackTrace *stack) { + ScopedInErrorReport in_report(/*fatal*/ true); + ErrorInvalidPosixMemalignAlignment error(GetCurrentTidOrInvalid(), stack, + alignment); + in_report.ReportError(error); +} + +void ReportAllocationSizeTooBig(uptr user_size, uptr total_size, uptr max_size, + BufferedStackTrace *stack) { + ScopedInErrorReport in_report(/*fatal*/ true); + ErrorAllocationSizeTooBig error(GetCurrentTidOrInvalid(), stack, user_size, + total_size, max_size); + in_report.ReportError(error); +} + +void ReportRssLimitExceeded(BufferedStackTrace *stack) { + ScopedInErrorReport in_report(/*fatal*/ true); + ErrorRssLimitExceeded error(GetCurrentTidOrInvalid(), stack); + in_report.ReportError(error); +} + +void ReportOutOfMemory(uptr requested_size, BufferedStackTrace *stack) { + ScopedInErrorReport in_report(/*fatal*/ true); + ErrorOutOfMemory error(GetCurrentTidOrInvalid(), stack, requested_size); + in_report.ReportError(error); +} + void ReportStringFunctionMemoryRangesOverlap(const char *function, const char *offset1, uptr length1, const char *offset2, uptr length2, diff --git a/libsanitizer/asan/asan_report.h b/libsanitizer/asan/asan_report.h index 5d47712bd2d..b48605da41e 100644 --- a/libsanitizer/asan/asan_report.h +++ b/libsanitizer/asan/asan_report.h @@ -10,6 +10,9 @@ // ASan-private header for error reporting functions. //===----------------------------------------------------------------------===// +#ifndef ASAN_REPORT_H +#define ASAN_REPORT_H + #include "asan_allocator.h" #include "asan_internal.h" #include "asan_thread.h" @@ -45,7 +48,8 @@ bool ParseFrameDescription(const char *frame_descr, void ReportGenericError(uptr pc, uptr bp, uptr sp, uptr addr, bool is_write, uptr access_size, u32 exp, bool fatal); void ReportDeadlySignal(const SignalContext &sig); -void ReportNewDeleteSizeMismatch(uptr addr, uptr delete_size, +void ReportNewDeleteTypeMismatch(uptr addr, uptr delete_size, + uptr delete_alignment, BufferedStackTrace *free_stack); void ReportDoubleFree(uptr addr, BufferedStackTrace *free_stack); void ReportFreeNotMalloced(uptr addr, BufferedStackTrace *free_stack); @@ -55,6 +59,18 @@ void ReportAllocTypeMismatch(uptr addr, BufferedStackTrace *free_stack, void ReportMallocUsableSizeNotOwned(uptr addr, BufferedStackTrace *stack); void ReportSanitizerGetAllocatedSizeNotOwned(uptr addr, BufferedStackTrace *stack); +void ReportCallocOverflow(uptr count, uptr size, BufferedStackTrace *stack); +void ReportPvallocOverflow(uptr size, BufferedStackTrace *stack); +void ReportInvalidAllocationAlignment(uptr alignment, + BufferedStackTrace *stack); +void ReportInvalidAlignedAllocAlignment(uptr size, uptr alignment, + BufferedStackTrace *stack); +void ReportInvalidPosixMemalignAlignment(uptr alignment, + BufferedStackTrace *stack); +void ReportAllocationSizeTooBig(uptr user_size, uptr total_size, uptr max_size, + BufferedStackTrace *stack); +void ReportRssLimitExceeded(BufferedStackTrace *stack); +void ReportOutOfMemory(uptr requested_size, BufferedStackTrace *stack); void ReportStringFunctionMemoryRangesOverlap(const char *function, const char *offset1, uptr length1, const char *offset2, uptr length2, @@ -77,3 +93,4 @@ void ReportMacCfReallocUnknown(uptr addr, uptr zone_ptr, BufferedStackTrace *stack); } // namespace __asan +#endif // ASAN_REPORT_H diff --git a/libsanitizer/asan/asan_rtems.cc b/libsanitizer/asan/asan_rtems.cc new file mode 100644 index 00000000000..fa68373e63a --- /dev/null +++ b/libsanitizer/asan/asan_rtems.cc @@ -0,0 +1,251 @@ +//===-- asan_rtems.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. +// +// RTEMS-specific details. +//===----------------------------------------------------------------------===// + +#include "sanitizer_common/sanitizer_rtems.h" +#if SANITIZER_RTEMS + +#include "asan_internal.h" +#include "asan_interceptors.h" +#include "asan_mapping.h" +#include "asan_poisoning.h" +#include "asan_report.h" +#include "asan_stack.h" +#include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_libc.h" + +#include +#include + +namespace __asan { + +static void ResetShadowMemory() { + uptr shadow_start = SHADOW_OFFSET; + uptr shadow_end = MEM_TO_SHADOW(kMyriadMemoryEnd32); + uptr gap_start = MEM_TO_SHADOW(shadow_start); + uptr gap_end = MEM_TO_SHADOW(shadow_end); + + REAL(memset)((void *)shadow_start, 0, shadow_end - shadow_start); + REAL(memset)((void *)gap_start, kAsanShadowGap, gap_end - gap_start); +} + +void InitializeShadowMemory() { + kHighMemEnd = 0; + kMidMemBeg = 0; + kMidMemEnd = 0; + + ResetShadowMemory(); +} + +void AsanApplyToGlobals(globals_op_fptr op, const void *needle) { + UNIMPLEMENTED(); +} + +void AsanCheckDynamicRTPrereqs() {} +void AsanCheckIncompatibleRT() {} +void InitializeAsanInterceptors() {} +void InitializePlatformInterceptors() {} +void InitializePlatformExceptionHandlers() {} + +// RTEMS only support static linking; it sufficies to return with no +// error. +void *AsanDoesNotSupportStaticLinkage() { return nullptr; } + +void AsanOnDeadlySignal(int signo, void *siginfo, void *context) { + UNIMPLEMENTED(); +} + +void EarlyInit() { + // Provide early initialization of shadow memory so that + // instrumented code running before full initialzation will not + // report spurious errors. + ResetShadowMemory(); +} + +// We can use a plain thread_local variable for TSD. +static thread_local void *per_thread; + +void *AsanTSDGet() { return per_thread; } + +void AsanTSDSet(void *tsd) { per_thread = tsd; } + +// There's no initialization needed, and the passed-in destructor +// will never be called. Instead, our own thread destruction hook +// (below) will call AsanThread::TSDDtor directly. +void AsanTSDInit(void (*destructor)(void *tsd)) { + DCHECK(destructor == &PlatformTSDDtor); +} + +void PlatformTSDDtor(void *tsd) { UNREACHABLE(__func__); } + +// +// Thread registration. We provide an API similar to the Fushia port. +// + +struct AsanThread::InitOptions { + uptr stack_bottom, stack_size, tls_bottom, tls_size; +}; + +// Shared setup between thread creation and startup for the initial thread. +static AsanThread *CreateAsanThread(StackTrace *stack, u32 parent_tid, + uptr user_id, bool detached, + uptr stack_bottom, uptr stack_size, + uptr tls_bottom, uptr tls_size) { + // In lieu of AsanThread::Create. + AsanThread *thread = (AsanThread *)MmapOrDie(sizeof(AsanThread), __func__); + AsanThreadContext::CreateThreadContextArgs args = {thread, stack}; + asanThreadRegistry().CreateThread(user_id, detached, parent_tid, &args); + + // On other systems, AsanThread::Init() is called from the new + // thread itself. But on RTEMS we already know the stack address + // range beforehand, so we can do most of the setup right now. + const AsanThread::InitOptions options = {stack_bottom, stack_size, + tls_bottom, tls_size}; + thread->Init(&options); + return thread; +} + +// This gets the same arguments passed to Init by CreateAsanThread, above. +// We're in the creator thread before the new thread is actually started, but +// its stack and tls address range are already known. +void AsanThread::SetThreadStackAndTls(const AsanThread::InitOptions *options) { + DCHECK_NE(GetCurrentThread(), this); + DCHECK_NE(GetCurrentThread(), nullptr); + CHECK_NE(options->stack_bottom, 0); + CHECK_NE(options->stack_size, 0); + stack_bottom_ = options->stack_bottom; + stack_top_ = options->stack_bottom + options->stack_size; + tls_begin_ = options->tls_bottom; + tls_end_ = options->tls_bottom + options->tls_size; +} + +// Called by __asan::AsanInitInternal (asan_rtl.c). Unlike other ports, the +// main thread on RTEMS does not require special treatment; its AsanThread is +// already created by the provided hooks. This function simply looks up and +// returns the created thread. +AsanThread *CreateMainThread() { + return GetThreadContextByTidLocked(0)->thread; +} + +// This is called before each thread creation is attempted. So, in +// its first call, the calling thread is the initial and sole thread. +static void *BeforeThreadCreateHook(uptr user_id, bool detached, + uptr stack_bottom, uptr stack_size, + uptr tls_bottom, uptr tls_size) { + EnsureMainThreadIDIsCorrect(); + // Strict init-order checking is thread-hostile. + if (flags()->strict_init_order) StopInitOrderChecking(); + + GET_STACK_TRACE_THREAD; + u32 parent_tid = GetCurrentTidOrInvalid(); + + return CreateAsanThread(&stack, parent_tid, user_id, detached, + stack_bottom, stack_size, tls_bottom, tls_size); +} + +// This is called after creating a new thread (in the creating thread), +// with the pointer returned by BeforeThreadCreateHook (above). +static void ThreadCreateHook(void *hook, bool aborted) { + AsanThread *thread = static_cast(hook); + if (!aborted) { + // The thread was created successfully. + // ThreadStartHook is already running in the new thread. + } else { + // The thread wasn't created after all. + // Clean up everything we set up in BeforeThreadCreateHook. + asanThreadRegistry().FinishThread(thread->tid()); + UnmapOrDie(thread, sizeof(AsanThread)); + } +} + +// This is called (1) in the newly-created thread before it runs anything else, +// with the pointer returned by BeforeThreadCreateHook (above). (2) before a +// thread restart. +static void ThreadStartHook(void *hook, uptr os_id) { + if (!hook) + return; + + AsanThread *thread = static_cast(hook); + SetCurrentThread(thread); + + ThreadStatus status = + asanThreadRegistry().GetThreadLocked(thread->tid())->status; + DCHECK(status == ThreadStatusCreated || status == ThreadStatusRunning); + // 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); + else { + // In a thread restart, a thread may resume execution at an + // arbitrary function entry point, with its stack and TLS state + // reset. We unpoison the stack in that case. + PoisonShadow(thread->stack_bottom(), thread->stack_size(), 0); + } +} + +// Each thread runs this just before it exits, +// with the pointer returned by BeforeThreadCreateHook (above). +// All per-thread destructors have already been called. +static void ThreadExitHook(void *hook, uptr os_id) { + AsanThread *thread = static_cast(hook); + if (thread) + AsanThread::TSDDtor(thread->context()); +} + +static void HandleExit() { + // Disable ASan by setting it to uninitialized. Also reset the + // shadow memory to avoid reporting errors after the run-time has + // been desroyed. + if (asan_inited) { + asan_inited = false; + ResetShadowMemory(); + } +} + +} // namespace __asan + +// These are declared (in extern "C") by . +// The system runtime will call our definitions directly. + +extern "C" { +void __sanitizer_early_init() { + __asan::EarlyInit(); +} + +void *__sanitizer_before_thread_create_hook(uptr thread, bool detached, + const char *name, + void *stack_base, size_t stack_size, + void *tls_base, size_t tls_size) { + return __asan::BeforeThreadCreateHook( + thread, detached, + reinterpret_cast(stack_base), stack_size, + reinterpret_cast(tls_base), tls_size); +} + +void __sanitizer_thread_create_hook(void *handle, uptr thread, int status) { + __asan::ThreadCreateHook(handle, status != 0); +} + +void __sanitizer_thread_start_hook(void *handle, uptr self) { + __asan::ThreadStartHook(handle, self); +} + +void __sanitizer_thread_exit_hook(void *handle, uptr self) { + __asan::ThreadExitHook(handle, self); +} + +void __sanitizer_exit() { + __asan::HandleExit(); +} +} // "C" + +#endif // SANITIZER_RTEMS diff --git a/libsanitizer/asan/asan_rtl.cc b/libsanitizer/asan/asan_rtl.cc index 3905658a494..ba3acf2c5d2 100644 --- a/libsanitizer/asan/asan_rtl.cc +++ b/libsanitizer/asan/asan_rtl.cc @@ -54,7 +54,8 @@ static void AsanDie() { UnmapOrDie((void*)kLowShadowBeg, kMidMemBeg - kLowShadowBeg); UnmapOrDie((void*)kMidMemEnd, kHighShadowEnd - kMidMemEnd); } else { - UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg); + if (kHighShadowEnd) + UnmapOrDie((void*)kLowShadowBeg, kHighShadowEnd - kLowShadowBeg); } } } @@ -63,8 +64,14 @@ static void AsanCheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2) { Report("AddressSanitizer CHECK failed: %s:%d \"%s\" (0x%zx, 0x%zx)\n", file, line, cond, (uptr)v1, (uptr)v2); - // FIXME: check for infinite recursion without a thread-local counter here. - PRINT_CURRENT_STACK_CHECK(); + + // Print a stack trace the first time we come here. Otherwise, we probably + // failed a CHECK during symbolization. + static atomic_uint32_t num_calls; + if (atomic_fetch_add(&num_calls, 1, memory_order_relaxed) == 0) { + PRINT_CURRENT_STACK_CHECK(); + } + Die(); } @@ -138,6 +145,8 @@ ASAN_REPORT_ERROR_N(load, false) ASAN_REPORT_ERROR_N(store, true) #define ASAN_MEMORY_ACCESS_CALLBACK_BODY(type, is_write, size, exp_arg, fatal) \ + if (SANITIZER_MYRIAD2 && !AddrIsInMem(addr) && !AddrIsInShadow(addr)) \ + return; \ uptr sp = MEM_TO_SHADOW(addr); \ uptr s = size <= SHADOW_GRANULARITY ? *reinterpret_cast(sp) \ : *reinterpret_cast(sp); \ @@ -304,20 +313,24 @@ static void asan_atexit() { } static void InitializeHighMemEnd() { +#if !SANITIZER_MYRIAD2 #if !ASAN_FIXED_MAPPING - kHighMemEnd = GetMaxVirtualAddress(); + kHighMemEnd = GetMaxUserVirtualAddress(); // Increase kHighMemEnd to make sure it's properly // aligned together with kHighMemBeg: kHighMemEnd |= SHADOW_GRANULARITY * GetMmapGranularity() - 1; #endif // !ASAN_FIXED_MAPPING CHECK_EQ((kHighMemBeg % GetMmapGranularity()), 0); +#endif // !SANITIZER_MYRIAD2 } void PrintAddressSpaceLayout() { - Printf("|| `[%p, %p]` || HighMem ||\n", - (void*)kHighMemBeg, (void*)kHighMemEnd); - Printf("|| `[%p, %p]` || HighShadow ||\n", - (void*)kHighShadowBeg, (void*)kHighShadowEnd); + if (kHighMemBeg) { + Printf("|| `[%p, %p]` || HighMem ||\n", + (void*)kHighMemBeg, (void*)kHighMemEnd); + Printf("|| `[%p, %p]` || HighShadow ||\n", + (void*)kHighShadowBeg, (void*)kHighShadowEnd); + } if (kMidMemBeg) { Printf("|| `[%p, %p]` || ShadowGap3 ||\n", (void*)kShadowGap3Beg, (void*)kShadowGap3End); @@ -336,11 +349,14 @@ void PrintAddressSpaceLayout() { Printf("|| `[%p, %p]` || LowMem ||\n", (void*)kLowMemBeg, (void*)kLowMemEnd); } - Printf("MemToShadow(shadow): %p %p %p %p", + Printf("MemToShadow(shadow): %p %p", (void*)MEM_TO_SHADOW(kLowShadowBeg), - (void*)MEM_TO_SHADOW(kLowShadowEnd), - (void*)MEM_TO_SHADOW(kHighShadowBeg), - (void*)MEM_TO_SHADOW(kHighShadowEnd)); + (void*)MEM_TO_SHADOW(kLowShadowEnd)); + if (kHighMemBeg) { + Printf(" %p %p", + (void*)MEM_TO_SHADOW(kHighShadowBeg), + (void*)MEM_TO_SHADOW(kHighShadowEnd)); + } if (kMidMemBeg) { Printf(" %p %p", (void*)MEM_TO_SHADOW(kMidShadowBeg), @@ -372,6 +388,7 @@ static void AsanInitInternal() { asan_init_is_running = true; CacheBinaryName(); + CheckASLR(); // Initialize flags. This must be done early, because most of the // initialization steps look at flags(). @@ -405,6 +422,7 @@ static void AsanInitInternal() { MaybeReexec(); // Setup internal allocator callback. + SetLowLevelAllocateMinAlignment(SHADOW_GRANULARITY); SetLowLevelAllocateCallback(OnLowLevelAllocate); InitializeAsanInterceptors(); @@ -523,6 +541,9 @@ void NOINLINE __asan_handle_no_return() { if (curr_thread) { top = curr_thread->stack_top(); bottom = ((uptr)&local_stack - PageSize) & ~(PageSize - 1); + } else if (SANITIZER_RTEMS) { + // Give up On RTEMS. + return; } else { CHECK(!SANITIZER_FUCHSIA); // If we haven't seen this thread, try asking the OS for stack bounds. diff --git a/libsanitizer/asan/asan_shadow_setup.cc b/libsanitizer/asan/asan_shadow_setup.cc index 9629b36798f..823187bf5f1 100644 --- a/libsanitizer/asan/asan_shadow_setup.cc +++ b/libsanitizer/asan/asan_shadow_setup.cc @@ -12,8 +12,9 @@ #include "sanitizer_common/sanitizer_platform.h" -// asan_fuchsia.cc has its own InitializeShadowMemory implementation. -#if !SANITIZER_FUCHSIA +// asan_fuchsia.cc and asan_rtems.cc have their own +// InitializeShadowMemory implementation. +#if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS #include "asan_internal.h" #include "asan_mapping.h" @@ -28,8 +29,7 @@ void ReserveShadowMemoryRange(uptr beg, uptr end, const char *name) { CHECK_EQ(((end + 1) % GetMmapGranularity()), 0); uptr size = end - beg + 1; DecreaseTotalMmap(size); // Don't count the shadow against mmap_limit_mb. - void *res = MmapFixedNoReserve(beg, size, name); - if (res != (void *)beg) { + if (!MmapFixedNoReserve(beg, size, name)) { Report( "ReserveShadowMemoryRange failed while trying to map 0x%zx bytes. " "Perhaps you're using ulimit -v\n", @@ -97,17 +97,21 @@ void InitializeShadowMemory() { // when necessary. When dynamic address is used, the macro |kLowShadowBeg| // expands to |__asan_shadow_memory_dynamic_address| which is // |kDefaultShadowSentinel|. + bool full_shadow_is_available = false; if (shadow_start == kDefaultShadowSentinel) { __asan_shadow_memory_dynamic_address = 0; CHECK_EQ(0, kLowShadowBeg); shadow_start = FindDynamicShadowStart(); + if (SANITIZER_LINUX) full_shadow_is_available = true; } // Update the shadow memory address (potentially) used by instrumentation. __asan_shadow_memory_dynamic_address = shadow_start; if (kLowShadowBeg) shadow_start -= GetMmapGranularity(); - bool full_shadow_is_available = - MemoryRangeIsAvailable(shadow_start, kHighShadowEnd); + + if (!full_shadow_is_available) + full_shadow_is_available = + MemoryRangeIsAvailable(shadow_start, kHighShadowEnd); #if SANITIZER_LINUX && defined(__x86_64__) && defined(_LP64) && \ !ASAN_FIXED_MAPPING @@ -156,4 +160,4 @@ void InitializeShadowMemory() { } // namespace __asan -#endif // !SANITIZER_FUCHSIA +#endif // !SANITIZER_FUCHSIA && !SANITIZER_RTEMS diff --git a/libsanitizer/asan/asan_stack.h b/libsanitizer/asan/asan_stack.h index aa8c4cdc2f2..5775e9d325c 100644 --- a/libsanitizer/asan/asan_stack.h +++ b/libsanitizer/asan/asan_stack.h @@ -29,9 +29,8 @@ u32 GetMallocContextSize(); // 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 GetStackTraceWithPcBpAndContext(BufferedStackTrace *stack, uptr max_depth, - uptr pc, uptr bp, void *context, - bool fast) { +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 @@ -60,32 +59,29 @@ void GetStackTraceWithPcBpAndContext(BufferedStackTrace *stack, uptr max_depth, // as early as possible (in functions exposed to the user), as we generally // don't want stack trace to contain functions from ASan internals. -#define GET_STACK_TRACE(max_size, fast) \ - BufferedStackTrace stack; \ - if (max_size <= 2) { \ - stack.size = max_size; \ - if (max_size > 0) { \ - stack.top_frame_bp = GET_CURRENT_FRAME(); \ - stack.trace_buffer[0] = StackTrace::GetCurrentPc(); \ - if (max_size > 1) \ - stack.trace_buffer[1] = GET_CALLER_PC(); \ - } \ - } else { \ - GetStackTraceWithPcBpAndContext(&stack, max_size, \ - StackTrace::GetCurrentPc(), \ - GET_CURRENT_FRAME(), 0, fast); \ +#define GET_STACK_TRACE(max_size, fast) \ + BufferedStackTrace stack; \ + if (max_size <= 2) { \ + stack.size = max_size; \ + if (max_size > 0) { \ + stack.top_frame_bp = GET_CURRENT_FRAME(); \ + stack.trace_buffer[0] = StackTrace::GetCurrentPc(); \ + if (max_size > 1) stack.trace_buffer[1] = GET_CALLER_PC(); \ + } \ + } else { \ + GetStackTrace(&stack, max_size, StackTrace::GetCurrentPc(), \ + GET_CURRENT_FRAME(), 0, fast); \ } -#define GET_STACK_TRACE_FATAL(pc, bp) \ - BufferedStackTrace stack; \ - GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, 0, \ - common_flags()->fast_unwind_on_fatal) +#define GET_STACK_TRACE_FATAL(pc, bp) \ + BufferedStackTrace stack; \ + GetStackTrace(&stack, kStackTraceMax, pc, bp, 0, \ + common_flags()->fast_unwind_on_fatal) -#define GET_STACK_TRACE_SIGNAL(sig) \ - BufferedStackTrace stack; \ - GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, \ - (sig).pc, (sig).bp, (sig).context, \ - 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) #define GET_STACK_TRACE_FATAL_HERE \ GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_fatal) diff --git a/libsanitizer/asan/asan_thread.cc b/libsanitizer/asan/asan_thread.cc index f817a10db27..82da9a28e82 100644 --- a/libsanitizer/asan/asan_thread.cc +++ b/libsanitizer/asan/asan_thread.cc @@ -219,22 +219,25 @@ FakeStack *AsanThread::AsyncSignalSafeLazyInitFakeStack() { void AsanThread::Init(const InitOptions *options) { next_stack_top_ = next_stack_bottom_ = 0; atomic_store(&stack_switching_, false, memory_order_release); - fake_stack_ = nullptr; // Will be initialized lazily if needed. CHECK_EQ(this->stack_size(), 0U); SetThreadStackAndTls(options); 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) + AsyncSignalSafeLazyInitFakeStack(); int local = 0; VReport(1, "T%d: stack [%p,%p) size 0x%zx; local=%p\n", tid(), (void *)stack_bottom_, (void *)stack_top_, stack_top_ - stack_bottom_, &local); } -// Fuchsia doesn't use ThreadStart. -// asan_fuchsia.c defines CreateMainThread and SetThreadStackAndTls. -#if !SANITIZER_FUCHSIA +// Fuchsia and RTEMS don't use ThreadStart. +// asan_fuchsia.c/asan_rtems.c define CreateMainThread and +// SetThreadStackAndTls. +#if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS thread_return_t AsanThread::ThreadStart( tid_t os_id, atomic_uintptr_t *signal_thread_is_registered) { @@ -294,12 +297,17 @@ void AsanThread::SetThreadStackAndTls(const InitOptions *options) { CHECK(AddrIsInStack((uptr)&local)); } -#endif // !SANITIZER_FUCHSIA +#endif // !SANITIZER_FUCHSIA && !SANITIZER_RTEMS void AsanThread::ClearShadowForThreadStackAndTLS() { PoisonShadow(stack_bottom_, stack_top_ - stack_bottom_, 0); - if (tls_begin_ != tls_end_) - PoisonShadow(tls_begin_, tls_end_ - tls_begin_, 0); + if (tls_begin_ != tls_end_) { + uptr tls_begin_aligned = RoundDownTo(tls_begin_, SHADOW_GRANULARITY); + uptr tls_end_aligned = RoundUpTo(tls_end_, SHADOW_GRANULARITY); + FastPoisonShadowPartialRightRedzone(tls_begin_aligned, + tls_end_ - tls_begin_aligned, + tls_end_aligned - tls_end_, 0); + } } bool AsanThread::GetStackFrameAccessByAddr(uptr addr, @@ -384,6 +392,9 @@ static bool ThreadStackContainsAddress(ThreadContextBase *tctx_base, } AsanThread *GetCurrentThread() { + if (SANITIZER_RTEMS && !asan_inited) + return nullptr; + AsanThreadContext *context = reinterpret_cast(AsanTSDGet()); if (!context) { @@ -475,6 +486,11 @@ void UnlockThreadRegistry() { __asan::asanThreadRegistry().Unlock(); } +ThreadRegistry *GetThreadRegistryLocked() { + __asan::asanThreadRegistry().CheckLocked(); + return &__asan::asanThreadRegistry(); +} + void EnsureMainThreadIDIsCorrect() { __asan::EnsureMainThreadIDIsCorrect(); } diff --git a/libsanitizer/asan/asan_win.cc b/libsanitizer/asan/asan_win.cc index 02c7ed11628..8473f59c78a 100644 --- a/libsanitizer/asan/asan_win.cc +++ b/libsanitizer/asan/asan_win.cc @@ -157,6 +157,14 @@ INTERCEPTOR_WINAPI(DWORD, CreateThread, namespace __asan { 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)); + ASAN_INTERCEPT_FUNC(CreateThread); ASAN_INTERCEPT_FUNC(SetUnhandledExceptionFilter); @@ -220,8 +228,8 @@ uptr FindDynamicShadowStart() { uptr alignment = 8 * granularity; uptr left_padding = granularity; uptr space_size = kHighShadowEnd + left_padding; - uptr shadow_start = - FindAvailableMemoryRange(space_size, alignment, granularity, nullptr); + uptr shadow_start = FindAvailableMemoryRange(space_size, alignment, + granularity, nullptr, nullptr); CHECK_NE((uptr)0, shadow_start); CHECK(IsAligned(shadow_start, alignment)); return shadow_start; @@ -263,11 +271,6 @@ ShadowExceptionHandler(PEXCEPTION_POINTERS exception_pointers) { // Determine the address of the page that is being accessed. uptr page = RoundDownTo(addr, page_size); - // Query the existing page. - MEMORY_BASIC_INFORMATION mem_info = {}; - if (::VirtualQuery((LPVOID)page, &mem_info, sizeof(mem_info)) == 0) - return EXCEPTION_CONTINUE_SEARCH; - // Commit the page. uptr result = (uptr)::VirtualAlloc((LPVOID)page, page_size, MEM_COMMIT, PAGE_READWRITE); diff --git a/libsanitizer/asan/asan_win_dll_thunk.cc b/libsanitizer/asan/asan_win_dll_thunk.cc index 31847efe77a..8df7ab2b177 100644 --- a/libsanitizer/asan/asan_win_dll_thunk.cc +++ b/libsanitizer/asan/asan_win_dll_thunk.cc @@ -97,7 +97,7 @@ INTERCEPTOR(int, _except_handler4, void *a, void *b, void *c, void *d) { } #endif -// Window specific functions not included in asan_interface.inc. +// Windows specific functions not included in asan_interface.inc. INTERCEPT_WRAP_W_V(__asan_should_detect_stack_use_after_return) INTERCEPT_WRAP_W_V(__asan_get_shadow_memory_dynamic_address) INTERCEPT_WRAP_W_W(__asan_unhandled_exception_filter) diff --git a/libsanitizer/include/sanitizer/allocator_interface.h b/libsanitizer/include/sanitizer/allocator_interface.h index d4801e9ff0c..e125ad21d31 100644 --- a/libsanitizer/include/sanitizer/allocator_interface.h +++ b/libsanitizer/include/sanitizer/allocator_interface.h @@ -30,7 +30,7 @@ extern "C" { size_t __sanitizer_get_allocated_size(const volatile void *p); /* Number of bytes, allocated and not yet freed by the application. */ - size_t __sanitizer_get_current_allocated_bytes(); + size_t __sanitizer_get_current_allocated_bytes(void); /* Number of bytes, mmaped by the allocator to fulfill allocation requests. Generally, for request of X bytes, allocator can reserve and add to free @@ -38,17 +38,17 @@ extern "C" { All these chunks count toward the heap size. Currently, allocator never releases memory to OS (instead, it just puts freed chunks to free lists). */ - size_t __sanitizer_get_heap_size(); + size_t __sanitizer_get_heap_size(void); /* Number of bytes, mmaped by the allocator, which can be used to fulfill allocation requests. When a user program frees memory chunk, it can first fall into quarantine and will count toward __sanitizer_get_free_bytes() later. */ - size_t __sanitizer_get_free_bytes(); + size_t __sanitizer_get_free_bytes(void); /* Number of bytes in unmapped pages, that are released to OS. Currently, always returns 0. */ - size_t __sanitizer_get_unmapped_bytes(); + size_t __sanitizer_get_unmapped_bytes(void); /* Malloc hooks that may be optionally provided by user. __sanitizer_malloc_hook(ptr, size) is called immediately after @@ -74,6 +74,12 @@ extern "C" { void (*malloc_hook)(const volatile void *, size_t), void (*free_hook)(const volatile void *)); + /* Drains allocator quarantines (calling thread's and global ones), returns + freed memory back to OS and releases other non-essential internal allocator + resources in attempt to reduce process RSS. + Currently available with ASan only. + */ + void __sanitizer_purge_allocator(void); #ifdef __cplusplus } // extern "C" #endif diff --git a/libsanitizer/include/sanitizer/asan_interface.h b/libsanitizer/include/sanitizer/asan_interface.h index ad69ab46c92..6e8fe256a95 100644 --- a/libsanitizer/include/sanitizer/asan_interface.h +++ b/libsanitizer/include/sanitizer/asan_interface.h @@ -62,19 +62,19 @@ extern "C" { // 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(); + 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 *__asan_get_report_bp(); - void *__asan_get_report_sp(); - void *__asan_get_report_address(); - int __asan_get_report_access_type(); - size_t __asan_get_report_access_size(); - const char *__asan_get_report_description(); + 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. @@ -116,21 +116,21 @@ extern "C" { // 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 __asan_on_error(void); // Prints accumulated stats to stderr. Used for debugging. - void __asan_print_accumulated_stats(); + 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(); + 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 *__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 diff --git a/libsanitizer/include/sanitizer/common_interface_defs.h b/libsanitizer/include/sanitizer/common_interface_defs.h index a66c932b0ae..b8ae094ac5f 100644 --- a/libsanitizer/include/sanitizer/common_interface_defs.h +++ b/libsanitizer/include/sanitizer/common_interface_defs.h @@ -63,6 +63,11 @@ extern "C" { 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 @@ -113,10 +118,16 @@ extern "C" { 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 __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, diff --git a/libsanitizer/include/sanitizer/coverage_interface.h b/libsanitizer/include/sanitizer/coverage_interface.h index 85447b68a46..2f3613583da 100644 --- a/libsanitizer/include/sanitizer/coverage_interface.h +++ b/libsanitizer/include/sanitizer/coverage_interface.h @@ -18,10 +18,10 @@ extern "C" { #endif // Record and dump coverage info. - void __sanitizer_cov_dump(); + void __sanitizer_cov_dump(void); // Clear collected coverage info. - void __sanitizer_cov_reset(); + void __sanitizer_cov_reset(void); // Dump collected coverage info. Sorts pcs by module into individual .sancov // files. diff --git a/libsanitizer/include/sanitizer/esan_interface.h b/libsanitizer/include/sanitizer/esan_interface.h index cd18f34fc00..e22b6a8f4d7 100644 --- a/libsanitizer/include/sanitizer/esan_interface.h +++ b/libsanitizer/include/sanitizer/esan_interface.h @@ -35,11 +35,11 @@ extern "C" { // 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 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(); +unsigned int COMPILER_RT_WEAK __esan_get_sample_count(void); #ifdef __cplusplus } // extern "C" diff --git a/libsanitizer/include/sanitizer/hwasan_interface.h b/libsanitizer/include/sanitizer/hwasan_interface.h new file mode 100644 index 00000000000..938e9ac464a --- /dev/null +++ b/libsanitizer/include/sanitizer/hwasan_interface.h @@ -0,0 +1,82 @@ +//===-- sanitizer/asan_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 HWAddressSanitizer. +// +// Public interface header. +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_HWASAN_INTERFACE_H +#define SANITIZER_HWASAN_INTERFACE_H + +#include + +#ifdef __cplusplus +extern "C" { +#endif + // Initialize shadow but not the rest of the runtime. + // 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); + + // This function may be optionally provided by user and should return + // a string containing HWASan runtime options. See asan_flags.h for details. + const char* __hwasan_default_options(void); + + void __hwasan_enable_allocator_tagging(void); + void __hwasan_disable_allocator_tagging(void); + + // Mark region of memory with the given tag. Both address and size need to be + // 16-byte aligned. + void __hwasan_tag_memory(const volatile void *p, unsigned char tag, + size_t size); + + /// Set pointer tag. Previous tag is lost. + void *__hwasan_tag_pointer(const volatile void *p, unsigned char tag); + + // Set memory tag from the current SP address to the given address to zero. + // This is meant to annotate longjmp and other non-local jumps. + // This function needs to know the (almost) exact destination frame address; + // clearing shadow for the entire thread stack like __asan_handle_no_return + // does would cause false reports. + void __hwasan_handle_longjmp(const void *sp_dst); + + // Libc hook for thread creation. Should be called in the child thread before + // any instrumented code. + void __hwasan_thread_enter(); + + // Libc hook for thread destruction. No instrumented code should run after + // this call. + void __hwasan_thread_exit(); + + // Print shadow and origin for the memory range to stderr in a human-readable + // format. + void __hwasan_print_shadow(const volatile void *x, size_t size); + + // Print one-line report about the memory usage of the current process. + void __hwasan_print_memory_usage(); + + 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); + void * __sanitizer___libc_memalign(size_t alignment, size_t size); + void * __sanitizer_valloc(size_t size); + void * __sanitizer_pvalloc(size_t size); + void __sanitizer_free(void *ptr); + void __sanitizer_cfree(void *ptr); + size_t __sanitizer_malloc_usable_size(const void *ptr); + struct mallinfo __sanitizer_mallinfo(); + int __sanitizer_mallopt(int cmd, int value); + void __sanitizer_malloc_stats(void); + void * __sanitizer_calloc(size_t nmemb, size_t size); + void * __sanitizer_realloc(void *ptr, size_t size); + void * __sanitizer_malloc(size_t size); +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // SANITIZER_HWASAN_INTERFACE_H diff --git a/libsanitizer/include/sanitizer/lsan_interface.h b/libsanitizer/include/sanitizer/lsan_interface.h index 32051e62a00..93b2e9ca3f1 100644 --- a/libsanitizer/include/sanitizer/lsan_interface.h +++ b/libsanitizer/include/sanitizer/lsan_interface.h @@ -19,8 +19,8 @@ extern "C" { #endif // Allocations made between calls to __lsan_disable() and __lsan_enable() will // be treated as non-leaks. Disable/enable pairs may be nested. - void __lsan_disable(); - void __lsan_enable(); + void __lsan_disable(void); + void __lsan_enable(void); // The heap object into which p points will be treated as a non-leak. void __lsan_ignore_object(const void *p); @@ -47,7 +47,7 @@ extern "C" { // the time of first invocation of this function. // By calling this function early during process shutdown, you can instruct // LSan to ignore shutdown-only leaks which happen later on. - void __lsan_do_leak_check(); + void __lsan_do_leak_check(void); // Check for leaks now. Returns zero if no leaks have been found or if leak // detection is disabled, non-zero otherwise. @@ -56,7 +56,7 @@ extern "C" { // terminate the process. It does not affect the behavior of // __lsan_do_leak_check() or the end-of-process leak check, and is not // affected by them. - int __lsan_do_recoverable_leak_check(); + int __lsan_do_recoverable_leak_check(void); // The user may optionally provide this function to disallow leak checking // for the program it is linked into (if the return value is non-zero). This @@ -64,15 +64,15 @@ extern "C" { // that is unsupported. // To avoid dead stripping, you may need to define this function with // __attribute__((used)) - int __lsan_is_turned_off(); + int __lsan_is_turned_off(void); // This function may be optionally provided by user and should return // a string containing LSan runtime options. See lsan_flags.inc for details. - const char *__lsan_default_options(); + const char *__lsan_default_options(void); // This function may be optionally provided by the user and should return // a string containing LSan suppressions. - const char *__lsan_default_suppressions(); + const char *__lsan_default_suppressions(void); #ifdef __cplusplus } // extern "C" diff --git a/libsanitizer/include/sanitizer/msan_interface.h b/libsanitizer/include/sanitizer/msan_interface.h index 92793a19bde..4dfae604f7a 100644 --- a/libsanitizer/include/sanitizer/msan_interface.h +++ b/libsanitizer/include/sanitizer/msan_interface.h @@ -29,10 +29,10 @@ extern "C" { int __msan_origin_is_descendant_or_same(uint32_t this_id, uint32_t prev_id); /* Returns non-zero if tracking origins. */ - int __msan_get_track_origins(); + int __msan_get_track_origins(void); /* Returns the origin id of the latest UMR in the calling thread. */ - uint32_t __msan_get_umr_origin(); + uint32_t __msan_get_umr_origin(void); /* Make memory region fully initialized (without changing its contents). */ void __msan_unpoison(const volatile void *a, size_t size); @@ -80,7 +80,7 @@ extern "C" { void __msan_dump_shadow(const volatile void *x, size_t size); /* Returns true if running under a dynamic tool (DynamoRio-based). */ - int __msan_has_dynamic_component(); + int __msan_has_dynamic_component(void); /* Tell MSan about newly allocated memory (ex.: custom allocator). Memory will be marked uninitialized, with origin at the call site. */ @@ -91,7 +91,7 @@ extern "C" { /* This function may be optionally provided by user and should return a string containing Msan runtime options. See msan_flags.h for details. */ - const char* __msan_default_options(); + const char* __msan_default_options(void); /* Deprecated. Call __sanitizer_set_death_callback instead. */ void __msan_set_death_callback(void (*callback)(void)); @@ -102,6 +102,14 @@ extern "C" { copy. Source and destination regions can overlap. */ void __msan_copy_shadow(const volatile void *dst, const volatile void *src, size_t size); + + /* Disables uninitialized memory checks in interceptors. */ + void __msan_scoped_disable_interceptor_checks(void); + + /* Re-enables uninitialized memory checks in interceptors after a previous + call to __msan_scoped_disable_interceptor_checks. */ + void __msan_scoped_enable_interceptor_checks(void); + #ifdef __cplusplus } // extern "C" #endif diff --git a/libsanitizer/include/sanitizer/netbsd_syscall_hooks.h b/libsanitizer/include/sanitizer/netbsd_syscall_hooks.h new file mode 100644 index 00000000000..8cf5121726e --- /dev/null +++ b/libsanitizer/include/sanitizer/netbsd_syscall_hooks.h @@ -0,0 +1,4732 @@ +//===-- netbsd_syscall_hooks.h --------------------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of public sanitizer interface. +// +// System call handlers. +// +// Interface methods declared in this header implement pre- and post- syscall +// actions for the active sanitizer. +// Usage: +// __sanitizer_syscall_pre_getfoo(...args...); +// long long res = syscall(SYS_getfoo, ...args...); +// __sanitizer_syscall_post_getfoo(res, ...args...); +// +// 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 +// +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_NETBSD_SYSCALL_HOOKS_H +#define SANITIZER_NETBSD_SYSCALL_HOOKS_H + +#define __sanitizer_syscall_pre_syscall(code, arg0, arg1, arg2, arg3, arg4, \ + arg5, arg6, arg7) \ + __sanitizer_syscall_pre_impl_syscall( \ + (long long)(code), (long long)(arg0), (long long)(arg1), \ + (long long)(arg2), (long long)(arg3), (long long)(arg4), \ + (long long)(arg5), (long long)(arg6), (long long)(arg7)) +#define __sanitizer_syscall_post_syscall(res, code, arg0, arg1, arg2, arg3, \ + arg4, arg5, arg6, arg7) \ + __sanitizer_syscall_post_impl_syscall( \ + res, (long long)(code), (long long)(arg0), (long long)(arg1), \ + (long long)(arg2), (long long)(arg3), (long long)(arg4), \ + (long long)(arg5), (long long)(arg6), (long long)(arg7)) +#define __sanitizer_syscall_pre_exit(rval) \ + __sanitizer_syscall_pre_impl_exit((long long)(rval)) +#define __sanitizer_syscall_post_exit(res, rval) \ + __sanitizer_syscall_post_impl_exit(res, (long long)(rval)) +#define __sanitizer_syscall_pre_fork() __sanitizer_syscall_pre_impl_fork() +#define __sanitizer_syscall_post_fork(res) \ + __sanitizer_syscall_post_impl_fork(res) +#define __sanitizer_syscall_pre_read(fd, buf, nbyte) \ + __sanitizer_syscall_pre_impl_read((long long)(fd), (long long)(buf), \ + (long long)(nbyte)) +#define __sanitizer_syscall_post_read(res, fd, buf, nbyte) \ + __sanitizer_syscall_post_impl_read(res, (long long)(fd), (long long)(buf), \ + (long long)(nbyte)) +#define __sanitizer_syscall_pre_write(fd, buf, nbyte) \ + __sanitizer_syscall_pre_impl_write((long long)(fd), (long long)(buf), \ + (long long)(nbyte)) +#define __sanitizer_syscall_post_write(res, fd, buf, nbyte) \ + __sanitizer_syscall_post_impl_write(res, (long long)(fd), (long long)(buf), \ + (long long)(nbyte)) +#define __sanitizer_syscall_pre_open(path, flags, mode) \ + __sanitizer_syscall_pre_impl_open((long long)(path), (long long)(flags), \ + (long long)(mode)) +#define __sanitizer_syscall_post_open(res, path, flags, mode) \ + __sanitizer_syscall_post_impl_open(res, (long long)(path), \ + (long long)(flags), (long long)(mode)) +#define __sanitizer_syscall_pre_close(fd) \ + __sanitizer_syscall_pre_impl_close((long long)(fd)) +#define __sanitizer_syscall_post_close(res, fd) \ + __sanitizer_syscall_post_impl_close(res, (long long)(fd)) +#define __sanitizer_syscall_pre_compat_50_wait4(pid, status, options, rusage) \ + __sanitizer_syscall_pre_impl_compat_50_wait4( \ + (long long)(pid), (long long)(status), (long long)(options), \ + (long long)(rusage)) +#define __sanitizer_syscall_post_compat_50_wait4(res, pid, status, options, \ + rusage) \ + __sanitizer_syscall_post_impl_compat_50_wait4( \ + res, (long long)(pid), (long long)(status), (long long)(options), \ + (long long)(rusage)) +#define __sanitizer_syscall_pre_compat_43_ocreat(path, mode) \ + __sanitizer_syscall_pre_impl_compat_43_ocreat((long long)(path), \ + (long long)(mode)) +#define __sanitizer_syscall_post_compat_43_ocreat(res, path, mode) \ + __sanitizer_syscall_post_impl_compat_43_ocreat(res, (long long)(path), \ + (long long)(mode)) +#define __sanitizer_syscall_pre_link(path, link) \ + __sanitizer_syscall_pre_impl_link((long long)(path), (long long)(link)) +#define __sanitizer_syscall_post_link(res, path, link) \ + __sanitizer_syscall_post_impl_link(res, (long long)(path), (long long)(link)) +#define __sanitizer_syscall_pre_unlink(path) \ + __sanitizer_syscall_pre_impl_unlink((long long)(path)) +#define __sanitizer_syscall_post_unlink(res, path) \ + __sanitizer_syscall_post_impl_unlink(res, (long long)(path)) +/* syscall 11 has been skipped */ +#define __sanitizer_syscall_pre_chdir(path) \ + __sanitizer_syscall_pre_impl_chdir((long long)(path)) +#define __sanitizer_syscall_post_chdir(res, path) \ + __sanitizer_syscall_post_impl_chdir(res, (long long)(path)) +#define __sanitizer_syscall_pre_fchdir(fd) \ + __sanitizer_syscall_pre_impl_fchdir((long long)(fd)) +#define __sanitizer_syscall_post_fchdir(res, fd) \ + __sanitizer_syscall_post_impl_fchdir(res, (long long)(fd)) +#define __sanitizer_syscall_pre_compat_50_mknod(path, mode, dev) \ + __sanitizer_syscall_pre_impl_compat_50_mknod( \ + (long long)(path), (long long)(mode), (long long)(dev)) +#define __sanitizer_syscall_post_compat_50_mknod(res, path, mode, dev) \ + __sanitizer_syscall_post_impl_compat_50_mknod( \ + res, (long long)(path), (long long)(mode), (long long)(dev)) +#define __sanitizer_syscall_pre_chmod(path, mode) \ + __sanitizer_syscall_pre_impl_chmod((long long)(path), (long long)(mode)) +#define __sanitizer_syscall_post_chmod(res, path, mode) \ + __sanitizer_syscall_post_impl_chmod(res, (long long)(path), (long long)(mode)) +#define __sanitizer_syscall_pre_chown(path, uid, gid) \ + __sanitizer_syscall_pre_impl_chown((long long)(path), (long long)(uid), \ + (long long)(gid)) +#define __sanitizer_syscall_post_chown(res, path, uid, gid) \ + __sanitizer_syscall_post_impl_chown(res, (long long)(path), \ + (long long)(uid), (long long)(gid)) +#define __sanitizer_syscall_pre_break(nsize) \ + __sanitizer_syscall_pre_impl_break((long long)(nsize)) +#define __sanitizer_syscall_post_break(res, nsize) \ + __sanitizer_syscall_post_impl_break(res, (long long)(nsize)) +#define __sanitizer_syscall_pre_compat_20_getfsstat(buf, bufsize, flags) \ + __sanitizer_syscall_pre_impl_compat_20_getfsstat( \ + (long long)(buf), (long long)(bufsize), (long long)(flags)) +#define __sanitizer_syscall_post_compat_20_getfsstat(res, buf, bufsize, flags) \ + __sanitizer_syscall_post_impl_compat_20_getfsstat( \ + res, (long long)(buf), (long long)(bufsize), (long long)(flags)) +#define __sanitizer_syscall_pre_compat_43_olseek(fd, offset, whence) \ + __sanitizer_syscall_pre_impl_compat_43_olseek( \ + (long long)(fd), (long long)(offset), (long long)(whence)) +#define __sanitizer_syscall_post_compat_43_olseek(res, fd, offset, whence) \ + __sanitizer_syscall_post_impl_compat_43_olseek( \ + res, (long long)(fd), (long long)(offset), (long long)(whence)) +#define __sanitizer_syscall_pre_getpid() __sanitizer_syscall_pre_impl_getpid() +#define __sanitizer_syscall_post_getpid(res) \ + __sanitizer_syscall_post_impl_getpid(res) +#define __sanitizer_syscall_pre_compat_40_mount(type, path, flags, data) \ + __sanitizer_syscall_pre_impl_compat_40_mount( \ + (long long)(type), (long long)(path), (long long)(flags), \ + (long long)(data)) +#define __sanitizer_syscall_post_compat_40_mount(res, type, path, flags, data) \ + __sanitizer_syscall_post_impl_compat_40_mount( \ + res, (long long)(type), (long long)(path), (long long)(flags), \ + (long long)(data)) +#define __sanitizer_syscall_pre_unmount(path, flags) \ + __sanitizer_syscall_pre_impl_unmount((long long)(path), (long long)(flags)) +#define __sanitizer_syscall_post_unmount(res, path, flags) \ + __sanitizer_syscall_post_impl_unmount(res, (long long)(path), \ + (long long)(flags)) +#define __sanitizer_syscall_pre_setuid(uid) \ + __sanitizer_syscall_pre_impl_setuid((long long)(uid)) +#define __sanitizer_syscall_post_setuid(res, uid) \ + __sanitizer_syscall_post_impl_setuid(res, (long long)(uid)) +#define __sanitizer_syscall_pre_getuid() __sanitizer_syscall_pre_impl_getuid() +#define __sanitizer_syscall_post_getuid(res) \ + __sanitizer_syscall_post_impl_getuid(res) +#define __sanitizer_syscall_pre_geteuid() __sanitizer_syscall_pre_impl_geteuid() +#define __sanitizer_syscall_post_geteuid(res) \ + __sanitizer_syscall_post_impl_geteuid(res) +#define __sanitizer_syscall_pre_ptrace(req, pid, addr, data) \ + __sanitizer_syscall_pre_impl_ptrace((long long)(req), (long long)(pid), \ + (long long)(addr), (long long)(data)) +#define __sanitizer_syscall_post_ptrace(res, req, pid, addr, data) \ + __sanitizer_syscall_post_impl_ptrace(res, (long long)(req), \ + (long long)(pid), (long long)(addr), \ + (long long)(data)) +#define __sanitizer_syscall_pre_recvmsg(s, msg, flags) \ + __sanitizer_syscall_pre_impl_recvmsg((long long)(s), (long long)(msg), \ + (long long)(flags)) +#define __sanitizer_syscall_post_recvmsg(res, s, msg, flags) \ + __sanitizer_syscall_post_impl_recvmsg(res, (long long)(s), (long long)(msg), \ + (long long)(flags)) +#define __sanitizer_syscall_pre_sendmsg(s, msg, flags) \ + __sanitizer_syscall_pre_impl_sendmsg((long long)(s), (long long)(msg), \ + (long long)(flags)) +#define __sanitizer_syscall_post_sendmsg(res, s, msg, flags) \ + __sanitizer_syscall_post_impl_sendmsg(res, (long long)(s), (long long)(msg), \ + (long long)(flags)) +#define __sanitizer_syscall_pre_recvfrom(s, buf, len, flags, from, \ + fromlenaddr) \ + __sanitizer_syscall_pre_impl_recvfrom( \ + (long long)(s), (long long)(buf), (long long)(len), (long long)(flags), \ + (long long)(from), (long long)(fromlenaddr)) +#define __sanitizer_syscall_post_recvfrom(res, s, buf, len, flags, from, \ + fromlenaddr) \ + __sanitizer_syscall_post_impl_recvfrom( \ + res, (long long)(s), (long long)(buf), (long long)(len), \ + (long long)(flags), (long long)(from), (long long)(fromlenaddr)) +#define __sanitizer_syscall_pre_accept(s, name, anamelen) \ + __sanitizer_syscall_pre_impl_accept((long long)(s), (long long)(name), \ + (long long)(anamelen)) +#define __sanitizer_syscall_post_accept(res, s, name, anamelen) \ + __sanitizer_syscall_post_impl_accept(res, (long long)(s), (long long)(name), \ + (long long)(anamelen)) +#define __sanitizer_syscall_pre_getpeername(fdes, asa, alen) \ + __sanitizer_syscall_pre_impl_getpeername( \ + (long long)(fdes), (long long)(asa), (long long)(alen)) +#define __sanitizer_syscall_post_getpeername(res, fdes, asa, alen) \ + __sanitizer_syscall_post_impl_getpeername( \ + res, (long long)(fdes), (long long)(asa), (long long)(alen)) +#define __sanitizer_syscall_pre_getsockname(fdes, asa, alen) \ + __sanitizer_syscall_pre_impl_getsockname( \ + (long long)(fdes), (long long)(asa), (long long)(alen)) +#define __sanitizer_syscall_post_getsockname(res, fdes, asa, alen) \ + __sanitizer_syscall_post_impl_getsockname( \ + res, (long long)(fdes), (long long)(asa), (long long)(alen)) +#define __sanitizer_syscall_pre_access(path, flags) \ + __sanitizer_syscall_pre_impl_access((long long)(path), (long long)(flags)) +#define __sanitizer_syscall_post_access(res, path, flags) \ + __sanitizer_syscall_post_impl_access(res, (long long)(path), \ + (long long)(flags)) +#define __sanitizer_syscall_pre_chflags(path, flags) \ + __sanitizer_syscall_pre_impl_chflags((long long)(path), (long long)(flags)) +#define __sanitizer_syscall_post_chflags(res, path, flags) \ + __sanitizer_syscall_post_impl_chflags(res, (long long)(path), \ + (long long)(flags)) +#define __sanitizer_syscall_pre_fchflags(fd, flags) \ + __sanitizer_syscall_pre_impl_fchflags((long long)(fd), (long long)(flags)) +#define __sanitizer_syscall_post_fchflags(res, fd, flags) \ + __sanitizer_syscall_post_impl_fchflags(res, (long long)(fd), \ + (long long)(flags)) +#define __sanitizer_syscall_pre_sync() __sanitizer_syscall_pre_impl_sync() +#define __sanitizer_syscall_post_sync(res) \ + __sanitizer_syscall_post_impl_sync(res) +#define __sanitizer_syscall_pre_kill(pid, signum) \ + __sanitizer_syscall_pre_impl_kill((long long)(pid), (long long)(signum)) +#define __sanitizer_syscall_post_kill(res, pid, signum) \ + __sanitizer_syscall_post_impl_kill(res, (long long)(pid), (long long)(signum)) +#define __sanitizer_syscall_pre_compat_43_stat43(path, ub) \ + __sanitizer_syscall_pre_impl_compat_43_stat43((long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_post_compat_43_stat43(res, path, ub) \ + __sanitizer_syscall_post_impl_compat_43_stat43(res, (long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_pre_getppid() __sanitizer_syscall_pre_impl_getppid() +#define __sanitizer_syscall_post_getppid(res) \ + __sanitizer_syscall_post_impl_getppid(res) +#define __sanitizer_syscall_pre_compat_43_lstat43(path, ub) \ + __sanitizer_syscall_pre_impl_compat_43_lstat43((long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_post_compat_43_lstat43(res, path, ub) \ + __sanitizer_syscall_post_impl_compat_43_lstat43(res, (long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_pre_dup(fd) \ + __sanitizer_syscall_pre_impl_dup((long long)(fd)) +#define __sanitizer_syscall_post_dup(res, fd) \ + __sanitizer_syscall_post_impl_dup(res, (long long)(fd)) +#define __sanitizer_syscall_pre_pipe() __sanitizer_syscall_pre_impl_pipe() +#define __sanitizer_syscall_post_pipe(res) \ + __sanitizer_syscall_post_impl_pipe(res) +#define __sanitizer_syscall_pre_getegid() __sanitizer_syscall_pre_impl_getegid() +#define __sanitizer_syscall_post_getegid(res) \ + __sanitizer_syscall_post_impl_getegid(res) +#define __sanitizer_syscall_pre_profil(samples, size, offset, scale) \ + __sanitizer_syscall_pre_impl_profil((long long)(samples), (long long)(size), \ + (long long)(offset), (long long)(scale)) +#define __sanitizer_syscall_post_profil(res, samples, size, offset, scale) \ + __sanitizer_syscall_post_impl_profil(res, (long long)(samples), \ + (long long)(size), (long long)(offset), \ + (long long)(scale)) +#define __sanitizer_syscall_pre_ktrace(fname, ops, facs, pid) \ + __sanitizer_syscall_pre_impl_ktrace((long long)(fname), (long long)(ops), \ + (long long)(facs), (long long)(pid)) +#define __sanitizer_syscall_post_ktrace(res, fname, ops, facs, pid) \ + __sanitizer_syscall_post_impl_ktrace(res, (long long)(fname), \ + (long long)(ops), (long long)(facs), \ + (long long)(pid)) +#define __sanitizer_syscall_pre_compat_13_sigaction13(signum, nsa, osa) \ + __sanitizer_syscall_pre_impl_compat_13_sigaction13( \ + (long long)(signum), (long long)(nsa), (long long)(osa)) +#define __sanitizer_syscall_post_compat_13_sigaction13(res, signum, nsa, osa) \ + __sanitizer_syscall_post_impl_compat_13_sigaction13( \ + res, (long long)(signum), (long long)(nsa), (long long)(osa)) +#define __sanitizer_syscall_pre_getgid() __sanitizer_syscall_pre_impl_getgid() +#define __sanitizer_syscall_post_getgid(res) \ + __sanitizer_syscall_post_impl_getgid(res) +#define __sanitizer_syscall_pre_compat_13_sigprocmask13(how, mask) \ + __sanitizer_syscall_pre_impl_compat_13_sigprocmask13((long long)(how), \ + (long long)(mask)) +#define __sanitizer_syscall_post_compat_13_sigprocmask13(res, how, mask) \ + __sanitizer_syscall_post_impl_compat_13_sigprocmask13(res, (long long)(how), \ + (long long)(mask)) +#define __sanitizer_syscall_pre___getlogin(namebuf, namelen) \ + __sanitizer_syscall_pre_impl___getlogin((long long)(namebuf), \ + (long long)(namelen)) +#define __sanitizer_syscall_post___getlogin(res, namebuf, namelen) \ + __sanitizer_syscall_post_impl___getlogin(res, (long long)(namebuf), \ + (long long)(namelen)) +#define __sanitizer_syscall_pre___setlogin(namebuf) \ + __sanitizer_syscall_pre_impl___setlogin((long long)(namebuf)) +#define __sanitizer_syscall_post___setlogin(res, namebuf) \ + __sanitizer_syscall_post_impl___setlogin(res, (long long)(namebuf)) +#define __sanitizer_syscall_pre_acct(path) \ + __sanitizer_syscall_pre_impl_acct((long long)(path)) +#define __sanitizer_syscall_post_acct(res, path) \ + __sanitizer_syscall_post_impl_acct(res, (long long)(path)) +#define __sanitizer_syscall_pre_compat_13_sigpending13() \ + __sanitizer_syscall_pre_impl_compat_13_sigpending13() +#define __sanitizer_syscall_post_compat_13_sigpending13(res) \ + __sanitizer_syscall_post_impl_compat_13_sigpending13(res) +#define __sanitizer_syscall_pre_compat_13_sigaltstack13(nss, oss) \ + __sanitizer_syscall_pre_impl_compat_13_sigaltstack13((long long)(nss), \ + (long long)(oss)) +#define __sanitizer_syscall_post_compat_13_sigaltstack13(res, nss, oss) \ + __sanitizer_syscall_post_impl_compat_13_sigaltstack13(res, (long long)(nss), \ + (long long)(oss)) +#define __sanitizer_syscall_pre_ioctl(fd, com, data) \ + __sanitizer_syscall_pre_impl_ioctl((long long)(fd), (long long)(com), \ + (long long)(data)) +#define __sanitizer_syscall_post_ioctl(res, fd, com, data) \ + __sanitizer_syscall_post_impl_ioctl(res, (long long)(fd), (long long)(com), \ + (long long)(data)) +#define __sanitizer_syscall_pre_compat_12_oreboot(opt) \ + __sanitizer_syscall_pre_impl_compat_12_oreboot((long long)(opt)) +#define __sanitizer_syscall_post_compat_12_oreboot(res, opt) \ + __sanitizer_syscall_post_impl_compat_12_oreboot(res, (long long)(opt)) +#define __sanitizer_syscall_pre_revoke(path) \ + __sanitizer_syscall_pre_impl_revoke((long long)(path)) +#define __sanitizer_syscall_post_revoke(res, path) \ + __sanitizer_syscall_post_impl_revoke(res, (long long)(path)) +#define __sanitizer_syscall_pre_symlink(path, link) \ + __sanitizer_syscall_pre_impl_symlink((long long)(path), (long long)(link)) +#define __sanitizer_syscall_post_symlink(res, path, link) \ + __sanitizer_syscall_post_impl_symlink(res, (long long)(path), \ + (long long)(link)) +#define __sanitizer_syscall_pre_readlink(path, buf, count) \ + __sanitizer_syscall_pre_impl_readlink((long long)(path), (long long)(buf), \ + (long long)(count)) +#define __sanitizer_syscall_post_readlink(res, path, buf, count) \ + __sanitizer_syscall_post_impl_readlink(res, (long long)(path), \ + (long long)(buf), (long long)(count)) +#define __sanitizer_syscall_pre_execve(path, argp, envp) \ + __sanitizer_syscall_pre_impl_execve((long long)(path), (long long)(argp), \ + (long long)(envp)) +#define __sanitizer_syscall_post_execve(res, path, argp, envp) \ + __sanitizer_syscall_post_impl_execve(res, (long long)(path), \ + (long long)(argp), (long long)(envp)) +#define __sanitizer_syscall_pre_umask(newmask) \ + __sanitizer_syscall_pre_impl_umask((long long)(newmask)) +#define __sanitizer_syscall_post_umask(res, newmask) \ + __sanitizer_syscall_post_impl_umask(res, (long long)(newmask)) +#define __sanitizer_syscall_pre_chroot(path) \ + __sanitizer_syscall_pre_impl_chroot((long long)(path)) +#define __sanitizer_syscall_post_chroot(res, path) \ + __sanitizer_syscall_post_impl_chroot(res, (long long)(path)) +#define __sanitizer_syscall_pre_compat_43_fstat43(fd, sb) \ + __sanitizer_syscall_pre_impl_compat_43_fstat43((long long)(fd), \ + (long long)(sb)) +#define __sanitizer_syscall_post_compat_43_fstat43(res, fd, sb) \ + __sanitizer_syscall_post_impl_compat_43_fstat43(res, (long long)(fd), \ + (long long)(sb)) +#define __sanitizer_syscall_pre_compat_43_ogetkerninfo(op, where, size, arg) \ + __sanitizer_syscall_pre_impl_compat_43_ogetkerninfo( \ + (long long)(op), (long long)(where), (long long)(size), \ + (long long)(arg)) +#define __sanitizer_syscall_post_compat_43_ogetkerninfo(res, op, where, size, \ + arg) \ + __sanitizer_syscall_post_impl_compat_43_ogetkerninfo( \ + res, (long long)(op), (long long)(where), (long long)(size), \ + (long long)(arg)) +#define __sanitizer_syscall_pre_compat_43_ogetpagesize() \ + __sanitizer_syscall_pre_impl_compat_43_ogetpagesize() +#define __sanitizer_syscall_post_compat_43_ogetpagesize(res) \ + __sanitizer_syscall_post_impl_compat_43_ogetpagesize(res) +#define __sanitizer_syscall_pre_compat_12_msync(addr, len) \ + __sanitizer_syscall_pre_impl_compat_12_msync((long long)(addr), \ + (long long)(len)) +#define __sanitizer_syscall_post_compat_12_msync(res, addr, len) \ + __sanitizer_syscall_post_impl_compat_12_msync(res, (long long)(addr), \ + (long long)(len)) +#define __sanitizer_syscall_pre_vfork() __sanitizer_syscall_pre_impl_vfork() +#define __sanitizer_syscall_post_vfork(res) \ + __sanitizer_syscall_post_impl_vfork(res) +/* syscall 67 has been skipped */ +/* syscall 68 has been skipped */ +/* syscall 69 has been skipped */ +/* syscall 70 has been skipped */ +#define __sanitizer_syscall_pre_compat_43_ommap(addr, len, prot, flags, fd, \ + pos) \ + __sanitizer_syscall_pre_impl_compat_43_ommap( \ + (long long)(addr), (long long)(len), (long long)(prot), \ + (long long)(flags), (long long)(fd), (long long)(pos)) +#define __sanitizer_syscall_post_compat_43_ommap(res, addr, len, prot, flags, \ + fd, pos) \ + __sanitizer_syscall_post_impl_compat_43_ommap( \ + res, (long long)(addr), (long long)(len), (long long)(prot), \ + (long long)(flags), (long long)(fd), (long long)(pos)) +#define __sanitizer_syscall_pre_vadvise(anom) \ + __sanitizer_syscall_pre_impl_vadvise((long long)(anom)) +#define __sanitizer_syscall_post_vadvise(res, anom) \ + __sanitizer_syscall_post_impl_vadvise(res, (long long)(anom)) +#define __sanitizer_syscall_pre_munmap(addr, len) \ + __sanitizer_syscall_pre_impl_munmap((long long)(addr), (long long)(len)) +#define __sanitizer_syscall_post_munmap(res, addr, len) \ + __sanitizer_syscall_post_impl_munmap(res, (long long)(addr), (long long)(len)) +#define __sanitizer_syscall_pre_mprotect(addr, len, prot) \ + __sanitizer_syscall_pre_impl_mprotect((long long)(addr), (long long)(len), \ + (long long)(prot)) +#define __sanitizer_syscall_post_mprotect(res, addr, len, prot) \ + __sanitizer_syscall_post_impl_mprotect(res, (long long)(addr), \ + (long long)(len), (long long)(prot)) +#define __sanitizer_syscall_pre_madvise(addr, len, behav) \ + __sanitizer_syscall_pre_impl_madvise((long long)(addr), (long long)(len), \ + (long long)(behav)) +#define __sanitizer_syscall_post_madvise(res, addr, len, behav) \ + __sanitizer_syscall_post_impl_madvise(res, (long long)(addr), \ + (long long)(len), (long long)(behav)) +/* syscall 76 has been skipped */ +/* syscall 77 has been skipped */ +#define __sanitizer_syscall_pre_mincore(addr, len, vec) \ + __sanitizer_syscall_pre_impl_mincore((long long)(addr), (long long)(len), \ + (long long)(vec)) +#define __sanitizer_syscall_post_mincore(res, addr, len, vec) \ + __sanitizer_syscall_post_impl_mincore(res, (long long)(addr), \ + (long long)(len), (long long)(vec)) +#define __sanitizer_syscall_pre_getgroups(gidsetsize, gidset) \ + __sanitizer_syscall_pre_impl_getgroups((long long)(gidsetsize), \ + (long long)(gidset)) +#define __sanitizer_syscall_post_getgroups(res, gidsetsize, gidset) \ + __sanitizer_syscall_post_impl_getgroups(res, (long long)(gidsetsize), \ + (long long)(gidset)) +#define __sanitizer_syscall_pre_setgroups(gidsetsize, gidset) \ + __sanitizer_syscall_pre_impl_setgroups((long long)(gidsetsize), \ + (long long)(gidset)) +#define __sanitizer_syscall_post_setgroups(res, gidsetsize, gidset) \ + __sanitizer_syscall_post_impl_setgroups(res, (long long)(gidsetsize), \ + (long long)(gidset)) +#define __sanitizer_syscall_pre_getpgrp() __sanitizer_syscall_pre_impl_getpgrp() +#define __sanitizer_syscall_post_getpgrp(res) \ + __sanitizer_syscall_post_impl_getpgrp(res) +#define __sanitizer_syscall_pre_setpgid(pid, pgid) \ + __sanitizer_syscall_pre_impl_setpgid((long long)(pid), (long long)(pgid)) +#define __sanitizer_syscall_post_setpgid(res, pid, pgid) \ + __sanitizer_syscall_post_impl_setpgid(res, (long long)(pid), \ + (long long)(pgid)) +#define __sanitizer_syscall_pre_compat_50_setitimer(which, itv, oitv) \ + __sanitizer_syscall_pre_impl_compat_50_setitimer( \ + (long long)(which), (long long)(itv), (long long)(oitv)) +#define __sanitizer_syscall_post_compat_50_setitimer(res, which, itv, oitv) \ + __sanitizer_syscall_post_impl_compat_50_setitimer( \ + res, (long long)(which), (long long)(itv), (long long)(oitv)) +#define __sanitizer_syscall_pre_compat_43_owait() \ + __sanitizer_syscall_pre_impl_compat_43_owait() +#define __sanitizer_syscall_post_compat_43_owait(res) \ + __sanitizer_syscall_post_impl_compat_43_owait(res) +#define __sanitizer_syscall_pre_compat_12_oswapon(name) \ + __sanitizer_syscall_pre_impl_compat_12_oswapon((long long)(name)) +#define __sanitizer_syscall_post_compat_12_oswapon(res, name) \ + __sanitizer_syscall_post_impl_compat_12_oswapon(res, (long long)(name)) +#define __sanitizer_syscall_pre_compat_50_getitimer(which, itv) \ + __sanitizer_syscall_pre_impl_compat_50_getitimer((long long)(which), \ + (long long)(itv)) +#define __sanitizer_syscall_post_compat_50_getitimer(res, which, itv) \ + __sanitizer_syscall_post_impl_compat_50_getitimer(res, (long long)(which), \ + (long long)(itv)) +#define __sanitizer_syscall_pre_compat_43_ogethostname(hostname, len) \ + __sanitizer_syscall_pre_impl_compat_43_ogethostname((long long)(hostname), \ + (long long)(len)) +#define __sanitizer_syscall_post_compat_43_ogethostname(res, hostname, len) \ + __sanitizer_syscall_post_impl_compat_43_ogethostname( \ + res, (long long)(hostname), (long long)(len)) +#define __sanitizer_syscall_pre_compat_43_osethostname(hostname, len) \ + __sanitizer_syscall_pre_impl_compat_43_osethostname((long long)(hostname), \ + (long long)(len)) +#define __sanitizer_syscall_post_compat_43_osethostname(res, hostname, len) \ + __sanitizer_syscall_post_impl_compat_43_osethostname( \ + res, (long long)(hostname), (long long)(len)) +#define __sanitizer_syscall_pre_compat_43_ogetdtablesize() \ + __sanitizer_syscall_pre_impl_compat_43_ogetdtablesize() +#define __sanitizer_syscall_post_compat_43_ogetdtablesize(res) \ + __sanitizer_syscall_post_impl_compat_43_ogetdtablesize(res) +#define __sanitizer_syscall_pre_dup2(from, to) \ + __sanitizer_syscall_pre_impl_dup2((long long)(from), (long long)(to)) +#define __sanitizer_syscall_post_dup2(res, from, to) \ + __sanitizer_syscall_post_impl_dup2(res, (long long)(from), (long long)(to)) +/* syscall 91 has been skipped */ +#define __sanitizer_syscall_pre_fcntl(fd, cmd, arg) \ + __sanitizer_syscall_pre_impl_fcntl((long long)(fd), (long long)(cmd), \ + (long long)(arg)) +#define __sanitizer_syscall_post_fcntl(res, fd, cmd, arg) \ + __sanitizer_syscall_post_impl_fcntl(res, (long long)(fd), (long long)(cmd), \ + (long long)(arg)) +#define __sanitizer_syscall_pre_compat_50_select(nd, in, ou, ex, tv) \ + __sanitizer_syscall_pre_impl_compat_50_select( \ + (long long)(nd), (long long)(in), (long long)(ou), (long long)(ex), \ + (long long)(tv)) +#define __sanitizer_syscall_post_compat_50_select(res, nd, in, ou, ex, tv) \ + __sanitizer_syscall_post_impl_compat_50_select( \ + res, (long long)(nd), (long long)(in), (long long)(ou), (long long)(ex), \ + (long long)(tv)) +/* syscall 94 has been skipped */ +#define __sanitizer_syscall_pre_fsync(fd) \ + __sanitizer_syscall_pre_impl_fsync((long long)(fd)) +#define __sanitizer_syscall_post_fsync(res, fd) \ + __sanitizer_syscall_post_impl_fsync(res, (long long)(fd)) +#define __sanitizer_syscall_pre_setpriority(which, who, prio) \ + __sanitizer_syscall_pre_impl_setpriority( \ + (long long)(which), (long long)(who), (long long)(prio)) +#define __sanitizer_syscall_post_setpriority(res, which, who, prio) \ + __sanitizer_syscall_post_impl_setpriority( \ + res, (long long)(which), (long long)(who), (long long)(prio)) +#define __sanitizer_syscall_pre_compat_30_socket(domain, type, protocol) \ + __sanitizer_syscall_pre_impl_compat_30_socket( \ + (long long)(domain), (long long)(type), (long long)(protocol)) +#define __sanitizer_syscall_post_compat_30_socket(res, domain, type, protocol) \ + __sanitizer_syscall_post_impl_compat_30_socket( \ + res, (long long)(domain), (long long)(type), (long long)(protocol)) +#define __sanitizer_syscall_pre_connect(s, name, namelen) \ + __sanitizer_syscall_pre_impl_connect((long long)(s), (long long)(name), \ + (long long)(namelen)) +#define __sanitizer_syscall_post_connect(res, s, name, namelen) \ + __sanitizer_syscall_post_impl_connect( \ + res, (long long)(s), (long long)(name), (long long)(namelen)) +#define __sanitizer_syscall_pre_compat_43_oaccept(s, name, anamelen) \ + __sanitizer_syscall_pre_impl_compat_43_oaccept( \ + (long long)(s), (long long)(name), (long long)(anamelen)) +#define __sanitizer_syscall_post_compat_43_oaccept(res, s, name, anamelen) \ + __sanitizer_syscall_post_impl_compat_43_oaccept( \ + res, (long long)(s), (long long)(name), (long long)(anamelen)) +#define __sanitizer_syscall_pre_getpriority(which, who) \ + __sanitizer_syscall_pre_impl_getpriority((long long)(which), (long long)(who)) +#define __sanitizer_syscall_post_getpriority(res, which, who) \ + __sanitizer_syscall_post_impl_getpriority(res, (long long)(which), \ + (long long)(who)) +#define __sanitizer_syscall_pre_compat_43_osend(s, buf, len, flags) \ + __sanitizer_syscall_pre_impl_compat_43_osend( \ + (long long)(s), (long long)(buf), (long long)(len), (long long)(flags)) +#define __sanitizer_syscall_post_compat_43_osend(res, s, buf, len, flags) \ + __sanitizer_syscall_post_impl_compat_43_osend( \ + res, (long long)(s), (long long)(buf), (long long)(len), \ + (long long)(flags)) +#define __sanitizer_syscall_pre_compat_43_orecv(s, buf, len, flags) \ + __sanitizer_syscall_pre_impl_compat_43_orecv( \ + (long long)(s), (long long)(buf), (long long)(len), (long long)(flags)) +#define __sanitizer_syscall_post_compat_43_orecv(res, s, buf, len, flags) \ + __sanitizer_syscall_post_impl_compat_43_orecv( \ + res, (long long)(s), (long long)(buf), (long long)(len), \ + (long long)(flags)) +#define __sanitizer_syscall_pre_compat_13_sigreturn13(sigcntxp) \ + __sanitizer_syscall_pre_impl_compat_13_sigreturn13((long long)(sigcntxp)) +#define __sanitizer_syscall_post_compat_13_sigreturn13(res, sigcntxp) \ + __sanitizer_syscall_post_impl_compat_13_sigreturn13(res, \ + (long long)(sigcntxp)) +#define __sanitizer_syscall_pre_bind(s, name, namelen) \ + __sanitizer_syscall_pre_impl_bind((long long)(s), (long long)(name), \ + (long long)(namelen)) +#define __sanitizer_syscall_post_bind(res, s, name, namelen) \ + __sanitizer_syscall_post_impl_bind(res, (long long)(s), (long long)(name), \ + (long long)(namelen)) +#define __sanitizer_syscall_pre_setsockopt(s, level, name, val, valsize) \ + __sanitizer_syscall_pre_impl_setsockopt((long long)(s), (long long)(level), \ + (long long)(name), (long long)(val), \ + (long long)(valsize)) +#define __sanitizer_syscall_post_setsockopt(res, s, level, name, val, valsize) \ + __sanitizer_syscall_post_impl_setsockopt( \ + res, (long long)(s), (long long)(level), (long long)(name), \ + (long long)(val), (long long)(valsize)) +#define __sanitizer_syscall_pre_listen(s, backlog) \ + __sanitizer_syscall_pre_impl_listen((long long)(s), (long long)(backlog)) +#define __sanitizer_syscall_post_listen(res, s, backlog) \ + __sanitizer_syscall_post_impl_listen(res, (long long)(s), \ + (long long)(backlog)) +/* syscall 107 has been skipped */ +#define __sanitizer_syscall_pre_compat_43_osigvec(signum, nsv, osv) \ + __sanitizer_syscall_pre_impl_compat_43_osigvec( \ + (long long)(signum), (long long)(nsv), (long long)(osv)) +#define __sanitizer_syscall_post_compat_43_osigvec(res, signum, nsv, osv) \ + __sanitizer_syscall_post_impl_compat_43_osigvec( \ + res, (long long)(signum), (long long)(nsv), (long long)(osv)) +#define __sanitizer_syscall_pre_compat_43_osigblock(mask) \ + __sanitizer_syscall_pre_impl_compat_43_osigblock((long long)(mask)) +#define __sanitizer_syscall_post_compat_43_osigblock(res, mask) \ + __sanitizer_syscall_post_impl_compat_43_osigblock(res, (long long)(mask)) +#define __sanitizer_syscall_pre_compat_43_osigsetmask(mask) \ + __sanitizer_syscall_pre_impl_compat_43_osigsetmask((long long)(mask)) +#define __sanitizer_syscall_post_compat_43_osigsetmask(res, mask) \ + __sanitizer_syscall_post_impl_compat_43_osigsetmask(res, (long long)(mask)) +#define __sanitizer_syscall_pre_compat_13_sigsuspend13(mask) \ + __sanitizer_syscall_pre_impl_compat_13_sigsuspend13((long long)(mask)) +#define __sanitizer_syscall_post_compat_13_sigsuspend13(res, mask) \ + __sanitizer_syscall_post_impl_compat_13_sigsuspend13(res, (long long)(mask)) +#define __sanitizer_syscall_pre_compat_43_osigstack(nss, oss) \ + __sanitizer_syscall_pre_impl_compat_43_osigstack((long long)(nss), \ + (long long)(oss)) +#define __sanitizer_syscall_post_compat_43_osigstack(res, nss, oss) \ + __sanitizer_syscall_post_impl_compat_43_osigstack(res, (long long)(nss), \ + (long long)(oss)) +#define __sanitizer_syscall_pre_compat_43_orecvmsg(s, msg, flags) \ + __sanitizer_syscall_pre_impl_compat_43_orecvmsg( \ + (long long)(s), (long long)(msg), (long long)(flags)) +#define __sanitizer_syscall_post_compat_43_orecvmsg(res, s, msg, flags) \ + __sanitizer_syscall_post_impl_compat_43_orecvmsg( \ + res, (long long)(s), (long long)(msg), (long long)(flags)) +#define __sanitizer_syscall_pre_compat_43_osendmsg(s, msg, flags) \ + __sanitizer_syscall_pre_impl_compat_43_osendmsg( \ + (long long)(s), (long long)(msg), (long long)(flags)) +#define __sanitizer_syscall_post_compat_43_osendmsg(res, s, msg, flags) \ + __sanitizer_syscall_post_impl_compat_43_osendmsg( \ + res, (long long)(s), (long long)(msg), (long long)(flags)) +/* syscall 115 has been skipped */ +#define __sanitizer_syscall_pre_compat_50_gettimeofday(tp, tzp) \ + __sanitizer_syscall_pre_impl_compat_50_gettimeofday((long long)(tp), \ + (long long)(tzp)) +#define __sanitizer_syscall_post_compat_50_gettimeofday(res, tp, tzp) \ + __sanitizer_syscall_post_impl_compat_50_gettimeofday(res, (long long)(tp), \ + (long long)(tzp)) +#define __sanitizer_syscall_pre_compat_50_getrusage(who, rusage) \ + __sanitizer_syscall_pre_impl_compat_50_getrusage((long long)(who), \ + (long long)(rusage)) +#define __sanitizer_syscall_post_compat_50_getrusage(res, who, rusage) \ + __sanitizer_syscall_post_impl_compat_50_getrusage(res, (long long)(who), \ + (long long)(rusage)) +#define __sanitizer_syscall_pre_getsockopt(s, level, name, val, avalsize) \ + __sanitizer_syscall_pre_impl_getsockopt((long long)(s), (long long)(level), \ + (long long)(name), (long long)(val), \ + (long long)(avalsize)) +#define __sanitizer_syscall_post_getsockopt(res, s, level, name, val, \ + avalsize) \ + __sanitizer_syscall_post_impl_getsockopt( \ + res, (long long)(s), (long long)(level), (long long)(name), \ + (long long)(val), (long long)(avalsize)) +/* syscall 119 has been skipped */ +#define __sanitizer_syscall_pre_readv(fd, iovp, iovcnt) \ + __sanitizer_syscall_pre_impl_readv((long long)(fd), (long long)(iovp), \ + (long long)(iovcnt)) +#define __sanitizer_syscall_post_readv(res, fd, iovp, iovcnt) \ + __sanitizer_syscall_post_impl_readv(res, (long long)(fd), (long long)(iovp), \ + (long long)(iovcnt)) +#define __sanitizer_syscall_pre_writev(fd, iovp, iovcnt) \ + __sanitizer_syscall_pre_impl_writev((long long)(fd), (long long)(iovp), \ + (long long)(iovcnt)) +#define __sanitizer_syscall_post_writev(res, fd, iovp, iovcnt) \ + __sanitizer_syscall_post_impl_writev(res, (long long)(fd), \ + (long long)(iovp), (long long)(iovcnt)) +#define __sanitizer_syscall_pre_compat_50_settimeofday(tv, tzp) \ + __sanitizer_syscall_pre_impl_compat_50_settimeofday((long long)(tv), \ + (long long)(tzp)) +#define __sanitizer_syscall_post_compat_50_settimeofday(res, tv, tzp) \ + __sanitizer_syscall_post_impl_compat_50_settimeofday(res, (long long)(tv), \ + (long long)(tzp)) +#define __sanitizer_syscall_pre_fchown(fd, uid, gid) \ + __sanitizer_syscall_pre_impl_fchown((long long)(fd), (long long)(uid), \ + (long long)(gid)) +#define __sanitizer_syscall_post_fchown(res, fd, uid, gid) \ + __sanitizer_syscall_post_impl_fchown(res, (long long)(fd), (long long)(uid), \ + (long long)(gid)) +#define __sanitizer_syscall_pre_fchmod(fd, mode) \ + __sanitizer_syscall_pre_impl_fchmod((long long)(fd), (long long)(mode)) +#define __sanitizer_syscall_post_fchmod(res, fd, mode) \ + __sanitizer_syscall_post_impl_fchmod(res, (long long)(fd), (long long)(mode)) +#define __sanitizer_syscall_pre_compat_43_orecvfrom(s, buf, len, flags, from, \ + fromlenaddr) \ + __sanitizer_syscall_pre_impl_compat_43_orecvfrom( \ + (long long)(s), (long long)(buf), (long long)(len), (long long)(flags), \ + (long long)(from), (long long)(fromlenaddr)) +#define __sanitizer_syscall_post_compat_43_orecvfrom(res, s, buf, len, flags, \ + from, fromlenaddr) \ + __sanitizer_syscall_post_impl_compat_43_orecvfrom( \ + res, (long long)(s), (long long)(buf), (long long)(len), \ + (long long)(flags), (long long)(from), (long long)(fromlenaddr)) +#define __sanitizer_syscall_pre_setreuid(ruid, euid) \ + __sanitizer_syscall_pre_impl_setreuid((long long)(ruid), (long long)(euid)) +#define __sanitizer_syscall_post_setreuid(res, ruid, euid) \ + __sanitizer_syscall_post_impl_setreuid(res, (long long)(ruid), \ + (long long)(euid)) +#define __sanitizer_syscall_pre_setregid(rgid, egid) \ + __sanitizer_syscall_pre_impl_setregid((long long)(rgid), (long long)(egid)) +#define __sanitizer_syscall_post_setregid(res, rgid, egid) \ + __sanitizer_syscall_post_impl_setregid(res, (long long)(rgid), \ + (long long)(egid)) +#define __sanitizer_syscall_pre_rename(from, to) \ + __sanitizer_syscall_pre_impl_rename((long long)(from), (long long)(to)) +#define __sanitizer_syscall_post_rename(res, from, to) \ + __sanitizer_syscall_post_impl_rename(res, (long long)(from), (long long)(to)) +#define __sanitizer_syscall_pre_compat_43_otruncate(path, length) \ + __sanitizer_syscall_pre_impl_compat_43_otruncate((long long)(path), \ + (long long)(length)) +#define __sanitizer_syscall_post_compat_43_otruncate(res, path, length) \ + __sanitizer_syscall_post_impl_compat_43_otruncate(res, (long long)(path), \ + (long long)(length)) +#define __sanitizer_syscall_pre_compat_43_oftruncate(fd, length) \ + __sanitizer_syscall_pre_impl_compat_43_oftruncate((long long)(fd), \ + (long long)(length)) +#define __sanitizer_syscall_post_compat_43_oftruncate(res, fd, length) \ + __sanitizer_syscall_post_impl_compat_43_oftruncate(res, (long long)(fd), \ + (long long)(length)) +#define __sanitizer_syscall_pre_flock(fd, how) \ + __sanitizer_syscall_pre_impl_flock((long long)(fd), (long long)(how)) +#define __sanitizer_syscall_post_flock(res, fd, how) \ + __sanitizer_syscall_post_impl_flock(res, (long long)(fd), (long long)(how)) +#define __sanitizer_syscall_pre_mkfifo(path, mode) \ + __sanitizer_syscall_pre_impl_mkfifo((long long)(path), (long long)(mode)) +#define __sanitizer_syscall_post_mkfifo(res, path, mode) \ + __sanitizer_syscall_post_impl_mkfifo(res, (long long)(path), \ + (long long)(mode)) +#define __sanitizer_syscall_pre_sendto(s, buf, len, flags, to, tolen) \ + __sanitizer_syscall_pre_impl_sendto((long long)(s), (long long)(buf), \ + (long long)(len), (long long)(flags), \ + (long long)(to), (long long)(tolen)) +#define __sanitizer_syscall_post_sendto(res, s, buf, len, flags, to, tolen) \ + __sanitizer_syscall_post_impl_sendto(res, (long long)(s), (long long)(buf), \ + (long long)(len), (long long)(flags), \ + (long long)(to), (long long)(tolen)) +#define __sanitizer_syscall_pre_shutdown(s, how) \ + __sanitizer_syscall_pre_impl_shutdown((long long)(s), (long long)(how)) +#define __sanitizer_syscall_post_shutdown(res, s, how) \ + __sanitizer_syscall_post_impl_shutdown(res, (long long)(s), (long long)(how)) +#define __sanitizer_syscall_pre_socketpair(domain, type, protocol, rsv) \ + __sanitizer_syscall_pre_impl_socketpair( \ + (long long)(domain), (long long)(type), (long long)(protocol), \ + (long long)(rsv)) +#define __sanitizer_syscall_post_socketpair(res, domain, type, protocol, rsv) \ + __sanitizer_syscall_post_impl_socketpair( \ + res, (long long)(domain), (long long)(type), (long long)(protocol), \ + (long long)(rsv)) +#define __sanitizer_syscall_pre_mkdir(path, mode) \ + __sanitizer_syscall_pre_impl_mkdir((long long)(path), (long long)(mode)) +#define __sanitizer_syscall_post_mkdir(res, path, mode) \ + __sanitizer_syscall_post_impl_mkdir(res, (long long)(path), (long long)(mode)) +#define __sanitizer_syscall_pre_rmdir(path) \ + __sanitizer_syscall_pre_impl_rmdir((long long)(path)) +#define __sanitizer_syscall_post_rmdir(res, path) \ + __sanitizer_syscall_post_impl_rmdir(res, (long long)(path)) +#define __sanitizer_syscall_pre_compat_50_utimes(path, tptr) \ + __sanitizer_syscall_pre_impl_compat_50_utimes((long long)(path), \ + (long long)(tptr)) +#define __sanitizer_syscall_post_compat_50_utimes(res, path, tptr) \ + __sanitizer_syscall_post_impl_compat_50_utimes(res, (long long)(path), \ + (long long)(tptr)) +/* syscall 139 has been skipped */ +#define __sanitizer_syscall_pre_compat_50_adjtime(delta, olddelta) \ + __sanitizer_syscall_pre_impl_compat_50_adjtime((long long)(delta), \ + (long long)(olddelta)) +#define __sanitizer_syscall_post_compat_50_adjtime(res, delta, olddelta) \ + __sanitizer_syscall_post_impl_compat_50_adjtime(res, (long long)(delta), \ + (long long)(olddelta)) +#define __sanitizer_syscall_pre_compat_43_ogetpeername(fdes, asa, alen) \ + __sanitizer_syscall_pre_impl_compat_43_ogetpeername( \ + (long long)(fdes), (long long)(asa), (long long)(alen)) +#define __sanitizer_syscall_post_compat_43_ogetpeername(res, fdes, asa, alen) \ + __sanitizer_syscall_post_impl_compat_43_ogetpeername( \ + res, (long long)(fdes), (long long)(asa), (long long)(alen)) +#define __sanitizer_syscall_pre_compat_43_ogethostid() \ + __sanitizer_syscall_pre_impl_compat_43_ogethostid() +#define __sanitizer_syscall_post_compat_43_ogethostid(res) \ + __sanitizer_syscall_post_impl_compat_43_ogethostid(res) +#define __sanitizer_syscall_pre_compat_43_osethostid(hostid) \ + __sanitizer_syscall_pre_impl_compat_43_osethostid((long long)(hostid)) +#define __sanitizer_syscall_post_compat_43_osethostid(res, hostid) \ + __sanitizer_syscall_post_impl_compat_43_osethostid(res, (long long)(hostid)) +#define __sanitizer_syscall_pre_compat_43_ogetrlimit(which, rlp) \ + __sanitizer_syscall_pre_impl_compat_43_ogetrlimit((long long)(which), \ + (long long)(rlp)) +#define __sanitizer_syscall_post_compat_43_ogetrlimit(res, which, rlp) \ + __sanitizer_syscall_post_impl_compat_43_ogetrlimit(res, (long long)(which), \ + (long long)(rlp)) +#define __sanitizer_syscall_pre_compat_43_osetrlimit(which, rlp) \ + __sanitizer_syscall_pre_impl_compat_43_osetrlimit((long long)(which), \ + (long long)(rlp)) +#define __sanitizer_syscall_post_compat_43_osetrlimit(res, which, rlp) \ + __sanitizer_syscall_post_impl_compat_43_osetrlimit(res, (long long)(which), \ + (long long)(rlp)) +#define __sanitizer_syscall_pre_compat_43_okillpg(pgid, signum) \ + __sanitizer_syscall_pre_impl_compat_43_okillpg((long long)(pgid), \ + (long long)(signum)) +#define __sanitizer_syscall_post_compat_43_okillpg(res, pgid, signum) \ + __sanitizer_syscall_post_impl_compat_43_okillpg(res, (long long)(pgid), \ + (long long)(signum)) +#define __sanitizer_syscall_pre_setsid() __sanitizer_syscall_pre_impl_setsid() +#define __sanitizer_syscall_post_setsid(res) \ + __sanitizer_syscall_post_impl_setsid(res) +#define __sanitizer_syscall_pre_compat_50_quotactl(path, cmd, uid, arg) \ + __sanitizer_syscall_pre_impl_compat_50_quotactl( \ + (long long)(path), (long long)(cmd), (long long)(uid), (long long)(arg)) +#define __sanitizer_syscall_post_compat_50_quotactl(res, path, cmd, uid, arg) \ + __sanitizer_syscall_post_impl_compat_50_quotactl( \ + res, (long long)(path), (long long)(cmd), (long long)(uid), \ + (long long)(arg)) +#define __sanitizer_syscall_pre_compat_43_oquota() \ + __sanitizer_syscall_pre_impl_compat_43_oquota() +#define __sanitizer_syscall_post_compat_43_oquota(res) \ + __sanitizer_syscall_post_impl_compat_43_oquota(res) +#define __sanitizer_syscall_pre_compat_43_ogetsockname(fdec, asa, alen) \ + __sanitizer_syscall_pre_impl_compat_43_ogetsockname( \ + (long long)(fdec), (long long)(asa), (long long)(alen)) +#define __sanitizer_syscall_post_compat_43_ogetsockname(res, fdec, asa, alen) \ + __sanitizer_syscall_post_impl_compat_43_ogetsockname( \ + res, (long long)(fdec), (long long)(asa), (long long)(alen)) +/* syscall 151 has been skipped */ +/* syscall 152 has been skipped */ +/* syscall 153 has been skipped */ +/* syscall 154 has been skipped */ +#define __sanitizer_syscall_pre_nfssvc(flag, argp) \ + __sanitizer_syscall_pre_impl_nfssvc((long long)(flag), (long long)(argp)) +#define __sanitizer_syscall_post_nfssvc(res, flag, argp) \ + __sanitizer_syscall_post_impl_nfssvc(res, (long long)(flag), \ + (long long)(argp)) +#define __sanitizer_syscall_pre_compat_43_ogetdirentries(fd, buf, count, \ + basep) \ + __sanitizer_syscall_pre_impl_compat_43_ogetdirentries( \ + (long long)(fd), (long long)(buf), (long long)(count), \ + (long long)(basep)) +#define __sanitizer_syscall_post_compat_43_ogetdirentries(res, fd, buf, count, \ + basep) \ + __sanitizer_syscall_post_impl_compat_43_ogetdirentries( \ + res, (long long)(fd), (long long)(buf), (long long)(count), \ + (long long)(basep)) +#define __sanitizer_syscall_pre_compat_20_statfs(path, buf) \ + __sanitizer_syscall_pre_impl_compat_20_statfs((long long)(path), \ + (long long)(buf)) +#define __sanitizer_syscall_post_compat_20_statfs(res, path, buf) \ + __sanitizer_syscall_post_impl_compat_20_statfs(res, (long long)(path), \ + (long long)(buf)) +#define __sanitizer_syscall_pre_compat_20_fstatfs(fd, buf) \ + __sanitizer_syscall_pre_impl_compat_20_fstatfs((long long)(fd), \ + (long long)(buf)) +#define __sanitizer_syscall_post_compat_20_fstatfs(res, fd, buf) \ + __sanitizer_syscall_post_impl_compat_20_fstatfs(res, (long long)(fd), \ + (long long)(buf)) +/* syscall 159 has been skipped */ +/* syscall 160 has been skipped */ +#define __sanitizer_syscall_pre_compat_30_getfh(fname, fhp) \ + __sanitizer_syscall_pre_impl_compat_30_getfh((long long)(fname), \ + (long long)(fhp)) +#define __sanitizer_syscall_post_compat_30_getfh(res, fname, fhp) \ + __sanitizer_syscall_post_impl_compat_30_getfh(res, (long long)(fname), \ + (long long)(fhp)) +#define __sanitizer_syscall_pre_compat_09_ogetdomainname(domainname, len) \ + __sanitizer_syscall_pre_impl_compat_09_ogetdomainname( \ + (long long)(domainname), (long long)(len)) +#define __sanitizer_syscall_post_compat_09_ogetdomainname(res, domainname, \ + len) \ + __sanitizer_syscall_post_impl_compat_09_ogetdomainname( \ + res, (long long)(domainname), (long long)(len)) +#define __sanitizer_syscall_pre_compat_09_osetdomainname(domainname, len) \ + __sanitizer_syscall_pre_impl_compat_09_osetdomainname( \ + (long long)(domainname), (long long)(len)) +#define __sanitizer_syscall_post_compat_09_osetdomainname(res, domainname, \ + len) \ + __sanitizer_syscall_post_impl_compat_09_osetdomainname( \ + res, (long long)(domainname), (long long)(len)) +#define __sanitizer_syscall_pre_compat_09_ouname(name) \ + __sanitizer_syscall_pre_impl_compat_09_ouname((long long)(name)) +#define __sanitizer_syscall_post_compat_09_ouname(res, name) \ + __sanitizer_syscall_post_impl_compat_09_ouname(res, (long long)(name)) +#define __sanitizer_syscall_pre_sysarch(op, parms) \ + __sanitizer_syscall_pre_impl_sysarch((long long)(op), (long long)(parms)) +#define __sanitizer_syscall_post_sysarch(res, op, parms) \ + __sanitizer_syscall_post_impl_sysarch(res, (long long)(op), \ + (long long)(parms)) +/* syscall 166 has been skipped */ +/* syscall 167 has been skipped */ +/* syscall 168 has been skipped */ +#if !defined(_LP64) +#define __sanitizer_syscall_pre_compat_10_osemsys(which, a2, a3, a4, a5) \ + __sanitizer_syscall_pre_impl_compat_10_osemsys( \ + (long long)(which), (long long)(a2), (long long)(a3), (long long)(a4), \ + (long long)(a5)) +#define __sanitizer_syscall_post_compat_10_osemsys(res, which, a2, a3, a4, a5) \ + __sanitizer_syscall_post_impl_compat_10_osemsys( \ + res, (long long)(which), (long long)(a2), (long long)(a3), \ + (long long)(a4), (long long)(a5)) +#else +/* syscall 169 has been skipped */ +#endif +#if !defined(_LP64) +#define __sanitizer_syscall_pre_compat_10_omsgsys(which, a2, a3, a4, a5, a6) \ + __sanitizer_syscall_pre_impl_compat_10_omsgsys( \ + (long long)(which), (long long)(a2), (long long)(a3), (long long)(a4), \ + (long long)(a5), (long long)(a6)) +#define __sanitizer_syscall_post_compat_10_omsgsys(res, which, a2, a3, a4, a5, \ + a6) \ + __sanitizer_syscall_post_impl_compat_10_omsgsys( \ + res, (long long)(which), (long long)(a2), (long long)(a3), \ + (long long)(a4), (long long)(a5), (long long)(a6)) +#else +/* syscall 170 has been skipped */ +#endif +#if !defined(_LP64) +#define __sanitizer_syscall_pre_compat_10_oshmsys(which, a2, a3, a4) \ + __sanitizer_syscall_pre_impl_compat_10_oshmsys( \ + (long long)(which), (long long)(a2), (long long)(a3), (long long)(a4)) +#define __sanitizer_syscall_post_compat_10_oshmsys(res, which, a2, a3, a4) \ + __sanitizer_syscall_post_impl_compat_10_oshmsys( \ + res, (long long)(which), (long long)(a2), (long long)(a3), \ + (long long)(a4)) +#else +/* syscall 171 has been skipped */ +#endif +/* syscall 172 has been skipped */ +#define __sanitizer_syscall_pre_pread(fd, buf, nbyte, PAD, offset) \ + __sanitizer_syscall_pre_impl_pread((long long)(fd), (long long)(buf), \ + (long long)(nbyte), (long long)(PAD), \ + (long long)(offset)) +#define __sanitizer_syscall_post_pread(res, fd, buf, nbyte, PAD, offset) \ + __sanitizer_syscall_post_impl_pread(res, (long long)(fd), (long long)(buf), \ + (long long)(nbyte), (long long)(PAD), \ + (long long)(offset)) +#define __sanitizer_syscall_pre_pwrite(fd, buf, nbyte, PAD, offset) \ + __sanitizer_syscall_pre_impl_pwrite((long long)(fd), (long long)(buf), \ + (long long)(nbyte), (long long)(PAD), \ + (long long)(offset)) +#define __sanitizer_syscall_post_pwrite(res, fd, buf, nbyte, PAD, offset) \ + __sanitizer_syscall_post_impl_pwrite(res, (long long)(fd), (long long)(buf), \ + (long long)(nbyte), (long long)(PAD), \ + (long long)(offset)) +#define __sanitizer_syscall_pre_compat_30_ntp_gettime(ntvp) \ + __sanitizer_syscall_pre_impl_compat_30_ntp_gettime((long long)(ntvp)) +#define __sanitizer_syscall_post_compat_30_ntp_gettime(res, ntvp) \ + __sanitizer_syscall_post_impl_compat_30_ntp_gettime(res, (long long)(ntvp)) +#if defined(NTP) || !defined(_KERNEL_OPT) +#define __sanitizer_syscall_pre_ntp_adjtime(tp) \ + __sanitizer_syscall_pre_impl_ntp_adjtime((long long)(tp)) +#define __sanitizer_syscall_post_ntp_adjtime(res, tp) \ + __sanitizer_syscall_post_impl_ntp_adjtime(res, (long long)(tp)) +#else +/* syscall 176 has been skipped */ +#endif +/* syscall 177 has been skipped */ +/* syscall 178 has been skipped */ +/* syscall 179 has been skipped */ +/* syscall 180 has been skipped */ +#define __sanitizer_syscall_pre_setgid(gid) \ + __sanitizer_syscall_pre_impl_setgid((long long)(gid)) +#define __sanitizer_syscall_post_setgid(res, gid) \ + __sanitizer_syscall_post_impl_setgid(res, (long long)(gid)) +#define __sanitizer_syscall_pre_setegid(egid) \ + __sanitizer_syscall_pre_impl_setegid((long long)(egid)) +#define __sanitizer_syscall_post_setegid(res, egid) \ + __sanitizer_syscall_post_impl_setegid(res, (long long)(egid)) +#define __sanitizer_syscall_pre_seteuid(euid) \ + __sanitizer_syscall_pre_impl_seteuid((long long)(euid)) +#define __sanitizer_syscall_post_seteuid(res, euid) \ + __sanitizer_syscall_post_impl_seteuid(res, (long long)(euid)) +#define __sanitizer_syscall_pre_lfs_bmapv(fsidp, blkiov, blkcnt) \ + __sanitizer_syscall_pre_impl_lfs_bmapv( \ + (long long)(fsidp), (long long)(blkiov), (long long)(blkcnt)) +#define __sanitizer_syscall_post_lfs_bmapv(res, fsidp, blkiov, blkcnt) \ + __sanitizer_syscall_post_impl_lfs_bmapv( \ + res, (long long)(fsidp), (long long)(blkiov), (long long)(blkcnt)) +#define __sanitizer_syscall_pre_lfs_markv(fsidp, blkiov, blkcnt) \ + __sanitizer_syscall_pre_impl_lfs_markv( \ + (long long)(fsidp), (long long)(blkiov), (long long)(blkcnt)) +#define __sanitizer_syscall_post_lfs_markv(res, fsidp, blkiov, blkcnt) \ + __sanitizer_syscall_post_impl_lfs_markv( \ + res, (long long)(fsidp), (long long)(blkiov), (long long)(blkcnt)) +#define __sanitizer_syscall_pre_lfs_segclean(fsidp, segment) \ + __sanitizer_syscall_pre_impl_lfs_segclean((long long)(fsidp), \ + (long long)(segment)) +#define __sanitizer_syscall_post_lfs_segclean(res, fsidp, segment) \ + __sanitizer_syscall_post_impl_lfs_segclean(res, (long long)(fsidp), \ + (long long)(segment)) +#define __sanitizer_syscall_pre_compat_50_lfs_segwait(fsidp, tv) \ + __sanitizer_syscall_pre_impl_compat_50_lfs_segwait((long long)(fsidp), \ + (long long)(tv)) +#define __sanitizer_syscall_post_compat_50_lfs_segwait(res, fsidp, tv) \ + __sanitizer_syscall_post_impl_compat_50_lfs_segwait(res, (long long)(fsidp), \ + (long long)(tv)) +#define __sanitizer_syscall_pre_compat_12_stat12(path, ub) \ + __sanitizer_syscall_pre_impl_compat_12_stat12((long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_post_compat_12_stat12(res, path, ub) \ + __sanitizer_syscall_post_impl_compat_12_stat12(res, (long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_pre_compat_12_fstat12(fd, sb) \ + __sanitizer_syscall_pre_impl_compat_12_fstat12((long long)(fd), \ + (long long)(sb)) +#define __sanitizer_syscall_post_compat_12_fstat12(res, fd, sb) \ + __sanitizer_syscall_post_impl_compat_12_fstat12(res, (long long)(fd), \ + (long long)(sb)) +#define __sanitizer_syscall_pre_compat_12_lstat12(path, ub) \ + __sanitizer_syscall_pre_impl_compat_12_lstat12((long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_post_compat_12_lstat12(res, path, ub) \ + __sanitizer_syscall_post_impl_compat_12_lstat12(res, (long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_pre_pathconf(path, name) \ + __sanitizer_syscall_pre_impl_pathconf((long long)(path), (long long)(name)) +#define __sanitizer_syscall_post_pathconf(res, path, name) \ + __sanitizer_syscall_post_impl_pathconf(res, (long long)(path), \ + (long long)(name)) +#define __sanitizer_syscall_pre_fpathconf(fd, name) \ + __sanitizer_syscall_pre_impl_fpathconf((long long)(fd), (long long)(name)) +#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_getrlimit(which, rlp) \ + __sanitizer_syscall_pre_impl_getrlimit((long long)(which), (long long)(rlp)) +#define __sanitizer_syscall_post_getrlimit(res, which, rlp) \ + __sanitizer_syscall_post_impl_getrlimit(res, (long long)(which), \ + (long long)(rlp)) +#define __sanitizer_syscall_pre_setrlimit(which, rlp) \ + __sanitizer_syscall_pre_impl_setrlimit((long long)(which), (long long)(rlp)) +#define __sanitizer_syscall_post_setrlimit(res, which, rlp) \ + __sanitizer_syscall_post_impl_setrlimit(res, (long long)(which), \ + (long long)(rlp)) +#define __sanitizer_syscall_pre_compat_12_getdirentries(fd, buf, count, basep) \ + __sanitizer_syscall_pre_impl_compat_12_getdirentries( \ + (long long)(fd), (long long)(buf), (long long)(count), \ + (long long)(basep)) +#define __sanitizer_syscall_post_compat_12_getdirentries(res, fd, buf, count, \ + basep) \ + __sanitizer_syscall_post_impl_compat_12_getdirentries( \ + res, (long long)(fd), (long long)(buf), (long long)(count), \ + (long long)(basep)) +#define __sanitizer_syscall_pre_mmap(addr, len, prot, flags, fd, PAD, pos) \ + __sanitizer_syscall_pre_impl_mmap( \ + (long long)(addr), (long long)(len), (long long)(prot), \ + (long long)(flags), (long long)(fd), (long long)(PAD), (long long)(pos)) +#define __sanitizer_syscall_post_mmap(res, addr, len, prot, flags, fd, PAD, \ + pos) \ + __sanitizer_syscall_post_impl_mmap( \ + res, (long long)(addr), (long long)(len), (long long)(prot), \ + (long long)(flags), (long long)(fd), (long long)(PAD), (long long)(pos)) +#define __sanitizer_syscall_pre___syscall(code, arg0, arg1, arg2, arg3, arg4, \ + arg5, arg6, arg7) \ + __sanitizer_syscall_pre_impl___syscall( \ + (long long)(code), (long long)(arg0), (long long)(arg1), \ + (long long)(arg2), (long long)(arg3), (long long)(arg4), \ + (long long)(arg5), (long long)(arg6), (long long)(arg7)) +#define __sanitizer_syscall_post___syscall(res, code, arg0, arg1, arg2, arg3, \ + arg4, arg5, arg6, arg7) \ + __sanitizer_syscall_post_impl___syscall( \ + res, (long long)(code), (long long)(arg0), (long long)(arg1), \ + (long long)(arg2), (long long)(arg3), (long long)(arg4), \ + (long long)(arg5), (long long)(arg6), (long long)(arg7)) +#define __sanitizer_syscall_pre_lseek(fd, PAD, offset, whence) \ + __sanitizer_syscall_pre_impl_lseek((long long)(fd), (long long)(PAD), \ + (long long)(offset), (long long)(whence)) +#define __sanitizer_syscall_post_lseek(res, fd, PAD, offset, whence) \ + __sanitizer_syscall_post_impl_lseek(res, (long long)(fd), (long long)(PAD), \ + (long long)(offset), \ + (long long)(whence)) +#define __sanitizer_syscall_pre_truncate(path, PAD, length) \ + __sanitizer_syscall_pre_impl_truncate((long long)(path), (long long)(PAD), \ + (long long)(length)) +#define __sanitizer_syscall_post_truncate(res, path, PAD, length) \ + __sanitizer_syscall_post_impl_truncate( \ + res, (long long)(path), (long long)(PAD), (long long)(length)) +#define __sanitizer_syscall_pre_ftruncate(fd, PAD, length) \ + __sanitizer_syscall_pre_impl_ftruncate((long long)(fd), (long long)(PAD), \ + (long long)(length)) +#define __sanitizer_syscall_post_ftruncate(res, fd, PAD, length) \ + __sanitizer_syscall_post_impl_ftruncate( \ + res, (long long)(fd), (long long)(PAD), (long long)(length)) +#define __sanitizer_syscall_pre___sysctl(name, namelen, oldv, oldlenp, newv, \ + newlen) \ + __sanitizer_syscall_pre_impl___sysctl( \ + (long long)(name), (long long)(namelen), (long long)(oldv), \ + (long long)(oldlenp), (long long)(newv), (long long)(newlen)) +#define __sanitizer_syscall_post___sysctl(res, name, namelen, oldv, oldlenp, \ + newv, newlen) \ + __sanitizer_syscall_post_impl___sysctl( \ + res, (long long)(name), (long long)(namelen), (long long)(oldv), \ + (long long)(oldlenp), (long long)(newv), (long long)(newlen)) +#define __sanitizer_syscall_pre_mlock(addr, len) \ + __sanitizer_syscall_pre_impl_mlock((long long)(addr), (long long)(len)) +#define __sanitizer_syscall_post_mlock(res, addr, len) \ + __sanitizer_syscall_post_impl_mlock(res, (long long)(addr), (long long)(len)) +#define __sanitizer_syscall_pre_munlock(addr, len) \ + __sanitizer_syscall_pre_impl_munlock((long long)(addr), (long long)(len)) +#define __sanitizer_syscall_post_munlock(res, addr, len) \ + __sanitizer_syscall_post_impl_munlock(res, (long long)(addr), \ + (long long)(len)) +#define __sanitizer_syscall_pre_undelete(path) \ + __sanitizer_syscall_pre_impl_undelete((long long)(path)) +#define __sanitizer_syscall_post_undelete(res, path) \ + __sanitizer_syscall_post_impl_undelete(res, (long long)(path)) +#define __sanitizer_syscall_pre_compat_50_futimes(fd, tptr) \ + __sanitizer_syscall_pre_impl_compat_50_futimes((long long)(fd), \ + (long long)(tptr)) +#define __sanitizer_syscall_post_compat_50_futimes(res, fd, tptr) \ + __sanitizer_syscall_post_impl_compat_50_futimes(res, (long long)(fd), \ + (long long)(tptr)) +#define __sanitizer_syscall_pre_getpgid(pid) \ + __sanitizer_syscall_pre_impl_getpgid((long long)(pid)) +#define __sanitizer_syscall_post_getpgid(res, pid) \ + __sanitizer_syscall_post_impl_getpgid(res, (long long)(pid)) +#define __sanitizer_syscall_pre_reboot(opt, bootstr) \ + __sanitizer_syscall_pre_impl_reboot((long long)(opt), (long long)(bootstr)) +#define __sanitizer_syscall_post_reboot(res, opt, bootstr) \ + __sanitizer_syscall_post_impl_reboot(res, (long long)(opt), \ + (long long)(bootstr)) +#define __sanitizer_syscall_pre_poll(fds, nfds, timeout) \ + __sanitizer_syscall_pre_impl_poll((long long)(fds), (long long)(nfds), \ + (long long)(timeout)) +#define __sanitizer_syscall_post_poll(res, fds, nfds, timeout) \ + __sanitizer_syscall_post_impl_poll(res, (long long)(fds), (long long)(nfds), \ + (long long)(timeout)) +#define __sanitizer_syscall_pre_afssys(id, a1, a2, a3, a4, a5, a6) \ + __sanitizer_syscall_pre_impl_afssys( \ + (long long)(id), (long long)(a1), (long long)(a2), (long long)(a3), \ + (long long)(a4), (long long)(a5), (long long)(a6)) +#define __sanitizer_syscall_post_afssys(res, id, a1, a2, a3, a4, a5, a6) \ + __sanitizer_syscall_post_impl_afssys( \ + res, (long long)(id), (long long)(a1), (long long)(a2), (long long)(a3), \ + (long long)(a4), (long long)(a5), (long long)(a6)) +/* syscall 211 has been skipped */ +/* syscall 212 has been skipped */ +/* syscall 213 has been skipped */ +/* syscall 214 has been skipped */ +/* syscall 215 has been skipped */ +/* syscall 216 has been skipped */ +/* syscall 217 has been skipped */ +/* syscall 218 has been skipped */ +/* syscall 219 has been skipped */ +#define __sanitizer_syscall_pre_compat_14___semctl(semid, semnum, cmd, arg) \ + __sanitizer_syscall_pre_impl_compat_14___semctl( \ + (long long)(semid), (long long)(semnum), (long long)(cmd), \ + (long long)(arg)) +#define __sanitizer_syscall_post_compat_14___semctl(res, semid, semnum, cmd, \ + arg) \ + __sanitizer_syscall_post_impl_compat_14___semctl( \ + res, (long long)(semid), (long long)(semnum), (long long)(cmd), \ + (long long)(arg)) +#define __sanitizer_syscall_pre_semget(key, nsems, semflg) \ + __sanitizer_syscall_pre_impl_semget((long long)(key), (long long)(nsems), \ + (long long)(semflg)) +#define __sanitizer_syscall_post_semget(res, key, nsems, semflg) \ + __sanitizer_syscall_post_impl_semget( \ + res, (long long)(key), (long long)(nsems), (long long)(semflg)) +#define __sanitizer_syscall_pre_semop(semid, sops, nsops) \ + __sanitizer_syscall_pre_impl_semop((long long)(semid), (long long)(sops), \ + (long long)(nsops)) +#define __sanitizer_syscall_post_semop(res, semid, sops, nsops) \ + __sanitizer_syscall_post_impl_semop(res, (long long)(semid), \ + (long long)(sops), (long long)(nsops)) +#define __sanitizer_syscall_pre_semconfig(flag) \ + __sanitizer_syscall_pre_impl_semconfig((long long)(flag)) +#define __sanitizer_syscall_post_semconfig(res, flag) \ + __sanitizer_syscall_post_impl_semconfig(res, (long long)(flag)) +#define __sanitizer_syscall_pre_compat_14_msgctl(msqid, cmd, buf) \ + __sanitizer_syscall_pre_impl_compat_14_msgctl( \ + (long long)(msqid), (long long)(cmd), (long long)(buf)) +#define __sanitizer_syscall_post_compat_14_msgctl(res, msqid, cmd, buf) \ + __sanitizer_syscall_post_impl_compat_14_msgctl( \ + res, (long long)(msqid), (long long)(cmd), (long long)(buf)) +#define __sanitizer_syscall_pre_msgget(key, msgflg) \ + __sanitizer_syscall_pre_impl_msgget((long long)(key), (long long)(msgflg)) +#define __sanitizer_syscall_post_msgget(res, key, msgflg) \ + __sanitizer_syscall_post_impl_msgget(res, (long long)(key), \ + (long long)(msgflg)) +#define __sanitizer_syscall_pre_msgsnd(msqid, msgp, msgsz, msgflg) \ + __sanitizer_syscall_pre_impl_msgsnd((long long)(msqid), (long long)(msgp), \ + (long long)(msgsz), (long long)(msgflg)) +#define __sanitizer_syscall_post_msgsnd(res, msqid, msgp, msgsz, msgflg) \ + __sanitizer_syscall_post_impl_msgsnd(res, (long long)(msqid), \ + (long long)(msgp), (long long)(msgsz), \ + (long long)(msgflg)) +#define __sanitizer_syscall_pre_msgrcv(msqid, msgp, msgsz, msgtyp, msgflg) \ + __sanitizer_syscall_pre_impl_msgrcv((long long)(msqid), (long long)(msgp), \ + (long long)(msgsz), (long long)(msgtyp), \ + (long long)(msgflg)) +#define __sanitizer_syscall_post_msgrcv(res, msqid, msgp, msgsz, msgtyp, \ + msgflg) \ + __sanitizer_syscall_post_impl_msgrcv( \ + res, (long long)(msqid), (long long)(msgp), (long long)(msgsz), \ + (long long)(msgtyp), (long long)(msgflg)) +#define __sanitizer_syscall_pre_shmat(shmid, shmaddr, shmflg) \ + __sanitizer_syscall_pre_impl_shmat((long long)(shmid), (long long)(shmaddr), \ + (long long)(shmflg)) +#define __sanitizer_syscall_post_shmat(res, shmid, shmaddr, shmflg) \ + __sanitizer_syscall_post_impl_shmat( \ + res, (long long)(shmid), (long long)(shmaddr), (long long)(shmflg)) +#define __sanitizer_syscall_pre_compat_14_shmctl(shmid, cmd, buf) \ + __sanitizer_syscall_pre_impl_compat_14_shmctl( \ + (long long)(shmid), (long long)(cmd), (long long)(buf)) +#define __sanitizer_syscall_post_compat_14_shmctl(res, shmid, cmd, buf) \ + __sanitizer_syscall_post_impl_compat_14_shmctl( \ + res, (long long)(shmid), (long long)(cmd), (long long)(buf)) +#define __sanitizer_syscall_pre_shmdt(shmaddr) \ + __sanitizer_syscall_pre_impl_shmdt((long long)(shmaddr)) +#define __sanitizer_syscall_post_shmdt(res, shmaddr) \ + __sanitizer_syscall_post_impl_shmdt(res, (long long)(shmaddr)) +#define __sanitizer_syscall_pre_shmget(key, size, shmflg) \ + __sanitizer_syscall_pre_impl_shmget((long long)(key), (long long)(size), \ + (long long)(shmflg)) +#define __sanitizer_syscall_post_shmget(res, key, size, shmflg) \ + __sanitizer_syscall_post_impl_shmget(res, (long long)(key), \ + (long long)(size), (long long)(shmflg)) +#define __sanitizer_syscall_pre_compat_50_clock_gettime(clock_id, tp) \ + __sanitizer_syscall_pre_impl_compat_50_clock_gettime((long long)(clock_id), \ + (long long)(tp)) +#define __sanitizer_syscall_post_compat_50_clock_gettime(res, clock_id, tp) \ + __sanitizer_syscall_post_impl_compat_50_clock_gettime( \ + res, (long long)(clock_id), (long long)(tp)) +#define __sanitizer_syscall_pre_compat_50_clock_settime(clock_id, tp) \ + __sanitizer_syscall_pre_impl_compat_50_clock_settime((long long)(clock_id), \ + (long long)(tp)) +#define __sanitizer_syscall_post_compat_50_clock_settime(res, clock_id, tp) \ + __sanitizer_syscall_post_impl_compat_50_clock_settime( \ + res, (long long)(clock_id), (long long)(tp)) +#define __sanitizer_syscall_pre_compat_50_clock_getres(clock_id, tp) \ + __sanitizer_syscall_pre_impl_compat_50_clock_getres((long long)(clock_id), \ + (long long)(tp)) +#define __sanitizer_syscall_post_compat_50_clock_getres(res, clock_id, tp) \ + __sanitizer_syscall_post_impl_compat_50_clock_getres( \ + res, (long long)(clock_id), (long long)(tp)) +#define __sanitizer_syscall_pre_timer_create(clock_id, evp, timerid) \ + __sanitizer_syscall_pre_impl_timer_create( \ + (long long)(clock_id), (long long)(evp), (long long)(timerid)) +#define __sanitizer_syscall_post_timer_create(res, clock_id, evp, timerid) \ + __sanitizer_syscall_post_impl_timer_create( \ + res, (long long)(clock_id), (long long)(evp), (long long)(timerid)) +#define __sanitizer_syscall_pre_timer_delete(timerid) \ + __sanitizer_syscall_pre_impl_timer_delete((long long)(timerid)) +#define __sanitizer_syscall_post_timer_delete(res, timerid) \ + __sanitizer_syscall_post_impl_timer_delete(res, (long long)(timerid)) +#define __sanitizer_syscall_pre_compat_50_timer_settime(timerid, flags, value, \ + ovalue) \ + __sanitizer_syscall_pre_impl_compat_50_timer_settime( \ + (long long)(timerid), (long long)(flags), (long long)(value), \ + (long long)(ovalue)) +#define __sanitizer_syscall_post_compat_50_timer_settime(res, timerid, flags, \ + value, ovalue) \ + __sanitizer_syscall_post_impl_compat_50_timer_settime( \ + res, (long long)(timerid), (long long)(flags), (long long)(value), \ + (long long)(ovalue)) +#define __sanitizer_syscall_pre_compat_50_timer_gettime(timerid, value) \ + __sanitizer_syscall_pre_impl_compat_50_timer_gettime((long long)(timerid), \ + (long long)(value)) +#define __sanitizer_syscall_post_compat_50_timer_gettime(res, timerid, value) \ + __sanitizer_syscall_post_impl_compat_50_timer_gettime( \ + res, (long long)(timerid), (long long)(value)) +#define __sanitizer_syscall_pre_timer_getoverrun(timerid) \ + __sanitizer_syscall_pre_impl_timer_getoverrun((long long)(timerid)) +#define __sanitizer_syscall_post_timer_getoverrun(res, timerid) \ + __sanitizer_syscall_post_impl_timer_getoverrun(res, (long long)(timerid)) +#define __sanitizer_syscall_pre_compat_50_nanosleep(rqtp, rmtp) \ + __sanitizer_syscall_pre_impl_compat_50_nanosleep((long long)(rqtp), \ + (long long)(rmtp)) +#define __sanitizer_syscall_post_compat_50_nanosleep(res, rqtp, rmtp) \ + __sanitizer_syscall_post_impl_compat_50_nanosleep(res, (long long)(rqtp), \ + (long long)(rmtp)) +#define __sanitizer_syscall_pre_fdatasync(fd) \ + __sanitizer_syscall_pre_impl_fdatasync((long long)(fd)) +#define __sanitizer_syscall_post_fdatasync(res, fd) \ + __sanitizer_syscall_post_impl_fdatasync(res, (long long)(fd)) +#define __sanitizer_syscall_pre_mlockall(flags) \ + __sanitizer_syscall_pre_impl_mlockall((long long)(flags)) +#define __sanitizer_syscall_post_mlockall(res, flags) \ + __sanitizer_syscall_post_impl_mlockall(res, (long long)(flags)) +#define __sanitizer_syscall_pre_munlockall() \ + __sanitizer_syscall_pre_impl_munlockall() +#define __sanitizer_syscall_post_munlockall(res) \ + __sanitizer_syscall_post_impl_munlockall(res) +#define __sanitizer_syscall_pre_compat_50___sigtimedwait(set, info, timeout) \ + __sanitizer_syscall_pre_impl_compat_50___sigtimedwait( \ + (long long)(set), (long long)(info), (long long)(timeout)) +#define __sanitizer_syscall_post_compat_50___sigtimedwait(res, set, info, \ + timeout) \ + __sanitizer_syscall_post_impl_compat_50___sigtimedwait( \ + res, (long long)(set), (long long)(info), (long long)(timeout)) +#define __sanitizer_syscall_pre_sigqueueinfo(pid, info) \ + __sanitizer_syscall_pre_impl_sigqueueinfo((long long)(pid), (long long)(info)) +#define __sanitizer_syscall_post_sigqueueinfo(res, pid, info) \ + __sanitizer_syscall_post_impl_sigqueueinfo(res, (long long)(pid), \ + (long long)(info)) +#define __sanitizer_syscall_pre_modctl(cmd, arg) \ + __sanitizer_syscall_pre_impl_modctl((long long)(cmd), (long long)(arg)) +#define __sanitizer_syscall_post_modctl(res, cmd, arg) \ + __sanitizer_syscall_post_impl_modctl(res, (long long)(cmd), (long long)(arg)) +#define __sanitizer_syscall_pre__ksem_init(value, idp) \ + __sanitizer_syscall_pre_impl__ksem_init((long long)(value), (long long)(idp)) +#define __sanitizer_syscall_post__ksem_init(res, value, idp) \ + __sanitizer_syscall_post_impl__ksem_init(res, (long long)(value), \ + (long long)(idp)) +#define __sanitizer_syscall_pre__ksem_open(name, oflag, mode, value, idp) \ + __sanitizer_syscall_pre_impl__ksem_open( \ + (long long)(name), (long long)(oflag), (long long)(mode), \ + (long long)(value), (long long)(idp)) +#define __sanitizer_syscall_post__ksem_open(res, name, oflag, mode, value, \ + idp) \ + __sanitizer_syscall_post_impl__ksem_open( \ + res, (long long)(name), (long long)(oflag), (long long)(mode), \ + (long long)(value), (long long)(idp)) +#define __sanitizer_syscall_pre__ksem_unlink(name) \ + __sanitizer_syscall_pre_impl__ksem_unlink((long long)(name)) +#define __sanitizer_syscall_post__ksem_unlink(res, name) \ + __sanitizer_syscall_post_impl__ksem_unlink(res, (long long)(name)) +#define __sanitizer_syscall_pre__ksem_close(id) \ + __sanitizer_syscall_pre_impl__ksem_close((long long)(id)) +#define __sanitizer_syscall_post__ksem_close(res, id) \ + __sanitizer_syscall_post_impl__ksem_close(res, (long long)(id)) +#define __sanitizer_syscall_pre__ksem_post(id) \ + __sanitizer_syscall_pre_impl__ksem_post((long long)(id)) +#define __sanitizer_syscall_post__ksem_post(res, id) \ + __sanitizer_syscall_post_impl__ksem_post(res, (long long)(id)) +#define __sanitizer_syscall_pre__ksem_wait(id) \ + __sanitizer_syscall_pre_impl__ksem_wait((long long)(id)) +#define __sanitizer_syscall_post__ksem_wait(res, id) \ + __sanitizer_syscall_post_impl__ksem_wait(res, (long long)(id)) +#define __sanitizer_syscall_pre__ksem_trywait(id) \ + __sanitizer_syscall_pre_impl__ksem_trywait((long long)(id)) +#define __sanitizer_syscall_post__ksem_trywait(res, id) \ + __sanitizer_syscall_post_impl__ksem_trywait(res, (long long)(id)) +#define __sanitizer_syscall_pre__ksem_getvalue(id, value) \ + __sanitizer_syscall_pre_impl__ksem_getvalue((long long)(id), \ + (long long)(value)) +#define __sanitizer_syscall_post__ksem_getvalue(res, id, value) \ + __sanitizer_syscall_post_impl__ksem_getvalue(res, (long long)(id), \ + (long long)(value)) +#define __sanitizer_syscall_pre__ksem_destroy(id) \ + __sanitizer_syscall_pre_impl__ksem_destroy((long long)(id)) +#define __sanitizer_syscall_post__ksem_destroy(res, id) \ + __sanitizer_syscall_post_impl__ksem_destroy(res, (long long)(id)) +#define __sanitizer_syscall_pre__ksem_timedwait(id, abstime) \ + __sanitizer_syscall_pre_impl__ksem_timedwait((long long)(id), \ + (long long)(abstime)) +#define __sanitizer_syscall_post__ksem_timedwait(res, id, abstime) \ + __sanitizer_syscall_post_impl__ksem_timedwait(res, (long long)(id), \ + (long long)(abstime)) +#define __sanitizer_syscall_pre_mq_open(name, oflag, mode, attr) \ + __sanitizer_syscall_pre_impl_mq_open((long long)(name), (long long)(oflag), \ + (long long)(mode), (long long)(attr)) +#define __sanitizer_syscall_post_mq_open(res, name, oflag, mode, attr) \ + __sanitizer_syscall_post_impl_mq_open(res, (long long)(name), \ + (long long)(oflag), (long long)(mode), \ + (long long)(attr)) +#define __sanitizer_syscall_pre_mq_close(mqdes) \ + __sanitizer_syscall_pre_impl_mq_close((long long)(mqdes)) +#define __sanitizer_syscall_post_mq_close(res, mqdes) \ + __sanitizer_syscall_post_impl_mq_close(res, (long long)(mqdes)) +#define __sanitizer_syscall_pre_mq_unlink(name) \ + __sanitizer_syscall_pre_impl_mq_unlink((long long)(name)) +#define __sanitizer_syscall_post_mq_unlink(res, name) \ + __sanitizer_syscall_post_impl_mq_unlink(res, (long long)(name)) +#define __sanitizer_syscall_pre_mq_getattr(mqdes, mqstat) \ + __sanitizer_syscall_pre_impl_mq_getattr((long long)(mqdes), \ + (long long)(mqstat)) +#define __sanitizer_syscall_post_mq_getattr(res, mqdes, mqstat) \ + __sanitizer_syscall_post_impl_mq_getattr(res, (long long)(mqdes), \ + (long long)(mqstat)) +#define __sanitizer_syscall_pre_mq_setattr(mqdes, mqstat, omqstat) \ + __sanitizer_syscall_pre_impl_mq_setattr( \ + (long long)(mqdes), (long long)(mqstat), (long long)(omqstat)) +#define __sanitizer_syscall_post_mq_setattr(res, mqdes, mqstat, omqstat) \ + __sanitizer_syscall_post_impl_mq_setattr( \ + res, (long long)(mqdes), (long long)(mqstat), (long long)(omqstat)) +#define __sanitizer_syscall_pre_mq_notify(mqdes, notification) \ + __sanitizer_syscall_pre_impl_mq_notify((long long)(mqdes), \ + (long long)(notification)) +#define __sanitizer_syscall_post_mq_notify(res, mqdes, notification) \ + __sanitizer_syscall_post_impl_mq_notify(res, (long long)(mqdes), \ + (long long)(notification)) +#define __sanitizer_syscall_pre_mq_send(mqdes, msg_ptr, msg_len, msg_prio) \ + __sanitizer_syscall_pre_impl_mq_send( \ + (long long)(mqdes), (long long)(msg_ptr), (long long)(msg_len), \ + (long long)(msg_prio)) +#define __sanitizer_syscall_post_mq_send(res, mqdes, msg_ptr, msg_len, \ + msg_prio) \ + __sanitizer_syscall_post_impl_mq_send( \ + res, (long long)(mqdes), (long long)(msg_ptr), (long long)(msg_len), \ + (long long)(msg_prio)) +#define __sanitizer_syscall_pre_mq_receive(mqdes, msg_ptr, msg_len, msg_prio) \ + __sanitizer_syscall_pre_impl_mq_receive( \ + (long long)(mqdes), (long long)(msg_ptr), (long long)(msg_len), \ + (long long)(msg_prio)) +#define __sanitizer_syscall_post_mq_receive(res, mqdes, msg_ptr, msg_len, \ + msg_prio) \ + __sanitizer_syscall_post_impl_mq_receive( \ + res, (long long)(mqdes), (long long)(msg_ptr), (long long)(msg_len), \ + (long long)(msg_prio)) +#define __sanitizer_syscall_pre_compat_50_mq_timedsend( \ + mqdes, msg_ptr, msg_len, msg_prio, abs_timeout) \ + __sanitizer_syscall_pre_impl_compat_50_mq_timedsend( \ + (long long)(mqdes), (long long)(msg_ptr), (long long)(msg_len), \ + (long long)(msg_prio), (long long)(abs_timeout)) +#define __sanitizer_syscall_post_compat_50_mq_timedsend( \ + res, mqdes, msg_ptr, msg_len, msg_prio, abs_timeout) \ + __sanitizer_syscall_post_impl_compat_50_mq_timedsend( \ + res, (long long)(mqdes), (long long)(msg_ptr), (long long)(msg_len), \ + (long long)(msg_prio), (long long)(abs_timeout)) +#define __sanitizer_syscall_pre_compat_50_mq_timedreceive( \ + mqdes, msg_ptr, msg_len, msg_prio, abs_timeout) \ + __sanitizer_syscall_pre_impl_compat_50_mq_timedreceive( \ + (long long)(mqdes), (long long)(msg_ptr), (long long)(msg_len), \ + (long long)(msg_prio), (long long)(abs_timeout)) +#define __sanitizer_syscall_post_compat_50_mq_timedreceive( \ + res, mqdes, msg_ptr, msg_len, msg_prio, abs_timeout) \ + __sanitizer_syscall_post_impl_compat_50_mq_timedreceive( \ + res, (long long)(mqdes), (long long)(msg_ptr), (long long)(msg_len), \ + (long long)(msg_prio), (long long)(abs_timeout)) +/* syscall 267 has been skipped */ +/* syscall 268 has been skipped */ +/* syscall 269 has been skipped */ +#define __sanitizer_syscall_pre___posix_rename(from, to) \ + __sanitizer_syscall_pre_impl___posix_rename((long long)(from), \ + (long long)(to)) +#define __sanitizer_syscall_post___posix_rename(res, from, to) \ + __sanitizer_syscall_post_impl___posix_rename(res, (long long)(from), \ + (long long)(to)) +#define __sanitizer_syscall_pre_swapctl(cmd, arg, misc) \ + __sanitizer_syscall_pre_impl_swapctl((long long)(cmd), (long long)(arg), \ + (long long)(misc)) +#define __sanitizer_syscall_post_swapctl(res, cmd, arg, misc) \ + __sanitizer_syscall_post_impl_swapctl(res, (long long)(cmd), \ + (long long)(arg), (long long)(misc)) +#define __sanitizer_syscall_pre_compat_30_getdents(fd, buf, count) \ + __sanitizer_syscall_pre_impl_compat_30_getdents( \ + (long long)(fd), (long long)(buf), (long long)(count)) +#define __sanitizer_syscall_post_compat_30_getdents(res, fd, buf, count) \ + __sanitizer_syscall_post_impl_compat_30_getdents( \ + res, (long long)(fd), (long long)(buf), (long long)(count)) +#define __sanitizer_syscall_pre_minherit(addr, len, inherit) \ + __sanitizer_syscall_pre_impl_minherit((long long)(addr), (long long)(len), \ + (long long)(inherit)) +#define __sanitizer_syscall_post_minherit(res, addr, len, inherit) \ + __sanitizer_syscall_post_impl_minherit( \ + res, (long long)(addr), (long long)(len), (long long)(inherit)) +#define __sanitizer_syscall_pre_lchmod(path, mode) \ + __sanitizer_syscall_pre_impl_lchmod((long long)(path), (long long)(mode)) +#define __sanitizer_syscall_post_lchmod(res, path, mode) \ + __sanitizer_syscall_post_impl_lchmod(res, (long long)(path), \ + (long long)(mode)) +#define __sanitizer_syscall_pre_lchown(path, uid, gid) \ + __sanitizer_syscall_pre_impl_lchown((long long)(path), (long long)(uid), \ + (long long)(gid)) +#define __sanitizer_syscall_post_lchown(res, path, uid, gid) \ + __sanitizer_syscall_post_impl_lchown(res, (long long)(path), \ + (long long)(uid), (long long)(gid)) +#define __sanitizer_syscall_pre_compat_50_lutimes(path, tptr) \ + __sanitizer_syscall_pre_impl_compat_50_lutimes((long long)(path), \ + (long long)(tptr)) +#define __sanitizer_syscall_post_compat_50_lutimes(res, path, tptr) \ + __sanitizer_syscall_post_impl_compat_50_lutimes(res, (long long)(path), \ + (long long)(tptr)) +#define __sanitizer_syscall_pre___msync13(addr, len, flags) \ + __sanitizer_syscall_pre_impl___msync13((long long)(addr), (long long)(len), \ + (long long)(flags)) +#define __sanitizer_syscall_post___msync13(res, addr, len, flags) \ + __sanitizer_syscall_post_impl___msync13( \ + res, (long long)(addr), (long long)(len), (long long)(flags)) +#define __sanitizer_syscall_pre_compat_30___stat13(path, ub) \ + __sanitizer_syscall_pre_impl_compat_30___stat13((long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_post_compat_30___stat13(res, path, ub) \ + __sanitizer_syscall_post_impl_compat_30___stat13(res, (long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_pre_compat_30___fstat13(fd, sb) \ + __sanitizer_syscall_pre_impl_compat_30___fstat13((long long)(fd), \ + (long long)(sb)) +#define __sanitizer_syscall_post_compat_30___fstat13(res, fd, sb) \ + __sanitizer_syscall_post_impl_compat_30___fstat13(res, (long long)(fd), \ + (long long)(sb)) +#define __sanitizer_syscall_pre_compat_30___lstat13(path, ub) \ + __sanitizer_syscall_pre_impl_compat_30___lstat13((long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_post_compat_30___lstat13(res, path, ub) \ + __sanitizer_syscall_post_impl_compat_30___lstat13(res, (long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_pre___sigaltstack14(nss, oss) \ + __sanitizer_syscall_pre_impl___sigaltstack14((long long)(nss), \ + (long long)(oss)) +#define __sanitizer_syscall_post___sigaltstack14(res, nss, oss) \ + __sanitizer_syscall_post_impl___sigaltstack14(res, (long long)(nss), \ + (long long)(oss)) +#define __sanitizer_syscall_pre___vfork14() \ + __sanitizer_syscall_pre_impl___vfork14() +#define __sanitizer_syscall_post___vfork14(res) \ + __sanitizer_syscall_post_impl___vfork14(res) +#define __sanitizer_syscall_pre___posix_chown(path, uid, gid) \ + __sanitizer_syscall_pre_impl___posix_chown( \ + (long long)(path), (long long)(uid), (long long)(gid)) +#define __sanitizer_syscall_post___posix_chown(res, path, uid, gid) \ + __sanitizer_syscall_post_impl___posix_chown( \ + res, (long long)(path), (long long)(uid), (long long)(gid)) +#define __sanitizer_syscall_pre___posix_fchown(fd, uid, gid) \ + __sanitizer_syscall_pre_impl___posix_fchown( \ + (long long)(fd), (long long)(uid), (long long)(gid)) +#define __sanitizer_syscall_post___posix_fchown(res, fd, uid, gid) \ + __sanitizer_syscall_post_impl___posix_fchown( \ + res, (long long)(fd), (long long)(uid), (long long)(gid)) +#define __sanitizer_syscall_pre___posix_lchown(path, uid, gid) \ + __sanitizer_syscall_pre_impl___posix_lchown( \ + (long long)(path), (long long)(uid), (long long)(gid)) +#define __sanitizer_syscall_post___posix_lchown(res, path, uid, gid) \ + __sanitizer_syscall_post_impl___posix_lchown( \ + res, (long long)(path), (long long)(uid), (long long)(gid)) +#define __sanitizer_syscall_pre_getsid(pid) \ + __sanitizer_syscall_pre_impl_getsid((long long)(pid)) +#define __sanitizer_syscall_post_getsid(res, pid) \ + __sanitizer_syscall_post_impl_getsid(res, (long long)(pid)) +#define __sanitizer_syscall_pre___clone(flags, stack) \ + __sanitizer_syscall_pre_impl___clone((long long)(flags), (long long)(stack)) +#define __sanitizer_syscall_post___clone(res, flags, stack) \ + __sanitizer_syscall_post_impl___clone(res, (long long)(flags), \ + (long long)(stack)) +#define __sanitizer_syscall_pre_fktrace(fd, ops, facs, pid) \ + __sanitizer_syscall_pre_impl_fktrace((long long)(fd), (long long)(ops), \ + (long long)(facs), (long long)(pid)) +#define __sanitizer_syscall_post_fktrace(res, fd, ops, facs, pid) \ + __sanitizer_syscall_post_impl_fktrace(res, (long long)(fd), \ + (long long)(ops), (long long)(facs), \ + (long long)(pid)) +#define __sanitizer_syscall_pre_preadv(fd, iovp, iovcnt, PAD, offset) \ + __sanitizer_syscall_pre_impl_preadv((long long)(fd), (long long)(iovp), \ + (long long)(iovcnt), (long long)(PAD), \ + (long long)(offset)) +#define __sanitizer_syscall_post_preadv(res, fd, iovp, iovcnt, PAD, offset) \ + __sanitizer_syscall_post_impl_preadv(res, (long long)(fd), \ + (long long)(iovp), (long long)(iovcnt), \ + (long long)(PAD), (long long)(offset)) +#define __sanitizer_syscall_pre_pwritev(fd, iovp, iovcnt, PAD, offset) \ + __sanitizer_syscall_pre_impl_pwritev((long long)(fd), (long long)(iovp), \ + (long long)(iovcnt), (long long)(PAD), \ + (long long)(offset)) +#define __sanitizer_syscall_post_pwritev(res, fd, iovp, iovcnt, PAD, offset) \ + __sanitizer_syscall_post_impl_pwritev( \ + res, (long long)(fd), (long long)(iovp), (long long)(iovcnt), \ + (long long)(PAD), (long long)(offset)) +#define __sanitizer_syscall_pre_compat_16___sigaction14(signum, nsa, osa) \ + __sanitizer_syscall_pre_impl_compat_16___sigaction14( \ + (long long)(signum), (long long)(nsa), (long long)(osa)) +#define __sanitizer_syscall_post_compat_16___sigaction14(res, signum, nsa, \ + osa) \ + __sanitizer_syscall_post_impl_compat_16___sigaction14( \ + res, (long long)(signum), (long long)(nsa), (long long)(osa)) +#define __sanitizer_syscall_pre___sigpending14(set) \ + __sanitizer_syscall_pre_impl___sigpending14((long long)(set)) +#define __sanitizer_syscall_post___sigpending14(res, set) \ + __sanitizer_syscall_post_impl___sigpending14(res, (long long)(set)) +#define __sanitizer_syscall_pre___sigprocmask14(how, set, oset) \ + __sanitizer_syscall_pre_impl___sigprocmask14( \ + (long long)(how), (long long)(set), (long long)(oset)) +#define __sanitizer_syscall_post___sigprocmask14(res, how, set, oset) \ + __sanitizer_syscall_post_impl___sigprocmask14( \ + res, (long long)(how), (long long)(set), (long long)(oset)) +#define __sanitizer_syscall_pre___sigsuspend14(set) \ + __sanitizer_syscall_pre_impl___sigsuspend14((long long)(set)) +#define __sanitizer_syscall_post___sigsuspend14(res, set) \ + __sanitizer_syscall_post_impl___sigsuspend14(res, (long long)(set)) +#define __sanitizer_syscall_pre_compat_16___sigreturn14(sigcntxp) \ + __sanitizer_syscall_pre_impl_compat_16___sigreturn14((long long)(sigcntxp)) +#define __sanitizer_syscall_post_compat_16___sigreturn14(res, sigcntxp) \ + __sanitizer_syscall_post_impl_compat_16___sigreturn14(res, \ + (long long)(sigcntxp)) +#define __sanitizer_syscall_pre___getcwd(bufp, length) \ + __sanitizer_syscall_pre_impl___getcwd((long long)(bufp), (long long)(length)) +#define __sanitizer_syscall_post___getcwd(res, bufp, length) \ + __sanitizer_syscall_post_impl___getcwd(res, (long long)(bufp), \ + (long long)(length)) +#define __sanitizer_syscall_pre_fchroot(fd) \ + __sanitizer_syscall_pre_impl_fchroot((long long)(fd)) +#define __sanitizer_syscall_post_fchroot(res, fd) \ + __sanitizer_syscall_post_impl_fchroot(res, (long long)(fd)) +#define __sanitizer_syscall_pre_compat_30_fhopen(fhp, flags) \ + __sanitizer_syscall_pre_impl_compat_30_fhopen((long long)(fhp), \ + (long long)(flags)) +#define __sanitizer_syscall_post_compat_30_fhopen(res, fhp, flags) \ + __sanitizer_syscall_post_impl_compat_30_fhopen(res, (long long)(fhp), \ + (long long)(flags)) +#define __sanitizer_syscall_pre_compat_30_fhstat(fhp, sb) \ + __sanitizer_syscall_pre_impl_compat_30_fhstat((long long)(fhp), \ + (long long)(sb)) +#define __sanitizer_syscall_post_compat_30_fhstat(res, fhp, sb) \ + __sanitizer_syscall_post_impl_compat_30_fhstat(res, (long long)(fhp), \ + (long long)(sb)) +#define __sanitizer_syscall_pre_compat_20_fhstatfs(fhp, buf) \ + __sanitizer_syscall_pre_impl_compat_20_fhstatfs((long long)(fhp), \ + (long long)(buf)) +#define __sanitizer_syscall_post_compat_20_fhstatfs(res, fhp, buf) \ + __sanitizer_syscall_post_impl_compat_20_fhstatfs(res, (long long)(fhp), \ + (long long)(buf)) +#define __sanitizer_syscall_pre_compat_50_____semctl13(semid, semnum, cmd, \ + arg) \ + __sanitizer_syscall_pre_impl_compat_50_____semctl13( \ + (long long)(semid), (long long)(semnum), (long long)(cmd), \ + (long long)(arg)) +#define __sanitizer_syscall_post_compat_50_____semctl13(res, semid, semnum, \ + cmd, arg) \ + __sanitizer_syscall_post_impl_compat_50_____semctl13( \ + res, (long long)(semid), (long long)(semnum), (long long)(cmd), \ + (long long)(arg)) +#define __sanitizer_syscall_pre_compat_50___msgctl13(msqid, cmd, buf) \ + __sanitizer_syscall_pre_impl_compat_50___msgctl13( \ + (long long)(msqid), (long long)(cmd), (long long)(buf)) +#define __sanitizer_syscall_post_compat_50___msgctl13(res, msqid, cmd, buf) \ + __sanitizer_syscall_post_impl_compat_50___msgctl13( \ + res, (long long)(msqid), (long long)(cmd), (long long)(buf)) +#define __sanitizer_syscall_pre_compat_50___shmctl13(shmid, cmd, buf) \ + __sanitizer_syscall_pre_impl_compat_50___shmctl13( \ + (long long)(shmid), (long long)(cmd), (long long)(buf)) +#define __sanitizer_syscall_post_compat_50___shmctl13(res, shmid, cmd, buf) \ + __sanitizer_syscall_post_impl_compat_50___shmctl13( \ + res, (long long)(shmid), (long long)(cmd), (long long)(buf)) +#define __sanitizer_syscall_pre_lchflags(path, flags) \ + __sanitizer_syscall_pre_impl_lchflags((long long)(path), (long long)(flags)) +#define __sanitizer_syscall_post_lchflags(res, path, flags) \ + __sanitizer_syscall_post_impl_lchflags(res, (long long)(path), \ + (long long)(flags)) +#define __sanitizer_syscall_pre_issetugid() \ + __sanitizer_syscall_pre_impl_issetugid() +#define __sanitizer_syscall_post_issetugid(res) \ + __sanitizer_syscall_post_impl_issetugid(res) +#define __sanitizer_syscall_pre_utrace(label, addr, len) \ + __sanitizer_syscall_pre_impl_utrace((long long)(label), (long long)(addr), \ + (long long)(len)) +#define __sanitizer_syscall_post_utrace(res, label, addr, len) \ + __sanitizer_syscall_post_impl_utrace(res, (long long)(label), \ + (long long)(addr), (long long)(len)) +#define __sanitizer_syscall_pre_getcontext(ucp) \ + __sanitizer_syscall_pre_impl_getcontext((long long)(ucp)) +#define __sanitizer_syscall_post_getcontext(res, ucp) \ + __sanitizer_syscall_post_impl_getcontext(res, (long long)(ucp)) +#define __sanitizer_syscall_pre_setcontext(ucp) \ + __sanitizer_syscall_pre_impl_setcontext((long long)(ucp)) +#define __sanitizer_syscall_post_setcontext(res, ucp) \ + __sanitizer_syscall_post_impl_setcontext(res, (long long)(ucp)) +#define __sanitizer_syscall_pre__lwp_create(ucp, flags, new_lwp) \ + __sanitizer_syscall_pre_impl__lwp_create( \ + (long long)(ucp), (long long)(flags), (long long)(new_lwp)) +#define __sanitizer_syscall_post__lwp_create(res, ucp, flags, new_lwp) \ + __sanitizer_syscall_post_impl__lwp_create( \ + res, (long long)(ucp), (long long)(flags), (long long)(new_lwp)) +#define __sanitizer_syscall_pre__lwp_exit() \ + __sanitizer_syscall_pre_impl__lwp_exit() +#define __sanitizer_syscall_post__lwp_exit(res) \ + __sanitizer_syscall_post_impl__lwp_exit(res) +#define __sanitizer_syscall_pre__lwp_self() \ + __sanitizer_syscall_pre_impl__lwp_self() +#define __sanitizer_syscall_post__lwp_self(res) \ + __sanitizer_syscall_post_impl__lwp_self(res) +#define __sanitizer_syscall_pre__lwp_wait(wait_for, departed) \ + __sanitizer_syscall_pre_impl__lwp_wait((long long)(wait_for), \ + (long long)(departed)) +#define __sanitizer_syscall_post__lwp_wait(res, wait_for, departed) \ + __sanitizer_syscall_post_impl__lwp_wait(res, (long long)(wait_for), \ + (long long)(departed)) +#define __sanitizer_syscall_pre__lwp_suspend(target) \ + __sanitizer_syscall_pre_impl__lwp_suspend((long long)(target)) +#define __sanitizer_syscall_post__lwp_suspend(res, target) \ + __sanitizer_syscall_post_impl__lwp_suspend(res, (long long)(target)) +#define __sanitizer_syscall_pre__lwp_continue(target) \ + __sanitizer_syscall_pre_impl__lwp_continue((long long)(target)) +#define __sanitizer_syscall_post__lwp_continue(res, target) \ + __sanitizer_syscall_post_impl__lwp_continue(res, (long long)(target)) +#define __sanitizer_syscall_pre__lwp_wakeup(target) \ + __sanitizer_syscall_pre_impl__lwp_wakeup((long long)(target)) +#define __sanitizer_syscall_post__lwp_wakeup(res, target) \ + __sanitizer_syscall_post_impl__lwp_wakeup(res, (long long)(target)) +#define __sanitizer_syscall_pre__lwp_getprivate() \ + __sanitizer_syscall_pre_impl__lwp_getprivate() +#define __sanitizer_syscall_post__lwp_getprivate(res) \ + __sanitizer_syscall_post_impl__lwp_getprivate(res) +#define __sanitizer_syscall_pre__lwp_setprivate(ptr) \ + __sanitizer_syscall_pre_impl__lwp_setprivate((long long)(ptr)) +#define __sanitizer_syscall_post__lwp_setprivate(res, ptr) \ + __sanitizer_syscall_post_impl__lwp_setprivate(res, (long long)(ptr)) +#define __sanitizer_syscall_pre__lwp_kill(target, signo) \ + __sanitizer_syscall_pre_impl__lwp_kill((long long)(target), \ + (long long)(signo)) +#define __sanitizer_syscall_post__lwp_kill(res, target, signo) \ + __sanitizer_syscall_post_impl__lwp_kill(res, (long long)(target), \ + (long long)(signo)) +#define __sanitizer_syscall_pre__lwp_detach(target) \ + __sanitizer_syscall_pre_impl__lwp_detach((long long)(target)) +#define __sanitizer_syscall_post__lwp_detach(res, target) \ + __sanitizer_syscall_post_impl__lwp_detach(res, (long long)(target)) +#define __sanitizer_syscall_pre_compat_50__lwp_park(ts, unpark, hint, \ + unparkhint) \ + __sanitizer_syscall_pre_impl_compat_50__lwp_park( \ + (long long)(ts), (long long)(unpark), (long long)(hint), \ + (long long)(unparkhint)) +#define __sanitizer_syscall_post_compat_50__lwp_park(res, ts, unpark, hint, \ + unparkhint) \ + __sanitizer_syscall_post_impl_compat_50__lwp_park( \ + res, (long long)(ts), (long long)(unpark), (long long)(hint), \ + (long long)(unparkhint)) +#define __sanitizer_syscall_pre__lwp_unpark(target, hint) \ + __sanitizer_syscall_pre_impl__lwp_unpark((long long)(target), \ + (long long)(hint)) +#define __sanitizer_syscall_post__lwp_unpark(res, target, hint) \ + __sanitizer_syscall_post_impl__lwp_unpark(res, (long long)(target), \ + (long long)(hint)) +#define __sanitizer_syscall_pre__lwp_unpark_all(targets, ntargets, hint) \ + __sanitizer_syscall_pre_impl__lwp_unpark_all( \ + (long long)(targets), (long long)(ntargets), (long long)(hint)) +#define __sanitizer_syscall_post__lwp_unpark_all(res, targets, ntargets, hint) \ + __sanitizer_syscall_post_impl__lwp_unpark_all( \ + res, (long long)(targets), (long long)(ntargets), (long long)(hint)) +#define __sanitizer_syscall_pre__lwp_setname(target, name) \ + __sanitizer_syscall_pre_impl__lwp_setname((long long)(target), \ + (long long)(name)) +#define __sanitizer_syscall_post__lwp_setname(res, target, name) \ + __sanitizer_syscall_post_impl__lwp_setname(res, (long long)(target), \ + (long long)(name)) +#define __sanitizer_syscall_pre__lwp_getname(target, name, len) \ + __sanitizer_syscall_pre_impl__lwp_getname( \ + (long long)(target), (long long)(name), (long long)(len)) +#define __sanitizer_syscall_post__lwp_getname(res, target, name, len) \ + __sanitizer_syscall_post_impl__lwp_getname( \ + res, (long long)(target), (long long)(name), (long long)(len)) +#define __sanitizer_syscall_pre__lwp_ctl(features, address) \ + __sanitizer_syscall_pre_impl__lwp_ctl((long long)(features), \ + (long long)(address)) +#define __sanitizer_syscall_post__lwp_ctl(res, features, address) \ + __sanitizer_syscall_post_impl__lwp_ctl(res, (long long)(features), \ + (long long)(address)) +/* syscall 326 has been skipped */ +/* syscall 327 has been skipped */ +/* syscall 328 has been skipped */ +/* syscall 329 has been skipped */ +#define __sanitizer_syscall_pre_compat_60_sa_register(newv, oldv, flags, \ + stackinfo_offset) \ + __sanitizer_syscall_pre_impl_compat_60_sa_register( \ + (long long)(newv), (long long)(oldv), (long long)(flags), \ + (long long)(stackinfo_offset)) +#define __sanitizer_syscall_post_compat_60_sa_register(res, newv, oldv, flags, \ + stackinfo_offset) \ + __sanitizer_syscall_post_impl_compat_60_sa_register( \ + res, (long long)(newv), (long long)(oldv), (long long)(flags), \ + (long long)(stackinfo_offset)) +#define __sanitizer_syscall_pre_compat_60_sa_stacks(num, stacks) \ + __sanitizer_syscall_pre_impl_compat_60_sa_stacks((long long)(num), \ + (long long)(stacks)) +#define __sanitizer_syscall_post_compat_60_sa_stacks(res, num, stacks) \ + __sanitizer_syscall_post_impl_compat_60_sa_stacks(res, (long long)(num), \ + (long long)(stacks)) +#define __sanitizer_syscall_pre_compat_60_sa_enable() \ + __sanitizer_syscall_pre_impl_compat_60_sa_enable() +#define __sanitizer_syscall_post_compat_60_sa_enable(res) \ + __sanitizer_syscall_post_impl_compat_60_sa_enable(res) +#define __sanitizer_syscall_pre_compat_60_sa_setconcurrency(concurrency) \ + __sanitizer_syscall_pre_impl_compat_60_sa_setconcurrency( \ + (long long)(concurrency)) +#define __sanitizer_syscall_post_compat_60_sa_setconcurrency(res, concurrency) \ + __sanitizer_syscall_post_impl_compat_60_sa_setconcurrency( \ + res, (long long)(concurrency)) +#define __sanitizer_syscall_pre_compat_60_sa_yield() \ + __sanitizer_syscall_pre_impl_compat_60_sa_yield() +#define __sanitizer_syscall_post_compat_60_sa_yield(res) \ + __sanitizer_syscall_post_impl_compat_60_sa_yield(res) +#define __sanitizer_syscall_pre_compat_60_sa_preempt(sa_id) \ + __sanitizer_syscall_pre_impl_compat_60_sa_preempt((long long)(sa_id)) +#define __sanitizer_syscall_post_compat_60_sa_preempt(res, sa_id) \ + __sanitizer_syscall_post_impl_compat_60_sa_preempt(res, (long long)(sa_id)) +/* syscall 336 has been skipped */ +/* syscall 337 has been skipped */ +/* syscall 338 has been skipped */ +/* syscall 339 has been skipped */ +#define __sanitizer_syscall_pre___sigaction_sigtramp(signum, nsa, osa, tramp, \ + vers) \ + __sanitizer_syscall_pre_impl___sigaction_sigtramp( \ + (long long)(signum), (long long)(nsa), (long long)(osa), \ + (long long)(tramp), (long long)(vers)) +#define __sanitizer_syscall_post___sigaction_sigtramp(res, signum, nsa, osa, \ + tramp, vers) \ + __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)) +#define __sanitizer_syscall_pre_rasctl(addr, len, op) \ + __sanitizer_syscall_pre_impl_rasctl((long long)(addr), (long long)(len), \ + (long long)(op)) +#define __sanitizer_syscall_post_rasctl(res, addr, len, op) \ + __sanitizer_syscall_post_impl_rasctl(res, (long long)(addr), \ + (long long)(len), (long long)(op)) +#define __sanitizer_syscall_pre_kqueue() __sanitizer_syscall_pre_impl_kqueue() +#define __sanitizer_syscall_post_kqueue(res) \ + __sanitizer_syscall_post_impl_kqueue(res) +#define __sanitizer_syscall_pre_compat_50_kevent(fd, changelist, nchanges, \ + eventlist, nevents, timeout) \ + __sanitizer_syscall_pre_impl_compat_50_kevent( \ + (long long)(fd), (long long)(changelist), (long long)(nchanges), \ + (long long)(eventlist), (long long)(nevents), (long long)(timeout)) +#define __sanitizer_syscall_post_compat_50_kevent( \ + res, fd, changelist, nchanges, eventlist, nevents, timeout) \ + __sanitizer_syscall_post_impl_compat_50_kevent( \ + res, (long long)(fd), (long long)(changelist), (long long)(nchanges), \ + (long long)(eventlist), (long long)(nevents), (long long)(timeout)) +#define __sanitizer_syscall_pre__sched_setparam(pid, lid, policy, params) \ + __sanitizer_syscall_pre_impl__sched_setparam( \ + (long long)(pid), (long long)(lid), (long long)(policy), \ + (long long)(params)) +#define __sanitizer_syscall_post__sched_setparam(res, pid, lid, policy, \ + params) \ + __sanitizer_syscall_post_impl__sched_setparam( \ + res, (long long)(pid), (long long)(lid), (long long)(policy), \ + (long long)(params)) +#define __sanitizer_syscall_pre__sched_getparam(pid, lid, policy, params) \ + __sanitizer_syscall_pre_impl__sched_getparam( \ + (long long)(pid), (long long)(lid), (long long)(policy), \ + (long long)(params)) +#define __sanitizer_syscall_post__sched_getparam(res, pid, lid, policy, \ + params) \ + __sanitizer_syscall_post_impl__sched_getparam( \ + res, (long long)(pid), (long long)(lid), (long long)(policy), \ + (long long)(params)) +#define __sanitizer_syscall_pre__sched_setaffinity(pid, lid, size, cpuset) \ + __sanitizer_syscall_pre_impl__sched_setaffinity( \ + (long long)(pid), (long long)(lid), (long long)(size), \ + (long long)(cpuset)) +#define __sanitizer_syscall_post__sched_setaffinity(res, pid, lid, size, \ + cpuset) \ + __sanitizer_syscall_post_impl__sched_setaffinity( \ + res, (long long)(pid), (long long)(lid), (long long)(size), \ + (long long)(cpuset)) +#define __sanitizer_syscall_pre__sched_getaffinity(pid, lid, size, cpuset) \ + __sanitizer_syscall_pre_impl__sched_getaffinity( \ + (long long)(pid), (long long)(lid), (long long)(size), \ + (long long)(cpuset)) +#define __sanitizer_syscall_post__sched_getaffinity(res, pid, lid, size, \ + cpuset) \ + __sanitizer_syscall_post_impl__sched_getaffinity( \ + res, (long long)(pid), (long long)(lid), (long long)(size), \ + (long long)(cpuset)) +#define __sanitizer_syscall_pre_sched_yield() \ + __sanitizer_syscall_pre_impl_sched_yield() +#define __sanitizer_syscall_post_sched_yield(res) \ + __sanitizer_syscall_post_impl_sched_yield(res) +#define __sanitizer_syscall_pre__sched_protect(priority) \ + __sanitizer_syscall_pre_impl__sched_protect((long long)(priority)) +#define __sanitizer_syscall_post__sched_protect(res, priority) \ + __sanitizer_syscall_post_impl__sched_protect(res, (long long)(priority)) +/* syscall 352 has been skipped */ +/* syscall 353 has been skipped */ +#define __sanitizer_syscall_pre_fsync_range(fd, flags, start, length) \ + __sanitizer_syscall_pre_impl_fsync_range( \ + (long long)(fd), (long long)(flags), (long long)(start), \ + (long long)(length)) +#define __sanitizer_syscall_post_fsync_range(res, fd, flags, start, length) \ + __sanitizer_syscall_post_impl_fsync_range( \ + res, (long long)(fd), (long long)(flags), (long long)(start), \ + (long long)(length)) +#define __sanitizer_syscall_pre_uuidgen(store, count) \ + __sanitizer_syscall_pre_impl_uuidgen((long long)(store), (long long)(count)) +#define __sanitizer_syscall_post_uuidgen(res, store, count) \ + __sanitizer_syscall_post_impl_uuidgen(res, (long long)(store), \ + (long long)(count)) +#define __sanitizer_syscall_pre_getvfsstat(buf, bufsize, flags) \ + __sanitizer_syscall_pre_impl_getvfsstat( \ + (long long)(buf), (long long)(bufsize), (long long)(flags)) +#define __sanitizer_syscall_post_getvfsstat(res, buf, bufsize, flags) \ + __sanitizer_syscall_post_impl_getvfsstat( \ + res, (long long)(buf), (long long)(bufsize), (long long)(flags)) +#define __sanitizer_syscall_pre_statvfs1(path, buf, flags) \ + __sanitizer_syscall_pre_impl_statvfs1((long long)(path), (long long)(buf), \ + (long long)(flags)) +#define __sanitizer_syscall_post_statvfs1(res, path, buf, flags) \ + __sanitizer_syscall_post_impl_statvfs1(res, (long long)(path), \ + (long long)(buf), (long long)(flags)) +#define __sanitizer_syscall_pre_fstatvfs1(fd, buf, flags) \ + __sanitizer_syscall_pre_impl_fstatvfs1((long long)(fd), (long long)(buf), \ + (long long)(flags)) +#define __sanitizer_syscall_post_fstatvfs1(res, fd, buf, flags) \ + __sanitizer_syscall_post_impl_fstatvfs1( \ + res, (long long)(fd), (long long)(buf), (long long)(flags)) +#define __sanitizer_syscall_pre_compat_30_fhstatvfs1(fhp, buf, flags) \ + __sanitizer_syscall_pre_impl_compat_30_fhstatvfs1( \ + (long long)(fhp), (long long)(buf), (long long)(flags)) +#define __sanitizer_syscall_post_compat_30_fhstatvfs1(res, fhp, buf, flags) \ + __sanitizer_syscall_post_impl_compat_30_fhstatvfs1( \ + res, (long long)(fhp), (long long)(buf), (long long)(flags)) +#define __sanitizer_syscall_pre_extattrctl(path, cmd, filename, attrnamespace, \ + attrname) \ + __sanitizer_syscall_pre_impl_extattrctl( \ + (long long)(path), (long long)(cmd), (long long)(filename), \ + (long long)(attrnamespace), (long long)(attrname)) +#define __sanitizer_syscall_post_extattrctl(res, path, cmd, filename, \ + attrnamespace, attrname) \ + __sanitizer_syscall_post_impl_extattrctl( \ + res, (long long)(path), (long long)(cmd), (long long)(filename), \ + (long long)(attrnamespace), (long long)(attrname)) +#define __sanitizer_syscall_pre_extattr_set_file(path, attrnamespace, \ + attrname, data, nbytes) \ + __sanitizer_syscall_pre_impl_extattr_set_file( \ + (long long)(path), (long long)(attrnamespace), (long long)(attrname), \ + (long long)(data), (long long)(nbytes)) +#define __sanitizer_syscall_post_extattr_set_file(res, path, attrnamespace, \ + attrname, data, nbytes) \ + __sanitizer_syscall_post_impl_extattr_set_file( \ + res, (long long)(path), (long long)(attrnamespace), \ + (long long)(attrname), (long long)(data), (long long)(nbytes)) +#define __sanitizer_syscall_pre_extattr_get_file(path, attrnamespace, \ + attrname, data, nbytes) \ + __sanitizer_syscall_pre_impl_extattr_get_file( \ + (long long)(path), (long long)(attrnamespace), (long long)(attrname), \ + (long long)(data), (long long)(nbytes)) +#define __sanitizer_syscall_post_extattr_get_file(res, path, attrnamespace, \ + attrname, data, nbytes) \ + __sanitizer_syscall_post_impl_extattr_get_file( \ + res, (long long)(path), (long long)(attrnamespace), \ + (long long)(attrname), (long long)(data), (long long)(nbytes)) +#define __sanitizer_syscall_pre_extattr_delete_file(path, attrnamespace, \ + attrname) \ + __sanitizer_syscall_pre_impl_extattr_delete_file( \ + (long long)(path), (long long)(attrnamespace), (long long)(attrname)) +#define __sanitizer_syscall_post_extattr_delete_file(res, path, attrnamespace, \ + attrname) \ + __sanitizer_syscall_post_impl_extattr_delete_file( \ + res, (long long)(path), (long long)(attrnamespace), \ + (long long)(attrname)) +#define __sanitizer_syscall_pre_extattr_set_fd(fd, attrnamespace, attrname, \ + data, nbytes) \ + __sanitizer_syscall_pre_impl_extattr_set_fd( \ + (long long)(fd), (long long)(attrnamespace), (long long)(attrname), \ + (long long)(data), (long long)(nbytes)) +#define __sanitizer_syscall_post_extattr_set_fd(res, fd, attrnamespace, \ + attrname, data, nbytes) \ + __sanitizer_syscall_post_impl_extattr_set_fd( \ + res, (long long)(fd), (long long)(attrnamespace), (long long)(attrname), \ + (long long)(data), (long long)(nbytes)) +#define __sanitizer_syscall_pre_extattr_get_fd(fd, attrnamespace, attrname, \ + data, nbytes) \ + __sanitizer_syscall_pre_impl_extattr_get_fd( \ + (long long)(fd), (long long)(attrnamespace), (long long)(attrname), \ + (long long)(data), (long long)(nbytes)) +#define __sanitizer_syscall_post_extattr_get_fd(res, fd, attrnamespace, \ + attrname, data, nbytes) \ + __sanitizer_syscall_post_impl_extattr_get_fd( \ + res, (long long)(fd), (long long)(attrnamespace), (long long)(attrname), \ + (long long)(data), (long long)(nbytes)) +#define __sanitizer_syscall_pre_extattr_delete_fd(fd, attrnamespace, attrname) \ + __sanitizer_syscall_pre_impl_extattr_delete_fd( \ + (long long)(fd), (long long)(attrnamespace), (long long)(attrname)) +#define __sanitizer_syscall_post_extattr_delete_fd(res, fd, attrnamespace, \ + attrname) \ + __sanitizer_syscall_post_impl_extattr_delete_fd( \ + res, (long long)(fd), (long long)(attrnamespace), (long long)(attrname)) +#define __sanitizer_syscall_pre_extattr_set_link(path, attrnamespace, \ + attrname, data, nbytes) \ + __sanitizer_syscall_pre_impl_extattr_set_link( \ + (long long)(path), (long long)(attrnamespace), (long long)(attrname), \ + (long long)(data), (long long)(nbytes)) +#define __sanitizer_syscall_post_extattr_set_link(res, path, attrnamespace, \ + attrname, data, nbytes) \ + __sanitizer_syscall_post_impl_extattr_set_link( \ + res, (long long)(path), (long long)(attrnamespace), \ + (long long)(attrname), (long long)(data), (long long)(nbytes)) +#define __sanitizer_syscall_pre_extattr_get_link(path, attrnamespace, \ + attrname, data, nbytes) \ + __sanitizer_syscall_pre_impl_extattr_get_link( \ + (long long)(path), (long long)(attrnamespace), (long long)(attrname), \ + (long long)(data), (long long)(nbytes)) +#define __sanitizer_syscall_post_extattr_get_link(res, path, attrnamespace, \ + attrname, data, nbytes) \ + __sanitizer_syscall_post_impl_extattr_get_link( \ + res, (long long)(path), (long long)(attrnamespace), \ + (long long)(attrname), (long long)(data), (long long)(nbytes)) +#define __sanitizer_syscall_pre_extattr_delete_link(path, attrnamespace, \ + attrname) \ + __sanitizer_syscall_pre_impl_extattr_delete_link( \ + (long long)(path), (long long)(attrnamespace), (long long)(attrname)) +#define __sanitizer_syscall_post_extattr_delete_link(res, path, attrnamespace, \ + attrname) \ + __sanitizer_syscall_post_impl_extattr_delete_link( \ + res, (long long)(path), (long long)(attrnamespace), \ + (long long)(attrname)) +#define __sanitizer_syscall_pre_extattr_list_fd(fd, attrnamespace, data, \ + nbytes) \ + __sanitizer_syscall_pre_impl_extattr_list_fd( \ + (long long)(fd), (long long)(attrnamespace), (long long)(data), \ + (long long)(nbytes)) +#define __sanitizer_syscall_post_extattr_list_fd(res, fd, attrnamespace, data, \ + nbytes) \ + __sanitizer_syscall_post_impl_extattr_list_fd( \ + res, (long long)(fd), (long long)(attrnamespace), (long long)(data), \ + (long long)(nbytes)) +#define __sanitizer_syscall_pre_extattr_list_file(path, attrnamespace, data, \ + nbytes) \ + __sanitizer_syscall_pre_impl_extattr_list_file( \ + (long long)(path), (long long)(attrnamespace), (long long)(data), \ + (long long)(nbytes)) +#define __sanitizer_syscall_post_extattr_list_file(res, path, attrnamespace, \ + data, nbytes) \ + __sanitizer_syscall_post_impl_extattr_list_file( \ + res, (long long)(path), (long long)(attrnamespace), (long long)(data), \ + (long long)(nbytes)) +#define __sanitizer_syscall_pre_extattr_list_link(path, attrnamespace, data, \ + nbytes) \ + __sanitizer_syscall_pre_impl_extattr_list_link( \ + (long long)(path), (long long)(attrnamespace), (long long)(data), \ + (long long)(nbytes)) +#define __sanitizer_syscall_post_extattr_list_link(res, path, attrnamespace, \ + data, nbytes) \ + __sanitizer_syscall_post_impl_extattr_list_link( \ + res, (long long)(path), (long long)(attrnamespace), (long long)(data), \ + (long long)(nbytes)) +#define __sanitizer_syscall_pre_compat_50_pselect(nd, in, ou, ex, ts, mask) \ + __sanitizer_syscall_pre_impl_compat_50_pselect( \ + (long long)(nd), (long long)(in), (long long)(ou), (long long)(ex), \ + (long long)(ts), (long long)(mask)) +#define __sanitizer_syscall_post_compat_50_pselect(res, nd, in, ou, ex, ts, \ + mask) \ + __sanitizer_syscall_post_impl_compat_50_pselect( \ + res, (long long)(nd), (long long)(in), (long long)(ou), (long long)(ex), \ + (long long)(ts), (long long)(mask)) +#define __sanitizer_syscall_pre_compat_50_pollts(fds, nfds, ts, mask) \ + __sanitizer_syscall_pre_impl_compat_50_pollts( \ + (long long)(fds), (long long)(nfds), (long long)(ts), (long long)(mask)) +#define __sanitizer_syscall_post_compat_50_pollts(res, fds, nfds, ts, mask) \ + __sanitizer_syscall_post_impl_compat_50_pollts( \ + res, (long long)(fds), (long long)(nfds), (long long)(ts), \ + (long long)(mask)) +#define __sanitizer_syscall_pre_setxattr(path, name, value, size, flags) \ + __sanitizer_syscall_pre_impl_setxattr((long long)(path), (long long)(name), \ + (long long)(value), (long long)(size), \ + (long long)(flags)) +#define __sanitizer_syscall_post_setxattr(res, path, name, value, size, flags) \ + __sanitizer_syscall_post_impl_setxattr( \ + res, (long long)(path), (long long)(name), (long long)(value), \ + (long long)(size), (long long)(flags)) +#define __sanitizer_syscall_pre_lsetxattr(path, name, value, size, flags) \ + __sanitizer_syscall_pre_impl_lsetxattr( \ + (long long)(path), (long long)(name), (long long)(value), \ + (long long)(size), (long long)(flags)) +#define __sanitizer_syscall_post_lsetxattr(res, path, name, value, size, \ + flags) \ + __sanitizer_syscall_post_impl_lsetxattr( \ + res, (long long)(path), (long long)(name), (long long)(value), \ + (long long)(size), (long long)(flags)) +#define __sanitizer_syscall_pre_fsetxattr(fd, name, value, size, flags) \ + __sanitizer_syscall_pre_impl_fsetxattr( \ + (long long)(fd), (long long)(name), (long long)(value), \ + (long long)(size), (long long)(flags)) +#define __sanitizer_syscall_post_fsetxattr(res, fd, name, value, size, flags) \ + __sanitizer_syscall_post_impl_fsetxattr( \ + res, (long long)(fd), (long long)(name), (long long)(value), \ + (long long)(size), (long long)(flags)) +#define __sanitizer_syscall_pre_getxattr(path, name, value, size) \ + __sanitizer_syscall_pre_impl_getxattr((long long)(path), (long long)(name), \ + (long long)(value), (long long)(size)) +#define __sanitizer_syscall_post_getxattr(res, path, name, value, size) \ + __sanitizer_syscall_post_impl_getxattr( \ + res, (long long)(path), (long long)(name), (long long)(value), \ + (long long)(size)) +#define __sanitizer_syscall_pre_lgetxattr(path, name, value, size) \ + __sanitizer_syscall_pre_impl_lgetxattr((long long)(path), (long long)(name), \ + (long long)(value), \ + (long long)(size)) +#define __sanitizer_syscall_post_lgetxattr(res, path, name, value, size) \ + __sanitizer_syscall_post_impl_lgetxattr( \ + res, (long long)(path), (long long)(name), (long long)(value), \ + (long long)(size)) +#define __sanitizer_syscall_pre_fgetxattr(fd, name, value, size) \ + __sanitizer_syscall_pre_impl_fgetxattr((long long)(fd), (long long)(name), \ + (long long)(value), \ + (long long)(size)) +#define __sanitizer_syscall_post_fgetxattr(res, fd, name, value, size) \ + __sanitizer_syscall_post_impl_fgetxattr( \ + res, (long long)(fd), (long long)(name), (long long)(value), \ + (long long)(size)) +#define __sanitizer_syscall_pre_listxattr(path, list, size) \ + __sanitizer_syscall_pre_impl_listxattr((long long)(path), (long long)(list), \ + (long long)(size)) +#define __sanitizer_syscall_post_listxattr(res, path, list, size) \ + __sanitizer_syscall_post_impl_listxattr( \ + res, (long long)(path), (long long)(list), (long long)(size)) +#define __sanitizer_syscall_pre_llistxattr(path, list, size) \ + __sanitizer_syscall_pre_impl_llistxattr( \ + (long long)(path), (long long)(list), (long long)(size)) +#define __sanitizer_syscall_post_llistxattr(res, path, list, size) \ + __sanitizer_syscall_post_impl_llistxattr( \ + res, (long long)(path), (long long)(list), (long long)(size)) +#define __sanitizer_syscall_pre_flistxattr(fd, list, size) \ + __sanitizer_syscall_pre_impl_flistxattr((long long)(fd), (long long)(list), \ + (long long)(size)) +#define __sanitizer_syscall_post_flistxattr(res, fd, list, size) \ + __sanitizer_syscall_post_impl_flistxattr( \ + res, (long long)(fd), (long long)(list), (long long)(size)) +#define __sanitizer_syscall_pre_removexattr(path, name) \ + __sanitizer_syscall_pre_impl_removexattr((long long)(path), (long long)(name)) +#define __sanitizer_syscall_post_removexattr(res, path, name) \ + __sanitizer_syscall_post_impl_removexattr(res, (long long)(path), \ + (long long)(name)) +#define __sanitizer_syscall_pre_lremovexattr(path, name) \ + __sanitizer_syscall_pre_impl_lremovexattr((long long)(path), \ + (long long)(name)) +#define __sanitizer_syscall_post_lremovexattr(res, path, name) \ + __sanitizer_syscall_post_impl_lremovexattr(res, (long long)(path), \ + (long long)(name)) +#define __sanitizer_syscall_pre_fremovexattr(fd, name) \ + __sanitizer_syscall_pre_impl_fremovexattr((long long)(fd), (long long)(name)) +#define __sanitizer_syscall_post_fremovexattr(res, fd, name) \ + __sanitizer_syscall_post_impl_fremovexattr(res, (long long)(fd), \ + (long long)(name)) +#define __sanitizer_syscall_pre_compat_50___stat30(path, ub) \ + __sanitizer_syscall_pre_impl_compat_50___stat30((long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_post_compat_50___stat30(res, path, ub) \ + __sanitizer_syscall_post_impl_compat_50___stat30(res, (long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_pre_compat_50___fstat30(fd, sb) \ + __sanitizer_syscall_pre_impl_compat_50___fstat30((long long)(fd), \ + (long long)(sb)) +#define __sanitizer_syscall_post_compat_50___fstat30(res, fd, sb) \ + __sanitizer_syscall_post_impl_compat_50___fstat30(res, (long long)(fd), \ + (long long)(sb)) +#define __sanitizer_syscall_pre_compat_50___lstat30(path, ub) \ + __sanitizer_syscall_pre_impl_compat_50___lstat30((long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_post_compat_50___lstat30(res, path, ub) \ + __sanitizer_syscall_post_impl_compat_50___lstat30(res, (long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_pre___getdents30(fd, buf, count) \ + __sanitizer_syscall_pre_impl___getdents30((long long)(fd), (long long)(buf), \ + (long long)(count)) +#define __sanitizer_syscall_post___getdents30(res, fd, buf, count) \ + __sanitizer_syscall_post_impl___getdents30( \ + res, (long long)(fd), (long long)(buf), (long long)(count)) +#define __sanitizer_syscall_pre_posix_fadvise() \ + __sanitizer_syscall_pre_impl_posix_fadvise((long long)()) +#define __sanitizer_syscall_post_posix_fadvise(res) \ + __sanitizer_syscall_post_impl_posix_fadvise(res, (long long)()) +#define __sanitizer_syscall_pre_compat_30___fhstat30(fhp, sb) \ + __sanitizer_syscall_pre_impl_compat_30___fhstat30((long long)(fhp), \ + (long long)(sb)) +#define __sanitizer_syscall_post_compat_30___fhstat30(res, fhp, sb) \ + __sanitizer_syscall_post_impl_compat_30___fhstat30(res, (long long)(fhp), \ + (long long)(sb)) +#define __sanitizer_syscall_pre_compat_50___ntp_gettime30(ntvp) \ + __sanitizer_syscall_pre_impl_compat_50___ntp_gettime30((long long)(ntvp)) +#define __sanitizer_syscall_post_compat_50___ntp_gettime30(res, ntvp) \ + __sanitizer_syscall_post_impl_compat_50___ntp_gettime30(res, \ + (long long)(ntvp)) +#define __sanitizer_syscall_pre___socket30(domain, type, protocol) \ + __sanitizer_syscall_pre_impl___socket30( \ + (long long)(domain), (long long)(type), (long long)(protocol)) +#define __sanitizer_syscall_post___socket30(res, domain, type, protocol) \ + __sanitizer_syscall_post_impl___socket30( \ + res, (long long)(domain), (long long)(type), (long long)(protocol)) +#define __sanitizer_syscall_pre___getfh30(fname, fhp, fh_size) \ + __sanitizer_syscall_pre_impl___getfh30((long long)(fname), (long long)(fhp), \ + (long long)(fh_size)) +#define __sanitizer_syscall_post___getfh30(res, fname, fhp, fh_size) \ + __sanitizer_syscall_post_impl___getfh30( \ + res, (long long)(fname), (long long)(fhp), (long long)(fh_size)) +#define __sanitizer_syscall_pre___fhopen40(fhp, fh_size, flags) \ + __sanitizer_syscall_pre_impl___fhopen40( \ + (long long)(fhp), (long long)(fh_size), (long long)(flags)) +#define __sanitizer_syscall_post___fhopen40(res, fhp, fh_size, flags) \ + __sanitizer_syscall_post_impl___fhopen40( \ + res, (long long)(fhp), (long long)(fh_size), (long long)(flags)) +#define __sanitizer_syscall_pre___fhstatvfs140(fhp, fh_size, buf, flags) \ + __sanitizer_syscall_pre_impl___fhstatvfs140( \ + (long long)(fhp), (long long)(fh_size), (long long)(buf), \ + (long long)(flags)) +#define __sanitizer_syscall_post___fhstatvfs140(res, fhp, fh_size, buf, flags) \ + __sanitizer_syscall_post_impl___fhstatvfs140( \ + res, (long long)(fhp), (long long)(fh_size), (long long)(buf), \ + (long long)(flags)) +#define __sanitizer_syscall_pre_compat_50___fhstat40(fhp, fh_size, sb) \ + __sanitizer_syscall_pre_impl_compat_50___fhstat40( \ + (long long)(fhp), (long long)(fh_size), (long long)(sb)) +#define __sanitizer_syscall_post_compat_50___fhstat40(res, fhp, fh_size, sb) \ + __sanitizer_syscall_post_impl_compat_50___fhstat40( \ + res, (long long)(fhp), (long long)(fh_size), (long long)(sb)) +#define __sanitizer_syscall_pre_aio_cancel(fildes, aiocbp) \ + __sanitizer_syscall_pre_impl_aio_cancel((long long)(fildes), \ + (long long)(aiocbp)) +#define __sanitizer_syscall_post_aio_cancel(res, fildes, aiocbp) \ + __sanitizer_syscall_post_impl_aio_cancel(res, (long long)(fildes), \ + (long long)(aiocbp)) +#define __sanitizer_syscall_pre_aio_error(aiocbp) \ + __sanitizer_syscall_pre_impl_aio_error((long long)(aiocbp)) +#define __sanitizer_syscall_post_aio_error(res, aiocbp) \ + __sanitizer_syscall_post_impl_aio_error(res, (long long)(aiocbp)) +#define __sanitizer_syscall_pre_aio_fsync(op, aiocbp) \ + __sanitizer_syscall_pre_impl_aio_fsync((long long)(op), (long long)(aiocbp)) +#define __sanitizer_syscall_post_aio_fsync(res, op, aiocbp) \ + __sanitizer_syscall_post_impl_aio_fsync(res, (long long)(op), \ + (long long)(aiocbp)) +#define __sanitizer_syscall_pre_aio_read(aiocbp) \ + __sanitizer_syscall_pre_impl_aio_read((long long)(aiocbp)) +#define __sanitizer_syscall_post_aio_read(res, aiocbp) \ + __sanitizer_syscall_post_impl_aio_read(res, (long long)(aiocbp)) +#define __sanitizer_syscall_pre_aio_return(aiocbp) \ + __sanitizer_syscall_pre_impl_aio_return((long long)(aiocbp)) +#define __sanitizer_syscall_post_aio_return(res, aiocbp) \ + __sanitizer_syscall_post_impl_aio_return(res, (long long)(aiocbp)) +#define __sanitizer_syscall_pre_compat_50_aio_suspend(list, nent, timeout) \ + __sanitizer_syscall_pre_impl_compat_50_aio_suspend( \ + (long long)(list), (long long)(nent), (long long)(timeout)) +#define __sanitizer_syscall_post_compat_50_aio_suspend(res, list, nent, \ + timeout) \ + __sanitizer_syscall_post_impl_compat_50_aio_suspend( \ + res, (long long)(list), (long long)(nent), (long long)(timeout)) +#define __sanitizer_syscall_pre_aio_write(aiocbp) \ + __sanitizer_syscall_pre_impl_aio_write((long long)(aiocbp)) +#define __sanitizer_syscall_post_aio_write(res, aiocbp) \ + __sanitizer_syscall_post_impl_aio_write(res, (long long)(aiocbp)) +#define __sanitizer_syscall_pre_lio_listio(mode, list, nent, sig) \ + __sanitizer_syscall_pre_impl_lio_listio((long long)(mode), \ + (long long)(list), \ + (long long)(nent), (long long)(sig)) +#define __sanitizer_syscall_post_lio_listio(res, mode, list, nent, sig) \ + __sanitizer_syscall_post_impl_lio_listio( \ + res, (long long)(mode), (long long)(list), (long long)(nent), \ + (long long)(sig)) +/* syscall 407 has been skipped */ +/* syscall 408 has been skipped */ +/* syscall 409 has been skipped */ +#define __sanitizer_syscall_pre___mount50(type, path, flags, data, data_len) \ + __sanitizer_syscall_pre_impl___mount50( \ + (long long)(type), (long long)(path), (long long)(flags), \ + (long long)(data), (long long)(data_len)) +#define __sanitizer_syscall_post___mount50(res, type, path, flags, data, \ + data_len) \ + __sanitizer_syscall_post_impl___mount50( \ + res, (long long)(type), (long long)(path), (long long)(flags), \ + (long long)(data), (long long)(data_len)) +#define __sanitizer_syscall_pre_mremap(old_address, old_size, new_address, \ + new_size, flags) \ + __sanitizer_syscall_pre_impl_mremap( \ + (long long)(old_address), (long long)(old_size), \ + (long long)(new_address), (long long)(new_size), (long long)(flags)) +#define __sanitizer_syscall_post_mremap(res, old_address, old_size, \ + new_address, new_size, flags) \ + __sanitizer_syscall_post_impl_mremap( \ + res, (long long)(old_address), (long long)(old_size), \ + (long long)(new_address), (long long)(new_size), (long long)(flags)) +#define __sanitizer_syscall_pre_pset_create(psid) \ + __sanitizer_syscall_pre_impl_pset_create((long long)(psid)) +#define __sanitizer_syscall_post_pset_create(res, psid) \ + __sanitizer_syscall_post_impl_pset_create(res, (long long)(psid)) +#define __sanitizer_syscall_pre_pset_destroy(psid) \ + __sanitizer_syscall_pre_impl_pset_destroy((long long)(psid)) +#define __sanitizer_syscall_post_pset_destroy(res, psid) \ + __sanitizer_syscall_post_impl_pset_destroy(res, (long long)(psid)) +#define __sanitizer_syscall_pre_pset_assign(psid, cpuid, opsid) \ + __sanitizer_syscall_pre_impl_pset_assign( \ + (long long)(psid), (long long)(cpuid), (long long)(opsid)) +#define __sanitizer_syscall_post_pset_assign(res, psid, cpuid, opsid) \ + __sanitizer_syscall_post_impl_pset_assign( \ + res, (long long)(psid), (long long)(cpuid), (long long)(opsid)) +#define __sanitizer_syscall_pre__pset_bind(idtype, first_id, second_id, psid, \ + opsid) \ + __sanitizer_syscall_pre_impl__pset_bind( \ + (long long)(idtype), (long long)(first_id), (long long)(second_id), \ + (long long)(psid), (long long)(opsid)) +#define __sanitizer_syscall_post__pset_bind(res, idtype, first_id, second_id, \ + psid, opsid) \ + __sanitizer_syscall_post_impl__pset_bind( \ + res, (long long)(idtype), (long long)(first_id), (long long)(second_id), \ + (long long)(psid), (long long)(opsid)) +#define __sanitizer_syscall_pre___posix_fadvise50(fd, PAD, offset, len, \ + advice) \ + __sanitizer_syscall_pre_impl___posix_fadvise50( \ + (long long)(fd), (long long)(PAD), (long long)(offset), \ + (long long)(len), (long long)(advice)) +#define __sanitizer_syscall_post___posix_fadvise50(res, fd, PAD, offset, len, \ + advice) \ + __sanitizer_syscall_post_impl___posix_fadvise50( \ + res, (long long)(fd), (long long)(PAD), (long long)(offset), \ + (long long)(len), (long long)(advice)) +#define __sanitizer_syscall_pre___select50(nd, in, ou, ex, tv) \ + __sanitizer_syscall_pre_impl___select50((long long)(nd), (long long)(in), \ + (long long)(ou), (long long)(ex), \ + (long long)(tv)) +#define __sanitizer_syscall_post___select50(res, nd, in, ou, ex, tv) \ + __sanitizer_syscall_post_impl___select50(res, (long long)(nd), \ + (long long)(in), (long long)(ou), \ + (long long)(ex), (long long)(tv)) +#define __sanitizer_syscall_pre___gettimeofday50(tp, tzp) \ + __sanitizer_syscall_pre_impl___gettimeofday50((long long)(tp), \ + (long long)(tzp)) +#define __sanitizer_syscall_post___gettimeofday50(res, tp, tzp) \ + __sanitizer_syscall_post_impl___gettimeofday50(res, (long long)(tp), \ + (long long)(tzp)) +#define __sanitizer_syscall_pre___settimeofday50(tv, tzp) \ + __sanitizer_syscall_pre_impl___settimeofday50((long long)(tv), \ + (long long)(tzp)) +#define __sanitizer_syscall_post___settimeofday50(res, tv, tzp) \ + __sanitizer_syscall_post_impl___settimeofday50(res, (long long)(tv), \ + (long long)(tzp)) +#define __sanitizer_syscall_pre___utimes50(path, tptr) \ + __sanitizer_syscall_pre_impl___utimes50((long long)(path), (long long)(tptr)) +#define __sanitizer_syscall_post___utimes50(res, path, tptr) \ + __sanitizer_syscall_post_impl___utimes50(res, (long long)(path), \ + (long long)(tptr)) +#define __sanitizer_syscall_pre___adjtime50(delta, olddelta) \ + __sanitizer_syscall_pre_impl___adjtime50((long long)(delta), \ + (long long)(olddelta)) +#define __sanitizer_syscall_post___adjtime50(res, delta, olddelta) \ + __sanitizer_syscall_post_impl___adjtime50(res, (long long)(delta), \ + (long long)(olddelta)) +#define __sanitizer_syscall_pre___lfs_segwait50(fsidp, tv) \ + __sanitizer_syscall_pre_impl___lfs_segwait50((long long)(fsidp), \ + (long long)(tv)) +#define __sanitizer_syscall_post___lfs_segwait50(res, fsidp, tv) \ + __sanitizer_syscall_post_impl___lfs_segwait50(res, (long long)(fsidp), \ + (long long)(tv)) +#define __sanitizer_syscall_pre___futimes50(fd, tptr) \ + __sanitizer_syscall_pre_impl___futimes50((long long)(fd), (long long)(tptr)) +#define __sanitizer_syscall_post___futimes50(res, fd, tptr) \ + __sanitizer_syscall_post_impl___futimes50(res, (long long)(fd), \ + (long long)(tptr)) +#define __sanitizer_syscall_pre___lutimes50(path, tptr) \ + __sanitizer_syscall_pre_impl___lutimes50((long long)(path), (long long)(tptr)) +#define __sanitizer_syscall_post___lutimes50(res, path, tptr) \ + __sanitizer_syscall_post_impl___lutimes50(res, (long long)(path), \ + (long long)(tptr)) +#define __sanitizer_syscall_pre___setitimer50(which, itv, oitv) \ + __sanitizer_syscall_pre_impl___setitimer50( \ + (long long)(which), (long long)(itv), (long long)(oitv)) +#define __sanitizer_syscall_post___setitimer50(res, which, itv, oitv) \ + __sanitizer_syscall_post_impl___setitimer50( \ + res, (long long)(which), (long long)(itv), (long long)(oitv)) +#define __sanitizer_syscall_pre___getitimer50(which, itv) \ + __sanitizer_syscall_pre_impl___getitimer50((long long)(which), \ + (long long)(itv)) +#define __sanitizer_syscall_post___getitimer50(res, which, itv) \ + __sanitizer_syscall_post_impl___getitimer50(res, (long long)(which), \ + (long long)(itv)) +#define __sanitizer_syscall_pre___clock_gettime50(clock_id, tp) \ + __sanitizer_syscall_pre_impl___clock_gettime50((long long)(clock_id), \ + (long long)(tp)) +#define __sanitizer_syscall_post___clock_gettime50(res, clock_id, tp) \ + __sanitizer_syscall_post_impl___clock_gettime50(res, (long long)(clock_id), \ + (long long)(tp)) +#define __sanitizer_syscall_pre___clock_settime50(clock_id, tp) \ + __sanitizer_syscall_pre_impl___clock_settime50((long long)(clock_id), \ + (long long)(tp)) +#define __sanitizer_syscall_post___clock_settime50(res, clock_id, tp) \ + __sanitizer_syscall_post_impl___clock_settime50(res, (long long)(clock_id), \ + (long long)(tp)) +#define __sanitizer_syscall_pre___clock_getres50(clock_id, tp) \ + __sanitizer_syscall_pre_impl___clock_getres50((long long)(clock_id), \ + (long long)(tp)) +#define __sanitizer_syscall_post___clock_getres50(res, clock_id, tp) \ + __sanitizer_syscall_post_impl___clock_getres50(res, (long long)(clock_id), \ + (long long)(tp)) +#define __sanitizer_syscall_pre___nanosleep50(rqtp, rmtp) \ + __sanitizer_syscall_pre_impl___nanosleep50((long long)(rqtp), \ + (long long)(rmtp)) +#define __sanitizer_syscall_post___nanosleep50(res, rqtp, rmtp) \ + __sanitizer_syscall_post_impl___nanosleep50(res, (long long)(rqtp), \ + (long long)(rmtp)) +#define __sanitizer_syscall_pre_____sigtimedwait50(set, info, timeout) \ + __sanitizer_syscall_pre_impl_____sigtimedwait50( \ + (long long)(set), (long long)(info), (long long)(timeout)) +#define __sanitizer_syscall_post_____sigtimedwait50(res, set, info, timeout) \ + __sanitizer_syscall_post_impl_____sigtimedwait50( \ + res, (long long)(set), (long long)(info), (long long)(timeout)) +#define __sanitizer_syscall_pre___mq_timedsend50(mqdes, msg_ptr, msg_len, \ + msg_prio, abs_timeout) \ + __sanitizer_syscall_pre_impl___mq_timedsend50( \ + (long long)(mqdes), (long long)(msg_ptr), (long long)(msg_len), \ + (long long)(msg_prio), (long long)(abs_timeout)) +#define __sanitizer_syscall_post___mq_timedsend50( \ + res, mqdes, msg_ptr, msg_len, msg_prio, abs_timeout) \ + __sanitizer_syscall_post_impl___mq_timedsend50( \ + res, (long long)(mqdes), (long long)(msg_ptr), (long long)(msg_len), \ + (long long)(msg_prio), (long long)(abs_timeout)) +#define __sanitizer_syscall_pre___mq_timedreceive50(mqdes, msg_ptr, msg_len, \ + msg_prio, abs_timeout) \ + __sanitizer_syscall_pre_impl___mq_timedreceive50( \ + (long long)(mqdes), (long long)(msg_ptr), (long long)(msg_len), \ + (long long)(msg_prio), (long long)(abs_timeout)) +#define __sanitizer_syscall_post___mq_timedreceive50( \ + res, mqdes, msg_ptr, msg_len, msg_prio, abs_timeout) \ + __sanitizer_syscall_post_impl___mq_timedreceive50( \ + res, (long long)(mqdes), (long long)(msg_ptr), (long long)(msg_len), \ + (long long)(msg_prio), (long long)(abs_timeout)) +#define __sanitizer_syscall_pre_compat_60__lwp_park(ts, unpark, hint, \ + unparkhint) \ + __sanitizer_syscall_pre_impl_compat_60__lwp_park( \ + (long long)(ts), (long long)(unpark), (long long)(hint), \ + (long long)(unparkhint)) +#define __sanitizer_syscall_post_compat_60__lwp_park(res, ts, unpark, hint, \ + unparkhint) \ + __sanitizer_syscall_post_impl_compat_60__lwp_park( \ + res, (long long)(ts), (long long)(unpark), (long long)(hint), \ + (long long)(unparkhint)) +#define __sanitizer_syscall_pre___kevent50(fd, changelist, nchanges, \ + eventlist, nevents, timeout) \ + __sanitizer_syscall_pre_impl___kevent50( \ + (long long)(fd), (long long)(changelist), (long long)(nchanges), \ + (long long)(eventlist), (long long)(nevents), (long long)(timeout)) +#define __sanitizer_syscall_post___kevent50(res, fd, changelist, nchanges, \ + eventlist, nevents, timeout) \ + __sanitizer_syscall_post_impl___kevent50( \ + res, (long long)(fd), (long long)(changelist), (long long)(nchanges), \ + (long long)(eventlist), (long long)(nevents), (long long)(timeout)) +#define __sanitizer_syscall_pre___pselect50(nd, in, ou, ex, ts, mask) \ + __sanitizer_syscall_pre_impl___pselect50((long long)(nd), (long long)(in), \ + (long long)(ou), (long long)(ex), \ + (long long)(ts), (long long)(mask)) +#define __sanitizer_syscall_post___pselect50(res, nd, in, ou, ex, ts, mask) \ + __sanitizer_syscall_post_impl___pselect50( \ + res, (long long)(nd), (long long)(in), (long long)(ou), (long long)(ex), \ + (long long)(ts), (long long)(mask)) +#define __sanitizer_syscall_pre___pollts50(fds, nfds, ts, mask) \ + __sanitizer_syscall_pre_impl___pollts50((long long)(fds), (long long)(nfds), \ + (long long)(ts), (long long)(mask)) +#define __sanitizer_syscall_post___pollts50(res, fds, nfds, ts, mask) \ + __sanitizer_syscall_post_impl___pollts50(res, (long long)(fds), \ + (long long)(nfds), (long long)(ts), \ + (long long)(mask)) +#define __sanitizer_syscall_pre___aio_suspend50(list, nent, timeout) \ + __sanitizer_syscall_pre_impl___aio_suspend50( \ + (long long)(list), (long long)(nent), (long long)(timeout)) +#define __sanitizer_syscall_post___aio_suspend50(res, list, nent, timeout) \ + __sanitizer_syscall_post_impl___aio_suspend50( \ + res, (long long)(list), (long long)(nent), (long long)(timeout)) +#define __sanitizer_syscall_pre___stat50(path, ub) \ + __sanitizer_syscall_pre_impl___stat50((long long)(path), (long long)(ub)) +#define __sanitizer_syscall_post___stat50(res, path, ub) \ + __sanitizer_syscall_post_impl___stat50(res, (long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_pre___fstat50(fd, sb) \ + __sanitizer_syscall_pre_impl___fstat50((long long)(fd), (long long)(sb)) +#define __sanitizer_syscall_post___fstat50(res, fd, sb) \ + __sanitizer_syscall_post_impl___fstat50(res, (long long)(fd), (long long)(sb)) +#define __sanitizer_syscall_pre___lstat50(path, ub) \ + __sanitizer_syscall_pre_impl___lstat50((long long)(path), (long long)(ub)) +#define __sanitizer_syscall_post___lstat50(res, path, ub) \ + __sanitizer_syscall_post_impl___lstat50(res, (long long)(path), \ + (long long)(ub)) +#define __sanitizer_syscall_pre_____semctl50(semid, semnum, cmd, arg) \ + __sanitizer_syscall_pre_impl_____semctl50( \ + (long long)(semid), (long long)(semnum), (long long)(cmd), \ + (long long)(arg)) +#define __sanitizer_syscall_post_____semctl50(res, semid, semnum, cmd, arg) \ + __sanitizer_syscall_post_impl_____semctl50( \ + res, (long long)(semid), (long long)(semnum), (long long)(cmd), \ + (long long)(arg)) +#define __sanitizer_syscall_pre___shmctl50(shmid, cmd, buf) \ + __sanitizer_syscall_pre_impl___shmctl50((long long)(shmid), \ + (long long)(cmd), (long long)(buf)) +#define __sanitizer_syscall_post___shmctl50(res, shmid, cmd, buf) \ + __sanitizer_syscall_post_impl___shmctl50(res, (long long)(shmid), \ + (long long)(cmd), (long long)(buf)) +#define __sanitizer_syscall_pre___msgctl50(msqid, cmd, buf) \ + __sanitizer_syscall_pre_impl___msgctl50((long long)(msqid), \ + (long long)(cmd), (long long)(buf)) +#define __sanitizer_syscall_post___msgctl50(res, msqid, cmd, buf) \ + __sanitizer_syscall_post_impl___msgctl50(res, (long long)(msqid), \ + (long long)(cmd), (long long)(buf)) +#define __sanitizer_syscall_pre___getrusage50(who, rusage) \ + __sanitizer_syscall_pre_impl___getrusage50((long long)(who), \ + (long long)(rusage)) +#define __sanitizer_syscall_post___getrusage50(res, who, rusage) \ + __sanitizer_syscall_post_impl___getrusage50(res, (long long)(who), \ + (long long)(rusage)) +#define __sanitizer_syscall_pre___timer_settime50(timerid, flags, value, \ + ovalue) \ + __sanitizer_syscall_pre_impl___timer_settime50( \ + (long long)(timerid), (long long)(flags), (long long)(value), \ + (long long)(ovalue)) +#define __sanitizer_syscall_post___timer_settime50(res, timerid, flags, value, \ + ovalue) \ + __sanitizer_syscall_post_impl___timer_settime50( \ + res, (long long)(timerid), (long long)(flags), (long long)(value), \ + (long long)(ovalue)) +#define __sanitizer_syscall_pre___timer_gettime50(timerid, value) \ + __sanitizer_syscall_pre_impl___timer_gettime50((long long)(timerid), \ + (long long)(value)) +#define __sanitizer_syscall_post___timer_gettime50(res, timerid, value) \ + __sanitizer_syscall_post_impl___timer_gettime50(res, (long long)(timerid), \ + (long long)(value)) +#if defined(NTP) || !defined(_KERNEL_OPT) +#define __sanitizer_syscall_pre___ntp_gettime50(ntvp) \ + __sanitizer_syscall_pre_impl___ntp_gettime50((long long)(ntvp)) +#define __sanitizer_syscall_post___ntp_gettime50(res, ntvp) \ + __sanitizer_syscall_post_impl___ntp_gettime50(res, (long long)(ntvp)) +#else +/* syscall 448 has been skipped */ +#endif +#define __sanitizer_syscall_pre___wait450(pid, status, options, rusage) \ + __sanitizer_syscall_pre_impl___wait450( \ + (long long)(pid), (long long)(status), (long long)(options), \ + (long long)(rusage)) +#define __sanitizer_syscall_post___wait450(res, pid, status, options, rusage) \ + __sanitizer_syscall_post_impl___wait450( \ + res, (long long)(pid), (long long)(status), (long long)(options), \ + (long long)(rusage)) +#define __sanitizer_syscall_pre___mknod50(path, mode, dev) \ + __sanitizer_syscall_pre_impl___mknod50((long long)(path), (long long)(mode), \ + (long long)(dev)) +#define __sanitizer_syscall_post___mknod50(res, path, mode, dev) \ + __sanitizer_syscall_post_impl___mknod50(res, (long long)(path), \ + (long long)(mode), (long long)(dev)) +#define __sanitizer_syscall_pre___fhstat50(fhp, fh_size, sb) \ + __sanitizer_syscall_pre_impl___fhstat50( \ + (long long)(fhp), (long long)(fh_size), (long long)(sb)) +#define __sanitizer_syscall_post___fhstat50(res, fhp, fh_size, sb) \ + __sanitizer_syscall_post_impl___fhstat50( \ + res, (long long)(fhp), (long long)(fh_size), (long long)(sb)) +/* syscall 452 has been skipped */ +#define __sanitizer_syscall_pre_pipe2(fildes, flags) \ + __sanitizer_syscall_pre_impl_pipe2((long long)(fildes), (long long)(flags)) +#define __sanitizer_syscall_post_pipe2(res, fildes, flags) \ + __sanitizer_syscall_post_impl_pipe2(res, (long long)(fildes), \ + (long long)(flags)) +#define __sanitizer_syscall_pre_dup3(from, to, flags) \ + __sanitizer_syscall_pre_impl_dup3((long long)(from), (long long)(to), \ + (long long)(flags)) +#define __sanitizer_syscall_post_dup3(res, from, to, flags) \ + __sanitizer_syscall_post_impl_dup3(res, (long long)(from), (long long)(to), \ + (long long)(flags)) +#define __sanitizer_syscall_pre_kqueue1(flags) \ + __sanitizer_syscall_pre_impl_kqueue1((long long)(flags)) +#define __sanitizer_syscall_post_kqueue1(res, flags) \ + __sanitizer_syscall_post_impl_kqueue1(res, (long long)(flags)) +#define __sanitizer_syscall_pre_paccept(s, name, anamelen, mask, flags) \ + __sanitizer_syscall_pre_impl_paccept((long long)(s), (long long)(name), \ + (long long)(anamelen), \ + (long long)(mask), (long long)(flags)) +#define __sanitizer_syscall_post_paccept(res, s, name, anamelen, mask, flags) \ + __sanitizer_syscall_post_impl_paccept( \ + res, (long long)(s), (long long)(name), (long long)(anamelen), \ + (long long)(mask), (long long)(flags)) +#define __sanitizer_syscall_pre_linkat(fd1, name1, fd2, name2, flags) \ + __sanitizer_syscall_pre_impl_linkat((long long)(fd1), (long long)(name1), \ + (long long)(fd2), (long long)(name2), \ + (long long)(flags)) +#define __sanitizer_syscall_post_linkat(res, fd1, name1, fd2, name2, flags) \ + __sanitizer_syscall_post_impl_linkat(res, (long long)(fd1), \ + (long long)(name1), (long long)(fd2), \ + (long long)(name2), (long long)(flags)) +#define __sanitizer_syscall_pre_renameat(fromfd, from, tofd, to) \ + __sanitizer_syscall_pre_impl_renameat((long long)(fromfd), \ + (long long)(from), (long long)(tofd), \ + (long long)(to)) +#define __sanitizer_syscall_post_renameat(res, fromfd, from, tofd, to) \ + __sanitizer_syscall_post_impl_renameat(res, (long long)(fromfd), \ + (long long)(from), (long long)(tofd), \ + (long long)(to)) +#define __sanitizer_syscall_pre_mkfifoat(fd, path, mode) \ + __sanitizer_syscall_pre_impl_mkfifoat((long long)(fd), (long long)(path), \ + (long long)(mode)) +#define __sanitizer_syscall_post_mkfifoat(res, fd, path, mode) \ + __sanitizer_syscall_post_impl_mkfifoat(res, (long long)(fd), \ + (long long)(path), (long long)(mode)) +#define __sanitizer_syscall_pre_mknodat(fd, path, mode, PAD, dev) \ + __sanitizer_syscall_pre_impl_mknodat((long long)(fd), (long long)(path), \ + (long long)(mode), (long long)(PAD), \ + (long long)(dev)) +#define __sanitizer_syscall_post_mknodat(res, fd, path, mode, PAD, dev) \ + __sanitizer_syscall_post_impl_mknodat(res, (long long)(fd), \ + (long long)(path), (long long)(mode), \ + (long long)(PAD), (long long)(dev)) +#define __sanitizer_syscall_pre_mkdirat(fd, path, mode) \ + __sanitizer_syscall_pre_impl_mkdirat((long long)(fd), (long long)(path), \ + (long long)(mode)) +#define __sanitizer_syscall_post_mkdirat(res, fd, path, mode) \ + __sanitizer_syscall_post_impl_mkdirat(res, (long long)(fd), \ + (long long)(path), (long long)(mode)) +#define __sanitizer_syscall_pre_faccessat(fd, path, amode, flag) \ + __sanitizer_syscall_pre_impl_faccessat((long long)(fd), (long long)(path), \ + (long long)(amode), \ + (long long)(flag)) +#define __sanitizer_syscall_post_faccessat(res, fd, path, amode, flag) \ + __sanitizer_syscall_post_impl_faccessat( \ + res, (long long)(fd), (long long)(path), (long long)(amode), \ + (long long)(flag)) +#define __sanitizer_syscall_pre_fchmodat(fd, path, mode, flag) \ + __sanitizer_syscall_pre_impl_fchmodat((long long)(fd), (long long)(path), \ + (long long)(mode), (long long)(flag)) +#define __sanitizer_syscall_post_fchmodat(res, fd, path, mode, flag) \ + __sanitizer_syscall_post_impl_fchmodat(res, (long long)(fd), \ + (long long)(path), (long long)(mode), \ + (long long)(flag)) +#define __sanitizer_syscall_pre_fchownat(fd, path, owner, group, flag) \ + __sanitizer_syscall_pre_impl_fchownat((long long)(fd), (long long)(path), \ + (long long)(owner), \ + (long long)(group), (long long)(flag)) +#define __sanitizer_syscall_post_fchownat(res, fd, path, owner, group, flag) \ + __sanitizer_syscall_post_impl_fchownat( \ + res, (long long)(fd), (long long)(path), (long long)(owner), \ + (long long)(group), (long long)(flag)) +#define __sanitizer_syscall_pre_fexecve(fd, argp, envp) \ + __sanitizer_syscall_pre_impl_fexecve((long long)(fd), (long long)(argp), \ + (long long)(envp)) +#define __sanitizer_syscall_post_fexecve(res, fd, argp, envp) \ + __sanitizer_syscall_post_impl_fexecve(res, (long long)(fd), \ + (long long)(argp), (long long)(envp)) +#define __sanitizer_syscall_pre_fstatat(fd, path, buf, flag) \ + __sanitizer_syscall_pre_impl_fstatat((long long)(fd), (long long)(path), \ + (long long)(buf), (long long)(flag)) +#define __sanitizer_syscall_post_fstatat(res, fd, path, buf, flag) \ + __sanitizer_syscall_post_impl_fstatat(res, (long long)(fd), \ + (long long)(path), (long long)(buf), \ + (long long)(flag)) +#define __sanitizer_syscall_pre_utimensat(fd, path, tptr, flag) \ + __sanitizer_syscall_pre_impl_utimensat((long long)(fd), (long long)(path), \ + (long long)(tptr), (long long)(flag)) +#define __sanitizer_syscall_post_utimensat(res, fd, path, tptr, flag) \ + __sanitizer_syscall_post_impl_utimensat( \ + res, (long long)(fd), (long long)(path), (long long)(tptr), \ + (long long)(flag)) +#define __sanitizer_syscall_pre_openat(fd, path, oflags, mode) \ + __sanitizer_syscall_pre_impl_openat((long long)(fd), (long long)(path), \ + (long long)(oflags), (long long)(mode)) +#define __sanitizer_syscall_post_openat(res, fd, path, oflags, mode) \ + __sanitizer_syscall_post_impl_openat(res, (long long)(fd), \ + (long long)(path), (long long)(oflags), \ + (long long)(mode)) +#define __sanitizer_syscall_pre_readlinkat(fd, path, buf, bufsize) \ + __sanitizer_syscall_pre_impl_readlinkat((long long)(fd), (long long)(path), \ + (long long)(buf), \ + (long long)(bufsize)) +#define __sanitizer_syscall_post_readlinkat(res, fd, path, buf, bufsize) \ + __sanitizer_syscall_post_impl_readlinkat( \ + res, (long long)(fd), (long long)(path), (long long)(buf), \ + (long long)(bufsize)) +#define __sanitizer_syscall_pre_symlinkat(path1, fd, path2) \ + __sanitizer_syscall_pre_impl_symlinkat((long long)(path1), (long long)(fd), \ + (long long)(path2)) +#define __sanitizer_syscall_post_symlinkat(res, path1, fd, path2) \ + __sanitizer_syscall_post_impl_symlinkat(res, (long long)(path1), \ + (long long)(fd), (long long)(path2)) +#define __sanitizer_syscall_pre_unlinkat(fd, path, flag) \ + __sanitizer_syscall_pre_impl_unlinkat((long long)(fd), (long long)(path), \ + (long long)(flag)) +#define __sanitizer_syscall_post_unlinkat(res, fd, path, flag) \ + __sanitizer_syscall_post_impl_unlinkat(res, (long long)(fd), \ + (long long)(path), (long long)(flag)) +#define __sanitizer_syscall_pre_futimens(fd, tptr) \ + __sanitizer_syscall_pre_impl_futimens((long long)(fd), (long long)(tptr)) +#define __sanitizer_syscall_post_futimens(res, fd, tptr) \ + __sanitizer_syscall_post_impl_futimens(res, (long long)(fd), \ + (long long)(tptr)) +#define __sanitizer_syscall_pre___quotactl(path, args) \ + __sanitizer_syscall_pre_impl___quotactl((long long)(path), (long long)(args)) +#define __sanitizer_syscall_post___quotactl(res, path, args) \ + __sanitizer_syscall_post_impl___quotactl(res, (long long)(path), \ + (long long)(args)) +#define __sanitizer_syscall_pre_posix_spawn(pid, path, file_actions, attrp, \ + argv, envp) \ + __sanitizer_syscall_pre_impl_posix_spawn( \ + (long long)(pid), (long long)(path), (long long)(file_actions), \ + (long long)(attrp), (long long)(argv), (long long)(envp)) +#define __sanitizer_syscall_post_posix_spawn(res, pid, path, file_actions, \ + attrp, argv, envp) \ + __sanitizer_syscall_post_impl_posix_spawn( \ + res, (long long)(pid), (long long)(path), (long long)(file_actions), \ + (long long)(attrp), (long long)(argv), (long long)(envp)) +#define __sanitizer_syscall_pre_recvmmsg(s, mmsg, vlen, flags, timeout) \ + __sanitizer_syscall_pre_impl_recvmmsg((long long)(s), (long long)(mmsg), \ + (long long)(vlen), (long long)(flags), \ + (long long)(timeout)) +#define __sanitizer_syscall_post_recvmmsg(res, s, mmsg, vlen, flags, timeout) \ + __sanitizer_syscall_post_impl_recvmmsg( \ + res, (long long)(s), (long long)(mmsg), (long long)(vlen), \ + (long long)(flags), (long long)(timeout)) +#define __sanitizer_syscall_pre_sendmmsg(s, mmsg, vlen, flags) \ + __sanitizer_syscall_pre_impl_sendmmsg((long long)(s), (long long)(mmsg), \ + (long long)(vlen), (long long)(flags)) +#define __sanitizer_syscall_post_sendmmsg(res, s, mmsg, vlen, flags) \ + __sanitizer_syscall_post_impl_sendmmsg(res, (long long)(s), \ + (long long)(mmsg), (long long)(vlen), \ + (long long)(flags)) +#define __sanitizer_syscall_pre_clock_nanosleep(clock_id, flags, rqtp, rmtp) \ + __sanitizer_syscall_pre_impl_clock_nanosleep( \ + (long long)(clock_id), (long long)(flags), (long long)(rqtp), \ + (long long)(rmtp)) +#define __sanitizer_syscall_post_clock_nanosleep(res, clock_id, flags, rqtp, \ + rmtp) \ + __sanitizer_syscall_post_impl_clock_nanosleep( \ + res, (long long)(clock_id), (long long)(flags), (long long)(rqtp), \ + (long long)(rmtp)) +#define __sanitizer_syscall_pre____lwp_park60(clock_id, flags, ts, unpark, \ + hint, unparkhint) \ + __sanitizer_syscall_pre_impl____lwp_park60( \ + (long long)(clock_id), (long long)(flags), (long long)(ts), \ + (long long)(unpark), (long long)(hint), (long long)(unparkhint)) +#define __sanitizer_syscall_post____lwp_park60(res, clock_id, flags, ts, \ + unpark, hint, unparkhint) \ + __sanitizer_syscall_post_impl____lwp_park60( \ + res, (long long)(clock_id), (long long)(flags), (long long)(ts), \ + (long long)(unpark), (long long)(hint), (long long)(unparkhint)) +#define __sanitizer_syscall_pre_posix_fallocate(fd, PAD, pos, len) \ + __sanitizer_syscall_pre_impl_posix_fallocate( \ + (long long)(fd), (long long)(PAD), (long long)(pos), (long long)(len)) +#define __sanitizer_syscall_post_posix_fallocate(res, fd, PAD, pos, len) \ + __sanitizer_syscall_post_impl_posix_fallocate( \ + res, (long long)(fd), (long long)(PAD), (long long)(pos), \ + (long long)(len)) +#define __sanitizer_syscall_pre_fdiscard(fd, PAD, pos, len) \ + __sanitizer_syscall_pre_impl_fdiscard((long long)(fd), (long long)(PAD), \ + (long long)(pos), (long long)(len)) +#define __sanitizer_syscall_post_fdiscard(res, fd, PAD, pos, len) \ + __sanitizer_syscall_post_impl_fdiscard(res, (long long)(fd), \ + (long long)(PAD), (long long)(pos), \ + (long long)(len)) +#define __sanitizer_syscall_pre_wait6(idtype, id, status, options, wru, info) \ + __sanitizer_syscall_pre_impl_wait6( \ + (long long)(idtype), (long long)(id), (long long)(status), \ + (long long)(options), (long long)(wru), (long long)(info)) +#define __sanitizer_syscall_post_wait6(res, idtype, id, status, options, wru, \ + info) \ + __sanitizer_syscall_post_impl_wait6( \ + res, (long long)(idtype), (long long)(id), (long long)(status), \ + (long long)(options), (long long)(wru), (long long)(info)) +#define __sanitizer_syscall_pre_clock_getcpuclockid2(idtype, id, clock_id) \ + __sanitizer_syscall_pre_impl_clock_getcpuclockid2( \ + (long long)(idtype), (long long)(id), (long long)(clock_id)) +#define __sanitizer_syscall_post_clock_getcpuclockid2(res, idtype, id, \ + clock_id) \ + __sanitizer_syscall_post_impl_clock_getcpuclockid2( \ + res, (long long)(idtype), (long long)(id), (long long)(clock_id)) + +#ifdef __cplusplus +extern "C" { +#endif + +// Private declarations. Do not call directly from user code. Use macros above. + +// DO NOT EDIT! THIS FILE HAS BEEN GENERATED! + +void __sanitizer_syscall_pre_impl_syscall(long long code, long long arg0, + long long arg1, long long arg2, + long long arg3, long long arg4, + long long arg5, long long arg6, + long long arg7); +void __sanitizer_syscall_post_impl_syscall(long long res, long long code, + long long arg0, long long arg1, + long long arg2, long long arg3, + long long arg4, long long arg5, + long long arg6, long long arg7); +void __sanitizer_syscall_pre_impl_exit(long long rval); +void __sanitizer_syscall_post_impl_exit(long long res, long long rval); +void __sanitizer_syscall_pre_impl_fork(void); +void __sanitizer_syscall_post_impl_fork(long long res); +void __sanitizer_syscall_pre_impl_read(long long fd, long long buf, + long long nbyte); +void __sanitizer_syscall_post_impl_read(long long res, long long fd, + long long buf, long long nbyte); +void __sanitizer_syscall_pre_impl_write(long long fd, long long buf, + long long nbyte); +void __sanitizer_syscall_post_impl_write(long long res, long long fd, + long long buf, long long nbyte); +void __sanitizer_syscall_pre_impl_open(long long path, long long flags, + long long mode); +void __sanitizer_syscall_post_impl_open(long long res, long long path, + long long flags, long long mode); +void __sanitizer_syscall_pre_impl_close(long long fd); +void __sanitizer_syscall_post_impl_close(long long res, long long fd); +void __sanitizer_syscall_pre_impl_compat_50_wait4(long long pid, + long long status, + long long options, + long long rusage); +void __sanitizer_syscall_post_impl_compat_50_wait4(long long res, long long pid, + long long status, + long long options, + long long rusage); +void __sanitizer_syscall_pre_impl_compat_43_ocreat(long long path, + long long mode); +void __sanitizer_syscall_post_impl_compat_43_ocreat(long long res, + long long path, + long long mode); +void __sanitizer_syscall_pre_impl_link(long long path, long long link); +void __sanitizer_syscall_post_impl_link(long long res, long long path, + long long link); +void __sanitizer_syscall_pre_impl_unlink(long long path); +void __sanitizer_syscall_post_impl_unlink(long long res, long long path); +/* syscall 11 has been skipped */ +void __sanitizer_syscall_pre_impl_chdir(long long path); +void __sanitizer_syscall_post_impl_chdir(long long res, long long path); +void __sanitizer_syscall_pre_impl_fchdir(long long fd); +void __sanitizer_syscall_post_impl_fchdir(long long res, long long fd); +void __sanitizer_syscall_pre_impl_compat_50_mknod(long long path, + long long mode, + long long dev); +void __sanitizer_syscall_post_impl_compat_50_mknod(long long res, + long long path, + long long mode, + long long dev); +void __sanitizer_syscall_pre_impl_chmod(long long path, long long mode); +void __sanitizer_syscall_post_impl_chmod(long long res, long long path, + long long mode); +void __sanitizer_syscall_pre_impl_chown(long long path, long long uid, + long long gid); +void __sanitizer_syscall_post_impl_chown(long long res, long long path, + long long uid, long long gid); +void __sanitizer_syscall_pre_impl_break(long long nsize); +void __sanitizer_syscall_post_impl_break(long long res, long long nsize); +void __sanitizer_syscall_pre_impl_compat_20_getfsstat(long long buf, + long long bufsize, + long long flags); +void __sanitizer_syscall_post_impl_compat_20_getfsstat(long long res, + long long buf, + long long bufsize, + long long flags); +void __sanitizer_syscall_pre_impl_compat_43_olseek(long long fd, + long long offset, + long long whence); +void __sanitizer_syscall_post_impl_compat_43_olseek(long long res, long long fd, + long long offset, + long long whence); +void __sanitizer_syscall_pre_impl_getpid(void); +void __sanitizer_syscall_post_impl_getpid(long long res); +void __sanitizer_syscall_pre_impl_compat_40_mount(long long type, + long long path, + long long flags, + long long data); +void __sanitizer_syscall_post_impl_compat_40_mount(long long res, + long long type, + long long path, + long long flags, + long long data); +void __sanitizer_syscall_pre_impl_unmount(long long path, long long flags); +void __sanitizer_syscall_post_impl_unmount(long long res, long long path, + long long flags); +void __sanitizer_syscall_pre_impl_setuid(long long uid); +void __sanitizer_syscall_post_impl_setuid(long long res, long long uid); +void __sanitizer_syscall_pre_impl_getuid(void); +void __sanitizer_syscall_post_impl_getuid(long long res); +void __sanitizer_syscall_pre_impl_geteuid(void); +void __sanitizer_syscall_post_impl_geteuid(long long res); +void __sanitizer_syscall_pre_impl_ptrace(long long req, long long pid, + long long addr, long long data); +void __sanitizer_syscall_post_impl_ptrace(long long res, long long req, + long long pid, long long addr, + long long data); +void __sanitizer_syscall_pre_impl_recvmsg(long long s, long long msg, + long long flags); +void __sanitizer_syscall_post_impl_recvmsg(long long res, long long s, + long long msg, long long flags); +void __sanitizer_syscall_pre_impl_sendmsg(long long s, long long msg, + long long flags); +void __sanitizer_syscall_post_impl_sendmsg(long long res, long long s, + long long msg, long long flags); +void __sanitizer_syscall_pre_impl_recvfrom(long long s, long long buf, + long long len, long long flags, + long long from, + long long fromlenaddr); +void __sanitizer_syscall_post_impl_recvfrom(long long res, long long s, + long long buf, long long len, + long long flags, long long from, + long long fromlenaddr); +void __sanitizer_syscall_pre_impl_accept(long long s, long long name, + long long anamelen); +void __sanitizer_syscall_post_impl_accept(long long res, long long s, + long long name, long long anamelen); +void __sanitizer_syscall_pre_impl_getpeername(long long fdes, long long asa, + long long alen); +void __sanitizer_syscall_post_impl_getpeername(long long res, long long fdes, + long long asa, long long alen); +void __sanitizer_syscall_pre_impl_getsockname(long long fdes, long long asa, + long long alen); +void __sanitizer_syscall_post_impl_getsockname(long long res, long long fdes, + long long asa, long long alen); +void __sanitizer_syscall_pre_impl_access(long long path, long long flags); +void __sanitizer_syscall_post_impl_access(long long res, long long path, + long long flags); +void __sanitizer_syscall_pre_impl_chflags(long long path, long long flags); +void __sanitizer_syscall_post_impl_chflags(long long res, long long path, + long long flags); +void __sanitizer_syscall_pre_impl_fchflags(long long fd, long long flags); +void __sanitizer_syscall_post_impl_fchflags(long long res, long long fd, + long long flags); +void __sanitizer_syscall_pre_impl_sync(void); +void __sanitizer_syscall_post_impl_sync(long long res); +void __sanitizer_syscall_pre_impl_kill(long long pid, long long signum); +void __sanitizer_syscall_post_impl_kill(long long res, long long pid, + long long signum); +void __sanitizer_syscall_pre_impl_compat_43_stat43(long long path, + long long ub); +void __sanitizer_syscall_post_impl_compat_43_stat43(long long res, + long long path, + long long ub); +void __sanitizer_syscall_pre_impl_getppid(void); +void __sanitizer_syscall_post_impl_getppid(long long res); +void __sanitizer_syscall_pre_impl_compat_43_lstat43(long long path, + long long ub); +void __sanitizer_syscall_post_impl_compat_43_lstat43(long long res, + long long path, + long long ub); +void __sanitizer_syscall_pre_impl_dup(long long fd); +void __sanitizer_syscall_post_impl_dup(long long res, long long fd); +void __sanitizer_syscall_pre_impl_pipe(void); +void __sanitizer_syscall_post_impl_pipe(long long res); +void __sanitizer_syscall_pre_impl_getegid(void); +void __sanitizer_syscall_post_impl_getegid(long long res); +void __sanitizer_syscall_pre_impl_profil(long long samples, long long size, + long long offset, long long scale); +void __sanitizer_syscall_post_impl_profil(long long res, long long samples, + long long size, long long offset, + long long scale); +void __sanitizer_syscall_pre_impl_ktrace(long long fname, long long ops, + long long facs, long long pid); +void __sanitizer_syscall_post_impl_ktrace(long long res, long long fname, + long long ops, long long facs, + long long pid); +void __sanitizer_syscall_pre_impl_compat_13_sigaction13(long long signum, + long long nsa, + long long osa); +void __sanitizer_syscall_post_impl_compat_13_sigaction13(long long res, + long long signum, + long long nsa, + long long osa); +void __sanitizer_syscall_pre_impl_getgid(void); +void __sanitizer_syscall_post_impl_getgid(long long res); +void __sanitizer_syscall_pre_impl_compat_13_sigprocmask13(long long how, + long long mask); +void __sanitizer_syscall_post_impl_compat_13_sigprocmask13(long long res, + long long how, + long long mask); +void __sanitizer_syscall_pre_impl___getlogin(long long namebuf, + long long namelen); +void __sanitizer_syscall_post_impl___getlogin(long long res, long long namebuf, + long long namelen); +void __sanitizer_syscall_pre_impl___setlogin(long long namebuf); +void __sanitizer_syscall_post_impl___setlogin(long long res, long long namebuf); +void __sanitizer_syscall_pre_impl_acct(long long path); +void __sanitizer_syscall_post_impl_acct(long long res, long long path); +void __sanitizer_syscall_pre_impl_compat_13_sigpending13(void); +void __sanitizer_syscall_post_impl_compat_13_sigpending13(long long res); +void __sanitizer_syscall_pre_impl_compat_13_sigaltstack13(long long nss, + long long oss); +void __sanitizer_syscall_post_impl_compat_13_sigaltstack13(long long res, + long long nss, + long long oss); +void __sanitizer_syscall_pre_impl_ioctl(long long fd, long long com, + long long data); +void __sanitizer_syscall_post_impl_ioctl(long long res, long long fd, + long long com, long long data); +void __sanitizer_syscall_pre_impl_compat_12_oreboot(long long opt); +void __sanitizer_syscall_post_impl_compat_12_oreboot(long long res, + long long opt); +void __sanitizer_syscall_pre_impl_revoke(long long path); +void __sanitizer_syscall_post_impl_revoke(long long res, long long path); +void __sanitizer_syscall_pre_impl_symlink(long long path, long long link); +void __sanitizer_syscall_post_impl_symlink(long long res, long long path, + long long link); +void __sanitizer_syscall_pre_impl_readlink(long long path, long long buf, + long long count); +void __sanitizer_syscall_post_impl_readlink(long long res, long long path, + long long buf, long long count); +void __sanitizer_syscall_pre_impl_execve(long long path, long long argp, + long long envp); +void __sanitizer_syscall_post_impl_execve(long long res, long long path, + long long argp, long long envp); +void __sanitizer_syscall_pre_impl_umask(long long newmask); +void __sanitizer_syscall_post_impl_umask(long long res, long long newmask); +void __sanitizer_syscall_pre_impl_chroot(long long path); +void __sanitizer_syscall_post_impl_chroot(long long res, long long path); +void __sanitizer_syscall_pre_impl_compat_43_fstat43(long long fd, long long sb); +void __sanitizer_syscall_post_impl_compat_43_fstat43(long long res, + long long fd, + long long sb); +void __sanitizer_syscall_pre_impl_compat_43_ogetkerninfo(long long op, + long long where, + long long size, + long long arg); +void __sanitizer_syscall_post_impl_compat_43_ogetkerninfo(long long res, + long long op, + long long where, + long long size, + long long arg); +void __sanitizer_syscall_pre_impl_compat_43_ogetpagesize(void); +void __sanitizer_syscall_post_impl_compat_43_ogetpagesize(long long res); +void __sanitizer_syscall_pre_impl_compat_12_msync(long long addr, + long long len); +void __sanitizer_syscall_post_impl_compat_12_msync(long long res, + long long addr, + long long len); +void __sanitizer_syscall_pre_impl_vfork(void); +void __sanitizer_syscall_post_impl_vfork(long long res); +/* syscall 67 has been skipped */ +/* syscall 68 has been skipped */ +/* syscall 69 has been skipped */ +/* syscall 70 has been skipped */ +void __sanitizer_syscall_pre_impl_compat_43_ommap(long long addr, long long len, + long long prot, + long long flags, long long fd, + long long pos); +void __sanitizer_syscall_post_impl_compat_43_ommap( + long long res, long long addr, long long len, long long prot, + long long flags, long long fd, long long pos); +void __sanitizer_syscall_pre_impl_vadvise(long long anom); +void __sanitizer_syscall_post_impl_vadvise(long long res, long long anom); +void __sanitizer_syscall_pre_impl_munmap(long long addr, long long len); +void __sanitizer_syscall_post_impl_munmap(long long res, long long addr, + long long len); +void __sanitizer_syscall_pre_impl_mprotect(long long addr, long long len, + long long prot); +void __sanitizer_syscall_post_impl_mprotect(long long res, long long addr, + long long len, long long prot); +void __sanitizer_syscall_pre_impl_madvise(long long addr, long long len, + long long behav); +void __sanitizer_syscall_post_impl_madvise(long long res, long long addr, + long long len, long long behav); +/* syscall 76 has been skipped */ +/* syscall 77 has been skipped */ +void __sanitizer_syscall_pre_impl_mincore(long long addr, long long len, + long long vec); +void __sanitizer_syscall_post_impl_mincore(long long res, long long addr, + long long len, long long vec); +void __sanitizer_syscall_pre_impl_getgroups(long long gidsetsize, + long long gidset); +void __sanitizer_syscall_post_impl_getgroups(long long res, + long long gidsetsize, + long long gidset); +void __sanitizer_syscall_pre_impl_setgroups(long long gidsetsize, + long long gidset); +void __sanitizer_syscall_post_impl_setgroups(long long res, + long long gidsetsize, + long long gidset); +void __sanitizer_syscall_pre_impl_getpgrp(void); +void __sanitizer_syscall_post_impl_getpgrp(long long res); +void __sanitizer_syscall_pre_impl_setpgid(long long pid, long long pgid); +void __sanitizer_syscall_post_impl_setpgid(long long res, long long pid, + long long pgid); +void __sanitizer_syscall_pre_impl_compat_50_setitimer(long long which, + long long itv, + long long oitv); +void __sanitizer_syscall_post_impl_compat_50_setitimer(long long res, + long long which, + long long itv, + long long oitv); +void __sanitizer_syscall_pre_impl_compat_43_owait(void); +void __sanitizer_syscall_post_impl_compat_43_owait(long long res); +void __sanitizer_syscall_pre_impl_compat_12_oswapon(long long name); +void __sanitizer_syscall_post_impl_compat_12_oswapon(long long res, + long long name); +void __sanitizer_syscall_pre_impl_compat_50_getitimer(long long which, + long long itv); +void __sanitizer_syscall_post_impl_compat_50_getitimer(long long res, + long long which, + long long itv); +void __sanitizer_syscall_pre_impl_compat_43_ogethostname(long long hostname, + long long len); +void __sanitizer_syscall_post_impl_compat_43_ogethostname(long long res, + long long hostname, + long long len); +void __sanitizer_syscall_pre_impl_compat_43_osethostname(long long hostname, + long long len); +void __sanitizer_syscall_post_impl_compat_43_osethostname(long long res, + long long hostname, + long long len); +void __sanitizer_syscall_pre_impl_compat_43_ogetdtablesize(void); +void __sanitizer_syscall_post_impl_compat_43_ogetdtablesize(long long res); +void __sanitizer_syscall_pre_impl_dup2(long long from, long long to); +void __sanitizer_syscall_post_impl_dup2(long long res, long long from, + long long to); +/* syscall 91 has been skipped */ +void __sanitizer_syscall_pre_impl_fcntl(long long fd, long long cmd, + long long arg); +void __sanitizer_syscall_post_impl_fcntl(long long res, long long fd, + long long cmd, long long arg); +void __sanitizer_syscall_pre_impl_compat_50_select(long long nd, long long in, + long long ou, long long ex, + long long tv); +void __sanitizer_syscall_post_impl_compat_50_select(long long res, long long nd, + long long in, long long ou, + long long ex, long long tv); +/* syscall 94 has been skipped */ +void __sanitizer_syscall_pre_impl_fsync(long long fd); +void __sanitizer_syscall_post_impl_fsync(long long res, long long fd); +void __sanitizer_syscall_pre_impl_setpriority(long long which, long long who, + long long prio); +void __sanitizer_syscall_post_impl_setpriority(long long res, long long which, + long long who, long long prio); +void __sanitizer_syscall_pre_impl_compat_30_socket(long long domain, + long long type, + long long protocol); +void __sanitizer_syscall_post_impl_compat_30_socket(long long res, + long long domain, + long long type, + long long protocol); +void __sanitizer_syscall_pre_impl_connect(long long s, long long name, + long long namelen); +void __sanitizer_syscall_post_impl_connect(long long res, long long s, + long long name, long long namelen); +void __sanitizer_syscall_pre_impl_compat_43_oaccept(long long s, long long name, + long long anamelen); +void __sanitizer_syscall_post_impl_compat_43_oaccept(long long res, long long s, + long long name, + long long anamelen); +void __sanitizer_syscall_pre_impl_getpriority(long long which, long long who); +void __sanitizer_syscall_post_impl_getpriority(long long res, long long which, + long long who); +void __sanitizer_syscall_pre_impl_compat_43_osend(long long s, long long buf, + long long len, + long long flags); +void __sanitizer_syscall_post_impl_compat_43_osend(long long res, long long s, + long long buf, long long len, + long long flags); +void __sanitizer_syscall_pre_impl_compat_43_orecv(long long s, long long buf, + long long len, + long long flags); +void __sanitizer_syscall_post_impl_compat_43_orecv(long long res, long long s, + long long buf, long long len, + long long flags); +void __sanitizer_syscall_pre_impl_compat_13_sigreturn13(long long sigcntxp); +void __sanitizer_syscall_post_impl_compat_13_sigreturn13(long long res, + long long sigcntxp); +void __sanitizer_syscall_pre_impl_bind(long long s, long long name, + long long namelen); +void __sanitizer_syscall_post_impl_bind(long long res, long long s, + long long name, long long namelen); +void __sanitizer_syscall_pre_impl_setsockopt(long long s, long long level, + long long name, long long val, + long long valsize); +void __sanitizer_syscall_post_impl_setsockopt(long long res, long long s, + long long level, long long name, + long long val, long long valsize); +void __sanitizer_syscall_pre_impl_listen(long long s, long long backlog); +void __sanitizer_syscall_post_impl_listen(long long res, long long s, + long long backlog); +/* syscall 107 has been skipped */ +void __sanitizer_syscall_pre_impl_compat_43_osigvec(long long signum, + long long nsv, + long long osv); +void __sanitizer_syscall_post_impl_compat_43_osigvec(long long res, + long long signum, + long long nsv, + long long osv); +void __sanitizer_syscall_pre_impl_compat_43_osigblock(long long mask); +void __sanitizer_syscall_post_impl_compat_43_osigblock(long long res, + long long mask); +void __sanitizer_syscall_pre_impl_compat_43_osigsetmask(long long mask); +void __sanitizer_syscall_post_impl_compat_43_osigsetmask(long long res, + long long mask); +void __sanitizer_syscall_pre_impl_compat_13_sigsuspend13(long long mask); +void __sanitizer_syscall_post_impl_compat_13_sigsuspend13(long long res, + long long mask); +void __sanitizer_syscall_pre_impl_compat_43_osigstack(long long nss, + long long oss); +void __sanitizer_syscall_post_impl_compat_43_osigstack(long long res, + long long nss, + long long oss); +void __sanitizer_syscall_pre_impl_compat_43_orecvmsg(long long s, long long msg, + long long flags); +void __sanitizer_syscall_post_impl_compat_43_orecvmsg(long long res, + long long s, + long long msg, + long long flags); +void __sanitizer_syscall_pre_impl_compat_43_osendmsg(long long s, long long msg, + long long flags); +void __sanitizer_syscall_post_impl_compat_43_osendmsg(long long res, + long long s, + long long msg, + long long flags); +/* syscall 115 has been skipped */ +void __sanitizer_syscall_pre_impl_compat_50_gettimeofday(long long tp, + long long tzp); +void __sanitizer_syscall_post_impl_compat_50_gettimeofday(long long res, + long long tp, + long long tzp); +void __sanitizer_syscall_pre_impl_compat_50_getrusage(long long who, + long long rusage); +void __sanitizer_syscall_post_impl_compat_50_getrusage(long long res, + long long who, + long long rusage); +void __sanitizer_syscall_pre_impl_getsockopt(long long s, long long level, + long long name, long long val, + long long avalsize); +void __sanitizer_syscall_post_impl_getsockopt(long long res, long long s, + long long level, long long name, + long long val, + long long avalsize); +/* syscall 119 has been skipped */ +void __sanitizer_syscall_pre_impl_readv(long long fd, long long iovp, + long long iovcnt); +void __sanitizer_syscall_post_impl_readv(long long res, long long fd, + long long iovp, long long iovcnt); +void __sanitizer_syscall_pre_impl_writev(long long fd, long long iovp, + long long iovcnt); +void __sanitizer_syscall_post_impl_writev(long long res, long long fd, + long long iovp, long long iovcnt); +void __sanitizer_syscall_pre_impl_compat_50_settimeofday(long long tv, + long long tzp); +void __sanitizer_syscall_post_impl_compat_50_settimeofday(long long res, + long long tv, + long long tzp); +void __sanitizer_syscall_pre_impl_fchown(long long fd, long long uid, + long long gid); +void __sanitizer_syscall_post_impl_fchown(long long res, long long fd, + long long uid, long long gid); +void __sanitizer_syscall_pre_impl_fchmod(long long fd, long long mode); +void __sanitizer_syscall_post_impl_fchmod(long long res, long long fd, + long long mode); +void __sanitizer_syscall_pre_impl_compat_43_orecvfrom( + long long s, long long buf, long long len, long long flags, long long from, + long long fromlenaddr); +void __sanitizer_syscall_post_impl_compat_43_orecvfrom( + long long res, long long s, long long buf, long long len, long long flags, + long long from, long long fromlenaddr); +void __sanitizer_syscall_pre_impl_setreuid(long long ruid, long long euid); +void __sanitizer_syscall_post_impl_setreuid(long long res, long long ruid, + long long euid); +void __sanitizer_syscall_pre_impl_setregid(long long rgid, long long egid); +void __sanitizer_syscall_post_impl_setregid(long long res, long long rgid, + long long egid); +void __sanitizer_syscall_pre_impl_rename(long long from, long long to); +void __sanitizer_syscall_post_impl_rename(long long res, long long from, + long long to); +void __sanitizer_syscall_pre_impl_compat_43_otruncate(long long path, + long long length); +void __sanitizer_syscall_post_impl_compat_43_otruncate(long long res, + long long path, + long long length); +void __sanitizer_syscall_pre_impl_compat_43_oftruncate(long long fd, + long long length); +void __sanitizer_syscall_post_impl_compat_43_oftruncate(long long res, + long long fd, + long long length); +void __sanitizer_syscall_pre_impl_flock(long long fd, long long how); +void __sanitizer_syscall_post_impl_flock(long long res, long long fd, + long long how); +void __sanitizer_syscall_pre_impl_mkfifo(long long path, long long mode); +void __sanitizer_syscall_post_impl_mkfifo(long long res, long long path, + long long mode); +void __sanitizer_syscall_pre_impl_sendto(long long s, long long buf, + long long len, long long flags, + long long to, long long tolen); +void __sanitizer_syscall_post_impl_sendto(long long res, long long s, + long long buf, long long len, + long long flags, long long to, + long long tolen); +void __sanitizer_syscall_pre_impl_shutdown(long long s, long long how); +void __sanitizer_syscall_post_impl_shutdown(long long res, long long s, + long long how); +void __sanitizer_syscall_pre_impl_socketpair(long long domain, long long type, + long long protocol, long long rsv); +void __sanitizer_syscall_post_impl_socketpair(long long res, long long domain, + long long type, + long long protocol, + long long rsv); +void __sanitizer_syscall_pre_impl_mkdir(long long path, long long mode); +void __sanitizer_syscall_post_impl_mkdir(long long res, long long path, + long long mode); +void __sanitizer_syscall_pre_impl_rmdir(long long path); +void __sanitizer_syscall_post_impl_rmdir(long long res, long long path); +void __sanitizer_syscall_pre_impl_compat_50_utimes(long long path, + long long tptr); +void __sanitizer_syscall_post_impl_compat_50_utimes(long long res, + long long path, + long long tptr); +/* syscall 139 has been skipped */ +void __sanitizer_syscall_pre_impl_compat_50_adjtime(long long delta, + long long olddelta); +void __sanitizer_syscall_post_impl_compat_50_adjtime(long long res, + long long delta, + long long olddelta); +void __sanitizer_syscall_pre_impl_compat_43_ogetpeername(long long fdes, + long long asa, + long long alen); +void __sanitizer_syscall_post_impl_compat_43_ogetpeername(long long res, + long long fdes, + long long asa, + long long alen); +void __sanitizer_syscall_pre_impl_compat_43_ogethostid(void); +void __sanitizer_syscall_post_impl_compat_43_ogethostid(long long res); +void __sanitizer_syscall_pre_impl_compat_43_osethostid(long long hostid); +void __sanitizer_syscall_post_impl_compat_43_osethostid(long long res, + long long hostid); +void __sanitizer_syscall_pre_impl_compat_43_ogetrlimit(long long which, + long long rlp); +void __sanitizer_syscall_post_impl_compat_43_ogetrlimit(long long res, + long long which, + long long rlp); +void __sanitizer_syscall_pre_impl_compat_43_osetrlimit(long long which, + long long rlp); +void __sanitizer_syscall_post_impl_compat_43_osetrlimit(long long res, + long long which, + long long rlp); +void __sanitizer_syscall_pre_impl_compat_43_okillpg(long long pgid, + long long signum); +void __sanitizer_syscall_post_impl_compat_43_okillpg(long long res, + long long pgid, + long long signum); +void __sanitizer_syscall_pre_impl_setsid(void); +void __sanitizer_syscall_post_impl_setsid(long long res); +void __sanitizer_syscall_pre_impl_compat_50_quotactl(long long path, + long long cmd, + long long uid, + long long arg); +void __sanitizer_syscall_post_impl_compat_50_quotactl( + long long res, long long path, long long cmd, long long uid, long long arg); +void __sanitizer_syscall_pre_impl_compat_43_oquota(void); +void __sanitizer_syscall_post_impl_compat_43_oquota(long long res); +void __sanitizer_syscall_pre_impl_compat_43_ogetsockname(long long fdec, + long long asa, + long long alen); +void __sanitizer_syscall_post_impl_compat_43_ogetsockname(long long res, + long long fdec, + long long asa, + long long alen); +/* syscall 151 has been skipped */ +/* syscall 152 has been skipped */ +/* syscall 153 has been skipped */ +/* syscall 154 has been skipped */ +void __sanitizer_syscall_pre_impl_nfssvc(long long flag, long long argp); +void __sanitizer_syscall_post_impl_nfssvc(long long res, long long flag, + long long argp); +void __sanitizer_syscall_pre_impl_compat_43_ogetdirentries(long long fd, + long long buf, + long long count, + long long basep); +void __sanitizer_syscall_post_impl_compat_43_ogetdirentries(long long res, + long long fd, + long long buf, + long long count, + long long basep); +void __sanitizer_syscall_pre_impl_compat_20_statfs(long long path, + long long buf); +void __sanitizer_syscall_post_impl_compat_20_statfs(long long res, + long long path, + long long buf); +void __sanitizer_syscall_pre_impl_compat_20_fstatfs(long long fd, + long long buf); +void __sanitizer_syscall_post_impl_compat_20_fstatfs(long long res, + long long fd, + long long buf); +/* syscall 159 has been skipped */ +/* syscall 160 has been skipped */ +void __sanitizer_syscall_pre_impl_compat_30_getfh(long long fname, + long long fhp); +void __sanitizer_syscall_post_impl_compat_30_getfh(long long res, + long long fname, + long long fhp); +void __sanitizer_syscall_pre_impl_compat_09_ogetdomainname(long long domainname, + long long len); +void __sanitizer_syscall_post_impl_compat_09_ogetdomainname( + long long res, long long domainname, long long len); +void __sanitizer_syscall_pre_impl_compat_09_osetdomainname(long long domainname, + long long len); +void __sanitizer_syscall_post_impl_compat_09_osetdomainname( + long long res, long long domainname, long long len); +void __sanitizer_syscall_pre_impl_compat_09_ouname(long long name); +void __sanitizer_syscall_post_impl_compat_09_ouname(long long res, + long long name); +void __sanitizer_syscall_pre_impl_sysarch(long long op, long long parms); +void __sanitizer_syscall_post_impl_sysarch(long long res, long long op, + long long parms); +/* syscall 166 has been skipped */ +/* syscall 167 has been skipped */ +/* syscall 168 has been skipped */ +#if !defined(_LP64) +void __sanitizer_syscall_pre_impl_compat_10_osemsys(long long which, + long long a2, long long a3, + long long a4, long long a5); +void __sanitizer_syscall_post_impl_compat_10_osemsys(long long res, + long long which, + long long a2, long long a3, + long long a4, + long long a5); +#else +/* syscall 169 has been skipped */ +#endif +#if !defined(_LP64) +void __sanitizer_syscall_pre_impl_compat_10_omsgsys(long long which, + long long a2, long long a3, + long long a4, long long a5, + long long a6); +void __sanitizer_syscall_post_impl_compat_10_omsgsys(long long res, + long long which, + long long a2, long long a3, + long long a4, long long a5, + long long a6); +#else +/* syscall 170 has been skipped */ +#endif +#if !defined(_LP64) +void __sanitizer_syscall_pre_impl_compat_10_oshmsys(long long which, + long long a2, long long a3, + long long a4); +void __sanitizer_syscall_post_impl_compat_10_oshmsys(long long res, + long long which, + long long a2, long long a3, + long long a4); +#else +/* syscall 171 has been skipped */ +#endif +/* syscall 172 has been skipped */ +void __sanitizer_syscall_pre_impl_pread(long long fd, long long buf, + long long nbyte, long long PAD, + long long offset); +void __sanitizer_syscall_post_impl_pread(long long res, long long fd, + long long buf, long long nbyte, + long long PAD, long long offset); +void __sanitizer_syscall_pre_impl_pwrite(long long fd, long long buf, + long long nbyte, long long PAD, + long long offset); +void __sanitizer_syscall_post_impl_pwrite(long long res, long long fd, + long long buf, long long nbyte, + long long PAD, long long offset); +void __sanitizer_syscall_pre_impl_compat_30_ntp_gettime(long long ntvp); +void __sanitizer_syscall_post_impl_compat_30_ntp_gettime(long long res, + long long ntvp); +#if defined(NTP) || !defined(_KERNEL_OPT) +void __sanitizer_syscall_pre_impl_ntp_adjtime(long long tp); +void __sanitizer_syscall_post_impl_ntp_adjtime(long long res, long long tp); +#else +/* syscall 176 has been skipped */ +#endif +/* syscall 177 has been skipped */ +/* syscall 178 has been skipped */ +/* syscall 179 has been skipped */ +/* syscall 180 has been skipped */ +void __sanitizer_syscall_pre_impl_setgid(long long gid); +void __sanitizer_syscall_post_impl_setgid(long long res, long long gid); +void __sanitizer_syscall_pre_impl_setegid(long long egid); +void __sanitizer_syscall_post_impl_setegid(long long res, long long egid); +void __sanitizer_syscall_pre_impl_seteuid(long long euid); +void __sanitizer_syscall_post_impl_seteuid(long long res, long long euid); +void __sanitizer_syscall_pre_impl_lfs_bmapv(long long fsidp, long long blkiov, + long long blkcnt); +void __sanitizer_syscall_post_impl_lfs_bmapv(long long res, long long fsidp, + long long blkiov, + long long blkcnt); +void __sanitizer_syscall_pre_impl_lfs_markv(long long fsidp, long long blkiov, + long long blkcnt); +void __sanitizer_syscall_post_impl_lfs_markv(long long res, long long fsidp, + long long blkiov, + long long blkcnt); +void __sanitizer_syscall_pre_impl_lfs_segclean(long long fsidp, + long long segment); +void __sanitizer_syscall_post_impl_lfs_segclean(long long res, long long fsidp, + long long segment); +void __sanitizer_syscall_pre_impl_compat_50_lfs_segwait(long long fsidp, + long long tv); +void __sanitizer_syscall_post_impl_compat_50_lfs_segwait(long long res, + long long fsidp, + long long tv); +void __sanitizer_syscall_pre_impl_compat_12_stat12(long long path, + long long ub); +void __sanitizer_syscall_post_impl_compat_12_stat12(long long res, + long long path, + long long ub); +void __sanitizer_syscall_pre_impl_compat_12_fstat12(long long fd, long long sb); +void __sanitizer_syscall_post_impl_compat_12_fstat12(long long res, + long long fd, + long long sb); +void __sanitizer_syscall_pre_impl_compat_12_lstat12(long long path, + long long ub); +void __sanitizer_syscall_post_impl_compat_12_lstat12(long long res, + long long path, + long long ub); +void __sanitizer_syscall_pre_impl_pathconf(long long path, long long name); +void __sanitizer_syscall_post_impl_pathconf(long long res, long long path, + long long name); +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_getrlimit(long long which, long long rlp); +void __sanitizer_syscall_post_impl_getrlimit(long long res, long long which, + long long rlp); +void __sanitizer_syscall_pre_impl_setrlimit(long long which, long long rlp); +void __sanitizer_syscall_post_impl_setrlimit(long long res, long long which, + long long rlp); +void __sanitizer_syscall_pre_impl_compat_12_getdirentries(long long fd, + long long buf, + long long count, + long long basep); +void __sanitizer_syscall_post_impl_compat_12_getdirentries(long long res, + long long fd, + long long buf, + long long count, + long long basep); +void __sanitizer_syscall_pre_impl_mmap(long long addr, long long len, + long long prot, long long flags, + long long fd, long long PAD, + long long pos); +void __sanitizer_syscall_post_impl_mmap(long long res, long long addr, + long long len, long long prot, + long long flags, long long fd, + long long PAD, long long pos); +void __sanitizer_syscall_pre_impl___syscall(long long code, long long arg0, + long long arg1, long long arg2, + long long arg3, long long arg4, + long long arg5, long long arg6, + long long arg7); +void __sanitizer_syscall_post_impl___syscall(long long res, long long code, + long long arg0, long long arg1, + long long arg2, long long arg3, + long long arg4, long long arg5, + long long arg6, long long arg7); +void __sanitizer_syscall_pre_impl_lseek(long long fd, long long PAD, + long long offset, long long whence); +void __sanitizer_syscall_post_impl_lseek(long long res, long long fd, + long long PAD, long long offset, + long long whence); +void __sanitizer_syscall_pre_impl_truncate(long long path, long long PAD, + long long length); +void __sanitizer_syscall_post_impl_truncate(long long res, long long path, + long long PAD, long long length); +void __sanitizer_syscall_pre_impl_ftruncate(long long fd, long long PAD, + long long length); +void __sanitizer_syscall_post_impl_ftruncate(long long res, long long fd, + long long PAD, long long length); +void __sanitizer_syscall_pre_impl___sysctl(long long name, long long namelen, + long long oldv, long long oldlenp, + long long newv, long long newlen); +void __sanitizer_syscall_post_impl___sysctl(long long res, long long name, + long long namelen, long long oldv, + long long oldlenp, long long newv, + long long newlen); +void __sanitizer_syscall_pre_impl_mlock(long long addr, long long len); +void __sanitizer_syscall_post_impl_mlock(long long res, long long addr, + long long len); +void __sanitizer_syscall_pre_impl_munlock(long long addr, long long len); +void __sanitizer_syscall_post_impl_munlock(long long res, long long addr, + long long len); +void __sanitizer_syscall_pre_impl_undelete(long long path); +void __sanitizer_syscall_post_impl_undelete(long long res, long long path); +void __sanitizer_syscall_pre_impl_compat_50_futimes(long long fd, + long long tptr); +void __sanitizer_syscall_post_impl_compat_50_futimes(long long res, + long long fd, + long long tptr); +void __sanitizer_syscall_pre_impl_getpgid(long long pid); +void __sanitizer_syscall_post_impl_getpgid(long long res, long long pid); +void __sanitizer_syscall_pre_impl_reboot(long long opt, long long bootstr); +void __sanitizer_syscall_post_impl_reboot(long long res, long long opt, + long long bootstr); +void __sanitizer_syscall_pre_impl_poll(long long fds, long long nfds, + long long timeout); +void __sanitizer_syscall_post_impl_poll(long long res, long long fds, + long long nfds, long long timeout); +void __sanitizer_syscall_pre_impl_afssys(long long id, long long a1, + long long a2, long long a3, + long long a4, long long a5, + long long a6); +void __sanitizer_syscall_post_impl_afssys(long long res, long long id, + long long a1, long long a2, + long long a3, long long a4, + long long a5, long long a6); +/* syscall 211 has been skipped */ +/* syscall 212 has been skipped */ +/* syscall 213 has been skipped */ +/* syscall 214 has been skipped */ +/* syscall 215 has been skipped */ +/* syscall 216 has been skipped */ +/* syscall 217 has been skipped */ +/* syscall 218 has been skipped */ +/* syscall 219 has been skipped */ +void __sanitizer_syscall_pre_impl_compat_14___semctl(long long semid, + long long semnum, + long long cmd, + long long arg); +void __sanitizer_syscall_post_impl_compat_14___semctl(long long res, + long long semid, + long long semnum, + long long cmd, + long long arg); +void __sanitizer_syscall_pre_impl_semget(long long key, long long nsems, + long long semflg); +void __sanitizer_syscall_post_impl_semget(long long res, long long key, + long long nsems, long long semflg); +void __sanitizer_syscall_pre_impl_semop(long long semid, long long sops, + long long nsops); +void __sanitizer_syscall_post_impl_semop(long long res, long long semid, + long long sops, long long nsops); +void __sanitizer_syscall_pre_impl_semconfig(long long flag); +void __sanitizer_syscall_post_impl_semconfig(long long res, long long flag); +void __sanitizer_syscall_pre_impl_compat_14_msgctl(long long msqid, + long long cmd, + long long buf); +void __sanitizer_syscall_post_impl_compat_14_msgctl(long long res, + long long msqid, + long long cmd, + long long buf); +void __sanitizer_syscall_pre_impl_msgget(long long key, long long msgflg); +void __sanitizer_syscall_post_impl_msgget(long long res, long long key, + long long msgflg); +void __sanitizer_syscall_pre_impl_msgsnd(long long msqid, long long msgp, + long long msgsz, long long msgflg); +void __sanitizer_syscall_post_impl_msgsnd(long long res, long long msqid, + long long msgp, long long msgsz, + long long msgflg); +void __sanitizer_syscall_pre_impl_msgrcv(long long msqid, long long msgp, + long long msgsz, long long msgtyp, + long long msgflg); +void __sanitizer_syscall_post_impl_msgrcv(long long res, long long msqid, + long long msgp, long long msgsz, + long long msgtyp, long long msgflg); +void __sanitizer_syscall_pre_impl_shmat(long long shmid, long long shmaddr, + long long shmflg); +void __sanitizer_syscall_post_impl_shmat(long long res, long long shmid, + long long shmaddr, long long shmflg); +void __sanitizer_syscall_pre_impl_compat_14_shmctl(long long shmid, + long long cmd, + long long buf); +void __sanitizer_syscall_post_impl_compat_14_shmctl(long long res, + long long shmid, + long long cmd, + long long buf); +void __sanitizer_syscall_pre_impl_shmdt(long long shmaddr); +void __sanitizer_syscall_post_impl_shmdt(long long res, long long shmaddr); +void __sanitizer_syscall_pre_impl_shmget(long long key, long long size, + long long shmflg); +void __sanitizer_syscall_post_impl_shmget(long long res, long long key, + long long size, long long shmflg); +void __sanitizer_syscall_pre_impl_compat_50_clock_gettime(long long clock_id, + long long tp); +void __sanitizer_syscall_post_impl_compat_50_clock_gettime(long long res, + long long clock_id, + long long tp); +void __sanitizer_syscall_pre_impl_compat_50_clock_settime(long long clock_id, + long long tp); +void __sanitizer_syscall_post_impl_compat_50_clock_settime(long long res, + long long clock_id, + long long tp); +void __sanitizer_syscall_pre_impl_compat_50_clock_getres(long long clock_id, + long long tp); +void __sanitizer_syscall_post_impl_compat_50_clock_getres(long long res, + long long clock_id, + long long tp); +void __sanitizer_syscall_pre_impl_timer_create(long long clock_id, + long long evp, + long long timerid); +void __sanitizer_syscall_post_impl_timer_create(long long res, + long long clock_id, + long long evp, + long long timerid); +void __sanitizer_syscall_pre_impl_timer_delete(long long timerid); +void __sanitizer_syscall_post_impl_timer_delete(long long res, + long long timerid); +void __sanitizer_syscall_pre_impl_compat_50_timer_settime(long long timerid, + long long flags, + long long value, + long long ovalue); +void __sanitizer_syscall_post_impl_compat_50_timer_settime(long long res, + long long timerid, + long long flags, + long long value, + long long ovalue); +void __sanitizer_syscall_pre_impl_compat_50_timer_gettime(long long timerid, + long long value); +void __sanitizer_syscall_post_impl_compat_50_timer_gettime(long long res, + long long timerid, + long long value); +void __sanitizer_syscall_pre_impl_timer_getoverrun(long long timerid); +void __sanitizer_syscall_post_impl_timer_getoverrun(long long res, + long long timerid); +void __sanitizer_syscall_pre_impl_compat_50_nanosleep(long long rqtp, + long long rmtp); +void __sanitizer_syscall_post_impl_compat_50_nanosleep(long long res, + long long rqtp, + long long rmtp); +void __sanitizer_syscall_pre_impl_fdatasync(long long fd); +void __sanitizer_syscall_post_impl_fdatasync(long long res, long long fd); +void __sanitizer_syscall_pre_impl_mlockall(long long flags); +void __sanitizer_syscall_post_impl_mlockall(long long res, long long flags); +void __sanitizer_syscall_pre_impl_munlockall(void); +void __sanitizer_syscall_post_impl_munlockall(long long res); +void __sanitizer_syscall_pre_impl_compat_50___sigtimedwait(long long set, + long long info, + long long timeout); +void __sanitizer_syscall_post_impl_compat_50___sigtimedwait(long long res, + long long set, + long long info, + long long timeout); +void __sanitizer_syscall_pre_impl_sigqueueinfo(long long pid, long long info); +void __sanitizer_syscall_post_impl_sigqueueinfo(long long res, long long pid, + long long info); +void __sanitizer_syscall_pre_impl_modctl(long long cmd, long long arg); +void __sanitizer_syscall_post_impl_modctl(long long res, long long cmd, + long long arg); +void __sanitizer_syscall_pre_impl__ksem_init(long long value, long long idp); +void __sanitizer_syscall_post_impl__ksem_init(long long res, long long value, + long long idp); +void __sanitizer_syscall_pre_impl__ksem_open(long long name, long long oflag, + long long mode, long long value, + long long idp); +void __sanitizer_syscall_post_impl__ksem_open(long long res, long long name, + long long oflag, long long mode, + long long value, long long idp); +void __sanitizer_syscall_pre_impl__ksem_unlink(long long name); +void __sanitizer_syscall_post_impl__ksem_unlink(long long res, long long name); +void __sanitizer_syscall_pre_impl__ksem_close(long long id); +void __sanitizer_syscall_post_impl__ksem_close(long long res, long long id); +void __sanitizer_syscall_pre_impl__ksem_post(long long id); +void __sanitizer_syscall_post_impl__ksem_post(long long res, long long id); +void __sanitizer_syscall_pre_impl__ksem_wait(long long id); +void __sanitizer_syscall_post_impl__ksem_wait(long long res, long long id); +void __sanitizer_syscall_pre_impl__ksem_trywait(long long id); +void __sanitizer_syscall_post_impl__ksem_trywait(long long res, long long id); +void __sanitizer_syscall_pre_impl__ksem_getvalue(long long id, long long value); +void __sanitizer_syscall_post_impl__ksem_getvalue(long long res, long long id, + long long value); +void __sanitizer_syscall_pre_impl__ksem_destroy(long long id); +void __sanitizer_syscall_post_impl__ksem_destroy(long long res, long long id); +void __sanitizer_syscall_pre_impl__ksem_timedwait(long long id, + long long abstime); +void __sanitizer_syscall_post_impl__ksem_timedwait(long long res, long long id, + long long abstime); +void __sanitizer_syscall_pre_impl_mq_open(long long name, long long oflag, + long long mode, long long attr); +void __sanitizer_syscall_post_impl_mq_open(long long res, long long name, + long long oflag, long long mode, + long long attr); +void __sanitizer_syscall_pre_impl_mq_close(long long mqdes); +void __sanitizer_syscall_post_impl_mq_close(long long res, long long mqdes); +void __sanitizer_syscall_pre_impl_mq_unlink(long long name); +void __sanitizer_syscall_post_impl_mq_unlink(long long res, long long name); +void __sanitizer_syscall_pre_impl_mq_getattr(long long mqdes, long long mqstat); +void __sanitizer_syscall_post_impl_mq_getattr(long long res, long long mqdes, + long long mqstat); +void __sanitizer_syscall_pre_impl_mq_setattr(long long mqdes, long long mqstat, + long long omqstat); +void __sanitizer_syscall_post_impl_mq_setattr(long long res, long long mqdes, + long long mqstat, + long long omqstat); +void __sanitizer_syscall_pre_impl_mq_notify(long long mqdes, + long long notification); +void __sanitizer_syscall_post_impl_mq_notify(long long res, long long mqdes, + long long notification); +void __sanitizer_syscall_pre_impl_mq_send(long long mqdes, long long msg_ptr, + long long msg_len, + long long msg_prio); +void __sanitizer_syscall_post_impl_mq_send(long long res, long long mqdes, + long long msg_ptr, long long msg_len, + long long msg_prio); +void __sanitizer_syscall_pre_impl_mq_receive(long long mqdes, long long msg_ptr, + long long msg_len, + long long msg_prio); +void __sanitizer_syscall_post_impl_mq_receive(long long res, long long mqdes, + long long msg_ptr, + long long msg_len, + long long msg_prio); +void __sanitizer_syscall_pre_impl_compat_50_mq_timedsend(long long mqdes, + long long msg_ptr, + long long msg_len, + long long msg_prio, + long long abs_timeout); +void __sanitizer_syscall_post_impl_compat_50_mq_timedsend( + long long res, long long mqdes, long long msg_ptr, long long msg_len, + long long msg_prio, long long abs_timeout); +void __sanitizer_syscall_pre_impl_compat_50_mq_timedreceive( + long long mqdes, long long msg_ptr, long long msg_len, long long msg_prio, + long long abs_timeout); +void __sanitizer_syscall_post_impl_compat_50_mq_timedreceive( + long long res, long long mqdes, long long msg_ptr, long long msg_len, + long long msg_prio, long long abs_timeout); +/* syscall 267 has been skipped */ +/* syscall 268 has been skipped */ +/* syscall 269 has been skipped */ +void __sanitizer_syscall_pre_impl___posix_rename(long long from, long long to); +void __sanitizer_syscall_post_impl___posix_rename(long long res, long long from, + long long to); +void __sanitizer_syscall_pre_impl_swapctl(long long cmd, long long arg, + long long misc); +void __sanitizer_syscall_post_impl_swapctl(long long res, long long cmd, + long long arg, long long misc); +void __sanitizer_syscall_pre_impl_compat_30_getdents(long long fd, + long long buf, + long long count); +void __sanitizer_syscall_post_impl_compat_30_getdents(long long res, + long long fd, + long long buf, + long long count); +void __sanitizer_syscall_pre_impl_minherit(long long addr, long long len, + long long inherit); +void __sanitizer_syscall_post_impl_minherit(long long res, long long addr, + long long len, long long inherit); +void __sanitizer_syscall_pre_impl_lchmod(long long path, long long mode); +void __sanitizer_syscall_post_impl_lchmod(long long res, long long path, + long long mode); +void __sanitizer_syscall_pre_impl_lchown(long long path, long long uid, + long long gid); +void __sanitizer_syscall_post_impl_lchown(long long res, long long path, + long long uid, long long gid); +void __sanitizer_syscall_pre_impl_compat_50_lutimes(long long path, + long long tptr); +void __sanitizer_syscall_post_impl_compat_50_lutimes(long long res, + long long path, + long long tptr); +void __sanitizer_syscall_pre_impl___msync13(long long addr, long long len, + long long flags); +void __sanitizer_syscall_post_impl___msync13(long long res, long long addr, + long long len, long long flags); +void __sanitizer_syscall_pre_impl_compat_30___stat13(long long path, + long long ub); +void __sanitizer_syscall_post_impl_compat_30___stat13(long long res, + long long path, + long long ub); +void __sanitizer_syscall_pre_impl_compat_30___fstat13(long long fd, + long long sb); +void __sanitizer_syscall_post_impl_compat_30___fstat13(long long res, + long long fd, + long long sb); +void __sanitizer_syscall_pre_impl_compat_30___lstat13(long long path, + long long ub); +void __sanitizer_syscall_post_impl_compat_30___lstat13(long long res, + long long path, + long long ub); +void __sanitizer_syscall_pre_impl___sigaltstack14(long long nss, long long oss); +void __sanitizer_syscall_post_impl___sigaltstack14(long long res, long long nss, + long long oss); +void __sanitizer_syscall_pre_impl___vfork14(void); +void __sanitizer_syscall_post_impl___vfork14(long long res); +void __sanitizer_syscall_pre_impl___posix_chown(long long path, long long uid, + long long gid); +void __sanitizer_syscall_post_impl___posix_chown(long long res, long long path, + long long uid, long long gid); +void __sanitizer_syscall_pre_impl___posix_fchown(long long fd, long long uid, + long long gid); +void __sanitizer_syscall_post_impl___posix_fchown(long long res, long long fd, + long long uid, long long gid); +void __sanitizer_syscall_pre_impl___posix_lchown(long long path, long long uid, + long long gid); +void __sanitizer_syscall_post_impl___posix_lchown(long long res, long long path, + long long uid, long long gid); +void __sanitizer_syscall_pre_impl_getsid(long long pid); +void __sanitizer_syscall_post_impl_getsid(long long res, long long pid); +void __sanitizer_syscall_pre_impl___clone(long long flags, long long stack); +void __sanitizer_syscall_post_impl___clone(long long res, long long flags, + long long stack); +void __sanitizer_syscall_pre_impl_fktrace(long long fd, long long ops, + long long facs, long long pid); +void __sanitizer_syscall_post_impl_fktrace(long long res, long long fd, + long long ops, long long facs, + long long pid); +void __sanitizer_syscall_pre_impl_preadv(long long fd, long long iovp, + long long iovcnt, long long PAD, + long long offset); +void __sanitizer_syscall_post_impl_preadv(long long res, long long fd, + long long iovp, long long iovcnt, + long long PAD, long long offset); +void __sanitizer_syscall_pre_impl_pwritev(long long fd, long long iovp, + long long iovcnt, long long PAD, + long long offset); +void __sanitizer_syscall_post_impl_pwritev(long long res, long long fd, + long long iovp, long long iovcnt, + long long PAD, long long offset); +void __sanitizer_syscall_pre_impl_compat_16___sigaction14(long long signum, + long long nsa, + long long osa); +void __sanitizer_syscall_post_impl_compat_16___sigaction14(long long res, + long long signum, + long long nsa, + long long osa); +void __sanitizer_syscall_pre_impl___sigpending14(long long set); +void __sanitizer_syscall_post_impl___sigpending14(long long res, long long set); +void __sanitizer_syscall_pre_impl___sigprocmask14(long long how, long long set, + long long oset); +void __sanitizer_syscall_post_impl___sigprocmask14(long long res, long long how, + long long set, + long long oset); +void __sanitizer_syscall_pre_impl___sigsuspend14(long long set); +void __sanitizer_syscall_post_impl___sigsuspend14(long long res, long long set); +void __sanitizer_syscall_pre_impl_compat_16___sigreturn14(long long sigcntxp); +void __sanitizer_syscall_post_impl_compat_16___sigreturn14(long long res, + long long sigcntxp); +void __sanitizer_syscall_pre_impl___getcwd(long long bufp, long long length); +void __sanitizer_syscall_post_impl___getcwd(long long res, long long bufp, + long long length); +void __sanitizer_syscall_pre_impl_fchroot(long long fd); +void __sanitizer_syscall_post_impl_fchroot(long long res, long long fd); +void __sanitizer_syscall_pre_impl_compat_30_fhopen(long long fhp, + long long flags); +void __sanitizer_syscall_post_impl_compat_30_fhopen(long long res, + long long fhp, + long long flags); +void __sanitizer_syscall_pre_impl_compat_30_fhstat(long long fhp, long long sb); +void __sanitizer_syscall_post_impl_compat_30_fhstat(long long res, + long long fhp, + long long sb); +void __sanitizer_syscall_pre_impl_compat_20_fhstatfs(long long fhp, + long long buf); +void __sanitizer_syscall_post_impl_compat_20_fhstatfs(long long res, + long long fhp, + long long buf); +void __sanitizer_syscall_pre_impl_compat_50_____semctl13(long long semid, + long long semnum, + long long cmd, + long long arg); +void __sanitizer_syscall_post_impl_compat_50_____semctl13(long long res, + long long semid, + long long semnum, + long long cmd, + long long arg); +void __sanitizer_syscall_pre_impl_compat_50___msgctl13(long long msqid, + long long cmd, + long long buf); +void __sanitizer_syscall_post_impl_compat_50___msgctl13(long long res, + long long msqid, + long long cmd, + long long buf); +void __sanitizer_syscall_pre_impl_compat_50___shmctl13(long long shmid, + long long cmd, + long long buf); +void __sanitizer_syscall_post_impl_compat_50___shmctl13(long long res, + long long shmid, + long long cmd, + long long buf); +void __sanitizer_syscall_pre_impl_lchflags(long long path, long long flags); +void __sanitizer_syscall_post_impl_lchflags(long long res, long long path, + long long flags); +void __sanitizer_syscall_pre_impl_issetugid(void); +void __sanitizer_syscall_post_impl_issetugid(long long res); +void __sanitizer_syscall_pre_impl_utrace(long long label, long long addr, + long long len); +void __sanitizer_syscall_post_impl_utrace(long long res, long long label, + long long addr, long long len); +void __sanitizer_syscall_pre_impl_getcontext(long long ucp); +void __sanitizer_syscall_post_impl_getcontext(long long res, long long ucp); +void __sanitizer_syscall_pre_impl_setcontext(long long ucp); +void __sanitizer_syscall_post_impl_setcontext(long long res, long long ucp); +void __sanitizer_syscall_pre_impl__lwp_create(long long ucp, long long flags, + long long new_lwp); +void __sanitizer_syscall_post_impl__lwp_create(long long res, long long ucp, + long long flags, + long long new_lwp); +void __sanitizer_syscall_pre_impl__lwp_exit(void); +void __sanitizer_syscall_post_impl__lwp_exit(long long res); +void __sanitizer_syscall_pre_impl__lwp_self(void); +void __sanitizer_syscall_post_impl__lwp_self(long long res); +void __sanitizer_syscall_pre_impl__lwp_wait(long long wait_for, + long long departed); +void __sanitizer_syscall_post_impl__lwp_wait(long long res, long long wait_for, + long long departed); +void __sanitizer_syscall_pre_impl__lwp_suspend(long long target); +void __sanitizer_syscall_post_impl__lwp_suspend(long long res, + long long target); +void __sanitizer_syscall_pre_impl__lwp_continue(long long target); +void __sanitizer_syscall_post_impl__lwp_continue(long long res, + long long target); +void __sanitizer_syscall_pre_impl__lwp_wakeup(long long target); +void __sanitizer_syscall_post_impl__lwp_wakeup(long long res, long long target); +void __sanitizer_syscall_pre_impl__lwp_getprivate(void); +void __sanitizer_syscall_post_impl__lwp_getprivate(long long res); +void __sanitizer_syscall_pre_impl__lwp_setprivate(long long ptr); +void __sanitizer_syscall_post_impl__lwp_setprivate(long long res, + long long ptr); +void __sanitizer_syscall_pre_impl__lwp_kill(long long target, long long signo); +void __sanitizer_syscall_post_impl__lwp_kill(long long res, long long target, + long long signo); +void __sanitizer_syscall_pre_impl__lwp_detach(long long target); +void __sanitizer_syscall_post_impl__lwp_detach(long long res, long long target); +void __sanitizer_syscall_pre_impl_compat_50__lwp_park(long long ts, + long long unpark, + long long hint, + long long unparkhint); +void __sanitizer_syscall_post_impl_compat_50__lwp_park(long long res, + long long ts, + long long unpark, + long long hint, + long long unparkhint); +void __sanitizer_syscall_pre_impl__lwp_unpark(long long target, long long hint); +void __sanitizer_syscall_post_impl__lwp_unpark(long long res, long long target, + long long hint); +void __sanitizer_syscall_pre_impl__lwp_unpark_all(long long targets, + long long ntargets, + long long hint); +void __sanitizer_syscall_post_impl__lwp_unpark_all(long long res, + long long targets, + long long ntargets, + long long hint); +void __sanitizer_syscall_pre_impl__lwp_setname(long long target, + long long name); +void __sanitizer_syscall_post_impl__lwp_setname(long long res, long long target, + long long name); +void __sanitizer_syscall_pre_impl__lwp_getname(long long target, long long name, + long long len); +void __sanitizer_syscall_post_impl__lwp_getname(long long res, long long target, + long long name, long long len); +void __sanitizer_syscall_pre_impl__lwp_ctl(long long features, + long long address); +void __sanitizer_syscall_post_impl__lwp_ctl(long long res, long long features, + long long address); +/* syscall 326 has been skipped */ +/* syscall 327 has been skipped */ +/* syscall 328 has been skipped */ +/* syscall 329 has been skipped */ +void __sanitizer_syscall_pre_impl_compat_60_sa_register( + long long newv, long long oldv, long long flags, + long long stackinfo_offset); +void __sanitizer_syscall_post_impl_compat_60_sa_register( + long long res, long long newv, long long oldv, long long flags, + long long stackinfo_offset); +void __sanitizer_syscall_pre_impl_compat_60_sa_stacks(long long num, + long long stacks); +void __sanitizer_syscall_post_impl_compat_60_sa_stacks(long long res, + long long num, + long long stacks); +void __sanitizer_syscall_pre_impl_compat_60_sa_enable(void); +void __sanitizer_syscall_post_impl_compat_60_sa_enable(long long res); +void __sanitizer_syscall_pre_impl_compat_60_sa_setconcurrency( + long long concurrency); +void __sanitizer_syscall_post_impl_compat_60_sa_setconcurrency( + long long res, long long concurrency); +void __sanitizer_syscall_pre_impl_compat_60_sa_yield(void); +void __sanitizer_syscall_post_impl_compat_60_sa_yield(long long res); +void __sanitizer_syscall_pre_impl_compat_60_sa_preempt(long long sa_id); +void __sanitizer_syscall_post_impl_compat_60_sa_preempt(long long res, + long long sa_id); +/* syscall 336 has been skipped */ +/* syscall 337 has been skipped */ +/* syscall 338 has been skipped */ +/* syscall 339 has been skipped */ +void __sanitizer_syscall_pre_impl___sigaction_sigtramp(long long signum, + long long nsa, + long long osa, + long long tramp, + long long vers); +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); +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, + long long len, long long op); +void __sanitizer_syscall_pre_impl_kqueue(void); +void __sanitizer_syscall_post_impl_kqueue(long long res); +void __sanitizer_syscall_pre_impl_compat_50_kevent( + long long fd, long long changelist, long long nchanges, long long eventlist, + long long nevents, long long timeout); +void __sanitizer_syscall_post_impl_compat_50_kevent( + long long res, long long fd, long long changelist, long long nchanges, + long long eventlist, long long nevents, long long timeout); +void __sanitizer_syscall_pre_impl__sched_setparam(long long pid, long long lid, + long long policy, + long long params); +void __sanitizer_syscall_post_impl__sched_setparam(long long res, long long pid, + long long lid, + long long policy, + long long params); +void __sanitizer_syscall_pre_impl__sched_getparam(long long pid, long long lid, + long long policy, + long long params); +void __sanitizer_syscall_post_impl__sched_getparam(long long res, long long pid, + long long lid, + long long policy, + long long params); +void __sanitizer_syscall_pre_impl__sched_setaffinity(long long pid, + long long lid, + long long size, + long long cpuset); +void __sanitizer_syscall_post_impl__sched_setaffinity(long long res, + long long pid, + long long lid, + long long size, + long long cpuset); +void __sanitizer_syscall_pre_impl__sched_getaffinity(long long pid, + long long lid, + long long size, + long long cpuset); +void __sanitizer_syscall_post_impl__sched_getaffinity(long long res, + long long pid, + long long lid, + long long size, + long long cpuset); +void __sanitizer_syscall_pre_impl_sched_yield(void); +void __sanitizer_syscall_post_impl_sched_yield(long long res); +void __sanitizer_syscall_pre_impl__sched_protect(long long priority); +void __sanitizer_syscall_post_impl__sched_protect(long long res, + long long priority); +/* syscall 352 has been skipped */ +/* syscall 353 has been skipped */ +void __sanitizer_syscall_pre_impl_fsync_range(long long fd, long long flags, + long long start, + long long length); +void __sanitizer_syscall_post_impl_fsync_range(long long res, long long fd, + long long flags, long long start, + long long length); +void __sanitizer_syscall_pre_impl_uuidgen(long long store, long long count); +void __sanitizer_syscall_post_impl_uuidgen(long long res, long long store, + long long count); +void __sanitizer_syscall_pre_impl_getvfsstat(long long buf, long long bufsize, + long long flags); +void __sanitizer_syscall_post_impl_getvfsstat(long long res, long long buf, + long long bufsize, + long long flags); +void __sanitizer_syscall_pre_impl_statvfs1(long long path, long long buf, + long long flags); +void __sanitizer_syscall_post_impl_statvfs1(long long res, long long path, + long long buf, long long flags); +void __sanitizer_syscall_pre_impl_fstatvfs1(long long fd, long long buf, + long long flags); +void __sanitizer_syscall_post_impl_fstatvfs1(long long res, long long fd, + long long buf, long long flags); +void __sanitizer_syscall_pre_impl_compat_30_fhstatvfs1(long long fhp, + long long buf, + long long flags); +void __sanitizer_syscall_post_impl_compat_30_fhstatvfs1(long long res, + long long fhp, + long long buf, + long long flags); +void __sanitizer_syscall_pre_impl_extattrctl(long long path, long long cmd, + long long filename, + long long attrnamespace, + long long attrname); +void __sanitizer_syscall_post_impl_extattrctl(long long res, long long path, + long long cmd, long long filename, + long long attrnamespace, + long long attrname); +void __sanitizer_syscall_pre_impl_extattr_set_file(long long path, + long long attrnamespace, + long long attrname, + long long data, + long long nbytes); +void __sanitizer_syscall_post_impl_extattr_set_file( + long long res, long long path, long long attrnamespace, long long attrname, + long long data, long long nbytes); +void __sanitizer_syscall_pre_impl_extattr_get_file(long long path, + long long attrnamespace, + long long attrname, + long long data, + long long nbytes); +void __sanitizer_syscall_post_impl_extattr_get_file( + long long res, long long path, long long attrnamespace, long long attrname, + long long data, long long nbytes); +void __sanitizer_syscall_pre_impl_extattr_delete_file(long long path, + long long attrnamespace, + long long attrname); +void __sanitizer_syscall_post_impl_extattr_delete_file(long long res, + long long path, + long long attrnamespace, + long long attrname); +void __sanitizer_syscall_pre_impl_extattr_set_fd(long long fd, + long long attrnamespace, + long long attrname, + long long data, + long long nbytes); +void __sanitizer_syscall_post_impl_extattr_set_fd(long long res, long long fd, + long long attrnamespace, + long long attrname, + long long data, + long long nbytes); +void __sanitizer_syscall_pre_impl_extattr_get_fd(long long fd, + long long attrnamespace, + long long attrname, + long long data, + long long nbytes); +void __sanitizer_syscall_post_impl_extattr_get_fd(long long res, long long fd, + long long attrnamespace, + long long attrname, + long long data, + long long nbytes); +void __sanitizer_syscall_pre_impl_extattr_delete_fd(long long fd, + long long attrnamespace, + long long attrname); +void __sanitizer_syscall_post_impl_extattr_delete_fd(long long res, + long long fd, + long long attrnamespace, + long long attrname); +void __sanitizer_syscall_pre_impl_extattr_set_link(long long path, + long long attrnamespace, + long long attrname, + long long data, + long long nbytes); +void __sanitizer_syscall_post_impl_extattr_set_link( + long long res, long long path, long long attrnamespace, long long attrname, + long long data, long long nbytes); +void __sanitizer_syscall_pre_impl_extattr_get_link(long long path, + long long attrnamespace, + long long attrname, + long long data, + long long nbytes); +void __sanitizer_syscall_post_impl_extattr_get_link( + long long res, long long path, long long attrnamespace, long long attrname, + long long data, long long nbytes); +void __sanitizer_syscall_pre_impl_extattr_delete_link(long long path, + long long attrnamespace, + long long attrname); +void __sanitizer_syscall_post_impl_extattr_delete_link(long long res, + long long path, + long long attrnamespace, + long long attrname); +void __sanitizer_syscall_pre_impl_extattr_list_fd(long long fd, + long long attrnamespace, + long long data, + long long nbytes); +void __sanitizer_syscall_post_impl_extattr_list_fd(long long res, long long fd, + long long attrnamespace, + long long data, + long long nbytes); +void __sanitizer_syscall_pre_impl_extattr_list_file(long long path, + long long attrnamespace, + long long data, + long long nbytes); +void __sanitizer_syscall_post_impl_extattr_list_file(long long res, + long long path, + long long attrnamespace, + long long data, + long long nbytes); +void __sanitizer_syscall_pre_impl_extattr_list_link(long long path, + long long attrnamespace, + long long data, + long long nbytes); +void __sanitizer_syscall_post_impl_extattr_list_link(long long res, + long long path, + long long attrnamespace, + long long data, + long long nbytes); +void __sanitizer_syscall_pre_impl_compat_50_pselect(long long nd, long long in, + long long ou, long long ex, + long long ts, + long long mask); +void __sanitizer_syscall_post_impl_compat_50_pselect(long long res, + long long nd, long long in, + long long ou, long long ex, + long long ts, + long long mask); +void __sanitizer_syscall_pre_impl_compat_50_pollts(long long fds, + long long nfds, long long ts, + long long mask); +void __sanitizer_syscall_post_impl_compat_50_pollts( + long long res, long long fds, long long nfds, long long ts, long long mask); +void __sanitizer_syscall_pre_impl_setxattr(long long path, long long name, + long long value, long long size, + long long flags); +void __sanitizer_syscall_post_impl_setxattr(long long res, long long path, + long long name, long long value, + long long size, long long flags); +void __sanitizer_syscall_pre_impl_lsetxattr(long long path, long long name, + long long value, long long size, + long long flags); +void __sanitizer_syscall_post_impl_lsetxattr(long long res, long long path, + long long name, long long value, + long long size, long long flags); +void __sanitizer_syscall_pre_impl_fsetxattr(long long fd, long long name, + long long value, long long size, + long long flags); +void __sanitizer_syscall_post_impl_fsetxattr(long long res, long long fd, + long long name, long long value, + long long size, long long flags); +void __sanitizer_syscall_pre_impl_getxattr(long long path, long long name, + long long value, long long size); +void __sanitizer_syscall_post_impl_getxattr(long long res, long long path, + long long name, long long value, + long long size); +void __sanitizer_syscall_pre_impl_lgetxattr(long long path, long long name, + long long value, long long size); +void __sanitizer_syscall_post_impl_lgetxattr(long long res, long long path, + long long name, long long value, + long long size); +void __sanitizer_syscall_pre_impl_fgetxattr(long long fd, long long name, + long long value, long long size); +void __sanitizer_syscall_post_impl_fgetxattr(long long res, long long fd, + long long name, long long value, + long long size); +void __sanitizer_syscall_pre_impl_listxattr(long long path, long long list, + long long size); +void __sanitizer_syscall_post_impl_listxattr(long long res, long long path, + long long list, long long size); +void __sanitizer_syscall_pre_impl_llistxattr(long long path, long long list, + long long size); +void __sanitizer_syscall_post_impl_llistxattr(long long res, long long path, + long long list, long long size); +void __sanitizer_syscall_pre_impl_flistxattr(long long fd, long long list, + long long size); +void __sanitizer_syscall_post_impl_flistxattr(long long res, long long fd, + long long list, long long size); +void __sanitizer_syscall_pre_impl_removexattr(long long path, long long name); +void __sanitizer_syscall_post_impl_removexattr(long long res, long long path, + long long name); +void __sanitizer_syscall_pre_impl_lremovexattr(long long path, long long name); +void __sanitizer_syscall_post_impl_lremovexattr(long long res, long long path, + long long name); +void __sanitizer_syscall_pre_impl_fremovexattr(long long fd, long long name); +void __sanitizer_syscall_post_impl_fremovexattr(long long res, long long fd, + long long name); +void __sanitizer_syscall_pre_impl_compat_50___stat30(long long path, + long long ub); +void __sanitizer_syscall_post_impl_compat_50___stat30(long long res, + long long path, + long long ub); +void __sanitizer_syscall_pre_impl_compat_50___fstat30(long long fd, + long long sb); +void __sanitizer_syscall_post_impl_compat_50___fstat30(long long res, + long long fd, + long long sb); +void __sanitizer_syscall_pre_impl_compat_50___lstat30(long long path, + long long ub); +void __sanitizer_syscall_post_impl_compat_50___lstat30(long long res, + long long path, + long long ub); +void __sanitizer_syscall_pre_impl___getdents30(long long fd, long long buf, + long long count); +void __sanitizer_syscall_post_impl___getdents30(long long res, long long fd, + long long buf, long long count); +void __sanitizer_syscall_pre_impl_posix_fadvise(long long); +void __sanitizer_syscall_post_impl_posix_fadvise(long long res, long long); +void __sanitizer_syscall_pre_impl_compat_30___fhstat30(long long fhp, + long long sb); +void __sanitizer_syscall_post_impl_compat_30___fhstat30(long long res, + long long fhp, + long long sb); +void __sanitizer_syscall_pre_impl_compat_50___ntp_gettime30(long long ntvp); +void __sanitizer_syscall_post_impl_compat_50___ntp_gettime30(long long res, + long long ntvp); +void __sanitizer_syscall_pre_impl___socket30(long long domain, long long type, + long long protocol); +void __sanitizer_syscall_post_impl___socket30(long long res, long long domain, + long long type, + long long protocol); +void __sanitizer_syscall_pre_impl___getfh30(long long fname, long long fhp, + long long fh_size); +void __sanitizer_syscall_post_impl___getfh30(long long res, long long fname, + long long fhp, long long fh_size); +void __sanitizer_syscall_pre_impl___fhopen40(long long fhp, long long fh_size, + long long flags); +void __sanitizer_syscall_post_impl___fhopen40(long long res, long long fhp, + long long fh_size, + long long flags); +void __sanitizer_syscall_pre_impl___fhstatvfs140(long long fhp, + long long fh_size, + long long buf, + long long flags); +void __sanitizer_syscall_post_impl___fhstatvfs140(long long res, long long fhp, + long long fh_size, + long long buf, + long long flags); +void __sanitizer_syscall_pre_impl_compat_50___fhstat40(long long fhp, + long long fh_size, + long long sb); +void __sanitizer_syscall_post_impl_compat_50___fhstat40(long long res, + long long fhp, + long long fh_size, + long long sb); +void __sanitizer_syscall_pre_impl_aio_cancel(long long fildes, + long long aiocbp); +void __sanitizer_syscall_post_impl_aio_cancel(long long res, long long fildes, + long long aiocbp); +void __sanitizer_syscall_pre_impl_aio_error(long long aiocbp); +void __sanitizer_syscall_post_impl_aio_error(long long res, long long aiocbp); +void __sanitizer_syscall_pre_impl_aio_fsync(long long op, long long aiocbp); +void __sanitizer_syscall_post_impl_aio_fsync(long long res, long long op, + long long aiocbp); +void __sanitizer_syscall_pre_impl_aio_read(long long aiocbp); +void __sanitizer_syscall_post_impl_aio_read(long long res, long long aiocbp); +void __sanitizer_syscall_pre_impl_aio_return(long long aiocbp); +void __sanitizer_syscall_post_impl_aio_return(long long res, long long aiocbp); +void __sanitizer_syscall_pre_impl_compat_50_aio_suspend(long long list, + long long nent, + long long timeout); +void __sanitizer_syscall_post_impl_compat_50_aio_suspend(long long res, + long long list, + long long nent, + long long timeout); +void __sanitizer_syscall_pre_impl_aio_write(long long aiocbp); +void __sanitizer_syscall_post_impl_aio_write(long long res, long long aiocbp); +void __sanitizer_syscall_pre_impl_lio_listio(long long mode, long long list, + long long nent, long long sig); +void __sanitizer_syscall_post_impl_lio_listio(long long res, long long mode, + long long list, long long nent, + long long sig); +/* syscall 407 has been skipped */ +/* syscall 408 has been skipped */ +/* syscall 409 has been skipped */ +void __sanitizer_syscall_pre_impl___mount50(long long type, long long path, + long long flags, long long data, + long long data_len); +void __sanitizer_syscall_post_impl___mount50(long long res, long long type, + long long path, long long flags, + long long data, + long long data_len); +void __sanitizer_syscall_pre_impl_mremap(long long old_address, + long long old_size, + long long new_address, + long long new_size, long long flags); +void __sanitizer_syscall_post_impl_mremap(long long res, long long old_address, + long long old_size, + long long new_address, + long long new_size, long long flags); +void __sanitizer_syscall_pre_impl_pset_create(long long psid); +void __sanitizer_syscall_post_impl_pset_create(long long res, long long psid); +void __sanitizer_syscall_pre_impl_pset_destroy(long long psid); +void __sanitizer_syscall_post_impl_pset_destroy(long long res, long long psid); +void __sanitizer_syscall_pre_impl_pset_assign(long long psid, long long cpuid, + long long opsid); +void __sanitizer_syscall_post_impl_pset_assign(long long res, long long psid, + long long cpuid, + long long opsid); +void __sanitizer_syscall_pre_impl__pset_bind(long long idtype, + long long first_id, + long long second_id, + long long psid, long long opsid); +void __sanitizer_syscall_post_impl__pset_bind(long long res, long long idtype, + long long first_id, + long long second_id, + long long psid, long long opsid); +void __sanitizer_syscall_pre_impl___posix_fadvise50(long long fd, long long PAD, + long long offset, + long long len, + long long advice); +void __sanitizer_syscall_post_impl___posix_fadvise50( + long long res, long long fd, long long PAD, long long offset, long long len, + long long advice); +void __sanitizer_syscall_pre_impl___select50(long long nd, long long in, + long long ou, long long ex, + long long tv); +void __sanitizer_syscall_post_impl___select50(long long res, long long nd, + long long in, long long ou, + long long ex, long long tv); +void __sanitizer_syscall_pre_impl___gettimeofday50(long long tp, long long tzp); +void __sanitizer_syscall_post_impl___gettimeofday50(long long res, long long tp, + long long tzp); +void __sanitizer_syscall_pre_impl___settimeofday50(long long tv, long long tzp); +void __sanitizer_syscall_post_impl___settimeofday50(long long res, long long tv, + long long tzp); +void __sanitizer_syscall_pre_impl___utimes50(long long path, long long tptr); +void __sanitizer_syscall_post_impl___utimes50(long long res, long long path, + long long tptr); +void __sanitizer_syscall_pre_impl___adjtime50(long long delta, + long long olddelta); +void __sanitizer_syscall_post_impl___adjtime50(long long res, long long delta, + long long olddelta); +void __sanitizer_syscall_pre_impl___lfs_segwait50(long long fsidp, + long long tv); +void __sanitizer_syscall_post_impl___lfs_segwait50(long long res, + long long fsidp, + long long tv); +void __sanitizer_syscall_pre_impl___futimes50(long long fd, long long tptr); +void __sanitizer_syscall_post_impl___futimes50(long long res, long long fd, + long long tptr); +void __sanitizer_syscall_pre_impl___lutimes50(long long path, long long tptr); +void __sanitizer_syscall_post_impl___lutimes50(long long res, long long path, + long long tptr); +void __sanitizer_syscall_pre_impl___setitimer50(long long which, long long itv, + long long oitv); +void __sanitizer_syscall_post_impl___setitimer50(long long res, long long which, + long long itv, long long oitv); +void __sanitizer_syscall_pre_impl___getitimer50(long long which, long long itv); +void __sanitizer_syscall_post_impl___getitimer50(long long res, long long which, + long long itv); +void __sanitizer_syscall_pre_impl___clock_gettime50(long long clock_id, + long long tp); +void __sanitizer_syscall_post_impl___clock_gettime50(long long res, + long long clock_id, + long long tp); +void __sanitizer_syscall_pre_impl___clock_settime50(long long clock_id, + long long tp); +void __sanitizer_syscall_post_impl___clock_settime50(long long res, + long long clock_id, + long long tp); +void __sanitizer_syscall_pre_impl___clock_getres50(long long clock_id, + long long tp); +void __sanitizer_syscall_post_impl___clock_getres50(long long res, + long long clock_id, + long long tp); +void __sanitizer_syscall_pre_impl___nanosleep50(long long rqtp, long long rmtp); +void __sanitizer_syscall_post_impl___nanosleep50(long long res, long long rqtp, + long long rmtp); +void __sanitizer_syscall_pre_impl_____sigtimedwait50(long long set, + long long info, + long long timeout); +void __sanitizer_syscall_post_impl_____sigtimedwait50(long long res, + long long set, + long long info, + long long timeout); +void __sanitizer_syscall_pre_impl___mq_timedsend50(long long mqdes, + long long msg_ptr, + long long msg_len, + long long msg_prio, + long long abs_timeout); +void __sanitizer_syscall_post_impl___mq_timedsend50( + long long res, long long mqdes, long long msg_ptr, long long msg_len, + long long msg_prio, long long abs_timeout); +void __sanitizer_syscall_pre_impl___mq_timedreceive50(long long mqdes, + long long msg_ptr, + long long msg_len, + long long msg_prio, + long long abs_timeout); +void __sanitizer_syscall_post_impl___mq_timedreceive50( + long long res, long long mqdes, long long msg_ptr, long long msg_len, + long long msg_prio, long long abs_timeout); +void __sanitizer_syscall_pre_impl_compat_60__lwp_park(long long ts, + long long unpark, + long long hint, + long long unparkhint); +void __sanitizer_syscall_post_impl_compat_60__lwp_park(long long res, + long long ts, + long long unpark, + long long hint, + long long unparkhint); +void __sanitizer_syscall_pre_impl___kevent50(long long fd, long long changelist, + long long nchanges, + long long eventlist, + long long nevents, + long long timeout); +void __sanitizer_syscall_post_impl___kevent50( + long long res, long long fd, long long changelist, long long nchanges, + long long eventlist, long long nevents, long long timeout); +void __sanitizer_syscall_pre_impl___pselect50(long long nd, long long in, + long long ou, long long ex, + long long ts, long long mask); +void __sanitizer_syscall_post_impl___pselect50(long long res, long long nd, + long long in, long long ou, + long long ex, long long ts, + long long mask); +void __sanitizer_syscall_pre_impl___pollts50(long long fds, long long nfds, + long long ts, long long mask); +void __sanitizer_syscall_post_impl___pollts50(long long res, long long fds, + long long nfds, long long ts, + long long mask); +void __sanitizer_syscall_pre_impl___aio_suspend50(long long list, + long long nent, + long long timeout); +void __sanitizer_syscall_post_impl___aio_suspend50(long long res, + long long list, + long long nent, + long long timeout); +void __sanitizer_syscall_pre_impl___stat50(long long path, long long ub); +void __sanitizer_syscall_post_impl___stat50(long long res, long long path, + long long ub); +void __sanitizer_syscall_pre_impl___fstat50(long long fd, long long sb); +void __sanitizer_syscall_post_impl___fstat50(long long res, long long fd, + long long sb); +void __sanitizer_syscall_pre_impl___lstat50(long long path, long long ub); +void __sanitizer_syscall_post_impl___lstat50(long long res, long long path, + long long ub); +void __sanitizer_syscall_pre_impl_____semctl50(long long semid, + long long semnum, long long cmd, + long long arg); +void __sanitizer_syscall_post_impl_____semctl50(long long res, long long semid, + long long semnum, long long cmd, + long long arg); +void __sanitizer_syscall_pre_impl___shmctl50(long long shmid, long long cmd, + long long buf); +void __sanitizer_syscall_post_impl___shmctl50(long long res, long long shmid, + long long cmd, long long buf); +void __sanitizer_syscall_pre_impl___msgctl50(long long msqid, long long cmd, + long long buf); +void __sanitizer_syscall_post_impl___msgctl50(long long res, long long msqid, + long long cmd, long long buf); +void __sanitizer_syscall_pre_impl___getrusage50(long long who, + long long rusage); +void __sanitizer_syscall_post_impl___getrusage50(long long res, long long who, + long long rusage); +void __sanitizer_syscall_pre_impl___timer_settime50(long long timerid, + long long flags, + long long value, + long long ovalue); +void __sanitizer_syscall_post_impl___timer_settime50(long long res, + long long timerid, + long long flags, + long long value, + long long ovalue); +void __sanitizer_syscall_pre_impl___timer_gettime50(long long timerid, + long long value); +void __sanitizer_syscall_post_impl___timer_gettime50(long long res, + long long timerid, + long long value); +#if defined(NTP) || !defined(_KERNEL_OPT) +void __sanitizer_syscall_pre_impl___ntp_gettime50(long long ntvp); +void __sanitizer_syscall_post_impl___ntp_gettime50(long long res, + long long ntvp); +#else +/* syscall 448 has been skipped */ +#endif +void __sanitizer_syscall_pre_impl___wait450(long long pid, long long status, + long long options, + long long rusage); +void __sanitizer_syscall_post_impl___wait450(long long res, long long pid, + long long status, + long long options, + long long rusage); +void __sanitizer_syscall_pre_impl___mknod50(long long path, long long mode, + long long dev); +void __sanitizer_syscall_post_impl___mknod50(long long res, long long path, + long long mode, long long dev); +void __sanitizer_syscall_pre_impl___fhstat50(long long fhp, long long fh_size, + long long sb); +void __sanitizer_syscall_post_impl___fhstat50(long long res, long long fhp, + long long fh_size, long long sb); +/* syscall 452 has been skipped */ +void __sanitizer_syscall_pre_impl_pipe2(long long fildes, long long flags); +void __sanitizer_syscall_post_impl_pipe2(long long res, long long fildes, + long long flags); +void __sanitizer_syscall_pre_impl_dup3(long long from, long long to, + long long flags); +void __sanitizer_syscall_post_impl_dup3(long long res, long long from, + long long to, long long flags); +void __sanitizer_syscall_pre_impl_kqueue1(long long flags); +void __sanitizer_syscall_post_impl_kqueue1(long long res, long long flags); +void __sanitizer_syscall_pre_impl_paccept(long long s, long long name, + long long anamelen, long long mask, + long long flags); +void __sanitizer_syscall_post_impl_paccept(long long res, long long s, + long long name, long long anamelen, + long long mask, long long flags); +void __sanitizer_syscall_pre_impl_linkat(long long fd1, long long name1, + long long fd2, long long name2, + long long flags); +void __sanitizer_syscall_post_impl_linkat(long long res, long long fd1, + long long name1, long long fd2, + long long name2, long long flags); +void __sanitizer_syscall_pre_impl_renameat(long long fromfd, long long from, + long long tofd, long long to); +void __sanitizer_syscall_post_impl_renameat(long long res, long long fromfd, + long long from, long long tofd, + long long to); +void __sanitizer_syscall_pre_impl_mkfifoat(long long fd, long long path, + long long mode); +void __sanitizer_syscall_post_impl_mkfifoat(long long res, long long fd, + long long path, long long mode); +void __sanitizer_syscall_pre_impl_mknodat(long long fd, long long path, + long long mode, long long PAD, + long long dev); +void __sanitizer_syscall_post_impl_mknodat(long long res, long long fd, + long long path, long long mode, + long long PAD, long long dev); +void __sanitizer_syscall_pre_impl_mkdirat(long long fd, long long path, + long long mode); +void __sanitizer_syscall_post_impl_mkdirat(long long res, long long fd, + long long path, long long mode); +void __sanitizer_syscall_pre_impl_faccessat(long long fd, long long path, + long long amode, long long flag); +void __sanitizer_syscall_post_impl_faccessat(long long res, long long fd, + long long path, long long amode, + long long flag); +void __sanitizer_syscall_pre_impl_fchmodat(long long fd, long long path, + long long mode, long long flag); +void __sanitizer_syscall_post_impl_fchmodat(long long res, long long fd, + long long path, long long mode, + long long flag); +void __sanitizer_syscall_pre_impl_fchownat(long long fd, long long path, + long long owner, long long group, + long long flag); +void __sanitizer_syscall_post_impl_fchownat(long long res, long long fd, + long long path, long long owner, + long long group, long long flag); +void __sanitizer_syscall_pre_impl_fexecve(long long fd, long long argp, + long long envp); +void __sanitizer_syscall_post_impl_fexecve(long long res, long long fd, + long long argp, long long envp); +void __sanitizer_syscall_pre_impl_fstatat(long long fd, long long path, + long long buf, long long flag); +void __sanitizer_syscall_post_impl_fstatat(long long res, long long fd, + long long path, long long buf, + long long flag); +void __sanitizer_syscall_pre_impl_utimensat(long long fd, long long path, + long long tptr, long long flag); +void __sanitizer_syscall_post_impl_utimensat(long long res, long long fd, + long long path, long long tptr, + long long flag); +void __sanitizer_syscall_pre_impl_openat(long long fd, long long path, + long long oflags, long long mode); +void __sanitizer_syscall_post_impl_openat(long long res, long long fd, + long long path, long long oflags, + long long mode); +void __sanitizer_syscall_pre_impl_readlinkat(long long fd, long long path, + long long buf, long long bufsize); +void __sanitizer_syscall_post_impl_readlinkat(long long res, long long fd, + long long path, long long buf, + long long bufsize); +void __sanitizer_syscall_pre_impl_symlinkat(long long path1, long long fd, + long long path2); +void __sanitizer_syscall_post_impl_symlinkat(long long res, long long path1, + long long fd, long long path2); +void __sanitizer_syscall_pre_impl_unlinkat(long long fd, long long path, + long long flag); +void __sanitizer_syscall_post_impl_unlinkat(long long res, long long fd, + long long path, long long flag); +void __sanitizer_syscall_pre_impl_futimens(long long fd, long long tptr); +void __sanitizer_syscall_post_impl_futimens(long long res, long long fd, + long long tptr); +void __sanitizer_syscall_pre_impl___quotactl(long long path, long long args); +void __sanitizer_syscall_post_impl___quotactl(long long res, long long path, + long long args); +void __sanitizer_syscall_pre_impl_posix_spawn(long long pid, long long path, + long long file_actions, + long long attrp, long long argv, + long long envp); +void __sanitizer_syscall_post_impl_posix_spawn(long long res, long long pid, + long long path, + long long file_actions, + long long attrp, long long argv, + long long envp); +void __sanitizer_syscall_pre_impl_recvmmsg(long long s, long long mmsg, + long long vlen, long long flags, + long long timeout); +void __sanitizer_syscall_post_impl_recvmmsg(long long res, long long s, + long long mmsg, long long vlen, + long long flags, long long timeout); +void __sanitizer_syscall_pre_impl_sendmmsg(long long s, long long mmsg, + long long vlen, long long flags); +void __sanitizer_syscall_post_impl_sendmmsg(long long res, long long s, + long long mmsg, long long vlen, + long long flags); +void __sanitizer_syscall_pre_impl_clock_nanosleep(long long clock_id, + long long flags, + long long rqtp, + long long rmtp); +void __sanitizer_syscall_post_impl_clock_nanosleep(long long res, + long long clock_id, + long long flags, + long long rqtp, + long long rmtp); +void __sanitizer_syscall_pre_impl____lwp_park60(long long clock_id, + long long flags, long long ts, + long long unpark, + long long hint, + long long unparkhint); +void __sanitizer_syscall_post_impl____lwp_park60( + long long res, long long clock_id, long long flags, long long ts, + long long unpark, long long hint, long long unparkhint); +void __sanitizer_syscall_pre_impl_posix_fallocate(long long fd, long long PAD, + long long pos, long long len); +void __sanitizer_syscall_post_impl_posix_fallocate(long long res, long long fd, + long long PAD, long long pos, + long long len); +void __sanitizer_syscall_pre_impl_fdiscard(long long fd, long long PAD, + long long pos, long long len); +void __sanitizer_syscall_post_impl_fdiscard(long long res, long long fd, + long long PAD, long long pos, + long long len); +void __sanitizer_syscall_pre_impl_wait6(long long idtype, long long id, + long long status, long long options, + long long wru, long long info); +void __sanitizer_syscall_post_impl_wait6(long long res, long long idtype, + long long id, long long status, + long long options, long long wru, + long long info); +void __sanitizer_syscall_pre_impl_clock_getcpuclockid2(long long idtype, + long long id, + long long clock_id); +void __sanitizer_syscall_post_impl_clock_getcpuclockid2(long long res, + long long idtype, + long long id, + long long clock_id); + +#ifdef __cplusplus +} // extern "C" +#endif + +// DO NOT EDIT! THIS FILE HAS BEEN GENERATED! + +#endif // SANITIZER_NETBSD_SYSCALL_HOOKS_H diff --git a/libsanitizer/include/sanitizer/scudo_interface.h b/libsanitizer/include/sanitizer/scudo_interface.h new file mode 100644 index 00000000000..ca9a6f1fcb7 --- /dev/null +++ b/libsanitizer/include/sanitizer/scudo_interface.h @@ -0,0 +1,37 @@ +//===-- sanitizer/scudo_interface.h -----------------------------*- C++ -*-===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +/// Public Scudo interface header. +// +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_SCUDO_INTERFACE_H_ +#define SANITIZER_SCUDO_INTERFACE_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + // This function may be optionally provided by a user and should return + // a string containing Scudo runtime options. See scudo_flags.h for details. + const char* __scudo_default_options(void); + + // This function allows to set the RSS limit at runtime. This can be either + // the hard limit (HardLimit=1) or the soft limit (HardLimit=0). The limit + // can be removed by setting LimitMb to 0. This function's parameters should + // be fully trusted to avoid security mishaps. + void __scudo_set_rss_limit(size_t LimitMb, int HardLimit); + + // This function outputs various allocator statistics for both the Primary + // and Secondary allocators, including memory usage, number of allocations + // and deallocations. + void __scudo_print_stats(void); +#ifdef __cplusplus +} // extern "C" +#endif + +#endif // SANITIZER_SCUDO_INTERFACE_H_ diff --git a/libsanitizer/include/sanitizer/tsan_interface.h b/libsanitizer/include/sanitizer/tsan_interface.h index 9d9119262f8..b86062bb119 100644 --- a/libsanitizer/include/sanitizer/tsan_interface.h +++ b/libsanitizer/include/sanitizer/tsan_interface.h @@ -42,6 +42,11 @@ const unsigned __tsan_mutex_linker_init = 1 << 0; const unsigned __tsan_mutex_write_reentrant = 1 << 1; // Mutex is read reentrant. const unsigned __tsan_mutex_read_reentrant = 1 << 2; +// Mutex does not have static storage duration, and must not be used after +// its destructor runs. The opposite of __tsan_mutex_linker_init. +// If this flag is passed to __tsan_mutex_destroy, then the destruction +// is ignored unless this flag was previously set on the mutex. +const unsigned __tsan_mutex_not_static = 1 << 8; // Mutex operation flags: @@ -68,6 +73,7 @@ void __tsan_mutex_create(void *addr, unsigned flags); // Annotate destruction of a mutex. // Supported flags: // - __tsan_mutex_linker_init +// - __tsan_mutex_not_static void __tsan_mutex_destroy(void *addr, unsigned flags); // Annotate start of lock operation. diff --git a/libsanitizer/interception/interception.h b/libsanitizer/interception/interception.h index 75631da55ee..3d43df804f3 100644 --- a/libsanitizer/interception/interception.h +++ b/libsanitizer/interception/interception.h @@ -13,19 +13,21 @@ #ifndef INTERCEPTION_H #define INTERCEPTION_H -#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__APPLE__) && \ - !defined(__NetBSD__) && !defined(_WIN32) && !defined(__Fuchsia__) +#include "sanitizer_common/sanitizer_internal_defs.h" + +#if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_MAC && \ + !SANITIZER_NETBSD && !SANITIZER_OPENBSD && !SANITIZER_WINDOWS && \ + !SANITIZER_FUCHSIA && !SANITIZER_RTEMS && !SANITIZER_SOLARIS # error "Interception doesn't work on this operating system." #endif -#include "sanitizer_common/sanitizer_internal_defs.h" - // These typedefs should be used only in the interceptor definitions to replace // the standard system types (e.g. SSIZE_T instead of ssize_t) typedef __sanitizer::uptr SIZE_T; typedef __sanitizer::sptr SSIZE_T; typedef __sanitizer::sptr PTRDIFF_T; typedef __sanitizer::s64 INTMAX_T; +typedef __sanitizer::u64 UINTMAX_T; typedef __sanitizer::OFF_T OFF_T; typedef __sanitizer::OFF64_T OFF64_T; @@ -85,7 +87,7 @@ typedef __sanitizer::OFF64_T OFF64_T; // As it's decided at compile time which functions are to be intercepted on Mac, // INTERCEPT_FUNCTION() is effectively a no-op on this system. -#if defined(__APPLE__) +#if SANITIZER_MAC #include // For __DARWIN_ALIAS_C(). // Just a pair of pointers. @@ -119,7 +121,7 @@ const interpose_substitution substitution_##func_name[] \ # define INTERCEPTOR_ATTRIBUTE # define DECLARE_WRAPPER(ret_type, func, ...) -#elif defined(_WIN32) +#elif SANITIZER_WINDOWS # define WRAP(x) __asan_wrap_##x # define WRAPPER_NAME(x) "__asan_wrap_"#x # define INTERCEPTOR_ATTRIBUTE __declspec(dllexport) @@ -127,7 +129,12 @@ const interpose_substitution substitution_##func_name[] \ extern "C" ret_type func(__VA_ARGS__); # define DECLARE_WRAPPER_WINAPI(ret_type, func, ...) \ extern "C" __declspec(dllimport) ret_type __stdcall func(__VA_ARGS__); -#elif defined(__FreeBSD__) || defined(__NetBSD__) +#elif SANITIZER_RTEMS +# define WRAP(x) x +# define WRAPPER_NAME(x) #x +# define INTERCEPTOR_ATTRIBUTE +# define DECLARE_WRAPPER(ret_type, func, ...) +#elif SANITIZER_FREEBSD || SANITIZER_NETBSD # define WRAP(x) __interceptor_ ## x # define WRAPPER_NAME(x) "__interceptor_" #x # define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default"))) @@ -137,7 +144,7 @@ const interpose_substitution substitution_##func_name[] \ # define DECLARE_WRAPPER(ret_type, func, ...) \ extern "C" ret_type func(__VA_ARGS__) \ __attribute__((alias("__interceptor_" #func), visibility("default"))); -#elif !defined(__Fuchsia__) +#elif !SANITIZER_FUCHSIA # define WRAP(x) __interceptor_ ## x # define WRAPPER_NAME(x) "__interceptor_" #x # define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default"))) @@ -146,7 +153,7 @@ const interpose_substitution substitution_##func_name[] \ __attribute__((weak, alias("__interceptor_" #func), visibility("default"))); #endif -#if defined(__Fuchsia__) +#if SANITIZER_FUCHSIA // There is no general interception at all on Fuchsia. // Sanitizer runtimes just define functions directly to preempt them, // and have bespoke ways to access the underlying libc functions. @@ -154,10 +161,14 @@ const interpose_substitution substitution_##func_name[] \ # define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default"))) # define REAL(x) __unsanitized_##x # define DECLARE_REAL(ret_type, func, ...) -#elif !defined(__APPLE__) +#elif SANITIZER_RTEMS +# define REAL(x) __real_ ## x +# define DECLARE_REAL(ret_type, func, ...) \ + extern "C" ret_type REAL(func)(__VA_ARGS__); +#elif !SANITIZER_MAC # define PTR_TO_REAL(x) real_##x # define REAL(x) __interception::PTR_TO_REAL(x) -# define FUNC_TYPE(x) x##_f +# define FUNC_TYPE(x) x##_type # define DECLARE_REAL(ret_type, func, ...) \ typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \ @@ -165,14 +176,14 @@ const interpose_substitution substitution_##func_name[] \ extern FUNC_TYPE(func) PTR_TO_REAL(func); \ } # define ASSIGN_REAL(dst, src) REAL(dst) = REAL(src) -#else // __APPLE__ +#else // SANITIZER_MAC # define REAL(x) x # define DECLARE_REAL(ret_type, func, ...) \ extern "C" ret_type func(__VA_ARGS__); # define ASSIGN_REAL(x, y) -#endif // __APPLE__ +#endif // SANITIZER_MAC -#if !defined(__Fuchsia__) +#if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS #define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...) \ DECLARE_REAL(ret_type, func, __VA_ARGS__) \ extern "C" ret_type WRAP(func)(__VA_ARGS__); @@ -184,7 +195,7 @@ const interpose_substitution substitution_##func_name[] \ // macros does its job. In exceptional cases you may need to call REAL(foo) // without defining INTERCEPTOR(..., foo, ...). For example, if you override // foo with an interceptor for other function. -#if !defined(__APPLE__) && !defined(__Fuchsia__) +#if !SANITIZER_MAC && !SANITIZER_FUCHSIA && !SANITIZER_RTEMS # define DEFINE_REAL(ret_type, func, ...) \ typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \ namespace __interception { \ @@ -194,7 +205,7 @@ const interpose_substitution substitution_##func_name[] \ # define DEFINE_REAL(ret_type, func, ...) #endif -#if defined(__Fuchsia__) +#if SANITIZER_FUCHSIA // We need to define the __interceptor_func name just to get // sanitizer_common/scripts/gen_dynamic_list.py to export func. @@ -204,7 +215,7 @@ const interpose_substitution substitution_##func_name[] \ __interceptor_##func(__VA_ARGS__); \ extern "C" INTERCEPTOR_ATTRIBUTE ret_type func(__VA_ARGS__) -#elif !defined(__APPLE__) +#elif !SANITIZER_MAC #define INTERCEPTOR(ret_type, func, ...) \ DEFINE_REAL(ret_type, func, __VA_ARGS__) \ @@ -217,7 +228,7 @@ const interpose_substitution substitution_##func_name[] \ #define INTERCEPTOR_WITH_SUFFIX(ret_type, func, ...) \ INTERCEPTOR(ret_type, func, __VA_ARGS__) -#else // __APPLE__ +#else // SANITIZER_MAC #define INTERCEPTOR_ZZZ(suffix, ret_type, func, ...) \ extern "C" ret_type func(__VA_ARGS__) suffix; \ @@ -236,7 +247,7 @@ const interpose_substitution substitution_##func_name[] \ INTERPOSER_2(overridee, WRAP(overrider)) #endif -#if defined(_WIN32) +#if SANITIZER_WINDOWS # define INTERCEPTOR_WINAPI(ret_type, func, ...) \ typedef ret_type (__stdcall *FUNC_TYPE(func))(__VA_ARGS__); \ namespace __interception { \ @@ -262,17 +273,19 @@ typedef unsigned long uptr; // NOLINT #define INCLUDED_FROM_INTERCEPTION_LIB -#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ + SANITIZER_OPENBSD || SANITIZER_SOLARIS + # include "interception_linux.h" # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) # define INTERCEPT_FUNCTION_VER(func, symver) \ INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) -#elif defined(__APPLE__) +#elif SANITIZER_MAC # include "interception_mac.h" # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_MAC(func) # define INTERCEPT_FUNCTION_VER(func, symver) \ INTERCEPT_FUNCTION_VER_MAC(func, symver) -#elif defined(_WIN32) +#elif SANITIZER_WINDOWS # include "interception_win.h" # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_WIN(func) # define INTERCEPT_FUNCTION_VER(func, symver) \ diff --git a/libsanitizer/interception/interception_linux.cc b/libsanitizer/interception/interception_linux.cc index 888b2ceac13..781b77e46fd 100644 --- a/libsanitizer/interception/interception_linux.cc +++ b/libsanitizer/interception/interception_linux.cc @@ -10,32 +10,44 @@ // Linux-specific interception methods. //===----------------------------------------------------------------------===// -#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) #include "interception.h" +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ + SANITIZER_OPENBSD || SANITIZER_SOLARIS + #include // for dlsym() and dlvsym() -#ifdef __NetBSD__ +#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) { -#ifdef __NetBSD__ +#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; } -#if !defined(__ANDROID__) // android does not have dlvsym +// 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 // !defined(__ANDROID__) +#endif // !SANITIZER_ANDROID } // namespace __interception -#endif // __linux__ || __FreeBSD__ || __NetBSD__ +#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 f5965180888..37e6386df5b 100644 --- a/libsanitizer/interception/interception_linux.h +++ b/libsanitizer/interception/interception_linux.h @@ -10,7 +10,8 @@ // Linux-specific interception methods. //===----------------------------------------------------------------------===// -#if defined(__linux__) || defined(__FreeBSD__) || defined(__NetBSD__) +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ + SANITIZER_OPENBSD || SANITIZER_SOLARIS #if !defined(INCLUDED_FROM_INTERCEPTION_LIB) # error "interception_linux.h should be included from interception library only" @@ -32,14 +33,16 @@ void *GetFuncAddrVer(const char *func_name, const char *ver); (::__interception::uptr) & (func), \ (::__interception::uptr) & WRAP(func)) -#if !defined(__ANDROID__) // android does not have dlvsym +// 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##_f)( \ + (::__interception::real_##func = (func##_type)( \ unsigned long)::__interception::GetFuncAddrVer(#func, symver)) #else #define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \ INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) -#endif // !defined(__ANDROID__) +#endif // !SANITIZER_ANDROID && !SANITIZER_SOLARIS #endif // INTERCEPTION_LINUX_H -#endif // __linux__ || __FreeBSD__ || __NetBSD__ +#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || + // SANITIZER_OPENBSD || SANITIZER_SOLARIS diff --git a/libsanitizer/interception/interception_mac.cc b/libsanitizer/interception/interception_mac.cc index 801dcba3d13..1ffc1af9d55 100644 --- a/libsanitizer/interception/interception_mac.cc +++ b/libsanitizer/interception/interception_mac.cc @@ -10,9 +10,8 @@ // Mac-specific interception methods. //===----------------------------------------------------------------------===// -#ifdef __APPLE__ - #include "interception.h" +#if SANITIZER_MAC -#endif // __APPLE__ +#endif // SANITIZER_MAC diff --git a/libsanitizer/interception/interception_mac.h b/libsanitizer/interception/interception_mac.h index fbcb473b579..c3a3eace53d 100644 --- a/libsanitizer/interception/interception_mac.h +++ b/libsanitizer/interception/interception_mac.h @@ -10,7 +10,7 @@ // Mac-specific interception methods. //===----------------------------------------------------------------------===// -#ifdef __APPLE__ +#if SANITIZER_MAC #if !defined(INCLUDED_FROM_INTERCEPTION_LIB) # error "interception_mac.h should be included from interception.h only" @@ -23,4 +23,4 @@ #define INTERCEPT_FUNCTION_VER_MAC(func, symver) #endif // INTERCEPTION_MAC_H -#endif // __APPLE__ +#endif // SANITIZER_MAC diff --git a/libsanitizer/interception/interception_type_test.cc b/libsanitizer/interception/interception_type_test.cc index 6ba45e26dda..726cc7b71b2 100644 --- a/libsanitizer/interception/interception_type_test.cc +++ b/libsanitizer/interception/interception_type_test.cc @@ -10,9 +10,10 @@ // Compile-time tests of the internal type definitions. //===----------------------------------------------------------------------===// -#if defined(__linux__) || defined(__APPLE__) - #include "interception.h" + +#if SANITIZER_LINUX || SANITIZER_MAC + #include #include #include @@ -22,14 +23,14 @@ COMPILER_CHECK(sizeof(::SSIZE_T) == sizeof(ssize_t)); COMPILER_CHECK(sizeof(::PTRDIFF_T) == sizeof(ptrdiff_t)); COMPILER_CHECK(sizeof(::INTMAX_T) == sizeof(intmax_t)); -#ifndef __APPLE__ +#if !SANITIZER_MAC COMPILER_CHECK(sizeof(::OFF64_T) == sizeof(off64_t)); #endif // The following are the cases when pread (and friends) is used instead of // pread64. In those cases we need OFF_T to match off_t. We don't care about the // rest (they depend on _FILE_OFFSET_BITS setting when building an application). -# if defined(__ANDROID__) || !defined _FILE_OFFSET_BITS || \ +# if SANITIZER_ANDROID || !defined _FILE_OFFSET_BITS || \ _FILE_OFFSET_BITS != 64 COMPILER_CHECK(sizeof(::OFF_T) == sizeof(off_t)); # endif diff --git a/libsanitizer/interception/interception_win.cc b/libsanitizer/interception/interception_win.cc index 1957397bdad..74f444d8f4a 100644 --- a/libsanitizer/interception/interception_win.cc +++ b/libsanitizer/interception/interception_win.cc @@ -123,9 +123,9 @@ // addr2: .bytes //===----------------------------------------------------------------------===// -#ifdef _WIN32 - #include "interception.h" + +#if SANITIZER_WINDOWS #include "sanitizer_common/sanitizer_platform.h" #define WIN32_LEAN_AND_MEAN #include @@ -221,8 +221,8 @@ static bool IsMemoryPadding(uptr address, uptr size) { return true; } -static const u8 kHintNop9Bytes[] = { - 0x66, 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 +static const u8 kHintNop8Bytes[] = { + 0x0F, 0x1F, 0x84, 0x00, 0x00, 0x00, 0x00, 0x00 }; template @@ -237,8 +237,8 @@ static bool FunctionHasPrefix(uptr address, const T &pattern) { static bool FunctionHasPadding(uptr address, uptr size) { if (IsMemoryPadding(address - size, size)) return true; - if (size <= sizeof(kHintNop9Bytes) && - FunctionHasPrefix(address, kHintNop9Bytes)) + if (size <= sizeof(kHintNop8Bytes) && + FunctionHasPrefix(address, kHintNop8Bytes)) return true; return false; } @@ -451,6 +451,7 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { } switch (*(u16*)(address)) { + case 0x018A: // 8A 01 : mov al, byte ptr [ecx] case 0xFF8B: // 8B FF : mov edi, edi case 0xEC8B: // 8B EC : mov ebp, esp case 0xc889: // 89 C8 : mov eax, ecx @@ -551,7 +552,10 @@ static size_t GetInstructionSize(uptr address, size_t* rel_offset = nullptr) { case 0x246c8948: // 48 89 6C 24 XX : mov QWORD ptr [rsp + XX], rbp 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 return 5; + case 0x24648348: // 48 83 64 24 XX : and QWORD PTR [rsp + XX], YY + return 6; } #else @@ -830,6 +834,7 @@ bool OverrideFunction( static void **InterestingDLLsAvailable() { static const char *InterestingDLLs[] = { "kernel32.dll", + "msvcr100.dll", // VS2010 "msvcr110.dll", // VS2012 "msvcr120.dll", // VS2013 "vcruntime140.dll", // VS2015 @@ -1007,4 +1012,4 @@ bool OverrideImportedFunction(const char *module_to_patch, } // namespace __interception -#endif // _WIN32 +#endif // SANITIZER_MAC diff --git a/libsanitizer/interception/interception_win.h b/libsanitizer/interception/interception_win.h index f092d18d28f..3202a0e37b6 100644 --- a/libsanitizer/interception/interception_win.h +++ b/libsanitizer/interception/interception_win.h @@ -10,7 +10,7 @@ // Windows-specific interception methods. //===----------------------------------------------------------------------===// -#ifdef _WIN32 +#if SANITIZER_WINDOWS #if !defined(INCLUDED_FROM_INTERCEPTION_LIB) # error "interception_win.h should be included from interception library only" @@ -79,4 +79,4 @@ void TestOnlyReleaseTrampolineRegions(); (::__interception::uptr *)&REAL(func)) #endif // INTERCEPTION_WIN_H -#endif // _WIN32 +#endif // SANITIZER_WINDOWS diff --git a/libsanitizer/lsan/lsan.cc b/libsanitizer/lsan/lsan.cc index 7540aeb327b..e9261109c9e 100644 --- a/libsanitizer/lsan/lsan.cc +++ b/libsanitizer/lsan/lsan.cc @@ -64,16 +64,17 @@ static void InitializeFlags() { if (Verbosity()) ReportUnrecognizedFlags(); if (common_flags()->help) parser.PrintFlagDescriptions(); + + __sanitizer_set_report_path(common_flags()->log_path); } static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { - GetStackTraceWithPcBpAndContext(stack, kStackTraceMax, sig.pc, sig.bp, - sig.context, - common_flags()->fast_unwind_on_fatal); + GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context, + common_flags()->fast_unwind_on_fatal); } -void LsanOnDeadlySignal(int signo, void *siginfo, void *context) { +static void LsanOnDeadlySignal(int signo, void *siginfo, void *context) { HandleDeadlySignal(siginfo, context, GetCurrentThread(), &OnStackUnwind, nullptr); } diff --git a/libsanitizer/lsan/lsan.h b/libsanitizer/lsan/lsan.h index 42d4214ed0f..a40493c8879 100644 --- a/libsanitizer/lsan/lsan.h +++ b/libsanitizer/lsan/lsan.h @@ -16,9 +16,8 @@ #define GET_STACK_TRACE(max_size, fast) \ __sanitizer::BufferedStackTrace stack; \ - GetStackTraceWithPcBpAndContext(&stack, max_size, \ - StackTrace::GetCurrentPc(), \ - GET_CURRENT_FRAME(), nullptr, fast); + GetStackTrace(&stack, max_size, StackTrace::GetCurrentPc(), \ + GET_CURRENT_FRAME(), nullptr, fast); #define GET_STACK_TRACE_FATAL \ GET_STACK_TRACE(kStackTraceMax, common_flags()->fast_unwind_on_fatal) @@ -44,10 +43,9 @@ void ReplaceSystemMalloc(); // 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 GetStackTraceWithPcBpAndContext(__sanitizer::BufferedStackTrace *stack, - __sanitizer::uptr max_depth, - __sanitizer::uptr pc, __sanitizer::uptr bp, - void *context, bool fast) { +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())) { diff --git a/libsanitizer/lsan/lsan_allocator.cc b/libsanitizer/lsan/lsan_allocator.cc index 9e166807791..6b57c5070a9 100644 --- a/libsanitizer/lsan/lsan_allocator.cc +++ b/libsanitizer/lsan/lsan_allocator.cc @@ -15,6 +15,7 @@ #include "sanitizer_common/sanitizer_allocator.h" #include "sanitizer_common/sanitizer_allocator_checks.h" #include "sanitizer_common/sanitizer_allocator_interface.h" +#include "sanitizer_common/sanitizer_allocator_report.h" #include "sanitizer_common/sanitizer_errno.h" #include "sanitizer_common/sanitizer_internal_defs.h" #include "sanitizer_common/sanitizer_stackdepot.h" @@ -68,15 +69,27 @@ static void RegisterDeallocation(void *p) { atomic_store(reinterpret_cast(m), 0, memory_order_relaxed); } +static void *ReportAllocationSizeTooBig(uptr size, const StackTrace &stack) { + if (AllocatorMayReturnNull()) { + Report("WARNING: LeakSanitizer failed to allocate 0x%zx bytes\n", size); + return nullptr; + } + ReportAllocationSizeTooBig(size, kMaxAllowedMallocSize, &stack); +} + void *Allocate(const StackTrace &stack, uptr size, uptr alignment, bool cleared) { if (size == 0) size = 1; - if (size > kMaxAllowedMallocSize) { - Report("WARNING: LeakSanitizer failed to allocate %zu bytes\n", size); - return Allocator::FailureHandler::OnBadRequest(); - } + if (size > kMaxAllowedMallocSize) + return ReportAllocationSizeTooBig(size, stack); void *p = allocator.Allocate(GetAllocatorCache(), size, alignment); + if (UNLIKELY(!p)) { + SetAllocatorOutOfMemory(); + if (AllocatorMayReturnNull()) + return nullptr; + ReportOutOfMemory(size, &stack); + } // Do not rely on the allocator to clear the memory (it's slow). if (cleared && allocator.FromPrimary(p)) memset(p, 0, size); @@ -87,8 +100,11 @@ void *Allocate(const StackTrace &stack, uptr size, uptr alignment, } static void *Calloc(uptr nmemb, uptr size, const StackTrace &stack) { - if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) - return Allocator::FailureHandler::OnBadRequest(); + if (UNLIKELY(CheckForCallocOverflow(size, nmemb))) { + if (AllocatorMayReturnNull()) + return nullptr; + ReportCallocOverflow(nmemb, size, &stack); + } size *= nmemb; return Allocate(stack, size, 1, true); } @@ -104,9 +120,8 @@ void *Reallocate(const StackTrace &stack, void *p, uptr new_size, uptr alignment) { RegisterDeallocation(p); if (new_size > kMaxAllowedMallocSize) { - Report("WARNING: LeakSanitizer failed to allocate %zu bytes\n", new_size); allocator.Deallocate(GetAllocatorCache(), p); - return Allocator::FailureHandler::OnBadRequest(); + return ReportAllocationSizeTooBig(new_size, stack); } p = allocator.Reallocate(GetAllocatorCache(), p, new_size, alignment); RegisterAllocation(stack, p, new_size); @@ -124,10 +139,38 @@ uptr GetMallocUsableSize(const void *p) { return m->requested_size; } +int lsan_posix_memalign(void **memptr, uptr alignment, uptr size, + const StackTrace &stack) { + if (UNLIKELY(!CheckPosixMemalignAlignment(alignment))) { + if (AllocatorMayReturnNull()) + return errno_EINVAL; + ReportInvalidPosixMemalignAlignment(alignment, &stack); + } + void *ptr = Allocate(stack, size, alignment, kAlwaysClearMemory); + if (UNLIKELY(!ptr)) + // OOM error is already taken care of by Allocate. + return errno_ENOMEM; + CHECK(IsAligned((uptr)ptr, alignment)); + *memptr = ptr; + return 0; +} + +void *lsan_aligned_alloc(uptr alignment, uptr size, const StackTrace &stack) { + if (UNLIKELY(!CheckAlignedAllocAlignmentAndSize(alignment, size))) { + errno = errno_EINVAL; + if (AllocatorMayReturnNull()) + return nullptr; + ReportInvalidAlignedAllocAlignment(size, alignment, &stack); + } + return SetErrnoOnNull(Allocate(stack, size, alignment, kAlwaysClearMemory)); +} + void *lsan_memalign(uptr alignment, uptr size, const StackTrace &stack) { if (UNLIKELY(!IsPowerOfTwo(alignment))) { errno = errno_EINVAL; - return Allocator::FailureHandler::OnBadRequest(); + if (AllocatorMayReturnNull()) + return nullptr; + ReportInvalidAllocationAlignment(alignment, &stack); } return SetErrnoOnNull(Allocate(stack, size, alignment, kAlwaysClearMemory)); } @@ -153,6 +196,19 @@ void *lsan_valloc(uptr size, const StackTrace &stack) { Allocate(stack, size, GetPageSizeCached(), kAlwaysClearMemory)); } +void *lsan_pvalloc(uptr size, const StackTrace &stack) { + uptr PageSize = GetPageSizeCached(); + if (UNLIKELY(CheckForPvallocOverflow(size, PageSize))) { + errno = errno_ENOMEM; + if (AllocatorMayReturnNull()) + return nullptr; + ReportPvallocOverflow(size, &stack); + } + // pvalloc(0) should allocate one page. + size = size ? RoundUpTo(size, PageSize) : PageSize; + return SetErrnoOnNull(Allocate(stack, size, PageSize, kAlwaysClearMemory)); +} + uptr lsan_mz_size(const void *p) { return GetMallocUsableSize(p); } diff --git a/libsanitizer/lsan/lsan_allocator.h b/libsanitizer/lsan/lsan_allocator.h index b0c0ec241d9..37260c0b5ae 100644 --- a/libsanitizer/lsan/lsan_allocator.h +++ b/libsanitizer/lsan/lsan_allocator.h @@ -66,9 +66,16 @@ struct AP32 { }; typedef SizeClassAllocator32 PrimaryAllocator; #elif defined(__x86_64__) || defined(__powerpc64__) +# if defined(__powerpc64__) +const uptr kAllocatorSpace = 0xa0000000000ULL; +const uptr kAllocatorSize = 0x20000000000ULL; // 2T. +# else +const uptr kAllocatorSpace = 0x600000000000ULL; +const uptr kAllocatorSize = 0x40000000000ULL; // 4T. +# endif struct AP64 { // Allocator64 parameters. Deliberately using a short name. - static const uptr kSpaceBeg = 0x600000000000ULL; - static const uptr kSpaceSize = 0x40000000000ULL; // 4T. + static const uptr kSpaceBeg = kAllocatorSpace; + static const uptr kSpaceSize = kAllocatorSize; static const uptr kMetadataSize = sizeof(ChunkMetadata); typedef DefaultSizeClassMap SizeClassMap; typedef NoOpMapUnmapCallback MapUnmapCallback; @@ -81,12 +88,16 @@ typedef SizeClassAllocatorLocalCache AllocatorCache; AllocatorCache *GetAllocatorCache(); +int lsan_posix_memalign(void **memptr, uptr alignment, uptr size, + const StackTrace &stack); +void *lsan_aligned_alloc(uptr alignment, uptr size, const StackTrace &stack); 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_calloc(uptr nmemb, uptr size, const StackTrace &stack); void *lsan_valloc(uptr size, const StackTrace &stack); +void *lsan_pvalloc(uptr size, const StackTrace &stack); uptr lsan_mz_size(const void *p); } // namespace __lsan diff --git a/libsanitizer/lsan/lsan_common.cc b/libsanitizer/lsan/lsan_common.cc index 4afce9df071..a4424a8871a 100644 --- a/libsanitizer/lsan/lsan_common.cc +++ b/libsanitizer/lsan/lsan_common.cc @@ -13,14 +13,15 @@ #include "lsan_common.h" #include "sanitizer_common/sanitizer_common.h" -#include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_flag_parser.h" +#include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_placement_new.h" #include "sanitizer_common/sanitizer_procmaps.h" +#include "sanitizer_common/sanitizer_report_decorator.h" #include "sanitizer_common/sanitizer_stackdepot.h" #include "sanitizer_common/sanitizer_stacktrace.h" #include "sanitizer_common/sanitizer_suppressions.h" -#include "sanitizer_common/sanitizer_report_decorator.h" +#include "sanitizer_common/sanitizer_thread_registry.h" #include "sanitizer_common/sanitizer_tls_get_addr.h" #if CAN_SANITIZE_LEAKS @@ -102,7 +103,7 @@ InternalMmapVector const *GetRootRegions() { return root_regions; } void InitializeRootRegions() { CHECK(!root_regions); ALIGNED(64) static char placeholder[sizeof(InternalMmapVector)]; - root_regions = new(placeholder) InternalMmapVector(1); + root_regions = new (placeholder) InternalMmapVector(); // NOLINT } const char *MaybeCallLsanDefaultOptions() { @@ -212,9 +213,10 @@ void ForEachExtraStackRangeCb(uptr begin, uptr end, void* arg) { // Scans thread data (stacks and TLS) for heap pointers. static void ProcessThreads(SuspendedThreadsList const &suspended_threads, Frontier *frontier) { - InternalScopedBuffer registers(suspended_threads.RegisterCount()); + InternalMmapVector registers(suspended_threads.RegisterCount()); uptr registers_begin = reinterpret_cast(registers.data()); - uptr registers_end = registers_begin + registers.size(); + uptr registers_end = + reinterpret_cast(registers.data() + registers.size()); for (uptr i = 0; i < suspended_threads.ThreadCount(); i++) { tid_t os_id = static_cast(suspended_threads.GetThreadID(i)); LOG_THREADS("Processing thread %d.\n", os_id); @@ -409,8 +411,9 @@ static void MarkInvalidPCCb(uptr chunk, void *arg) { } } -// On Linux, handles dynamically allocated TLS blocks by treating all chunks -// allocated from ld-linux.so as reachable. +// On Linux, treats all chunks allocated from ld-linux.so as reachable, which +// covers dynamically allocated TLS blocks, internal dynamic loader's loaded +// modules accounting etc. // Dynamic TLS blocks contain the TLS variables of dynamically loaded modules. // They are allocated with a __libc_memalign() call in allocate_and_init() // (elf/dl-tls.c). Glibc won't tell us the address ranges occupied by those @@ -441,7 +444,7 @@ void ProcessPC(Frontier *frontier) { // Sets the appropriate tag on each chunk. static void ClassifyAllChunks(SuspendedThreadsList const &suspended_threads) { // Holds the flood fill frontier. - Frontier frontier(1); + Frontier frontier; ForEachChunk(CollectIgnoredCb, &frontier); ProcessGlobalRegions(&frontier); @@ -503,7 +506,7 @@ static void CollectLeaksCb(uptr chunk, void *arg) { } static void PrintMatchedSuppressions() { - InternalMmapVector matched(1); + InternalMmapVector matched; GetSuppressionContext()->GetMatched(&matched); if (!matched.size()) return; @@ -522,11 +525,36 @@ struct CheckForLeaksParam { LeakReport leak_report; }; +static void ReportIfNotSuspended(ThreadContextBase *tctx, void *arg) { + const InternalMmapVector &suspended_threads = + *(const InternalMmapVector *)arg; + if (tctx->status == ThreadStatusRunning) { + uptr i = InternalLowerBound(suspended_threads, 0, suspended_threads.size(), + tctx->os_id, CompareLess()); + if (i >= suspended_threads.size() || suspended_threads[i] != tctx->os_id) + Report("Running thread %d was not suspended. False leaks are possible.\n", + tctx->os_id); + }; +} + +static void ReportUnsuspendedThreads( + const SuspendedThreadsList &suspended_threads) { + InternalMmapVector threads(suspended_threads.ThreadCount()); + for (uptr i = 0; i < suspended_threads.ThreadCount(); ++i) + threads[i] = suspended_threads.GetThreadID(i); + + Sort(threads.data(), threads.size()); + + GetThreadRegistryLocked()->RunCallbackForEachThreadLocked( + &ReportIfNotSuspended, &threads); +} + static void CheckForLeaksCallback(const SuspendedThreadsList &suspended_threads, void *arg) { CheckForLeaksParam *param = reinterpret_cast(arg); CHECK(param); CHECK(!param->success); + ReportUnsuspendedThreads(suspended_threads); ClassifyAllChunks(suspended_threads); ForEachChunk(CollectLeaksCb, ¶m->leak_report); // Clean up for subsequent leak checks. This assumes we did not overwrite any @@ -681,7 +709,7 @@ void LeakReport::ReportTopLeaks(uptr num_leaks_to_report) { uptr unsuppressed_count = UnsuppressedLeakCount(); if (num_leaks_to_report > 0 && num_leaks_to_report < unsuppressed_count) Printf("The %zu top leak(s):\n", num_leaks_to_report); - InternalSort(&leaks_, leaks_.size(), LeakComparator); + Sort(leaks_.data(), leaks_.size(), &LeakComparator); uptr leaks_reported = 0; for (uptr i = 0; i < leaks_.size(); i++) { if (leaks_[i].is_suppressed) continue; diff --git a/libsanitizer/lsan/lsan_common.h b/libsanitizer/lsan/lsan_common.h index e99cd9e1b52..b82474a51c9 100644 --- a/libsanitizer/lsan/lsan_common.h +++ b/libsanitizer/lsan/lsan_common.h @@ -25,9 +25,9 @@ // 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. -// To enable LeakSanitizer on new architecture, one need to implement -// internal_clone function as well as (probably) adjust TLS machinery for -// new architecture inside sanitizer library. +// To enable LeakSanitizer on a new architecture, one needs to implement the +// internal_clone function as well as (probably) adjust the TLS machinery for +// the new architecture inside the sanitizer library. #if (SANITIZER_LINUX && !SANITIZER_ANDROID || SANITIZER_MAC) && \ (SANITIZER_WORDSIZE == 64) && \ (defined(__x86_64__) || defined(__mips64) || defined(__aarch64__) || \ @@ -45,6 +45,7 @@ namespace __sanitizer { class FlagParser; +class ThreadRegistry; struct DTLS; } @@ -93,7 +94,7 @@ struct LeakedObject { // Aggregates leaks by stack trace prefix. class LeakReport { public: - LeakReport() : next_id_(0), leaks_(1), leaked_objects_(1) {} + LeakReport() {} void AddLeakedChunk(uptr chunk, u32 stack_trace_id, uptr leaked_size, ChunkTag tag); void ReportTopLeaks(uptr max_leaks); @@ -101,12 +102,11 @@ class LeakReport { void ApplySuppressions(); uptr UnsuppressedLeakCount(); - private: void PrintReportForLeak(uptr index); void PrintLeakedObjectsForLeak(uptr index); - u32 next_id_; + u32 next_id_ = 0; InternalMmapVector leaks_; InternalMmapVector leaked_objects_; }; @@ -203,6 +203,7 @@ bool WordIsPoisoned(uptr addr); // Wrappers for ThreadRegistry access. void LockThreadRegistry(); void UnlockThreadRegistry(); +ThreadRegistry *GetThreadRegistryLocked(); bool GetThreadRangesLocked(tid_t os_id, uptr *stack_begin, uptr *stack_end, uptr *tls_begin, uptr *tls_end, uptr *cache_begin, uptr *cache_end, DTLS **dtls); diff --git a/libsanitizer/lsan/lsan_common_linux.cc b/libsanitizer/lsan/lsan_common_linux.cc index 677727229b1..cffbfc9f8b1 100644 --- a/libsanitizer/lsan/lsan_common_linux.cc +++ b/libsanitizer/lsan/lsan_common_linux.cc @@ -18,6 +18,7 @@ #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_flags.h" +#include "sanitizer_common/sanitizer_getauxval.h" #include "sanitizer_common/sanitizer_linux.h" #include "sanitizer_common/sanitizer_stackdepot.h" @@ -28,8 +29,12 @@ static const char kLinkerName[] = "ld"; static char linker_placeholder[sizeof(LoadedModule)] ALIGNED(64); static LoadedModule *linker = nullptr; -static bool IsLinker(const char* full_name) { - return LibraryNameIs(full_name, kLinkerName); +static bool IsLinker(const LoadedModule& module) { +#if SANITIZER_USE_GETAUXVAL + return module.base_address() == getauxval(AT_BASE); +#else + return LibraryNameIs(module.full_name(), kLinkerName); +#endif // SANITIZER_USE_GETAUXVAL } __attribute__((tls_model("initial-exec"))) @@ -47,22 +52,25 @@ void InitializePlatformSpecificModules() { ListOfModules modules; modules.init(); for (LoadedModule &module : modules) { - if (!IsLinker(module.full_name())) continue; + if (!IsLinker(module)) + continue; if (linker == nullptr) { linker = reinterpret_cast(linker_placeholder); *linker = module; module = LoadedModule(); } else { VReport(1, "LeakSanitizer: Multiple modules match \"%s\". " - "TLS will not be handled correctly.\n", kLinkerName); + "TLS and other allocations originating from linker might be " + "falsely reported as leaks.\n", kLinkerName); linker->clear(); linker = nullptr; return; } } if (linker == nullptr) { - VReport(1, "LeakSanitizer: Dynamic linker not found. " - "TLS will not be handled correctly.\n"); + VReport(1, "LeakSanitizer: Dynamic linker not found. TLS and other " + "allocations originating from linker might be falsely reported " + "as leaks.\n"); } } diff --git a/libsanitizer/lsan/lsan_common_mac.cc b/libsanitizer/lsan/lsan_common_mac.cc index 6e763dab7f8..8337cd2116f 100644 --- a/libsanitizer/lsan/lsan_common_mac.cc +++ b/libsanitizer/lsan/lsan_common_mac.cc @@ -117,7 +117,8 @@ void ProcessGlobalRegions(Frontier *frontier) { for (auto name : kSkippedSecNames) CHECK(ARRAY_SIZE(name) < kMaxSegName); MemoryMappingLayout memory_mapping(false); - InternalMmapVector modules(/*initial_capacity*/ 128); + InternalMmapVector modules; + modules.reserve(128); memory_mapping.DumpListOfModules(&modules); for (uptr i = 0; i < modules.size(); ++i) { // Even when global scanning is disabled, we still need to scan @@ -139,12 +140,6 @@ void ProcessGlobalRegions(Frontier *frontier) { } void ProcessPlatformSpecificAllocations(Frontier *frontier) { - mach_port_name_t port; - if (task_for_pid(mach_task_self(), internal_getpid(), &port) - != KERN_SUCCESS) { - return; - } - unsigned depth = 1; vm_size_t size = 0; vm_address_t address = 0; @@ -155,7 +150,7 @@ void ProcessPlatformSpecificAllocations(Frontier *frontier) { while (err == KERN_SUCCESS) { struct vm_region_submap_info_64 info; - err = vm_region_recurse_64(port, &address, &size, &depth, + err = vm_region_recurse_64(mach_task_self(), &address, &size, &depth, (vm_region_info_t)&info, &count); uptr end_address = address + size; diff --git a/libsanitizer/lsan/lsan_interceptors.cc b/libsanitizer/lsan/lsan_interceptors.cc index c9279aad676..7c594e5ed17 100644 --- a/libsanitizer/lsan/lsan_interceptors.cc +++ b/libsanitizer/lsan/lsan_interceptors.cc @@ -12,6 +12,7 @@ #include "interception/interception.h" #include "sanitizer_common/sanitizer_allocator.h" +#include "sanitizer_common/sanitizer_allocator_report.h" #include "sanitizer_common/sanitizer_atomic.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_flags.h" @@ -84,9 +85,7 @@ INTERCEPTOR(void*, realloc, void *q, uptr size) { INTERCEPTOR(int, posix_memalign, void **memptr, uptr alignment, uptr size) { ENSURE_LSAN_INITED; GET_STACK_TRACE_MALLOC; - *memptr = lsan_memalign(alignment, size, stack); - // FIXME: Return ENOMEM if user requested more than max alloc size. - return 0; + return lsan_posix_memalign(memptr, alignment, size, stack); } INTERCEPTOR(void*, valloc, uptr size) { @@ -121,7 +120,7 @@ INTERCEPTOR(void *, __libc_memalign, uptr alignment, uptr size) { INTERCEPTOR(void*, aligned_alloc, uptr alignment, uptr size) { ENSURE_LSAN_INITED; GET_STACK_TRACE_MALLOC; - return lsan_memalign(alignment, size, stack); + return lsan_aligned_alloc(alignment, size, stack); } #define LSAN_MAYBE_INTERCEPT_ALIGNED_ALLOC INTERCEPT_FUNCTION(aligned_alloc) #else @@ -164,13 +163,7 @@ INTERCEPTOR(int, mallopt, int cmd, int value) { INTERCEPTOR(void*, pvalloc, uptr size) { ENSURE_LSAN_INITED; GET_STACK_TRACE_MALLOC; - uptr PageSize = GetPageSizeCached(); - size = RoundUpTo(size, PageSize); - if (size == 0) { - // pvalloc(0) should allocate one page. - size = PageSize; - } - return Allocate(stack, size, GetPageSizeCached(), kAlwaysClearMemory); + return lsan_pvalloc(size, stack); } #define LSAN_MAYBE_INTERCEPT_PVALLOC INTERCEPT_FUNCTION(pvalloc) #else @@ -200,21 +193,21 @@ INTERCEPTOR(int, mprobe, void *ptr) { // TODO(alekseys): throw std::bad_alloc instead of dying on OOM. -#define OPERATOR_NEW_BODY(nothrow) \ - ENSURE_LSAN_INITED; \ - GET_STACK_TRACE_MALLOC; \ - void *res = lsan_malloc(size, stack); \ - if (!nothrow && UNLIKELY(!res)) DieOnFailure::OnOOM(); \ +#define OPERATOR_NEW_BODY(nothrow)\ + ENSURE_LSAN_INITED;\ + GET_STACK_TRACE_MALLOC;\ + void *res = lsan_malloc(size, stack);\ + if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\ return res; -#define OPERATOR_NEW_BODY_ALIGN(nothrow) \ - ENSURE_LSAN_INITED; \ - GET_STACK_TRACE_MALLOC; \ - void *res = lsan_memalign((uptr)align, size, stack); \ - if (!nothrow && UNLIKELY(!res)) DieOnFailure::OnOOM(); \ +#define OPERATOR_NEW_BODY_ALIGN(nothrow)\ + ENSURE_LSAN_INITED;\ + GET_STACK_TRACE_MALLOC;\ + void *res = lsan_memalign((uptr)align, size, stack);\ + if (!nothrow && UNLIKELY(!res)) ReportOutOfMemory(size, &stack);\ return res; -#define OPERATOR_DELETE_BODY \ - ENSURE_LSAN_INITED; \ +#define OPERATOR_DELETE_BODY\ + ENSURE_LSAN_INITED;\ lsan_free(ptr); // On OS X it's not enough to just provide our own 'operator new' and @@ -307,6 +300,7 @@ INTERCEPTOR(void, _ZdaPvRKSt9nothrow_t, void *ptr, std::nothrow_t const&) ///// Thread initialization and finalization. ///// +#if !SANITIZER_NETBSD && !SANITIZER_FREEBSD static unsigned g_thread_finalize_key; static void thread_finalize(void *v) { @@ -320,6 +314,29 @@ static void thread_finalize(void *v) { } ThreadFinish(); } +#endif + +#if SANITIZER_NETBSD +INTERCEPTOR(void, _lwp_exit) { + ENSURE_LSAN_INITED; + ThreadFinish(); + REAL(_lwp_exit)(); +} +#define LSAN_MAYBE_INTERCEPT__LWP_EXIT INTERCEPT_FUNCTION(_lwp_exit) +#else +#define LSAN_MAYBE_INTERCEPT__LWP_EXIT +#endif + +#if SANITIZER_INTERCEPT_THR_EXIT +INTERCEPTOR(void, thr_exit, tid_t *state) { + ENSURE_LSAN_INITED; + ThreadFinish(); + REAL(thr_exit)(state); +} +#define LSAN_MAYBE_INTERCEPT_THR_EXIT INTERCEPT_FUNCTION(thr_exit) +#else +#define LSAN_MAYBE_INTERCEPT_THR_EXIT +#endif struct ThreadParam { void *(*callback)(void *arg); @@ -333,11 +350,13 @@ extern "C" void *__lsan_thread_start_func(void *arg) { void *param = p->param; // Wait until the last iteration to maximize the chance that we are the last // destructor to run. +#if !SANITIZER_NETBSD && !SANITIZER_FREEBSD if (pthread_setspecific(g_thread_finalize_key, (void*)GetPthreadDestructorIterations())) { Report("LeakSanitizer: failed to set thread key.\n"); Die(); } +#endif int tid = 0; while ((tid = atomic_load(&p->tid, memory_order_acquire)) == 0) internal_sched_yield(); @@ -425,10 +444,15 @@ void InitializeInterceptors() { INTERCEPT_FUNCTION(pthread_join); INTERCEPT_FUNCTION(_exit); + LSAN_MAYBE_INTERCEPT__LWP_EXIT; + LSAN_MAYBE_INTERCEPT_THR_EXIT; + +#if !SANITIZER_NETBSD && !SANITIZER_FREEBSD if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) { Report("LeakSanitizer: failed to create thread key.\n"); Die(); } +#endif } } // namespace __lsan diff --git a/libsanitizer/lsan/lsan_malloc_mac.cc b/libsanitizer/lsan/lsan_malloc_mac.cc index 2d810af841f..2458b50892f 100644 --- a/libsanitizer/lsan/lsan_malloc_mac.cc +++ b/libsanitizer/lsan/lsan_malloc_mac.cc @@ -35,6 +35,9 @@ using namespace __lsan; #define COMMON_MALLOC_CALLOC(count, size) \ GET_STACK_TRACE_MALLOC; \ void *p = lsan_calloc(count, size, stack) +#define COMMON_MALLOC_POSIX_MEMALIGN(memptr, alignment, size) \ + GET_STACK_TRACE_MALLOC; \ + int res = lsan_posix_memalign(memptr, alignment, size, stack) #define COMMON_MALLOC_VALLOC(size) \ GET_STACK_TRACE_MALLOC; \ void *p = lsan_valloc(size, stack) diff --git a/libsanitizer/lsan/lsan_thread.cc b/libsanitizer/lsan/lsan_thread.cc index e03e8766ae1..388990bf5fd 100644 --- a/libsanitizer/lsan/lsan_thread.cc +++ b/libsanitizer/lsan/lsan_thread.cc @@ -153,4 +153,9 @@ void UnlockThreadRegistry() { thread_registry->Unlock(); } +ThreadRegistry *GetThreadRegistryLocked() { + thread_registry->CheckLocked(); + return thread_registry; +} + } // namespace __lsan diff --git a/libsanitizer/sanitizer_common/sancov_begin.S b/libsanitizer/sanitizer_common/sancov_begin.S new file mode 100644 index 00000000000..c8ad0a0bcb5 --- /dev/null +++ b/libsanitizer/sanitizer_common/sancov_begin.S @@ -0,0 +1,5 @@ + .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 new file mode 100644 index 00000000000..31117b1c0b5 --- /dev/null +++ b/libsanitizer/sanitizer_common/sancov_end.S @@ -0,0 +1,5 @@ + .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/sanitizer_allocator.cc b/libsanitizer/sanitizer_common/sanitizer_allocator.cc index 895efcf1be0..2fd6e8a4248 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator.cc +++ b/libsanitizer/sanitizer_common/sanitizer_allocator.cc @@ -19,6 +19,10 @@ namespace __sanitizer { +// Default allocator names. +const char *PrimaryAllocatorName = "SizeClassAllocator"; +const char *SecondaryAllocatorName = "LargeMmapAllocator"; + // ThreadSanitizer for Go uses libc malloc/free. #if SANITIZER_GO || defined(SANITIZER_USE_MALLOC) # if SANITIZER_LINUX && !SANITIZER_ANDROID @@ -134,12 +138,19 @@ static void RawInternalFree(void *ptr, InternalAllocatorCache *cache) { const u64 kBlockMagic = 0x6A6CB03ABCEBC041ull; +static void NORETURN ReportInternalAllocatorOutOfMemory(uptr requested_size) { + SetAllocatorOutOfMemory(); + Report("FATAL: %s: internal allocator is out of memory trying to allocate " + "0x%zx bytes\n", SanitizerToolName, requested_size); + Die(); +} + void *InternalAlloc(uptr size, InternalAllocatorCache *cache, uptr alignment) { if (size + sizeof(u64) < size) return nullptr; void *p = RawInternalAlloc(size + sizeof(u64), cache, alignment); - if (!p) - return nullptr; + if (UNLIKELY(!p)) + ReportInternalAllocatorOutOfMemory(size + sizeof(u64)); ((u64*)p)[0] = kBlockMagic; return (char*)p + sizeof(u64); } @@ -153,16 +164,21 @@ void *InternalRealloc(void *addr, uptr size, InternalAllocatorCache *cache) { size = size + sizeof(u64); CHECK_EQ(kBlockMagic, ((u64*)addr)[0]); void *p = RawInternalRealloc(addr, size, cache); - if (!p) - return nullptr; + if (UNLIKELY(!p)) + ReportInternalAllocatorOutOfMemory(size); return (char*)p + sizeof(u64); } void *InternalCalloc(uptr count, uptr size, InternalAllocatorCache *cache) { - if (UNLIKELY(CheckForCallocOverflow(count, size))) - return InternalAllocator::FailureHandler::OnBadRequest(); + if (UNLIKELY(CheckForCallocOverflow(count, size))) { + Report("FATAL: %s: calloc parameters overflow: count * size (%zd * %zd) " + "cannot be represented in type size_t\n", SanitizerToolName, count, + size); + Die(); + } void *p = InternalAlloc(count * size, cache); - if (p) internal_memset(p, 0, count * size); + if (LIKELY(p)) + internal_memset(p, 0, count * size); return p; } @@ -176,11 +192,13 @@ void InternalFree(void *addr, InternalAllocatorCache *cache) { } // LowLevelAllocator +constexpr uptr kLowLevelAllocatorDefaultAlignment = 8; +static uptr low_level_alloc_min_alignment = kLowLevelAllocatorDefaultAlignment; static LowLevelAllocateCallback low_level_alloc_callback; void *LowLevelAllocator::Allocate(uptr size) { // Align allocation size. - size = RoundUpTo(size, 8); + size = RoundUpTo(size, low_level_alloc_min_alignment); if (allocated_end_ - allocated_current_ < (sptr)size) { uptr size_to_allocate = Max(size, GetPageSizeCached()); allocated_current_ = @@ -197,10 +215,17 @@ void *LowLevelAllocator::Allocate(uptr size) { return res; } +void SetLowLevelAllocateMinAlignment(uptr alignment) { + CHECK(IsPowerOfTwo(alignment)); + low_level_alloc_min_alignment = Max(alignment, low_level_alloc_min_alignment); +} + void SetLowLevelAllocateCallback(LowLevelAllocateCallback callback) { low_level_alloc_callback = callback; } +// Allocator's OOM and other errors handling support. + static atomic_uint8_t allocator_out_of_memory = {0}; static atomic_uint8_t allocator_may_return_null = {0}; @@ -208,13 +233,8 @@ bool IsAllocatorOutOfMemory() { return atomic_load_relaxed(&allocator_out_of_memory); } -// Prints error message and kills the program. -void NORETURN ReportAllocatorCannotReturnNull() { - Report("%s's allocator is terminating the process instead of returning 0\n", - SanitizerToolName); - Report("If you don't like this behavior set allocator_may_return_null=1\n"); - CHECK(0); - Die(); +void SetAllocatorOutOfMemory() { + atomic_store_relaxed(&allocator_out_of_memory, 1); } bool AllocatorMayReturnNull() { @@ -226,26 +246,9 @@ void SetAllocatorMayReturnNull(bool may_return_null) { memory_order_relaxed); } -void *ReturnNullOrDieOnFailure::OnBadRequest() { - if (AllocatorMayReturnNull()) - return nullptr; - ReportAllocatorCannotReturnNull(); -} - -void *ReturnNullOrDieOnFailure::OnOOM() { - atomic_store_relaxed(&allocator_out_of_memory, 1); - if (AllocatorMayReturnNull()) - return nullptr; - ReportAllocatorCannotReturnNull(); -} - -void NORETURN *DieOnFailure::OnBadRequest() { - ReportAllocatorCannotReturnNull(); -} - -void NORETURN *DieOnFailure::OnOOM() { - atomic_store_relaxed(&allocator_out_of_memory, 1); - ReportAllocatorCannotReturnNull(); +void PrintHintAllocatorCannotReturnNull() { + Report("HINT: if you don't care about these errors you may set " + "allocator_may_return_null=1\n"); } } // namespace __sanitizer diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator.h b/libsanitizer/sanitizer_common/sanitizer_allocator.h index 523578a9d60..7dbb9f72017 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator.h @@ -22,28 +22,23 @@ namespace __sanitizer { +// Allows the tools to name their allocations appropriately. +extern const char *PrimaryAllocatorName; +extern const char *SecondaryAllocatorName; + // Since flags are immutable and allocator behavior can be changed at runtime // (unit tests or ASan on Android are some examples), allocator_may_return_null // flag value is cached here and can be altered later. bool AllocatorMayReturnNull(); void SetAllocatorMayReturnNull(bool may_return_null); -// Allocator failure handling policies: -// Implements AllocatorMayReturnNull policy, returns null when the flag is set, -// dies otherwise. -struct ReturnNullOrDieOnFailure { - static void *OnBadRequest(); - static void *OnOOM(); -}; -// Always dies on the failure. -struct DieOnFailure { - static void NORETURN *OnBadRequest(); - static void NORETURN *OnOOM(); -}; - // Returns true if allocator detected OOM condition. Can be used to avoid memory -// hungry operations. Set when AllocatorReturnNullOrDieOnOOM() is called. +// hungry operations. bool IsAllocatorOutOfMemory(); +// Should be called by a particular allocator when OOM is detected. +void SetAllocatorOutOfMemory(); + +void PrintHintAllocatorCannotReturnNull(); // Allocators call these callbacks on mmap/munmap. struct NoOpMapUnmapCallback { @@ -54,6 +49,21 @@ struct NoOpMapUnmapCallback { // Callback type for iterating over chunks. typedef void (*ForEachChunkCallback)(uptr chunk, void *arg); +INLINE u32 Rand(u32 *state) { // ANSI C linear congruential PRNG. + return (*state = *state * 1103515245 + 12345) >> 16; +} + +INLINE u32 RandN(u32 *state, u32 n) { return Rand(state) % n; } // [0, n) + +template +INLINE void RandomShuffle(T *a, u32 n, u32 *rand_state) { + if (n <= 1) return; + u32 state = *rand_state; + for (u32 i = n - 1; i > 0; i--) + Swap(a[i], a[RandN(&state, i + 1)]); + *rand_state = state; +} + #include "sanitizer_allocator_size_class_map.h" #include "sanitizer_allocator_stats.h" #include "sanitizer_allocator_primary64.h" diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_bytemap.h b/libsanitizer/sanitizer_common/sanitizer_allocator_bytemap.h index 5e768ce9ef9..3a3f22266f7 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_bytemap.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_bytemap.h @@ -16,7 +16,7 @@ template class FlatByteMap { public: - void TestOnlyInit() { + void Init() { internal_memset(map_, 0, sizeof(map_)); } @@ -42,7 +42,7 @@ class FlatByteMap { template class TwoLevelByteMap { public: - void TestOnlyInit() { + void Init() { internal_memset(map1_, 0, sizeof(map1_)); mu_.Init(); } diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_checks.h b/libsanitizer/sanitizer_common/sanitizer_allocator_checks.h index 978813222b5..9056ed57987 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_checks.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_checks.h @@ -42,16 +42,18 @@ INLINE void *SetErrnoOnNull(void *ptr) { // of alignment. INLINE bool CheckAlignedAllocAlignmentAndSize(uptr alignment, uptr size) { #if SANITIZER_POSIX - return IsPowerOfTwo(alignment) && (size & (alignment - 1)) == 0; + return alignment != 0 && IsPowerOfTwo(alignment) && + (size & (alignment - 1)) == 0; #else - return size % alignment == 0; + return alignment != 0 && size % alignment == 0; #endif } // Checks posix_memalign() parameters, verifies that alignment is a power of two // and a multiple of sizeof(void *). INLINE bool CheckPosixMemalignAlignment(uptr alignment) { - return IsPowerOfTwo(alignment) && (alignment % sizeof(void *)) == 0; // NOLINT + return alignment != 0 && IsPowerOfTwo(alignment) && + (alignment % sizeof(void *)) == 0; // NOLINT } // Returns true if calloc(size, n) call overflows on size*n calculation. diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_combined.h b/libsanitizer/sanitizer_common/sanitizer_allocator_combined.h index 99e411f4378..ec6c0da8538 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_combined.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_combined.h @@ -22,8 +22,6 @@ template // NOLINT class CombinedAllocator { public: - typedef typename SecondaryAllocator::FailureHandler FailureHandler; - void InitLinkerInitialized(s32 release_to_os_interval_ms) { primary_.Init(release_to_os_interval_ms); secondary_.InitLinkerInitialized(); @@ -40,8 +38,12 @@ class CombinedAllocator { // Returning 0 on malloc(0) may break a lot of code. if (size == 0) size = 1; - if (size + alignment < size) - return FailureHandler::OnBadRequest(); + if (size + alignment < size) { + Report("WARNING: %s: CombinedAllocator allocation overflow: " + "0x%zx bytes with 0x%zx alignment requested\n", + SanitizerToolName, size, alignment); + return nullptr; + } uptr original_size = size; // If alignment requirements are to be fulfilled by the frontend allocator // rather than by the primary or secondary, passing an alignment lower than @@ -60,8 +62,6 @@ class CombinedAllocator { res = cache->Allocate(&primary_, primary_.ClassID(size)); else res = secondary_.Allocate(&stats_, original_size, alignment); - if (!res) - return FailureHandler::OnOOM(); if (alignment > 8) CHECK_EQ(reinterpret_cast(res) & (alignment - 1), 0); return res; @@ -75,6 +75,10 @@ class CombinedAllocator { primary_.SetReleaseToOSIntervalMs(release_to_os_interval_ms); } + void ForceReleaseToOS() { + primary_.ForceReleaseToOS(); + } + void Deallocate(AllocatorCache *cache, void *p) { if (!p) return; if (primary_.PointerIsMine(p)) diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_interface.h b/libsanitizer/sanitizer_common/sanitizer_allocator_interface.h index fa74f8ca640..35213c74c00 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_interface.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_interface.h @@ -36,6 +36,9 @@ SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void __sanitizer_free_hook(void *ptr); +SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void +__sanitizer_purge_allocator(); + SANITIZER_INTERFACE_ATTRIBUTE SANITIZER_WEAK_ATTRIBUTE void __sanitizer_print_memory_profile(uptr top_percent, uptr max_number_of_contexts); } // extern "C" diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_internal.h b/libsanitizer/sanitizer_common/sanitizer_allocator_internal.h index f1aed0f3bec..05aed0ecfe0 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_internal.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_internal.h @@ -44,9 +44,12 @@ typedef SizeClassAllocator32 PrimaryInternalAllocator; typedef SizeClassAllocatorLocalCache InternalAllocatorCache; +typedef LargeMmapAllocator + SecondaryInternalAllocator; + typedef CombinedAllocator - > InternalAllocator; + SecondaryInternalAllocator> InternalAllocator; void *InternalAlloc(uptr size, InternalAllocatorCache *cache = nullptr, uptr alignment = 0); @@ -57,15 +60,6 @@ void *InternalCalloc(uptr countr, uptr size, void InternalFree(void *p, InternalAllocatorCache *cache = nullptr); InternalAllocator *internal_allocator(); -enum InternalAllocEnum { - INTERNAL_ALLOC -}; - } // namespace __sanitizer -inline void *operator new(__sanitizer::operator_new_size_type size, - __sanitizer::InternalAllocEnum) { - return __sanitizer::InternalAlloc(size); -} - #endif // SANITIZER_ALLOCATOR_INTERNAL_H diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_local_cache.h b/libsanitizer/sanitizer_common/sanitizer_allocator_local_cache.h index 99013e37f8a..d23c59aa05c 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_local_cache.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_local_cache.h @@ -17,8 +17,7 @@ // object per thread in TLS, is has to be POD. template struct SizeClassAllocatorLocalCache - : SizeClassAllocator::AllocatorCache { -}; + : SizeClassAllocator::AllocatorCache {}; // Cache used by SizeClassAllocator64. template @@ -44,13 +43,12 @@ struct SizeClassAllocator64LocalCache { if (UNLIKELY(c->count == 0)) { if (UNLIKELY(!Refill(c, allocator, class_id))) return nullptr; + DCHECK_GT(c->count, 0); } - stats_.Add(AllocatorStatAllocated, c->class_size); - CHECK_GT(c->count, 0); CompactPtrT chunk = c->chunks[--c->count]; - void *res = reinterpret_cast(allocator->CompactPtrToPointer( + stats_.Add(AllocatorStatAllocated, c->class_size); + return reinterpret_cast(allocator->CompactPtrToPointer( allocator->GetRegionBeginBySizeClass(class_id), chunk)); - return res; } void Deallocate(SizeClassAllocator *allocator, uptr class_id, void *p) { @@ -58,20 +56,19 @@ struct SizeClassAllocator64LocalCache { CHECK_LT(class_id, kNumClasses); // If the first allocator call on a new thread is a deallocation, then // max_count will be zero, leading to check failure. - InitCache(); PerClass *c = &per_class_[class_id]; - stats_.Sub(AllocatorStatAllocated, c->class_size); - CHECK_NE(c->max_count, 0UL); + InitCache(c); if (UNLIKELY(c->count == c->max_count)) Drain(c, allocator, class_id, c->max_count / 2); CompactPtrT chunk = allocator->PointerToCompactPtr( allocator->GetRegionBeginBySizeClass(class_id), reinterpret_cast(p)); c->chunks[c->count++] = chunk; + stats_.Sub(AllocatorStatAllocated, c->class_size); } void Drain(SizeClassAllocator *allocator) { - for (uptr i = 0; i < kNumClasses; i++) { + for (uptr i = 1; i < kNumClasses; i++) { PerClass *c = &per_class_[i]; while (c->count > 0) Drain(c, allocator, i, c->count); @@ -92,20 +89,22 @@ struct SizeClassAllocator64LocalCache { PerClass per_class_[kNumClasses]; AllocatorStats stats_; - void InitCache() { - if (LIKELY(per_class_[1].max_count)) + void InitCache(PerClass *c) { + if (LIKELY(c->max_count)) return; - for (uptr i = 0; i < kNumClasses; i++) { + for (uptr i = 1; i < kNumClasses; i++) { PerClass *c = &per_class_[i]; - c->max_count = 2 * SizeClassMap::MaxCachedHint(i); - c->class_size = Allocator::ClassIdToSize(i); + const uptr size = Allocator::ClassIdToSize(i); + c->max_count = 2 * SizeClassMap::MaxCachedHint(size); + c->class_size = size; } + DCHECK_NE(c->max_count, 0UL); } NOINLINE bool Refill(PerClass *c, SizeClassAllocator *allocator, uptr class_id) { - InitCache(); - uptr num_requested_chunks = c->max_count / 2; + InitCache(c); + const uptr num_requested_chunks = c->max_count / 2; if (UNLIKELY(!allocator->GetFromAllocator(&stats_, class_id, c->chunks, num_requested_chunks))) return false; @@ -115,9 +114,8 @@ struct SizeClassAllocator64LocalCache { NOINLINE void Drain(PerClass *c, SizeClassAllocator *allocator, uptr class_id, uptr count) { - InitCache(); CHECK_GE(c->count, count); - uptr first_idx_to_drain = c->count - count; + const uptr first_idx_to_drain = c->count - count; c->count -= count; allocator->ReturnToAllocator(&stats_, class_id, &c->chunks[first_idx_to_drain], count); @@ -162,12 +160,13 @@ struct SizeClassAllocator32LocalCache { CHECK_LT(class_id, kNumClasses); PerClass *c = &per_class_[class_id]; if (UNLIKELY(c->count == 0)) { - if (UNLIKELY(!Refill(allocator, class_id))) + if (UNLIKELY(!Refill(c, allocator, class_id))) return nullptr; + DCHECK_GT(c->count, 0); } - stats_.Add(AllocatorStatAllocated, c->class_size); void *res = c->batch[--c->count]; PREFETCH(c->batch[c->count - 1]); + stats_.Add(AllocatorStatAllocated, c->class_size); return res; } @@ -176,20 +175,19 @@ struct SizeClassAllocator32LocalCache { CHECK_LT(class_id, kNumClasses); // If the first allocator call on a new thread is a deallocation, then // max_count will be zero, leading to check failure. - InitCache(); PerClass *c = &per_class_[class_id]; - stats_.Sub(AllocatorStatAllocated, c->class_size); - CHECK_NE(c->max_count, 0UL); + InitCache(c); if (UNLIKELY(c->count == c->max_count)) - Drain(allocator, class_id); + Drain(c, allocator, class_id); c->batch[c->count++] = p; + stats_.Sub(AllocatorStatAllocated, c->class_size); } void Drain(SizeClassAllocator *allocator) { - for (uptr i = 0; i < kNumClasses; i++) { + for (uptr i = 1; i < kNumClasses; i++) { PerClass *c = &per_class_[i]; while (c->count > 0) - Drain(allocator, i); + Drain(c, allocator, i); } } @@ -214,15 +212,16 @@ struct SizeClassAllocator32LocalCache { PerClass per_class_[kNumClasses]; AllocatorStats stats_; - void InitCache() { - if (LIKELY(per_class_[1].max_count)) + void InitCache(PerClass *c) { + if (LIKELY(c->max_count)) return; const uptr batch_class_id = SizeClassMap::ClassID(sizeof(TransferBatch)); - for (uptr i = 0; i < kNumClasses; i++) { + for (uptr i = 1; i < kNumClasses; i++) { PerClass *c = &per_class_[i]; - uptr max_cached = TransferBatch::MaxCached(i); + const uptr size = Allocator::ClassIdToSize(i); + const uptr max_cached = TransferBatch::MaxCached(size); c->max_count = 2 * max_cached; - c->class_size = Allocator::ClassIdToSize(i); + c->class_size = size; // Precompute the class id to use to store batches for the current class // id. 0 means the class size is large enough to store a batch within one // of the chunks. If using a separate size class, it will always be @@ -230,16 +229,17 @@ struct SizeClassAllocator32LocalCache { if (kUseSeparateSizeClassForBatch) { c->batch_class_id = (i == kBatchClassID) ? 0 : kBatchClassID; } else { - c->batch_class_id = (c->class_size < + c->batch_class_id = (size < TransferBatch::AllocationSizeRequiredForNElements(max_cached)) ? batch_class_id : 0; } } + DCHECK_NE(c->max_count, 0UL); } - NOINLINE bool Refill(SizeClassAllocator *allocator, uptr class_id) { - InitCache(); - PerClass *c = &per_class_[class_id]; + NOINLINE bool Refill(PerClass *c, SizeClassAllocator *allocator, + uptr class_id) { + InitCache(c); TransferBatch *b = allocator->AllocateBatch(&stats_, this, class_id); if (UNLIKELY(!b)) return false; @@ -250,20 +250,21 @@ struct SizeClassAllocator32LocalCache { return true; } - NOINLINE void Drain(SizeClassAllocator *allocator, uptr class_id) { - InitCache(); - PerClass *c = &per_class_[class_id]; - uptr cnt = Min(c->max_count / 2, c->count); - uptr first_idx_to_drain = c->count - cnt; + NOINLINE void Drain(PerClass *c, SizeClassAllocator *allocator, + uptr class_id) { + const uptr count = Min(c->max_count / 2, c->count); + const uptr first_idx_to_drain = c->count - count; TransferBatch *b = CreateBatch( class_id, allocator, (TransferBatch *)c->batch[first_idx_to_drain]); // Failure to allocate a batch while releasing memory is non recoverable. // TODO(alekseys): Figure out how to do it without allocating a new batch. - if (UNLIKELY(!b)) - DieOnFailure::OnOOM(); - b->SetFromArray(allocator->GetRegionBeginBySizeClass(class_id), - &c->batch[first_idx_to_drain], cnt); - c->count -= cnt; + if (UNLIKELY(!b)) { + Report("FATAL: Internal error: %s's allocator failed to allocate a " + "transfer batch.\n", SanitizerToolName); + Die(); + } + b->SetFromArray(&c->batch[first_idx_to_drain], count); + c->count -= count; allocator->DeallocateBatch(&stats_, class_id, b); } }; diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_primary32.h b/libsanitizer/sanitizer_common/sanitizer_allocator_primary32.h index 90a57dbb6cf..bdea498fb5e 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_primary32.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_primary32.h @@ -61,9 +61,9 @@ class SizeClassAllocator32 { struct TransferBatch { static const uptr kMaxNumCached = SizeClassMap::kMaxNumCachedHint - 2; - void SetFromArray(uptr region_beg_unused, void *batch[], uptr count) { + void SetFromArray(void *batch[], uptr count) { + DCHECK_LE(count, kMaxNumCached); count_ = count; - CHECK_LE(count_, kMaxNumCached); for (uptr i = 0; i < count; i++) batch_[i] = batch[i]; } @@ -71,9 +71,9 @@ class SizeClassAllocator32 { void Clear() { count_ = 0; } void Add(void *ptr) { batch_[count_++] = ptr; - CHECK_LE(count_, kMaxNumCached); + DCHECK_LE(count_, kMaxNumCached); } - void CopyToArray(void *to_batch[]) { + void CopyToArray(void *to_batch[]) const { for (uptr i = 0, n = Count(); i < n; i++) to_batch[i] = batch_[i]; } @@ -82,8 +82,8 @@ class SizeClassAllocator32 { static uptr AllocationSizeRequiredForNElements(uptr n) { return sizeof(uptr) * 2 + sizeof(void *) * n; } - static uptr MaxCached(uptr class_id) { - return Min(kMaxNumCached, SizeClassMap::MaxCachedHint(class_id)); + static uptr MaxCached(uptr size) { + return Min(kMaxNumCached, SizeClassMap::MaxCachedHint(size)); } TransferBatch *next; @@ -106,7 +106,7 @@ class SizeClassAllocator32 { typedef SizeClassAllocator32LocalCache AllocatorCache; void Init(s32 release_to_os_interval_ms) { - possible_regions.TestOnlyInit(); + possible_regions.Init(); internal_memset(size_class_info_array, 0, sizeof(size_class_info_array)); } @@ -118,8 +118,12 @@ class SizeClassAllocator32 { // This is empty here. Currently only implemented in 64-bit allocator. } + void ForceReleaseToOS() { + // Currently implemented in 64-bit allocator only. + } + void *MapWithCallback(uptr size) { - void *res = MmapOrDie(size, "SizeClassAllocator32"); + void *res = MmapOrDie(size, PrimaryAllocatorName); MapUnmapCallback().OnMap((uptr)res, size); return res; } @@ -147,13 +151,14 @@ class SizeClassAllocator32 { NOINLINE TransferBatch *AllocateBatch(AllocatorStats *stat, AllocatorCache *c, uptr class_id) { - CHECK_LT(class_id, kNumClasses); + DCHECK_LT(class_id, kNumClasses); SizeClassInfo *sci = GetSizeClassInfo(class_id); SpinMutexLock l(&sci->mutex); - if (sci->free_list.empty() && - UNLIKELY(!PopulateFreeList(stat, c, sci, class_id))) - return nullptr; - CHECK(!sci->free_list.empty()); + if (sci->free_list.empty()) { + if (UNLIKELY(!PopulateFreeList(stat, c, sci, class_id))) + return nullptr; + DCHECK(!sci->free_list.empty()); + } TransferBatch *b = sci->free_list.front(); sci->free_list.pop_front(); return b; @@ -161,15 +166,13 @@ class SizeClassAllocator32 { NOINLINE void DeallocateBatch(AllocatorStats *stat, uptr class_id, TransferBatch *b) { - CHECK_LT(class_id, kNumClasses); + DCHECK_LT(class_id, kNumClasses); CHECK_GT(b->Count(), 0); SizeClassInfo *sci = GetSizeClassInfo(class_id); SpinMutexLock l(&sci->mutex); sci->free_list.push_front(b); } - uptr GetRegionBeginBySizeClass(uptr class_id) { return 0; } - bool PointerIsMine(const void *p) { uptr mem = reinterpret_cast(p); if (mem < kSpaceBeg || mem >= kSpaceBeg + kSpaceSize) @@ -245,12 +248,9 @@ class SizeClassAllocator32 { } } - void PrintStats() { - } + void PrintStats() {} - static uptr AdditionalSize() { - return 0; - } + static uptr AdditionalSize() { return 0; } typedef SizeClassMap SizeClassMapT; static const uptr kNumClasses = SizeClassMap::kNumClasses; @@ -259,16 +259,15 @@ class SizeClassAllocator32 { static const uptr kRegionSize = 1 << kRegionSizeLog; static const uptr kNumPossibleRegions = kSpaceSize / kRegionSize; - struct SizeClassInfo { - SpinMutex mutex; + struct ALIGNED(SANITIZER_CACHE_LINE_SIZE) SizeClassInfo { + StaticSpinMutex mutex; IntrusiveList free_list; - char padding[kCacheLineSize - sizeof(uptr) - - sizeof(IntrusiveList)]; + u32 rand_state; }; - COMPILER_CHECK(sizeof(SizeClassInfo) == kCacheLineSize); + COMPILER_CHECK(sizeof(SizeClassInfo) % kCacheLineSize == 0); uptr ComputeRegionId(uptr mem) { - uptr res = mem >> kRegionSizeLog; + const uptr res = mem >> kRegionSizeLog; CHECK_LT(res, kNumPossibleRegions); return res; } @@ -278,9 +277,9 @@ class SizeClassAllocator32 { } uptr AllocateRegion(AllocatorStats *stat, uptr class_id) { - CHECK_LT(class_id, kNumClasses); - uptr res = reinterpret_cast(MmapAlignedOrDieOnFatalError( - kRegionSize, kRegionSize, "SizeClassAllocator32")); + DCHECK_LT(class_id, kNumClasses); + const uptr res = reinterpret_cast(MmapAlignedOrDieOnFatalError( + kRegionSize, kRegionSize, PrimaryAllocatorName)); if (UNLIKELY(!res)) return 0; MapUnmapCallback().OnMap(res, kRegionSize); @@ -291,33 +290,66 @@ class SizeClassAllocator32 { } SizeClassInfo *GetSizeClassInfo(uptr class_id) { - CHECK_LT(class_id, kNumClasses); + DCHECK_LT(class_id, kNumClasses); return &size_class_info_array[class_id]; } - bool PopulateFreeList(AllocatorStats *stat, AllocatorCache *c, - SizeClassInfo *sci, uptr class_id) { - uptr size = ClassIdToSize(class_id); - uptr reg = AllocateRegion(stat, class_id); - if (UNLIKELY(!reg)) - return false; - uptr n_chunks = kRegionSize / (size + kMetadataSize); - uptr max_count = TransferBatch::MaxCached(class_id); - CHECK_GT(max_count, 0); - TransferBatch *b = nullptr; - for (uptr i = reg; i < reg + n_chunks * size; i += size) { + bool PopulateBatches(AllocatorCache *c, SizeClassInfo *sci, uptr class_id, + TransferBatch **current_batch, uptr max_count, + uptr *pointers_array, uptr count) { + // If using a separate class for batches, we do not need to shuffle it. + if (kRandomShuffleChunks && (!kUseSeparateSizeClassForBatch || + class_id != SizeClassMap::kBatchClassID)) + RandomShuffle(pointers_array, count, &sci->rand_state); + TransferBatch *b = *current_batch; + for (uptr i = 0; i < count; i++) { if (!b) { - b = c->CreateBatch(class_id, this, (TransferBatch*)i); + b = c->CreateBatch(class_id, this, (TransferBatch*)pointers_array[i]); if (UNLIKELY(!b)) return false; b->Clear(); } - b->Add((void*)i); + b->Add((void*)pointers_array[i]); if (b->Count() == max_count) { sci->free_list.push_back(b); b = nullptr; } } + *current_batch = b; + return true; + } + + bool PopulateFreeList(AllocatorStats *stat, AllocatorCache *c, + SizeClassInfo *sci, uptr class_id) { + const uptr region = AllocateRegion(stat, class_id); + if (UNLIKELY(!region)) + return false; + if (kRandomShuffleChunks) + if (UNLIKELY(sci->rand_state == 0)) + // The random state is initialized from ASLR (PIE) and time. + sci->rand_state = reinterpret_cast(sci) ^ NanoTime(); + const uptr size = ClassIdToSize(class_id); + const uptr n_chunks = kRegionSize / (size + kMetadataSize); + const uptr max_count = TransferBatch::MaxCached(size); + DCHECK_GT(max_count, 0); + TransferBatch *b = nullptr; + constexpr uptr kShuffleArraySize = 48; + uptr shuffle_array[kShuffleArraySize]; + uptr count = 0; + for (uptr i = region; i < region + n_chunks * size; i += size) { + shuffle_array[count++] = i; + if (count == kShuffleArraySize) { + if (UNLIKELY(!PopulateBatches(c, sci, class_id, &b, max_count, + shuffle_array, count))) + return false; + count = 0; + } + } + if (count) { + if (UNLIKELY(!PopulateBatches(c, sci, class_id, &b, max_count, + shuffle_array, count))) + return false; + } if (b) { CHECK_GT(b->Count(), 0); sci->free_list.push_back(b); diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h b/libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h index 4ae59c8b6b1..119443b3ebe 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_primary64.h @@ -70,15 +70,17 @@ class SizeClassAllocator64 { void Init(s32 release_to_os_interval_ms) { uptr TotalSpaceSize = kSpaceSize + AdditionalSize(); if (kUsingConstantSpaceBeg) { - CHECK_EQ(kSpaceBeg, reinterpret_cast( - MmapFixedNoAccess(kSpaceBeg, TotalSpaceSize))); + CHECK_EQ(kSpaceBeg, address_range.Init(TotalSpaceSize, + PrimaryAllocatorName, kSpaceBeg)); } else { - NonConstSpaceBeg = - reinterpret_cast(MmapNoAccess(TotalSpaceSize)); + NonConstSpaceBeg = address_range.Init(TotalSpaceSize, + PrimaryAllocatorName); CHECK_NE(NonConstSpaceBeg, ~(uptr)0); } SetReleaseToOSIntervalMs(release_to_os_interval_ms); MapWithCallbackOrDie(SpaceEnd(), AdditionalSize()); + // Check that the RegionInfo array is aligned on the CacheLine size. + DCHECK_EQ(SpaceEnd() % kCacheLineSize, 0); } s32 ReleaseToOSIntervalMs() const { @@ -90,6 +92,13 @@ class SizeClassAllocator64 { memory_order_relaxed); } + void ForceReleaseToOS() { + for (uptr class_id = 1; class_id < kNumClasses; class_id++) { + BlockingMutexLock l(&GetRegionInfo(class_id)->mutex); + MaybeReleaseToOS(class_id, true /*force*/); + } + } + static bool CanAllocate(uptr size, uptr alignment) { return size <= SizeClassMap::kMaxSize && alignment <= SizeClassMap::kMaxSize; @@ -107,14 +116,18 @@ class SizeClassAllocator64 { // Failure to allocate free array space while releasing memory is non // recoverable. if (UNLIKELY(!EnsureFreeArraySpace(region, region_beg, - new_num_freed_chunks))) - DieOnFailure::OnOOM(); + new_num_freed_chunks))) { + Report("FATAL: Internal error: %s's allocator exhausted the free list " + "space for size class %zd (%zd bytes).\n", SanitizerToolName, + class_id, ClassIdToSize(class_id)); + Die(); + } for (uptr i = 0; i < n_chunks; i++) free_array[old_num_chunks + i] = chunks[i]; region->num_freed_chunks = new_num_freed_chunks; region->stats.n_freed += n_chunks; - MaybeReleaseToOS(class_id); + MaybeReleaseToOS(class_id, false /*force*/); } NOINLINE bool GetFromAllocator(AllocatorStats *stat, uptr class_id, @@ -232,22 +245,28 @@ class SizeClassAllocator64 { } void PrintStats() { + uptr rss_stats[kNumClasses]; + for (uptr class_id = 0; class_id < kNumClasses; class_id++) + rss_stats[class_id] = SpaceBeg() + kRegionSize * class_id; + GetMemoryProfile(FillMemoryProfile, rss_stats, kNumClasses); + uptr total_mapped = 0; + uptr total_rss = 0; uptr n_allocated = 0; uptr n_freed = 0; for (uptr class_id = 1; class_id < kNumClasses; class_id++) { RegionInfo *region = GetRegionInfo(class_id); - total_mapped += region->mapped_user; + if (region->mapped_user != 0) { + total_mapped += region->mapped_user; + total_rss += rss_stats[class_id]; + } n_allocated += region->stats.n_allocated; n_freed += region->stats.n_freed; } - Printf("Stats: SizeClassAllocator64: %zdM mapped in %zd allocations; " - "remains %zd\n", - total_mapped >> 20, n_allocated, n_allocated - n_freed); - uptr rss_stats[kNumClasses]; - for (uptr class_id = 0; class_id < kNumClasses; class_id++) - rss_stats[class_id] = SpaceBeg() + kRegionSize * class_id; - GetMemoryProfile(FillMemoryProfile, rss_stats, kNumClasses); + + Printf("Stats: SizeClassAllocator64: %zdM mapped (%zdM rss) in " + "%zd allocations; remains %zd\n", total_mapped >> 20, + total_rss >> 20, n_allocated, n_allocated - n_freed); for (uptr class_id = 1; class_id < kNumClasses; class_id++) PrintStats(class_id, rss_stats[class_id]); } @@ -529,6 +548,8 @@ class SizeClassAllocator64 { private: friend class MemoryMapper; + ReservedAddressRange address_range; + static const uptr kRegionSize = kSpaceSize / kNumClassesRounded; // FreeArray is the array of free-d chunks (stored as 4-byte offsets). // In the worst case it may reguire kRegionSize/SizeClassMap::kMinSize @@ -567,7 +588,7 @@ class SizeClassAllocator64 { u64 last_released_bytes; }; - struct RegionInfo { + struct ALIGNED(SANITIZER_CACHE_LINE_SIZE) RegionInfo { BlockingMutex mutex; uptr num_freed_chunks; // Number of elements in the freearray. uptr mapped_free_array; // Bytes mapped for freearray. @@ -580,24 +601,11 @@ class SizeClassAllocator64 { Stats stats; ReleaseToOsInfo rtoi; }; - COMPILER_CHECK(sizeof(RegionInfo) >= kCacheLineSize); - - u32 Rand(u32 *state) { // ANSI C linear congruential PRNG. - return (*state = *state * 1103515245 + 12345) >> 16; - } - - u32 RandN(u32 *state, u32 n) { return Rand(state) % n; } // [0, n) - - void RandomShuffle(u32 *a, u32 n, u32 *rand_state) { - if (n <= 1) return; - for (u32 i = n - 1; i > 0; i--) - Swap(a[i], a[RandN(rand_state, i + 1)]); - } + COMPILER_CHECK(sizeof(RegionInfo) % kCacheLineSize == 0); RegionInfo *GetRegionInfo(uptr class_id) const { - CHECK_LT(class_id, kNumClasses); - RegionInfo *regions = - reinterpret_cast(SpaceBeg() + kSpaceSize); + DCHECK_LT(class_id, kNumClasses); + RegionInfo *regions = reinterpret_cast(SpaceEnd()); return ®ions[class_id]; } @@ -622,7 +630,7 @@ class SizeClassAllocator64 { } bool MapWithCallback(uptr beg, uptr size) { - uptr mapped = reinterpret_cast(MmapFixedOrDieOnFatalError(beg, size)); + uptr mapped = address_range.Map(beg, size); if (UNLIKELY(!mapped)) return false; CHECK_EQ(beg, mapped); @@ -631,13 +639,13 @@ class SizeClassAllocator64 { } void MapWithCallbackOrDie(uptr beg, uptr size) { - CHECK_EQ(beg, reinterpret_cast(MmapFixedOrDie(beg, size))); + CHECK_EQ(beg, address_range.MapOrDie(beg, size)); MapUnmapCallback().OnMap(beg, size); } void UnmapWithCallbackOrDie(uptr beg, uptr size) { MapUnmapCallback().OnUnmap(beg, size); - UnmapOrDie(reinterpret_cast(beg), size); + address_range.Unmap(beg, size); } bool EnsureFreeArraySpace(RegionInfo *region, uptr region_beg, @@ -656,55 +664,74 @@ class SizeClassAllocator64 { return true; } + // Check whether this size class is exhausted. + bool IsRegionExhausted(RegionInfo *region, uptr class_id, + uptr additional_map_size) { + if (LIKELY(region->mapped_user + region->mapped_meta + + additional_map_size <= kRegionSize - kFreeArraySize)) + return false; + if (!region->exhausted) { + region->exhausted = true; + Printf("%s: Out of memory. ", SanitizerToolName); + Printf("The process has exhausted %zuMB for size class %zu.\n", + kRegionSize >> 20, ClassIdToSize(class_id)); + } + return true; + } + NOINLINE bool PopulateFreeArray(AllocatorStats *stat, uptr class_id, RegionInfo *region, uptr requested_count) { // region->mutex is held. - const uptr size = ClassIdToSize(class_id); - const uptr new_space_beg = region->allocated_user; - const uptr new_space_end = new_space_beg + requested_count * size; const uptr region_beg = GetRegionBeginBySizeClass(class_id); + const uptr size = ClassIdToSize(class_id); + const uptr total_user_bytes = + region->allocated_user + requested_count * size; // Map more space for chunks, if necessary. - if (new_space_end > region->mapped_user) { - if (!kUsingConstantSpaceBeg && region->mapped_user == 0) - region->rand_state = static_cast(region_beg >> 12); // From ASLR. + if (LIKELY(total_user_bytes > region->mapped_user)) { + if (UNLIKELY(region->mapped_user == 0)) { + if (!kUsingConstantSpaceBeg && kRandomShuffleChunks) + // The random state is initialized from ASLR. + region->rand_state = static_cast(region_beg >> 12); + // Postpone the first release to OS attempt for ReleaseToOSIntervalMs, + // preventing just allocated memory from being released sooner than + // necessary and also preventing extraneous ReleaseMemoryPagesToOS calls + // for short lived processes. + // Do it only when the feature is turned on, to avoid a potentially + // extraneous syscall. + if (ReleaseToOSIntervalMs() >= 0) + region->rtoi.last_release_at_ns = MonotonicNanoTime(); + } // Do the mmap for the user memory. - uptr map_size = kUserMapSize; - while (new_space_end > region->mapped_user + map_size) - map_size += kUserMapSize; - CHECK_GE(region->mapped_user + map_size, new_space_end); + const uptr user_map_size = + RoundUpTo(total_user_bytes - region->mapped_user, kUserMapSize); + if (UNLIKELY(IsRegionExhausted(region, class_id, user_map_size))) + return false; if (UNLIKELY(!MapWithCallback(region_beg + region->mapped_user, - map_size))) + user_map_size))) return false; - stat->Add(AllocatorStatMapped, map_size); - region->mapped_user += map_size; - } - const uptr new_chunks_count = (region->mapped_user - new_space_beg) / size; - - // Calculate the required space for metadata. - const uptr requested_allocated_meta = - region->allocated_meta + new_chunks_count * kMetadataSize; - uptr requested_mapped_meta = region->mapped_meta; - while (requested_allocated_meta > requested_mapped_meta) - requested_mapped_meta += kMetaMapSize; - // Check whether this size class is exhausted. - if (region->mapped_user + requested_mapped_meta > - kRegionSize - kFreeArraySize) { - if (!region->exhausted) { - region->exhausted = true; - Printf("%s: Out of memory. ", SanitizerToolName); - Printf("The process has exhausted %zuMB for size class %zu.\n", - kRegionSize >> 20, size); - } - return false; + stat->Add(AllocatorStatMapped, user_map_size); + region->mapped_user += user_map_size; } - // Map more space for metadata, if necessary. - if (requested_mapped_meta > region->mapped_meta) { - if (UNLIKELY(!MapWithCallback( - GetMetadataEnd(region_beg) - requested_mapped_meta, - requested_mapped_meta - region->mapped_meta))) - return false; - region->mapped_meta = requested_mapped_meta; + const uptr new_chunks_count = + (region->mapped_user - region->allocated_user) / size; + + if (kMetadataSize) { + // Calculate the required space for metadata. + const uptr total_meta_bytes = + region->allocated_meta + new_chunks_count * kMetadataSize; + const uptr meta_map_size = (total_meta_bytes > region->mapped_meta) ? + RoundUpTo(total_meta_bytes - region->mapped_meta, kMetaMapSize) : 0; + // Map more space for metadata, if necessary. + if (meta_map_size) { + if (UNLIKELY(IsRegionExhausted(region, class_id, meta_map_size))) + return false; + if (UNLIKELY(!MapWithCallback( + GetMetadataEnd(region_beg) - region->mapped_meta - meta_map_size, + meta_map_size))) + return false; + region->mapped_meta += meta_map_size; + } } // If necessary, allocate more space for the free array and populate it with @@ -713,7 +740,7 @@ class SizeClassAllocator64 { if (UNLIKELY(!EnsureFreeArraySpace(region, region_beg, total_freed_chunks))) return false; CompactPtrT *free_array = GetFreeArray(region_beg); - for (uptr i = 0, chunk = new_space_beg; i < new_chunks_count; + for (uptr i = 0, chunk = region->allocated_user; i < new_chunks_count; i++, chunk += size) free_array[total_freed_chunks - 1 - i] = PointerToCompactPtr(0, chunk); if (kRandomShuffleChunks) @@ -725,7 +752,7 @@ class SizeClassAllocator64 { region->num_freed_chunks += new_chunks_count; region->allocated_user += new_chunks_count * size; CHECK_LE(region->allocated_user, region->mapped_user); - region->allocated_meta = requested_allocated_meta; + region->allocated_meta += new_chunks_count * kMetadataSize; CHECK_LE(region->allocated_meta, region->mapped_meta); region->exhausted = false; @@ -784,7 +811,7 @@ class SizeClassAllocator64 { // Attempts to release RAM occupied by freed chunks back to OS. The region is // expected to be locked. - void MaybeReleaseToOS(uptr class_id) { + void MaybeReleaseToOS(uptr class_id, bool force) { RegionInfo *region = GetRegionInfo(class_id); const uptr chunk_size = ClassIdToSize(class_id); const uptr page_size = GetPageSizeCached(); @@ -797,12 +824,16 @@ class SizeClassAllocator64 { return; // Nothing new to release. } - s32 interval_ms = ReleaseToOSIntervalMs(); - if (interval_ms < 0) - return; + if (!force) { + s32 interval_ms = ReleaseToOSIntervalMs(); + if (interval_ms < 0) + return; - if (region->rtoi.last_release_at_ns + interval_ms * 1000000ULL > NanoTime()) - return; // Memory was returned recently. + if (region->rtoi.last_release_at_ns + interval_ms * 1000000ULL > + MonotonicNanoTime()) { + return; // Memory was returned recently. + } + } MemoryMapper memory_mapper(*this, class_id); @@ -816,6 +847,6 @@ class SizeClassAllocator64 { region->rtoi.num_releases += memory_mapper.GetReleasedRangesCount(); region->rtoi.last_released_bytes = memory_mapper.GetReleasedBytes(); } - region->rtoi.last_release_at_ns = NanoTime(); + region->rtoi.last_release_at_ns = MonotonicNanoTime(); } }; diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_report.cc b/libsanitizer/sanitizer_common/sanitizer_allocator_report.cc new file mode 100644 index 00000000000..a09fb91e6b1 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_report.cc @@ -0,0 +1,123 @@ +//===-- sanitizer_allocator_report.cc ---------------------------*- C++ -*-===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Shared allocator error reporting for ThreadSanitizer, MemorySanitizer, etc. +/// +//===----------------------------------------------------------------------===// + +#include "sanitizer_allocator.h" +#include "sanitizer_allocator_report.h" +#include "sanitizer_common.h" +#include "sanitizer_report_decorator.h" + +namespace __sanitizer { + +class ScopedAllocatorErrorReport { + public: + ScopedAllocatorErrorReport(const char *error_summary_, + const StackTrace *stack_) + : error_summary(error_summary_), + stack(stack_) { + Printf("%s", d.Error()); + } + ~ScopedAllocatorErrorReport() { + Printf("%s", d.Default()); + stack->Print(); + PrintHintAllocatorCannotReturnNull(); + ReportErrorSummary(error_summary, stack); + } + + private: + ScopedErrorReportLock lock; + const char *error_summary; + const StackTrace* const stack; + const SanitizerCommonDecorator d; +}; + +void NORETURN ReportCallocOverflow(uptr count, uptr size, + const StackTrace *stack) { + { + ScopedAllocatorErrorReport report("calloc-overflow", stack); + Report("ERROR: %s: calloc 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); + Report("ERROR: %s: pvalloc parameters overflow: size 0x%zx rounded up to " + "system page size 0x%zx cannot be represented in type size_t\n", + SanitizerToolName, size, GetPageSizeCached()); + } + Die(); +} + +void NORETURN ReportInvalidAllocationAlignment(uptr alignment, + const StackTrace *stack) { + { + ScopedAllocatorErrorReport report("invalid-allocation-alignment", stack); + Report("ERROR: %s: invalid allocation alignment: %zd, alignment must be a " + "power of two\n", SanitizerToolName, alignment); + } + Die(); +} + +void NORETURN ReportInvalidAlignedAllocAlignment(uptr size, uptr alignment, + const StackTrace *stack) { + { + ScopedAllocatorErrorReport report("invalid-aligned-alloc-alignment", stack); +#if SANITIZER_POSIX + Report("ERROR: %s: invalid alignment requested in " + "aligned_alloc: %zd, alignment must be a power of two and the " + "requested size 0x%zx must be a multiple of alignment\n", + SanitizerToolName, alignment, size); +#else + Report("ERROR: %s: invalid alignment requested in aligned_alloc: %zd, " + "the requested size 0x%zx must be a multiple of alignment\n", + SanitizerToolName, alignment, size); +#endif + } + Die(); +} + +void NORETURN ReportInvalidPosixMemalignAlignment(uptr alignment, + const StackTrace *stack) { + { + ScopedAllocatorErrorReport report("invalid-posix-memalign-alignment", + stack); + Report("ERROR: %s: invalid alignment requested in " + "posix_memalign: %zd, alignment must be a power of two and a " + "multiple of sizeof(void*) == %zd\n", SanitizerToolName, alignment, + sizeof(void*)); // NOLINT + } + Die(); +} + +void NORETURN ReportAllocationSizeTooBig(uptr user_size, uptr max_size, + const StackTrace *stack) { + { + ScopedAllocatorErrorReport report("allocation-size-too-big", stack); + Report("ERROR: %s: requested allocation size 0x%zx exceeds maximum " + "supported size of 0x%zx\n", SanitizerToolName, user_size, max_size); + } + Die(); +} + +void NORETURN ReportOutOfMemory(uptr requested_size, const StackTrace *stack) { + { + ScopedAllocatorErrorReport report("out-of-memory", stack); + Report("ERROR: %s: allocator is out of memory trying to allocate 0x%zx " + "bytes\n", SanitizerToolName, requested_size); + } + Die(); +} + +} // namespace __sanitizer diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_report.h b/libsanitizer/sanitizer_common/sanitizer_allocator_report.h new file mode 100644 index 00000000000..892f7ffb7f8 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_report.h @@ -0,0 +1,36 @@ +//===-- sanitizer_allocator_report.h ----------------------------*- C++ -*-===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// \file +/// Shared allocator error reporting for ThreadSanitizer, MemorySanitizer, etc. +/// +//===----------------------------------------------------------------------===// + +#ifndef SANITIZER_ALLOCATOR_REPORT_H +#define SANITIZER_ALLOCATOR_REPORT_H + +#include "sanitizer_internal_defs.h" +#include "sanitizer_stacktrace.h" + +namespace __sanitizer { + +void NORETURN ReportCallocOverflow(uptr count, uptr size, + const StackTrace *stack); +void NORETURN ReportPvallocOverflow(uptr size, const StackTrace *stack); +void NORETURN ReportInvalidAllocationAlignment(uptr alignment, + const StackTrace *stack); +void NORETURN ReportInvalidAlignedAllocAlignment(uptr size, uptr alignment, + const StackTrace *stack); +void NORETURN ReportInvalidPosixMemalignAlignment(uptr alignment, + const StackTrace *stack); +void NORETURN ReportAllocationSizeTooBig(uptr user_size, uptr max_size, + const StackTrace *stack); +void NORETURN ReportOutOfMemory(uptr requested_size, const StackTrace *stack); + +} // namespace __sanitizer + +#endif // SANITIZER_ALLOCATOR_REPORT_H diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_secondary.h b/libsanitizer/sanitizer_common/sanitizer_allocator_secondary.h index 9a9b83a884f..1dbca60b823 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_secondary.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_secondary.h @@ -12,17 +12,66 @@ #error This file must be included inside sanitizer_allocator.h #endif +// Fixed array to store LargeMmapAllocator chunks list, limited to 32K total +// allocated chunks. To be used in memory constrained or not memory hungry cases +// (currently, 32 bits and internal allocator). +class LargeMmapAllocatorPtrArrayStatic { + public: + INLINE void *Init() { return &p_[0]; } + INLINE void EnsureSpace(uptr n) { CHECK_LT(n, kMaxNumChunks); } + private: + static const int kMaxNumChunks = 1 << 15; + uptr p_[kMaxNumChunks]; +}; + +// Much less restricted LargeMmapAllocator chunks list (comparing to +// PtrArrayStatic). Backed by mmaped memory region and can hold up to 1M chunks. +// ReservedAddressRange was used instead of just MAP_NORESERVE to achieve the +// same functionality in Fuchsia case, which does not support MAP_NORESERVE. +class LargeMmapAllocatorPtrArrayDynamic { + public: + INLINE void *Init() { + uptr p = address_range_.Init(kMaxNumChunks * sizeof(uptr), + SecondaryAllocatorName); + CHECK(p); + return reinterpret_cast(p); + } + + INLINE void EnsureSpace(uptr n) { + CHECK_LT(n, kMaxNumChunks); + DCHECK(n <= n_reserved_); + if (UNLIKELY(n == n_reserved_)) { + address_range_.MapOrDie( + reinterpret_cast(address_range_.base()) + + n_reserved_ * sizeof(uptr), + kChunksBlockCount * sizeof(uptr)); + n_reserved_ += kChunksBlockCount; + } + } + + private: + static const int kMaxNumChunks = 1 << 20; + static const int kChunksBlockCount = 1 << 14; + ReservedAddressRange address_range_; + uptr n_reserved_; +}; + +#if SANITIZER_WORDSIZE == 32 +typedef LargeMmapAllocatorPtrArrayStatic DefaultLargeMmapAllocatorPtrArray; +#else +typedef LargeMmapAllocatorPtrArrayDynamic DefaultLargeMmapAllocatorPtrArray; +#endif + // This class can (de)allocate only large chunks of memory using mmap/unmap. // 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 LargeMmapAllocator { public: - typedef FailureHandlerT FailureHandler; - void InitLinkerInitialized() { page_size_ = GetPageSizeCached(); + chunks_ = reinterpret_cast(ptr_array_.Init()); } void Init() { @@ -36,12 +85,16 @@ class LargeMmapAllocator { if (alignment > page_size_) map_size += alignment; // Overflow. - if (map_size < size) - return FailureHandler::OnBadRequest(); + if (map_size < size) { + Report("WARNING: %s: LargeMmapAllocator allocation overflow: " + "0x%zx bytes with 0x%zx alignment requested\n", + SanitizerToolName, map_size, alignment); + return nullptr; + } uptr map_beg = reinterpret_cast( - MmapOrDieOnFatalError(map_size, "LargeMmapAllocator")); + MmapOrDieOnFatalError(map_size, SecondaryAllocatorName)); if (!map_beg) - return FailureHandler::OnOOM(); + return nullptr; CHECK(IsAligned(map_beg, page_size_)); MapUnmapCallback().OnMap(map_beg, map_size); uptr map_end = map_beg + map_size; @@ -60,11 +113,11 @@ class LargeMmapAllocator { CHECK_LT(size_log, ARRAY_SIZE(stats.by_size_log)); { SpinMutexLock l(&mutex_); + ptr_array_.EnsureSpace(n_chunks_); uptr idx = n_chunks_++; - chunks_sorted_ = false; - CHECK_LT(idx, kMaxNumChunks); h->chunk_idx = idx; chunks_[idx] = h; + chunks_sorted_ = false; stats.n_allocs++; stats.currently_allocated += map_size; stats.max_allocated = Max(stats.max_allocated, stats.currently_allocated); @@ -82,9 +135,8 @@ class LargeMmapAllocator { uptr idx = h->chunk_idx; CHECK_EQ(chunks_[idx], h); CHECK_LT(idx, n_chunks_); - chunks_[idx] = chunks_[n_chunks_ - 1]; + chunks_[idx] = chunks_[--n_chunks_]; chunks_[idx]->chunk_idx = idx; - n_chunks_--; chunks_sorted_ = false; stats.n_frees++; stats.currently_allocated -= h->map_size; @@ -148,7 +200,7 @@ class LargeMmapAllocator { void EnsureSortedChunks() { if (chunks_sorted_) return; - SortArray(reinterpret_cast(chunks_), n_chunks_); + Sort(reinterpret_cast(chunks_), n_chunks_); for (uptr i = 0; i < n_chunks_; i++) chunks_[i]->chunk_idx = i; chunks_sorted_ = true; @@ -220,7 +272,7 @@ class LargeMmapAllocator { EnsureSortedChunks(); // Avoid doing the sort while iterating. for (uptr i = 0; i < n_chunks_; i++) { auto t = chunks_[i]; - callback(reinterpret_cast(GetUser(chunks_[i])), arg); + 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); @@ -228,7 +280,6 @@ class LargeMmapAllocator { } private: - static const int kMaxNumChunks = 1 << FIRST_32_SECOND_64(15, 18); struct Header { uptr map_beg; uptr map_size; @@ -254,11 +305,12 @@ class LargeMmapAllocator { } uptr page_size_; - Header *chunks_[kMaxNumChunks]; + Header **chunks_; + PtrArrayT ptr_array_; uptr n_chunks_; bool chunks_sorted_; struct Stats { uptr n_allocs, n_frees, currently_allocated, max_allocated, by_size_log[64]; } stats; - SpinMutex mutex_; + StaticSpinMutex mutex_; }; diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_size_class_map.h b/libsanitizer/sanitizer_common/sanitizer_allocator_size_class_map.h index 19af55138d1..cfe6299fdec 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_size_class_map.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_size_class_map.h @@ -159,23 +159,24 @@ class SizeClassMap { return 0; if (size <= kMidSize) return (size + kMinSize - 1) >> kMinSizeLog; - uptr l = MostSignificantSetBitIndex(size); - uptr hbits = (size >> (l - S)) & M; - uptr lbits = size & ((1 << (l - S)) - 1); - uptr l1 = l - kMidSizeLog; + const uptr l = MostSignificantSetBitIndex(size); + const uptr hbits = (size >> (l - S)) & M; + const uptr lbits = size & ((1U << (l - S)) - 1); + const uptr l1 = l - kMidSizeLog; return kMidClass + (l1 << S) + hbits + (lbits > 0); } - static uptr MaxCachedHint(uptr class_id) { - // Estimate the result for kBatchClassID because this class does not know - // the exact size of TransferBatch. We need to cache fewer batches than user - // chunks, so this number can be small. - if (UNLIKELY(class_id == kBatchClassID)) - return 16; - if (UNLIKELY(class_id == 0)) + static uptr MaxCachedHint(uptr size) { + DCHECK_LE(size, kMaxSize); + if (UNLIKELY(size == 0)) return 0; - uptr n = (1UL << kMaxBytesCachedLog) / Size(class_id); - return Max(1, Min(kMaxNumCachedHint, n)); + uptr n; + // Force a 32-bit division if the template parameters allow for it. + if (kMaxBytesCachedLog > 31 || kMaxSizeLog > 31) + n = (1UL << kMaxBytesCachedLog) / size; + else + n = (1U << kMaxBytesCachedLog) / static_cast(size); + return Max(1U, Min(kMaxNumCachedHint, n)); } static void Print() { @@ -188,12 +189,12 @@ class SizeClassMap { uptr d = s - prev_s; uptr p = prev_s ? (d * 100 / prev_s) : 0; uptr l = s ? MostSignificantSetBitIndex(s) : 0; - uptr cached = MaxCachedHint(i) * s; + uptr cached = MaxCachedHint(s) * s; if (i == kBatchClassID) d = p = l = 0; Printf("c%02zd => s: %zd diff: +%zd %02zd%% l %zd " "cached: %zd %zd; id %zd\n", - i, Size(i), d, p, l, MaxCachedHint(i), cached, ClassID(s)); + i, Size(i), d, p, l, MaxCachedHint(s), cached, ClassID(s)); total_cached += cached; prev_s = s; } @@ -229,3 +230,8 @@ class SizeClassMap { typedef SizeClassMap<3, 4, 8, 17, 128, 16> DefaultSizeClassMap; typedef SizeClassMap<3, 4, 8, 17, 64, 14> CompactSizeClassMap; typedef SizeClassMap<2, 5, 9, 16, 64, 14> VeryCompactSizeClassMap; + +// The following SizeClassMap only holds a way small number of cached entries, +// 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; diff --git a/libsanitizer/sanitizer_common/sanitizer_allocator_stats.h b/libsanitizer/sanitizer_common/sanitizer_allocator_stats.h index e336b5d365a..93360919fee 100644 --- a/libsanitizer/sanitizer_common/sanitizer_allocator_stats.h +++ b/libsanitizer/sanitizer_common/sanitizer_allocator_stats.h @@ -99,5 +99,5 @@ class AllocatorGlobalStats : public AllocatorStats { } private: - mutable SpinMutex mu_; + mutable StaticSpinMutex mu_; }; diff --git a/libsanitizer/sanitizer_common/sanitizer_asm.h b/libsanitizer/sanitizer_common/sanitizer_asm.h index 737ccbb716d..4c75b413268 100644 --- a/libsanitizer/sanitizer_common/sanitizer_asm.h +++ b/libsanitizer/sanitizer_common/sanitizer_asm.h @@ -45,12 +45,12 @@ # define ASM_HIDDEN(symbol) .hidden symbol # define ASM_TYPE_FUNCTION(symbol) .type symbol, @function # define ASM_SIZE(symbol) .size symbol, .-symbol -# define ASM_TSAN_SYMBOL(symbol) symbol -# define ASM_TSAN_SYMBOL_INTERCEPTOR(symbol) symbol +# define ASM_SYMBOL(symbol) symbol +# define ASM_SYMBOL_INTERCEPTOR(symbol) symbol #else # define ASM_HIDDEN(symbol) # define ASM_TYPE_FUNCTION(symbol) # define ASM_SIZE(symbol) -# define ASM_TSAN_SYMBOL(symbol) _##symbol -# define ASM_TSAN_SYMBOL_INTERCEPTOR(symbol) _wrap_##symbol +# define ASM_SYMBOL(symbol) _##symbol +# define ASM_SYMBOL_INTERCEPTOR(symbol) _wrap_##symbol #endif diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic_clang.h b/libsanitizer/sanitizer_common/sanitizer_atomic_clang.h index dcdcd0ea4ad..89fb748e758 100644 --- a/libsanitizer/sanitizer_common/sanitizer_atomic_clang.h +++ b/libsanitizer/sanitizer_common/sanitizer_atomic_clang.h @@ -76,17 +76,7 @@ INLINE bool atomic_compare_exchange_strong(volatile T *a, typename T::Type *cmp, typedef typename T::Type Type; Type cmpv = *cmp; Type prev; -#if defined(_MIPS_SIM) && _MIPS_SIM == _ABIO32 - if (sizeof(*a) == 8) { - Type volatile *val_ptr = const_cast(&a->val_dont_use); - prev = __mips_sync_val_compare_and_swap( - reinterpret_cast(val_ptr), (u64)cmpv, (u64)xchg); - } else { - prev = __sync_val_compare_and_swap(&a->val_dont_use, cmpv, xchg); - } -#else prev = __sync_val_compare_and_swap(&a->val_dont_use, cmpv, xchg); -#endif if (prev == cmpv) return true; *cmp = prev; return false; @@ -102,6 +92,13 @@ INLINE bool atomic_compare_exchange_weak(volatile T *a, } // namespace __sanitizer +// This include provides explicit template instantiations for atomic_uint64_t +// on MIPS32, which does not directly support 8 byte atomics. It has to +// proceed the template definitions above. +#if defined(_MIPS_SIM) && defined(_ABIO32) + #include "sanitizer_atomic_clang_mips.h" +#endif + #undef ATOMIC_ORDER #endif // SANITIZER_ATOMIC_CLANG_H diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_mips.h b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_mips.h new file mode 100644 index 00000000000..41e58dcae4d --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_mips.h @@ -0,0 +1,115 @@ +//===-- sanitizer_atomic_clang_mips.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 ThreadSanitizer/AddressSanitizer runtime. +// Not intended for direct inclusion. Include sanitizer_atomic.h. +// +//===----------------------------------------------------------------------===// + +#ifndef SANITIZER_ATOMIC_CLANG_MIPS_H +#define SANITIZER_ATOMIC_CLANG_MIPS_H + +namespace __sanitizer { + +// MIPS32 does not support atomics > 4 bytes. To address this lack of +// functionality, the sanitizer library provides helper methods which use an +// internal spin lock mechanism to emulate atomic oprations when the size is +// 8 bytes. +static void __spin_lock(volatile int *lock) { + while (__sync_lock_test_and_set(lock, 1)) + while (*lock) { + } +} + +static void __spin_unlock(volatile int *lock) { __sync_lock_release(lock); } + +// Make sure the lock is on its own cache line to prevent false sharing. +// Put it inside a struct that is aligned and padded to the typical MIPS +// cacheline which is 32 bytes. +static struct { + int lock; + char pad[32 - sizeof(int)]; +} __attribute__((aligned(32))) lock = {0, {0}}; + +template <> +INLINE atomic_uint64_t::Type atomic_fetch_add(volatile atomic_uint64_t *ptr, + atomic_uint64_t::Type val, + memory_order mo) { + DCHECK(mo & + (memory_order_relaxed | memory_order_releasae | memory_order_seq_cst)); + DCHECK(!((uptr)ptr % sizeof(*ptr))); + + atomic_uint64_t::Type ret; + + __spin_lock(&lock.lock); + ret = *(const_cast(&ptr->val_dont_use)); + ptr->val_dont_use = ret + val; + __spin_unlock(&lock.lock); + + return ret; +} + +template <> +INLINE atomic_uint64_t::Type atomic_fetch_sub(volatile atomic_uint64_t *ptr, + atomic_uint64_t::Type val, + memory_order mo) { + return atomic_fetch_add(ptr, -val, mo); +} + +template <> +INLINE bool atomic_compare_exchange_strong(volatile atomic_uint64_t *ptr, + atomic_uint64_t::Type *cmp, + atomic_uint64_t::Type xchg, + memory_order mo) { + DCHECK(mo & + (memory_order_relaxed | memory_order_releasae | memory_order_seq_cst)); + DCHECK(!((uptr)ptr % sizeof(*ptr))); + + typedef atomic_uint64_t::Type Type; + Type cmpv = *cmp; + Type prev; + bool ret = false; + + __spin_lock(&lock.lock); + prev = *(const_cast(&ptr->val_dont_use)); + if (prev == cmpv) { + ret = true; + ptr->val_dont_use = xchg; + } + __spin_unlock(&lock.lock); + + return ret; +} + +template <> +INLINE atomic_uint64_t::Type atomic_load(const volatile atomic_uint64_t *ptr, + memory_order mo) { + DCHECK(mo & + (memory_order_relaxed | memory_order_releasae | memory_order_seq_cst)); + DCHECK(!((uptr)ptr % sizeof(*ptr))); + + atomic_uint64_t::Type zero = 0; + volatile atomic_uint64_t *Newptr = + const_cast(ptr); + return atomic_fetch_add(Newptr, zero, mo); +} + +template <> +INLINE void atomic_store(volatile atomic_uint64_t *ptr, atomic_uint64_t::Type v, + memory_order mo) { + DCHECK(mo & + (memory_order_relaxed | memory_order_releasae | memory_order_seq_cst)); + DCHECK(!((uptr)ptr % sizeof(*ptr))); + + __spin_lock(&lock.lock); + ptr->val_dont_use = v; + __spin_unlock(&lock.lock); +} + +} // 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 59e9f645f68..b11efccc91b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_other.h +++ b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_other.h @@ -15,55 +15,6 @@ namespace __sanitizer { -// MIPS32 does not support atomic > 4 bytes. To address this lack of -// functionality, the sanitizer library provides helper methods which use an -// internal spin lock mechanism to emulate atomic oprations when the size is -// 8 bytes. -#if defined(_MIPS_SIM) && _MIPS_SIM == _ABIO32 -static void __spin_lock(volatile int *lock) { - while (__sync_lock_test_and_set(lock, 1)) - while (*lock) { - } -} - -static void __spin_unlock(volatile int *lock) { __sync_lock_release(lock); } - - -// Make sure the lock is on its own cache line to prevent false sharing. -// Put it inside a struct that is aligned and padded to the typical MIPS -// cacheline which is 32 bytes. -static struct { - int lock; - char pad[32 - sizeof(int)]; -} __attribute__((aligned(32))) lock = {0, {0}}; - -template -T __mips_sync_fetch_and_add(volatile T *ptr, T val) { - T ret; - - __spin_lock(&lock.lock); - - ret = *ptr; - *ptr = ret + val; - - __spin_unlock(&lock.lock); - - return ret; -} - -template -T __mips_sync_val_compare_and_swap(volatile T *ptr, T oldval, T newval) { - T ret; - __spin_lock(&lock.lock); - - ret = *ptr; - if (ret == oldval) *ptr = newval; - - __spin_unlock(&lock.lock); - - return ret; -} -#endif INLINE void proc_yield(int cnt) { __asm__ __volatile__("" ::: "memory"); @@ -101,15 +52,8 @@ INLINE typename T::Type atomic_load( // 64-bit load on 32-bit platform. // Gross, but simple and reliable. // Assume that it is not in read-only memory. -#if defined(_MIPS_SIM) && _MIPS_SIM == _ABIO32 - typename T::Type volatile *val_ptr = - const_cast(&a->val_dont_use); - v = __mips_sync_fetch_and_add( - reinterpret_cast(val_ptr), 0); -#else v = __sync_fetch_and_add( const_cast(&a->val_dont_use), 0); -#endif } return v; } @@ -139,15 +83,8 @@ INLINE void atomic_store(volatile T *a, typename T::Type v, memory_order mo) { typename T::Type cmp = a->val_dont_use; typename T::Type cur; for (;;) { -#if defined(_MIPS_SIM) && _MIPS_SIM == _ABIO32 - typename T::Type volatile *val_ptr = - const_cast(&a->val_dont_use); - cur = __mips_sync_val_compare_and_swap( - reinterpret_cast(val_ptr), (u64)cmp, (u64)v); -#else cur = __sync_val_compare_and_swap(&a->val_dont_use, cmp, v); -#endif - if (cmp == v) + if (cur == cmp || cur == v) break; cmp = cur; } diff --git a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_x86.h b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_x86.h index 5df210eca79..aab9935676f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_atomic_clang_x86.h +++ b/libsanitizer/sanitizer_common/sanitizer_atomic_clang_x86.h @@ -59,8 +59,7 @@ INLINE typename T::Type atomic_load( "emms;" // Empty mmx state/Reset FP regs : "=m" (v) : "m" (a->val_dont_use) - : // mark the FP stack and mmx registers as clobbered - "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", + : // mark the mmx registers as clobbered #ifdef __MMX__ "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", #endif // #ifdef __MMX__ @@ -98,8 +97,7 @@ INLINE void atomic_store(volatile T *a, typename T::Type v, memory_order mo) { "emms;" // Empty mmx state/Reset FP regs : "=m" (a->val_dont_use) : "m" (v) - : // mark the FP stack and mmx registers as clobbered - "st", "st(1)", "st(2)", "st(3)", "st(4)", "st(5)", "st(6)", "st(7)", + : // mark the mmx registers as clobbered #ifdef __MMX__ "mm0", "mm1", "mm2", "mm3", "mm4", "mm5", "mm6", "mm7", #endif // #ifdef __MMX__ diff --git a/libsanitizer/sanitizer_common/sanitizer_bitvector.h b/libsanitizer/sanitizer_common/sanitizer_bitvector.h index bb2872facde..6ecac818845 100644 --- a/libsanitizer/sanitizer_common/sanitizer_bitvector.h +++ b/libsanitizer/sanitizer_common/sanitizer_bitvector.h @@ -20,7 +20,7 @@ namespace __sanitizer { template class BasicBitVector { public: - enum SizeEnum { kSize = sizeof(basic_int_t) * 8 }; + enum SizeEnum : uptr { kSize = sizeof(basic_int_t) * 8 }; uptr size() const { return kSize; } // No CTOR. @@ -113,7 +113,7 @@ class TwoLevelBitVector { // This structure allows O(kLevel1Size) time for clear() and empty(), // as well fast handling of sparse BVs. public: - enum SizeEnum { kSize = BV::kSize * BV::kSize * kLevel1Size }; + enum SizeEnum : uptr { kSize = BV::kSize * BV::kSize * kLevel1Size }; // No CTOR. uptr size() const { return kSize; } diff --git a/libsanitizer/sanitizer_common/sanitizer_bvgraph.h b/libsanitizer/sanitizer_common/sanitizer_bvgraph.h index 6ef0e81e044..a7f76bf585f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_bvgraph.h +++ b/libsanitizer/sanitizer_common/sanitizer_bvgraph.h @@ -23,7 +23,7 @@ namespace __sanitizer { template class BVGraph { public: - enum SizeEnum { kSize = BV::kSize }; + enum SizeEnum : uptr { kSize = BV::kSize }; uptr size() const { return kSize; } // No CTOR. void clear() { diff --git a/libsanitizer/sanitizer_common/sanitizer_common.cc b/libsanitizer/sanitizer_common/sanitizer_common.cc index 8d7e9fae64e..7f0f47c005d 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common.cc +++ b/libsanitizer/sanitizer_common/sanitizer_common.cc @@ -12,11 +12,10 @@ #include "sanitizer_common.h" #include "sanitizer_allocator_interface.h" #include "sanitizer_allocator_internal.h" +#include "sanitizer_atomic.h" #include "sanitizer_flags.h" #include "sanitizer_libc.h" #include "sanitizer_placement_new.h" -#include "sanitizer_stacktrace_printer.h" -#include "sanitizer_symbolizer.h" namespace __sanitizer { @@ -24,6 +23,7 @@ const char *SanitizerToolName = "SanitizerTool"; atomic_uint32_t current_verbosity; uptr PageSizeCached; +u32 NumberOfCPUsCached; // PID of the tracer task in StopTheWorld. It shares the address space with the // main process, but has a different PID and thus requires special handling. @@ -32,15 +32,14 @@ uptr stoptheworld_tracer_pid = 0; // writing to the same log file. uptr stoptheworld_tracer_ppid = 0; -StaticSpinMutex CommonSanitizerReportMutex; - void NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type, const char *mmap_type, error_t err, bool raw_report) { static int recursion_count; - if (raw_report || recursion_count) { - // If raw report is requested or we went into recursion, just die. - // The Report() and CHECK calls below may call mmap recursively and fail. + if (SANITIZER_RTEMS || raw_report || recursion_count) { + // If we are on RTEMS or raw report is requested or we went into recursion, + // just die. The Report() and CHECK calls below may call mmap recursively + // and fail. RawWrite("ERROR: Failed to mmap\n"); Die(); } @@ -57,19 +56,6 @@ void NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type, typedef bool UptrComparisonFunction(const uptr &a, const uptr &b); typedef bool U32ComparisonFunction(const u32 &a, const u32 &b); -template -static inline bool CompareLess(const T &a, const T &b) { - return a < b; -} - -void SortArray(uptr *array, uptr size) { - InternalSort(&array, size, CompareLess); -} - -void SortArray(u32 *array, uptr size) { - InternalSort(&array, size, CompareLess); -} - const char *StripPathPrefix(const char *filepath, const char *strip_path_prefix) { if (!filepath) return nullptr; @@ -106,18 +92,6 @@ void ReportErrorSummary(const char *error_message, const char *alt_tool_name) { __sanitizer_report_error_summary(buff.data()); } -#if !SANITIZER_GO -void ReportErrorSummary(const char *error_type, const AddressInfo &info, - const char *alt_tool_name) { - if (!common_flags()->print_summary) return; - InternalScopedString buff(kMaxSummaryLength); - buff.append("%s ", error_type); - RenderFrame(&buff, "%L %F", 0, info, common_flags()->symbolize_vs_style, - common_flags()->strip_path_prefix); - ReportErrorSummary(buff.data(), alt_tool_name); -} -#endif - // Removes the ANSI escape sequences from the input string (in-place). void RemoveANSIEscapeSequencesFromString(char *str) { if (!str) @@ -357,8 +331,9 @@ SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_report_error_summary, } SANITIZER_INTERFACE_ATTRIBUTE -void __sanitizer_set_death_callback(void (*callback)(void)) { - SetUserDieCallback(callback); +int __sanitizer_acquire_crash_state() { + static atomic_uint8_t in_crash_state = {}; + return !atomic_exchange(&in_crash_state, 1, memory_order_relaxed); } SANITIZER_INTERFACE_ATTRIBUTE diff --git a/libsanitizer/sanitizer_common/sanitizer_common.h b/libsanitizer/sanitizer_common/sanitizer_common.h index dd207d72e29..603d922b969 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common.h +++ b/libsanitizer/sanitizer_common/sanitizer_common.h @@ -37,11 +37,7 @@ struct StackTrace; const uptr kWordSize = SANITIZER_WORDSIZE / 8; const uptr kWordSizeInBits = 8 * kWordSize; -#if defined(__powerpc__) || defined(__powerpc64__) - const uptr kCacheLineSize = 128; -#else - const uptr kCacheLineSize = 64; -#endif +const uptr kCacheLineSize = SANITIZER_CACHE_LINE_SIZE; const uptr kMaxPathLength = 4096; @@ -50,7 +46,7 @@ const uptr kMaxThreadStackSize = 1 << 30; // 1Gb static const uptr kErrorMessageBufferSize = 1 << 16; // Denotes fake PC values that come from JIT/JAVA/etc. -// For such PC values __tsan_symbolize_external() will be called. +// For such PC values __tsan_symbolize_external_ex() will be called. const u64 kExternalPCBit = 1ULL << 60; extern const char *SanitizerToolName; // Can be changed by the tool. @@ -72,8 +68,10 @@ INLINE uptr GetPageSizeCached() { } uptr GetMmapGranularity(); uptr GetMaxVirtualAddress(); +uptr GetMaxUserVirtualAddress(); // Threads tid_t GetTid(); +int TgKill(pid_t pid, tid_t tid, int sig); uptr GetThreadSelf(); void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top, uptr *stack_bottom); @@ -89,8 +87,8 @@ void UnmapOrDie(void *addr, uptr size); // Behaves just like MmapOrDie, but tolerates out of memory condition, in that // case returns nullptr. void *MmapOrDieOnFatalError(uptr size, const char *mem_type); -void *MmapFixedNoReserve(uptr fixed_addr, uptr size, - const char *name = nullptr); +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); // Behaves just like MmapFixedOrDie, but tolerates out of memory condition, in @@ -107,9 +105,11 @@ void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment, bool MprotectNoAccess(uptr addr, uptr size); bool MprotectReadOnly(uptr addr, uptr size); +void MprotectMallocZones(void *addr, int prot); + // Find an available address space. uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding, - uptr *largest_gap_found); + uptr *largest_gap_found, uptr *max_occupied_addr); // Used to check if we can map shadow memory to a fixed location. bool MemoryRangeIsAvailable(uptr range_start, uptr range_end); @@ -119,13 +119,29 @@ void ReleaseMemoryPagesToOS(uptr beg, uptr end); void IncreaseTotalMmap(uptr size); void DecreaseTotalMmap(uptr size); uptr GetRSS(); -void NoHugePagesInRegion(uptr addr, uptr length); -void DontDumpShadowMemory(uptr addr, uptr length); +bool NoHugePagesInRegion(uptr addr, uptr length); +bool DontDumpShadowMemory(uptr addr, uptr length); // Check if the built VMA size matches the runtime one. void CheckVMASize(); void RunMallocHooks(const void *ptr, uptr size); 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); + void Unmap(uptr addr, uptr size); + void *base() const { return base_; } + uptr size() const { return size_; } + + private: + void* base_; + uptr size_; + const char* name_; + uptr os_handle_; +}; + typedef void (*fill_profile_f)(uptr start, uptr rss, bool file, /*out*/uptr *stats, uptr stats_size); @@ -134,49 +150,6 @@ typedef void (*fill_profile_f)(uptr start, uptr rss, bool file, // |stats_size| elements. void GetMemoryProfile(fill_profile_f cb, uptr *stats, uptr stats_size); -// InternalScopedBuffer can be used instead of large stack arrays to -// keep frame size low. -// FIXME: use InternalAlloc instead of MmapOrDie once -// InternalAlloc is made libc-free. -template -class InternalScopedBuffer { - public: - explicit InternalScopedBuffer(uptr cnt) { - cnt_ = cnt; - ptr_ = (T *)MmapOrDie(cnt * sizeof(T), "InternalScopedBuffer"); - } - ~InternalScopedBuffer() { UnmapOrDie(ptr_, cnt_ * sizeof(T)); } - T &operator[](uptr i) { return ptr_[i]; } - T *data() { return ptr_; } - uptr size() { return cnt_ * sizeof(T); } - - private: - T *ptr_; - uptr cnt_; - // Disallow copies and moves. - InternalScopedBuffer(const InternalScopedBuffer &) = delete; - InternalScopedBuffer &operator=(const InternalScopedBuffer &) = delete; - InternalScopedBuffer(InternalScopedBuffer &&) = delete; - InternalScopedBuffer &operator=(InternalScopedBuffer &&) = delete; -}; - -class InternalScopedString : public InternalScopedBuffer { - public: - explicit InternalScopedString(uptr max_length) - : InternalScopedBuffer(max_length), length_(0) { - (*this)[0] = '\0'; - } - uptr length() { return length_; } - void clear() { - (*this)[0] = '\0'; - length_ = 0; - } - void append(const char *format, ...); - - private: - uptr length_; -}; - // Simple low-level (mmap-based) allocator for internal use. Doesn't have // constructor, so all instances of LowLevelAllocator should be // linker initialized. @@ -188,6 +161,8 @@ class LowLevelAllocator { char *allocated_end_; char *allocated_current_; }; +// Set the min alignment of LowLevelAllocator to at least alignment. +void SetLowLevelAllocateMinAlignment(uptr alignment); typedef void (*LowLevelAllocateCallback)(uptr ptr, uptr size); // Allows to register tool-specific callbacks for LowLevelAllocator. // Passing NULL removes the callback. @@ -210,10 +185,6 @@ void SetPrintfAndReportCallback(void (*callback)(const char *)); if ((uptr)Verbosity() >= (level)) Printf(__VA_ARGS__); \ } while (0) -// Can be used to prevent mixing error reports from different sanitizers. -// FIXME: Replace with ScopedErrorReportLock and hide. -extern StaticSpinMutex CommonSanitizerReportMutex; - // Lock sanitizer error reporting and protects against nested errors. class ScopedErrorReportLock { public: @@ -226,15 +197,6 @@ class ScopedErrorReportLock { extern uptr stoptheworld_tracer_pid; extern uptr stoptheworld_tracer_ppid; -// Opens the file 'file_name" and reads up to 'max_len' bytes. -// The resulting buffer is mmaped and stored in '*buff'. -// The size of the mmaped region is stored in '*buff_size'. -// The total number of read bytes is stored in '*read_len'. -// Returns true if file was successfully opened and read. -bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size, - uptr *read_len, uptr max_len = 1 << 26, - error_t *errno_p = nullptr); - bool IsAccessibleMemoryRange(uptr beg, uptr size); // Error report formatting. @@ -258,6 +220,7 @@ bool SetEnv(const char *name, const char *value); u32 GetUid(); void ReExec(); +void CheckASLR(); char **GetArgv(); void PrintCmdline(); bool StackSizeIsUnlimited(); @@ -266,7 +229,7 @@ void SetStackSizeLimitInBytes(uptr limit); bool AddressSpaceIsUnlimited(); void SetAddressSpaceUnlimited(); void AdjustStackSize(void *attr); -void PrepareForSandboxing(__sanitizer_sandbox_arguments *args); +void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args); void SetSandboxingCallback(void (*f)()); void InitializeCoverage(bool enabled, const char *coverage_dir); @@ -278,9 +241,8 @@ uptr GetTlsSize(); void SleepForSeconds(int seconds); void SleepForMillis(int millis); u64 NanoTime(); +u64 MonotonicNanoTime(); int Atexit(void (*function)(void)); -void SortArray(uptr *array, uptr size); -void SortArray(u32 *array, uptr size); bool TemplateMatch(const char *templ, const char *str); // Exit @@ -292,13 +254,6 @@ void NORETURN ReportMmapFailureAndDie(uptr size, const char *mem_type, const char *mmap_type, error_t err, bool raw_report = false); -// Set the name of the current thread to 'name', return true on succees. -// The name may be truncated to a system-dependent limit. -bool SanitizerSetThreadName(const char *name); -// Get the name of the current thread (no more than max_len bytes), -// return true on succees. name should have space for at least max_len+1 bytes. -bool SanitizerGetThreadName(char *name, int max_len); - // Specific tools may override behavior of "Die" and "CheckFailed" functions // to do tool-specific job. typedef void (*DieCallbackType)(void); @@ -364,6 +319,8 @@ void ReportErrorSummary(const char *error_type, const AddressInfo &info, void ReportErrorSummary(const char *error_type, const StackTrace *trace, const char *alt_tool_name = nullptr); +void ReportMmapWriteExec(int prot); + // Math #if SANITIZER_WINDOWS && !defined(__clang__) && !defined(__GNUC__) extern "C" { @@ -471,13 +428,12 @@ template class InternalMmapVectorNoCtor { public: void Initialize(uptr initial_capacity) { - capacity_ = Max(initial_capacity, (uptr)1); + capacity_bytes_ = 0; size_ = 0; - data_ = (T *)MmapOrDie(capacity_ * sizeof(T), "InternalMmapVectorNoCtor"); - } - void Destroy() { - UnmapOrDie(data_, capacity_ * sizeof(T)); + data_ = 0; + reserve(initial_capacity); } + void Destroy() { UnmapOrDie(data_, capacity_bytes_); } T &operator[](uptr i) { CHECK_LT(i, size_); return data_[i]; @@ -487,10 +443,10 @@ class InternalMmapVectorNoCtor { return data_[i]; } void push_back(const T &element) { - CHECK_LE(size_, capacity_); - if (size_ == capacity_) { + CHECK_LE(size_, capacity()); + if (size_ == capacity()) { uptr new_capacity = RoundUpToPowerOfTwo(size_ + 1); - Resize(new_capacity); + Realloc(new_capacity); } internal_memcpy(&data_[size_++], &element, sizeof(T)); } @@ -511,12 +467,15 @@ class InternalMmapVectorNoCtor { T *data() { return data_; } - uptr capacity() const { - return capacity_; + uptr capacity() const { return capacity_bytes_ / sizeof(T); } + void reserve(uptr new_size) { + // Never downsize internal buffer. + if (new_size > capacity()) + Realloc(new_size); } void resize(uptr new_size) { - Resize(new_size); if (new_size > size_) { + reserve(new_size); internal_memset(&data_[size_], 0, sizeof(T) * (new_size - size_)); } size_ = new_size; @@ -538,39 +497,84 @@ class InternalMmapVectorNoCtor { return data() + size(); } + void swap(InternalMmapVectorNoCtor &other) { + Swap(data_, other.data_); + Swap(capacity_bytes_, other.capacity_bytes_); + Swap(size_, other.size_); + } + private: - void Resize(uptr new_capacity) { + void Realloc(uptr new_capacity) { CHECK_GT(new_capacity, 0); CHECK_LE(size_, new_capacity); - T *new_data = (T *)MmapOrDie(new_capacity * sizeof(T), - "InternalMmapVector"); + uptr new_capacity_bytes = + RoundUpTo(new_capacity * sizeof(T), GetPageSizeCached()); + T *new_data = (T *)MmapOrDie(new_capacity_bytes, "InternalMmapVector"); internal_memcpy(new_data, data_, size_ * sizeof(T)); - T *old_data = data_; + UnmapOrDie(data_, capacity_bytes_); data_ = new_data; - UnmapOrDie(old_data, capacity_ * sizeof(T)); - capacity_ = new_capacity; + capacity_bytes_ = new_capacity_bytes; } T *data_; - uptr capacity_; + uptr capacity_bytes_; uptr size_; }; +template +bool operator==(const InternalMmapVectorNoCtor &lhs, + const InternalMmapVectorNoCtor &rhs) { + if (lhs.size() != rhs.size()) return false; + return internal_memcmp(lhs.data(), rhs.data(), lhs.size() * sizeof(T)) == 0; +} + +template +bool operator!=(const InternalMmapVectorNoCtor &lhs, + const InternalMmapVectorNoCtor &rhs) { + return !(lhs == rhs); +} + template class InternalMmapVector : public InternalMmapVectorNoCtor { public: - explicit InternalMmapVector(uptr initial_capacity) { - InternalMmapVectorNoCtor::Initialize(initial_capacity); + InternalMmapVector() { InternalMmapVectorNoCtor::Initialize(1); } + explicit InternalMmapVector(uptr cnt) { + InternalMmapVectorNoCtor::Initialize(cnt); + this->resize(cnt); } ~InternalMmapVector() { InternalMmapVectorNoCtor::Destroy(); } - // Disallow evil constructors. - InternalMmapVector(const InternalMmapVector&); - void operator=(const InternalMmapVector&); + // Disallow copies and moves. + InternalMmapVector(const InternalMmapVector &) = delete; + InternalMmapVector &operator=(const InternalMmapVector &) = delete; + InternalMmapVector(InternalMmapVector &&) = delete; + InternalMmapVector &operator=(InternalMmapVector &&) = delete; +}; + +class InternalScopedString : public InternalMmapVector { + public: + explicit InternalScopedString(uptr max_length) + : InternalMmapVector(max_length), length_(0) { + (*this)[0] = '\0'; + } + uptr length() { return length_; } + void clear() { + (*this)[0] = '\0'; + length_ = 0; + } + void append(const char *format, ...); + + private: + uptr length_; +}; + +template +struct CompareLess { + bool operator()(const T &a, const T &b) const { return a < b; } }; // HeapSort for arrays and InternalMmapVector. -template -void InternalSort(Container *v, uptr size, Compare comp) { +template > +void Sort(T *v, uptr size, Compare comp = {}) { if (size < 2) return; // Stage 1: insert elements to the heap. @@ -578,8 +582,8 @@ void InternalSort(Container *v, uptr size, Compare comp) { uptr j, p; for (j = i; j > 0; j = p) { p = (j - 1) / 2; - if (comp((*v)[p], (*v)[j])) - Swap((*v)[j], (*v)[p]); + if (comp(v[p], v[j])) + Swap(v[j], v[p]); else break; } @@ -587,18 +591,18 @@ void InternalSort(Container *v, uptr size, Compare comp) { // Stage 2: swap largest element with the last one, // and sink the new top. for (uptr i = size - 1; i > 0; i--) { - Swap((*v)[0], (*v)[i]); + Swap(v[0], v[i]); uptr j, max_ind; for (j = 0; j < i; j = max_ind) { uptr left = 2 * j + 1; uptr right = 2 * j + 2; max_ind = j; - if (left < i && comp((*v)[max_ind], (*v)[left])) + if (left < i && comp(v[max_ind], v[left])) max_ind = left; - if (right < i && comp((*v)[max_ind], (*v)[right])) + if (right < i && comp(v[max_ind], v[right])) max_ind = right; if (max_ind != j) - Swap((*v)[j], (*v)[max_ind]); + Swap(v[j], v[max_ind]); else break; } @@ -632,6 +636,25 @@ enum ModuleArch { kModuleArchARM64 }; +// Opens the file 'file_name" and reads up to 'max_len' bytes. +// The resulting buffer is mmaped and stored in '*buff'. +// Returns true if file was successfully opened and read. +bool ReadFileToVector(const char *file_name, + InternalMmapVectorNoCtor *buff, + uptr max_len = 1 << 26, error_t *errno_p = nullptr); + +// Opens the file 'file_name" and reads up to 'max_len' bytes. +// This function is less I/O efficient than ReadFileToVector as it may reread +// file multiple times to avoid mmap during read attempts. It's used to read +// procmap, so short reads with mmap in between can produce inconsistent result. +// The resulting buffer is mmaped and stored in '*buff'. +// The size of the mmaped region is stored in '*buff_size'. +// The total number of read bytes is stored in '*read_len'. +// Returns true if file was successfully opened and read. +bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size, + uptr *read_len, uptr max_len = 1 << 26, + 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. inline const char *ModuleArchToString(ModuleArch arch) { @@ -916,6 +939,15 @@ void CheckNoDeepBind(const char *filename, int flag); // be used to seed a PRNG. Defaults to blocking like the underlying syscall. bool GetRandom(void *buffer, uptr length, bool blocking = true); +// Returns the number of logical processors on the system. +u32 GetNumberOfCPUs(); +extern u32 NumberOfCPUsCached; +INLINE u32 GetNumberOfCPUsCached() { + if (!NumberOfCPUsCached) + NumberOfCPUsCached = GetNumberOfCPUs(); + return NumberOfCPUsCached; +} + } // namespace __sanitizer inline void *operator new(__sanitizer::operator_new_size_type size, diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc index 3f32b2f78ef..c810e65f0ad 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors.inc @@ -32,6 +32,7 @@ // COMMON_INTERCEPTOR_MEMSET_IMPL // COMMON_INTERCEPTOR_MEMMOVE_IMPL // COMMON_INTERCEPTOR_MEMCPY_IMPL +// COMMON_INTERCEPTOR_MMAP_IMPL // COMMON_INTERCEPTOR_COPY_STRING // COMMON_INTERCEPTOR_STRNDUP_IMPL //===----------------------------------------------------------------------===// @@ -67,6 +68,52 @@ #define iconv __bsd_iconv #endif +#if SANITIZER_NETBSD +#define clock_getres __clock_getres50 +#define clock_gettime __clock_gettime50 +#define clock_settime __clock_settime50 +#define ctime __ctime50 +#define ctime_r __ctime_r50 +#define devname __devname50 +#define getitimer __getitimer50 +#define getpwent __getpwent50 +#define getpwnam __getpwnam50 +#define getpwnam_r __getpwnam_r50 +#define getpwuid __getpwuid50 +#define getpwuid_r __getpwuid_r50 +#define getutent __getutent50 +#define getutxent __getutxent50 +#define getutxid __getutxid50 +#define getutxline __getutxline50 +#define glob __glob30 +#define gmtime __gmtime50 +#define gmtime_r __gmtime_r50 +#define localtime __locatime50 +#define localtime_r __localtime_r50 +#define mktime __mktime50 +#define lstat __lstat50 +#define opendir __opendir30 +#define readdir __readdir30 +#define readdir_r __readdir_r30 +#define scandir __scandir30 +#define setitimer __setitimer50 +#define setlocale __setlocale50 +#define shmctl __shmctl50 +#define sigemptyset __sigemptyset14 +#define sigfillset __sigfillset14 +#define sigpending __sigpending14 +#define sigprocmask __sigprocmask14 +#define sigtimedwait __sigtimedwait50 +#define stat __stat50 +#define time __time50 +#define times __times13 +#define wait3 __wait350 +#define wait4 __wait450 +extern const unsigned short *_ctype_tab_; +extern const short *_toupper_tab_; +extern const short *_tolower_tab_; +#endif + // Platform-specific options. #if SANITIZER_MAC namespace __sanitizer { @@ -219,6 +266,12 @@ bool PlatformHasDifferentMemcpyAndMemmove(); } #endif +#ifndef COMMON_INTERCEPTOR_MMAP_IMPL +#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \ + off) \ + { return REAL(mmap)(addr, sz, prot, flags, fd, off); } +#endif + #ifndef COMMON_INTERCEPTOR_COPY_STRING #define COMMON_INTERCEPTOR_COPY_STRING(ctx, to, from, size) {} #endif @@ -271,7 +324,7 @@ UNUSED static const FileMetadata *GetInterceptorMetadata( MetadataHashMap::Handle h(interceptor_metadata_map, (uptr)addr, /* remove */ false, /* create */ false); - if (h.exists()) { + if (addr && h.exists()) { CHECK(!h.created()); CHECK(h->type == CommonInterceptorMetadata::CIMT_FILE); return &h->file; @@ -1134,6 +1187,50 @@ INTERCEPTOR(SSIZE_T, pwritev64, int fd, __sanitizer_iovec *iov, int iovcnt, #define INIT_PWRITEV64 #endif +#if SANITIZER_INTERCEPT_FGETS +INTERCEPTOR(char *, fgets, char *s, SIZE_T size, void *file) { + // libc file streams can call user-supplied functions, see fopencookie. + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, fgets, s, size, file); + // FIXME: under ASan the call below may write to freed memory and corrupt + // its metadata. See + // https://github.com/google/sanitizers/issues/321. + char *res = REAL(fgets)(s, size, file); + if (res) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, s, REAL(strlen)(s) + 1); + return res; +} +#define INIT_FGETS COMMON_INTERCEPT_FUNCTION(fgets) +#else +#define INIT_FGETS +#endif + +#if SANITIZER_INTERCEPT_FPUTS +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); + return REAL(fputs)(s, file); +} +#define INIT_FPUTS COMMON_INTERCEPT_FUNCTION(fputs) +#else +#define INIT_FPUTS +#endif + +#if SANITIZER_INTERCEPT_PUTS +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); + return REAL(puts)(s); +} +#define INIT_PUTS COMMON_INTERCEPT_FUNCTION(puts) +#else +#define INIT_PUTS +#endif + #if SANITIZER_INTERCEPT_PRCTL INTERCEPTOR(int, prctl, int option, unsigned long arg2, unsigned long arg3, // NOLINT @@ -1175,12 +1272,14 @@ INTERCEPTOR(unsigned long, time, unsigned long *t) { #if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS static void unpoison_tm(void *ctx, __sanitizer_tm *tm) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); +#if !SANITIZER_SOLARIS if (tm->tm_zone) { // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone // can point to shared memory and tsan would report a data race. COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone, REAL(strlen(tm->tm_zone)) + 1); } +#endif } INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) { void *ctx; @@ -1508,6 +1607,12 @@ INTERCEPTOR(int, vsnprintf, char *str, SIZE_T size, const char *format, va_list ap) VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap) +#if SANITIZER_INTERCEPT___PRINTF_CHK +INTERCEPTOR(int, __vsnprintf_chk, char *str, SIZE_T size, int flag, + SIZE_T size_to, const char *format, va_list ap) +VSNPRINTF_INTERCEPTOR_IMPL(vsnprintf, str, size, format, ap) +#endif + #if SANITIZER_INTERCEPT_PRINTF_L INTERCEPTOR(int, vsnprintf_l, char *str, SIZE_T size, void *loc, const char *format, va_list ap) @@ -1521,6 +1626,12 @@ FORMAT_INTERCEPTOR_IMPL(snprintf_l, vsnprintf_l, str, size, loc, format) INTERCEPTOR(int, vsprintf, char *str, const char *format, va_list ap) VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap) +#if SANITIZER_INTERCEPT___PRINTF_CHK +INTERCEPTOR(int, __vsprintf_chk, char *str, int flag, SIZE_T size_to, + const char *format, va_list ap) +VSPRINTF_INTERCEPTOR_IMPL(vsprintf, str, format, ap) +#endif + INTERCEPTOR(int, vasprintf, char **strp, const char *format, va_list ap) VASPRINTF_INTERCEPTOR_IMPL(vasprintf, strp, format, ap) @@ -1549,12 +1660,30 @@ FORMAT_INTERCEPTOR_IMPL(printf, vprintf, format) INTERCEPTOR(int, fprintf, __sanitizer_FILE *stream, const char *format, ...) FORMAT_INTERCEPTOR_IMPL(fprintf, vfprintf, stream, format) +#if SANITIZER_INTERCEPT___PRINTF_CHK +INTERCEPTOR(int, __fprintf_chk, __sanitizer_FILE *stream, SIZE_T size, + const char *format, ...) +FORMAT_INTERCEPTOR_IMPL(__fprintf_chk, vfprintf, stream, format) +#endif + INTERCEPTOR(int, sprintf, char *str, const char *format, ...) // NOLINT FORMAT_INTERCEPTOR_IMPL(sprintf, vsprintf, str, format) // NOLINT +#if SANITIZER_INTERCEPT___PRINTF_CHK +INTERCEPTOR(int, __sprintf_chk, char *str, int flag, SIZE_T size_to, + const char *format, ...) // NOLINT +FORMAT_INTERCEPTOR_IMPL(__sprintf_chk, vsprintf, str, format) // NOLINT +#endif + INTERCEPTOR(int, snprintf, char *str, SIZE_T size, const char *format, ...) FORMAT_INTERCEPTOR_IMPL(snprintf, vsnprintf, str, size, format) +#if SANITIZER_INTERCEPT___PRINTF_CHK +INTERCEPTOR(int, __snprintf_chk, char *str, SIZE_T size, int flag, + SIZE_T size_to, const char *format, ...) // NOLINT +FORMAT_INTERCEPTOR_IMPL(__snprintf_chk, vsnprintf, str, size, format) // NOLINT +#endif + INTERCEPTOR(int, asprintf, char **strp, const char *format, ...) FORMAT_INTERCEPTOR_IMPL(asprintf, vasprintf, strp, format) @@ -1594,6 +1723,17 @@ FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size, #define INIT_PRINTF #endif +#if SANITIZER_INTERCEPT___PRINTF_CHK +#define INIT___PRINTF_CHK \ + COMMON_INTERCEPT_FUNCTION(__sprintf_chk); \ + COMMON_INTERCEPT_FUNCTION(__snprintf_chk); \ + COMMON_INTERCEPT_FUNCTION(__vsprintf_chk); \ + COMMON_INTERCEPT_FUNCTION(__vsnprintf_chk); \ + COMMON_INTERCEPT_FUNCTION(__fprintf_chk); +#else +#define INIT___PRINTF_CHK +#endif + #if SANITIZER_INTERCEPT_PRINTF_L #define INIT_PRINTF_L \ COMMON_INTERCEPT_FUNCTION(snprintf_l); \ @@ -1618,6 +1758,7 @@ FORMAT_INTERCEPTOR_IMPL(__isoc99_snprintf, __isoc99_vsnprintf, str, size, #if SANITIZER_INTERCEPT_IOCTL #include "sanitizer_common_interceptors_ioctl.inc" +#include "sanitizer_interceptors_ioctl_netbsd.inc" INTERCEPTOR(int, ioctl, int d, unsigned long request, ...) { // We need a frame pointer, because we call into ioctl_common_[pre|post] which // can trigger a report and we need to be able to unwind through this @@ -1722,7 +1863,8 @@ static void unpoison_group(void *ctx, __sanitizer_group *grp) { INTERCEPTOR(__sanitizer_passwd *, getpwnam, const char *name) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, getpwnam, name); - COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + if (name) + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); __sanitizer_passwd *res = REAL(getpwnam)(name); if (res) unpoison_passwd(ctx, res); return res; @@ -2002,6 +2144,13 @@ INTERCEPTOR(int, clock_gettime, u32 clk_id, void *tp) { } return res; } +namespace __sanitizer { +extern "C" { +int real_clock_gettime(u32 clk_id, void *tp) { + return REAL(clock_gettime)(clk_id, tp); +} +} // extern "C" +} // namespace __sanitizer INTERCEPTOR(int, clock_settime, u32 clk_id, const void *tp) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, clock_settime, clk_id, tp); @@ -2032,8 +2181,19 @@ INTERCEPTOR(int, getitimer, int which, void *curr_value) { INTERCEPTOR(int, setitimer, int which, const void *new_value, void *old_value) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, setitimer, which, new_value, old_value); - if (new_value) - COMMON_INTERCEPTOR_READ_RANGE(ctx, new_value, struct_itimerval_sz); + if (new_value) { + // itimerval can contain padding that may be legitimately uninitialized + const struct __sanitizer_itimerval *nv = + (const struct __sanitizer_itimerval *)new_value; + COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_sec, + sizeof(__sanitizer_time_t)); + COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_interval.tv_usec, + sizeof(__sanitizer_suseconds_t)); + COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_sec, + sizeof(__sanitizer_time_t)); + COMMON_INTERCEPTOR_READ_RANGE(ctx, &nv->it_value.tv_usec, + sizeof(__sanitizer_suseconds_t)); + } // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. @@ -2063,6 +2223,18 @@ static void unpoison_glob_t(void *ctx, __sanitizer_glob_t *pglob) { } } +#if SANITIZER_SOLARIS +INTERCEPTOR(int, glob, const char *pattern, int flags, + int (*errfunc)(const char *epath, int eerrno), + __sanitizer_glob_t *pglob) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); + COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0); + int res = REAL(glob)(pattern, flags, errfunc, pglob); + if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); + return res; +} +#else static THREADLOCAL __sanitizer_glob_t *pglob_copy; static void wrapped_gl_closedir(void *dir) { @@ -2126,7 +2298,14 @@ INTERCEPTOR(int, glob, const char *pattern, int flags, if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); return res; } +#endif // SANITIZER_SOLARIS +#define INIT_GLOB \ + COMMON_INTERCEPT_FUNCTION(glob); +#else // SANITIZER_INTERCEPT_GLOB +#define INIT_GLOB +#endif // SANITIZER_INTERCEPT_GLOB +#if SANITIZER_INTERCEPT_GLOB64 INTERCEPTOR(int, glob64, const char *pattern, int flags, int (*errfunc)(const char *epath, int eerrno), __sanitizer_glob_t *pglob) { @@ -2155,12 +2334,11 @@ INTERCEPTOR(int, glob64, const char *pattern, int flags, if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); return res; } -#define INIT_GLOB \ - COMMON_INTERCEPT_FUNCTION(glob); \ +#define INIT_GLOB64 \ COMMON_INTERCEPT_FUNCTION(glob64); -#else // SANITIZER_INTERCEPT_GLOB -#define INIT_GLOB -#endif // SANITIZER_INTERCEPT_GLOB +#else // SANITIZER_INTERCEPT_GLOB64 +#define INIT_GLOB64 +#endif // SANITIZER_INTERCEPT_GLOB64 #if SANITIZER_INTERCEPT_WAIT // According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version @@ -2465,7 +2643,15 @@ INTERCEPTOR(struct __sanitizer_hostent *, gethostent, int fake) { if (res) write_hostent(ctx, res); return res; } +#define INIT_GETHOSTBYNAME \ + COMMON_INTERCEPT_FUNCTION(gethostent); \ + COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \ + COMMON_INTERCEPT_FUNCTION(gethostbyname); +#else +#define INIT_GETHOSTBYNAME +#endif // SANITIZER_INTERCEPT_GETHOSTBYNAME +#if SANITIZER_INTERCEPT_GETHOSTBYNAME2 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af); @@ -2473,14 +2659,10 @@ INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { if (res) write_hostent(ctx, res); return res; } -#define INIT_GETHOSTBYNAME \ - COMMON_INTERCEPT_FUNCTION(gethostent); \ - COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \ - COMMON_INTERCEPT_FUNCTION(gethostbyname); \ - COMMON_INTERCEPT_FUNCTION(gethostbyname2); +#define INIT_GETHOSTBYNAME2 COMMON_INTERCEPT_FUNCTION(gethostbyname2); #else -#define INIT_GETHOSTBYNAME -#endif +#define INIT_GETHOSTBYNAME2 +#endif // SANITIZER_INTERCEPT_GETHOSTBYNAME2 #if SANITIZER_INTERCEPT_GETHOSTBYNAME_R INTERCEPTOR(int, gethostbyname_r, char *name, struct __sanitizer_hostent *ret, @@ -2650,6 +2832,30 @@ INTERCEPTOR(int, accept4, int fd, void *addr, unsigned *addrlen, int f) { #define INIT_ACCEPT4 #endif +#if SANITIZER_INTERCEPT_PACCEPT +INTERCEPTOR(int, paccept, int fd, void *addr, unsigned *addrlen, + __sanitizer_sigset_t *set, int f) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, paccept, fd, addr, addrlen, set, f); + unsigned addrlen0 = 0; + if (addrlen) { + COMMON_INTERCEPTOR_READ_RANGE(ctx, addrlen, sizeof(*addrlen)); + addrlen0 = *addrlen; + } + if (set) COMMON_INTERCEPTOR_READ_RANGE(ctx, set, sizeof(*set)); + int fd2 = REAL(paccept)(fd, addr, addrlen, set, f); + if (fd2 >= 0) { + if (fd >= 0) COMMON_INTERCEPTOR_FD_SOCKET_ACCEPT(ctx, fd, fd2); + if (addr && addrlen) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, addr, Min(*addrlen, addrlen0)); + } + return fd2; +} +#define INIT_PACCEPT COMMON_INTERCEPT_FUNCTION(paccept); +#else +#define INIT_PACCEPT +#endif + #if SANITIZER_INTERCEPT_MODF INTERCEPTOR(double, modf, double x, double *iptr) { void *ctx; @@ -2695,7 +2901,7 @@ INTERCEPTOR(long double, modfl, long double x, long double *iptr) { #define INIT_MODF #endif -#if SANITIZER_INTERCEPT_RECVMSG +#if SANITIZER_INTERCEPT_RECVMSG || SANITIZER_INTERCEPT_RECVMMSG static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg, SSIZE_T maxlen) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg, sizeof(*msg)); @@ -2708,7 +2914,9 @@ static void write_msghdr(void *ctx, struct __sanitizer_msghdr *msg, if (msg->msg_control && msg->msg_controllen) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, msg->msg_control, msg->msg_controllen); } +#endif +#if SANITIZER_INTERCEPT_RECVMSG INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, int flags) { void *ctx; @@ -2731,7 +2939,30 @@ INTERCEPTOR(SSIZE_T, recvmsg, int fd, struct __sanitizer_msghdr *msg, #define INIT_RECVMSG #endif -#if SANITIZER_INTERCEPT_SENDMSG +#if SANITIZER_INTERCEPT_RECVMMSG +INTERCEPTOR(int, recvmmsg, int fd, struct __sanitizer_mmsghdr *msgvec, + unsigned int vlen, int flags, void *timeout) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, recvmmsg, fd, msgvec, vlen, flags, timeout); + if (timeout) COMMON_INTERCEPTOR_READ_RANGE(ctx, timeout, struct_timespec_sz); + int res = REAL(recvmmsg)(fd, msgvec, vlen, flags, timeout); + if (res >= 0) { + if (fd >= 0) COMMON_INTERCEPTOR_FD_ACQUIRE(ctx, fd); + for (int i = 0; i < res; ++i) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len, + sizeof(msgvec[i].msg_len)); + write_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len); + COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, &msgvec[i].msg_hdr); + } + } + return res; +} +#define INIT_RECVMMSG COMMON_INTERCEPT_FUNCTION(recvmmsg); +#else +#define INIT_RECVMMSG +#endif + +#if SANITIZER_INTERCEPT_SENDMSG || SANITIZER_INTERCEPT_SENDMMSG static void read_msghdr_control(void *ctx, void *control, uptr controllen) { const unsigned kCmsgDataOffset = RoundUpTo(sizeof(__sanitizer_cmsghdr), sizeof(uptr)); @@ -2781,7 +3012,9 @@ static void read_msghdr(void *ctx, struct __sanitizer_msghdr *msg, if (msg->msg_control && msg->msg_controllen) read_msghdr_control(ctx, msg->msg_control, msg->msg_controllen); } +#endif +#if SANITIZER_INTERCEPT_SENDMSG INTERCEPTOR(SSIZE_T, sendmsg, int fd, struct __sanitizer_msghdr *msg, int flags) { void *ctx; @@ -2800,6 +3033,30 @@ INTERCEPTOR(SSIZE_T, sendmsg, int fd, struct __sanitizer_msghdr *msg, #define INIT_SENDMSG #endif +#if SANITIZER_INTERCEPT_SENDMMSG +INTERCEPTOR(int, sendmmsg, int fd, struct __sanitizer_mmsghdr *msgvec, + unsigned vlen, int flags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, sendmmsg, fd, msgvec, vlen, flags); + if (fd >= 0) { + COMMON_INTERCEPTOR_FD_ACCESS(ctx, fd); + COMMON_INTERCEPTOR_FD_RELEASE(ctx, fd); + } + int res = REAL(sendmmsg)(fd, msgvec, vlen, flags); + if (res >= 0 && msgvec) + for (int i = 0; i < res; ++i) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, &msgvec[i].msg_len, + sizeof(msgvec[i].msg_len)); + if (common_flags()->intercept_send) + read_msghdr(ctx, &msgvec[i].msg_hdr, msgvec[i].msg_len); + } + return res; +} +#define INIT_SENDMMSG COMMON_INTERCEPT_FUNCTION(sendmmsg); +#else +#define INIT_SENDMMSG +#endif + #if SANITIZER_INTERCEPT_GETPEERNAME INTERCEPTOR(int, getpeername, int sockfd, void *addr, unsigned *addrlen) { void *ctx; @@ -2981,13 +3238,25 @@ INTERCEPTOR(uptr, ptrace, int request, int pid, void *addr, void *data) { #endif #if SANITIZER_INTERCEPT_SETLOCALE +static void unpoison_ctype_arrays(void *ctx) { +#if SANITIZER_NETBSD + // These arrays contain 256 regular elements in unsigned char range + 1 EOF + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _ctype_tab_, 257 * sizeof(short)); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _toupper_tab_, 257 * sizeof(short)); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, _tolower_tab_, 257 * sizeof(short)); +#endif +} + INTERCEPTOR(char *, setlocale, int category, char *locale) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, setlocale, category, locale); if (locale) COMMON_INTERCEPTOR_READ_RANGE(ctx, locale, REAL(strlen)(locale) + 1); char *res = REAL(setlocale)(category, locale); - if (res) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + if (res) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, res, REAL(strlen)(res) + 1); + unpoison_ctype_arrays(ctx); + } return res; } @@ -3074,14 +3343,14 @@ INTERCEPTOR(INTMAX_T, strtoimax, const char *nptr, char **endptr, int base) { return res; } -INTERCEPTOR(INTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { +INTERCEPTOR(UINTMAX_T, strtoumax, const char *nptr, char **endptr, int base) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, strtoumax, nptr, endptr, base); // FIXME: under ASan the call below may write to freed memory and corrupt // its metadata. See // https://github.com/google/sanitizers/issues/321. char *real_endptr; - INTMAX_T res = REAL(strtoumax)(nptr, &real_endptr, base); + UINTMAX_T res = REAL(strtoumax)(nptr, &real_endptr, base); StrtolFixAndCheck(ctx, nptr, endptr, real_endptr, base); return res; } @@ -3370,7 +3639,8 @@ INTERCEPTOR(char *, strerror, int errnum) { // * GNU version returns message pointer, which points to either buf or some // static storage. #if ((_POSIX_C_SOURCE >= 200112L || _XOPEN_SOURCE >= 600) && !_GNU_SOURCE) || \ - SANITIZER_MAC || SANITIZER_ANDROID + SANITIZER_MAC || SANITIZER_ANDROID || SANITIZER_NETBSD || \ + SANITIZER_FREEBSD || SANITIZER_OPENBSD // POSIX version. Spec is not clear on whether buf is NULL-terminated. // At least on OSX, buf contents are valid even when the call fails. INTERCEPTOR(int, strerror_r, int errnum, char *buf, SIZE_T buflen) { @@ -3793,7 +4063,7 @@ INTERCEPTOR(void, _exit, int status) { #define INIT__EXIT #endif -#if SANITIZER_INTERCEPT_PHTREAD_MUTEX +#if SANITIZER_INTERCEPT_PTHREAD_MUTEX INTERCEPTOR(int, pthread_mutex_lock, void *m) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, pthread_mutex_lock, m); @@ -3826,6 +4096,44 @@ INTERCEPTOR(int, pthread_mutex_unlock, void *m) { #define INIT_PTHREAD_MUTEX_UNLOCK #endif +#if SANITIZER_INTERCEPT___PTHREAD_MUTEX +INTERCEPTOR(int, __pthread_mutex_lock, void *m) { + return WRAP(pthread_mutex_lock)(m); +} + +INTERCEPTOR(int, __pthread_mutex_unlock, void *m) { + return WRAP(pthread_mutex_unlock)(m); +} + +#define INIT___PTHREAD_MUTEX_LOCK \ + COMMON_INTERCEPT_FUNCTION(__pthread_mutex_lock) +#define INIT___PTHREAD_MUTEX_UNLOCK \ + COMMON_INTERCEPT_FUNCTION(__pthread_mutex_unlock) +#else +#define INIT___PTHREAD_MUTEX_LOCK +#define INIT___PTHREAD_MUTEX_UNLOCK +#endif + +#if SANITIZER_INTERCEPT___LIBC_MUTEX +INTERCEPTOR(int, __libc_mutex_lock, void *m) +ALIAS(WRAPPER_NAME(pthread_mutex_lock)); + +INTERCEPTOR(int, __libc_mutex_unlock, void *m) +ALIAS(WRAPPER_NAME(pthread_mutex_unlock)); + +INTERCEPTOR(int, __libc_thr_setcancelstate, int state, int *oldstate) +ALIAS(WRAPPER_NAME(pthread_setcancelstate)); + +#define INIT___LIBC_MUTEX_LOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_lock) +#define INIT___LIBC_MUTEX_UNLOCK COMMON_INTERCEPT_FUNCTION(__libc_mutex_unlock) +#define INIT___LIBC_THR_SETCANCELSTATE \ + COMMON_INTERCEPT_FUNCTION(__libc_thr_setcancelstate) +#else +#define INIT___LIBC_MUTEX_LOCK +#define INIT___LIBC_MUTEX_UNLOCK +#define INIT___LIBC_THR_SETCANCELSTATE +#endif + #if SANITIZER_INTERCEPT_GETMNTENT || SANITIZER_INTERCEPT_GETMNTENT_R static void write_mntent(void *ctx, __sanitizer_mntent *mnt) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mnt, sizeof(*mnt)); @@ -4150,6 +4458,7 @@ INTERCEPTOR(int, random_r, void *buf, u32 *result) { // its metadata. See // https://github.com/google/sanitizers/issues/321. #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET || \ + SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED || \ SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSSCHED || \ SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GET || \ SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GET || \ @@ -4178,8 +4487,6 @@ INTERCEPTOR(int, random_r, void *buf, u32 *result) { #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET INTERCEPTOR_PTHREAD_ATTR_GET(detachstate, sizeof(int)) INTERCEPTOR_PTHREAD_ATTR_GET(guardsize, sizeof(SIZE_T)) -INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz) -INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int)) INTERCEPTOR_PTHREAD_ATTR_GET(scope, sizeof(int)) INTERCEPTOR_PTHREAD_ATTR_GET(stacksize, sizeof(SIZE_T)) INTERCEPTOR(int, pthread_attr_getstack, void *attr, void **addr, SIZE_T *size) { @@ -4210,8 +4517,6 @@ int real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) { #define INIT_PTHREAD_ATTR_GET \ COMMON_INTERCEPT_FUNCTION(pthread_attr_getdetachstate); \ COMMON_INTERCEPT_FUNCTION(pthread_attr_getguardsize); \ - COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam); \ - COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); \ COMMON_INTERCEPT_FUNCTION(pthread_attr_getscope); \ COMMON_INTERCEPT_FUNCTION(pthread_attr_getstacksize); \ COMMON_INTERCEPT_FUNCTION(pthread_attr_getstack); @@ -4219,6 +4524,17 @@ int real_pthread_attr_getstack(void *attr, void **addr, SIZE_T *size) { #define INIT_PTHREAD_ATTR_GET #endif +#if SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED +INTERCEPTOR_PTHREAD_ATTR_GET(schedparam, struct_sched_param_sz) +INTERCEPTOR_PTHREAD_ATTR_GET(schedpolicy, sizeof(int)) + +#define INIT_PTHREAD_ATTR_GET_SCHED \ + COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedparam); \ + COMMON_INTERCEPT_FUNCTION(pthread_attr_getschedpolicy); +#else +#define INIT_PTHREAD_ATTR_GET_SCHED +#endif + #if SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED INTERCEPTOR_PTHREAD_ATTR_GET(inheritsched, sizeof(int)) @@ -4403,7 +4719,7 @@ INTERCEPTOR(char *, tempnam, char *dir, char *pfx) { #define INIT_TEMPNAM #endif -#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP +#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && !SANITIZER_NETBSD INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name); @@ -4412,10 +4728,35 @@ INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) { return REAL(pthread_setname_np)(thread, name); } #define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np); +#elif SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && SANITIZER_NETBSD +INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name, void *arg) { + void *ctx; + char newname[32]; // PTHREAD_MAX_NAMELEN_NP=32 + COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name, arg); + COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0); + internal_snprintf(newname, sizeof(newname), name, arg); + COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, newname); + return REAL(pthread_setname_np)(thread, name, arg); +} +#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np); #else #define INIT_PTHREAD_SETNAME_NP #endif +#if SANITIZER_INTERCEPT_PTHREAD_GETNAME_NP +INTERCEPTOR(int, pthread_getname_np, uptr thread, char *name, SIZE_T len) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, pthread_getname_np, thread, name, len); + int res = REAL(pthread_getname_np)(thread, name, len); + if (!res) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, internal_strnlen(name, len) + 1); + return res; +} +#define INIT_PTHREAD_GETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_getname_np); +#else +#define INIT_PTHREAD_GETNAME_NP +#endif + #if SANITIZER_INTERCEPT_SINCOS INTERCEPTOR(void, sincos, double x, double *sin, double *cos) { void *ctx; @@ -5822,7 +6163,7 @@ INTERCEPTOR(int, pthread_setcancelstate, int state, int *oldstate) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcancelstate, state, oldstate); int res = REAL(pthread_setcancelstate)(state, oldstate); - if (res == 0) + if (res == 0 && oldstate != nullptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldstate, sizeof(*oldstate)); return res; } @@ -5831,7 +6172,7 @@ INTERCEPTOR(int, pthread_setcanceltype, int type, int *oldtype) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, pthread_setcanceltype, type, oldtype); int res = REAL(pthread_setcanceltype)(type, oldtype); - if (res == 0) + if (res == 0 && oldtype != nullptr) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, oldtype, sizeof(*oldtype)); return res; } @@ -6040,6 +6381,22 @@ INTERCEPTOR(int, stat, const char *path, void *buf) { #define INIT_STAT #endif +#if SANITIZER_INTERCEPT_LSTAT +INTERCEPTOR(int, lstat, const char *path, void *buf) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, lstat, path, buf); + if (common_flags()->intercept_stat) + COMMON_INTERCEPTOR_READ_STRING(ctx, path, 0); + int res = REAL(lstat)(path, buf); + if (!res) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, __sanitizer::struct_stat_sz); + return res; +} +#define INIT_LSTAT COMMON_INTERCEPT_FUNCTION(lstat) +#else +#define INIT_LSTAT +#endif + #if SANITIZER_INTERCEPT___XSTAT INTERCEPTOR(int, __xstat, int version, const char *path, void *buf) { void *ctx; @@ -6252,10 +6609,636 @@ INTERCEPTOR(wchar_t *, wcsncat, wchar_t *dst, const wchar_t *src, SIZE_T n) { #define INIT_WCSCAT #endif +#if SANITIZER_INTERCEPT_STRXFRM +static SIZE_T RealStrLen(const char *str) { return REAL(strlen)(str); } + +static SIZE_T RealStrLen(const wchar_t *str) { return REAL(wcslen)(str); } + +#define STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len, ...) \ + { \ + void *ctx; \ + COMMON_INTERCEPTOR_ENTER(ctx, strxfrm, dest, src, len, ##__VA_ARGS__); \ + COMMON_INTERCEPTOR_READ_RANGE(ctx, src, \ + sizeof(*src) * (RealStrLen(src) + 1)); \ + SIZE_T res = REAL(strxfrm)(dest, src, len, ##__VA_ARGS__); \ + if (res < len) \ + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, dest, sizeof(*src) * (res + 1)); \ + return res; \ + } + +INTERCEPTOR(SIZE_T, strxfrm, char *dest, const char *src, SIZE_T len) { + STRXFRM_INTERCEPTOR_IMPL(strxfrm, dest, src, len); +} + +INTERCEPTOR(SIZE_T, strxfrm_l, char *dest, const char *src, SIZE_T len, + void *locale) { + STRXFRM_INTERCEPTOR_IMPL(strxfrm_l, dest, src, len, locale); +} + +#define INIT_STRXFRM \ + COMMON_INTERCEPT_FUNCTION(strxfrm); \ + COMMON_INTERCEPT_FUNCTION(strxfrm_l); +#else +#define INIT_STRXFRM +#endif + +#if SANITIZER_INTERCEPT___STRXFRM_L +INTERCEPTOR(SIZE_T, __strxfrm_l, char *dest, const char *src, SIZE_T len, + void *locale) { + STRXFRM_INTERCEPTOR_IMPL(__strxfrm_l, dest, src, len, locale); +} + +#define INIT___STRXFRM_L COMMON_INTERCEPT_FUNCTION(__strxfrm_l); +#else +#define INIT___STRXFRM_L +#endif + +#if SANITIZER_INTERCEPT_WCSXFRM +INTERCEPTOR(SIZE_T, wcsxfrm, wchar_t *dest, const wchar_t *src, SIZE_T len) { + STRXFRM_INTERCEPTOR_IMPL(wcsxfrm, dest, src, len); +} + +INTERCEPTOR(SIZE_T, wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len, + void *locale) { + STRXFRM_INTERCEPTOR_IMPL(wcsxfrm_l, dest, src, len, locale); +} + +#define INIT_WCSXFRM \ + COMMON_INTERCEPT_FUNCTION(wcsxfrm); \ + COMMON_INTERCEPT_FUNCTION(wcsxfrm_l); +#else +#define INIT_WCSXFRM +#endif + +#if SANITIZER_INTERCEPT___WCSXFRM_L +INTERCEPTOR(SIZE_T, __wcsxfrm_l, wchar_t *dest, const wchar_t *src, SIZE_T len, + void *locale) { + STRXFRM_INTERCEPTOR_IMPL(__wcsxfrm_l, dest, src, len, locale); +} + +#define INIT___WCSXFRM_L COMMON_INTERCEPT_FUNCTION(__wcsxfrm_l); +#else +#define INIT___WCSXFRM_L +#endif + +#if SANITIZER_INTERCEPT_ACCT +INTERCEPTOR(int, acct, const char *file) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, acct, file); + if (file) + COMMON_INTERCEPTOR_READ_RANGE(ctx, file, REAL(strlen)(file) + 1); + return REAL(acct)(file); +} +#define INIT_ACCT COMMON_INTERCEPT_FUNCTION(acct) +#else +#define INIT_ACCT +#endif + +#if SANITIZER_INTERCEPT_USER_FROM_UID +INTERCEPTOR(const char *, user_from_uid, u32 uid, int nouser) { + void *ctx; + const char *user; + COMMON_INTERCEPTOR_ENTER(ctx, user_from_uid, uid, nouser); + user = REAL(user_from_uid)(uid, nouser); + if (user) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, user, REAL(strlen)(user) + 1); + return user; +} +#define INIT_USER_FROM_UID COMMON_INTERCEPT_FUNCTION(user_from_uid) +#else +#define INIT_USER_FROM_UID +#endif + +#if SANITIZER_INTERCEPT_UID_FROM_USER +INTERCEPTOR(int, uid_from_user, const char *name, u32 *uid) { + void *ctx; + int res; + COMMON_INTERCEPTOR_ENTER(ctx, uid_from_user, name, uid); + if (name) + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + res = REAL(uid_from_user)(name, uid); + if (uid) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, uid, sizeof(*uid)); + return res; +} +#define INIT_UID_FROM_USER COMMON_INTERCEPT_FUNCTION(uid_from_user) +#else +#define INIT_UID_FROM_USER +#endif + +#if SANITIZER_INTERCEPT_GROUP_FROM_GID +INTERCEPTOR(const char *, group_from_gid, u32 gid, int nogroup) { + void *ctx; + const char *group; + COMMON_INTERCEPTOR_ENTER(ctx, group_from_gid, gid, nogroup); + group = REAL(group_from_gid)(gid, nogroup); + if (group) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, group, REAL(strlen)(group) + 1); + return group; +} +#define INIT_GROUP_FROM_GID COMMON_INTERCEPT_FUNCTION(group_from_gid) +#else +#define INIT_GROUP_FROM_GID +#endif + +#if SANITIZER_INTERCEPT_GID_FROM_GROUP +INTERCEPTOR(int, gid_from_group, const char *group, u32 *gid) { + void *ctx; + int res; + COMMON_INTERCEPTOR_ENTER(ctx, gid_from_group, group, gid); + if (group) + COMMON_INTERCEPTOR_READ_RANGE(ctx, group, REAL(strlen)(group) + 1); + res = REAL(gid_from_group)(group, gid); + if (gid) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, gid, sizeof(*gid)); + return res; +} +#define INIT_GID_FROM_GROUP COMMON_INTERCEPT_FUNCTION(gid_from_group) +#else +#define INIT_GID_FROM_GROUP +#endif + +#if SANITIZER_INTERCEPT_ACCESS +INTERCEPTOR(int, access, const char *path, int mode) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, access, path, mode); + if (path) + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + return REAL(access)(path, mode); +} +#define INIT_ACCESS COMMON_INTERCEPT_FUNCTION(access) +#else +#define INIT_ACCESS +#endif + +#if SANITIZER_INTERCEPT_FACCESSAT +INTERCEPTOR(int, faccessat, int fd, const char *path, int mode, int flags) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, faccessat, fd, path, mode, flags); + if (path) + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + return REAL(faccessat)(fd, path, mode, flags); +} +#define INIT_FACCESSAT COMMON_INTERCEPT_FUNCTION(faccessat) +#else +#define INIT_FACCESSAT +#endif + +#if SANITIZER_INTERCEPT_GETGROUPLIST +INTERCEPTOR(int, getgrouplist, const char *name, u32 basegid, u32 *groups, + int *ngroups) { + void *ctx; + int res; + COMMON_INTERCEPTOR_ENTER(ctx, getgrouplist, name, basegid, groups, ngroups); + if (name) + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + if (ngroups) + COMMON_INTERCEPTOR_READ_RANGE(ctx, ngroups, sizeof(*ngroups)); + res = REAL(getgrouplist)(name, basegid, groups, ngroups); + if (!res && groups && ngroups) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups)); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups)); + } + return res; +} + +#define INIT_GETGROUPLIST COMMON_INTERCEPT_FUNCTION(getgrouplist); +#else +#define INIT_GETGROUPLIST +#endif + +#if SANITIZER_INTERCEPT_GETGROUPMEMBERSHIP +INTERCEPTOR(int, getgroupmembership, const char *name, u32 basegid, u32 *groups, + int maxgrp, int *ngroups) { + void *ctx; + int res; + COMMON_INTERCEPTOR_ENTER(ctx, getgroupmembership, name, basegid, groups, + maxgrp, ngroups); + if (name) + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + res = REAL(getgroupmembership)(name, basegid, groups, maxgrp, ngroups); + if (!res && groups && ngroups) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, groups, sizeof(*groups) * (*ngroups)); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ngroups, sizeof(*ngroups)); + } + return res; +} + +#define INIT_GETGROUPMEMBERSHIP COMMON_INTERCEPT_FUNCTION(getgroupmembership); +#else +#define INIT_GETGROUPMEMBERSHIP +#endif + +#if SANITIZER_INTERCEPT_READLINK +INTERCEPTOR(SSIZE_T, readlink, const char *path, char *buf, SIZE_T bufsiz) { + void* ctx; + COMMON_INTERCEPTOR_ENTER(ctx, readlink, path, buf, bufsiz); + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + SSIZE_T res = REAL(readlink)(path, buf, bufsiz); + if (res > 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res); + return res; +} + +#define INIT_READLINK COMMON_INTERCEPT_FUNCTION(readlink) +#else +#define INIT_READLINK +#endif + +#if SANITIZER_INTERCEPT_READLINKAT +INTERCEPTOR(SSIZE_T, readlinkat, int dirfd, const char *path, char *buf, + SIZE_T bufsiz) { + void* ctx; + COMMON_INTERCEPTOR_ENTER(ctx, readlinkat, dirfd, path, buf, bufsiz); + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + SSIZE_T res = REAL(readlinkat)(dirfd, path, buf, bufsiz); + if (res > 0) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, res); + return res; +} + +#define INIT_READLINKAT COMMON_INTERCEPT_FUNCTION(readlinkat) +#else +#define INIT_READLINKAT +#endif + +#if SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT +INTERCEPTOR(int, name_to_handle_at, int dirfd, const char *pathname, + struct file_handle *handle, int *mount_id, int flags) { + void* ctx; + COMMON_INTERCEPTOR_ENTER(ctx, name_to_handle_at, dirfd, pathname, handle, + mount_id, flags); + COMMON_INTERCEPTOR_READ_RANGE(ctx, pathname, REAL(strlen)(pathname) + 1); + + __sanitizer_file_handle *sanitizer_handle = + reinterpret_cast<__sanitizer_file_handle*>(handle); + COMMON_INTERCEPTOR_READ_RANGE( + ctx, &sanitizer_handle->handle_bytes, + sizeof(sanitizer_handle->handle_bytes)); + + int res = REAL(name_to_handle_at)(dirfd, pathname, handle, mount_id, flags); + if (!res) { + COMMON_INTERCEPTOR_WRITE_RANGE( + ctx, &sanitizer_handle->handle_bytes, + sizeof(sanitizer_handle->handle_bytes)); + COMMON_INTERCEPTOR_WRITE_RANGE( + ctx, &sanitizer_handle->handle_type, + sizeof(sanitizer_handle->handle_type)); + COMMON_INTERCEPTOR_WRITE_RANGE( + ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, mount_id, sizeof(*mount_id)); + } + return res; +} + +#define INIT_NAME_TO_HANDLE_AT COMMON_INTERCEPT_FUNCTION(name_to_handle_at) +#else +#define INIT_NAME_TO_HANDLE_AT +#endif + +#if SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT +INTERCEPTOR(int, open_by_handle_at, int mount_fd, struct file_handle* handle, + int flags) { + void* ctx; + COMMON_INTERCEPTOR_ENTER(ctx, open_by_handle_at, mount_fd, handle, flags); + + __sanitizer_file_handle *sanitizer_handle = + reinterpret_cast<__sanitizer_file_handle*>(handle); + COMMON_INTERCEPTOR_READ_RANGE( + ctx, &sanitizer_handle->handle_bytes, + sizeof(sanitizer_handle->handle_bytes)); + COMMON_INTERCEPTOR_READ_RANGE( + ctx, &sanitizer_handle->handle_type, + sizeof(sanitizer_handle->handle_type)); + COMMON_INTERCEPTOR_READ_RANGE( + ctx, &sanitizer_handle->f_handle, sanitizer_handle->handle_bytes); + + return REAL(open_by_handle_at)(mount_fd, handle, flags); +} + +#define INIT_OPEN_BY_HANDLE_AT COMMON_INTERCEPT_FUNCTION(open_by_handle_at) +#else +#define INIT_OPEN_BY_HANDLE_AT +#endif + +#if SANITIZER_INTERCEPT_STRLCPY +INTERCEPTOR(SIZE_T, strlcpy, char *dst, char *src, SIZE_T size) { + void *ctx; + SIZE_T res; + COMMON_INTERCEPTOR_ENTER(ctx, strlcpy, dst, src, size); + if (src) { + // Keep strnlen as macro argument, as macro may ignore it. + COMMON_INTERCEPTOR_READ_STRING( + ctx, src, Min(internal_strnlen(src, size), size - 1) + 1); + } + res = REAL(strlcpy)(dst, src, size); + COMMON_INTERCEPTOR_COPY_STRING(ctx, dst, src, REAL(strlen)(dst) + 1); + return res; +} + +INTERCEPTOR(SIZE_T, strlcat, char *dst, char *src, SIZE_T size) { + void *ctx; + SIZE_T len = 0; + COMMON_INTERCEPTOR_ENTER(ctx, strlcat, dst, src, size); + // src is checked in the strlcpy() interceptor + if (dst) { + len = internal_strnlen(dst, size); + COMMON_INTERCEPTOR_READ_STRING(ctx, dst, Min(len, size - 1) + 1); + } + // Reuse the rest of the code in the strlcpy() interceptor + return WRAP(strlcpy)(dst + len, src, size - len) + len; +} +#define INIT_STRLCPY \ + COMMON_INTERCEPT_FUNCTION(strlcpy); \ + COMMON_INTERCEPT_FUNCTION(strlcat); +#else +#define INIT_STRLCPY +#endif + +#if SANITIZER_INTERCEPT_MMAP +INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags, int fd, + OFF_T off) { + void *ctx; + if (common_flags()->detect_write_exec) + ReportMmapWriteExec(prot); + if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) + return (void *)internal_mmap(addr, sz, prot, flags, fd, off); + COMMON_INTERCEPTOR_ENTER(ctx, mmap, addr, sz, prot, flags, fd, off); + COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, off); +} + +INTERCEPTOR(int, mprotect, void *addr, SIZE_T sz, int prot) { + void *ctx; + if (common_flags()->detect_write_exec) + ReportMmapWriteExec(prot); + if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) + return (int)internal_mprotect(addr, sz, prot); + COMMON_INTERCEPTOR_ENTER(ctx, mprotect, addr, sz, prot); + MprotectMallocZones(addr, prot); + return REAL(mprotect)(addr, sz, prot); +} +#define INIT_MMAP \ + COMMON_INTERCEPT_FUNCTION(mmap); \ + COMMON_INTERCEPT_FUNCTION(mprotect); +#else +#define INIT_MMAP +#endif + +#if SANITIZER_INTERCEPT_MMAP64 +INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, int fd, + OFF64_T off) { + void *ctx; + if (common_flags()->detect_write_exec) + ReportMmapWriteExec(prot); + if (COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED) + return (void *)internal_mmap(addr, sz, prot, flags, fd, off); + COMMON_INTERCEPTOR_ENTER(ctx, mmap64, addr, sz, prot, flags, fd, off); + COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap64, addr, sz, prot, flags, fd, off); +} +#define INIT_MMAP64 COMMON_INTERCEPT_FUNCTION(mmap64); +#else +#define INIT_MMAP64 +#endif + +#if SANITIZER_INTERCEPT_DEVNAME +INTERCEPTOR(char *, devname, u64 dev, u32 type) { + void *ctx; + char *name; + COMMON_INTERCEPTOR_ENTER(ctx, devname, dev, type); + name = REAL(devname)(dev, type); + if (name) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, name, REAL(strlen)(name) + 1); + return name; +} +#define INIT_DEVNAME COMMON_INTERCEPT_FUNCTION(devname); +#else +#define INIT_DEVNAME +#endif + +#if SANITIZER_INTERCEPT_DEVNAME_R +INTERCEPTOR(int, 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) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, path, REAL(strlen)(path) + 1); + return res; +} +#define INIT_DEVNAME_R COMMON_INTERCEPT_FUNCTION(devname_r); +#else +#define INIT_DEVNAME_R +#endif + +#if SANITIZER_INTERCEPT_FGETLN +INTERCEPTOR(char *, fgetln, __sanitizer_FILE *stream, SIZE_T *len) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, fgetln, stream, len); + char *str = REAL(fgetln)(stream, len); + if (str && len) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, len, sizeof(*len)); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, str, *len); + } + return str; +} +#define INIT_FGETLN COMMON_INTERCEPT_FUNCTION(fgetln) +#else +#define INIT_FGETLN +#endif + +#if SANITIZER_INTERCEPT_STRMODE +INTERCEPTOR(void, strmode, u32 mode, char *bp) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, strmode, mode, bp); + REAL(strmode)(mode, bp); + if (bp) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, bp, REAL(strlen)(bp) + 1); +} +#define INIT_STRMODE COMMON_INTERCEPT_FUNCTION(strmode) +#else +#define INIT_STRMODE +#endif + +#if SANITIZER_INTERCEPT_TTYENT +INTERCEPTOR(struct __sanitizer_ttyent *, getttyent, void) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getttyent); + struct __sanitizer_ttyent *ttyent = REAL(getttyent)(); + if (ttyent) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz); + return ttyent; +} +INTERCEPTOR(struct __sanitizer_ttyent *, getttynam, char *name) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getttynam, name); + if (name) + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + struct __sanitizer_ttyent *ttyent = REAL(getttynam)(name); + if (ttyent) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ttyent, struct_ttyent_sz); + return ttyent; +} +INTERCEPTOR(int, setttyentpath, char *path) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, setttyentpath, path); + if (path) + COMMON_INTERCEPTOR_READ_RANGE(ctx, path, REAL(strlen)(path) + 1); + return REAL(setttyentpath)(path); +} +#define INIT_TTYENT \ + COMMON_INTERCEPT_FUNCTION(getttyent); \ + COMMON_INTERCEPT_FUNCTION(getttynam); \ + COMMON_INTERCEPT_FUNCTION(setttyentpath) +#else +#define INIT_TTYENT +#endif + +#if SANITIZER_INTERCEPT_PROTOENT +INTERCEPTOR(struct __sanitizer_protoent *, getprotoent) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getprotoent); + struct __sanitizer_protoent *p = REAL(getprotoent)(); + if (p) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); + + SIZE_T pp_size = 1; // One handles the trailing \0 + + for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, + pp_size * sizeof(char **)); + } + return p; +} + +INTERCEPTOR(struct __sanitizer_protoent *, getprotobyname, const char *name) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getprotobyname, name); + if (name) + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + struct __sanitizer_protoent *p = REAL(getprotobyname)(name); + if (p) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); + + SIZE_T pp_size = 1; // One handles the trailing \0 + + for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, + pp_size * sizeof(char **)); + } + return p; +} + +INTERCEPTOR(struct __sanitizer_protoent *, getprotobynumber, int proto) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getprotobynumber, proto); + struct __sanitizer_protoent *p = REAL(getprotobynumber)(proto); + if (p) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p, sizeof(*p)); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_name, REAL(strlen)(p->p_name) + 1); + + SIZE_T pp_size = 1; // One handles the trailing \0 + + for (char **pp = p->p_aliases; *pp; ++pp, ++pp_size) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *pp, REAL(strlen)(*pp) + 1); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, p->p_aliases, + pp_size * sizeof(char **)); + } + return p; +} +#define INIT_PROTOENT \ + COMMON_INTERCEPT_FUNCTION(getprotoent); \ + COMMON_INTERCEPT_FUNCTION(getprotobyname); \ + COMMON_INTERCEPT_FUNCTION(getprotobynumber) +#else +#define INIT_PROTOENT +#endif + +#if SANITIZER_INTERCEPT_NETENT +INTERCEPTOR(struct __sanitizer_netent *, getnetent) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getnetent); + struct __sanitizer_netent *n = REAL(getnetent)(); + if (n) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); + + SIZE_T nn_size = 1; // One handles the trailing \0 + + for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, + nn_size * sizeof(char **)); + } + return n; +} + +INTERCEPTOR(struct __sanitizer_netent *, getnetbyname, const char *name) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getnetbyname, name); + if (name) + COMMON_INTERCEPTOR_READ_RANGE(ctx, name, REAL(strlen)(name) + 1); + struct __sanitizer_netent *n = REAL(getnetbyname)(name); + if (n) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); + + SIZE_T nn_size = 1; // One handles the trailing \0 + + for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, + nn_size * sizeof(char **)); + } + return n; +} + +INTERCEPTOR(struct __sanitizer_netent *, getnetbyaddr, u32 net, int type) { + void *ctx; + COMMON_INTERCEPTOR_ENTER(ctx, getnetbyaddr, net, type); + struct __sanitizer_netent *n = REAL(getnetbyaddr)(net, type); + if (n) { + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n, sizeof(*n)); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_name, REAL(strlen)(n->n_name) + 1); + + SIZE_T nn_size = 1; // One handles the trailing \0 + + for (char **nn = n->n_aliases; *nn; ++nn, ++nn_size) + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, *nn, REAL(strlen)(*nn) + 1); + + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, n->n_aliases, + nn_size * sizeof(char **)); + } + return n; +} +#define INIT_NETENT \ + COMMON_INTERCEPT_FUNCTION(getnetent); \ + COMMON_INTERCEPT_FUNCTION(getnetbyname); \ + COMMON_INTERCEPT_FUNCTION(getnetbyaddr) +#else +#define INIT_NETENT +#endif + static void InitializeCommonInterceptors() { static u64 metadata_mem[sizeof(MetadataHashMap) / sizeof(u64) + 1]; interceptor_metadata_map = new((void *)&metadata_mem) MetadataHashMap(); + INIT_MMAP; + INIT_MMAP64; INIT_TEXTDOMAIN; INIT_STRLEN; INIT_STRNLEN; @@ -6273,6 +7256,8 @@ static void InitializeCommonInterceptors() { INIT_STRSPN; INIT_STRTOK; INIT_STRPBRK; + INIT_STRXFRM; + INIT___STRXFRM_L; INIT_MEMSET; INIT_MEMMOVE; INIT_MEMCPY; @@ -6294,6 +7279,9 @@ static void InitializeCommonInterceptors() { INIT_WRITEV; INIT_PWRITEV; INIT_PWRITEV64; + INIT_FGETS; + INIT_FPUTS; + INIT_PUTS; INIT_PRCTL; INIT_LOCALTIME_AND_FRIENDS; INIT_STRPTIME; @@ -6314,6 +7302,7 @@ static void InitializeCommonInterceptors() { INIT_GETITIMER; INIT_TIME; INIT_GLOB; + INIT_GLOB64; INIT_WAIT; INIT_WAIT4; INIT_INET; @@ -6322,6 +7311,7 @@ static void InitializeCommonInterceptors() { INIT_GETNAMEINFO; INIT_GETSOCKNAME; INIT_GETHOSTBYNAME; + INIT_GETHOSTBYNAME2; INIT_GETHOSTBYNAME_R; INIT_GETHOSTBYNAME2_R; INIT_GETHOSTBYADDR_R; @@ -6329,9 +7319,12 @@ static void InitializeCommonInterceptors() { INIT_GETSOCKOPT; INIT_ACCEPT; INIT_ACCEPT4; + INIT_PACCEPT; INIT_MODF; INIT_RECVMSG; INIT_SENDMSG; + INIT_RECVMMSG; + INIT_SENDMMSG; INIT_GETPEERNAME; INIT_IOCTL; INIT_INET_ATON; @@ -6373,6 +7366,11 @@ static void InitializeCommonInterceptors() { INIT__EXIT; INIT_PTHREAD_MUTEX_LOCK; INIT_PTHREAD_MUTEX_UNLOCK; + INIT___PTHREAD_MUTEX_LOCK; + INIT___PTHREAD_MUTEX_UNLOCK; + INIT___LIBC_MUTEX_LOCK; + INIT___LIBC_MUTEX_UNLOCK; + INIT___LIBC_THR_SETCANCELSTATE; INIT_GETMNTENT; INIT_GETMNTENT_R; INIT_STATFS; @@ -6386,6 +7384,7 @@ static void InitializeCommonInterceptors() { INIT_SHMCTL; INIT_RANDOM_R; INIT_PTHREAD_ATTR_GET; + INIT_PTHREAD_ATTR_GET_SCHED; INIT_PTHREAD_ATTR_GETINHERITSCHED; INIT_PTHREAD_ATTR_GETAFFINITY_NP; INIT_PTHREAD_MUTEXATTR_GETPSHARED; @@ -6404,6 +7403,7 @@ static void InitializeCommonInterceptors() { INIT_TTYNAME_R; INIT_TEMPNAM; INIT_PTHREAD_SETNAME_NP; + INIT_PTHREAD_GETNAME_NP; INIT_SINCOS; INIT_REMQUO; INIT_LGAMMA; @@ -6448,6 +7448,7 @@ static void InitializeCommonInterceptors() { INIT_SEND_SENDTO; INIT_STAT; INIT_EVENTFD_READ_WRITE; + INIT_LSTAT; INIT___XSTAT; INIT___XSTAT64; INIT___LXSTAT; @@ -6458,4 +7459,29 @@ static void InitializeCommonInterceptors() { INIT_GETLOADAVG; INIT_WCSLEN; INIT_WCSCAT; + INIT_WCSXFRM; + INIT___WCSXFRM_L; + INIT_ACCT; + INIT_USER_FROM_UID; + INIT_UID_FROM_USER; + INIT_GROUP_FROM_GID; + INIT_GID_FROM_GROUP; + INIT_ACCESS; + INIT_FACCESSAT; + INIT_GETGROUPLIST; + INIT_GETGROUPMEMBERSHIP; + INIT_READLINK; + INIT_READLINKAT; + INIT_NAME_TO_HANDLE_AT; + INIT_OPEN_BY_HANDLE_AT; + INIT_STRLCPY; + INIT_DEVNAME; + INIT_DEVNAME_R; + INIT_FGETLN; + INIT_STRMODE; + INIT_TTYENT; + INIT_PROTOENT; + INIT_NETENT; + + INIT___PRINTF_CHK; } diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_ioctl.inc b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_ioctl.inc index a68534c5a0a..5408ea17c59 100755 --- a/libsanitizer/sanitizer_common/sanitizer_common_interceptors_ioctl.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_interceptors_ioctl.inc @@ -8,6 +8,8 @@ // Ioctl handling in common sanitizer interceptors. //===----------------------------------------------------------------------===// +#if !SANITIZER_NETBSD + #include "sanitizer_flags.h" struct ioctl_desc { @@ -55,7 +57,9 @@ static void ioctl_table_fill() { _(SIOCGIFCONF, CUSTOM, 0); _(SIOCGPGRP, WRITE, sizeof(int)); _(SIOCSPGRP, READ, sizeof(int)); +#if !SANITIZER_SOLARIS _(TIOCCONS, NONE, 0); +#endif _(TIOCEXCL, NONE, 0); _(TIOCGETD, WRITE, sizeof(int)); _(TIOCGPGRP, WRITE, pid_t_sz); @@ -474,7 +478,7 @@ struct ioctl_desc_compare { static void ioctl_init() { ioctl_table_fill(); - InternalSort(&ioctl_table, ioctl_table_size, ioctl_desc_compare()); + Sort(ioctl_table, ioctl_table_size, ioctl_desc_compare()); bool bad = false; for (unsigned i = 0; i < ioctl_table_size - 1; ++i) { @@ -600,3 +604,5 @@ static void ioctl_common_post(void *ctx, const ioctl_desc *desc, int res, int d, COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifc->ifc_ifcu.ifcu_req, ifc->ifc_len); } } + +#endif diff --git a/libsanitizer/sanitizer_common/sanitizer_common_interface.inc b/libsanitizer/sanitizer_common/sanitizer_common_interface.inc index bd296f6dece..89d47bda7df 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_interface.inc +++ b/libsanitizer/sanitizer_common/sanitizer_common_interface.inc @@ -6,6 +6,7 @@ //===----------------------------------------------------------------------===// // Sanitizer Common interface list. //===----------------------------------------------------------------------===// +INTERFACE_FUNCTION(__sanitizer_acquire_crash_state) INTERFACE_FUNCTION(__sanitizer_annotate_contiguous_container) INTERFACE_FUNCTION(__sanitizer_contiguous_container_find_bad_address) INTERFACE_FUNCTION(__sanitizer_set_death_callback) @@ -32,6 +33,7 @@ INTERFACE_FUNCTION(__sanitizer_get_heap_size) INTERFACE_FUNCTION(__sanitizer_get_ownership) INTERFACE_FUNCTION(__sanitizer_get_unmapped_bytes) INTERFACE_FUNCTION(__sanitizer_install_malloc_and_free_hooks) +INTERFACE_FUNCTION(__sanitizer_purge_allocator) INTERFACE_FUNCTION(__sanitizer_print_memory_profile) INTERFACE_WEAK_FUNCTION(__sanitizer_free_hook) INTERFACE_WEAK_FUNCTION(__sanitizer_malloc_hook) diff --git a/libsanitizer/sanitizer_common/sanitizer_common_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_common_libcdep.cc index a3f35319e23..6a63650c81b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_common_libcdep.cc @@ -9,76 +9,14 @@ // run-time libraries. //===----------------------------------------------------------------------===// -#include "sanitizer_common.h" - #include "sanitizer_allocator_interface.h" -#include "sanitizer_file.h" +#include "sanitizer_common.h" #include "sanitizer_flags.h" #include "sanitizer_procmaps.h" -#include "sanitizer_report_decorator.h" -#include "sanitizer_stackdepot.h" -#include "sanitizer_stacktrace.h" -#include "sanitizer_symbolizer.h" -#if SANITIZER_POSIX -#include "sanitizer_posix.h" -#endif namespace __sanitizer { -#if !SANITIZER_FUCHSIA - -bool ReportFile::SupportsColors() { - SpinMutexLock l(mu); - ReopenIfNecessary(); - return SupportsColoredOutput(fd); -} - -static INLINE bool ReportSupportsColors() { - return report_file.SupportsColors(); -} - -#else // SANITIZER_FUCHSIA - -// Fuchsia's logs always go through post-processing that handles colorization. -static INLINE bool ReportSupportsColors() { return true; } - -#endif // !SANITIZER_FUCHSIA - -bool ColorizeReports() { - // FIXME: Add proper Windows support to AnsiColorDecorator and re-enable color - // printing on Windows. - if (SANITIZER_WINDOWS) - return false; - - const char *flag = common_flags()->color; - return internal_strcmp(flag, "always") == 0 || - (internal_strcmp(flag, "auto") == 0 && ReportSupportsColors()); -} - -static void (*sandboxing_callback)(); -void SetSandboxingCallback(void (*f)()) { - sandboxing_callback = f; -} - -void ReportErrorSummary(const char *error_type, const StackTrace *stack, - const char *alt_tool_name) { -#if !SANITIZER_GO - if (!common_flags()->print_summary) - return; - if (stack->size == 0) { - ReportErrorSummary(error_type); - return; - } - // Currently, we include the first stack frame into the report summary. - // Maybe sometimes we need to choose another frame (e.g. skip memcpy/etc). - uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]); - SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc); - ReportErrorSummary(error_type, frame->info, alt_tool_name); - frame->ClearAll(); -#endif -} - static void (*SoftRssLimitExceededCallback)(bool exceeded); void SetSoftRssLimitExceededCallback(void (*Callback)(bool exceeded)) { CHECK_EQ(SoftRssLimitExceededCallback, nullptr); @@ -86,17 +24,22 @@ void SetSoftRssLimitExceededCallback(void (*Callback)(bool exceeded)) { } #if SANITIZER_LINUX && !SANITIZER_GO +// Weak default implementation for when sanitizer_stackdepot is not linked in. +SANITIZER_WEAK_ATTRIBUTE StackDepotStats *StackDepotGetStats() { + return nullptr; +} + void BackgroundThread(void *arg) { - uptr hard_rss_limit_mb = common_flags()->hard_rss_limit_mb; - uptr soft_rss_limit_mb = common_flags()->soft_rss_limit_mb; - bool heap_profile = common_flags()->heap_profile; + const uptr hard_rss_limit_mb = common_flags()->hard_rss_limit_mb; + const uptr soft_rss_limit_mb = common_flags()->soft_rss_limit_mb; + const bool heap_profile = common_flags()->heap_profile; uptr prev_reported_rss = 0; uptr prev_reported_stack_depot_size = 0; bool reached_soft_rss_limit = false; uptr rss_during_last_reported_profile = 0; while (true) { SleepForMillis(100); - uptr current_rss_mb = GetRSS() >> 20; + const uptr current_rss_mb = GetRSS() >> 20; if (Verbosity()) { // If RSS has grown 10% since last time, print some information. if (prev_reported_rss * 11 / 10 < current_rss_mb) { @@ -105,13 +48,15 @@ void BackgroundThread(void *arg) { } // If stack depot has grown 10% since last time, print it too. StackDepotStats *stack_depot_stats = StackDepotGetStats(); - if (prev_reported_stack_depot_size * 11 / 10 < - stack_depot_stats->allocated) { - Printf("%s: StackDepot: %zd ids; %zdM allocated\n", - SanitizerToolName, - stack_depot_stats->n_uniq_ids, - stack_depot_stats->allocated >> 20); - prev_reported_stack_depot_size = stack_depot_stats->allocated; + if (stack_depot_stats) { + if (prev_reported_stack_depot_size * 11 / 10 < + stack_depot_stats->allocated) { + Printf("%s: StackDepot: %zd ids; %zdM allocated\n", + SanitizerToolName, + stack_depot_stats->n_uniq_ids, + stack_depot_stats->allocated >> 20); + prev_reported_stack_depot_size = stack_depot_stats->allocated; + } } } // Check RSS against the limit. @@ -145,127 +90,6 @@ void BackgroundThread(void *arg) { } #endif -#if !SANITIZER_FUCHSIA && !SANITIZER_GO -void StartReportDeadlySignal() { - // Write the first message using fd=2, just in case. - // It may actually fail to write in case stderr is closed. - CatastrophicErrorWrite(SanitizerToolName, internal_strlen(SanitizerToolName)); - static const char kDeadlySignal[] = ":DEADLYSIGNAL\n"; - CatastrophicErrorWrite(kDeadlySignal, sizeof(kDeadlySignal) - 1); -} - -static void MaybeReportNonExecRegion(uptr pc) { -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD - MemoryMappingLayout proc_maps(/*cache_enabled*/ true); - MemoryMappedSegment segment; - while (proc_maps.Next(&segment)) { - if (pc >= segment.start && pc < segment.end && !segment.IsExecutable()) - Report("Hint: PC is at a non-executable region. Maybe a wild jump?\n"); - } -#endif -} - -static void PrintMemoryByte(InternalScopedString *str, const char *before, - u8 byte) { - SanitizerCommonDecorator d; - str->append("%s%s%x%x%s ", before, d.MemoryByte(), byte >> 4, byte & 15, - d.Default()); -} - -static void MaybeDumpInstructionBytes(uptr pc) { - if (!common_flags()->dump_instruction_bytes || (pc < GetPageSizeCached())) - return; - InternalScopedString str(1024); - str.append("First 16 instruction bytes at pc: "); - if (IsAccessibleMemoryRange(pc, 16)) { - for (int i = 0; i < 16; ++i) { - PrintMemoryByte(&str, "", ((u8 *)pc)[i]); - } - str.append("\n"); - } else { - str.append("unaccessible\n"); - } - Report("%s", str.data()); -} - -static void MaybeDumpRegisters(void *context) { - if (!common_flags()->dump_registers) return; - SignalContext::DumpAllRegisters(context); -} - -static void ReportStackOverflowImpl(const SignalContext &sig, u32 tid, - UnwindSignalStackCallbackType unwind, - const void *unwind_context) { - SanitizerCommonDecorator d; - Printf("%s", d.Warning()); - static const char kDescription[] = "stack-overflow"; - Report("ERROR: %s: %s on address %p (pc %p bp %p sp %p T%d)\n", - SanitizerToolName, kDescription, (void *)sig.addr, (void *)sig.pc, - (void *)sig.bp, (void *)sig.sp, tid); - Printf("%s", d.Default()); - InternalScopedBuffer stack_buffer(1); - BufferedStackTrace *stack = stack_buffer.data(); - stack->Reset(); - unwind(sig, unwind_context, stack); - stack->Print(); - ReportErrorSummary(kDescription, stack); -} - -static void ReportDeadlySignalImpl(const SignalContext &sig, u32 tid, - UnwindSignalStackCallbackType unwind, - const void *unwind_context) { - SanitizerCommonDecorator d; - Printf("%s", d.Warning()); - const char *description = sig.Describe(); - Report("ERROR: %s: %s on unknown address %p (pc %p bp %p sp %p T%d)\n", - SanitizerToolName, description, (void *)sig.addr, (void *)sig.pc, - (void *)sig.bp, (void *)sig.sp, tid); - Printf("%s", d.Default()); - if (sig.pc < GetPageSizeCached()) - Report("Hint: pc points to the zero page.\n"); - if (sig.is_memory_access) { - const char *access_type = - sig.write_flag == SignalContext::WRITE - ? "WRITE" - : (sig.write_flag == SignalContext::READ ? "READ" : "UNKNOWN"); - Report("The signal is caused by a %s memory access.\n", access_type); - if (sig.addr < GetPageSizeCached()) - Report("Hint: address points to the zero page.\n"); - } - MaybeReportNonExecRegion(sig.pc); - InternalScopedBuffer stack_buffer(1); - BufferedStackTrace *stack = stack_buffer.data(); - stack->Reset(); - unwind(sig, unwind_context, stack); - stack->Print(); - MaybeDumpInstructionBytes(sig.pc); - MaybeDumpRegisters(sig.context); - Printf("%s can not provide additional info.\n", SanitizerToolName); - ReportErrorSummary(description, stack); -} - -void ReportDeadlySignal(const SignalContext &sig, u32 tid, - UnwindSignalStackCallbackType unwind, - const void *unwind_context) { - if (sig.IsStackOverflow()) - ReportStackOverflowImpl(sig, tid, unwind, unwind_context); - else - ReportDeadlySignalImpl(sig, tid, unwind, unwind_context); -} - -void HandleDeadlySignal(void *siginfo, void *context, u32 tid, - UnwindSignalStackCallbackType unwind, - const void *unwind_context) { - StartReportDeadlySignal(); - ScopedErrorReportLock rl; - SignalContext sig(siginfo, context); - ReportDeadlySignal(sig, tid, unwind, unwind_context); - Report("ABORTING\n"); - Die(); -} - -#endif // !SANITIZER_FUCHSIA && !SANITIZER_GO - void WriteToSyslog(const char *msg) { InternalScopedString msg_copy(kErrorMessageBufferSize); msg_copy.append("%s", msg); @@ -274,14 +98,17 @@ void WriteToSyslog(const char *msg) { // Print one line at a time. // syslog, at least on Android, has an implicit message length limit. - do { - q = internal_strchr(p, '\n'); - if (q) - *q = '\0'; + while ((q = internal_strchr(p, '\n'))) { + *q = '\0'; + WriteOneLineToSyslog(p); + p = q + 1; + } + // Print remaining characters, if there are any. + // Note that this will add an extra newline at the end. + // FIXME: buffer extra output. This would need a thread-local buffer, which + // on Android requires plugging into the tools (ex. ASan's) Thread class. + if (*p) WriteOneLineToSyslog(p); - if (q) - p = q + 1; - } while (q); } void MaybeStartBackgroudThread() { @@ -296,51 +123,16 @@ void MaybeStartBackgroudThread() { #endif } -static atomic_uintptr_t reporting_thread = {0}; - -ScopedErrorReportLock::ScopedErrorReportLock() { - uptr current = GetThreadSelf(); - for (;;) { - uptr expected = 0; - if (atomic_compare_exchange_strong(&reporting_thread, &expected, current, - memory_order_relaxed)) { - // We've claimed reporting_thread so proceed. - CommonSanitizerReportMutex.Lock(); - return; - } - - if (expected == current) { - // This is either asynch signal or nested error during error reporting. - // Fail simple to avoid deadlocks in Report(). - - // Can't use Report() here because of potential deadlocks in nested - // signal handlers. - CatastrophicErrorWrite(SanitizerToolName, - internal_strlen(SanitizerToolName)); - static const char msg[] = ": nested bug in the same thread, aborting.\n"; - CatastrophicErrorWrite(msg, sizeof(msg) - 1); - - internal__exit(common_flags()->exitcode); - } - - internal_sched_yield(); - } -} - -ScopedErrorReportLock::~ScopedErrorReportLock() { - CommonSanitizerReportMutex.Unlock(); - atomic_store_relaxed(&reporting_thread, 0); -} - -void ScopedErrorReportLock::CheckLocked() { - CommonSanitizerReportMutex.CheckLocked(); +static void (*sandboxing_callback)(); +void SetSandboxingCallback(void (*f)()) { + sandboxing_callback = f; } } // namespace __sanitizer SANITIZER_INTERFACE_WEAK_DEF(void, __sanitizer_sandbox_on_notify, __sanitizer_sandbox_arguments *args) { - __sanitizer::PrepareForSandboxing(args); + __sanitizer::PlatformPrepareForSandboxing(args); if (__sanitizer::sandboxing_callback) __sanitizer::sandboxing_callback(); } diff --git a/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cc b/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cc index 7397a011098..7f92bdcec24 100644 --- a/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cc +++ b/libsanitizer/sanitizer_common/sanitizer_common_nolibc.cc @@ -19,7 +19,6 @@ namespace __sanitizer { // bypassing libc. #if !SANITIZER_WINDOWS #if SANITIZER_LINUX -bool ShouldLogAfterPrintf() { return false; } void LogMessageOnPrintf(const char *str) {} #endif void WriteToSyslog(const char *buffer) {} diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cc b/libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cc index 7f294512e9a..8426aad432a 100644 --- a/libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cc +++ b/libsanitizer/sanitizer_common/sanitizer_coverage_fuchsia.cc @@ -1,9 +1,9 @@ -//===-- sanitizer_coverage_fuchsia.cc ------------------------------------===// +//===-- sanitizer_coverage_fuchsia.cc -------------------------------------===// // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // // Sanitizer Coverage Controller for Trace PC Guard, Fuchsia-specific version. // @@ -47,7 +47,7 @@ constexpr const char kSancovSinkName[] = "sancov"; // Collects trace-pc guard coverage. // This class relies on zero-initialization. -class TracePcGuardController { +class TracePcGuardController final { public: // For each PC location being tracked, there is a u32 reserved in global // data called the "guard". At startup, we assign each guard slot a @@ -111,11 +111,11 @@ class TracePcGuardController { // We can always spare the 32G of address space. static constexpr size_t MappingSize = sizeof(uptr) << 32; - BlockingMutex setup_lock_; - uptr *array_; - u32 next_index_; - zx_handle_t vmo_; - char vmo_name_[ZX_MAX_NAME_LEN]; + BlockingMutex setup_lock_ = BlockingMutex(LINKER_INITIALIZED); + uptr *array_ = nullptr; + u32 next_index_ = 0; + zx_handle_t vmo_ = {}; + char vmo_name_[ZX_MAX_NAME_LEN] = {}; size_t DataSize() const { return next_index_ * sizeof(uintptr_t); } @@ -145,8 +145,8 @@ class TracePcGuardController { // any multi-thread synchronization issues with that. uintptr_t mapping; status = - _zx_vmar_map(_zx_vmar_root_self(), 0, vmo_, 0, MappingSize, - ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE, &mapping); + _zx_vmar_map(_zx_vmar_root_self(), ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, + 0, vmo_, 0, MappingSize, &mapping); CHECK_EQ(status, ZX_OK); // Hereafter other threads are free to start storing into diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cc b/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cc index 25a5001bd3e..84db6474ab5 100644 --- a/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cc +++ b/libsanitizer/sanitizer_common/sanitizer_coverage_libcdep_new.cc @@ -14,7 +14,6 @@ #include "sanitizer_atomic.h" #include "sanitizer_common.h" #include "sanitizer_file.h" -#include "sanitizer_symbolizer.h" using namespace __sanitizer; @@ -62,7 +61,7 @@ static void SanitizerDumpCoverage(const uptr* unsorted_pcs, uptr len) { uptr* pcs = static_cast(InternalAlloc(len * sizeof(uptr))); internal_memcpy(pcs, unsorted_pcs, len * sizeof(uptr)); - SortArray(pcs, len); + Sort(pcs, len); bool module_found = false; uptr last_base = 0; diff --git a/libsanitizer/sanitizer_common/sanitizer_coverage_win_sections.cc b/libsanitizer/sanitizer_common/sanitizer_coverage_win_sections.cc index 485dd45e14b..12832fcc90e 100644 --- a/libsanitizer/sanitizer_common/sanitizer_coverage_win_sections.cc +++ b/libsanitizer/sanitizer_common/sanitizer_coverage_win_sections.cc @@ -5,16 +5,57 @@ // //===----------------------------------------------------------------------===// // -// This file defines delimiters for Sanitizer Coverage's section. +// This file defines delimiters for Sanitizer Coverage's section. It contains +// Windows specific tricks to coax the linker into giving us the start and stop +// addresses of a section, as ELF linkers can do, to get the size of certain +// arrays. According to https://msdn.microsoft.com/en-us/library/7977wcck.aspx +// sections with the same name before "$" are sorted alphabetically by the +// string that comes after "$" and merged into one section. We take advantage +// of this by putting data we want the size of into the middle (M) of a section, +// by using the letter "M" after "$". We get the start of this data (ie: +// __start_section_name) by making the start variable come at the start of the +// section (using the letter A after "$"). We do the same to get the end of the +// data by using the letter "Z" after "$" to make the end variable come after +// the data. Note that because of our technique the address of the start +// variable is actually the address of data that comes before our middle +// section. We also need to prevent the linker from adding any padding. Each +// technique we use for this is explained in the comments below. //===----------------------------------------------------------------------===// #include "sanitizer_platform.h" #if SANITIZER_WINDOWS #include -#pragma section(".SCOV$A", read, write) // NOLINT -#pragma section(".SCOV$Z", read, write) // NOLINT extern "C" { -__declspec(allocate(".SCOV$A")) uint32_t __start___sancov_guards = 0; -__declspec(allocate(".SCOV$Z")) uint32_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 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; + +#pragma section(".SCOV$CA", read, write) // NOLINT +__declspec(allocate(".SCOV$CA")) __declspec(align(1)) uint64_t + __start___sancov_cntrs = 0; +#pragma section(".SCOV$CZ", read, write) // NOLINT +__declspec(allocate(".SCOV$CZ")) __declspec(align(1)) uint64_t + __stop___sancov_cntrs = 0; + +#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; +#pragma section(".SCOVP$Z", read) // NOLINT +__declspec(allocate(".SCOVP$Z")) __declspec(align(1)) uint64_t + __stop___sancov_pcs = 0; + +#pragma comment(linker, "/MERGE:.SCOVP=.rdata") } -#endif // SANITIZER_WINDOWS +#endif // SANITIZER_WINDOWS diff --git a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cc b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cc index bc96ad230db..fb4785317f0 100644 --- a/libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cc +++ b/libsanitizer/sanitizer_common/sanitizer_deadlock_detector2.cc @@ -109,7 +109,7 @@ struct DD : public DDetector { SpinMutex mtx; InternalMmapVector free_id; - int id_gen; + int id_gen = 0; }; DDetector *DDetector::Create(const DDFlags *flags) { @@ -118,11 +118,7 @@ DDetector *DDetector::Create(const DDFlags *flags) { return new(mem) DD(flags); } -DD::DD(const DDFlags *flags) - : flags(*flags) - , free_id(1024) { - id_gen = 0; -} +DD::DD(const DDFlags *flags) : flags(*flags) { free_id.reserve(1024); } DDPhysicalThread* DD::CreatePhysicalThread() { DDPhysicalThread *pt = (DDPhysicalThread*)MmapOrDie(sizeof(DDPhysicalThread), diff --git a/libsanitizer/sanitizer_common/sanitizer_errno.h b/libsanitizer/sanitizer_common/sanitizer_errno.h index e9fc00f6c2a..d67cc24da1a 100644 --- a/libsanitizer/sanitizer_common/sanitizer_errno.h +++ b/libsanitizer/sanitizer_common/sanitizer_errno.h @@ -22,8 +22,11 @@ #if SANITIZER_FREEBSD || SANITIZER_MAC # define __errno_location __error -#elif SANITIZER_ANDROID || SANITIZER_NETBSD +#elif SANITIZER_ANDROID || SANITIZER_NETBSD || SANITIZER_OPENBSD || \ + SANITIZER_RTEMS # define __errno_location __errno +#elif SANITIZER_SOLARIS +# define __errno_location ___errno #elif SANITIZER_WINDOWS # define __errno_location _errno #endif diff --git a/libsanitizer/sanitizer_common/sanitizer_file.cc b/libsanitizer/sanitizer_common/sanitizer_file.cc index 8740dbb5b6f..61fcc9f90d7 100644 --- a/libsanitizer/sanitizer_common/sanitizer_file.cc +++ b/libsanitizer/sanitizer_common/sanitizer_file.cc @@ -93,32 +93,40 @@ void ReportFile::SetReportPath(const char *path) { bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size, uptr *read_len, uptr max_len, error_t *errno_p) { - uptr PageSize = GetPageSizeCached(); - uptr kMinFileLen = PageSize; *buff = nullptr; *buff_size = 0; *read_len = 0; + if (!max_len) + return true; + uptr PageSize = GetPageSizeCached(); + uptr kMinFileLen = Min(PageSize, max_len); + // The files we usually open are not seekable, so try different buffer sizes. - for (uptr size = kMinFileLen; size <= max_len; size *= 2) { - fd_t fd = OpenFile(file_name, RdOnly, errno_p); - if (fd == kInvalidFd) return false; + for (uptr size = kMinFileLen;; size = Min(size * 2, max_len)) { UnmapOrDie(*buff, *buff_size); *buff = (char*)MmapOrDie(size, __func__); *buff_size = size; + fd_t fd = OpenFile(file_name, RdOnly, errno_p); + if (fd == kInvalidFd) { + UnmapOrDie(*buff, *buff_size); + return false; + } *read_len = 0; // Read up to one page at a time. bool reached_eof = false; - while (*read_len + PageSize <= size) { + while (*read_len < size) { uptr just_read; - if (!ReadFromFile(fd, *buff + *read_len, PageSize, &just_read, errno_p)) { + if (!ReadFromFile(fd, *buff + *read_len, size - *read_len, &just_read, + errno_p)) { UnmapOrDie(*buff, *buff_size); + CloseFile(fd); return false; } - if (just_read == 0) { + *read_len += just_read; + if (just_read == 0 || *read_len == max_len) { reached_eof = true; break; } - *read_len += just_read; } CloseFile(fd); if (reached_eof) // We've read the whole file. @@ -127,6 +135,37 @@ bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size, return true; } +bool ReadFileToVector(const char *file_name, + InternalMmapVectorNoCtor *buff, uptr max_len, + error_t *errno_p) { + buff->clear(); + if (!max_len) + return true; + uptr PageSize = GetPageSizeCached(); + fd_t fd = OpenFile(file_name, RdOnly, errno_p); + if (fd == kInvalidFd) + return false; + uptr read_len = 0; + while (read_len < max_len) { + if (read_len >= buff->size()) + buff->resize(Min(Max(PageSize, read_len * 2), max_len)); + CHECK_LT(read_len, buff->size()); + CHECK_LE(buff->size(), max_len); + uptr just_read; + if (!ReadFromFile(fd, buff->data() + read_len, buff->size() - read_len, + &just_read, errno_p)) { + CloseFile(fd); + return false; + } + read_len += just_read; + if (!just_read) + break; + } + CloseFile(fd); + buff->resize(read_len); + return true; +} + static const char kPathSeparator = SANITIZER_WINDOWS ? ';' : ':'; char *FindPathToBinary(const char *name) { @@ -138,7 +177,7 @@ char *FindPathToBinary(const char *name) { if (!path) return nullptr; uptr name_len = internal_strlen(name); - InternalScopedBuffer buffer(kMaxPathLength); + InternalMmapVector buffer(kMaxPathLength); const char *beg = path; while (true) { const char *end = internal_strchrnul(beg, kPathSeparator); diff --git a/libsanitizer/sanitizer_common/sanitizer_flag_parser.h b/libsanitizer/sanitizer_common/sanitizer_flag_parser.h index 13677c0ea68..6bf3fedf2fd 100644 --- a/libsanitizer/sanitizer_common/sanitizer_flag_parser.h +++ b/libsanitizer/sanitizer_common/sanitizer_flag_parser.h @@ -79,7 +79,7 @@ inline bool FlagHandler::Parse(const char *value) { template <> inline bool FlagHandler::Parse(const char *value) { - char *value_end; + const char *value_end; *t_ = internal_simple_strtoll(value, &value_end, 10); bool ok = *value_end == 0; if (!ok) Printf("ERROR: Invalid value for int option: '%s'\n", value); @@ -88,7 +88,7 @@ inline bool FlagHandler::Parse(const char *value) { template <> inline bool FlagHandler::Parse(const char *value) { - char *value_end; + const char *value_end; *t_ = internal_simple_strtoll(value, &value_end, 10); bool ok = *value_end == 0; if (!ok) Printf("ERROR: Invalid value for uptr option: '%s'\n", value); diff --git a/libsanitizer/sanitizer_common/sanitizer_flags.cc b/libsanitizer/sanitizer_common/sanitizer_flags.cc index 5f69e58ffb2..cbd00026c1b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_flags.cc +++ b/libsanitizer/sanitizer_common/sanitizer_flags.cc @@ -20,14 +20,6 @@ namespace __sanitizer { CommonFlags common_flags_dont_use; -struct FlagDescription { - const char *name; - const char *description; - FlagDescription *next; -}; - -IntrusiveList flag_descriptions; - void CommonFlags::SetDefaults() { #define COMMON_FLAG(Type, Name, DefaultValue, Description) Name = DefaultValue; #include "sanitizer_flags.inc" diff --git a/libsanitizer/sanitizer_common/sanitizer_flags.inc b/libsanitizer/sanitizer_common/sanitizer_flags.inc index 9e9b8a7daa6..a62dbebb575 100644 --- a/libsanitizer/sanitizer_common/sanitizer_flags.inc +++ b/libsanitizer/sanitizer_common/sanitizer_flags.inc @@ -54,12 +54,15 @@ COMMON_FLAG( "Mention name of executable when reporting error and " "append executable name to logs (as in \"log_path.exe_name.pid\").") COMMON_FLAG( - bool, log_to_syslog, SANITIZER_ANDROID || SANITIZER_MAC, + bool, log_to_syslog, (bool)SANITIZER_ANDROID || (bool)SANITIZER_MAC, "Write all sanitizer output to syslog in addition to other means of " "logging.") COMMON_FLAG( int, verbosity, 0, "Verbosity level (0 - silent, 1 - a bit of output, 2+ - more output).") +COMMON_FLAG(bool, strip_env, 1, + "Whether to remove the sanitizer from DYLD_INSERT_LIBRARIES to " + "avoid passing it to children. Default is true.") COMMON_FLAG(bool, detect_leaks, !SANITIZER_MAC, "Enable memory leak detection.") COMMON_FLAG( bool, leak_check_at_exit, true, @@ -88,6 +91,8 @@ COMMON_FLAG(HandleSignalMode, handle_abort, kHandleSignalNo, COMMON_FLAG_HANDLE_SIGNAL_HELP(SIGABRT)) COMMON_FLAG(HandleSignalMode, handle_sigill, kHandleSignalNo, COMMON_FLAG_HANDLE_SIGNAL_HELP(SIGILL)) +COMMON_FLAG(HandleSignalMode, handle_sigtrap, kHandleSignalNo, + COMMON_FLAG_HANDLE_SIGNAL_HELP(SIGTRAP)) COMMON_FLAG(HandleSignalMode, handle_sigfpe, kHandleSignalYes, COMMON_FLAG_HANDLE_SIGNAL_HELP(SIGFPE)) #undef COMMON_FLAG_HANDLE_SIGNAL_HELP @@ -127,11 +132,12 @@ COMMON_FLAG(uptr, soft_rss_limit_mb, 0, " This limit does not affect memory allocations other than" " malloc/new.") COMMON_FLAG(bool, heap_profile, false, "Experimental heap profiler, asan-only") -COMMON_FLAG(s32, allocator_release_to_os_interval_ms, kReleaseToOSIntervalNever, - "Experimental. Only affects a 64-bit allocator. If set, tries to " - "release unused memory to the OS, but not more often than this " - "interval (in milliseconds). Negative values mean do not attempt " - "to release memory to the OS.\n") +COMMON_FLAG(s32, allocator_release_to_os_interval_ms, + ((bool)SANITIZER_FUCHSIA || (bool)SANITIZER_WINDOWS) ? -1 : 5000, + "Only affects a 64-bit allocator. If set, tries to release unused " + "memory to the OS, but not more often than this interval (in " + "milliseconds). Negative values mean do not attempt to release " + "memory to the OS.\n") COMMON_FLAG(bool, can_use_proc_maps_statm, true, "If false, do not attempt to read /proc/maps/statm." " Mostly useful for testing sanitizers.") @@ -217,7 +223,7 @@ COMMON_FLAG(bool, decorate_proc_maps, false, "If set, decorate sanitizer " COMMON_FLAG(int, exitcode, 1, "Override the program exit status if the tool " "found an error") COMMON_FLAG( - bool, abort_on_error, SANITIZER_ANDROID || SANITIZER_MAC, + bool, abort_on_error, (bool)SANITIZER_ANDROID || (bool)SANITIZER_MAC, "If set, the tool calls abort() instead of _exit() after printing the " "error report.") COMMON_FLAG(bool, suppress_equal_pcs, true, @@ -232,3 +238,6 @@ COMMON_FLAG(bool, dump_instruction_bytes, false, COMMON_FLAG(bool, dump_registers, true, "If true, dump values of CPU registers when SEGV happens. Only " "available on OS X for now.") +COMMON_FLAG(bool, detect_write_exec, false, + "If true, triggers warning when writable-executable pages requests " + "are being made") diff --git a/libsanitizer/sanitizer_common/sanitizer_fuchsia.cc b/libsanitizer/sanitizer_common/sanitizer_fuchsia.cc index da7018ca33d..6602f97b40b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_fuchsia.cc +++ b/libsanitizer/sanitizer_common/sanitizer_fuchsia.cc @@ -1,14 +1,14 @@ -//===-- sanitizer_fuchsia.cc ---------------------------------------------===// +//===-- sanitizer_fuchsia.cc ----------------------------------------------===// // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// // // This file is shared between AddressSanitizer and other sanitizer // run-time libraries and implements Fuchsia-specific functions from // sanitizer_common.h. -//===---------------------------------------------------------------------===// +//===----------------------------------------------------------------------===// #include "sanitizer_fuchsia.h" #if SANITIZER_FUCHSIA @@ -16,13 +16,11 @@ #include "sanitizer_common.h" #include "sanitizer_libc.h" #include "sanitizer_mutex.h" -#include "sanitizer_stacktrace.h" #include #include #include #include -#include #include #include #include @@ -47,7 +45,9 @@ unsigned int internal_sleep(unsigned int seconds) { return 0; } -u64 NanoTime() { return _zx_time_get(ZX_CLOCK_UTC); } +u64 NanoTime() { return _zx_clock_get(ZX_CLOCK_UTC); } + +u64 MonotonicNanoTime() { return _zx_clock_get(ZX_CLOCK_MONOTONIC); } uptr internal_getpid() { zx_info_handle_basic_t info; @@ -62,7 +62,7 @@ uptr internal_getpid() { uptr GetThreadSelf() { return reinterpret_cast(thrd_current()); } -uptr GetTid() { return GetThreadSelf(); } +tid_t GetTid() { return GetThreadSelf(); } void Abort() { abort(); } @@ -85,13 +85,10 @@ void GetThreadStackTopAndBottom(bool, uptr *stack_top, uptr *stack_bottom) { } void MaybeReexec() {} -void PrepareForSandboxing(__sanitizer_sandbox_arguments *args) {} +void CheckASLR() {} +void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {} void DisableCoreDumperIfNecessary() {} void InstallDeadlySignalHandlers(SignalHandlerType handler) {} -void StartReportDeadlySignal() {} -void ReportDeadlySignal(const SignalContext &sig, u32 tid, - UnwindSignalStackCallbackType unwind, - const void *unwind_context) {} void SetAlternateSignalStack() {} void UnsetAlternateSignalStack() {} void InitTlsSize() {} @@ -102,42 +99,6 @@ bool SignalContext::IsStackOverflow() const { return false; } void SignalContext::DumpAllRegisters(void *context) { UNIMPLEMENTED(); } const char *SignalContext::Describe() const { UNIMPLEMENTED(); } -struct UnwindTraceArg { - BufferedStackTrace *stack; - u32 max_depth; -}; - -_Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) { - UnwindTraceArg *arg = static_cast(param); - CHECK_LT(arg->stack->size, arg->max_depth); - uptr pc = _Unwind_GetIP(ctx); - if (pc < PAGE_SIZE) return _URC_NORMAL_STOP; - arg->stack->trace_buffer[arg->stack->size++] = pc; - return (arg->stack->size == arg->max_depth ? _URC_NORMAL_STOP - : _URC_NO_REASON); -} - -void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) { - CHECK_GE(max_depth, 2); - size = 0; - UnwindTraceArg arg = {this, Min(max_depth + 1, kStackTraceMax)}; - _Unwind_Backtrace(Unwind_Trace, &arg); - CHECK_GT(size, 0); - // We need to pop a few frames so that pc is on top. - uptr to_pop = LocatePcInTrace(pc); - // trace_buffer[0] belongs to the current function so we always pop it, - // unless there is only 1 frame in the stack trace (1 frame is always better - // than 0!). - PopStackFrames(Min(to_pop, static_cast(1))); - trace_buffer[0] = pc; -} - -void BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context, - u32 max_depth) { - CHECK_NE(context, nullptr); - UNREACHABLE("signal context doesn't exist"); -} - enum MutexState : int { MtxUnlocked = 0, MtxLocked = 1, MtxSleeping = 2 }; BlockingMutex::BlockingMutex() { @@ -184,11 +145,13 @@ uptr GetMmapGranularity() { return PAGE_SIZE; } sanitizer_shadow_bounds_t ShadowBounds; -uptr GetMaxVirtualAddress() { +uptr GetMaxUserVirtualAddress() { ShadowBounds = __sanitizer_shadow_bounds(); return ShadowBounds.memory_limit - 1; } +uptr GetMaxVirtualAddress() { return GetMaxUserVirtualAddress(); } + static void *DoAnonymousMmapOrDie(uptr size, const char *mem_type, bool raw_report, bool die_for_nomem) { size = RoundUpTo(size, PAGE_SIZE); @@ -206,8 +169,9 @@ static void *DoAnonymousMmapOrDie(uptr size, const char *mem_type, // TODO(mcgrathr): Maybe allocate a VMAR for all sanitizer heap and use that? uintptr_t addr; - status = _zx_vmar_map(_zx_vmar_root_self(), 0, vmo, 0, size, - ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE, &addr); + status = + _zx_vmar_map(_zx_vmar_root_self(), ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0, + vmo, 0, size, &addr); _zx_handle_close(vmo); if (status != ZX_OK) { @@ -234,76 +198,99 @@ void *MmapOrDieOnFatalError(uptr size, const char *mem_type) { return DoAnonymousMmapOrDie(size, mem_type, false, false); } -// MmapNoAccess and MmapFixedOrDie are used only by sanitizer_allocator. -// Instead of doing exactly what they say, we make MmapNoAccess actually -// just allocate a VMAR to reserve the address space. Then MmapFixedOrDie -// uses that VMAR instead of the root. - -zx_handle_t allocator_vmar = ZX_HANDLE_INVALID; -uintptr_t allocator_vmar_base; -size_t allocator_vmar_size; - -void *MmapNoAccess(uptr size) { - size = RoundUpTo(size, PAGE_SIZE); - CHECK_EQ(allocator_vmar, ZX_HANDLE_INVALID); +uptr ReservedAddressRange::Init(uptr init_size, const char *name, + uptr fixed_addr) { + init_size = RoundUpTo(init_size, PAGE_SIZE); + DCHECK_EQ(os_handle_, ZX_HANDLE_INVALID); uintptr_t base; + zx_handle_t vmar; zx_status_t status = - _zx_vmar_allocate(_zx_vmar_root_self(), 0, size, - ZX_VM_FLAG_CAN_MAP_READ | ZX_VM_FLAG_CAN_MAP_WRITE | - ZX_VM_FLAG_CAN_MAP_SPECIFIC, - &allocator_vmar, &base); + _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); if (status != ZX_OK) - ReportMmapFailureAndDie(size, "sanitizer allocator address space", - "zx_vmar_allocate", status); + ReportMmapFailureAndDie(init_size, name, "zx_vmar_allocate", status); + base_ = reinterpret_cast(base); + size_ = init_size; + name_ = name; + os_handle_ = vmar; - allocator_vmar_base = base; - allocator_vmar_size = size; - return reinterpret_cast(base); + return reinterpret_cast(base_); } -constexpr const char kAllocatorVmoName[] = "sanitizer_allocator"; - -static void *DoMmapFixedOrDie(uptr fixed_addr, uptr size, bool die_for_nomem) { - size = RoundUpTo(size, PAGE_SIZE); - +static uptr DoMmapFixedOrDie(zx_handle_t vmar, uptr fixed_addr, uptr map_size, + void *base, const char *name, bool die_for_nomem) { + uptr offset = fixed_addr - reinterpret_cast(base); + map_size = RoundUpTo(map_size, PAGE_SIZE); zx_handle_t vmo; - zx_status_t status = _zx_vmo_create(size, 0, &vmo); + zx_status_t status = _zx_vmo_create(map_size, 0, &vmo); if (status != ZX_OK) { if (status != ZX_ERR_NO_MEMORY || die_for_nomem) - ReportMmapFailureAndDie(size, kAllocatorVmoName, "zx_vmo_create", status); - return nullptr; + ReportMmapFailureAndDie(map_size, name, "zx_vmo_create", status); + return 0; } - _zx_object_set_property(vmo, ZX_PROP_NAME, kAllocatorVmoName, - sizeof(kAllocatorVmoName) - 1); - - DCHECK_GE(fixed_addr, allocator_vmar_base); - uintptr_t offset = fixed_addr - allocator_vmar_base; - DCHECK_LE(size, allocator_vmar_size); - DCHECK_GE(allocator_vmar_size - offset, size); - + _zx_object_set_property(vmo, ZX_PROP_NAME, name, internal_strlen(name)); + DCHECK_GE(base + size_, map_size + offset); uintptr_t addr; - status = _zx_vmar_map( - allocator_vmar, offset, vmo, 0, size, - ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE | ZX_VM_FLAG_SPECIFIC, - &addr); + + status = + _zx_vmar_map(vmar, ZX_VM_PERM_READ | ZX_VM_PERM_WRITE | ZX_VM_SPECIFIC, + offset, vmo, 0, map_size, &addr); _zx_handle_close(vmo); if (status != ZX_OK) { - if (status != ZX_ERR_NO_MEMORY || die_for_nomem) - ReportMmapFailureAndDie(size, kAllocatorVmoName, "zx_vmar_map", status); - return nullptr; + if (status != ZX_ERR_NO_MEMORY || die_for_nomem) { + ReportMmapFailureAndDie(map_size, name, "zx_vmar_map", status); + } + return 0; } + IncreaseTotalMmap(map_size); + return addr; +} - IncreaseTotalMmap(size); +uptr ReservedAddressRange::Map(uptr fixed_addr, uptr map_size) { + return DoMmapFixedOrDie(os_handle_, fixed_addr, map_size, base_, + name_, false); +} - return reinterpret_cast(addr); +uptr ReservedAddressRange::MapOrDie(uptr fixed_addr, uptr map_size) { + return DoMmapFixedOrDie(os_handle_, fixed_addr, map_size, base_, + name_, true); } -void *MmapFixedOrDie(uptr fixed_addr, uptr size) { - return DoMmapFixedOrDie(fixed_addr, size, true); +void UnmapOrDieVmar(void *addr, uptr size, zx_handle_t target_vmar) { + if (!addr || !size) return; + size = RoundUpTo(size, PAGE_SIZE); + + zx_status_t status = + _zx_vmar_unmap(target_vmar, reinterpret_cast(addr), size); + if (status != ZX_OK) { + Report("ERROR: %s failed to deallocate 0x%zx (%zd) bytes at address %p\n", + SanitizerToolName, size, size, addr); + CHECK("unable to unmap" && 0); + } + + DecreaseTotalMmap(size); } -void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size) { - return DoMmapFixedOrDie(fixed_addr, size, false); +void ReservedAddressRange::Unmap(uptr addr, uptr size) { + CHECK_LE(size, size_); + const zx_handle_t vmar = static_cast(os_handle_); + if (addr == reinterpret_cast(base_)) { + if (size == size_) { + // Destroying the vmar effectively unmaps the whole mapping. + _zx_vmar_destroy(vmar); + _zx_handle_close(vmar); + os_handle_ = static_cast(ZX_HANDLE_INVALID); + DecreaseTotalMmap(size); + return; + } + } else { + CHECK_EQ(addr + size, reinterpret_cast(base_) + size_); + } + // Partial unmapping does not affect the fact that the initial range is still + // reserved, and the resulting unmapped memory can't be reused. + UnmapOrDieVmar(reinterpret_cast(addr), size, vmar); } // This should never be called. @@ -335,8 +322,9 @@ void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment, // beginning of the VMO, and unmap the excess before and after. size_t map_size = size + alignment; uintptr_t addr; - status = _zx_vmar_map(_zx_vmar_root_self(), 0, vmo, 0, map_size, - ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE, &addr); + status = + _zx_vmar_map(_zx_vmar_root_self(), ZX_VM_PERM_READ | ZX_VM_PERM_WRITE, 0, + vmo, 0, map_size, &addr); if (status == ZX_OK) { uintptr_t map_addr = addr; uintptr_t map_end = map_addr + map_size; @@ -348,11 +336,10 @@ void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment, sizeof(info), NULL, NULL); if (status == ZX_OK) { uintptr_t new_addr; - status = - _zx_vmar_map(_zx_vmar_root_self(), addr - info.base, vmo, 0, size, - ZX_VM_FLAG_PERM_READ | ZX_VM_FLAG_PERM_WRITE | - ZX_VM_FLAG_SPECIFIC_OVERWRITE, - &new_addr); + status = _zx_vmar_map( + _zx_vmar_root_self(), + ZX_VM_PERM_READ | ZX_VM_PERM_WRITE | ZX_VM_SPECIFIC_OVERWRITE, + addr - info.base, vmo, 0, size, &new_addr); if (status == ZX_OK) CHECK_EQ(new_addr, addr); } } @@ -375,18 +362,7 @@ void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment, } void UnmapOrDie(void *addr, uptr size) { - if (!addr || !size) return; - size = RoundUpTo(size, PAGE_SIZE); - - zx_status_t status = _zx_vmar_unmap(_zx_vmar_root_self(), - reinterpret_cast(addr), size); - if (status != ZX_OK) { - Report("ERROR: %s failed to deallocate 0x%zx (%zd) bytes at address %p\n", - SanitizerToolName, size, size, addr); - CHECK("unable to unmap" && 0); - } - - DecreaseTotalMmap(size); + UnmapOrDieVmar(addr, size, _zx_vmar_root_self()); } // This is used on the shadow mapping, which cannot be changed. @@ -394,7 +370,8 @@ void UnmapOrDie(void *addr, uptr size) { void ReleaseMemoryPagesToOS(uptr beg, uptr end) {} void DumpProcessMap() { - UNIMPLEMENTED(); // TODO(mcgrathr): write it + // TODO(mcgrathr): write it + return; } bool IsAccessibleMemoryRange(uptr beg, uptr size) { @@ -402,16 +379,7 @@ bool IsAccessibleMemoryRange(uptr beg, uptr size) { zx_handle_t vmo; zx_status_t status = _zx_vmo_create(size, 0, &vmo); if (status == ZX_OK) { - while (size > 0) { - size_t wrote; - status = _zx_vmo_write(vmo, reinterpret_cast(beg), 0, size, - &wrote); - if (status != ZX_OK) break; - CHECK_GT(wrote, 0); - CHECK_LE(wrote, size); - beg += wrote; - size -= wrote; - } + status = _zx_vmo_write(vmo, reinterpret_cast(beg), 0, size); _zx_handle_close(vmo); } return status == ZX_OK; @@ -431,8 +399,8 @@ bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size, if (vmo_size < max_len) max_len = vmo_size; size_t map_size = RoundUpTo(max_len, PAGE_SIZE); uintptr_t addr; - status = _zx_vmar_map(_zx_vmar_root_self(), 0, vmo, 0, map_size, - ZX_VM_FLAG_PERM_READ, &addr); + status = _zx_vmar_map(_zx_vmar_root_self(), ZX_VM_PERM_READ, 0, vmo, 0, + map_size, &addr); if (status == ZX_OK) { *buff = reinterpret_cast(addr); *buff_size = map_size; @@ -446,7 +414,31 @@ bool ReadFileToBuffer(const char *file_name, char **buff, uptr *buff_size, } void RawWrite(const char *buffer) { - __sanitizer_log_write(buffer, internal_strlen(buffer)); + constexpr size_t size = 128; + static _Thread_local char line[size]; + static _Thread_local size_t lastLineEnd = 0; + static _Thread_local size_t cur = 0; + + while (*buffer) { + if (cur >= size) { + if (lastLineEnd == 0) + lastLineEnd = size; + __sanitizer_log_write(line, lastLineEnd); + internal_memmove(line, line + lastLineEnd, cur - lastLineEnd); + cur = cur - lastLineEnd; + lastLineEnd = 0; + } + if (*buffer == '\n') + lastLineEnd = cur + 1; + line[cur++] = *buffer++; + } + // Flush all complete lines before returning. + if (lastLineEnd != 0) { + __sanitizer_log_write(line, lastLineEnd); + internal_memmove(line, line + lastLineEnd, cur - lastLineEnd); + cur = cur - lastLineEnd; + lastLineEnd = 0; + } } void CatastrophicErrorWrite(const char *buffer, uptr length) { @@ -470,8 +462,10 @@ const char *GetEnv(const char *name) { } uptr ReadBinaryName(/*out*/ char *buf, uptr buf_len) { - const char *argv0 = StoredArgv[0]; - if (!argv0) argv0 = ""; + const char *argv0 = ""; + if (StoredArgv && StoredArgv[0]) { + argv0 = StoredArgv[0]; + } internal_strncpy(buf, argv0, buf_len); return internal_strlen(buf); } @@ -484,12 +478,16 @@ uptr MainThreadStackBase, MainThreadStackSize; bool GetRandom(void *buffer, uptr length, bool blocking) { CHECK_LE(length, ZX_CPRNG_DRAW_MAX_LEN); - size_t size; - CHECK_EQ(_zx_cprng_draw(buffer, length, &size), ZX_OK); - CHECK_EQ(size, length); + _zx_cprng_draw(buffer, length); return true; } +u32 GetNumberOfCPUs() { + return zx_system_get_num_cpus(); +} + +uptr GetRSS() { UNIMPLEMENTED(); } + } // namespace __sanitizer using namespace __sanitizer; // NOLINT diff --git a/libsanitizer/sanitizer_common/sanitizer_getauxval.h b/libsanitizer/sanitizer_common/sanitizer_getauxval.h new file mode 100644 index 00000000000..a2868614cfc --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_getauxval.h @@ -0,0 +1,46 @@ +//===-- sanitizer_getauxval.h -----------------------------------*- C++ -*-===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Common getauxval() guards and definitions. +// getauxval() is not defined until glibc version 2.16, or until API level 21 +// for Android. +// +//===----------------------------------------------------------------------===// + +#ifndef SANITIZER_GETAUXVAL_H +#define SANITIZER_GETAUXVAL_H + +#include "sanitizer_platform.h" + +#if SANITIZER_LINUX || SANITIZER_FUCHSIA + +# include + +# ifndef __GLIBC_PREREQ +# define __GLIBC_PREREQ(x, y) 0 +# endif + +# if __GLIBC_PREREQ(2, 16) || (SANITIZER_ANDROID && __ANDROID_API__ >= 21) || \ + SANITIZER_FUCHSIA +# define SANITIZER_USE_GETAUXVAL 1 +# else +# define SANITIZER_USE_GETAUXVAL 0 +# endif + +# if SANITIZER_USE_GETAUXVAL +# include +# else +// The weak getauxval definition allows to check for the function at runtime. +// This is useful for Android, when compiled at a lower API level yet running +// on a more recent platform that offers the function. +extern "C" SANITIZER_WEAK_ATTRIBUTE +unsigned long getauxval(unsigned long type); // NOLINT +# endif + +#endif // SANITIZER_LINUX || SANITIZER_FUCHSIA + +#endif // SANITIZER_GETAUXVAL_H diff --git a/libsanitizer/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc b/libsanitizer/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc new file mode 100644 index 00000000000..b42e6314434 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_interceptors_ioctl_netbsd.inc @@ -0,0 +1,1487 @@ +//===-- sanitizer_interceptors_ioctl_netbsd.inc -----------------*- C++ -*-===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Ioctl handling in common sanitizer interceptors. +//===----------------------------------------------------------------------===// + +#if SANITIZER_NETBSD + +#include "sanitizer_flags.h" + +struct ioctl_desc { + unsigned req; + // FIXME: support read+write arguments. Currently READWRITE and WRITE do the + // same thing. + // XXX: The declarations below may use WRITE instead of READWRITE, unless + // explicitly noted. + enum { NONE, READ, WRITE, READWRITE, CUSTOM } type : 3; + unsigned size : 29; + const char *name; +}; + +const unsigned ioctl_table_max = 1198; +static ioctl_desc ioctl_table[ioctl_table_max]; +static unsigned ioctl_table_size = 0; + +// This can not be declared as a global, because references to struct_*_sz +// require a global initializer. And this table must be available before global +// initializers are run. +static void ioctl_table_fill() { +#define _(rq, tp, sz) \ + if (IOCTL_##rq != IOCTL_NOT_PRESENT) { \ + CHECK(ioctl_table_size < ioctl_table_max); \ + ioctl_table[ioctl_table_size].req = IOCTL_##rq; \ + ioctl_table[ioctl_table_size].type = ioctl_desc::tp; \ + ioctl_table[ioctl_table_size].size = sz; \ + ioctl_table[ioctl_table_size].name = #rq; \ + ++ioctl_table_size; \ + } + + /* Entries from file: altq/altq_afmap.h */ + _(AFM_ADDFMAP, READWRITE, struct_atm_flowmap_sz); + _(AFM_DELFMAP, READWRITE, struct_atm_flowmap_sz); + _(AFM_CLEANFMAP, READWRITE, struct_atm_flowmap_sz); + _(AFM_GETFMAP, READWRITE, struct_atm_flowmap_sz); + /* Entries from file: altq/altq.h */ + _(ALTQGTYPE, READWRITE, struct_altqreq_sz); + _(ALTQTBRSET, READ, struct_tbrreq_sz); + _(ALTQTBRGET, READWRITE, struct_tbrreq_sz); + /* Entries from file: altq/altq_blue.h */ + _(BLUE_IF_ATTACH, READ, struct_blue_interface_sz); + _(BLUE_DISABLE, READ, struct_blue_interface_sz); + _(BLUE_CONFIG, READWRITE, struct_blue_conf_sz); + _(BLUE_GETSTATS, READWRITE, struct_blue_stats_sz); + /* Entries from file: altq/altq_cbq.h */ + _(CBQ_ENABLE, READ, struct_cbq_interface_sz); + _(CBQ_ADD_CLASS, READWRITE, struct_cbq_add_class_sz); + _(CBQ_DEL_CLASS, READ, struct_cbq_delete_class_sz); + _(CBQ_MODIFY_CLASS, READWRITE, struct_cbq_modify_class_sz); + _(CBQ_DEL_FILTER, READ, struct_cbq_delete_filter_sz); + _(CBQ_GETSTATS, READWRITE, struct_cbq_getstats_sz); + /* Entries from file: altq/altq_cdnr.h */ + _(CDNR_IF_DETACH, READ, struct_cdnr_interface_sz); + _(CDNR_ADD_FILTER, READWRITE, struct_cdnr_add_filter_sz); + _(CDNR_GETSTATS, READWRITE, struct_cdnr_get_stats_sz); + _(CDNR_ADD_ELEM, READWRITE, struct_cdnr_add_element_sz); + _(CDNR_DEL_ELEM, READ, struct_cdnr_delete_element_sz); + _(CDNR_ADD_TBM, READWRITE, struct_cdnr_add_tbmeter_sz); + _(CDNR_MOD_TBM, READ, struct_cdnr_modify_tbmeter_sz); + _(CDNR_TBM_STATS, READWRITE, struct_cdnr_tbmeter_stats_sz); + _(CDNR_ADD_TCM, READWRITE, struct_cdnr_add_trtcm_sz); + _(CDNR_MOD_TCM, READWRITE, struct_cdnr_modify_trtcm_sz); + _(CDNR_TCM_STATS, READWRITE, struct_cdnr_tcm_stats_sz); + _(CDNR_ADD_TSW, READWRITE, struct_cdnr_add_tswtcm_sz); + _(CDNR_MOD_TSW, READWRITE, struct_cdnr_modify_tswtcm_sz); + /* Entries from file: altq/altq_fifoq.h */ + _(FIFOQ_CONFIG, READWRITE, struct_fifoq_conf_sz); + _(FIFOQ_GETSTATS, READWRITE, struct_fifoq_getstats_sz); + /* Entries from file: altq/altq_hfsc.h */ + _(HFSC_CLEAR_HIERARCHY, READ, struct_hfsc_interface_sz); + _(HFSC_ADD_CLASS, READWRITE, struct_hfsc_add_class_sz); + _(HFSC_GETSTATS, READWRITE, struct_hfsc_class_stats_sz); + /* Entries from file: altq/altq_jobs.h */ + _(JOBS_IF_ATTACH, READ, struct_jobs_attach_sz); + _(JOBS_IF_DETACH, READ, struct_jobs_interface_sz); + _(JOBS_ENABLE, READ, struct_jobs_interface_sz); + _(JOBS_DISABLE, READ, struct_jobs_interface_sz); + _(JOBS_CLEAR, READ, struct_jobs_interface_sz); + _(JOBS_ADD_CLASS, READWRITE, struct_jobs_add_class_sz); + _(JOBS_MOD_CLASS, READ, struct_jobs_modify_class_sz); + /* Entries from file: altq/altq_priq.h */ + _(PRIQ_IF_ATTACH, READ, struct_priq_interface_sz); + _(PRIQ_CLEAR, READ, struct_priq_interface_sz); + _(PRIQ_ADD_CLASS, READWRITE, struct_priq_add_class_sz); + _(PRIQ_DEL_CLASS, READ, struct_priq_delete_class_sz); + _(PRIQ_MOD_CLASS, READ, struct_priq_modify_class_sz); + _(PRIQ_ADD_FILTER, READWRITE, struct_priq_add_filter_sz); + _(PRIQ_DEL_FILTER, READ, struct_priq_delete_filter_sz); + _(PRIQ_GETSTATS, READWRITE, struct_priq_class_stats_sz); + /* Entries from file: altq/altq_red.h */ + _(RED_CONFIG, READWRITE, struct_red_conf_sz); + _(RED_GETSTATS, READWRITE, struct_red_stats_sz); + _(RED_SETDEFAULTS, READ, struct_redparams_sz); + /* Entries from file: altq/altq_rio.h */ + _(RIO_CONFIG, READWRITE, struct_rio_conf_sz); + _(RIO_GETSTATS, READWRITE, struct_rio_stats_sz); + _(RIO_SETDEFAULTS, READ, struct_redparams_sz); + /* Entries from file: altq/altq_wfq.h */ + _(WFQ_CONFIG, READWRITE, struct_wfq_conf_sz); + _(WFQ_GET_QID, READWRITE, struct_wfq_getqid_sz); + _(WFQ_SET_WEIGHT, READWRITE, struct_wfq_setweight_sz); + /* Entries from file: crypto/cryptodev.h */ + _(CRIOGET, READWRITE, sizeof(u32)); + _(CIOCFSESSION, READ, sizeof(u32)); + _(CIOCKEY, READWRITE, struct_crypt_kop_sz); + _(CIOCNFKEYM, READWRITE, struct_crypt_mkop_sz); + _(CIOCNFSESSION, READ, struct_crypt_sfop_sz); + _(CIOCNCRYPTRETM, READWRITE, struct_cryptret_sz); + _(CIOCNCRYPTRET, READWRITE, struct_crypt_result_sz); + _(CIOCGSESSION, READWRITE, struct_session_op_sz); + _(CIOCNGSESSION, READWRITE, struct_crypt_sgop_sz); + _(CIOCCRYPT, READWRITE, struct_crypt_op_sz); + _(CIOCNCRYPTM, READWRITE, struct_crypt_mop_sz); + _(CIOCASYMFEAT, WRITE, sizeof(u32)); + /* Entries from file: dev/apm/apmio.h */ + _(APM_IOC_REJECT, READ, struct_apm_event_info_sz); + _(OAPM_IOC_GETPOWER, WRITE, struct_apm_power_info_sz); + _(APM_IOC_GETPOWER, READWRITE, struct_apm_power_info_sz); + _(APM_IOC_NEXTEVENT, WRITE, struct_apm_event_info_sz); + _(APM_IOC_DEV_CTL, READ, struct_apm_ctl_sz); + /* Entries from file: dev/dm/netbsd-dm.h */ + _(NETBSD_DM_IOCTL, READWRITE, struct_plistref_sz); + /* Entries from file: dev/dmover/dmover_io.h */ + _(DMIO_SETFUNC, READ, struct_dmio_setfunc_sz); + /* Entries from file: dev/dtv/dtvio_demux.h */ + _(DMX_START, NONE, 0); + _(DMX_STOP, NONE, 0); + _(DMX_SET_FILTER, READ, struct_dmx_sct_filter_params_sz); + _(DMX_SET_PES_FILTER, READ, struct_dmx_pes_filter_params_sz); + _(DMX_SET_BUFFER_SIZE, NONE, 0); + _(DMX_GET_STC, READWRITE, struct_dmx_stc_sz); + _(DMX_ADD_PID, READ, sizeof(u16)); + _(DMX_REMOVE_PID, READ, sizeof(u16)); + _(DMX_GET_CAPS, WRITE, struct_dmx_caps_sz); + _(DMX_SET_SOURCE, READ, enum_dmx_source_sz); + /* Entries from file: dev/dtv/dtvio_frontend.h */ + _(FE_READ_STATUS, WRITE, enum_fe_status_sz); + _(FE_READ_BER, WRITE, sizeof(u32)); + _(FE_READ_SNR, WRITE, sizeof(u16)); + _(FE_READ_SIGNAL_STRENGTH, WRITE, sizeof(u16)); + _(FE_READ_UNCORRECTED_BLOCKS, WRITE, sizeof(u32)); + _(FE_SET_FRONTEND, READWRITE, struct_dvb_frontend_parameters_sz); + _(FE_GET_FRONTEND, WRITE, struct_dvb_frontend_parameters_sz); + _(FE_GET_EVENT, WRITE, struct_dvb_frontend_event_sz); + _(FE_GET_INFO, WRITE, struct_dvb_frontend_info_sz); + _(FE_DISEQC_RESET_OVERLOAD, NONE, 0); + _(FE_DISEQC_SEND_MASTER_CMD, READ, struct_dvb_diseqc_master_cmd_sz); + _(FE_DISEQC_RECV_SLAVE_REPLY, WRITE, struct_dvb_diseqc_slave_reply_sz); + _(FE_DISEQC_SEND_BURST, READ, enum_fe_sec_mini_cmd_sz); + _(FE_SET_TONE, READ, enum_fe_sec_tone_mode_sz); + _(FE_SET_VOLTAGE, READ, enum_fe_sec_voltage_sz); + _(FE_ENABLE_HIGH_LNB_VOLTAGE, READ, sizeof(int)); + _(FE_SET_FRONTEND_TUNE_MODE, READ, sizeof(unsigned int)); + _(FE_DISHNETWORK_SEND_LEGACY_CMD, READ, sizeof(unsigned long)); + /* Entries from file: dev/filemon/filemon.h */ + _(FILEMON_SET_FD, READWRITE, sizeof(int)); + _(FILEMON_SET_PID, READWRITE, sizeof(int)); + /* Entries from file: dev/hdaudio/hdaudioio.h */ + _(HDAUDIO_FGRP_INFO, READWRITE, struct_plistref_sz); + _(HDAUDIO_FGRP_GETCONFIG, READWRITE, struct_plistref_sz); + _(HDAUDIO_FGRP_SETCONFIG, READWRITE, struct_plistref_sz); + _(HDAUDIO_FGRP_WIDGET_INFO, READWRITE, struct_plistref_sz); + _(HDAUDIO_FGRP_CODEC_INFO, READWRITE, struct_plistref_sz); + _(HDAUDIO_AFG_WIDGET_INFO, READWRITE, struct_plistref_sz); + _(HDAUDIO_AFG_CODEC_INFO, READWRITE, struct_plistref_sz); + /* Entries from file: dev/hdmicec/hdmicecio.h */ + _(CEC_GET_PHYS_ADDR, WRITE, sizeof(u16)); + _(CEC_GET_LOG_ADDRS, WRITE, sizeof(u16)); + _(CEC_SET_LOG_ADDRS, READ, sizeof(u16)); + _(CEC_GET_VENDOR_ID, WRITE, sizeof(u32)); + /* Entries from file: dev/hpc/hpcfbio.h */ + _(HPCFBIO_GCONF, READWRITE, struct_hpcfb_fbconf_sz); + _(HPCFBIO_SCONF, READ, struct_hpcfb_fbconf_sz); + _(HPCFBIO_GDSPCONF, READWRITE, struct_hpcfb_dspconf_sz); + _(HPCFBIO_SDSPCONF, READ, struct_hpcfb_dspconf_sz); + _(HPCFBIO_GOP, WRITE, struct_hpcfb_dsp_op_sz); + _(HPCFBIO_SOP, READWRITE, struct_hpcfb_dsp_op_sz); + /* Entries from file: dev/i2o/iopio.h */ + _(IOPIOCPT, READWRITE, struct_ioppt_sz); + _(IOPIOCGLCT, READWRITE, struct_iovec_sz); + _(IOPIOCGSTATUS, READWRITE, struct_iovec_sz); + _(IOPIOCRECONFIG, NONE, 0); + _(IOPIOCGTIDMAP, READWRITE, struct_iovec_sz); + /* Entries from file: dev/ic/athioctl.h */ + _(SIOCGATHSTATS, READWRITE, struct_ifreq_sz); + _(SIOCGATHDIAG, READWRITE, struct_ath_diag_sz); + /* Entries from file: dev/ic/bt8xx.h */ + _(METEORCAPTUR, READ, sizeof(int)); + _(METEORCAPFRM, READ, struct_meteor_capframe_sz); + _(METEORSETGEO, READ, struct_meteor_geomet_sz); + _(METEORGETGEO, WRITE, struct_meteor_geomet_sz); + _(METEORSTATUS, WRITE, sizeof(unsigned short)); + _(METEORSHUE, READ, sizeof(signed char)); + _(METEORGHUE, WRITE, sizeof(signed char)); + _(METEORSFMT, READ, sizeof(unsigned int)); + _(METEORGFMT, WRITE, sizeof(unsigned int)); + _(METEORSINPUT, READ, sizeof(unsigned int)); + _(METEORGINPUT, WRITE, sizeof(unsigned int)); + _(METEORSCHCV, READ, sizeof(unsigned char)); + _(METEORGCHCV, WRITE, sizeof(unsigned char)); + _(METEORSCOUNT, READ, struct_meteor_counts_sz); + _(METEORGCOUNT, WRITE, struct_meteor_counts_sz); + _(METEORSFPS, READ, sizeof(unsigned short)); + _(METEORGFPS, WRITE, sizeof(unsigned short)); + _(METEORSSIGNAL, READ, sizeof(unsigned int)); + _(METEORGSIGNAL, WRITE, sizeof(unsigned int)); + _(METEORSVIDEO, READ, struct_meteor_video_sz); + _(METEORGVIDEO, WRITE, struct_meteor_video_sz); + _(METEORSBRIG, READ, sizeof(unsigned char)); + _(METEORGBRIG, WRITE, sizeof(unsigned char)); + _(METEORSCSAT, READ, sizeof(unsigned char)); + _(METEORGCSAT, WRITE, sizeof(unsigned char)); + _(METEORSCONT, READ, sizeof(unsigned char)); + _(METEORGCONT, WRITE, sizeof(unsigned char)); + _(METEORSHWS, READ, sizeof(unsigned char)); + _(METEORGHWS, WRITE, sizeof(unsigned char)); + _(METEORSVWS, READ, sizeof(unsigned char)); + _(METEORGVWS, WRITE, sizeof(unsigned char)); + _(METEORSTS, READ, sizeof(unsigned char)); + _(METEORGTS, WRITE, sizeof(unsigned char)); + _(TVTUNER_SETCHNL, READ, sizeof(unsigned int)); + _(TVTUNER_GETCHNL, WRITE, sizeof(unsigned int)); + _(TVTUNER_SETTYPE, READ, sizeof(unsigned int)); + _(TVTUNER_GETTYPE, WRITE, sizeof(unsigned int)); + _(TVTUNER_GETSTATUS, WRITE, sizeof(unsigned int)); + _(TVTUNER_SETFREQ, READ, sizeof(unsigned int)); + _(TVTUNER_GETFREQ, WRITE, sizeof(unsigned int)); + _(TVTUNER_SETAFC, READ, sizeof(int)); + _(TVTUNER_GETAFC, WRITE, sizeof(int)); + _(RADIO_SETMODE, READ, sizeof(unsigned int)); + _(RADIO_GETMODE, WRITE, sizeof(unsigned char)); + _(RADIO_SETFREQ, READ, sizeof(unsigned int)); + _(RADIO_GETFREQ, WRITE, sizeof(unsigned int)); + _(METEORSACTPIXFMT, READ, sizeof(int)); + _(METEORGACTPIXFMT, WRITE, sizeof(int)); + _(METEORGSUPPIXFMT, READWRITE, struct_meteor_pixfmt_sz); + _(TVTUNER_GETCHNLSET, READWRITE, struct_bktr_chnlset_sz); + _(REMOTE_GETKEY, WRITE, struct_bktr_remote_sz); + /* Entries from file: dev/ic/icp_ioctl.h */ + _(GDT_IOCTL_GENERAL, READWRITE, struct_gdt_ucmd_sz); + _(GDT_IOCTL_DRVERS, WRITE, sizeof(int)); + _(GDT_IOCTL_CTRTYPE, READWRITE, struct_gdt_ctrt_sz); + _(GDT_IOCTL_OSVERS, WRITE, struct_gdt_osv_sz); + _(GDT_IOCTL_CTRCNT, WRITE, sizeof(int)); + _(GDT_IOCTL_EVENT, READWRITE, struct_gdt_event_sz); + _(GDT_IOCTL_STATIST, WRITE, struct_gdt_statist_sz); + _(GDT_IOCTL_RESCAN, READWRITE, struct_gdt_rescan_sz); + /* Entries from file: dev/ic/isp_ioctl.h */ + _(ISP_SDBLEV, READWRITE, sizeof(int)); + _(ISP_RESETHBA, NONE, 0); + _(ISP_RESCAN, NONE, 0); + _(ISP_SETROLE, READWRITE, sizeof(int)); + _(ISP_GETROLE, WRITE, sizeof(int)); + _(ISP_GET_STATS, WRITE, struct_isp_stats_sz); + _(ISP_CLR_STATS, NONE, 0); + _(ISP_FC_LIP, NONE, 0); + _(ISP_FC_GETDINFO, READWRITE, struct_isp_fc_device_sz); + _(ISP_GET_FW_CRASH_DUMP, NONE, 0); + _(ISP_FORCE_CRASH_DUMP, NONE, 0); + _(ISP_FC_GETHINFO, READWRITE, struct_isp_hba_device_sz); + _(ISP_TSK_MGMT, READWRITE, struct_isp_fc_tsk_mgmt_sz); + _(ISP_FC_GETDLIST, NONE, 0); + /* Entries from file: dev/ic/mlxio.h */ + _(MLXD_STATUS, WRITE, sizeof(int)); + _(MLXD_CHECKASYNC, WRITE, sizeof(int)); + _(MLXD_DETACH, READ, sizeof(int)); + _(MLX_RESCAN_DRIVES, NONE, 0); + _(MLX_PAUSE_CHANNEL, READ, struct_mlx_pause_sz); + _(MLX_COMMAND, READWRITE, struct_mlx_usercommand_sz); + _(MLX_REBUILDASYNC, READWRITE, struct_mlx_rebuild_request_sz); + _(MLX_REBUILDSTAT, WRITE, struct_mlx_rebuild_status_sz); + _(MLX_GET_SYSDRIVE, READWRITE, sizeof(int)); + _(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/ir/irdaio.h */ + _(IRDA_RESET_PARAMS, NONE, 0); + _(IRDA_SET_PARAMS, READ, struct_irda_params_sz); + _(IRDA_GET_SPEEDMASK, WRITE, sizeof(unsigned int)); + _(IRDA_GET_TURNAROUNDMASK, WRITE, sizeof(unsigned int)); + _(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 */ + _(WTQICMD, NONE, 0); + /* Entries from file: dev/iscsi/iscsi_ioctl.h */ + _(ISCSI_GET_VERSION, READWRITE, struct_iscsi_get_version_parameters_sz); + _(ISCSI_LOGIN, READWRITE, struct_iscsi_login_parameters_sz); + _(ISCSI_LOGOUT, READWRITE, struct_iscsi_logout_parameters_sz); + _(ISCSI_ADD_CONNECTION, READWRITE, struct_iscsi_login_parameters_sz); + _(ISCSI_RESTORE_CONNECTION, READWRITE, struct_iscsi_login_parameters_sz); + _(ISCSI_REMOVE_CONNECTION, READWRITE, struct_iscsi_remove_parameters_sz); + _(ISCSI_CONNECTION_STATUS, READWRITE, struct_iscsi_conn_status_parameters_sz); + _(ISCSI_SEND_TARGETS, READWRITE, struct_iscsi_send_targets_parameters_sz); + _(ISCSI_SET_NODE_NAME, READWRITE, struct_iscsi_set_node_name_parameters_sz); + _(ISCSI_IO_COMMAND, READWRITE, struct_iscsi_iocommand_parameters_sz); + _(ISCSI_REGISTER_EVENT, READWRITE, struct_iscsi_register_event_parameters_sz); + _(ISCSI_DEREGISTER_EVENT, READWRITE, + struct_iscsi_register_event_parameters_sz); + _(ISCSI_WAIT_EVENT, READWRITE, struct_iscsi_wait_event_parameters_sz); + _(ISCSI_POLL_EVENT, READWRITE, struct_iscsi_wait_event_parameters_sz); + /* Entries from file: dev/ofw/openfirmio.h */ + _(OFIOCGET, READWRITE, struct_ofiocdesc_sz); + _(OFIOCSET, READ, struct_ofiocdesc_sz); + _(OFIOCNEXTPROP, READWRITE, struct_ofiocdesc_sz); + _(OFIOCGETOPTNODE, WRITE, sizeof(int)); + _(OFIOCGETNEXT, READWRITE, sizeof(int)); + _(OFIOCGETCHILD, READWRITE, sizeof(int)); + _(OFIOCFINDDEVICE, READWRITE, struct_ofiocdesc_sz); + /* Entries from file: dev/pci/amrio.h */ + _(AMR_IO_VERSION, WRITE, sizeof(int)); + _(AMR_IO_COMMAND, READWRITE, struct_amr_user_ioctl_sz); + /* Entries from file: dev/pci/mlyio.h */ + _(MLYIO_COMMAND, READWRITE, struct_mly_user_command_sz); + _(MLYIO_HEALTH, READ, struct_mly_user_health_sz); + /* Entries from file: dev/pci/pciio.h */ + _(PCI_IOC_CFGREAD, READWRITE, struct_pciio_cfgreg_sz); + _(PCI_IOC_CFGWRITE, READ, struct_pciio_cfgreg_sz); + _(PCI_IOC_BDF_CFGREAD, READWRITE, struct_pciio_bdf_cfgreg_sz); + _(PCI_IOC_BDF_CFGWRITE, READ, struct_pciio_bdf_cfgreg_sz); + _(PCI_IOC_BUSINFO, WRITE, struct_pciio_businfo_sz); + _(PCI_IOC_DRVNAME, READWRITE, struct_pciio_drvname_sz); + _(PCI_IOC_DRVNAMEONBUS, READWRITE, struct_pciio_drvnameonbus_sz); + /* Entries from file: dev/pci/tweio.h */ + _(TWEIO_COMMAND, READWRITE, struct_twe_usercommand_sz); + _(TWEIO_STATS, READWRITE, union_twe_statrequest_sz); + _(TWEIO_AEN_POLL, WRITE, sizeof(int)); + _(TWEIO_AEN_WAIT, WRITE, sizeof(int)); + _(TWEIO_SET_PARAM, READ, struct_twe_paramcommand_sz); + _(TWEIO_GET_PARAM, READ, struct_twe_paramcommand_sz); + _(TWEIO_RESET, NONE, 0); + _(TWEIO_ADD_UNIT, READ, struct_twe_drivecommand_sz); + _(TWEIO_DEL_UNIT, READ, struct_twe_drivecommand_sz); + /* Entries from file: dev/pcmcia/if_cnwioctl.h */ + _(SIOCSCNWDOMAIN, READ, struct_ifreq_sz); + _(SIOCGCNWDOMAIN, READWRITE, struct_ifreq_sz); + _(SIOCSCNWKEY, READWRITE, struct_ifreq_sz); + _(SIOCGCNWSTATUS, READWRITE, struct_cnwstatus_sz); + _(SIOCGCNWSTATS, READWRITE, struct_cnwistats_sz); + _(SIOCGCNWTRAIL, READWRITE, struct_cnwitrail_sz); + /* Entries from file: dev/pcmcia/if_rayreg.h */ + _(SIOCGRAYSIGLEV, READWRITE, struct_ifreq_sz); + /* Entries from file: dev/raidframe/raidframeio.h */ + _(RAIDFRAME_SHUTDOWN, NONE, 0); + _(RAIDFRAME_TUR, READ, sizeof(u64)); + _(RAIDFRAME_FAIL_DISK, READ, struct_rf_recon_req_sz); + _(RAIDFRAME_CHECK_RECON_STATUS, READWRITE, sizeof(int)); + _(RAIDFRAME_REWRITEPARITY, NONE, 0); + _(RAIDFRAME_COPYBACK, NONE, 0); + _(RAIDFRAME_SPARET_WAIT, WRITE, struct_RF_SparetWait_sz); + _(RAIDFRAME_SEND_SPARET, READ, sizeof(uptr)); + _(RAIDFRAME_ABORT_SPARET_WAIT, NONE, 0); + _(RAIDFRAME_START_ATRACE, NONE, 0); + _(RAIDFRAME_STOP_ATRACE, NONE, 0); + _(RAIDFRAME_GET_SIZE, WRITE, sizeof(int)); + _(RAIDFRAME_RESET_ACCTOTALS, NONE, 0); + _(RAIDFRAME_KEEP_ACCTOTALS, READ, sizeof(int)); + _(RAIDFRAME_GET_COMPONENT_LABEL, READWRITE, struct_RF_ComponentLabel_sz); + _(RAIDFRAME_SET_COMPONENT_LABEL, READ, struct_RF_ComponentLabel_sz); + _(RAIDFRAME_INIT_LABELS, READ, struct_RF_ComponentLabel_sz); + _(RAIDFRAME_ADD_HOT_SPARE, READ, struct_RF_SingleComponent_sz); + _(RAIDFRAME_REMOVE_HOT_SPARE, READ, struct_RF_SingleComponent_sz); + _(RAIDFRAME_REBUILD_IN_PLACE, READ, struct_RF_SingleComponent_sz); + _(RAIDFRAME_CHECK_PARITY, READWRITE, sizeof(int)); + _(RAIDFRAME_CHECK_PARITYREWRITE_STATUS, READWRITE, sizeof(int)); + _(RAIDFRAME_CHECK_COPYBACK_STATUS, READWRITE, sizeof(int)); + _(RAIDFRAME_SET_AUTOCONFIG, READWRITE, sizeof(int)); + _(RAIDFRAME_SET_ROOT, READWRITE, sizeof(int)); + _(RAIDFRAME_DELETE_COMPONENT, READ, struct_RF_SingleComponent_sz); + _(RAIDFRAME_INCORPORATE_HOT_SPARE, READ, struct_RF_SingleComponent_sz); + _(RAIDFRAME_CHECK_RECON_STATUS_EXT, READWRITE, struct_RF_ProgressInfo_sz); + _(RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT, READWRITE, + struct_RF_ProgressInfo_sz); + _(RAIDFRAME_CHECK_COPYBACK_STATUS_EXT, READWRITE, struct_RF_ProgressInfo_sz); + _(RAIDFRAME_PARITYMAP_STATUS, WRITE, struct_rf_pmstat_sz); + _(RAIDFRAME_PARITYMAP_GET_DISABLE, WRITE, sizeof(int)); + _(RAIDFRAME_PARITYMAP_SET_DISABLE, READ, sizeof(int)); + _(RAIDFRAME_PARITYMAP_SET_PARAMS, READ, struct_rf_pmparams_sz); + _(RAIDFRAME_SET_LAST_UNIT, READ, sizeof(int)); + _(RAIDFRAME_GET_INFO, READWRITE, sizeof(uptr)); + _(RAIDFRAME_CONFIGURE, READ, sizeof(uptr)); + /* Entries from file: dev/sbus/mbppio.h */ + _(MBPPIOCSPARAM, READ, struct_mbpp_param_sz); + _(MBPPIOCGPARAM, WRITE, struct_mbpp_param_sz); + _(MBPPIOCGSTAT, WRITE, sizeof(int)); + /* Entries from file: dev/scsipi/ses.h */ + _(SESIOC_GETNOBJ, NONE, 0); + _(SESIOC_GETOBJMAP, NONE, 0); + _(SESIOC_GETENCSTAT, NONE, 0); + _(SESIOC_SETENCSTAT, NONE, 0); + _(SESIOC_GETOBJSTAT, NONE, 0); + _(SESIOC_SETOBJSTAT, NONE, 0); + _(SESIOC_GETTEXT, NONE, 0); + _(SESIOC_INIT, NONE, 0); + /* Entries from file: dev/sun/disklabel.h */ + _(SUN_DKIOCGGEOM, WRITE, struct_sun_dkgeom_sz); + _(SUN_DKIOCINFO, WRITE, struct_sun_dkctlr_sz); + _(SUN_DKIOCGPART, WRITE, struct_sun_dkpart_sz); + /* Entries from file: dev/sun/fbio.h */ + _(FBIOGTYPE, WRITE, struct_fbtype_sz); + _(FBIOPUTCMAP, READ, struct_fbcmap_sz); + _(FBIOGETCMAP, READ, struct_fbcmap_sz); + _(FBIOGATTR, WRITE, struct_fbgattr_sz); + _(FBIOSVIDEO, READ, sizeof(int)); + _(FBIOGVIDEO, WRITE, sizeof(int)); + _(FBIOSCURSOR, READ, struct_fbcursor_sz); + _(FBIOGCURSOR, READWRITE, struct_fbcursor_sz); + _(FBIOSCURPOS, READ, struct_fbcurpos_sz); + _(FBIOGCURPOS, READ, struct_fbcurpos_sz); + _(FBIOGCURMAX, WRITE, struct_fbcurpos_sz); + /* Entries from file: dev/sun/kbio.h */ + _(KIOCTRANS, READ, sizeof(int)); + _(KIOCSETKEY, READWRITE, struct_okiockey_sz); + _(KIOCGETKEY, READWRITE, struct_okiockey_sz); + _(KIOCGTRANS, WRITE, sizeof(int)); + _(KIOCCMD, READ, sizeof(int)); + _(KIOCTYPE, WRITE, sizeof(int)); + _(KIOCSDIRECT, READ, sizeof(int)); + _(KIOCSKEY, READ, struct_kiockeymap_sz); + _(KIOCGKEY, READWRITE, struct_kiockeymap_sz); + _(KIOCSLED, READ, sizeof(char)); + _(KIOCGLED, WRITE, sizeof(char)); + _(KIOCLAYOUT, WRITE, sizeof(int)); + /* Entries from file: dev/sun/vuid_event.h */ + _(VUIDSFORMAT, READ, sizeof(int)); + _(VUIDGFORMAT, WRITE, sizeof(int)); + /* Entries from file: dev/tc/sticio.h */ + _(STICIO_GXINFO, WRITE, struct_stic_xinfo_sz); + _(STICIO_RESET, NONE, 0); + _(STICIO_STARTQ, NONE, 0); + _(STICIO_STOPQ, NONE, 0); + /* Entries from file: dev/usb/ukyopon.h */ + _(UKYOPON_IDENTIFY, WRITE, struct_ukyopon_identify_sz); + /* Entries from file: dev/usb/urio.h */ + _(URIO_SEND_COMMAND, READWRITE, struct_urio_command_sz); + _(URIO_RECV_COMMAND, READWRITE, struct_urio_command_sz); + /* Entries from file: dev/usb/usb.h */ + _(USB_REQUEST, READWRITE, struct_usb_ctl_request_sz); + _(USB_SETDEBUG, READ, sizeof(int)); + _(USB_DISCOVER, NONE, 0); + _(USB_DEVICEINFO, READWRITE, struct_usb_device_info_sz); + _(USB_DEVICEINFO_OLD, READWRITE, struct_usb_device_info_old_sz); + _(USB_DEVICESTATS, WRITE, struct_usb_device_stats_sz); + _(USB_GET_REPORT_DESC, WRITE, struct_usb_ctl_report_desc_sz); + _(USB_SET_IMMED, READ, sizeof(int)); + _(USB_GET_REPORT, READWRITE, struct_usb_ctl_report_sz); + _(USB_SET_REPORT, READ, struct_usb_ctl_report_sz); + _(USB_GET_REPORT_ID, WRITE, sizeof(int)); + _(USB_GET_CONFIG, WRITE, sizeof(int)); + _(USB_SET_CONFIG, READ, sizeof(int)); + _(USB_GET_ALTINTERFACE, READWRITE, struct_usb_alt_interface_sz); + _(USB_SET_ALTINTERFACE, READWRITE, struct_usb_alt_interface_sz); + _(USB_GET_NO_ALT, READWRITE, struct_usb_alt_interface_sz); + _(USB_GET_DEVICE_DESC, WRITE, struct_usb_device_descriptor_sz); + _(USB_GET_CONFIG_DESC, READWRITE, struct_usb_config_desc_sz); + _(USB_GET_INTERFACE_DESC, READWRITE, struct_usb_interface_desc_sz); + _(USB_GET_ENDPOINT_DESC, READWRITE, struct_usb_endpoint_desc_sz); + _(USB_GET_FULL_DESC, READWRITE, struct_usb_full_desc_sz); + _(USB_GET_STRING_DESC, READWRITE, struct_usb_string_desc_sz); + _(USB_DO_REQUEST, READWRITE, struct_usb_ctl_request_sz); + _(USB_GET_DEVICEINFO, WRITE, struct_usb_device_info_sz); + _(USB_GET_DEVICEINFO_OLD, WRITE, struct_usb_device_info_old_sz); + _(USB_SET_SHORT_XFER, READ, sizeof(int)); + _(USB_SET_TIMEOUT, READ, sizeof(int)); + _(USB_SET_BULK_RA, READ, sizeof(int)); + _(USB_SET_BULK_WB, READ, sizeof(int)); + _(USB_SET_BULK_RA_OPT, READ, struct_usb_bulk_ra_wb_opt_sz); + _(USB_SET_BULK_WB_OPT, READ, struct_usb_bulk_ra_wb_opt_sz); + _(USB_GET_CM_OVER_DATA, WRITE, sizeof(int)); + _(USB_SET_CM_OVER_DATA, READ, sizeof(int)); + /* Entries from file: dev/usb/utoppy.h */ + _(UTOPPYIOTURBO, READ, sizeof(int)); + _(UTOPPYIOREBOOT, NONE, 0); + _(UTOPPYIOSTATS, WRITE, struct_utoppy_stats_sz); + _(UTOPPYIORENAME, READ, struct_utoppy_rename_sz); + _(UTOPPYIOMKDIR, READ, sizeof(uptr)); + _(UTOPPYIODELETE, READ, sizeof(uptr)); + _(UTOPPYIOREADDIR, READ, sizeof(uptr)); + _(UTOPPYIOREADFILE, READ, struct_utoppy_readfile_sz); + _(UTOPPYIOWRITEFILE, READ, struct_utoppy_writefile_sz); + /* Entries from file: dev/vme/xio.h */ + _(DIOSXDCMD, READWRITE, struct_xd_iocmd_sz); + /* Entries from file: dev/wscons/wsdisplay_usl_io.h */ + _(VT_OPENQRY, WRITE, sizeof(int)); + _(VT_SETMODE, READ, struct_vt_mode_sz); + _(VT_GETMODE, WRITE, struct_vt_mode_sz); + _(VT_RELDISP, NONE, 0); + _(VT_ACTIVATE, NONE, 0); + _(VT_WAITACTIVE, NONE, 0); + _(VT_GETACTIVE, WRITE, sizeof(int)); + _(VT_GETSTATE, WRITE, struct_vt_stat_sz); + _(KDGETKBENT, READWRITE, struct_kbentry_sz); + _(KDGKBMODE, WRITE, sizeof(int)); + _(KDSKBMODE, NONE, 0); + _(KDMKTONE, NONE, 0); + _(KDSETMODE, NONE, 0); + _(KDENABIO, NONE, 0); + _(KDDISABIO, NONE, 0); + _(KDGKBTYPE, WRITE, sizeof(char)); + _(KDGETLED, WRITE, sizeof(int)); + _(KDSETLED, NONE, 0); + _(KDSETRAD, NONE, 0); + _(VGAPCVTID, READWRITE, struct_pcvtid_sz); + _(CONS_GETVERS, WRITE, sizeof(int)); + /* Entries from file: dev/wscons/wsconsio.h */ + _(WSKBDIO_GTYPE, WRITE, sizeof(unsigned int)); + _(WSKBDIO_BELL, NONE, 0); + _(WSKBDIO_COMPLEXBELL, READ, struct_wskbd_bell_data_sz); + _(WSKBDIO_SETBELL, READ, struct_wskbd_bell_data_sz); + _(WSKBDIO_GETBELL, WRITE, struct_wskbd_bell_data_sz); + _(WSKBDIO_SETDEFAULTBELL, READ, struct_wskbd_bell_data_sz); + _(WSKBDIO_GETDEFAULTBELL, WRITE, struct_wskbd_bell_data_sz); + _(WSKBDIO_SETKEYREPEAT, READ, struct_wskbd_keyrepeat_data_sz); + _(WSKBDIO_GETKEYREPEAT, WRITE, struct_wskbd_keyrepeat_data_sz); + _(WSKBDIO_SETDEFAULTKEYREPEAT, READ, struct_wskbd_keyrepeat_data_sz); + _(WSKBDIO_GETDEFAULTKEYREPEAT, WRITE, struct_wskbd_keyrepeat_data_sz); + _(WSKBDIO_SETLEDS, READ, sizeof(int)); + _(WSKBDIO_GETLEDS, WRITE, sizeof(int)); + _(WSKBDIO_GETMAP, READWRITE, struct_wskbd_map_data_sz); + _(WSKBDIO_SETMAP, READ, struct_wskbd_map_data_sz); + _(WSKBDIO_GETENCODING, WRITE, sizeof(int)); + _(WSKBDIO_SETENCODING, READ, sizeof(int)); + _(WSKBDIO_SETMODE, READ, sizeof(int)); + _(WSKBDIO_GETMODE, WRITE, sizeof(int)); + _(WSKBDIO_SETKEYCLICK, READ, sizeof(int)); + _(WSKBDIO_GETKEYCLICK, WRITE, sizeof(int)); + _(WSKBDIO_GETSCROLL, WRITE, struct_wskbd_scroll_data_sz); + _(WSKBDIO_SETSCROLL, READ, struct_wskbd_scroll_data_sz); + _(WSKBDIO_SETVERSION, READ, sizeof(int)); + _(WSMOUSEIO_GTYPE, WRITE, sizeof(unsigned int)); + _(WSMOUSEIO_SRES, READ, sizeof(unsigned int)); + _(WSMOUSEIO_SSCALE, READ, sizeof(unsigned int)); + _(WSMOUSEIO_SRATE, READ, sizeof(unsigned int)); + _(WSMOUSEIO_SCALIBCOORDS, READ, struct_wsmouse_calibcoords_sz); + _(WSMOUSEIO_GCALIBCOORDS, WRITE, struct_wsmouse_calibcoords_sz); + _(WSMOUSEIO_GETID, READWRITE, struct_wsmouse_id_sz); + _(WSMOUSEIO_GETREPEAT, WRITE, struct_wsmouse_repeat_sz); + _(WSMOUSEIO_SETREPEAT, READ, struct_wsmouse_repeat_sz); + _(WSMOUSEIO_SETVERSION, READ, sizeof(int)); + _(WSDISPLAYIO_GTYPE, WRITE, sizeof(unsigned int)); + _(WSDISPLAYIO_GINFO, WRITE, struct_wsdisplay_fbinfo_sz); + _(WSDISPLAYIO_GETCMAP, READ, struct_wsdisplay_cmap_sz); + _(WSDISPLAYIO_PUTCMAP, READ, struct_wsdisplay_cmap_sz); + _(WSDISPLAYIO_GVIDEO, WRITE, sizeof(unsigned int)); + _(WSDISPLAYIO_SVIDEO, READ, sizeof(unsigned int)); + _(WSDISPLAYIO_GCURPOS, WRITE, struct_wsdisplay_curpos_sz); + _(WSDISPLAYIO_SCURPOS, READ, struct_wsdisplay_curpos_sz); + _(WSDISPLAYIO_GCURMAX, WRITE, struct_wsdisplay_curpos_sz); + _(WSDISPLAYIO_GCURSOR, READWRITE, struct_wsdisplay_cursor_sz); + _(WSDISPLAYIO_SCURSOR, READ, struct_wsdisplay_cursor_sz); + _(WSDISPLAYIO_GMODE, WRITE, sizeof(unsigned int)); + _(WSDISPLAYIO_SMODE, READ, sizeof(unsigned int)); + _(WSDISPLAYIO_LDFONT, READ, struct_wsdisplay_font_sz); + _(WSDISPLAYIO_ADDSCREEN, READ, struct_wsdisplay_addscreendata_sz); + _(WSDISPLAYIO_DELSCREEN, READ, struct_wsdisplay_delscreendata_sz); + _(WSDISPLAYIO_SFONT, READ, struct_wsdisplay_usefontdata_sz); + _(_O_WSDISPLAYIO_SETKEYBOARD, READWRITE, struct_wsdisplay_kbddata_sz); + _(WSDISPLAYIO_GETPARAM, READWRITE, struct_wsdisplay_param_sz); + _(WSDISPLAYIO_SETPARAM, READWRITE, struct_wsdisplay_param_sz); + _(WSDISPLAYIO_GETACTIVESCREEN, WRITE, sizeof(int)); + _(WSDISPLAYIO_GETWSCHAR, READWRITE, struct_wsdisplay_char_sz); + _(WSDISPLAYIO_PUTWSCHAR, READWRITE, struct_wsdisplay_char_sz); + _(WSDISPLAYIO_DGSCROLL, WRITE, struct_wsdisplay_scroll_data_sz); + _(WSDISPLAYIO_DSSCROLL, READ, struct_wsdisplay_scroll_data_sz); + _(WSDISPLAYIO_GMSGATTRS, WRITE, struct_wsdisplay_msgattrs_sz); + _(WSDISPLAYIO_SMSGATTRS, READ, struct_wsdisplay_msgattrs_sz); + _(WSDISPLAYIO_GBORDER, WRITE, sizeof(int)); + _(WSDISPLAYIO_SBORDER, READ, sizeof(int)); + _(WSDISPLAYIO_SSPLASH, READ, sizeof(int)); + _(WSDISPLAYIO_SPROGRESS, READ, sizeof(int)); + _(WSDISPLAYIO_LINEBYTES, WRITE, sizeof(unsigned int)); + _(WSDISPLAYIO_SETVERSION, READ, sizeof(int)); + _(WSMUXIO_ADD_DEVICE, READ, struct_wsmux_device_sz); + _(WSMUXIO_REMOVE_DEVICE, READ, struct_wsmux_device_sz); + _(WSMUXIO_LIST_DEVICES, READWRITE, struct_wsmux_device_list_sz); + _(WSMUXIO_INJECTEVENT, READ, struct_wscons_event_sz); + _(WSDISPLAYIO_GET_BUSID, WRITE, struct_wsdisplayio_bus_id_sz); + _(WSDISPLAYIO_GET_EDID, READWRITE, struct_wsdisplayio_edid_info_sz); + _(WSDISPLAYIO_SET_POLLING, READ, sizeof(int)); + _(WSDISPLAYIO_GET_FBINFO, READWRITE, struct_wsdisplayio_fbinfo_sz); + _(WSDISPLAYIO_DOBLIT, READWRITE, struct_wsdisplayio_blit_sz); + _(WSDISPLAYIO_WAITBLIT, READWRITE, struct_wsdisplayio_blit_sz); + /* Entries from file: dev/biovar.h */ + _(BIOCLOCATE, READWRITE, struct_bio_locate_sz); + _(BIOCINQ, READWRITE, struct_bioc_inq_sz); + _(BIOCDISK_NOVOL, READWRITE, struct_bioc_disk_sz); + _(BIOCDISK, READWRITE, struct_bioc_disk_sz); + _(BIOCVOL, READWRITE, struct_bioc_vol_sz); + _(BIOCALARM, READWRITE, struct_bioc_alarm_sz); + _(BIOCBLINK, READWRITE, struct_bioc_blink_sz); + _(BIOCSETSTATE, READWRITE, struct_bioc_setstate_sz); + _(BIOCVOLOPS, READWRITE, struct_bioc_volops_sz); + /* Entries from file: dev/md.h */ + _(MD_GETCONF, WRITE, struct_md_conf_sz); + _(MD_SETCONF, READ, struct_md_conf_sz); + /* Entries from file: dev/ccdvar.h */ + _(CCDIOCSET, READWRITE, struct_ccd_ioctl_sz); + _(CCDIOCCLR, READ, struct_ccd_ioctl_sz); + /* Entries from file: dev/cgdvar.h */ + _(CGDIOCSET, READWRITE, struct_cgd_ioctl_sz); + _(CGDIOCCLR, READ, struct_cgd_ioctl_sz); + _(CGDIOCGET, READWRITE, struct_cgd_user_sz); + /* Entries from file: dev/fssvar.h */ + _(FSSIOCSET, READ, struct_fss_set_sz); + _(FSSIOCGET, WRITE, struct_fss_get_sz); + _(FSSIOCCLR, NONE, 0); + _(FSSIOFSET, READ, sizeof(int)); + _(FSSIOFGET, WRITE, sizeof(int)); + /* Entries from file: dev/bluetooth/btdev.h */ + _(BTDEV_ATTACH, READ, struct_plistref_sz); + _(BTDEV_DETACH, READ, struct_plistref_sz); + /* Entries from file: dev/bluetooth/btsco.h */ + _(BTSCO_GETINFO, WRITE, struct_btsco_info_sz); + /* Entries from file: dev/kttcpio.h */ + _(KTTCP_IO_SEND, READWRITE, struct_kttcp_io_args_sz); + _(KTTCP_IO_RECV, READWRITE, struct_kttcp_io_args_sz); + /* Entries from file: dev/lockstat.h */ + _(IOC_LOCKSTAT_GVERSION, WRITE, sizeof(int)); + _(IOC_LOCKSTAT_ENABLE, READ, struct_lsenable_sz); + _(IOC_LOCKSTAT_DISABLE, WRITE, struct_lsdisable_sz); + /* Entries from file: dev/vndvar.h */ + _(VNDIOCSET, READWRITE, struct_vnd_ioctl_sz); + _(VNDIOCCLR, READ, struct_vnd_ioctl_sz); + _(VNDIOCGET, READWRITE, struct_vnd_user_sz); + /* Entries from file: dev/spkrio.h */ + _(SPKRTONE, READ, struct_tone_sz); + _(SPKRTUNE, NONE, 0); + _(SPKRGETVOL, WRITE, sizeof(unsigned int)); + _(SPKRSETVOL, READ, sizeof(unsigned int)); + /* Entries from file: net/bpf.h */ + _(BIOCGBLEN, WRITE, sizeof(unsigned int)); + _(BIOCSBLEN, READWRITE, sizeof(unsigned int)); + _(BIOCSETF, READ, struct_bpf_program_sz); + _(BIOCFLUSH, NONE, 0); + _(BIOCPROMISC, NONE, 0); + _(BIOCGDLT, WRITE, sizeof(unsigned int)); + _(BIOCGETIF, WRITE, struct_ifreq_sz); + _(BIOCSETIF, READ, struct_ifreq_sz); + _(BIOCGSTATS, WRITE, struct_bpf_stat_sz); + _(BIOCGSTATSOLD, WRITE, struct_bpf_stat_old_sz); + _(BIOCIMMEDIATE, READ, sizeof(unsigned int)); + _(BIOCVERSION, WRITE, struct_bpf_version_sz); + _(BIOCSTCPF, READ, struct_bpf_program_sz); + _(BIOCSUDPF, READ, struct_bpf_program_sz); + _(BIOCGHDRCMPLT, WRITE, sizeof(unsigned int)); + _(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)); + _(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); + _(GREGADDRS, READWRITE, struct_ifreq_sz); + _(GREGADDRD, READWRITE, struct_ifreq_sz); + _(GRESPROTO, READ, struct_ifreq_sz); + _(GREGPROTO, READWRITE, struct_ifreq_sz); + _(GRESSOCK, READ, struct_ifreq_sz); + _(GREDSOCK, READ, struct_ifreq_sz); + /* Entries from file: net/if_ppp.h */ + _(PPPIOCGRAWIN, WRITE, struct_ppp_rawin_sz); + _(PPPIOCGFLAGS, WRITE, sizeof(int)); + _(PPPIOCSFLAGS, READ, sizeof(int)); + _(PPPIOCGASYNCMAP, WRITE, sizeof(int)); + _(PPPIOCSASYNCMAP, READ, sizeof(int)); + _(PPPIOCGUNIT, WRITE, sizeof(int)); + _(PPPIOCGRASYNCMAP, WRITE, sizeof(int)); + _(PPPIOCSRASYNCMAP, READ, sizeof(int)); + _(PPPIOCGMRU, WRITE, sizeof(int)); + _(PPPIOCSMRU, READ, sizeof(int)); + _(PPPIOCSMAXCID, READ, sizeof(int)); + _(PPPIOCGXASYNCMAP, WRITE, (8 * sizeof(u32))); + _(PPPIOCSXASYNCMAP, READ, (8 * sizeof(u32))); + _(PPPIOCXFERUNIT, NONE, 0); + _(PPPIOCSCOMPRESS, READ, struct_ppp_option_data_sz); + _(PPPIOCGNPMODE, READWRITE, struct_npioctl_sz); + _(PPPIOCSNPMODE, READ, struct_npioctl_sz); + _(PPPIOCGIDLE, WRITE, struct_ppp_idle_sz); + _(PPPIOCGMTU, WRITE, sizeof(int)); + _(PPPIOCSMTU, READ, sizeof(int)); + _(SIOCGPPPSTATS, READWRITE, struct_ifpppstatsreq_sz); + _(SIOCGPPPCSTATS, READWRITE, struct_ifpppcstatsreq_sz); + /* 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_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); + /* Entries from file: net/if_pppoe.h */ + _(PPPOESETPARMS, READ, struct_pppoediscparms_sz); + _(PPPOEGETPARMS, READWRITE, struct_pppoediscparms_sz); + _(PPPOEGETSESSION, READWRITE, struct_pppoeconnectionstate_sz); + /* Entries from file: net/if_sppp.h */ + _(SPPPGETAUTHCFG, READWRITE, struct_spppauthcfg_sz); + _(SPPPSETAUTHCFG, READ, struct_spppauthcfg_sz); + _(SPPPGETLCPCFG, READWRITE, struct_sppplcpcfg_sz); + _(SPPPSETLCPCFG, READ, struct_sppplcpcfg_sz); + _(SPPPGETSTATUS, READWRITE, struct_spppstatus_sz); + _(SPPPGETSTATUSNCP, READWRITE, struct_spppstatusncp_sz); + _(SPPPGETIDLETO, READWRITE, struct_spppidletimeout_sz); + _(SPPPSETIDLETO, READ, struct_spppidletimeout_sz); + _(SPPPGETAUTHFAILURES, READWRITE, struct_spppauthfailurestats_sz); + _(SPPPSETAUTHFAILURE, READ, struct_spppauthfailuresettings_sz); + _(SPPPSETDNSOPTS, READ, struct_spppdnssettings_sz); + _(SPPPGETDNSOPTS, READWRITE, struct_spppdnssettings_sz); + _(SPPPGETDNSADDRS, READWRITE, struct_spppdnsaddrs_sz); + _(SPPPSETKEEPALIVE, READ, struct_spppkeepalivesettings_sz); + _(SPPPGETKEEPALIVE, READWRITE, struct_spppkeepalivesettings_sz); + /* Entries from file: net/if_srt.h */ + _(SRT_GETNRT, WRITE, sizeof(unsigned int)); + _(SRT_GETRT, READWRITE, struct_srt_rt_sz); + _(SRT_SETRT, READ, struct_srt_rt_sz); + _(SRT_DELRT, READ, sizeof(unsigned int)); + _(SRT_SFLAGS, READ, sizeof(unsigned int)); + _(SRT_GFLAGS, WRITE, sizeof(unsigned int)); + _(SRT_SGFLAGS, READWRITE, sizeof(unsigned int)); + _(SRT_DEBUG, READ, sizeof(uptr)); + /* Entries from file: net/if_tap.h */ + _(TAPGIFNAME, WRITE, struct_ifreq_sz); + /* Entries from file: net/if_tun.h */ + _(TUNSDEBUG, READ, sizeof(int)); + _(TUNGDEBUG, WRITE, sizeof(int)); + _(TUNSIFMODE, READ, sizeof(int)); + _(TUNSIFHEAD, READ, sizeof(int)); + _(TUNGIFHEAD, WRITE, sizeof(int)); + /* Entries from file: net/pfvar.h */ + _(DIOCSTART, NONE, 0); + _(DIOCSTOP, NONE, 0); + _(DIOCADDRULE, READWRITE, struct_pfioc_rule_sz); + _(DIOCGETRULES, READWRITE, struct_pfioc_rule_sz); + _(DIOCGETRULE, READWRITE, struct_pfioc_rule_sz); + _(DIOCSETLCK, READWRITE, sizeof(u32)); + _(DIOCCLRSTATES, READWRITE, struct_pfioc_state_kill_sz); + _(DIOCGETSTATE, READWRITE, struct_pfioc_state_sz); + _(DIOCSETSTATUSIF, READWRITE, struct_pfioc_if_sz); + _(DIOCGETSTATUS, READWRITE, struct_pf_status_sz); + _(DIOCCLRSTATUS, NONE, 0); + _(DIOCNATLOOK, READWRITE, struct_pfioc_natlook_sz); + _(DIOCSETDEBUG, READWRITE, sizeof(u32)); + _(DIOCGETSTATES, READWRITE, struct_pfioc_states_sz); + _(DIOCCHANGERULE, READWRITE, struct_pfioc_rule_sz); + _(DIOCSETTIMEOUT, READWRITE, struct_pfioc_tm_sz); + _(DIOCGETTIMEOUT, READWRITE, struct_pfioc_tm_sz); + _(DIOCADDSTATE, READWRITE, struct_pfioc_state_sz); + _(DIOCCLRRULECTRS, NONE, 0); + _(DIOCGETLIMIT, READWRITE, struct_pfioc_limit_sz); + _(DIOCSETLIMIT, READWRITE, struct_pfioc_limit_sz); + _(DIOCKILLSTATES, READWRITE, struct_pfioc_state_kill_sz); + _(DIOCSTARTALTQ, NONE, 0); + _(DIOCSTOPALTQ, NONE, 0); + _(DIOCADDALTQ, READWRITE, struct_pfioc_altq_sz); + _(DIOCGETALTQS, READWRITE, struct_pfioc_altq_sz); + _(DIOCGETALTQ, READWRITE, struct_pfioc_altq_sz); + _(DIOCCHANGEALTQ, READWRITE, struct_pfioc_altq_sz); + _(DIOCGETQSTATS, READWRITE, struct_pfioc_qstats_sz); + _(DIOCBEGINADDRS, READWRITE, struct_pfioc_pooladdr_sz); + _(DIOCADDADDR, READWRITE, struct_pfioc_pooladdr_sz); + _(DIOCGETADDRS, READWRITE, struct_pfioc_pooladdr_sz); + _(DIOCGETADDR, READWRITE, struct_pfioc_pooladdr_sz); + _(DIOCCHANGEADDR, READWRITE, struct_pfioc_pooladdr_sz); + _(DIOCADDSTATES, READWRITE, struct_pfioc_states_sz); + _(DIOCGETRULESETS, READWRITE, struct_pfioc_ruleset_sz); + _(DIOCGETRULESET, READWRITE, struct_pfioc_ruleset_sz); + _(DIOCRCLRTABLES, READWRITE, struct_pfioc_table_sz); + _(DIOCRADDTABLES, READWRITE, struct_pfioc_table_sz); + _(DIOCRDELTABLES, READWRITE, struct_pfioc_table_sz); + _(DIOCRGETTABLES, READWRITE, struct_pfioc_table_sz); + _(DIOCRGETTSTATS, READWRITE, struct_pfioc_table_sz); + _(DIOCRCLRTSTATS, READWRITE, struct_pfioc_table_sz); + _(DIOCRCLRADDRS, READWRITE, struct_pfioc_table_sz); + _(DIOCRADDADDRS, READWRITE, struct_pfioc_table_sz); + _(DIOCRDELADDRS, READWRITE, struct_pfioc_table_sz); + _(DIOCRSETADDRS, READWRITE, struct_pfioc_table_sz); + _(DIOCRGETADDRS, READWRITE, struct_pfioc_table_sz); + _(DIOCRGETASTATS, READWRITE, struct_pfioc_table_sz); + _(DIOCRCLRASTATS, READWRITE, struct_pfioc_table_sz); + _(DIOCRTSTADDRS, READWRITE, struct_pfioc_table_sz); + _(DIOCRSETTFLAGS, READWRITE, struct_pfioc_table_sz); + _(DIOCRINADEFINE, READWRITE, struct_pfioc_table_sz); + _(DIOCOSFPFLUSH, NONE, 0); + _(DIOCOSFPADD, READWRITE, struct_pf_osfp_ioctl_sz); + _(DIOCOSFPGET, READWRITE, struct_pf_osfp_ioctl_sz); + _(DIOCXBEGIN, READWRITE, struct_pfioc_trans_sz); + _(DIOCXCOMMIT, READWRITE, struct_pfioc_trans_sz); + _(DIOCXROLLBACK, READWRITE, struct_pfioc_trans_sz); + _(DIOCGETSRCNODES, READWRITE, struct_pfioc_src_nodes_sz); + _(DIOCCLRSRCNODES, NONE, 0); + _(DIOCSETHOSTID, READWRITE, sizeof(u32)); + _(DIOCIGETIFACES, READWRITE, struct_pfioc_iface_sz); + _(DIOCSETIFFLAG, READWRITE, struct_pfioc_iface_sz); + _(DIOCCLRIFFLAG, READWRITE, struct_pfioc_iface_sz); + _(DIOCKILLSRCNODES, READWRITE, struct_pfioc_src_node_kill_sz); + /* Entries from file: netbt/hci.h */ + _(SIOCGBTINFO, READWRITE, struct_btreq_sz); + _(SIOCGBTINFOA, READWRITE, struct_btreq_sz); + _(SIOCNBTINFO, READWRITE, struct_btreq_sz); + _(SIOCSBTFLAGS, READWRITE, struct_btreq_sz); + _(SIOCSBTPOLICY, READWRITE, struct_btreq_sz); + _(SIOCSBTPTYPE, READWRITE, struct_btreq_sz); + _(SIOCGBTSTATS, READWRITE, struct_btreq_sz); + _(SIOCZBTSTATS, READWRITE, struct_btreq_sz); + _(SIOCBTDUMP, READ, struct_btreq_sz); + _(SIOCSBTSCOMTU, READWRITE, struct_btreq_sz); + _(SIOCGBTFEAT, READWRITE, struct_btreq_sz); + /* Entries from file: netinet/ip_nat.h */ + _(SIOCADNAT, READ, struct_ipfobj_sz); + _(SIOCRMNAT, READ, struct_ipfobj_sz); + _(SIOCGNATS, READWRITE, struct_ipfobj_sz); + _(SIOCGNATL, READWRITE, struct_ipfobj_sz); + _(SIOCPURGENAT, READWRITE, struct_ipfobj_sz); + /* Entries from file: netinet6/in6_var.h */ + _(SIOCSIFINFO_FLAGS, READWRITE, struct_in6_ndireq_sz); + _(SIOCAADDRCTL_POLICY, READ, struct_in6_addrpolicy_sz); + _(SIOCDADDRCTL_POLICY, READ, struct_in6_addrpolicy_sz); + /* Entries from file: netsmb/smb_dev.h */ + _(SMBIOC_OPENSESSION, READ, struct_smbioc_ossn_sz); + _(SMBIOC_OPENSHARE, READ, struct_smbioc_oshare_sz); + _(SMBIOC_REQUEST, READWRITE, struct_smbioc_rq_sz); + _(SMBIOC_SETFLAGS, READ, struct_smbioc_flags_sz); + _(SMBIOC_LOOKUP, READ, struct_smbioc_lookup_sz); + _(SMBIOC_READ, READWRITE, struct_smbioc_rw_sz); + _(SMBIOC_WRITE, READWRITE, struct_smbioc_rw_sz); + /* Entries from file: sys/agpio.h */ + _(AGPIOC_INFO, WRITE, struct__agp_info_sz); + _(AGPIOC_ACQUIRE, NONE, 0); + _(AGPIOC_RELEASE, NONE, 0); + _(AGPIOC_SETUP, READ, struct__agp_setup_sz); + _(AGPIOC_ALLOCATE, READWRITE, struct__agp_allocate_sz); + _(AGPIOC_DEALLOCATE, READ, sizeof(int)); + _(AGPIOC_BIND, READ, struct__agp_bind_sz); + _(AGPIOC_UNBIND, READ, struct__agp_unbind_sz); + /* Entries from file: sys/audioio.h */ + _(AUDIO_GETINFO, WRITE, struct_audio_info_sz); + _(AUDIO_SETINFO, READWRITE, struct_audio_info_sz); + _(AUDIO_DRAIN, NONE, 0); + _(AUDIO_FLUSH, NONE, 0); + _(AUDIO_WSEEK, WRITE, sizeof(unsigned long)); + _(AUDIO_RERROR, WRITE, sizeof(int)); + _(AUDIO_GETDEV, WRITE, struct_audio_device_sz); + _(AUDIO_GETENC, READWRITE, struct_audio_encoding_sz); + _(AUDIO_GETFD, WRITE, sizeof(int)); + _(AUDIO_SETFD, READWRITE, sizeof(int)); + _(AUDIO_PERROR, WRITE, sizeof(int)); + _(AUDIO_GETIOFFS, WRITE, struct_audio_offset_sz); + _(AUDIO_GETOOFFS, WRITE, struct_audio_offset_sz); + _(AUDIO_GETPROPS, WRITE, sizeof(int)); + _(AUDIO_GETBUFINFO, WRITE, struct_audio_info_sz); + _(AUDIO_SETCHAN, READ, sizeof(int)); + _(AUDIO_GETCHAN, WRITE, sizeof(int)); + _(AUDIO_MIXER_READ, READWRITE, struct_mixer_ctrl_sz); + _(AUDIO_MIXER_WRITE, READWRITE, struct_mixer_ctrl_sz); + _(AUDIO_MIXER_DEVINFO, READWRITE, struct_mixer_devinfo_sz); + /* Entries from file: sys/ataio.h */ + _(ATAIOCCOMMAND, READWRITE, struct_atareq_sz); + _(ATABUSIOSCAN, READ, struct_atabusioscan_args_sz); + _(ATABUSIORESET, NONE, 0); + _(ATABUSIODETACH, READ, struct_atabusiodetach_args_sz); + /* Entries from file: sys/cdio.h */ + _(CDIOCPLAYTRACKS, READ, struct_ioc_play_track_sz); + _(CDIOCPLAYBLOCKS, READ, struct_ioc_play_blocks_sz); + _(CDIOCREADSUBCHANNEL, READWRITE, struct_ioc_read_subchannel_sz); + _(CDIOREADTOCHEADER, WRITE, struct_ioc_toc_header_sz); + _(CDIOREADTOCENTRIES, READWRITE, struct_ioc_read_toc_entry_sz); + _(CDIOREADMSADDR, READWRITE, sizeof(int)); + _(CDIOCSETPATCH, READ, struct_ioc_patch_sz); + _(CDIOCGETVOL, WRITE, struct_ioc_vol_sz); + _(CDIOCSETVOL, READ, struct_ioc_vol_sz); + _(CDIOCSETMONO, NONE, 0); + _(CDIOCSETSTEREO, NONE, 0); + _(CDIOCSETMUTE, NONE, 0); + _(CDIOCSETLEFT, NONE, 0); + _(CDIOCSETRIGHT, NONE, 0); + _(CDIOCSETDEBUG, NONE, 0); + _(CDIOCCLRDEBUG, NONE, 0); + _(CDIOCPAUSE, NONE, 0); + _(CDIOCRESUME, NONE, 0); + _(CDIOCRESET, NONE, 0); + _(CDIOCSTART, NONE, 0); + _(CDIOCSTOP, NONE, 0); + _(CDIOCEJECT, NONE, 0); + _(CDIOCALLOW, NONE, 0); + _(CDIOCPREVENT, NONE, 0); + _(CDIOCCLOSE, NONE, 0); + _(CDIOCPLAYMSF, READ, struct_ioc_play_msf_sz); + _(CDIOCLOADUNLOAD, READ, struct_ioc_load_unload_sz); + /* Entries from file: sys/chio.h */ + _(CHIOMOVE, READ, struct_changer_move_request_sz); + _(CHIOEXCHANGE, READ, struct_changer_exchange_request_sz); + _(CHIOPOSITION, READ, struct_changer_position_request_sz); + _(CHIOSPICKER, READ, sizeof(int)); + _(CHIOGPARAMS, WRITE, struct_changer_params_sz); + _(CHIOIELEM, NONE, 0); + _(OCHIOGSTATUS, READ, struct_ochanger_element_status_request_sz); + _(CHIOGSTATUS, READ, struct_changer_element_status_request_sz); + _(CHIOSVOLTAG, READ, struct_changer_set_voltag_request_sz); + /* Entries from file: sys/clockctl.h */ + _(CLOCKCTL_SETTIMEOFDAY, READ, struct_clockctl_settimeofday_sz); + _(CLOCKCTL_ADJTIME, READWRITE, struct_clockctl_adjtime_sz); + _(CLOCKCTL_CLOCK_SETTIME, READ, struct_clockctl_clock_settime_sz); + _(CLOCKCTL_NTP_ADJTIME, READWRITE, struct_clockctl_ntp_adjtime_sz); + /* Entries from file: sys/cpuio.h */ + _(IOC_CPU_SETSTATE, READ, struct_cpustate_sz); + _(IOC_CPU_GETSTATE, READWRITE, struct_cpustate_sz); + _(IOC_CPU_GETCOUNT, WRITE, sizeof(int)); + _(IOC_CPU_MAPID, READWRITE, sizeof(int)); + _(IOC_CPU_UCODE_GET_VERSION, READWRITE, struct_cpu_ucode_version_sz); + _(IOC_CPU_UCODE_APPLY, READ, struct_cpu_ucode_sz); + /* Entries from file: sys/dkio.h */ + _(DIOCGDINFO, WRITE, struct_disklabel_sz); + _(DIOCSDINFO, READ, struct_disklabel_sz); + _(DIOCWDINFO, READ, 0); + _(DIOCRFORMAT, READWRITE, struct_format_op_sz); + _(DIOCWFORMAT, READWRITE, struct_format_op_sz); + _(DIOCSSTEP, READ, sizeof(int)); + _(DIOCSRETRIES, READ, sizeof(int)); + _(DIOCKLABEL, READ, sizeof(int)); + _(DIOCWLABEL, READ, sizeof(int)); + _(DIOCSBAD, READ, struct_dkbad_sz); + _(DIOCEJECT, READ, sizeof(int)); + _(ODIOCEJECT, NONE, 0); + _(DIOCLOCK, READ, sizeof(int)); + _(DIOCGDEFLABEL, WRITE, struct_disklabel_sz); + _(DIOCCLRLABEL, NONE, 0); + _(DIOCGCACHE, WRITE, sizeof(int)); + _(DIOCSCACHE, READ, sizeof(int)); + _(DIOCCACHESYNC, READ, sizeof(int)); + _(DIOCBSLIST, READWRITE, struct_disk_badsecinfo_sz); + _(DIOCBSFLUSH, NONE, 0); + _(DIOCAWEDGE, READWRITE, struct_dkwedge_info_sz); + _(DIOCGWEDGEINFO, WRITE, struct_dkwedge_info_sz); + _(DIOCDWEDGE, READ, struct_dkwedge_info_sz); + _(DIOCLWEDGES, READWRITE, struct_dkwedge_list_sz); + _(DIOCGSTRATEGY, WRITE, struct_disk_strategy_sz); + _(DIOCSSTRATEGY, READ, struct_disk_strategy_sz); + _(DIOCGDISKINFO, WRITE, struct_plistref_sz); + _(DIOCTUR, WRITE, sizeof(int)); + _(DIOCMWEDGES, WRITE, sizeof(int)); + _(DIOCGSECTORSIZE, WRITE, sizeof(unsigned int)); + _(DIOCGMEDIASIZE, WRITE, sizeof(uptr)); + /* Entries from file: sys/drvctlio.h */ + _(DRVDETACHDEV, READ, struct_devdetachargs_sz); + _(DRVRESCANBUS, READ, struct_devrescanargs_sz); + _(DRVCTLCOMMAND, READWRITE, struct_plistref_sz); + _(DRVRESUMEDEV, READ, struct_devpmargs_sz); + _(DRVLISTDEV, READWRITE, struct_devlistargs_sz); + _(DRVGETEVENT, WRITE, struct_plistref_sz); + _(DRVSUSPENDDEV, READ, struct_devpmargs_sz); + /* Entries from file: sys/dvdio.h */ + _(DVD_READ_STRUCT, READWRITE, union_dvd_struct_sz); + _(DVD_WRITE_STRUCT, READWRITE, union_dvd_struct_sz); + _(DVD_AUTH, READWRITE, union_dvd_authinfo_sz); + /* Entries from file: sys/envsys.h */ + _(ENVSYS_GETDICTIONARY, READWRITE, struct_plistref_sz); + _(ENVSYS_SETDICTIONARY, READWRITE, struct_plistref_sz); + _(ENVSYS_REMOVEPROPS, READWRITE, struct_plistref_sz); + _(ENVSYS_GTREDATA, READWRITE, struct_envsys_tre_data_sz); + _(ENVSYS_GTREINFO, READWRITE, struct_envsys_basic_info_sz); + /* Entries from file: sys/event.h */ + _(KFILTER_BYFILTER, READWRITE, struct_kfilter_mapping_sz); + _(KFILTER_BYNAME, READWRITE, struct_kfilter_mapping_sz); + /* Entries from file: sys/fdio.h */ + _(FDIOCGETOPTS, WRITE, 0); + _(FDIOCSETOPTS, READ, sizeof(int)); + _(FDIOCSETFORMAT, READ, struct_fdformat_parms_sz); + _(FDIOCGETFORMAT, WRITE, struct_fdformat_parms_sz); + _(FDIOCFORMAT_TRACK, READ, struct_fdformat_cmd_sz); + /* Entries from file: sys/filio.h */ + _(FIOCLEX, NONE, 0); + _(FIONCLEX, NONE, 0); + _(FIONREAD, WRITE, sizeof(int)); + _(FIONBIO, READ, sizeof(int)); + _(FIOASYNC, READ, sizeof(int)); + _(FIOSETOWN, READ, sizeof(int)); + _(FIOGETOWN, WRITE, sizeof(int)); + _(OFIOGETBMAP, READWRITE, sizeof(u32)); + _(FIOGETBMAP, READWRITE, sizeof(u64)); + _(FIONWRITE, WRITE, sizeof(int)); + _(FIONSPACE, WRITE, sizeof(int)); + /* Entries from file: sys/gpio.h */ + _(GPIOINFO, WRITE, struct_gpio_info_sz); + _(GPIOSET, READWRITE, struct_gpio_set_sz); + _(GPIOUNSET, READWRITE, struct_gpio_set_sz); + _(GPIOREAD, READWRITE, struct_gpio_req_sz); + _(GPIOWRITE, READWRITE, struct_gpio_req_sz); + _(GPIOTOGGLE, READWRITE, struct_gpio_req_sz); + _(GPIOATTACH, READWRITE, struct_gpio_attach_sz); + /* Entries from file: sys/ioctl.h */ + _(PTIOCNETBSD, READ, struct_ioctl_pt_sz); + _(PTIOCSUNOS, READ, struct_ioctl_pt_sz); + _(PTIOCLINUX, READ, struct_ioctl_pt_sz); + _(PTIOCFREEBSD, READ, struct_ioctl_pt_sz); + _(PTIOCULTRIX, READ, struct_ioctl_pt_sz); + /* Entries from file: sys/ioctl_compat.h */ + _(TIOCHPCL, NONE, 0); + _(TIOCGETP, WRITE, struct_sgttyb_sz); + _(TIOCSETP, READ, struct_sgttyb_sz); + _(TIOCSETN, READ, 0); + _(TIOCSETC, READ, struct_tchars_sz); + _(TIOCGETC, WRITE, struct_tchars_sz); + _(TIOCLBIS, READ, sizeof(int)); + _(TIOCLBIC, READ, sizeof(int)); + _(TIOCLSET, READ, sizeof(int)); + _(TIOCLGET, WRITE, sizeof(int)); + _(TIOCSLTC, READ, struct_ltchars_sz); + _(TIOCGLTC, WRITE, struct_ltchars_sz); + _(OTIOCCONS, NONE, 0); + /* Entries from file: sys/joystick.h */ + _(JOY_SETTIMEOUT, READ, sizeof(int)); + _(JOY_GETTIMEOUT, WRITE, sizeof(int)); + _(JOY_SET_X_OFFSET, READ, sizeof(int)); + _(JOY_SET_Y_OFFSET, READ, sizeof(int)); + _(JOY_GET_Y_OFFSET, WRITE, sizeof(int)); + /* Entries from file: sys/ksyms.h */ + _(OKIOCGSYMBOL, READ, struct_ksyms_ogsymbol_sz); + _(OKIOCGVALUE, READ, struct_ksyms_ogsymbol_sz); + _(KIOCGSIZE, WRITE, sizeof(int)); + _(KIOCGVALUE, READWRITE, struct_ksyms_gvalue_sz); + _(KIOCGSYMBOL, READWRITE, struct_ksyms_gsymbol_sz); + /* Entries from file: sys/lua.h */ + _(LUAINFO, READWRITE, struct_lua_info_sz); + _(LUACREATE, READWRITE, struct_lua_create_sz); + _(LUADESTROY, READWRITE, struct_lua_create_sz); + _(LUAREQUIRE, READWRITE, struct_lua_require_sz); + _(LUALOAD, READWRITE, struct_lua_load_sz); + /* Entries from file: sys/midiio.h */ + _(MIDI_PRETIME, READWRITE, sizeof(int)); + _(MIDI_MPUMODE, READWRITE, sizeof(int)); + _(MIDI_MPUCMD, READWRITE, struct_mpu_command_rec_sz); + _(SEQUENCER_RESET, NONE, 0); + _(SEQUENCER_SYNC, NONE, 0); + _(SEQUENCER_INFO, READWRITE, struct_synth_info_sz); + _(SEQUENCER_CTRLRATE, READWRITE, sizeof(int)); + _(SEQUENCER_GETOUTCOUNT, WRITE, sizeof(int)); + _(SEQUENCER_GETINCOUNT, WRITE, sizeof(int)); + _(SEQUENCER_RESETSAMPLES, READ, sizeof(int)); + _(SEQUENCER_NRSYNTHS, WRITE, sizeof(int)); + _(SEQUENCER_NRMIDIS, WRITE, sizeof(int)); + _(SEQUENCER_THRESHOLD, READ, sizeof(int)); + _(SEQUENCER_MEMAVL, READWRITE, sizeof(int)); + _(SEQUENCER_PANIC, NONE, 0); + _(SEQUENCER_OUTOFBAND, READ, struct_seq_event_rec_sz); + _(SEQUENCER_GETTIME, WRITE, sizeof(int)); + _(SEQUENCER_TMR_TIMEBASE, READWRITE, sizeof(int)); + _(SEQUENCER_TMR_START, NONE, 0); + _(SEQUENCER_TMR_STOP, NONE, 0); + _(SEQUENCER_TMR_CONTINUE, NONE, 0); + _(SEQUENCER_TMR_TEMPO, READWRITE, sizeof(int)); + _(SEQUENCER_TMR_SOURCE, READWRITE, sizeof(int)); + _(SEQUENCER_TMR_METRONOME, READ, sizeof(int)); + _(SEQUENCER_TMR_SELECT, READ, sizeof(int)); + /* Entries from file: sys/mtio.h */ + _(MTIOCTOP, READ, struct_mtop_sz); + _(MTIOCGET, WRITE, struct_mtget_sz); + _(MTIOCIEOT, NONE, 0); + _(MTIOCEEOT, NONE, 0); + _(MTIOCRDSPOS, WRITE, sizeof(u32)); + _(MTIOCRDHPOS, WRITE, sizeof(u32)); + _(MTIOCSLOCATE, READ, sizeof(u32)); + _(MTIOCHLOCATE, READ, sizeof(u32)); + /* 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); + _(RIOCSSRCH, READ, sizeof(int)); + /* Entries from file: sys/rndio.h */ + _(RNDGETENTCNT, WRITE, sizeof(u32)); + _(RNDGETSRCNUM, READWRITE, struct_rndstat_sz); + _(RNDGETSRCNAME, READWRITE, struct_rndstat_name_sz); + _(RNDCTL, READ, struct_rndctl_sz); + _(RNDADDDATA, READ, struct_rnddata_sz); + _(RNDGETPOOLSTAT, WRITE, struct_rndpoolstat_sz); + _(RNDGETESTNUM, READWRITE, struct_rndstat_est_sz); + _(RNDGETESTNAME, READWRITE, struct_rndstat_est_name_sz); + /* Entries from file: sys/scanio.h */ + _(SCIOCGET, WRITE, struct_scan_io_sz); + _(SCIOCSET, READ, struct_scan_io_sz); + _(SCIOCRESTART, NONE, 0); + /* Entries from file: sys/scsiio.h */ + _(SCIOCCOMMAND, READWRITE, struct_scsireq_sz); + _(SCIOCDEBUG, READ, sizeof(int)); + _(SCIOCIDENTIFY, WRITE, struct_scsi_addr_sz); + _(OSCIOCIDENTIFY, WRITE, struct_oscsi_addr_sz); + _(SCIOCDECONFIG, NONE, 0); + _(SCIOCRECONFIG, NONE, 0); + _(SCIOCRESET, NONE, 0); + _(SCBUSIOSCAN, READ, struct_scbusioscan_args_sz); + _(SCBUSIORESET, NONE, 0); + _(SCBUSIODETACH, READ, struct_scbusiodetach_args_sz); + _(SCBUSACCEL, READ, struct_scbusaccel_args_sz); + /* Entries from file: sys/sockio.h */ + _(SIOCSHIWAT, READ, sizeof(int)); + _(SIOCGHIWAT, WRITE, sizeof(int)); + _(SIOCSLOWAT, READ, sizeof(int)); + _(SIOCGLOWAT, WRITE, sizeof(int)); + _(SIOCATMARK, WRITE, sizeof(int)); + _(SIOCSPGRP, READ, sizeof(int)); + _(SIOCGPGRP, WRITE, sizeof(int)); + _(SIOCADDRT, READ, struct_ortentry_sz); + _(SIOCDELRT, READ, struct_ortentry_sz); + _(SIOCSIFADDR, READ, struct_ifreq_sz); + _(SIOCGIFADDR, READWRITE, struct_ifreq_sz); + _(SIOCSIFDSTADDR, READ, struct_ifreq_sz); + _(SIOCGIFDSTADDR, READWRITE, struct_ifreq_sz); + _(SIOCSIFFLAGS, READ, struct_ifreq_sz); + _(SIOCGIFFLAGS, READWRITE, struct_ifreq_sz); + _(SIOCGIFBRDADDR, READWRITE, struct_ifreq_sz); + _(SIOCSIFBRDADDR, READ, struct_ifreq_sz); + _(SIOCGIFCONF, READWRITE, struct_ifconf_sz); + _(SIOCGIFNETMASK, READWRITE, struct_ifreq_sz); + _(SIOCSIFNETMASK, READ, struct_ifreq_sz); + _(SIOCGIFMETRIC, READWRITE, struct_ifreq_sz); + _(SIOCSIFMETRIC, READ, struct_ifreq_sz); + _(SIOCDIFADDR, READ, struct_ifreq_sz); + _(SIOCAIFADDR, READ, struct_ifaliasreq_sz); + _(SIOCGIFALIAS, READWRITE, struct_ifaliasreq_sz); + _(SIOCGIFAFLAG_IN, READWRITE, struct_ifreq_sz); + _(SIOCALIFADDR, READ, struct_if_laddrreq_sz); + _(SIOCGLIFADDR, READWRITE, struct_if_laddrreq_sz); + _(SIOCDLIFADDR, READ, struct_if_laddrreq_sz); + _(SIOCSIFADDRPREF, READ, struct_if_addrprefreq_sz); + _(SIOCGIFADDRPREF, READWRITE, struct_if_addrprefreq_sz); + _(SIOCADDMULTI, READ, struct_ifreq_sz); + _(SIOCDELMULTI, READ, struct_ifreq_sz); + _(SIOCGETVIFCNT, READWRITE, struct_sioc_vif_req_sz); + _(SIOCGETSGCNT, READWRITE, struct_sioc_sg_req_sz); + _(SIOCSIFMEDIA, READWRITE, struct_ifreq_sz); + _(SIOCGIFMEDIA, READWRITE, struct_ifmediareq_sz); + _(SIOCSIFGENERIC, READ, struct_ifreq_sz); + _(SIOCGIFGENERIC, READWRITE, struct_ifreq_sz); + _(SIOCSIFPHYADDR, READ, struct_ifaliasreq_sz); + _(SIOCGIFPSRCADDR, READWRITE, struct_ifreq_sz); + _(SIOCGIFPDSTADDR, READWRITE, struct_ifreq_sz); + _(SIOCDIFPHYADDR, READ, struct_ifreq_sz); + _(SIOCSLIFPHYADDR, READ, struct_if_laddrreq_sz); + _(SIOCGLIFPHYADDR, READWRITE, struct_if_laddrreq_sz); + _(SIOCSIFMTU, READ, struct_ifreq_sz); + _(SIOCGIFMTU, READWRITE, struct_ifreq_sz); + _(SIOCSDRVSPEC, READ, struct_ifdrv_sz); + _(SIOCGDRVSPEC, READWRITE, struct_ifdrv_sz); + _(SIOCIFCREATE, READ, struct_ifreq_sz); + _(SIOCIFDESTROY, READ, struct_ifreq_sz); + _(SIOCIFGCLONERS, READWRITE, struct_if_clonereq_sz); + _(SIOCGIFDLT, READWRITE, struct_ifreq_sz); + _(SIOCGIFCAP, READWRITE, struct_ifcapreq_sz); + _(SIOCSIFCAP, READ, struct_ifcapreq_sz); + _(SIOCSVH, READWRITE, struct_ifreq_sz); + _(SIOCGVH, READWRITE, struct_ifreq_sz); + _(SIOCINITIFADDR, READWRITE, struct_ifaddr_sz); + _(SIOCGIFDATA, READWRITE, struct_ifdatareq_sz); + _(SIOCZIFDATA, READWRITE, struct_ifdatareq_sz); + _(SIOCGLINKSTR, READWRITE, struct_ifdrv_sz); + _(SIOCSLINKSTR, READ, struct_ifdrv_sz); + _(SIOCGETHERCAP, READWRITE, struct_eccapreq_sz); + _(SIOCGIFINDEX, READWRITE, struct_ifreq_sz); + _(SIOCSETPFSYNC, READ, struct_ifreq_sz); + _(SIOCGETPFSYNC, READWRITE, struct_ifreq_sz); + /* Entries from file: sys/timepps.h */ + _(PPS_IOC_CREATE, NONE, 0); + _(PPS_IOC_DESTROY, NONE, 0); + _(PPS_IOC_SETPARAMS, READ, struct_pps_params_sz); + _(PPS_IOC_GETPARAMS, WRITE, struct_pps_params_sz); + _(PPS_IOC_GETCAP, WRITE, sizeof(int)); + _(PPS_IOC_FETCH, READWRITE, struct_pps_info_sz); + _(PPS_IOC_KCBIND, READ, sizeof(int)); + /* Entries from file: sys/ttycom.h */ + _(TIOCEXCL, NONE, 0); + _(TIOCNXCL, NONE, 0); + _(TIOCFLUSH, READ, sizeof(int)); + _(TIOCGETA, WRITE, struct_termios_sz); + _(TIOCSETA, READ, struct_termios_sz); + _(TIOCSETAW, READ, 0); + _(TIOCSETAF, READ, 0); + _(TIOCGETD, WRITE, sizeof(int)); + _(TIOCSETD, READ, sizeof(int)); + _(TIOCGLINED, WRITE, (32 * sizeof(char))); + _(TIOCSLINED, READ, (32 * sizeof(char))); + _(TIOCSBRK, NONE, 0); + _(TIOCCBRK, NONE, 0); + _(TIOCSDTR, NONE, 0); + _(TIOCCDTR, NONE, 0); + _(TIOCGPGRP, WRITE, sizeof(int)); + _(TIOCSPGRP, READ, sizeof(int)); + _(TIOCOUTQ, WRITE, sizeof(int)); + _(TIOCSTI, READ, sizeof(char)); + _(TIOCNOTTY, NONE, 0); + _(TIOCPKT, READ, sizeof(int)); + _(TIOCSTOP, NONE, 0); + _(TIOCSTART, NONE, 0); + _(TIOCMSET, READ, sizeof(int)); + _(TIOCMBIS, READ, sizeof(int)); + _(TIOCMBIC, READ, sizeof(int)); + _(TIOCMGET, WRITE, sizeof(int)); + _(TIOCREMOTE, READ, sizeof(int)); + _(TIOCGWINSZ, WRITE, struct_winsize_sz); + _(TIOCSWINSZ, READ, struct_winsize_sz); + _(TIOCUCNTL, READ, sizeof(int)); + _(TIOCSTAT, READ, sizeof(int)); + _(TIOCGSID, WRITE, sizeof(int)); + _(TIOCCONS, READ, sizeof(int)); + _(TIOCSCTTY, NONE, 0); + _(TIOCEXT, READ, sizeof(int)); + _(TIOCSIG, NONE, 0); + _(TIOCDRAIN, NONE, 0); + _(TIOCGFLAGS, WRITE, sizeof(int)); + _(TIOCSFLAGS, READ, sizeof(int)); + _(TIOCDCDTIMESTAMP, WRITE, struct_timeval_sz); + _(TIOCRCVFRAME, READ, sizeof(uptr)); + _(TIOCXMTFRAME, READ, sizeof(uptr)); + _(TIOCPTMGET, WRITE, struct_ptmget_sz); + _(TIOCGRANTPT, NONE, 0); + _(TIOCPTSNAME, WRITE, struct_ptmget_sz); + _(TIOCSQSIZE, READ, sizeof(int)); + _(TIOCGQSIZE, WRITE, sizeof(int)); + /* Entries from file: sys/verified_exec.h */ + _(VERIEXEC_LOAD, READ, struct_plistref_sz); + _(VERIEXEC_TABLESIZE, READ, struct_plistref_sz); + _(VERIEXEC_DELETE, READ, struct_plistref_sz); + _(VERIEXEC_QUERY, READWRITE, struct_plistref_sz); + _(VERIEXEC_DUMP, WRITE, struct_plistref_sz); + _(VERIEXEC_FLUSH, NONE, 0); + /* Entries from file: sys/videoio.h */ + _(VIDIOC_QUERYCAP, WRITE, struct_v4l2_capability_sz); + _(VIDIOC_RESERVED, NONE, 0); + _(VIDIOC_ENUM_FMT, READWRITE, struct_v4l2_fmtdesc_sz); + _(VIDIOC_G_FMT, READWRITE, struct_v4l2_format_sz); + _(VIDIOC_S_FMT, READWRITE, struct_v4l2_format_sz); + _(VIDIOC_REQBUFS, READWRITE, struct_v4l2_requestbuffers_sz); + _(VIDIOC_QUERYBUF, READWRITE, struct_v4l2_buffer_sz); + _(VIDIOC_G_FBUF, WRITE, struct_v4l2_framebuffer_sz); + _(VIDIOC_S_FBUF, READ, struct_v4l2_framebuffer_sz); + _(VIDIOC_OVERLAY, READ, sizeof(int)); + _(VIDIOC_QBUF, READWRITE, struct_v4l2_buffer_sz); + _(VIDIOC_DQBUF, READWRITE, struct_v4l2_buffer_sz); + _(VIDIOC_STREAMON, READ, sizeof(int)); + _(VIDIOC_STREAMOFF, READ, sizeof(int)); + _(VIDIOC_G_PARM, READWRITE, struct_v4l2_streamparm_sz); + _(VIDIOC_S_PARM, READWRITE, struct_v4l2_streamparm_sz); + _(VIDIOC_G_STD, WRITE, sizeof(u64)); + _(VIDIOC_S_STD, READ, sizeof(u64)); + _(VIDIOC_ENUMSTD, READWRITE, struct_v4l2_standard_sz); + _(VIDIOC_ENUMINPUT, READWRITE, struct_v4l2_input_sz); + _(VIDIOC_G_CTRL, READWRITE, struct_v4l2_control_sz); + _(VIDIOC_S_CTRL, READWRITE, struct_v4l2_control_sz); + _(VIDIOC_G_TUNER, READWRITE, struct_v4l2_tuner_sz); + _(VIDIOC_S_TUNER, READ, struct_v4l2_tuner_sz); + _(VIDIOC_G_AUDIO, WRITE, struct_v4l2_audio_sz); + _(VIDIOC_S_AUDIO, READ, struct_v4l2_audio_sz); + _(VIDIOC_QUERYCTRL, READWRITE, struct_v4l2_queryctrl_sz); + _(VIDIOC_QUERYMENU, READWRITE, struct_v4l2_querymenu_sz); + _(VIDIOC_G_INPUT, WRITE, sizeof(int)); + _(VIDIOC_S_INPUT, READWRITE, sizeof(int)); + _(VIDIOC_G_OUTPUT, WRITE, sizeof(int)); + _(VIDIOC_S_OUTPUT, READWRITE, sizeof(int)); + _(VIDIOC_ENUMOUTPUT, READWRITE, struct_v4l2_output_sz); + _(VIDIOC_G_AUDOUT, WRITE, struct_v4l2_audioout_sz); + _(VIDIOC_S_AUDOUT, READ, struct_v4l2_audioout_sz); + _(VIDIOC_G_MODULATOR, READWRITE, struct_v4l2_modulator_sz); + _(VIDIOC_S_MODULATOR, READ, struct_v4l2_modulator_sz); + _(VIDIOC_G_FREQUENCY, READWRITE, struct_v4l2_frequency_sz); + _(VIDIOC_S_FREQUENCY, READ, struct_v4l2_frequency_sz); + _(VIDIOC_CROPCAP, READWRITE, struct_v4l2_cropcap_sz); + _(VIDIOC_G_CROP, READWRITE, struct_v4l2_crop_sz); + _(VIDIOC_S_CROP, READ, struct_v4l2_crop_sz); + _(VIDIOC_G_JPEGCOMP, WRITE, struct_v4l2_jpegcompression_sz); + _(VIDIOC_S_JPEGCOMP, READ, struct_v4l2_jpegcompression_sz); + _(VIDIOC_QUERYSTD, WRITE, sizeof(u64)); + _(VIDIOC_TRY_FMT, READWRITE, struct_v4l2_format_sz); + _(VIDIOC_ENUMAUDIO, READWRITE, struct_v4l2_audio_sz); + _(VIDIOC_ENUMAUDOUT, READWRITE, struct_v4l2_audioout_sz); + _(VIDIOC_G_PRIORITY, WRITE, enum_v4l2_priority_sz); + _(VIDIOC_S_PRIORITY, READ, enum_v4l2_priority_sz); + _(VIDIOC_ENUM_FRAMESIZES, READWRITE, struct_v4l2_frmsizeenum_sz); + _(VIDIOC_ENUM_FRAMEINTERVALS, READWRITE, struct_v4l2_frmivalenum_sz); + /* Entries from file: sys/wdog.h */ + _(WDOGIOC_GMODE, READWRITE, struct_wdog_mode_sz); + _(WDOGIOC_SMODE, READ, struct_wdog_mode_sz); + _(WDOGIOC_WHICH, WRITE, struct_wdog_mode_sz); + _(WDOGIOC_TICKLE, NONE, 0); + _(WDOGIOC_GTICKLER, WRITE, sizeof(int)); + _(WDOGIOC_GWDOGS, READWRITE, struct_wdog_conf_sz); + /* Entries from file: soundcard.h */ + _(SNDCTL_DSP_RESET, NONE, 0); + _(SNDCTL_DSP_SYNC, NONE, 0); + _(SNDCTL_DSP_SPEED, READWRITE, sizeof(int)); + _(SOUND_PCM_READ_RATE, WRITE, sizeof(int)); + _(SNDCTL_DSP_STEREO, READWRITE, sizeof(int)); + _(SNDCTL_DSP_GETBLKSIZE, READWRITE, sizeof(int)); + _(SNDCTL_DSP_SETFMT, READWRITE, sizeof(int)); + _(SOUND_PCM_READ_BITS, WRITE, sizeof(int)); + _(SNDCTL_DSP_CHANNELS, READWRITE, sizeof(int)); + _(SOUND_PCM_READ_CHANNELS, WRITE, sizeof(int)); + _(SOUND_PCM_WRITE_FILTER, READWRITE, sizeof(int)); + _(SOUND_PCM_READ_FILTER, WRITE, sizeof(int)); + _(SNDCTL_DSP_POST, NONE, 0); + _(SNDCTL_DSP_SUBDIVIDE, READWRITE, sizeof(int)); + _(SNDCTL_DSP_SETFRAGMENT, READWRITE, sizeof(int)); + _(SNDCTL_DSP_GETFMTS, WRITE, sizeof(int)); + _(SNDCTL_DSP_GETOSPACE, WRITE, struct_audio_buf_info_sz); + _(SNDCTL_DSP_GETISPACE, WRITE, struct_audio_buf_info_sz); + _(SNDCTL_DSP_NONBLOCK, NONE, 0); + _(SNDCTL_DSP_GETCAPS, WRITE, sizeof(int)); + _(SNDCTL_DSP_GETTRIGGER, WRITE, sizeof(int)); + _(SNDCTL_DSP_SETTRIGGER, READ, sizeof(int)); + _(SNDCTL_DSP_GETIPTR, WRITE, struct_count_info_sz); + _(SNDCTL_DSP_GETOPTR, WRITE, struct_count_info_sz); + _(SNDCTL_DSP_MAPINBUF, WRITE, struct_buffmem_desc_sz); + _(SNDCTL_DSP_MAPOUTBUF, WRITE, struct_buffmem_desc_sz); + _(SNDCTL_DSP_SETSYNCRO, NONE, 0); + _(SNDCTL_DSP_SETDUPLEX, NONE, 0); + _(SNDCTL_DSP_PROFILE, READ, sizeof(int)); + _(SNDCTL_DSP_GETODELAY, WRITE, sizeof(int)); + _(SOUND_MIXER_INFO, WRITE, struct_mixer_info_sz); + _(SOUND_OLD_MIXER_INFO, WRITE, struct__old_mixer_info_sz); + _(OSS_GETVERSION, WRITE, sizeof(int)); + _(SNDCTL_SYSINFO, WRITE, struct_oss_sysinfo_sz); + _(SNDCTL_AUDIOINFO, READWRITE, struct_oss_audioinfo_sz); + _(SNDCTL_ENGINEINFO, READWRITE, struct_oss_audioinfo_sz); + _(SNDCTL_DSP_GETPLAYVOL, WRITE, sizeof(unsigned int)); + _(SNDCTL_DSP_SETPLAYVOL, READ, sizeof(unsigned int)); + _(SNDCTL_DSP_GETRECVOL, WRITE, sizeof(unsigned int)); + _(SNDCTL_DSP_SETRECVOL, READ, sizeof(unsigned int)); + _(SNDCTL_DSP_SKIP, NONE, 0); + _(SNDCTL_DSP_SILENCE, NONE, 0); +#undef _ +} + +static bool ioctl_initialized = false; + +struct ioctl_desc_compare { + bool operator()(const ioctl_desc &left, const ioctl_desc &right) const { + return left.req < right.req; + } +}; + +static void ioctl_init() { + ioctl_table_fill(); + Sort(ioctl_table, ioctl_table_size, ioctl_desc_compare()); + + bool bad = false; + for (unsigned i = 0; i < ioctl_table_size - 1; ++i) { + if (ioctl_table[i].req >= ioctl_table[i + 1].req) { + Printf("Duplicate or unsorted ioctl request id %x >= %x (%s vs %s)\n", + ioctl_table[i].req, ioctl_table[i + 1].req, ioctl_table[i].name, + ioctl_table[i + 1].name); + bad = true; + } + } + + if (bad) + Die(); + + ioctl_initialized = true; +} + +static const ioctl_desc *ioctl_table_lookup(unsigned req) { + int left = 0; + int right = ioctl_table_size; + while (left < right) { + int mid = (left + right) / 2; + if (ioctl_table[mid].req < req) + left = mid + 1; + else + right = mid; + } + if (left == right && ioctl_table[left].req == req) + return ioctl_table + left; + else + return nullptr; +} + +static bool ioctl_decode(unsigned req, ioctl_desc *desc) { + CHECK(desc); + desc->req = req; + desc->name = ""; + desc->size = IOC_SIZE(req); + // Sanity check. + if (desc->size > 0xFFFF) + return false; + unsigned dir = IOC_DIR(req); + switch (dir) { + case IOC_NONE: + desc->type = ioctl_desc::NONE; + break; + case IOC_READ | IOC_WRITE: + desc->type = ioctl_desc::READWRITE; + break; + case IOC_READ: + desc->type = ioctl_desc::WRITE; + break; + case IOC_WRITE: + desc->type = ioctl_desc::READ; + break; + default: + return false; + } + // Size can be 0 iff type is NONE. + if ((desc->type == IOC_NONE) != (desc->size == 0)) + return false; + // Sanity check. + if (IOC_TYPE(req) == 0) + return false; + return true; +} + +static const ioctl_desc *ioctl_lookup(unsigned req) { + const ioctl_desc *desc = ioctl_table_lookup(req); + if (desc) + return desc; + + // Try stripping access size from the request id. + desc = ioctl_table_lookup(req & ~(IOC_SIZEMASK << IOC_SIZESHIFT)); + // Sanity check: requests that encode access size are either read or write and + // have size of 0 in the table. + if (desc && desc->size == 0 && + (desc->type == ioctl_desc::READWRITE || desc->type == ioctl_desc::WRITE || + desc->type == ioctl_desc::READ)) + return desc; + return nullptr; +} + +static void ioctl_common_pre(void *ctx, const ioctl_desc *desc, int d, + unsigned request, void *arg) { + if (desc->type == ioctl_desc::READ || desc->type == ioctl_desc::READWRITE) { + unsigned size = desc->size ? desc->size : IOC_SIZE(request); + COMMON_INTERCEPTOR_READ_RANGE(ctx, arg, size); + } + if (desc->type != ioctl_desc::CUSTOM) + return; + if (request == IOCTL_SIOCGIFCONF) { + struct __sanitizer_ifconf *ifc = (__sanitizer_ifconf *)arg; + COMMON_INTERCEPTOR_READ_RANGE(ctx, (char *)&ifc->ifc_len, + sizeof(ifc->ifc_len)); + } +} + +static void ioctl_common_post(void *ctx, const ioctl_desc *desc, int res, int d, + unsigned request, void *arg) { + if (desc->type == ioctl_desc::WRITE || desc->type == ioctl_desc::READWRITE) { + // FIXME: add verbose output + unsigned size = desc->size ? desc->size : IOC_SIZE(request); + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, arg, size); + } + if (desc->type != ioctl_desc::CUSTOM) + return; + if (request == IOCTL_SIOCGIFCONF) { + struct __sanitizer_ifconf *ifc = (__sanitizer_ifconf *)arg; + COMMON_INTERCEPTOR_WRITE_RANGE(ctx, ifc->ifc_ifcu.ifcu_req, ifc->ifc_len); + } +} + +#endif // SANITIZER_NETBSD diff --git a/libsanitizer/sanitizer_common/sanitizer_interface_internal.h b/libsanitizer/sanitizer_common/sanitizer_interface_internal.h index 08c110c707c..6597efa2def 100644 --- a/libsanitizer/sanitizer_common/sanitizer_interface_internal.h +++ b/libsanitizer/sanitizer_common/sanitizer_interface_internal.h @@ -50,6 +50,12 @@ extern "C" { SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_dump_trace_pc_guard_coverage(); SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_cov(__sanitizer::u32 *guard); + + // 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. + SANITIZER_INTERFACE_ATTRIBUTE int __sanitizer_acquire_crash_state(); + SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_annotate_contiguous_container(const void *beg, const void *end, diff --git a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h index 4413a88bea0..8bd1bcacac1 100644 --- a/libsanitizer/sanitizer_common/sanitizer_internal_defs.h +++ b/libsanitizer/sanitizer_common/sanitizer_internal_defs.h @@ -17,6 +17,9 @@ # define SANITIZER_DEBUG 0 #endif +#define SANITIZER_STRINGIFY_(S) #S +#define SANITIZER_STRINGIFY(S) SANITIZER_STRINGIFY_(S) + // Only use SANITIZER_*ATTRIBUTE* before the function return type! #if SANITIZER_WINDOWS #if SANITIZER_IMPORT_INTERFACE @@ -34,7 +37,8 @@ #endif // TLS is handled differently on different platforms -#if SANITIZER_LINUX +#if SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_FREEBSD || SANITIZER_OPENBSD # define SANITIZER_TLS_INITIAL_EXEC_ATTRIBUTE \ __attribute__((tls_model("initial-exec"))) thread_local #else @@ -63,7 +67,7 @@ // SANITIZER_SUPPORTS_WEAK_HOOKS means that we support real weak functions that // will evaluate to a null pointer when not defined. #ifndef SANITIZER_SUPPORTS_WEAK_HOOKS -#if SANITIZER_LINUX && !SANITIZER_GO +#if (SANITIZER_LINUX || SANITIZER_SOLARIS) && !SANITIZER_GO # define SANITIZER_SUPPORTS_WEAK_HOOKS 1 // Before Xcode 4.5, the Darwin linker doesn't reliably support undefined // weak symbols. Mac OS X 10.9/Darwin 13 is the first release only supported @@ -92,12 +96,24 @@ // We can use .preinit_array section on Linux to call sanitizer initialization // functions very early in the process startup (unless PIC macro is defined). +// +// On FreeBSD, .preinit_array functions are called with rtld_bind_lock writer +// lock held. It will lead to dead lock if unresolved PLT functions (which helds +// rtld_bind_lock reader lock) are called inside .preinit_array functions. +// // FIXME: do we have anything like this on Mac? -#if SANITIZER_LINUX && !SANITIZER_ANDROID && !defined(PIC) +#ifndef SANITIZER_CAN_USE_PREINIT_ARRAY +#if ((SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_OPENBSD || \ + SANITIZER_FUCHSIA) && !defined(PIC) +#define SANITIZER_CAN_USE_PREINIT_ARRAY 1 +// Before Solaris 11.4, .preinit_array is fully supported only with GNU ld. +// FIXME: Check for those conditions. +#elif SANITIZER_SOLARIS && !defined(PIC) # define SANITIZER_CAN_USE_PREINIT_ARRAY 1 #else # define SANITIZER_CAN_USE_PREINIT_ARRAY 0 #endif +#endif // SANITIZER_CAN_USE_PREINIT_ARRAY // GCC does not understand __has_feature #if !defined(__has_feature) @@ -146,9 +162,14 @@ typedef unsigned error_t; typedef int fd_t; typedef int error_t; #endif +#if SANITIZER_SOLARIS && !defined(_LP64) +typedef long pid_t; +#else typedef int pid_t; +#endif -#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC || \ +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || \ + SANITIZER_OPENBSD || SANITIZER_MAC || \ (SANITIZER_LINUX && defined(__x86_64__)) typedef u64 OFF_T; #else @@ -159,7 +180,7 @@ typedef u64 OFF64_T; #if (SANITIZER_WORDSIZE == 64) || SANITIZER_MAC typedef uptr operator_new_size_type; #else -# if defined(__s390__) && !defined(__s390x__) +# if SANITIZER_OPENBSD || defined(__s390__) && !defined(__s390x__) // Special case: 31-bit s390 has unsigned long as size_t. typedef unsigned long operator_new_size_type; # else @@ -167,12 +188,7 @@ typedef u32 operator_new_size_type; # endif #endif -#if SANITIZER_MAC -// On Darwin, thread IDs are 64-bit even on 32-bit systems. typedef u64 tid_t; -#else -typedef uptr tid_t; -#endif // ----------- ATTENTION ------------- // This header should NOT include any other headers to avoid portability issues. @@ -198,6 +214,7 @@ typedef uptr tid_t; # define LIKELY(x) (x) # define UNLIKELY(x) (x) # define PREFETCH(x) /* _mm_prefetch(x, _MM_HINT_NTA) */ (void)0 +# define WARN_UNUSED_RESULT #else // _MSC_VER # define ALWAYS_INLINE inline __attribute__((always_inline)) # define ALIAS(x) __attribute__((alias(x))) @@ -216,6 +233,7 @@ typedef uptr tid_t; # else # define PREFETCH(x) __builtin_prefetch(x) # endif +# define WARN_UNUSED_RESULT __attribute__((warn_unused_result)) #endif // _MSC_VER #if !defined(_MSC_VER) || defined(__clang__) @@ -255,8 +273,6 @@ typedef thread_return_t (THREAD_CALLING_CONV *thread_callback_t)(void* arg); // NOTE: Functions below must be defined in each run-time. void NORETURN Die(); -// FIXME: No, this shouldn't be in the sanitizer interface. -SANITIZER_INTERFACE_ATTRIBUTE void NORETURN CheckFailed(const char *file, int line, const char *cond, u64 v1, u64 v2); @@ -344,6 +360,12 @@ void NORETURN CheckFailed(const char *file, int line, const char *cond, #define INT64_MAX (__INT64_C(9223372036854775807)) #undef UINT64_MAX #define UINT64_MAX (__UINT64_C(18446744073709551615)) +#undef UINTPTR_MAX +#if SANITIZER_WORDSIZE == 64 +# define UINTPTR_MAX (18446744073709551615UL) +#else +# define UINTPTR_MAX (4294967295U) +#endif // SANITIZER_WORDSIZE == 64 enum LinkerInitialized { LINKER_INITIALIZED = 0 }; @@ -399,11 +421,13 @@ 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 namespace __tsan { using namespace __sanitizer; } // NOLINT namespace __scudo { using namespace __sanitizer; } // NOLINT namespace __ubsan { using namespace __sanitizer; } // NOLINT namespace __xray { using namespace __sanitizer; } // NOLINT namespace __interception { using namespace __sanitizer; } // NOLINT +namespace __hwasan { using namespace __sanitizer; } // NOLINT #endif // SANITIZER_DEFS_H diff --git a/libsanitizer/sanitizer_common/sanitizer_libc.cc b/libsanitizer/sanitizer_common/sanitizer_libc.cc index 82d37675e47..94fa69b6a2d 100644 --- a/libsanitizer/sanitizer_common/sanitizer_libc.cc +++ b/libsanitizer/sanitizer_common/sanitizer_libc.cc @@ -70,18 +70,19 @@ void *internal_memmove(void *dest, const void *src, uptr n) { return dest; } -// Semi-fast bzero for 16-aligned data. Still far from peak performance. -void internal_bzero_aligned16(void *s, uptr n) { - struct ALIGNED(16) S16 { u64 a, b; }; - CHECK_EQ((reinterpret_cast(s) | n) & 15, 0); - for (S16 *p = reinterpret_cast(s), *end = p + n / 16; p < end; p++) { - p->a = p->b = 0; - // Make sure this does not become memset. - SanitizerBreakOptimization(nullptr); - } -} - void *internal_memset(void* s, int c, uptr n) { + // Optimize for the most performance-critical case: + if ((reinterpret_cast(s) % 16) == 0 && (n % 16) == 0) { + u64 *p = reinterpret_cast(s); + u64 *e = p + n / 8; + u64 v = c; + v |= v << 8; + v |= v << 16; + v |= v << 32; + for (; p < e; p += 2) + p[0] = p[1] = v; + return s; + } // The next line prevents Clang from making a call to memset() instead of the // loop below. // FIXME: building the runtime with -ffreestanding is a better idea. However @@ -110,14 +111,6 @@ char* internal_strdup(const char *s) { return s2; } -char* internal_strndup(const char *s, uptr n) { - uptr len = internal_strnlen(s, n); - char *s2 = (char*)InternalAlloc(len + 1); - internal_memcpy(s2, s, len); - s2[len] = 0; - return s2; -} - int internal_strcmp(const char *s1, const char *s2) { while (true) { unsigned c1 = *s1; @@ -232,13 +225,7 @@ char *internal_strstr(const char *haystack, const char *needle) { return nullptr; } -uptr internal_wcslen(const wchar_t *s) { - uptr i = 0; - while (s[i]) i++; - return i; -} - -s64 internal_simple_strtoll(const char *nptr, char **endptr, int base) { +s64 internal_simple_strtoll(const char *nptr, const char **endptr, int base) { CHECK_EQ(base, 10); while (IsSpace(*nptr)) nptr++; int sgn = 1; diff --git a/libsanitizer/sanitizer_common/sanitizer_libc.h b/libsanitizer/sanitizer_common/sanitizer_libc.h index d26ec8704c0..4bc6791be56 100644 --- a/libsanitizer/sanitizer_common/sanitizer_libc.h +++ b/libsanitizer/sanitizer_common/sanitizer_libc.h @@ -30,8 +30,6 @@ void *internal_memrchr(const void *s, int c, uptr n); int internal_memcmp(const void* s1, const void* s2, uptr n); void *internal_memcpy(void *dest, const void *src, uptr n); void *internal_memmove(void *dest, const void *src, uptr n); -// Set [s, s + n) to 0. Both s and n should be 16-aligned. -void internal_bzero_aligned16(void *s, uptr n); // Should not be used in performance-critical places. void *internal_memset(void *s, int c, uptr n); char* internal_strchr(const char *s, int c); @@ -39,7 +37,6 @@ char *internal_strchrnul(const char *s, int c); int internal_strcmp(const char *s1, const char *s2); uptr internal_strcspn(const char *s, const char *reject); char *internal_strdup(const char *s); -char *internal_strndup(const char *s, uptr n); uptr internal_strlen(const char *s); uptr internal_strlcat(char *dst, const char *src, uptr maxlen); char *internal_strncat(char *dst, const char *src, uptr n); @@ -48,11 +45,9 @@ uptr internal_strlcpy(char *dst, const char *src, uptr maxlen); char *internal_strncpy(char *dst, const char *src, uptr n); uptr internal_strnlen(const char *s, uptr maxlen); char *internal_strrchr(const char *s, int c); -// This is O(N^2), but we are not using it in hot places. -uptr internal_wcslen(const wchar_t *s); char *internal_strstr(const char *haystack, const char *needle); // Works only for base=10 and doesn't set errno. -s64 internal_simple_strtoll(const char *nptr, char **endptr, int base); +s64 internal_simple_strtoll(const char *nptr, const char **endptr, int base); int internal_snprintf(char *buffer, uptr length, const char *format, ...); // Return true if all bytes in [mem, mem+size) are zero. diff --git a/libsanitizer/sanitizer_common/sanitizer_libignore.cc b/libsanitizer/sanitizer_common/sanitizer_libignore.cc index e20c7559b8e..0a551490b7f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_libignore.cc +++ b/libsanitizer/sanitizer_common/sanitizer_libignore.cc @@ -7,7 +7,8 @@ #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \ + SANITIZER_NETBSD || SANITIZER_OPENBSD #include "sanitizer_libignore.h" #include "sanitizer_flags.h" @@ -78,7 +79,7 @@ void LibIgnore::OnLibraryLoaded(const char *name) { lib->name = internal_strdup(mod.full_name()); const uptr idx = atomic_load(&ignored_ranges_count_, memory_order_relaxed); - CHECK_LT(idx, kMaxLibs); + CHECK_LT(idx, ARRAY_SIZE(ignored_code_ranges_)); ignored_code_ranges_[idx].begin = range.beg; ignored_code_ranges_[idx].end = range.end; atomic_store(&ignored_ranges_count_, idx + 1, memory_order_release); @@ -107,7 +108,7 @@ void LibIgnore::OnLibraryLoaded(const char *name) { range.beg, range.end, mod.full_name()); const uptr idx = atomic_load(&instrumented_ranges_count_, memory_order_relaxed); - CHECK_LT(idx, kMaxLibs); + CHECK_LT(idx, ARRAY_SIZE(instrumented_code_ranges_)); instrumented_code_ranges_[idx].begin = range.beg; instrumented_code_ranges_[idx].end = range.end; atomic_store(&instrumented_ranges_count_, idx + 1, diff --git a/libsanitizer/sanitizer_common/sanitizer_libignore.h b/libsanitizer/sanitizer_common/sanitizer_libignore.h index e7627ee0256..b2884fa3c91 100644 --- a/libsanitizer/sanitizer_common/sanitizer_libignore.h +++ b/libsanitizer/sanitizer_common/sanitizer_libignore.h @@ -64,14 +64,16 @@ class LibIgnore { return (pc >= range.begin && pc < range.end); } - static const uptr kMaxLibs = 128; + static const uptr kMaxIgnoredRanges = 128; + static const uptr kMaxInstrumentedRanges = 1024; + static const uptr kMaxLibs = 1024; // Hot part: atomic_uintptr_t ignored_ranges_count_; - LibCodeRange ignored_code_ranges_[kMaxLibs]; + LibCodeRange ignored_code_ranges_[kMaxIgnoredRanges]; atomic_uintptr_t instrumented_ranges_count_; - LibCodeRange instrumented_code_ranges_[kMaxLibs]; + LibCodeRange instrumented_code_ranges_[kMaxInstrumentedRanges]; // Cold part: BlockingMutex mutex_; diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.cc b/libsanitizer/sanitizer_common/sanitizer_linux.cc index 2826cc89e20..f1f70ec57fc 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux.cc +++ b/libsanitizer/sanitizer_common/sanitizer_linux.cc @@ -12,27 +12,23 @@ #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_OPENBSD || SANITIZER_SOLARIS #include "sanitizer_common.h" #include "sanitizer_flags.h" +#include "sanitizer_getauxval.h" #include "sanitizer_internal_defs.h" #include "sanitizer_libc.h" #include "sanitizer_linux.h" #include "sanitizer_mutex.h" #include "sanitizer_placement_new.h" #include "sanitizer_procmaps.h" -#include "sanitizer_stacktrace.h" -#include "sanitizer_symbolizer.h" #if SANITIZER_LINUX #include #endif -#if SANITIZER_NETBSD -#include -#endif - // For mips64, syscall(__NR_stat) fills the buffer in the 'struct kernel_stat' // format. Struct kernel_stat is defined as 'struct stat' in asm/stat.h. To // access stat from asm/stat.h, without conflicting with definition in @@ -51,14 +47,24 @@ #include #include #include +#include #include +#include +#if !SANITIZER_SOLARIS #include +#endif #include #include #include #include #include +#if !SANITIZER_OPENBSD #include +#endif +#if SANITIZER_OPENBSD +#include +#include +#endif #include #if SANITIZER_LINUX @@ -78,32 +84,23 @@ extern "C" { // FreeBSD 9.2 and 10.0. #include } -extern char **environ; // provided by crt1 +#include #endif // SANITIZER_FREEBSD #if SANITIZER_NETBSD #include // For NAME_MAX #include -extern char **environ; // provided by crt1 -#endif // SANITIZER_NETBSD - -#if !SANITIZER_ANDROID -#include -#endif - -#ifndef __GLIBC_PREREQ -#define __GLIBC_PREREQ(x, y) 0 -#endif +#include +extern struct ps_strings *__ps_strings; +#endif // SANITIZER_NETBSD -#if SANITIZER_LINUX && __GLIBC_PREREQ(2, 16) -# define SANITIZER_USE_GETAUXVAL 1 -#else -# define SANITIZER_USE_GETAUXVAL 0 +#if SANITIZER_SOLARIS +#include +#include +#define environ _environ #endif -#if SANITIZER_USE_GETAUXVAL -#include -#endif +extern char **environ; #if SANITIZER_LINUX // @@ -115,13 +112,16 @@ struct kernel_timeval { // is broken on some linux distributions. const int FUTEX_WAIT = 0; const int FUTEX_WAKE = 1; +const int FUTEX_PRIVATE_FLAG = 128; +const int FUTEX_WAIT_PRIVATE = FUTEX_WAIT | FUTEX_PRIVATE_FLAG; +const int FUTEX_WAKE_PRIVATE = FUTEX_WAKE | FUTEX_PRIVATE_FLAG; #endif // SANITIZER_LINUX // Are we using 32-bit or 64-bit Linux syscalls? // x32 (which defines __x86_64__) has SANITIZER_WORDSIZE == 32 // but it still needs to use 64-bit syscalls. -#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__powerpc64__) || \ - SANITIZER_WORDSIZE == 64) +#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__powerpc64__) || \ + SANITIZER_WORDSIZE == 64) # define SANITIZER_LINUX_USES_64BIT_SYSCALLS 1 #else # define SANITIZER_LINUX_USES_64BIT_SYSCALLS 0 @@ -133,6 +133,9 @@ extern void internal_sigreturn(); } #endif +// Note : FreeBSD had implemented both +// Linux and OpenBSD apis, available from +// future 12.x version most likely #if SANITIZER_LINUX && defined(__NR_getrandom) # if !defined(GRND_NONBLOCK) # define GRND_NONBLOCK 1 @@ -142,24 +145,34 @@ extern void internal_sigreturn(); # define SANITIZER_USE_GETRANDOM 0 #endif // SANITIZER_LINUX && defined(__NR_getrandom) +#if SANITIZER_OPENBSD +# define SANITIZER_USE_GETENTROPY 1 +#else +# if SANITIZER_FREEBSD && __FreeBSD_version >= 1200000 +# define SANITIZER_USE_GETENTROPY 1 +# else +# define SANITIZER_USE_GETENTROPY 0 +# endif +#endif // SANITIZER_USE_GETENTROPY + namespace __sanitizer { #if SANITIZER_LINUX && defined(__x86_64__) #include "sanitizer_syscall_linux_x86_64.inc" #elif SANITIZER_LINUX && defined(__aarch64__) #include "sanitizer_syscall_linux_aarch64.inc" +#elif SANITIZER_LINUX && defined(__arm__) +#include "sanitizer_syscall_linux_arm.inc" #else #include "sanitizer_syscall_generic.inc" #endif // --------------- sanitizer_libc.h -#if !SANITIZER_S390 +#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD +#if !SANITIZER_S390 && !SANITIZER_OPENBSD uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, OFF_T offset) { -#if SANITIZER_NETBSD - return internal_syscall_ptr(SYSCALL(mmap), addr, length, prot, flags, fd, - (long)0, offset); -#elif SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS +#if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS return internal_syscall(SYSCALL(mmap), (uptr)addr, length, prot, flags, fd, offset); #else @@ -169,8 +182,9 @@ uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, offset / 4096); #endif } -#endif // !SANITIZER_S390 +#endif // !SANITIZER_S390 && !SANITIZER_OPENBSD +#if !SANITIZER_OPENBSD uptr internal_munmap(void *addr, uptr length) { return internal_syscall(SYSCALL(munmap), (uptr)addr, length); } @@ -178,6 +192,7 @@ uptr internal_munmap(void *addr, uptr length) { int internal_mprotect(void *addr, uptr length, int prot) { return internal_syscall(SYSCALL(mprotect), (uptr)addr, length, prot); } +#endif uptr internal_close(fd_t fd) { return internal_syscall(SYSCALL(close), fd); @@ -202,34 +217,22 @@ uptr internal_open(const char *filename, int flags, u32 mode) { uptr internal_read(fd_t fd, void *buf, uptr count) { sptr res; -#if SANITIZER_NETBSD - HANDLE_EINTR(res, internal_syscall_ptr(SYSCALL(read), fd, buf, count)); -#else - HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(read), fd, (uptr)buf, - count)); -#endif + HANDLE_EINTR(res, + (sptr)internal_syscall(SYSCALL(read), fd, (uptr)buf, count)); return res; } uptr internal_write(fd_t fd, const void *buf, uptr count) { sptr res; -#if SANITIZER_NETBSD - HANDLE_EINTR(res, internal_syscall_ptr(SYSCALL(write), fd, buf, count)); -#else - HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(write), fd, (uptr)buf, - count)); -#endif + HANDLE_EINTR(res, + (sptr)internal_syscall(SYSCALL(write), fd, (uptr)buf, count)); return res; } uptr internal_ftruncate(fd_t fd, uptr size) { sptr res; -#if SANITIZER_NETBSD - HANDLE_EINTR(res, internal_syscall(SYSCALL(ftruncate), fd, 0, (s64)size)); -#else HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(ftruncate), fd, (OFF_T)size)); -#endif return res; } @@ -301,12 +304,11 @@ static void kernel_stat_to_stat(struct kernel_stat *in, struct stat *out) { #endif uptr internal_stat(const char *path, void *buf) { -#if SANITIZER_FREEBSD || SANITIZER_NETBSD - return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, - (uptr)buf, 0); +#if SANITIZER_FREEBSD || SANITIZER_OPENBSD + return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf, 0); #elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS - return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, - (uptr)buf, 0); + return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf, + 0); #elif SANITIZER_LINUX_USES_64BIT_SYSCALLS # if defined(__mips64) // For mips64, stat syscall fills buffer in the format of kernel_stat @@ -326,14 +328,12 @@ uptr internal_stat(const char *path, void *buf) { } uptr internal_lstat(const char *path, void *buf) { -#if SANITIZER_NETBSD - return internal_syscall(SYSCALL(lstat), path, buf); -#elif SANITIZER_FREEBSD - return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, - (uptr)buf, AT_SYMLINK_NOFOLLOW); +#if SANITIZER_FREEBSD || SANITIZER_OPENBSD + return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf, + AT_SYMLINK_NOFOLLOW); #elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS - return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, - (uptr)buf, AT_SYMLINK_NOFOLLOW); + return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf, + AT_SYMLINK_NOFOLLOW); #elif SANITIZER_LINUX_USES_64BIT_SYSCALLS # if SANITIZER_MIPS64 // For mips64, lstat syscall fills buffer in the format of kernel_stat @@ -353,8 +353,9 @@ uptr internal_lstat(const char *path, void *buf) { } uptr internal_fstat(fd_t fd, void *buf) { -#if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS || SANITIZER_NETBSD -# if SANITIZER_MIPS64 +#if SANITIZER_FREEBSD || SANITIZER_OPENBSD || \ + SANITIZER_LINUX_USES_64BIT_SYSCALLS +#if SANITIZER_MIPS64 && !SANITIZER_OPENBSD // For mips64, fstat syscall fills buffer in the format of kernel_stat struct kernel_stat kbuf; int res = internal_syscall(SYSCALL(fstat), fd, &kbuf); @@ -387,18 +388,19 @@ uptr internal_dup2(int oldfd, int newfd) { } uptr internal_readlink(const char *path, char *buf, uptr bufsize) { -#if SANITIZER_NETBSD - return internal_syscall_ptr(SYSCALL(readlink), path, buf, bufsize); -#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS - return internal_syscall(SYSCALL(readlinkat), AT_FDCWD, - (uptr)path, (uptr)buf, bufsize); +#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS + return internal_syscall(SYSCALL(readlinkat), AT_FDCWD, (uptr)path, (uptr)buf, + bufsize); +#elif SANITIZER_OPENBSD + return internal_syscall(SYSCALL(readlinkat), AT_FDCWD, (uptr)path, (uptr)buf, + bufsize); #else - return internal_syscall(SYSCALL(readlink), (uptr)path, (uptr)buf, bufsize); + return internal_syscall(SYSCALL(readlink), path, buf, bufsize); #endif } uptr internal_unlink(const char *path) { -#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS +#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS || SANITIZER_OPENBSD return internal_syscall(SYSCALL(unlinkat), AT_FDCWD, (uptr)path, 0); #else return internal_syscall(SYSCALL(unlink), (uptr)path); @@ -406,7 +408,7 @@ uptr internal_unlink(const char *path) { } uptr internal_rename(const char *oldpath, const char *newpath) { -#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS +#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS || SANITIZER_OPENBSD return internal_syscall(SYSCALL(renameat), AT_FDCWD, (uptr)oldpath, AT_FDCWD, (uptr)newpath); #else @@ -419,7 +421,7 @@ uptr internal_sched_yield() { } void internal__exit(int exitcode) { -#if SANITIZER_FREEBSD || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_OPENBSD internal_syscall(SYSCALL(exit), exitcode); #else internal_syscall(SYSCALL(exit_group), exitcode); @@ -441,6 +443,7 @@ uptr internal_execve(const char *filename, char *const argv[], return internal_syscall(SYSCALL(execve), (uptr)filename, (uptr)argv, (uptr)envp); } +#endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD // ----------------- sanitizer_common.h bool FileExists(const char *filename) { @@ -455,36 +458,59 @@ bool FileExists(const char *filename) { return S_ISREG(st.st_mode); } +#if !SANITIZER_NETBSD tid_t GetTid() { #if SANITIZER_FREEBSD - return (uptr)pthread_self(); -#elif SANITIZER_NETBSD - return _lwp_self(); + long Tid; + thr_self(&Tid); + return Tid; +#elif SANITIZER_OPENBSD + return internal_syscall(SYSCALL(getthrid)); +#elif SANITIZER_SOLARIS + return thr_self(); #else return internal_syscall(SYSCALL(gettid)); #endif } +int TgKill(pid_t pid, tid_t tid, int sig) { +#if SANITIZER_LINUX + return internal_syscall(SYSCALL(tgkill), pid, tid, sig); +#elif SANITIZER_FREEBSD + return internal_syscall(SYSCALL(thr_kill2), pid, tid, sig); +#elif SANITIZER_OPENBSD + (void)pid; + return internal_syscall(SYSCALL(thrkill), tid, sig, nullptr); +#elif SANITIZER_SOLARIS + (void)pid; + return thr_kill(tid, sig); +#endif +} +#endif + +#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD u64 NanoTime() { -#if SANITIZER_FREEBSD || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_OPENBSD timeval tv; #else kernel_timeval tv; #endif internal_memset(&tv, 0, sizeof(tv)); -#if SANITIZER_NETBSD - internal_syscall_ptr(SYSCALL(gettimeofday), &tv, NULL); -#else - internal_syscall(SYSCALL(gettimeofday), (uptr)&tv, 0); -#endif + internal_syscall(SYSCALL(gettimeofday), &tv, 0); return (u64)tv.tv_sec * 1000*1000*1000 + tv.tv_usec * 1000; } +uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) { + return internal_syscall(SYSCALL(clock_gettime), clk_id, tp); +} +#endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD + // Like getenv, but reads env directly from /proc (on Linux) or parses the -// 'environ' array (on FreeBSD) and does not use libc. This function should be -// called first inside __asan_init. +// 'environ' array (on some others) and does not use libc. This function +// should be called first inside __asan_init. const char *GetEnv(const char *name) { -#if SANITIZER_FREEBSD || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD || \ + SANITIZER_SOLARIS if (::environ != 0) { uptr NameLen = internal_strlen(name); for (char **Env = ::environ; *Env != 0; Env++) { @@ -522,13 +548,14 @@ const char *GetEnv(const char *name) { #endif } -#if !SANITIZER_FREEBSD +#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD && !SANITIZER_OPENBSD extern "C" { - SANITIZER_WEAK_ATTRIBUTE extern void *__libc_stack_end; +SANITIZER_WEAK_ATTRIBUTE extern void *__libc_stack_end; } #endif -#if !SANITIZER_GO && !SANITIZER_FREEBSD +#if !SANITIZER_GO && !SANITIZER_FREEBSD && !SANITIZER_NETBSD && \ + !SANITIZER_OPENBSD static void ReadNullSepFileToArray(const char *path, char ***arr, int arr_size) { char *buff; @@ -553,11 +580,27 @@ static void ReadNullSepFileToArray(const char *path, char ***arr, } #endif +#if !SANITIZER_OPENBSD static void GetArgsAndEnv(char ***argv, char ***envp) { -#if !SANITIZER_FREEBSD +#if SANITIZER_FREEBSD + // On FreeBSD, retrieving the argument and environment arrays is done via the + // kern.ps_strings sysctl, which returns a pointer to a structure containing + // this information. See also . + ps_strings *pss; + uptr sz = sizeof(pss); + if (internal_sysctlbyname("kern.ps_strings", &pss, &sz, NULL, 0) == -1) { + Printf("sysctl kern.ps_strings failed\n"); + Die(); + } + *argv = pss->ps_argvstr; + *envp = pss->ps_envstr; +#elif SANITIZER_NETBSD + *argv = __ps_strings->ps_argvstr; + *envp = __ps_strings->ps_envstr; +#else // SANITIZER_FREEBSD #if !SANITIZER_GO if (&__libc_stack_end) { -#endif +#endif // !SANITIZER_GO uptr* stack_end = (uptr*)__libc_stack_end; int argc = *stack_end; *argv = (char**)(stack_end + 1); @@ -568,20 +611,8 @@ static void GetArgsAndEnv(char ***argv, char ***envp) { ReadNullSepFileToArray("/proc/self/cmdline", argv, kMaxArgv); ReadNullSepFileToArray("/proc/self/environ", envp, kMaxEnvp); } -#endif -#else - // On FreeBSD, retrieving the argument and environment arrays is done via the - // kern.ps_strings sysctl, which returns a pointer to a structure containing - // this information. See also . - ps_strings *pss; - size_t sz = sizeof(pss); - if (sysctlbyname("kern.ps_strings", &pss, &sz, NULL, 0) == -1) { - Printf("sysctl kern.ps_strings failed\n"); - Die(); - } - *argv = pss->ps_argvstr; - *envp = pss->ps_envstr; -#endif +#endif // !SANITIZER_GO +#endif // SANITIZER_FREEBSD } char **GetArgv() { @@ -592,14 +623,33 @@ char **GetArgv() { void ReExec() { 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("/proc/self/exe", 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(); } +#endif +#if !SANITIZER_SOLARIS enum MutexState { MtxUnlocked = 0, MtxLocked = 1, @@ -619,9 +669,10 @@ void BlockingMutex::Lock() { #if SANITIZER_FREEBSD _umtx_op(m, UMTX_OP_WAIT_UINT, MtxSleeping, 0, 0); #elif SANITIZER_NETBSD - sched_yield(); /* No userspace futex-like synchromization */ + sched_yield(); /* No userspace futex-like synchronization */ #else - internal_syscall(SYSCALL(futex), (uptr)m, FUTEX_WAIT, MtxSleeping, 0, 0, 0); + internal_syscall(SYSCALL(futex), (uptr)m, FUTEX_WAIT_PRIVATE, MtxSleeping, + 0, 0, 0); #endif } } @@ -634,9 +685,9 @@ void BlockingMutex::Unlock() { #if SANITIZER_FREEBSD _umtx_op(m, UMTX_OP_WAKE, 1, 0, 0); #elif SANITIZER_NETBSD - /* No userspace futex-like synchromization */ + /* No userspace futex-like synchronization */ #else - internal_syscall(SYSCALL(futex), (uptr)m, FUTEX_WAKE, 1, 0, 0, 0); + internal_syscall(SYSCALL(futex), (uptr)m, FUTEX_WAKE_PRIVATE, 1, 0, 0, 0); #endif } } @@ -645,12 +696,15 @@ void BlockingMutex::CheckLocked() { atomic_uint32_t *m = reinterpret_cast(&opaque_storage_); CHECK_NE(MtxUnlocked, atomic_load(m, memory_order_relaxed)); } +#endif // !SANITIZER_SOLARIS // ----------------- sanitizer_linux.h // The actual size of this structure is specified by d_reclen. // Note that getdents64 uses a different structure format. We only provide the // 32-bit syscall here. #if SANITIZER_NETBSD +// Not used +#elif SANITIZER_OPENBSD // struct dirent is different for Linux and us. At this moment, we use only // d_fileno (Linux call this d_ino), d_reclen, and d_name. struct linux_dirent { @@ -677,32 +731,16 @@ struct linux_dirent { }; #endif +#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD // Syscall wrappers. uptr internal_ptrace(int request, int pid, void *addr, void *data) { -#if SANITIZER_NETBSD - // XXX We need additional work for ptrace: - // - for request, we use PT_FOO whereas Linux uses PTRACE_FOO - // - data is int for us, but void * for Linux - // - Linux sometimes uses data in the case where we use addr instead - // At this moment, this function is used only within - // "#if SANITIZER_LINUX && defined(__x86_64__)" block in - // sanitizer_stoptheworld_linux_libcdep.cc. - return internal_syscall_ptr(SYSCALL(ptrace), request, pid, (uptr)addr, - (uptr)data); -#else return internal_syscall(SYSCALL(ptrace), request, pid, (uptr)addr, (uptr)data); -#endif } uptr internal_waitpid(int pid, int *status, int options) { -#if SANITIZER_NETBSD - return internal_syscall(SYSCALL(wait4), pid, status, options, - NULL /* rusage */); -#else return internal_syscall(SYSCALL(wait4), pid, (uptr)status, options, 0 /* rusage */); -#endif } uptr internal_getpid() { @@ -714,9 +752,7 @@ uptr internal_getppid() { } uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count) { -#if SANITIZER_NETBSD - return internal_syscall(SYSCALL(getdents), fd, dirp, (uptr)count); -#elif SANITIZER_FREEBSD +#if SANITIZER_FREEBSD return internal_syscall(SYSCALL(getdirentries), fd, (uptr)dirp, count, NULL); #elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS return internal_syscall(SYSCALL(getdents64), fd, (uptr)dirp, count); @@ -726,11 +762,7 @@ uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count) { } uptr internal_lseek(fd_t fd, OFF_T offset, int whence) { -#if SANITIZER_NETBSD - return internal_syscall64(SYSCALL(lseek), fd, 0, offset, whence); -#else return internal_syscall(SYSCALL(lseek), fd, offset, whence); -#endif } #if SANITIZER_LINUX @@ -751,6 +783,25 @@ int internal_fork() { #endif } +#if SANITIZER_FREEBSD || SANITIZER_OPENBSD +int internal_sysctl(const int *name, unsigned int namelen, void *oldp, + uptr *oldlenp, const void *newp, uptr newlen) { +#if SANITIZER_OPENBSD + 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); +#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); +} +#endif +#endif + #if SANITIZER_LINUX #define SA_RESTORER 0x04000000 // Doesn't set sa_restorer if the caller did not set it, so use with caution @@ -809,19 +860,18 @@ int internal_sigaction_syscall(int signum, const void *act, void *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; - } + if (u_adjust.sa_restorer == nullptr) { + u_adjust.sa_restorer = internal_sigreturn; + } #endif - return internal_sigaction_norestorer(signum, (const void *)&u_adjust, - oldact); + return internal_sigaction_norestorer(signum, (const void *)&u_adjust, oldact); } -#endif // defined(__x86_64__) && !SANITIZER_GO +#endif // defined(__x86_64__) && !SANITIZER_GO #endif // SANITIZER_LINUX uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set, - __sanitizer_sigset_t *oldset) { -#if SANITIZER_FREEBSD || SANITIZER_NETBSD + __sanitizer_sigset_t *oldset) { +#if SANITIZER_FREEBSD || SANITIZER_OPENBSD return internal_syscall(SYSCALL(sigprocmask), how, set, oldset); #else __sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set; @@ -860,75 +910,107 @@ bool internal_sigismember(__sanitizer_sigset_t *set, int signum) { const uptr bit = signum % (sizeof(k_set->sig[0]) * 8); return k_set->sig[idx] & (1 << bit); } -#endif // SANITIZER_LINUX +#elif SANITIZER_FREEBSD +void internal_sigdelset(__sanitizer_sigset_t *set, int signum) { + sigset_t *rset = reinterpret_cast(set); + sigdelset(rset, signum); +} + +bool internal_sigismember(__sanitizer_sigset_t *set, int signum) { + sigset_t *rset = reinterpret_cast(set); + return sigismember(rset, signum); +} +#endif +#endif // !SANITIZER_SOLARIS +#if !SANITIZER_NETBSD // ThreadLister implementation. -ThreadLister::ThreadLister(int pid) - : pid_(pid), - descriptor_(-1), - buffer_(4096), - error_(true), - entry_((struct linux_dirent *)buffer_.data()), - bytes_read_(0) { +ThreadLister::ThreadLister(pid_t pid) : pid_(pid), buffer_(4096) { char task_directory_path[80]; internal_snprintf(task_directory_path, sizeof(task_directory_path), "/proc/%d/task/", pid); - uptr openrv = internal_open(task_directory_path, O_RDONLY | O_DIRECTORY); - if (internal_iserror(openrv)) { - error_ = true; + descriptor_ = internal_open(task_directory_path, O_RDONLY | O_DIRECTORY); + if (internal_iserror(descriptor_)) { Report("Can't open /proc/%d/task for reading.\n", pid); - } else { - error_ = false; - descriptor_ = openrv; } } -int ThreadLister::GetNextTID() { - int tid = -1; - do { - if (error_) - return -1; - if ((char *)entry_ >= &buffer_[bytes_read_] && !GetDirectoryEntries()) - return -1; - if (entry_->d_ino != 0 && entry_->d_name[0] >= '0' && - entry_->d_name[0] <= '9') { - // Found a valid tid. - tid = (int)internal_atoll(entry_->d_name); +ThreadLister::Result ThreadLister::ListThreads( + InternalMmapVector *threads) { + if (internal_iserror(descriptor_)) + return Error; + internal_lseek(descriptor_, 0, SEEK_SET); + threads->clear(); + + Result result = Ok; + for (bool first_read = true;; first_read = false) { + // Resize to max capacity if it was downsized by IsAlive. + buffer_.resize(buffer_.capacity()); + CHECK_GE(buffer_.size(), 4096); + uptr read = internal_getdents( + descriptor_, (struct linux_dirent *)buffer_.data(), buffer_.size()); + if (!read) + return result; + if (internal_iserror(read)) { + Report("Can't read directory entries from /proc/%d/task.\n", pid_); + return Error; } - entry_ = (struct linux_dirent *)(((char *)entry_) + entry_->d_reclen); - } while (tid < 0); - return tid; -} -void ThreadLister::Reset() { - if (error_ || descriptor_ < 0) - return; - internal_lseek(descriptor_, 0, SEEK_SET); -} + for (uptr begin = (uptr)buffer_.data(), end = begin + read; begin < end;) { + struct linux_dirent *entry = (struct linux_dirent *)begin; + begin += entry->d_reclen; + if (entry->d_ino == 1) { + // Inode 1 is for bad blocks and also can be a reason for early return. + // Should be emitted if kernel tried to output terminating thread. + // See proc_task_readdir implementation in Linux. + result = Incomplete; + } + if (entry->d_ino && *entry->d_name >= '0' && *entry->d_name <= '9') + threads->push_back(internal_atoll(entry->d_name)); + } -ThreadLister::~ThreadLister() { - if (descriptor_ >= 0) - internal_close(descriptor_); + // Now we are going to detect short-read or early EOF. In such cases Linux + // can return inconsistent list with missing alive threads. + // Code will just remember that the list can be incomplete but it will + // continue reads to return as much as possible. + if (!first_read) { + // The first one was a short-read by definition. + result = Incomplete; + } else if (read > buffer_.size() - 1024) { + // Read was close to the buffer size. So double the size and assume the + // worst. + buffer_.resize(buffer_.size() * 2); + result = Incomplete; + } else if (!threads->empty() && !IsAlive(threads->back())) { + // Maybe Linux early returned from read on terminated thread (!pid_alive) + // and failed to restore read position. + // See next_tid and proc_task_instantiate in Linux. + result = Incomplete; + } + } } -bool ThreadLister::error() { return error_; } - -bool ThreadLister::GetDirectoryEntries() { - CHECK_GE(descriptor_, 0); - CHECK_NE(error_, true); - bytes_read_ = internal_getdents(descriptor_, - (struct linux_dirent *)buffer_.data(), - buffer_.size()); - if (internal_iserror(bytes_read_)) { - Report("Can't read directory entries from /proc/%d/task.\n", pid_); - error_ = true; +bool ThreadLister::IsAlive(int tid) { + // /proc/%d/task/%d/status uses same call to detect alive threads as + // proc_task_readdir. See task_state implementation in Linux. + char path[80]; + internal_snprintf(path, sizeof(path), "/proc/%d/task/%d/status", pid_, tid); + if (!ReadFileToVector(path, &buffer_) || buffer_.empty()) return false; - } else if (bytes_read_ == 0) { + buffer_.push_back(0); + static const char kPrefix[] = "\nPPid:"; + const char *field = internal_strstr(buffer_.data(), kPrefix); + if (!field) return false; - } - entry_ = (struct linux_dirent *)buffer_.data(); - return true; + field += internal_strlen(kPrefix); + return (int)internal_atoll(field) != 0; +} + +ThreadLister::~ThreadLister() { + if (!internal_iserror(descriptor_)) + internal_close(descriptor_); } +#endif #if SANITIZER_WORDSIZE == 32 // Take care of unusable kernel area in top gigabyte. @@ -966,7 +1048,7 @@ static uptr GetKernelAreaSize() { #endif // SANITIZER_WORDSIZE == 32 uptr GetMaxVirtualAddress() { -#if SANITIZER_NETBSD && defined(__x86_64__) +#if (SANITIZER_NETBSD || SANITIZER_OPENBSD) && defined(__x86_64__) return 0x7f7ffffff000ULL; // (0x00007f8000000000 - PAGE_SIZE) #elif SANITIZER_WORDSIZE == 64 # if defined(__powerpc64__) || defined(__aarch64__) @@ -989,15 +1071,21 @@ uptr GetMaxVirtualAddress() { # if defined(__s390__) return (1ULL << 31) - 1; // 0x7fffffff; # else - uptr res = (1ULL << 32) - 1; // 0xffffffff; - if (!common_flags()->full_address_space) - res -= GetKernelAreaSize(); - CHECK_LT(reinterpret_cast(&res), res); - return res; + return (1ULL << 32) - 1; // 0xffffffff; # endif #endif // SANITIZER_WORDSIZE } +uptr GetMaxUserVirtualAddress() { + uptr addr = GetMaxVirtualAddress(); +#if SANITIZER_WORDSIZE == 32 && !defined(__s390__) + if (!common_flags()->full_address_space) + addr -= GetKernelAreaSize(); + CHECK_LT(reinterpret_cast(&addr), addr); +#endif + return addr; +} + uptr GetPageSize() { // Android post-M sysconf(_SC_PAGESIZE) crashes if called from .preinit_array. #if SANITIZER_ANDROID @@ -1011,7 +1099,13 @@ uptr GetPageSize() { #endif } +#if !SANITIZER_OPENBSD uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { +#if SANITIZER_SOLARIS + const char *default_module_name = getexecname(); + CHECK_NE(default_module_name, NULL); + return internal_snprintf(buf, buf_len, "%s", default_module_name); +#else #if SANITIZER_FREEBSD || SANITIZER_NETBSD #if SANITIZER_FREEBSD const int Mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; @@ -1019,8 +1113,9 @@ uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { const int Mib[4] = {CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME}; #endif const char *default_module_name = "kern.proc.pathname"; - size_t Size = buf_len; - bool IsErr = (sysctl(Mib, ARRAY_SIZE(Mib), buf, &Size, NULL, 0) != 0); + uptr Size = buf_len; + bool IsErr = + (internal_sysctl(Mib, ARRAY_SIZE(Mib), buf, &Size, NULL, 0) != 0); int readlink_error = IsErr ? errno : 0; uptr module_name_len = Size; #else @@ -1029,7 +1124,7 @@ uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { default_module_name, buf, buf_len); int readlink_error; bool IsErr = internal_iserror(module_name_len, &readlink_error); -#endif +#endif // SANITIZER_SOLARIS if (IsErr) { // We can't read binary name for some reason, assume it's unknown. Report("WARNING: reading executable name failed with errno %d, " @@ -1039,7 +1134,9 @@ uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { CHECK_LT(module_name_len, buf_len); } return module_name_len; +#endif } +#endif // !SANITIZER_OPENBSD uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) { #if SANITIZER_LINUX @@ -1072,10 +1169,10 @@ 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)) { CHECK_NE(map, nullptr); -#if !SANITIZER_FREEBSD +#if !SANITIZER_FREEBSD && !SANITIZER_OPENBSD typedef ElfW(Phdr) Elf_Phdr; typedef ElfW(Ehdr) Elf_Ehdr; -#endif // !SANITIZER_FREEBSD +#endif // !SANITIZER_FREEBSD && !SANITIZER_OPENBSD char *base = (char *)map->l_addr; Elf_Ehdr *ehdr = (Elf_Ehdr *)base; char *phdrs = base + ehdr->e_phoff; @@ -1168,7 +1265,7 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, "d"(parent_tidptr), "r"(r8), "r"(r10) - : "rsp", "memory", "r11", "rcx"); + : "memory", "r11", "rcx"); return res; } #elif defined(__mips__) @@ -1560,6 +1657,16 @@ static int dl_iterate_phdr_test_cb(struct dl_phdr_info *info, size_t size, static atomic_uint32_t android_api_level; +static AndroidApiLevel AndroidDetectApiLevelStatic() { +#if __ANDROID_API__ <= 19 + return ANDROID_KITKAT; +#elif __ANDROID_API__ <= 22 + return ANDROID_LOLLIPOP_MR1; +#else + return ANDROID_POST_LOLLIPOP; +#endif +} + static AndroidApiLevel AndroidDetectApiLevel() { if (!&dl_iterate_phdr) return ANDROID_KITKAT; // K or lower @@ -1572,11 +1679,14 @@ static AndroidApiLevel AndroidDetectApiLevel() { // interesting to detect. } +extern "C" __attribute__((weak)) void* _DYNAMIC; + AndroidApiLevel AndroidGetApiLevel() { AndroidApiLevel level = (AndroidApiLevel)atomic_load(&android_api_level, memory_order_relaxed); if (level) return level; - level = AndroidDetectApiLevel(); + level = &_DYNAMIC == nullptr ? AndroidDetectApiLevelStatic() + : AndroidDetectApiLevel(); atomic_store(&android_api_level, level, memory_order_relaxed); return level; } @@ -1589,6 +1699,8 @@ static HandleSignalMode GetHandleSignalModeImpl(int signum) { return common_flags()->handle_abort; case SIGILL: return common_flags()->handle_sigill; + case SIGTRAP: + return common_flags()->handle_sigtrap; case SIGFPE: return common_flags()->handle_sigfpe; case SIGSEGV: @@ -1655,18 +1767,78 @@ static bool Aarch64GetESR(ucontext_t *ucontext, u64 *esr) { } #endif +#if SANITIZER_OPENBSD +using Context = sigcontext; +#else +using Context = ucontext_t; +#endif + SignalContext::WriteFlag SignalContext::GetWriteFlag() const { - ucontext_t *ucontext = (ucontext_t *)context; + Context *ucontext = (Context *)context; #if defined(__x86_64__) || defined(__i386__) static const uptr PF_WRITE = 1U << 1; #if SANITIZER_FREEBSD uptr err = ucontext->uc_mcontext.mc_err; #elif SANITIZER_NETBSD uptr err = ucontext->uc_mcontext.__gregs[_REG_ERR]; +#elif SANITIZER_OPENBSD + uptr err = ucontext->sc_err; +#elif SANITIZER_SOLARIS && defined(__i386__) + const int Err = 13; + uptr err = ucontext->uc_mcontext.gregs[Err]; #else uptr err = ucontext->uc_mcontext.gregs[REG_ERR]; -#endif +#endif // SANITIZER_FREEBSD return err & PF_WRITE ? WRITE : READ; +#elif defined(__mips__) + uint32_t *exception_source; + uint32_t faulty_instruction; + uint32_t op_code; + + exception_source = (uint32_t *)ucontext->uc_mcontext.pc; + faulty_instruction = (uint32_t)(*exception_source); + + op_code = (faulty_instruction >> 26) & 0x3f; + + // FIXME: Add support for FPU, microMIPS, DSP, MSA memory instructions. + switch (op_code) { + case 0x28: // sb + case 0x29: // sh + case 0x2b: // sw + case 0x3f: // sd +#if __mips_isa_rev < 6 + case 0x2c: // sdl + case 0x2d: // sdr + case 0x2a: // swl + case 0x2e: // swr +#endif + return SignalContext::WRITE; + + case 0x20: // lb + case 0x24: // lbu + case 0x21: // lh + case 0x25: // lhu + case 0x23: // lw + case 0x27: // lwu + case 0x37: // ld +#if __mips_isa_rev < 6 + case 0x1a: // ldl + case 0x1b: // ldr + case 0x22: // lwl + case 0x26: // lwr +#endif + return SignalContext::READ; +#if __mips_isa_rev == 6 + case 0x3b: // pcrel + op_code = (faulty_instruction >> 19) & 0x3; + switch (op_code) { + case 0x1: // lwpc + case 0x2: // lwupc + return SignalContext::READ; + } +#endif + } + return SignalContext::UNKNOWN; #elif defined(__arm__) static const uptr FSR_WRITE = 1U << 11; uptr fsr = ucontext->uc_mcontext.error_code; @@ -1676,6 +1848,12 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { u64 esr; if (!Aarch64GetESR(ucontext, &esr)) return UNKNOWN; return esr & ESR_ELx_WNR ? WRITE : READ; +#elif SANITIZER_SOLARIS && defined(__sparc__) + // Decode the instruction to determine the access type. + // From OpenSolaris $SRC/uts/sun4/os/trap.c (get_accesstype). + uptr pc = ucontext->uc_mcontext.gregs[REG_PC]; + u32 instr = *(u32 *)pc; + return (instr >> 21) & 1 ? WRITE: READ; #else (void)ucontext; return UNKNOWN; // FIXME: Implement. @@ -1687,7 +1865,13 @@ void SignalContext::DumpAllRegisters(void *context) { } static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { -#if defined(__arm__) +#if SANITIZER_NETBSD + // This covers all NetBSD architectures + ucontext_t *ucontext = (ucontext_t *)context; + *pc = _UC_MACHINE_PC(ucontext); + *bp = _UC_MACHINE_FP(ucontext); + *sp = _UC_MACHINE_SP(ucontext); +#elif defined(__arm__) ucontext_t *ucontext = (ucontext_t*)context; *pc = ucontext->uc_mcontext.arm_pc; *bp = ucontext->uc_mcontext.arm_fp; @@ -1709,11 +1893,11 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { *pc = ucontext->uc_mcontext.mc_rip; *bp = ucontext->uc_mcontext.mc_rbp; *sp = ucontext->uc_mcontext.mc_rsp; -#elif SANITIZER_NETBSD - ucontext_t *ucontext = (ucontext_t *)context; - *pc = ucontext->uc_mcontext.__gregs[_REG_RIP]; - *bp = ucontext->uc_mcontext.__gregs[_REG_RBP]; - *sp = ucontext->uc_mcontext.__gregs[_REG_RSP]; +#elif SANITIZER_OPENBSD + sigcontext *ucontext = (sigcontext *)context; + *pc = ucontext->sc_rip; + *bp = ucontext->sc_rbp; + *sp = ucontext->sc_rsp; # else ucontext_t *ucontext = (ucontext_t*)context; *pc = ucontext->uc_mcontext.gregs[REG_RIP]; @@ -1726,13 +1910,26 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { *pc = ucontext->uc_mcontext.mc_eip; *bp = ucontext->uc_mcontext.mc_ebp; *sp = ucontext->uc_mcontext.mc_esp; -#elif SANITIZER_NETBSD - ucontext_t *ucontext = (ucontext_t *)context; - *pc = ucontext->uc_mcontext.__gregs[_REG_EIP]; - *bp = ucontext->uc_mcontext.__gregs[_REG_EBP]; - *sp = ucontext->uc_mcontext.__gregs[_REG_ESP]; +#elif SANITIZER_OPENBSD + sigcontext *ucontext = (sigcontext *)context; + *pc = ucontext->sc_eip; + *bp = ucontext->sc_ebp; + *sp = ucontext->sc_esp; # else ucontext_t *ucontext = (ucontext_t*)context; +# if SANITIZER_SOLARIS + /* Use the numeric values: the symbolic ones are undefined by llvm + include/llvm/Support/Solaris.h. */ +# ifndef REG_EIP +# define REG_EIP 14 // REG_PC +# endif +# ifndef REG_EBP +# define REG_EBP 6 // REG_FP +# endif +# ifndef REG_ESP +# define REG_ESP 17 // REG_SP +# endif +# endif *pc = ucontext->uc_mcontext.gregs[REG_EIP]; *bp = ucontext->uc_mcontext.gregs[REG_EBP]; *sp = ucontext->uc_mcontext.gregs[REG_ESP]; @@ -1747,7 +1944,16 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { #elif defined(__sparc__) ucontext_t *ucontext = (ucontext_t*)context; uptr *stk_ptr; -# if defined (__arch64__) +# if defined (__sparcv9) +# ifndef MC_PC +# define MC_PC REG_PC +# endif +# ifndef MC_O6 +# define MC_O6 REG_O6 +# endif +# ifdef SANITIZER_SOLARIS +# define mc_gregs gregs +# endif *pc = ucontext->uc_mcontext.mc_gregs[MC_PC]; *sp = ucontext->uc_mcontext.mc_gregs[MC_O6]; stk_ptr = (uptr *) (*sp + 2047); @@ -1783,6 +1989,30 @@ void MaybeReexec() { // No need to re-exec on Linux. } +void CheckASLR() { +#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_ASLR)) { + Printf("This sanitizer is not compatible with enabled ASLR\n"); + Die(); + } +#else + // Do nothing +#endif +} + void PrintModuleMap() { } void CheckNoDeepBind(const char *filename, int flag) { @@ -1801,7 +2031,8 @@ void CheckNoDeepBind(const char *filename, int flag) { } uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding, - uptr *largest_gap_found) { + uptr *largest_gap_found, + uptr *max_occupied_addr) { UNREACHABLE("FindAvailableMemoryRange is not available"); return 0; } @@ -1809,6 +2040,15 @@ uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding, bool GetRandom(void *buffer, uptr length, bool blocking) { if (!buffer || !length || length > 256) return false; +#if SANITIZER_USE_GETENTROPY + uptr rnd = getentropy(buffer, length); + int rverrno = 0; + if (internal_iserror(rnd, &rverrno) && rverrno == EFAULT) + return false; + else if (rnd == 0) + return true; +#endif // SANITIZER_USE_GETENTROPY + #if SANITIZER_USE_GETRANDOM static atomic_uint8_t skip_getrandom_syscall; if (!atomic_load_relaxed(&skip_getrandom_syscall)) { @@ -1821,7 +2061,7 @@ bool GetRandom(void *buffer, uptr length, bool blocking) { else if (res == length) return true; } -#endif // SANITIZER_USE_GETRANDOM +#endif // SANITIZER_USE_GETRANDOM // Up to 256 bytes, a read off /dev/urandom will not be interrupted. // blocking is moot here, O_NONBLOCK has no effect when opening /dev/urandom. uptr fd = internal_open("/dev/urandom", O_RDONLY); @@ -1836,4 +2076,4 @@ bool GetRandom(void *buffer, uptr length, bool blocking) { } // namespace __sanitizer -#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#endif diff --git a/libsanitizer/sanitizer_common/sanitizer_linux.h b/libsanitizer/sanitizer_common/sanitizer_linux.h index 910703d8b29..e1f606fd5f6 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux.h +++ b/libsanitizer/sanitizer_common/sanitizer_linux.h @@ -12,11 +12,14 @@ #define SANITIZER_LINUX_H #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_OPENBSD || SANITIZER_SOLARIS #include "sanitizer_common.h" #include "sanitizer_internal_defs.h" #include "sanitizer_platform_limits_netbsd.h" +#include "sanitizer_platform_limits_openbsd.h" #include "sanitizer_platform_limits_posix.h" +#include "sanitizer_platform_limits_solaris.h" #include "sanitizer_posix.h" struct link_map; // Opaque type returned by dlopen(). @@ -44,6 +47,7 @@ uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count); uptr internal_sigaltstack(const void* ss, void* oss); uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set, __sanitizer_sigset_t *oldset); +uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp); // Linux-only syscalls. #if SANITIZER_LINUX @@ -63,28 +67,28 @@ void internal_sigdelset(__sanitizer_sigset_t *set, int signum); uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg, int *parent_tidptr, void *newtls, int *child_tidptr); #endif +#elif SANITIZER_FREEBSD +void internal_sigdelset(__sanitizer_sigset_t *set, int signum); #endif // SANITIZER_LINUX // This class reads thread IDs from /proc//task using only syscalls. class ThreadLister { public: - explicit ThreadLister(int pid); + explicit ThreadLister(pid_t pid); ~ThreadLister(); - // GetNextTID returns -1 if the list of threads is exhausted, or if there has - // been an error. - int GetNextTID(); - void Reset(); - bool error(); + enum Result { + Error, + Incomplete, + Ok, + }; + Result ListThreads(InternalMmapVector *threads); private: - bool GetDirectoryEntries(); - - int pid_; - int descriptor_; - InternalScopedBuffer buffer_; - bool error_; - struct linux_dirent* entry_; - int bytes_read_; + bool IsAlive(int tid); + + pid_t pid_; + int descriptor_ = -1; + InternalMmapVector buffer_; }; // Exposed for testing. @@ -140,5 +144,5 @@ ALWAYS_INLINE uptr *get_android_tls_ptr() { } // namespace __sanitizer -#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#endif #endif // SANITIZER_LINUX_H diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc index 3b1a2174c46..32f335eaf23 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_linux_libcdep.cc @@ -12,7 +12,8 @@ #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_OPENBSD || SANITIZER_SOLARIS #include "sanitizer_allocator_internal.h" #include "sanitizer_atomic.h" @@ -23,7 +24,6 @@ #include "sanitizer_linux.h" #include "sanitizer_placement_new.h" #include "sanitizer_procmaps.h" -#include "sanitizer_stacktrace.h" #include // for dlsym() #include @@ -35,19 +35,36 @@ #if SANITIZER_FREEBSD #include #include +#include #define pthread_getattr_np pthread_attr_get_np #endif -#if SANITIZER_LINUX -#include +#if SANITIZER_OPENBSD +#include +#include +#endif + +#if SANITIZER_NETBSD +#include +#include +#endif + +#if SANITIZER_SOLARIS +#include #endif #if SANITIZER_ANDROID #include +#if !defined(CPU_COUNT) && !defined(__aarch64__) +#include +#include +struct __sanitizer::linux_dirent { + long d_ino; + off_t d_off; + unsigned short d_reclen; + char d_name[]; +}; #endif - -#if SANITIZER_ANDROID && __ANDROID_API__ < 21 -#include #endif #if !SANITIZER_ANDROID @@ -101,13 +118,25 @@ void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top, *stack_bottom = segment.end - stacksize; return; } + uptr stacksize = 0; + void *stackaddr = nullptr; +#if SANITIZER_SOLARIS + stack_t ss; + CHECK_EQ(thr_stksegment(&ss), 0); + stacksize = ss.ss_size; + stackaddr = (char *)ss.ss_sp - stacksize; +#elif SANITIZER_OPENBSD + stack_t sattr; + CHECK_EQ(pthread_stackseg_np(pthread_self(), &sattr), 0); + stackaddr = sattr.ss_sp; + stacksize = sattr.ss_size; +#else // !SANITIZER_SOLARIS pthread_attr_t attr; pthread_attr_init(&attr); CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0); - uptr stacksize = 0; - void *stackaddr = nullptr; my_pthread_attr_getstack(&attr, &stackaddr, &stacksize); pthread_attr_destroy(&attr); +#endif // SANITIZER_SOLARIS *stack_top = (uptr)stackaddr + stacksize; *stack_bottom = (uptr)stackaddr; @@ -126,65 +155,98 @@ bool SetEnv(const char *name, const char *value) { } #endif -bool SanitizerSetThreadName(const char *name) { -#ifdef PR_SET_NAME - return 0 == prctl(PR_SET_NAME, (unsigned long)name, 0, 0, 0); // NOLINT +__attribute__((unused)) static bool GetLibcVersion(int *major, int *minor, + int *patch) { +#ifdef _CS_GNU_LIBC_VERSION + char buf[64]; + uptr len = confstr(_CS_GNU_LIBC_VERSION, buf, sizeof(buf)); + if (len >= sizeof(buf)) + return false; + buf[len] = 0; + static const char kGLibC[] = "glibc "; + if (internal_strncmp(buf, kGLibC, sizeof(kGLibC) - 1) != 0) + return false; + const char *p = buf + sizeof(kGLibC) - 1; + *major = internal_simple_strtoll(p, &p, 10); + *minor = (*p == '.') ? internal_simple_strtoll(p + 1, &p, 10) : 0; + *patch = (*p == '.') ? internal_simple_strtoll(p + 1, &p, 10) : 0; + return true; #else return false; #endif } -bool SanitizerGetThreadName(char *name, int max_len) { -#ifdef PR_GET_NAME - char buff[17]; - if (prctl(PR_GET_NAME, (unsigned long)buff, 0, 0, 0)) // NOLINT - return false; - internal_strncpy(name, buff, max_len); - name[max_len] = 0; - return true; +#if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO && \ + !SANITIZER_NETBSD && !SANITIZER_OPENBSD && !SANITIZER_SOLARIS +static uptr g_tls_size; + +#ifdef __i386__ +# ifndef __GLIBC_PREREQ +# define CHECK_GET_TLS_STATIC_INFO_VERSION 1 +# else +# define CHECK_GET_TLS_STATIC_INFO_VERSION (!__GLIBC_PREREQ(2, 27)) +# endif #else - return false; +# define CHECK_GET_TLS_STATIC_INFO_VERSION 0 #endif -} -#ifndef __GLIBC_PREREQ -#define __GLIBC_PREREQ(x, y) 0 +#if CHECK_GET_TLS_STATIC_INFO_VERSION +# define DL_INTERNAL_FUNCTION __attribute__((regparm(3), stdcall)) +#else +# define DL_INTERNAL_FUNCTION #endif -#if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO && \ - !SANITIZER_NETBSD -static uptr g_tls_size; +namespace { +struct GetTlsStaticInfoCall { + typedef void (*get_tls_func)(size_t*, size_t*); +}; +struct GetTlsStaticInfoRegparmCall { + typedef void (*get_tls_func)(size_t*, size_t*) DL_INTERNAL_FUNCTION; +}; + +template +void CallGetTls(void* ptr, size_t* size, size_t* align) { + typename T::get_tls_func get_tls; + CHECK_EQ(sizeof(get_tls), sizeof(ptr)); + internal_memcpy(&get_tls, &ptr, sizeof(ptr)); + CHECK_NE(get_tls, 0); + get_tls(size, align); +} + +bool CmpLibcVersion(int major, int minor, int patch) { + int ma; + int mi; + int pa; + if (!GetLibcVersion(&ma, &mi, &pa)) + return false; + if (ma > major) + return true; + if (ma < major) + return false; + if (mi > minor) + return true; + if (mi < minor) + return false; + return pa >= patch; +} + +} // namespace void InitTlsSize() { -// all current supported platforms have 16 bytes stack alignment + // all current supported platforms have 16 bytes stack alignment const size_t kStackAlign = 16; + void *get_tls_static_info_ptr = dlsym(RTLD_NEXT, "_dl_get_tls_static_info"); size_t tls_size = 0; size_t tls_align = 0; - void *get_tls_static_info_ptr = dlsym(RTLD_NEXT, "_dl_get_tls_static_info"); -#if defined(__i386__) && !__GLIBC_PREREQ(2, 27) - /* On i?86, _dl_get_tls_static_info used to be internal_function, i.e. - __attribute__((regparm(3), stdcall)) before glibc 2.27 and is normal - function in 2.27 and later. */ - if (!dlvsym(RTLD_NEXT, "glob", "GLIBC_2.27")) { - typedef void (*get_tls_func)(size_t*, size_t*) - __attribute__((regparm(3), stdcall)); - get_tls_func get_tls; - CHECK_EQ(sizeof(get_tls), sizeof(get_tls_static_info_ptr)); - internal_memcpy(&get_tls, &get_tls_static_info_ptr, - sizeof(get_tls_static_info_ptr)); - CHECK_NE(get_tls, 0); - get_tls(&tls_size, &tls_align); - } else -#endif - { - typedef void (*get_tls_func)(size_t*, size_t*); - get_tls_func get_tls; - CHECK_EQ(sizeof(get_tls), sizeof(get_tls_static_info_ptr)); - internal_memcpy(&get_tls, &get_tls_static_info_ptr, - sizeof(get_tls_static_info_ptr)); - CHECK_NE(get_tls, 0); - get_tls(&tls_size, &tls_align); - } + // On i?86, _dl_get_tls_static_info used to be internal_function, i.e. + // __attribute__((regparm(3), stdcall)) before glibc 2.27 and is normal + // function in 2.27 and later. + if (CHECK_GET_TLS_STATIC_INFO_VERSION && !CmpLibcVersion(2, 27, 0)) + CallGetTls(get_tls_static_info_ptr, + &tls_size, &tls_align); + else + CallGetTls(get_tls_static_info_ptr, + &tls_size, &tls_align); if (tls_align < kStackAlign) tls_align = kStackAlign; g_tls_size = RoundUpTo(tls_size, tls_align); @@ -192,79 +254,61 @@ void InitTlsSize() { #else void InitTlsSize() { } #endif // !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO && - // !SANITIZER_NETBSD + // !SANITIZER_NETBSD && !SANITIZER_SOLARIS -#if (defined(__x86_64__) || defined(__i386__) || defined(__mips__) \ - || defined(__aarch64__) || defined(__powerpc64__) || defined(__s390__) \ - || defined(__arm__)) && SANITIZER_LINUX && !SANITIZER_ANDROID +#if (defined(__x86_64__) || defined(__i386__) || defined(__mips__) || \ + defined(__aarch64__) || defined(__powerpc64__) || defined(__s390__) || \ + defined(__arm__)) && \ + SANITIZER_LINUX && !SANITIZER_ANDROID // sizeof(struct pthread) from glibc. -static atomic_uintptr_t kThreadDescriptorSize; +static atomic_uintptr_t thread_descriptor_size; uptr ThreadDescriptorSize() { - uptr val = atomic_load(&kThreadDescriptorSize, memory_order_relaxed); + uptr val = atomic_load_relaxed(&thread_descriptor_size); if (val) return val; #if defined(__x86_64__) || defined(__i386__) || defined(__arm__) -#ifdef _CS_GNU_LIBC_VERSION - char buf[64]; - uptr len = confstr(_CS_GNU_LIBC_VERSION, buf, sizeof(buf)); - if (len < sizeof(buf) && internal_strncmp(buf, "glibc 2.", 8) == 0) { - char *end; - int minor = internal_simple_strtoll(buf + 8, &end, 10); - if (end != buf + 8 && (*end == '\0' || *end == '.' || *end == '-')) { - int patch = 0; - if (*end == '.') - // strtoll will return 0 if no valid conversion could be performed - patch = internal_simple_strtoll(end + 1, nullptr, 10); - - /* sizeof(struct pthread) values from various glibc versions. */ - if (SANITIZER_X32) - val = 1728; // Assume only one particular version for x32. - // For ARM sizeof(struct pthread) changed in Glibc 2.23. - else if (SANITIZER_ARM) - val = minor <= 22 ? 1120 : 1216; - else if (minor <= 3) - val = FIRST_32_SECOND_64(1104, 1696); - else if (minor == 4) - val = FIRST_32_SECOND_64(1120, 1728); - else if (minor == 5) - val = FIRST_32_SECOND_64(1136, 1728); - else if (minor <= 9) - val = FIRST_32_SECOND_64(1136, 1712); - else if (minor == 10) - val = FIRST_32_SECOND_64(1168, 1776); - else if (minor == 11 || (minor == 12 && patch == 1)) - val = FIRST_32_SECOND_64(1168, 2288); - else if (minor <= 14) - val = FIRST_32_SECOND_64(1168, 2304); - else - val = FIRST_32_SECOND_64(1216, 2304); - } - if (val) - atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed); - return val; + int major; + int minor; + int patch; + if (GetLibcVersion(&major, &minor, &patch) && major == 2) { + /* sizeof(struct pthread) values from various glibc versions. */ + if (SANITIZER_X32) + val = 1728; // Assume only one particular version for x32. + // For ARM sizeof(struct pthread) changed in Glibc 2.23. + else if (SANITIZER_ARM) + val = minor <= 22 ? 1120 : 1216; + else if (minor <= 3) + val = FIRST_32_SECOND_64(1104, 1696); + else if (minor == 4) + val = FIRST_32_SECOND_64(1120, 1728); + else if (minor == 5) + val = FIRST_32_SECOND_64(1136, 1728); + else if (minor <= 9) + val = FIRST_32_SECOND_64(1136, 1712); + else if (minor == 10) + val = FIRST_32_SECOND_64(1168, 1776); + else if (minor == 11 || (minor == 12 && patch == 1)) + val = FIRST_32_SECOND_64(1168, 2288); + else if (minor <= 14) + val = FIRST_32_SECOND_64(1168, 2304); + else + val = FIRST_32_SECOND_64(1216, 2304); } -#endif #elif defined(__mips__) // TODO(sagarthakur): add more values as per different glibc versions. val = FIRST_32_SECOND_64(1152, 1776); - if (val) - atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed); - return val; #elif defined(__aarch64__) // The sizeof (struct pthread) is the same from GLIBC 2.17 to 2.22. val = 1776; - atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed); - return val; #elif defined(__powerpc64__) val = 1776; // from glibc.ppc64le 2.20-8.fc21 - atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed); - return val; #elif defined(__s390__) val = FIRST_32_SECOND_64(1152, 1776); // valid for glibc 2.22 - atomic_store(&kThreadDescriptorSize, val, memory_order_relaxed); #endif - return 0; + if (val) + atomic_store_relaxed(&thread_descriptor_size, val); + return val; } // The offset at which pointer to self is located in the thread descriptor. @@ -339,7 +383,7 @@ static void **ThreadSelfSegbase() { // sysarch(AMD64_GET_FSBASE, segbase); __asm __volatile("movq %%fs:0, %0" : "=r" (segbase)); # else -# error "unsupported CPU arch for FreeBSD platform" +# error "unsupported CPU arch" # endif return segbase; } @@ -347,8 +391,35 @@ static void **ThreadSelfSegbase() { uptr ThreadSelf() { return (uptr)ThreadSelfSegbase()[2]; } -#elif SANITIZER_NETBSD -uptr ThreadSelf() { return (uptr)pthread_self(); } +#endif // SANITIZER_FREEBSD + +#if SANITIZER_NETBSD +static struct tls_tcb * ThreadSelfTlsTcb() { + struct tls_tcb * tcb; +# ifdef __HAVE___LWP_GETTCB_FAST + tcb = (struct tls_tcb *)__lwp_gettcb_fast(); +# elif defined(__HAVE___LWP_GETPRIVATE_FAST) + tcb = (struct tls_tcb *)__lwp_getprivate_fast(); +# endif + return tcb; +} + +uptr ThreadSelf() { + return (uptr)ThreadSelfTlsTcb()->tcb_pthread; +} + +int GetSizeFromHdr(struct dl_phdr_info *info, size_t size, void *data) { + const Elf_Phdr *hdr = info->dlpi_phdr; + const Elf_Phdr *last_hdr = hdr + info->dlpi_phnum; + + for (; hdr != last_hdr; ++hdr) { + if (hdr->p_type == PT_TLS && info->dlpi_tls_modid == 1) { + *(uptr*)data = hdr->p_memsz; + break; + } + } + return 0; +} #endif // SANITIZER_NETBSD #if !SANITIZER_GO @@ -380,7 +451,28 @@ static void GetTls(uptr *addr, uptr *size) { *addr = (uptr) dtv[2]; *size = (*addr == 0) ? 0 : ((uptr) segbase[0] - (uptr) dtv[2]); } -#elif SANITIZER_ANDROID || SANITIZER_NETBSD +#elif SANITIZER_NETBSD + struct tls_tcb * const tcb = ThreadSelfTlsTcb(); + *addr = 0; + *size = 0; + if (tcb != 0) { + // Find size (p_memsz) of dlpi_tls_modid 1 (TLS block of the main program). + // ld.elf_so hardcodes the index 1. + dl_iterate_phdr(GetSizeFromHdr, size); + + if (*size != 0) { + // The block has been found and tcb_dtv[1] contains the base address + *addr = (uptr)tcb->tcb_dtv[1]; + } + } +#elif SANITIZER_OPENBSD + *addr = 0; + *size = 0; +#elif SANITIZER_ANDROID + *addr = 0; + *size = 0; +#elif SANITIZER_SOLARIS + // FIXME *addr = 0; *size = 0; #else @@ -391,7 +483,8 @@ static void GetTls(uptr *addr, uptr *size) { #if !SANITIZER_GO uptr GetTlsSize() { -#if SANITIZER_FREEBSD || SANITIZER_ANDROID || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_ANDROID || SANITIZER_NETBSD || \ + SANITIZER_OPENBSD || SANITIZER_SOLARIS uptr addr, size; GetTls(&addr, &size); return size; @@ -428,13 +521,13 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, #endif } -# if !SANITIZER_FREEBSD +#if !SANITIZER_FREEBSD && !SANITIZER_OPENBSD typedef ElfW(Phdr) Elf_Phdr; -# elif SANITIZER_WORDSIZE == 32 && __FreeBSD_version <= 902001 // v9.2 -# define Elf_Phdr XElf32_Phdr -# define dl_phdr_info xdl_phdr_info -# define dl_iterate_phdr(c, b) xdl_iterate_phdr((c), (b)) -# endif +#elif SANITIZER_WORDSIZE == 32 && __FreeBSD_version <= 902001 // v9.2 +#define Elf_Phdr XElf32_Phdr +#define dl_phdr_info xdl_phdr_info +#define dl_iterate_phdr(c, b) xdl_iterate_phdr((c), (b)) +#endif // !SANITIZER_FREEBSD && !SANITIZER_OPENBSD struct DlIteratePhdrData { InternalMmapVectorNoCtor *modules; @@ -455,7 +548,7 @@ static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) { return 0; LoadedModule cur_module; cur_module.set(module_name.data(), info->dlpi_addr); - for (int i = 0; i < info->dlpi_phnum; i++) { + for (int i = 0; i < (int)info->dlpi_phnum; i++) { const Elf_Phdr *phdr = &info->dlpi_phdr[i]; if (phdr->p_type == PT_LOAD) { uptr cur_beg = info->dlpi_addr + phdr->p_vaddr; @@ -551,12 +644,65 @@ uptr GetRSS() { return rss * GetPageSizeCached(); } -// 64-bit Android targets don't provide the deprecated __android_log_write. -// Starting with the L release, syslog() works and is preferable to -// __android_log_write. +// sysconf(_SC_NPROCESSORS_{CONF,ONLN}) cannot be used on most platforms as +// they allocate memory. +u32 GetNumberOfCPUs() { +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD + u32 ncpu; + int req[2]; + uptr len = sizeof(ncpu); + req[0] = CTL_HW; + req[1] = HW_NCPU; + CHECK_EQ(internal_sysctl(req, 2, &ncpu, &len, NULL, 0), 0); + return ncpu; +#elif SANITIZER_ANDROID && !defined(CPU_COUNT) && !defined(__aarch64__) + // Fall back to /sys/devices/system/cpu on Android when cpu_set_t doesn't + // exist in sched.h. That is the case for toolchains generated with older + // NDKs. + // This code doesn't work on AArch64 because internal_getdents makes use of + // the 64bit getdents syscall, but cpu_set_t seems to always exist on AArch64. + uptr fd = internal_open("/sys/devices/system/cpu", O_RDONLY | O_DIRECTORY); + if (internal_iserror(fd)) + return 0; + InternalMmapVector buffer(4096); + uptr bytes_read = buffer.size(); + uptr n_cpus = 0; + u8 *d_type; + struct linux_dirent *entry = (struct linux_dirent *)&buffer[bytes_read]; + while (true) { + if ((u8 *)entry >= &buffer[bytes_read]) { + bytes_read = internal_getdents(fd, (struct linux_dirent *)buffer.data(), + buffer.size()); + if (internal_iserror(bytes_read) || !bytes_read) + break; + entry = (struct linux_dirent *)buffer.data(); + } + d_type = (u8 *)entry + entry->d_reclen - 1; + if (d_type >= &buffer[bytes_read] || + (u8 *)&entry->d_name[3] >= &buffer[bytes_read]) + break; + if (entry->d_ino != 0 && *d_type == DT_DIR) { + if (entry->d_name[0] == 'c' && entry->d_name[1] == 'p' && + entry->d_name[2] == 'u' && + entry->d_name[3] >= '0' && entry->d_name[3] <= '9') + n_cpus++; + } + entry = (struct linux_dirent *)(((u8 *)entry) + entry->d_reclen); + } + internal_close(fd); + return n_cpus; +#elif SANITIZER_SOLARIS + return sysconf(_SC_NPROCESSORS_ONLN); +#else + cpu_set_t CPUs; + CHECK_EQ(sched_getaffinity(0, sizeof(cpu_set_t), &CPUs), 0); + return CPU_COUNT(&CPUs); +#endif +} + #if SANITIZER_LINUX -#if SANITIZER_ANDROID +# if SANITIZER_ANDROID static atomic_uint8_t android_log_initialized; void AndroidLogInit() { @@ -567,36 +713,97 @@ void AndroidLogInit() { static bool ShouldLogAfterPrintf() { return atomic_load(&android_log_initialized, memory_order_acquire); } -#else -void AndroidLogInit() {} -static bool ShouldLogAfterPrintf() { return true; } -#endif // SANITIZER_ANDROID +extern "C" SANITIZER_WEAK_ATTRIBUTE +int async_safe_write_log(int pri, const char* tag, const char* msg); +extern "C" SANITIZER_WEAK_ATTRIBUTE +int __android_log_write(int prio, const char* tag, const char* msg); +// ANDROID_LOG_INFO is 4, but can't be resolved at runtime. +#define SANITIZER_ANDROID_LOG_INFO 4 + +// async_safe_write_log is a new public version of __libc_write_log that is +// used behind syslog. It is preferable to syslog as it will not do any dynamic +// memory allocation or formatting. +// If the function is not available, syslog is preferred for L+ (it was broken +// pre-L) as __android_log_write triggers a racey behavior with the strncpy +// interceptor. Fallback to __android_log_write pre-L. void WriteOneLineToSyslog(const char *s) { -#if SANITIZER_ANDROID &&__ANDROID_API__ < 21 - __android_log_write(ANDROID_LOG_INFO, NULL, s); -#else - syslog(LOG_INFO, "%s", s); -#endif + if (&async_safe_write_log) { + async_safe_write_log(SANITIZER_ANDROID_LOG_INFO, GetProcessName(), s); + } else if (AndroidGetApiLevel() > ANDROID_KITKAT) { + syslog(LOG_INFO, "%s", s); + } else { + CHECK(&__android_log_write); + __android_log_write(SANITIZER_ANDROID_LOG_INFO, nullptr, s); + } } +extern "C" SANITIZER_WEAK_ATTRIBUTE +void android_set_abort_message(const char *); + +void SetAbortMessage(const char *str) { + if (&android_set_abort_message) + android_set_abort_message(str); +} +# else +void AndroidLogInit() {} + +static bool ShouldLogAfterPrintf() { return true; } + +void WriteOneLineToSyslog(const char *s) { syslog(LOG_INFO, "%s", s); } + +void SetAbortMessage(const char *str) {} +# endif // SANITIZER_ANDROID + void LogMessageOnPrintf(const char *str) { if (common_flags()->log_to_syslog && ShouldLogAfterPrintf()) WriteToSyslog(str); } -#if SANITIZER_ANDROID -extern "C" __attribute__((weak)) void android_set_abort_message(const char *); -void SetAbortMessage(const char *str) { - if (&android_set_abort_message) android_set_abort_message(str); +#endif // SANITIZER_LINUX + +#if SANITIZER_LINUX && !SANITIZER_GO +// glibc crashes when using clock_gettime from a preinit_array function as the +// vDSO function pointers haven't been initialized yet. __progname is +// initialized after the vDSO function pointers, so if it exists, is not null +// and is not empty, we can use clock_gettime. +extern "C" SANITIZER_WEAK_ATTRIBUTE char *__progname; +INLINE bool CanUseVDSO() { + // Bionic is safe, it checks for the vDSO function pointers to be initialized. + if (SANITIZER_ANDROID) + return true; + if (&__progname && __progname && *__progname) + return true; + return false; } -#else -void SetAbortMessage(const char *str) {} -#endif -#endif // SANITIZER_LINUX +// MonotonicNanoTime is a timing function that can leverage the vDSO by calling +// clock_gettime. real_clock_gettime only exists if clock_gettime is +// intercepted, so define it weakly and use it if available. +extern "C" SANITIZER_WEAK_ATTRIBUTE +int real_clock_gettime(u32 clk_id, void *tp); +u64 MonotonicNanoTime() { + timespec ts; + if (CanUseVDSO()) { + if (&real_clock_gettime) + real_clock_gettime(CLOCK_MONOTONIC, &ts); + else + clock_gettime(CLOCK_MONOTONIC, &ts); + } else { + internal_clock_gettime(CLOCK_MONOTONIC, &ts); + } + return (u64)ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec; +} +#else +// Non-Linux & Go always use the syscall. +u64 MonotonicNanoTime() { + timespec ts; + internal_clock_gettime(CLOCK_MONOTONIC, &ts); + return (u64)ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec; +} +#endif // SANITIZER_LINUX && !SANITIZER_GO } // namespace __sanitizer -#endif // SANITIZER_FREEBSD || SANITIZER_LINUX +#endif diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_s390.cc b/libsanitizer/sanitizer_common/sanitizer_linux_s390.cc index b836447bd5d..e55ffe00cfb 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux_s390.cc +++ b/libsanitizer/sanitizer_common/sanitizer_linux_s390.cc @@ -124,7 +124,7 @@ static bool FixedCVE_2016_2143() { // This should never fail, but just in case... if (uname(&buf)) return false; - char *ptr = buf.release; + const char *ptr = buf.release; major = internal_simple_strtoll(ptr, &ptr, 10); // At least first 2 should be matched. if (ptr[0] != '.') diff --git a/libsanitizer/sanitizer_common/sanitizer_linux_x86_64.S b/libsanitizer/sanitizer_common/sanitizer_linux_x86_64.S index 846d1a43370..8ff909542b6 100644 --- a/libsanitizer/sanitizer_common/sanitizer_linux_x86_64.S +++ b/libsanitizer/sanitizer_common/sanitizer_linux_x86_64.S @@ -10,14 +10,12 @@ #if defined(__linux__) && defined(__x86_64__) #include "../builtins/assembly.h" -#include "cet.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) - _CET_ENDBR mov $0xf, %eax // 0xf == SYS_rt_sigreturn mov %rcx, %r10 syscall diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.cc b/libsanitizer/sanitizer_common/sanitizer_mac.cc index 8c78494e81a..df7a897e45a 100644 --- a/libsanitizer/sanitizer_common/sanitizer_mac.cc +++ b/libsanitizer/sanitizer_common/sanitizer_mac.cc @@ -35,7 +35,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 @@ -57,7 +57,9 @@ extern "C" { #include #include #include +#include #include +#include #include #include #include @@ -98,9 +100,15 @@ extern "C" void *__mmap(void *addr, size_t len, int prot, int flags, int fildes, extern "C" int __munmap(void *, size_t) SANITIZER_WEAK_ATTRIBUTE; // ---------------------- sanitizer_libc.h + +// From , but not on older OSs. +#ifndef VM_MEMORY_SANITIZER +#define VM_MEMORY_SANITIZER 99 +#endif + 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_ANALYSIS_TOOL); + if (fd == -1) fd = VM_MAKE_TAG(VM_MEMORY_SANITIZER); if (&__mmap) return (uptr)__mmap(addr, length, prot, flags, fd, offset); return (uptr)mmap(addr, length, prot, flags, fd, offset); } @@ -183,7 +191,7 @@ uptr internal_getpid() { int internal_sigaction(int signum, const void *act, void *oldact) { return sigaction(signum, - (struct sigaction *)act, (struct sigaction *)oldact); + (const struct sigaction *)act, (struct sigaction *)oldact); } void internal_sigfillset(__sanitizer_sigset_t *set) { sigfillset(set); } @@ -203,6 +211,18 @@ int internal_fork() { return fork(); } +int internal_sysctl(const int *name, unsigned int namelen, void *oldp, + uptr *oldlenp, const void *newp, uptr newlen) { + return sysctl(const_cast(name), namelen, oldp, (size_t *)oldlenp, + const_cast(newp), (size_t)newlen); +} + +int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp, + const void *newp, uptr newlen) { + return sysctlbyname(sname, oldp, (size_t *)oldlenp, const_cast(newp), + (size_t)newlen); +} + int internal_forkpty(int *amaster) { int master, slave; if (openpty(&master, &slave, nullptr, nullptr, nullptr) == -1) return -1; @@ -336,10 +356,37 @@ void ReExec() { UNIMPLEMENTED(); } +void CheckASLR() { + // Do nothing +} + uptr GetPageSize() { return sysconf(_SC_PAGESIZE); } +extern "C" unsigned malloc_num_zones; +extern "C" malloc_zone_t **malloc_zones; +malloc_zone_t sanitizer_zone; + +// We need to make sure that sanitizer_zone is registered as malloc_zones[0]. If +// libmalloc tries to set up a different zone as malloc_zones[0], it will call +// mprotect(malloc_zones, ..., PROT_READ). This interceptor will catch that and +// make sure we are still the first (default) zone. +void MprotectMallocZones(void *addr, int prot) { + if (addr == malloc_zones && prot == PROT_READ) { + if (malloc_num_zones > 1 && malloc_zones[0] != &sanitizer_zone) { + for (unsigned i = 1; i < malloc_num_zones; i++) { + if (malloc_zones[i] == &sanitizer_zone) { + // Swap malloc_zones[0] and malloc_zones[i]. + malloc_zones[i] = malloc_zones[0]; + malloc_zones[0] = &sanitizer_zone; + break; + } + } + } + } +} + BlockingMutex::BlockingMutex() { internal_memset(this, 0, sizeof(*this)); } @@ -360,7 +407,17 @@ void BlockingMutex::CheckLocked() { } u64 NanoTime() { - return 0; + timeval tv; + internal_memset(&tv, 0, sizeof(tv)); + gettimeofday(&tv, 0); + return (u64)tv.tv_sec * 1000*1000*1000 + tv.tv_usec * 1000; +} + +// This needs to be called during initialization to avoid being racy. +u64 MonotonicNanoTime() { + static mach_timebase_info_data_t timebase_info; + if (timebase_info.denom == 0) mach_timebase_info(&timebase_info); + return (mach_absolute_time() * timebase_info.numer) / timebase_info.denom; } uptr GetTlsSize() { @@ -422,6 +479,8 @@ static HandleSignalMode GetHandleSignalModeImpl(int signum) { return common_flags()->handle_abort; case SIGILL: return common_flags()->handle_sigill; + case SIGTRAP: + return common_flags()->handle_sigtrap; case SIGFPE: return common_flags()->handle_sigfpe; case SIGSEGV: @@ -450,9 +509,9 @@ MacosVersion GetMacosVersionInternal() { uptr len = 0, maxlen = sizeof(version) / sizeof(version[0]); for (uptr i = 0; i < maxlen; i++) version[i] = '\0'; // Get the version length. - CHECK_NE(sysctl(mib, 2, 0, &len, 0, 0), -1); + CHECK_NE(internal_sysctl(mib, 2, 0, &len, 0, 0), -1); CHECK_LT(len, maxlen); - CHECK_NE(sysctl(mib, 2, version, &len, 0, 0), -1); + CHECK_NE(internal_sysctl(mib, 2, version, &len, 0, 0), -1); switch (version[0]) { case '9': return MACOS_VERSION_LEOPARD; case '1': { @@ -462,6 +521,10 @@ MacosVersion GetMacosVersionInternal() { 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; @@ -667,6 +730,9 @@ bool DyldNeedsEnvVariable() { } void MaybeReexec() { + // FIXME: This should really live in some "InitializePlatform" method. + MonotonicNanoTime(); + if (ReexecDisabled()) return; // Make sure the dynamic runtime library is preloaded so that the @@ -739,6 +805,9 @@ void MaybeReexec() { if (!lib_is_in_env) return; + if (!common_flags()->strip_env) + return; + // DYLD_INSERT_LIBRARIES is set and contains the runtime library. Let's remove // the dylib from the environment variable, because interceptors are installed // and we don't want our children to inherit the variable. @@ -835,10 +904,10 @@ struct __sanitizer_task_vm_info { (sizeof(__sanitizer_task_vm_info) / sizeof(natural_t))) uptr GetTaskInfoMaxAddress() { - __sanitizer_task_vm_info vm_info = {}; + __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) { + if (err == 0 && vm_info.max_address != 0) { return vm_info.max_address - 1; } else { // xnu cannot provide vm address limit @@ -847,7 +916,7 @@ uptr GetTaskInfoMaxAddress() { } #endif -uptr GetMaxVirtualAddress() { +uptr GetMaxUserVirtualAddress() { #if SANITIZER_WORDSIZE == 64 # if defined(__aarch64__) && SANITIZER_IOS && !SANITIZER_IOSSIM // Get the maximum VM address @@ -862,10 +931,13 @@ uptr GetMaxVirtualAddress() { #endif // SANITIZER_WORDSIZE } -uptr FindAvailableMemoryRange(uptr shadow_size, - uptr alignment, - uptr left_padding, - uptr *largest_gap_found) { +uptr GetMaxVirtualAddress() { + return GetMaxUserVirtualAddress(); +} + +uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding, + uptr *largest_gap_found, + uptr *max_occupied_addr) { typedef vm_region_submap_short_info_data_64_t RegionInfo; enum { kRegionInfoSize = VM_REGION_SUBMAP_SHORT_INFO_COUNT_64 }; // Start searching for available memory region past PAGEZERO, which is @@ -877,6 +949,7 @@ uptr FindAvailableMemoryRange(uptr shadow_size, mach_vm_address_t free_begin = start_address; kern_return_t kr = KERN_SUCCESS; if (largest_gap_found) *largest_gap_found = 0; + if (max_occupied_addr) *max_occupied_addr = 0; while (kr == KERN_SUCCESS) { mach_vm_size_t vmsize = 0; natural_t depth = 0; @@ -884,12 +957,19 @@ uptr FindAvailableMemoryRange(uptr shadow_size, mach_msg_type_number_t count = kRegionInfoSize; kr = mach_vm_region_recurse(mach_task_self(), &address, &vmsize, &depth, (vm_region_info_t)&vminfo, &count); + if (kr == KERN_INVALID_ADDRESS) { + // No more regions beyond "address", consider the gap at the end of VM. + address = GetMaxVirtualAddress() + 1; + vmsize = 0; + } else { + if (max_occupied_addr) *max_occupied_addr = address + vmsize; + } if (free_begin != address) { // We found a free region [free_begin..address-1]. uptr gap_start = RoundUpTo((uptr)free_begin + left_padding, alignment); uptr gap_end = RoundDownTo((uptr)address, alignment); uptr gap_size = gap_end > gap_start ? gap_end - gap_start : 0; - if (shadow_size < gap_size) { + if (size < gap_size) { return gap_start; } @@ -976,9 +1056,10 @@ void FormatUUID(char *out, uptr size, const u8 *uuid) { void PrintModuleMap() { Printf("Process module map:\n"); MemoryMappingLayout memory_mapping(false); - InternalMmapVector modules(/*initial_capacity*/ 128); + InternalMmapVector modules; + modules.reserve(128); memory_mapping.DumpListOfModules(&modules); - InternalSort(&modules, modules.size(), CompareBaseAddress); + Sort(modules.data(), modules.size(), CompareBaseAddress); for (uptr i = 0; i < modules.size(); ++i) { char uuid_str[128]; FormatUUID(uuid_str, sizeof(uuid_str), modules[i].uuid()); @@ -993,9 +1074,16 @@ void CheckNoDeepBind(const char *filename, int flag) { // Do nothing. } -// FIXME: implement on this platform. bool GetRandom(void *buffer, uptr length, bool blocking) { - UNIMPLEMENTED(); + if (!buffer || !length || length > 256) + return false; + // arc4random never fails. + arc4random_buf(buffer, length); + return true; +} + +u32 GetNumberOfCPUs() { + return (u32)sysconf(_SC_NPROCESSORS_ONLN); } } // namespace __sanitizer diff --git a/libsanitizer/sanitizer_common/sanitizer_mac.h b/libsanitizer/sanitizer_common/sanitizer_mac.h index 4881b62ff57..8e7a4a24525 100644 --- a/libsanitizer/sanitizer_common/sanitizer_mac.h +++ b/libsanitizer/sanitizer_common/sanitizer_mac.h @@ -25,7 +25,7 @@ struct MemoryMappingLayoutData { ModuleArch current_arch; u8 current_uuid[kModuleUUIDSize]; int current_load_cmd_count; - char *current_load_cmd_addr; + const char *current_load_cmd_addr; bool current_instrumented; }; @@ -38,6 +38,10 @@ enum MacosVersion { MACOS_VERSION_MOUNTAIN_LION, MACOS_VERSION_MAVERICKS, MACOS_VERSION_YOSEMITE, + MACOS_VERSION_EL_CAPITAN, + MACOS_VERSION_SIERRA, + MACOS_VERSION_HIGH_SIERRA, + MACOS_VERSION_MOJAVE, MACOS_VERSION_UNKNOWN_NEWER }; diff --git a/libsanitizer/sanitizer_common/sanitizer_mac_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_mac_libcdep.cc index b376a0710b9..a0d5c3f8f55 100644 --- a/libsanitizer/sanitizer_common/sanitizer_mac_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_mac_libcdep.cc @@ -18,7 +18,7 @@ namespace __sanitizer { void RestrictMemoryToMaxAddress(uptr max_address) { - uptr size_to_mmap = GetMaxVirtualAddress() + 1 - max_address; + uptr size_to_mmap = GetMaxUserVirtualAddress() + 1 - max_address; void *res = MmapFixedNoAccess(max_address, size_to_mmap, "high gap"); CHECK(res != MAP_FAILED); } diff --git a/libsanitizer/sanitizer_common/sanitizer_malloc_mac.inc b/libsanitizer/sanitizer_common/sanitizer_malloc_mac.inc index 2ca4e061464..8887f5d5ca4 100644 --- a/libsanitizer/sanitizer_common/sanitizer_malloc_mac.inc +++ b/libsanitizer/sanitizer_common/sanitizer_malloc_mac.inc @@ -27,7 +27,9 @@ // Similar code is used in Google Perftools, // https://github.com/gperftools/gperftools. -static malloc_zone_t sanitizer_zone; +namespace __sanitizer { +extern malloc_zone_t sanitizer_zone; +} INTERCEPTOR(malloc_zone_t *, malloc_create_zone, vm_size_t start_size, unsigned zone_flags) { @@ -63,29 +65,6 @@ INTERCEPTOR(void, malloc_destroy_zone, malloc_zone_t *zone) { COMMON_MALLOC_FREE(zone); } -extern unsigned malloc_num_zones; -extern malloc_zone_t **malloc_zones; - -// We need to make sure that sanitizer_zone is registered as malloc_zones[0]. If -// libmalloc tries to set up a different zone as malloc_zones[0], it will call -// mprotect(malloc_zones, ..., PROT_READ). This interceptor will catch that and -// make sure we are still the first (default) zone. -INTERCEPTOR(int, mprotect, void *addr, size_t len, int prot) { - if (addr == malloc_zones && prot == PROT_READ) { - if (malloc_num_zones > 1 && malloc_zones[0] != &sanitizer_zone) { - for (unsigned i = 1; i < malloc_num_zones; i++) { - if (malloc_zones[i] == &sanitizer_zone) { - // Swap malloc_zones[0] and malloc_zones[i]. - malloc_zones[i] = malloc_zones[0]; - malloc_zones[0] = &sanitizer_zone; - break; - } - } - } - } - return REAL(mprotect)(addr, len, prot); -} - INTERCEPTOR(malloc_zone_t *, malloc_default_zone, void) { COMMON_MALLOC_ENTER(); return &sanitizer_zone; @@ -168,12 +147,8 @@ INTERCEPTOR(size_t, malloc_good_size, size_t size) { INTERCEPTOR(int, posix_memalign, void **memptr, size_t alignment, size_t size) { COMMON_MALLOC_ENTER(); CHECK(memptr); - COMMON_MALLOC_MEMALIGN(alignment, size); - if (p) { - *memptr = p; - return 0; - } - return -1; + COMMON_MALLOC_POSIX_MEMALIGN(memptr, alignment, size); + return res; } namespace { diff --git a/libsanitizer/sanitizer_common/sanitizer_mutex.h b/libsanitizer/sanitizer_common/sanitizer_mutex.h index 1ec409def41..2b7f7d24f2e 100644 --- a/libsanitizer/sanitizer_common/sanitizer_mutex.h +++ b/libsanitizer/sanitizer_common/sanitizer_mutex.h @@ -71,13 +71,8 @@ class SpinMutex : public StaticSpinMutex { class BlockingMutex { public: -#if SANITIZER_WINDOWS - // Windows does not currently support LinkerInitialized - explicit BlockingMutex(LinkerInitialized); -#else explicit constexpr BlockingMutex(LinkerInitialized) - : opaque_storage_ {0, }, owner_(0) {} -#endif + : opaque_storage_ {0, }, owner_ {0} {} BlockingMutex(); void Lock(); void Unlock(); @@ -90,8 +85,10 @@ class BlockingMutex { // checks that the mutex is owned, and assumes callers to be generally // well-behaved. void CheckLocked(); + private: - uptr opaque_storage_[10]; + // Solaris mutex_t has a member that requires 64-bit alignment. + ALIGNED(8) uptr opaque_storage_[10]; uptr owner_; // for debugging }; diff --git a/libsanitizer/sanitizer_common/sanitizer_netbsd.cc b/libsanitizer/sanitizer_common/sanitizer_netbsd.cc new file mode 100644 index 00000000000..d0df94d1f95 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_netbsd.cc @@ -0,0 +1,328 @@ +//===-- sanitizer_netbsd.cc -----------------------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is shared between Sanitizer run-time libraries and implements +// NetBSD-specific functions from sanitizer_libc.h. +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" + +#if SANITIZER_NETBSD + +#include "sanitizer_common.h" +#include "sanitizer_flags.h" +#include "sanitizer_getauxval.h" +#include "sanitizer_internal_defs.h" +#include "sanitizer_libc.h" +#include "sanitizer_linux.h" +#include "sanitizer_mutex.h" +#include "sanitizer_placement_new.h" +#include "sanitizer_procmaps.h" + +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern "C" void *__mmap(void *, size_t, int, int, int, int, + off_t) SANITIZER_WEAK_ATTRIBUTE; +extern "C" int __sysctl(const int *, unsigned int, void *, size_t *, + const void *, size_t) SANITIZER_WEAK_ATTRIBUTE; +extern "C" int _sys_close(int) SANITIZER_WEAK_ATTRIBUTE; +extern "C" int _sys_open(const char *, int, ...) SANITIZER_WEAK_ATTRIBUTE; +extern "C" ssize_t _sys_read(int, void *, size_t) SANITIZER_WEAK_ATTRIBUTE; +extern "C" ssize_t _sys_write(int, const void *, + size_t) SANITIZER_WEAK_ATTRIBUTE; +extern "C" int __ftruncate(int, int, off_t) SANITIZER_WEAK_ATTRIBUTE; +extern "C" ssize_t _sys_readlink(const char *, char *, + size_t) SANITIZER_WEAK_ATTRIBUTE; +extern "C" int _sys_sched_yield() SANITIZER_WEAK_ATTRIBUTE; +extern "C" int _sys___nanosleep50(const void *, + void *) SANITIZER_WEAK_ATTRIBUTE; +extern "C" int _sys_execve(const char *, char *const[], + char *const[]) SANITIZER_WEAK_ATTRIBUTE; +extern "C" off_t __lseek(int, int, off_t, int) SANITIZER_WEAK_ATTRIBUTE; +extern "C" int __fork() SANITIZER_WEAK_ATTRIBUTE; +extern "C" int _sys___sigprocmask14(int, const void *, + void *) SANITIZER_WEAK_ATTRIBUTE; +extern "C" int _sys___wait450(int wpid, int *, int, + void *) SANITIZER_WEAK_ATTRIBUTE; + +namespace __sanitizer { + +static void *GetRealLibcAddress(const char *symbol) { + void *real = dlsym(RTLD_NEXT, symbol); + if (!real) + real = dlsym(RTLD_DEFAULT, symbol); + if (!real) { + Printf("GetRealLibcAddress failed for symbol=%s", symbol); + Die(); + } + return real; +} + +#define _REAL(func, ...) real##_##func(__VA_ARGS__) +#define DEFINE__REAL(ret_type, func, ...) \ + static ret_type (*real_##func)(__VA_ARGS__) = NULL; \ + if (!real_##func) { \ + real_##func = (ret_type(*)(__VA_ARGS__))GetRealLibcAddress(#func); \ + } \ + CHECK(real_##func); + +// --------------- sanitizer_libc.h +uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, + OFF_T offset) { + CHECK(&__mmap); + return (uptr)__mmap(addr, length, prot, flags, fd, 0, offset); +} + +uptr internal_munmap(void *addr, uptr length) { + DEFINE__REAL(int, munmap, void *a, uptr b); + return _REAL(munmap, addr, length); +} + +int internal_mprotect(void *addr, uptr length, int prot) { + DEFINE__REAL(int, mprotect, void *a, uptr b, int c); + return _REAL(mprotect, addr, length, prot); +} + +uptr internal_close(fd_t fd) { + CHECK(&_sys_close); + return _sys_close(fd); +} + +uptr internal_open(const char *filename, int flags) { + CHECK(&_sys_open); + return _sys_open(filename, flags); +} + +uptr internal_open(const char *filename, int flags, u32 mode) { + CHECK(&_sys_open); + return _sys_open(filename, flags, mode); +} + +uptr internal_read(fd_t fd, void *buf, uptr count) { + sptr res; + CHECK(&_sys_read); + HANDLE_EINTR(res, (sptr)_sys_read(fd, buf, (size_t)count)); + return res; +} + +uptr internal_write(fd_t fd, const void *buf, uptr count) { + sptr res; + CHECK(&_sys_write); + HANDLE_EINTR(res, (sptr)_sys_write(fd, buf, count)); + return res; +} + +uptr internal_ftruncate(fd_t fd, uptr size) { + sptr res; + CHECK(&__ftruncate); + HANDLE_EINTR(res, __ftruncate(fd, 0, (s64)size)); + return res; +} + +uptr internal_stat(const char *path, void *buf) { + DEFINE__REAL(int, __stat50, const char *a, void *b); + return _REAL(__stat50, path, buf); +} + +uptr internal_lstat(const char *path, void *buf) { + DEFINE__REAL(int, __lstat50, const char *a, void *b); + return _REAL(__lstat50, path, buf); +} + +uptr internal_fstat(fd_t fd, void *buf) { + DEFINE__REAL(int, __fstat50, int a, void *b); + return _REAL(__fstat50, fd, buf); +} + +uptr internal_filesize(fd_t fd) { + struct stat st; + if (internal_fstat(fd, &st)) + return -1; + return (uptr)st.st_size; +} + +uptr internal_dup2(int oldfd, int newfd) { + DEFINE__REAL(int, dup2, int a, int b); + return _REAL(dup2, oldfd, newfd); +} + +uptr internal_readlink(const char *path, char *buf, uptr bufsize) { + CHECK(&_sys_readlink); + return (uptr)_sys_readlink(path, buf, bufsize); +} + +uptr internal_unlink(const char *path) { + DEFINE__REAL(int, unlink, const char *a); + return _REAL(unlink, path); +} + +uptr internal_rename(const char *oldpath, const char *newpath) { + DEFINE__REAL(int, rename, const char *a, const char *b); + return _REAL(rename, oldpath, newpath); +} + +uptr internal_sched_yield() { + CHECK(&_sys_sched_yield); + return _sys_sched_yield(); +} + +void internal__exit(int exitcode) { + DEFINE__REAL(void, _exit, int a); + _REAL(_exit, exitcode); + Die(); // Unreachable. +} + +unsigned int internal_sleep(unsigned int seconds) { + struct timespec ts; + ts.tv_sec = 1; + ts.tv_nsec = 0; + CHECK(&_sys___nanosleep50); + int res = _sys___nanosleep50(&ts, &ts); + if (res) + return ts.tv_sec; + return 0; +} + +uptr internal_execve(const char *filename, char *const argv[], + char *const envp[]) { + CHECK(&_sys_execve); + return _sys_execve(filename, argv, envp); +} + +tid_t GetTid() { + DEFINE__REAL(int, _lwp_self); + return _REAL(_lwp_self); +} + +int TgKill(pid_t pid, tid_t tid, int sig) { + DEFINE__REAL(int, _lwp_kill, int a, int b); + (void)pid; + return _REAL(_lwp_kill, tid, sig); +} + +u64 NanoTime() { + timeval tv; + DEFINE__REAL(int, __gettimeofday50, void *a, void *b); + internal_memset(&tv, 0, sizeof(tv)); + _REAL(__gettimeofday50, &tv, 0); + return (u64)tv.tv_sec * 1000 * 1000 * 1000 + tv.tv_usec * 1000; +} + +uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) { + DEFINE__REAL(int, __clock_gettime50, __sanitizer_clockid_t a, void *b); + 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_waitpid(int pid, int *status, int options) { + CHECK(&_sys___wait450); + return _sys___wait450(pid, status, options, 0 /* rusage */); +} + +uptr internal_getpid() { + DEFINE__REAL(int, getpid); + return _REAL(getpid); +} + +uptr internal_getppid() { + DEFINE__REAL(int, getppid); + return _REAL(getppid); +} + +uptr internal_getdents(fd_t fd, void *dirp, unsigned int count) { + DEFINE__REAL(int, __getdents30, int a, void *b, size_t c); + return _REAL(__getdents30, fd, dirp, count); +} + +uptr internal_lseek(fd_t fd, OFF_T offset, int whence) { + CHECK(&__lseek); + return __lseek(fd, 0, offset, whence); +} + +uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5) { + Printf("internal_prctl not implemented for NetBSD"); + Die(); + return 0; +} + +uptr internal_sigaltstack(const void *ss, void *oss) { + DEFINE__REAL(int, __sigaltstack14, const void *a, void *b); + return _REAL(__sigaltstack14, ss, oss); +} + +int internal_fork() { + CHECK(&__fork); + return __fork(); +} + +int internal_sysctl(const int *name, unsigned int namelen, void *oldp, + uptr *oldlenp, const void *newp, uptr newlen) { + CHECK(&__sysctl); + return __sysctl(name, namelen, oldp, (size_t *)oldlenp, newp, (size_t)newlen); +} + +int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp, + const void *newp, uptr newlen) { + DEFINE__REAL(int, sysctlbyname, const char *a, void *b, size_t *c, + const void *d, size_t e); + return _REAL(sysctlbyname, sname, oldp, (size_t *)oldlenp, newp, + (size_t)newlen); +} + +uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set, + __sanitizer_sigset_t *oldset) { + CHECK(&_sys___sigprocmask14); + return _sys___sigprocmask14(how, set, oldset); +} + +void internal_sigfillset(__sanitizer_sigset_t *set) { + DEFINE__REAL(int, __sigfillset14, const void *a); + (void)_REAL(__sigfillset14, set); +} + +void internal_sigemptyset(__sanitizer_sigset_t *set) { + DEFINE__REAL(int, __sigemptyset14, const void *a); + (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; +} + +} // namespace __sanitizer + +#endif diff --git a/libsanitizer/sanitizer_common/sanitizer_openbsd.cc b/libsanitizer/sanitizer_common/sanitizer_openbsd.cc new file mode 100644 index 00000000000..6ff8b0d10a9 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_openbsd.cc @@ -0,0 +1,108 @@ +//===-- sanitizer_openbsd.cc ----------------------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is shared between various sanitizers' runtime libraries and +// implements Solaris-specific functions. +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" +#if SANITIZER_OPENBSD + +#include + +#include "sanitizer_common.h" +#include "sanitizer_flags.h" +#include "sanitizer_internal_defs.h" +#include "sanitizer_libc.h" +#include "sanitizer_placement_new.h" +#include "sanitizer_platform_limits_posix.h" +#include "sanitizer_procmaps.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +extern char **environ; + +namespace __sanitizer { + +uptr internal_mmap(void *addr, size_t length, int prot, int flags, int fd, + u64 offset) { + return (uptr)mmap(addr, length, prot, flags, fd, offset); +} + +uptr internal_munmap(void *addr, uptr length) { return munmap(addr, length); } + +int internal_mprotect(void *addr, uptr length, int prot) { + return mprotect(addr, length, prot); +} + +int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp, + const void *newp, uptr newlen) { + Printf("internal_sysctlbyname not implemented for OpenBSD"); + Die(); + return 0; +} + +uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { + // On OpenBSD we cannot get the full path + struct kinfo_proc kp; + uptr kl; + const int Mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PID, getpid()}; + if (internal_sysctl(Mib, ARRAY_SIZE(Mib), &kp, &kl, NULL, 0) != -1) + return internal_snprintf(buf, + (KI_MAXCOMLEN < buf_len ? KI_MAXCOMLEN : buf_len), + "%s", kp.p_comm); + return (uptr)0; +} + +static void GetArgsAndEnv(char ***argv, char ***envp) { + uptr nargv; + uptr nenv; + int argvmib[4] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ARGV}; + int envmib[4] = {CTL_KERN, KERN_PROC_ARGS, getpid(), KERN_PROC_ENV}; + if (internal_sysctl(argvmib, 4, NULL, &nargv, NULL, 0) == -1) { + Printf("sysctl KERN_PROC_NARGV failed\n"); + Die(); + } + if (internal_sysctl(envmib, 4, NULL, &nenv, NULL, 0) == -1) { + Printf("sysctl KERN_PROC_NENV failed\n"); + Die(); + } + if (internal_sysctl(argvmib, 4, &argv, &nargv, NULL, 0) == -1) { + Printf("sysctl KERN_PROC_ARGV failed\n"); + Die(); + } + if (internal_sysctl(envmib, 4, &envp, &nenv, NULL, 0) == -1) { + Printf("sysctl KERN_PROC_ENV failed\n"); + Die(); + } +} + +char **GetArgv() { + char **argv, **envp; + GetArgsAndEnv(&argv, &envp); + return argv; +} + +void ReExec() { + UNIMPLEMENTED(); +} + +} // namespace __sanitizer + +#endif // SANITIZER_OPENBSD diff --git a/libsanitizer/sanitizer_common/sanitizer_platform.h b/libsanitizer/sanitizer_common/sanitizer_platform.h index 1eb4d0c61c6..352b374e177 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform.h @@ -12,7 +12,9 @@ #define SANITIZER_PLATFORM_H #if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \ - !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) + !defined(__OpenBSD__) && !defined(__APPLE__) && !defined(_WIN32) && \ + !defined(__Fuchsia__) && !defined(__rtems__) && \ + !(defined(__sun__) && defined(__svr4__)) # error "This operating system is not supported" #endif @@ -34,6 +36,18 @@ # define SANITIZER_NETBSD 0 #endif +#if defined(__OpenBSD__) +# define SANITIZER_OPENBSD 1 +#else +# define SANITIZER_OPENBSD 0 +#endif + +#if defined(__sun__) && defined(__svr4__) +# define SANITIZER_SOLARIS 1 +#else +# define SANITIZER_SOLARIS 0 +#endif + #if defined(__APPLE__) # define SANITIZER_MAC 1 # include @@ -42,7 +56,7 @@ # else # define SANITIZER_IOS 0 # endif -# if TARGET_IPHONE_SIMULATOR +# if TARGET_OS_SIMULATOR # define SANITIZER_IOSSIM 1 # else # define SANITIZER_IOSSIM 0 @@ -89,8 +103,15 @@ # define SANITIZER_FUCHSIA 0 #endif +#if defined(__rtems__) +# define SANITIZER_RTEMS 1 +#else +# define SANITIZER_RTEMS 0 +#endif + #define SANITIZER_POSIX \ - (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || SANITIZER_NETBSD) + (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \ + SANITIZER_NETBSD || SANITIZER_OPENBSD || SANITIZER_SOLARIS) #if __LP64__ || defined(_WIN64) # define SANITIZER_WORDSIZE 64 @@ -179,6 +200,18 @@ # define SANITIZER_ARM 0 #endif +#if SANITIZER_SOLARIS && SANITIZER_WORDSIZE == 32 +# define SANITIZER_SOLARIS32 1 +#else +# define SANITIZER_SOLARIS32 0 +#endif + +#if defined(__myriad2__) +# define SANITIZER_MYRIAD2 1 +#else +# define SANITIZER_MYRIAD2 0 +#endif + // By default we allow to use SizeClassAllocator64 on 64-bit platform. // But in some cases (e.g. AArch64's 39-bit address space) SizeClassAllocator64 // does not work well and we need to fallback to SizeClassAllocator32. @@ -200,7 +233,12 @@ #if defined(__mips__) # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40) #elif defined(__aarch64__) -# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 48) +# if SANITIZER_MAC +// Darwin iOS/ARM64 has a 36-bit VMA, 64GiB VM +# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 36) +# else +# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 48) +# endif #else # define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47) #endif @@ -280,5 +318,26 @@ # define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 0 #endif +#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD || \ + SANITIZER_OPENBSD || SANITIZER_SOLARIS +# define SANITIZER_MADVISE_DONTNEED MADV_FREE +#else +# define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED +#endif + +// Older gcc have issues aligning to a constexpr, and require an integer. +// See https://gcc.gnu.org/bugzilla/show_bug.cgi?id=56859 among others. +#if defined(__powerpc__) || defined(__powerpc64__) +# define SANITIZER_CACHE_LINE_SIZE 128 +#else +# define SANITIZER_CACHE_LINE_SIZE 64 +#endif + +// Enable offline markup symbolizer for Fuchsia and RTEMS. +#if SANITIZER_FUCHSIA || SANITIZER_RTEMS +#define SANITIZER_SYMBOLIZER_MARKUP 1 +#else +#define SANITIZER_SYMBOLIZER_MARKUP 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 b9eb09ad3bd..d6fc2b9ce23 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_interceptors.h @@ -26,13 +26,15 @@ # define SI_WINDOWS 1 #endif -#if (SI_POSIX != 0) == (SI_WINDOWS != 0) && !SANITIZER_FUCHSIA +#if SI_WINDOWS && SI_POSIX # error "Windows is not POSIX!" #endif #if SI_POSIX # include "sanitizer_platform_limits_netbsd.h" +#include "sanitizer_platform_limits_openbsd.h" # include "sanitizer_platform_limits_posix.h" +# include "sanitizer_platform_limits_solaris.h" #endif #if SANITIZER_LINUX && !SANITIZER_ANDROID @@ -59,6 +61,12 @@ # define SI_NETBSD 0 #endif +#if SANITIZER_OPENBSD +#define SI_OPENBSD 1 +#else +#define SI_OPENBSD 0 +#endif + #if SANITIZER_LINUX # define SI_LINUX 1 #else @@ -85,6 +93,24 @@ # define SI_NOT_FUCHSIA 1 #endif +#if SANITIZER_RTEMS +# define SI_NOT_RTEMS 0 +#else +# define SI_NOT_RTEMS 1 +#endif + +#if SANITIZER_SOLARIS +# define SI_SOLARIS 1 +#else +# define SI_SOLARIS 0 +#endif + +#if SANITIZER_SOLARIS32 +# define SI_SOLARIS32 1 +#else +# define SI_SOLARIS32 0 +#endif + #if SANITIZER_POSIX && !SANITIZER_MAC # define SI_POSIX_NOT_MAC 1 #else @@ -108,7 +134,7 @@ #define SANITIZER_INTERCEPT_STRRCHR SI_NOT_FUCHSIA #define SANITIZER_INTERCEPT_STRSPN SI_NOT_FUCHSIA #define SANITIZER_INTERCEPT_STRPBRK SI_NOT_FUCHSIA -#define SANITIZER_INTERCEPT_TEXTDOMAIN SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_TEXTDOMAIN SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_STRCASECMP SI_POSIX #define SANITIZER_INTERCEPT_MEMSET 1 #define SANITIZER_INTERCEPT_MEMMOVE 1 @@ -126,7 +152,8 @@ // FIXME: enable memmem on Windows. #define SANITIZER_INTERCEPT_MEMMEM (SI_POSIX && !SI_MAC_DEPLOYMENT_BELOW_10_7) #define SANITIZER_INTERCEPT_MEMCHR SI_NOT_FUCHSIA -#define SANITIZER_INTERCEPT_MEMRCHR (SI_FREEBSD || SI_LINUX || SI_NETBSD) +#define SANITIZER_INTERCEPT_MEMRCHR \ + (SI_FREEBSD || SI_LINUX || SI_NETBSD || SI_OPENBSD) #define SANITIZER_INTERCEPT_READ SI_POSIX #define SANITIZER_INTERCEPT_PREAD SI_POSIX @@ -135,15 +162,18 @@ #define SANITIZER_INTERCEPT_FREAD SI_POSIX #define SANITIZER_INTERCEPT_FWRITE SI_POSIX +#define SANITIZER_INTERCEPT_FGETS SI_POSIX +#define SANITIZER_INTERCEPT_FPUTS SI_POSIX +#define SANITIZER_INTERCEPT_PUTS SI_POSIX -#define SANITIZER_INTERCEPT_PREAD64 SI_LINUX_NOT_ANDROID -#define SANITIZER_INTERCEPT_PWRITE64 SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_PREAD64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32 +#define SANITIZER_INTERCEPT_PWRITE64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32 #define SANITIZER_INTERCEPT_READV SI_POSIX #define SANITIZER_INTERCEPT_WRITEV SI_POSIX #define SANITIZER_INTERCEPT_PREADV \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_PWRITEV SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_PREADV64 SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_PWRITEV64 SI_LINUX_NOT_ANDROID @@ -162,46 +192,62 @@ # define SANITIZER_INTERCEPT_ISOC99_PRINTF SI_LINUX_NOT_ANDROID #endif +#define SANITIZER_INTERCEPT___PRINTF_CHK \ + (SANITIZER_INTERCEPT_PRINTF && SI_LINUX_NOT_ANDROID) + #define SANITIZER_INTERCEPT_FREXP SI_NOT_FUCHSIA #define SANITIZER_INTERCEPT_FREXPF_FREXPL SI_POSIX #define SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS SI_POSIX -#define SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_GETPWENT \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_FGETPWENT SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS \ + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \ + SI_SOLARIS) +#define SANITIZER_INTERCEPT_GETPWENT \ + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || 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_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_SETPWENT (SI_MAC || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_CLOCK_GETTIME (SI_FREEBSD || SI_NETBSD || SI_LINUX) + (SI_FREEBSD || SI_NETBSD || 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 \ + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX || SI_SOLARIS) #define SANITIZER_INTERCEPT_GETITIMER SI_POSIX #define SANITIZER_INTERCEPT_TIME SI_POSIX -#define SANITIZER_INTERCEPT_GLOB SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_GLOB SI_LINUX_NOT_ANDROID || SI_SOLARIS +#define SANITIZER_INTERCEPT_GLOB64 SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_WAIT SI_POSIX #define SANITIZER_INTERCEPT_INET SI_POSIX -#define SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM SI_POSIX +#define SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM (SI_POSIX && !SI_OPENBSD) #define SANITIZER_INTERCEPT_GETADDRINFO SI_POSIX #define SANITIZER_INTERCEPT_GETNAMEINFO SI_POSIX #define SANITIZER_INTERCEPT_GETSOCKNAME SI_POSIX #define SANITIZER_INTERCEPT_GETHOSTBYNAME SI_POSIX -#define SANITIZER_INTERCEPT_GETHOSTBYNAME_R (SI_FREEBSD || SI_LINUX) +#define SANITIZER_INTERCEPT_GETHOSTBYNAME2 SI_POSIX && !SI_SOLARIS +#define SANITIZER_INTERCEPT_GETHOSTBYNAME_R \ + (SI_FREEBSD || SI_LINUX || SI_SOLARIS) #define SANITIZER_INTERCEPT_GETHOSTBYNAME2_R \ (SI_FREEBSD || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_GETHOSTBYADDR_R (SI_FREEBSD || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_GETHOSTENT_R (SI_FREEBSD || SI_LINUX_NOT_ANDROID) +#define SANITIZER_INTERCEPT_GETHOSTBYADDR_R \ + (SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) +#define SANITIZER_INTERCEPT_GETHOSTENT_R \ + (SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_GETSOCKOPT SI_POSIX #define SANITIZER_INTERCEPT_ACCEPT SI_POSIX -#define SANITIZER_INTERCEPT_ACCEPT4 SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_ACCEPT4 \ + (SI_LINUX_NOT_ANDROID || SI_NETBSD || SI_OPENBSD) +#define SANITIZER_INTERCEPT_PACCEPT SI_NETBSD #define SANITIZER_INTERCEPT_MODF SI_POSIX #define SANITIZER_INTERCEPT_RECVMSG SI_POSIX #define SANITIZER_INTERCEPT_SENDMSG SI_POSIX +#define SANITIZER_INTERCEPT_RECVMMSG SI_LINUX +#define SANITIZER_INTERCEPT_SENDMMSG SI_LINUX #define SANITIZER_INTERCEPT_GETPEERNAME SI_POSIX #define SANITIZER_INTERCEPT_IOCTL SI_POSIX #define SANITIZER_INTERCEPT_INET_ATON SI_POSIX #define SANITIZER_INTERCEPT_SYSINFO SI_LINUX #define SANITIZER_INTERCEPT_READDIR SI_POSIX -#define SANITIZER_INTERCEPT_READDIR64 SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_READDIR64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32 #if SI_LINUX_NOT_ANDROID && \ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ @@ -215,111 +261,137 @@ #define SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_STRTOIMAX SI_POSIX #define SANITIZER_INTERCEPT_MBSTOWCS SI_POSIX -#define SANITIZER_INTERCEPT_MBSNRTOWCS (SI_MAC || SI_LINUX_NOT_ANDROID) +#define SANITIZER_INTERCEPT_MBSNRTOWCS \ + (SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_WCSTOMBS SI_POSIX -#define SANITIZER_INTERCEPT_WCSNRTOMBS \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_WCRTOMB \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_STRXFRM SI_POSIX +#define SANITIZER_INTERCEPT___STRXFRM_L SI_LINUX +#define SANITIZER_INTERCEPT_WCSXFRM SI_POSIX +#define SANITIZER_INTERCEPT___WCSXFRM_L SI_LINUX +#define SANITIZER_INTERCEPT_WCSNRTOMBS \ + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \ + SI_SOLARIS) +#define SANITIZER_INTERCEPT_WCRTOMB \ + (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 SI_LINUX_NOT_ANDROID -#define SANITIZER_INTERCEPT_CONFSTR \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID) +#define SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME \ + (SI_LINUX_NOT_ANDROID || SI_SOLARIS) +#define SANITIZER_INTERCEPT_CONFSTR \ + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \ + SI_SOLARIS) #define SANITIZER_INTERCEPT_SCHED_GETAFFINITY SI_LINUX_NOT_ANDROID -#define SANITIZER_INTERCEPT_SCHED_GETPARAM SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_SCHED_GETPARAM SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_STRERROR SI_POSIX #define SANITIZER_INTERCEPT_STRERROR_R SI_POSIX #define SANITIZER_INTERCEPT_XPG_STRERROR_R SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_SCANDIR \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_SCANDIR64 SI_LINUX_NOT_ANDROID + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) +#define SANITIZER_INTERCEPT_SCANDIR64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32 #define SANITIZER_INTERCEPT_GETGROUPS SI_POSIX #define SANITIZER_INTERCEPT_POLL SI_POSIX -#define SANITIZER_INTERCEPT_PPOLL SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_PPOLL SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_WORDEXP \ - (SI_FREEBSD || SI_NETBSD || (SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || (SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID || \ + SI_SOLARIS) #define SANITIZER_INTERCEPT_SIGWAIT SI_POSIX -#define SANITIZER_INTERCEPT_SIGWAITINFO SI_LINUX_NOT_ANDROID -#define SANITIZER_INTERCEPT_SIGTIMEDWAIT SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_SIGWAITINFO SI_LINUX_NOT_ANDROID || SI_SOLARIS +#define SANITIZER_INTERCEPT_SIGTIMEDWAIT SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_SIGSETOPS \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID) + (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_BACKTRACE \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_GETMNTENT SI_LINUX #define SANITIZER_INTERCEPT_GETMNTENT_R SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_STATFS \ - (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_STATFS64 \ ((SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_STATVFS \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_STATVFS64 SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_INITGROUPS SI_POSIX -#define SANITIZER_INTERCEPT_ETHER_NTOA_ATON SI_POSIX +#define SANITIZER_INTERCEPT_ETHER_NTOA_ATON (SI_POSIX && !SI_OPENBSD) #define SANITIZER_INTERCEPT_ETHER_HOST \ (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_ETHER_R (SI_FREEBSD || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_SHMCTL \ - (SI_NETBSD || ((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && \ - SANITIZER_WORDSIZE == 64)) // NOLINT +#define SANITIZER_INTERCEPT_SHMCTL \ + (SI_NETBSD || SI_OPENBSD || SI_SOLARIS || \ + ((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && \ + SANITIZER_WORDSIZE == 64)) // NOLINT #define SANITIZER_INTERCEPT_RANDOM_R SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET SI_POSIX #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP SI_LINUX_NOT_ANDROID -#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED SI_POSIX -#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE SI_POSIX +#define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET_SCHED (SI_POSIX && !SI_OPENBSD) +#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED \ + (SI_POSIX && !SI_NETBSD && !SI_OPENBSD) +#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE (SI_POSIX && !SI_OPENBSD) #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL \ - (SI_MAC || SI_NETBSD || SI_LINUX_NOT_ANDROID) + (SI_MAC || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING \ - (SI_MAC || SI_NETBSD || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST SI_LINUX_NOT_ANDROID + (SI_MAC || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) +#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST \ + (SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP SI_LINUX_NOT_ANDROID -#define SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED SI_POSIX +#define SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED \ + (SI_POSIX && !SI_NETBSD && !SI_OPENBSD) #define SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP SI_LINUX_NOT_ANDROID -#define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED SI_POSIX -#define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK SI_LINUX_NOT_ANDROID -#define SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED \ + (SI_POSIX && !SI_NETBSD && !SI_OPENBSD) +#define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK \ + (SI_LINUX_NOT_ANDROID || SI_SOLARIS) +#define SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED \ + (SI_LINUX_NOT_ANDROID && !SI_NETBSD && !SI_OPENBSD) +#define SANITIZER_INTERCEPT_THR_EXIT SI_FREEBSD #define SANITIZER_INTERCEPT_TMPNAM SI_POSIX -#define SANITIZER_INTERCEPT_TMPNAM_R SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_TMPNAM_R SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_TTYNAME_R SI_POSIX #define SANITIZER_INTERCEPT_TEMPNAM SI_POSIX -#define SANITIZER_INTERCEPT_SINCOS SI_LINUX +#define SANITIZER_INTERCEPT_SINCOS SI_LINUX || SI_SOLARIS #define SANITIZER_INTERCEPT_REMQUO SI_POSIX #define SANITIZER_INTERCEPT_LGAMMA SI_POSIX -#define SANITIZER_INTERCEPT_LGAMMA_R (SI_FREEBSD || SI_LINUX) -#define SANITIZER_INTERCEPT_LGAMMAL_R SI_LINUX_NOT_ANDROID +#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 -#define SANITIZER_INTERCEPT_RAND_R \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID) +#define SANITIZER_INTERCEPT_RAND_R \ + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_LINUX_NOT_ANDROID || \ + SI_SOLARIS) #define SANITIZER_INTERCEPT_ICONV \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_TIMES SI_POSIX // FIXME: getline seems to be available on OSX 10.7 #define SANITIZER_INTERCEPT_GETLINE \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT__EXIT \ - (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_MAC) + (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_MAC || SI_SOLARIS) -#define SANITIZER_INTERCEPT_PHTREAD_MUTEX SI_POSIX +#define SANITIZER_INTERCEPT_PTHREAD_MUTEX SI_POSIX +#define SANITIZER_INTERCEPT___PTHREAD_MUTEX SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT___LIBC_MUTEX SI_NETBSD #define SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) + (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) #define SANITIZER_INTERCEPT_TLS_GET_ADDR \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_LISTXATTR SI_LINUX #define SANITIZER_INTERCEPT_GETXATTR SI_LINUX #define SANITIZER_INTERCEPT_GETRESID SI_LINUX -#define SANITIZER_INTERCEPT_GETIFADDRS \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC) -#define SANITIZER_INTERCEPT_IF_INDEXTONAME \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC) +#define SANITIZER_INTERCEPT_GETIFADDRS \ + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_MAC || \ + SI_SOLARIS) +#define SANITIZER_INTERCEPT_IF_INDEXTONAME \ + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_MAC || \ + SI_SOLARIS) #define SANITIZER_INTERCEPT_CAPGET SI_LINUX_NOT_ANDROID #if SI_LINUX && defined(__arm__) #define SANITIZER_INTERCEPT_AEABI_MEM 1 @@ -327,67 +399,114 @@ #define SANITIZER_INTERCEPT_AEABI_MEM 0 #endif #define SANITIZER_INTERCEPT___BZERO SI_MAC -#define SANITIZER_INTERCEPT_FTIME (!SI_FREEBSD && !SI_NETBSD && SI_POSIX) -#define SANITIZER_INTERCEPT_XDR 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 #define SANITIZER_INTERCEPT_TSEARCH \ - (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD) + (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD || SI_OPENBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_LIBIO_INTERNALS SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_FOPEN SI_POSIX -#define SANITIZER_INTERCEPT_FOPEN64 SI_LINUX_NOT_ANDROID -#define SANITIZER_INTERCEPT_OPEN_MEMSTREAM (SI_LINUX_NOT_ANDROID || SI_NETBSD) +#define SANITIZER_INTERCEPT_FOPEN64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32 +#define SANITIZER_INTERCEPT_OPEN_MEMSTREAM \ + (SI_LINUX_NOT_ANDROID || SI_NETBSD || SI_OPENBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_OBSTACK SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_FFLUSH SI_POSIX #define SANITIZER_INTERCEPT_FCLOSE SI_POSIX #ifndef SANITIZER_INTERCEPT_DLOPEN_DLCLOSE -#define SANITIZER_INTERCEPT_DLOPEN_DLCLOSE \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC) +#define SANITIZER_INTERCEPT_DLOPEN_DLCLOSE \ + (SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_LINUX_NOT_ANDROID || SI_MAC || \ + SI_SOLARIS) #endif #define SANITIZER_INTERCEPT_GETPASS \ - (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD) + (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD || SI_OPENBSD) #define SANITIZER_INTERCEPT_TIMERFD SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_MLOCKX SI_POSIX #define SANITIZER_INTERCEPT_FOPENCOOKIE SI_LINUX_NOT_ANDROID -#define SANITIZER_INTERCEPT_SEM (SI_LINUX || SI_FREEBSD || SI_NETBSD) +#define SANITIZER_INTERCEPT_SEM \ + (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_SETCANCEL SI_POSIX -#define SANITIZER_INTERCEPT_MINCORE (SI_LINUX || SI_NETBSD) +#define SANITIZER_INTERCEPT_MINCORE \ + (SI_LINUX || SI_NETBSD || SI_OPENBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_PROCESS_VM_READV SI_LINUX #define SANITIZER_INTERCEPT_CTERMID \ - (SI_LINUX || SI_MAC || SI_FREEBSD || SI_NETBSD) -#define SANITIZER_INTERCEPT_CTERMID_R (SI_MAC || SI_FREEBSD) + (SI_LINUX || SI_MAC || SI_FREEBSD || SI_NETBSD || SI_OPENBSD || SI_SOLARIS) +#define SANITIZER_INTERCEPT_CTERMID_R (SI_MAC || SI_FREEBSD || SI_SOLARIS) -#define SANITIZER_INTERCEPTOR_HOOKS (SI_LINUX || SI_MAC || SI_WINDOWS) +#define SANITIZER_INTERCEPTOR_HOOKS \ + (SI_LINUX || SI_MAC || SI_WINDOWS || SI_NETBSD) #define SANITIZER_INTERCEPT_RECV_RECVFROM SI_POSIX #define SANITIZER_INTERCEPT_SEND_SENDTO SI_POSIX #define SANITIZER_INTERCEPT_EVENTFD_READ_WRITE SI_LINUX #define SANITIZER_INTERCEPT_STAT \ - (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD) + (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_OPENBSD || SI_SOLARIS) +#define SANITIZER_INTERCEPT_LSTAT (SI_NETBSD || SI_FREEBSD) #define SANITIZER_INTERCEPT___XSTAT (!SANITIZER_INTERCEPT_STAT && SI_POSIX) #define SANITIZER_INTERCEPT___XSTAT64 SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT___LXSTAT SANITIZER_INTERCEPT___XSTAT #define SANITIZER_INTERCEPT___LXSTAT64 SI_LINUX_NOT_ANDROID -#define SANITIZER_INTERCEPT_UTMP (SI_POSIX && !SI_MAC && !SI_FREEBSD) -#define SANITIZER_INTERCEPT_UTMPX (SI_LINUX_NOT_ANDROID || SI_MAC || SI_FREEBSD) +#define SANITIZER_INTERCEPT_UTMP \ + (SI_POSIX && !SI_MAC && !SI_FREEBSD && !SI_NETBSD) +#define SANITIZER_INTERCEPT_UTMPX \ + (SI_LINUX_NOT_ANDROID || SI_MAC || SI_FREEBSD || SI_NETBSD) #define SANITIZER_INTERCEPT_GETLOADAVG \ - (SI_LINUX_NOT_ANDROID || SI_MAC || SI_FREEBSD || SI_NETBSD) + (SI_LINUX_NOT_ANDROID || SI_MAC || SI_FREEBSD || SI_NETBSD || SI_OPENBSD) +#define SANITIZER_INTERCEPT_MMAP SI_POSIX +#define SANITIZER_INTERCEPT_MMAP64 SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_MALLOPT_AND_MALLINFO \ - (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && SI_NOT_FUCHSIA) -#define SANITIZER_INTERCEPT_MEMALIGN (!SI_FREEBSD && !SI_MAC && !SI_NETBSD) + (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA && \ + SI_NOT_RTEMS) +#define SANITIZER_INTERCEPT_MEMALIGN \ + (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_RTEMS) #define SANITIZER_INTERCEPT_PVALLOC \ - (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && SI_NOT_FUCHSIA) + (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA && \ + SI_NOT_RTEMS) #define SANITIZER_INTERCEPT_CFREE \ - (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && SI_NOT_FUCHSIA) -#define SANITIZER_INTERCEPT_ALIGNED_ALLOC (!SI_MAC) -#define SANITIZER_INTERCEPT_MALLOC_USABLE_SIZE (!SI_MAC) + (!SI_FREEBSD && !SI_MAC && !SI_NETBSD && !SI_OPENBSD && SI_NOT_FUCHSIA && \ + SI_NOT_RTEMS) +#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_SIGNAL_AND_SIGACTION (!SI_WINDOWS && SI_NOT_FUCHSIA) #define SANITIZER_INTERCEPT_BSD_SIGNAL SI_ANDROID +#define SANITIZER_INTERCEPT_ACCT (SI_NETBSD || SI_OPENBSD || SI_FREEBSD) +#define SANITIZER_INTERCEPT_USER_FROM_UID SI_NETBSD +#define SANITIZER_INTERCEPT_UID_FROM_USER SI_NETBSD +#define SANITIZER_INTERCEPT_GROUP_FROM_GID SI_NETBSD +#define SANITIZER_INTERCEPT_GID_FROM_GROUP SI_NETBSD +#define SANITIZER_INTERCEPT_ACCESS (SI_NETBSD || SI_OPENBSD || SI_FREEBSD) +#define SANITIZER_INTERCEPT_FACCESSAT (SI_NETBSD || SI_OPENBSD || SI_FREEBSD) +#define SANITIZER_INTERCEPT_GETGROUPLIST (SI_NETBSD || SI_OPENBSD) +#define SANITIZER_INTERCEPT_STRLCPY \ + (SI_NETBSD || SI_FREEBSD || SI_OPENBSD || SI_MAC || SI_ANDROID) + +#define SANITIZER_INTERCEPT_NAME_TO_HANDLE_AT SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_OPEN_BY_HANDLE_AT SI_LINUX_NOT_ANDROID + +#define SANITIZER_INTERCEPT_READLINK SI_POSIX +#if defined(__ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__) && \ + __ENVIRONMENT_MAC_OS_X_VERSION_MIN_REQUIRED__ < 101000 +# define SI_MAC_DEPLOYMENT_BELOW_10_10 1 +#else +# define SI_MAC_DEPLOYMENT_BELOW_10_10 0 +#endif +#define SANITIZER_INTERCEPT_READLINKAT \ + (SI_POSIX && !SI_MAC_DEPLOYMENT_BELOW_10_10) + +#define SANITIZER_INTERCEPT_DEVNAME (SI_NETBSD || SI_OPENBSD || SI_FREEBSD) +#define SANITIZER_INTERCEPT_DEVNAME_R (SI_NETBSD || SI_FREEBSD) +#define SANITIZER_INTERCEPT_FGETLN (SI_NETBSD || SI_FREEBSD) +#define SANITIZER_INTERCEPT_STRMODE (SI_NETBSD || SI_FREEBSD) +#define SANITIZER_INTERCEPT_TTYENT SI_NETBSD +#define SANITIZER_INTERCEPT_PROTOENT SI_NETBSD +#define SANITIZER_INTERCEPT_NETENT SI_NETBSD + #endif // #ifndef SANITIZER_PLATFORM_INTERCEPTORS_H diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc index 3a906538129..23a014823c4 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_linux.cc @@ -25,12 +25,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.cc index 3c18ca6ce25..8e74727c999 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cc +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.cc @@ -13,7 +13,53 @@ #include "sanitizer_platform.h" #if SANITIZER_NETBSD +#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 @@ -26,6 +72,8 @@ #include #include #include +#include +#include #include #include #include @@ -33,6 +81,93 @@ #include #include #include +#include +#include +#include +#include +#define RAY_DO_SIGLEV +#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 @@ -42,6 +177,7 @@ #include #include #include +#include #include #include #include @@ -60,6 +196,7 @@ #include #include #include +#include #include #include #include @@ -81,6 +218,7 @@ 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); @@ -96,16 +234,80 @@ 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_sembuf_sz = sizeof(struct sembuf); +unsigned struct_kevent_sz = sizeof(struct kevent); unsigned struct_utimbuf_sz = sizeof(struct utimbuf); unsigned struct_itimerspec_sz = sizeof(struct itimerspec); 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); +unsigned struct_sigaltstack_sz = sizeof(stack_t); + +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 ptrace_pt_io = PT_IO; +int ptrace_pt_lwpinfo = PT_LWPINFO; +int ptrace_pt_set_event_mask = PT_SET_EVENT_MASK; +int ptrace_pt_get_event_mask = PT_GET_EVENT_MASK; +int ptrace_pt_get_process_state = PT_GET_PROCESS_STATE; +int ptrace_pt_set_siginfo = PT_SET_SIGINFO; +int ptrace_pt_get_siginfo = PT_GET_SIGINFO; +int ptrace_piod_read_d = PIOD_READ_D; +int ptrace_piod_write_d = PIOD_WRITE_D; +int ptrace_piod_read_i = PIOD_READ_I; +int ptrace_piod_write_i = PIOD_WRITE_I; +int ptrace_piod_read_auxv = PIOD_READ_AUXV; + +#if defined(PT_SETREGS) && defined(PT_GETREGS) +int ptrace_pt_setregs = PT_SETREGS; +int ptrace_pt_getregs = PT_GETREGS; +#else +int ptrace_pt_setregs = -1; +int ptrace_pt_getregs = -1; +#endif + +#if defined(PT_SETFPREGS) && defined(PT_GETFPREGS) +int ptrace_pt_setfpregs = PT_SETFPREGS; +int ptrace_pt_getfpregs = PT_GETFPREGS; +#else +int ptrace_pt_setfpregs = -1; +int ptrace_pt_getfpregs = -1; +#endif + +#if defined(PT_SETDBREGS) && defined(PT_GETDBREGS) +int ptrace_pt_setdbregs = PT_SETDBREGS; +int ptrace_pt_getdbregs = PT_GETDBREGS; +#else +int ptrace_pt_setdbregs = -1; +int ptrace_pt_getdbregs = -1; +#endif + +unsigned struct_ptrace_ptrace_io_desc_struct_sz = sizeof(struct ptrace_io_desc); +unsigned struct_ptrace_ptrace_lwpinfo_struct_sz = sizeof(struct ptrace_lwpinfo); +unsigned struct_ptrace_ptrace_event_struct_sz = sizeof(ptrace_event_t); +unsigned struct_ptrace_ptrace_siginfo_struct_sz = sizeof(ptrace_siginfo_t); -uptr sig_ign = (uptr)SIG_IGN; -uptr sig_dfl = (uptr)SIG_DFL; -uptr sa_siginfo = (uptr)SA_SIGINFO; +#if defined(PT_SETREGS) +unsigned struct_ptrace_reg_struct_sz = sizeof(struct reg); +#else +unsigned struct_ptrace_reg_struct_sz = -1; +#endif + +#if defined(PT_SETFPREGS) +unsigned struct_ptrace_fpreg_struct_sz = sizeof(struct fpreg); +#else +unsigned struct_ptrace_fpreg_struct_sz = -1; +#endif + +#if defined(PT_SETDBREGS) +unsigned struct_ptrace_dbreg_struct_sz = sizeof(struct dbreg); +#else +unsigned struct_ptrace_dbreg_struct_sz = -1; +#endif int shmctl_ipc_stat = (int)IPC_STAT; @@ -126,70 +328,1736 @@ uptr __sanitizer_in_addr_sz(int af) { 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; +int struct_ttyent_sz = sizeof(struct ttyent); + // ioctl arguments -unsigned struct_ifreq_sz = sizeof(struct ifreq); -unsigned struct_termios_sz = sizeof(struct termios); -unsigned struct_winsize_sz = sizeof(struct winsize); -unsigned struct_mtget_sz = sizeof(struct mtget); -unsigned struct_mtop_sz = sizeof(struct mtop); -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); +unsigned struct_altqreq_sz = sizeof(altqreq); +unsigned struct_amr_user_ioctl_sz = sizeof(amr_user_ioctl); +unsigned struct_ap_control_sz = sizeof(ap_control); +unsigned struct_apm_ctl_sz = sizeof(apm_ctl); +unsigned struct_apm_event_info_sz = sizeof(apm_event_info); +unsigned struct_apm_power_info_sz = sizeof(apm_power_info); +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); +unsigned struct_audio_info_sz = sizeof(audio_info); +unsigned struct_audio_offset_sz = sizeof(audio_offset); +unsigned struct_bio_locate_sz = sizeof(bio_locate); +unsigned struct_bioc_alarm_sz = sizeof(bioc_alarm); +unsigned struct_bioc_blink_sz = sizeof(bioc_blink); +unsigned struct_bioc_disk_sz = sizeof(bioc_disk); +unsigned struct_bioc_inq_sz = sizeof(bioc_inq); +unsigned struct_bioc_setstate_sz = sizeof(bioc_setstate); +unsigned struct_bioc_vol_sz = sizeof(bioc_vol); +unsigned struct_bioc_volops_sz = sizeof(bioc_volops); +unsigned struct_bktr_chnlset_sz = sizeof(bktr_chnlset); +unsigned struct_bktr_remote_sz = sizeof(bktr_remote); +unsigned struct_blue_conf_sz = sizeof(blue_conf); +unsigned struct_blue_interface_sz = sizeof(blue_interface); +unsigned struct_blue_stats_sz = sizeof(blue_stats); +unsigned struct_bpf_dltlist_sz = sizeof(bpf_dltlist); +unsigned struct_bpf_program_sz = sizeof(bpf_program); +unsigned struct_bpf_stat_old_sz = sizeof(bpf_stat_old); +unsigned struct_bpf_stat_sz = sizeof(bpf_stat); +unsigned struct_bpf_version_sz = sizeof(bpf_version); +unsigned struct_btreq_sz = sizeof(btreq); +unsigned struct_btsco_info_sz = sizeof(btsco_info); +unsigned struct_buffmem_desc_sz = sizeof(buffmem_desc); +unsigned struct_cbq_add_class_sz = sizeof(cbq_add_class); +unsigned struct_cbq_add_filter_sz = sizeof(cbq_add_filter); +unsigned struct_cbq_delete_class_sz = sizeof(cbq_delete_class); +unsigned struct_cbq_delete_filter_sz = sizeof(cbq_delete_filter); +unsigned struct_cbq_getstats_sz = sizeof(cbq_getstats); +unsigned struct_cbq_interface_sz = sizeof(cbq_interface); +unsigned struct_cbq_modify_class_sz = sizeof(cbq_modify_class); +unsigned struct_ccd_ioctl_sz = sizeof(ccd_ioctl); +unsigned struct_cdnr_add_element_sz = sizeof(cdnr_add_element); +unsigned struct_cdnr_add_filter_sz = sizeof(cdnr_add_filter); +unsigned struct_cdnr_add_tbmeter_sz = sizeof(cdnr_add_tbmeter); +unsigned struct_cdnr_add_trtcm_sz = sizeof(cdnr_add_trtcm); +unsigned struct_cdnr_add_tswtcm_sz = sizeof(cdnr_add_tswtcm); +unsigned struct_cdnr_delete_element_sz = sizeof(cdnr_delete_element); +unsigned struct_cdnr_delete_filter_sz = sizeof(cdnr_delete_filter); +unsigned struct_cdnr_get_stats_sz = sizeof(cdnr_get_stats); +unsigned struct_cdnr_interface_sz = sizeof(cdnr_interface); +unsigned struct_cdnr_modify_tbmeter_sz = sizeof(cdnr_modify_tbmeter); +unsigned struct_cdnr_modify_trtcm_sz = sizeof(cdnr_modify_trtcm); +unsigned struct_cdnr_modify_tswtcm_sz = sizeof(cdnr_modify_tswtcm); +unsigned struct_cdnr_tbmeter_stats_sz = sizeof(cdnr_tbmeter_stats); +unsigned struct_cdnr_tcm_stats_sz = sizeof(cdnr_tcm_stats); +unsigned struct_cgd_ioctl_sz = sizeof(cgd_ioctl); +unsigned struct_cgd_user_sz = sizeof(cgd_user); +unsigned struct_changer_element_status_request_sz = + sizeof(changer_element_status_request); +unsigned struct_changer_exchange_request_sz = sizeof(changer_exchange_request); +unsigned struct_changer_move_request_sz = sizeof(changer_move_request); +unsigned struct_changer_params_sz = sizeof(changer_params); +unsigned struct_changer_position_request_sz = sizeof(changer_position_request); +unsigned struct_changer_set_voltag_request_sz = + sizeof(changer_set_voltag_request); +unsigned struct_clockctl_adjtime_sz = sizeof(clockctl_adjtime); +unsigned struct_clockctl_clock_settime_sz = sizeof(clockctl_clock_settime); +unsigned struct_clockctl_ntp_adjtime_sz = sizeof(clockctl_ntp_adjtime); +unsigned struct_clockctl_settimeofday_sz = sizeof(clockctl_settimeofday); +unsigned struct_cnwistats_sz = sizeof(cnwistats); +unsigned struct_cnwitrail_sz = sizeof(cnwitrail); +unsigned struct_cnwstatus_sz = sizeof(cnwstatus); +unsigned struct_count_info_sz = sizeof(count_info); +unsigned struct_cpu_ucode_sz = sizeof(cpu_ucode); +unsigned struct_cpu_ucode_version_sz = sizeof(cpu_ucode_version); +unsigned struct_crypt_kop_sz = sizeof(crypt_kop); +unsigned struct_crypt_mkop_sz = sizeof(crypt_mkop); +unsigned struct_crypt_mop_sz = sizeof(crypt_mop); +unsigned struct_crypt_op_sz = sizeof(crypt_op); +unsigned struct_crypt_result_sz = sizeof(crypt_result); +unsigned struct_crypt_sfop_sz = sizeof(crypt_sfop); +unsigned struct_crypt_sgop_sz = sizeof(crypt_sgop); +unsigned struct_cryptret_sz = sizeof(cryptret); +unsigned struct_devdetachargs_sz = sizeof(devdetachargs); +unsigned struct_devlistargs_sz = sizeof(devlistargs); +unsigned struct_devpmargs_sz = sizeof(devpmargs); +unsigned struct_devrescanargs_sz = sizeof(devrescanargs); +unsigned struct_disk_badsecinfo_sz = sizeof(disk_badsecinfo); +unsigned struct_disk_strategy_sz = sizeof(disk_strategy); +unsigned struct_disklabel_sz = sizeof(disklabel); +unsigned struct_dkbad_sz = sizeof(dkbad); +unsigned struct_dkwedge_info_sz = sizeof(dkwedge_info); +unsigned struct_dkwedge_list_sz = sizeof(dkwedge_list); +unsigned struct_dmio_setfunc_sz = sizeof(dmio_setfunc); +unsigned struct_dmx_pes_filter_params_sz = sizeof(dmx_pes_filter_params); +unsigned struct_dmx_sct_filter_params_sz = sizeof(dmx_sct_filter_params); +unsigned struct_dmx_stc_sz = sizeof(dmx_stc); +unsigned struct_dvb_diseqc_master_cmd_sz = sizeof(dvb_diseqc_master_cmd); +unsigned struct_dvb_diseqc_slave_reply_sz = sizeof(dvb_diseqc_slave_reply); +unsigned struct_dvb_frontend_event_sz = sizeof(dvb_frontend_event); +unsigned struct_dvb_frontend_info_sz = sizeof(dvb_frontend_info); +unsigned struct_dvb_frontend_parameters_sz = sizeof(dvb_frontend_parameters); +unsigned struct_eccapreq_sz = sizeof(eccapreq); +unsigned struct_fbcmap_sz = sizeof(fbcmap); +unsigned struct_fbcurpos_sz = sizeof(fbcurpos); +unsigned struct_fbcursor_sz = sizeof(fbcursor); +unsigned struct_fbgattr_sz = sizeof(fbgattr); +unsigned struct_fbsattr_sz = sizeof(fbsattr); +unsigned struct_fbtype_sz = sizeof(fbtype); +unsigned struct_fdformat_cmd_sz = sizeof(fdformat_cmd); +unsigned struct_fdformat_parms_sz = sizeof(fdformat_parms); +unsigned struct_fifoq_conf_sz = sizeof(fifoq_conf); +unsigned struct_fifoq_getstats_sz = sizeof(fifoq_getstats); +unsigned struct_fifoq_interface_sz = sizeof(fifoq_interface); +unsigned struct_format_op_sz = sizeof(format_op); +unsigned struct_fss_get_sz = sizeof(fss_get); +unsigned struct_fss_set_sz = sizeof(fss_set); +unsigned struct_gpio_attach_sz = sizeof(gpio_attach); +unsigned struct_gpio_info_sz = sizeof(gpio_info); +unsigned struct_gpio_req_sz = sizeof(gpio_req); +unsigned struct_gpio_set_sz = sizeof(gpio_set); +unsigned struct_hfsc_add_class_sz = sizeof(hfsc_add_class); +unsigned struct_hfsc_add_filter_sz = sizeof(hfsc_add_filter); +unsigned struct_hfsc_attach_sz = sizeof(hfsc_attach); +unsigned struct_hfsc_class_stats_sz = sizeof(hfsc_class_stats); +unsigned struct_hfsc_delete_class_sz = sizeof(hfsc_delete_class); +unsigned struct_hfsc_delete_filter_sz = sizeof(hfsc_delete_filter); +unsigned struct_hfsc_interface_sz = sizeof(hfsc_interface); +unsigned struct_hfsc_modify_class_sz = sizeof(hfsc_modify_class); +unsigned struct_hpcfb_dsp_op_sz = sizeof(hpcfb_dsp_op); +unsigned struct_hpcfb_dspconf_sz = sizeof(hpcfb_dspconf); +unsigned struct_hpcfb_fbconf_sz = sizeof(hpcfb_fbconf); +unsigned struct_if_addrprefreq_sz = sizeof(if_addrprefreq); +unsigned struct_if_clonereq_sz = sizeof(if_clonereq); +unsigned struct_if_laddrreq_sz = sizeof(if_laddrreq); +unsigned struct_ifaddr_sz = sizeof(ifaddr); +unsigned struct_ifaliasreq_sz = sizeof(ifaliasreq); +unsigned struct_ifcapreq_sz = sizeof(ifcapreq); +unsigned struct_ifconf_sz = sizeof(ifconf); +unsigned struct_ifdatareq_sz = sizeof(ifdatareq); +unsigned struct_ifdrv_sz = sizeof(ifdrv); +unsigned struct_ifmediareq_sz = sizeof(ifmediareq); +unsigned struct_ifpppcstatsreq_sz = sizeof(ifpppcstatsreq); +unsigned struct_ifpppstatsreq_sz = sizeof(ifpppstatsreq); +unsigned struct_ifreq_sz = sizeof(ifreq); +unsigned struct_in6_addrpolicy_sz = sizeof(in6_addrpolicy); +unsigned struct_in6_ndireq_sz = sizeof(in6_ndireq); +unsigned struct_ioc_load_unload_sz = sizeof(ioc_load_unload); +unsigned struct_ioc_patch_sz = sizeof(ioc_patch); +unsigned struct_ioc_play_blocks_sz = sizeof(ioc_play_blocks); +unsigned struct_ioc_play_msf_sz = sizeof(ioc_play_msf); +unsigned struct_ioc_play_track_sz = sizeof(ioc_play_track); +unsigned struct_ioc_read_subchannel_sz = sizeof(ioc_read_subchannel); +unsigned struct_ioc_read_toc_entry_sz = sizeof(ioc_read_toc_entry); +unsigned struct_ioc_toc_header_sz = sizeof(ioc_toc_header); +unsigned struct_ioc_vol_sz = sizeof(ioc_vol); +unsigned struct_ioctl_pt_sz = sizeof(ioctl_pt); +unsigned struct_ioppt_sz = sizeof(ioppt); +unsigned struct_iovec_sz = sizeof(iovec); +unsigned struct_ipfobj_sz = sizeof(ipfobj); +unsigned struct_irda_params_sz = sizeof(irda_params); +unsigned struct_isp_fc_device_sz = sizeof(isp_fc_device); +unsigned struct_isp_fc_tsk_mgmt_sz = sizeof(isp_fc_tsk_mgmt); +unsigned struct_isp_hba_device_sz = sizeof(isp_hba_device); +unsigned struct_isv_cmd_sz = sizeof(isv_cmd); +unsigned struct_jobs_add_class_sz = sizeof(jobs_add_class); +unsigned struct_jobs_add_filter_sz = sizeof(jobs_add_filter); +unsigned struct_jobs_attach_sz = sizeof(jobs_attach); +unsigned struct_jobs_class_stats_sz = sizeof(jobs_class_stats); +unsigned struct_jobs_delete_class_sz = sizeof(jobs_delete_class); +unsigned struct_jobs_delete_filter_sz = sizeof(jobs_delete_filter); +unsigned struct_jobs_interface_sz = sizeof(jobs_interface); +unsigned struct_jobs_modify_class_sz = sizeof(jobs_modify_class); +unsigned struct_kbentry_sz = sizeof(kbentry); +unsigned struct_kfilter_mapping_sz = sizeof(kfilter_mapping); +unsigned struct_kiockeymap_sz = sizeof(kiockeymap); +unsigned struct_ksyms_gsymbol_sz = sizeof(ksyms_gsymbol); +unsigned struct_ksyms_gvalue_sz = sizeof(ksyms_gvalue); +unsigned struct_ksyms_ogsymbol_sz = sizeof(ksyms_ogsymbol); +unsigned struct_kttcp_io_args_sz = sizeof(kttcp_io_args); +unsigned struct_ltchars_sz = sizeof(ltchars); +unsigned struct_lua_create_sz = sizeof(struct lua_create); +unsigned struct_lua_info_sz = sizeof(struct lua_info); +unsigned struct_lua_load_sz = sizeof(struct lua_load); +unsigned struct_lua_require_sz = sizeof(lua_require); +unsigned struct_mbpp_param_sz = sizeof(mbpp_param); +unsigned struct_md_conf_sz = sizeof(md_conf); +unsigned struct_meteor_capframe_sz = sizeof(meteor_capframe); +unsigned struct_meteor_counts_sz = sizeof(meteor_counts); +unsigned struct_meteor_geomet_sz = sizeof(meteor_geomet); +unsigned struct_meteor_pixfmt_sz = sizeof(meteor_pixfmt); +unsigned struct_meteor_video_sz = sizeof(meteor_video); +unsigned struct_mlx_cinfo_sz = sizeof(mlx_cinfo); +unsigned struct_mlx_pause_sz = sizeof(mlx_pause); +unsigned struct_mlx_rebuild_request_sz = sizeof(mlx_rebuild_request); +unsigned struct_mlx_rebuild_status_sz = sizeof(mlx_rebuild_status); +unsigned struct_mlx_usercommand_sz = sizeof(mlx_usercommand); +unsigned struct_mly_user_command_sz = sizeof(mly_user_command); +unsigned struct_mly_user_health_sz = sizeof(mly_user_health); +unsigned struct_mtget_sz = sizeof(mtget); +unsigned struct_mtop_sz = sizeof(mtop); +unsigned struct_npf_ioctl_table_sz = sizeof(npf_ioctl_table); +unsigned struct_npioctl_sz = sizeof(npioctl); +unsigned struct_nvme_pt_command_sz = sizeof(nvme_pt_command); +unsigned struct_ochanger_element_status_request_sz = + sizeof(ochanger_element_status_request); +unsigned struct_ofiocdesc_sz = sizeof(ofiocdesc); +unsigned struct_okiockey_sz = sizeof(okiockey); +unsigned struct_ortentry_sz = sizeof(ortentry); +unsigned struct_oscsi_addr_sz = sizeof(oscsi_addr); +unsigned struct_oss_audioinfo_sz = sizeof(oss_audioinfo); +unsigned struct_oss_sysinfo_sz = sizeof(oss_sysinfo); +unsigned struct_pciio_bdf_cfgreg_sz = sizeof(pciio_bdf_cfgreg); +unsigned struct_pciio_businfo_sz = sizeof(pciio_businfo); +unsigned struct_pciio_cfgreg_sz = sizeof(pciio_cfgreg); +unsigned struct_pciio_drvname_sz = sizeof(pciio_drvname); +unsigned struct_pciio_drvnameonbus_sz = sizeof(pciio_drvnameonbus); +unsigned struct_pcvtid_sz = sizeof(pcvtid); +unsigned struct_pf_osfp_ioctl_sz = sizeof(pf_osfp_ioctl); +unsigned struct_pf_status_sz = sizeof(pf_status); +unsigned struct_pfioc_altq_sz = sizeof(pfioc_altq); +unsigned struct_pfioc_if_sz = sizeof(pfioc_if); +unsigned struct_pfioc_iface_sz = sizeof(pfioc_iface); +unsigned struct_pfioc_limit_sz = sizeof(pfioc_limit); +unsigned struct_pfioc_natlook_sz = sizeof(pfioc_natlook); +unsigned struct_pfioc_pooladdr_sz = sizeof(pfioc_pooladdr); +unsigned struct_pfioc_qstats_sz = sizeof(pfioc_qstats); +unsigned struct_pfioc_rule_sz = sizeof(pfioc_rule); +unsigned struct_pfioc_ruleset_sz = sizeof(pfioc_ruleset); +unsigned struct_pfioc_src_node_kill_sz = sizeof(pfioc_src_node_kill); +unsigned struct_pfioc_src_nodes_sz = sizeof(pfioc_src_nodes); +unsigned struct_pfioc_state_kill_sz = sizeof(pfioc_state_kill); +unsigned struct_pfioc_state_sz = sizeof(pfioc_state); +unsigned struct_pfioc_states_sz = sizeof(pfioc_states); +unsigned struct_pfioc_table_sz = sizeof(pfioc_table); +unsigned struct_pfioc_tm_sz = sizeof(pfioc_tm); +unsigned struct_pfioc_trans_sz = sizeof(pfioc_trans); +unsigned struct_plistref_sz = sizeof(plistref); +unsigned struct_power_type_sz = sizeof(power_type); +unsigned struct_ppp_idle_sz = sizeof(ppp_idle); +unsigned struct_ppp_option_data_sz = sizeof(ppp_option_data); +unsigned struct_ppp_rawin_sz = sizeof(ppp_rawin); +unsigned struct_pppoeconnectionstate_sz = sizeof(pppoeconnectionstate); +unsigned struct_pppoediscparms_sz = sizeof(pppoediscparms); +unsigned struct_priq_add_class_sz = sizeof(priq_add_class); +unsigned struct_priq_add_filter_sz = sizeof(priq_add_filter); +unsigned struct_priq_class_stats_sz = sizeof(priq_class_stats); +unsigned struct_priq_delete_class_sz = sizeof(priq_delete_class); +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); +unsigned struct_red_stats_sz = sizeof(red_stats); +unsigned struct_redparams_sz = sizeof(redparams); +unsigned struct_rf_pmparams_sz = sizeof(rf_pmparams); +unsigned struct_rf_pmstat_sz = sizeof(rf_pmstat); +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); +unsigned struct_scbusioscan_args_sz = sizeof(scbusioscan_args); +unsigned struct_scsi_addr_sz = sizeof(scsi_addr); +unsigned struct_seq_event_rec_sz = sizeof(seq_event_rec); +unsigned struct_session_op_sz = sizeof(session_op); +unsigned struct_sgttyb_sz = sizeof(sgttyb); +unsigned struct_sioc_sg_req_sz = sizeof(sioc_sg_req); +unsigned struct_sioc_vif_req_sz = sizeof(sioc_vif_req); +unsigned struct_smbioc_flags_sz = sizeof(smbioc_flags); +unsigned struct_smbioc_lookup_sz = sizeof(smbioc_lookup); +unsigned struct_smbioc_oshare_sz = sizeof(smbioc_oshare); +unsigned struct_smbioc_ossn_sz = sizeof(smbioc_ossn); +unsigned struct_smbioc_rq_sz = sizeof(smbioc_rq); +unsigned struct_smbioc_rw_sz = sizeof(smbioc_rw); +unsigned struct_spppauthcfg_sz = sizeof(spppauthcfg); +unsigned struct_spppauthfailuresettings_sz = sizeof(spppauthfailuresettings); +unsigned struct_spppauthfailurestats_sz = sizeof(spppauthfailurestats); +unsigned struct_spppdnsaddrs_sz = sizeof(spppdnsaddrs); +unsigned struct_spppdnssettings_sz = sizeof(spppdnssettings); +unsigned struct_spppidletimeout_sz = sizeof(spppidletimeout); +unsigned struct_spppkeepalivesettings_sz = sizeof(spppkeepalivesettings); +unsigned struct_sppplcpcfg_sz = sizeof(sppplcpcfg); +unsigned struct_spppstatus_sz = sizeof(spppstatus); +unsigned struct_spppstatusncp_sz = sizeof(spppstatusncp); +unsigned struct_srt_rt_sz = sizeof(srt_rt); +unsigned struct_stic_xinfo_sz = sizeof(stic_xinfo); +unsigned struct_sun_dkctlr_sz = sizeof(sun_dkctlr); +unsigned struct_sun_dkgeom_sz = sizeof(sun_dkgeom); +unsigned struct_sun_dkpart_sz = sizeof(sun_dkpart); +unsigned struct_synth_info_sz = sizeof(synth_info); +unsigned struct_tbrreq_sz = sizeof(tbrreq); +unsigned struct_tchars_sz = sizeof(tchars); +unsigned struct_termios_sz = sizeof(termios); +unsigned struct_timeval_sz = sizeof(timeval); +unsigned struct_twe_drivecommand_sz = sizeof(twe_drivecommand); +unsigned struct_twe_paramcommand_sz = sizeof(twe_paramcommand); +unsigned struct_twe_usercommand_sz = sizeof(twe_usercommand); +unsigned struct_ukyopon_identify_sz = sizeof(ukyopon_identify); +unsigned struct_urio_command_sz = sizeof(urio_command); +unsigned struct_usb_alt_interface_sz = sizeof(usb_alt_interface); +unsigned struct_usb_bulk_ra_wb_opt_sz = sizeof(usb_bulk_ra_wb_opt); +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); +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); +unsigned struct_usb_endpoint_desc_sz = sizeof(usb_endpoint_desc); +unsigned struct_usb_full_desc_sz = sizeof(usb_full_desc); +unsigned struct_usb_interface_desc_sz = sizeof(usb_interface_desc); +unsigned struct_usb_string_desc_sz = sizeof(usb_string_desc); +unsigned struct_utoppy_readfile_sz = sizeof(utoppy_readfile); +unsigned struct_utoppy_rename_sz = sizeof(utoppy_rename); +unsigned struct_utoppy_stats_sz = sizeof(utoppy_stats); +unsigned struct_utoppy_writefile_sz = sizeof(utoppy_writefile); +unsigned struct_v4l2_audio_sz = sizeof(v4l2_audio); +unsigned struct_v4l2_audioout_sz = sizeof(v4l2_audioout); +unsigned struct_v4l2_buffer_sz = sizeof(v4l2_buffer); +unsigned struct_v4l2_capability_sz = sizeof(v4l2_capability); +unsigned struct_v4l2_control_sz = sizeof(v4l2_control); +unsigned struct_v4l2_crop_sz = sizeof(v4l2_crop); +unsigned struct_v4l2_cropcap_sz = sizeof(v4l2_cropcap); +unsigned struct_v4l2_fmtdesc_sz = sizeof(v4l2_fmtdesc); +unsigned struct_v4l2_format_sz = sizeof(v4l2_format); +unsigned struct_v4l2_framebuffer_sz = sizeof(v4l2_framebuffer); +unsigned struct_v4l2_frequency_sz = sizeof(v4l2_frequency); +unsigned struct_v4l2_frmivalenum_sz = sizeof(v4l2_frmivalenum); +unsigned struct_v4l2_frmsizeenum_sz = sizeof(v4l2_frmsizeenum); +unsigned struct_v4l2_input_sz = sizeof(v4l2_input); +unsigned struct_v4l2_jpegcompression_sz = sizeof(v4l2_jpegcompression); +unsigned struct_v4l2_modulator_sz = sizeof(v4l2_modulator); +unsigned struct_v4l2_output_sz = sizeof(v4l2_output); +unsigned struct_v4l2_queryctrl_sz = sizeof(v4l2_queryctrl); +unsigned struct_v4l2_querymenu_sz = sizeof(v4l2_querymenu); +unsigned struct_v4l2_requestbuffers_sz = sizeof(v4l2_requestbuffers); +unsigned struct_v4l2_standard_sz = sizeof(v4l2_standard); +unsigned struct_v4l2_streamparm_sz = sizeof(v4l2_streamparm); +unsigned struct_v4l2_tuner_sz = sizeof(v4l2_tuner); +unsigned struct_vnd_ioctl_sz = sizeof(vnd_ioctl); +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_wfq_conf_sz = sizeof(wfq_conf); +unsigned struct_wfq_getqid_sz = sizeof(wfq_getqid); +unsigned struct_wfq_getstats_sz = sizeof(wfq_getstats); +unsigned struct_wfq_interface_sz = sizeof(wfq_interface); +unsigned struct_wfq_setweight_sz = sizeof(wfq_setweight); +unsigned struct_winsize_sz = sizeof(winsize); +unsigned struct_wscons_event_sz = sizeof(wscons_event); +unsigned struct_wsdisplay_addscreendata_sz = sizeof(wsdisplay_addscreendata); +unsigned struct_wsdisplay_char_sz = sizeof(wsdisplay_char); +unsigned struct_wsdisplay_cmap_sz = sizeof(wsdisplay_cmap); +unsigned struct_wsdisplay_curpos_sz = sizeof(wsdisplay_curpos); +unsigned struct_wsdisplay_cursor_sz = sizeof(wsdisplay_cursor); +unsigned struct_wsdisplay_delscreendata_sz = sizeof(wsdisplay_delscreendata); +unsigned struct_wsdisplay_fbinfo_sz = sizeof(wsdisplay_fbinfo); +unsigned struct_wsdisplay_font_sz = sizeof(wsdisplay_font); +unsigned struct_wsdisplay_kbddata_sz = sizeof(wsdisplay_kbddata); +unsigned struct_wsdisplay_msgattrs_sz = sizeof(wsdisplay_msgattrs); +unsigned struct_wsdisplay_param_sz = sizeof(wsdisplay_param); +unsigned struct_wsdisplay_scroll_data_sz = sizeof(wsdisplay_scroll_data); +unsigned struct_wsdisplay_usefontdata_sz = sizeof(wsdisplay_usefontdata); +unsigned struct_wsdisplayio_blit_sz = sizeof(wsdisplayio_blit); +unsigned struct_wsdisplayio_bus_id_sz = sizeof(wsdisplayio_bus_id); +unsigned struct_wsdisplayio_edid_info_sz = sizeof(wsdisplayio_edid_info); +unsigned struct_wsdisplayio_fbinfo_sz = sizeof(wsdisplayio_fbinfo); +unsigned struct_wskbd_bell_data_sz = sizeof(wskbd_bell_data); +unsigned struct_wskbd_keyrepeat_data_sz = sizeof(wskbd_keyrepeat_data); +unsigned struct_wskbd_map_data_sz = sizeof(wskbd_map_data); +unsigned struct_wskbd_scroll_data_sz = sizeof(wskbd_scroll_data); +unsigned struct_wsmouse_calibcoords_sz = sizeof(wsmouse_calibcoords); +unsigned struct_wsmouse_id_sz = sizeof(wsmouse_id); +unsigned struct_wsmouse_repeat_sz = sizeof(wsmouse_repeat); +unsigned struct_wsmux_device_list_sz = sizeof(wsmux_device_list); +unsigned struct_wsmux_device_sz = sizeof(wsmux_device); +unsigned struct_xd_iocmd_sz = sizeof(xd_iocmd); + +unsigned struct_scsireq_sz = sizeof(struct scsireq); +unsigned struct_tone_sz = sizeof(tone_t); +unsigned union_twe_statrequest_sz = sizeof(union twe_statrequest); +unsigned struct_usb_device_descriptor_sz = sizeof(usb_device_descriptor_t); +unsigned struct_vt_mode_sz = sizeof(struct vt_mode); +unsigned struct__old_mixer_info_sz = sizeof(struct _old_mixer_info); +unsigned struct__agp_allocate_sz = sizeof(struct _agp_allocate); +unsigned struct__agp_bind_sz = sizeof(struct _agp_bind); +unsigned struct__agp_info_sz = sizeof(struct _agp_info); +unsigned struct__agp_setup_sz = sizeof(struct _agp_setup); +unsigned struct__agp_unbind_sz = sizeof(struct _agp_unbind); +unsigned struct_atareq_sz = sizeof(struct atareq); +unsigned struct_cpustate_sz = sizeof(struct cpustate); +unsigned struct_dmx_caps_sz = sizeof(struct dmx_caps); +unsigned enum_dmx_source_sz = sizeof(dmx_source_t); +unsigned union_dvd_authinfo_sz = sizeof(dvd_authinfo); +unsigned union_dvd_struct_sz = sizeof(dvd_struct); +unsigned enum_v4l2_priority_sz = sizeof(enum v4l2_priority); +unsigned struct_envsys_basic_info_sz = sizeof(struct envsys_basic_info); +unsigned struct_envsys_tre_data_sz = sizeof(struct envsys_tre_data); +unsigned enum_fe_sec_mini_cmd_sz = sizeof(enum fe_sec_mini_cmd); +unsigned enum_fe_sec_tone_mode_sz = sizeof(enum fe_sec_tone_mode); +unsigned enum_fe_sec_voltage_sz = sizeof(enum fe_sec_voltage); +unsigned enum_fe_status_sz = sizeof(enum fe_status); +unsigned struct_gdt_ctrt_sz = sizeof(struct gdt_ctrt); +unsigned struct_gdt_event_sz = sizeof(struct gdt_event); +unsigned struct_gdt_osv_sz = sizeof(struct gdt_osv); +unsigned struct_gdt_rescan_sz = sizeof(struct gdt_rescan); +unsigned struct_gdt_statist_sz = sizeof(struct gdt_statist); +unsigned struct_gdt_ucmd_sz = sizeof(struct gdt_ucmd); +unsigned struct_iscsi_conn_status_parameters_sz = + sizeof(iscsi_conn_status_parameters_t); +unsigned struct_iscsi_get_version_parameters_sz = + sizeof(iscsi_get_version_parameters_t); +unsigned struct_iscsi_iocommand_parameters_sz = + sizeof(iscsi_iocommand_parameters_t); +unsigned struct_iscsi_login_parameters_sz = sizeof(iscsi_login_parameters_t); +unsigned struct_iscsi_logout_parameters_sz = sizeof(iscsi_logout_parameters_t); +unsigned struct_iscsi_register_event_parameters_sz = + sizeof(iscsi_register_event_parameters_t); +unsigned struct_iscsi_remove_parameters_sz = sizeof(iscsi_remove_parameters_t); +unsigned struct_iscsi_send_targets_parameters_sz = + sizeof(iscsi_send_targets_parameters_t); +unsigned struct_iscsi_set_node_name_parameters_sz = + sizeof(iscsi_set_node_name_parameters_t); +unsigned struct_iscsi_wait_event_parameters_sz = + sizeof(iscsi_wait_event_parameters_t); +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_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); +unsigned struct_rndstat_sz = sizeof(rndstat_t); +unsigned struct_rndstat_name_sz = sizeof(rndstat_name_t); +unsigned struct_rndctl_sz = sizeof(rndctl_t); +unsigned struct_rnddata_sz = sizeof(rnddata_t); +unsigned struct_rndpoolstat_sz = sizeof(rndpoolstat_t); +unsigned struct_rndstat_est_sz = sizeof(rndstat_est_t); +unsigned struct_rndstat_est_name_sz = sizeof(rndstat_est_name_t); +unsigned struct_pps_params_sz = sizeof(pps_params_t); +unsigned struct_pps_info_sz = sizeof(pps_info_t); +unsigned struct_mixer_info_sz = sizeof(struct mixer_info); +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); const unsigned IOCTL_NOT_PRESENT = 0; -unsigned IOCTL_FIOASYNC = FIOASYNC; +unsigned IOCTL_AFM_ADDFMAP = AFM_ADDFMAP; +unsigned IOCTL_AFM_DELFMAP = AFM_DELFMAP; +unsigned IOCTL_AFM_CLEANFMAP = AFM_CLEANFMAP; +unsigned IOCTL_AFM_GETFMAP = AFM_GETFMAP; +unsigned IOCTL_ALTQGTYPE = ALTQGTYPE; +unsigned IOCTL_ALTQTBRSET = ALTQTBRSET; +unsigned IOCTL_ALTQTBRGET = ALTQTBRGET; +unsigned IOCTL_BLUE_IF_ATTACH = BLUE_IF_ATTACH; +unsigned IOCTL_BLUE_IF_DETACH = BLUE_IF_DETACH; +unsigned IOCTL_BLUE_ENABLE = BLUE_ENABLE; +unsigned IOCTL_BLUE_DISABLE = BLUE_DISABLE; +unsigned IOCTL_BLUE_CONFIG = BLUE_CONFIG; +unsigned IOCTL_BLUE_GETSTATS = BLUE_GETSTATS; +unsigned IOCTL_CBQ_IF_ATTACH = CBQ_IF_ATTACH; +unsigned IOCTL_CBQ_IF_DETACH = CBQ_IF_DETACH; +unsigned IOCTL_CBQ_ENABLE = CBQ_ENABLE; +unsigned IOCTL_CBQ_DISABLE = CBQ_DISABLE; +unsigned IOCTL_CBQ_CLEAR_HIERARCHY = CBQ_CLEAR_HIERARCHY; +unsigned IOCTL_CBQ_ADD_CLASS = CBQ_ADD_CLASS; +unsigned IOCTL_CBQ_DEL_CLASS = CBQ_DEL_CLASS; +unsigned IOCTL_CBQ_MODIFY_CLASS = CBQ_MODIFY_CLASS; +unsigned IOCTL_CBQ_ADD_FILTER = CBQ_ADD_FILTER; +unsigned IOCTL_CBQ_DEL_FILTER = CBQ_DEL_FILTER; +unsigned IOCTL_CBQ_GETSTATS = CBQ_GETSTATS; +unsigned IOCTL_CDNR_IF_ATTACH = CDNR_IF_ATTACH; +unsigned IOCTL_CDNR_IF_DETACH = CDNR_IF_DETACH; +unsigned IOCTL_CDNR_ENABLE = CDNR_ENABLE; +unsigned IOCTL_CDNR_DISABLE = CDNR_DISABLE; +unsigned IOCTL_CDNR_ADD_FILTER = CDNR_ADD_FILTER; +unsigned IOCTL_CDNR_DEL_FILTER = CDNR_DEL_FILTER; +unsigned IOCTL_CDNR_GETSTATS = CDNR_GETSTATS; +unsigned IOCTL_CDNR_ADD_ELEM = CDNR_ADD_ELEM; +unsigned IOCTL_CDNR_DEL_ELEM = CDNR_DEL_ELEM; +unsigned IOCTL_CDNR_ADD_TBM = CDNR_ADD_TBM; +unsigned IOCTL_CDNR_MOD_TBM = CDNR_MOD_TBM; +unsigned IOCTL_CDNR_TBM_STATS = CDNR_TBM_STATS; +unsigned IOCTL_CDNR_ADD_TCM = CDNR_ADD_TCM; +unsigned IOCTL_CDNR_MOD_TCM = CDNR_MOD_TCM; +unsigned IOCTL_CDNR_TCM_STATS = CDNR_TCM_STATS; +unsigned IOCTL_CDNR_ADD_TSW = CDNR_ADD_TSW; +unsigned IOCTL_CDNR_MOD_TSW = CDNR_MOD_TSW; +unsigned IOCTL_FIFOQ_IF_ATTACH = FIFOQ_IF_ATTACH; +unsigned IOCTL_FIFOQ_IF_DETACH = FIFOQ_IF_DETACH; +unsigned IOCTL_FIFOQ_ENABLE = FIFOQ_ENABLE; +unsigned IOCTL_FIFOQ_DISABLE = FIFOQ_DISABLE; +unsigned IOCTL_FIFOQ_CONFIG = FIFOQ_CONFIG; +unsigned IOCTL_FIFOQ_GETSTATS = FIFOQ_GETSTATS; +unsigned IOCTL_HFSC_IF_ATTACH = HFSC_IF_ATTACH; +unsigned IOCTL_HFSC_IF_DETACH = HFSC_IF_DETACH; +unsigned IOCTL_HFSC_ENABLE = HFSC_ENABLE; +unsigned IOCTL_HFSC_DISABLE = HFSC_DISABLE; +unsigned IOCTL_HFSC_CLEAR_HIERARCHY = HFSC_CLEAR_HIERARCHY; +unsigned IOCTL_HFSC_ADD_CLASS = HFSC_ADD_CLASS; +unsigned IOCTL_HFSC_DEL_CLASS = HFSC_DEL_CLASS; +unsigned IOCTL_HFSC_MOD_CLASS = HFSC_MOD_CLASS; +unsigned IOCTL_HFSC_ADD_FILTER = HFSC_ADD_FILTER; +unsigned IOCTL_HFSC_DEL_FILTER = HFSC_DEL_FILTER; +unsigned IOCTL_HFSC_GETSTATS = HFSC_GETSTATS; +unsigned IOCTL_JOBS_IF_ATTACH = JOBS_IF_ATTACH; +unsigned IOCTL_JOBS_IF_DETACH = JOBS_IF_DETACH; +unsigned IOCTL_JOBS_ENABLE = JOBS_ENABLE; +unsigned IOCTL_JOBS_DISABLE = JOBS_DISABLE; +unsigned IOCTL_JOBS_CLEAR = JOBS_CLEAR; +unsigned IOCTL_JOBS_ADD_CLASS = JOBS_ADD_CLASS; +unsigned IOCTL_JOBS_DEL_CLASS = JOBS_DEL_CLASS; +unsigned IOCTL_JOBS_MOD_CLASS = JOBS_MOD_CLASS; +unsigned IOCTL_JOBS_ADD_FILTER = JOBS_ADD_FILTER; +unsigned IOCTL_JOBS_DEL_FILTER = JOBS_DEL_FILTER; +unsigned IOCTL_JOBS_GETSTATS = JOBS_GETSTATS; +unsigned IOCTL_PRIQ_IF_ATTACH = PRIQ_IF_ATTACH; +unsigned IOCTL_PRIQ_IF_DETACH = PRIQ_IF_DETACH; +unsigned IOCTL_PRIQ_ENABLE = PRIQ_ENABLE; +unsigned IOCTL_PRIQ_DISABLE = PRIQ_DISABLE; +unsigned IOCTL_PRIQ_CLEAR = PRIQ_CLEAR; +unsigned IOCTL_PRIQ_ADD_CLASS = PRIQ_ADD_CLASS; +unsigned IOCTL_PRIQ_DEL_CLASS = PRIQ_DEL_CLASS; +unsigned IOCTL_PRIQ_MOD_CLASS = PRIQ_MOD_CLASS; +unsigned IOCTL_PRIQ_ADD_FILTER = PRIQ_ADD_FILTER; +unsigned IOCTL_PRIQ_DEL_FILTER = PRIQ_DEL_FILTER; +unsigned IOCTL_PRIQ_GETSTATS = PRIQ_GETSTATS; +unsigned IOCTL_RED_IF_ATTACH = RED_IF_ATTACH; +unsigned IOCTL_RED_IF_DETACH = RED_IF_DETACH; +unsigned IOCTL_RED_ENABLE = RED_ENABLE; +unsigned IOCTL_RED_DISABLE = RED_DISABLE; +unsigned IOCTL_RED_CONFIG = RED_CONFIG; +unsigned IOCTL_RED_GETSTATS = RED_GETSTATS; +unsigned IOCTL_RED_SETDEFAULTS = RED_SETDEFAULTS; +unsigned IOCTL_RIO_IF_ATTACH = RIO_IF_ATTACH; +unsigned IOCTL_RIO_IF_DETACH = RIO_IF_DETACH; +unsigned IOCTL_RIO_ENABLE = RIO_ENABLE; +unsigned IOCTL_RIO_DISABLE = RIO_DISABLE; +unsigned IOCTL_RIO_CONFIG = RIO_CONFIG; +unsigned IOCTL_RIO_GETSTATS = RIO_GETSTATS; +unsigned IOCTL_RIO_SETDEFAULTS = RIO_SETDEFAULTS; +unsigned IOCTL_WFQ_IF_ATTACH = WFQ_IF_ATTACH; +unsigned IOCTL_WFQ_IF_DETACH = WFQ_IF_DETACH; +unsigned IOCTL_WFQ_ENABLE = WFQ_ENABLE; +unsigned IOCTL_WFQ_DISABLE = WFQ_DISABLE; +unsigned IOCTL_WFQ_CONFIG = WFQ_CONFIG; +unsigned IOCTL_WFQ_GET_STATS = WFQ_GET_STATS; +unsigned IOCTL_WFQ_GET_QID = WFQ_GET_QID; +unsigned IOCTL_WFQ_SET_WEIGHT = WFQ_SET_WEIGHT; +unsigned IOCTL_CRIOGET = CRIOGET; +unsigned IOCTL_CIOCFSESSION = CIOCFSESSION; +unsigned IOCTL_CIOCKEY = CIOCKEY; +unsigned IOCTL_CIOCNFKEYM = CIOCNFKEYM; +unsigned IOCTL_CIOCNFSESSION = CIOCNFSESSION; +unsigned IOCTL_CIOCNCRYPTRETM = CIOCNCRYPTRETM; +unsigned IOCTL_CIOCNCRYPTRET = CIOCNCRYPTRET; +unsigned IOCTL_CIOCGSESSION = CIOCGSESSION; +unsigned IOCTL_CIOCNGSESSION = CIOCNGSESSION; +unsigned IOCTL_CIOCCRYPT = CIOCCRYPT; +unsigned IOCTL_CIOCNCRYPTM = CIOCNCRYPTM; +unsigned IOCTL_CIOCASYMFEAT = CIOCASYMFEAT; +unsigned IOCTL_APM_IOC_REJECT = APM_IOC_REJECT; +unsigned IOCTL_APM_IOC_STANDBY = APM_IOC_STANDBY; +unsigned IOCTL_APM_IOC_SUSPEND = APM_IOC_SUSPEND; +unsigned IOCTL_OAPM_IOC_GETPOWER = OAPM_IOC_GETPOWER; +unsigned IOCTL_APM_IOC_GETPOWER = APM_IOC_GETPOWER; +unsigned IOCTL_APM_IOC_NEXTEVENT = APM_IOC_NEXTEVENT; +unsigned IOCTL_APM_IOC_DEV_CTL = APM_IOC_DEV_CTL; +unsigned IOCTL_NETBSD_DM_IOCTL = NETBSD_DM_IOCTL; +unsigned IOCTL_DMIO_SETFUNC = DMIO_SETFUNC; +unsigned IOCTL_DMX_START = DMX_START; +unsigned IOCTL_DMX_STOP = DMX_STOP; +unsigned IOCTL_DMX_SET_FILTER = DMX_SET_FILTER; +unsigned IOCTL_DMX_SET_PES_FILTER = DMX_SET_PES_FILTER; +unsigned IOCTL_DMX_SET_BUFFER_SIZE = DMX_SET_BUFFER_SIZE; +unsigned IOCTL_DMX_GET_STC = DMX_GET_STC; +unsigned IOCTL_DMX_ADD_PID = DMX_ADD_PID; +unsigned IOCTL_DMX_REMOVE_PID = DMX_REMOVE_PID; +unsigned IOCTL_DMX_GET_CAPS = DMX_GET_CAPS; +unsigned IOCTL_DMX_SET_SOURCE = DMX_SET_SOURCE; +unsigned IOCTL_FE_READ_STATUS = FE_READ_STATUS; +unsigned IOCTL_FE_READ_BER = FE_READ_BER; +unsigned IOCTL_FE_READ_SNR = FE_READ_SNR; +unsigned IOCTL_FE_READ_SIGNAL_STRENGTH = FE_READ_SIGNAL_STRENGTH; +unsigned IOCTL_FE_READ_UNCORRECTED_BLOCKS = FE_READ_UNCORRECTED_BLOCKS; +unsigned IOCTL_FE_SET_FRONTEND = FE_SET_FRONTEND; +unsigned IOCTL_FE_GET_FRONTEND = FE_GET_FRONTEND; +unsigned IOCTL_FE_GET_EVENT = FE_GET_EVENT; +unsigned IOCTL_FE_GET_INFO = FE_GET_INFO; +unsigned IOCTL_FE_DISEQC_RESET_OVERLOAD = FE_DISEQC_RESET_OVERLOAD; +unsigned IOCTL_FE_DISEQC_SEND_MASTER_CMD = FE_DISEQC_SEND_MASTER_CMD; +unsigned IOCTL_FE_DISEQC_RECV_SLAVE_REPLY = FE_DISEQC_RECV_SLAVE_REPLY; +unsigned IOCTL_FE_DISEQC_SEND_BURST = FE_DISEQC_SEND_BURST; +unsigned IOCTL_FE_SET_TONE = FE_SET_TONE; +unsigned IOCTL_FE_SET_VOLTAGE = FE_SET_VOLTAGE; +unsigned IOCTL_FE_ENABLE_HIGH_LNB_VOLTAGE = FE_ENABLE_HIGH_LNB_VOLTAGE; +unsigned IOCTL_FE_SET_FRONTEND_TUNE_MODE = FE_SET_FRONTEND_TUNE_MODE; +unsigned IOCTL_FE_DISHNETWORK_SEND_LEGACY_CMD = FE_DISHNETWORK_SEND_LEGACY_CMD; +unsigned IOCTL_FILEMON_SET_FD = FILEMON_SET_FD; +unsigned IOCTL_FILEMON_SET_PID = FILEMON_SET_PID; +unsigned IOCTL_HDAUDIO_FGRP_INFO = HDAUDIO_FGRP_INFO; +unsigned IOCTL_HDAUDIO_FGRP_GETCONFIG = HDAUDIO_FGRP_GETCONFIG; +unsigned IOCTL_HDAUDIO_FGRP_SETCONFIG = HDAUDIO_FGRP_SETCONFIG; +unsigned IOCTL_HDAUDIO_FGRP_WIDGET_INFO = HDAUDIO_FGRP_WIDGET_INFO; +unsigned IOCTL_HDAUDIO_FGRP_CODEC_INFO = HDAUDIO_FGRP_CODEC_INFO; +unsigned IOCTL_HDAUDIO_AFG_WIDGET_INFO = HDAUDIO_AFG_WIDGET_INFO; +unsigned IOCTL_HDAUDIO_AFG_CODEC_INFO = HDAUDIO_AFG_CODEC_INFO; +unsigned IOCTL_CEC_GET_PHYS_ADDR = CEC_GET_PHYS_ADDR; +unsigned IOCTL_CEC_GET_LOG_ADDRS = CEC_GET_LOG_ADDRS; +unsigned IOCTL_CEC_SET_LOG_ADDRS = CEC_SET_LOG_ADDRS; +unsigned IOCTL_CEC_GET_VENDOR_ID = CEC_GET_VENDOR_ID; +unsigned IOCTL_HPCFBIO_GCONF = HPCFBIO_GCONF; +unsigned IOCTL_HPCFBIO_SCONF = HPCFBIO_SCONF; +unsigned IOCTL_HPCFBIO_GDSPCONF = HPCFBIO_GDSPCONF; +unsigned IOCTL_HPCFBIO_SDSPCONF = HPCFBIO_SDSPCONF; +unsigned IOCTL_HPCFBIO_GOP = HPCFBIO_GOP; +unsigned IOCTL_HPCFBIO_SOP = HPCFBIO_SOP; +unsigned IOCTL_IOPIOCPT = IOPIOCPT; +unsigned IOCTL_IOPIOCGLCT = IOPIOCGLCT; +unsigned IOCTL_IOPIOCGSTATUS = IOPIOCGSTATUS; +unsigned IOCTL_IOPIOCRECONFIG = IOPIOCRECONFIG; +unsigned IOCTL_IOPIOCGTIDMAP = IOPIOCGTIDMAP; +unsigned IOCTL_SIOCGATHSTATS = SIOCGATHSTATS; +unsigned IOCTL_SIOCGATHDIAG = SIOCGATHDIAG; +unsigned IOCTL_METEORCAPTUR = METEORCAPTUR; +unsigned IOCTL_METEORCAPFRM = METEORCAPFRM; +unsigned IOCTL_METEORSETGEO = METEORSETGEO; +unsigned IOCTL_METEORGETGEO = METEORGETGEO; +unsigned IOCTL_METEORSTATUS = METEORSTATUS; +unsigned IOCTL_METEORSHUE = METEORSHUE; +unsigned IOCTL_METEORGHUE = METEORGHUE; +unsigned IOCTL_METEORSFMT = METEORSFMT; +unsigned IOCTL_METEORGFMT = METEORGFMT; +unsigned IOCTL_METEORSINPUT = METEORSINPUT; +unsigned IOCTL_METEORGINPUT = METEORGINPUT; +unsigned IOCTL_METEORSCHCV = METEORSCHCV; +unsigned IOCTL_METEORGCHCV = METEORGCHCV; +unsigned IOCTL_METEORSCOUNT = METEORSCOUNT; +unsigned IOCTL_METEORGCOUNT = METEORGCOUNT; +unsigned IOCTL_METEORSFPS = METEORSFPS; +unsigned IOCTL_METEORGFPS = METEORGFPS; +unsigned IOCTL_METEORSSIGNAL = METEORSSIGNAL; +unsigned IOCTL_METEORGSIGNAL = METEORGSIGNAL; +unsigned IOCTL_METEORSVIDEO = METEORSVIDEO; +unsigned IOCTL_METEORGVIDEO = METEORGVIDEO; +unsigned IOCTL_METEORSBRIG = METEORSBRIG; +unsigned IOCTL_METEORGBRIG = METEORGBRIG; +unsigned IOCTL_METEORSCSAT = METEORSCSAT; +unsigned IOCTL_METEORGCSAT = METEORGCSAT; +unsigned IOCTL_METEORSCONT = METEORSCONT; +unsigned IOCTL_METEORGCONT = METEORGCONT; +unsigned IOCTL_METEORSHWS = METEORSHWS; +unsigned IOCTL_METEORGHWS = METEORGHWS; +unsigned IOCTL_METEORSVWS = METEORSVWS; +unsigned IOCTL_METEORGVWS = METEORGVWS; +unsigned IOCTL_METEORSTS = METEORSTS; +unsigned IOCTL_METEORGTS = METEORGTS; +unsigned IOCTL_TVTUNER_SETCHNL = TVTUNER_SETCHNL; +unsigned IOCTL_TVTUNER_GETCHNL = TVTUNER_GETCHNL; +unsigned IOCTL_TVTUNER_SETTYPE = TVTUNER_SETTYPE; +unsigned IOCTL_TVTUNER_GETTYPE = TVTUNER_GETTYPE; +unsigned IOCTL_TVTUNER_GETSTATUS = TVTUNER_GETSTATUS; +unsigned IOCTL_TVTUNER_SETFREQ = TVTUNER_SETFREQ; +unsigned IOCTL_TVTUNER_GETFREQ = TVTUNER_GETFREQ; +unsigned IOCTL_TVTUNER_SETAFC = TVTUNER_SETAFC; +unsigned IOCTL_TVTUNER_GETAFC = TVTUNER_GETAFC; +unsigned IOCTL_RADIO_SETMODE = RADIO_SETMODE; +unsigned IOCTL_RADIO_GETMODE = RADIO_GETMODE; +unsigned IOCTL_RADIO_SETFREQ = RADIO_SETFREQ; +unsigned IOCTL_RADIO_GETFREQ = RADIO_GETFREQ; +unsigned IOCTL_METEORSACTPIXFMT = METEORSACTPIXFMT; +unsigned IOCTL_METEORGACTPIXFMT = METEORGACTPIXFMT; +unsigned IOCTL_METEORGSUPPIXFMT = METEORGSUPPIXFMT; +unsigned IOCTL_TVTUNER_GETCHNLSET = TVTUNER_GETCHNLSET; +unsigned IOCTL_REMOTE_GETKEY = REMOTE_GETKEY; +unsigned IOCTL_GDT_IOCTL_GENERAL = GDT_IOCTL_GENERAL; +unsigned IOCTL_GDT_IOCTL_DRVERS = GDT_IOCTL_DRVERS; +unsigned IOCTL_GDT_IOCTL_CTRTYPE = GDT_IOCTL_CTRTYPE; +unsigned IOCTL_GDT_IOCTL_OSVERS = GDT_IOCTL_OSVERS; +unsigned IOCTL_GDT_IOCTL_CTRCNT = GDT_IOCTL_CTRCNT; +unsigned IOCTL_GDT_IOCTL_EVENT = GDT_IOCTL_EVENT; +unsigned IOCTL_GDT_IOCTL_STATIST = GDT_IOCTL_STATIST; +unsigned IOCTL_GDT_IOCTL_RESCAN = GDT_IOCTL_RESCAN; +unsigned IOCTL_ISP_SDBLEV = ISP_SDBLEV; +unsigned IOCTL_ISP_RESETHBA = ISP_RESETHBA; +unsigned IOCTL_ISP_RESCAN = ISP_RESCAN; +unsigned IOCTL_ISP_SETROLE = ISP_SETROLE; +unsigned IOCTL_ISP_GETROLE = ISP_GETROLE; +unsigned IOCTL_ISP_GET_STATS = ISP_GET_STATS; +unsigned IOCTL_ISP_CLR_STATS = ISP_CLR_STATS; +unsigned IOCTL_ISP_FC_LIP = ISP_FC_LIP; +unsigned IOCTL_ISP_FC_GETDINFO = ISP_FC_GETDINFO; +unsigned IOCTL_ISP_GET_FW_CRASH_DUMP = ISP_GET_FW_CRASH_DUMP; +unsigned IOCTL_ISP_FORCE_CRASH_DUMP = ISP_FORCE_CRASH_DUMP; +unsigned IOCTL_ISP_FC_GETHINFO = ISP_FC_GETHINFO; +unsigned IOCTL_ISP_TSK_MGMT = ISP_TSK_MGMT; +unsigned IOCTL_ISP_FC_GETDLIST = ISP_FC_GETDLIST; +unsigned IOCTL_MLXD_STATUS = MLXD_STATUS; +unsigned IOCTL_MLXD_CHECKASYNC = MLXD_CHECKASYNC; +unsigned IOCTL_MLXD_DETACH = MLXD_DETACH; +unsigned IOCTL_MLX_RESCAN_DRIVES = MLX_RESCAN_DRIVES; +unsigned IOCTL_MLX_PAUSE_CHANNEL = MLX_PAUSE_CHANNEL; +unsigned IOCTL_MLX_COMMAND = MLX_COMMAND; +unsigned IOCTL_MLX_REBUILDASYNC = MLX_REBUILDASYNC; +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_IRDA_RESET_PARAMS = IRDA_RESET_PARAMS; +unsigned IOCTL_IRDA_SET_PARAMS = IRDA_SET_PARAMS; +unsigned IOCTL_IRDA_GET_SPEEDMASK = IRDA_GET_SPEEDMASK; +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; +unsigned IOCTL_ISCSI_LOGIN = ISCSI_LOGIN; +unsigned IOCTL_ISCSI_LOGOUT = ISCSI_LOGOUT; +unsigned IOCTL_ISCSI_ADD_CONNECTION = ISCSI_ADD_CONNECTION; +unsigned IOCTL_ISCSI_RESTORE_CONNECTION = ISCSI_RESTORE_CONNECTION; +unsigned IOCTL_ISCSI_REMOVE_CONNECTION = ISCSI_REMOVE_CONNECTION; +unsigned IOCTL_ISCSI_CONNECTION_STATUS = ISCSI_CONNECTION_STATUS; +unsigned IOCTL_ISCSI_SEND_TARGETS = ISCSI_SEND_TARGETS; +unsigned IOCTL_ISCSI_SET_NODE_NAME = ISCSI_SET_NODE_NAME; +unsigned IOCTL_ISCSI_IO_COMMAND = ISCSI_IO_COMMAND; +unsigned IOCTL_ISCSI_REGISTER_EVENT = ISCSI_REGISTER_EVENT; +unsigned IOCTL_ISCSI_DEREGISTER_EVENT = ISCSI_DEREGISTER_EVENT; +unsigned IOCTL_ISCSI_WAIT_EVENT = ISCSI_WAIT_EVENT; +unsigned IOCTL_ISCSI_POLL_EVENT = ISCSI_POLL_EVENT; +unsigned IOCTL_OFIOCGET = OFIOCGET; +unsigned IOCTL_OFIOCSET = OFIOCSET; +unsigned IOCTL_OFIOCNEXTPROP = OFIOCNEXTPROP; +unsigned IOCTL_OFIOCGETOPTNODE = OFIOCGETOPTNODE; +unsigned IOCTL_OFIOCGETNEXT = OFIOCGETNEXT; +unsigned IOCTL_OFIOCGETCHILD = OFIOCGETCHILD; +unsigned IOCTL_OFIOCFINDDEVICE = OFIOCFINDDEVICE; +unsigned IOCTL_AMR_IO_VERSION = AMR_IO_VERSION; +unsigned IOCTL_AMR_IO_COMMAND = AMR_IO_COMMAND; +unsigned IOCTL_MLYIO_COMMAND = MLYIO_COMMAND; +unsigned IOCTL_MLYIO_HEALTH = MLYIO_HEALTH; +unsigned IOCTL_PCI_IOC_CFGREAD = PCI_IOC_CFGREAD; +unsigned IOCTL_PCI_IOC_CFGWRITE = PCI_IOC_CFGWRITE; +unsigned IOCTL_PCI_IOC_BDF_CFGREAD = PCI_IOC_BDF_CFGREAD; +unsigned IOCTL_PCI_IOC_BDF_CFGWRITE = PCI_IOC_BDF_CFGWRITE; +unsigned IOCTL_PCI_IOC_BUSINFO = PCI_IOC_BUSINFO; +unsigned IOCTL_PCI_IOC_DRVNAME = PCI_IOC_DRVNAME; +unsigned IOCTL_PCI_IOC_DRVNAMEONBUS = PCI_IOC_DRVNAMEONBUS; +unsigned IOCTL_TWEIO_COMMAND = TWEIO_COMMAND; +unsigned IOCTL_TWEIO_STATS = TWEIO_STATS; +unsigned IOCTL_TWEIO_AEN_POLL = TWEIO_AEN_POLL; +unsigned IOCTL_TWEIO_AEN_WAIT = TWEIO_AEN_WAIT; +unsigned IOCTL_TWEIO_SET_PARAM = TWEIO_SET_PARAM; +unsigned IOCTL_TWEIO_GET_PARAM = TWEIO_GET_PARAM; +unsigned IOCTL_TWEIO_RESET = TWEIO_RESET; +unsigned IOCTL_TWEIO_ADD_UNIT = TWEIO_ADD_UNIT; +unsigned IOCTL_TWEIO_DEL_UNIT = TWEIO_DEL_UNIT; +unsigned IOCTL_SIOCSCNWDOMAIN = SIOCSCNWDOMAIN; +unsigned IOCTL_SIOCGCNWDOMAIN = SIOCGCNWDOMAIN; +unsigned IOCTL_SIOCSCNWKEY = SIOCSCNWKEY; +unsigned IOCTL_SIOCGCNWSTATUS = SIOCGCNWSTATUS; +unsigned IOCTL_SIOCGCNWSTATS = SIOCGCNWSTATS; +unsigned IOCTL_SIOCGCNWTRAIL = SIOCGCNWTRAIL; +unsigned IOCTL_SIOCGRAYSIGLEV = SIOCGRAYSIGLEV; +unsigned IOCTL_RAIDFRAME_SHUTDOWN = RAIDFRAME_SHUTDOWN; +unsigned IOCTL_RAIDFRAME_TUR = RAIDFRAME_TUR; +unsigned IOCTL_RAIDFRAME_FAIL_DISK = RAIDFRAME_FAIL_DISK; +unsigned IOCTL_RAIDFRAME_CHECK_RECON_STATUS = RAIDFRAME_CHECK_RECON_STATUS; +unsigned IOCTL_RAIDFRAME_REWRITEPARITY = RAIDFRAME_REWRITEPARITY; +unsigned IOCTL_RAIDFRAME_COPYBACK = RAIDFRAME_COPYBACK; +unsigned IOCTL_RAIDFRAME_SPARET_WAIT = RAIDFRAME_SPARET_WAIT; +unsigned IOCTL_RAIDFRAME_SEND_SPARET = RAIDFRAME_SEND_SPARET; +unsigned IOCTL_RAIDFRAME_ABORT_SPARET_WAIT = RAIDFRAME_ABORT_SPARET_WAIT; +unsigned IOCTL_RAIDFRAME_START_ATRACE = RAIDFRAME_START_ATRACE; +unsigned IOCTL_RAIDFRAME_STOP_ATRACE = RAIDFRAME_STOP_ATRACE; +unsigned IOCTL_RAIDFRAME_GET_SIZE = RAIDFRAME_GET_SIZE; +unsigned IOCTL_RAIDFRAME_RESET_ACCTOTALS = RAIDFRAME_RESET_ACCTOTALS; +unsigned IOCTL_RAIDFRAME_KEEP_ACCTOTALS = RAIDFRAME_KEEP_ACCTOTALS; +unsigned IOCTL_RAIDFRAME_GET_COMPONENT_LABEL = RAIDFRAME_GET_COMPONENT_LABEL; +unsigned IOCTL_RAIDFRAME_SET_COMPONENT_LABEL = RAIDFRAME_SET_COMPONENT_LABEL; +unsigned IOCTL_RAIDFRAME_INIT_LABELS = RAIDFRAME_INIT_LABELS; +unsigned IOCTL_RAIDFRAME_ADD_HOT_SPARE = RAIDFRAME_ADD_HOT_SPARE; +unsigned IOCTL_RAIDFRAME_REMOVE_HOT_SPARE = RAIDFRAME_REMOVE_HOT_SPARE; +unsigned IOCTL_RAIDFRAME_REBUILD_IN_PLACE = RAIDFRAME_REBUILD_IN_PLACE; +unsigned IOCTL_RAIDFRAME_CHECK_PARITY = RAIDFRAME_CHECK_PARITY; +unsigned IOCTL_RAIDFRAME_CHECK_PARITYREWRITE_STATUS = + RAIDFRAME_CHECK_PARITYREWRITE_STATUS; +unsigned IOCTL_RAIDFRAME_CHECK_COPYBACK_STATUS = + RAIDFRAME_CHECK_COPYBACK_STATUS; +unsigned IOCTL_RAIDFRAME_SET_AUTOCONFIG = RAIDFRAME_SET_AUTOCONFIG; +unsigned IOCTL_RAIDFRAME_SET_ROOT = RAIDFRAME_SET_ROOT; +unsigned IOCTL_RAIDFRAME_DELETE_COMPONENT = RAIDFRAME_DELETE_COMPONENT; +unsigned IOCTL_RAIDFRAME_INCORPORATE_HOT_SPARE = + RAIDFRAME_INCORPORATE_HOT_SPARE; +unsigned IOCTL_RAIDFRAME_CHECK_RECON_STATUS_EXT = + RAIDFRAME_CHECK_RECON_STATUS_EXT; +unsigned IOCTL_RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT = + RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT; +unsigned IOCTL_RAIDFRAME_CHECK_COPYBACK_STATUS_EXT = + RAIDFRAME_CHECK_COPYBACK_STATUS_EXT; +unsigned IOCTL_RAIDFRAME_CONFIGURE = RAIDFRAME_CONFIGURE; +unsigned IOCTL_RAIDFRAME_GET_INFO = RAIDFRAME_GET_INFO; +unsigned IOCTL_RAIDFRAME_PARITYMAP_STATUS = RAIDFRAME_PARITYMAP_STATUS; +unsigned IOCTL_RAIDFRAME_PARITYMAP_GET_DISABLE = + RAIDFRAME_PARITYMAP_GET_DISABLE; +unsigned IOCTL_RAIDFRAME_PARITYMAP_SET_DISABLE = + RAIDFRAME_PARITYMAP_SET_DISABLE; +unsigned IOCTL_RAIDFRAME_PARITYMAP_SET_PARAMS = RAIDFRAME_PARITYMAP_SET_PARAMS; +unsigned IOCTL_RAIDFRAME_SET_LAST_UNIT = RAIDFRAME_SET_LAST_UNIT; +unsigned IOCTL_MBPPIOCSPARAM = MBPPIOCSPARAM; +unsigned IOCTL_MBPPIOCGPARAM = MBPPIOCGPARAM; +unsigned IOCTL_MBPPIOCGSTAT = MBPPIOCGSTAT; +unsigned IOCTL_SESIOC_GETNOBJ = SESIOC_GETNOBJ; +unsigned IOCTL_SESIOC_GETOBJMAP = SESIOC_GETOBJMAP; +unsigned IOCTL_SESIOC_GETENCSTAT = SESIOC_GETENCSTAT; +unsigned IOCTL_SESIOC_SETENCSTAT = SESIOC_SETENCSTAT; +unsigned IOCTL_SESIOC_GETOBJSTAT = SESIOC_GETOBJSTAT; +unsigned IOCTL_SESIOC_SETOBJSTAT = SESIOC_SETOBJSTAT; +unsigned IOCTL_SESIOC_GETTEXT = SESIOC_GETTEXT; +unsigned IOCTL_SESIOC_INIT = SESIOC_INIT; +unsigned IOCTL_SUN_DKIOCGGEOM = SUN_DKIOCGGEOM; +unsigned IOCTL_SUN_DKIOCINFO = SUN_DKIOCINFO; +unsigned IOCTL_SUN_DKIOCGPART = SUN_DKIOCGPART; +unsigned IOCTL_FBIOGTYPE = FBIOGTYPE; +unsigned IOCTL_FBIOPUTCMAP = FBIOPUTCMAP; +unsigned IOCTL_FBIOGETCMAP = FBIOGETCMAP; +unsigned IOCTL_FBIOGATTR = FBIOGATTR; +unsigned IOCTL_FBIOSVIDEO = FBIOSVIDEO; +unsigned IOCTL_FBIOGVIDEO = FBIOGVIDEO; +unsigned IOCTL_FBIOSCURSOR = FBIOSCURSOR; +unsigned IOCTL_FBIOGCURSOR = FBIOGCURSOR; +unsigned IOCTL_FBIOSCURPOS = FBIOSCURPOS; +unsigned IOCTL_FBIOGCURPOS = FBIOGCURPOS; +unsigned IOCTL_FBIOGCURMAX = FBIOGCURMAX; +unsigned IOCTL_KIOCTRANS = KIOCTRANS; +unsigned IOCTL_KIOCSETKEY = KIOCSETKEY; +unsigned IOCTL_KIOCGETKEY = KIOCGETKEY; +unsigned IOCTL_KIOCGTRANS = KIOCGTRANS; +unsigned IOCTL_KIOCCMD = KIOCCMD; +unsigned IOCTL_KIOCTYPE = KIOCTYPE; +unsigned IOCTL_KIOCSDIRECT = KIOCSDIRECT; +unsigned IOCTL_KIOCSKEY = KIOCSKEY; +unsigned IOCTL_KIOCGKEY = KIOCGKEY; +unsigned IOCTL_KIOCSLED = KIOCSLED; +unsigned IOCTL_KIOCGLED = KIOCGLED; +unsigned IOCTL_KIOCLAYOUT = KIOCLAYOUT; +unsigned IOCTL_VUIDSFORMAT = VUIDSFORMAT; +unsigned IOCTL_VUIDGFORMAT = VUIDGFORMAT; +unsigned IOCTL_STICIO_GXINFO = STICIO_GXINFO; +unsigned IOCTL_STICIO_RESET = STICIO_RESET; +unsigned IOCTL_STICIO_STARTQ = STICIO_STARTQ; +unsigned IOCTL_STICIO_STOPQ = STICIO_STOPQ; +unsigned IOCTL_UKYOPON_IDENTIFY = UKYOPON_IDENTIFY; +unsigned IOCTL_URIO_SEND_COMMAND = URIO_SEND_COMMAND; +unsigned IOCTL_URIO_RECV_COMMAND = URIO_RECV_COMMAND; +unsigned IOCTL_USB_REQUEST = USB_REQUEST; +unsigned IOCTL_USB_SETDEBUG = USB_SETDEBUG; +unsigned IOCTL_USB_DISCOVER = USB_DISCOVER; +unsigned IOCTL_USB_DEVICEINFO = USB_DEVICEINFO; +unsigned IOCTL_USB_DEVICEINFO_OLD = USB_DEVICEINFO_OLD; +unsigned IOCTL_USB_DEVICESTATS = USB_DEVICESTATS; +unsigned IOCTL_USB_GET_REPORT_DESC = USB_GET_REPORT_DESC; +unsigned IOCTL_USB_SET_IMMED = USB_SET_IMMED; +unsigned IOCTL_USB_GET_REPORT = USB_GET_REPORT; +unsigned IOCTL_USB_SET_REPORT = USB_SET_REPORT; +unsigned IOCTL_USB_GET_REPORT_ID = USB_GET_REPORT_ID; +unsigned IOCTL_USB_GET_CONFIG = USB_GET_CONFIG; +unsigned IOCTL_USB_SET_CONFIG = USB_SET_CONFIG; +unsigned IOCTL_USB_GET_ALTINTERFACE = USB_GET_ALTINTERFACE; +unsigned IOCTL_USB_SET_ALTINTERFACE = USB_SET_ALTINTERFACE; +unsigned IOCTL_USB_GET_NO_ALT = USB_GET_NO_ALT; +unsigned IOCTL_USB_GET_DEVICE_DESC = USB_GET_DEVICE_DESC; +unsigned IOCTL_USB_GET_CONFIG_DESC = USB_GET_CONFIG_DESC; +unsigned IOCTL_USB_GET_INTERFACE_DESC = USB_GET_INTERFACE_DESC; +unsigned IOCTL_USB_GET_ENDPOINT_DESC = USB_GET_ENDPOINT_DESC; +unsigned IOCTL_USB_GET_FULL_DESC = USB_GET_FULL_DESC; +unsigned IOCTL_USB_GET_STRING_DESC = USB_GET_STRING_DESC; +unsigned IOCTL_USB_DO_REQUEST = USB_DO_REQUEST; +unsigned IOCTL_USB_GET_DEVICEINFO = USB_GET_DEVICEINFO; +unsigned IOCTL_USB_GET_DEVICEINFO_OLD = USB_GET_DEVICEINFO_OLD; +unsigned IOCTL_USB_SET_SHORT_XFER = USB_SET_SHORT_XFER; +unsigned IOCTL_USB_SET_TIMEOUT = USB_SET_TIMEOUT; +unsigned IOCTL_USB_SET_BULK_RA = USB_SET_BULK_RA; +unsigned IOCTL_USB_SET_BULK_WB = USB_SET_BULK_WB; +unsigned IOCTL_USB_SET_BULK_RA_OPT = USB_SET_BULK_RA_OPT; +unsigned IOCTL_USB_SET_BULK_WB_OPT = USB_SET_BULK_WB_OPT; +unsigned IOCTL_USB_GET_CM_OVER_DATA = USB_GET_CM_OVER_DATA; +unsigned IOCTL_USB_SET_CM_OVER_DATA = USB_SET_CM_OVER_DATA; +unsigned IOCTL_UTOPPYIOTURBO = UTOPPYIOTURBO; +unsigned IOCTL_UTOPPYIOCANCEL = UTOPPYIOCANCEL; +unsigned IOCTL_UTOPPYIOREBOOT = UTOPPYIOREBOOT; +unsigned IOCTL_UTOPPYIOSTATS = UTOPPYIOSTATS; +unsigned IOCTL_UTOPPYIORENAME = UTOPPYIORENAME; +unsigned IOCTL_UTOPPYIOMKDIR = UTOPPYIOMKDIR; +unsigned IOCTL_UTOPPYIODELETE = UTOPPYIODELETE; +unsigned IOCTL_UTOPPYIOREADDIR = UTOPPYIOREADDIR; +unsigned IOCTL_UTOPPYIOREADFILE = UTOPPYIOREADFILE; +unsigned IOCTL_UTOPPYIOWRITEFILE = UTOPPYIOWRITEFILE; +unsigned IOCTL_DIOSXDCMD = DIOSXDCMD; +unsigned IOCTL_VT_OPENQRY = VT_OPENQRY; +unsigned IOCTL_VT_SETMODE = VT_SETMODE; +unsigned IOCTL_VT_GETMODE = VT_GETMODE; +unsigned IOCTL_VT_RELDISP = VT_RELDISP; +unsigned IOCTL_VT_ACTIVATE = VT_ACTIVATE; +unsigned IOCTL_VT_WAITACTIVE = VT_WAITACTIVE; +unsigned IOCTL_VT_GETACTIVE = VT_GETACTIVE; +unsigned IOCTL_VT_GETSTATE = VT_GETSTATE; +unsigned IOCTL_KDGETKBENT = KDGETKBENT; +unsigned IOCTL_KDGKBMODE = KDGKBMODE; +unsigned IOCTL_KDSKBMODE = KDSKBMODE; +unsigned IOCTL_KDMKTONE = KDMKTONE; +unsigned IOCTL_KDSETMODE = KDSETMODE; +unsigned IOCTL_KDENABIO = KDENABIO; +unsigned IOCTL_KDDISABIO = KDDISABIO; +unsigned IOCTL_KDGKBTYPE = KDGKBTYPE; +unsigned IOCTL_KDGETLED = KDGETLED; +unsigned IOCTL_KDSETLED = KDSETLED; +unsigned IOCTL_KDSETRAD = KDSETRAD; +unsigned IOCTL_VGAPCVTID = VGAPCVTID; +unsigned IOCTL_CONS_GETVERS = CONS_GETVERS; +unsigned IOCTL_WSKBDIO_GTYPE = WSKBDIO_GTYPE; +unsigned IOCTL_WSKBDIO_BELL = WSKBDIO_BELL; +unsigned IOCTL_WSKBDIO_COMPLEXBELL = WSKBDIO_COMPLEXBELL; +unsigned IOCTL_WSKBDIO_SETBELL = WSKBDIO_SETBELL; +unsigned IOCTL_WSKBDIO_GETBELL = WSKBDIO_GETBELL; +unsigned IOCTL_WSKBDIO_SETDEFAULTBELL = WSKBDIO_SETDEFAULTBELL; +unsigned IOCTL_WSKBDIO_GETDEFAULTBELL = WSKBDIO_GETDEFAULTBELL; +unsigned IOCTL_WSKBDIO_SETKEYREPEAT = WSKBDIO_SETKEYREPEAT; +unsigned IOCTL_WSKBDIO_GETKEYREPEAT = WSKBDIO_GETKEYREPEAT; +unsigned IOCTL_WSKBDIO_SETDEFAULTKEYREPEAT = WSKBDIO_SETDEFAULTKEYREPEAT; +unsigned IOCTL_WSKBDIO_GETDEFAULTKEYREPEAT = WSKBDIO_GETDEFAULTKEYREPEAT; +unsigned IOCTL_WSKBDIO_SETLEDS = WSKBDIO_SETLEDS; +unsigned IOCTL_WSKBDIO_GETLEDS = WSKBDIO_GETLEDS; +unsigned IOCTL_WSKBDIO_GETMAP = WSKBDIO_GETMAP; +unsigned IOCTL_WSKBDIO_SETMAP = WSKBDIO_SETMAP; +unsigned IOCTL_WSKBDIO_GETENCODING = WSKBDIO_GETENCODING; +unsigned IOCTL_WSKBDIO_SETENCODING = WSKBDIO_SETENCODING; +unsigned IOCTL_WSKBDIO_SETMODE = WSKBDIO_SETMODE; +unsigned IOCTL_WSKBDIO_GETMODE = WSKBDIO_GETMODE; +unsigned IOCTL_WSKBDIO_SETKEYCLICK = WSKBDIO_SETKEYCLICK; +unsigned IOCTL_WSKBDIO_GETKEYCLICK = WSKBDIO_GETKEYCLICK; +unsigned IOCTL_WSKBDIO_GETSCROLL = WSKBDIO_GETSCROLL; +unsigned IOCTL_WSKBDIO_SETSCROLL = WSKBDIO_SETSCROLL; +unsigned IOCTL_WSKBDIO_SETVERSION = WSKBDIO_SETVERSION; +unsigned IOCTL_WSMOUSEIO_GTYPE = WSMOUSEIO_GTYPE; +unsigned IOCTL_WSMOUSEIO_SRES = WSMOUSEIO_SRES; +unsigned IOCTL_WSMOUSEIO_SSCALE = WSMOUSEIO_SSCALE; +unsigned IOCTL_WSMOUSEIO_SRATE = WSMOUSEIO_SRATE; +unsigned IOCTL_WSMOUSEIO_SCALIBCOORDS = WSMOUSEIO_SCALIBCOORDS; +unsigned IOCTL_WSMOUSEIO_GCALIBCOORDS = WSMOUSEIO_GCALIBCOORDS; +unsigned IOCTL_WSMOUSEIO_GETID = WSMOUSEIO_GETID; +unsigned IOCTL_WSMOUSEIO_GETREPEAT = WSMOUSEIO_GETREPEAT; +unsigned IOCTL_WSMOUSEIO_SETREPEAT = WSMOUSEIO_SETREPEAT; +unsigned IOCTL_WSMOUSEIO_SETVERSION = WSMOUSEIO_SETVERSION; +unsigned IOCTL_WSDISPLAYIO_GTYPE = WSDISPLAYIO_GTYPE; +unsigned IOCTL_WSDISPLAYIO_GINFO = WSDISPLAYIO_GINFO; +unsigned IOCTL_WSDISPLAYIO_GETCMAP = WSDISPLAYIO_GETCMAP; +unsigned IOCTL_WSDISPLAYIO_PUTCMAP = WSDISPLAYIO_PUTCMAP; +unsigned IOCTL_WSDISPLAYIO_GVIDEO = WSDISPLAYIO_GVIDEO; +unsigned IOCTL_WSDISPLAYIO_SVIDEO = WSDISPLAYIO_SVIDEO; +unsigned IOCTL_WSDISPLAYIO_GCURPOS = WSDISPLAYIO_GCURPOS; +unsigned IOCTL_WSDISPLAYIO_SCURPOS = WSDISPLAYIO_SCURPOS; +unsigned IOCTL_WSDISPLAYIO_GCURMAX = WSDISPLAYIO_GCURMAX; +unsigned IOCTL_WSDISPLAYIO_GCURSOR = WSDISPLAYIO_GCURSOR; +unsigned IOCTL_WSDISPLAYIO_SCURSOR = WSDISPLAYIO_SCURSOR; +unsigned IOCTL_WSDISPLAYIO_GMODE = WSDISPLAYIO_GMODE; +unsigned IOCTL_WSDISPLAYIO_SMODE = WSDISPLAYIO_SMODE; +unsigned IOCTL_WSDISPLAYIO_LDFONT = WSDISPLAYIO_LDFONT; +unsigned IOCTL_WSDISPLAYIO_ADDSCREEN = WSDISPLAYIO_ADDSCREEN; +unsigned IOCTL_WSDISPLAYIO_DELSCREEN = WSDISPLAYIO_DELSCREEN; +unsigned IOCTL_WSDISPLAYIO_SFONT = WSDISPLAYIO_SFONT; +unsigned IOCTL__O_WSDISPLAYIO_SETKEYBOARD = _O_WSDISPLAYIO_SETKEYBOARD; +unsigned IOCTL_WSDISPLAYIO_GETPARAM = WSDISPLAYIO_GETPARAM; +unsigned IOCTL_WSDISPLAYIO_SETPARAM = WSDISPLAYIO_SETPARAM; +unsigned IOCTL_WSDISPLAYIO_GETACTIVESCREEN = WSDISPLAYIO_GETACTIVESCREEN; +unsigned IOCTL_WSDISPLAYIO_GETWSCHAR = WSDISPLAYIO_GETWSCHAR; +unsigned IOCTL_WSDISPLAYIO_PUTWSCHAR = WSDISPLAYIO_PUTWSCHAR; +unsigned IOCTL_WSDISPLAYIO_DGSCROLL = WSDISPLAYIO_DGSCROLL; +unsigned IOCTL_WSDISPLAYIO_DSSCROLL = WSDISPLAYIO_DSSCROLL; +unsigned IOCTL_WSDISPLAYIO_GMSGATTRS = WSDISPLAYIO_GMSGATTRS; +unsigned IOCTL_WSDISPLAYIO_SMSGATTRS = WSDISPLAYIO_SMSGATTRS; +unsigned IOCTL_WSDISPLAYIO_GBORDER = WSDISPLAYIO_GBORDER; +unsigned IOCTL_WSDISPLAYIO_SBORDER = WSDISPLAYIO_SBORDER; +unsigned IOCTL_WSDISPLAYIO_SSPLASH = WSDISPLAYIO_SSPLASH; +unsigned IOCTL_WSDISPLAYIO_SPROGRESS = WSDISPLAYIO_SPROGRESS; +unsigned IOCTL_WSDISPLAYIO_LINEBYTES = WSDISPLAYIO_LINEBYTES; +unsigned IOCTL_WSDISPLAYIO_SETVERSION = WSDISPLAYIO_SETVERSION; +unsigned IOCTL_WSMUXIO_ADD_DEVICE = WSMUXIO_ADD_DEVICE; +unsigned IOCTL_WSMUXIO_REMOVE_DEVICE = WSMUXIO_REMOVE_DEVICE; +unsigned IOCTL_WSMUXIO_LIST_DEVICES = WSMUXIO_LIST_DEVICES; +unsigned IOCTL_WSMUXIO_INJECTEVENT = WSMUXIO_INJECTEVENT; +unsigned IOCTL_WSDISPLAYIO_GET_BUSID = WSDISPLAYIO_GET_BUSID; +unsigned IOCTL_WSDISPLAYIO_GET_EDID = WSDISPLAYIO_GET_EDID; +unsigned IOCTL_WSDISPLAYIO_SET_POLLING = WSDISPLAYIO_SET_POLLING; +unsigned IOCTL_WSDISPLAYIO_GET_FBINFO = WSDISPLAYIO_GET_FBINFO; +unsigned IOCTL_WSDISPLAYIO_DOBLIT = WSDISPLAYIO_DOBLIT; +unsigned IOCTL_WSDISPLAYIO_WAITBLIT = WSDISPLAYIO_WAITBLIT; +unsigned IOCTL_BIOCLOCATE = BIOCLOCATE; +unsigned IOCTL_BIOCINQ = BIOCINQ; +unsigned IOCTL_BIOCDISK_NOVOL = BIOCDISK_NOVOL; +unsigned IOCTL_BIOCDISK = BIOCDISK; +unsigned IOCTL_BIOCVOL = BIOCVOL; +unsigned IOCTL_BIOCALARM = BIOCALARM; +unsigned IOCTL_BIOCBLINK = BIOCBLINK; +unsigned IOCTL_BIOCSETSTATE = BIOCSETSTATE; +unsigned IOCTL_BIOCVOLOPS = BIOCVOLOPS; +unsigned IOCTL_MD_GETCONF = MD_GETCONF; +unsigned IOCTL_MD_SETCONF = MD_SETCONF; +unsigned IOCTL_CCDIOCSET = CCDIOCSET; +unsigned IOCTL_CCDIOCCLR = CCDIOCCLR; +unsigned IOCTL_CGDIOCSET = CGDIOCSET; +unsigned IOCTL_CGDIOCCLR = CGDIOCCLR; +unsigned IOCTL_CGDIOCGET = CGDIOCGET; +unsigned IOCTL_FSSIOCSET = FSSIOCSET; +unsigned IOCTL_FSSIOCGET = FSSIOCGET; +unsigned IOCTL_FSSIOCCLR = FSSIOCCLR; +unsigned IOCTL_FSSIOFSET = FSSIOFSET; +unsigned IOCTL_FSSIOFGET = FSSIOFGET; +unsigned IOCTL_BTDEV_ATTACH = BTDEV_ATTACH; +unsigned IOCTL_BTDEV_DETACH = BTDEV_DETACH; +unsigned IOCTL_BTSCO_GETINFO = BTSCO_GETINFO; +unsigned IOCTL_KTTCP_IO_SEND = KTTCP_IO_SEND; +unsigned IOCTL_KTTCP_IO_RECV = KTTCP_IO_RECV; +unsigned IOCTL_IOC_LOCKSTAT_GVERSION = IOC_LOCKSTAT_GVERSION; +unsigned IOCTL_IOC_LOCKSTAT_ENABLE = IOC_LOCKSTAT_ENABLE; +unsigned IOCTL_IOC_LOCKSTAT_DISABLE = IOC_LOCKSTAT_DISABLE; +unsigned IOCTL_VNDIOCSET = VNDIOCSET; +unsigned IOCTL_VNDIOCCLR = VNDIOCCLR; +unsigned IOCTL_VNDIOCGET = VNDIOCGET; +unsigned IOCTL_SPKRTONE = SPKRTONE; +unsigned IOCTL_SPKRTUNE = SPKRTUNE; +unsigned IOCTL_SPKRGETVOL = SPKRGETVOL; +unsigned IOCTL_SPKRSETVOL = SPKRSETVOL; +unsigned IOCTL_BIOCGBLEN = BIOCGBLEN; +unsigned IOCTL_BIOCSBLEN = BIOCSBLEN; +unsigned IOCTL_BIOCSETF = BIOCSETF; +unsigned IOCTL_BIOCFLUSH = BIOCFLUSH; +unsigned IOCTL_BIOCPROMISC = BIOCPROMISC; +unsigned IOCTL_BIOCGDLT = BIOCGDLT; +unsigned IOCTL_BIOCGETIF = BIOCGETIF; +unsigned IOCTL_BIOCSETIF = BIOCSETIF; +unsigned IOCTL_BIOCGSTATS = BIOCGSTATS; +unsigned IOCTL_BIOCGSTATSOLD = BIOCGSTATSOLD; +unsigned IOCTL_BIOCIMMEDIATE = BIOCIMMEDIATE; +unsigned IOCTL_BIOCVERSION = BIOCVERSION; +unsigned IOCTL_BIOCSTCPF = BIOCSTCPF; +unsigned IOCTL_BIOCSUDPF = BIOCSUDPF; +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_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; +unsigned IOCTL_GREGADDRD = GREGADDRD; +unsigned IOCTL_GRESPROTO = GRESPROTO; +unsigned IOCTL_GREGPROTO = GREGPROTO; +unsigned IOCTL_GRESSOCK = GRESSOCK; +unsigned IOCTL_GREDSOCK = GREDSOCK; +unsigned IOCTL_PPPIOCGRAWIN = PPPIOCGRAWIN; +unsigned IOCTL_PPPIOCGFLAGS = PPPIOCGFLAGS; +unsigned IOCTL_PPPIOCSFLAGS = PPPIOCSFLAGS; +unsigned IOCTL_PPPIOCGASYNCMAP = PPPIOCGASYNCMAP; +unsigned IOCTL_PPPIOCSASYNCMAP = PPPIOCSASYNCMAP; +unsigned IOCTL_PPPIOCGUNIT = PPPIOCGUNIT; +unsigned IOCTL_PPPIOCGRASYNCMAP = PPPIOCGRASYNCMAP; +unsigned IOCTL_PPPIOCSRASYNCMAP = PPPIOCSRASYNCMAP; +unsigned IOCTL_PPPIOCGMRU = PPPIOCGMRU; +unsigned IOCTL_PPPIOCSMRU = PPPIOCSMRU; +unsigned IOCTL_PPPIOCSMAXCID = PPPIOCSMAXCID; +unsigned IOCTL_PPPIOCGXASYNCMAP = PPPIOCGXASYNCMAP; +unsigned IOCTL_PPPIOCSXASYNCMAP = PPPIOCSXASYNCMAP; +unsigned IOCTL_PPPIOCXFERUNIT = PPPIOCXFERUNIT; +unsigned IOCTL_PPPIOCSCOMPRESS = PPPIOCSCOMPRESS; +unsigned IOCTL_PPPIOCGNPMODE = PPPIOCGNPMODE; +unsigned IOCTL_PPPIOCSNPMODE = PPPIOCSNPMODE; +unsigned IOCTL_PPPIOCGIDLE = PPPIOCGIDLE; +unsigned IOCTL_PPPIOCGMTU = PPPIOCGMTU; +unsigned IOCTL_PPPIOCSMTU = PPPIOCSMTU; +unsigned IOCTL_SIOCGPPPSTATS = SIOCGPPPSTATS; +unsigned IOCTL_SIOCGPPPCSTATS = SIOCGPPPCSTATS; +unsigned IOCTL_IOC_NPF_VERSION = IOC_NPF_VERSION; +unsigned IOCTL_IOC_NPF_SWITCH = IOC_NPF_SWITCH; +unsigned IOCTL_IOC_NPF_LOAD = IOC_NPF_LOAD; +unsigned IOCTL_IOC_NPF_TABLE = IOC_NPF_TABLE; +unsigned IOCTL_IOC_NPF_STATS = IOC_NPF_STATS; +unsigned IOCTL_IOC_NPF_SAVE = IOC_NPF_SAVE; +unsigned IOCTL_IOC_NPF_RULE = IOC_NPF_RULE; +unsigned IOCTL_IOC_NPF_CONN_LOOKUP = IOC_NPF_CONN_LOOKUP; +unsigned IOCTL_PPPOESETPARMS = PPPOESETPARMS; +unsigned IOCTL_PPPOEGETPARMS = PPPOEGETPARMS; +unsigned IOCTL_PPPOEGETSESSION = PPPOEGETSESSION; +unsigned IOCTL_SPPPGETAUTHCFG = SPPPGETAUTHCFG; +unsigned IOCTL_SPPPSETAUTHCFG = SPPPSETAUTHCFG; +unsigned IOCTL_SPPPGETLCPCFG = SPPPGETLCPCFG; +unsigned IOCTL_SPPPSETLCPCFG = SPPPSETLCPCFG; +unsigned IOCTL_SPPPGETSTATUS = SPPPGETSTATUS; +unsigned IOCTL_SPPPGETSTATUSNCP = SPPPGETSTATUSNCP; +unsigned IOCTL_SPPPGETIDLETO = SPPPGETIDLETO; +unsigned IOCTL_SPPPSETIDLETO = SPPPSETIDLETO; +unsigned IOCTL_SPPPGETAUTHFAILURES = SPPPGETAUTHFAILURES; +unsigned IOCTL_SPPPSETAUTHFAILURE = SPPPSETAUTHFAILURE; +unsigned IOCTL_SPPPSETDNSOPTS = SPPPSETDNSOPTS; +unsigned IOCTL_SPPPGETDNSOPTS = SPPPGETDNSOPTS; +unsigned IOCTL_SPPPGETDNSADDRS = SPPPGETDNSADDRS; +unsigned IOCTL_SPPPSETKEEPALIVE = SPPPSETKEEPALIVE; +unsigned IOCTL_SPPPGETKEEPALIVE = SPPPGETKEEPALIVE; +unsigned IOCTL_SRT_GETNRT = SRT_GETNRT; +unsigned IOCTL_SRT_GETRT = SRT_GETRT; +unsigned IOCTL_SRT_SETRT = SRT_SETRT; +unsigned IOCTL_SRT_DELRT = SRT_DELRT; +unsigned IOCTL_SRT_SFLAGS = SRT_SFLAGS; +unsigned IOCTL_SRT_GFLAGS = SRT_GFLAGS; +unsigned IOCTL_SRT_SGFLAGS = SRT_SGFLAGS; +unsigned IOCTL_SRT_DEBUG = SRT_DEBUG; +unsigned IOCTL_TAPGIFNAME = TAPGIFNAME; +unsigned IOCTL_TUNSDEBUG = TUNSDEBUG; +unsigned IOCTL_TUNGDEBUG = TUNGDEBUG; +unsigned IOCTL_TUNSIFMODE = TUNSIFMODE; +unsigned IOCTL_TUNSLMODE = TUNSLMODE; +unsigned IOCTL_TUNSIFHEAD = TUNSIFHEAD; +unsigned IOCTL_TUNGIFHEAD = TUNGIFHEAD; +unsigned IOCTL_DIOCSTART = DIOCSTART; +unsigned IOCTL_DIOCSTOP = DIOCSTOP; +unsigned IOCTL_DIOCADDRULE = DIOCADDRULE; +unsigned IOCTL_DIOCGETRULES = DIOCGETRULES; +unsigned IOCTL_DIOCGETRULE = DIOCGETRULE; +unsigned IOCTL_DIOCSETLCK = DIOCSETLCK; +unsigned IOCTL_DIOCCLRSTATES = DIOCCLRSTATES; +unsigned IOCTL_DIOCGETSTATE = DIOCGETSTATE; +unsigned IOCTL_DIOCSETSTATUSIF = DIOCSETSTATUSIF; +unsigned IOCTL_DIOCGETSTATUS = DIOCGETSTATUS; +unsigned IOCTL_DIOCCLRSTATUS = DIOCCLRSTATUS; +unsigned IOCTL_DIOCNATLOOK = DIOCNATLOOK; +unsigned IOCTL_DIOCSETDEBUG = DIOCSETDEBUG; +unsigned IOCTL_DIOCGETSTATES = DIOCGETSTATES; +unsigned IOCTL_DIOCCHANGERULE = DIOCCHANGERULE; +unsigned IOCTL_DIOCSETTIMEOUT = DIOCSETTIMEOUT; +unsigned IOCTL_DIOCGETTIMEOUT = DIOCGETTIMEOUT; +unsigned IOCTL_DIOCADDSTATE = DIOCADDSTATE; +unsigned IOCTL_DIOCCLRRULECTRS = DIOCCLRRULECTRS; +unsigned IOCTL_DIOCGETLIMIT = DIOCGETLIMIT; +unsigned IOCTL_DIOCSETLIMIT = DIOCSETLIMIT; +unsigned IOCTL_DIOCKILLSTATES = DIOCKILLSTATES; +unsigned IOCTL_DIOCSTARTALTQ = DIOCSTARTALTQ; +unsigned IOCTL_DIOCSTOPALTQ = DIOCSTOPALTQ; +unsigned IOCTL_DIOCADDALTQ = DIOCADDALTQ; +unsigned IOCTL_DIOCGETALTQS = DIOCGETALTQS; +unsigned IOCTL_DIOCGETALTQ = DIOCGETALTQ; +unsigned IOCTL_DIOCCHANGEALTQ = DIOCCHANGEALTQ; +unsigned IOCTL_DIOCGETQSTATS = DIOCGETQSTATS; +unsigned IOCTL_DIOCBEGINADDRS = DIOCBEGINADDRS; +unsigned IOCTL_DIOCADDADDR = DIOCADDADDR; +unsigned IOCTL_DIOCGETADDRS = DIOCGETADDRS; +unsigned IOCTL_DIOCGETADDR = DIOCGETADDR; +unsigned IOCTL_DIOCCHANGEADDR = DIOCCHANGEADDR; +unsigned IOCTL_DIOCADDSTATES = DIOCADDSTATES; +unsigned IOCTL_DIOCGETRULESETS = DIOCGETRULESETS; +unsigned IOCTL_DIOCGETRULESET = DIOCGETRULESET; +unsigned IOCTL_DIOCRCLRTABLES = DIOCRCLRTABLES; +unsigned IOCTL_DIOCRADDTABLES = DIOCRADDTABLES; +unsigned IOCTL_DIOCRDELTABLES = DIOCRDELTABLES; +unsigned IOCTL_DIOCRGETTABLES = DIOCRGETTABLES; +unsigned IOCTL_DIOCRGETTSTATS = DIOCRGETTSTATS; +unsigned IOCTL_DIOCRCLRTSTATS = DIOCRCLRTSTATS; +unsigned IOCTL_DIOCRCLRADDRS = DIOCRCLRADDRS; +unsigned IOCTL_DIOCRADDADDRS = DIOCRADDADDRS; +unsigned IOCTL_DIOCRDELADDRS = DIOCRDELADDRS; +unsigned IOCTL_DIOCRSETADDRS = DIOCRSETADDRS; +unsigned IOCTL_DIOCRGETADDRS = DIOCRGETADDRS; +unsigned IOCTL_DIOCRGETASTATS = DIOCRGETASTATS; +unsigned IOCTL_DIOCRCLRASTATS = DIOCRCLRASTATS; +unsigned IOCTL_DIOCRTSTADDRS = DIOCRTSTADDRS; +unsigned IOCTL_DIOCRSETTFLAGS = DIOCRSETTFLAGS; +unsigned IOCTL_DIOCRINADEFINE = DIOCRINADEFINE; +unsigned IOCTL_DIOCOSFPFLUSH = DIOCOSFPFLUSH; +unsigned IOCTL_DIOCOSFPADD = DIOCOSFPADD; +unsigned IOCTL_DIOCOSFPGET = DIOCOSFPGET; +unsigned IOCTL_DIOCXBEGIN = DIOCXBEGIN; +unsigned IOCTL_DIOCXCOMMIT = DIOCXCOMMIT; +unsigned IOCTL_DIOCXROLLBACK = DIOCXROLLBACK; +unsigned IOCTL_DIOCGETSRCNODES = DIOCGETSRCNODES; +unsigned IOCTL_DIOCCLRSRCNODES = DIOCCLRSRCNODES; +unsigned IOCTL_DIOCSETHOSTID = DIOCSETHOSTID; +unsigned IOCTL_DIOCIGETIFACES = DIOCIGETIFACES; +unsigned IOCTL_DIOCSETIFFLAG = DIOCSETIFFLAG; +unsigned IOCTL_DIOCCLRIFFLAG = DIOCCLRIFFLAG; +unsigned IOCTL_DIOCKILLSRCNODES = DIOCKILLSRCNODES; +unsigned IOCTL_SLIOCGUNIT = SLIOCGUNIT; +unsigned IOCTL_SIOCGBTINFO = SIOCGBTINFO; +unsigned IOCTL_SIOCGBTINFOA = SIOCGBTINFOA; +unsigned IOCTL_SIOCNBTINFO = SIOCNBTINFO; +unsigned IOCTL_SIOCSBTFLAGS = SIOCSBTFLAGS; +unsigned IOCTL_SIOCSBTPOLICY = SIOCSBTPOLICY; +unsigned IOCTL_SIOCSBTPTYPE = SIOCSBTPTYPE; +unsigned IOCTL_SIOCGBTSTATS = SIOCGBTSTATS; +unsigned IOCTL_SIOCZBTSTATS = SIOCZBTSTATS; +unsigned IOCTL_SIOCBTDUMP = SIOCBTDUMP; +unsigned IOCTL_SIOCSBTSCOMTU = SIOCSBTSCOMTU; +unsigned IOCTL_SIOCGBTFEAT = SIOCGBTFEAT; +unsigned IOCTL_SIOCADNAT = SIOCADNAT; +unsigned IOCTL_SIOCRMNAT = SIOCRMNAT; +unsigned IOCTL_SIOCGNATS = SIOCGNATS; +unsigned IOCTL_SIOCGNATL = SIOCGNATL; +unsigned IOCTL_SIOCPURGENAT = SIOCPURGENAT; +unsigned IOCTL_SIOCSIFINFO_FLAGS = SIOCSIFINFO_FLAGS; +unsigned IOCTL_SIOCAADDRCTL_POLICY = SIOCAADDRCTL_POLICY; +unsigned IOCTL_SIOCDADDRCTL_POLICY = SIOCDADDRCTL_POLICY; +unsigned IOCTL_SMBIOC_OPENSESSION = SMBIOC_OPENSESSION; +unsigned IOCTL_SMBIOC_OPENSHARE = SMBIOC_OPENSHARE; +unsigned IOCTL_SMBIOC_REQUEST = SMBIOC_REQUEST; +unsigned IOCTL_SMBIOC_SETFLAGS = SMBIOC_SETFLAGS; +unsigned IOCTL_SMBIOC_LOOKUP = SMBIOC_LOOKUP; +unsigned IOCTL_SMBIOC_READ = SMBIOC_READ; +unsigned IOCTL_SMBIOC_WRITE = SMBIOC_WRITE; +unsigned IOCTL_AGPIOC_INFO = AGPIOC_INFO; +unsigned IOCTL_AGPIOC_ACQUIRE = AGPIOC_ACQUIRE; +unsigned IOCTL_AGPIOC_RELEASE = AGPIOC_RELEASE; +unsigned IOCTL_AGPIOC_SETUP = AGPIOC_SETUP; +unsigned IOCTL_AGPIOC_ALLOCATE = AGPIOC_ALLOCATE; +unsigned IOCTL_AGPIOC_DEALLOCATE = AGPIOC_DEALLOCATE; +unsigned IOCTL_AGPIOC_BIND = AGPIOC_BIND; +unsigned IOCTL_AGPIOC_UNBIND = AGPIOC_UNBIND; +unsigned IOCTL_AUDIO_GETINFO = AUDIO_GETINFO; +unsigned IOCTL_AUDIO_SETINFO = AUDIO_SETINFO; +unsigned IOCTL_AUDIO_DRAIN = AUDIO_DRAIN; +unsigned IOCTL_AUDIO_FLUSH = AUDIO_FLUSH; +unsigned IOCTL_AUDIO_WSEEK = AUDIO_WSEEK; +unsigned IOCTL_AUDIO_RERROR = AUDIO_RERROR; +unsigned IOCTL_AUDIO_GETDEV = AUDIO_GETDEV; +unsigned IOCTL_AUDIO_GETENC = AUDIO_GETENC; +unsigned IOCTL_AUDIO_GETFD = AUDIO_GETFD; +unsigned IOCTL_AUDIO_SETFD = AUDIO_SETFD; +unsigned IOCTL_AUDIO_PERROR = AUDIO_PERROR; +unsigned IOCTL_AUDIO_GETIOFFS = AUDIO_GETIOFFS; +unsigned IOCTL_AUDIO_GETOOFFS = AUDIO_GETOOFFS; +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_MIXER_READ = AUDIO_MIXER_READ; +unsigned IOCTL_AUDIO_MIXER_WRITE = AUDIO_MIXER_WRITE; +unsigned IOCTL_AUDIO_MIXER_DEVINFO = AUDIO_MIXER_DEVINFO; +unsigned IOCTL_ATAIOCCOMMAND = ATAIOCCOMMAND; +unsigned IOCTL_ATABUSIOSCAN = ATABUSIOSCAN; +unsigned IOCTL_ATABUSIORESET = ATABUSIORESET; +unsigned IOCTL_ATABUSIODETACH = ATABUSIODETACH; +unsigned IOCTL_CDIOCPLAYTRACKS = CDIOCPLAYTRACKS; +unsigned IOCTL_CDIOCPLAYBLOCKS = CDIOCPLAYBLOCKS; +unsigned IOCTL_CDIOCREADSUBCHANNEL = CDIOCREADSUBCHANNEL; +unsigned IOCTL_CDIOREADTOCHEADER = CDIOREADTOCHEADER; +unsigned IOCTL_CDIOREADTOCENTRIES = CDIOREADTOCENTRIES; +unsigned IOCTL_CDIOREADMSADDR = CDIOREADMSADDR; +unsigned IOCTL_CDIOCSETPATCH = CDIOCSETPATCH; +unsigned IOCTL_CDIOCGETVOL = CDIOCGETVOL; +unsigned IOCTL_CDIOCSETVOL = CDIOCSETVOL; +unsigned IOCTL_CDIOCSETMONO = CDIOCSETMONO; +unsigned IOCTL_CDIOCSETSTEREO = CDIOCSETSTEREO; +unsigned IOCTL_CDIOCSETMUTE = CDIOCSETMUTE; +unsigned IOCTL_CDIOCSETLEFT = CDIOCSETLEFT; +unsigned IOCTL_CDIOCSETRIGHT = CDIOCSETRIGHT; +unsigned IOCTL_CDIOCSETDEBUG = CDIOCSETDEBUG; +unsigned IOCTL_CDIOCCLRDEBUG = CDIOCCLRDEBUG; +unsigned IOCTL_CDIOCPAUSE = CDIOCPAUSE; +unsigned IOCTL_CDIOCRESUME = CDIOCRESUME; +unsigned IOCTL_CDIOCRESET = CDIOCRESET; +unsigned IOCTL_CDIOCSTART = CDIOCSTART; +unsigned IOCTL_CDIOCSTOP = CDIOCSTOP; +unsigned IOCTL_CDIOCEJECT = CDIOCEJECT; +unsigned IOCTL_CDIOCALLOW = CDIOCALLOW; +unsigned IOCTL_CDIOCPREVENT = CDIOCPREVENT; +unsigned IOCTL_CDIOCCLOSE = CDIOCCLOSE; +unsigned IOCTL_CDIOCPLAYMSF = CDIOCPLAYMSF; +unsigned IOCTL_CDIOCLOADUNLOAD = CDIOCLOADUNLOAD; +unsigned IOCTL_CHIOMOVE = CHIOMOVE; +unsigned IOCTL_CHIOEXCHANGE = CHIOEXCHANGE; +unsigned IOCTL_CHIOPOSITION = CHIOPOSITION; +unsigned IOCTL_CHIOGPICKER = CHIOGPICKER; +unsigned IOCTL_CHIOSPICKER = CHIOSPICKER; +unsigned IOCTL_CHIOGPARAMS = CHIOGPARAMS; +unsigned IOCTL_CHIOIELEM = CHIOIELEM; +unsigned IOCTL_OCHIOGSTATUS = OCHIOGSTATUS; +unsigned IOCTL_CHIOGSTATUS = CHIOGSTATUS; +unsigned IOCTL_CHIOSVOLTAG = CHIOSVOLTAG; +unsigned IOCTL_CLOCKCTL_SETTIMEOFDAY = CLOCKCTL_SETTIMEOFDAY; +unsigned IOCTL_CLOCKCTL_ADJTIME = CLOCKCTL_ADJTIME; +unsigned IOCTL_CLOCKCTL_CLOCK_SETTIME = CLOCKCTL_CLOCK_SETTIME; +unsigned IOCTL_CLOCKCTL_NTP_ADJTIME = CLOCKCTL_NTP_ADJTIME; +unsigned IOCTL_IOC_CPU_SETSTATE = IOC_CPU_SETSTATE; +unsigned IOCTL_IOC_CPU_GETSTATE = IOC_CPU_GETSTATE; +unsigned IOCTL_IOC_CPU_GETCOUNT = IOC_CPU_GETCOUNT; +unsigned IOCTL_IOC_CPU_MAPID = IOC_CPU_MAPID; +unsigned IOCTL_IOC_CPU_UCODE_GET_VERSION = IOC_CPU_UCODE_GET_VERSION; +unsigned IOCTL_IOC_CPU_UCODE_APPLY = IOC_CPU_UCODE_APPLY; +unsigned IOCTL_DIOCGDINFO = DIOCGDINFO; +unsigned IOCTL_DIOCSDINFO = DIOCSDINFO; +unsigned IOCTL_DIOCWDINFO = DIOCWDINFO; +unsigned IOCTL_DIOCRFORMAT = DIOCRFORMAT; +unsigned IOCTL_DIOCWFORMAT = DIOCWFORMAT; +unsigned IOCTL_DIOCSSTEP = DIOCSSTEP; +unsigned IOCTL_DIOCSRETRIES = DIOCSRETRIES; +unsigned IOCTL_DIOCKLABEL = DIOCKLABEL; +unsigned IOCTL_DIOCWLABEL = DIOCWLABEL; +unsigned IOCTL_DIOCSBAD = DIOCSBAD; +unsigned IOCTL_DIOCEJECT = DIOCEJECT; +unsigned IOCTL_ODIOCEJECT = ODIOCEJECT; +unsigned IOCTL_DIOCLOCK = DIOCLOCK; +unsigned IOCTL_DIOCGDEFLABEL = DIOCGDEFLABEL; +unsigned IOCTL_DIOCCLRLABEL = DIOCCLRLABEL; +unsigned IOCTL_DIOCGCACHE = DIOCGCACHE; +unsigned IOCTL_DIOCSCACHE = DIOCSCACHE; +unsigned IOCTL_DIOCCACHESYNC = DIOCCACHESYNC; +unsigned IOCTL_DIOCBSLIST = DIOCBSLIST; +unsigned IOCTL_DIOCBSFLUSH = DIOCBSFLUSH; +unsigned IOCTL_DIOCAWEDGE = DIOCAWEDGE; +unsigned IOCTL_DIOCGWEDGEINFO = DIOCGWEDGEINFO; +unsigned IOCTL_DIOCDWEDGE = DIOCDWEDGE; +unsigned IOCTL_DIOCLWEDGES = DIOCLWEDGES; +unsigned IOCTL_DIOCGSTRATEGY = DIOCGSTRATEGY; +unsigned IOCTL_DIOCSSTRATEGY = DIOCSSTRATEGY; +unsigned IOCTL_DIOCGDISKINFO = DIOCGDISKINFO; +unsigned IOCTL_DIOCTUR = DIOCTUR; +unsigned IOCTL_DIOCMWEDGES = DIOCMWEDGES; +unsigned IOCTL_DIOCGSECTORSIZE = DIOCGSECTORSIZE; +unsigned IOCTL_DIOCGMEDIASIZE = DIOCGMEDIASIZE; +unsigned IOCTL_DRVDETACHDEV = DRVDETACHDEV; +unsigned IOCTL_DRVRESCANBUS = DRVRESCANBUS; +unsigned IOCTL_DRVCTLCOMMAND = DRVCTLCOMMAND; +unsigned IOCTL_DRVRESUMEDEV = DRVRESUMEDEV; +unsigned IOCTL_DRVLISTDEV = DRVLISTDEV; +unsigned IOCTL_DRVGETEVENT = DRVGETEVENT; +unsigned IOCTL_DRVSUSPENDDEV = DRVSUSPENDDEV; +unsigned IOCTL_DVD_READ_STRUCT = DVD_READ_STRUCT; +unsigned IOCTL_DVD_WRITE_STRUCT = DVD_WRITE_STRUCT; +unsigned IOCTL_DVD_AUTH = DVD_AUTH; +unsigned IOCTL_ENVSYS_GETDICTIONARY = ENVSYS_GETDICTIONARY; +unsigned IOCTL_ENVSYS_SETDICTIONARY = ENVSYS_SETDICTIONARY; +unsigned IOCTL_ENVSYS_REMOVEPROPS = ENVSYS_REMOVEPROPS; +unsigned IOCTL_ENVSYS_GTREDATA = ENVSYS_GTREDATA; +unsigned IOCTL_ENVSYS_GTREINFO = ENVSYS_GTREINFO; +unsigned IOCTL_KFILTER_BYFILTER = KFILTER_BYFILTER; +unsigned IOCTL_KFILTER_BYNAME = KFILTER_BYNAME; +unsigned IOCTL_FDIOCGETOPTS = FDIOCGETOPTS; +unsigned IOCTL_FDIOCSETOPTS = FDIOCSETOPTS; +unsigned IOCTL_FDIOCSETFORMAT = FDIOCSETFORMAT; +unsigned IOCTL_FDIOCGETFORMAT = FDIOCGETFORMAT; +unsigned IOCTL_FDIOCFORMAT_TRACK = FDIOCFORMAT_TRACK; unsigned IOCTL_FIOCLEX = FIOCLEX; -unsigned IOCTL_FIOGETOWN = FIOGETOWN; -unsigned IOCTL_FIONBIO = FIONBIO; unsigned IOCTL_FIONCLEX = FIONCLEX; +unsigned IOCTL_FIONREAD = FIONREAD; +unsigned IOCTL_FIONBIO = FIONBIO; +unsigned IOCTL_FIOASYNC = FIOASYNC; unsigned IOCTL_FIOSETOWN = FIOSETOWN; -unsigned IOCTL_SIOCADDMULTI = SIOCADDMULTI; +unsigned IOCTL_FIOGETOWN = FIOGETOWN; +unsigned IOCTL_OFIOGETBMAP = OFIOGETBMAP; +unsigned IOCTL_FIOGETBMAP = FIOGETBMAP; +unsigned IOCTL_FIONWRITE = FIONWRITE; +unsigned IOCTL_FIONSPACE = FIONSPACE; +unsigned IOCTL_GPIOINFO = GPIOINFO; +unsigned IOCTL_GPIOSET = GPIOSET; +unsigned IOCTL_GPIOUNSET = GPIOUNSET; +unsigned IOCTL_GPIOREAD = GPIOREAD; +unsigned IOCTL_GPIOWRITE = GPIOWRITE; +unsigned IOCTL_GPIOTOGGLE = GPIOTOGGLE; +unsigned IOCTL_GPIOATTACH = GPIOATTACH; +unsigned IOCTL_PTIOCNETBSD = PTIOCNETBSD; +unsigned IOCTL_PTIOCSUNOS = PTIOCSUNOS; +unsigned IOCTL_PTIOCLINUX = PTIOCLINUX; +unsigned IOCTL_PTIOCFREEBSD = PTIOCFREEBSD; +unsigned IOCTL_PTIOCULTRIX = PTIOCULTRIX; +unsigned IOCTL_TIOCHPCL = TIOCHPCL; +unsigned IOCTL_TIOCGETP = TIOCGETP; +unsigned IOCTL_TIOCSETP = TIOCSETP; +unsigned IOCTL_TIOCSETN = TIOCSETN; +unsigned IOCTL_TIOCSETC = TIOCSETC; +unsigned IOCTL_TIOCGETC = TIOCGETC; +unsigned IOCTL_TIOCLBIS = TIOCLBIS; +unsigned IOCTL_TIOCLBIC = TIOCLBIC; +unsigned IOCTL_TIOCLSET = TIOCLSET; +unsigned IOCTL_TIOCLGET = TIOCLGET; +unsigned IOCTL_TIOCSLTC = TIOCSLTC; +unsigned IOCTL_TIOCGLTC = TIOCGLTC; +unsigned IOCTL_OTIOCCONS = OTIOCCONS; +unsigned IOCTL_JOY_SETTIMEOUT = JOY_SETTIMEOUT; +unsigned IOCTL_JOY_GETTIMEOUT = JOY_GETTIMEOUT; +unsigned IOCTL_JOY_SET_X_OFFSET = JOY_SET_X_OFFSET; +unsigned IOCTL_JOY_SET_Y_OFFSET = JOY_SET_Y_OFFSET; +unsigned IOCTL_JOY_GET_X_OFFSET = JOY_GET_X_OFFSET; +unsigned IOCTL_JOY_GET_Y_OFFSET = JOY_GET_Y_OFFSET; +unsigned IOCTL_OKIOCGSYMBOL = OKIOCGSYMBOL; +unsigned IOCTL_OKIOCGVALUE = OKIOCGVALUE; +unsigned IOCTL_KIOCGSIZE = KIOCGSIZE; +unsigned IOCTL_KIOCGVALUE = KIOCGVALUE; +unsigned IOCTL_KIOCGSYMBOL = KIOCGSYMBOL; +unsigned IOCTL_LUAINFO = LUAINFO; +unsigned IOCTL_LUACREATE = LUACREATE; +unsigned IOCTL_LUADESTROY = LUADESTROY; +unsigned IOCTL_LUAREQUIRE = LUAREQUIRE; +unsigned IOCTL_LUALOAD = LUALOAD; +unsigned IOCTL_MIDI_PRETIME = MIDI_PRETIME; +unsigned IOCTL_MIDI_MPUMODE = MIDI_MPUMODE; +unsigned IOCTL_MIDI_MPUCMD = MIDI_MPUCMD; +unsigned IOCTL_SEQUENCER_RESET = SEQUENCER_RESET; +unsigned IOCTL_SEQUENCER_SYNC = SEQUENCER_SYNC; +unsigned IOCTL_SEQUENCER_INFO = SEQUENCER_INFO; +unsigned IOCTL_SEQUENCER_CTRLRATE = SEQUENCER_CTRLRATE; +unsigned IOCTL_SEQUENCER_GETOUTCOUNT = SEQUENCER_GETOUTCOUNT; +unsigned IOCTL_SEQUENCER_GETINCOUNT = SEQUENCER_GETINCOUNT; +unsigned IOCTL_SEQUENCER_RESETSAMPLES = SEQUENCER_RESETSAMPLES; +unsigned IOCTL_SEQUENCER_NRSYNTHS = SEQUENCER_NRSYNTHS; +unsigned IOCTL_SEQUENCER_NRMIDIS = SEQUENCER_NRMIDIS; +unsigned IOCTL_SEQUENCER_THRESHOLD = SEQUENCER_THRESHOLD; +unsigned IOCTL_SEQUENCER_MEMAVL = SEQUENCER_MEMAVL; +unsigned IOCTL_SEQUENCER_PANIC = SEQUENCER_PANIC; +unsigned IOCTL_SEQUENCER_OUTOFBAND = SEQUENCER_OUTOFBAND; +unsigned IOCTL_SEQUENCER_GETTIME = SEQUENCER_GETTIME; +unsigned IOCTL_SEQUENCER_TMR_TIMEBASE = SEQUENCER_TMR_TIMEBASE; +unsigned IOCTL_SEQUENCER_TMR_START = SEQUENCER_TMR_START; +unsigned IOCTL_SEQUENCER_TMR_STOP = SEQUENCER_TMR_STOP; +unsigned IOCTL_SEQUENCER_TMR_CONTINUE = SEQUENCER_TMR_CONTINUE; +unsigned IOCTL_SEQUENCER_TMR_TEMPO = SEQUENCER_TMR_TEMPO; +unsigned IOCTL_SEQUENCER_TMR_SOURCE = SEQUENCER_TMR_SOURCE; +unsigned IOCTL_SEQUENCER_TMR_METRONOME = SEQUENCER_TMR_METRONOME; +unsigned IOCTL_SEQUENCER_TMR_SELECT = SEQUENCER_TMR_SELECT; +unsigned IOCTL_MTIOCTOP = MTIOCTOP; +unsigned IOCTL_MTIOCGET = MTIOCGET; +unsigned IOCTL_MTIOCIEOT = MTIOCIEOT; +unsigned IOCTL_MTIOCEEOT = MTIOCEEOT; +unsigned IOCTL_MTIOCRDSPOS = MTIOCRDSPOS; +unsigned IOCTL_MTIOCRDHPOS = MTIOCRDHPOS; +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; +unsigned IOCTL_RNDGETENTCNT = RNDGETENTCNT; +unsigned IOCTL_RNDGETSRCNUM = RNDGETSRCNUM; +unsigned IOCTL_RNDGETSRCNAME = RNDGETSRCNAME; +unsigned IOCTL_RNDCTL = RNDCTL; +unsigned IOCTL_RNDADDDATA = RNDADDDATA; +unsigned IOCTL_RNDGETPOOLSTAT = RNDGETPOOLSTAT; +unsigned IOCTL_RNDGETESTNUM = RNDGETESTNUM; +unsigned IOCTL_RNDGETESTNAME = RNDGETESTNAME; +unsigned IOCTL_SCIOCGET = SCIOCGET; +unsigned IOCTL_SCIOCSET = SCIOCSET; +unsigned IOCTL_SCIOCRESTART = SCIOCRESTART; +unsigned IOCTL_SCIOC_USE_ADF = SCIOC_USE_ADF; +unsigned IOCTL_SCIOCCOMMAND = SCIOCCOMMAND; +unsigned IOCTL_SCIOCDEBUG = SCIOCDEBUG; +unsigned IOCTL_SCIOCIDENTIFY = SCIOCIDENTIFY; +unsigned IOCTL_OSCIOCIDENTIFY = OSCIOCIDENTIFY; +unsigned IOCTL_SCIOCDECONFIG = SCIOCDECONFIG; +unsigned IOCTL_SCIOCRECONFIG = SCIOCRECONFIG; +unsigned IOCTL_SCIOCRESET = SCIOCRESET; +unsigned IOCTL_SCBUSIOSCAN = SCBUSIOSCAN; +unsigned IOCTL_SCBUSIORESET = SCBUSIORESET; +unsigned IOCTL_SCBUSIODETACH = SCBUSIODETACH; +unsigned IOCTL_SCBUSACCEL = SCBUSACCEL; +unsigned IOCTL_SCBUSIOLLSCAN = SCBUSIOLLSCAN; +unsigned IOCTL_SIOCSHIWAT = SIOCSHIWAT; +unsigned IOCTL_SIOCGHIWAT = SIOCGHIWAT; +unsigned IOCTL_SIOCSLOWAT = SIOCSLOWAT; +unsigned IOCTL_SIOCGLOWAT = SIOCGLOWAT; 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_SIOCSPGRP = SIOCSPGRP; unsigned IOCTL_SIOCGPGRP = SIOCGPGRP; +unsigned IOCTL_SIOCADDRT = SIOCADDRT; +unsigned IOCTL_SIOCDELRT = SIOCDELRT; unsigned IOCTL_SIOCSIFADDR = SIOCSIFADDR; -unsigned IOCTL_SIOCSIFBRDADDR = SIOCSIFBRDADDR; +unsigned IOCTL_SIOCGIFADDR = SIOCGIFADDR; unsigned IOCTL_SIOCSIFDSTADDR = SIOCSIFDSTADDR; +unsigned IOCTL_SIOCGIFDSTADDR = SIOCGIFDSTADDR; unsigned IOCTL_SIOCSIFFLAGS = SIOCSIFFLAGS; +unsigned IOCTL_SIOCGIFFLAGS = SIOCGIFFLAGS; +unsigned IOCTL_SIOCGIFBRDADDR = SIOCGIFBRDADDR; +unsigned IOCTL_SIOCSIFBRDADDR = SIOCSIFBRDADDR; +unsigned IOCTL_SIOCGIFCONF = SIOCGIFCONF; +unsigned IOCTL_SIOCGIFNETMASK = SIOCGIFNETMASK; +unsigned IOCTL_SIOCSIFNETMASK = SIOCSIFNETMASK; +unsigned IOCTL_SIOCGIFMETRIC = SIOCGIFMETRIC; unsigned IOCTL_SIOCSIFMETRIC = SIOCSIFMETRIC; +unsigned IOCTL_SIOCDIFADDR = SIOCDIFADDR; +unsigned IOCTL_SIOCAIFADDR = SIOCAIFADDR; +unsigned IOCTL_SIOCGIFALIAS = SIOCGIFALIAS; +unsigned IOCTL_SIOCGIFAFLAG_IN = SIOCGIFAFLAG_IN; +unsigned IOCTL_SIOCALIFADDR = SIOCALIFADDR; +unsigned IOCTL_SIOCGLIFADDR = SIOCGLIFADDR; +unsigned IOCTL_SIOCDLIFADDR = SIOCDLIFADDR; +unsigned IOCTL_SIOCSIFADDRPREF = SIOCSIFADDRPREF; +unsigned IOCTL_SIOCGIFADDRPREF = SIOCGIFADDRPREF; +unsigned IOCTL_SIOCADDMULTI = SIOCADDMULTI; +unsigned IOCTL_SIOCDELMULTI = SIOCDELMULTI; +unsigned IOCTL_SIOCGETVIFCNT = SIOCGETVIFCNT; +unsigned IOCTL_SIOCGETSGCNT = SIOCGETSGCNT; +unsigned IOCTL_SIOCSIFMEDIA = SIOCSIFMEDIA; +unsigned IOCTL_SIOCGIFMEDIA = SIOCGIFMEDIA; +unsigned IOCTL_SIOCSIFGENERIC = SIOCSIFGENERIC; +unsigned IOCTL_SIOCGIFGENERIC = SIOCGIFGENERIC; +unsigned IOCTL_SIOCSIFPHYADDR = SIOCSIFPHYADDR; +unsigned IOCTL_SIOCGIFPSRCADDR = SIOCGIFPSRCADDR; +unsigned IOCTL_SIOCGIFPDSTADDR = SIOCGIFPDSTADDR; +unsigned IOCTL_SIOCDIFPHYADDR = SIOCDIFPHYADDR; +unsigned IOCTL_SIOCSLIFPHYADDR = SIOCSLIFPHYADDR; +unsigned IOCTL_SIOCGLIFPHYADDR = SIOCGLIFPHYADDR; unsigned IOCTL_SIOCSIFMTU = SIOCSIFMTU; -unsigned IOCTL_SIOCSIFNETMASK = SIOCSIFNETMASK; -unsigned IOCTL_SIOCSPGRP = SIOCSPGRP; -unsigned IOCTL_TIOCCONS = TIOCCONS; +unsigned IOCTL_SIOCGIFMTU = SIOCGIFMTU; +unsigned IOCTL_SIOCSDRVSPEC = SIOCSDRVSPEC; +unsigned IOCTL_SIOCGDRVSPEC = SIOCGDRVSPEC; +unsigned IOCTL_SIOCIFCREATE = SIOCIFCREATE; +unsigned IOCTL_SIOCIFDESTROY = SIOCIFDESTROY; +unsigned IOCTL_SIOCIFGCLONERS = SIOCIFGCLONERS; +unsigned IOCTL_SIOCGIFDLT = SIOCGIFDLT; +unsigned IOCTL_SIOCGIFCAP = SIOCGIFCAP; +unsigned IOCTL_SIOCSIFCAP = SIOCSIFCAP; +unsigned IOCTL_SIOCSVH = SIOCSVH; +unsigned IOCTL_SIOCGVH = SIOCGVH; +unsigned IOCTL_SIOCINITIFADDR = SIOCINITIFADDR; +unsigned IOCTL_SIOCGIFDATA = SIOCGIFDATA; +unsigned IOCTL_SIOCZIFDATA = SIOCZIFDATA; +unsigned IOCTL_SIOCGLINKSTR = SIOCGLINKSTR; +unsigned IOCTL_SIOCSLINKSTR = SIOCSLINKSTR; +unsigned IOCTL_SIOCGETHERCAP = SIOCGETHERCAP; +unsigned IOCTL_SIOCGIFINDEX = SIOCGIFINDEX; +unsigned IOCTL_SIOCSETPFSYNC = SIOCSETPFSYNC; +unsigned IOCTL_SIOCGETPFSYNC = SIOCGETPFSYNC; +unsigned IOCTL_PPS_IOC_CREATE = PPS_IOC_CREATE; +unsigned IOCTL_PPS_IOC_DESTROY = PPS_IOC_DESTROY; +unsigned IOCTL_PPS_IOC_SETPARAMS = PPS_IOC_SETPARAMS; +unsigned IOCTL_PPS_IOC_GETPARAMS = PPS_IOC_GETPARAMS; +unsigned IOCTL_PPS_IOC_GETCAP = PPS_IOC_GETCAP; +unsigned IOCTL_PPS_IOC_FETCH = PPS_IOC_FETCH; +unsigned IOCTL_PPS_IOC_KCBIND = PPS_IOC_KCBIND; 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_TIOCFLUSH = TIOCFLUSH; +unsigned IOCTL_TIOCGETA = TIOCGETA; +unsigned IOCTL_TIOCSETA = TIOCSETA; +unsigned IOCTL_TIOCSETAW = TIOCSETAW; +unsigned IOCTL_TIOCSETAF = TIOCSETAF; +unsigned IOCTL_TIOCGETD = TIOCGETD; unsigned IOCTL_TIOCSETD = TIOCSETD; +unsigned IOCTL_TIOCGLINED = TIOCGLINED; +unsigned IOCTL_TIOCSLINED = TIOCSLINED; +unsigned IOCTL_TIOCSBRK = TIOCSBRK; +unsigned IOCTL_TIOCCBRK = TIOCCBRK; +unsigned IOCTL_TIOCSDTR = TIOCSDTR; +unsigned IOCTL_TIOCCDTR = TIOCCDTR; +unsigned IOCTL_TIOCGPGRP = TIOCGPGRP; unsigned IOCTL_TIOCSPGRP = TIOCSPGRP; +unsigned IOCTL_TIOCOUTQ = TIOCOUTQ; unsigned IOCTL_TIOCSTI = TIOCSTI; +unsigned IOCTL_TIOCNOTTY = TIOCNOTTY; +unsigned IOCTL_TIOCPKT = TIOCPKT; +unsigned IOCTL_TIOCSTOP = TIOCSTOP; +unsigned IOCTL_TIOCSTART = TIOCSTART; +unsigned IOCTL_TIOCMSET = TIOCMSET; +unsigned IOCTL_TIOCMBIS = TIOCMBIS; +unsigned IOCTL_TIOCMBIC = TIOCMBIC; +unsigned IOCTL_TIOCMGET = TIOCMGET; +unsigned IOCTL_TIOCREMOTE = TIOCREMOTE; +unsigned IOCTL_TIOCGWINSZ = TIOCGWINSZ; unsigned IOCTL_TIOCSWINSZ = TIOCSWINSZ; -unsigned IOCTL_SIOCGETSGCNT = SIOCGETSGCNT; -unsigned IOCTL_SIOCGETVIFCNT = SIOCGETVIFCNT; +unsigned IOCTL_TIOCUCNTL = TIOCUCNTL; +unsigned IOCTL_TIOCSTAT = TIOCSTAT; +unsigned IOCTL_TIOCGSID = TIOCGSID; +unsigned IOCTL_TIOCCONS = TIOCCONS; +unsigned IOCTL_TIOCSCTTY = TIOCSCTTY; +unsigned IOCTL_TIOCEXT = TIOCEXT; +unsigned IOCTL_TIOCSIG = TIOCSIG; +unsigned IOCTL_TIOCDRAIN = TIOCDRAIN; +unsigned IOCTL_TIOCGFLAGS = TIOCGFLAGS; +unsigned IOCTL_TIOCSFLAGS = TIOCSFLAGS; +unsigned IOCTL_TIOCDCDTIMESTAMP = TIOCDCDTIMESTAMP; +unsigned IOCTL_TIOCRCVFRAME = TIOCRCVFRAME; +unsigned IOCTL_TIOCXMTFRAME = TIOCXMTFRAME; +unsigned IOCTL_TIOCPTMGET = TIOCPTMGET; +unsigned IOCTL_TIOCGRANTPT = TIOCGRANTPT; +unsigned IOCTL_TIOCPTSNAME = TIOCPTSNAME; +unsigned IOCTL_TIOCSQSIZE = TIOCSQSIZE; +unsigned IOCTL_TIOCGQSIZE = TIOCGQSIZE; +unsigned IOCTL_VERIEXEC_LOAD = VERIEXEC_LOAD; +unsigned IOCTL_VERIEXEC_TABLESIZE = VERIEXEC_TABLESIZE; +unsigned IOCTL_VERIEXEC_DELETE = VERIEXEC_DELETE; +unsigned IOCTL_VERIEXEC_QUERY = VERIEXEC_QUERY; +unsigned IOCTL_VERIEXEC_DUMP = VERIEXEC_DUMP; +unsigned IOCTL_VERIEXEC_FLUSH = VERIEXEC_FLUSH; +unsigned IOCTL_VIDIOC_QUERYCAP = VIDIOC_QUERYCAP; +unsigned IOCTL_VIDIOC_RESERVED = VIDIOC_RESERVED; +unsigned IOCTL_VIDIOC_ENUM_FMT = VIDIOC_ENUM_FMT; +unsigned IOCTL_VIDIOC_G_FMT = VIDIOC_G_FMT; +unsigned IOCTL_VIDIOC_S_FMT = VIDIOC_S_FMT; +unsigned IOCTL_VIDIOC_REQBUFS = VIDIOC_REQBUFS; +unsigned IOCTL_VIDIOC_QUERYBUF = VIDIOC_QUERYBUF; +unsigned IOCTL_VIDIOC_G_FBUF = VIDIOC_G_FBUF; +unsigned IOCTL_VIDIOC_S_FBUF = VIDIOC_S_FBUF; +unsigned IOCTL_VIDIOC_OVERLAY = VIDIOC_OVERLAY; +unsigned IOCTL_VIDIOC_QBUF = VIDIOC_QBUF; +unsigned IOCTL_VIDIOC_DQBUF = VIDIOC_DQBUF; +unsigned IOCTL_VIDIOC_STREAMON = VIDIOC_STREAMON; +unsigned IOCTL_VIDIOC_STREAMOFF = VIDIOC_STREAMOFF; +unsigned IOCTL_VIDIOC_G_PARM = VIDIOC_G_PARM; +unsigned IOCTL_VIDIOC_S_PARM = VIDIOC_S_PARM; +unsigned IOCTL_VIDIOC_G_STD = VIDIOC_G_STD; +unsigned IOCTL_VIDIOC_S_STD = VIDIOC_S_STD; +unsigned IOCTL_VIDIOC_ENUMSTD = VIDIOC_ENUMSTD; +unsigned IOCTL_VIDIOC_ENUMINPUT = VIDIOC_ENUMINPUT; +unsigned IOCTL_VIDIOC_G_CTRL = VIDIOC_G_CTRL; +unsigned IOCTL_VIDIOC_S_CTRL = VIDIOC_S_CTRL; +unsigned IOCTL_VIDIOC_G_TUNER = VIDIOC_G_TUNER; +unsigned IOCTL_VIDIOC_S_TUNER = VIDIOC_S_TUNER; +unsigned IOCTL_VIDIOC_G_AUDIO = VIDIOC_G_AUDIO; +unsigned IOCTL_VIDIOC_S_AUDIO = VIDIOC_S_AUDIO; +unsigned IOCTL_VIDIOC_QUERYCTRL = VIDIOC_QUERYCTRL; +unsigned IOCTL_VIDIOC_QUERYMENU = VIDIOC_QUERYMENU; +unsigned IOCTL_VIDIOC_G_INPUT = VIDIOC_G_INPUT; +unsigned IOCTL_VIDIOC_S_INPUT = VIDIOC_S_INPUT; +unsigned IOCTL_VIDIOC_G_OUTPUT = VIDIOC_G_OUTPUT; +unsigned IOCTL_VIDIOC_S_OUTPUT = VIDIOC_S_OUTPUT; +unsigned IOCTL_VIDIOC_ENUMOUTPUT = VIDIOC_ENUMOUTPUT; +unsigned IOCTL_VIDIOC_G_AUDOUT = VIDIOC_G_AUDOUT; +unsigned IOCTL_VIDIOC_S_AUDOUT = VIDIOC_S_AUDOUT; +unsigned IOCTL_VIDIOC_G_MODULATOR = VIDIOC_G_MODULATOR; +unsigned IOCTL_VIDIOC_S_MODULATOR = VIDIOC_S_MODULATOR; +unsigned IOCTL_VIDIOC_G_FREQUENCY = VIDIOC_G_FREQUENCY; +unsigned IOCTL_VIDIOC_S_FREQUENCY = VIDIOC_S_FREQUENCY; +unsigned IOCTL_VIDIOC_CROPCAP = VIDIOC_CROPCAP; +unsigned IOCTL_VIDIOC_G_CROP = VIDIOC_G_CROP; +unsigned IOCTL_VIDIOC_S_CROP = VIDIOC_S_CROP; +unsigned IOCTL_VIDIOC_G_JPEGCOMP = VIDIOC_G_JPEGCOMP; +unsigned IOCTL_VIDIOC_S_JPEGCOMP = VIDIOC_S_JPEGCOMP; +unsigned IOCTL_VIDIOC_QUERYSTD = VIDIOC_QUERYSTD; +unsigned IOCTL_VIDIOC_TRY_FMT = VIDIOC_TRY_FMT; +unsigned IOCTL_VIDIOC_ENUMAUDIO = VIDIOC_ENUMAUDIO; +unsigned IOCTL_VIDIOC_ENUMAUDOUT = VIDIOC_ENUMAUDOUT; +unsigned IOCTL_VIDIOC_G_PRIORITY = VIDIOC_G_PRIORITY; +unsigned IOCTL_VIDIOC_S_PRIORITY = VIDIOC_S_PRIORITY; +unsigned IOCTL_VIDIOC_ENUM_FRAMESIZES = VIDIOC_ENUM_FRAMESIZES; +unsigned IOCTL_VIDIOC_ENUM_FRAMEINTERVALS = VIDIOC_ENUM_FRAMEINTERVALS; +unsigned IOCTL_WDOGIOC_GMODE = WDOGIOC_GMODE; +unsigned IOCTL_WDOGIOC_SMODE = WDOGIOC_SMODE; +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_SNDCTL_DSP_RESET = SNDCTL_DSP_RESET; +unsigned IOCTL_SNDCTL_DSP_SYNC = SNDCTL_DSP_SYNC; +unsigned IOCTL_SNDCTL_DSP_SPEED = SNDCTL_DSP_SPEED; +unsigned IOCTL_SOUND_PCM_READ_RATE = SOUND_PCM_READ_RATE; +unsigned IOCTL_SNDCTL_DSP_STEREO = SNDCTL_DSP_STEREO; +unsigned IOCTL_SNDCTL_DSP_GETBLKSIZE = SNDCTL_DSP_GETBLKSIZE; +unsigned IOCTL_SNDCTL_DSP_SETFMT = SNDCTL_DSP_SETFMT; +unsigned IOCTL_SOUND_PCM_READ_BITS = SOUND_PCM_READ_BITS; +unsigned IOCTL_SNDCTL_DSP_CHANNELS = SNDCTL_DSP_CHANNELS; +unsigned IOCTL_SOUND_PCM_READ_CHANNELS = SOUND_PCM_READ_CHANNELS; +unsigned IOCTL_SOUND_PCM_WRITE_FILTER = SOUND_PCM_WRITE_FILTER; +unsigned IOCTL_SOUND_PCM_READ_FILTER = SOUND_PCM_READ_FILTER; +unsigned IOCTL_SNDCTL_DSP_POST = SNDCTL_DSP_POST; +unsigned IOCTL_SNDCTL_DSP_SUBDIVIDE = SNDCTL_DSP_SUBDIVIDE; +unsigned IOCTL_SNDCTL_DSP_SETFRAGMENT = SNDCTL_DSP_SETFRAGMENT; +unsigned IOCTL_SNDCTL_DSP_GETFMTS = SNDCTL_DSP_GETFMTS; +unsigned IOCTL_SNDCTL_DSP_GETOSPACE = SNDCTL_DSP_GETOSPACE; +unsigned IOCTL_SNDCTL_DSP_GETISPACE = SNDCTL_DSP_GETISPACE; +unsigned IOCTL_SNDCTL_DSP_NONBLOCK = SNDCTL_DSP_NONBLOCK; +unsigned IOCTL_SNDCTL_DSP_GETCAPS = SNDCTL_DSP_GETCAPS; +unsigned IOCTL_SNDCTL_DSP_GETTRIGGER = SNDCTL_DSP_GETTRIGGER; +unsigned IOCTL_SNDCTL_DSP_SETTRIGGER = SNDCTL_DSP_SETTRIGGER; +unsigned IOCTL_SNDCTL_DSP_GETIPTR = SNDCTL_DSP_GETIPTR; +unsigned IOCTL_SNDCTL_DSP_GETOPTR = SNDCTL_DSP_GETOPTR; +unsigned IOCTL_SNDCTL_DSP_MAPINBUF = SNDCTL_DSP_MAPINBUF; +unsigned IOCTL_SNDCTL_DSP_MAPOUTBUF = SNDCTL_DSP_MAPOUTBUF; +unsigned IOCTL_SNDCTL_DSP_SETSYNCRO = SNDCTL_DSP_SETSYNCRO; +unsigned IOCTL_SNDCTL_DSP_SETDUPLEX = SNDCTL_DSP_SETDUPLEX; +unsigned IOCTL_SNDCTL_DSP_PROFILE = SNDCTL_DSP_PROFILE; +unsigned IOCTL_SNDCTL_DSP_GETODELAY = SNDCTL_DSP_GETODELAY; +unsigned IOCTL_SOUND_MIXER_INFO = SOUND_MIXER_INFO; +unsigned IOCTL_SOUND_OLD_MIXER_INFO = SOUND_OLD_MIXER_INFO; +unsigned IOCTL_OSS_GETVERSION = OSS_GETVERSION; +unsigned IOCTL_SNDCTL_SYSINFO = SNDCTL_SYSINFO; +unsigned IOCTL_SNDCTL_AUDIOINFO = SNDCTL_AUDIOINFO; +unsigned IOCTL_SNDCTL_ENGINEINFO = SNDCTL_ENGINEINFO; +unsigned IOCTL_SNDCTL_DSP_GETPLAYVOL = SNDCTL_DSP_GETPLAYVOL; +unsigned IOCTL_SNDCTL_DSP_SETPLAYVOL = SNDCTL_DSP_SETPLAYVOL; +unsigned IOCTL_SNDCTL_DSP_GETRECVOL = SNDCTL_DSP_GETRECVOL; +unsigned IOCTL_SNDCTL_DSP_SETRECVOL = SNDCTL_DSP_SETRECVOL; +unsigned IOCTL_SNDCTL_DSP_SKIP = SNDCTL_DSP_SKIP; +unsigned IOCTL_SNDCTL_DSP_SILENCE = SNDCTL_DSP_SILENCE; const int si_SEGV_MAPERR = SEGV_MAPERR; const int si_SEGV_ACCERR = SEGV_ACCERR; diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.h index e7034ed6b52..eddfc124f07 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_netbsd.h @@ -23,10 +23,10 @@ #if defined(__x86_64__) #define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ - _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 608) + _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 312) #elif defined(__i386__) #define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ - _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 324) + _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 164) #endif namespace __sanitizer { @@ -36,6 +36,7 @@ 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; @@ -54,33 +55,36 @@ extern unsigned ucontext_t_sz; extern unsigned struct_rlimit_sz; extern unsigned struct_utimbuf_sz; extern unsigned struct_timespec_sz; +extern unsigned struct_sembuf_sz; -struct __sanitizer_iocb { +extern unsigned struct_kevent_sz; + +union __sanitizer_sigval { + int sival_int; + uptr sival_ptr; +}; + +struct __sanitizer_sigevent { + int sigev_notify; + int sigev_signo; + union __sanitizer_sigval sigev_value; + uptr sigev_notify_function; + uptr sigev_notify_attributes; +}; + +struct __sanitizer_aiocb { u64 aio_offset; uptr aio_buf; - long aio_nbytes; - u32 aio_fildes; - u32 aio_lio_opcode; - long aio_reqprio; -#if SANITIZER_WORDSIZE == 64 - u8 aio_sigevent[32]; -#else - u8 aio_sigevent[20]; -#endif - u32 _state; - u32 _errno; + uptr aio_nbytes; + int aio_fildes; + int aio_lio_opcode; + int aio_reqprio; + struct __sanitizer_sigevent aio_sigevent; + int _state; + int _errno; long _retval; }; -struct __sanitizer___sysctl_args { - int *name; - int nlen; - void *oldval; - uptr *oldlenp; - void *newval; - uptr newlen; -}; - struct __sanitizer_sem_t { uptr data[5]; }; @@ -107,6 +111,19 @@ struct __sanitizer_shmid_ds { void *_shm_internal; }; +struct __sanitizer_protoent { + char *p_name; + char **p_aliases; + int p_proto; +}; + +struct __sanitizer_netent { + char *n_name; + char **n_aliases; + int n_addrtype; + u32 n_net; +}; + extern unsigned struct_msqid_ds_sz; extern unsigned struct_mq_attr_sz; extern unsigned struct_timex_sz; @@ -128,9 +145,27 @@ struct __sanitizer_ifaddrs { unsigned int ifa_addrflags; }; +typedef unsigned int __sanitizer_socklen_t; + typedef unsigned __sanitizer_pthread_key_t; typedef long long __sanitizer_time_t; +typedef int __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_timespec { + __sanitizer_time_t tv_sec; + long tv_nsec; +}; struct __sanitizer_passwd { char *pw_name; @@ -186,6 +221,12 @@ struct __sanitizer_msghdr { unsigned msg_controllen; int msg_flags; }; + +struct __sanitizer_mmsghdr { + struct __sanitizer_msghdr msg_hdr; + unsigned int msg_len; +}; + struct __sanitizer_cmsghdr { unsigned cmsg_len; int cmsg_level; @@ -219,15 +260,41 @@ struct __sanitizer_sigset_t { unsigned int __bits[4]; }; +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 { - void (*handler)(int sig); - void (*sigaction)(int sig, void *siginfo, void *uctx); + __sanitizer_sighandler_ptr handler; + __sanitizer_sigactionhandler_ptr sigaction; }; __sanitizer_sigset_t sa_mask; int sa_flags; }; +extern unsigned struct_sigaltstack_sz; + +typedef unsigned int __sanitizer_sigset13_t; + +struct __sanitizer_sigaction13 { + __sanitizer_sighandler_ptr osa_handler; + __sanitizer_sigset13_t osa_mask; + int osa_flags; +}; + +struct __sanitizer_sigaltstack { + void *ss_sp; + uptr ss_size; + int ss_flags; +}; + typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t; struct __sanitizer_kernel_sigaction_t { @@ -240,9 +307,10 @@ struct __sanitizer_kernel_sigaction_t { __sanitizer_kernel_sigset_t sa_mask; }; -extern uptr sig_ign; -extern uptr sig_dfl; -extern uptr sa_siginfo; +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; @@ -284,6 +352,8 @@ struct __sanitizer_pollfd { typedef unsigned __sanitizer_nfds_t; +typedef int __sanitizer_lwpid_t; + struct __sanitizer_glob_t { uptr gl_pathc; uptr gl_matchc; @@ -303,6 +373,48 @@ extern int glob_altdirfunc; extern unsigned path_max; +extern int struct_ttyent_sz; + +extern int ptrace_pt_io; +extern int ptrace_pt_lwpinfo; +extern int ptrace_pt_set_event_mask; +extern int ptrace_pt_get_event_mask; +extern int ptrace_pt_get_process_state; +extern int ptrace_pt_set_siginfo; +extern int ptrace_pt_get_siginfo; +extern int ptrace_piod_read_d; +extern int ptrace_piod_write_d; +extern int ptrace_piod_read_i; +extern int ptrace_piod_write_i; +extern int ptrace_piod_read_auxv; +extern int ptrace_pt_setregs; +extern int ptrace_pt_getregs; +extern int ptrace_pt_setfpregs; +extern int ptrace_pt_getfpregs; +extern int ptrace_pt_setdbregs; +extern int ptrace_pt_getdbregs; + +struct __sanitizer_ptrace_io_desc { + int piod_op; + void *piod_offs; + void *piod_addr; + uptr piod_len; +}; + +struct __sanitizer_ptrace_lwpinfo { + __sanitizer_lwpid_t pl_lwpid; + int pl_event; +}; + +extern unsigned struct_ptrace_ptrace_io_desc_struct_sz; +extern unsigned struct_ptrace_ptrace_lwpinfo_struct_sz; +extern unsigned struct_ptrace_ptrace_event_struct_sz; +extern unsigned struct_ptrace_ptrace_siginfo_struct_sz; + +extern unsigned struct_ptrace_reg_struct_sz; +extern unsigned struct_ptrace_fpreg_struct_sz; +extern unsigned struct_ptrace_dbreg_struct_sz; + struct __sanitizer_wordexp_t { uptr we_wordc; char **we_wordv; @@ -311,7 +423,7 @@ struct __sanitizer_wordexp_t { uptr we_nbytes; }; -typedef void __sanitizer_FILE; +typedef char __sanitizer_FILE; #define SANITIZER_HAS_STRUCT_FILE 0 extern int shmctl_ipc_stat; @@ -336,6 +448,16 @@ struct __sanitizer_ifconf { } ifc_ifcu; }; +struct __sanitizer_ttyent { + char *ty_name; + char *ty_getty; + char *ty_type; + int ty_status; + char *ty_window; + char *ty_comment; + char *ty_class; +}; + #define IOC_NRBITS 8 #define IOC_TYPEBITS 8 #define IOC_SIZEBITS 14 @@ -360,185 +482,1713 @@ struct __sanitizer_ifconf { #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_arpreq_sz; +// ioctl request identifiers +extern unsigned struct_altqreq_sz; +extern unsigned struct_amr_user_ioctl_sz; +extern unsigned struct_ap_control_sz; +extern unsigned struct_apm_ctl_sz; +extern unsigned struct_apm_event_info_sz; +extern unsigned struct_apm_power_info_sz; +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; +extern unsigned struct_audio_info_sz; +extern unsigned struct_audio_offset_sz; +extern unsigned struct_bio_locate_sz; +extern unsigned struct_bioc_alarm_sz; +extern unsigned struct_bioc_blink_sz; +extern unsigned struct_bioc_disk_sz; +extern unsigned struct_bioc_inq_sz; +extern unsigned struct_bioc_setstate_sz; +extern unsigned struct_bioc_vol_sz; +extern unsigned struct_bioc_volops_sz; +extern unsigned struct_bktr_chnlset_sz; +extern unsigned struct_bktr_remote_sz; +extern unsigned struct_blue_conf_sz; +extern unsigned struct_blue_interface_sz; +extern unsigned struct_blue_stats_sz; +extern unsigned struct_bpf_dltlist_sz; +extern unsigned struct_bpf_program_sz; +extern unsigned struct_bpf_stat_old_sz; +extern unsigned struct_bpf_stat_sz; +extern unsigned struct_bpf_version_sz; +extern unsigned struct_btreq_sz; +extern unsigned struct_btsco_info_sz; +extern unsigned struct_buffmem_desc_sz; +extern unsigned struct_cbq_add_class_sz; +extern unsigned struct_cbq_add_filter_sz; +extern unsigned struct_cbq_delete_class_sz; +extern unsigned struct_cbq_delete_filter_sz; +extern unsigned struct_cbq_getstats_sz; +extern unsigned struct_cbq_interface_sz; +extern unsigned struct_cbq_modify_class_sz; +extern unsigned struct_ccd_ioctl_sz; +extern unsigned struct_cdnr_add_element_sz; +extern unsigned struct_cdnr_add_filter_sz; +extern unsigned struct_cdnr_add_tbmeter_sz; +extern unsigned struct_cdnr_add_trtcm_sz; +extern unsigned struct_cdnr_add_tswtcm_sz; +extern unsigned struct_cdnr_delete_element_sz; +extern unsigned struct_cdnr_delete_filter_sz; +extern unsigned struct_cdnr_get_stats_sz; +extern unsigned struct_cdnr_interface_sz; +extern unsigned struct_cdnr_modify_tbmeter_sz; +extern unsigned struct_cdnr_modify_trtcm_sz; +extern unsigned struct_cdnr_modify_tswtcm_sz; +extern unsigned struct_cdnr_tbmeter_stats_sz; +extern unsigned struct_cdnr_tcm_stats_sz; +extern unsigned struct_cgd_ioctl_sz; +extern unsigned struct_cgd_user_sz; +extern unsigned struct_changer_element_status_request_sz; +extern unsigned struct_changer_exchange_request_sz; +extern unsigned struct_changer_move_request_sz; +extern unsigned struct_changer_params_sz; +extern unsigned struct_changer_position_request_sz; +extern unsigned struct_changer_set_voltag_request_sz; +extern unsigned struct_clockctl_adjtime_sz; +extern unsigned struct_clockctl_clock_settime_sz; +extern unsigned struct_clockctl_ntp_adjtime_sz; +extern unsigned struct_clockctl_settimeofday_sz; +extern unsigned struct_cnwistats_sz; +extern unsigned struct_cnwitrail_sz; +extern unsigned struct_cnwstatus_sz; +extern unsigned struct_count_info_sz; +extern unsigned struct_cpu_ucode_sz; +extern unsigned struct_cpu_ucode_version_sz; +extern unsigned struct_crypt_kop_sz; +extern unsigned struct_crypt_mkop_sz; +extern unsigned struct_crypt_mop_sz; +extern unsigned struct_crypt_op_sz; +extern unsigned struct_crypt_result_sz; +extern unsigned struct_crypt_sfop_sz; +extern unsigned struct_crypt_sgop_sz; +extern unsigned struct_cryptret_sz; +extern unsigned struct_devdetachargs_sz; +extern unsigned struct_devlistargs_sz; +extern unsigned struct_devpmargs_sz; +extern unsigned struct_devrescanargs_sz; +extern unsigned struct_disk_badsecinfo_sz; +extern unsigned struct_disk_strategy_sz; +extern unsigned struct_disklabel_sz; +extern unsigned struct_dkbad_sz; +extern unsigned struct_dkwedge_info_sz; +extern unsigned struct_dkwedge_list_sz; +extern unsigned struct_dmio_setfunc_sz; +extern unsigned struct_dmx_pes_filter_params_sz; +extern unsigned struct_dmx_sct_filter_params_sz; +extern unsigned struct_dmx_stc_sz; +extern unsigned struct_dvb_diseqc_master_cmd_sz; +extern unsigned struct_dvb_diseqc_slave_reply_sz; +extern unsigned struct_dvb_frontend_event_sz; +extern unsigned struct_dvb_frontend_info_sz; +extern unsigned struct_dvb_frontend_parameters_sz; +extern unsigned struct_eccapreq_sz; +extern unsigned struct_fbcmap_sz; +extern unsigned struct_fbcurpos_sz; +extern unsigned struct_fbcursor_sz; +extern unsigned struct_fbgattr_sz; +extern unsigned struct_fbsattr_sz; +extern unsigned struct_fbtype_sz; +extern unsigned struct_fdformat_cmd_sz; +extern unsigned struct_fdformat_parms_sz; +extern unsigned struct_fifoq_conf_sz; +extern unsigned struct_fifoq_getstats_sz; +extern unsigned struct_fifoq_interface_sz; +extern unsigned struct_format_op_sz; +extern unsigned struct_fss_get_sz; +extern unsigned struct_fss_set_sz; +extern unsigned struct_gpio_attach_sz; +extern unsigned struct_gpio_info_sz; +extern unsigned struct_gpio_req_sz; +extern unsigned struct_gpio_set_sz; +extern unsigned struct_hfsc_add_class_sz; +extern unsigned struct_hfsc_add_filter_sz; +extern unsigned struct_hfsc_attach_sz; +extern unsigned struct_hfsc_class_stats_sz; +extern unsigned struct_hfsc_delete_class_sz; +extern unsigned struct_hfsc_delete_filter_sz; +extern unsigned struct_hfsc_interface_sz; +extern unsigned struct_hfsc_modify_class_sz; +extern unsigned struct_hpcfb_dsp_op_sz; +extern unsigned struct_hpcfb_dspconf_sz; +extern unsigned struct_hpcfb_fbconf_sz; +extern unsigned struct_if_addrprefreq_sz; +extern unsigned struct_if_clonereq_sz; +extern unsigned struct_if_laddrreq_sz; +extern unsigned struct_ifaddr_sz; +extern unsigned struct_ifaliasreq_sz; +extern unsigned struct_ifcapreq_sz; +extern unsigned struct_ifconf_sz; +extern unsigned struct_ifdatareq_sz; +extern unsigned struct_ifdrv_sz; +extern unsigned struct_ifmediareq_sz; +extern unsigned struct_ifpppcstatsreq_sz; +extern unsigned struct_ifpppstatsreq_sz; +extern unsigned struct_ifreq_sz; +extern unsigned struct_in6_addrpolicy_sz; +extern unsigned struct_in6_ndireq_sz; +extern unsigned struct_ioc_load_unload_sz; +extern unsigned struct_ioc_patch_sz; +extern unsigned struct_ioc_play_blocks_sz; +extern unsigned struct_ioc_play_msf_sz; +extern unsigned struct_ioc_play_track_sz; +extern unsigned struct_ioc_read_subchannel_sz; +extern unsigned struct_ioc_read_toc_entry_sz; +extern unsigned struct_ioc_toc_header_sz; +extern unsigned struct_ioc_vol_sz; +extern unsigned struct_ioctl_pt_sz; +extern unsigned struct_ioppt_sz; +extern unsigned struct_iovec_sz; +extern unsigned struct_ipfobj_sz; +extern unsigned struct_irda_params_sz; +extern unsigned struct_isp_fc_device_sz; +extern unsigned struct_isp_fc_tsk_mgmt_sz; +extern unsigned struct_isp_hba_device_sz; +extern unsigned struct_isv_cmd_sz; +extern unsigned struct_jobs_add_class_sz; +extern unsigned struct_jobs_add_filter_sz; +extern unsigned struct_jobs_attach_sz; +extern unsigned struct_jobs_class_stats_sz; +extern unsigned struct_jobs_delete_class_sz; +extern unsigned struct_jobs_delete_filter_sz; +extern unsigned struct_jobs_interface_sz; +extern unsigned struct_jobs_modify_class_sz; +extern unsigned struct_kbentry_sz; +extern unsigned struct_kfilter_mapping_sz; +extern unsigned struct_kiockeymap_sz; +extern unsigned struct_ksyms_gsymbol_sz; +extern unsigned struct_ksyms_gvalue_sz; +extern unsigned struct_ksyms_ogsymbol_sz; +extern unsigned struct_kttcp_io_args_sz; +extern unsigned struct_ltchars_sz; +extern unsigned struct_lua_create_sz; +extern unsigned struct_lua_info_sz; +extern unsigned struct_lua_load_sz; +extern unsigned struct_lua_require_sz; +extern unsigned struct_mbpp_param_sz; +extern unsigned struct_md_conf_sz; +extern unsigned struct_meteor_capframe_sz; +extern unsigned struct_meteor_counts_sz; +extern unsigned struct_meteor_geomet_sz; +extern unsigned struct_meteor_pixfmt_sz; +extern unsigned struct_meteor_video_sz; +extern unsigned struct_mlx_cinfo_sz; +extern unsigned struct_mlx_pause_sz; +extern unsigned struct_mlx_rebuild_request_sz; +extern unsigned struct_mlx_rebuild_status_sz; +extern unsigned struct_mlx_usercommand_sz; +extern unsigned struct_mly_user_command_sz; +extern unsigned struct_mly_user_health_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_npf_ioctl_table_sz; +extern unsigned struct_npioctl_sz; +extern unsigned struct_nvme_pt_command_sz; +extern unsigned struct_ochanger_element_status_request_sz; +extern unsigned struct_ofiocdesc_sz; +extern unsigned struct_okiockey_sz; +extern unsigned struct_ortentry_sz; +extern unsigned struct_oscsi_addr_sz; +extern unsigned struct_oss_audioinfo_sz; +extern unsigned struct_oss_sysinfo_sz; +extern unsigned struct_pciio_bdf_cfgreg_sz; +extern unsigned struct_pciio_businfo_sz; +extern unsigned struct_pciio_cfgreg_sz; +extern unsigned struct_pciio_drvname_sz; +extern unsigned struct_pciio_drvnameonbus_sz; +extern unsigned struct_pcvtid_sz; +extern unsigned struct_pf_osfp_ioctl_sz; +extern unsigned struct_pf_status_sz; +extern unsigned struct_pfioc_altq_sz; +extern unsigned struct_pfioc_if_sz; +extern unsigned struct_pfioc_iface_sz; +extern unsigned struct_pfioc_limit_sz; +extern unsigned struct_pfioc_natlook_sz; +extern unsigned struct_pfioc_pooladdr_sz; +extern unsigned struct_pfioc_qstats_sz; +extern unsigned struct_pfioc_rule_sz; +extern unsigned struct_pfioc_ruleset_sz; +extern unsigned struct_pfioc_src_node_kill_sz; +extern unsigned struct_pfioc_src_nodes_sz; +extern unsigned struct_pfioc_state_kill_sz; +extern unsigned struct_pfioc_state_sz; +extern unsigned struct_pfioc_states_sz; +extern unsigned struct_pfioc_table_sz; +extern unsigned struct_pfioc_tm_sz; +extern unsigned struct_pfioc_trans_sz; +extern unsigned struct_plistref_sz; +extern unsigned struct_power_type_sz; +extern unsigned struct_ppp_idle_sz; +extern unsigned struct_ppp_option_data_sz; +extern unsigned struct_ppp_rawin_sz; +extern unsigned struct_pppoeconnectionstate_sz; +extern unsigned struct_pppoediscparms_sz; +extern unsigned struct_priq_add_class_sz; +extern unsigned struct_priq_add_filter_sz; +extern unsigned struct_priq_class_stats_sz; +extern unsigned struct_priq_delete_class_sz; +extern unsigned struct_priq_delete_filter_sz; +extern unsigned struct_priq_interface_sz; +extern unsigned struct_priq_modify_class_sz; +extern unsigned struct_ptmget_sz; +extern unsigned struct_pvctxreq_sz; +extern unsigned struct_radio_info_sz; +extern unsigned struct_red_conf_sz; +extern unsigned struct_red_interface_sz; +extern unsigned struct_red_stats_sz; +extern unsigned struct_redparams_sz; +extern unsigned struct_rf_pmparams_sz; +extern unsigned struct_rf_pmstat_sz; +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; +extern unsigned struct_scbusioscan_args_sz; +extern unsigned struct_scsi_addr_sz; extern unsigned struct_seq_event_rec_sz; -extern unsigned struct_synth_info_sz; -extern unsigned struct_vt_mode_sz; -extern unsigned struct_audio_buf_info_sz; -extern unsigned struct_ppp_stats_sz; +extern unsigned struct_session_op_sz; +extern unsigned struct_sgttyb_sz; extern unsigned struct_sioc_sg_req_sz; extern unsigned struct_sioc_vif_req_sz; +extern unsigned struct_smbioc_flags_sz; +extern unsigned struct_smbioc_lookup_sz; +extern unsigned struct_smbioc_oshare_sz; +extern unsigned struct_smbioc_ossn_sz; +extern unsigned struct_smbioc_rq_sz; +extern unsigned struct_smbioc_rw_sz; +extern unsigned struct_spppauthcfg_sz; +extern unsigned struct_spppauthfailuresettings_sz; +extern unsigned struct_spppauthfailurestats_sz; +extern unsigned struct_spppdnsaddrs_sz; +extern unsigned struct_spppdnssettings_sz; +extern unsigned struct_spppidletimeout_sz; +extern unsigned struct_spppkeepalivesettings_sz; +extern unsigned struct_sppplcpcfg_sz; +extern unsigned struct_spppstatus_sz; +extern unsigned struct_spppstatusncp_sz; +extern unsigned struct_srt_rt_sz; +extern unsigned struct_stic_xinfo_sz; +extern unsigned struct_sun_dkctlr_sz; +extern unsigned struct_sun_dkgeom_sz; +extern unsigned struct_sun_dkpart_sz; +extern unsigned struct_synth_info_sz; +extern unsigned struct_tbrreq_sz; +extern unsigned struct_tchars_sz; +extern unsigned struct_termios_sz; +extern unsigned struct_timeval_sz; +extern unsigned struct_twe_drivecommand_sz; +extern unsigned struct_twe_paramcommand_sz; +extern unsigned struct_twe_usercommand_sz; +extern unsigned struct_ukyopon_identify_sz; +extern unsigned struct_urio_command_sz; +extern unsigned struct_usb_alt_interface_sz; +extern unsigned struct_usb_bulk_ra_wb_opt_sz; +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; +extern unsigned struct_usb_device_info_old_sz; +extern unsigned struct_usb_device_info_sz; +extern unsigned struct_usb_device_stats_sz; +extern unsigned struct_usb_endpoint_desc_sz; +extern unsigned struct_usb_full_desc_sz; +extern unsigned struct_usb_interface_desc_sz; +extern unsigned struct_usb_string_desc_sz; +extern unsigned struct_utoppy_readfile_sz; +extern unsigned struct_utoppy_rename_sz; +extern unsigned struct_utoppy_stats_sz; +extern unsigned struct_utoppy_writefile_sz; +extern unsigned struct_v4l2_audio_sz; +extern unsigned struct_v4l2_audioout_sz; +extern unsigned struct_v4l2_buffer_sz; +extern unsigned struct_v4l2_capability_sz; +extern unsigned struct_v4l2_control_sz; +extern unsigned struct_v4l2_crop_sz; +extern unsigned struct_v4l2_cropcap_sz; +extern unsigned struct_v4l2_fmtdesc_sz; +extern unsigned struct_v4l2_format_sz; +extern unsigned struct_v4l2_framebuffer_sz; +extern unsigned struct_v4l2_frequency_sz; +extern unsigned struct_v4l2_frmivalenum_sz; +extern unsigned struct_v4l2_frmsizeenum_sz; +extern unsigned struct_v4l2_input_sz; +extern unsigned struct_v4l2_jpegcompression_sz; +extern unsigned struct_v4l2_modulator_sz; +extern unsigned struct_v4l2_output_sz; +extern unsigned struct_v4l2_queryctrl_sz; +extern unsigned struct_v4l2_querymenu_sz; +extern unsigned struct_v4l2_requestbuffers_sz; +extern unsigned struct_v4l2_standard_sz; +extern unsigned struct_v4l2_streamparm_sz; +extern unsigned struct_v4l2_tuner_sz; +extern unsigned struct_vnd_ioctl_sz; +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_wfq_conf_sz; +extern unsigned struct_wfq_getqid_sz; +extern unsigned struct_wfq_getstats_sz; +extern unsigned struct_wfq_interface_sz; +extern unsigned struct_wfq_setweight_sz; +extern unsigned struct_winsize_sz; +extern unsigned struct_wscons_event_sz; +extern unsigned struct_wsdisplay_addscreendata_sz; +extern unsigned struct_wsdisplay_char_sz; +extern unsigned struct_wsdisplay_cmap_sz; +extern unsigned struct_wsdisplay_curpos_sz; +extern unsigned struct_wsdisplay_cursor_sz; +extern unsigned struct_wsdisplay_delscreendata_sz; +extern unsigned struct_wsdisplay_fbinfo_sz; +extern unsigned struct_wsdisplay_font_sz; +extern unsigned struct_wsdisplay_kbddata_sz; +extern unsigned struct_wsdisplay_msgattrs_sz; +extern unsigned struct_wsdisplay_param_sz; +extern unsigned struct_wsdisplay_scroll_data_sz; +extern unsigned struct_wsdisplay_usefontdata_sz; +extern unsigned struct_wsdisplayio_blit_sz; +extern unsigned struct_wsdisplayio_bus_id_sz; +extern unsigned struct_wsdisplayio_edid_info_sz; +extern unsigned struct_wsdisplayio_fbinfo_sz; +extern unsigned struct_wskbd_bell_data_sz; +extern unsigned struct_wskbd_keyrepeat_data_sz; +extern unsigned struct_wskbd_map_data_sz; +extern unsigned struct_wskbd_scroll_data_sz; +extern unsigned struct_wsmouse_calibcoords_sz; +extern unsigned struct_wsmouse_id_sz; +extern unsigned struct_wsmouse_repeat_sz; +extern unsigned struct_wsmux_device_list_sz; +extern unsigned struct_wsmux_device_sz; +extern unsigned struct_xd_iocmd_sz; + +extern unsigned struct_scsireq_sz; +extern unsigned struct_tone_sz; +extern unsigned union_twe_statrequest_sz; +extern unsigned struct_usb_device_descriptor_sz; +extern unsigned struct_vt_mode_sz; +extern unsigned struct__old_mixer_info_sz; +extern unsigned struct__agp_allocate_sz; +extern unsigned struct__agp_bind_sz; +extern unsigned struct__agp_info_sz; +extern unsigned struct__agp_setup_sz; +extern unsigned struct__agp_unbind_sz; +extern unsigned struct_atareq_sz; +extern unsigned struct_cpustate_sz; +extern unsigned struct_dmx_caps_sz; +extern unsigned enum_dmx_source_sz; +extern unsigned union_dvd_authinfo_sz; +extern unsigned union_dvd_struct_sz; +extern unsigned enum_v4l2_priority_sz; +extern unsigned struct_envsys_basic_info_sz; +extern unsigned struct_envsys_tre_data_sz; +extern unsigned enum_fe_sec_mini_cmd_sz; +extern unsigned enum_fe_sec_tone_mode_sz; +extern unsigned enum_fe_sec_voltage_sz; +extern unsigned enum_fe_status_sz; +extern unsigned struct_gdt_ctrt_sz; +extern unsigned struct_gdt_event_sz; +extern unsigned struct_gdt_osv_sz; +extern unsigned struct_gdt_rescan_sz; +extern unsigned struct_gdt_statist_sz; +extern unsigned struct_gdt_ucmd_sz; +extern unsigned struct_iscsi_conn_status_parameters_sz; +extern unsigned struct_iscsi_get_version_parameters_sz; +extern unsigned struct_iscsi_iocommand_parameters_sz; +extern unsigned struct_iscsi_login_parameters_sz; +extern unsigned struct_iscsi_logout_parameters_sz; +extern unsigned struct_iscsi_register_event_parameters_sz; +extern unsigned struct_iscsi_remove_parameters_sz; +extern unsigned struct_iscsi_send_targets_parameters_sz; +extern unsigned struct_iscsi_set_node_name_parameters_sz; +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_mixer_ctrl_sz; +extern unsigned struct_mixer_devinfo_sz; +extern unsigned struct_mpu_command_rec_sz; +extern unsigned struct_rndstat_sz; +extern unsigned struct_rndstat_name_sz; +extern unsigned struct_rndctl_sz; +extern unsigned struct_rnddata_sz; +extern unsigned struct_rndpoolstat_sz; +extern unsigned struct_rndstat_est_sz; +extern unsigned struct_rndstat_est_name_sz; +extern unsigned struct_pps_params_sz; +extern unsigned struct_pps_info_sz; +extern unsigned struct_mixer_info_sz; +extern unsigned struct_RF_SparetWait_sz; +extern unsigned struct_RF_ComponentLabel_sz; +extern unsigned struct_RF_SingleComponent_sz; +extern unsigned struct_RF_ProgressInfo_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_AFM_ADDFMAP; +extern unsigned IOCTL_AFM_DELFMAP; +extern unsigned IOCTL_AFM_CLEANFMAP; +extern unsigned IOCTL_AFM_GETFMAP; +extern unsigned IOCTL_ALTQGTYPE; +extern unsigned IOCTL_ALTQTBRSET; +extern unsigned IOCTL_ALTQTBRGET; +extern unsigned IOCTL_BLUE_IF_ATTACH; +extern unsigned IOCTL_BLUE_IF_DETACH; +extern unsigned IOCTL_BLUE_ENABLE; +extern unsigned IOCTL_BLUE_DISABLE; +extern unsigned IOCTL_BLUE_CONFIG; +extern unsigned IOCTL_BLUE_GETSTATS; +extern unsigned IOCTL_CBQ_IF_ATTACH; +extern unsigned IOCTL_CBQ_IF_DETACH; +extern unsigned IOCTL_CBQ_ENABLE; +extern unsigned IOCTL_CBQ_DISABLE; +extern unsigned IOCTL_CBQ_CLEAR_HIERARCHY; +extern unsigned IOCTL_CBQ_ADD_CLASS; +extern unsigned IOCTL_CBQ_DEL_CLASS; +extern unsigned IOCTL_CBQ_MODIFY_CLASS; +extern unsigned IOCTL_CBQ_ADD_FILTER; +extern unsigned IOCTL_CBQ_DEL_FILTER; +extern unsigned IOCTL_CBQ_GETSTATS; +extern unsigned IOCTL_CDNR_IF_ATTACH; +extern unsigned IOCTL_CDNR_IF_DETACH; +extern unsigned IOCTL_CDNR_ENABLE; +extern unsigned IOCTL_CDNR_DISABLE; +extern unsigned IOCTL_CDNR_ADD_FILTER; +extern unsigned IOCTL_CDNR_DEL_FILTER; +extern unsigned IOCTL_CDNR_GETSTATS; +extern unsigned IOCTL_CDNR_ADD_ELEM; +extern unsigned IOCTL_CDNR_DEL_ELEM; +extern unsigned IOCTL_CDNR_ADD_TBM; +extern unsigned IOCTL_CDNR_MOD_TBM; +extern unsigned IOCTL_CDNR_TBM_STATS; +extern unsigned IOCTL_CDNR_ADD_TCM; +extern unsigned IOCTL_CDNR_MOD_TCM; +extern unsigned IOCTL_CDNR_TCM_STATS; +extern unsigned IOCTL_CDNR_ADD_TSW; +extern unsigned IOCTL_CDNR_MOD_TSW; +extern unsigned IOCTL_FIFOQ_IF_ATTACH; +extern unsigned IOCTL_FIFOQ_IF_DETACH; +extern unsigned IOCTL_FIFOQ_ENABLE; +extern unsigned IOCTL_FIFOQ_DISABLE; +extern unsigned IOCTL_FIFOQ_CONFIG; +extern unsigned IOCTL_FIFOQ_GETSTATS; +extern unsigned IOCTL_HFSC_IF_ATTACH; +extern unsigned IOCTL_HFSC_IF_DETACH; +extern unsigned IOCTL_HFSC_ENABLE; +extern unsigned IOCTL_HFSC_DISABLE; +extern unsigned IOCTL_HFSC_CLEAR_HIERARCHY; +extern unsigned IOCTL_HFSC_ADD_CLASS; +extern unsigned IOCTL_HFSC_DEL_CLASS; +extern unsigned IOCTL_HFSC_MOD_CLASS; +extern unsigned IOCTL_HFSC_ADD_FILTER; +extern unsigned IOCTL_HFSC_DEL_FILTER; +extern unsigned IOCTL_HFSC_GETSTATS; +extern unsigned IOCTL_JOBS_IF_ATTACH; +extern unsigned IOCTL_JOBS_IF_DETACH; +extern unsigned IOCTL_JOBS_ENABLE; +extern unsigned IOCTL_JOBS_DISABLE; +extern unsigned IOCTL_JOBS_CLEAR; +extern unsigned IOCTL_JOBS_ADD_CLASS; +extern unsigned IOCTL_JOBS_DEL_CLASS; +extern unsigned IOCTL_JOBS_MOD_CLASS; +extern unsigned IOCTL_JOBS_ADD_FILTER; +extern unsigned IOCTL_JOBS_DEL_FILTER; +extern unsigned IOCTL_JOBS_GETSTATS; +extern unsigned IOCTL_PRIQ_IF_ATTACH; +extern unsigned IOCTL_PRIQ_IF_DETACH; +extern unsigned IOCTL_PRIQ_ENABLE; +extern unsigned IOCTL_PRIQ_DISABLE; +extern unsigned IOCTL_PRIQ_CLEAR; +extern unsigned IOCTL_PRIQ_ADD_CLASS; +extern unsigned IOCTL_PRIQ_DEL_CLASS; +extern unsigned IOCTL_PRIQ_MOD_CLASS; +extern unsigned IOCTL_PRIQ_ADD_FILTER; +extern unsigned IOCTL_PRIQ_DEL_FILTER; +extern unsigned IOCTL_PRIQ_GETSTATS; +extern unsigned IOCTL_RED_IF_ATTACH; +extern unsigned IOCTL_RED_IF_DETACH; +extern unsigned IOCTL_RED_ENABLE; +extern unsigned IOCTL_RED_DISABLE; +extern unsigned IOCTL_RED_CONFIG; +extern unsigned IOCTL_RED_GETSTATS; +extern unsigned IOCTL_RED_SETDEFAULTS; +extern unsigned IOCTL_RIO_IF_ATTACH; +extern unsigned IOCTL_RIO_IF_DETACH; +extern unsigned IOCTL_RIO_ENABLE; +extern unsigned IOCTL_RIO_DISABLE; +extern unsigned IOCTL_RIO_CONFIG; +extern unsigned IOCTL_RIO_GETSTATS; +extern unsigned IOCTL_RIO_SETDEFAULTS; +extern unsigned IOCTL_WFQ_IF_ATTACH; +extern unsigned IOCTL_WFQ_IF_DETACH; +extern unsigned IOCTL_WFQ_ENABLE; +extern unsigned IOCTL_WFQ_DISABLE; +extern unsigned IOCTL_WFQ_CONFIG; +extern unsigned IOCTL_WFQ_GET_STATS; +extern unsigned IOCTL_WFQ_GET_QID; +extern unsigned IOCTL_WFQ_SET_WEIGHT; +extern unsigned IOCTL_CRIOGET; +extern unsigned IOCTL_CIOCFSESSION; +extern unsigned IOCTL_CIOCKEY; +extern unsigned IOCTL_CIOCNFKEYM; +extern unsigned IOCTL_CIOCNFSESSION; +extern unsigned IOCTL_CIOCNCRYPTRETM; +extern unsigned IOCTL_CIOCNCRYPTRET; +extern unsigned IOCTL_CIOCGSESSION; +extern unsigned IOCTL_CIOCNGSESSION; +extern unsigned IOCTL_CIOCCRYPT; +extern unsigned IOCTL_CIOCNCRYPTM; +extern unsigned IOCTL_CIOCASYMFEAT; +extern unsigned IOCTL_APM_IOC_REJECT; +extern unsigned IOCTL_APM_IOC_STANDBY; +extern unsigned IOCTL_APM_IOC_SUSPEND; +extern unsigned IOCTL_OAPM_IOC_GETPOWER; +extern unsigned IOCTL_APM_IOC_GETPOWER; +extern unsigned IOCTL_APM_IOC_NEXTEVENT; +extern unsigned IOCTL_APM_IOC_DEV_CTL; +extern unsigned IOCTL_NETBSD_DM_IOCTL; +extern unsigned IOCTL_DMIO_SETFUNC; +extern unsigned IOCTL_DMX_START; +extern unsigned IOCTL_DMX_STOP; +extern unsigned IOCTL_DMX_SET_FILTER; +extern unsigned IOCTL_DMX_SET_PES_FILTER; +extern unsigned IOCTL_DMX_SET_BUFFER_SIZE; +extern unsigned IOCTL_DMX_GET_STC; +extern unsigned IOCTL_DMX_ADD_PID; +extern unsigned IOCTL_DMX_REMOVE_PID; +extern unsigned IOCTL_DMX_GET_CAPS; +extern unsigned IOCTL_DMX_SET_SOURCE; +extern unsigned IOCTL_FE_READ_STATUS; +extern unsigned IOCTL_FE_READ_BER; +extern unsigned IOCTL_FE_READ_SNR; +extern unsigned IOCTL_FE_READ_SIGNAL_STRENGTH; +extern unsigned IOCTL_FE_READ_UNCORRECTED_BLOCKS; +extern unsigned IOCTL_FE_SET_FRONTEND; +extern unsigned IOCTL_FE_GET_FRONTEND; +extern unsigned IOCTL_FE_GET_EVENT; +extern unsigned IOCTL_FE_GET_INFO; +extern unsigned IOCTL_FE_DISEQC_RESET_OVERLOAD; +extern unsigned IOCTL_FE_DISEQC_SEND_MASTER_CMD; +extern unsigned IOCTL_FE_DISEQC_RECV_SLAVE_REPLY; +extern unsigned IOCTL_FE_DISEQC_SEND_BURST; +extern unsigned IOCTL_FE_SET_TONE; +extern unsigned IOCTL_FE_SET_VOLTAGE; +extern unsigned IOCTL_FE_ENABLE_HIGH_LNB_VOLTAGE; +extern unsigned IOCTL_FE_SET_FRONTEND_TUNE_MODE; +extern unsigned IOCTL_FE_DISHNETWORK_SEND_LEGACY_CMD; +extern unsigned IOCTL_FILEMON_SET_FD; +extern unsigned IOCTL_FILEMON_SET_PID; +extern unsigned IOCTL_HDAUDIO_FGRP_INFO; +extern unsigned IOCTL_HDAUDIO_FGRP_GETCONFIG; +extern unsigned IOCTL_HDAUDIO_FGRP_SETCONFIG; +extern unsigned IOCTL_HDAUDIO_FGRP_WIDGET_INFO; +extern unsigned IOCTL_HDAUDIO_FGRP_CODEC_INFO; +extern unsigned IOCTL_HDAUDIO_AFG_WIDGET_INFO; +extern unsigned IOCTL_HDAUDIO_AFG_CODEC_INFO; +extern unsigned IOCTL_CEC_GET_PHYS_ADDR; +extern unsigned IOCTL_CEC_GET_LOG_ADDRS; +extern unsigned IOCTL_CEC_SET_LOG_ADDRS; +extern unsigned IOCTL_CEC_GET_VENDOR_ID; +extern unsigned IOCTL_HPCFBIO_GCONF; +extern unsigned IOCTL_HPCFBIO_SCONF; +extern unsigned IOCTL_HPCFBIO_GDSPCONF; +extern unsigned IOCTL_HPCFBIO_SDSPCONF; +extern unsigned IOCTL_HPCFBIO_GOP; +extern unsigned IOCTL_HPCFBIO_SOP; +extern unsigned IOCTL_IOPIOCPT; +extern unsigned IOCTL_IOPIOCGLCT; +extern unsigned IOCTL_IOPIOCGSTATUS; +extern unsigned IOCTL_IOPIOCRECONFIG; +extern unsigned IOCTL_IOPIOCGTIDMAP; +extern unsigned IOCTL_SIOCGATHSTATS; +extern unsigned IOCTL_SIOCGATHDIAG; +extern unsigned IOCTL_METEORCAPTUR; +extern unsigned IOCTL_METEORCAPFRM; +extern unsigned IOCTL_METEORSETGEO; +extern unsigned IOCTL_METEORGETGEO; +extern unsigned IOCTL_METEORSTATUS; +extern unsigned IOCTL_METEORSHUE; +extern unsigned IOCTL_METEORGHUE; +extern unsigned IOCTL_METEORSFMT; +extern unsigned IOCTL_METEORGFMT; +extern unsigned IOCTL_METEORSINPUT; +extern unsigned IOCTL_METEORGINPUT; +extern unsigned IOCTL_METEORSCHCV; +extern unsigned IOCTL_METEORGCHCV; +extern unsigned IOCTL_METEORSCOUNT; +extern unsigned IOCTL_METEORGCOUNT; +extern unsigned IOCTL_METEORSFPS; +extern unsigned IOCTL_METEORGFPS; +extern unsigned IOCTL_METEORSSIGNAL; +extern unsigned IOCTL_METEORGSIGNAL; +extern unsigned IOCTL_METEORSVIDEO; +extern unsigned IOCTL_METEORGVIDEO; +extern unsigned IOCTL_METEORSBRIG; +extern unsigned IOCTL_METEORGBRIG; +extern unsigned IOCTL_METEORSCSAT; +extern unsigned IOCTL_METEORGCSAT; +extern unsigned IOCTL_METEORSCONT; +extern unsigned IOCTL_METEORGCONT; +extern unsigned IOCTL_METEORSHWS; +extern unsigned IOCTL_METEORGHWS; +extern unsigned IOCTL_METEORSVWS; +extern unsigned IOCTL_METEORGVWS; +extern unsigned IOCTL_METEORSTS; +extern unsigned IOCTL_METEORGTS; +extern unsigned IOCTL_TVTUNER_SETCHNL; +extern unsigned IOCTL_TVTUNER_GETCHNL; +extern unsigned IOCTL_TVTUNER_SETTYPE; +extern unsigned IOCTL_TVTUNER_GETTYPE; +extern unsigned IOCTL_TVTUNER_GETSTATUS; +extern unsigned IOCTL_TVTUNER_SETFREQ; +extern unsigned IOCTL_TVTUNER_GETFREQ; +extern unsigned IOCTL_TVTUNER_SETAFC; +extern unsigned IOCTL_TVTUNER_GETAFC; +extern unsigned IOCTL_RADIO_SETMODE; +extern unsigned IOCTL_RADIO_GETMODE; +extern unsigned IOCTL_RADIO_SETFREQ; +extern unsigned IOCTL_RADIO_GETFREQ; +extern unsigned IOCTL_METEORSACTPIXFMT; +extern unsigned IOCTL_METEORGACTPIXFMT; +extern unsigned IOCTL_METEORGSUPPIXFMT; +extern unsigned IOCTL_TVTUNER_GETCHNLSET; +extern unsigned IOCTL_REMOTE_GETKEY; +extern unsigned IOCTL_GDT_IOCTL_GENERAL; +extern unsigned IOCTL_GDT_IOCTL_DRVERS; +extern unsigned IOCTL_GDT_IOCTL_CTRTYPE; +extern unsigned IOCTL_GDT_IOCTL_OSVERS; +extern unsigned IOCTL_GDT_IOCTL_CTRCNT; +extern unsigned IOCTL_GDT_IOCTL_EVENT; +extern unsigned IOCTL_GDT_IOCTL_STATIST; +extern unsigned IOCTL_GDT_IOCTL_RESCAN; +extern unsigned IOCTL_ISP_SDBLEV; +extern unsigned IOCTL_ISP_RESETHBA; +extern unsigned IOCTL_ISP_RESCAN; +extern unsigned IOCTL_ISP_SETROLE; +extern unsigned IOCTL_ISP_GETROLE; +extern unsigned IOCTL_ISP_GET_STATS; +extern unsigned IOCTL_ISP_CLR_STATS; +extern unsigned IOCTL_ISP_FC_LIP; +extern unsigned IOCTL_ISP_FC_GETDINFO; +extern unsigned IOCTL_ISP_GET_FW_CRASH_DUMP; +extern unsigned IOCTL_ISP_FORCE_CRASH_DUMP; +extern unsigned IOCTL_ISP_FC_GETHINFO; +extern unsigned IOCTL_ISP_TSK_MGMT; +extern unsigned IOCTL_ISP_FC_GETDLIST; +extern unsigned IOCTL_MLXD_STATUS; +extern unsigned IOCTL_MLXD_CHECKASYNC; +extern unsigned IOCTL_MLXD_DETACH; +extern unsigned IOCTL_MLX_RESCAN_DRIVES; +extern unsigned IOCTL_MLX_PAUSE_CHANNEL; +extern unsigned IOCTL_MLX_COMMAND; +extern unsigned IOCTL_MLX_REBUILDASYNC; +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_IRDA_RESET_PARAMS; +extern unsigned IOCTL_IRDA_SET_PARAMS; +extern unsigned IOCTL_IRDA_GET_SPEEDMASK; +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; +extern unsigned IOCTL_ISCSI_LOGIN; +extern unsigned IOCTL_ISCSI_LOGOUT; +extern unsigned IOCTL_ISCSI_ADD_CONNECTION; +extern unsigned IOCTL_ISCSI_RESTORE_CONNECTION; +extern unsigned IOCTL_ISCSI_REMOVE_CONNECTION; +extern unsigned IOCTL_ISCSI_CONNECTION_STATUS; +extern unsigned IOCTL_ISCSI_SEND_TARGETS; +extern unsigned IOCTL_ISCSI_SET_NODE_NAME; +extern unsigned IOCTL_ISCSI_IO_COMMAND; +extern unsigned IOCTL_ISCSI_REGISTER_EVENT; +extern unsigned IOCTL_ISCSI_DEREGISTER_EVENT; +extern unsigned IOCTL_ISCSI_WAIT_EVENT; +extern unsigned IOCTL_ISCSI_POLL_EVENT; +extern unsigned IOCTL_OFIOCGET; +extern unsigned IOCTL_OFIOCSET; +extern unsigned IOCTL_OFIOCNEXTPROP; +extern unsigned IOCTL_OFIOCGETOPTNODE; +extern unsigned IOCTL_OFIOCGETNEXT; +extern unsigned IOCTL_OFIOCGETCHILD; +extern unsigned IOCTL_OFIOCFINDDEVICE; +extern unsigned IOCTL_AMR_IO_VERSION; +extern unsigned IOCTL_AMR_IO_COMMAND; +extern unsigned IOCTL_MLYIO_COMMAND; +extern unsigned IOCTL_MLYIO_HEALTH; +extern unsigned IOCTL_PCI_IOC_CFGREAD; +extern unsigned IOCTL_PCI_IOC_CFGWRITE; +extern unsigned IOCTL_PCI_IOC_BDF_CFGREAD; +extern unsigned IOCTL_PCI_IOC_BDF_CFGWRITE; +extern unsigned IOCTL_PCI_IOC_BUSINFO; +extern unsigned IOCTL_PCI_IOC_DRVNAME; +extern unsigned IOCTL_PCI_IOC_DRVNAMEONBUS; +extern unsigned IOCTL_TWEIO_COMMAND; +extern unsigned IOCTL_TWEIO_STATS; +extern unsigned IOCTL_TWEIO_AEN_POLL; +extern unsigned IOCTL_TWEIO_AEN_WAIT; +extern unsigned IOCTL_TWEIO_SET_PARAM; +extern unsigned IOCTL_TWEIO_GET_PARAM; +extern unsigned IOCTL_TWEIO_RESET; +extern unsigned IOCTL_TWEIO_ADD_UNIT; +extern unsigned IOCTL_TWEIO_DEL_UNIT; +extern unsigned IOCTL_SIOCSCNWDOMAIN; +extern unsigned IOCTL_SIOCGCNWDOMAIN; +extern unsigned IOCTL_SIOCSCNWKEY; +extern unsigned IOCTL_SIOCGCNWSTATUS; +extern unsigned IOCTL_SIOCGCNWSTATS; +extern unsigned IOCTL_SIOCGCNWTRAIL; +extern unsigned IOCTL_SIOCGRAYSIGLEV; +extern unsigned IOCTL_RAIDFRAME_SHUTDOWN; +extern unsigned IOCTL_RAIDFRAME_TUR; +extern unsigned IOCTL_RAIDFRAME_FAIL_DISK; +extern unsigned IOCTL_RAIDFRAME_CHECK_RECON_STATUS; +extern unsigned IOCTL_RAIDFRAME_REWRITEPARITY; +extern unsigned IOCTL_RAIDFRAME_COPYBACK; +extern unsigned IOCTL_RAIDFRAME_SPARET_WAIT; +extern unsigned IOCTL_RAIDFRAME_SEND_SPARET; +extern unsigned IOCTL_RAIDFRAME_ABORT_SPARET_WAIT; +extern unsigned IOCTL_RAIDFRAME_START_ATRACE; +extern unsigned IOCTL_RAIDFRAME_STOP_ATRACE; +extern unsigned IOCTL_RAIDFRAME_GET_SIZE; +extern unsigned IOCTL_RAIDFRAME_RESET_ACCTOTALS; +extern unsigned IOCTL_RAIDFRAME_KEEP_ACCTOTALS; +extern unsigned IOCTL_RAIDFRAME_GET_COMPONENT_LABEL; +extern unsigned IOCTL_RAIDFRAME_SET_COMPONENT_LABEL; +extern unsigned IOCTL_RAIDFRAME_INIT_LABELS; +extern unsigned IOCTL_RAIDFRAME_ADD_HOT_SPARE; +extern unsigned IOCTL_RAIDFRAME_REMOVE_HOT_SPARE; +extern unsigned IOCTL_RAIDFRAME_REBUILD_IN_PLACE; +extern unsigned IOCTL_RAIDFRAME_CHECK_PARITY; +extern unsigned IOCTL_RAIDFRAME_CHECK_PARITYREWRITE_STATUS; +extern unsigned IOCTL_RAIDFRAME_CHECK_COPYBACK_STATUS; +extern unsigned IOCTL_RAIDFRAME_SET_AUTOCONFIG; +extern unsigned IOCTL_RAIDFRAME_SET_ROOT; +extern unsigned IOCTL_RAIDFRAME_DELETE_COMPONENT; +extern unsigned IOCTL_RAIDFRAME_INCORPORATE_HOT_SPARE; +extern unsigned IOCTL_RAIDFRAME_CHECK_RECON_STATUS_EXT; +extern unsigned IOCTL_RAIDFRAME_CHECK_PARITYREWRITE_STATUS_EXT; +extern unsigned IOCTL_RAIDFRAME_CHECK_COPYBACK_STATUS_EXT; +extern unsigned IOCTL_RAIDFRAME_CONFIGURE; +extern unsigned IOCTL_RAIDFRAME_GET_INFO; +extern unsigned IOCTL_RAIDFRAME_PARITYMAP_STATUS; +extern unsigned IOCTL_RAIDFRAME_PARITYMAP_GET_DISABLE; +extern unsigned IOCTL_RAIDFRAME_PARITYMAP_SET_DISABLE; +extern unsigned IOCTL_RAIDFRAME_PARITYMAP_SET_PARAMS; +extern unsigned IOCTL_RAIDFRAME_SET_LAST_UNIT; +extern unsigned IOCTL_MBPPIOCSPARAM; +extern unsigned IOCTL_MBPPIOCGPARAM; +extern unsigned IOCTL_MBPPIOCGSTAT; +extern unsigned IOCTL_SESIOC_GETNOBJ; +extern unsigned IOCTL_SESIOC_GETOBJMAP; +extern unsigned IOCTL_SESIOC_GETENCSTAT; +extern unsigned IOCTL_SESIOC_SETENCSTAT; +extern unsigned IOCTL_SESIOC_GETOBJSTAT; +extern unsigned IOCTL_SESIOC_SETOBJSTAT; +extern unsigned IOCTL_SESIOC_GETTEXT; +extern unsigned IOCTL_SESIOC_INIT; +extern unsigned IOCTL_SUN_DKIOCGGEOM; +extern unsigned IOCTL_SUN_DKIOCINFO; +extern unsigned IOCTL_SUN_DKIOCGPART; +extern unsigned IOCTL_FBIOGTYPE; +extern unsigned IOCTL_FBIOPUTCMAP; +extern unsigned IOCTL_FBIOGETCMAP; +extern unsigned IOCTL_FBIOGATTR; +extern unsigned IOCTL_FBIOSVIDEO; +extern unsigned IOCTL_FBIOGVIDEO; +extern unsigned IOCTL_FBIOSCURSOR; +extern unsigned IOCTL_FBIOGCURSOR; +extern unsigned IOCTL_FBIOSCURPOS; +extern unsigned IOCTL_FBIOGCURPOS; +extern unsigned IOCTL_FBIOGCURMAX; +extern unsigned IOCTL_KIOCTRANS; +extern unsigned IOCTL_KIOCSETKEY; +extern unsigned IOCTL_KIOCGETKEY; +extern unsigned IOCTL_KIOCGTRANS; +extern unsigned IOCTL_KIOCCMD; +extern unsigned IOCTL_KIOCTYPE; +extern unsigned IOCTL_KIOCSDIRECT; +extern unsigned IOCTL_KIOCSKEY; +extern unsigned IOCTL_KIOCGKEY; +extern unsigned IOCTL_KIOCSLED; +extern unsigned IOCTL_KIOCGLED; +extern unsigned IOCTL_KIOCLAYOUT; +extern unsigned IOCTL_VUIDSFORMAT; +extern unsigned IOCTL_VUIDGFORMAT; +extern unsigned IOCTL_STICIO_GXINFO; +extern unsigned IOCTL_STICIO_RESET; +extern unsigned IOCTL_STICIO_STARTQ; +extern unsigned IOCTL_STICIO_STOPQ; +extern unsigned IOCTL_UKYOPON_IDENTIFY; +extern unsigned IOCTL_URIO_SEND_COMMAND; +extern unsigned IOCTL_URIO_RECV_COMMAND; +extern unsigned IOCTL_USB_REQUEST; +extern unsigned IOCTL_USB_SETDEBUG; +extern unsigned IOCTL_USB_DISCOVER; +extern unsigned IOCTL_USB_DEVICEINFO; +extern unsigned IOCTL_USB_DEVICEINFO_OLD; +extern unsigned IOCTL_USB_DEVICESTATS; +extern unsigned IOCTL_USB_GET_REPORT_DESC; +extern unsigned IOCTL_USB_SET_IMMED; +extern unsigned IOCTL_USB_GET_REPORT; +extern unsigned IOCTL_USB_SET_REPORT; +extern unsigned IOCTL_USB_GET_REPORT_ID; +extern unsigned IOCTL_USB_GET_CONFIG; +extern unsigned IOCTL_USB_SET_CONFIG; +extern unsigned IOCTL_USB_GET_ALTINTERFACE; +extern unsigned IOCTL_USB_SET_ALTINTERFACE; +extern unsigned IOCTL_USB_GET_NO_ALT; +extern unsigned IOCTL_USB_GET_DEVICE_DESC; +extern unsigned IOCTL_USB_GET_CONFIG_DESC; +extern unsigned IOCTL_USB_GET_INTERFACE_DESC; +extern unsigned IOCTL_USB_GET_ENDPOINT_DESC; +extern unsigned IOCTL_USB_GET_FULL_DESC; +extern unsigned IOCTL_USB_GET_STRING_DESC; +extern unsigned IOCTL_USB_DO_REQUEST; +extern unsigned IOCTL_USB_GET_DEVICEINFO; +extern unsigned IOCTL_USB_GET_DEVICEINFO_OLD; +extern unsigned IOCTL_USB_SET_SHORT_XFER; +extern unsigned IOCTL_USB_SET_TIMEOUT; +extern unsigned IOCTL_USB_SET_BULK_RA; +extern unsigned IOCTL_USB_SET_BULK_WB; +extern unsigned IOCTL_USB_SET_BULK_RA_OPT; +extern unsigned IOCTL_USB_SET_BULK_WB_OPT; +extern unsigned IOCTL_USB_GET_CM_OVER_DATA; +extern unsigned IOCTL_USB_SET_CM_OVER_DATA; +extern unsigned IOCTL_UTOPPYIOTURBO; +extern unsigned IOCTL_UTOPPYIOCANCEL; +extern unsigned IOCTL_UTOPPYIOREBOOT; +extern unsigned IOCTL_UTOPPYIOSTATS; +extern unsigned IOCTL_UTOPPYIORENAME; +extern unsigned IOCTL_UTOPPYIOMKDIR; +extern unsigned IOCTL_UTOPPYIODELETE; +extern unsigned IOCTL_UTOPPYIOREADDIR; +extern unsigned IOCTL_UTOPPYIOREADFILE; +extern unsigned IOCTL_UTOPPYIOWRITEFILE; +extern unsigned IOCTL_DIOSXDCMD; +extern unsigned IOCTL_VT_OPENQRY; +extern unsigned IOCTL_VT_SETMODE; +extern unsigned IOCTL_VT_GETMODE; +extern unsigned IOCTL_VT_RELDISP; +extern unsigned IOCTL_VT_ACTIVATE; +extern unsigned IOCTL_VT_WAITACTIVE; +extern unsigned IOCTL_VT_GETACTIVE; +extern unsigned IOCTL_VT_GETSTATE; +extern unsigned IOCTL_KDGETKBENT; +extern unsigned IOCTL_KDGKBMODE; +extern unsigned IOCTL_KDSKBMODE; +extern unsigned IOCTL_KDMKTONE; +extern unsigned IOCTL_KDSETMODE; +extern unsigned IOCTL_KDENABIO; +extern unsigned IOCTL_KDDISABIO; +extern unsigned IOCTL_KDGKBTYPE; +extern unsigned IOCTL_KDGETLED; +extern unsigned IOCTL_KDSETLED; +extern unsigned IOCTL_KDSETRAD; +extern unsigned IOCTL_VGAPCVTID; +extern unsigned IOCTL_CONS_GETVERS; +extern unsigned IOCTL_WSKBDIO_GTYPE; +extern unsigned IOCTL_WSKBDIO_BELL; +extern unsigned IOCTL_WSKBDIO_COMPLEXBELL; +extern unsigned IOCTL_WSKBDIO_SETBELL; +extern unsigned IOCTL_WSKBDIO_GETBELL; +extern unsigned IOCTL_WSKBDIO_SETDEFAULTBELL; +extern unsigned IOCTL_WSKBDIO_GETDEFAULTBELL; +extern unsigned IOCTL_WSKBDIO_SETKEYREPEAT; +extern unsigned IOCTL_WSKBDIO_GETKEYREPEAT; +extern unsigned IOCTL_WSKBDIO_SETDEFAULTKEYREPEAT; +extern unsigned IOCTL_WSKBDIO_GETDEFAULTKEYREPEAT; +extern unsigned IOCTL_WSKBDIO_SETLEDS; +extern unsigned IOCTL_WSKBDIO_GETLEDS; +extern unsigned IOCTL_WSKBDIO_GETMAP; +extern unsigned IOCTL_WSKBDIO_SETMAP; +extern unsigned IOCTL_WSKBDIO_GETENCODING; +extern unsigned IOCTL_WSKBDIO_SETENCODING; +extern unsigned IOCTL_WSKBDIO_SETMODE; +extern unsigned IOCTL_WSKBDIO_GETMODE; +extern unsigned IOCTL_WSKBDIO_SETKEYCLICK; +extern unsigned IOCTL_WSKBDIO_GETKEYCLICK; +extern unsigned IOCTL_WSKBDIO_GETSCROLL; +extern unsigned IOCTL_WSKBDIO_SETSCROLL; +extern unsigned IOCTL_WSKBDIO_SETVERSION; +extern unsigned IOCTL_WSMOUSEIO_GTYPE; +extern unsigned IOCTL_WSMOUSEIO_SRES; +extern unsigned IOCTL_WSMOUSEIO_SSCALE; +extern unsigned IOCTL_WSMOUSEIO_SRATE; +extern unsigned IOCTL_WSMOUSEIO_SCALIBCOORDS; +extern unsigned IOCTL_WSMOUSEIO_GCALIBCOORDS; +extern unsigned IOCTL_WSMOUSEIO_GETID; +extern unsigned IOCTL_WSMOUSEIO_GETREPEAT; +extern unsigned IOCTL_WSMOUSEIO_SETREPEAT; +extern unsigned IOCTL_WSMOUSEIO_SETVERSION; +extern unsigned IOCTL_WSDISPLAYIO_GTYPE; +extern unsigned IOCTL_WSDISPLAYIO_GINFO; +extern unsigned IOCTL_WSDISPLAYIO_GETCMAP; +extern unsigned IOCTL_WSDISPLAYIO_PUTCMAP; +extern unsigned IOCTL_WSDISPLAYIO_GVIDEO; +extern unsigned IOCTL_WSDISPLAYIO_SVIDEO; +extern unsigned IOCTL_WSDISPLAYIO_GCURPOS; +extern unsigned IOCTL_WSDISPLAYIO_SCURPOS; +extern unsigned IOCTL_WSDISPLAYIO_GCURMAX; +extern unsigned IOCTL_WSDISPLAYIO_GCURSOR; +extern unsigned IOCTL_WSDISPLAYIO_SCURSOR; +extern unsigned IOCTL_WSDISPLAYIO_GMODE; +extern unsigned IOCTL_WSDISPLAYIO_SMODE; +extern unsigned IOCTL_WSDISPLAYIO_LDFONT; +extern unsigned IOCTL_WSDISPLAYIO_ADDSCREEN; +extern unsigned IOCTL_WSDISPLAYIO_DELSCREEN; +extern unsigned IOCTL_WSDISPLAYIO_SFONT; +extern unsigned IOCTL__O_WSDISPLAYIO_SETKEYBOARD; +extern unsigned IOCTL_WSDISPLAYIO_GETPARAM; +extern unsigned IOCTL_WSDISPLAYIO_SETPARAM; +extern unsigned IOCTL_WSDISPLAYIO_GETACTIVESCREEN; +extern unsigned IOCTL_WSDISPLAYIO_GETWSCHAR; +extern unsigned IOCTL_WSDISPLAYIO_PUTWSCHAR; +extern unsigned IOCTL_WSDISPLAYIO_DGSCROLL; +extern unsigned IOCTL_WSDISPLAYIO_DSSCROLL; +extern unsigned IOCTL_WSDISPLAYIO_GMSGATTRS; +extern unsigned IOCTL_WSDISPLAYIO_SMSGATTRS; +extern unsigned IOCTL_WSDISPLAYIO_GBORDER; +extern unsigned IOCTL_WSDISPLAYIO_SBORDER; +extern unsigned IOCTL_WSDISPLAYIO_SSPLASH; +extern unsigned IOCTL_WSDISPLAYIO_SPROGRESS; +extern unsigned IOCTL_WSDISPLAYIO_LINEBYTES; +extern unsigned IOCTL_WSDISPLAYIO_SETVERSION; +extern unsigned IOCTL_WSMUXIO_ADD_DEVICE; +extern unsigned IOCTL_WSMUXIO_REMOVE_DEVICE; +extern unsigned IOCTL_WSMUXIO_LIST_DEVICES; +extern unsigned IOCTL_WSMUXIO_INJECTEVENT; +extern unsigned IOCTL_WSDISPLAYIO_GET_BUSID; +extern unsigned IOCTL_WSDISPLAYIO_GET_EDID; +extern unsigned IOCTL_WSDISPLAYIO_SET_POLLING; +extern unsigned IOCTL_WSDISPLAYIO_GET_FBINFO; +extern unsigned IOCTL_WSDISPLAYIO_DOBLIT; +extern unsigned IOCTL_WSDISPLAYIO_WAITBLIT; +extern unsigned IOCTL_BIOCLOCATE; +extern unsigned IOCTL_BIOCINQ; +extern unsigned IOCTL_BIOCDISK_NOVOL; +extern unsigned IOCTL_BIOCDISK; +extern unsigned IOCTL_BIOCVOL; +extern unsigned IOCTL_BIOCALARM; +extern unsigned IOCTL_BIOCBLINK; +extern unsigned IOCTL_BIOCSETSTATE; +extern unsigned IOCTL_BIOCVOLOPS; +extern unsigned IOCTL_MD_GETCONF; +extern unsigned IOCTL_MD_SETCONF; +extern unsigned IOCTL_CCDIOCSET; +extern unsigned IOCTL_CCDIOCCLR; +extern unsigned IOCTL_CGDIOCSET; +extern unsigned IOCTL_CGDIOCCLR; +extern unsigned IOCTL_CGDIOCGET; +extern unsigned IOCTL_FSSIOCSET; +extern unsigned IOCTL_FSSIOCGET; +extern unsigned IOCTL_FSSIOCCLR; +extern unsigned IOCTL_FSSIOFSET; +extern unsigned IOCTL_FSSIOFGET; +extern unsigned IOCTL_BTDEV_ATTACH; +extern unsigned IOCTL_BTDEV_DETACH; +extern unsigned IOCTL_BTSCO_GETINFO; +extern unsigned IOCTL_KTTCP_IO_SEND; +extern unsigned IOCTL_KTTCP_IO_RECV; +extern unsigned IOCTL_IOC_LOCKSTAT_GVERSION; +extern unsigned IOCTL_IOC_LOCKSTAT_ENABLE; +extern unsigned IOCTL_IOC_LOCKSTAT_DISABLE; +extern unsigned IOCTL_VNDIOCSET; +extern unsigned IOCTL_VNDIOCCLR; +extern unsigned IOCTL_VNDIOCGET; +extern unsigned IOCTL_SPKRTONE; +extern unsigned IOCTL_SPKRTUNE; +extern unsigned IOCTL_SPKRGETVOL; +extern unsigned IOCTL_SPKRSETVOL; +extern unsigned IOCTL_BIOCGBLEN; +extern unsigned IOCTL_BIOCSBLEN; +extern unsigned IOCTL_BIOCSETF; +extern unsigned IOCTL_BIOCFLUSH; +extern unsigned IOCTL_BIOCPROMISC; +extern unsigned IOCTL_BIOCGDLT; +extern unsigned IOCTL_BIOCGETIF; +extern unsigned IOCTL_BIOCSETIF; +extern unsigned IOCTL_BIOCGSTATS; +extern unsigned IOCTL_BIOCGSTATSOLD; +extern unsigned IOCTL_BIOCIMMEDIATE; +extern unsigned IOCTL_BIOCVERSION; +extern unsigned IOCTL_BIOCSTCPF; +extern unsigned IOCTL_BIOCSUDPF; +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_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; +extern unsigned IOCTL_GREGADDRD; +extern unsigned IOCTL_GRESPROTO; +extern unsigned IOCTL_GREGPROTO; +extern unsigned IOCTL_GRESSOCK; +extern unsigned IOCTL_GREDSOCK; +extern unsigned IOCTL_PPPIOCGRAWIN; +extern unsigned IOCTL_PPPIOCGFLAGS; +extern unsigned IOCTL_PPPIOCSFLAGS; +extern unsigned IOCTL_PPPIOCGASYNCMAP; +extern unsigned IOCTL_PPPIOCSASYNCMAP; +extern unsigned IOCTL_PPPIOCGUNIT; +extern unsigned IOCTL_PPPIOCGRASYNCMAP; +extern unsigned IOCTL_PPPIOCSRASYNCMAP; +extern unsigned IOCTL_PPPIOCGMRU; +extern unsigned IOCTL_PPPIOCSMRU; +extern unsigned IOCTL_PPPIOCSMAXCID; +extern unsigned IOCTL_PPPIOCGXASYNCMAP; +extern unsigned IOCTL_PPPIOCSXASYNCMAP; +extern unsigned IOCTL_PPPIOCXFERUNIT; +extern unsigned IOCTL_PPPIOCSCOMPRESS; +extern unsigned IOCTL_PPPIOCGNPMODE; +extern unsigned IOCTL_PPPIOCSNPMODE; +extern unsigned IOCTL_PPPIOCGIDLE; +extern unsigned IOCTL_PPPIOCGMTU; +extern unsigned IOCTL_PPPIOCSMTU; +extern unsigned IOCTL_SIOCGPPPSTATS; +extern unsigned IOCTL_SIOCGPPPCSTATS; +extern unsigned IOCTL_IOC_NPF_VERSION; +extern unsigned IOCTL_IOC_NPF_SWITCH; +extern unsigned IOCTL_IOC_NPF_LOAD; +extern unsigned IOCTL_IOC_NPF_TABLE; +extern unsigned IOCTL_IOC_NPF_STATS; +extern unsigned IOCTL_IOC_NPF_SAVE; +extern unsigned IOCTL_IOC_NPF_RULE; +extern unsigned IOCTL_IOC_NPF_CONN_LOOKUP; +extern unsigned IOCTL_PPPOESETPARMS; +extern unsigned IOCTL_PPPOEGETPARMS; +extern unsigned IOCTL_PPPOEGETSESSION; +extern unsigned IOCTL_SPPPGETAUTHCFG; +extern unsigned IOCTL_SPPPSETAUTHCFG; +extern unsigned IOCTL_SPPPGETLCPCFG; +extern unsigned IOCTL_SPPPSETLCPCFG; +extern unsigned IOCTL_SPPPGETSTATUS; +extern unsigned IOCTL_SPPPGETSTATUSNCP; +extern unsigned IOCTL_SPPPGETIDLETO; +extern unsigned IOCTL_SPPPSETIDLETO; +extern unsigned IOCTL_SPPPGETAUTHFAILURES; +extern unsigned IOCTL_SPPPSETAUTHFAILURE; +extern unsigned IOCTL_SPPPSETDNSOPTS; +extern unsigned IOCTL_SPPPGETDNSOPTS; +extern unsigned IOCTL_SPPPGETDNSADDRS; +extern unsigned IOCTL_SPPPSETKEEPALIVE; +extern unsigned IOCTL_SPPPGETKEEPALIVE; +extern unsigned IOCTL_SRT_GETNRT; +extern unsigned IOCTL_SRT_GETRT; +extern unsigned IOCTL_SRT_SETRT; +extern unsigned IOCTL_SRT_DELRT; +extern unsigned IOCTL_SRT_SFLAGS; +extern unsigned IOCTL_SRT_GFLAGS; +extern unsigned IOCTL_SRT_SGFLAGS; +extern unsigned IOCTL_SRT_DEBUG; +extern unsigned IOCTL_TAPGIFNAME; +extern unsigned IOCTL_TUNSDEBUG; +extern unsigned IOCTL_TUNGDEBUG; +extern unsigned IOCTL_TUNSIFMODE; +extern unsigned IOCTL_TUNSLMODE; +extern unsigned IOCTL_TUNSIFHEAD; +extern unsigned IOCTL_TUNGIFHEAD; +extern unsigned IOCTL_DIOCSTART; +extern unsigned IOCTL_DIOCSTOP; +extern unsigned IOCTL_DIOCADDRULE; +extern unsigned IOCTL_DIOCGETRULES; +extern unsigned IOCTL_DIOCGETRULE; +extern unsigned IOCTL_DIOCSETLCK; +extern unsigned IOCTL_DIOCCLRSTATES; +extern unsigned IOCTL_DIOCGETSTATE; +extern unsigned IOCTL_DIOCSETSTATUSIF; +extern unsigned IOCTL_DIOCGETSTATUS; +extern unsigned IOCTL_DIOCCLRSTATUS; +extern unsigned IOCTL_DIOCNATLOOK; +extern unsigned IOCTL_DIOCSETDEBUG; +extern unsigned IOCTL_DIOCGETSTATES; +extern unsigned IOCTL_DIOCCHANGERULE; +extern unsigned IOCTL_DIOCSETTIMEOUT; +extern unsigned IOCTL_DIOCGETTIMEOUT; +extern unsigned IOCTL_DIOCADDSTATE; +extern unsigned IOCTL_DIOCCLRRULECTRS; +extern unsigned IOCTL_DIOCGETLIMIT; +extern unsigned IOCTL_DIOCSETLIMIT; +extern unsigned IOCTL_DIOCKILLSTATES; +extern unsigned IOCTL_DIOCSTARTALTQ; +extern unsigned IOCTL_DIOCSTOPALTQ; +extern unsigned IOCTL_DIOCADDALTQ; +extern unsigned IOCTL_DIOCGETALTQS; +extern unsigned IOCTL_DIOCGETALTQ; +extern unsigned IOCTL_DIOCCHANGEALTQ; +extern unsigned IOCTL_DIOCGETQSTATS; +extern unsigned IOCTL_DIOCBEGINADDRS; +extern unsigned IOCTL_DIOCADDADDR; +extern unsigned IOCTL_DIOCGETADDRS; +extern unsigned IOCTL_DIOCGETADDR; +extern unsigned IOCTL_DIOCCHANGEADDR; +extern unsigned IOCTL_DIOCADDSTATES; +extern unsigned IOCTL_DIOCGETRULESETS; +extern unsigned IOCTL_DIOCGETRULESET; +extern unsigned IOCTL_DIOCRCLRTABLES; +extern unsigned IOCTL_DIOCRADDTABLES; +extern unsigned IOCTL_DIOCRDELTABLES; +extern unsigned IOCTL_DIOCRGETTABLES; +extern unsigned IOCTL_DIOCRGETTSTATS; +extern unsigned IOCTL_DIOCRCLRTSTATS; +extern unsigned IOCTL_DIOCRCLRADDRS; +extern unsigned IOCTL_DIOCRADDADDRS; +extern unsigned IOCTL_DIOCRDELADDRS; +extern unsigned IOCTL_DIOCRSETADDRS; +extern unsigned IOCTL_DIOCRGETADDRS; +extern unsigned IOCTL_DIOCRGETASTATS; +extern unsigned IOCTL_DIOCRCLRASTATS; +extern unsigned IOCTL_DIOCRTSTADDRS; +extern unsigned IOCTL_DIOCRSETTFLAGS; +extern unsigned IOCTL_DIOCRINADEFINE; +extern unsigned IOCTL_DIOCOSFPFLUSH; +extern unsigned IOCTL_DIOCOSFPADD; +extern unsigned IOCTL_DIOCOSFPGET; +extern unsigned IOCTL_DIOCXBEGIN; +extern unsigned IOCTL_DIOCXCOMMIT; +extern unsigned IOCTL_DIOCXROLLBACK; +extern unsigned IOCTL_DIOCGETSRCNODES; +extern unsigned IOCTL_DIOCCLRSRCNODES; +extern unsigned IOCTL_DIOCSETHOSTID; +extern unsigned IOCTL_DIOCIGETIFACES; +extern unsigned IOCTL_DIOCSETIFFLAG; +extern unsigned IOCTL_DIOCCLRIFFLAG; +extern unsigned IOCTL_DIOCKILLSRCNODES; +extern unsigned IOCTL_SLIOCGUNIT; +extern unsigned IOCTL_SIOCGBTINFO; +extern unsigned IOCTL_SIOCGBTINFOA; +extern unsigned IOCTL_SIOCNBTINFO; +extern unsigned IOCTL_SIOCSBTFLAGS; +extern unsigned IOCTL_SIOCSBTPOLICY; +extern unsigned IOCTL_SIOCSBTPTYPE; +extern unsigned IOCTL_SIOCGBTSTATS; +extern unsigned IOCTL_SIOCZBTSTATS; +extern unsigned IOCTL_SIOCBTDUMP; +extern unsigned IOCTL_SIOCSBTSCOMTU; +extern unsigned IOCTL_SIOCGBTFEAT; +extern unsigned IOCTL_SIOCADNAT; +extern unsigned IOCTL_SIOCRMNAT; +extern unsigned IOCTL_SIOCGNATS; +extern unsigned IOCTL_SIOCGNATL; +extern unsigned IOCTL_SIOCPURGENAT; +extern unsigned IOCTL_SIOCSIFINFO_FLAGS; +extern unsigned IOCTL_SIOCAADDRCTL_POLICY; +extern unsigned IOCTL_SIOCDADDRCTL_POLICY; +extern unsigned IOCTL_SMBIOC_OPENSESSION; +extern unsigned IOCTL_SMBIOC_OPENSHARE; +extern unsigned IOCTL_SMBIOC_REQUEST; +extern unsigned IOCTL_SMBIOC_SETFLAGS; +extern unsigned IOCTL_SMBIOC_LOOKUP; +extern unsigned IOCTL_SMBIOC_READ; +extern unsigned IOCTL_SMBIOC_WRITE; +extern unsigned IOCTL_AGPIOC_INFO; +extern unsigned IOCTL_AGPIOC_ACQUIRE; +extern unsigned IOCTL_AGPIOC_RELEASE; +extern unsigned IOCTL_AGPIOC_SETUP; +extern unsigned IOCTL_AGPIOC_ALLOCATE; +extern unsigned IOCTL_AGPIOC_DEALLOCATE; +extern unsigned IOCTL_AGPIOC_BIND; +extern unsigned IOCTL_AGPIOC_UNBIND; +extern unsigned IOCTL_AUDIO_GETINFO; +extern unsigned IOCTL_AUDIO_SETINFO; +extern unsigned IOCTL_AUDIO_DRAIN; +extern unsigned IOCTL_AUDIO_FLUSH; +extern unsigned IOCTL_AUDIO_WSEEK; +extern unsigned IOCTL_AUDIO_RERROR; +extern unsigned IOCTL_AUDIO_GETDEV; +extern unsigned IOCTL_AUDIO_GETENC; +extern unsigned IOCTL_AUDIO_GETFD; +extern unsigned IOCTL_AUDIO_SETFD; +extern unsigned IOCTL_AUDIO_PERROR; +extern unsigned IOCTL_AUDIO_GETIOFFS; +extern unsigned IOCTL_AUDIO_GETOOFFS; +extern unsigned IOCTL_AUDIO_GETPROPS; +extern unsigned IOCTL_AUDIO_GETBUFINFO; +extern unsigned IOCTL_AUDIO_SETCHAN; +extern unsigned IOCTL_AUDIO_GETCHAN; +extern unsigned IOCTL_AUDIO_MIXER_READ; +extern unsigned IOCTL_AUDIO_MIXER_WRITE; +extern unsigned IOCTL_AUDIO_MIXER_DEVINFO; +extern unsigned IOCTL_ATAIOCCOMMAND; +extern unsigned IOCTL_ATABUSIOSCAN; +extern unsigned IOCTL_ATABUSIORESET; +extern unsigned IOCTL_ATABUSIODETACH; +extern unsigned IOCTL_CDIOCPLAYTRACKS; +extern unsigned IOCTL_CDIOCPLAYBLOCKS; +extern unsigned IOCTL_CDIOCREADSUBCHANNEL; +extern unsigned IOCTL_CDIOREADTOCHEADER; +extern unsigned IOCTL_CDIOREADTOCENTRIES; +extern unsigned IOCTL_CDIOREADMSADDR; +extern unsigned IOCTL_CDIOCSETPATCH; +extern unsigned IOCTL_CDIOCGETVOL; +extern unsigned IOCTL_CDIOCSETVOL; +extern unsigned IOCTL_CDIOCSETMONO; +extern unsigned IOCTL_CDIOCSETSTEREO; +extern unsigned IOCTL_CDIOCSETMUTE; +extern unsigned IOCTL_CDIOCSETLEFT; +extern unsigned IOCTL_CDIOCSETRIGHT; +extern unsigned IOCTL_CDIOCSETDEBUG; +extern unsigned IOCTL_CDIOCCLRDEBUG; +extern unsigned IOCTL_CDIOCPAUSE; +extern unsigned IOCTL_CDIOCRESUME; +extern unsigned IOCTL_CDIOCRESET; +extern unsigned IOCTL_CDIOCSTART; +extern unsigned IOCTL_CDIOCSTOP; +extern unsigned IOCTL_CDIOCEJECT; +extern unsigned IOCTL_CDIOCALLOW; +extern unsigned IOCTL_CDIOCPREVENT; +extern unsigned IOCTL_CDIOCCLOSE; +extern unsigned IOCTL_CDIOCPLAYMSF; +extern unsigned IOCTL_CDIOCLOADUNLOAD; +extern unsigned IOCTL_CHIOMOVE; +extern unsigned IOCTL_CHIOEXCHANGE; +extern unsigned IOCTL_CHIOPOSITION; +extern unsigned IOCTL_CHIOGPICKER; +extern unsigned IOCTL_CHIOSPICKER; +extern unsigned IOCTL_CHIOGPARAMS; +extern unsigned IOCTL_CHIOIELEM; +extern unsigned IOCTL_OCHIOGSTATUS; +extern unsigned IOCTL_CHIOGSTATUS; +extern unsigned IOCTL_CHIOSVOLTAG; +extern unsigned IOCTL_CLOCKCTL_SETTIMEOFDAY; +extern unsigned IOCTL_CLOCKCTL_ADJTIME; +extern unsigned IOCTL_CLOCKCTL_CLOCK_SETTIME; +extern unsigned IOCTL_CLOCKCTL_NTP_ADJTIME; +extern unsigned IOCTL_IOC_CPU_SETSTATE; +extern unsigned IOCTL_IOC_CPU_GETSTATE; +extern unsigned IOCTL_IOC_CPU_GETCOUNT; +extern unsigned IOCTL_IOC_CPU_MAPID; +extern unsigned IOCTL_IOC_CPU_UCODE_GET_VERSION; +extern unsigned IOCTL_IOC_CPU_UCODE_APPLY; +extern unsigned IOCTL_DIOCGDINFO; +extern unsigned IOCTL_DIOCSDINFO; +extern unsigned IOCTL_DIOCWDINFO; +extern unsigned IOCTL_DIOCRFORMAT; +extern unsigned IOCTL_DIOCWFORMAT; +extern unsigned IOCTL_DIOCSSTEP; +extern unsigned IOCTL_DIOCSRETRIES; +extern unsigned IOCTL_DIOCKLABEL; +extern unsigned IOCTL_DIOCWLABEL; +extern unsigned IOCTL_DIOCSBAD; +extern unsigned IOCTL_DIOCEJECT; +extern unsigned IOCTL_ODIOCEJECT; +extern unsigned IOCTL_DIOCLOCK; +extern unsigned IOCTL_DIOCGDEFLABEL; +extern unsigned IOCTL_DIOCCLRLABEL; +extern unsigned IOCTL_DIOCGCACHE; +extern unsigned IOCTL_DIOCSCACHE; +extern unsigned IOCTL_DIOCCACHESYNC; +extern unsigned IOCTL_DIOCBSLIST; +extern unsigned IOCTL_DIOCBSFLUSH; +extern unsigned IOCTL_DIOCAWEDGE; +extern unsigned IOCTL_DIOCGWEDGEINFO; +extern unsigned IOCTL_DIOCDWEDGE; +extern unsigned IOCTL_DIOCLWEDGES; +extern unsigned IOCTL_DIOCGSTRATEGY; +extern unsigned IOCTL_DIOCSSTRATEGY; +extern unsigned IOCTL_DIOCGDISKINFO; +extern unsigned IOCTL_DIOCTUR; +extern unsigned IOCTL_DIOCMWEDGES; +extern unsigned IOCTL_DIOCGSECTORSIZE; +extern unsigned IOCTL_DIOCGMEDIASIZE; +extern unsigned IOCTL_DRVDETACHDEV; +extern unsigned IOCTL_DRVRESCANBUS; +extern unsigned IOCTL_DRVCTLCOMMAND; +extern unsigned IOCTL_DRVRESUMEDEV; +extern unsigned IOCTL_DRVLISTDEV; +extern unsigned IOCTL_DRVGETEVENT; +extern unsigned IOCTL_DRVSUSPENDDEV; +extern unsigned IOCTL_DVD_READ_STRUCT; +extern unsigned IOCTL_DVD_WRITE_STRUCT; +extern unsigned IOCTL_DVD_AUTH; +extern unsigned IOCTL_ENVSYS_GETDICTIONARY; +extern unsigned IOCTL_ENVSYS_SETDICTIONARY; +extern unsigned IOCTL_ENVSYS_REMOVEPROPS; +extern unsigned IOCTL_ENVSYS_GTREDATA; +extern unsigned IOCTL_ENVSYS_GTREINFO; +extern unsigned IOCTL_KFILTER_BYFILTER; +extern unsigned IOCTL_KFILTER_BYNAME; +extern unsigned IOCTL_FDIOCGETOPTS; +extern unsigned IOCTL_FDIOCSETOPTS; +extern unsigned IOCTL_FDIOCSETFORMAT; +extern unsigned IOCTL_FDIOCGETFORMAT; +extern unsigned IOCTL_FDIOCFORMAT_TRACK; extern unsigned IOCTL_FIOCLEX; -extern unsigned IOCTL_FIOGETOWN; -extern unsigned IOCTL_FIONBIO; extern unsigned IOCTL_FIONCLEX; +extern unsigned IOCTL_FIONREAD; +extern unsigned IOCTL_FIONBIO; +extern unsigned IOCTL_FIOASYNC; extern unsigned IOCTL_FIOSETOWN; -extern unsigned IOCTL_SIOCADDMULTI; +extern unsigned IOCTL_FIOGETOWN; +extern unsigned IOCTL_OFIOGETBMAP; +extern unsigned IOCTL_FIOGETBMAP; +extern unsigned IOCTL_FIONWRITE; +extern unsigned IOCTL_FIONSPACE; +extern unsigned IOCTL_GPIOINFO; +extern unsigned IOCTL_GPIOSET; +extern unsigned IOCTL_GPIOUNSET; +extern unsigned IOCTL_GPIOREAD; +extern unsigned IOCTL_GPIOWRITE; +extern unsigned IOCTL_GPIOTOGGLE; +extern unsigned IOCTL_GPIOATTACH; +extern unsigned IOCTL_PTIOCNETBSD; +extern unsigned IOCTL_PTIOCSUNOS; +extern unsigned IOCTL_PTIOCLINUX; +extern unsigned IOCTL_PTIOCFREEBSD; +extern unsigned IOCTL_PTIOCULTRIX; +extern unsigned IOCTL_TIOCHPCL; +extern unsigned IOCTL_TIOCGETP; +extern unsigned IOCTL_TIOCSETP; +extern unsigned IOCTL_TIOCSETN; +extern unsigned IOCTL_TIOCSETC; +extern unsigned IOCTL_TIOCGETC; +extern unsigned IOCTL_TIOCLBIS; +extern unsigned IOCTL_TIOCLBIC; +extern unsigned IOCTL_TIOCLSET; +extern unsigned IOCTL_TIOCLGET; +extern unsigned IOCTL_TIOCSLTC; +extern unsigned IOCTL_TIOCGLTC; +extern unsigned IOCTL_OTIOCCONS; +extern unsigned IOCTL_JOY_SETTIMEOUT; +extern unsigned IOCTL_JOY_GETTIMEOUT; +extern unsigned IOCTL_JOY_SET_X_OFFSET; +extern unsigned IOCTL_JOY_SET_Y_OFFSET; +extern unsigned IOCTL_JOY_GET_X_OFFSET; +extern unsigned IOCTL_JOY_GET_Y_OFFSET; +extern unsigned IOCTL_OKIOCGSYMBOL; +extern unsigned IOCTL_OKIOCGVALUE; +extern unsigned IOCTL_KIOCGSIZE; +extern unsigned IOCTL_KIOCGVALUE; +extern unsigned IOCTL_KIOCGSYMBOL; +extern unsigned IOCTL_LUAINFO; +extern unsigned IOCTL_LUACREATE; +extern unsigned IOCTL_LUADESTROY; +extern unsigned IOCTL_LUAREQUIRE; +extern unsigned IOCTL_LUALOAD; +extern unsigned IOCTL_MIDI_PRETIME; +extern unsigned IOCTL_MIDI_MPUMODE; +extern unsigned IOCTL_MIDI_MPUCMD; +extern unsigned IOCTL_SEQUENCER_RESET; +extern unsigned IOCTL_SEQUENCER_SYNC; +extern unsigned IOCTL_SEQUENCER_INFO; +extern unsigned IOCTL_SEQUENCER_CTRLRATE; +extern unsigned IOCTL_SEQUENCER_GETOUTCOUNT; +extern unsigned IOCTL_SEQUENCER_GETINCOUNT; +extern unsigned IOCTL_SEQUENCER_RESETSAMPLES; +extern unsigned IOCTL_SEQUENCER_NRSYNTHS; +extern unsigned IOCTL_SEQUENCER_NRMIDIS; +extern unsigned IOCTL_SEQUENCER_THRESHOLD; +extern unsigned IOCTL_SEQUENCER_MEMAVL; +extern unsigned IOCTL_SEQUENCER_PANIC; +extern unsigned IOCTL_SEQUENCER_OUTOFBAND; +extern unsigned IOCTL_SEQUENCER_GETTIME; +extern unsigned IOCTL_SEQUENCER_TMR_TIMEBASE; +extern unsigned IOCTL_SEQUENCER_TMR_START; +extern unsigned IOCTL_SEQUENCER_TMR_STOP; +extern unsigned IOCTL_SEQUENCER_TMR_CONTINUE; +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_MTIOCTOP; +extern unsigned IOCTL_MTIOCGET; +extern unsigned IOCTL_MTIOCIEOT; +extern unsigned IOCTL_MTIOCEEOT; +extern unsigned IOCTL_MTIOCRDSPOS; +extern unsigned IOCTL_MTIOCRDHPOS; +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; +extern unsigned IOCTL_RNDGETENTCNT; +extern unsigned IOCTL_RNDGETSRCNUM; +extern unsigned IOCTL_RNDGETSRCNAME; +extern unsigned IOCTL_RNDCTL; +extern unsigned IOCTL_RNDADDDATA; +extern unsigned IOCTL_RNDGETPOOLSTAT; +extern unsigned IOCTL_RNDGETESTNUM; +extern unsigned IOCTL_RNDGETESTNAME; +extern unsigned IOCTL_SCIOCGET; +extern unsigned IOCTL_SCIOCSET; +extern unsigned IOCTL_SCIOCRESTART; +extern unsigned IOCTL_SCIOC_USE_ADF; +extern unsigned IOCTL_SCIOCCOMMAND; +extern unsigned IOCTL_SCIOCDEBUG; +extern unsigned IOCTL_SCIOCIDENTIFY; +extern unsigned IOCTL_OSCIOCIDENTIFY; +extern unsigned IOCTL_SCIOCDECONFIG; +extern unsigned IOCTL_SCIOCRECONFIG; +extern unsigned IOCTL_SCIOCRESET; +extern unsigned IOCTL_SCBUSIOSCAN; +extern unsigned IOCTL_SCBUSIORESET; +extern unsigned IOCTL_SCBUSIODETACH; +extern unsigned IOCTL_SCBUSACCEL; +extern unsigned IOCTL_SCBUSIOLLSCAN; +extern unsigned IOCTL_SIOCSHIWAT; +extern unsigned IOCTL_SIOCGHIWAT; +extern unsigned IOCTL_SIOCSLOWAT; +extern unsigned IOCTL_SIOCGLOWAT; 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_SIOCSPGRP; extern unsigned IOCTL_SIOCGPGRP; +extern unsigned IOCTL_SIOCADDRT; +extern unsigned IOCTL_SIOCDELRT; extern unsigned IOCTL_SIOCSIFADDR; -extern unsigned IOCTL_SIOCSIFBRDADDR; +extern unsigned IOCTL_SIOCGIFADDR; extern unsigned IOCTL_SIOCSIFDSTADDR; +extern unsigned IOCTL_SIOCGIFDSTADDR; extern unsigned IOCTL_SIOCSIFFLAGS; +extern unsigned IOCTL_SIOCGIFFLAGS; +extern unsigned IOCTL_SIOCGIFBRDADDR; +extern unsigned IOCTL_SIOCSIFBRDADDR; +extern unsigned IOCTL_SIOCGIFCONF; +extern unsigned IOCTL_SIOCGIFNETMASK; +extern unsigned IOCTL_SIOCSIFNETMASK; +extern unsigned IOCTL_SIOCGIFMETRIC; extern unsigned IOCTL_SIOCSIFMETRIC; +extern unsigned IOCTL_SIOCDIFADDR; +extern unsigned IOCTL_SIOCAIFADDR; +extern unsigned IOCTL_SIOCGIFALIAS; +extern unsigned IOCTL_SIOCGIFAFLAG_IN; +extern unsigned IOCTL_SIOCALIFADDR; +extern unsigned IOCTL_SIOCGLIFADDR; +extern unsigned IOCTL_SIOCDLIFADDR; +extern unsigned IOCTL_SIOCSIFADDRPREF; +extern unsigned IOCTL_SIOCGIFADDRPREF; +extern unsigned IOCTL_SIOCADDMULTI; +extern unsigned IOCTL_SIOCDELMULTI; +extern unsigned IOCTL_SIOCGETVIFCNT; +extern unsigned IOCTL_SIOCGETSGCNT; +extern unsigned IOCTL_SIOCSIFMEDIA; +extern unsigned IOCTL_SIOCGIFMEDIA; +extern unsigned IOCTL_SIOCSIFGENERIC; +extern unsigned IOCTL_SIOCGIFGENERIC; +extern unsigned IOCTL_SIOCSIFPHYADDR; +extern unsigned IOCTL_SIOCGIFPSRCADDR; +extern unsigned IOCTL_SIOCGIFPDSTADDR; +extern unsigned IOCTL_SIOCDIFPHYADDR; +extern unsigned IOCTL_SIOCSLIFPHYADDR; +extern unsigned IOCTL_SIOCGLIFPHYADDR; extern unsigned IOCTL_SIOCSIFMTU; -extern unsigned IOCTL_SIOCSIFNETMASK; -extern unsigned IOCTL_SIOCSPGRP; -extern unsigned IOCTL_TIOCCONS; +extern unsigned IOCTL_SIOCGIFMTU; +extern unsigned IOCTL_SIOCSDRVSPEC; +extern unsigned IOCTL_SIOCGDRVSPEC; +extern unsigned IOCTL_SIOCIFCREATE; +extern unsigned IOCTL_SIOCIFDESTROY; +extern unsigned IOCTL_SIOCIFGCLONERS; +extern unsigned IOCTL_SIOCGIFDLT; +extern unsigned IOCTL_SIOCGIFCAP; +extern unsigned IOCTL_SIOCSIFCAP; +extern unsigned IOCTL_SIOCSVH; +extern unsigned IOCTL_SIOCGVH; +extern unsigned IOCTL_SIOCINITIFADDR; +extern unsigned IOCTL_SIOCGIFDATA; +extern unsigned IOCTL_SIOCZIFDATA; +extern unsigned IOCTL_SIOCGLINKSTR; +extern unsigned IOCTL_SIOCSLINKSTR; +extern unsigned IOCTL_SIOCGETHERCAP; +extern unsigned IOCTL_SIOCGIFINDEX; +extern unsigned IOCTL_SIOCSETPFSYNC; +extern unsigned IOCTL_SIOCGETPFSYNC; +extern unsigned IOCTL_PPS_IOC_CREATE; +extern unsigned IOCTL_PPS_IOC_DESTROY; +extern unsigned IOCTL_PPS_IOC_SETPARAMS; +extern unsigned IOCTL_PPS_IOC_GETPARAMS; +extern unsigned IOCTL_PPS_IOC_GETCAP; +extern unsigned IOCTL_PPS_IOC_FETCH; +extern unsigned IOCTL_PPS_IOC_KCBIND; 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_TIOCFLUSH; +extern unsigned IOCTL_TIOCGETA; +extern unsigned IOCTL_TIOCSETA; +extern unsigned IOCTL_TIOCSETAW; +extern unsigned IOCTL_TIOCSETAF; +extern unsigned IOCTL_TIOCGETD; extern unsigned IOCTL_TIOCSETD; +extern unsigned IOCTL_TIOCGLINED; +extern unsigned IOCTL_TIOCSLINED; +extern unsigned IOCTL_TIOCSBRK; +extern unsigned IOCTL_TIOCCBRK; +extern unsigned IOCTL_TIOCSDTR; +extern unsigned IOCTL_TIOCCDTR; +extern unsigned IOCTL_TIOCGPGRP; extern unsigned IOCTL_TIOCSPGRP; +extern unsigned IOCTL_TIOCOUTQ; extern unsigned IOCTL_TIOCSTI; +extern unsigned IOCTL_TIOCNOTTY; +extern unsigned IOCTL_TIOCPKT; +extern unsigned IOCTL_TIOCSTOP; +extern unsigned IOCTL_TIOCSTART; +extern unsigned IOCTL_TIOCMSET; +extern unsigned IOCTL_TIOCMBIS; +extern unsigned IOCTL_TIOCMBIC; +extern unsigned IOCTL_TIOCMGET; +extern unsigned IOCTL_TIOCREMOTE; +extern unsigned IOCTL_TIOCGWINSZ; 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_TIOCUCNTL; +extern unsigned IOCTL_TIOCSTAT; +extern unsigned IOCTL_TIOCGSID; +extern unsigned IOCTL_TIOCCONS; +extern unsigned IOCTL_TIOCSCTTY; +extern unsigned IOCTL_TIOCEXT; +extern unsigned IOCTL_TIOCSIG; +extern unsigned IOCTL_TIOCDRAIN; +extern unsigned IOCTL_TIOCGFLAGS; +extern unsigned IOCTL_TIOCSFLAGS; +extern unsigned IOCTL_TIOCDCDTIMESTAMP; +extern unsigned IOCTL_TIOCRCVFRAME; +extern unsigned IOCTL_TIOCXMTFRAME; +extern unsigned IOCTL_TIOCPTMGET; +extern unsigned IOCTL_TIOCGRANTPT; +extern unsigned IOCTL_TIOCPTSNAME; +extern unsigned IOCTL_TIOCSQSIZE; +extern unsigned IOCTL_TIOCGQSIZE; +extern unsigned IOCTL_VERIEXEC_LOAD; +extern unsigned IOCTL_VERIEXEC_TABLESIZE; +extern unsigned IOCTL_VERIEXEC_DELETE; +extern unsigned IOCTL_VERIEXEC_QUERY; +extern unsigned IOCTL_VERIEXEC_DUMP; +extern unsigned IOCTL_VERIEXEC_FLUSH; +extern unsigned IOCTL_VIDIOC_QUERYCAP; +extern unsigned IOCTL_VIDIOC_RESERVED; +extern unsigned IOCTL_VIDIOC_ENUM_FMT; +extern unsigned IOCTL_VIDIOC_G_FMT; +extern unsigned IOCTL_VIDIOC_S_FMT; +extern unsigned IOCTL_VIDIOC_REQBUFS; +extern unsigned IOCTL_VIDIOC_QUERYBUF; +extern unsigned IOCTL_VIDIOC_G_FBUF; +extern unsigned IOCTL_VIDIOC_S_FBUF; +extern unsigned IOCTL_VIDIOC_OVERLAY; +extern unsigned IOCTL_VIDIOC_QBUF; +extern unsigned IOCTL_VIDIOC_DQBUF; +extern unsigned IOCTL_VIDIOC_STREAMON; +extern unsigned IOCTL_VIDIOC_STREAMOFF; +extern unsigned IOCTL_VIDIOC_G_PARM; +extern unsigned IOCTL_VIDIOC_S_PARM; +extern unsigned IOCTL_VIDIOC_G_STD; +extern unsigned IOCTL_VIDIOC_S_STD; +extern unsigned IOCTL_VIDIOC_ENUMSTD; +extern unsigned IOCTL_VIDIOC_ENUMINPUT; +extern unsigned IOCTL_VIDIOC_G_CTRL; +extern unsigned IOCTL_VIDIOC_S_CTRL; +extern unsigned IOCTL_VIDIOC_G_TUNER; +extern unsigned IOCTL_VIDIOC_S_TUNER; +extern unsigned IOCTL_VIDIOC_G_AUDIO; +extern unsigned IOCTL_VIDIOC_S_AUDIO; +extern unsigned IOCTL_VIDIOC_QUERYCTRL; +extern unsigned IOCTL_VIDIOC_QUERYMENU; +extern unsigned IOCTL_VIDIOC_G_INPUT; +extern unsigned IOCTL_VIDIOC_S_INPUT; +extern unsigned IOCTL_VIDIOC_G_OUTPUT; +extern unsigned IOCTL_VIDIOC_S_OUTPUT; +extern unsigned IOCTL_VIDIOC_ENUMOUTPUT; +extern unsigned IOCTL_VIDIOC_G_AUDOUT; +extern unsigned IOCTL_VIDIOC_S_AUDOUT; +extern unsigned IOCTL_VIDIOC_G_MODULATOR; +extern unsigned IOCTL_VIDIOC_S_MODULATOR; +extern unsigned IOCTL_VIDIOC_G_FREQUENCY; +extern unsigned IOCTL_VIDIOC_S_FREQUENCY; +extern unsigned IOCTL_VIDIOC_CROPCAP; +extern unsigned IOCTL_VIDIOC_G_CROP; +extern unsigned IOCTL_VIDIOC_S_CROP; +extern unsigned IOCTL_VIDIOC_G_JPEGCOMP; +extern unsigned IOCTL_VIDIOC_S_JPEGCOMP; +extern unsigned IOCTL_VIDIOC_QUERYSTD; +extern unsigned IOCTL_VIDIOC_TRY_FMT; +extern unsigned IOCTL_VIDIOC_ENUMAUDIO; +extern unsigned IOCTL_VIDIOC_ENUMAUDOUT; +extern unsigned IOCTL_VIDIOC_G_PRIORITY; +extern unsigned IOCTL_VIDIOC_S_PRIORITY; +extern unsigned IOCTL_VIDIOC_ENUM_FRAMESIZES; +extern unsigned IOCTL_VIDIOC_ENUM_FRAMEINTERVALS; +extern unsigned IOCTL_WDOGIOC_GMODE; +extern unsigned IOCTL_WDOGIOC_SMODE; +extern unsigned IOCTL_WDOGIOC_WHICH; +extern unsigned IOCTL_WDOGIOC_TICKLE; +extern unsigned IOCTL_WDOGIOC_GTICKLER; +extern unsigned IOCTL_WDOGIOC_GWDOGS; extern unsigned IOCTL_SNDCTL_DSP_RESET; -extern unsigned IOCTL_SNDCTL_DSP_SETFMT; -extern unsigned IOCTL_SNDCTL_DSP_SETFRAGMENT; +extern unsigned IOCTL_SNDCTL_DSP_SYNC; extern unsigned IOCTL_SNDCTL_DSP_SPEED; +extern unsigned IOCTL_SOUND_PCM_READ_RATE; 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_SNDCTL_DSP_GETBLKSIZE; +extern unsigned IOCTL_SNDCTL_DSP_SETFMT; extern unsigned IOCTL_SOUND_PCM_READ_BITS; +extern unsigned IOCTL_SNDCTL_DSP_CHANNELS; 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_KDDISABIO; -extern unsigned IOCTL_KDENABIO; -extern unsigned IOCTL_KDGETLED; -extern unsigned IOCTL_KDGKBMODE; -extern unsigned IOCTL_KDGKBTYPE; -extern unsigned IOCTL_KDMKTONE; -extern unsigned IOCTL_KDSETLED; -extern unsigned IOCTL_KDSETMODE; -extern unsigned IOCTL_KDSKBMODE; +extern unsigned IOCTL_SOUND_PCM_READ_FILTER; +extern unsigned IOCTL_SNDCTL_DSP_POST; +extern unsigned IOCTL_SNDCTL_DSP_SUBDIVIDE; +extern unsigned IOCTL_SNDCTL_DSP_SETFRAGMENT; +extern unsigned IOCTL_SNDCTL_DSP_GETFMTS; +extern unsigned IOCTL_SNDCTL_DSP_GETOSPACE; +extern unsigned IOCTL_SNDCTL_DSP_GETISPACE; +extern unsigned IOCTL_SNDCTL_DSP_NONBLOCK; +extern unsigned IOCTL_SNDCTL_DSP_GETCAPS; +extern unsigned IOCTL_SNDCTL_DSP_GETTRIGGER; +extern unsigned IOCTL_SNDCTL_DSP_SETTRIGGER; +extern unsigned IOCTL_SNDCTL_DSP_GETIPTR; +extern unsigned IOCTL_SNDCTL_DSP_GETOPTR; +extern unsigned IOCTL_SNDCTL_DSP_MAPINBUF; +extern unsigned IOCTL_SNDCTL_DSP_MAPOUTBUF; +extern unsigned IOCTL_SNDCTL_DSP_SETSYNCRO; +extern unsigned IOCTL_SNDCTL_DSP_SETDUPLEX; +extern unsigned IOCTL_SNDCTL_DSP_PROFILE; +extern unsigned IOCTL_SNDCTL_DSP_GETODELAY; +extern unsigned IOCTL_SOUND_MIXER_INFO; +extern unsigned IOCTL_SOUND_OLD_MIXER_INFO; +extern unsigned IOCTL_OSS_GETVERSION; +extern unsigned IOCTL_SNDCTL_SYSINFO; +extern unsigned IOCTL_SNDCTL_AUDIOINFO; +extern unsigned IOCTL_SNDCTL_ENGINEINFO; +extern unsigned IOCTL_SNDCTL_DSP_GETPLAYVOL; +extern unsigned IOCTL_SNDCTL_DSP_SETPLAYVOL; +extern unsigned IOCTL_SNDCTL_DSP_GETRECVOL; +extern unsigned IOCTL_SNDCTL_DSP_SETRECVOL; +extern unsigned IOCTL_SNDCTL_DSP_SKIP; +extern unsigned IOCTL_SNDCTL_DSP_SILENCE; extern const int si_SEGV_MAPERR; extern const int si_SEGV_ACCERR; @@ -561,6 +2211,8 @@ extern const int si_SEGV_ACCERR; COMPILER_CHECK(offsetof(struct __sanitizer_##CLASS, MEMBER) == \ offsetof(struct CLASS, MEMBER)) +#define SIGACTION_SYMNAME __sigaction14 + #endif // SANITIZER_NETBSD #endif diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cc new file mode 100644 index 00000000000..e114ff42f70 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.cc @@ -0,0 +1,277 @@ +//===-- sanitizer_platform_limits_openbsd.cc ------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of Sanitizer common code. +// +// Sizes and layouts of platform-specific NetBSD data structures. +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" + +#if SANITIZER_OPENBSD +#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 these after system headers to avoid name clashes and ambiguities. +#include "sanitizer_internal_defs.h" +#include "sanitizer_platform_limits_openbsd.h" + +namespace __sanitizer { +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 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_sched_param_sz = sizeof(struct sched_param); +unsigned struct_sockaddr_sz = sizeof(struct sockaddr); +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_msqid_ds_sz = sizeof(struct msqid_ds); +unsigned struct_statvfs_sz = sizeof(struct statvfs); + +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; + +unsigned struct_utmp_sz = sizeof(struct utmp); + +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; + +const int si_SEGV_MAPERR = SEGV_MAPERR; +const int si_SEGV_ACCERR = SEGV_ACCERR; +} // 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); + +CHECK_TYPE_SIZE(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_addrlen); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_addr); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_canonname); +CHECK_SIZE_AND_OFFSET(addrinfo, ai_next); + +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_fileno); +CHECK_SIZE_AND_OFFSET(dirent, d_off); +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(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(ipc_perm); +CHECK_SIZE_AND_OFFSET(ipc_perm, cuid); +CHECK_SIZE_AND_OFFSET(ipc_perm, cgid); +CHECK_SIZE_AND_OFFSET(ipc_perm, uid); +CHECK_SIZE_AND_OFFSET(ipc_perm, gid); +CHECK_SIZE_AND_OFFSET(ipc_perm, mode); +CHECK_SIZE_AND_OFFSET(ipc_perm, seq); +CHECK_SIZE_AND_OFFSET(ipc_perm, key); + +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_atimensec); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_dtime); +CHECK_SIZE_AND_OFFSET(shmid_ds, __shm_dtimensec); +CHECK_SIZE_AND_OFFSET(shmid_ds, shm_ctime); +CHECK_SIZE_AND_OFFSET(shmid_ds, __shm_ctimensec); +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); +// Compare against the union, because we can't reach into the union in a +// compliant way. +#ifdef ifa_dstaddr +#undef ifa_dstaddr +#endif +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_dstaddr); +CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_data); + +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); + +#endif // SANITIZER_OPENBSD diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h new file mode 100644 index 00000000000..8f21de75228 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_openbsd.h @@ -0,0 +1,380 @@ +//===-- sanitizer_platform_limits_openbsd.h -------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of Sanitizer common code. +// +// Sizes and layouts of platform-specific OpenBSD data structures. +//===----------------------------------------------------------------------===// + +#ifndef SANITIZER_PLATFORM_LIMITS_OPENBSD_H +#define SANITIZER_PLATFORM_LIMITS_OPENBSD_H + +#if SANITIZER_OPENBSD + +#include "sanitizer_internal_defs.h" +#include "sanitizer_platform.h" + +#define _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, shift) \ + ((link_map *)((handle) == nullptr ? nullptr : ((char *)(handle) + (shift)))) + +#if defined(__x86_64__) +#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ + _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 312) +#elif defined(__i386__) +#define GET_LINK_MAP_BY_DLOPEN_HANDLE(handle) \ + _GET_LINK_MAP_BY_DLOPEN_HANDLE(handle, 164) +#endif + +#define RLIMIT_AS RLIMIT_DATA + +namespace __sanitizer { +extern unsigned struct_utsname_sz; +extern unsigned struct_stat_sz; +extern unsigned struct_rusage_sz; +extern unsigned siginfo_t_sz; +extern unsigned struct_itimerval_sz; +extern unsigned pthread_t_sz; +extern unsigned pthread_mutex_t_sz; +extern unsigned pthread_cond_t_sz; +extern unsigned pid_t_sz; +extern unsigned timeval_sz; +extern unsigned uid_t_sz; +extern unsigned gid_t_sz; +extern unsigned mbstate_t_sz; +extern unsigned struct_timezone_sz; +extern unsigned struct_tms_sz; +extern unsigned struct_itimerspec_sz; +extern unsigned struct_sigevent_sz; +extern unsigned struct_statfs_sz; +extern unsigned struct_sockaddr_sz; + +extern unsigned struct_rlimit_sz; +extern unsigned struct_utimbuf_sz; +extern unsigned struct_timespec_sz; + +struct __sanitizer_iocb { + u64 aio_offset; + uptr aio_buf; + long aio_nbytes; + u32 aio_fildes; + u32 aio_lio_opcode; + long aio_reqprio; +#if SANITIZER_WORDSIZE == 64 + u8 aio_sigevent[32]; +#else + u8 aio_sigevent[20]; +#endif + u32 _state; + u32 _errno; + long _retval; +}; + +struct __sanitizer___sysctl_args { + int *name; + int nlen; + void *oldval; + uptr *oldlenp; + void *newval; + uptr newlen; +}; + +struct __sanitizer_sem_t { + uptr data[5]; +}; + +struct __sanitizer_ipc_perm { + u32 cuid; + u32 cgid; + u32 uid; + u32 gid; + u32 mode; + unsigned short seq; + long key; +}; + +struct __sanitizer_shmid_ds { + __sanitizer_ipc_perm shm_perm; + int shm_segsz; + u32 shm_lpid; + u32 shm_cpid; + short shm_nattch; + u64 shm_atime; + long __shm_atimensec; + u64 shm_dtime; + long __shm_dtimensec; + u64 shm_ctime; + long __shm_ctimensec; + void *_shm_internal; +}; + +extern unsigned struct_msqid_ds_sz; +extern unsigned struct_mq_attr_sz; +extern unsigned struct_timex_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; + struct __sanitizer_sockaddr *ifa_addr; // (struct sockaddr *) + struct __sanitizer_sockaddr *ifa_netmask; // (struct sockaddr *) + struct __sanitizer_sockaddr *ifa_dstaddr; // (struct sockaddr *) + void *ifa_data; +}; + +typedef unsigned __sanitizer_pthread_key_t; + +typedef long long __sanitizer_time_t; +typedef int __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_passwd { + char *pw_name; + char *pw_passwd; + int pw_uid; + int pw_gid; + __sanitizer_time_t pw_change; + char *pw_class; + char *pw_gecos; + char *pw_dir; + char *pw_shell; + __sanitizer_time_t pw_expire; +}; + +struct __sanitizer_group { + char *gr_name; + char *gr_passwd; + int gr_gid; + char **gr_mem; +}; + +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 { + u64 d_fileno; + u64 d_off; + u16 d_reclen; +}; + +typedef u64 __sanitizer_clock_t; +typedef u32 __sanitizer_clockid_t; + +typedef u32 __sanitizer___kernel_uid_t; +typedef u32 __sanitizer___kernel_gid_t; +typedef u64 __sanitizer___kernel_off_t; +typedef struct { + u32 fds_bits[8]; +} __sanitizer___kernel_fd_set; + +typedef struct { + unsigned int pta_magic; + int pta_flags; + void *pta_private; +} __sanitizer_pthread_attr_t; + +typedef unsigned int __sanitizer_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_sighandler_ptr handler; + __sanitizer_sigactionhandler_ptr sigaction; + }; + __sanitizer_sigset_t sa_mask; + int sa_flags; +}; + +typedef __sanitizer_sigset_t __sanitizer_kernel_sigset_t; + +struct __sanitizer_kernel_sigaction_t { + union { + void (*handler)(int signo); + void (*sigaction)(int signo, void *info, void *ctx); + }; + unsigned long sa_flags; + void (*sa_restorer)(void); + __sanitizer_kernel_sigset_t sa_mask; +}; + +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 { +#if SANITIZER_WORDSIZE == 64 + u64 dlpi_addr; +#else + u32 dlpi_addr; +#endif + const char *dlpi_name; + const void *dlpi_phdr; +#if SANITIZER_WORDSIZE == 64 + u32 dlpi_phnum; +#else + u16 dlpi_phnum; +#endif +}; + +extern unsigned struct_ElfW_Phdr_sz; + +struct __sanitizer_addrinfo { + int ai_flags; + int ai_family; + int ai_socktype; + int ai_protocol; + unsigned ai_addrlen; + struct __sanitizer_sockaddr *ai_addr; + char *ai_canonname; + 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 { + int gl_pathc; + int gl_matchc; + int gl_offs; + int gl_flags; + char **gl_pathv; + void **gl_statv; + 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; + +typedef char __sanitizer_FILE; +#define SANITIZER_HAS_STRUCT_FILE 0 + +extern int shmctl_ipc_stat; + +// This simplifies generic code +#define struct_shminfo_sz -1 +#define struct_shm_info_sz -1 +#define shmctl_shm_stat -1 +#define shmctl_ipc_info -1 +#define shmctl_shm_info -1 + +extern unsigned struct_utmp_sz; +extern unsigned struct_utmpx_sz; + +extern int map_fixed; + +// ioctl arguments +struct __sanitizer_ifconf { + int ifc_len; + union { + void *ifcu_req; + } ifc_ifcu; +}; + +extern const int si_SEGV_MAPERR; +extern const int si_SEGV_ACCERR; +} // namespace __sanitizer + +#define CHECK_TYPE_SIZE(TYPE) \ + COMPILER_CHECK(sizeof(__sanitizer_##TYPE) == sizeof(TYPE)) + +#define CHECK_SIZE_AND_OFFSET(CLASS, MEMBER) \ + COMPILER_CHECK(sizeof(((__sanitizer_##CLASS *)NULL)->MEMBER) == \ + sizeof(((CLASS *)NULL)->MEMBER)); \ + COMPILER_CHECK(offsetof(__sanitizer_##CLASS, MEMBER) == \ + 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 __sigaction14 + +#endif // SANITIZER_OPENBSD + +#endif diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc index a915d37cdfe..6cd4a5bac8b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.cc @@ -207,6 +207,7 @@ namespace __sanitizer { 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); @@ -273,9 +274,10 @@ namespace __sanitizer { unsigned struct_statvfs_sz = sizeof(struct statvfs); #endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID - uptr sig_ign = (uptr)SIG_IGN; - uptr sig_dfl = (uptr)SIG_DFL; - uptr sa_siginfo = (uptr)SA_SIGINFO; + 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; #if SANITIZER_LINUX int e_tabsz = (int)E_TABSZ; @@ -1033,6 +1035,16 @@ CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_len); CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_level); CHECK_SIZE_AND_OFFSET(cmsghdr, cmsg_type); +#ifndef __GLIBC_PREREQ +#define __GLIBC_PREREQ(x, y) 0 +#endif + +#if SANITIZER_LINUX && (__ANDROID_API__ >= 21 || __GLIBC_PREREQ (2, 14)) +CHECK_TYPE_SIZE(mmsghdr); +CHECK_SIZE_AND_OFFSET(mmsghdr, msg_hdr); +CHECK_SIZE_AND_OFFSET(mmsghdr, msg_len); +#endif + COMPILER_CHECK(sizeof(__sanitizer_dirent) <= sizeof(dirent)); CHECK_SIZE_AND_OFFSET(dirent, d_ino); #if SANITIZER_MAC @@ -1068,9 +1080,6 @@ 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); -#ifndef __GLIBC_PREREQ -#define __GLIBC_PREREQ(x, y) 0 -#endif #if !defined(__s390x__) || __GLIBC_PREREQ (2, 20) // On s390x glibc 2.19 and earlier sa_flags was unsigned long, and sa_resv // didn't exist. @@ -1196,7 +1205,7 @@ CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_data); #endif #if SANITIZER_LINUX -COMPILER_CHECK(sizeof(__sanitizer_mallinfo) == sizeof(struct mallinfo)); +COMPILER_CHECK(sizeof(__sanitizer_struct_mallinfo) == sizeof(struct mallinfo)); #endif #if !SANITIZER_ANDROID diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h index 132e5e9beea..91f38918f35 100644 --- a/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_posix.h @@ -22,7 +22,7 @@ // 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) + 544))) + ((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 @@ -44,6 +44,7 @@ namespace __sanitizer { 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; @@ -86,7 +87,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; @@ -184,13 +185,13 @@ namespace __sanitizer { #endif // SANITIZER_LINUX || SANITIZER_FREEBSD #if SANITIZER_ANDROID - struct __sanitizer_mallinfo { + struct __sanitizer_struct_mallinfo { uptr v[10]; }; #endif #if SANITIZER_LINUX && !SANITIZER_ANDROID - struct __sanitizer_mallinfo { + struct __sanitizer_struct_mallinfo { int v[10]; }; @@ -411,6 +412,18 @@ namespace __sanitizer { 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; @@ -445,6 +458,12 @@ namespace __sanitizer { int mnt_freq; int mnt_passno; }; + + struct __sanitizer_file_handle { + unsigned int handle_bytes; + int handle_type; + unsigned char f_handle[1]; // variable sized + }; #endif #if SANITIZER_MAC || SANITIZER_FREEBSD @@ -479,6 +498,13 @@ namespace __sanitizer { }; #endif +#if SANITIZER_LINUX + struct __sanitizer_mmsghdr { + __sanitizer_msghdr msg_hdr; + unsigned int msg_len; + }; +#endif + #if SANITIZER_MAC struct __sanitizer_dirent { unsigned long long d_ino; @@ -531,7 +557,7 @@ namespace __sanitizer { typedef long __sanitizer_clock_t; #endif -#if SANITIZER_LINUX +#if SANITIZER_LINUX || SANITIZER_FREEBSD typedef int __sanitizer_clockid_t; #endif @@ -592,13 +618,22 @@ namespace __sanitizer { }; #endif + 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); + // Linux system headers define the 'sa_handler' and 'sa_sigaction' macros. #if SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 64) struct __sanitizer_sigaction { unsigned sa_flags; union { - void (*sigaction)(int sig, void *siginfo, void *uctx); - void (*handler)(int sig); + __sanitizer_sigactionhandler_ptr sigaction; + __sanitizer_sighandler_ptr handler; }; __sanitizer_sigset_t sa_mask; void (*sa_restorer)(); @@ -607,16 +642,16 @@ namespace __sanitizer { struct __sanitizer_sigaction { unsigned sa_flags; union { - void (*sigaction)(int sig, void *siginfo, void *uctx); - void (*handler)(int sig); + __sanitizer_sigactionhandler_ptr sigaction; + __sanitizer_sighandler_ptr handler; }; __sanitizer_sigset_t sa_mask; }; #elif SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 32) struct __sanitizer_sigaction { union { - void (*sigaction)(int sig, void *siginfo, void *uctx); - void (*handler)(int sig); + __sanitizer_sigactionhandler_ptr sigaction; + __sanitizer_sighandler_ptr handler; }; __sanitizer_sigset_t sa_mask; uptr sa_flags; @@ -628,8 +663,8 @@ namespace __sanitizer { unsigned int sa_flags; #endif union { - void (*sigaction)(int sig, void *siginfo, void *uctx); - void (*handler)(int sig); + __sanitizer_sigactionhandler_ptr sigaction; + __sanitizer_sighandler_ptr handler; }; #if SANITIZER_FREEBSD int sa_flags; @@ -688,7 +723,7 @@ namespace __sanitizer { unsigned int sa_flags; union { void (*handler)(int signo); - void (*sigaction)(int signo, void *info, void *ctx); + void (*sigaction)(int signo, __sanitizer_siginfo *info, void *ctx); }; __sanitizer_kernel_sigset_t sa_mask; void (*sa_restorer)(void); @@ -697,7 +732,7 @@ namespace __sanitizer { struct __sanitizer_kernel_sigaction_t { union { void (*handler)(int signo); - void (*sigaction)(int signo, void *info, void *ctx); + void (*sigaction)(int signo, __sanitizer_siginfo *info, void *ctx); }; unsigned long sa_flags; void (*sa_restorer)(void); @@ -705,9 +740,10 @@ namespace __sanitizer { }; #endif - extern uptr sig_ign; - extern uptr sig_dfl; - extern uptr sa_siginfo; + extern const uptr sig_ign; + extern const uptr sig_dfl; + extern const uptr sig_err; + extern const uptr sa_siginfo; #if SANITIZER_LINUX extern int e_tabsz; @@ -1485,6 +1521,8 @@ struct __sanitizer_cookie_io_functions_t { COMPILER_CHECK(offsetof(struct __sanitizer_##CLASS, MEMBER) == \ offsetof(struct CLASS, MEMBER)) +#define SIGACTION_SYMNAME sigaction + #endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC #endif diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cc b/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cc new file mode 100644 index 00000000000..00b0ffcff59 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.cc @@ -0,0 +1,364 @@ +//===-- sanitizer_platform_limits_solaris.cc ------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of Sanitizer common code. +// +// Sizes and layouts of platform-specific Solaris data structures. +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" + +#if SANITIZER_SOLARIS +#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 these after system headers to avoid name clashes and ambiguities. +#include "sanitizer_internal_defs.h" +#include "sanitizer_platform_limits_solaris.h" + +namespace __sanitizer { + unsigned struct_utsname_sz = sizeof(struct utsname); + unsigned struct_stat_sz = sizeof(struct stat); + unsigned struct_stat64_sz = sizeof(struct stat64); + 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 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_timespec_sz = sizeof(struct timespec); +#if SANITIZER_SOLARIS32 + unsigned struct_statvfs64_sz = sizeof(struct statvfs64); +#endif + unsigned struct_statvfs_sz = sizeof(struct statvfs); + + 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; + + unsigned struct_utmp_sz = sizeof(struct utmp); + 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(ElfW(Phdr)); + + int glob_nomatch = GLOB_NOMATCH; + + 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); + + unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req); + unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req); + + 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_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_MTIOCGET = MTIOCGET; + unsigned IOCTL_MTIOCTOP = MTIOCTOP; + + const int si_SEGV_MAPERR = SEGV_MAPERR; + const int si_SEGV_ACCERR = SEGV_ACCERR; +} // 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_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_off); +CHECK_SIZE_AND_OFFSET(dirent, d_reclen); + +#if SANITIZER_SOLARIS32 +COMPILER_CHECK(sizeof(__sanitizer_dirent64) <= sizeof(dirent64)); +CHECK_SIZE_AND_OFFSET(dirent64, d_ino); +CHECK_SIZE_AND_OFFSET(dirent64, d_off); +CHECK_SIZE_AND_OFFSET(dirent64, d_reclen); +#endif + +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_STRUCT_SIZE_AND_OFFSET(sigaction, sa_flags); + +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_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_SIZE_AND_OFFSET(ipc_perm, mode); + +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); +// Compare against the union, because we can't reach into the union in a +// compliant way. +#ifdef ifa_dstaddr +#undef ifa_dstaddr +#endif +COMPILER_CHECK(sizeof(((__sanitizer_ifaddrs *)nullptr)->ifa_dstaddr) == + sizeof(((ifaddrs *)nullptr)->ifa_ifu)); +COMPILER_CHECK(offsetof(__sanitizer_ifaddrs, ifa_dstaddr) == + offsetof(ifaddrs, ifa_ifu)); +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); + +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); + +CHECK_TYPE_SIZE(sem_t); + +#endif // SANITIZER_SOLARIS diff --git a/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.h b/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.h new file mode 100644 index 00000000000..0bd3de88562 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_platform_limits_solaris.h @@ -0,0 +1,495 @@ +//===-- sanitizer_platform_limits_solaris.h -------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is a part of Sanitizer common code. +// +// Sizes and layouts of platform-specific Solaris data structures. +//===----------------------------------------------------------------------===// + +#ifndef SANITIZER_PLATFORM_LIMITS_SOLARIS_H +#define SANITIZER_PLATFORM_LIMITS_SOLARIS_H + +#if SANITIZER_SOLARIS + +#include "sanitizer_internal_defs.h" +#include "sanitizer_platform.h" + +namespace __sanitizer { +extern unsigned struct_utsname_sz; +extern unsigned struct_stat_sz; +extern unsigned struct_stat64_sz; +extern unsigned struct_rusage_sz; +extern unsigned siginfo_t_sz; +extern unsigned struct_itimerval_sz; +extern unsigned pthread_t_sz; +extern unsigned pthread_mutex_t_sz; +extern unsigned pthread_cond_t_sz; +extern unsigned pid_t_sz; +extern unsigned timeval_sz; +extern unsigned uid_t_sz; +extern unsigned gid_t_sz; +extern unsigned mbstate_t_sz; +extern unsigned struct_timezone_sz; +extern unsigned struct_tms_sz; +extern unsigned struct_itimerspec_sz; +extern unsigned struct_sigevent_sz; +extern unsigned struct_sched_param_sz; +extern unsigned struct_statfs64_sz; +extern unsigned struct_statfs_sz; +extern unsigned struct_sockaddr_sz; +extern unsigned ucontext_t_sz; + +extern unsigned struct_timespec_sz; +extern unsigned struct_rlimit_sz; +extern unsigned struct_utimbuf_sz; + +struct __sanitizer_sem_t { + //u64 data[6]; + u32 sem_count; + u16 sem_type; + u16 sem_magic; + u64 sem_pad1[3]; + u64 sem_pad2[2]; +}; + +struct __sanitizer_ipc_perm { + unsigned int uid; // uid_t + unsigned int gid; // gid_t + unsigned int cuid; // uid_t + unsigned int cgid; // gid_t + unsigned int mode; // mode_t + unsigned int seq; // uint_t + int key; // key_t +#if !defined(_LP64) + int pad[4]; +#endif + }; + +struct __sanitizer_shmid_ds { + __sanitizer_ipc_perm shm_perm; + unsigned long shm_segsz; // size_t + unsigned long shm_flags; // uintptr_t + unsigned short shm_lkcnt; // ushort_t + int shm_lpid; // pid_t + int shm_cpid; // pid_t + unsigned long shm_nattch; // shmatt_t + unsigned long shm_cnattch; // ulong_t +#if defined(_LP64) + long shm_atime; // time_t + long shm_dtime; + long shm_ctime; + void *shm_amp; + u64 shm_gransize; // uint64_t + u64 shm_allocated; // uint64_t + u64 shm_pad4[1]; // int64_t +#else + long shm_atime; // time_t + int shm_pad1; // int32_t + long shm_dtime; // time_t + int shm_pad2; // int32_t + long shm_ctime; // time_t + void *shm_amp; + u64 shm_gransize; // uint64_t + u64 shm_allocated; // uint64_t +#endif +}; + +extern unsigned struct_statvfs_sz; +#if SANITIZER_SOLARIS32 +extern unsigned struct_statvfs64_sz; +#endif + +struct __sanitizer_iovec { + void *iov_base; + uptr iov_len; +}; + +struct __sanitizer_ifaddrs { + struct __sanitizer_ifaddrs *ifa_next; + char *ifa_name; + u64 ifa_flags; // uint64_t + void *ifa_addr; // (struct sockaddr *) + void *ifa_netmask; // (struct sockaddr *) + // This is a union on Linux. +# ifdef ifa_dstaddr +# undef ifa_dstaddr +# endif + void *ifa_dstaddr; // (struct sockaddr *) + void *ifa_data; +}; + +typedef unsigned __sanitizer_pthread_key_t; + +struct __sanitizer_XDR { + int x_op; + void *x_ops; + uptr x_public; + uptr x_private; + uptr x_base; + unsigned x_handy; +}; + +const int __sanitizer_XDR_ENCODE = 0; +const int __sanitizer_XDR_DECODE = 1; +const int __sanitizer_XDR_FREE = 2; + +struct __sanitizer_passwd { + char *pw_name; + char *pw_passwd; + unsigned int pw_uid; // uid_t + unsigned int pw_gid; // gid_t + char *pw_age; + char *pw_comment; + char *pw_gecos; + char *pw_dir; + char *pw_shell; +}; + +struct __sanitizer_group { + char *gr_name; + char *gr_passwd; + int gr_gid; + char **gr_mem; +}; + +typedef long __sanitizer_time_t; + +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; +}; + +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; +}; + +#if SANITIZER_SOLARIS32 && 0 +// FIXME: need to deal with large file and non-large file cases +struct __sanitizer_dirent { + unsigned long long d_ino; + long long d_off; + unsigned short d_reclen; + // more fields that we don't care about +}; +#else +struct __sanitizer_dirent { + unsigned long d_ino; + long d_off; + unsigned short d_reclen; + // more fields that we don't care about +}; +#endif + +struct __sanitizer_dirent64 { + unsigned long long d_ino; + unsigned long long d_off; + unsigned short d_reclen; + // more fields that we don't care about +}; + +typedef long __sanitizer_clock_t; +typedef int __sanitizer_clockid_t; + +// This thing depends on the platform. We are only interested in the upper +// limit. Verified with a compiler assert in .cc. +const int pthread_attr_t_max_sz = 128; +union __sanitizer_pthread_attr_t { + char size[pthread_attr_t_max_sz]; // NOLINT + void *align; +}; + +struct __sanitizer_sigset_t { + // uint32_t * 4 + unsigned int __bits[4]; +}; + +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 { + int sa_flags; + union { + __sanitizer_sigactionhandler_ptr sigaction; + __sanitizer_sighandler_ptr handler; + }; + __sanitizer_sigset_t sa_mask; +#if !defined(_LP64) + int sa_resv[2]; +#endif +}; + +struct __sanitizer_kernel_sigset_t { + u8 sig[8]; +}; + +struct __sanitizer_kernel_sigaction_t { + union { + void (*handler)(int signo); + void (*sigaction)(int signo, __sanitizer_siginfo *info, void *ctx); + }; + unsigned long sa_flags; + void (*sa_restorer)(void); + __sanitizer_kernel_sigset_t sa_mask; +}; + +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; +#if defined(__sparcv9) + int _ai_pad; +#endif + 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 long __sanitizer_nfds_t; + +struct __sanitizer_glob_t { + uptr gl_pathc; + char **gl_pathv; + uptr gl_offs; + char **gl_pathp; + int gl_pathn; +}; + +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_wordp; + int we_wordn; +}; + +typedef void __sanitizer_FILE; +#define SANITIZER_HAS_STRUCT_FILE 0 + +// This simplifies generic code +#define struct_shminfo_sz -1 +#define struct_shm_info_sz -1 +#define shmctl_shm_stat -1 +#define shmctl_ipc_info -1 +#define shmctl_shm_info -1 + +extern int shmctl_ipc_stat; + +extern unsigned struct_utmp_sz; +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 +#define IOC_SIZEBITS 12 +#define IOC_DIRBITS 4 +#undef IOC_NONE +#define IOC_NONE 2U // IOC_VOID +#define IOC_READ 4U // IOC_OUT +#define IOC_WRITE 8U // IOC_IN + +#define IOC_NRMASK ((1 << IOC_NRBITS) - 1) +#define IOC_TYPEMASK ((1 << IOC_TYPEBITS) - 1) +#define IOC_SIZEMASK ((1 << IOC_SIZEBITS) - 1) +#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 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) + +#if defined(__sparc__) +// In sparc the 14 bits SIZE field overlaps with the +// least significant bit of DIR, so either IOC_READ or +// IOC_WRITE shall be 1 in order to get a non-zero SIZE. +#define IOC_SIZE(nr) \ + ((((((nr) >> 29) & 0x7) & (4U | 2U)) == 0) ? 0 : (((nr) >> 16) & 0x3fff)) +#else +#define IOC_SIZE(nr) (((nr) >> IOC_SIZESHIFT) & IOC_SIZEMASK) +#endif + +extern unsigned struct_ifreq_sz; +extern unsigned struct_termios_sz; +extern unsigned struct_winsize_sz; + +extern unsigned struct_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_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_MTIOCGET; +extern unsigned IOCTL_MTIOCTOP; + +extern const int si_SEGV_MAPERR; +extern const int si_SEGV_ACCERR; +} // namespace __sanitizer + +#define CHECK_TYPE_SIZE(TYPE) \ + COMPILER_CHECK(sizeof(__sanitizer_##TYPE) == sizeof(TYPE)) + +#define CHECK_SIZE_AND_OFFSET(CLASS, MEMBER) \ + COMPILER_CHECK(sizeof(((__sanitizer_##CLASS *) NULL)->MEMBER) == \ + sizeof(((CLASS *) NULL)->MEMBER)); \ + COMPILER_CHECK(offsetof(__sanitizer_##CLASS, MEMBER) == \ + 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)) + +#endif // SANITIZER_SOLARIS + +#endif diff --git a/libsanitizer/sanitizer_common/sanitizer_posix.cc b/libsanitizer/sanitizer_common/sanitizer_posix.cc index 8f59deb23b3..71994bac840 100644 --- a/libsanitizer/sanitizer_common/sanitizer_posix.cc +++ b/libsanitizer/sanitizer_common/sanitizer_posix.cc @@ -19,7 +19,6 @@ #include "sanitizer_libc.h" #include "sanitizer_posix.h" #include "sanitizer_procmaps.h" -#include "sanitizer_stacktrace.h" #include #include @@ -151,11 +150,15 @@ bool MprotectReadOnly(uptr addr, uptr size) { return 0 == internal_mprotect((void *)addr, size, PROT_READ); } +#if !SANITIZER_MAC +void MprotectMallocZones(void *addr, int prot) {} +#endif + fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *errno_p) { int flags; switch (mode) { case RdOnly: flags = O_RDONLY; break; - case WrOnly: flags = O_WRONLY | O_CREAT; break; + case WrOnly: flags = O_WRONLY | O_CREAT | O_TRUNC; break; case RdWr: flags = O_RDWR | O_CREAT; break; } fd_t res = internal_open(filename, flags, 0660); diff --git a/libsanitizer/sanitizer_common/sanitizer_posix.h b/libsanitizer/sanitizer_common/sanitizer_posix.h index 9626654e53a..a013f354eec 100644 --- a/libsanitizer/sanitizer_common/sanitizer_posix.h +++ b/libsanitizer/sanitizer_common/sanitizer_posix.h @@ -15,7 +15,9 @@ // This header should NOT include any other headers from sanitizer runtime. #include "sanitizer_internal_defs.h" #include "sanitizer_platform_limits_netbsd.h" +#include "sanitizer_platform_limits_openbsd.h" #include "sanitizer_platform_limits_posix.h" +#include "sanitizer_platform_limits_solaris.h" #if !SANITIZER_POSIX // Make it hard to accidentally use any of functions declared in this file: @@ -56,6 +58,11 @@ uptr internal_waitpid(int pid, int *status, int options); int internal_fork(); int internal_forkpty(int *amaster); +int internal_sysctl(const int *name, unsigned int namelen, void *oldp, + uptr *oldlenp, const void *newp, uptr newlen); +int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp, + const void *newp, uptr newlen); + // These functions call appropriate pthread_ functions directly, bypassing // the interceptor. They are weak and may not be present in some tools. SANITIZER_WEAK_ATTRIBUTE diff --git a/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cc index 1a37118c299..a0e96fac223 100644 --- a/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_posix_libcdep.cc @@ -17,11 +17,11 @@ #include "sanitizer_common.h" #include "sanitizer_flags.h" #include "sanitizer_platform_limits_netbsd.h" +#include "sanitizer_platform_limits_openbsd.h" #include "sanitizer_platform_limits_posix.h" +#include "sanitizer_platform_limits_solaris.h" #include "sanitizer_posix.h" #include "sanitizer_procmaps.h" -#include "sanitizer_stacktrace.h" -#include "sanitizer_symbolizer.h" #include #include @@ -39,7 +39,7 @@ #if SANITIZER_FREEBSD // The MAP_NORESERVE define has been removed in FreeBSD 11.x, and even before // that, it was never implemented. So just define it to zero. -#undef MAP_NORESERVE +#undef MAP_NORESERVE #define MAP_NORESERVE 0 #endif @@ -60,19 +60,29 @@ void ReleaseMemoryPagesToOS(uptr beg, uptr end) { uptr beg_aligned = RoundUpTo(beg, page_size); uptr end_aligned = RoundDownTo(end, page_size); if (beg_aligned < end_aligned) - madvise((void*)beg_aligned, end_aligned - beg_aligned, MADV_DONTNEED); + // In the default Solaris compilation environment, madvise() is declared + // to take a caddr_t arg; casting it to void * results in an invalid + // conversion error, so use char * instead. + madvise((char *)beg_aligned, end_aligned - beg_aligned, + SANITIZER_MADVISE_DONTNEED); } -void NoHugePagesInRegion(uptr addr, uptr size) { +bool NoHugePagesInRegion(uptr addr, uptr size) { #ifdef MADV_NOHUGEPAGE // May not be defined on old systems. - madvise((void *)addr, size, MADV_NOHUGEPAGE); + return madvise((void *)addr, size, MADV_NOHUGEPAGE) == 0; +#else + return true; #endif // MADV_NOHUGEPAGE } -void DontDumpShadowMemory(uptr addr, uptr length) { -#ifdef MADV_DONTDUMP - madvise((void *)addr, length, MADV_DONTDUMP); -#endif +bool DontDumpShadowMemory(uptr addr, uptr length) { +#if defined(MADV_DONTDUMP) + return madvise((void *)addr, length, MADV_DONTDUMP) == 0; +#elif defined(MADV_NOCORE) + return madvise((void *)addr, length, MADV_NOCORE) == 0; +#else + return true; +#endif // MADV_DONTDUMP } static rlim_t getlim(int res) { @@ -211,6 +221,7 @@ void InstallDeadlySignalHandlers(SignalHandlerType handler) { MaybeInstallSigaction(SIGABRT, handler); MaybeInstallSigaction(SIGFPE, handler); MaybeInstallSigaction(SIGILL, handler); + MaybeInstallSigaction(SIGTRAP, handler); } bool SignalContext::IsStackOverflow() const { @@ -223,7 +234,9 @@ bool SignalContext::IsStackOverflow() const { // take it into account. bool IsStackAccess = addr >= (sp & ~0xFFF) && addr < sp + 0xFFFF; #else - bool IsStackAccess = addr + 512 > sp && addr < sp + 0xFFFF; + // Let's accept up to a page size away from top of stack. Things like stack + // probing can trigger accesses with such large offsets. + bool IsStackAccess = addr + GetPageSizeCached() > sp && addr < sp + 0xFFFF; #endif #if __powerpc__ @@ -283,16 +296,12 @@ bool IsAccessibleMemoryRange(uptr beg, uptr size) { return result; } -void PrepareForSandboxing(__sanitizer_sandbox_arguments *args) { +void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args) { // Some kinds of sandboxes may forbid filesystem access, so we won't be able // to read the file mappings from /proc/self/maps. Luckily, neither the // process will be able to load additional libraries, so it's fine to use the // cached mappings. MemoryMappingLayout::CacheMemoryMappings(); - // Same for /proc/self/exe in the symbolizer. -#if !SANITIZER_GO - Symbolizer::GetOrInit()->PrepareForSandboxing(); -#endif } #if SANITIZER_ANDROID || SANITIZER_GO @@ -317,7 +326,7 @@ int GetNamedMappingFd(const char *name, uptr size) { } #endif -void *MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) { +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; @@ -327,12 +336,48 @@ void *MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) { RoundUpTo(size, PageSize), PROT_READ | PROT_WRITE, flags, fd, 0); int reserrno; - if (internal_iserror(p, &reserrno)) + if (internal_iserror(p, &reserrno)) { Report("ERROR: %s failed to " "allocate 0x%zx (%zd) bytes at address %zx (errno: %d)\n", SanitizerToolName, size, size, fixed_addr, reserrno); + return false; + } IncreaseTotalMmap(size); - return (void *)p; + return true; +} + +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); + size_ = size; + name_ = name; + (void)os_handle_; // unsupported + return reinterpret_cast(base_); +} + +// 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::MapOrDie(uptr fixed_addr, uptr size) { + return reinterpret_cast(MmapFixedOrDie(fixed_addr, size)); +} + +void ReservedAddressRange::Unmap(uptr addr, uptr size) { + CHECK_LE(size, size_); + if (addr == reinterpret_cast(base_)) + // If we unmap the whole range, just null out the base. + base_ = (size == size_) ? nullptr : reinterpret_cast(addr + size); + else + CHECK_EQ(addr + size, reinterpret_cast(base_) + size_); + size_ -= size; + UnmapOrDie(reinterpret_cast(addr), size); } void *MmapFixedNoAccess(uptr fixed_addr, uptr size, const char *name) { diff --git a/libsanitizer/sanitizer_common/sanitizer_printf.cc b/libsanitizer/sanitizer_common/sanitizer_printf.cc index 1456c765b2c..5da8c5f189d 100644 --- a/libsanitizer/sanitizer_common/sanitizer_printf.cc +++ b/libsanitizer/sanitizer_common/sanitizer_printf.cc @@ -93,22 +93,31 @@ static int AppendSignedDecimal(char **buff, const char *buff_end, s64 num, false /* uppercase */); } -static int AppendString(char **buff, const char *buff_end, int precision, - const char *s) { + +// Use the fact that explicitly requesting 0 width (%0s) results in UB and +// interpret width == 0 as "no width requested": +// width == 0 - no width requested +// width < 0 - left-justify s within and pad it to -width chars, if necessary +// width > 0 - right-justify s, not implemented yet +static int AppendString(char **buff, const char *buff_end, int width, + int max_chars, const char *s) { if (!s) s = ""; int result = 0; for (; *s; s++) { - if (precision >= 0 && result >= precision) + if (max_chars >= 0 && result >= max_chars) break; result += AppendChar(buff, buff_end, *s); } + // Only the left justified strings are supported. + while (width < -result) + result += AppendChar(buff, buff_end, ' '); return result; } static int AppendPointer(char **buff, const char *buff_end, u64 ptr_value) { int result = 0; - result += AppendString(buff, buff_end, -1, "0x"); + result += AppendString(buff, buff_end, 0, -1, "0x"); result += AppendUnsigned(buff, buff_end, ptr_value, 16, SANITIZER_POINTER_FORMAT_LENGTH, true /* pad_with_zero */, false /* uppercase */); @@ -118,8 +127,8 @@ static int AppendPointer(char **buff, const char *buff_end, u64 ptr_value) { int VSNPrintf(char *buff, int buff_length, const char *format, va_list args) { static const char *kPrintfFormatsHelp = - "Supported Printf formats: %([0-9]*)?(z|ll)?{d,u,x,X}; %p; %(\\.\\*)?s; " - "%c\n"; + "Supported Printf formats: %([0-9]*)?(z|ll)?{d,u,x,X}; %p; " + "%[-]([0-9]*)?(\\.\\*)?s; %c\n"; RAW_CHECK(format); RAW_CHECK(buff_length > 0); const char *buff_end = &buff[buff_length - 1]; @@ -131,6 +140,9 @@ int VSNPrintf(char *buff, int buff_length, continue; } cur++; + bool left_justified = *cur == '-'; + if (left_justified) + cur++; bool have_width = (*cur >= '0' && *cur <= '9'); bool pad_with_zero = (*cur == '0'); int width = 0; @@ -151,9 +163,10 @@ int VSNPrintf(char *buff, int buff_length, cur += have_ll * 2; s64 dval; u64 uval; - bool have_flags = have_width | have_z | have_ll; - // Only %s supports precision for now - CHECK(!(precision >= 0 && *cur != 's')); + const bool have_length = have_z || have_ll; + const bool have_flags = have_width || have_length; + // At the moment only %s supports precision and left-justification. + CHECK(!((precision >= 0 || left_justified) && *cur != 's')); switch (*cur) { case 'd': { dval = have_ll ? va_arg(args, s64) @@ -180,8 +193,11 @@ int VSNPrintf(char *buff, int buff_length, break; } case 's': { - RAW_CHECK_MSG(!have_flags, kPrintfFormatsHelp); - result += AppendString(&buff, buff_end, precision, va_arg(args, char*)); + RAW_CHECK_MSG(!have_length, kPrintfFormatsHelp); + // Only left-justified width is supported. + CHECK(!have_width || left_justified); + result += AppendString(&buff, buff_end, left_justified ? -width : width, + precision, va_arg(args, char*)); break; } case 'c': { diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps.h b/libsanitizer/sanitizer_common/sanitizer_procmaps.h index 040f6940f17..606b2921443 100644 --- a/libsanitizer/sanitizer_common/sanitizer_procmaps.h +++ b/libsanitizer/sanitizer_common/sanitizer_procmaps.h @@ -14,7 +14,8 @@ #include "sanitizer_platform.h" -#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ + SANITIZER_OPENBSD || SANITIZER_MAC || SANITIZER_SOLARIS #include "sanitizer_common.h" #include "sanitizer_internal_defs.h" @@ -92,6 +93,5 @@ uptr ParseHex(const char **p); } // namespace __sanitizer -#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || - // SANITIZER_MAC +#endif #endif // SANITIZER_PROCMAPS_H diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_freebsd.cc b/libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cc similarity index 57% rename from libsanitizer/sanitizer_common/sanitizer_procmaps_freebsd.cc rename to libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cc index ba5d1449c0e..b7887d9e4d3 100644 --- a/libsanitizer/sanitizer_common/sanitizer_procmaps_freebsd.cc +++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_bsd.cc @@ -1,33 +1,44 @@ -//===-- sanitizer_procmaps_freebsd.cc -------------------------------------===// +//===-- sanitizer_procmaps_bsd.cc -----------------------------------------===// // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// // -// Information about the process mappings (FreeBSD and NetBSD-specific parts). +// Information about the process mappings +// (FreeBSD, OpenBSD and NetBSD-specific parts). //===----------------------------------------------------------------------===// #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD #include "sanitizer_common.h" #if SANITIZER_FREEBSD #include "sanitizer_freebsd.h" #endif #include "sanitizer_procmaps.h" -#include +// clang-format off +#include #include +// clang-format on +#include #if SANITIZER_FREEBSD #include #endif +#include +#if SANITIZER_OPENBSD +#define KVME_PROT_READ KVE_PROT_READ +#define KVME_PROT_WRITE KVE_PROT_WRITE +#define KVME_PROT_EXEC KVE_PROT_EXEC +#endif + // Fix 'kinfo_vmentry' definition on FreeBSD prior v9.2 in 32-bit mode. #if SANITIZER_FREEBSD && (SANITIZER_WORDSIZE == 32) -# include -# if __FreeBSD_version <= 902001 // v9.2 -# define kinfo_vmentry xkinfo_vmentry -# endif +#include +#if __FreeBSD_version <= 902001 // v9.2 +#define kinfo_vmentry xkinfo_vmentry +#endif #endif namespace __sanitizer { @@ -39,35 +50,58 @@ void ReadProcMaps(ProcSelfMapsBuff *proc_maps) { KERN_PROC, KERN_PROC_VMMAP, getpid() -#else +#elif SANITIZER_OPENBSD + CTL_KERN, + KERN_PROC_VMMAP, + getpid() +#elif SANITIZER_NETBSD CTL_VM, VM_PROC, VM_PROC_MAP, getpid(), sizeof(struct kinfo_vmentry) +#else +#error "not supported" #endif }; - size_t Size = 0; - int Err = sysctl(Mib, ARRAY_SIZE(Mib), NULL, &Size, NULL, 0); + uptr Size = 0; + int Err = internal_sysctl(Mib, ARRAY_SIZE(Mib), NULL, &Size, NULL, 0); CHECK_EQ(Err, 0); CHECK_GT(Size, 0); +#if !SANITIZER_OPENBSD size_t MmapedSize = Size * 4 / 3; void *VmMap = MmapOrDie(MmapedSize, "ReadProcMaps()"); Size = MmapedSize; - Err = sysctl(Mib, ARRAY_SIZE(Mib), VmMap, &Size, NULL, 0); + Err = internal_sysctl(Mib, ARRAY_SIZE(Mib), VmMap, &Size, NULL, 0); + CHECK_EQ(Err, 0); + proc_maps->data = (char *)VmMap; +#else + size_t PageSize = GetPageSize(); + size_t MmapedSize = Size; + MmapedSize = ((MmapedSize - 1) / PageSize + 1) * PageSize; + char *Mem = (char *)MmapOrDie(MmapedSize, "ReadProcMaps()"); + Size = 2 * Size + 10 * sizeof(struct kinfo_vmentry); + if (Size > 0x10000) + Size = 0x10000; + Size = (Size / sizeof(struct kinfo_vmentry)) * sizeof(struct kinfo_vmentry); + Err = internal_sysctl(Mib, ARRAY_SIZE(Mib), Mem, &Size, NULL, 0); CHECK_EQ(Err, 0); + MmapedSize = Size; + proc_maps->data = Mem; +#endif - proc_maps->data = (char*)VmMap; proc_maps->mmaped_size = MmapedSize; proc_maps->len = Size; } bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { char *last = data_.proc_self_maps.data + data_.proc_self_maps.len; - if (data_.current >= last) return false; - struct kinfo_vmentry *VmEntry = (struct kinfo_vmentry *)data_.current; + if (data_.current >= last) + return false; + const struct kinfo_vmentry *VmEntry = + (const struct kinfo_vmentry *)data_.current; segment->start = (uptr)VmEntry->kve_start; segment->end = (uptr)VmEntry->kve_end; @@ -81,11 +115,13 @@ bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { if ((VmEntry->kve_protection & KVME_PROT_EXEC) != 0) segment->protection |= kProtectionExecute; +#if !SANITIZER_OPENBSD if (segment->filename != NULL && segment->filename_size > 0) { internal_snprintf(segment->filename, Min(segment->filename_size, (uptr)PATH_MAX), "%s", VmEntry->kve_path); } +#endif #if SANITIZER_FREEBSD data_.current += VmEntry->kve_structsize; @@ -96,6 +132,6 @@ bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { return true; } -} // namespace __sanitizer +} // namespace __sanitizer -#endif // SANITIZER_FREEBSD || SANITIZER_NETBSD +#endif diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_common.cc b/libsanitizer/sanitizer_common/sanitizer_procmaps_common.cc index 36b97b1166e..24cf9f8b00d 100644 --- a/libsanitizer/sanitizer_common/sanitizer_procmaps_common.cc +++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_common.cc @@ -10,7 +10,8 @@ #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_OPENBSD || SANITIZER_SOLARIS #include "sanitizer_common.h" #include "sanitizer_placement_new.h" @@ -68,53 +69,49 @@ void MemoryMappedSegment::AddAddressRanges(LoadedModule *module) { } MemoryMappingLayout::MemoryMappingLayout(bool cache_enabled) { - ReadProcMaps(&data_.proc_self_maps); - if (cache_enabled) { - if (data_.proc_self_maps.mmaped_size == 0) { - LoadFromCache(); - CHECK_GT(data_.proc_self_maps.len, 0); - } - } else { - CHECK_GT(data_.proc_self_maps.mmaped_size, 0); - } - Reset(); // FIXME: in the future we may want to cache the mappings on demand only. if (cache_enabled) CacheMemoryMappings(); + + // Read maps after the cache update to capture the maps/unmaps happening in + // the process of updating. + 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(); } MemoryMappingLayout::~MemoryMappingLayout() { // Only unmap the buffer if it is different from the cached one. Otherwise // it will be unmapped when the cache is refreshed. - if (data_.proc_self_maps.data != cached_proc_self_maps.data) { + if (data_.proc_self_maps.data != cached_proc_self_maps.data) UnmapOrDie(data_.proc_self_maps.data, data_.proc_self_maps.mmaped_size); - } } -void MemoryMappingLayout::Reset() { data_.current = data_.proc_self_maps.data; } +void MemoryMappingLayout::Reset() { + data_.current = data_.proc_self_maps.data; +} // static void MemoryMappingLayout::CacheMemoryMappings() { - SpinMutexLock l(&cache_lock); + ProcSelfMapsBuff new_proc_self_maps; + ReadProcMaps(&new_proc_self_maps); // Don't invalidate the cache if the mappings are unavailable. - ProcSelfMapsBuff old_proc_self_maps; - old_proc_self_maps = cached_proc_self_maps; - ReadProcMaps(&cached_proc_self_maps); - if (cached_proc_self_maps.mmaped_size == 0) { - cached_proc_self_maps = old_proc_self_maps; - } else { - if (old_proc_self_maps.mmaped_size) { - UnmapOrDie(old_proc_self_maps.data, - old_proc_self_maps.mmaped_size); - } - } + if (new_proc_self_maps.mmaped_size == 0) + return; + SpinMutexLock l(&cache_lock); + if (cached_proc_self_maps.mmaped_size) + UnmapOrDie(cached_proc_self_maps.data, cached_proc_self_maps.mmaped_size); + cached_proc_self_maps = new_proc_self_maps; } void MemoryMappingLayout::LoadFromCache() { SpinMutexLock l(&cache_lock); - if (cached_proc_self_maps.data) { + if (cached_proc_self_maps.data) data_.proc_self_maps = cached_proc_self_maps; - } } void MemoryMappingLayout::DumpListOfModules( @@ -171,4 +168,4 @@ void GetMemoryProfile(fill_profile_f cb, uptr *stats, uptr stats_size) { } // namespace __sanitizer -#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#endif diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_linux.cc b/libsanitizer/sanitizer_common/sanitizer_procmaps_linux.cc index b97d5f62dd2..f9092f4832e 100644 --- a/libsanitizer/sanitizer_common/sanitizer_procmaps_linux.cc +++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_linux.cc @@ -16,8 +16,12 @@ namespace __sanitizer { void ReadProcMaps(ProcSelfMapsBuff *proc_maps) { - ReadFileToBuffer("/proc/self/maps", &proc_maps->data, &proc_maps->mmaped_size, - &proc_maps->len); + if (!ReadFileToBuffer("/proc/self/maps", &proc_maps->data, + &proc_maps->mmaped_size, &proc_maps->len)) { + proc_maps->data = nullptr; + proc_maps->mmaped_size = 0; + proc_maps->len = 0; + } } static bool IsOneOf(char c, char c1, char c2) { diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cc b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cc index 34f0c207b09..b0e68fde762 100644 --- a/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cc +++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_mac.cc @@ -38,7 +38,7 @@ namespace __sanitizer { struct MemoryMappedSegmentData { char name[kMaxSegName]; uptr nsects; - char *current_load_cmd_addr; + const char *current_load_cmd_addr; u32 lc_type; uptr base_virt_addr; uptr addr_mask; @@ -138,12 +138,6 @@ void MemoryMappingLayout::LoadFromCache() { // early in the process, when dyld is one of the only images loaded, // so it will be hit after only a few iterations. static mach_header *get_dyld_image_header() { - mach_port_name_t port; - if (task_for_pid(mach_task_self(), internal_getpid(), &port) != - KERN_SUCCESS) { - return nullptr; - } - unsigned depth = 1; vm_size_t size = 0; vm_address_t address = 0; @@ -152,7 +146,7 @@ static mach_header *get_dyld_image_header() { while (true) { struct vm_region_submap_info_64 info; - err = vm_region_recurse_64(port, &address, &size, &depth, + err = vm_region_recurse_64(mach_task_self(), &address, &size, &depth, (vm_region_info_t)&info, &count); if (err != KERN_SUCCESS) return nullptr; @@ -210,7 +204,7 @@ MemoryMappedSegmentData *seg_data, MemoryMappingLayoutData &layout_data) { if (seg_data) { seg_data->nsects = sc->nsects; seg_data->current_load_cmd_addr = - (char *)lc + sizeof(SegmentCommand); + (const char *)lc + sizeof(SegmentCommand); seg_data->lc_type = kLCSegment; seg_data->base_virt_addr = base_virt_addr; seg_data->addr_mask = addr_mask; @@ -263,7 +257,7 @@ ModuleArch ModuleArchFromCpuType(cpu_type_t cputype, cpu_subtype_t cpusubtype) { } static const load_command *NextCommand(const load_command *lc) { - return (const load_command *)((char *)lc + lc->cmdsize); + return (const load_command *)((const char *)lc + lc->cmdsize); } static void FindUUID(const load_command *first_lc, u8 *uuid_output) { @@ -307,12 +301,13 @@ bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { switch (data_.current_magic) { #ifdef MH_MAGIC_64 case MH_MAGIC_64: { - data_.current_load_cmd_addr = (char *)hdr + sizeof(mach_header_64); + data_.current_load_cmd_addr = + (const char *)hdr + sizeof(mach_header_64); break; } #endif case MH_MAGIC: { - data_.current_load_cmd_addr = (char *)hdr + sizeof(mach_header); + data_.current_load_cmd_addr = (const char *)hdr + sizeof(mach_header); break; } default: { diff --git a/libsanitizer/sanitizer_common/sanitizer_procmaps_solaris.cc b/libsanitizer/sanitizer_common/sanitizer_procmaps_solaris.cc new file mode 100644 index 00000000000..bfe83170f4e --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_procmaps_solaris.cc @@ -0,0 +1,57 @@ +//===-- sanitizer_procmaps_solaris.cc -------------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Information about the process mappings (Solaris-specific parts). +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" +#if SANITIZER_SOLARIS +#include "sanitizer_common.h" +#include "sanitizer_procmaps.h" + +#include +#include + +namespace __sanitizer { + +void ReadProcMaps(ProcSelfMapsBuff *proc_maps) { + ReadFileToBuffer("/proc/self/xmap", &proc_maps->data, &proc_maps->mmaped_size, + &proc_maps->len); +} + +bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { + char *last = data_.proc_self_maps.data + data_.proc_self_maps.len; + if (data_.current >= last) return false; + + prxmap_t *xmapentry = (prxmap_t*)data_.current; + + segment->start = (uptr)xmapentry->pr_vaddr; + segment->end = (uptr)(xmapentry->pr_vaddr + xmapentry->pr_size); + segment->offset = (uptr)xmapentry->pr_offset; + + segment->protection = 0; + if ((xmapentry->pr_mflags & MA_READ) != 0) + segment->protection |= kProtectionRead; + if ((xmapentry->pr_mflags & MA_WRITE) != 0) + segment->protection |= kProtectionWrite; + if ((xmapentry->pr_mflags & MA_EXEC) != 0) + segment->protection |= kProtectionExecute; + + if (segment->filename != NULL && segment->filename_size > 0) { + internal_snprintf(segment->filename, + Min(segment->filename_size, (uptr)PATH_MAX), "%s", + xmapentry->pr_mapname); + } + + data_.current += sizeof(prxmap_t); + + return true; +} + +} // namespace __sanitizer + +#endif // SANITIZER_SOLARIS diff --git a/libsanitizer/sanitizer_common/sanitizer_quarantine.h b/libsanitizer/sanitizer_common/sanitizer_quarantine.h index a90c8e3bdb8..0ebe97d1e40 100644 --- a/libsanitizer/sanitizer_common/sanitizer_quarantine.h +++ b/libsanitizer/sanitizer_common/sanitizer_quarantine.h @@ -85,15 +85,17 @@ class Quarantine { // is zero (it allows us to perform just one atomic read per Put() call). CHECK((size == 0 && cache_size == 0) || cache_size != 0); - atomic_store(&max_size_, size, memory_order_relaxed); - atomic_store(&min_size_, size / 10 * 9, - memory_order_relaxed); // 90% of max size. - atomic_store(&max_cache_size_, cache_size, memory_order_relaxed); + atomic_store_relaxed(&max_size_, size); + atomic_store_relaxed(&min_size_, size / 10 * 9); // 90% of max size. + atomic_store_relaxed(&max_cache_size_, cache_size); + + cache_mutex_.Init(); + recycle_mutex_.Init(); } - uptr GetSize() const { return atomic_load(&max_size_, memory_order_relaxed); } + uptr GetSize() const { return atomic_load_relaxed(&max_size_); } uptr GetCacheSize() const { - return atomic_load(&max_cache_size_, memory_order_relaxed); + return atomic_load_relaxed(&max_cache_size_); } void Put(Cache *c, Callback cb, Node *ptr, uptr size) { @@ -115,7 +117,16 @@ class Quarantine { cache_.Transfer(c); } if (cache_.Size() > GetSize() && recycle_mutex_.TryLock()) - Recycle(cb); + Recycle(atomic_load_relaxed(&min_size_), cb); + } + + void NOINLINE DrainAndRecycle(Cache *c, Callback cb) { + { + SpinMutexLock l(&cache_mutex_); + cache_.Transfer(c); + } + recycle_mutex_.Lock(); + Recycle(0, cb); } void PrintStats() const { @@ -132,14 +143,13 @@ class Quarantine { atomic_uintptr_t min_size_; atomic_uintptr_t max_cache_size_; char pad1_[kCacheLineSize]; - SpinMutex cache_mutex_; - SpinMutex recycle_mutex_; + StaticSpinMutex cache_mutex_; + StaticSpinMutex recycle_mutex_; Cache cache_; char pad2_[kCacheLineSize]; - void NOINLINE Recycle(Callback cb) { + void NOINLINE Recycle(uptr min_size, Callback cb) { Cache tmp; - uptr min_size = atomic_load(&min_size_, memory_order_relaxed); { SpinMutexLock l(&cache_mutex_); // Go over the batches and merge partially filled ones to @@ -199,7 +209,7 @@ class QuarantineCache { // Total memory used, including internal accounting. uptr Size() const { - return atomic_load(&size_, memory_order_relaxed); + return atomic_load_relaxed(&size_); } // Memory used for internal accounting. @@ -223,7 +233,7 @@ class QuarantineCache { list_.append_back(&from_cache->list_); SizeAdd(from_cache->Size()); - atomic_store(&from_cache->size_, 0, memory_order_relaxed); + atomic_store_relaxed(&from_cache->size_, 0); } void EnqueueBatch(QuarantineBatch *b) { @@ -294,10 +304,10 @@ class QuarantineCache { atomic_uintptr_t size_; void SizeAdd(uptr add) { - atomic_store(&size_, Size() + add, memory_order_relaxed); + atomic_store_relaxed(&size_, Size() + add); } void SizeSub(uptr sub) { - atomic_store(&size_, Size() - sub, memory_order_relaxed); + atomic_store_relaxed(&size_, Size() - sub); } }; diff --git a/libsanitizer/sanitizer_common/sanitizer_report_decorator.h b/libsanitizer/sanitizer_common/sanitizer_report_decorator.h index c0edfcf7437..b46a02844df 100644 --- a/libsanitizer/sanitizer_common/sanitizer_report_decorator.h +++ b/libsanitizer/sanitizer_common/sanitizer_report_decorator.h @@ -23,10 +23,11 @@ class SanitizerCommonDecorator { // stdout, which is not the case on Windows (see SetConsoleTextAttribute()). public: SanitizerCommonDecorator() : ansi_(ColorizeReports()) {} - const char *Bold() const { return ansi_ ? "\033[1m" : ""; } + const char *Bold() const { return ansi_ ? "\033[1m" : ""; } const char *Default() const { return ansi_ ? "\033[1m\033[0m" : ""; } const char *Warning() const { return Red(); } - const char *MemoryByte() { return Magenta(); } + const char *Error() const { return Red(); } + const char *MemoryByte() const { return Magenta(); } protected: const char *Black() const { return ansi_ ? "\033[1m\033[30m" : ""; } diff --git a/libsanitizer/sanitizer_common/sanitizer_ring_buffer.h b/libsanitizer/sanitizer_common/sanitizer_ring_buffer.h new file mode 100644 index 00000000000..39ee6315a70 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_ring_buffer.h @@ -0,0 +1,160 @@ +//===-- sanitizer_ring_buffer.h ---------------------------------*- C++ -*-===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Simple ring buffer. +// +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_RING_BUFFER_H +#define SANITIZER_RING_BUFFER_H + +#include "sanitizer_common.h" + +namespace __sanitizer { +// RingBuffer: fixed-size ring buffer optimized for speed of push(). +// T should be a POD type and sizeof(T) should be divisible by sizeof(void*). +// At creation, all elements are zero. +template +class RingBuffer { + public: + COMPILER_CHECK(sizeof(T) % sizeof(void *) == 0); + static RingBuffer *New(uptr Size) { + void *Ptr = MmapOrDie(SizeInBytes(Size), "RingBuffer"); + RingBuffer *RB = reinterpret_cast(Ptr); + uptr End = reinterpret_cast(Ptr) + SizeInBytes(Size); + RB->last_ = RB->next_ = reinterpret_cast(End - sizeof(T)); + return RB; + } + void Delete() { + UnmapOrDie(this, SizeInBytes(size())); + } + uptr size() const { + return last_ + 1 - + reinterpret_cast(reinterpret_cast(this) + + 2 * sizeof(T *)); + } + + static uptr SizeInBytes(uptr Size) { + return Size * sizeof(T) + 2 * sizeof(T*); + } + + uptr SizeInBytes() { return SizeInBytes(size()); } + + void push(T t) { + *next_ = t; + next_--; + // The condition below works only if sizeof(T) is divisible by sizeof(T*). + if (next_ <= reinterpret_cast(&next_)) + next_ = last_; + } + + T operator[](uptr Idx) const { + CHECK_LT(Idx, size()); + sptr IdxNext = Idx + 1; + if (IdxNext > last_ - next_) + IdxNext -= size(); + return next_[IdxNext]; + } + + private: + RingBuffer() {} + ~RingBuffer() {} + RingBuffer(const RingBuffer&) = delete; + + // Data layout: + // LNDDDDDDDD + // D: data elements. + // L: last_, always points to the last data element. + // N: next_, initially equals to last_, is decremented on every push, + // wraps around if it's less or equal than its own address. + T *last_; + T *next_; + T data_[1]; // flexible array. +}; + +// A ring buffer with externally provided storage that encodes its state in 8 +// bytes. Has significant constraints on size and alignment of storage. +// See a comment in hwasan/hwasan_thread_list.h for the motivation behind this. +#if SANITIZER_WORDSIZE == 64 +template +class CompactRingBuffer { + // Top byte of long_ stores the buffer size in pages. + // Lower bytes store the address of the next buffer element. + static constexpr int kPageSizeBits = 12; + static constexpr int kSizeShift = 56; + static constexpr uptr kNextMask = (1ULL << kSizeShift) - 1; + + uptr GetStorageSize() const { return (long_ >> kSizeShift) << kPageSizeBits; } + + void Init(void *storage, uptr size) { + CHECK_EQ(sizeof(CompactRingBuffer), sizeof(void *)); + CHECK(IsPowerOfTwo(size)); + CHECK_GE(size, 1 << kPageSizeBits); + CHECK_LE(size, 128 << kPageSizeBits); + CHECK_EQ(size % 4096, 0); + CHECK_EQ(size % sizeof(T), 0); + CHECK_EQ((uptr)storage % (size * 2), 0); + long_ = (uptr)storage | ((size >> kPageSizeBits) << kSizeShift); + } + + void SetNext(const T *next) { + long_ = (long_ & ~kNextMask) | (uptr)next; + } + + public: + CompactRingBuffer(void *storage, uptr size) { + Init(storage, size); + } + + // A copy constructor of sorts. + CompactRingBuffer(const CompactRingBuffer &other, void *storage) { + uptr size = other.GetStorageSize(); + internal_memcpy(storage, other.StartOfStorage(), size); + Init(storage, size); + uptr Idx = other.Next() - (const T *)other.StartOfStorage(); + SetNext((const T *)storage + Idx); + } + + T *Next() const { return (T *)(long_ & kNextMask); } + + void *StartOfStorage() const { + return (void *)((uptr)Next() & ~(GetStorageSize() - 1)); + } + + void *EndOfStorage() const { + return (void *)((uptr)StartOfStorage() + GetStorageSize()); + } + + uptr size() const { return GetStorageSize() / sizeof(T); } + + void push(T t) { + T *next = Next(); + *next = t; + next++; + next = (T *)((uptr)next & ~GetStorageSize()); + SetNext(next); + } + + T operator[](uptr Idx) const { + CHECK_LT(Idx, size()); + const T *Begin = (const T *)StartOfStorage(); + sptr StorageIdx = Next() - Begin; + StorageIdx -= (sptr)(Idx + 1); + if (StorageIdx < 0) + StorageIdx += size(); + return Begin[StorageIdx]; + } + + public: + ~CompactRingBuffer() {} + CompactRingBuffer(const CompactRingBuffer &) = delete; + + uptr long_; +}; +#endif +} // namespace __sanitizer + +#endif // SANITIZER_RING_BUFFER_H diff --git a/libsanitizer/sanitizer_common/sanitizer_rtems.cc b/libsanitizer/sanitizer_common/sanitizer_rtems.cc new file mode 100644 index 00000000000..2792c59da60 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_rtems.cc @@ -0,0 +1,280 @@ +//===-- sanitizer_rtems.cc ------------------------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is shared between various sanitizers' runtime libraries and +// implements RTEMS-specific functions. +//===----------------------------------------------------------------------===// + +#include "sanitizer_rtems.h" +#if SANITIZER_RTEMS + +#define posix_memalign __real_posix_memalign +#define free __real_free +#define memset __real_memset + +#include "sanitizer_file.h" +#include "sanitizer_symbolizer.h" +#include +#include +#include +#include +#include +#include +#include +#include + +// There is no mmap on RTEMS. Use memalign, etc. +#define __mmap_alloc_aligned posix_memalign +#define __mmap_free free +#define __mmap_memset memset + +namespace __sanitizer { + +#include "sanitizer_syscall_generic.inc" + +void NORETURN internal__exit(int exitcode) { + _exit(exitcode); +} + +uptr internal_sched_yield() { + return sched_yield(); +} + +uptr internal_getpid() { + return getpid(); +} + +bool FileExists(const char *filename) { + struct stat st; + if (stat(filename, &st)) + return false; + // Sanity check: filename is a regular file. + return S_ISREG(st.st_mode); +} + +uptr GetThreadSelf() { return static_cast(pthread_self()); } + +tid_t GetTid() { return GetThreadSelf(); } + +void Abort() { abort(); } + +int Atexit(void (*function)(void)) { return atexit(function); } + +void SleepForSeconds(int seconds) { sleep(seconds); } + +void SleepForMillis(int millis) { usleep(millis * 1000); } + +bool SupportsColoredOutput(fd_t fd) { return false; } + +void GetThreadStackTopAndBottom(bool at_initialization, + uptr *stack_top, uptr *stack_bottom) { + pthread_attr_t attr; + pthread_attr_init(&attr); + CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0); + void *base = nullptr; + size_t size = 0; + CHECK_EQ(pthread_attr_getstack(&attr, &base, &size), 0); + CHECK_EQ(pthread_attr_destroy(&attr), 0); + + *stack_bottom = reinterpret_cast(base); + *stack_top = *stack_bottom + size; +} + +void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, + uptr *tls_addr, uptr *tls_size) { + uptr stack_top, stack_bottom; + GetThreadStackTopAndBottom(main, &stack_top, &stack_bottom); + *stk_addr = stack_bottom; + *stk_size = stack_top - stack_bottom; + *tls_addr = *tls_size = 0; +} + +void MaybeReexec() {} +void CheckASLR() {} +void DisableCoreDumperIfNecessary() {} +void InstallDeadlySignalHandlers(SignalHandlerType handler) {} +void SetAlternateSignalStack() {} +void UnsetAlternateSignalStack() {} +void InitTlsSize() {} + +void PrintModuleMap() {} + +void SignalContext::DumpAllRegisters(void *context) {} +const char *DescribeSignalOrException(int signo) { UNIMPLEMENTED(); } + +enum MutexState { MtxUnlocked = 0, MtxLocked = 1, MtxSleeping = 2 }; + +BlockingMutex::BlockingMutex() { + internal_memset(this, 0, sizeof(*this)); +} + +void BlockingMutex::Lock() { + CHECK_EQ(owner_, 0); + atomic_uint32_t *m = reinterpret_cast(&opaque_storage_); + if (atomic_exchange(m, MtxLocked, memory_order_acquire) == MtxUnlocked) + return; + while (atomic_exchange(m, MtxSleeping, memory_order_acquire) != MtxUnlocked) { + internal_sched_yield(); + } +} + +void BlockingMutex::Unlock() { + atomic_uint32_t *m = reinterpret_cast(&opaque_storage_); + u32 v = atomic_exchange(m, MtxUnlocked, memory_order_release); + CHECK_NE(v, MtxUnlocked); +} + +void BlockingMutex::CheckLocked() { + atomic_uint32_t *m = reinterpret_cast(&opaque_storage_); + CHECK_NE(MtxUnlocked, atomic_load(m, memory_order_relaxed)); +} + +uptr GetPageSize() { return getpagesize(); } + +uptr GetMmapGranularity() { return GetPageSize(); } + +uptr GetMaxVirtualAddress() { + return (1ULL << 32) - 1; // 0xffffffff +} + +void *MmapOrDie(uptr size, const char *mem_type, bool raw_report) { + void* ptr = 0; + int res = __mmap_alloc_aligned(&ptr, GetPageSize(), size); + if (UNLIKELY(res)) + ReportMmapFailureAndDie(size, mem_type, "allocate", res, raw_report); + __mmap_memset(ptr, 0, size); + IncreaseTotalMmap(size); + return ptr; +} + +void *MmapOrDieOnFatalError(uptr size, const char *mem_type) { + void* ptr = 0; + int res = __mmap_alloc_aligned(&ptr, GetPageSize(), size); + if (UNLIKELY(res)) { + if (res == ENOMEM) + return nullptr; + ReportMmapFailureAndDie(size, mem_type, "allocate", false); + } + __mmap_memset(ptr, 0, size); + IncreaseTotalMmap(size); + return ptr; +} + +void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment, + const char *mem_type) { + CHECK(IsPowerOfTwo(size)); + CHECK(IsPowerOfTwo(alignment)); + void* ptr = 0; + int res = __mmap_alloc_aligned(&ptr, alignment, size); + if (res) + ReportMmapFailureAndDie(size, mem_type, "align allocate", res, false); + __mmap_memset(ptr, 0, size); + IncreaseTotalMmap(size); + return ptr; +} + +void *MmapNoReserveOrDie(uptr size, const char *mem_type) { + return MmapOrDie(size, mem_type, false); +} + +void UnmapOrDie(void *addr, uptr size) { + if (!addr || !size) return; + __mmap_free(addr); + DecreaseTotalMmap(size); +} + +fd_t OpenFile(const char *filename, FileAccessMode mode, error_t *errno_p) { + int flags; + switch (mode) { + case RdOnly: flags = O_RDONLY; break; + case WrOnly: flags = O_WRONLY | O_CREAT | O_TRUNC; break; + case RdWr: flags = O_RDWR | O_CREAT; break; + } + fd_t res = open(filename, flags, 0660); + if (internal_iserror(res, errno_p)) + return kInvalidFd; + return res; +} + +void CloseFile(fd_t fd) { + close(fd); +} + +bool ReadFromFile(fd_t fd, void *buff, uptr buff_size, uptr *bytes_read, + error_t *error_p) { + uptr res = read(fd, buff, buff_size); + if (internal_iserror(res, error_p)) + return false; + if (bytes_read) + *bytes_read = res; + return true; +} + +bool WriteToFile(fd_t fd, const void *buff, uptr buff_size, uptr *bytes_written, + error_t *error_p) { + uptr res = write(fd, buff, buff_size); + if (internal_iserror(res, error_p)) + return false; + if (bytes_written) + *bytes_written = res; + 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() {} + +// There is no page protection so everything is "accessible." +bool IsAccessibleMemoryRange(uptr beg, uptr size) { + return true; +} + +char **GetArgv() { return nullptr; } + +const char *GetEnv(const char *name) { + return getenv(name); +} + +uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { + internal_strncpy(buf, "StubBinaryName", buf_len); + return internal_strlen(buf); +} + +uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) { + internal_strncpy(buf, "StubProcessName", buf_len); + return internal_strlen(buf); +} + +bool IsPathSeparator(const char c) { + return c == '/'; +} + +bool IsAbsolutePath(const char *path) { + return path != nullptr && IsPathSeparator(path[0]); +} + +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 != write(fd, buffer, length)) { + write(fd, kWriteError, internal_strlen(kWriteError)); + Die(); + } +} + +uptr MainThreadStackBase, MainThreadStackSize; +uptr MainThreadTlsBase, MainThreadTlsSize; + +} // namespace __sanitizer + +#endif // SANITIZER_RTEMS diff --git a/libsanitizer/sanitizer_common/sanitizer_rtems.h b/libsanitizer/sanitizer_common/sanitizer_rtems.h new file mode 100644 index 00000000000..dc64bbc00df --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_rtems.h @@ -0,0 +1,19 @@ +//===-- sanitizer_rtems.h ---------------------------------------*- C++ -*-===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is shared between various sanitizers' runtime libraries and +// provides definitions for RTEMS-specific functions. +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_RTEMS_H +#define SANITIZER_RTEMS_H + +#include "sanitizer_platform.h" +#if SANITIZER_RTEMS +#include "sanitizer_common.h" + +#endif // SANITIZER_RTEMS +#endif // SANITIZER_RTEMS_H diff --git a/libsanitizer/sanitizer_common/sanitizer_signal_interceptors.inc b/libsanitizer/sanitizer_common/sanitizer_signal_interceptors.inc index b278f82ce03..7ec63396d79 100644 --- a/libsanitizer/sanitizer_common/sanitizer_signal_interceptors.inc +++ b/libsanitizer/sanitizer_common/sanitizer_signal_interceptors.inc @@ -16,10 +16,26 @@ using namespace __sanitizer; +#if SANITIZER_NETBSD +#define sigaction_symname __sigaction14 +#else +#define sigaction_symname sigaction +#endif + +#ifndef SIGNAL_INTERCEPTOR_SIGNAL_IMPL +#define SIGNAL_INTERCEPTOR_SIGNAL_IMPL(func, signum, handler) \ + { return REAL(func)(signum, handler); } +#endif + +#ifndef SIGNAL_INTERCEPTOR_SIGACTION_IMPL +#define SIGNAL_INTERCEPTOR_SIGACTION_IMPL(signum, act, oldact) \ + { return REAL(sigaction_symname)(signum, act, oldact); } +#endif + #if SANITIZER_INTERCEPT_BSD_SIGNAL -INTERCEPTOR(void *, bsd_signal, int signum, void *handler) { +INTERCEPTOR(uptr, bsd_signal, int signum, uptr handler) { if (GetHandleSignalMode(signum) == kHandleSignalExclusive) return 0; - return REAL(bsd_signal)(signum, handler); + SIGNAL_INTERCEPTOR_SIGNAL_IMPL(bsd_signal, signum, handler); } #define INIT_BSD_SIGNAL COMMON_INTERCEPT_FUNCTION(bsd_signal) #else // SANITIZER_INTERCEPT_BSD_SIGNAL @@ -27,31 +43,35 @@ INTERCEPTOR(void *, bsd_signal, int signum, void *handler) { #endif // SANITIZER_INTERCEPT_BSD_SIGNAL #if SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION -INTERCEPTOR(void *, signal, int signum, void *handler) { - if (GetHandleSignalMode(signum) == kHandleSignalExclusive) return nullptr; - return REAL(signal)(signum, handler); +INTERCEPTOR(uptr, signal, int signum, uptr handler) { + if (GetHandleSignalMode(signum) == kHandleSignalExclusive) + return (uptr) nullptr; + SIGNAL_INTERCEPTOR_SIGNAL_IMPL(signal, signum, handler); } #define INIT_SIGNAL COMMON_INTERCEPT_FUNCTION(signal) -INTERCEPTOR(int, sigaction, int signum, const struct sigaction *act, - struct sigaction *oldact) { +INTERCEPTOR(int, sigaction_symname, int signum, + const __sanitizer_sigaction *act, __sanitizer_sigaction *oldact) { if (GetHandleSignalMode(signum) == kHandleSignalExclusive) return 0; - return REAL(sigaction)(signum, act, oldact); + SIGNAL_INTERCEPTOR_SIGACTION_IMPL(signum, act, oldact); } -#define INIT_SIGACTION COMMON_INTERCEPT_FUNCTION(sigaction) +#define INIT_SIGACTION COMMON_INTERCEPT_FUNCTION(sigaction_symname) namespace __sanitizer { int real_sigaction(int signum, const void *act, void *oldact) { - return REAL(sigaction)(signum, (const struct sigaction *)act, - (struct sigaction *)oldact); + return REAL(sigaction_symname)(signum, (const __sanitizer_sigaction *)act, + (__sanitizer_sigaction *)oldact); } } // namespace __sanitizer #else // SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION #define INIT_SIGNAL #define INIT_SIGACTION // We need to have defined REAL(sigaction) on other systems. -DEFINE_REAL(int, sigaction, int signum, const struct sigaction *act, - struct sigaction *oldact) +namespace __sanitizer { +struct __sanitizer_sigaction; +} +DEFINE_REAL(int, sigaction, int signum, const __sanitizer_sigaction *act, + __sanitizer_sigaction *oldact) #endif // SANITIZER_INTERCEPT_SIGNAL_AND_SIGACTION static void InitializeSignalInterceptors() { diff --git a/libsanitizer/sanitizer_common/sanitizer_solaris.cc b/libsanitizer/sanitizer_common/sanitizer_solaris.cc new file mode 100644 index 00000000000..a5db22994e0 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_solaris.cc @@ -0,0 +1,219 @@ +//===-- sanitizer_solaris.cc ----------------------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is shared between various sanitizers' runtime libraries and +// implements Solaris-specific functions. +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" +#if SANITIZER_SOLARIS + +#include + +#include "sanitizer_common.h" +#include "sanitizer_flags.h" +#include "sanitizer_internal_defs.h" +#include "sanitizer_libc.h" +#include "sanitizer_placement_new.h" +#include "sanitizer_platform_limits_posix.h" +#include "sanitizer_procmaps.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace __sanitizer { + +//#include "sanitizer_syscall_generic.inc" + +#define _REAL(func) _ ## func +#define DECLARE__REAL(ret_type, func, ...) \ + extern "C" ret_type _REAL(func)(__VA_ARGS__) +#define DECLARE__REAL_AND_INTERNAL(ret_type, func, ...) \ + DECLARE__REAL(ret_type, func, __VA_ARGS__); \ + ret_type internal_ ## func(__VA_ARGS__) + +// ---------------------- sanitizer_libc.h +DECLARE__REAL_AND_INTERNAL(uptr, mmap, void *addr, uptr /*size_t*/ length, + int prot, int flags, int fd, OFF_T offset) { + return (uptr)_REAL(mmap)(addr, length, prot, flags, fd, offset); +} + +DECLARE__REAL_AND_INTERNAL(uptr, munmap, void *addr, uptr length) { + return _REAL(munmap)(addr, length); +} + +DECLARE__REAL_AND_INTERNAL(int, mprotect, void *addr, uptr length, int prot) { + return _REAL(mprotect)(addr, length, prot); +} + +DECLARE__REAL_AND_INTERNAL(uptr, close, fd_t fd) { + return _REAL(close)(fd); +} + +extern "C" int _REAL(open)(const char *, int, ...); + +uptr internal_open(const char *filename, int flags) { + return _REAL(open)(filename, flags); +} + +uptr internal_open(const char *filename, int flags, u32 mode) { + return _REAL(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); +} + +DECLARE__REAL_AND_INTERNAL(uptr, write, fd_t fd, const void *buf, uptr count) { + return _REAL(write)(fd, buf, count); +} + +// FIXME: There's only _ftruncate64 beginning with Solaris 11. +DECLARE__REAL_AND_INTERNAL(uptr, ftruncate, fd_t fd, uptr size) { + return ftruncate(fd, size); +} + +DECLARE__REAL_AND_INTERNAL(uptr, stat, const char *path, void *buf) { + return _REAL(stat)(path, (struct stat *)buf); +} + +DECLARE__REAL_AND_INTERNAL(uptr, lstat, const char *path, void *buf) { + return _REAL(lstat)(path, (struct stat *)buf); +} + +DECLARE__REAL_AND_INTERNAL(uptr, fstat, fd_t fd, void *buf) { + return _REAL(fstat)(fd, (struct stat *)buf); +} + +uptr internal_filesize(fd_t fd) { + struct stat st; + if (internal_fstat(fd, &st)) + return -1; + return (uptr)st.st_size; +} + +DECLARE__REAL_AND_INTERNAL(uptr, dup2, int oldfd, int newfd) { + return _REAL(dup2)(oldfd, newfd); +} + +DECLARE__REAL_AND_INTERNAL(uptr, readlink, const char *path, char *buf, + uptr bufsize) { + return _REAL(readlink)(path, buf, bufsize); +} + +DECLARE__REAL_AND_INTERNAL(uptr, unlink, const char *path) { + return _REAL(unlink)(path); +} + +DECLARE__REAL_AND_INTERNAL(uptr, rename, const char *oldpath, + const char *newpath) { + return _REAL(rename)(oldpath, newpath); +} + +DECLARE__REAL_AND_INTERNAL(uptr, sched_yield, void) { + return sched_yield(); +} + +DECLARE__REAL_AND_INTERNAL(void, _exit, int exitcode) { + _exit(exitcode); +} + +DECLARE__REAL_AND_INTERNAL(uptr, execve, const char *filename, + char *const argv[], char *const envp[]) { + return _REAL(execve)(filename, argv, envp); +} + +DECLARE__REAL_AND_INTERNAL(uptr, waitpid, int pid, int *status, int options) { + return _REAL(waitpid)(pid, status, options); +} + +DECLARE__REAL_AND_INTERNAL(uptr, getpid, void) { + return _REAL(getpid)(); +} + +// FIXME: This might be wrong: _getdents doesn't take a struct linux_dirent *. +DECLARE__REAL_AND_INTERNAL(uptr, getdents, fd_t fd, struct linux_dirent *dirp, + unsigned int count) { + return _REAL(getdents)(fd, dirp, count); +} + +DECLARE__REAL_AND_INTERNAL(uptr, lseek, fd_t fd, OFF_T offset, int whence) { + return _REAL(lseek)(fd, offset, whence); +} + +// FIXME: This might be wrong: _sigfillset doesn't take a +// __sanitizer_sigset_t *. +DECLARE__REAL_AND_INTERNAL(void, sigfillset, __sanitizer_sigset_t *set) { + _REAL(sigfillset)(set); +} + +// FIXME: This might be wrong: _sigprocmask doesn't take __sanitizer_sigset_t *. +DECLARE__REAL_AND_INTERNAL(uptr, sigprocmask, int how, + __sanitizer_sigset_t *set, + __sanitizer_sigset_t *oldset) { + return _REAL(sigprocmask)(how, set, oldset); +} + +DECLARE__REAL_AND_INTERNAL(int, fork, void) { + // TODO(glider): this may call user's pthread_atfork() handlers which is bad. + return _REAL(fork)(); +} + +u64 NanoTime() { + return gethrtime(); +} + +uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) { + // FIXME: No internal variant. + return clock_gettime(clk_id, (timespec *)tp); +} + +// ----------------- sanitizer_common.h +BlockingMutex::BlockingMutex() { + CHECK(sizeof(mutex_t) <= sizeof(opaque_storage_)); + internal_memset(this, 0, sizeof(*this)); + CHECK_EQ(mutex_init((mutex_t *)&opaque_storage_, USYNC_THREAD, NULL), 0); +} + +void BlockingMutex::Lock() { + CHECK(sizeof(mutex_t) <= sizeof(opaque_storage_)); + CHECK_NE(owner_, (uptr)thr_self()); + CHECK_EQ(mutex_lock((mutex_t *)&opaque_storage_), 0); + CHECK(!owner_); + owner_ = (uptr)thr_self(); +} + +void BlockingMutex::Unlock() { + CHECK(owner_ == (uptr)thr_self()); + owner_ = 0; + CHECK_EQ(mutex_unlock((mutex_t *)&opaque_storage_), 0); +} + +void BlockingMutex::CheckLocked() { + CHECK_EQ((uptr)thr_self(), owner_); +} + +} // namespace __sanitizer + +#endif // SANITIZER_SOLARIS diff --git a/libsanitizer/sanitizer_common/sanitizer_stackdepot.cc b/libsanitizer/sanitizer_common/sanitizer_stackdepot.cc index 816a35cfb46..d48f7d27689 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stackdepot.cc +++ b/libsanitizer/sanitizer_common/sanitizer_stackdepot.cc @@ -133,8 +133,8 @@ bool StackDepotReverseMap::IdDescPair::IdComparator( return a.id < b.id; } -StackDepotReverseMap::StackDepotReverseMap() - : map_(StackDepotGetStats()->n_uniq_ids + 100) { +StackDepotReverseMap::StackDepotReverseMap() { + map_.reserve(StackDepotGetStats()->n_uniq_ids + 100); for (int idx = 0; idx < StackDepot::kTabSize; idx++) { atomic_uintptr_t *p = &theDepot.tab[idx]; uptr v = atomic_load(p, memory_order_consume); @@ -144,7 +144,7 @@ StackDepotReverseMap::StackDepotReverseMap() map_.push_back(pair); } } - InternalSort(&map_, map_.size(), IdDescPair::IdComparator); + Sort(map_.data(), map_.size(), &IdDescPair::IdComparator); } StackTrace StackDepotReverseMap::Get(u32 id) { diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc index 2de585c3298..db51f5926d2 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.cc @@ -18,7 +18,8 @@ namespace __sanitizer { uptr StackTrace::GetNextInstructionPc(uptr pc) { #if defined(__mips__) return pc + 8; -#elif defined(__powerpc__) +#elif defined(__powerpc__) || defined(__sparc__) || defined(__arm__) || \ + defined(__aarch64__) return pc + 4; #else return pc + 1; @@ -38,6 +39,9 @@ void BufferedStackTrace::Init(const uptr *pcs, uptr cnt, uptr extra_top_pc) { top_frame_bp = 0; } +// Sparc implemention is in its own file. +#if !defined(__sparc__) + // In GCC on ARM bp points to saved lr, not fp, so we should check the next // cell in stack to be a saved frame pointer. GetCanonicFrame returns the // pointer to saved frame pointer in any case. @@ -55,8 +59,8 @@ 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 @@ -78,21 +82,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 @@ -111,6 +108,8 @@ void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top, } } +#endif // !defined(__sparc__) + void BufferedStackTrace::PopStackFrames(uptr count) { CHECK_LT(count, size); size -= count; diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace.h b/libsanitizer/sanitizer_common/sanitizer_stacktrace.h index 31e99f6b9db..fa457d5bfb4 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace.h +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace.h @@ -21,6 +21,8 @@ static const u32 kStackTraceMax = 256; # define SANITIZER_CAN_FAST_UNWIND 0 #elif SANITIZER_WINDOWS # define SANITIZER_CAN_FAST_UNWIND 0 +#elif SANITIZER_OPENBSD +# define SANITIZER_CAN_FAST_UNWIND 0 #else # define SANITIZER_CAN_FAST_UNWIND 1 #endif @@ -28,7 +30,7 @@ static const u32 kStackTraceMax = 256; // Fast unwind is the only option on Mac for now; we will need to // revisit this macro when slow unwind works on Mac, see // https://github.com/google/sanitizers/issues/137 -#if SANITIZER_MAC +#if SANITIZER_MAC || SANITIZER_OPENBSD || SANITIZER_RTEMS # define SANITIZER_CAN_SLOW_UNWIND 0 #else # define SANITIZER_CAN_SLOW_UNWIND 1 @@ -71,10 +73,11 @@ struct StackTrace { ALWAYS_INLINE uptr StackTrace::GetPreviousInstructionPc(uptr pc) { #if defined(__arm__) - // Cancel Thumb bit. - pc = pc & (~1); -#endif -#if defined(__powerpc__) || defined(__powerpc64__) + // T32 (Thumb) branch instructions might be 16 or 32 bit long, + // so we return (pc-2) in that case in order to be safe. + // For A32 mode we return (pc-4) because all instructions are 32 bit long. + return (pc - 3) & (~1); +#elif defined(__powerpc__) || defined(__powerpc64__) || defined(__aarch64__) // PCs are always 4 byte aligned. return pc - 4; #elif defined(__sparc__) || defined(__mips__) diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cc index f4c0f31b2af..ff085519e52 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace_libcdep.cc @@ -112,11 +112,25 @@ void __sanitizer_symbolize_pc(uptr pc, const char *fmt, char *out_buf, return; } InternalScopedString frame_desc(GetPageSizeCached()); - RenderFrame(&frame_desc, fmt, 0, frame->info, - common_flags()->symbolize_vs_style, - common_flags()->strip_path_prefix); - internal_strncpy(out_buf, frame_desc.data(), out_buf_size); - out_buf[out_buf_size - 1] = 0; + uptr frame_num = 0; + // Reserve one byte for the final 0. + char *out_end = out_buf + out_buf_size - 1; + for (SymbolizedStack *cur = frame; cur && out_buf < out_end; + cur = cur->next) { + frame_desc.clear(); + RenderFrame(&frame_desc, fmt, frame_num++, cur->info, + common_flags()->symbolize_vs_style, + common_flags()->strip_path_prefix); + if (!frame_desc.length()) + continue; + // Reserve one byte for the terminating 0. + uptr n = out_end - out_buf - 1; + internal_strncpy(out_buf, frame_desc.data(), n); + out_buf += __sanitizer::Min(n, frame_desc.length()); + *out_buf++ = 0; + } + CHECK(out_buf <= out_end); + *out_buf = 0; } SANITIZER_INTERFACE_ATTRIBUTE diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cc index 3c5bed3d75a..7e21c4b883f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cc +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace_printer.cc @@ -15,8 +15,8 @@ namespace __sanitizer { -// sanitizer_symbolizer_fuchsia.cc implements these differently for Fuchsia. -#if !SANITIZER_FUCHSIA +// sanitizer_symbolizer_markup.cc implements these differently. +#if !SANITIZER_SYMBOLIZER_MARKUP static const char *StripFunctionName(const char *function, const char *prefix) { if (!function) return nullptr; @@ -27,6 +27,80 @@ static const char *StripFunctionName(const char *function, const char *prefix) { return function; } +static const char *DemangleFunctionName(const char *function) { + if (!function) return nullptr; + + // NetBSD uses indirection for old threading functions for historical reasons + // The mangled names are internal implementation detail and should not be + // exposed even in backtraces. +#if SANITIZER_NETBSD + if (!internal_strcmp(function, "__libc_mutex_init")) + return "pthread_mutex_init"; + if (!internal_strcmp(function, "__libc_mutex_lock")) + return "pthread_mutex_lock"; + if (!internal_strcmp(function, "__libc_mutex_trylock")) + return "pthread_mutex_trylock"; + if (!internal_strcmp(function, "__libc_mutex_unlock")) + return "pthread_mutex_unlock"; + if (!internal_strcmp(function, "__libc_mutex_destroy")) + return "pthread_mutex_destroy"; + if (!internal_strcmp(function, "__libc_mutexattr_init")) + return "pthread_mutexattr_init"; + if (!internal_strcmp(function, "__libc_mutexattr_settype")) + return "pthread_mutexattr_settype"; + if (!internal_strcmp(function, "__libc_mutexattr_destroy")) + return "pthread_mutexattr_destroy"; + if (!internal_strcmp(function, "__libc_cond_init")) + return "pthread_cond_init"; + if (!internal_strcmp(function, "__libc_cond_signal")) + return "pthread_cond_signal"; + if (!internal_strcmp(function, "__libc_cond_broadcast")) + return "pthread_cond_broadcast"; + if (!internal_strcmp(function, "__libc_cond_wait")) + return "pthread_cond_wait"; + if (!internal_strcmp(function, "__libc_cond_timedwait")) + return "pthread_cond_timedwait"; + if (!internal_strcmp(function, "__libc_cond_destroy")) + return "pthread_cond_destroy"; + if (!internal_strcmp(function, "__libc_rwlock_init")) + return "pthread_rwlock_init"; + if (!internal_strcmp(function, "__libc_rwlock_rdlock")) + return "pthread_rwlock_rdlock"; + if (!internal_strcmp(function, "__libc_rwlock_wrlock")) + return "pthread_rwlock_wrlock"; + if (!internal_strcmp(function, "__libc_rwlock_tryrdlock")) + return "pthread_rwlock_tryrdlock"; + if (!internal_strcmp(function, "__libc_rwlock_trywrlock")) + return "pthread_rwlock_trywrlock"; + if (!internal_strcmp(function, "__libc_rwlock_unlock")) + return "pthread_rwlock_unlock"; + if (!internal_strcmp(function, "__libc_rwlock_destroy")) + return "pthread_rwlock_destroy"; + if (!internal_strcmp(function, "__libc_thr_keycreate")) + return "pthread_key_create"; + if (!internal_strcmp(function, "__libc_thr_setspecific")) + return "pthread_setspecific"; + if (!internal_strcmp(function, "__libc_thr_getspecific")) + return "pthread_getspecific"; + if (!internal_strcmp(function, "__libc_thr_keydelete")) + return "pthread_key_delete"; + if (!internal_strcmp(function, "__libc_thr_once")) + return "pthread_once"; + if (!internal_strcmp(function, "__libc_thr_self")) + return "pthread_self"; + if (!internal_strcmp(function, "__libc_thr_exit")) + return "pthread_exit"; + if (!internal_strcmp(function, "__libc_thr_setcancelstate")) + return "pthread_setcancelstate"; + if (!internal_strcmp(function, "__libc_thr_equal")) + return "pthread_equal"; + if (!internal_strcmp(function, "__libc_thr_curcpu")) + return "pthread_curcpu_np"; +#endif + + return function; +} + static const char kDefaultFormat[] = " #%n %p %F %L"; void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no, @@ -58,7 +132,9 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no, buffer->append("0x%zx", info.module_offset); break; case 'f': - buffer->append("%s", StripFunctionName(info.function, strip_func_prefix)); + buffer->append("%s", + DemangleFunctionName( + StripFunctionName(info.function, strip_func_prefix))); break; case 'q': buffer->append("0x%zx", info.function_offset != AddressInfo::kUnknown @@ -79,7 +155,8 @@ void RenderFrame(InternalScopedString *buffer, const char *format, int frame_no, // Function name and offset, if file is unknown. if (info.function) { buffer->append("in %s", - StripFunctionName(info.function, strip_func_prefix)); + DemangleFunctionName( + StripFunctionName(info.function, strip_func_prefix))); if (!info.file && info.function_offset != AddressInfo::kUnknown) buffer->append("+0x%zx", info.function_offset); } @@ -149,7 +226,7 @@ void RenderData(InternalScopedString *buffer, const char *format, } } -#endif // !SANITIZER_FUCHSIA +#endif // !SANITIZER_SYMBOLIZER_MARKUP void RenderSourceLocation(InternalScopedString *buffer, const char *file, int line, int column, bool vs_style, diff --git a/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cc b/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cc new file mode 100644 index 00000000000..623fba25ed5 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_stacktrace_sparc.cc @@ -0,0 +1,56 @@ +//===-- sanitizer_stacktrace_sparc.cc -------------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is shared between AddressSanitizer and ThreadSanitizer +// run-time libraries. +// +// Implemention of fast stack unwinding for Sparc. +//===----------------------------------------------------------------------===// + +// This file is ported to Sparc v8, but it should be easy to port to +// Sparc v9. +#if defined(__sparcv8__) + +#include "sanitizer_common.h" +#include "sanitizer_stacktrace.h" + +namespace __sanitizer { + +void BufferedStackTrace::FastUnwindStack(uptr pc, uptr bp, uptr stack_top, + uptr stack_bottom, u32 max_depth) { + const uptr kPageSize = GetPageSizeCached(); + CHECK_GE(max_depth, 2); + trace_buffer[0] = pc; + size = 1; + if (stack_top < 4096) return; // Sanity check for stack top. + // Flush register windows to memory + asm volatile("ta 3" ::: "memory"); + uhwptr *frame = (uhwptr*)bp; + // Lowest possible address that makes sense as the next frame pointer. + // 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((uptr)frame, stack_top, bottom) && + IsAligned((uptr)frame, sizeof(*frame)) && + size < max_depth) { + uhwptr pc1 = frame[15]; + // Let's assume that any pointer in the 0th page is invalid and + // stop unwinding here. If we're adding support for a platform + // where this isn't true, we need to reconsider this check. + if (pc1 < kPageSize) + break; + if (pc1 != pc) { + trace_buffer[size++] = (uptr) pc1; + } + bottom = (uptr)frame; + frame = (uhwptr*)frame[14]; + } +} + +} // namespace __sanitizer + +#endif // !defined(__sparcv8__) diff --git a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc index d746fa5403a..635c5732d84 100644 --- a/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc @@ -55,6 +55,14 @@ #include "sanitizer_mutex.h" #include "sanitizer_placement_new.h" +// Sufficiently old kernel headers don't provide this value, but we can still +// call prctl with it. If the runtime kernel is new enough, the prctl call will +// have the desired effect; if the kernel is too old, the call will error and we +// can ignore said error. +#ifndef PR_SET_PTRACER +#define PR_SET_PTRACER 0x59616d61 +#endif + // This module works by spawning a Linux task which then attaches to every // thread in the caller process with ptrace. This suspends the threads, and // PTRACE_GETREGS can then be used to obtain their register state. The callback @@ -78,7 +86,7 @@ namespace __sanitizer { class SuspendedThreadsListLinux : public SuspendedThreadsList { public: - SuspendedThreadsListLinux() : thread_ids_(1024) {} + SuspendedThreadsListLinux() { thread_ids_.reserve(1024); } tid_t GetThreadID(uptr index) const; uptr ThreadCount() const; @@ -199,26 +207,26 @@ void ThreadSuspender::KillAllThreads() { bool ThreadSuspender::SuspendAllThreads() { ThreadLister thread_lister(pid_); - bool added_threads; - bool first_iteration = true; - do { - // Run through the directory entries once. - added_threads = false; - pid_t tid = thread_lister.GetNextTID(); - while (tid >= 0) { - if (SuspendThread(tid)) - added_threads = true; - tid = thread_lister.GetNextTID(); - } - if (thread_lister.error() || (first_iteration && !added_threads)) { - // Detach threads and fail. - ResumeAllThreads(); - return false; + bool retry = true; + InternalMmapVector threads; + threads.reserve(128); + for (int i = 0; i < 30 && retry; ++i) { + retry = false; + switch (thread_lister.ListThreads(&threads)) { + case ThreadLister::Error: + ResumeAllThreads(); + return false; + case ThreadLister::Incomplete: + retry = true; + break; + case ThreadLister::Ok: + break; } - thread_lister.Reset(); - first_iteration = false; - } while (added_threads); - return true; + for (tid_t tid : threads) + if (SuspendThread(tid)) + retry = true; + }; + return suspended_threads_list_.ThreadCount(); } // Pointer to the ThreadSuspender instance for use in signal handler. @@ -243,7 +251,8 @@ static void TracerThreadDieCallback() { } // Signal handler to wake up suspended threads when the tracer thread dies. -static void TracerThreadSignalHandler(int signum, void *siginfo, void *uctx) { +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); @@ -284,7 +293,7 @@ static int TracerThread(void* argument) { thread_suspender_instance = &thread_suspender; // Alternate stack for signal handling. - InternalScopedBuffer handler_stack_memory(kHandlerStackSize); + 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(); @@ -431,9 +440,7 @@ void StopTheWorld(StopTheWorldCallback callback, void *argument) { ScopedSetTracerPID scoped_set_tracer_pid(tracer_pid); // On some systems we have to explicitly declare that we want to be traced // by the tracer thread. -#ifdef PR_SET_PTRACER internal_prctl(PR_SET_PTRACER, tracer_pid, 0, 0, 0); -#endif // Allow the tracer thread to start. tracer_thread_argument.mutex.Unlock(); // NOTE: errno is shared between this thread and the tracer thread. diff --git a/libsanitizer/sanitizer_common/sanitizer_suppressions.cc b/libsanitizer/sanitizer_common/sanitizer_suppressions.cc index 4095a0942a3..6c682a1fb62 100644 --- a/libsanitizer/sanitizer_common/sanitizer_suppressions.cc +++ b/libsanitizer/sanitizer_common/sanitizer_suppressions.cc @@ -23,7 +23,7 @@ namespace __sanitizer { SuppressionContext::SuppressionContext(const char *suppression_types[], int suppression_types_num) : suppression_types_(suppression_types), - suppression_types_num_(suppression_types_num), suppressions_(1), + suppression_types_num_(suppression_types_num), can_parse_(true) { CHECK_LE(suppression_types_num_, kMaxSuppressionTypes); internal_memset(has_suppression_type_, 0, suppression_types_num_); diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer.h index 5e2c843d86e..ef2fb4a0af3 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer.h +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer.h @@ -105,7 +105,6 @@ class Symbolizer final { void Flush(); // Attempts to demangle the provided C++ mangled name. const char *Demangle(const char *name); - void PrepareForSandboxing(); // Allow user to install hooks that would be called before/after Symbolizer // does the actual file/line info fetching. Specific sanitizers may need this @@ -131,8 +130,9 @@ class Symbolizer final { class ModuleNameOwner { public: explicit ModuleNameOwner(BlockingMutex *synchronized_by) - : storage_(kInitialCapacity), last_match_(nullptr), - mu_(synchronized_by) {} + : last_match_(nullptr), mu_(synchronized_by) { + storage_.reserve(kInitialCapacity); + } const char *GetOwnedCopy(const char *str); private: @@ -156,7 +156,6 @@ class Symbolizer final { // Platform-specific default demangler, must not return nullptr. const char *PlatformDemangle(const char *name); - void PlatformPrepareForSandboxing(); static Symbolizer *symbolizer_; static StaticSpinMutex init_mu_; diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_fuchsia.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer_fuchsia.h new file mode 100644 index 00000000000..2f680752255 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_fuchsia.h @@ -0,0 +1,38 @@ +//===-- sanitizer_symbolizer_fuchsia.h -----------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is shared between various sanitizers' runtime libraries. +// +// Define Fuchsia's string formats and limits for the markup symbolizer. +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_SYMBOLIZER_FUCHSIA_H +#define SANITIZER_SYMBOLIZER_FUCHSIA_H + +#include "sanitizer_internal_defs.h" + +namespace __sanitizer { + +// See the spec at: +// https://fuchsia.googlesource.com/zircon/+/master/docs/symbolizer_markup.md + +// This is used by UBSan for type names, and by ASan for global variable names. +constexpr const char *kFormatDemangle = "{{{symbol:%s}}}"; +constexpr uptr kFormatDemangleMax = 1024; // Arbitrary. + +// Function name or equivalent from PC location. +constexpr const char *kFormatFunction = "{{{pc:%p}}}"; +constexpr uptr kFormatFunctionMax = 64; // More than big enough for 64-bit hex. + +// Global variable name or equivalent from data memory address. +constexpr const char *kFormatData = "{{{data:%p}}}"; + +// One frame in a backtrace (printed on a line by itself). +constexpr const char *kFormatFrame = "{{{bt:%u:%p}}}"; + +} // namespace __sanitizer + +#endif // SANITIZER_SYMBOLIZER_FUCHSIA_H diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cc index df934412146..9e57bb62485 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_libcdep.cc @@ -24,8 +24,8 @@ Symbolizer *Symbolizer::GetOrInit() { return symbolizer_; } -// See sanitizer_symbolizer_fuchsia.cc. -#if !SANITIZER_FUCHSIA +// See sanitizer_symbolizer_markup.cc. +#if !SANITIZER_SYMBOLIZER_MARKUP const char *ExtractToken(const char *str, const char *delims, char **result) { uptr prefix_len = internal_strcspn(str, delims); @@ -143,11 +143,6 @@ const char *Symbolizer::Demangle(const char *name) { return PlatformDemangle(name); } -void Symbolizer::PrepareForSandboxing() { - BlockingMutexLock l(&mu_); - PlatformPrepareForSandboxing(); -} - bool Symbolizer::FindModuleNameAndOffsetForAddress(uptr address, const char **module_name, uptr *module_offset, @@ -492,6 +487,6 @@ bool SymbolizerProcess::WriteToSymbolizer(const char *buffer, uptr length) { return true; } -#endif // !SANITIZER_FUCHSIA +#endif // !SANITIZER_SYMBOLIZER_MARKUP } // namespace __sanitizer diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_fuchsia.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_markup.cc similarity index 61% rename from libsanitizer/sanitizer_common/sanitizer_symbolizer_fuchsia.cc rename to libsanitizer/sanitizer_common/sanitizer_symbolizer_markup.cc index 04263205e16..3897aab0b9a 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_fuchsia.cc +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_markup.cc @@ -1,4 +1,4 @@ -//===-- sanitizer_symbolizer_fuchsia.cc -----------------------------------===// +//===-- sanitizer_symbolizer_markup.cc ------------------------------------===// // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. @@ -7,18 +7,27 @@ // // This file is shared between various sanitizers' runtime libraries. // -// Implementation of Fuchsia-specific symbolizer. +// Implementation of offline markup symbolizer. //===----------------------------------------------------------------------===// #include "sanitizer_platform.h" -#if SANITIZER_FUCHSIA +#if SANITIZER_SYMBOLIZER_MARKUP -#include "sanitizer_fuchsia.h" +#if SANITIZER_FUCHSIA +#include "sanitizer_symbolizer_fuchsia.h" +#elif SANITIZER_RTEMS +#include "sanitizer_symbolizer_rtems.h" +#endif +#include "sanitizer_stacktrace.h" #include "sanitizer_symbolizer.h" +#include +#include + namespace __sanitizer { -// For Fuchsia we don't do any actual symbolization per se. +// This generic support for offline symbolizing is based on the +// Fuchsia port. We don't do any actual symbolization per se. // Instead, we emit text containing raw addresses and raw linkage // symbol names, embedded in Fuchsia's symbolization markup format. // Fuchsia's logging infrastructure emits enough information about @@ -26,20 +35,6 @@ namespace __sanitizer { // symbolization and pretty-print the markup. See the spec at: // https://fuchsia.googlesource.com/zircon/+/master/docs/symbolizer_markup.md -// This is used by UBSan for type names, and by ASan for global variable names. -constexpr const char *kFormatDemangle = "{{{symbol:%s}}}"; -constexpr uptr kFormatDemangleMax = 1024; // Arbitrary. - -// Function name or equivalent from PC location. -constexpr const char *kFormatFunction = "{{{pc:%p}}}"; -constexpr uptr kFormatFunctionMax = 64; // More than big enough for 64-bit hex. - -// Global variable name or equivalent from data memory address. -constexpr const char *kFormatData = "{{{data:%p}}}"; - -// One frame in a backtrace (printed on a line by itself). -constexpr const char *kFormatFrame = "{{{bt:%u:%p}}}"; - // This is used by UBSan for type names, and by ASan for global variable names. // It's expected to return a static buffer that will be reused on each call. const char *Symbolizer::Demangle(const char *name) { @@ -100,6 +95,49 @@ Symbolizer *Symbolizer::PlatformInit() { void Symbolizer::LateInitialize() { Symbolizer::GetOrInit(); } +void StartReportDeadlySignal() {} +void ReportDeadlySignal(const SignalContext &sig, u32 tid, + UnwindSignalStackCallbackType unwind, + const void *unwind_context) {} + +#if SANITIZER_CAN_SLOW_UNWIND +struct UnwindTraceArg { + BufferedStackTrace *stack; + u32 max_depth; +}; + +_Unwind_Reason_Code Unwind_Trace(struct _Unwind_Context *ctx, void *param) { + UnwindTraceArg *arg = static_cast(param); + CHECK_LT(arg->stack->size, arg->max_depth); + uptr pc = _Unwind_GetIP(ctx); + if (pc < PAGE_SIZE) return _URC_NORMAL_STOP; + arg->stack->trace_buffer[arg->stack->size++] = pc; + return (arg->stack->size == arg->max_depth ? _URC_NORMAL_STOP + : _URC_NO_REASON); +} + +void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) { + CHECK_GE(max_depth, 2); + size = 0; + UnwindTraceArg arg = {this, Min(max_depth + 1, kStackTraceMax)}; + _Unwind_Backtrace(Unwind_Trace, &arg); + CHECK_GT(size, 0); + // We need to pop a few frames so that pc is on top. + uptr to_pop = LocatePcInTrace(pc); + // trace_buffer[0] belongs to the current function so we always pop it, + // unless there is only 1 frame in the stack trace (1 frame is always better + // than 0!). + PopStackFrames(Min(to_pop, static_cast(1))); + trace_buffer[0] = pc; +} + +void BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context, + u32 max_depth) { + CHECK_NE(context, nullptr); + UNREACHABLE("signal context doesn't exist"); +} +#endif // SANITIZER_CAN_SLOW_UNWIND + } // namespace __sanitizer -#endif // SANITIZER_FUCHSIA +#endif // SANITIZER_SYMBOLIZER_MARKUP diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc index afd6bbe7fbf..750e89e2960 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cc @@ -75,6 +75,7 @@ static swift_demangle_ft swift_demangle_f; // symbolication. static void InitializeSwiftDemangler() { swift_demangle_f = (swift_demangle_ft)dlsym(RTLD_DEFAULT, "swift_demangle"); + (void)dlerror(); // Cleanup error message in case of failure } // Attempts to demangle a Swift name. The demangler will return nullptr if a @@ -312,8 +313,9 @@ class Addr2LinePool : public SymbolizerTool { public: explicit Addr2LinePool(const char *addr2line_path, LowLevelAllocator *allocator) - : addr2line_path_(addr2line_path), allocator_(allocator), - addr2line_pool_(16) {} + : addr2line_path_(addr2line_path), allocator_(allocator) { + addr2line_pool_.reserve(16); + } bool SymbolizePC(uptr addr, SymbolizedStack *stack) override { if (const char *buf = @@ -442,8 +444,6 @@ const char *Symbolizer::PlatformDemangle(const char *name) { return DemangleSwiftAndCXX(name); } -void Symbolizer::PlatformPrepareForSandboxing() {} - static SymbolizerTool *ChooseExternalSymbolizer(LowLevelAllocator *allocator) { const char *path = common_flags()->external_symbolizer_path; const char *binary_name = path ? StripModuleName(path) : ""; diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cc new file mode 100644 index 00000000000..1157724125e --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_report.cc @@ -0,0 +1,280 @@ +//===-- sanitizer_symbolizer_report.cc ------------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +/// +/// This file is shared between AddressSanitizer and other sanitizer run-time +/// libraries and implements symbolized reports related functions. +/// +//===----------------------------------------------------------------------===// + +#include "sanitizer_common.h" +#include "sanitizer_file.h" +#include "sanitizer_flags.h" +#include "sanitizer_procmaps.h" +#include "sanitizer_report_decorator.h" +#include "sanitizer_stacktrace.h" +#include "sanitizer_stacktrace_printer.h" +#include "sanitizer_symbolizer.h" + +#if SANITIZER_POSIX +# include "sanitizer_posix.h" +# include +#endif + +namespace __sanitizer { + +#if !SANITIZER_GO +void ReportErrorSummary(const char *error_type, const AddressInfo &info, + const char *alt_tool_name) { + if (!common_flags()->print_summary) return; + InternalScopedString buff(kMaxSummaryLength); + buff.append("%s ", error_type); + RenderFrame(&buff, "%L %F", 0, info, common_flags()->symbolize_vs_style, + common_flags()->strip_path_prefix); + ReportErrorSummary(buff.data(), alt_tool_name); +} +#endif + +#if !SANITIZER_FUCHSIA + +bool ReportFile::SupportsColors() { + SpinMutexLock l(mu); + ReopenIfNecessary(); + return SupportsColoredOutput(fd); +} + +static INLINE bool ReportSupportsColors() { + return report_file.SupportsColors(); +} + +#else // SANITIZER_FUCHSIA + +// Fuchsia's logs always go through post-processing that handles colorization. +static INLINE bool ReportSupportsColors() { return true; } + +#endif // !SANITIZER_FUCHSIA + +bool ColorizeReports() { + // FIXME: Add proper Windows support to AnsiColorDecorator and re-enable color + // printing on Windows. + if (SANITIZER_WINDOWS) + return false; + + const char *flag = common_flags()->color; + return internal_strcmp(flag, "always") == 0 || + (internal_strcmp(flag, "auto") == 0 && ReportSupportsColors()); +} + +void ReportErrorSummary(const char *error_type, const StackTrace *stack, + const char *alt_tool_name) { +#if !SANITIZER_GO + if (!common_flags()->print_summary) + return; + if (stack->size == 0) { + ReportErrorSummary(error_type); + return; + } + // Currently, we include the first stack frame into the report summary. + // Maybe sometimes we need to choose another frame (e.g. skip memcpy/etc). + uptr pc = StackTrace::GetPreviousInstructionPc(stack->trace[0]); + SymbolizedStack *frame = Symbolizer::GetOrInit()->SymbolizePC(pc); + ReportErrorSummary(error_type, frame->info, alt_tool_name); + frame->ClearAll(); +#endif +} + +void ReportMmapWriteExec(int prot) { +#if SANITIZER_POSIX && (!SANITIZER_GO && !SANITIZER_ANDROID) + if ((prot & (PROT_WRITE | PROT_EXEC)) != (PROT_WRITE | PROT_EXEC)) + return; + + ScopedErrorReportLock l; + SanitizerCommonDecorator d; + + InternalMmapVector stack_buffer(1); + BufferedStackTrace *stack = stack_buffer.data(); + stack->Reset(); + uptr top = 0; + uptr bottom = 0; + GET_CALLER_PC_BP_SP; + (void)sp; + bool fast = common_flags()->fast_unwind_on_fatal; + if (fast) + GetThreadStackTopAndBottom(false, &top, &bottom); + stack->Unwind(kStackTraceMax, pc, bp, nullptr, top, bottom, fast); + + Printf("%s", d.Warning()); + Report("WARNING: %s: writable-executable page usage\n", SanitizerToolName); + Printf("%s", d.Default()); + + stack->Print(); + ReportErrorSummary("w-and-x-usage", stack); +#endif +} + +#if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS && !SANITIZER_GO +void StartReportDeadlySignal() { + // Write the first message using fd=2, just in case. + // It may actually fail to write in case stderr is closed. + CatastrophicErrorWrite(SanitizerToolName, internal_strlen(SanitizerToolName)); + static const char kDeadlySignal[] = ":DEADLYSIGNAL\n"; + CatastrophicErrorWrite(kDeadlySignal, sizeof(kDeadlySignal) - 1); +} + +static void MaybeReportNonExecRegion(uptr pc) { +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD + MemoryMappingLayout proc_maps(/*cache_enabled*/ true); + MemoryMappedSegment segment; + while (proc_maps.Next(&segment)) { + if (pc >= segment.start && pc < segment.end && !segment.IsExecutable()) + Report("Hint: PC is at a non-executable region. Maybe a wild jump?\n"); + } +#endif +} + +static void PrintMemoryByte(InternalScopedString *str, const char *before, + u8 byte) { + SanitizerCommonDecorator d; + str->append("%s%s%x%x%s ", before, d.MemoryByte(), byte >> 4, byte & 15, + d.Default()); +} + +static void MaybeDumpInstructionBytes(uptr pc) { + if (!common_flags()->dump_instruction_bytes || (pc < GetPageSizeCached())) + return; + InternalScopedString str(1024); + str.append("First 16 instruction bytes at pc: "); + if (IsAccessibleMemoryRange(pc, 16)) { + for (int i = 0; i < 16; ++i) { + PrintMemoryByte(&str, "", ((u8 *)pc)[i]); + } + str.append("\n"); + } else { + str.append("unaccessible\n"); + } + Report("%s", str.data()); +} + +static void MaybeDumpRegisters(void *context) { + if (!common_flags()->dump_registers) return; + SignalContext::DumpAllRegisters(context); +} + +static void ReportStackOverflowImpl(const SignalContext &sig, u32 tid, + UnwindSignalStackCallbackType unwind, + const void *unwind_context) { + SanitizerCommonDecorator d; + Printf("%s", d.Warning()); + static const char kDescription[] = "stack-overflow"; + Report("ERROR: %s: %s on address %p (pc %p bp %p sp %p T%d)\n", + SanitizerToolName, kDescription, (void *)sig.addr, (void *)sig.pc, + (void *)sig.bp, (void *)sig.sp, tid); + Printf("%s", d.Default()); + InternalMmapVector stack_buffer(1); + BufferedStackTrace *stack = stack_buffer.data(); + stack->Reset(); + unwind(sig, unwind_context, stack); + stack->Print(); + ReportErrorSummary(kDescription, stack); +} + +static void ReportDeadlySignalImpl(const SignalContext &sig, u32 tid, + UnwindSignalStackCallbackType unwind, + const void *unwind_context) { + SanitizerCommonDecorator d; + Printf("%s", d.Warning()); + const char *description = sig.Describe(); + Report("ERROR: %s: %s on unknown address %p (pc %p bp %p sp %p T%d)\n", + SanitizerToolName, description, (void *)sig.addr, (void *)sig.pc, + (void *)sig.bp, (void *)sig.sp, tid); + Printf("%s", d.Default()); + if (sig.pc < GetPageSizeCached()) + Report("Hint: pc points to the zero page.\n"); + if (sig.is_memory_access) { + const char *access_type = + sig.write_flag == SignalContext::WRITE + ? "WRITE" + : (sig.write_flag == SignalContext::READ ? "READ" : "UNKNOWN"); + Report("The signal is caused by a %s memory access.\n", access_type); + if (sig.addr < GetPageSizeCached()) + Report("Hint: address points to the zero page.\n"); + } + MaybeReportNonExecRegion(sig.pc); + InternalMmapVector stack_buffer(1); + BufferedStackTrace *stack = stack_buffer.data(); + stack->Reset(); + unwind(sig, unwind_context, stack); + stack->Print(); + MaybeDumpInstructionBytes(sig.pc); + MaybeDumpRegisters(sig.context); + Printf("%s can not provide additional info.\n", SanitizerToolName); + ReportErrorSummary(description, stack); +} + +void ReportDeadlySignal(const SignalContext &sig, u32 tid, + UnwindSignalStackCallbackType unwind, + const void *unwind_context) { + if (sig.IsStackOverflow()) + ReportStackOverflowImpl(sig, tid, unwind, unwind_context); + else + ReportDeadlySignalImpl(sig, tid, unwind, unwind_context); +} + +void HandleDeadlySignal(void *siginfo, void *context, u32 tid, + UnwindSignalStackCallbackType unwind, + const void *unwind_context) { + StartReportDeadlySignal(); + ScopedErrorReportLock rl; + SignalContext sig(siginfo, context); + ReportDeadlySignal(sig, tid, unwind, unwind_context); + Report("ABORTING\n"); + Die(); +} + +#endif // !SANITIZER_FUCHSIA && !SANITIZER_GO + +static atomic_uintptr_t reporting_thread = {0}; +static StaticSpinMutex CommonSanitizerReportMutex; + +ScopedErrorReportLock::ScopedErrorReportLock() { + uptr current = GetThreadSelf(); + for (;;) { + uptr expected = 0; + if (atomic_compare_exchange_strong(&reporting_thread, &expected, current, + memory_order_relaxed)) { + // We've claimed reporting_thread so proceed. + CommonSanitizerReportMutex.Lock(); + return; + } + + if (expected == current) { + // This is either asynch signal or nested error during error reporting. + // Fail simple to avoid deadlocks in Report(). + + // Can't use Report() here because of potential deadlocks in nested + // signal handlers. + CatastrophicErrorWrite(SanitizerToolName, + internal_strlen(SanitizerToolName)); + static const char msg[] = ": nested bug in the same thread, aborting.\n"; + CatastrophicErrorWrite(msg, sizeof(msg) - 1); + + internal__exit(common_flags()->exitcode); + } + + internal_sched_yield(); + } +} + +ScopedErrorReportLock::~ScopedErrorReportLock() { + CommonSanitizerReportMutex.Unlock(); + atomic_store_relaxed(&reporting_thread, 0); +} + +void ScopedErrorReportLock::CheckLocked() { + CommonSanitizerReportMutex.CheckLocked(); +} + +} // namespace __sanitizer diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_rtems.h b/libsanitizer/sanitizer_common/sanitizer_symbolizer_rtems.h new file mode 100644 index 00000000000..2afd01ed9f7 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_rtems.h @@ -0,0 +1,39 @@ +//===-- sanitizer_symbolizer_rtems.h -----------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is shared between various sanitizers' runtime libraries. +// +// Define RTEMS's string formats and limits for the markup symbolizer. +//===----------------------------------------------------------------------===// +#ifndef SANITIZER_SYMBOLIZER_RTEMS_H +#define SANITIZER_SYMBOLIZER_RTEMS_H + +#include "sanitizer_internal_defs.h" + +namespace __sanitizer { + +// The Myriad RTEMS symbolizer currently only parses backtrace lines, +// so use a format that the symbolizer understands. For other +// markups, keep them the same as the Fuchsia's. + +// This is used by UBSan for type names, and by ASan for global variable names. +constexpr const char *kFormatDemangle = "{{{symbol:%s}}}"; +constexpr uptr kFormatDemangleMax = 1024; // Arbitrary. + +// Function name or equivalent from PC location. +constexpr const char *kFormatFunction = "{{{pc:%p}}}"; +constexpr uptr kFormatFunctionMax = 64; // More than big enough for 64-bit hex. + +// Global variable name or equivalent from data memory address. +constexpr const char *kFormatData = "{{{data:%p}}}"; + +// One frame in a backtrace (printed on a line by itself). +constexpr const char *kFormatFrame = " [%u] IP: %p"; + +} // namespace __sanitizer + +#endif // SANITIZER_SYMBOLIZER_RTEMS_H diff --git a/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cc b/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cc index 06375fc2f4e..3b455125c7a 100644 --- a/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cc +++ b/libsanitizer/sanitizer_common/sanitizer_symbolizer_win.cc @@ -174,10 +174,6 @@ const char *Symbolizer::PlatformDemangle(const char *name) { return name; } -void Symbolizer::PlatformPrepareForSandboxing() { - // Do nothing. -} - namespace { struct ScopedHandle { ScopedHandle() : h_(nullptr) {} diff --git a/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc b/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc index 7c9a2719eea..0c3b7f97045 100644 --- a/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc +++ b/libsanitizer/sanitizer_common/sanitizer_syscall_generic.inc @@ -9,42 +9,23 @@ // //===----------------------------------------------------------------------===// -#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD +// NetBSD uses libc calls directly +#if !SANITIZER_NETBSD + +#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_OPENBSD || SANITIZER_SOLARIS # define SYSCALL(name) SYS_ ## name #else # define SYSCALL(name) __NR_ ## name #endif -#if SANITIZER_NETBSD -// We use 3 kinds of internal_syscall's for different types of retval in order -// to address differences in calling conventions (e.g. registers to place the -// return value in). -// - internal_syscall for 32-bit length (int, pid_t) -// - internal_syscall64 for 64-bit length (off_t) -// - internal_syscall_ptr for pointer and (s)size_t -# define internal_syscall syscall -# define internal_syscall64 __syscall -// Handle syscall renames manually -# define SYS_stat SYS___stat50 -# define SYS_lstat SYS___lstat50 -# define SYS_fstat SYS___fstat50 -# define SYS_gettimeofday SYS___gettimeofday50 -# define SYS_wait4 SYS___wait450 -# define SYS_getdents SYS___getdents30 -# define SYS_sigaltstack SYS___sigaltstack14 -# define SYS_sigprocmask SYS___sigprocmask14 -# define SYS_nanosleep SYS___nanosleep50 -# if SANITIZER_WORDSIZE == 64 -# define internal_syscall_ptr __syscall -# else -# define internal_syscall_ptr syscall -# endif -#elif defined(__x86_64__) && (SANITIZER_FREEBSD || SANITIZER_MAC) +#if defined(__x86_64__) && (SANITIZER_FREEBSD || SANITIZER_MAC) # define internal_syscall __syscall # else # define internal_syscall syscall #endif +#endif + bool internal_iserror(uptr retval, int *rverrno) { if (retval == (uptr)-1) { if (rverrno) diff --git a/libsanitizer/sanitizer_common/sanitizer_syscall_linux_arm.inc b/libsanitizer/sanitizer_common/sanitizer_syscall_linux_arm.inc new file mode 100644 index 00000000000..71ac0d52d0c --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_syscall_linux_arm.inc @@ -0,0 +1,136 @@ +//===-- sanitizer_syscall_linux_arm.inc -------------------------*- C++ -*-===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Implementations of internal_syscall and internal_iserror for Linux/arm. +// +//===----------------------------------------------------------------------===// + +#define SYSCALL(name) __NR_ ## name + +static uptr __internal_syscall(u32 nr) { + register u32 r8 asm("r7") = nr; + register u32 r0 asm("r0"); + asm volatile("swi #0" + : "=r"(r0) + : "r"(r8) + : "memory", "cc"); + return r0; +} +#define __internal_syscall0(n) \ + (__internal_syscall)(n) + +static uptr __internal_syscall(u32 nr, u32 arg1) { + register u32 r8 asm("r7") = nr; + register u32 r0 asm("r0") = arg1; + asm volatile("swi #0" + : "=r"(r0) + : "r"(r8), "0"(r0) + : "memory", "cc"); + return r0; +} +#define __internal_syscall1(n, a1) \ + (__internal_syscall)(n, (u32)(a1)) + +static uptr __internal_syscall(u32 nr, u32 arg1, long arg2) { + register u32 r8 asm("r7") = nr; + register u32 r0 asm("r0") = arg1; + register u32 r1 asm("r1") = arg2; + asm volatile("swi #0" + : "=r"(r0) + : "r"(r8), "0"(r0), "r"(r1) + : "memory", "cc"); + return r0; +} +#define __internal_syscall2(n, a1, a2) \ + (__internal_syscall)(n, (u32)(a1), (long)(a2)) + +static uptr __internal_syscall(u32 nr, u32 arg1, long arg2, long arg3) { + register u32 r8 asm("r7") = nr; + register u32 r0 asm("r0") = arg1; + register u32 r1 asm("r1") = arg2; + register u32 r2 asm("r2") = arg3; + asm volatile("swi #0" + : "=r"(r0) + : "r"(r8), "0"(r0), "r"(r1), "r"(r2) + : "memory", "cc"); + return r0; +} +#define __internal_syscall3(n, a1, a2, a3) \ + (__internal_syscall)(n, (u32)(a1), (long)(a2), (long)(a3)) + +static uptr __internal_syscall(u32 nr, u32 arg1, long arg2, long arg3, + u32 arg4) { + register u32 r8 asm("r7") = nr; + register u32 r0 asm("r0") = arg1; + register u32 r1 asm("r1") = arg2; + register u32 r2 asm("r2") = arg3; + register u32 r3 asm("r3") = arg4; + asm volatile("swi #0" + : "=r"(r0) + : "r"(r8), "0"(r0), "r"(r1), "r"(r2), "r"(r3) + : "memory", "cc"); + return r0; +} +#define __internal_syscall4(n, a1, a2, a3, a4) \ + (__internal_syscall)(n, (u32)(a1), (long)(a2), (long)(a3), (long)(a4)) + +static uptr __internal_syscall(u32 nr, u32 arg1, long arg2, long arg3, + u32 arg4, long arg5) { + register u32 r8 asm("r7") = nr; + register u32 r0 asm("r0") = arg1; + register u32 r1 asm("r1") = arg2; + register u32 r2 asm("r2") = arg3; + register u32 r3 asm("r3") = arg4; + register u32 r4 asm("r4") = arg5; + asm volatile("swi #0" + : "=r"(r0) + : "r"(r8), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4) + : "memory", "cc"); + return r0; +} +#define __internal_syscall5(n, a1, a2, a3, a4, a5) \ + (__internal_syscall)(n, (u32)(a1), (long)(a2), (long)(a3), (long)(a4), \ + (u32)(a5)) + +static uptr __internal_syscall(u32 nr, u32 arg1, long arg2, long arg3, + u32 arg4, long arg5, long arg6) { + register u32 r8 asm("r7") = nr; + register u32 r0 asm("r0") = arg1; + register u32 r1 asm("r1") = arg2; + register u32 r2 asm("r2") = arg3; + register u32 r3 asm("r3") = arg4; + register u32 r4 asm("r4") = arg5; + register u32 r5 asm("r5") = arg6; + asm volatile("swi #0" + : "=r"(r0) + : "r"(r8), "0"(r0), "r"(r1), "r"(r2), "r"(r3), "r"(r4), "r"(r5) + : "memory", "cc"); + return r0; +} +#define __internal_syscall6(n, a1, a2, a3, a4, a5, a6) \ + (__internal_syscall)(n, (u32)(a1), (long)(a2), (long)(a3), (long)(a4), \ + (u32)(a5), (long)(a6)) + +#define __SYSCALL_NARGS_X(a1, a2, a3, a4, a5, a6, a7, a8, n, ...) n +#define __SYSCALL_NARGS(...) \ + __SYSCALL_NARGS_X(__VA_ARGS__, 7, 6, 5, 4, 3, 2, 1, 0, ) +#define __SYSCALL_CONCAT_X(a, b) a##b +#define __SYSCALL_CONCAT(a, b) __SYSCALL_CONCAT_X(a, b) +#define __SYSCALL_DISP(b, ...) \ + __SYSCALL_CONCAT(b, __SYSCALL_NARGS(__VA_ARGS__))(__VA_ARGS__) + +#define internal_syscall(...) __SYSCALL_DISP(__internal_syscall, __VA_ARGS__) + +// Helper function used to avoid cobbler errno. +bool internal_iserror(uptr retval, int *rverrno) { + if (retval >= (uptr)-4095) { + if (rverrno) + *rverrno = -retval; + return true; + } + return false; +} diff --git a/libsanitizer/sanitizer_common/sanitizer_syscalls_netbsd.inc b/libsanitizer/sanitizer_common/sanitizer_syscalls_netbsd.inc new file mode 100644 index 00000000000..4fd4d06a0d1 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_syscalls_netbsd.inc @@ -0,0 +1,3784 @@ +//===-- sanitizer_syscalls_netbsd.inc ---------------------------*- C++ -*-===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Common syscalls handlers for tools like AddressSanitizer, +// ThreadSanitizer, MemorySanitizer, etc. +// +// This file should be included into the tool's interceptor file, +// which has to define it's own macros: +// COMMON_SYSCALL_PRE_READ_RANGE +// Called in prehook for regions that will be read by the kernel and +// must be initialized. +// COMMON_SYSCALL_PRE_WRITE_RANGE +// Called in prehook for regions that will be written to by the kernel +// and must be addressable. The actual write range may be smaller than +// reported in the prehook. See POST_WRITE_RANGE. +// COMMON_SYSCALL_POST_READ_RANGE +// Called in posthook for regions that were read by the kernel. Does +// not make much sense. +// COMMON_SYSCALL_POST_WRITE_RANGE +// Called in posthook for regions that were written to by the kernel +// and are now initialized. +// COMMON_SYSCALL_ACQUIRE(addr) +// Acquire memory visibility from addr. +// COMMON_SYSCALL_RELEASE(addr) +// Release memory visibility to addr. +// COMMON_SYSCALL_FD_CLOSE(fd) +// Called before closing file descriptor fd. +// COMMON_SYSCALL_FD_ACQUIRE(fd) +// Acquire memory visibility from fd. +// COMMON_SYSCALL_FD_RELEASE(fd) +// Release memory visibility to fd. +// COMMON_SYSCALL_PRE_FORK() +// Called before fork syscall. +// COMMON_SYSCALL_POST_FORK(long long res) +// Called after fork syscall. +// +// 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 +// +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" +#if SANITIZER_NETBSD + +#include "sanitizer_libc.h" + +#define PRE_SYSCALL(name) \ + SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_pre_impl_##name +#define PRE_READ(p, s) COMMON_SYSCALL_PRE_READ_RANGE(p, s) +#define PRE_WRITE(p, s) COMMON_SYSCALL_PRE_WRITE_RANGE(p, s) + +#define POST_SYSCALL(name) \ + SANITIZER_INTERFACE_ATTRIBUTE void __sanitizer_syscall_post_impl_##name +#define POST_READ(p, s) COMMON_SYSCALL_POST_READ_RANGE(p, s) +#define POST_WRITE(p, s) COMMON_SYSCALL_POST_WRITE_RANGE(p, s) + +#ifndef COMMON_SYSCALL_ACQUIRE +#define COMMON_SYSCALL_ACQUIRE(addr) ((void)(addr)) +#endif + +#ifndef COMMON_SYSCALL_RELEASE +#define COMMON_SYSCALL_RELEASE(addr) ((void)(addr)) +#endif + +#ifndef COMMON_SYSCALL_FD_CLOSE +#define COMMON_SYSCALL_FD_CLOSE(fd) ((void)(fd)) +#endif + +#ifndef COMMON_SYSCALL_FD_ACQUIRE +#define COMMON_SYSCALL_FD_ACQUIRE(fd) ((void)(fd)) +#endif + +#ifndef COMMON_SYSCALL_FD_RELEASE +#define COMMON_SYSCALL_FD_RELEASE(fd) ((void)(fd)) +#endif + +#ifndef COMMON_SYSCALL_PRE_FORK +#define COMMON_SYSCALL_PRE_FORK() \ + {} +#endif + +#ifndef COMMON_SYSCALL_POST_FORK +#define COMMON_SYSCALL_POST_FORK(res) \ + {} +#endif + +// FIXME: do some kind of PRE_READ for all syscall arguments (int(s) and such). + +extern "C" { +#define SYS_MAXSYSARGS 8 +PRE_SYSCALL(syscall)(long long code_, long long args_[SYS_MAXSYSARGS]) { + /* Nothing to do */ +} +POST_SYSCALL(syscall) +(long long res, long long code_, long long args_[SYS_MAXSYSARGS]) { + /* Nothing to do */ +} +PRE_SYSCALL(exit)(long long rval_) { /* Nothing to do */ } +POST_SYSCALL(exit)(long long res, long long rval_) { /* Nothing to do */ } +PRE_SYSCALL(fork)(void) { COMMON_SYSCALL_PRE_FORK(); } +POST_SYSCALL(fork)(long long res) { COMMON_SYSCALL_POST_FORK(res); } +PRE_SYSCALL(read)(long long fd_, void *buf_, long long nbyte_) { + if (buf_) { + PRE_WRITE(buf_, nbyte_); + } +} +POST_SYSCALL(read)(long long res, long long fd_, void *buf_, long long nbyte_) { + if (res > 0) { + POST_WRITE(buf_, res); + } +} +PRE_SYSCALL(write)(long long fd_, void *buf_, long long nbyte_) { + if (buf_) { + PRE_READ(buf_, nbyte_); + } +} +POST_SYSCALL(write) +(long long res, long long fd_, void *buf_, long long nbyte_) { + if (res > 0) { + POST_READ(buf_, res); + } +} +PRE_SYSCALL(open)(void *path_, long long flags_, long long mode_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(open) +(long long res, void *path_, long long flags_, long long mode_) { + if (res > 0) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(close)(long long fd_) { COMMON_SYSCALL_FD_CLOSE((int)fd_); } +POST_SYSCALL(close)(long long res, long long fd_) { /* Nothing to do */ } +PRE_SYSCALL(compat_50_wait4) +(long long pid_, void *status_, long long options_, void *rusage_) { + /* TODO */ +} +POST_SYSCALL(compat_50_wait4) +(long long res, long long pid_, void *status_, long long options_, + void *rusage_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_ocreat)(void *path_, long long mode_) { /* TODO */ } +POST_SYSCALL(compat_43_ocreat)(long long res, void *path_, long long mode_) { + /* TODO */ +} +PRE_SYSCALL(link)(void *path_, void *link_) { + const char *path = (const char *)path_; + const char *link = (const char *)link_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } + if (link) { + PRE_READ(path, __sanitizer::internal_strlen(link) + 1); + } +} +POST_SYSCALL(link)(long long res, void *path_, void *link_) { + if (res == 0) { + const char *path = (const char *)path_; + const char *link = (const char *)link_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + if (link) { + POST_READ(path, __sanitizer::internal_strlen(link) + 1); + } + } +} +PRE_SYSCALL(unlink)(void *path_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(unlink)(long long res, void *path_) { + if (res == 0) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +/* syscall 11 has been skipped */ +PRE_SYSCALL(chdir)(void *path_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(chdir)(long long res, void *path_) { + if (res == 0) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(fchdir)(long long fd_) { /* Nothing to do */ } +POST_SYSCALL(fchdir)(long long res, long long fd_) { /* Nothing to do */ } +PRE_SYSCALL(compat_50_mknod)(void *path_, long long mode_, long long dev_) { + /* TODO */ +} +POST_SYSCALL(compat_50_mknod) +(long long res, void *path_, long long mode_, long long dev_) { + /* TODO */ +} +PRE_SYSCALL(chmod)(void *path_, long long mode_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(chmod)(long long res, void *path_, long long mode_) { + if (res == 0) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(chown)(void *path_, long long uid_, long long gid_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(chown) +(long long res, void *path_, long long uid_, long long gid_) { + if (res == 0) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(break)(void *nsize_) { /* Nothing to do */ } +POST_SYSCALL(break)(long long res, void *nsize_) { /* Nothing to do */ } +PRE_SYSCALL(compat_20_getfsstat) +(void *buf_, long long bufsize_, long long flags_) { + /* TODO */ +} +POST_SYSCALL(compat_20_getfsstat) +(long long res, void *buf_, long long bufsize_, long long flags_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_olseek) +(long long fd_, long long offset_, long long whence_) { + /* TODO */ +} +POST_SYSCALL(compat_43_olseek) +(long long res, long long fd_, long long offset_, long long whence_) { + /* TODO */ +} +PRE_SYSCALL(getpid)(void) { /* Nothing to do */ } +POST_SYSCALL(getpid)(long long res) { /* Nothing to do */ } +PRE_SYSCALL(compat_40_mount) +(void *type_, void *path_, long long flags_, void *data_) { + /* TODO */ +} +POST_SYSCALL(compat_40_mount) +(long long res, void *type_, void *path_, long long flags_, void *data_) { + /* TODO */ +} +PRE_SYSCALL(unmount)(void *path_, long long flags_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(unmount)(long long res, void *path_, long long flags_) { + if (res == 0) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(setuid)(long long uid_) { /* Nothing to do */ } +POST_SYSCALL(setuid)(long long res, long long uid_) { /* Nothing to do */ } +PRE_SYSCALL(getuid)(void) { /* Nothing to do */ } +POST_SYSCALL(getuid)(long long res) { /* Nothing to do */ } +PRE_SYSCALL(geteuid)(void) { /* Nothing to do */ } +POST_SYSCALL(geteuid)(long long res) { /* Nothing to do */ } +PRE_SYSCALL(ptrace) +(long long req_, long long pid_, void *addr_, long long data_) { + if (req_ == ptrace_pt_io) { + struct __sanitizer_ptrace_io_desc *addr = + (struct __sanitizer_ptrace_io_desc *)addr_; + PRE_READ(addr, struct_ptrace_ptrace_io_desc_struct_sz); + if (addr->piod_op == ptrace_piod_write_d || + addr->piod_op == ptrace_piod_write_i) { + PRE_READ(addr->piod_addr, addr->piod_len); + } + if (addr->piod_op == ptrace_piod_read_d || + addr->piod_op == ptrace_piod_read_i || + addr->piod_op == ptrace_piod_read_auxv) { + PRE_WRITE(addr->piod_addr, addr->piod_len); + } + } else if (req_ == ptrace_pt_lwpinfo) { + struct __sanitizer_ptrace_lwpinfo *addr = + (struct __sanitizer_ptrace_lwpinfo *)addr_; + PRE_READ(&addr->pl_lwpid, sizeof(__sanitizer_lwpid_t)); + PRE_WRITE(addr, struct_ptrace_ptrace_lwpinfo_struct_sz); + } else if (req_ == ptrace_pt_set_event_mask) { + PRE_READ(addr_, struct_ptrace_ptrace_event_struct_sz); + } else if (req_ == ptrace_pt_get_event_mask) { + PRE_WRITE(addr_, struct_ptrace_ptrace_event_struct_sz); + } else if (req_ == ptrace_pt_set_siginfo) { + PRE_READ(addr_, struct_ptrace_ptrace_siginfo_struct_sz); + } else if (req_ == ptrace_pt_get_siginfo) { + PRE_WRITE(addr_, struct_ptrace_ptrace_siginfo_struct_sz); + } else if (req_ == ptrace_pt_setregs) { + PRE_READ(addr_, struct_ptrace_reg_struct_sz); + } else if (req_ == ptrace_pt_getregs) { + PRE_WRITE(addr_, struct_ptrace_reg_struct_sz); + } else if (req_ == ptrace_pt_setfpregs) { + PRE_READ(addr_, struct_ptrace_fpreg_struct_sz); + } else if (req_ == ptrace_pt_getfpregs) { + PRE_WRITE(addr_, struct_ptrace_fpreg_struct_sz); + } else if (req_ == ptrace_pt_setdbregs) { + PRE_READ(addr_, struct_ptrace_dbreg_struct_sz); + } else if (req_ == ptrace_pt_getdbregs) { + PRE_WRITE(addr_, struct_ptrace_dbreg_struct_sz); + } +} +POST_SYSCALL(ptrace) +(long long res, long long req_, long long pid_, void *addr_, long long data_) { + if (res == 0) { + if (req_ == ptrace_pt_io) { + struct __sanitizer_ptrace_io_desc *addr = + (struct __sanitizer_ptrace_io_desc *)addr_; + POST_READ(addr, struct_ptrace_ptrace_io_desc_struct_sz); + if (addr->piod_op == ptrace_piod_write_d || + addr->piod_op == ptrace_piod_write_i) { + POST_READ(addr->piod_addr, addr->piod_len); + } + if (addr->piod_op == ptrace_piod_read_d || + addr->piod_op == ptrace_piod_read_i || + addr->piod_op == ptrace_piod_read_auxv) { + POST_WRITE(addr->piod_addr, addr->piod_len); + } + } else if (req_ == ptrace_pt_lwpinfo) { + struct __sanitizer_ptrace_lwpinfo *addr = + (struct __sanitizer_ptrace_lwpinfo *)addr_; + POST_READ(&addr->pl_lwpid, sizeof(__sanitizer_lwpid_t)); + POST_WRITE(addr, struct_ptrace_ptrace_lwpinfo_struct_sz); + } else if (req_ == ptrace_pt_set_event_mask) { + POST_READ(addr_, struct_ptrace_ptrace_event_struct_sz); + } else if (req_ == ptrace_pt_get_event_mask) { + POST_WRITE(addr_, struct_ptrace_ptrace_event_struct_sz); + } else if (req_ == ptrace_pt_set_siginfo) { + POST_READ(addr_, struct_ptrace_ptrace_siginfo_struct_sz); + } else if (req_ == ptrace_pt_get_siginfo) { + POST_WRITE(addr_, struct_ptrace_ptrace_siginfo_struct_sz); + } else if (req_ == ptrace_pt_setregs) { + POST_READ(addr_, struct_ptrace_reg_struct_sz); + } else if (req_ == ptrace_pt_getregs) { + POST_WRITE(addr_, struct_ptrace_reg_struct_sz); + } else if (req_ == ptrace_pt_setfpregs) { + POST_READ(addr_, struct_ptrace_fpreg_struct_sz); + } else if (req_ == ptrace_pt_getfpregs) { + POST_WRITE(addr_, struct_ptrace_fpreg_struct_sz); + } else if (req_ == ptrace_pt_setdbregs) { + POST_READ(addr_, struct_ptrace_dbreg_struct_sz); + } else if (req_ == ptrace_pt_getdbregs) { + POST_WRITE(addr_, struct_ptrace_dbreg_struct_sz); + } + } +} +PRE_SYSCALL(recvmsg)(long long s_, void *msg_, long long flags_) { + PRE_WRITE(msg_, sizeof(__sanitizer_msghdr)); +} +POST_SYSCALL(recvmsg) +(long long res, long long s_, void *msg_, long long flags_) { + if (res > 0) { + POST_WRITE(msg_, sizeof(__sanitizer_msghdr)); + } +} +PRE_SYSCALL(sendmsg)(long long s_, void *msg_, long long flags_) { + PRE_READ(msg_, sizeof(__sanitizer_msghdr)); +} +POST_SYSCALL(sendmsg) +(long long res, long long s_, void *msg_, long long flags_) { + if (res > 0) { + POST_READ(msg_, sizeof(__sanitizer_msghdr)); + } +} +PRE_SYSCALL(recvfrom) +(long long s_, void *buf_, long long len_, long long flags_, void *from_, + void *fromlenaddr_) { + PRE_WRITE(buf_, len_); + PRE_WRITE(from_, struct_sockaddr_sz); + PRE_WRITE(fromlenaddr_, sizeof(__sanitizer_socklen_t)); +} +POST_SYSCALL(recvfrom) +(long long res, long long s_, void *buf_, long long len_, long long flags_, + void *from_, void *fromlenaddr_) { + if (res >= 0) { + POST_WRITE(buf_, res); + POST_WRITE(from_, struct_sockaddr_sz); + POST_WRITE(fromlenaddr_, sizeof(__sanitizer_socklen_t)); + } +} +PRE_SYSCALL(accept)(long long s_, void *name_, void *anamelen_) { + PRE_WRITE(name_, struct_sockaddr_sz); + PRE_WRITE(anamelen_, sizeof(__sanitizer_socklen_t)); +} +POST_SYSCALL(accept) +(long long res, long long s_, void *name_, void *anamelen_) { + if (res == 0) { + POST_WRITE(name_, struct_sockaddr_sz); + POST_WRITE(anamelen_, sizeof(__sanitizer_socklen_t)); + } +} +PRE_SYSCALL(getpeername)(long long fdes_, void *asa_, void *alen_) { + PRE_WRITE(asa_, struct_sockaddr_sz); + PRE_WRITE(alen_, sizeof(__sanitizer_socklen_t)); +} +POST_SYSCALL(getpeername) +(long long res, long long fdes_, void *asa_, void *alen_) { + if (res == 0) { + POST_WRITE(asa_, struct_sockaddr_sz); + POST_WRITE(alen_, sizeof(__sanitizer_socklen_t)); + } +} +PRE_SYSCALL(getsockname)(long long fdes_, void *asa_, void *alen_) { + PRE_WRITE(asa_, struct_sockaddr_sz); + PRE_WRITE(alen_, sizeof(__sanitizer_socklen_t)); +} +POST_SYSCALL(getsockname) +(long long res, long long fdes_, void *asa_, void *alen_) { + if (res == 0) { + POST_WRITE(asa_, struct_sockaddr_sz); + POST_WRITE(alen_, sizeof(__sanitizer_socklen_t)); + } +} +PRE_SYSCALL(access)(void *path_, long long flags_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(access)(long long res, void *path_, long long flags_) { + if (res == 0) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(chflags)(void *path_, long long flags_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(chflags)(long long res, void *path_, long long flags_) { + if (res == 0) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(fchflags)(long long fd_, long long flags_) { /* Nothing to do */ } +POST_SYSCALL(fchflags)(long long res, long long fd_, long long flags_) { + /* Nothing to do */ +} +PRE_SYSCALL(sync)(void) { /* Nothing to do */ } +POST_SYSCALL(sync)(long long res) { /* Nothing to do */ } +PRE_SYSCALL(kill)(long long pid_, long long signum_) { /* Nothing to do */ } +POST_SYSCALL(kill)(long long res, long long pid_, long long signum_) { + /* Nothing to do */ +} +PRE_SYSCALL(compat_43_stat43)(void *path_, void *ub_) { /* TODO */ } +POST_SYSCALL(compat_43_stat43)(long long res, void *path_, void *ub_) { + /* TODO */ +} +PRE_SYSCALL(getppid)(void) { /* Nothing to do */ } +POST_SYSCALL(getppid)(long long res) { /* Nothing to do */ } +PRE_SYSCALL(compat_43_lstat43)(void *path_, void *ub_) { /* TODO */ } +POST_SYSCALL(compat_43_lstat43)(long long res, void *path_, void *ub_) { + /* TODO */ +} +PRE_SYSCALL(dup)(long long fd_) { /* Nothing to do */ } +POST_SYSCALL(dup)(long long res, long long fd_) { /* Nothing to do */ } +PRE_SYSCALL(pipe)(void) { + /* pipe returns two descriptors through two returned values */ +} +POST_SYSCALL(pipe)(long long res) { + /* pipe returns two descriptors through two returned values */ +} +PRE_SYSCALL(getegid)(void) { /* Nothing to do */ } +POST_SYSCALL(getegid)(long long res) { /* Nothing to do */ } +PRE_SYSCALL(profil) +(void *samples_, long long size_, long long offset_, long long scale_) { + if (samples_) { + PRE_WRITE(samples_, size_); + } +} +POST_SYSCALL(profil) +(long long res, void *samples_, long long size_, long long offset_, + long long scale_) { + if (res == 0) { + if (samples_) { + POST_WRITE(samples_, size_); + } + } +} +PRE_SYSCALL(ktrace) +(void *fname_, long long ops_, long long facs_, long long pid_) { + const char *fname = (const char *)fname_; + if (fname) { + PRE_READ(fname, __sanitizer::internal_strlen(fname) + 1); + } +} +POST_SYSCALL(ktrace) +(long long res, void *fname_, long long ops_, long long facs_, long long pid_) { + const char *fname = (const char *)fname_; + if (res == 0) { + if (fname) { + POST_READ(fname, __sanitizer::internal_strlen(fname) + 1); + } + } +} +PRE_SYSCALL(compat_13_sigaction13)(long long signum_, void *nsa_, void *osa_) { + /* TODO */ +} +POST_SYSCALL(compat_13_sigaction13) +(long long res, long long signum_, void *nsa_, void *osa_) { + /* TODO */ +} +PRE_SYSCALL(getgid)(void) { /* Nothing to do */ } +POST_SYSCALL(getgid)(long long res) { /* Nothing to do */ } +PRE_SYSCALL(compat_13_sigprocmask13)(long long how_, long long mask_) { + /* TODO */ +} +POST_SYSCALL(compat_13_sigprocmask13) +(long long res, long long how_, long long mask_) { + /* TODO */ +} +PRE_SYSCALL(__getlogin)(void *namebuf_, long long namelen_) { + if (namebuf_) { + PRE_WRITE(namebuf_, namelen_); + } +} +POST_SYSCALL(__getlogin)(long long res, void *namebuf_, long long namelen_) { + if (res == 0) { + if (namebuf_) { + POST_WRITE(namebuf_, namelen_); + } + } +} +PRE_SYSCALL(__setlogin)(void *namebuf_) { + const char *namebuf = (const char *)namebuf_; + if (namebuf) { + PRE_READ(namebuf, __sanitizer::internal_strlen(namebuf) + 1); + } +} +POST_SYSCALL(__setlogin)(long long res, void *namebuf_) { + if (res == 0) { + const char *namebuf = (const char *)namebuf_; + if (namebuf) { + POST_READ(namebuf, __sanitizer::internal_strlen(namebuf) + 1); + } + } +} +PRE_SYSCALL(acct)(void *path_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(acct)(long long res, void *path_) { + if (res == 0) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(compat_13_sigpending13)(void) { /* TODO */ } +POST_SYSCALL(compat_13_sigpending13)(long long res) { /* TODO */ } +PRE_SYSCALL(compat_13_sigaltstack13)(void *nss_, void *oss_) { /* TODO */ } +POST_SYSCALL(compat_13_sigaltstack13)(long long res, void *nss_, void *oss_) { + /* TODO */ +} +PRE_SYSCALL(ioctl)(long long fd_, long long com_, void *data_) { + /* Nothing to do */ +} +POST_SYSCALL(ioctl)(long long res, long long fd_, long long com_, void *data_) { + /* Nothing to do */ +} +PRE_SYSCALL(compat_12_oreboot)(long long opt_) { /* TODO */ } +POST_SYSCALL(compat_12_oreboot)(long long res, long long opt_) { /* TODO */ } +PRE_SYSCALL(revoke)(void *path_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(revoke)(long long res, void *path_) { + if (res == 0) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(symlink)(void *path_, void *link_) { + const char *path = (const char *)path_; + const char *link = (const char *)link_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } + if (link) { + PRE_READ(link, __sanitizer::internal_strlen(link) + 1); + } +} +POST_SYSCALL(symlink)(long long res, void *path_, void *link_) { + if (res == 0) { + const char *path = (const char *)path_; + const char *link = (const char *)link_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + if (link) { + POST_READ(link, __sanitizer::internal_strlen(link) + 1); + } + } +} +PRE_SYSCALL(readlink)(void *path_, void *buf_, long long count_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } + if (buf_) { + PRE_WRITE(buf_, count_); + } +} +POST_SYSCALL(readlink) +(long long res, void *path_, void *buf_, long long count_) { + if (res > 0) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + if (buf_) { + PRE_WRITE(buf_, res); + } + } +} +PRE_SYSCALL(execve)(void *path_, void *argp_, void *envp_) { + const char *path = (const char *)path_; + char **argp = (char **)argp_; + char **envp = (char **)envp_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } + if (argp && argp[0]) { + char *a = argp[0]; + while (a++) { + PRE_READ(a, __sanitizer::internal_strlen(a) + 1); + } + } + if (envp && envp[0]) { + char *e = envp[0]; + while (e++) { + PRE_READ(e, __sanitizer::internal_strlen(e) + 1); + } + } +} +POST_SYSCALL(execve)(long long res, void *path_, void *argp_, void *envp_) { + /* If we are here, something went wrong */ + const char *path = (const char *)path_; + char **argp = (char **)argp_; + char **envp = (char **)envp_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + if (argp && argp[0]) { + char *a = argp[0]; + while (a++) { + POST_READ(a, __sanitizer::internal_strlen(a) + 1); + } + } + if (envp && envp[0]) { + char *e = envp[0]; + while (e++) { + POST_READ(e, __sanitizer::internal_strlen(e) + 1); + } + } +} +PRE_SYSCALL(umask)(long long newmask_) { /* Nothing to do */ } +POST_SYSCALL(umask)(long long res, long long newmask_) { /* Nothing to do */ } +PRE_SYSCALL(chroot)(void *path_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(chroot)(long long res, void *path_) { + if (res == 0) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(compat_43_fstat43)(long long fd_, void *sb_) { /* TODO */ } +POST_SYSCALL(compat_43_fstat43)(long long res, long long fd_, void *sb_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_ogetkerninfo) +(long long op_, void *where_, void *size_, long long arg_) { + /* TODO */ +} +POST_SYSCALL(compat_43_ogetkerninfo) +(long long res, long long op_, void *where_, void *size_, long long arg_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_ogetpagesize)(void) { /* TODO */ } +POST_SYSCALL(compat_43_ogetpagesize)(long long res) { /* TODO */ } +PRE_SYSCALL(compat_12_msync)(void *addr_, long long len_) { /* TODO */ } +POST_SYSCALL(compat_12_msync)(long long res, void *addr_, long long len_) { + /* TODO */ +} +PRE_SYSCALL(vfork)(void) { /* Nothing to do */ } +POST_SYSCALL(vfork)(long long res) { /* Nothing to do */ } +/* syscall 67 has been skipped */ +/* syscall 68 has been skipped */ +/* syscall 69 has been skipped */ +/* syscall 70 has been skipped */ +PRE_SYSCALL(compat_43_ommap) +(void *addr_, long long len_, long long prot_, long long flags_, long long fd_, + long long pos_) { + /* TODO */ +} +POST_SYSCALL(compat_43_ommap) +(long long res, void *addr_, long long len_, long long prot_, long long flags_, + long long fd_, long long pos_) { + /* TODO */ +} +PRE_SYSCALL(vadvise)(long long anom_) { /* Nothing to do */ } +POST_SYSCALL(vadvise)(long long res, long long anom_) { /* Nothing to do */ } +PRE_SYSCALL(munmap)(void *addr_, long long len_) { /* Nothing to do */ } +POST_SYSCALL(munmap)(long long res, void *addr_, long long len_) { + /* Nothing to do */ +} +PRE_SYSCALL(mprotect)(void *addr_, long long len_, long long prot_) { + /* Nothing to do */ +} +POST_SYSCALL(mprotect) +(long long res, void *addr_, long long len_, long long prot_) { + /* Nothing to do */ +} +PRE_SYSCALL(madvise)(void *addr_, long long len_, long long behav_) { + /* Nothing to do */ +} +POST_SYSCALL(madvise) +(long long res, void *addr_, long long len_, long long behav_) { + /* Nothing to do */ +} +/* syscall 76 has been skipped */ +/* syscall 77 has been skipped */ +PRE_SYSCALL(mincore)(void *addr_, long long len_, void *vec_) { + /* Nothing to do */ +} +POST_SYSCALL(mincore)(long long res, void *addr_, long long len_, void *vec_) { + /* Nothing to do */ +} +PRE_SYSCALL(getgroups)(long long gidsetsize_, void *gidset_) { + unsigned int *gidset = (unsigned int *)gidset_; + if (gidset) { + PRE_WRITE(gidset, sizeof(*gidset) * gidsetsize_); + } +} +POST_SYSCALL(getgroups)(long long res, long long gidsetsize_, void *gidset_) { + if (res == 0) { + unsigned int *gidset = (unsigned int *)gidset_; + if (gidset) { + POST_WRITE(gidset, sizeof(*gidset) * gidsetsize_); + } + } +} +PRE_SYSCALL(setgroups)(long long gidsetsize_, void *gidset_) { + unsigned int *gidset = (unsigned int *)gidset_; + if (gidset) { + PRE_READ(gidset, sizeof(*gidset) * gidsetsize_); + } +} +POST_SYSCALL(setgroups)(long long res, long long gidsetsize_, void *gidset_) { + if (res == 0) { + unsigned int *gidset = (unsigned int *)gidset_; + if (gidset) { + POST_READ(gidset, sizeof(*gidset) * gidsetsize_); + } + } +} +PRE_SYSCALL(getpgrp)(void) { /* Nothing to do */ } +POST_SYSCALL(getpgrp)(long long res) { /* Nothing to do */ } +PRE_SYSCALL(setpgid)(long long pid_, long long pgid_) { /* Nothing to do */ } +POST_SYSCALL(setpgid)(long long res, long long pid_, long long pgid_) { + /* Nothing to do */ +} +PRE_SYSCALL(compat_50_setitimer)(long long which_, void *itv_, void *oitv_) { + /* TODO */ +} +POST_SYSCALL(compat_50_setitimer) +(long long res, long long which_, void *itv_, void *oitv_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_owait)(void) { /* TODO */ } +POST_SYSCALL(compat_43_owait)(long long res) { /* TODO */ } +PRE_SYSCALL(compat_12_oswapon)(void *name_) { /* TODO */ } +POST_SYSCALL(compat_12_oswapon)(long long res, void *name_) { /* TODO */ } +PRE_SYSCALL(compat_50_getitimer)(long long which_, void *itv_) { /* TODO */ } +POST_SYSCALL(compat_50_getitimer)(long long res, long long which_, void *itv_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_ogethostname)(void *hostname_, long long len_) { + /* TODO */ +} +POST_SYSCALL(compat_43_ogethostname) +(long long res, void *hostname_, long long len_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_osethostname)(void *hostname_, long long len_) { + /* TODO */ +} +POST_SYSCALL(compat_43_osethostname) +(long long res, void *hostname_, long long len_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_ogetdtablesize)(void) { /* TODO */ } +POST_SYSCALL(compat_43_ogetdtablesize)(long long res) { /* TODO */ } +PRE_SYSCALL(dup2)(long long from_, long long to_) { /* Nothing to do */ } +POST_SYSCALL(dup2)(long long res, long long from_, long long to_) { + /* Nothing to do */ +} +/* syscall 91 has been skipped */ +PRE_SYSCALL(fcntl)(long long fd_, long long cmd_, void *arg_) { + /* Nothing to do */ +} +POST_SYSCALL(fcntl)(long long res, long long fd_, long long cmd_, void *arg_) { + /* Nothing to do */ +} +PRE_SYSCALL(compat_50_select) +(long long nd_, void *in_, void *ou_, void *ex_, void *tv_) { + /* TODO */ +} +POST_SYSCALL(compat_50_select) +(long long res, long long nd_, void *in_, void *ou_, void *ex_, void *tv_) { + /* TODO */ +} +/* syscall 94 has been skipped */ +PRE_SYSCALL(fsync)(long long fd_) { /* Nothing to do */ } +POST_SYSCALL(fsync)(long long res, long long fd_) { /* Nothing to do */ } +PRE_SYSCALL(setpriority)(long long which_, long long who_, long long prio_) { + /* Nothing to do */ +} +POST_SYSCALL(setpriority) +(long long res, long long which_, long long who_, long long prio_) { + /* Nothing to do */ +} +PRE_SYSCALL(compat_30_socket) +(long long domain_, long long type_, long long protocol_) { + /* TODO */ +} +POST_SYSCALL(compat_30_socket) +(long long res, long long domain_, long long type_, long long protocol_) { + /* TODO */ +} +PRE_SYSCALL(connect)(long long s_, void *name_, long long namelen_) { + PRE_READ(name_, namelen_); +} +POST_SYSCALL(connect) +(long long res, long long s_, void *name_, long long namelen_) { + if (res == 0) { + POST_READ(name_, namelen_); + } +} +PRE_SYSCALL(compat_43_oaccept)(long long s_, void *name_, void *anamelen_) { + /* TODO */ +} +POST_SYSCALL(compat_43_oaccept) +(long long res, long long s_, void *name_, void *anamelen_) { + /* TODO */ +} +PRE_SYSCALL(getpriority)(long long which_, long long who_) { + /* Nothing to do */ +} +POST_SYSCALL(getpriority)(long long res, long long which_, long long who_) { + /* Nothing to do */ +} +PRE_SYSCALL(compat_43_osend) +(long long s_, void *buf_, long long len_, long long flags_) { + /* TODO */ +} +POST_SYSCALL(compat_43_osend) +(long long res, long long s_, void *buf_, long long len_, long long flags_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_orecv) +(long long s_, void *buf_, long long len_, long long flags_) { + /* TODO */ +} +POST_SYSCALL(compat_43_orecv) +(long long res, long long s_, void *buf_, long long len_, long long flags_) { + /* TODO */ +} +PRE_SYSCALL(compat_13_sigreturn13)(void *sigcntxp_) { /* TODO */ } +POST_SYSCALL(compat_13_sigreturn13)(long long res, void *sigcntxp_) { + /* TODO */ +} +PRE_SYSCALL(bind)(long long s_, void *name_, long long namelen_) { + PRE_READ(name_, namelen_); +} +POST_SYSCALL(bind) +(long long res, long long s_, void *name_, long long namelen_) { + if (res == 0) { + PRE_READ(name_, namelen_); + } +} +PRE_SYSCALL(setsockopt) +(long long s_, long long level_, long long name_, void *val_, + long long valsize_) { + if (val_) { + PRE_READ(val_, valsize_); + } +} +POST_SYSCALL(setsockopt) +(long long res, long long s_, long long level_, long long name_, void *val_, + long long valsize_) { + if (res == 0) { + if (val_) { + POST_READ(val_, valsize_); + } + } +} +PRE_SYSCALL(listen)(long long s_, long long backlog_) { /* Nothing to do */ } +POST_SYSCALL(listen)(long long res, long long s_, long long backlog_) { + /* Nothing to do */ +} +/* syscall 107 has been skipped */ +PRE_SYSCALL(compat_43_osigvec)(long long signum_, void *nsv_, void *osv_) { + /* TODO */ +} +POST_SYSCALL(compat_43_osigvec) +(long long res, long long signum_, void *nsv_, void *osv_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_osigblock)(long long mask_) { /* TODO */ } +POST_SYSCALL(compat_43_osigblock)(long long res, long long mask_) { /* TODO */ } +PRE_SYSCALL(compat_43_osigsetmask)(long long mask_) { /* TODO */ } +POST_SYSCALL(compat_43_osigsetmask)(long long res, long long mask_) { + /* TODO */ +} +PRE_SYSCALL(compat_13_sigsuspend13)(long long mask_) { /* TODO */ } +POST_SYSCALL(compat_13_sigsuspend13)(long long res, long long mask_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_osigstack)(void *nss_, void *oss_) { /* TODO */ } +POST_SYSCALL(compat_43_osigstack)(long long res, void *nss_, void *oss_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_orecvmsg)(long long s_, void *msg_, long long flags_) { + /* TODO */ +} +POST_SYSCALL(compat_43_orecvmsg) +(long long res, long long s_, void *msg_, long long flags_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_osendmsg)(long long s_, void *msg_, long long flags_) { + /* TODO */ +} +POST_SYSCALL(compat_43_osendmsg) +(long long res, long long s_, void *msg_, long long flags_) { + /* TODO */ +} +/* syscall 115 has been skipped */ +PRE_SYSCALL(compat_50_gettimeofday)(void *tp_, void *tzp_) { /* TODO */ } +POST_SYSCALL(compat_50_gettimeofday)(long long res, void *tp_, void *tzp_) { + /* TODO */ +} +PRE_SYSCALL(compat_50_getrusage)(long long who_, void *rusage_) { /* TODO */ } +POST_SYSCALL(compat_50_getrusage) +(long long res, long long who_, void *rusage_) { + /* TODO */ +} +PRE_SYSCALL(getsockopt) +(long long s_, long long level_, long long name_, void *val_, void *avalsize_) { + /* TODO */ +} +POST_SYSCALL(getsockopt) +(long long res, long long s_, long long level_, long long name_, void *val_, + void *avalsize_) { + /* TODO */ +} +/* syscall 119 has been skipped */ +PRE_SYSCALL(readv)(long long fd_, void *iovp_, long long iovcnt_) { + struct __sanitizer_iovec *iovp = (struct __sanitizer_iovec *)iovp_; + int i; + if (iovp) { + PRE_READ(iovp, sizeof(struct __sanitizer_iovec) * iovcnt_); + for (i = 0; i < iovcnt_; i++) { + PRE_WRITE(iovp[i].iov_base, iovp[i].iov_len); + } + } +} +POST_SYSCALL(readv) +(long long res, long long fd_, void *iovp_, long long iovcnt_) { + struct __sanitizer_iovec *iovp = (struct __sanitizer_iovec *)iovp_; + int i; + uptr m, n = res; + if (res > 0) { + if (iovp) { + POST_READ(iovp, sizeof(struct __sanitizer_iovec) * iovcnt_); + for (i = 0; i < iovcnt_ && n > 0; i++) { + m = n > iovp[i].iov_len ? iovp[i].iov_len : n; + POST_WRITE(iovp[i].iov_base, m); + n -= m; + } + } + } +} +PRE_SYSCALL(writev)(long long fd_, void *iovp_, long long iovcnt_) { + struct __sanitizer_iovec *iovp = (struct __sanitizer_iovec *)iovp_; + int i; + if (iovp) { + PRE_READ(iovp, sizeof(struct __sanitizer_iovec) * iovcnt_); + for (i = 0; i < iovcnt_; i++) { + PRE_READ(iovp[i].iov_base, iovp[i].iov_len); + } + } +} +POST_SYSCALL(writev) +(long long res, long long fd_, void *iovp_, long long iovcnt_) { + struct __sanitizer_iovec *iovp = (struct __sanitizer_iovec *)iovp_; + int i; + uptr m, n = res; + if (res > 0) { + if (iovp) { + POST_READ(iovp, sizeof(struct __sanitizer_iovec) * iovcnt_); + for (i = 0; i < iovcnt_ && n > 0; i++) { + m = n > iovp[i].iov_len ? iovp[i].iov_len : n; + POST_READ(iovp[i].iov_base, m); + n -= m; + } + } + } +} +PRE_SYSCALL(compat_50_settimeofday)(void *tv_, void *tzp_) { /* TODO */ } +POST_SYSCALL(compat_50_settimeofday)(long long res, void *tv_, void *tzp_) { + /* TODO */ +} +PRE_SYSCALL(fchown)(long long fd_, long long uid_, long long gid_) { + /* Nothing to do */ +} +POST_SYSCALL(fchown) +(long long res, long long fd_, long long uid_, long long gid_) { + /* Nothing to do */ +} +PRE_SYSCALL(fchmod)(long long fd_, long long mode_) { /* Nothing to do */ } +POST_SYSCALL(fchmod)(long long res, long long fd_, long long mode_) { + /* Nothing to do */ +} +PRE_SYSCALL(compat_43_orecvfrom) +(long long s_, void *buf_, long long len_, long long flags_, void *from_, + void *fromlenaddr_) { + /* TODO */ +} +POST_SYSCALL(compat_43_orecvfrom) +(long long res, long long s_, void *buf_, long long len_, long long flags_, + void *from_, void *fromlenaddr_) { + /* TODO */ +} +PRE_SYSCALL(setreuid)(long long ruid_, long long euid_) { /* Nothing to do */ } +POST_SYSCALL(setreuid)(long long res, long long ruid_, long long euid_) { + /* Nothing to do */ +} +PRE_SYSCALL(setregid)(long long rgid_, long long egid_) { /* Nothing to do */ } +POST_SYSCALL(setregid)(long long res, long long rgid_, long long egid_) { + /* Nothing to do */ +} +PRE_SYSCALL(rename)(void *from_, void *to_) { + const char *from = (const char *)from_; + const char *to = (const char *)to_; + if (from) { + PRE_READ(from, __sanitizer::internal_strlen(from) + 1); + } + if (to) { + PRE_READ(to, __sanitizer::internal_strlen(to) + 1); + } +} +POST_SYSCALL(rename)(long long res, void *from_, void *to_) { + if (res == 0) { + const char *from = (const char *)from_; + const char *to = (const char *)to_; + if (from) { + POST_READ(from, __sanitizer::internal_strlen(from) + 1); + } + if (to) { + POST_READ(to, __sanitizer::internal_strlen(to) + 1); + } + } +} +PRE_SYSCALL(compat_43_otruncate)(void *path_, long long length_) { /* TODO */ } +POST_SYSCALL(compat_43_otruncate) +(long long res, void *path_, long long length_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_oftruncate)(long long fd_, long long length_) { + /* TODO */ +} +POST_SYSCALL(compat_43_oftruncate) +(long long res, long long fd_, long long length_) { + /* TODO */ +} +PRE_SYSCALL(flock)(long long fd_, long long how_) { /* Nothing to do */ } +POST_SYSCALL(flock)(long long res, long long fd_, long long how_) { + /* Nothing to do */ +} +PRE_SYSCALL(mkfifo)(void *path_, long long mode_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(mkfifo)(long long res, void *path_, long long mode_) { + if (res == 0) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(sendto) +(long long s_, void *buf_, long long len_, long long flags_, void *to_, + long long tolen_) { + PRE_READ(buf_, len_); + PRE_READ(to_, tolen_); +} +POST_SYSCALL(sendto) +(long long res, long long s_, void *buf_, long long len_, long long flags_, + void *to_, long long tolen_) { + if (res >= 0) { + POST_READ(buf_, len_); + POST_READ(to_, tolen_); + } +} +PRE_SYSCALL(shutdown)(long long s_, long long how_) { /* Nothing to do */ } +POST_SYSCALL(shutdown)(long long res, long long s_, long long how_) { + /* Nothing to do */ +} +PRE_SYSCALL(socketpair) +(long long domain_, long long type_, long long protocol_, void *rsv_) { + PRE_WRITE(rsv_, 2 * sizeof(int)); +} +POST_SYSCALL(socketpair) +(long long res, long long domain_, long long type_, long long protocol_, + void *rsv_) { + if (res == 0) { + POST_WRITE(rsv_, 2 * sizeof(int)); + } +} +PRE_SYSCALL(mkdir)(void *path_, long long mode_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(mkdir)(long long res, void *path_, long long mode_) { + if (res == 0) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(rmdir)(void *path_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(rmdir)(long long res, void *path_) { + if (res == 0) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(compat_50_utimes)(void *path_, void *tptr_) { /* TODO */ } +POST_SYSCALL(compat_50_utimes)(long long res, void *path_, void *tptr_) { + /* TODO */ +} +/* syscall 139 has been skipped */ +PRE_SYSCALL(compat_50_adjtime)(void *delta_, void *olddelta_) { /* TODO */ } +POST_SYSCALL(compat_50_adjtime)(long long res, void *delta_, void *olddelta_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_ogetpeername)(long long fdes_, void *asa_, void *alen_) { + /* TODO */ +} +POST_SYSCALL(compat_43_ogetpeername) +(long long res, long long fdes_, void *asa_, void *alen_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_ogethostid)(void) { /* TODO */ } +POST_SYSCALL(compat_43_ogethostid)(long long res) { /* TODO */ } +PRE_SYSCALL(compat_43_osethostid)(long long hostid_) { /* TODO */ } +POST_SYSCALL(compat_43_osethostid)(long long res, long long hostid_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_ogetrlimit)(long long which_, void *rlp_) { /* TODO */ } +POST_SYSCALL(compat_43_ogetrlimit) +(long long res, long long which_, void *rlp_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_osetrlimit)(long long which_, void *rlp_) { /* TODO */ } +POST_SYSCALL(compat_43_osetrlimit) +(long long res, long long which_, void *rlp_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_okillpg)(long long pgid_, long long signum_) { + /* TODO */ +} +POST_SYSCALL(compat_43_okillpg) +(long long res, long long pgid_, long long signum_) { + /* TODO */ +} +PRE_SYSCALL(setsid)(void) { /* Nothing to do */ } +POST_SYSCALL(setsid)(long long res) { /* Nothing to do */ } +PRE_SYSCALL(compat_50_quotactl) +(void *path_, long long cmd_, long long uid_, void *arg_) { + /* TODO */ +} +POST_SYSCALL(compat_50_quotactl) +(long long res, void *path_, long long cmd_, long long uid_, void *arg_) { + /* TODO */ +} +PRE_SYSCALL(compat_43_oquota)(void) { /* TODO */ } +POST_SYSCALL(compat_43_oquota)(long long res) { /* TODO */ } +PRE_SYSCALL(compat_43_ogetsockname)(long long fdec_, void *asa_, void *alen_) { + /* TODO */ +} +POST_SYSCALL(compat_43_ogetsockname) +(long long res, long long fdec_, void *asa_, void *alen_) { + /* TODO */ +} +/* syscall 151 has been skipped */ +/* syscall 152 has been skipped */ +/* syscall 153 has been skipped */ +/* syscall 154 has been skipped */ +PRE_SYSCALL(nfssvc)(long long flag_, void *argp_) { /* Nothing to do */ } +POST_SYSCALL(nfssvc)(long long res, long long flag_, void *argp_) { + /* Nothing to do */ +} +PRE_SYSCALL(compat_43_ogetdirentries) +(long long fd_, void *buf_, long long count_, void *basep_) { + /* TODO */ +} +POST_SYSCALL(compat_43_ogetdirentries) +(long long res, long long fd_, void *buf_, long long count_, void *basep_) { + /* TODO */ +} +PRE_SYSCALL(compat_20_statfs)(void *path_, void *buf_) { /* TODO */ } +POST_SYSCALL(compat_20_statfs)(long long res, void *path_, void *buf_) { + /* TODO */ +} +PRE_SYSCALL(compat_20_fstatfs)(long long fd_, void *buf_) { /* TODO */ } +POST_SYSCALL(compat_20_fstatfs)(long long res, long long fd_, void *buf_) { + /* TODO */ +} +/* syscall 159 has been skipped */ +/* syscall 160 has been skipped */ +PRE_SYSCALL(compat_30_getfh)(void *fname_, void *fhp_) { /* TODO */ } +POST_SYSCALL(compat_30_getfh)(long long res, void *fname_, void *fhp_) { + /* TODO */ +} +PRE_SYSCALL(compat_09_ogetdomainname)(void *domainname_, long long len_) { + /* TODO */ +} +POST_SYSCALL(compat_09_ogetdomainname) +(long long res, void *domainname_, long long len_) { + /* TODO */ +} +PRE_SYSCALL(compat_09_osetdomainname)(void *domainname_, long long len_) { + /* TODO */ +} +POST_SYSCALL(compat_09_osetdomainname) +(long long res, void *domainname_, long long len_) { + /* TODO */ +} +PRE_SYSCALL(compat_09_ouname)(void *name_) { /* TODO */ } +POST_SYSCALL(compat_09_ouname)(long long res, void *name_) { /* TODO */ } +PRE_SYSCALL(sysarch)(long long op_, void *parms_) { /* TODO */ } +POST_SYSCALL(sysarch)(long long res, long long op_, void *parms_) { /* TODO */ } +/* syscall 166 has been skipped */ +/* syscall 167 has been skipped */ +/* syscall 168 has been skipped */ +#if !defined(_LP64) +PRE_SYSCALL(compat_10_osemsys) +(long long which_, long long a2_, long long a3_, long long a4_, long long a5_) { + /* TODO */ +} +POST_SYSCALL(compat_10_osemsys) +(long long res, long long which_, long long a2_, long long a3_, long long a4_, + long long a5_) { + /* TODO */ +} +#else +/* syscall 169 has been skipped */ +#endif +#if !defined(_LP64) +PRE_SYSCALL(compat_10_omsgsys) +(long long which_, long long a2_, long long a3_, long long a4_, long long a5_, + long long a6_) { + /* TODO */ +} +POST_SYSCALL(compat_10_omsgsys) +(long long res, long long which_, long long a2_, long long a3_, long long a4_, + long long a5_, long long a6_) { + /* TODO */ +} +#else +/* syscall 170 has been skipped */ +#endif +#if !defined(_LP64) +PRE_SYSCALL(compat_10_oshmsys) +(long long which_, long long a2_, long long a3_, long long a4_) { + /* TODO */ +} +POST_SYSCALL(compat_10_oshmsys) +(long long res, long long which_, long long a2_, long long a3_, long long a4_) { + /* TODO */ +} +#else +/* syscall 171 has been skipped */ +#endif +/* syscall 172 has been skipped */ +PRE_SYSCALL(pread) +(long long fd_, void *buf_, long long nbyte_, long long PAD_, + long long offset_) { + if (buf_) { + PRE_WRITE(buf_, nbyte_); + } +} +POST_SYSCALL(pread) +(long long res, long long fd_, void *buf_, long long nbyte_, long long PAD_, + long long offset_) { + if (res > 0) { + POST_WRITE(buf_, res); + } +} +PRE_SYSCALL(pwrite) +(long long fd_, void *buf_, long long nbyte_, long long PAD_, + long long offset_) { + if (buf_) { + PRE_READ(buf_, nbyte_); + } +} +POST_SYSCALL(pwrite) +(long long res, long long fd_, void *buf_, long long nbyte_, long long PAD_, + long long offset_) { + if (res > 0) { + POST_READ(buf_, res); + } +} +PRE_SYSCALL(compat_30_ntp_gettime)(void *ntvp_) { /* TODO */ } +POST_SYSCALL(compat_30_ntp_gettime)(long long res, void *ntvp_) { /* TODO */ } +#if defined(NTP) || !defined(_KERNEL_OPT) +PRE_SYSCALL(ntp_adjtime)(void *tp_) { /* Nothing to do */ } +POST_SYSCALL(ntp_adjtime)(long long res, void *tp_) { /* Nothing to do */ } +#else +/* syscall 176 has been skipped */ +#endif +/* syscall 177 has been skipped */ +/* syscall 178 has been skipped */ +/* syscall 179 has been skipped */ +/* syscall 180 has been skipped */ +PRE_SYSCALL(setgid)(long long gid_) { /* Nothing to do */ } +POST_SYSCALL(setgid)(long long res, long long gid_) { /* Nothing to do */ } +PRE_SYSCALL(setegid)(long long egid_) { /* Nothing to do */ } +POST_SYSCALL(setegid)(long long res, long long egid_) { /* Nothing to do */ } +PRE_SYSCALL(seteuid)(long long euid_) { /* Nothing to do */ } +POST_SYSCALL(seteuid)(long long res, long long euid_) { /* Nothing to do */ } +PRE_SYSCALL(lfs_bmapv)(void *fsidp_, void *blkiov_, long long blkcnt_) { + /* TODO */ +} +POST_SYSCALL(lfs_bmapv) +(long long res, void *fsidp_, void *blkiov_, long long blkcnt_) { + /* TODO */ +} +PRE_SYSCALL(lfs_markv)(void *fsidp_, void *blkiov_, long long blkcnt_) { + /* TODO */ +} +POST_SYSCALL(lfs_markv) +(long long res, void *fsidp_, void *blkiov_, long long blkcnt_) { + /* TODO */ +} +PRE_SYSCALL(lfs_segclean)(void *fsidp_, long long segment_) { /* TODO */ } +POST_SYSCALL(lfs_segclean)(long long res, void *fsidp_, long long segment_) { + /* TODO */ +} +PRE_SYSCALL(compat_50_lfs_segwait)(void *fsidp_, void *tv_) { /* TODO */ } +POST_SYSCALL(compat_50_lfs_segwait)(long long res, void *fsidp_, void *tv_) { + /* TODO */ +} +PRE_SYSCALL(compat_12_stat12)(void *path_, void *ub_) { /* TODO */ } +POST_SYSCALL(compat_12_stat12)(long long res, void *path_, void *ub_) { + /* TODO */ +} +PRE_SYSCALL(compat_12_fstat12)(long long fd_, void *sb_) { /* TODO */ } +POST_SYSCALL(compat_12_fstat12)(long long res, long long fd_, void *sb_) { + /* TODO */ +} +PRE_SYSCALL(compat_12_lstat12)(void *path_, void *ub_) { /* TODO */ } +POST_SYSCALL(compat_12_lstat12)(long long res, void *path_, void *ub_) { + /* TODO */ +} +PRE_SYSCALL(pathconf)(void *path_, long long name_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(pathconf)(long long res, void *path_, long long name_) { + if (res != -1) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +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(getrlimit)(long long which_, void *rlp_) { + PRE_WRITE(rlp_, struct_rlimit_sz); +} +POST_SYSCALL(getrlimit)(long long res, long long which_, void *rlp_) { + if (res == 0) { + POST_WRITE(rlp_, struct_rlimit_sz); + } +} +PRE_SYSCALL(setrlimit)(long long which_, void *rlp_) { + PRE_READ(rlp_, struct_rlimit_sz); +} +POST_SYSCALL(setrlimit)(long long res, long long which_, void *rlp_) { + if (res == 0) { + POST_READ(rlp_, struct_rlimit_sz); + } +} +PRE_SYSCALL(compat_12_getdirentries) +(long long fd_, void *buf_, long long count_, void *basep_) { + /* TODO */ +} +POST_SYSCALL(compat_12_getdirentries) +(long long res, long long fd_, void *buf_, long long count_, void *basep_) { + /* TODO */ +} +PRE_SYSCALL(mmap) +(void *addr_, long long len_, long long prot_, long long flags_, long long fd_, + long long PAD_, long long pos_) { + /* Nothing to do */ +} +POST_SYSCALL(mmap) +(long long res, void *addr_, long long len_, long long prot_, long long flags_, + long long fd_, long long PAD_, long long pos_) { + /* Nothing to do */ +} +PRE_SYSCALL(__syscall)(long long code_, long long args_[SYS_MAXSYSARGS]) { + /* Nothing to do */ +} +POST_SYSCALL(__syscall) +(long long res, long long code_, long long args_[SYS_MAXSYSARGS]) { + /* Nothing to do */ +} +PRE_SYSCALL(lseek) +(long long fd_, long long PAD_, long long offset_, long long whence_) { + /* Nothing to do */ +} +POST_SYSCALL(lseek) +(long long res, long long fd_, long long PAD_, long long offset_, + long long whence_) { + /* Nothing to do */ +} +PRE_SYSCALL(truncate)(void *path_, long long PAD_, long long length_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(truncate) +(long long res, void *path_, long long PAD_, long long length_) { + if (res == 0) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(ftruncate)(long long fd_, long long PAD_, long long length_) { + /* Nothing to do */ +} +POST_SYSCALL(ftruncate) +(long long res, long long fd_, long long PAD_, long long length_) { + /* Nothing to do */ +} +PRE_SYSCALL(__sysctl) +(void *name_, long long namelen_, void *oldv_, void *oldlenp_, void *newv_, + long long newlen_) { + const int *name = (const int *)name_; + if (name) { + PRE_READ(name, namelen_ * sizeof(*name)); + } + if (newv_) { + PRE_READ(name, newlen_); + } +} +POST_SYSCALL(__sysctl) +(long long res, void *name_, long long namelen_, void *oldv_, void *oldlenp_, + void *newv_, long long newlen_) { + if (res == 0) { + const int *name = (const int *)name_; + if (name) { + POST_READ(name, namelen_ * sizeof(*name)); + } + if (newv_) { + POST_READ(name, newlen_); + } + } +} +PRE_SYSCALL(mlock)(void *addr_, long long len_) { /* Nothing to do */ } +POST_SYSCALL(mlock)(long long res, void *addr_, long long len_) { + /* Nothing to do */ +} +PRE_SYSCALL(munlock)(void *addr_, long long len_) { /* Nothing to do */ } +POST_SYSCALL(munlock)(long long res, void *addr_, long long len_) { + /* Nothing to do */ +} +PRE_SYSCALL(undelete)(void *path_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(undelete)(long long res, void *path_) { + if (res == 0) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(compat_50_futimes)(long long fd_, void *tptr_) { /* TODO */ } +POST_SYSCALL(compat_50_futimes)(long long res, long long fd_, void *tptr_) { + /* TODO */ +} +PRE_SYSCALL(getpgid)(long long pid_) { /* Nothing to do */ } +POST_SYSCALL(getpgid)(long long res, long long pid_) { /* Nothing to do */ } +PRE_SYSCALL(reboot)(long long opt_, void *bootstr_) { + const char *bootstr = (const char *)bootstr_; + if (bootstr) { + PRE_READ(bootstr, __sanitizer::internal_strlen(bootstr) + 1); + } +} +POST_SYSCALL(reboot)(long long res, long long opt_, void *bootstr_) { + /* This call should never return */ + const char *bootstr = (const char *)bootstr_; + if (bootstr) { + POST_READ(bootstr, __sanitizer::internal_strlen(bootstr) + 1); + } +} +PRE_SYSCALL(poll)(void *fds_, long long nfds_, long long timeout_) { + /* Nothing to do */ +} +POST_SYSCALL(poll) +(long long res, void *fds_, long long nfds_, long long timeout_) { + /* Nothing to do */ +} +PRE_SYSCALL(afssys) +(long long id_, long long a1_, long long a2_, long long a3_, long long a4_, + long long a5_, long long a6_) { + /* TODO */ +} +POST_SYSCALL(afssys) +(long long res, long long id_, long long a1_, long long a2_, long long a3_, + long long a4_, long long a5_, long long a6_) { + /* TODO */ +} +/* syscall 211 has been skipped */ +/* syscall 212 has been skipped */ +/* syscall 213 has been skipped */ +/* syscall 214 has been skipped */ +/* syscall 215 has been skipped */ +/* syscall 216 has been skipped */ +/* syscall 217 has been skipped */ +/* syscall 218 has been skipped */ +/* syscall 219 has been skipped */ +PRE_SYSCALL(compat_14___semctl) +(long long semid_, long long semnum_, long long cmd_, void *arg_) { + /* TODO */ +} +POST_SYSCALL(compat_14___semctl) +(long long res, long long semid_, long long semnum_, long long cmd_, + void *arg_) { + /* TODO */ +} +PRE_SYSCALL(semget)(long long key_, long long nsems_, long long semflg_) { + /* Nothing to do */ +} +POST_SYSCALL(semget) +(long long res, long long key_, long long nsems_, long long semflg_) { + /* Nothing to do */ +} +PRE_SYSCALL(semop)(long long semid_, void *sops_, long long nsops_) { + if (sops_) { + PRE_READ(sops_, nsops_ * struct_sembuf_sz); + } +} +POST_SYSCALL(semop) +(long long res, long long semid_, void *sops_, long long nsops_) { + if (res == 0) { + if (sops_) { + POST_READ(sops_, nsops_ * struct_sembuf_sz); + } + } +} +PRE_SYSCALL(semconfig)(long long flag_) { /* Nothing to do */ } +POST_SYSCALL(semconfig)(long long res, long long flag_) { /* Nothing to do */ } +PRE_SYSCALL(compat_14_msgctl)(long long msqid_, long long cmd_, void *buf_) { + /* TODO */ +} +POST_SYSCALL(compat_14_msgctl) +(long long res, long long msqid_, long long cmd_, void *buf_) { + /* TODO */ +} +PRE_SYSCALL(msgget)(long long key_, long long msgflg_) { /* Nothing to do */ } +POST_SYSCALL(msgget)(long long res, long long key_, long long msgflg_) { + /* Nothing to do */ +} +PRE_SYSCALL(msgsnd) +(long long msqid_, void *msgp_, long long msgsz_, long long msgflg_) { + if (msgp_) { + PRE_READ(msgp_, msgsz_); + } +} +POST_SYSCALL(msgsnd) +(long long res, long long msqid_, void *msgp_, long long msgsz_, + long long msgflg_) { + if (res == 0) { + if (msgp_) { + POST_READ(msgp_, msgsz_); + } + } +} +PRE_SYSCALL(msgrcv) +(long long msqid_, void *msgp_, long long msgsz_, long long msgtyp_, + long long msgflg_) { + /* Nothing to do */ +} +POST_SYSCALL(msgrcv) +(long long res, long long msqid_, void *msgp_, long long msgsz_, + long long msgtyp_, long long msgflg_) { + /* Nothing to do */ +} +PRE_SYSCALL(shmat)(long long shmid_, void *shmaddr_, long long shmflg_) { + /* Nothing to do */ +} +POST_SYSCALL(shmat) +(long long res, long long shmid_, void *shmaddr_, long long shmflg_) { + /* Nothing to do */ +} +PRE_SYSCALL(compat_14_shmctl)(long long shmid_, long long cmd_, void *buf_) { + /* TODO */ +} +POST_SYSCALL(compat_14_shmctl) +(long long res, long long shmid_, long long cmd_, void *buf_) { + /* TODO */ +} +PRE_SYSCALL(shmdt)(void *shmaddr_) { /* Nothing to do */ } +POST_SYSCALL(shmdt)(long long res, void *shmaddr_) { /* Nothing to do */ } +PRE_SYSCALL(shmget)(long long key_, long long size_, long long shmflg_) { + /* Nothing to do */ +} +POST_SYSCALL(shmget) +(long long res, long long key_, long long size_, long long shmflg_) { + /* Nothing to do */ +} +PRE_SYSCALL(compat_50_clock_gettime)(long long clock_id_, void *tp_) { + /* TODO */ +} +POST_SYSCALL(compat_50_clock_gettime) +(long long res, long long clock_id_, void *tp_) { + /* TODO */ +} +PRE_SYSCALL(compat_50_clock_settime)(long long clock_id_, void *tp_) { + /* TODO */ +} +POST_SYSCALL(compat_50_clock_settime) +(long long res, long long clock_id_, void *tp_) { + /* TODO */ +} +PRE_SYSCALL(compat_50_clock_getres)(long long clock_id_, void *tp_) { + /* TODO */ +} +POST_SYSCALL(compat_50_clock_getres) +(long long res, long long clock_id_, void *tp_) { + /* TODO */ +} +PRE_SYSCALL(timer_create)(long long clock_id_, void *evp_, void *timerid_) { + /* Nothing to do */ +} +POST_SYSCALL(timer_create) +(long long res, long long clock_id_, void *evp_, void *timerid_) { + /* Nothing to do */ +} +PRE_SYSCALL(timer_delete)(long long timerid_) { /* Nothing to do */ } +POST_SYSCALL(timer_delete)(long long res, long long timerid_) { + /* Nothing to do */ +} +PRE_SYSCALL(compat_50_timer_settime) +(long long timerid_, long long flags_, void *value_, void *ovalue_) { + /* TODO */ +} +POST_SYSCALL(compat_50_timer_settime) +(long long res, long long timerid_, long long flags_, void *value_, + void *ovalue_) { + /* TODO */ +} +PRE_SYSCALL(compat_50_timer_gettime)(long long timerid_, void *value_) { + /* TODO */ +} +POST_SYSCALL(compat_50_timer_gettime) +(long long res, long long timerid_, void *value_) { + /* TODO */ +} +PRE_SYSCALL(timer_getoverrun)(long long timerid_) { /* Nothing to do */ } +POST_SYSCALL(timer_getoverrun)(long long res, long long timerid_) { + /* Nothing to do */ +} +PRE_SYSCALL(compat_50_nanosleep)(void *rqtp_, void *rmtp_) { /* TODO */ } +POST_SYSCALL(compat_50_nanosleep)(long long res, void *rqtp_, void *rmtp_) { + /* TODO */ +} +PRE_SYSCALL(fdatasync)(long long fd_) { /* Nothing to do */ } +POST_SYSCALL(fdatasync)(long long res, long long fd_) { /* Nothing to do */ } +PRE_SYSCALL(mlockall)(long long flags_) { /* Nothing to do */ } +POST_SYSCALL(mlockall)(long long res, long long flags_) { /* Nothing to do */ } +PRE_SYSCALL(munlockall)(void) { /* Nothing to do */ } +POST_SYSCALL(munlockall)(long long res) { /* Nothing to do */ } +PRE_SYSCALL(compat_50___sigtimedwait)(void *set_, void *info_, void *timeout_) { + /* TODO */ +} +POST_SYSCALL(compat_50___sigtimedwait) +(long long res, void *set_, void *info_, void *timeout_) { + /* TODO */ +} +PRE_SYSCALL(sigqueueinfo)(long long pid_, void *info_) { + if (info_) { + PRE_READ(info_, siginfo_t_sz); + } +} +POST_SYSCALL(sigqueueinfo)(long long res, long long pid_, void *info_) {} +PRE_SYSCALL(modctl)(long long cmd_, void *arg_) { /* TODO */ } +POST_SYSCALL(modctl)(long long res, long long cmd_, void *arg_) { /* TODO */ } +PRE_SYSCALL(_ksem_init)(long long value_, void *idp_) { /* Nothing to do */ } +POST_SYSCALL(_ksem_init)(long long res, long long value_, void *idp_) { + /* Nothing to do */ +} +PRE_SYSCALL(_ksem_open) +(void *name_, long long oflag_, long long mode_, long long value_, void *idp_) { + const char *name = (const char *)name_; + if (name) { + PRE_READ(name, __sanitizer::internal_strlen(name) + 1); + } +} +POST_SYSCALL(_ksem_open) +(long long res, void *name_, long long oflag_, long long mode_, + long long value_, void *idp_) { + const char *name = (const char *)name_; + if (name) { + POST_READ(name, __sanitizer::internal_strlen(name) + 1); + } +} +PRE_SYSCALL(_ksem_unlink)(void *name_) { + const char *name = (const char *)name_; + if (name) { + PRE_READ(name, __sanitizer::internal_strlen(name) + 1); + } +} +POST_SYSCALL(_ksem_unlink)(long long res, void *name_) { + const char *name = (const char *)name_; + if (name) { + POST_READ(name, __sanitizer::internal_strlen(name) + 1); + } +} +PRE_SYSCALL(_ksem_close)(long long id_) { /* Nothing to do */ } +POST_SYSCALL(_ksem_close)(long long res, long long id_) { /* Nothing to do */ } +PRE_SYSCALL(_ksem_post)(long long id_) { /* Nothing to do */ } +POST_SYSCALL(_ksem_post)(long long res, long long id_) { /* Nothing to do */ } +PRE_SYSCALL(_ksem_wait)(long long id_) { /* Nothing to do */ } +POST_SYSCALL(_ksem_wait)(long long res, long long id_) { /* Nothing to do */ } +PRE_SYSCALL(_ksem_trywait)(long long id_) { /* Nothing to do */ } +POST_SYSCALL(_ksem_trywait)(long long res, long long id_) { + /* Nothing to do */ +} +PRE_SYSCALL(_ksem_getvalue)(long long id_, void *value_) { /* Nothing to do */ } +POST_SYSCALL(_ksem_getvalue)(long long res, long long id_, void *value_) { + /* Nothing to do */ +} +PRE_SYSCALL(_ksem_destroy)(long long id_) { /* Nothing to do */ } +POST_SYSCALL(_ksem_destroy)(long long res, long long id_) { + /* Nothing to do */ +} +PRE_SYSCALL(_ksem_timedwait)(long long id_, void *abstime_) { + if (abstime_) { + PRE_READ(abstime_, struct_timespec_sz); + } +} +POST_SYSCALL(_ksem_timedwait)(long long res, long long id_, void *abstime_) {} +PRE_SYSCALL(mq_open) +(void *name_, long long oflag_, long long mode_, void *attr_) { + const char *name = (const char *)name_; + if (name) { + PRE_READ(name, __sanitizer::internal_strlen(name) + 1); + } +} +POST_SYSCALL(mq_open) +(long long res, void *name_, long long oflag_, long long mode_, void *attr_) { + const char *name = (const char *)name_; + if (name) { + POST_READ(name, __sanitizer::internal_strlen(name) + 1); + } +} +PRE_SYSCALL(mq_close)(long long mqdes_) { /* Nothing to do */ } +POST_SYSCALL(mq_close)(long long res, long long mqdes_) { /* Nothing to do */ } +PRE_SYSCALL(mq_unlink)(void *name_) { + const char *name = (const char *)name_; + if (name) { + PRE_READ(name, __sanitizer::internal_strlen(name) + 1); + } +} +POST_SYSCALL(mq_unlink)(long long res, void *name_) { + const char *name = (const char *)name_; + if (name) { + POST_READ(name, __sanitizer::internal_strlen(name) + 1); + } +} +PRE_SYSCALL(mq_getattr)(long long mqdes_, void *mqstat_) { /* Nothing to do */ } +POST_SYSCALL(mq_getattr)(long long res, long long mqdes_, void *mqstat_) { + /* Nothing to do */ +} +PRE_SYSCALL(mq_setattr)(long long mqdes_, void *mqstat_, void *omqstat_) { + if (mqstat_) { + PRE_READ(mqstat_, struct_mq_attr_sz); + } +} +POST_SYSCALL(mq_setattr) +(long long res, long long mqdes_, void *mqstat_, void *omqstat_) {} +PRE_SYSCALL(mq_notify)(long long mqdes_, void *notification_) { + if (notification_) { + PRE_READ(notification_, struct_sigevent_sz); + } +} +POST_SYSCALL(mq_notify)(long long res, long long mqdes_, void *notification_) {} +PRE_SYSCALL(mq_send) +(long long mqdes_, void *msg_ptr_, long long msg_len_, long long msg_prio_) { + if (msg_ptr_) { + PRE_READ(msg_ptr_, msg_len_); + } +} +POST_SYSCALL(mq_send) +(long long res, long long mqdes_, void *msg_ptr_, long long msg_len_, + long long msg_prio_) {} +PRE_SYSCALL(mq_receive) +(long long mqdes_, void *msg_ptr_, long long msg_len_, void *msg_prio_) { + /* Nothing to do */ +} +POST_SYSCALL(mq_receive) +(long long res, long long mqdes_, void *msg_ptr_, long long msg_len_, + void *msg_prio_) { + /* Nothing to do */ +} +PRE_SYSCALL(compat_50_mq_timedsend) +(long long mqdes_, void *msg_ptr_, long long msg_len_, long long msg_prio_, + void *abs_timeout_) { + /* TODO */ +} +POST_SYSCALL(compat_50_mq_timedsend) +(long long res, long long mqdes_, void *msg_ptr_, long long msg_len_, + long long msg_prio_, void *abs_timeout_) { + /* TODO */ +} +PRE_SYSCALL(compat_50_mq_timedreceive) +(long long mqdes_, void *msg_ptr_, long long msg_len_, void *msg_prio_, + void *abs_timeout_) { + /* TODO */ +} +POST_SYSCALL(compat_50_mq_timedreceive) +(long long res, long long mqdes_, void *msg_ptr_, long long msg_len_, + void *msg_prio_, void *abs_timeout_) { + /* TODO */ +} +/* syscall 267 has been skipped */ +/* syscall 268 has been skipped */ +/* syscall 269 has been skipped */ +PRE_SYSCALL(__posix_rename)(void *from_, void *to_) { + const char *from = (const char *)from_; + const char *to = (const char *)to_; + if (from_) { + PRE_READ(from, __sanitizer::internal_strlen(from) + 1); + } + if (to) { + PRE_READ(to, __sanitizer::internal_strlen(to) + 1); + } +} +POST_SYSCALL(__posix_rename)(long long res, void *from_, void *to_) { + const char *from = (const char *)from_; + const char *to = (const char *)to_; + if (from) { + POST_READ(from, __sanitizer::internal_strlen(from) + 1); + } + if (to) { + POST_READ(to, __sanitizer::internal_strlen(to) + 1); + } +} +PRE_SYSCALL(swapctl)(long long cmd_, void *arg_, long long misc_) { /* TODO */ } +POST_SYSCALL(swapctl) +(long long res, long long cmd_, void *arg_, long long misc_) { + /* TODO */ +} +PRE_SYSCALL(compat_30_getdents)(long long fd_, void *buf_, long long count_) { + /* TODO */ +} +POST_SYSCALL(compat_30_getdents) +(long long res, long long fd_, void *buf_, long long count_) { + /* TODO */ +} +PRE_SYSCALL(minherit)(void *addr_, long long len_, long long inherit_) { + /* Nothing to do */ +} +POST_SYSCALL(minherit) +(long long res, void *addr_, long long len_, long long inherit_) { + /* Nothing to do */ +} +PRE_SYSCALL(lchmod)(void *path_, long long mode_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(lchmod)(long long res, void *path_, long long mode_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(lchown)(void *path_, long long uid_, long long gid_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(lchown) +(long long res, void *path_, long long uid_, long long gid_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(compat_50_lutimes)(void *path_, void *tptr_) { /* TODO */ } +POST_SYSCALL(compat_50_lutimes)(long long res, void *path_, void *tptr_) { + /* TODO */ +} +PRE_SYSCALL(__msync13)(void *addr_, long long len_, long long flags_) { + /* Nothing to do */ +} +POST_SYSCALL(__msync13) +(long long res, void *addr_, long long len_, long long flags_) { + /* Nothing to do */ +} +PRE_SYSCALL(compat_30___stat13)(void *path_, void *ub_) { /* TODO */ } +POST_SYSCALL(compat_30___stat13)(long long res, void *path_, void *ub_) { + /* TODO */ +} +PRE_SYSCALL(compat_30___fstat13)(long long fd_, void *sb_) { /* TODO */ } +POST_SYSCALL(compat_30___fstat13)(long long res, long long fd_, void *sb_) { + /* TODO */ +} +PRE_SYSCALL(compat_30___lstat13)(void *path_, void *ub_) { /* TODO */ } +POST_SYSCALL(compat_30___lstat13)(long long res, void *path_, void *ub_) { + /* TODO */ +} +PRE_SYSCALL(__sigaltstack14)(void *nss_, void *oss_) { + if (nss_) { + PRE_READ(nss_, struct_sigaltstack_sz); + } + if (oss_) { + PRE_READ(oss_, struct_sigaltstack_sz); + } +} +POST_SYSCALL(__sigaltstack14)(long long res, void *nss_, void *oss_) {} +PRE_SYSCALL(__vfork14)(void) { /* Nothing to do */ } +POST_SYSCALL(__vfork14)(long long res) { /* Nothing to do */ } +PRE_SYSCALL(__posix_chown)(void *path_, long long uid_, long long gid_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(__posix_chown) +(long long res, void *path_, long long uid_, long long gid_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(__posix_fchown)(long long fd_, long long uid_, long long gid_) { + /* Nothing to do */ +} +POST_SYSCALL(__posix_fchown) +(long long res, long long fd_, long long uid_, long long gid_) { + /* Nothing to do */ +} +PRE_SYSCALL(__posix_lchown)(void *path_, long long uid_, long long gid_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(__posix_lchown) +(long long res, void *path_, long long uid_, long long gid_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(getsid)(long long pid_) { /* Nothing to do */ } +POST_SYSCALL(getsid)(long long res, long long pid_) { /* Nothing to do */ } +PRE_SYSCALL(__clone)(long long flags_, void *stack_) { /* Nothing to do */ } +POST_SYSCALL(__clone)(long long res, long long flags_, void *stack_) { + /* Nothing to do */ +} +PRE_SYSCALL(fktrace) +(long long fd_, long long ops_, long long facs_, long long pid_) { + /* Nothing to do */ +} +POST_SYSCALL(fktrace) +(long long res, long long fd_, long long ops_, long long facs_, + long long pid_) { + /* Nothing to do */ +} +PRE_SYSCALL(preadv) +(long long fd_, void *iovp_, long long iovcnt_, long long PAD_, + long long offset_) { + /* Nothing to do */ +} +POST_SYSCALL(preadv) +(long long res, long long fd_, void *iovp_, long long iovcnt_, long long PAD_, + long long offset_) { + /* Nothing to do */ +} +PRE_SYSCALL(pwritev) +(long long fd_, void *iovp_, long long iovcnt_, long long PAD_, + long long offset_) { + /* Nothing to do */ +} +POST_SYSCALL(pwritev) +(long long res, long long fd_, void *iovp_, long long iovcnt_, long long PAD_, + long long offset_) { + /* Nothing to do */ +} +PRE_SYSCALL(compat_16___sigaction14) +(long long signum_, void *nsa_, void *osa_) { + /* TODO */ +} +POST_SYSCALL(compat_16___sigaction14) +(long long res, long long signum_, void *nsa_, void *osa_) { + /* TODO */ +} +PRE_SYSCALL(__sigpending14)(void *set_) { /* Nothing to do */ } +POST_SYSCALL(__sigpending14)(long long res, void *set_) { /* Nothing to do */ } +PRE_SYSCALL(__sigprocmask14)(long long how_, void *set_, void *oset_) { + /* Nothing to do */ +} +POST_SYSCALL(__sigprocmask14) +(long long res, long long how_, void *set_, void *oset_) { + /* Nothing to do */ +} +PRE_SYSCALL(__sigsuspend14)(void *set_) { + if (set_) { + PRE_READ(set_, sizeof(__sanitizer_sigset_t)); + } +} +POST_SYSCALL(__sigsuspend14)(long long res, void *set_) { + if (set_) { + PRE_READ(set_, sizeof(__sanitizer_sigset_t)); + } +} +PRE_SYSCALL(compat_16___sigreturn14)(void *sigcntxp_) { /* TODO */ } +POST_SYSCALL(compat_16___sigreturn14)(long long res, void *sigcntxp_) { + /* TODO */ +} +PRE_SYSCALL(__getcwd)(void *bufp_, long long length_) { /* Nothing to do */ } +POST_SYSCALL(__getcwd)(long long res, void *bufp_, long long length_) { + /* Nothing to do */ +} +PRE_SYSCALL(fchroot)(long long fd_) { /* Nothing to do */ } +POST_SYSCALL(fchroot)(long long res, long long fd_) { /* Nothing to do */ } +PRE_SYSCALL(compat_30_fhopen)(void *fhp_, long long flags_) { /* TODO */ } +POST_SYSCALL(compat_30_fhopen)(long long res, void *fhp_, long long flags_) { + /* TODO */ +} +PRE_SYSCALL(compat_30_fhstat)(void *fhp_, void *sb_) { /* TODO */ } +POST_SYSCALL(compat_30_fhstat)(long long res, void *fhp_, void *sb_) { + /* TODO */ +} +PRE_SYSCALL(compat_20_fhstatfs)(void *fhp_, void *buf_) { /* TODO */ } +POST_SYSCALL(compat_20_fhstatfs)(long long res, void *fhp_, void *buf_) { + /* TODO */ +} +PRE_SYSCALL(compat_50_____semctl13) +(long long semid_, long long semnum_, long long cmd_, void *arg_) { + /* TODO */ +} +POST_SYSCALL(compat_50_____semctl13) +(long long res, long long semid_, long long semnum_, long long cmd_, + void *arg_) { + /* TODO */ +} +PRE_SYSCALL(compat_50___msgctl13) +(long long msqid_, long long cmd_, void *buf_) { + /* TODO */ +} +POST_SYSCALL(compat_50___msgctl13) +(long long res, long long msqid_, long long cmd_, void *buf_) { + /* TODO */ +} +PRE_SYSCALL(compat_50___shmctl13) +(long long shmid_, long long cmd_, void *buf_) { + /* TODO */ +} +POST_SYSCALL(compat_50___shmctl13) +(long long res, long long shmid_, long long cmd_, void *buf_) { + /* TODO */ +} +PRE_SYSCALL(lchflags)(void *path_, long long flags_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(lchflags)(long long res, void *path_, long long flags_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(issetugid)(void) { /* Nothing to do */ } +POST_SYSCALL(issetugid)(long long res) { /* Nothing to do */ } +PRE_SYSCALL(utrace)(void *label_, void *addr_, long long len_) { + const char *label = (const char *)label_; + if (label) { + PRE_READ(label, __sanitizer::internal_strlen(label) + 1); + } + if (addr_) { + PRE_READ(addr_, len_); + } +} +POST_SYSCALL(utrace)(long long res, void *label_, void *addr_, long long len_) { + const char *label = (const char *)label_; + if (label) { + POST_READ(label, __sanitizer::internal_strlen(label) + 1); + } + if (addr_) { + POST_READ(addr_, len_); + } +} +PRE_SYSCALL(getcontext)(void *ucp_) { /* Nothing to do */ } +POST_SYSCALL(getcontext)(long long res, void *ucp_) { /* Nothing to do */ } +PRE_SYSCALL(setcontext)(void *ucp_) { + if (ucp_) { + PRE_READ(ucp_, ucontext_t_sz); + } +} +POST_SYSCALL(setcontext)(long long res, void *ucp_) {} +PRE_SYSCALL(_lwp_create)(void *ucp_, long long flags_, void *new_lwp_) { + if (ucp_) { + PRE_READ(ucp_, ucontext_t_sz); + } +} +POST_SYSCALL(_lwp_create) +(long long res, void *ucp_, long long flags_, void *new_lwp_) {} +PRE_SYSCALL(_lwp_exit)(void) { /* Nothing to do */ } +POST_SYSCALL(_lwp_exit)(long long res) { /* Nothing to do */ } +PRE_SYSCALL(_lwp_self)(void) { /* Nothing to do */ } +POST_SYSCALL(_lwp_self)(long long res) { /* Nothing to do */ } +PRE_SYSCALL(_lwp_wait)(long long wait_for_, void *departed_) { + /* Nothing to do */ +} +POST_SYSCALL(_lwp_wait)(long long res, long long wait_for_, void *departed_) { + /* Nothing to do */ +} +PRE_SYSCALL(_lwp_suspend)(long long target_) { /* Nothing to do */ } +POST_SYSCALL(_lwp_suspend)(long long res, long long target_) { + /* Nothing to do */ +} +PRE_SYSCALL(_lwp_continue)(long long target_) { /* Nothing to do */ } +POST_SYSCALL(_lwp_continue)(long long res, long long target_) { + /* Nothing to do */ +} +PRE_SYSCALL(_lwp_wakeup)(long long target_) { /* Nothing to do */ } +POST_SYSCALL(_lwp_wakeup)(long long res, long long target_) { + /* Nothing to do */ +} +PRE_SYSCALL(_lwp_getprivate)(void) { /* Nothing to do */ } +POST_SYSCALL(_lwp_getprivate)(long long res) { /* Nothing to do */ } +PRE_SYSCALL(_lwp_setprivate)(void *ptr_) { /* Nothing to do */ } +POST_SYSCALL(_lwp_setprivate)(long long res, void *ptr_) { /* Nothing to do */ } +PRE_SYSCALL(_lwp_kill)(long long target_, long long signo_) { + /* Nothing to do */ +} +POST_SYSCALL(_lwp_kill)(long long res, long long target_, long long signo_) { + /* Nothing to do */ +} +PRE_SYSCALL(_lwp_detach)(long long target_) { /* Nothing to do */ } +POST_SYSCALL(_lwp_detach)(long long res, long long target_) { + /* Nothing to do */ +} +PRE_SYSCALL(compat_50__lwp_park) +(void *ts_, long long unpark_, void *hint_, void *unparkhint_) { + /* TODO */ +} +POST_SYSCALL(compat_50__lwp_park) +(long long res, void *ts_, long long unpark_, void *hint_, void *unparkhint_) { + /* TODO */ +} +PRE_SYSCALL(_lwp_unpark)(long long target_, void *hint_) { /* Nothing to do */ } +POST_SYSCALL(_lwp_unpark)(long long res, long long target_, void *hint_) { + /* Nothing to do */ +} +PRE_SYSCALL(_lwp_unpark_all)(void *targets_, long long ntargets_, void *hint_) { + if (targets_) { + PRE_READ(targets_, ntargets_ * sizeof(__sanitizer_lwpid_t)); + } +} +POST_SYSCALL(_lwp_unpark_all) +(long long res, void *targets_, long long ntargets_, void *hint_) {} +PRE_SYSCALL(_lwp_setname)(long long target_, void *name_) { + const char *name = (const char *)name_; + if (name) { + PRE_READ(name, __sanitizer::internal_strlen(name) + 1); + } +} +POST_SYSCALL(_lwp_setname)(long long res, long long target_, void *name_) { + const char *name = (const char *)name_; + if (name) { + POST_READ(name, __sanitizer::internal_strlen(name) + 1); + } +} +PRE_SYSCALL(_lwp_getname)(long long target_, void *name_, long long len_) { + /* Nothing to do */ +} +POST_SYSCALL(_lwp_getname) +(long long res, long long target_, void *name_, long long len_) { + /* Nothing to do */ +} +PRE_SYSCALL(_lwp_ctl)(long long features_, void **address_) { + /* Nothing to do */ +} +POST_SYSCALL(_lwp_ctl)(long long res, long long features_, void **address_) { + /* Nothing to do */ +} +/* syscall 326 has been skipped */ +/* syscall 327 has been skipped */ +/* syscall 328 has been skipped */ +/* syscall 329 has been skipped */ +PRE_SYSCALL(compat_60_sa_register) +(void *newv_, void **oldv_, long long flags_, long long stackinfo_offset_) { + /* TODO */ +} +POST_SYSCALL(compat_60_sa_register) +(long long res, void *newv_, void **oldv_, long long flags_, + long long stackinfo_offset_) { + /* TODO */ +} +PRE_SYSCALL(compat_60_sa_stacks)(long long num_, void *stacks_) { /* TODO */ } +POST_SYSCALL(compat_60_sa_stacks) +(long long res, long long num_, void *stacks_) { + /* TODO */ +} +PRE_SYSCALL(compat_60_sa_enable)(void) { /* TODO */ } +POST_SYSCALL(compat_60_sa_enable)(long long res) { /* TODO */ } +PRE_SYSCALL(compat_60_sa_setconcurrency)(long long concurrency_) { /* TODO */ } +POST_SYSCALL(compat_60_sa_setconcurrency) +(long long res, long long concurrency_) { + /* TODO */ +} +PRE_SYSCALL(compat_60_sa_yield)(void) { /* TODO */ } +POST_SYSCALL(compat_60_sa_yield)(long long res) { /* TODO */ } +PRE_SYSCALL(compat_60_sa_preempt)(long long sa_id_) { /* TODO */ } +POST_SYSCALL(compat_60_sa_preempt)(long long res, long long sa_id_) { + /* TODO */ +} +/* syscall 336 has been skipped */ +/* syscall 337 has been skipped */ +/* syscall 338 has been skipped */ +/* syscall 339 has been skipped */ +PRE_SYSCALL(__sigaction_sigtramp) +(long long signum_, void *nsa_, void *osa_, void *tramp_, long long vers_) { + if (nsa_) { + PRE_READ(nsa_, sizeof(__sanitizer_sigaction)); + } +} +POST_SYSCALL(__sigaction_sigtramp) +(long long res, long long signum_, void *nsa_, void *osa_, void *tramp_, + long long vers_) { + if (nsa_) { + 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 */ +} +PRE_SYSCALL(rasctl)(void *addr_, long long len_, long long op_) { + /* Nothing to do */ +} +POST_SYSCALL(rasctl) +(long long res, void *addr_, long long len_, long long op_) { + /* Nothing to do */ +} +PRE_SYSCALL(kqueue)(void) { /* Nothing to do */ } +POST_SYSCALL(kqueue)(long long res) { /* Nothing to do */ } +PRE_SYSCALL(compat_50_kevent) +(long long fd_, void *changelist_, long long nchanges_, void *eventlist_, + long long nevents_, void *timeout_) { + /* TODO */ +} +POST_SYSCALL(compat_50_kevent) +(long long res, long long fd_, void *changelist_, long long nchanges_, + void *eventlist_, long long nevents_, void *timeout_) { + /* TODO */ +} +PRE_SYSCALL(_sched_setparam) +(long long pid_, long long lid_, long long policy_, void *params_) { + if (params_) { + PRE_READ(params_, struct_sched_param_sz); + } +} +POST_SYSCALL(_sched_setparam) +(long long res, long long pid_, long long lid_, long long policy_, + void *params_) { + if (params_) { + PRE_READ(params_, struct_sched_param_sz); + } +} +PRE_SYSCALL(_sched_getparam) +(long long pid_, long long lid_, void *policy_, void *params_) { + /* Nothing to do */ +} +POST_SYSCALL(_sched_getparam) +(long long res, long long pid_, long long lid_, void *policy_, void *params_) { + /* Nothing to do */ +} +PRE_SYSCALL(_sched_setaffinity) +(long long pid_, long long lid_, long long size_, void *cpuset_) { + if (cpuset_) { + PRE_READ(cpuset_, size_); + } +} +POST_SYSCALL(_sched_setaffinity) +(long long res, long long pid_, long long lid_, long long size_, + void *cpuset_) { + if (cpuset_) { + PRE_READ(cpuset_, size_); + } +} +PRE_SYSCALL(_sched_getaffinity) +(long long pid_, long long lid_, long long size_, void *cpuset_) { + /* Nothing to do */ +} +POST_SYSCALL(_sched_getaffinity) +(long long res, long long pid_, long long lid_, long long size_, + void *cpuset_) { + /* Nothing to do */ +} +PRE_SYSCALL(sched_yield)(void) { /* Nothing to do */ } +POST_SYSCALL(sched_yield)(long long res) { /* Nothing to do */ } +PRE_SYSCALL(_sched_protect)(long long priority_) { /* Nothing to do */ } +POST_SYSCALL(_sched_protect)(long long res, long long priority_) { + /* Nothing to do */ +} +/* syscall 352 has been skipped */ +/* syscall 353 has been skipped */ +PRE_SYSCALL(fsync_range) +(long long fd_, long long flags_, long long start_, long long length_) { + /* Nothing to do */ +} +POST_SYSCALL(fsync_range) +(long long res, long long fd_, long long flags_, long long start_, + long long length_) { + /* Nothing to do */ +} +PRE_SYSCALL(uuidgen)(void *store_, long long count_) { /* Nothing to do */ } +POST_SYSCALL(uuidgen)(long long res, void *store_, long long count_) { + /* Nothing to do */ +} +PRE_SYSCALL(getvfsstat)(void *buf_, long long bufsize_, long long flags_) { + /* Nothing to do */ +} +POST_SYSCALL(getvfsstat) +(long long res, void *buf_, long long bufsize_, long long flags_) { + /* Nothing to do */ +} +PRE_SYSCALL(statvfs1)(void *path_, void *buf_, long long flags_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(statvfs1) +(long long res, void *path_, void *buf_, long long flags_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(fstatvfs1)(long long fd_, void *buf_, long long flags_) { + /* Nothing to do */ +} +POST_SYSCALL(fstatvfs1) +(long long res, long long fd_, void *buf_, long long flags_) { + /* Nothing to do */ +} +PRE_SYSCALL(compat_30_fhstatvfs1)(void *fhp_, void *buf_, long long flags_) { + /* TODO */ +} +POST_SYSCALL(compat_30_fhstatvfs1) +(long long res, void *fhp_, void *buf_, long long flags_) { + /* TODO */ +} +PRE_SYSCALL(extattrctl) +(void *path_, long long cmd_, void *filename_, long long attrnamespace_, + void *attrname_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(extattrctl) +(long long res, void *path_, long long cmd_, void *filename_, + long long attrnamespace_, void *attrname_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(extattr_set_file) +(void *path_, long long attrnamespace_, void *attrname_, void *data_, + long long nbytes_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(extattr_set_file) +(long long res, void *path_, long long attrnamespace_, void *attrname_, + void *data_, long long nbytes_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(extattr_get_file) +(void *path_, long long attrnamespace_, void *attrname_, void *data_, + long long nbytes_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(extattr_get_file) +(long long res, void *path_, long long attrnamespace_, void *attrname_, + void *data_, long long nbytes_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(extattr_delete_file) +(void *path_, long long attrnamespace_, void *attrname_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(extattr_delete_file) +(long long res, void *path_, long long attrnamespace_, void *attrname_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(extattr_set_fd) +(long long fd_, long long attrnamespace_, void *attrname_, void *data_, + long long nbytes_) { + /* TODO */ +} +POST_SYSCALL(extattr_set_fd) +(long long res, long long fd_, long long attrnamespace_, void *attrname_, + void *data_, long long nbytes_) { + /* TODO */ +} +PRE_SYSCALL(extattr_get_fd) +(long long fd_, long long attrnamespace_, void *attrname_, void *data_, + long long nbytes_) { + /* TODO */ +} +POST_SYSCALL(extattr_get_fd) +(long long res, long long fd_, long long attrnamespace_, void *attrname_, + void *data_, long long nbytes_) { + /* TODO */ +} +PRE_SYSCALL(extattr_delete_fd) +(long long fd_, long long attrnamespace_, void *attrname_) { + /* TODO */ +} +POST_SYSCALL(extattr_delete_fd) +(long long res, long long fd_, long long attrnamespace_, void *attrname_) { + /* TODO */ +} +PRE_SYSCALL(extattr_set_link) +(void *path_, long long attrnamespace_, void *attrname_, void *data_, + long long nbytes_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(extattr_set_link) +(long long res, void *path_, long long attrnamespace_, void *attrname_, + void *data_, long long nbytes_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(extattr_get_link) +(void *path_, long long attrnamespace_, void *attrname_, void *data_, + long long nbytes_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(extattr_get_link) +(long long res, void *path_, long long attrnamespace_, void *attrname_, + void *data_, long long nbytes_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(extattr_delete_link) +(void *path_, long long attrnamespace_, void *attrname_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(extattr_delete_link) +(long long res, void *path_, long long attrnamespace_, void *attrname_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(extattr_list_fd) +(long long fd_, long long attrnamespace_, void *data_, long long nbytes_) { + /* TODO */ +} +POST_SYSCALL(extattr_list_fd) +(long long res, long long fd_, long long attrnamespace_, void *data_, + long long nbytes_) { + /* TODO */ +} +PRE_SYSCALL(extattr_list_file) +(void *path_, long long attrnamespace_, void *data_, long long nbytes_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(extattr_list_file) +(long long res, void *path_, long long attrnamespace_, void *data_, + long long nbytes_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(extattr_list_link) +(void *path_, long long attrnamespace_, void *data_, long long nbytes_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(extattr_list_link) +(long long res, void *path_, long long attrnamespace_, void *data_, + long long nbytes_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(compat_50_pselect) +(long long nd_, void *in_, void *ou_, void *ex_, void *ts_, void *mask_) { + /* TODO */ +} +POST_SYSCALL(compat_50_pselect) +(long long res, long long nd_, void *in_, void *ou_, void *ex_, void *ts_, + void *mask_) { + /* TODO */ +} +PRE_SYSCALL(compat_50_pollts) +(void *fds_, long long nfds_, void *ts_, void *mask_) { + /* TODO */ +} +POST_SYSCALL(compat_50_pollts) +(long long res, void *fds_, long long nfds_, void *ts_, void *mask_) { + /* TODO */ +} +PRE_SYSCALL(setxattr) +(void *path_, void *name_, void *value_, long long size_, long long flags_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(setxattr) +(long long res, void *path_, void *name_, void *value_, long long size_, + long long flags_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(lsetxattr) +(void *path_, void *name_, void *value_, long long size_, long long flags_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(lsetxattr) +(long long res, void *path_, void *name_, void *value_, long long size_, + long long flags_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(fsetxattr) +(long long fd_, void *name_, void *value_, long long size_, long long flags_) { + /* Nothing to do */ +} +POST_SYSCALL(fsetxattr) +(long long res, long long fd_, void *name_, void *value_, long long size_, + long long flags_) { + /* Nothing to do */ +} +PRE_SYSCALL(getxattr)(void *path_, void *name_, void *value_, long long size_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(getxattr) +(long long res, void *path_, void *name_, void *value_, long long size_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(lgetxattr) +(void *path_, void *name_, void *value_, long long size_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(lgetxattr) +(long long res, void *path_, void *name_, void *value_, long long size_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(fgetxattr) +(long long fd_, void *name_, void *value_, long long size_) { + /* Nothing to do */ +} +POST_SYSCALL(fgetxattr) +(long long res, long long fd_, void *name_, void *value_, long long size_) { + /* Nothing to do */ +} +PRE_SYSCALL(listxattr)(void *path_, void *list_, long long size_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(listxattr) +(long long res, void *path_, void *list_, long long size_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(llistxattr)(void *path_, void *list_, long long size_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(llistxattr) +(long long res, void *path_, void *list_, long long size_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(flistxattr)(long long fd_, void *list_, long long size_) { + /* TODO */ +} +POST_SYSCALL(flistxattr) +(long long res, long long fd_, void *list_, long long size_) { + /* TODO */ +} +PRE_SYSCALL(removexattr)(void *path_, void *name_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(removexattr)(long long res, void *path_, void *name_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(lremovexattr)(void *path_, void *name_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(lremovexattr)(long long res, void *path_, void *name_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(fremovexattr)(long long fd_, void *name_) { /* TODO */ } +POST_SYSCALL(fremovexattr)(long long res, long long fd_, void *name_) { + /* TODO */ +} +PRE_SYSCALL(compat_50___stat30)(void *path_, void *ub_) { /* TODO */ } +POST_SYSCALL(compat_50___stat30)(long long res, void *path_, void *ub_) { + /* TODO */ +} +PRE_SYSCALL(compat_50___fstat30)(long long fd_, void *sb_) { /* TODO */ } +POST_SYSCALL(compat_50___fstat30)(long long res, long long fd_, void *sb_) { + /* TODO */ +} +PRE_SYSCALL(compat_50___lstat30)(void *path_, void *ub_) { /* TODO */ } +POST_SYSCALL(compat_50___lstat30)(long long res, void *path_, void *ub_) { + /* TODO */ +} +PRE_SYSCALL(__getdents30)(long long fd_, void *buf_, long long count_) { + /* Nothing to do */ +} +POST_SYSCALL(__getdents30) +(long long res, long long fd_, void *buf_, long long count_) { + /* Nothing to do */ +} +PRE_SYSCALL(posix_fadvise)(long long) { /* Nothing to do */ } +POST_SYSCALL(posix_fadvise)(long long res, long long) { /* Nothing to do */ } +PRE_SYSCALL(compat_30___fhstat30)(void *fhp_, void *sb_) { /* TODO */ } +POST_SYSCALL(compat_30___fhstat30)(long long res, void *fhp_, void *sb_) { + /* TODO */ +} +PRE_SYSCALL(compat_50___ntp_gettime30)(void *ntvp_) { /* TODO */ } +POST_SYSCALL(compat_50___ntp_gettime30)(long long res, void *ntvp_) { + /* TODO */ +} +PRE_SYSCALL(__socket30) +(long long domain_, long long type_, long long protocol_) { + /* Nothing to do */ +} +POST_SYSCALL(__socket30) +(long long res, long long domain_, long long type_, long long protocol_) { + /* Nothing to do */ +} +PRE_SYSCALL(__getfh30)(void *fname_, void *fhp_, void *fh_size_) { + const char *fname = (const char *)fname_; + if (fname) { + PRE_READ(fname, __sanitizer::internal_strlen(fname) + 1); + } +} +POST_SYSCALL(__getfh30) +(long long res, void *fname_, void *fhp_, void *fh_size_) { + const char *fname = (const char *)fname_; + if (res == 0) { + if (fname) { + POST_READ(fname, __sanitizer::internal_strlen(fname) + 1); + } + } +} +PRE_SYSCALL(__fhopen40)(void *fhp_, long long fh_size_, long long flags_) { + if (fhp_) { + PRE_READ(fhp_, fh_size_); + } +} +POST_SYSCALL(__fhopen40) +(long long res, void *fhp_, long long fh_size_, long long flags_) {} +PRE_SYSCALL(__fhstatvfs140) +(void *fhp_, long long fh_size_, void *buf_, long long flags_) { + if (fhp_) { + PRE_READ(fhp_, fh_size_); + } +} +POST_SYSCALL(__fhstatvfs140) +(long long res, void *fhp_, long long fh_size_, void *buf_, long long flags_) {} +PRE_SYSCALL(compat_50___fhstat40)(void *fhp_, long long fh_size_, void *sb_) { + if (fhp_) { + PRE_READ(fhp_, fh_size_); + } +} +POST_SYSCALL(compat_50___fhstat40) +(long long res, void *fhp_, long long fh_size_, void *sb_) {} +PRE_SYSCALL(aio_cancel)(long long fildes_, void *aiocbp_) { + if (aiocbp_) { + PRE_READ(aiocbp_, sizeof(struct __sanitizer_aiocb)); + } +} +POST_SYSCALL(aio_cancel)(long long res, long long fildes_, void *aiocbp_) {} +PRE_SYSCALL(aio_error)(void *aiocbp_) { + if (aiocbp_) { + PRE_READ(aiocbp_, sizeof(struct __sanitizer_aiocb)); + } +} +POST_SYSCALL(aio_error)(long long res, void *aiocbp_) {} +PRE_SYSCALL(aio_fsync)(long long op_, void *aiocbp_) { + if (aiocbp_) { + PRE_READ(aiocbp_, sizeof(struct __sanitizer_aiocb)); + } +} +POST_SYSCALL(aio_fsync)(long long res, long long op_, void *aiocbp_) {} +PRE_SYSCALL(aio_read)(void *aiocbp_) { + if (aiocbp_) { + PRE_READ(aiocbp_, sizeof(struct __sanitizer_aiocb)); + } +} +POST_SYSCALL(aio_read)(long long res, void *aiocbp_) {} +PRE_SYSCALL(aio_return)(void *aiocbp_) { + if (aiocbp_) { + PRE_READ(aiocbp_, sizeof(struct __sanitizer_aiocb)); + } +} +POST_SYSCALL(aio_return)(long long res, void *aiocbp_) {} +PRE_SYSCALL(compat_50_aio_suspend) +(void *list_, long long nent_, void *timeout_) { + /* TODO */ +} +POST_SYSCALL(compat_50_aio_suspend) +(long long res, void *list_, long long nent_, void *timeout_) { + /* TODO */ +} +PRE_SYSCALL(aio_write)(void *aiocbp_) { + if (aiocbp_) { + PRE_READ(aiocbp_, sizeof(struct __sanitizer_aiocb)); + } +} +POST_SYSCALL(aio_write)(long long res, void *aiocbp_) {} +PRE_SYSCALL(lio_listio) +(long long mode_, void *list_, long long nent_, void *sig_) { + /* Nothing to do */ +} +POST_SYSCALL(lio_listio) +(long long res, long long mode_, void *list_, long long nent_, void *sig_) { + /* Nothing to do */ +} +/* syscall 407 has been skipped */ +/* syscall 408 has been skipped */ +/* syscall 409 has been skipped */ +PRE_SYSCALL(__mount50) +(void *type_, void *path_, long long flags_, void *data_, long long data_len_) { + const char *type = (const char *)type_; + const char *path = (const char *)path_; + if (type) { + PRE_READ(type, __sanitizer::internal_strlen(type) + 1); + } + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } + if (data_) { + PRE_READ(data_, data_len_); + } +} +POST_SYSCALL(__mount50) +(long long res, void *type_, void *path_, long long flags_, void *data_, + long long data_len_) { + const char *type = (const char *)type_; + const char *path = (const char *)path_; + if (type) { + POST_READ(type, __sanitizer::internal_strlen(type) + 1); + } + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + if (data_) { + POST_READ(data_, data_len_); + } +} +PRE_SYSCALL(mremap) +(void *old_address_, long long old_size_, void *new_address_, + long long new_size_, long long flags_) { + /* Nothing to do */ +} +POST_SYSCALL(mremap) +(long long res, void *old_address_, long long old_size_, void *new_address_, + long long new_size_, long long flags_) { + /* Nothing to do */ +} +PRE_SYSCALL(pset_create)(void *psid_) { /* Nothing to do */ } +POST_SYSCALL(pset_create)(long long res, void *psid_) { /* Nothing to do */ } +PRE_SYSCALL(pset_destroy)(long long psid_) { /* Nothing to do */ } +POST_SYSCALL(pset_destroy)(long long res, long long psid_) { + /* Nothing to do */ +} +PRE_SYSCALL(pset_assign)(long long psid_, long long cpuid_, void *opsid_) { + /* Nothing to do */ +} +POST_SYSCALL(pset_assign) +(long long res, long long psid_, long long cpuid_, void *opsid_) { + /* Nothing to do */ +} +PRE_SYSCALL(_pset_bind) +(long long idtype_, long long first_id_, long long second_id_, long long psid_, + void *opsid_) { + /* Nothing to do */ +} +POST_SYSCALL(_pset_bind) +(long long res, long long idtype_, long long first_id_, long long second_id_, + long long psid_, void *opsid_) { + /* Nothing to do */ +} +PRE_SYSCALL(__posix_fadvise50) +(long long fd_, long long PAD_, long long offset_, long long len_, + long long advice_) { + /* Nothing to do */ +} +POST_SYSCALL(__posix_fadvise50) +(long long res, long long fd_, long long PAD_, long long offset_, + long long len_, long long advice_) { + /* Nothing to do */ +} +PRE_SYSCALL(__select50) +(long long nd_, void *in_, void *ou_, void *ex_, void *tv_) { + /* Nothing to do */ +} +POST_SYSCALL(__select50) +(long long res, long long nd_, void *in_, void *ou_, void *ex_, void *tv_) { + /* Nothing to do */ +} +PRE_SYSCALL(__gettimeofday50)(void *tp_, void *tzp_) { /* Nothing to do */ } +POST_SYSCALL(__gettimeofday50)(long long res, void *tp_, void *tzp_) { + /* Nothing to do */ +} +PRE_SYSCALL(__settimeofday50)(void *tv_, void *tzp_) { + if (tv_) { + PRE_READ(tv_, timeval_sz); + } + if (tzp_) { + PRE_READ(tzp_, struct_timezone_sz); + } +} +POST_SYSCALL(__settimeofday50)(long long res, void *tv_, void *tzp_) {} +PRE_SYSCALL(__utimes50)(void *path_, void *tptr_) { + struct __sanitizer_timespec **tptr = (struct __sanitizer_timespec **)tptr_; + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } + if (tptr) { + PRE_READ(tptr[0], struct_timespec_sz); + PRE_READ(tptr[1], struct_timespec_sz); + } +} +POST_SYSCALL(__utimes50)(long long res, void *path_, void *tptr_) {} +PRE_SYSCALL(__adjtime50)(void *delta_, void *olddelta_) { + if (delta_) { + PRE_READ(delta_, timeval_sz); + } +} +POST_SYSCALL(__adjtime50)(long long res, void *delta_, void *olddelta_) {} +PRE_SYSCALL(__lfs_segwait50)(void *fsidp_, void *tv_) { /* TODO */ } +POST_SYSCALL(__lfs_segwait50)(long long res, void *fsidp_, void *tv_) { + /* TODO */ +} +PRE_SYSCALL(__futimes50)(long long fd_, void *tptr_) { + struct __sanitizer_timespec **tptr = (struct __sanitizer_timespec **)tptr_; + if (tptr) { + PRE_READ(tptr[0], struct_timespec_sz); + PRE_READ(tptr[1], struct_timespec_sz); + } +} +POST_SYSCALL(__futimes50)(long long res, long long fd_, void *tptr_) {} +PRE_SYSCALL(__lutimes50)(void *path_, void *tptr_) { + struct __sanitizer_timespec **tptr = (struct __sanitizer_timespec **)tptr_; + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } + if (tptr) { + PRE_READ(tptr[0], struct_timespec_sz); + PRE_READ(tptr[1], struct_timespec_sz); + } +} +POST_SYSCALL(__lutimes50)(long long res, void *path_, void *tptr_) { + struct __sanitizer_timespec **tptr = (struct __sanitizer_timespec **)tptr_; + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + if (tptr) { + POST_READ(tptr[0], struct_timespec_sz); + POST_READ(tptr[1], struct_timespec_sz); + } +} +PRE_SYSCALL(__setitimer50)(long long which_, void *itv_, void *oitv_) { + struct __sanitizer_itimerval *itv = (struct __sanitizer_itimerval *)itv_; + if (itv) { + PRE_READ(&itv->it_interval.tv_sec, sizeof(__sanitizer_time_t)); + PRE_READ(&itv->it_interval.tv_usec, sizeof(__sanitizer_suseconds_t)); + PRE_READ(&itv->it_value.tv_sec, sizeof(__sanitizer_time_t)); + PRE_READ(&itv->it_value.tv_usec, sizeof(__sanitizer_suseconds_t)); + } +} +POST_SYSCALL(__setitimer50) +(long long res, long long which_, void *itv_, void *oitv_) {} +PRE_SYSCALL(__getitimer50)(long long which_, void *itv_) { /* Nothing to do */ } +POST_SYSCALL(__getitimer50)(long long res, long long which_, void *itv_) { + /* Nothing to do */ +} +PRE_SYSCALL(__clock_gettime50)(long long clock_id_, void *tp_) { + /* Nothing to do */ +} +POST_SYSCALL(__clock_gettime50)(long long res, long long clock_id_, void *tp_) { + /* Nothing to do */ +} +PRE_SYSCALL(__clock_settime50)(long long clock_id_, void *tp_) { + if (tp_) { + PRE_READ(tp_, struct_timespec_sz); + } +} +POST_SYSCALL(__clock_settime50) +(long long res, long long clock_id_, void *tp_) {} +PRE_SYSCALL(__clock_getres50)(long long clock_id_, void *tp_) { + /* Nothing to do */ +} +POST_SYSCALL(__clock_getres50)(long long res, long long clock_id_, void *tp_) { + /* Nothing to do */ +} +PRE_SYSCALL(__nanosleep50)(void *rqtp_, void *rmtp_) { + if (rqtp_) { + PRE_READ(rqtp_, struct_timespec_sz); + } +} +POST_SYSCALL(__nanosleep50)(long long res, void *rqtp_, void *rmtp_) {} +PRE_SYSCALL(____sigtimedwait50)(void *set_, void *info_, void *timeout_) { + if (set_) { + PRE_READ(set_, sizeof(__sanitizer_sigset_t)); + } + if (timeout_) { + PRE_READ(timeout_, struct_timespec_sz); + } +} +POST_SYSCALL(____sigtimedwait50) +(long long res, void *set_, void *info_, void *timeout_) {} +PRE_SYSCALL(__mq_timedsend50) +(long long mqdes_, void *msg_ptr_, long long msg_len_, long long msg_prio_, + void *abs_timeout_) { + if (msg_ptr_) { + PRE_READ(msg_ptr_, msg_len_); + } + if (abs_timeout_) { + PRE_READ(abs_timeout_, struct_timespec_sz); + } +} +POST_SYSCALL(__mq_timedsend50) +(long long res, long long mqdes_, void *msg_ptr_, long long msg_len_, + long long msg_prio_, void *abs_timeout_) {} +PRE_SYSCALL(__mq_timedreceive50) +(long long mqdes_, void *msg_ptr_, long long msg_len_, void *msg_prio_, + void *abs_timeout_) { + if (msg_ptr_) { + PRE_READ(msg_ptr_, msg_len_); + } + if (abs_timeout_) { + PRE_READ(abs_timeout_, struct_timespec_sz); + } +} +POST_SYSCALL(__mq_timedreceive50) +(long long res, long long mqdes_, void *msg_ptr_, long long msg_len_, + void *msg_prio_, void *abs_timeout_) {} +PRE_SYSCALL(compat_60__lwp_park) +(void *ts_, long long unpark_, void *hint_, void *unparkhint_) { + /* TODO */ +} +POST_SYSCALL(compat_60__lwp_park) +(long long res, void *ts_, long long unpark_, void *hint_, void *unparkhint_) { + /* TODO */ +} +PRE_SYSCALL(__kevent50) +(long long fd_, void *changelist_, long long nchanges_, void *eventlist_, + long long nevents_, void *timeout_) { + if (changelist_) { + PRE_READ(changelist_, nchanges_ * struct_kevent_sz); + } + if (timeout_) { + PRE_READ(timeout_, struct_timespec_sz); + } +} +POST_SYSCALL(__kevent50) +(long long res, long long fd_, void *changelist_, long long nchanges_, + void *eventlist_, long long nevents_, void *timeout_) {} +PRE_SYSCALL(__pselect50) +(long long nd_, void *in_, void *ou_, void *ex_, void *ts_, void *mask_) { + if (ts_) { + PRE_READ(ts_, struct_timespec_sz); + } + if (mask_) { + PRE_READ(mask_, sizeof(struct __sanitizer_sigset_t)); + } +} +POST_SYSCALL(__pselect50) +(long long res, long long nd_, void *in_, void *ou_, void *ex_, void *ts_, + void *mask_) {} +PRE_SYSCALL(__pollts50)(void *fds_, long long nfds_, void *ts_, void *mask_) { + if (ts_) { + PRE_READ(ts_, struct_timespec_sz); + } + if (mask_) { + PRE_READ(mask_, sizeof(struct __sanitizer_sigset_t)); + } +} +POST_SYSCALL(__pollts50) +(long long res, void *fds_, long long nfds_, void *ts_, void *mask_) {} +PRE_SYSCALL(__aio_suspend50)(void *list_, long long nent_, void *timeout_) { + int i; + const struct aiocb *const *list = (const struct aiocb *const *)list_; + if (list) { + for (i = 0; i < nent_; i++) { + if (list[i]) { + PRE_READ(list[i], sizeof(struct __sanitizer_aiocb)); + } + } + } + if (timeout_) { + PRE_READ(timeout_, struct_timespec_sz); + } +} +POST_SYSCALL(__aio_suspend50) +(long long res, void *list_, long long nent_, void *timeout_) {} +PRE_SYSCALL(__stat50)(void *path_, void *ub_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(__stat50)(long long res, void *path_, void *ub_) { + const char *path = (const char *)path_; + if (res == 0) { + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(__fstat50)(long long fd_, void *sb_) { /* Nothing to do */ } +POST_SYSCALL(__fstat50)(long long res, long long fd_, void *sb_) { + /* Nothing to do */ +} +PRE_SYSCALL(__lstat50)(void *path_, void *ub_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(__lstat50)(long long res, void *path_, void *ub_) { + const char *path = (const char *)path_; + if (res == 0) { + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(____semctl50) +(long long semid_, long long semnum_, long long cmd_, void *arg_) { + /* Nothing to do */ +} +POST_SYSCALL(____semctl50) +(long long res, long long semid_, long long semnum_, long long cmd_, + void *arg_) { + /* Nothing to do */ +} +PRE_SYSCALL(__shmctl50)(long long shmid_, long long cmd_, void *buf_) { + /* Nothing to do */ +} +POST_SYSCALL(__shmctl50) +(long long res, long long shmid_, long long cmd_, void *buf_) { + /* Nothing to do */ +} +PRE_SYSCALL(__msgctl50)(long long msqid_, long long cmd_, void *buf_) { + /* Nothing to do */ +} +POST_SYSCALL(__msgctl50) +(long long res, long long msqid_, long long cmd_, void *buf_) { + /* Nothing to do */ +} +PRE_SYSCALL(__getrusage50)(long long who_, void *rusage_) { + /* Nothing to do */ +} +POST_SYSCALL(__getrusage50)(long long res, long long who_, void *rusage_) { + /* Nothing to do */ +} +PRE_SYSCALL(__timer_settime50) +(long long timerid_, long long flags_, void *value_, void *ovalue_) { + struct __sanitizer_itimerval *value = (struct __sanitizer_itimerval *)value_; + if (value) { + PRE_READ(&value->it_interval.tv_sec, sizeof(__sanitizer_time_t)); + PRE_READ(&value->it_interval.tv_usec, sizeof(__sanitizer_suseconds_t)); + PRE_READ(&value->it_value.tv_sec, sizeof(__sanitizer_time_t)); + PRE_READ(&value->it_value.tv_usec, sizeof(__sanitizer_suseconds_t)); + } +} +POST_SYSCALL(__timer_settime50) +(long long res, long long timerid_, long long flags_, void *value_, + void *ovalue_) { + struct __sanitizer_itimerval *value = (struct __sanitizer_itimerval *)value_; + if (res == 0) { + if (value) { + POST_READ(&value->it_interval.tv_sec, sizeof(__sanitizer_time_t)); + POST_READ(&value->it_interval.tv_usec, sizeof(__sanitizer_suseconds_t)); + POST_READ(&value->it_value.tv_sec, sizeof(__sanitizer_time_t)); + POST_READ(&value->it_value.tv_usec, sizeof(__sanitizer_suseconds_t)); + } + } +} +PRE_SYSCALL(__timer_gettime50)(long long timerid_, void *value_) { + /* Nothing to do */ +} +POST_SYSCALL(__timer_gettime50) +(long long res, long long timerid_, void *value_) { + /* Nothing to do */ +} +#if defined(NTP) || !defined(_KERNEL_OPT) +PRE_SYSCALL(__ntp_gettime50)(void *ntvp_) { /* Nothing to do */ } +POST_SYSCALL(__ntp_gettime50)(long long res, void *ntvp_) { + /* Nothing to do */ +} +#else +/* syscall 448 has been skipped */ +#endif +PRE_SYSCALL(__wait450) +(long long pid_, void *status_, long long options_, void *rusage_) { + /* Nothing to do */ +} +POST_SYSCALL(__wait450) +(long long res, long long pid_, void *status_, long long options_, + void *rusage_) { + /* Nothing to do */ +} +PRE_SYSCALL(__mknod50)(void *path_, long long mode_, long long dev_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(__mknod50) +(long long res, void *path_, long long mode_, long long dev_) { + const char *path = (const char *)path_; + if (res == 0) { + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(__fhstat50)(void *fhp_, long long fh_size_, void *sb_) { + if (fhp_) { + PRE_READ(fhp_, fh_size_); + } +} +POST_SYSCALL(__fhstat50) +(long long res, void *fhp_, long long fh_size_, void *sb_) { + if (res == 0) { + if (fhp_) { + POST_READ(fhp_, fh_size_); + } + } +} +/* syscall 452 has been skipped */ +PRE_SYSCALL(pipe2)(void *fildes_, long long flags_) { /* Nothing to do */ } +POST_SYSCALL(pipe2)(long long res, void *fildes_, long long flags_) { + /* Nothing to do */ +} +PRE_SYSCALL(dup3)(long long from_, long long to_, long long flags_) { + /* Nothing to do */ +} +POST_SYSCALL(dup3) +(long long res, long long from_, long long to_, long long flags_) { + /* Nothing to do */ +} +PRE_SYSCALL(kqueue1)(long long flags_) { /* Nothing to do */ } +POST_SYSCALL(kqueue1)(long long res, long long flags_) { /* Nothing to do */ } +PRE_SYSCALL(paccept) +(long long s_, void *name_, void *anamelen_, void *mask_, long long flags_) { + if (mask_) { + PRE_READ(mask_, sizeof(__sanitizer_sigset_t)); + } +} +POST_SYSCALL(paccept) +(long long res, long long s_, void *name_, void *anamelen_, void *mask_, + long long flags_) { + if (res >= 0) { + if (mask_) { + PRE_READ(mask_, sizeof(__sanitizer_sigset_t)); + } + } +} +PRE_SYSCALL(linkat) +(long long fd1_, void *name1_, long long fd2_, void *name2_, long long flags_) { + const char *name1 = (const char *)name1_; + const char *name2 = (const char *)name2_; + if (name1) { + PRE_READ(name1, __sanitizer::internal_strlen(name1) + 1); + } + if (name2) { + PRE_READ(name2, __sanitizer::internal_strlen(name2) + 1); + } +} +POST_SYSCALL(linkat) +(long long res, long long fd1_, void *name1_, long long fd2_, void *name2_, + long long flags_) { + const char *name1 = (const char *)name1_; + const char *name2 = (const char *)name2_; + if (res == 0) { + if (name1) { + POST_READ(name1, __sanitizer::internal_strlen(name1) + 1); + } + if (name2) { + POST_READ(name2, __sanitizer::internal_strlen(name2) + 1); + } + } +} +PRE_SYSCALL(renameat) +(long long fromfd_, void *from_, long long tofd_, void *to_) { + const char *from = (const char *)from_; + const char *to = (const char *)to_; + if (from) { + PRE_READ(from, __sanitizer::internal_strlen(from) + 1); + } + if (to) { + PRE_READ(to, __sanitizer::internal_strlen(to) + 1); + } +} +POST_SYSCALL(renameat) +(long long res, long long fromfd_, void *from_, long long tofd_, void *to_) { + const char *from = (const char *)from_; + const char *to = (const char *)to_; + if (res == 0) { + if (from) { + POST_READ(from, __sanitizer::internal_strlen(from) + 1); + } + if (to) { + POST_READ(to, __sanitizer::internal_strlen(to) + 1); + } + } +} +PRE_SYSCALL(mkfifoat)(long long fd_, void *path_, long long mode_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(mkfifoat) +(long long res, long long fd_, void *path_, long long mode_) { + const char *path = (const char *)path_; + if (res == 0) { + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(mknodat) +(long long fd_, void *path_, long long mode_, long long PAD_, long long dev_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(mknodat) +(long long res, long long fd_, void *path_, long long mode_, long long PAD_, + long long dev_) { + const char *path = (const char *)path_; + if (res == 0) { + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(mkdirat)(long long fd_, void *path_, long long mode_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(mkdirat) +(long long res, long long fd_, void *path_, long long mode_) { + const char *path = (const char *)path_; + if (res == 0) { + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(faccessat) +(long long fd_, void *path_, long long amode_, long long flag_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(faccessat) +(long long res, long long fd_, void *path_, long long amode_, long long flag_) { + const char *path = (const char *)path_; + if (res == 0) { + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(fchmodat) +(long long fd_, void *path_, long long mode_, long long flag_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(fchmodat) +(long long res, long long fd_, void *path_, long long mode_, long long flag_) { + const char *path = (const char *)path_; + if (res == 0) { + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(fchownat) +(long long fd_, void *path_, long long owner_, long long group_, + long long flag_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(fchownat) +(long long res, long long fd_, void *path_, long long owner_, long long group_, + long long flag_) { + const char *path = (const char *)path_; + if (res == 0) { + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(fexecve)(long long fd_, void *argp_, void *envp_) { /* TODO */ } +POST_SYSCALL(fexecve)(long long res, long long fd_, void *argp_, void *envp_) { + /* TODO */ +} +PRE_SYSCALL(fstatat)(long long fd_, void *path_, void *buf_, long long flag_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(fstatat) +(long long res, long long fd_, void *path_, void *buf_, long long flag_) { + const char *path = (const char *)path_; + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +PRE_SYSCALL(utimensat) +(long long fd_, void *path_, void *tptr_, long long flag_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } + if (tptr_) { + PRE_READ(tptr_, struct_timespec_sz); + } +} +POST_SYSCALL(utimensat) +(long long res, long long fd_, void *path_, void *tptr_, long long flag_) { + const char *path = (const char *)path_; + if (res > 0) { + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + if (tptr_) { + POST_READ(tptr_, struct_timespec_sz); + } + } +} +PRE_SYSCALL(openat) +(long long fd_, void *path_, long long oflags_, long long mode_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(openat) +(long long res, long long fd_, void *path_, long long oflags_, + long long mode_) { + const char *path = (const char *)path_; + if (res > 0) { + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(readlinkat) +(long long fd_, void *path_, void *buf_, long long bufsize_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(readlinkat) +(long long res, long long fd_, void *path_, void *buf_, long long bufsize_) { + const char *path = (const char *)path_; + if (res > 0) { + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(symlinkat)(void *path1_, long long fd_, void *path2_) { + const char *path1 = (const char *)path1_; + const char *path2 = (const char *)path2_; + if (path1) { + PRE_READ(path1, __sanitizer::internal_strlen(path1) + 1); + } + if (path2) { + PRE_READ(path2, __sanitizer::internal_strlen(path2) + 1); + } +} +POST_SYSCALL(symlinkat) +(long long res, void *path1_, long long fd_, void *path2_) { + const char *path1 = (const char *)path1_; + const char *path2 = (const char *)path2_; + if (res == 0) { + if (path1) { + POST_READ(path1, __sanitizer::internal_strlen(path1) + 1); + } + if (path2) { + POST_READ(path2, __sanitizer::internal_strlen(path2) + 1); + } + } +} +PRE_SYSCALL(unlinkat)(long long fd_, void *path_, long long flag_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(unlinkat) +(long long res, long long fd_, void *path_, long long flag_) { + const char *path = (const char *)path_; + if (res == 0) { + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(futimens)(long long fd_, void *tptr_) { + struct __sanitizer_timespec **tptr = (struct __sanitizer_timespec **)tptr_; + if (tptr) { + PRE_READ(tptr[0], struct_timespec_sz); + PRE_READ(tptr[1], struct_timespec_sz); + } +} +POST_SYSCALL(futimens)(long long res, long long fd_, void *tptr_) { + struct __sanitizer_timespec **tptr = (struct __sanitizer_timespec **)tptr_; + if (res == 0) { + if (tptr) { + POST_READ(tptr[0], struct_timespec_sz); + POST_READ(tptr[1], struct_timespec_sz); + } + } +} +PRE_SYSCALL(__quotactl)(void *path_, void *args_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(__quotactl)(long long res, void *path_, void *args_) { + const char *path = (const char *)path_; + if (res == 0) { + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(posix_spawn) +(void *pid_, void *path_, void *file_actions_, void *attrp_, void *argv_, + void *envp_) { + const char *path = (const char *)path_; + if (path) { + PRE_READ(path, __sanitizer::internal_strlen(path) + 1); + } +} +POST_SYSCALL(posix_spawn) +(long long res, void *pid_, void *path_, void *file_actions_, void *attrp_, + void *argv_, void *envp_) { + const char *path = (const char *)path_; + if (pid_) { + if (path) { + POST_READ(path, __sanitizer::internal_strlen(path) + 1); + } + } +} +PRE_SYSCALL(recvmmsg) +(long long s_, void *mmsg_, long long vlen_, long long flags_, void *timeout_) { + if (timeout_) { + PRE_READ(timeout_, struct_timespec_sz); + } +} +POST_SYSCALL(recvmmsg) +(long long res, long long s_, void *mmsg_, long long vlen_, long long flags_, + void *timeout_) { + if (res >= 0) { + if (timeout_) { + POST_READ(timeout_, struct_timespec_sz); + } + } +} +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); + } +} +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); + } + } +} +PRE_SYSCALL(clock_nanosleep) +(long long clock_id_, long long flags_, void *rqtp_, void *rmtp_) { + if (rqtp_) { + PRE_READ(rqtp_, struct_timespec_sz); + } +} +POST_SYSCALL(clock_nanosleep) +(long long res, long long clock_id_, long long flags_, void *rqtp_, + void *rmtp_) { + if (rqtp_) { + POST_READ(rqtp_, struct_timespec_sz); + } +} +PRE_SYSCALL(___lwp_park60) +(long long clock_id_, long long flags_, void *ts_, long long unpark_, + void *hint_, void *unparkhint_) { + if (ts_) { + PRE_READ(ts_, struct_timespec_sz); + } +} +POST_SYSCALL(___lwp_park60) +(long long res, long long clock_id_, long long flags_, void *ts_, + long long unpark_, void *hint_, void *unparkhint_) { + if (res == 0) { + if (ts_) { + POST_READ(ts_, struct_timespec_sz); + } + } +} +PRE_SYSCALL(posix_fallocate) +(long long fd_, long long PAD_, long long pos_, long long len_) { + /* Nothing to do */ +} +POST_SYSCALL(posix_fallocate) +(long long res, long long fd_, long long PAD_, long long pos_, long long len_) { + /* Nothing to do */ +} +PRE_SYSCALL(fdiscard) +(long long fd_, long long PAD_, long long pos_, long long len_) { + /* Nothing to do */ +} +POST_SYSCALL(fdiscard) +(long long res, long long fd_, long long PAD_, long long pos_, long long len_) { + /* Nothing to do */ +} +PRE_SYSCALL(wait6) +(long long idtype_, long long id_, void *status_, long long options_, + void *wru_, void *info_) { + /* Nothing to do */ +} +POST_SYSCALL(wait6) +(long long res, long long idtype_, long long id_, void *status_, + long long options_, void *wru_, void *info_) { + /* Nothing to do */ +} +PRE_SYSCALL(clock_getcpuclockid2) +(long long idtype_, long long id_, void *clock_id_) { + /* Nothing to do */ +} +POST_SYSCALL(clock_getcpuclockid2) +(long long res, long long idtype_, long long id_, void *clock_id_) { + /* Nothing to do */ +} +#undef SYS_MAXSYSARGS +} // extern "C" + +#undef PRE_SYSCALL +#undef PRE_READ +#undef PRE_WRITE +#undef POST_SYSCALL +#undef POST_READ +#undef POST_WRITE + +#endif // SANITIZER_NETBSD diff --git a/libsanitizer/sanitizer_common/sanitizer_termination.cc b/libsanitizer/sanitizer_common/sanitizer_termination.cc index 6d7335112b3..79754fa1dbf 100644 --- a/libsanitizer/sanitizer_common/sanitizer_termination.cc +++ b/libsanitizer/sanitizer_common/sanitizer_termination.cc @@ -82,3 +82,12 @@ void NORETURN CheckFailed(const char *file, int line, const char *cond, } } // namespace __sanitizer + +using namespace __sanitizer; // NOLINT + +extern "C" { +SANITIZER_INTERFACE_ATTRIBUTE +void __sanitizer_set_death_callback(void (*callback)(void)) { + SetUserDieCallback(callback); +} +} // extern "C" diff --git a/libsanitizer/sanitizer_common/sanitizer_thread_registry.cc b/libsanitizer/sanitizer_common/sanitizer_thread_registry.cc index d58c93983c5..0ab1ec360ee 100644 --- a/libsanitizer/sanitizer_common/sanitizer_thread_registry.cc +++ b/libsanitizer/sanitizer_common/sanitizer_thread_registry.cc @@ -19,6 +19,7 @@ ThreadContextBase::ThreadContextBase(u32 tid) status(ThreadStatusInvalid), detached(false), workerthread(false), parent_tid(0), next(0) { name[0] = '\0'; + atomic_store(&thread_destroyed, 0, memory_order_release); } ThreadContextBase::~ThreadContextBase() { @@ -42,6 +43,14 @@ void ThreadContextBase::SetDead() { OnDead(); } +void ThreadContextBase::SetDestroyed() { + atomic_store(&thread_destroyed, 1, memory_order_release); +} + +bool ThreadContextBase::GetDestroyed() { + return !!atomic_load(&thread_destroyed, memory_order_acquire); +} + void ThreadContextBase::SetJoined(void *arg) { // FIXME(dvyukov): print message and continue (it's user error). CHECK_EQ(false, detached); @@ -83,6 +92,7 @@ void ThreadContextBase::SetCreated(uptr _user_id, u64 _unique_id, void ThreadContextBase::Reset() { status = ThreadStatusInvalid; SetName(0); + atomic_store(&thread_destroyed, 0, memory_order_release); OnReset(); } @@ -241,16 +251,25 @@ void ThreadRegistry::DetachThread(u32 tid, void *arg) { } void ThreadRegistry::JoinThread(u32 tid, void *arg) { - BlockingMutexLock l(&mtx_); - CHECK_LT(tid, n_contexts_); - ThreadContextBase *tctx = threads_[tid]; - CHECK_NE(tctx, 0); - if (tctx->status == ThreadStatusInvalid) { - Report("%s: Join of non-existent thread\n", SanitizerToolName); - return; - } - tctx->SetJoined(arg); - QuarantinePush(tctx); + bool destroyed = false; + do { + { + BlockingMutexLock l(&mtx_); + CHECK_LT(tid, n_contexts_); + ThreadContextBase *tctx = threads_[tid]; + CHECK_NE(tctx, 0); + if (tctx->status == ThreadStatusInvalid) { + Report("%s: Join of non-existent thread\n", SanitizerToolName); + return; + } + if ((destroyed = tctx->GetDestroyed())) { + tctx->SetJoined(arg); + QuarantinePush(tctx); + } + } + if (!destroyed) + internal_sched_yield(); + } while (!destroyed); } // Normally this is called when the thread is about to exit. If @@ -279,6 +298,7 @@ void ThreadRegistry::FinishThread(u32 tid) { tctx->SetDead(); QuarantinePush(tctx); } + tctx->SetDestroyed(); } void ThreadRegistry::StartThread(u32 tid, tid_t os_id, bool workerthread, diff --git a/libsanitizer/sanitizer_common/sanitizer_thread_registry.h b/libsanitizer/sanitizer_common/sanitizer_thread_registry.h index 16c2f86e1f9..7dba28c388f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_thread_registry.h +++ b/libsanitizer/sanitizer_common/sanitizer_thread_registry.h @@ -48,6 +48,8 @@ class ThreadContextBase { u32 parent_tid; ThreadContextBase *next; // For storing thread contexts in a list. + atomic_uint32_t thread_destroyed; // To address race of Joined vs Finished + void SetName(const char *new_name); void SetDead(); @@ -58,6 +60,9 @@ class ThreadContextBase { u32 _parent_tid, void *arg); void Reset(); + void SetDestroyed(); + bool GetDestroyed(); + // The following methods may be overriden by subclasses. // Some of them take opaque arg that may be optionally be used // by subclasses. diff --git a/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cc b/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cc index ebf5ec09444..f1482c2a53b 100644 --- a/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cc +++ b/libsanitizer/sanitizer_common/sanitizer_tls_get_addr.cc @@ -140,7 +140,8 @@ bool DTLSInDestruction(DTLS *dtls) { #else void DTLS_on_libc_memalign(void *ptr, uptr size) {} -DTLS::DTV *DTLS_on_tls_get_addr(void *arg, void *res) { return 0; } +DTLS::DTV *DTLS_on_tls_get_addr(void *arg, void *res, + unsigned long, unsigned long) { return 0; } DTLS *DTLS_Get() { return 0; } void DTLS_Destroy() {} bool DTLSInDestruction(DTLS *dtls) { diff --git a/libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cc b/libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cc index 7dba9e7ccd2..460c000b79f 100644 --- a/libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cc +++ b/libsanitizer/sanitizer_common/sanitizer_unwind_linux_libcdep.cc @@ -6,11 +6,12 @@ //===----------------------------------------------------------------------===// // // This file contains the unwind.h-based (aka "slow") stack unwinding routines -// available to the tools on Linux, Android, NetBSD and FreeBSD. +// available to the tools on Linux, Android, NetBSD, FreeBSD, and Solaris. //===----------------------------------------------------------------------===// #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS #include "sanitizer_common.h" #include "sanitizer_stacktrace.h" @@ -146,7 +147,7 @@ void BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context, void *map = acquire_my_map_info_list(); CHECK(map); - InternalScopedBuffer frames(kStackTraceMax); + InternalMmapVector frames(kStackTraceMax); // siginfo argument appears to be unused. sptr res = unwind_backtrace_signal_arch(/* siginfo */ 0, context, map, frames.data(), @@ -164,4 +165,5 @@ void BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context, } // namespace __sanitizer -#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || + // SANITIZER_SOLARIS diff --git a/libsanitizer/sanitizer_common/sanitizer_unwind_win.cc b/libsanitizer/sanitizer_common/sanitizer_unwind_win.cc new file mode 100644 index 00000000000..8ea62faee52 --- /dev/null +++ b/libsanitizer/sanitizer_common/sanitizer_unwind_win.cc @@ -0,0 +1,73 @@ +//===-- sanitizer_unwind_win.cc -------------------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +/// Sanitizer unwind Windows specific functions. +// +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" +#if SANITIZER_WINDOWS + +#define WIN32_LEAN_AND_MEAN +#define NOGDI +#include + +#include "sanitizer_dbghelp.h" // for StackWalk64 +#include "sanitizer_stacktrace.h" +#include "sanitizer_symbolizer.h" // for InitializeDbgHelpIfNeeded + +using namespace __sanitizer; + +#if !SANITIZER_GO +void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) { + CHECK_GE(max_depth, 2); + // FIXME: CaptureStackBackTrace might be too slow for us. + // FIXME: Compare with StackWalk64. + // FIXME: Look at LLVMUnhandledExceptionFilter in Signals.inc + size = CaptureStackBackTrace(1, Min(max_depth, kStackTraceMax), + (void **)&trace_buffer[0], 0); + if (size == 0) + return; + + // Skip the RTL frames by searching for the PC in the stacktrace. + uptr pc_location = LocatePcInTrace(pc); + PopStackFrames(pc_location); +} + +void BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context, + u32 max_depth) { + CONTEXT ctx = *(CONTEXT *)context; + STACKFRAME64 stack_frame; + memset(&stack_frame, 0, sizeof(stack_frame)); + + InitializeDbgHelpIfNeeded(); + + size = 0; +#if defined(_WIN64) + int machine_type = IMAGE_FILE_MACHINE_AMD64; + stack_frame.AddrPC.Offset = ctx.Rip; + stack_frame.AddrFrame.Offset = ctx.Rbp; + stack_frame.AddrStack.Offset = ctx.Rsp; +#else + int machine_type = IMAGE_FILE_MACHINE_I386; + stack_frame.AddrPC.Offset = ctx.Eip; + stack_frame.AddrFrame.Offset = ctx.Ebp; + stack_frame.AddrStack.Offset = ctx.Esp; +#endif + stack_frame.AddrPC.Mode = AddrModeFlat; + stack_frame.AddrFrame.Mode = AddrModeFlat; + stack_frame.AddrStack.Mode = AddrModeFlat; + while (StackWalk64(machine_type, GetCurrentProcess(), GetCurrentThread(), + &stack_frame, &ctx, NULL, SymFunctionTableAccess64, + SymGetModuleBase64, NULL) && + size < Min(max_depth, kStackTraceMax)) { + trace_buffer[size++] = (uptr)stack_frame.AddrPC.Offset; + } +} +#endif // #if !SANITIZER_GO + +#endif // SANITIZER_WINDOWS diff --git a/libsanitizer/tsan/tsan_vector.h b/libsanitizer/sanitizer_common/sanitizer_vector.h similarity index 75% rename from libsanitizer/tsan/tsan_vector.h rename to libsanitizer/sanitizer_common/sanitizer_vector.h index c0485513ee2..ad6510bbe46 100644 --- a/libsanitizer/tsan/tsan_vector.h +++ b/libsanitizer/sanitizer_common/sanitizer_vector.h @@ -1,42 +1,41 @@ -//===-- tsan_vector.h -------------------------------------------*- C++ -*-===// +//===-- sanitizer_vector.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 ThreadSanitizer (TSan), a race detector. +// This file is shared between sanitizers run-time libraries. // //===----------------------------------------------------------------------===// // Low-fat STL-like vector container. -#ifndef TSAN_VECTOR_H -#define TSAN_VECTOR_H +#ifndef SANITIZER_VECTOR_H +#define SANITIZER_VECTOR_H -#include "tsan_defs.h" -#include "tsan_mman.h" +#include "sanitizer_common/sanitizer_allocator_internal.h" +#include "sanitizer_common/sanitizer_libc.h" -namespace __tsan { +namespace __sanitizer { template class Vector { public: - explicit Vector(MBlockType typ) - : typ_(typ) - , begin_() + explicit Vector() + : begin_() , end_() , last_() { } ~Vector() { if (begin_) - internal_free(begin_); + InternalFree(begin_); } void Reset() { if (begin_) - internal_free(begin_); + InternalFree(begin_); begin_ = 0; end_ = 0; last_ = 0; @@ -81,6 +80,10 @@ class Vector { return; } uptr old_size = Size(); + if (size <= old_size) { + end_ = begin_ + size; + return; + } EnsureSize(size); if (old_size < size) { for (uptr i = old_size; i < size; i++) @@ -89,7 +92,6 @@ class Vector { } private: - const MBlockType typ_; T *begin_; T *end_; T *last_; @@ -107,10 +109,10 @@ class Vector { cap = 16; if (cap < size) cap = size; - T *p = (T*)internal_alloc(typ_, cap * sizeof(T)); + T *p = (T*)InternalAlloc(cap * sizeof(T)); if (cap0) { internal_memcpy(p, begin_, cap0 * sizeof(T)); - internal_free(begin_); + InternalFree(begin_); } begin_ = p; end_ = begin_ + size; @@ -120,6 +122,6 @@ class Vector { Vector(const Vector&); void operator=(const Vector&); }; -} // namespace __tsan +} // namespace __sanitizer -#endif // #ifndef TSAN_VECTOR_H +#endif // #ifndef SANITIZER_VECTOR_H diff --git a/libsanitizer/sanitizer_common/sanitizer_win.cc b/libsanitizer/sanitizer_common/sanitizer_win.cc index 84e66b43c99..ebc6c503036 100644 --- a/libsanitizer/sanitizer_common/sanitizer_win.cc +++ b/libsanitizer/sanitizer_common/sanitizer_win.cc @@ -21,15 +21,16 @@ #include #include "sanitizer_common.h" -#include "sanitizer_dbghelp.h" #include "sanitizer_file.h" #include "sanitizer_libc.h" #include "sanitizer_mutex.h" #include "sanitizer_placement_new.h" -#include "sanitizer_stacktrace.h" -#include "sanitizer_symbolizer.h" #include "sanitizer_win_defs.h" +#if defined(PSAPI_VERSION) && PSAPI_VERSION == 1 +#pragma comment(lib, "psapi") +#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 // code that is called when terminating the process, the expansion of the @@ -62,12 +63,16 @@ uptr GetMmapGranularity() { return si.dwAllocationGranularity; } -uptr GetMaxVirtualAddress() { +uptr GetMaxUserVirtualAddress() { SYSTEM_INFO si; GetSystemInfo(&si); return (uptr)si.lpMaximumApplicationAddress; } +uptr GetMaxVirtualAddress() { + return GetMaxUserVirtualAddress(); +} + bool FileExists(const char *filename) { return ::GetFileAttributesA(filename) != INVALID_FILE_ATTRIBUTES; } @@ -199,7 +204,7 @@ void *MmapAlignedOrDieOnFatalError(uptr size, uptr alignment, return (void *)mapped_addr; } -void *MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) { +bool MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) { // FIXME: is this really "NoReserve"? On Win32 this does not matter much, // but on Win64 it does. (void)name; // unsupported @@ -212,11 +217,13 @@ void *MmapFixedNoReserve(uptr fixed_addr, uptr size, const char *name) { void *p = VirtualAlloc((LPVOID)fixed_addr, size, MEM_RESERVE | MEM_COMMIT, PAGE_READWRITE); #endif - if (p == 0) + if (p == 0) { Report("ERROR: %s failed to " "allocate %p (%zd) bytes at %p (error code: %d)\n", SanitizerToolName, size, size, fixed_addr, GetLastError()); - return p; + return false; + } + return true; } // Memory space mapped by 'MmapFixedOrDie' must have been reserved by @@ -233,6 +240,25 @@ void *MmapFixedOrDie(uptr fixed_addr, uptr size) { return p; } +// 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::MapOrDie(uptr fixed_addr, uptr size) { + return reinterpret_cast(MmapFixedOrDie(fixed_addr, size)); +} + +void ReservedAddressRange::Unmap(uptr addr, uptr size) { + // Only unmap if it covers the entire range. + CHECK((addr == reinterpret_cast(base_)) && (size == size_)); + // We unmap the whole range, just null out the base. + base_ = nullptr; + size_ = 0; + UnmapOrDie(reinterpret_cast(addr), size); +} + void *MmapFixedOrDieOnFatalError(uptr fixed_addr, uptr size) { void *p = VirtualAlloc((LPVOID)fixed_addr, size, MEM_COMMIT, PAGE_READWRITE); @@ -250,6 +276,15 @@ void *MmapNoReserveOrDie(uptr size, const char *mem_type) { return MmapOrDie(size, mem_type); } +uptr ReservedAddressRange::Init(uptr size, const char *name, uptr fixed_addr) { + base_ = fixed_addr ? MmapFixedNoAccess(fixed_addr, size) : MmapNoAccess(size); + size_ = size; + name_ = name; + (void)os_handle_; // unsupported + return reinterpret_cast(base_); +} + + void *MmapFixedNoAccess(uptr fixed_addr, uptr size, const char *name) { (void)name; // unsupported void *res = VirtualAlloc((LPVOID)fixed_addr, size, @@ -280,17 +315,20 @@ void ReleaseMemoryPagesToOS(uptr beg, uptr end) { // FIXME: add madvise-analog when we move to 64-bits. } -void NoHugePagesInRegion(uptr addr, uptr size) { +bool NoHugePagesInRegion(uptr addr, uptr size) { // FIXME: probably similar to ReleaseMemoryToOS. + return true; } -void DontDumpShadowMemory(uptr addr, uptr length) { +bool DontDumpShadowMemory(uptr addr, uptr length) { // This is almost useless on 32-bits. // FIXME: add madvise-analog when we move to 64-bits. + return true; } uptr FindAvailableMemoryRange(uptr size, uptr alignment, uptr left_padding, - uptr *largest_gap_found) { + uptr *largest_gap_found, + uptr *max_occupied_addr) { uptr address = 0; while (true) { MEMORY_BASIC_INFORMATION info; @@ -377,7 +415,7 @@ struct ModuleInfo { #if !SANITIZER_GO int CompareModulesBase(const void *pl, const void *pr) { - const ModuleInfo *l = (ModuleInfo *)pl, *r = (ModuleInfo *)pr; + const ModuleInfo *l = (const ModuleInfo *)pl, *r = (const ModuleInfo *)pr; if (l->base_address < r->base_address) return -1; return l->base_address > r->base_address; @@ -392,7 +430,7 @@ void DumpProcessMap() { modules.init(); uptr num_modules = modules.size(); - InternalScopedBuffer module_infos(num_modules); + InternalMmapVector module_infos(num_modules); for (size_t i = 0; i < num_modules; ++i) { module_infos[i].filepath = modules[i].full_name(); module_infos[i].base_address = modules[i].ranges().front()->beg; @@ -425,8 +463,7 @@ void ReExec() { UNIMPLEMENTED(); } -void PrepareForSandboxing(__sanitizer_sandbox_arguments *args) { -} +void PlatformPrepareForSandboxing(__sanitizer_sandbox_arguments *args) {} bool StackSizeIsUnlimited() { UNIMPLEMENTED(); @@ -461,9 +498,20 @@ void SleepForMillis(int millis) { } u64 NanoTime() { - return 0; + static LARGE_INTEGER frequency = {}; + LARGE_INTEGER counter; + if (UNLIKELY(frequency.QuadPart == 0)) { + QueryPerformanceFrequency(&frequency); + CHECK_NE(frequency.QuadPart, 0); + } + QueryPerformanceCounter(&counter); + counter.QuadPart *= 1000ULL * 1000000ULL; + counter.QuadPart /= frequency.QuadPart; + return counter.QuadPart; } +u64 MonotonicNanoTime() { return NanoTime(); } + void Abort() { internal__exit(3); } @@ -711,50 +759,32 @@ uptr internal_ftruncate(fd_t fd, uptr size) { } uptr GetRSS() { - return 0; + PROCESS_MEMORY_COUNTERS counters; + if (!GetProcessMemoryInfo(GetCurrentProcess(), &counters, sizeof(counters))) + return 0; + return counters.WorkingSetSize; } void *internal_start_thread(void (*func)(void *arg), void *arg) { return 0; } void internal_join_thread(void *th) { } // ---------------------- BlockingMutex ---------------- {{{1 -const uptr LOCK_UNINITIALIZED = 0; -const uptr LOCK_READY = (uptr)-1; - -BlockingMutex::BlockingMutex(LinkerInitialized li) { - // FIXME: see comments in BlockingMutex::Lock() for the details. - CHECK(li == LINKER_INITIALIZED || owner_ == LOCK_UNINITIALIZED); - - CHECK(sizeof(CRITICAL_SECTION) <= sizeof(opaque_storage_)); - InitializeCriticalSection((LPCRITICAL_SECTION)opaque_storage_); - owner_ = LOCK_READY; -} BlockingMutex::BlockingMutex() { - CHECK(sizeof(CRITICAL_SECTION) <= sizeof(opaque_storage_)); - InitializeCriticalSection((LPCRITICAL_SECTION)opaque_storage_); - owner_ = LOCK_READY; + CHECK(sizeof(SRWLOCK) <= sizeof(opaque_storage_)); + internal_memset(this, 0, sizeof(*this)); } void BlockingMutex::Lock() { - if (owner_ == LOCK_UNINITIALIZED) { - // FIXME: hm, global BlockingMutex objects are not initialized?!? - // This might be a side effect of the clang+cl+link Frankenbuild... - new(this) BlockingMutex((LinkerInitialized)(LINKER_INITIALIZED + 1)); - - // FIXME: If it turns out the linker doesn't invoke our - // constructors, we should probably manually Lock/Unlock all the global - // locks while we're starting in one thread to avoid double-init races. - } - EnterCriticalSection((LPCRITICAL_SECTION)opaque_storage_); - CHECK_EQ(owner_, LOCK_READY); + AcquireSRWLockExclusive((PSRWLOCK)opaque_storage_); + CHECK_EQ(owner_, 0); owner_ = GetThreadSelf(); } void BlockingMutex::Unlock() { - CHECK_EQ(owner_, GetThreadSelf()); - owner_ = LOCK_READY; - LeaveCriticalSection((LPCRITICAL_SECTION)opaque_storage_); + CheckLocked(); + owner_ = 0; + ReleaseSRWLockExclusive((PSRWLOCK)opaque_storage_); } void BlockingMutex::CheckLocked() { @@ -785,54 +815,6 @@ void GetThreadStackAndTls(bool main, uptr *stk_addr, uptr *stk_size, #endif } -#if !SANITIZER_GO -void BufferedStackTrace::SlowUnwindStack(uptr pc, u32 max_depth) { - CHECK_GE(max_depth, 2); - // FIXME: CaptureStackBackTrace might be too slow for us. - // FIXME: Compare with StackWalk64. - // FIXME: Look at LLVMUnhandledExceptionFilter in Signals.inc - size = CaptureStackBackTrace(1, Min(max_depth, kStackTraceMax), - (void**)trace, 0); - if (size == 0) - return; - - // Skip the RTL frames by searching for the PC in the stacktrace. - uptr pc_location = LocatePcInTrace(pc); - PopStackFrames(pc_location); -} - -void BufferedStackTrace::SlowUnwindStackWithContext(uptr pc, void *context, - u32 max_depth) { - CONTEXT ctx = *(CONTEXT *)context; - STACKFRAME64 stack_frame; - memset(&stack_frame, 0, sizeof(stack_frame)); - - InitializeDbgHelpIfNeeded(); - - size = 0; -#if defined(_WIN64) - int machine_type = IMAGE_FILE_MACHINE_AMD64; - stack_frame.AddrPC.Offset = ctx.Rip; - stack_frame.AddrFrame.Offset = ctx.Rbp; - stack_frame.AddrStack.Offset = ctx.Rsp; -#else - int machine_type = IMAGE_FILE_MACHINE_I386; - stack_frame.AddrPC.Offset = ctx.Eip; - stack_frame.AddrFrame.Offset = ctx.Ebp; - stack_frame.AddrStack.Offset = ctx.Esp; -#endif - stack_frame.AddrPC.Mode = AddrModeFlat; - stack_frame.AddrFrame.Mode = AddrModeFlat; - stack_frame.AddrStack.Mode = AddrModeFlat; - while (StackWalk64(machine_type, GetCurrentProcess(), GetCurrentThread(), - &stack_frame, &ctx, NULL, SymFunctionTableAccess64, - SymGetModuleBase64, NULL) && - size < Min(max_depth, kStackTraceMax)) { - trace_buffer[size++] = (uptr)stack_frame.AddrPC.Offset; - } -} -#endif // #if !SANITIZER_GO - void ReportFile::Write(const char *buffer, uptr length) { SpinMutexLock l(mu); ReopenIfNecessary(); @@ -915,7 +897,7 @@ bool IsAccessibleMemoryRange(uptr beg, uptr size) { } bool SignalContext::IsStackOverflow() const { - return GetType() == EXCEPTION_STACK_OVERFLOW; + return (DWORD)GetType() == EXCEPTION_STACK_OVERFLOW; } void SignalContext::InitPcSpBp() { @@ -1028,6 +1010,10 @@ void MaybeReexec() { // No need to re-exec on Windows. } +void CheckASLR() { + // Do nothing +} + char **GetArgv() { // FIXME: Actually implement this function. return 0; @@ -1061,6 +1047,12 @@ bool GetRandom(void *buffer, uptr length, bool blocking) { UNIMPLEMENTED(); } +u32 GetNumberOfCPUs() { + SYSTEM_INFO sysinfo = {}; + GetNativeSystemInfo(&sysinfo); + return sysinfo.dwNumberOfProcessors; +} + } // namespace __sanitizer #endif // _WIN32 diff --git a/libsanitizer/sanitizer_common/sanitizer_win_defs.h b/libsanitizer/sanitizer_common/sanitizer_win_defs.h index e71081db575..1b1a86c4719 100644 --- a/libsanitizer/sanitizer_common/sanitizer_win_defs.h +++ b/libsanitizer/sanitizer_common/sanitizer_win_defs.h @@ -15,17 +15,27 @@ #if SANITIZER_WINDOWS #ifndef WINAPI -#ifdef _M_IX86 +#if defined(_M_IX86) || defined(__i386__) #define WINAPI __stdcall #else #define WINAPI #endif #endif -#if defined(_WIN64) +#if defined(_M_IX86) || defined(__i386__) +#define WIN_SYM_PREFIX "_" +#else #define WIN_SYM_PREFIX +#endif + +// For MinGW, the /export: directives contain undecorated symbols, contrary to +// link/lld-link. The GNU linker doesn't support /alternatename and /include +// though, thus lld-link in MinGW mode interprets them in the same way as +// in the default mode. +#ifdef __MINGW32__ +#define WIN_EXPORT_PREFIX #else -#define WIN_SYM_PREFIX "_" +#define WIN_EXPORT_PREFIX WIN_SYM_PREFIX #endif // Intermediate macro to ensure the parameter is expanded before stringified. @@ -60,8 +70,8 @@ __pragma(comment(linker, "/include:" WIN_SYM_PREFIX STRINGIFY(Name))) #define WIN_EXPORT(ExportedName, Name) \ - __pragma(comment(linker, "/export:" WIN_SYM_PREFIX STRINGIFY(ExportedName) \ - "=" WIN_SYM_PREFIX STRINGIFY(Name))) + __pragma(comment(linker, "/export:" WIN_EXPORT_PREFIX STRINGIFY(ExportedName)\ + "=" WIN_EXPORT_PREFIX STRINGIFY(Name))) // We cannot define weak functions on Windows, but we can use WIN_WEAK_ALIAS() // which defines an alias to a default implementation, and only works when diff --git a/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.cc b/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.cc index dffec0c7943..3ee428b4723 100644 --- a/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.cc +++ b/libsanitizer/sanitizer_common/sanitizer_win_weak_interception.cc @@ -10,7 +10,7 @@ // definition is provided. //===----------------------------------------------------------------------===// -#include "sanitizer_common/sanitizer_platform.h" +#include "sanitizer_platform.h" #if SANITIZER_WINDOWS && SANITIZER_DYNAMIC #include "sanitizer_win_weak_interception.h" #include "sanitizer_allocator_interface.h" diff --git a/libsanitizer/tsan/tsan_debugging.cc b/libsanitizer/tsan/tsan_debugging.cc index 9a9c67fc42e..722b6c1b470 100644 --- a/libsanitizer/tsan/tsan_debugging.cc +++ b/libsanitizer/tsan/tsan_debugging.cc @@ -80,6 +80,13 @@ int __tsan_get_report_data(void *report, const char **description, int *count, return 1; } +SANITIZER_INTERFACE_ATTRIBUTE +int __tsan_get_report_tag(void *report, uptr *tag) { + const ReportDesc *rep = (ReportDesc *)report; + *tag = rep->tag; + return 1; +} + SANITIZER_INTERFACE_ATTRIBUTE int __tsan_get_report_stack(void *report, uptr idx, void **trace, uptr trace_size) { diff --git a/libsanitizer/tsan/tsan_interceptors.cc b/libsanitizer/tsan/tsan_interceptors.cc index 15f20d4b668..069df5951d8 100644 --- a/libsanitizer/tsan/tsan_interceptors.cc +++ b/libsanitizer/tsan/tsan_interceptors.cc @@ -41,8 +41,16 @@ using namespace __tsan; // NOLINT #if SANITIZER_NETBSD #define dirfd(dirp) (*(int *)(dirp)) #define fileno_unlocked fileno -#define stdout __sF[1] -#define stderr __sF[2] + +#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)) + #endif #if SANITIZER_ANDROID @@ -55,11 +63,6 @@ const int kSigCount = 129; const int kSigCount = 65; #endif -struct my_siginfo_t { - // The size is determined by looking at sizeof of real siginfo_t on linux. - u64 opaque[128 / sizeof(u64)]; -}; - #ifdef __mips__ struct ucontext_t { u64 opaque[768 / sizeof(u64) + 1]; @@ -97,7 +100,7 @@ extern "C" int dirfd(void *dirp); extern "C" int mallopt(int param, int value); #endif #if SANITIZER_NETBSD -extern __sanitizer_FILE **__sF; +extern __sanitizer_FILE __sF[]; #else extern __sanitizer_FILE *stdout, *stderr; #endif @@ -139,56 +142,6 @@ typedef long long_t; // NOLINT # define F_TLOCK 2 /* Test and lock a region for exclusive use. */ # define F_TEST 3 /* Test a region for other processes locks. */ -typedef void (*sighandler_t)(int sig); -typedef void (*sigactionhandler_t)(int sig, my_siginfo_t *siginfo, void *uctx); - -#if SANITIZER_ANDROID -struct sigaction_t { - u32 sa_flags; - union { - sighandler_t sa_handler; - sigactionhandler_t sa_sigaction; - }; - __sanitizer_sigset_t sa_mask; - void (*sa_restorer)(); -}; -#elif SANITIZER_NETBSD -struct sigaction_t { - union { - sighandler_t sa_handler; - sigactionhandler_t sa_sigaction; - }; - __sanitizer_sigset_t sa_mask; - int sa_flags; -}; -#else -struct sigaction_t { -#ifdef __mips__ - u32 sa_flags; -#endif - union { - sighandler_t sa_handler; - sigactionhandler_t sa_sigaction; - }; -#if SANITIZER_FREEBSD - int sa_flags; - __sanitizer_sigset_t sa_mask; -#elif SANITIZER_MAC - __sanitizer_sigset_t sa_mask; - int sa_flags; -#else - __sanitizer_sigset_t sa_mask; -#ifndef __mips__ - int sa_flags; -#endif - void (*sa_restorer)(); -#endif -}; -#endif - -const sighandler_t SIG_DFL = (sighandler_t)0; -const sighandler_t SIG_IGN = (sighandler_t)1; -const sighandler_t SIG_ERR = (sighandler_t)-1; #if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD const int SA_SIGINFO = 0x40; const int SIG_SETMASK = 3; @@ -203,13 +156,11 @@ const int SIG_SETMASK = 2; #define COMMON_INTERCEPTOR_NOTHING_IS_INITIALIZED \ (!cur_thread()->is_inited) -static sigaction_t sigactions[kSigCount]; - namespace __tsan { struct SignalDesc { bool armed; bool sigaction; - my_siginfo_t siginfo; + __sanitizer_siginfo siginfo; ucontext_t ctx; }; @@ -223,11 +174,41 @@ struct ThreadSignalContext { __sanitizer_sigset_t oldset; }; -// The object is 64-byte aligned, because we want hot data to be located in -// a single cache line if possible (it's accessed in every interceptor). -static ALIGNED(64) char libignore_placeholder[sizeof(LibIgnore)]; +// The sole reason tsan wraps atexit callbacks is to establish synchronization +// between callback setup and callback execution. +struct AtExitCtx { + void (*f)(); + void *arg; +}; + +// InterceptorContext holds all global data required for interceptors. +// It's explicitly constructed in InitializeInterceptors with placement new +// and is never destroyed. This allows usage of members with non-trivial +// constructors and destructors. +struct InterceptorContext { + // The object is 64-byte aligned, because we want hot data to be located + // in a single cache line if possible (it's accessed in every interceptor). + ALIGNED(64) LibIgnore libignore; + __sanitizer_sigaction sigactions[kSigCount]; +#if !SANITIZER_MAC && !SANITIZER_NETBSD + unsigned finalize_key; +#endif + + BlockingMutex atexit_mu; + Vector AtExitStack; + + InterceptorContext() + : libignore(LINKER_INITIALIZED), AtExitStack() { + } +}; + +static ALIGNED(64) char interceptor_placeholder[sizeof(InterceptorContext)]; +InterceptorContext *interceptor_ctx() { + return reinterpret_cast(&interceptor_placeholder[0]); +} + LibIgnore *libignore() { - return reinterpret_cast(&libignore_placeholder[0]); + return &interceptor_ctx()->libignore; } void InitializeLibIgnore() { @@ -255,10 +236,6 @@ static ThreadSignalContext *SigCtx(ThreadState *thr) { return ctx; } -#if !SANITIZER_MAC -static unsigned g_thread_finalize_key; -#endif - ScopedInterceptor::ScopedInterceptor(ThreadState *thr, const char *fname, uptr pc) : thr_(thr), pc_(pc), in_ignored_lib_(false), ignoring_(false) { @@ -305,10 +282,20 @@ void ScopedInterceptor::DisableIgnores() { } #define TSAN_INTERCEPT(func) INTERCEPT_FUNCTION(func) -#if SANITIZER_FREEBSD || SANITIZER_NETBSD +#if SANITIZER_FREEBSD # define TSAN_INTERCEPT_VER(func, ver) INTERCEPT_FUNCTION(func) +# define TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(func) +# define TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS_THR(func) +#elif SANITIZER_NETBSD +# define TSAN_INTERCEPT_VER(func, ver) INTERCEPT_FUNCTION(func) +# define TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(func) \ + INTERCEPT_FUNCTION(__libc_##func) +# define TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS_THR(func) \ + INTERCEPT_FUNCTION(__libc_thr_##func) #else # define TSAN_INTERCEPT_VER(func, ver) INTERCEPT_FUNCTION_VER(func, ver) +# define TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(func) +# define TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS_THR(func) #endif #define READ_STRING_OF_LEN(thr, pc, s, len, n) \ @@ -369,22 +356,30 @@ TSAN_INTERCEPTOR(int, nanosleep, void *req, void *rem) { return res; } -TSAN_INTERCEPTOR(int, pause) { - SCOPED_TSAN_INTERCEPTOR(pause); - return BLOCK_REAL(pause)(); +TSAN_INTERCEPTOR(int, pause, int fake) { + SCOPED_TSAN_INTERCEPTOR(pause, fake); + return BLOCK_REAL(pause)(fake); } -// The sole reason tsan wraps atexit callbacks is to establish synchronization -// between callback setup and callback execution. -struct AtExitCtx { - void (*f)(); - void *arg; -}; +static void at_exit_wrapper() { + AtExitCtx *ctx; + { + // Ensure thread-safety. + BlockingMutexLock l(&interceptor_ctx()->atexit_mu); -static void at_exit_wrapper(void *arg) { - ThreadState *thr = cur_thread(); - uptr pc = 0; - Acquire(thr, pc, (uptr)arg); + // Pop AtExitCtx from the top of the stack of callback functions + uptr element = interceptor_ctx()->AtExitStack.Size() - 1; + ctx = interceptor_ctx()->AtExitStack[element]; + interceptor_ctx()->AtExitStack.PopBack(); + } + + Acquire(cur_thread(), (uptr)0, (uptr)ctx); + ((void(*)())ctx->f)(); + InternalFree(ctx); +} + +static void cxa_at_exit_wrapper(void *arg) { + Acquire(cur_thread(), 0, (uptr)arg); AtExitCtx *ctx = (AtExitCtx*)arg; ((void(*)(void *arg))ctx->f)(ctx->arg); InternalFree(ctx); @@ -395,7 +390,7 @@ static int setup_at_exit_wrapper(ThreadState *thr, uptr pc, void(*f)(), #if !SANITIZER_ANDROID TSAN_INTERCEPTOR(int, atexit, void (*f)()) { - if (cur_thread()->in_symbolizer) + if (UNLIKELY(cur_thread()->in_symbolizer)) return 0; // We want to setup the atexit callback even if we are in ignored lib // or after fork. @@ -405,7 +400,7 @@ TSAN_INTERCEPTOR(int, atexit, void (*f)()) { #endif TSAN_INTERCEPTOR(int, __cxa_atexit, void (*f)(void *a), void *arg, void *dso) { - if (cur_thread()->in_symbolizer) + if (UNLIKELY(cur_thread()->in_symbolizer)) return 0; SCOPED_TSAN_INTERCEPTOR(__cxa_atexit, f, arg, dso); return setup_at_exit_wrapper(thr, pc, (void(*)())f, arg, dso); @@ -420,12 +415,27 @@ static int setup_at_exit_wrapper(ThreadState *thr, uptr pc, void(*f)(), // Memory allocation in __cxa_atexit will race with free during exit, // because we do not see synchronization around atexit callback list. ThreadIgnoreBegin(thr, pc); - int res = REAL(__cxa_atexit)(at_exit_wrapper, ctx, dso); + int res; + if (!dso) { + // NetBSD does not preserve the 2nd argument if dso is equal to 0 + // Store ctx in a local stack-like structure + + // Ensure thread-safety. + BlockingMutexLock l(&interceptor_ctx()->atexit_mu); + + res = REAL(__cxa_atexit)((void (*)(void *a))at_exit_wrapper, 0, 0); + // Push AtExitCtx on the top of the stack of callback functions + if (!res) { + interceptor_ctx()->AtExitStack.PushBack(ctx); + } + } else { + res = REAL(__cxa_atexit)(cxa_at_exit_wrapper, ctx, dso); + } ThreadIgnoreEnd(thr, pc); return res; } -#if !SANITIZER_MAC +#if !SANITIZER_MAC && !SANITIZER_NETBSD static void on_exit_wrapper(int status, void *arg) { ThreadState *thr = cur_thread(); uptr pc = 0; @@ -436,7 +446,7 @@ static void on_exit_wrapper(int status, void *arg) { } TSAN_INTERCEPTOR(int, on_exit, void(*f)(int, void*), void *arg) { - if (cur_thread()->in_symbolizer) + if (UNLIKELY(cur_thread()->in_symbolizer)) return 0; SCOPED_TSAN_INTERCEPTOR(on_exit, f, arg); AtExitCtx *ctx = (AtExitCtx*)InternalAlloc(sizeof(AtExitCtx)); @@ -450,6 +460,9 @@ TSAN_INTERCEPTOR(int, on_exit, void(*f)(int, void*), void *arg) { ThreadIgnoreEnd(thr, pc); return res; } +#define TSAN_MAYBE_INTERCEPT_ON_EXIT TSAN_INTERCEPT(on_exit) +#else +#define TSAN_MAYBE_INTERCEPT_ON_EXIT #endif // Cleanup old bufs. @@ -487,15 +500,18 @@ 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 || SANITIZER_NETBSD +#elif SANITIZER_FREEBSD uptr mangled_sp = env[2]; +#elif SANITIZER_NETBSD + uptr mangled_sp = env[6]; #elif SANITIZER_MAC # ifdef __aarch64__ - uptr mangled_sp = env[13]; + uptr mangled_sp = + (GetMacosVersion() >= MACOS_VERSION_MOJAVE) ? env[12] : env[13]; # else uptr mangled_sp = env[2]; # endif -#elif defined(SANITIZER_LINUX) +#elif SANITIZER_LINUX # ifdef __aarch64__ uptr mangled_sp = env[13]; # elif defined(__mips64) @@ -538,10 +554,27 @@ TSAN_INTERCEPTOR(int, setjmp, void *env); TSAN_INTERCEPTOR(int, _setjmp, void *env); TSAN_INTERCEPTOR(int, sigsetjmp, void *env); #else // SANITIZER_MAC + +#if SANITIZER_NETBSD +#define setjmp_symname __setjmp14 +#define sigsetjmp_symname __sigsetjmp14 +#else +#define setjmp_symname setjmp +#define sigsetjmp_symname sigsetjmp +#endif + +#define TSAN_INTERCEPTOR_SETJMP_(x) __interceptor_ ## x +#define TSAN_INTERCEPTOR_SETJMP__(x) TSAN_INTERCEPTOR_SETJMP_(x) +#define TSAN_INTERCEPTOR_SETJMP TSAN_INTERCEPTOR_SETJMP__(setjmp_symname) +#define TSAN_INTERCEPTOR_SIGSETJMP TSAN_INTERCEPTOR_SETJMP__(sigsetjmp_symname) + +#define TSAN_STRING_SETJMP SANITIZER_STRINGIFY(setjmp_symname) +#define TSAN_STRING_SIGSETJMP SANITIZER_STRINGIFY(sigsetjmp_symname) + // Not called. Merely to satisfy TSAN_INTERCEPT(). extern "C" SANITIZER_INTERFACE_ATTRIBUTE -int __interceptor_setjmp(void *env); -extern "C" int __interceptor_setjmp(void *env) { +int TSAN_INTERCEPTOR_SETJMP(void *env); +extern "C" int TSAN_INTERCEPTOR_SETJMP(void *env) { CHECK(0); return 0; } @@ -555,51 +588,75 @@ extern "C" int __interceptor__setjmp(void *env) { } extern "C" SANITIZER_INTERFACE_ATTRIBUTE -int __interceptor_sigsetjmp(void *env); -extern "C" int __interceptor_sigsetjmp(void *env) { +int TSAN_INTERCEPTOR_SIGSETJMP(void *env); +extern "C" int TSAN_INTERCEPTOR_SIGSETJMP(void *env) { CHECK(0); return 0; } +#if !SANITIZER_NETBSD extern "C" SANITIZER_INTERFACE_ATTRIBUTE int __interceptor___sigsetjmp(void *env); extern "C" int __interceptor___sigsetjmp(void *env) { CHECK(0); return 0; } +#endif -extern "C" int setjmp(void *env); +extern "C" int setjmp_symname(void *env); extern "C" int _setjmp(void *env); -extern "C" int sigsetjmp(void *env); +extern "C" int sigsetjmp_symname(void *env); +#if !SANITIZER_NETBSD extern "C" int __sigsetjmp(void *env); -DEFINE_REAL(int, setjmp, void *env) +#endif +DEFINE_REAL(int, setjmp_symname, void *env) DEFINE_REAL(int, _setjmp, void *env) -DEFINE_REAL(int, sigsetjmp, void *env) +DEFINE_REAL(int, sigsetjmp_symname, void *env) +#if !SANITIZER_NETBSD DEFINE_REAL(int, __sigsetjmp, void *env) +#endif #endif // SANITIZER_MAC -TSAN_INTERCEPTOR(void, longjmp, uptr *env, int val) { +#if SANITIZER_NETBSD +#define longjmp_symname __longjmp14 +#define siglongjmp_symname __siglongjmp14 +#else +#define longjmp_symname longjmp +#define siglongjmp_symname siglongjmp +#endif + +TSAN_INTERCEPTOR(void, longjmp_symname, uptr *env, int val) { // Note: if we call REAL(longjmp) in the context of ScopedInterceptor, // bad things will happen. We will jump over ScopedInterceptor dtor and can // leave thr->in_ignored_lib set. { - SCOPED_INTERCEPTOR_RAW(longjmp, env, val); + SCOPED_INTERCEPTOR_RAW(longjmp_symname, env, val); + } + LongJmp(cur_thread(), env); + REAL(longjmp_symname)(env, val); +} + +TSAN_INTERCEPTOR(void, siglongjmp_symname, uptr *env, int val) { + { + SCOPED_INTERCEPTOR_RAW(siglongjmp_symname, env, val); } LongJmp(cur_thread(), env); - REAL(longjmp)(env, val); + REAL(siglongjmp_symname)(env, val); } -TSAN_INTERCEPTOR(void, siglongjmp, uptr *env, int val) { +#if SANITIZER_NETBSD +TSAN_INTERCEPTOR(void, _longjmp, uptr *env, int val) { { - SCOPED_INTERCEPTOR_RAW(siglongjmp, env, val); + SCOPED_INTERCEPTOR_RAW(_longjmp, env, val); } LongJmp(cur_thread(), env); - REAL(siglongjmp)(env, val); + REAL(_longjmp)(env, val); } +#endif #if !SANITIZER_MAC TSAN_INTERCEPTOR(void*, malloc, uptr size) { - if (cur_thread()->in_symbolizer) + if (UNLIKELY(cur_thread()->in_symbolizer)) return InternalAlloc(size); void *p = 0; { @@ -616,7 +673,7 @@ TSAN_INTERCEPTOR(void*, __libc_memalign, uptr align, uptr sz) { } TSAN_INTERCEPTOR(void*, calloc, uptr size, uptr n) { - if (cur_thread()->in_symbolizer) + if (UNLIKELY(cur_thread()->in_symbolizer)) return InternalCalloc(size, n); void *p = 0; { @@ -628,7 +685,7 @@ TSAN_INTERCEPTOR(void*, calloc, uptr size, uptr n) { } TSAN_INTERCEPTOR(void*, realloc, void *p, uptr size) { - if (cur_thread()->in_symbolizer) + if (UNLIKELY(cur_thread()->in_symbolizer)) return InternalRealloc(p, size); if (p) invoke_free_hook(p); @@ -643,7 +700,7 @@ TSAN_INTERCEPTOR(void*, realloc, void *p, uptr size) { TSAN_INTERCEPTOR(void, free, void *p) { if (p == 0) return; - if (cur_thread()->in_symbolizer) + if (UNLIKELY(cur_thread()->in_symbolizer)) return InternalFree(p); invoke_free_hook(p); SCOPED_INTERCEPTOR_RAW(free, p); @@ -653,7 +710,7 @@ TSAN_INTERCEPTOR(void, free, void *p) { TSAN_INTERCEPTOR(void, cfree, void *p) { if (p == 0) return; - if (cur_thread()->in_symbolizer) + if (UNLIKELY(cur_thread()->in_symbolizer)) return InternalFree(p); invoke_free_hook(p); SCOPED_INTERCEPTOR_RAW(cfree, p); @@ -702,35 +759,14 @@ static bool fix_mmap_addr(void **addr, long_t sz, int flags) { return true; } -TSAN_INTERCEPTOR(void *, mmap, void *addr, SIZE_T sz, int prot, int flags, - int fd, OFF_T off) { - SCOPED_TSAN_INTERCEPTOR(mmap, addr, sz, prot, flags, fd, off); - if (!fix_mmap_addr(&addr, sz, flags)) - return MAP_FAILED; - void *res = REAL(mmap)(addr, sz, prot, flags, fd, off); - if (res != MAP_FAILED) { - if (fd > 0) - FdAccess(thr, pc, fd); - - if (thr->ignore_reads_and_writes == 0) - MemoryRangeImitateWrite(thr, pc, (uptr)res, sz); - else - MemoryResetRange(thr, pc, (uptr)res, sz); - } - return res; -} - -#if SANITIZER_LINUX -TSAN_INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, - int fd, OFF64_T off) { - SCOPED_TSAN_INTERCEPTOR(mmap64, addr, sz, prot, flags, fd, off); - if (!fix_mmap_addr(&addr, sz, flags)) - return MAP_FAILED; - void *res = REAL(mmap64)(addr, sz, prot, flags, fd, off); +template +static void *mmap_interceptor(ThreadState *thr, uptr pc, Mmap real_mmap, + void *addr, SIZE_T sz, int prot, int flags, + int fd, OFF64_T off) { + if (!fix_mmap_addr(&addr, sz, flags)) return MAP_FAILED; + void *res = real_mmap(addr, sz, prot, flags, fd, off); if (res != MAP_FAILED) { - if (fd > 0) - FdAccess(thr, pc, fd); - + if (fd > 0) FdAccess(thr, pc, fd); if (thr->ignore_reads_and_writes == 0) MemoryRangeImitateWrite(thr, pc, (uptr)res, sz); else @@ -738,10 +774,6 @@ TSAN_INTERCEPTOR(void *, mmap64, void *addr, SIZE_T sz, int prot, int flags, } return res; } -#define TSAN_MAYBE_INTERCEPT_MMAP64 TSAN_INTERCEPT(mmap64) -#else -#define TSAN_MAYBE_INTERCEPT_MMAP64 -#endif TSAN_INTERCEPTOR(int, munmap, void *addr, long_t sz) { SCOPED_TSAN_INTERCEPTOR(munmap, addr, sz); @@ -767,11 +799,15 @@ 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)) + 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)) + return InternalAlloc(sz, nullptr, GetPageSizeCached()); SCOPED_INTERCEPTOR_RAW(valloc, sz); return user_valloc(thr, pc, sz); } @@ -779,6 +815,11 @@ TSAN_INTERCEPTOR(void*, valloc, uptr sz) { #if SANITIZER_LINUX TSAN_INTERCEPTOR(void*, pvalloc, uptr sz) { + if (UNLIKELY(cur_thread()->in_symbolizer)) { + uptr PageSize = GetPageSizeCached(); + sz = sz ? RoundUpTo(sz, PageSize) : PageSize; + return InternalAlloc(sz, nullptr, PageSize); + } SCOPED_INTERCEPTOR_RAW(pvalloc, sz); return user_pvalloc(thr, pc, sz); } @@ -789,6 +830,13 @@ 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)) { + void *p = InternalAlloc(sz, nullptr, align); + if (!p) + return errno_ENOMEM; + *memptr = p; + return 0; + } SCOPED_INTERCEPTOR_RAW(posix_memalign, memptr, align, sz); return user_posix_memalign(thr, pc, memptr, align, sz); } @@ -856,11 +904,12 @@ void DestroyThreadState() { } } // namespace __tsan -#if !SANITIZER_MAC +#if !SANITIZER_MAC && !SANITIZER_NETBSD && !SANITIZER_FREEBSD static void thread_finalize(void *v) { uptr iter = (uptr)v; if (iter > 1) { - if (pthread_setspecific(g_thread_finalize_key, (void*)(iter - 1))) { + if (pthread_setspecific(interceptor_ctx()->finalize_key, + (void*)(iter - 1))) { Printf("ThreadSanitizer: failed to set thread key\n"); Die(); } @@ -886,9 +935,9 @@ extern "C" void *__tsan_thread_start_func(void *arg) { ThreadState *thr = cur_thread(); // Thread-local state is not initialized yet. ScopedIgnoreInterceptors ignore; -#if !SANITIZER_MAC +#if !SANITIZER_MAC && !SANITIZER_NETBSD && !SANITIZER_FREEBSD ThreadIgnoreBegin(thr, 0); - if (pthread_setspecific(g_thread_finalize_key, + if (pthread_setspecific(interceptor_ctx()->finalize_key, (void *)GetPthreadDestructorIterations())) { Printf("ThreadSanitizer: failed to set thread key\n"); Die(); @@ -913,6 +962,9 @@ extern "C" void *__tsan_thread_start_func(void *arg) { TSAN_INTERCEPTOR(int, pthread_create, void *th, void *attr, void *(*callback)(void*), void * param) { SCOPED_INTERCEPTOR_RAW(pthread_create, th, attr, callback, param); + + MaybeSpawnBackgroundThread(); + if (ctx->after_multithreaded_fork) { if (flags()->die_after_fork) { Report("ThreadSanitizer: starting new threads after multi-threaded " @@ -1338,10 +1390,15 @@ TSAN_INTERCEPTOR(int, pthread_once, void *o, void (*f)()) { if (o == 0 || f == 0) return errno_EINVAL; atomic_uint32_t *a; - if (!SANITIZER_MAC) - a = static_cast(o); - else // On OS X, pthread_once_t has a header with a long-sized signature. + + if (SANITIZER_MAC) a = static_cast((void *)((char *)o + sizeof(long_t))); + else if (SANITIZER_NETBSD) + a = static_cast + ((void *)((char *)o + __sanitizer::pthread_mutex_t_sz)); + else + a = static_cast(o); + u32 v = atomic_load(a, memory_order_acquire); if (v == 0 && atomic_compare_exchange_strong(a, &v, 1, memory_order_relaxed)) { @@ -1678,12 +1735,6 @@ TSAN_INTERCEPTOR(void, abort, int fake) { REAL(abort)(fake); } -TSAN_INTERCEPTOR(int, puts, const char *s) { - SCOPED_TSAN_INTERCEPTOR(puts, s); - MemoryAccessRange(thr, pc, (uptr)s, internal_strlen(s), false); - return REAL(puts)(s); -} - TSAN_INTERCEPTOR(int, rmdir, char *path) { SCOPED_TSAN_INTERCEPTOR(rmdir, path); Release(thr, pc, Dir2addr(path)); @@ -1788,7 +1839,9 @@ TSAN_INTERCEPTOR(int, pthread_sigmask, int how, const __sanitizer_sigset_t *set, namespace __tsan { static void CallUserSignalHandler(ThreadState *thr, bool sync, bool acquire, - bool sigact, int sig, my_siginfo_t *info, void *uctx) { + bool sigact, int sig, + __sanitizer_siginfo *info, void *uctx) { + __sanitizer_sigaction *sigactions = interceptor_ctx()->sigactions; if (acquire) Acquire(thr, 0, (uptr)&sigactions[sig]); // Signals are generally asynchronous, so if we receive a signals when @@ -1810,14 +1863,13 @@ static void CallUserSignalHandler(ThreadState *thr, bool sync, bool acquire, // This code races with sigaction. Be careful to not read sa_sigaction twice. // Also need to remember pc for reporting before the call, // because the handler can reset it. - volatile uptr pc = sigact ? - (uptr)sigactions[sig].sa_sigaction : - (uptr)sigactions[sig].sa_handler; - if (pc != (uptr)SIG_DFL && pc != (uptr)SIG_IGN) { + volatile uptr pc = + sigact ? (uptr)sigactions[sig].sigaction : (uptr)sigactions[sig].handler; + if (pc != sig_dfl && pc != sig_ign) { if (sigact) - ((sigactionhandler_t)pc)(sig, info, uctx); + ((__sanitizer_sigactionhandler_ptr)pc)(sig, info, uctx); else - ((sighandler_t)pc)(sig); + ((__sanitizer_sighandler_ptr)pc)(sig); } if (!ctx->after_multithreaded_fork) { thr->ignore_reads_and_writes = ignore_reads_and_writes; @@ -1881,7 +1933,8 @@ static bool is_sync_signal(ThreadSignalContext *sctx, int sig) { } void ALWAYS_INLINE rtl_generic_sighandler(bool sigact, int sig, - my_siginfo_t *info, void *ctx) { + __sanitizer_siginfo *info, + void *ctx) { ThreadState *thr = cur_thread(); ThreadSignalContext *sctx = SigCtx(thr); if (sig < 0 || sig >= kSigCount) { @@ -1931,58 +1984,10 @@ static void rtl_sighandler(int sig) { rtl_generic_sighandler(false, sig, 0, 0); } -static void rtl_sigaction(int sig, my_siginfo_t *info, void *ctx) { +static void rtl_sigaction(int sig, __sanitizer_siginfo *info, void *ctx) { rtl_generic_sighandler(true, sig, info, ctx); } -TSAN_INTERCEPTOR(int, sigaction, int sig, sigaction_t *act, sigaction_t *old) { - // Note: if we call REAL(sigaction) directly for any reason without proxying - // the signal handler through rtl_sigaction, very bad things will happen. - // The handler will run synchronously and corrupt tsan per-thread state. - SCOPED_INTERCEPTOR_RAW(sigaction, sig, act, old); - if (old) - internal_memcpy(old, &sigactions[sig], sizeof(*old)); - if (act == 0) - return 0; - // Copy act into sigactions[sig]. - // Can't use struct copy, because compiler can emit call to memcpy. - // Can't use internal_memcpy, because it copies byte-by-byte, - // and signal handler reads the sa_handler concurrently. It it can read - // some bytes from old value and some bytes from new value. - // Use volatile to prevent insertion of memcpy. - sigactions[sig].sa_handler = *(volatile sighandler_t*)&act->sa_handler; - sigactions[sig].sa_flags = *(volatile int*)&act->sa_flags; - internal_memcpy(&sigactions[sig].sa_mask, &act->sa_mask, - sizeof(sigactions[sig].sa_mask)); -#if !SANITIZER_FREEBSD && !SANITIZER_MAC && !SANITIZER_NETBSD - sigactions[sig].sa_restorer = act->sa_restorer; -#endif - sigaction_t newact; - internal_memcpy(&newact, act, sizeof(newact)); - internal_sigfillset(&newact.sa_mask); - if (act->sa_handler != SIG_IGN && act->sa_handler != SIG_DFL) { - if (newact.sa_flags & SA_SIGINFO) - newact.sa_sigaction = rtl_sigaction; - else - newact.sa_handler = rtl_sighandler; - } - ReleaseStore(thr, pc, (uptr)&sigactions[sig]); - int res = REAL(sigaction)(sig, &newact, 0); - return res; -} - -TSAN_INTERCEPTOR(sighandler_t, signal, int sig, sighandler_t h) { - sigaction_t act; - act.sa_handler = h; - internal_memset(&act.sa_mask, -1, sizeof(act.sa_mask)); - act.sa_flags = 0; - sigaction_t old; - int res = sigaction(sig, &act, &old); - if (res) - return SIG_ERR; - return old.sa_handler; -} - TSAN_INTERCEPTOR(int, raise, int sig) { SCOPED_TSAN_INTERCEPTOR(raise, sig); ThreadSignalContext *sctx = SigCtx(thr); @@ -2046,7 +2051,7 @@ TSAN_INTERCEPTOR(int, getaddrinfo, void *node, void *service, } TSAN_INTERCEPTOR(int, fork, int fake) { - if (cur_thread()->in_symbolizer) + if (UNLIKELY(cur_thread()->in_symbolizer)) return REAL(fork)(fake); SCOPED_INTERCEPTOR_RAW(fork, fake); ForkBefore(thr, pc); @@ -2274,6 +2279,13 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc, MutexInvalidAccess(((TsanInterceptorContext *)ctx)->thr, \ ((TsanInterceptorContext *)ctx)->pc, (uptr)m) +#define COMMON_INTERCEPTOR_MMAP_IMPL(ctx, mmap, addr, sz, prot, flags, fd, \ + off) \ + do { \ + return mmap_interceptor(thr, pc, REAL(mmap), addr, sz, prot, flags, fd, \ + off); \ + } while (false) + #if !SANITIZER_MAC #define COMMON_INTERCEPTOR_HANDLE_RECVMSG(ctx, msg) \ HandleRecvmsg(((TsanInterceptorContext *)ctx)->thr, \ @@ -2296,6 +2308,77 @@ static void HandleRecvmsg(ThreadState *thr, uptr pc, #include "sanitizer_common/sanitizer_common_interceptors.inc" +static int sigaction_impl(int sig, const __sanitizer_sigaction *act, + __sanitizer_sigaction *old); +static __sanitizer_sighandler_ptr signal_impl(int sig, + __sanitizer_sighandler_ptr h); + +#define SIGNAL_INTERCEPTOR_SIGACTION_IMPL(signo, act, oldact) \ + { return sigaction_impl(signo, act, oldact); } + +#define SIGNAL_INTERCEPTOR_SIGNAL_IMPL(func, signo, handler) \ + { return (uptr)signal_impl(signo, (__sanitizer_sighandler_ptr)handler); } + +#include "sanitizer_common/sanitizer_signal_interceptors.inc" + +int sigaction_impl(int sig, const __sanitizer_sigaction *act, + __sanitizer_sigaction *old) { + // Note: if we call REAL(sigaction) directly for any reason without proxying + // the signal handler through rtl_sigaction, very bad things will happen. + // The handler will run synchronously and corrupt tsan per-thread state. + SCOPED_INTERCEPTOR_RAW(sigaction, sig, act, old); + __sanitizer_sigaction *sigactions = interceptor_ctx()->sigactions; + __sanitizer_sigaction old_stored; + if (old) internal_memcpy(&old_stored, &sigactions[sig], sizeof(old_stored)); + __sanitizer_sigaction newact; + if (act) { + // Copy act into sigactions[sig]. + // Can't use struct copy, because compiler can emit call to memcpy. + // Can't use internal_memcpy, because it copies byte-by-byte, + // and signal handler reads the handler concurrently. It it can read + // some bytes from old value and some bytes from new value. + // Use volatile to prevent insertion of memcpy. + sigactions[sig].handler = + *(volatile __sanitizer_sighandler_ptr const *)&act->handler; + sigactions[sig].sa_flags = *(volatile int const *)&act->sa_flags; + internal_memcpy(&sigactions[sig].sa_mask, &act->sa_mask, + sizeof(sigactions[sig].sa_mask)); +#if !SANITIZER_FREEBSD && !SANITIZER_MAC && !SANITIZER_NETBSD + sigactions[sig].sa_restorer = act->sa_restorer; +#endif + internal_memcpy(&newact, act, sizeof(newact)); + internal_sigfillset(&newact.sa_mask); + if ((uptr)act->handler != sig_ign && (uptr)act->handler != sig_dfl) { + if (newact.sa_flags & SA_SIGINFO) + newact.sigaction = rtl_sigaction; + else + newact.handler = rtl_sighandler; + } + ReleaseStore(thr, pc, (uptr)&sigactions[sig]); + act = &newact; + } + int res = REAL(sigaction)(sig, act, old); + if (res == 0 && old) { + uptr cb = (uptr)old->sigaction; + if (cb == (uptr)rtl_sigaction || cb == (uptr)rtl_sighandler) { + internal_memcpy(old, &old_stored, sizeof(*old)); + } + } + return res; +} + +static __sanitizer_sighandler_ptr signal_impl(int sig, + __sanitizer_sighandler_ptr h) { + __sanitizer_sigaction act; + act.handler = h; + internal_memset(&act.sa_mask, -1, sizeof(act.sa_mask)); + act.sa_flags = 0; + __sanitizer_sigaction old; + int res = sigaction_symname(sig, &act, &old); + if (res) return (__sanitizer_sighandler_ptr)sig_err; + return old.handler; +} + #define TSAN_SYSCALL() \ ThreadState *thr = cur_thread(); \ if (thr->ignore_interceptors) \ @@ -2316,7 +2399,7 @@ struct ScopedSyscall { } }; -#if !SANITIZER_FREEBSD && !SANITIZER_MAC && !SANITIZER_NETBSD +#if !SANITIZER_FREEBSD && !SANITIZER_MAC static void syscall_access_range(uptr pc, uptr p, uptr s, bool write) { TSAN_SYSCALL(); MemoryAccessRange(thr, pc, p, s, write); @@ -2409,6 +2492,7 @@ static void syscall_post_fork(uptr pc, int pid) { syscall_post_fork(GET_CALLER_PC(), res) #include "sanitizer_common/sanitizer_common_syscalls.inc" +#include "sanitizer_common/sanitizer_syscalls_netbsd.inc" #ifdef NEED_TLS_GET_ADDR // Define own interceptor instead of sanitizer_common's for three reasons: @@ -2426,7 +2510,8 @@ TSAN_INTERCEPTOR(void *, __tls_get_addr, void *arg) { ThreadState *thr = cur_thread(); if (!thr) return res; - DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, thr->tls_addr, thr->tls_size); + DTLS::DTV *dtv = DTLS_on_tls_get_addr(arg, res, thr->tls_addr, + thr->tls_addr + thr->tls_size); if (!dtv) return res; // New DTLS block has been allocated. @@ -2435,6 +2520,45 @@ TSAN_INTERCEPTOR(void *, __tls_get_addr, void *arg) { } #endif +#if SANITIZER_NETBSD +TSAN_INTERCEPTOR(void, _lwp_exit) { + SCOPED_TSAN_INTERCEPTOR(_lwp_exit); + DestroyThreadState(); + REAL(_lwp_exit)(); +} +#define TSAN_MAYBE_INTERCEPT__LWP_EXIT TSAN_INTERCEPT(_lwp_exit) +#else +#define TSAN_MAYBE_INTERCEPT__LWP_EXIT +#endif + +#if SANITIZER_FREEBSD +TSAN_INTERCEPTOR(void, thr_exit, tid_t *state) { + SCOPED_TSAN_INTERCEPTOR(thr_exit, state); + DestroyThreadState(); + REAL(thr_exit(state)); +} +#define TSAN_MAYBE_INTERCEPT_THR_EXIT TSAN_INTERCEPT(thr_exit) +#else +#define TSAN_MAYBE_INTERCEPT_THR_EXIT +#endif + +TSAN_INTERCEPTOR_NETBSD_ALIAS(int, cond_init, void *c, void *a) +TSAN_INTERCEPTOR_NETBSD_ALIAS(int, cond_signal, void *c) +TSAN_INTERCEPTOR_NETBSD_ALIAS(int, cond_broadcast, void *c) +TSAN_INTERCEPTOR_NETBSD_ALIAS(int, cond_wait, void *c, void *m) +TSAN_INTERCEPTOR_NETBSD_ALIAS(int, cond_destroy, void *c) +TSAN_INTERCEPTOR_NETBSD_ALIAS(int, mutex_init, void *m, void *a) +TSAN_INTERCEPTOR_NETBSD_ALIAS(int, mutex_destroy, void *m) +TSAN_INTERCEPTOR_NETBSD_ALIAS(int, mutex_trylock, void *m) +TSAN_INTERCEPTOR_NETBSD_ALIAS(int, rwlock_init, void *m, void *a) +TSAN_INTERCEPTOR_NETBSD_ALIAS(int, rwlock_destroy, void *m) +TSAN_INTERCEPTOR_NETBSD_ALIAS(int, rwlock_rdlock, void *m) +TSAN_INTERCEPTOR_NETBSD_ALIAS(int, rwlock_tryrdlock, void *m) +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)()) + namespace __tsan { static void finalize(void *arg) { @@ -2466,20 +2590,30 @@ void InitializeInterceptors() { mallopt(-3, 32*1024); // M_MMAP_THRESHOLD #endif + new(interceptor_ctx()) InterceptorContext(); + InitializeCommonInterceptors(); + InitializeSignalInterceptors(); #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("setjmp", (uptr*)&REAL(setjmp), 0, 0); + GetRealFunctionAddress(TSAN_STRING_SETJMP, + (uptr*)&REAL(setjmp_symname), 0, 0); GetRealFunctionAddress("_setjmp", (uptr*)&REAL(_setjmp), 0, 0); - GetRealFunctionAddress("sigsetjmp", (uptr*)&REAL(sigsetjmp), 0, 0); + GetRealFunctionAddress(TSAN_STRING_SIGSETJMP, + (uptr*)&REAL(sigsetjmp_symname), 0, 0); +#if !SANITIZER_NETBSD GetRealFunctionAddress("__sigsetjmp", (uptr*)&REAL(__sigsetjmp), 0, 0); +#endif #endif - TSAN_INTERCEPT(longjmp); - TSAN_INTERCEPT(siglongjmp); + TSAN_INTERCEPT(longjmp_symname); + TSAN_INTERCEPT(siglongjmp_symname); +#if SANITIZER_NETBSD + TSAN_INTERCEPT(_longjmp); +#endif TSAN_INTERCEPT(malloc); TSAN_INTERCEPT(__libc_memalign); @@ -2487,8 +2621,6 @@ void InitializeInterceptors() { TSAN_INTERCEPT(realloc); TSAN_INTERCEPT(free); TSAN_INTERCEPT(cfree); - TSAN_INTERCEPT(mmap); - TSAN_MAYBE_INTERCEPT_MMAP64; TSAN_INTERCEPT(munmap); TSAN_MAYBE_INTERCEPT_MEMALIGN; TSAN_INTERCEPT(valloc); @@ -2567,15 +2699,10 @@ void InitializeInterceptors() { TSAN_INTERCEPT(unlink); TSAN_INTERCEPT(tmpfile); TSAN_MAYBE_INTERCEPT_TMPFILE64; - TSAN_INTERCEPT(fread); - TSAN_INTERCEPT(fwrite); TSAN_INTERCEPT(abort); - TSAN_INTERCEPT(puts); TSAN_INTERCEPT(rmdir); TSAN_INTERCEPT(closedir); - TSAN_INTERCEPT(sigaction); - TSAN_INTERCEPT(signal); TSAN_INTERCEPT(sigsuspend); TSAN_INTERCEPT(sigblock); TSAN_INTERCEPT(sigsetmask); @@ -2595,7 +2722,7 @@ void InitializeInterceptors() { #if !SANITIZER_ANDROID TSAN_INTERCEPT(dl_iterate_phdr); #endif - TSAN_INTERCEPT(on_exit); + TSAN_MAYBE_INTERCEPT_ON_EXIT; TSAN_INTERCEPT(__cxa_atexit); TSAN_INTERCEPT(_exit); @@ -2603,6 +2730,9 @@ void InitializeInterceptors() { TSAN_INTERCEPT(__tls_get_addr); #endif + TSAN_MAYBE_INTERCEPT__LWP_EXIT; + TSAN_MAYBE_INTERCEPT_THR_EXIT; + #if !SANITIZER_MAC && !SANITIZER_ANDROID // Need to setup it, because interceptors check that the function is resolved. // But atexit is emitted directly into the module, so can't be resolved. @@ -2614,13 +2744,30 @@ void InitializeInterceptors() { Die(); } -#if !SANITIZER_MAC - if (pthread_key_create(&g_thread_finalize_key, &thread_finalize)) { +#if !SANITIZER_MAC && !SANITIZER_NETBSD && !SANITIZER_FREEBSD + if (pthread_key_create(&interceptor_ctx()->finalize_key, &thread_finalize)) { Printf("ThreadSanitizer: failed to create thread key\n"); Die(); } #endif + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(cond_init); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(cond_signal); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(cond_broadcast); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(cond_wait); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(cond_destroy); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(mutex_init); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(mutex_destroy); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(mutex_trylock); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(rwlock_init); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(rwlock_destroy); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(rwlock_rdlock); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(rwlock_tryrdlock); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(rwlock_wrlock); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(rwlock_trywrlock); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS(rwlock_unlock); + TSAN_MAYBE_INTERCEPT_NETBSD_ALIAS_THR(once); + FdInit(); } diff --git a/libsanitizer/tsan/tsan_interceptors.h b/libsanitizer/tsan/tsan_interceptors.h index de47466501d..959a39465e3 100644 --- a/libsanitizer/tsan/tsan_interceptors.h +++ b/libsanitizer/tsan/tsan_interceptors.h @@ -49,4 +49,16 @@ LibIgnore *libignore(); #define TSAN_INTERCEPTOR(ret, func, ...) INTERCEPTOR(ret, func, __VA_ARGS__) +#if SANITIZER_NETBSD +# define TSAN_INTERCEPTOR_NETBSD_ALIAS(ret, func, ...) \ + TSAN_INTERCEPTOR(ret, __libc_##func, __VA_ARGS__) \ + ALIAS(WRAPPER_NAME(pthread_##func)); +# define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR(ret, func, ...) \ + TSAN_INTERCEPTOR(ret, __libc_thr_##func, __VA_ARGS__) \ + ALIAS(WRAPPER_NAME(pthread_##func)); +#else +# define TSAN_INTERCEPTOR_NETBSD_ALIAS(ret, func, ...) +# define TSAN_INTERCEPTOR_NETBSD_ALIAS_THR(ret, func, ...) +#endif + #endif // TSAN_INTERCEPTORS_H diff --git a/libsanitizer/tsan/tsan_interceptors_mac.cc b/libsanitizer/tsan/tsan_interceptors_mac.cc index 913e9ed0e14..1df6ac27f49 100644 --- a/libsanitizer/tsan/tsan_interceptors_mac.cc +++ b/libsanitizer/tsan/tsan_interceptors_mac.cc @@ -98,7 +98,7 @@ OSATOMIC_INTERCEPTORS_BITWISE(OSAtomicXor, fetch_xor, TSAN_INTERCEPTOR(bool, f, t old_value, t new_value, t volatile *ptr) { \ SCOPED_TSAN_INTERCEPTOR(f, old_value, new_value, ptr); \ return tsan_atomic_f##_compare_exchange_strong( \ - (tsan_t *)ptr, (tsan_t *)&old_value, (tsan_t)new_value, \ + (volatile tsan_t *)ptr, (tsan_t *)&old_value, (tsan_t)new_value, \ kMacOrderNonBarrier, kMacOrderNonBarrier); \ } \ \ @@ -106,7 +106,7 @@ OSATOMIC_INTERCEPTORS_BITWISE(OSAtomicXor, fetch_xor, t volatile *ptr) { \ SCOPED_TSAN_INTERCEPTOR(f##Barrier, old_value, new_value, ptr); \ return tsan_atomic_f##_compare_exchange_strong( \ - (tsan_t *)ptr, (tsan_t *)&old_value, (tsan_t)new_value, \ + (volatile tsan_t *)ptr, (tsan_t *)&old_value, (tsan_t)new_value, \ kMacOrderBarrier, kMacOrderNonBarrier); \ } @@ -120,14 +120,14 @@ OSATOMIC_INTERCEPTORS_CAS(OSAtomicCompareAndSwap32, __tsan_atomic32, a32, OSATOMIC_INTERCEPTORS_CAS(OSAtomicCompareAndSwap64, __tsan_atomic64, a64, int64_t) -#define OSATOMIC_INTERCEPTOR_BITOP(f, op, clear, mo) \ - TSAN_INTERCEPTOR(bool, f, uint32_t n, volatile void *ptr) { \ - SCOPED_TSAN_INTERCEPTOR(f, n, ptr); \ - char *byte_ptr = ((char *)ptr) + (n >> 3); \ - char bit = 0x80u >> (n & 7); \ - char mask = clear ? ~bit : bit; \ - char orig_byte = op((a8 *)byte_ptr, mask, mo); \ - return orig_byte & bit; \ +#define OSATOMIC_INTERCEPTOR_BITOP(f, op, clear, mo) \ + TSAN_INTERCEPTOR(bool, f, uint32_t n, volatile void *ptr) { \ + SCOPED_TSAN_INTERCEPTOR(f, n, ptr); \ + volatile char *byte_ptr = ((volatile char *)ptr) + (n >> 3); \ + char bit = 0x80u >> (n & 7); \ + char mask = clear ? ~bit : bit; \ + char orig_byte = op((volatile a8 *)byte_ptr, mask, mo); \ + return orig_byte & bit; \ } #define OSATOMIC_INTERCEPTORS_BITOP(f, op, clear) \ @@ -292,6 +292,43 @@ 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) { + 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; +} + +// 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); + return (uptr)obj; +} + +TSAN_INTERCEPTOR(int, objc_sync_enter, void *obj) { + SCOPED_TSAN_INTERCEPTOR(objc_sync_enter, obj); + int result = REAL(objc_sync_enter)(obj); + if (obj) Acquire(thr, pc, SyncAddressForObjCObject(obj)); + 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); +} + // On macOS, libc++ is always linked dynamically, so intercepting works the // usual way. #define STDCXX_INTERCEPTOR TSAN_INTERCEPTOR diff --git a/libsanitizer/tsan/tsan_interface.h b/libsanitizer/tsan/tsan_interface.h index 7dc67655276..bb097b9554b 100644 --- a/libsanitizer/tsan/tsan_interface.h +++ b/libsanitizer/tsan/tsan_interface.h @@ -115,6 +115,19 @@ int __tsan_get_report_data(void *report, const char **description, int *count, int *unique_tid_count, void **sleep_trace, uptr trace_size); +/// Retrieves the "tag" from a report (for external-race report types). External +/// races can be associated with a tag which give them more meaning. For example +/// tag value '1' means "Swift access race". Tag value '0' indicated a plain +/// external race. +/// +/// \param report opaque pointer to the current report (obtained as argument in +/// __tsan_on_report, or from __tsan_get_current_report) +/// \param [out] tag points to storage that will be filled with the tag value +/// +/// \returns non-zero value on success, zero on failure +SANITIZER_INTERFACE_ATTRIBUTE +int __tsan_get_report_tag(void *report, uptr *tag); + // Returns information about stack traces included in the report. SANITIZER_INTERFACE_ATTRIBUTE int __tsan_get_report_stack(void *report, uptr idx, void **trace, diff --git a/libsanitizer/tsan/tsan_interface_ann.cc b/libsanitizer/tsan/tsan_interface_ann.cc index 083138fc046..3e2b7c83c3a 100644 --- a/libsanitizer/tsan/tsan_interface_ann.cc +++ b/libsanitizer/tsan/tsan_interface_ann.cc @@ -12,6 +12,7 @@ #include "sanitizer_common/sanitizer_internal_defs.h" #include "sanitizer_common/sanitizer_placement_new.h" #include "sanitizer_common/sanitizer_stacktrace.h" +#include "sanitizer_common/sanitizer_vector.h" #include "tsan_interface_ann.h" #include "tsan_mutex.h" #include "tsan_report.h" @@ -19,7 +20,6 @@ #include "tsan_mman.h" #include "tsan_flags.h" #include "tsan_platform.h" -#include "tsan_vector.h" #define CALLERPC ((uptr)__builtin_return_address(0)) @@ -183,10 +183,10 @@ void PrintMatchedBenignRaces() { int unique_count = 0; int hit_count = 0; int add_count = 0; - Vector hit_matched(MBlockScopedBuf); + Vector hit_matched; CollectMatchedBenignRaces(&hit_matched, &unique_count, &hit_count, &ExpectRace::hitcount); - Vector add_matched(MBlockScopedBuf); + Vector add_matched; CollectMatchedBenignRaces(&add_matched, &unique_count, &add_count, &ExpectRace::addcount); if (hit_matched.Size()) { diff --git a/libsanitizer/tsan/tsan_libdispatch_mac.cc b/libsanitizer/tsan/tsan_libdispatch_mac.cc index 5200a791fc2..f7e08d46fbb 100644 --- a/libsanitizer/tsan/tsan_libdispatch_mac.cc +++ b/libsanitizer/tsan/tsan_libdispatch_mac.cc @@ -23,6 +23,11 @@ #include #include +// DISPATCH_NOESCAPE is not defined prior to XCode 8. +#ifndef DISPATCH_NOESCAPE +#define DISPATCH_NOESCAPE +#endif + typedef long long_t; // NOLINT namespace __tsan { @@ -178,11 +183,8 @@ 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); \ - 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 = { \ - q, heap_block, &invoke_and_release_block, false, true, barrier, 0}; \ + q, block, &invoke_block, false, true, barrier, 0}; \ Release(thr, pc, (uptr)&new_context); \ SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); \ REAL(name##_f)(q, &new_context, dispatch_callback_wrap); \ @@ -520,9 +522,9 @@ TSAN_INTERCEPTOR(dispatch_data_t, dispatch_data_create, const void *buffer, return REAL(dispatch_data_create)(buffer, size, q, destructor); if (destructor == DISPATCH_DATA_DESTRUCTOR_FREE) - destructor = ^(void) { WRAP(free)((void *)buffer); }; + destructor = ^(void) { WRAP(free)((void *)(uintptr_t)buffer); }; else if (destructor == DISPATCH_DATA_DESTRUCTOR_MUNMAP) - destructor = ^(void) { WRAP(munmap)((void *)buffer, size); }; + destructor = ^(void) { WRAP(munmap)((void *)(uintptr_t)buffer, size); }; SCOPED_TSAN_INTERCEPTOR_USER_CALLBACK_START(); dispatch_block_t heap_block = Block_copy(destructor); diff --git a/libsanitizer/tsan/tsan_malloc_mac.cc b/libsanitizer/tsan/tsan_malloc_mac.cc index b418a211b58..618fa2d6702 100644 --- a/libsanitizer/tsan/tsan_malloc_mac.cc +++ b/libsanitizer/tsan/tsan_malloc_mac.cc @@ -13,6 +13,7 @@ #include "sanitizer_common/sanitizer_platform.h" #if SANITIZER_MAC +#include "sanitizer_common/sanitizer_errno.h" #include "tsan_interceptors.h" #include "tsan_stack_trace.h" @@ -37,6 +38,15 @@ using namespace __tsan; if (cur_thread()->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) { \ + void *p = InternalAlloc(size, nullptr, alignment); \ + if (!p) return errno_ENOMEM; \ + *memptr = p; \ + return 0; \ + } \ + 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) \ return InternalAlloc(size, nullptr, GetPageSizeCached()); \ diff --git a/libsanitizer/tsan/tsan_mman.cc b/libsanitizer/tsan/tsan_mman.cc index 18505aca70e..76d12a43b27 100644 --- a/libsanitizer/tsan/tsan_mman.cc +++ b/libsanitizer/tsan/tsan_mman.cc @@ -10,6 +10,7 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_allocator_checks.h" #include "sanitizer_common/sanitizer_allocator_interface.h" +#include "sanitizer_common/sanitizer_allocator_report.h" #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_errno.h" #include "sanitizer_common/sanitizer_placement_new.h" @@ -148,13 +149,24 @@ static void SignalUnsafeCall(ThreadState *thr, uptr pc) { OutputReport(thr, rep); } +static constexpr uptr kMaxAllowedMallocSize = 1ull << 40; + void *user_alloc_internal(ThreadState *thr, uptr pc, uptr sz, uptr align, bool signal) { - if ((sz >= (1ull << 40)) || (align >= (1ull << 40))) - return Allocator::FailureHandler::OnBadRequest(); + if (sz >= kMaxAllowedMallocSize || align >= kMaxAllowedMallocSize) { + if (AllocatorMayReturnNull()) + return nullptr; + GET_STACK_TRACE_FATAL(thr, pc); + ReportAllocationSizeTooBig(sz, kMaxAllowedMallocSize, &stack); + } void *p = allocator()->Allocate(&thr->proc()->alloc_cache, sz, align); - if (UNLIKELY(p == 0)) - return 0; + if (UNLIKELY(!p)) { + SetAllocatorOutOfMemory(); + if (AllocatorMayReturnNull()) + return nullptr; + GET_STACK_TRACE_FATAL(thr, pc); + ReportOutOfMemory(sz, &stack); + } if (ctx && ctx->initialized) OnUserAlloc(thr, pc, (uptr)p, sz, true); if (signal) @@ -176,8 +188,12 @@ void *user_alloc(ThreadState *thr, uptr pc, uptr sz) { } void *user_calloc(ThreadState *thr, uptr pc, uptr size, uptr n) { - if (UNLIKELY(CheckForCallocOverflow(size, n))) - return SetErrnoOnNull(Allocator::FailureHandler::OnBadRequest()); + if (UNLIKELY(CheckForCallocOverflow(size, n))) { + if (AllocatorMayReturnNull()) + return SetErrnoOnNull(nullptr); + GET_STACK_TRACE_FATAL(thr, pc); + ReportCallocOverflow(n, size, &stack); + } void *p = user_alloc_internal(thr, pc, n * size); if (p) internal_memset(p, 0, n * size); @@ -222,7 +238,10 @@ void *user_realloc(ThreadState *thr, uptr pc, void *p, uptr sz) { void *user_memalign(ThreadState *thr, uptr pc, uptr align, uptr sz) { if (UNLIKELY(!IsPowerOfTwo(align))) { errno = errno_EINVAL; - return Allocator::FailureHandler::OnBadRequest(); + if (AllocatorMayReturnNull()) + return nullptr; + GET_STACK_TRACE_FATAL(thr, pc); + ReportInvalidAllocationAlignment(align, &stack); } return SetErrnoOnNull(user_alloc_internal(thr, pc, sz, align)); } @@ -230,11 +249,14 @@ 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) { if (UNLIKELY(!CheckPosixMemalignAlignment(align))) { - Allocator::FailureHandler::OnBadRequest(); - return errno_EINVAL; + if (AllocatorMayReturnNull()) + return errno_EINVAL; + GET_STACK_TRACE_FATAL(thr, pc); + ReportInvalidPosixMemalignAlignment(align, &stack); } void *ptr = user_alloc_internal(thr, pc, sz, align); if (UNLIKELY(!ptr)) + // OOM error is already taken care of by user_alloc_internal. return errno_ENOMEM; CHECK(IsAligned((uptr)ptr, align)); *memptr = ptr; @@ -244,7 +266,10 @@ int user_posix_memalign(ThreadState *thr, uptr pc, void **memptr, uptr align, void *user_aligned_alloc(ThreadState *thr, uptr pc, uptr align, uptr sz) { if (UNLIKELY(!CheckAlignedAllocAlignmentAndSize(align, sz))) { errno = errno_EINVAL; - return Allocator::FailureHandler::OnBadRequest(); + if (AllocatorMayReturnNull()) + return nullptr; + GET_STACK_TRACE_FATAL(thr, pc); + ReportInvalidAlignedAllocAlignment(sz, align, &stack); } return SetErrnoOnNull(user_alloc_internal(thr, pc, sz, align)); } @@ -257,7 +282,10 @@ void *user_pvalloc(ThreadState *thr, uptr pc, uptr sz) { uptr PageSize = GetPageSizeCached(); if (UNLIKELY(CheckForPvallocOverflow(sz, PageSize))) { errno = errno_ENOMEM; - return Allocator::FailureHandler::OnBadRequest(); + if (AllocatorMayReturnNull()) + return nullptr; + GET_STACK_TRACE_FATAL(thr, pc); + ReportPvallocOverflow(sz, &stack); } // pvalloc(0) should allocate one page. sz = sz ? RoundUpTo(sz, PageSize) : PageSize; diff --git a/libsanitizer/tsan/tsan_new_delete.cc b/libsanitizer/tsan/tsan_new_delete.cc index 65ae61b8164..1346aa7a4e6 100644 --- a/libsanitizer/tsan/tsan_new_delete.cc +++ b/libsanitizer/tsan/tsan_new_delete.cc @@ -11,13 +11,16 @@ //===----------------------------------------------------------------------===// #include "interception/interception.h" #include "sanitizer_common/sanitizer_allocator.h" +#include "sanitizer_common/sanitizer_allocator_report.h" #include "sanitizer_common/sanitizer_internal_defs.h" #include "tsan_interceptors.h" +#include "tsan_rtl.h" using namespace __tsan; // NOLINT namespace std { struct nothrow_t {}; +enum class align_val_t: __sanitizer::uptr {}; } // namespace std DECLARE_REAL(void *, malloc, uptr size) @@ -31,7 +34,25 @@ DECLARE_REAL(void, free, void *ptr) { \ SCOPED_INTERCEPTOR_RAW(mangled_name, size); \ p = user_alloc(thr, pc, size); \ - if (!nothrow && UNLIKELY(!p)) DieOnFailure::OnOOM(); \ + if (!nothrow && UNLIKELY(!p)) { \ + GET_STACK_TRACE_FATAL(thr, pc); \ + ReportOutOfMemory(size, &stack); \ + } \ + } \ + invoke_malloc_hook(p, size); \ + return p; + +#define OPERATOR_NEW_BODY_ALIGN(mangled_name, nothrow) \ + if (cur_thread()->in_symbolizer) \ + return InternalAlloc(size, nullptr, (uptr)align); \ + void *p = 0; \ + { \ + SCOPED_INTERCEPTOR_RAW(mangled_name, size); \ + p = user_memalign(thr, pc, (uptr)align, size); \ + if (!nothrow && UNLIKELY(!p)) { \ + GET_STACK_TRACE_FATAL(thr, pc); \ + ReportOutOfMemory(size, &stack); \ + } \ } \ invoke_malloc_hook(p, size); \ return p; @@ -60,6 +81,36 @@ void *operator new[](__sanitizer::uptr size, std::nothrow_t const&) { OPERATOR_NEW_BODY(_ZnamRKSt9nothrow_t, true /*nothrow*/); } +SANITIZER_INTERFACE_ATTRIBUTE +void *operator new(__sanitizer::uptr size, std::align_val_t align); +void *operator new(__sanitizer::uptr size, std::align_val_t align) { + OPERATOR_NEW_BODY_ALIGN(_ZnwmSt11align_val_t, false /*nothrow*/); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void *operator new[](__sanitizer::uptr size, std::align_val_t align); +void *operator new[](__sanitizer::uptr size, std::align_val_t align) { + OPERATOR_NEW_BODY_ALIGN(_ZnamSt11align_val_t, false /*nothrow*/); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void *operator new(__sanitizer::uptr size, std::align_val_t align, + std::nothrow_t const&); +void *operator new(__sanitizer::uptr size, std::align_val_t align, + std::nothrow_t const&) { + OPERATOR_NEW_BODY_ALIGN(_ZnwmSt11align_val_tRKSt9nothrow_t, + true /*nothrow*/); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void *operator new[](__sanitizer::uptr size, std::align_val_t align, + std::nothrow_t const&); +void *operator new[](__sanitizer::uptr size, std::align_val_t align, + std::nothrow_t const&) { + OPERATOR_NEW_BODY_ALIGN(_ZnamSt11align_val_tRKSt9nothrow_t, + true /*nothrow*/); +} + #define OPERATOR_DELETE_BODY(mangled_name) \ if (ptr == 0) return; \ if (cur_thread()->in_symbolizer) \ @@ -91,3 +142,57 @@ void operator delete[](void *ptr, std::nothrow_t const&); void operator delete[](void *ptr, std::nothrow_t const&) { OPERATOR_DELETE_BODY(_ZdaPvRKSt9nothrow_t); } + +SANITIZER_INTERFACE_ATTRIBUTE +void operator delete(void *ptr, __sanitizer::uptr size) NOEXCEPT; +void operator delete(void *ptr, __sanitizer::uptr size) NOEXCEPT { + OPERATOR_DELETE_BODY(_ZdlPvm); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void operator delete[](void *ptr, __sanitizer::uptr size) NOEXCEPT; +void operator delete[](void *ptr, __sanitizer::uptr size) NOEXCEPT { + OPERATOR_DELETE_BODY(_ZdaPvm); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void operator delete(void *ptr, std::align_val_t align) NOEXCEPT; +void operator delete(void *ptr, std::align_val_t align) NOEXCEPT { + OPERATOR_DELETE_BODY(_ZdlPvSt11align_val_t); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT; +void operator delete[](void *ptr, std::align_val_t align) NOEXCEPT { + OPERATOR_DELETE_BODY(_ZdaPvSt11align_val_t); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&); +void operator delete(void *ptr, std::align_val_t align, std::nothrow_t const&) { + OPERATOR_DELETE_BODY(_ZdlPvSt11align_val_tRKSt9nothrow_t); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void operator delete[](void *ptr, std::align_val_t align, + std::nothrow_t const&); +void operator delete[](void *ptr, std::align_val_t align, + std::nothrow_t const&) { + OPERATOR_DELETE_BODY(_ZdaPvSt11align_val_tRKSt9nothrow_t); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void operator delete(void *ptr, __sanitizer::uptr size, + std::align_val_t align) NOEXCEPT; +void operator delete(void *ptr, __sanitizer::uptr size, + std::align_val_t align) NOEXCEPT { + OPERATOR_DELETE_BODY(_ZdlPvmSt11align_val_t); +} + +SANITIZER_INTERFACE_ATTRIBUTE +void operator delete[](void *ptr, __sanitizer::uptr size, + std::align_val_t align) NOEXCEPT; +void operator delete[](void *ptr, __sanitizer::uptr size, + std::align_val_t align) NOEXCEPT { + OPERATOR_DELETE_BODY(_ZdaPvmSt11align_val_t); +} diff --git a/libsanitizer/tsan/tsan_platform.h b/libsanitizer/tsan/tsan_platform.h index 44a3ea99107..871df468b65 100644 --- a/libsanitizer/tsan/tsan_platform.h +++ b/libsanitizer/tsan/tsan_platform.h @@ -40,6 +40,19 @@ C/C++ on linux/x86_64 and freebsd/x86_64 7b00 0000 0000 - 7c00 0000 0000: heap 7c00 0000 0000 - 7e80 0000 0000: - 7e80 0000 0000 - 8000 0000 0000: modules and main thread stack + +C/C++ on netbsd/amd64 can reuse the same mapping: + * The address space starts from 0x1000 (option with 0x0) and ends with + 0x7f7ffffff000. + * LoAppMem-kHeapMemEnd can be reused as it is. + * No VDSO support. + * No MidAppMem region. + * No additional HeapMem region. + * HiAppMem contains the stack, loader, shared libraries and heap. + * Stack on NetBSD/amd64 has prereserved 128MB. + * Heap grows downwards (top-down). + * ASLR must be disabled per-process or globally. + */ struct Mapping { static const uptr kMetaShadowBeg = 0x300000000000ull; @@ -64,25 +77,27 @@ struct Mapping { #define TSAN_MID_APP_RANGE 1 #elif defined(__mips64) /* -C/C++ on linux/mips64 -0100 0000 00 - 0200 0000 00: main binary -0200 0000 00 - 1400 0000 00: - -1400 0000 00 - 2400 0000 00: shadow -2400 0000 00 - 3000 0000 00: - -3000 0000 00 - 4000 0000 00: metainfo (memory blocks and sync objects) -4000 0000 00 - 6000 0000 00: - -6000 0000 00 - 6200 0000 00: traces -6200 0000 00 - fe00 0000 00: - -fe00 0000 00 - ff00 0000 00: heap -ff00 0000 00 - ff80 0000 00: - -ff80 0000 00 - ffff ffff ff: modules and main thread stack +C/C++ on linux/mips64 (40-bit VMA) +0000 0000 00 - 0100 0000 00: - (4 GB) +0100 0000 00 - 0200 0000 00: main binary (4 GB) +0200 0000 00 - 2000 0000 00: - (120 GB) +2000 0000 00 - 4000 0000 00: shadow (128 GB) +4000 0000 00 - 5000 0000 00: metainfo (memory blocks and sync objects) (64 GB) +5000 0000 00 - aa00 0000 00: - (360 GB) +aa00 0000 00 - ab00 0000 00: main binary (PIE) (4 GB) +ab00 0000 00 - b000 0000 00: - (20 GB) +b000 0000 00 - b200 0000 00: traces (8 GB) +b200 0000 00 - fe00 0000 00: - (304 GB) +fe00 0000 00 - ff00 0000 00: heap (4 GB) +ff00 0000 00 - ff80 0000 00: - (2 GB) +ff80 0000 00 - ffff ffff ff: modules and main thread stack (<2 GB) */ struct Mapping { static const uptr kMetaShadowBeg = 0x4000000000ull; static const uptr kMetaShadowEnd = 0x5000000000ull; static const uptr kTraceMemBeg = 0xb000000000ull; static const uptr kTraceMemEnd = 0xb200000000ull; - static const uptr kShadowBeg = 0x2400000000ull; + static const uptr kShadowBeg = 0x2000000000ull; static const uptr kShadowEnd = 0x4000000000ull; static const uptr kHeapMemBeg = 0xfe00000000ull; static const uptr kHeapMemEnd = 0xff00000000ull; @@ -109,7 +124,8 @@ C/C++ on Darwin/iOS/ARM64 (36-bit VMA, 64 GB VM) 0c00 0000 00 - 0d00 0000 00: - (4 GB) 0d00 0000 00 - 0e00 0000 00: metainfo (4 GB) 0e00 0000 00 - 0f00 0000 00: - (4 GB) -0f00 0000 00 - 1000 0000 00: traces (4 GB) +0f00 0000 00 - 0fc0 0000 00: traces (3 GB) +0fc0 0000 00 - 1000 0000 00: - */ struct Mapping { static const uptr kLoAppMemBeg = 0x0100000000ull; @@ -121,9 +137,9 @@ struct Mapping { static const uptr kMetaShadowBeg = 0x0d00000000ull; static const uptr kMetaShadowEnd = 0x0e00000000ull; static const uptr kTraceMemBeg = 0x0f00000000ull; - static const uptr kTraceMemEnd = 0x1000000000ull; - static const uptr kHiAppMemBeg = 0x1000000000ull; - static const uptr kHiAppMemEnd = 0x1000000000ull; + static const uptr kTraceMemEnd = 0x0fc0000000ull; + static const uptr kHiAppMemBeg = 0x0fc0000000ull; + static const uptr kHiAppMemEnd = 0x0fc0000000ull; static const uptr kAppMemMsk = 0x0ull; static const uptr kAppMemXor = 0x0ull; static const uptr kVdsoBeg = 0x7000000000000000ull; @@ -337,9 +353,9 @@ struct Mapping47 { #define TSAN_RUNTIME_VMA 1 #endif -#elif SANITIZER_GO && !SANITIZER_WINDOWS +#elif SANITIZER_GO && !SANITIZER_WINDOWS && defined(__x86_64__) -/* Go on linux, darwin and freebsd +/* Go on linux, darwin and freebsd on x86_64 0000 0000 1000 - 0000 1000 0000: executable 0000 1000 0000 - 00c0 0000 0000: - 00c0 0000 0000 - 00e0 0000 0000: heap @@ -388,6 +404,87 @@ struct Mapping { static const uptr kAppMemEnd = 0x00e000000000ull; }; +#elif SANITIZER_GO && defined(__powerpc64__) + +/* Only Mapping46 and Mapping47 are currently supported for powercp64 on Go. */ + +/* Go on linux/powerpc64 (46-bit VMA) +0000 0000 1000 - 0000 1000 0000: executable +0000 1000 0000 - 00c0 0000 0000: - +00c0 0000 0000 - 00e0 0000 0000: heap +00e0 0000 0000 - 2000 0000 0000: - +2000 0000 0000 - 2380 0000 0000: shadow +2380 0000 0000 - 2400 0000 0000: - +2400 0000 0000 - 3400 0000 0000: metainfo (memory blocks and sync objects) +3400 0000 0000 - 3600 0000 0000: - +3600 0000 0000 - 3800 0000 0000: traces +3800 0000 0000 - 4000 0000 0000: - +*/ + +struct Mapping46 { + static const uptr kMetaShadowBeg = 0x240000000000ull; + static const uptr kMetaShadowEnd = 0x340000000000ull; + static const uptr kTraceMemBeg = 0x360000000000ull; + static const uptr kTraceMemEnd = 0x380000000000ull; + static const uptr kShadowBeg = 0x200000000000ull; + static const uptr kShadowEnd = 0x238000000000ull; + static const uptr kAppMemBeg = 0x000000001000ull; + static const uptr kAppMemEnd = 0x00e000000000ull; +}; + +/* Go on linux/powerpc64 (47-bit VMA) +0000 0000 1000 - 0000 1000 0000: executable +0000 1000 0000 - 00c0 0000 0000: - +00c0 0000 0000 - 00e0 0000 0000: heap +00e0 0000 0000 - 2000 0000 0000: - +2000 0000 0000 - 3000 0000 0000: shadow +3000 0000 0000 - 3000 0000 0000: - +3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects) +4000 0000 0000 - 6000 0000 0000: - +6000 0000 0000 - 6200 0000 0000: traces +6200 0000 0000 - 8000 0000 0000: - +*/ + +struct Mapping47 { + static const uptr kMetaShadowBeg = 0x300000000000ull; + static const uptr kMetaShadowEnd = 0x400000000000ull; + static const uptr kTraceMemBeg = 0x600000000000ull; + static const uptr kTraceMemEnd = 0x620000000000ull; + static const uptr kShadowBeg = 0x200000000000ull; + static const uptr kShadowEnd = 0x300000000000ull; + static const uptr kAppMemBeg = 0x000000001000ull; + static const uptr kAppMemEnd = 0x00e000000000ull; +}; + +#elif SANITIZER_GO && defined(__aarch64__) + +/* Go on linux/aarch64 (48-bit VMA) +0000 0000 1000 - 0000 1000 0000: executable +0000 1000 0000 - 00c0 0000 0000: - +00c0 0000 0000 - 00e0 0000 0000: heap +00e0 0000 0000 - 2000 0000 0000: - +2000 0000 0000 - 3000 0000 0000: shadow +3000 0000 0000 - 3000 0000 0000: - +3000 0000 0000 - 4000 0000 0000: metainfo (memory blocks and sync objects) +4000 0000 0000 - 6000 0000 0000: - +6000 0000 0000 - 6200 0000 0000: traces +6200 0000 0000 - 8000 0000 0000: - +*/ + +struct Mapping { + static const uptr kMetaShadowBeg = 0x300000000000ull; + static const uptr kMetaShadowEnd = 0x400000000000ull; + static const uptr kTraceMemBeg = 0x600000000000ull; + static const uptr kTraceMemEnd = 0x620000000000ull; + static const uptr kShadowBeg = 0x200000000000ull; + static const uptr kShadowEnd = 0x300000000000ull; + static const uptr kAppMemBeg = 0x000000001000ull; + static const uptr kAppMemEnd = 0x00e000000000ull; +}; + +// Indicates the runtime will define the memory regions at runtime. +#define TSAN_RUNTIME_VMA 1 + #else # error "Unknown platform" #endif @@ -450,7 +547,7 @@ uptr MappingImpl(void) { template uptr MappingArchImpl(void) { -#if defined(__aarch64__) && !defined(__APPLE__) +#if defined(__aarch64__) && !defined(__APPLE__) && !SANITIZER_GO switch (vmaSize) { case 39: return MappingImpl(); case 42: return MappingImpl(); @@ -460,7 +557,9 @@ uptr MappingArchImpl(void) { return 0; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return MappingImpl(); +#endif case 46: return MappingImpl(); case 47: return MappingImpl(); } @@ -605,7 +704,7 @@ bool IsAppMemImpl(uptr mem) { ALWAYS_INLINE bool IsAppMem(uptr mem) { -#if defined(__aarch64__) && !defined(__APPLE__) +#if defined(__aarch64__) && !defined(__APPLE__) && !SANITIZER_GO switch (vmaSize) { case 39: return IsAppMemImpl(mem); case 42: return IsAppMemImpl(mem); @@ -615,7 +714,9 @@ bool IsAppMem(uptr mem) { return false; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return IsAppMemImpl(mem); +#endif case 46: return IsAppMemImpl(mem); case 47: return IsAppMemImpl(mem); } @@ -634,7 +735,7 @@ bool IsShadowMemImpl(uptr mem) { ALWAYS_INLINE bool IsShadowMem(uptr mem) { -#if defined(__aarch64__) && !defined(__APPLE__) +#if defined(__aarch64__) && !defined(__APPLE__) && !SANITIZER_GO switch (vmaSize) { case 39: return IsShadowMemImpl(mem); case 42: return IsShadowMemImpl(mem); @@ -644,7 +745,9 @@ bool IsShadowMem(uptr mem) { return false; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return IsShadowMemImpl(mem); +#endif case 46: return IsShadowMemImpl(mem); case 47: return IsShadowMemImpl(mem); } @@ -663,7 +766,7 @@ bool IsMetaMemImpl(uptr mem) { ALWAYS_INLINE bool IsMetaMem(uptr mem) { -#if defined(__aarch64__) && !defined(__APPLE__) +#if defined(__aarch64__) && !defined(__APPLE__) && !SANITIZER_GO switch (vmaSize) { case 39: return IsMetaMemImpl(mem); case 42: return IsMetaMemImpl(mem); @@ -673,7 +776,9 @@ bool IsMetaMem(uptr mem) { return false; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return IsMetaMemImpl(mem); +#endif case 46: return IsMetaMemImpl(mem); case 47: return IsMetaMemImpl(mem); } @@ -702,7 +807,7 @@ uptr MemToShadowImpl(uptr x) { ALWAYS_INLINE uptr MemToShadow(uptr x) { -#if defined(__aarch64__) && !defined(__APPLE__) +#if defined(__aarch64__) && !defined(__APPLE__) && !SANITIZER_GO switch (vmaSize) { case 39: return MemToShadowImpl(x); case 42: return MemToShadowImpl(x); @@ -712,7 +817,9 @@ uptr MemToShadow(uptr x) { return 0; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return MemToShadowImpl(x); +#endif case 46: return MemToShadowImpl(x); case 47: return MemToShadowImpl(x); } @@ -743,7 +850,7 @@ u32 *MemToMetaImpl(uptr x) { ALWAYS_INLINE u32 *MemToMeta(uptr x) { -#if defined(__aarch64__) && !defined(__APPLE__) +#if defined(__aarch64__) && !defined(__APPLE__) && !SANITIZER_GO switch (vmaSize) { case 39: return MemToMetaImpl(x); case 42: return MemToMetaImpl(x); @@ -753,7 +860,9 @@ u32 *MemToMeta(uptr x) { return 0; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return MemToMetaImpl(x); +#endif case 46: return MemToMetaImpl(x); case 47: return MemToMetaImpl(x); } @@ -797,7 +906,7 @@ uptr ShadowToMemImpl(uptr s) { ALWAYS_INLINE uptr ShadowToMem(uptr s) { -#if defined(__aarch64__) && !defined(__APPLE__) +#if defined(__aarch64__) && !defined(__APPLE__) && !SANITIZER_GO switch (vmaSize) { case 39: return ShadowToMemImpl(s); case 42: return ShadowToMemImpl(s); @@ -807,7 +916,9 @@ uptr ShadowToMem(uptr s) { return 0; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return ShadowToMemImpl(s); +#endif case 46: return ShadowToMemImpl(s); case 47: return ShadowToMemImpl(s); } @@ -834,7 +945,7 @@ uptr GetThreadTraceImpl(int tid) { ALWAYS_INLINE uptr GetThreadTrace(int tid) { -#if defined(__aarch64__) && !defined(__APPLE__) +#if defined(__aarch64__) && !defined(__APPLE__) && !SANITIZER_GO switch (vmaSize) { case 39: return GetThreadTraceImpl(tid); case 42: return GetThreadTraceImpl(tid); @@ -844,7 +955,9 @@ uptr GetThreadTrace(int tid) { return 0; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return GetThreadTraceImpl(tid); +#endif case 46: return GetThreadTraceImpl(tid); case 47: return GetThreadTraceImpl(tid); } @@ -866,7 +979,7 @@ uptr GetThreadTraceHeaderImpl(int tid) { ALWAYS_INLINE uptr GetThreadTraceHeader(int tid) { -#if defined(__aarch64__) && !defined(__APPLE__) +#if defined(__aarch64__) && !defined(__APPLE__) && !SANITIZER_GO switch (vmaSize) { case 39: return GetThreadTraceHeaderImpl(tid); case 42: return GetThreadTraceHeaderImpl(tid); @@ -876,7 +989,9 @@ uptr GetThreadTraceHeader(int tid) { return 0; #elif defined(__powerpc64__) switch (vmaSize) { +#if !SANITIZER_GO case 44: return GetThreadTraceHeaderImpl(tid); +#endif case 46: return GetThreadTraceHeaderImpl(tid); case 47: return GetThreadTraceHeaderImpl(tid); } diff --git a/libsanitizer/tsan/tsan_platform_linux.cc b/libsanitizer/tsan/tsan_platform_linux.cc index d46dff45a67..9b4dea20659 100644 --- a/libsanitizer/tsan/tsan_platform_linux.cc +++ b/libsanitizer/tsan/tsan_platform_linux.cc @@ -12,11 +12,12 @@ #include "sanitizer_common/sanitizer_platform.h" -#if SANITIZER_LINUX || SANITIZER_FREEBSD +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD #include "sanitizer_common/sanitizer_common.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_linux.h" +#include "sanitizer_common/sanitizer_platform_limits_netbsd.h" #include "sanitizer_common/sanitizer_platform_limits_posix.h" #include "sanitizer_common/sanitizer_posix.h" #include "sanitizer_common/sanitizer_procmaps.h" @@ -165,11 +166,11 @@ static void MapRodata() { fd_t fd = openrv; // Fill the file with kShadowRodata. const uptr kMarkerSize = 512 * 1024 / sizeof(u64); - InternalScopedBuffer marker(kMarkerSize); + InternalMmapVector marker(kMarkerSize); // volatile to prevent insertion of memset for (volatile u64 *p = marker.data(); p < marker.data() + kMarkerSize; p++) *p = kShadowRodata; - internal_write(fd, marker.data(), marker.size()); + internal_write(fd, marker.data(), marker.size() * sizeof(u64)); // Map the file into memory. uptr page = internal_mmap(0, GetPageSizeCached(), PROT_READ | PROT_WRITE, MAP_PRIVATE | MAP_ANONYMOUS, fd, 0); @@ -188,8 +189,9 @@ static void MapRodata() { // Assume it's .rodata char *shadow_start = (char *)MemToShadow(segment.start); char *shadow_end = (char *)MemToShadow(segment.end); - for (char *p = shadow_start; p < shadow_end; p += marker.size()) { - internal_mmap(p, Min(marker.size(), shadow_end - p), + for (char *p = shadow_start; p < shadow_end; + p += marker.size() * sizeof(u64)) { + internal_mmap(p, Min(marker.size() * sizeof(u64), shadow_end - p), PROT_READ, MAP_PRIVATE | MAP_FIXED, fd, 0); } } @@ -208,17 +210,33 @@ void InitializePlatformEarly() { vmaSize = (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1); #if defined(__aarch64__) +# if !SANITIZER_GO if (vmaSize != 39 && vmaSize != 42 && vmaSize != 48) { Printf("FATAL: ThreadSanitizer: unsupported VMA range\n"); - Printf("FATAL: Found %d - Supported 39, 42 and 48\n", vmaSize); + Printf("FATAL: Found %zd - Supported 39, 42 and 48\n", vmaSize); Die(); } +#else + if (vmaSize != 48) { + Printf("FATAL: ThreadSanitizer: unsupported VMA range\n"); + Printf("FATAL: Found %zd - Supported 48\n", vmaSize); + Die(); + } +#endif #elif defined(__powerpc64__) +# if !SANITIZER_GO if (vmaSize != 44 && vmaSize != 46 && vmaSize != 47) { Printf("FATAL: ThreadSanitizer: unsupported VMA range\n"); - Printf("FATAL: Found %d - Supported 44, 46, and 47\n", vmaSize); + Printf("FATAL: Found %zd - Supported 44, 46, and 47\n", vmaSize); + Die(); + } +# else + if (vmaSize != 46 && vmaSize != 47) { + Printf("FATAL: ThreadSanitizer: unsupported VMA range\n"); + Printf("FATAL: Found %zd - Supported 46, and 47\n", vmaSize); Die(); } +# endif #endif #endif } @@ -399,4 +417,4 @@ void cur_thread_finalize() { } // namespace __tsan -#endif // SANITIZER_LINUX || SANITIZER_FREEBSD +#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD diff --git a/libsanitizer/tsan/tsan_platform_mac.cc b/libsanitizer/tsan/tsan_platform_mac.cc index 8eb22fa58ea..14395ba614a 100644 --- a/libsanitizer/tsan/tsan_platform_mac.cc +++ b/libsanitizer/tsan/tsan_platform_mac.cc @@ -229,7 +229,7 @@ static void my_pthread_introspection_hook(unsigned int event, pthread_t thread, void InitializePlatformEarly() { #if defined(__aarch64__) - uptr max_vm = GetMaxVirtualAddress() + 1; + uptr max_vm = GetMaxUserVirtualAddress() + 1; if (max_vm != Mapping::kHiAppMemEnd) { Printf("ThreadSanitizer: unsupported vm address limit %p, expected %p.\n", max_vm, Mapping::kHiAppMemEnd); @@ -238,6 +238,9 @@ void InitializePlatformEarly() { #endif } +static const uptr kPthreadSetjmpXorKeySlot = 0x7; +extern "C" uptr __tsan_darwin_setjmp_xor_key = 0; + void InitializePlatform() { DisableCoreDumperIfNecessary(); #if !SANITIZER_GO @@ -249,6 +252,11 @@ void InitializePlatform() { prev_pthread_introspection_hook = pthread_introspection_hook_install(&my_pthread_introspection_hook); #endif + + if (GetMacosVersion() >= MACOS_VERSION_MOJAVE) { + __tsan_darwin_setjmp_xor_key = + (uptr)pthread_getspecific(kPthreadSetjmpXorKeySlot); + } } #if !SANITIZER_GO diff --git a/libsanitizer/tsan/tsan_platform_posix.cc b/libsanitizer/tsan/tsan_platform_posix.cc index 6e62575f1ec..df9b6d41828 100644 --- a/libsanitizer/tsan/tsan_platform_posix.cc +++ b/libsanitizer/tsan/tsan_platform_posix.cc @@ -14,6 +14,7 @@ #if SANITIZER_POSIX #include "sanitizer_common/sanitizer_common.h" +#include "sanitizer_common/sanitizer_errno.h" #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_procmaps.h" #include "tsan_platform.h" @@ -21,16 +22,39 @@ namespace __tsan { +static const char kShadowMemoryMappingWarning[] = + "FATAL: %s can not madvise shadow region [%zx, %zx] with %s (errno: %d)\n"; +static const char kShadowMemoryMappingHint[] = + "HINT: if %s is not supported in your environment, you may set " + "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(); + } +} + +static void DontDumpShadow(uptr addr, uptr size) { + if (common_flags()->use_madv_dontdump) + if (!DontDumpShadowMemory(addr, size)) { + Printf(kShadowMemoryMappingWarning, SanitizerToolName, addr, addr + size, + "MADV_DONTDUMP", errno); + Printf(kShadowMemoryMappingHint, "MADV_DONTDUMP", "use_madv_dontdump"); + Die(); + } +} + #if !SANITIZER_GO void InitializeShadowMemory() { // Map memory shadow. - uptr shadow = - (uptr)MmapFixedNoReserve(ShadowBeg(), ShadowEnd() - ShadowBeg(), - "shadow"); - if (shadow != ShadowBeg()) { + if (!MmapFixedNoReserve(ShadowBeg(), ShadowEnd() - ShadowBeg(), "shadow")) { Printf("FATAL: ThreadSanitizer can not mmap the shadow memory\n"); - Printf("FATAL: Make sure to compile with -fPIE and " - "to link with -pie (%p, %p).\n", shadow, ShadowBeg()); + Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n"); Die(); } // This memory range is used for thread stacks and large user mmaps. @@ -72,30 +96,23 @@ void InitializeShadowMemory() { DCHECK(0); } #endif - NoHugePagesInRegion(MemToShadow(kMadviseRangeBeg), + NoHugePagesInShadow(MemToShadow(kMadviseRangeBeg), kMadviseRangeSize * kShadowMultiplier); - // Meta shadow is compressing and we don't flush it, - // so it makes sense to mark it as NOHUGEPAGE to not over-allocate memory. - // On one program it reduces memory consumption from 5GB to 2.5GB. - NoHugePagesInRegion(MetaShadowBeg(), MetaShadowEnd() - MetaShadowBeg()); - if (common_flags()->use_madv_dontdump) - DontDumpShadowMemory(ShadowBeg(), ShadowEnd() - ShadowBeg()); + DontDumpShadow(ShadowBeg(), ShadowEnd() - ShadowBeg()); DPrintf("memory shadow: %zx-%zx (%zuGB)\n", ShadowBeg(), ShadowEnd(), (ShadowEnd() - ShadowBeg()) >> 30); // Map meta shadow. - uptr meta_size = MetaShadowEnd() - MetaShadowBeg(); - uptr meta = - (uptr)MmapFixedNoReserve(MetaShadowBeg(), meta_size, "meta shadow"); - if (meta != MetaShadowBeg()) { + const uptr meta = MetaShadowBeg(); + const uptr meta_size = MetaShadowEnd() - meta; + if (!MmapFixedNoReserve(meta, meta_size, "meta shadow")) { Printf("FATAL: ThreadSanitizer can not mmap the shadow memory\n"); - Printf("FATAL: Make sure to compile with -fPIE and " - "to link with -pie (%p, %p).\n", meta, MetaShadowBeg()); + Printf("FATAL: Make sure to compile with -fPIE and to link with -pie.\n"); Die(); } - if (common_flags()->use_madv_dontdump) - DontDumpShadowMemory(meta, meta_size); + NoHugePagesInShadow(meta, meta_size); + DontDumpShadow(meta, meta_size); DPrintf("meta shadow: %zx-%zx (%zuGB)\n", meta, meta + meta_size, meta_size >> 30); diff --git a/libsanitizer/tsan/tsan_report.cc b/libsanitizer/tsan/tsan_report.cc index f8cb3e73ca4..4dffc342a92 100644 --- a/libsanitizer/tsan/tsan_report.cc +++ b/libsanitizer/tsan/tsan_report.cc @@ -46,18 +46,18 @@ class Decorator: public __sanitizer::SanitizerCommonDecorator { ReportDesc::ReportDesc() : tag(kExternalTagNone) - , stacks(MBlockReportStack) - , mops(MBlockReportMop) - , locs(MBlockReportLoc) - , mutexes(MBlockReportMutex) - , threads(MBlockReportThread) - , unique_tids(MBlockReportThread) + , stacks() + , mops() + , locs() + , mutexes() + , threads() + , unique_tids() , sleep() , count() { } ReportMop::ReportMop() - : mset(MBlockReportMutex) { + : mset() { } ReportDesc::~ReportDesc() { diff --git a/libsanitizer/tsan/tsan_report.h b/libsanitizer/tsan/tsan_report.h index 6eb043fc866..8e96e975804 100644 --- a/libsanitizer/tsan/tsan_report.h +++ b/libsanitizer/tsan/tsan_report.h @@ -12,8 +12,8 @@ #define TSAN_REPORT_H #include "sanitizer_common/sanitizer_symbolizer.h" +#include "sanitizer_common/sanitizer_vector.h" #include "tsan_defs.h" -#include "tsan_vector.h" namespace __tsan { diff --git a/libsanitizer/tsan/tsan_rtl.cc b/libsanitizer/tsan/tsan_rtl.cc index 4a1f50061a6..bd0892d0de5 100644 --- a/libsanitizer/tsan/tsan_rtl.cc +++ b/libsanitizer/tsan/tsan_rtl.cc @@ -100,11 +100,11 @@ Context::Context() , thread_registry(new(thread_registry_placeholder) ThreadRegistry( CreateThreadContext, kMaxTid, kThreadQuarantineSize, kMaxTidReuse)) , racy_mtx(MutexTypeRacy, StatMtxRacy) - , racy_stacks(MBlockRacyStacks) - , racy_addresses(MBlockRacyAddresses) + , racy_stacks() + , racy_addresses() , fired_suppressions_mtx(MutexTypeFired, StatMtxFired) - , fired_suppressions(8) , clock_alloc("clock allocator") { + fired_suppressions.reserve(8); } // The objects are allocated in TLS, so one may rely on zero-initialization. @@ -119,7 +119,7 @@ ThreadState::ThreadState(Context *ctx, int tid, int unique_id, u64 epoch, // , ignore_interceptors() , clock(tid, reuse_count) #if !SANITIZER_GO - , jmp_bufs(MBlockJmpBuf) + , jmp_bufs() #endif , tid(tid) , unique_id(unique_id) @@ -138,7 +138,7 @@ static void MemoryProfiler(Context *ctx, fd_t fd, int i) { uptr n_threads; uptr n_running_threads; ctx->thread_registry->GetNumberOfThreads(&n_threads, &n_running_threads); - InternalScopedBuffer buf(4096); + InternalMmapVector buf(4096); WriteMemoryProfile(buf.data(), buf.size(), n_threads, n_running_threads); WriteToFile(fd, buf.data(), internal_strlen(buf.data())); } @@ -212,7 +212,7 @@ static void BackgroundThread(void *arg) { memory_order_relaxed); if (last != 0 && last + flags()->flush_symbolizer_ms * kMs2Ns < now) { Lock l(&ctx->report_mtx); - SpinMutexLock l2(&CommonSanitizerReportMutex); + ScopedErrorReportLock l2; SymbolizeFlush(); atomic_store(&ctx->last_symbolize_time_ns, 0, memory_order_relaxed); } @@ -244,7 +244,8 @@ void MapShadow(uptr addr, uptr size) { const uptr kPageSize = GetPageSizeCached(); uptr shadow_begin = RoundDownTo((uptr)MemToShadow(addr), kPageSize); uptr shadow_end = RoundUpTo((uptr)MemToShadow(addr + size), kPageSize); - MmapFixedNoReserve(shadow_begin, shadow_end - shadow_begin, "shadow"); + if (!MmapFixedNoReserve(shadow_begin, shadow_end - shadow_begin, "shadow")) + Die(); // Meta shadow is 2:1, so tread carefully. static bool data_mapped = false; @@ -256,7 +257,8 @@ void MapShadow(uptr addr, uptr size) { if (!data_mapped) { // First call maps data+bss. data_mapped = true; - MmapFixedNoReserve(meta_begin, meta_end - meta_begin, "meta shadow"); + if (!MmapFixedNoReserve(meta_begin, meta_end - meta_begin, "meta shadow")) + Die(); } else { // Mapping continous heap. // Windows wants 64K alignment. @@ -266,7 +268,8 @@ void MapShadow(uptr addr, uptr size) { return; if (meta_begin < mapped_meta_end) meta_begin = mapped_meta_end; - MmapFixedNoReserve(meta_begin, meta_end - meta_begin, "meta shadow"); + if (!MmapFixedNoReserve(meta_begin, meta_end - meta_begin, "meta shadow")) + Die(); mapped_meta_end = meta_end; } VPrintf(2, "mapped meta shadow for (%p-%p) at (%p-%p)\n", @@ -278,10 +281,9 @@ void MapThreadTrace(uptr addr, uptr size, const char *name) { CHECK_GE(addr, TraceMemBeg()); CHECK_LE(addr + size, TraceMemEnd()); CHECK_EQ(addr, addr & ~((64 << 10) - 1)); // windows wants 64K alignment - uptr addr1 = (uptr)MmapFixedNoReserve(addr, size, name); - if (addr1 != addr) { - Printf("FATAL: ThreadSanitizer can not mmap thread trace (%p/%p->%p)\n", - addr, size, addr1); + if (!MmapFixedNoReserve(addr, size, name)) { + Printf("FATAL: ThreadSanitizer can not mmap thread trace (%p/%p)\n", + addr, size); Die(); } } @@ -322,6 +324,21 @@ 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); +} + +static void TsanOnDeadlySignal(int signo, void *siginfo, void *context) { + HandleDeadlySignal(siginfo, context, GetTid(), &OnStackUnwind, nullptr); +} +#endif + void Initialize(ThreadState *thr) { // Thread safe because done before all threads exist. static bool is_initialized = false; @@ -337,6 +354,7 @@ void Initialize(ThreadState *thr) { ctx = new(ctx_placeholder) Context; const char *options = GetEnv(SANITIZER_GO ? "GORACE" : "TSAN_OPTIONS"); CacheBinaryName(); + CheckASLR(); InitializeFlags(&ctx->flags, options); AvoidCVE_2016_2143(); InitializePlatformEarly(); @@ -359,6 +377,7 @@ void Initialize(ThreadState *thr) { #if !SANITIZER_GO InitializeShadowMemory(); InitializeAllocatorLate(); + InstallDeadlySignalHandlers(TsanOnDeadlySignal); #endif // Setup correct file descriptor for error reports. __sanitizer_set_report_path(common_flags()->log_path); @@ -366,13 +385,6 @@ void Initialize(ThreadState *thr) { #if !SANITIZER_GO InitializeLibIgnore(); Symbolizer::GetOrInit()->AddHooks(EnterSymbolizer, ExitSymbolizer); - // On MIPS, TSan initialization is run before - // __pthread_initialize_minimal_internal() is finished, so we can not spawn - // new threads. -#ifndef __mips__ - StartBackgroundThread(); - SetSandboxingCallback(StopBackgroundThread); -#endif #endif VPrintf(1, "***** Running under ThreadSanitizer v2 (pid %d) *****\n", @@ -401,6 +413,21 @@ void Initialize(ThreadState *thr) { OnInitialize(); } +void MaybeSpawnBackgroundThread() { + // On MIPS, TSan initialization is run before + // __pthread_initialize_minimal_internal() is finished, so we can not spawn + // new threads. +#if !SANITIZER_GO && !defined(__mips__) + static atomic_uint32_t bg_thread = {}; + if (atomic_load(&bg_thread, memory_order_relaxed) == 0 && + atomic_exchange(&bg_thread, 1, memory_order_relaxed) == 0) { + StartBackgroundThread(); + SetSandboxingCallback(StopBackgroundThread); + } +#endif +} + + int Finalize(ThreadState *thr) { bool failed = false; @@ -411,8 +438,7 @@ int Finalize(ThreadState *thr) { // Wait for pending reports. ctx->report_mtx.Lock(); - CommonSanitizerReportMutex.Lock(); - CommonSanitizerReportMutex.Unlock(); + { ScopedErrorReportLock l; } ctx->report_mtx.Unlock(); #if !SANITIZER_GO @@ -522,6 +548,10 @@ u32 CurrentStackId(ThreadState *thr, uptr pc) { } void TraceSwitch(ThreadState *thr) { +#if !SANITIZER_GO + if (ctx->after_multithreaded_fork) + return; +#endif thr->nomalloc++; Trace *thr_trace = ThreadTrace(thr->tid); Lock l(&thr_trace->mtx); @@ -893,7 +923,8 @@ static void MemoryRangeSet(ThreadState *thr, uptr pc, uptr addr, uptr size, u64 *p1 = p; p = RoundDown(end, kPageSize); UnmapOrDie((void*)p1, (uptr)p - (uptr)p1); - MmapFixedNoReserve((uptr)p1, (uptr)p - (uptr)p1); + if (!MmapFixedNoReserve((uptr)p1, (uptr)p - (uptr)p1)) + Die(); // Set the ending. while (p < end) { *p++ = val; diff --git a/libsanitizer/tsan/tsan_rtl.h b/libsanitizer/tsan/tsan_rtl.h index 7dd9779e42b..f97b583c48b 100644 --- a/libsanitizer/tsan/tsan_rtl.h +++ b/libsanitizer/tsan/tsan_rtl.h @@ -32,12 +32,13 @@ #include "sanitizer_common/sanitizer_libignore.h" #include "sanitizer_common/sanitizer_suppressions.h" #include "sanitizer_common/sanitizer_thread_registry.h" +#include "sanitizer_common/sanitizer_vector.h" #include "tsan_clock.h" #include "tsan_defs.h" #include "tsan_flags.h" +#include "tsan_mman.h" #include "tsan_sync.h" #include "tsan_trace.h" -#include "tsan_vector.h" #include "tsan_report.h" #include "tsan_platform.h" #include "tsan_mutexset.h" @@ -517,7 +518,9 @@ struct Context { Context(); bool initialized; +#if !SANITIZER_GO bool after_multithreaded_fork; +#endif MetaMap metamap; @@ -572,11 +575,8 @@ const char *GetObjectTypeFromTag(uptr tag); const char *GetReportHeaderFromTag(uptr tag); uptr TagFromShadowStackFrame(uptr pc); -class ScopedReport { +class ScopedReportBase { public: - explicit ScopedReport(ReportType typ, uptr tag = kExternalTagNone); - ~ScopedReport(); - void AddMemoryAccess(uptr addr, uptr external_tag, Shadow s, StackTrace stack, const MutexSet *mset); void AddStack(StackTrace stack, bool suppressable = false); @@ -591,6 +591,10 @@ class ScopedReport { const ReportDesc *GetReport() const; + protected: + ScopedReportBase(ReportType typ, uptr tag); + ~ScopedReportBase(); + private: ReportDesc *rep_; // Symbolizer makes lots of intercepted calls. If we try to process them, @@ -599,8 +603,17 @@ class ScopedReport { void AddDeadMutex(u64 id); - ScopedReport(const ScopedReport&); - void operator = (const ScopedReport&); + ScopedReportBase(const ScopedReportBase &) = delete; + void operator=(const ScopedReportBase &) = delete; +}; + +class ScopedReport : public ScopedReportBase { + public: + explicit ScopedReport(ReportType typ, uptr tag = kExternalTagNone); + ~ScopedReport(); + + private: + ScopedErrorReportLock lock_; }; ThreadContext *IsThreadStackOrTls(uptr addr, bool *is_stack); @@ -635,6 +648,10 @@ void ObtainCurrentStack(ThreadState *thr, uptr toppc, StackTraceTy *stack, ExtractTagFromStack(stack, tag); } +#define GET_STACK_TRACE_FATAL(thr, pc) \ + VarSizeStackTrace stack; \ + ObtainCurrentStack(thr, pc, &stack); \ + stack.ReverseOrder(); #if TSAN_COLLECT_STATS void StatAggregate(u64 *dst, u64 *src); @@ -688,6 +705,7 @@ void PrintCurrentStack(ThreadState *thr, uptr pc); void PrintCurrentStackSlow(uptr pc); // uses libunwind void Initialize(ThreadState *thr); +void MaybeSpawnBackgroundThread(); int Finalize(ThreadState *thr); void OnUserAlloc(ThreadState *thr, uptr pc, uptr p, uptr sz, bool write); diff --git a/libsanitizer/tsan/tsan_rtl_aarch64.S b/libsanitizer/tsan/tsan_rtl_aarch64.S index 61171d635c1..3d02bf22f8a 100644 --- a/libsanitizer/tsan/tsan_rtl_aarch64.S +++ b/libsanitizer/tsan/tsan_rtl_aarch64.S @@ -6,7 +6,7 @@ #if !defined(__APPLE__) .section .bss .type __tsan_pointer_chk_guard, %object -ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(__tsan_pointer_chk_guard)) +ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__tsan_pointer_chk_guard)) __tsan_pointer_chk_guard: .zero 8 #endif @@ -51,7 +51,7 @@ _sigsetjmp$non_lazy_ptr: // original ones. ASM_HIDDEN(_Z18InitializeGuardPtrv) .global _Z18InitializeGuardPtrv -ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(_Z18InitializeGuardPtrv)) +ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_Z18InitializeGuardPtrv)) _Z18InitializeGuardPtrv: CFI_STARTPROC // Allocates a jmp_buf for the setjmp call. @@ -88,14 +88,14 @@ _Z18InitializeGuardPtrv: CFI_DEF_CFA (31, 0) ret CFI_ENDPROC -ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(_Z18InitializeGuardPtrv)) +ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_Z18InitializeGuardPtrv)) #endif ASM_HIDDEN(__tsan_setjmp) .comm _ZN14__interception11real_setjmpE,8,8 -.globl ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp) -ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp)) -ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp): +.globl ASM_SYMBOL_INTERCEPTOR(setjmp) +ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(setjmp)) +ASM_SYMBOL_INTERCEPTOR(setjmp): CFI_STARTPROC // save env parameters for function call @@ -120,12 +120,14 @@ ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp): 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 - mov x1, x0 + eor x1, x2, x0 #endif // call tsan interceptor - bl ASM_TSAN_SYMBOL(__tsan_setjmp) + bl ASM_SYMBOL(__tsan_setjmp) // restore env parameter mov x0, x19 @@ -148,12 +150,12 @@ ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp): br x1 CFI_ENDPROC -ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp)) +ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(setjmp)) .comm _ZN14__interception12real__setjmpE,8,8 -.globl ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp) -ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp)) -ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp): +.globl ASM_SYMBOL_INTERCEPTOR(_setjmp) +ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_setjmp)) +ASM_SYMBOL_INTERCEPTOR(_setjmp): CFI_STARTPROC // save env parameters for function call @@ -178,12 +180,14 @@ ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp): 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 - mov x1, x0 + eor x1, x2, x0 #endif // call tsan interceptor - bl ASM_TSAN_SYMBOL(__tsan_setjmp) + bl ASM_SYMBOL(__tsan_setjmp) // Restore jmp_buf parameter mov x0, x19 @@ -206,12 +210,12 @@ ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp): br x1 CFI_ENDPROC -ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp)) +ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_setjmp)) .comm _ZN14__interception14real_sigsetjmpE,8,8 -.globl ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp) -ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp)) -ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp): +.globl ASM_SYMBOL_INTERCEPTOR(sigsetjmp) +ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(sigsetjmp)) +ASM_SYMBOL_INTERCEPTOR(sigsetjmp): CFI_STARTPROC // save env parameters for function call @@ -238,12 +242,14 @@ ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp): 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 - mov x1, x0 + eor x1, x2, x0 #endif // call tsan interceptor - bl ASM_TSAN_SYMBOL(__tsan_setjmp) + bl ASM_SYMBOL(__tsan_setjmp) // restore env parameter mov w1, w20 @@ -268,13 +274,13 @@ ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp): #endif br x2 CFI_ENDPROC -ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp)) +ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(sigsetjmp)) #if !defined(__APPLE__) .comm _ZN14__interception16real___sigsetjmpE,8,8 -.globl ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp) -ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp)) -ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp): +.globl ASM_SYMBOL_INTERCEPTOR(__sigsetjmp) +ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)) +ASM_SYMBOL_INTERCEPTOR(__sigsetjmp): CFI_STARTPROC // save env parameters for function call @@ -303,7 +309,7 @@ ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp): #endif // call tsan interceptor - bl ASM_TSAN_SYMBOL(__tsan_setjmp) + bl ASM_SYMBOL(__tsan_setjmp) mov w1, w20 mov x0, x19 @@ -321,12 +327,12 @@ ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp): ldr x2, [x2, #:got_lo12:_ZN14__interception16real___sigsetjmpE] ldr x2, [x2] #else - adrp x2, ASM_TSAN_SYMBOL(__sigsetjmp)@page - add x2, x2, ASM_TSAN_SYMBOL(__sigsetjmp)@pageoff + adrp x2, ASM_SYMBOL(__sigsetjmp)@page + add x2, x2, ASM_SYMBOL(__sigsetjmp)@pageoff #endif br x2 CFI_ENDPROC -ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp)) +ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)) #endif #if defined(__linux__) diff --git a/libsanitizer/tsan/tsan_rtl_amd64.S b/libsanitizer/tsan/tsan_rtl_amd64.S index 4eb1ffdd2b7..34ef51c2a72 100644 --- a/libsanitizer/tsan/tsan_rtl_amd64.S +++ b/libsanitizer/tsan/tsan_rtl_amd64.S @@ -2,7 +2,6 @@ #if defined(__x86_64__) #include "sanitizer_common/sanitizer_asm.h" -#include "cet.h" #if !defined(__APPLE__) .section .text @@ -11,10 +10,9 @@ #endif ASM_HIDDEN(__tsan_trace_switch) -.globl ASM_TSAN_SYMBOL(__tsan_trace_switch_thunk) -ASM_TSAN_SYMBOL(__tsan_trace_switch_thunk): +.globl ASM_SYMBOL(__tsan_trace_switch_thunk) +ASM_SYMBOL(__tsan_trace_switch_thunk): CFI_STARTPROC - _CET_ENDBR # Save scratch registers. push %rax CFI_ADJUST_CFA_OFFSET(8) @@ -52,7 +50,7 @@ ASM_TSAN_SYMBOL(__tsan_trace_switch_thunk): shr $4, %rsp # clear 4 lsb, align to 16 shl $4, %rsp - call ASM_TSAN_SYMBOL(__tsan_trace_switch) + call ASM_SYMBOL(__tsan_trace_switch) # Unalign stack frame back. mov %rbx, %rsp # restore the original rsp @@ -92,10 +90,9 @@ ASM_TSAN_SYMBOL(__tsan_trace_switch_thunk): CFI_ENDPROC ASM_HIDDEN(__tsan_report_race) -.globl ASM_TSAN_SYMBOL(__tsan_report_race_thunk) -ASM_TSAN_SYMBOL(__tsan_report_race_thunk): +.globl ASM_SYMBOL(__tsan_report_race_thunk) +ASM_SYMBOL(__tsan_report_race_thunk): CFI_STARTPROC - _CET_ENDBR # Save scratch registers. push %rax CFI_ADJUST_CFA_OFFSET(8) @@ -133,7 +130,7 @@ ASM_TSAN_SYMBOL(__tsan_report_race_thunk): shr $4, %rsp # clear 4 lsb, align to 16 shl $4, %rsp - call ASM_TSAN_SYMBOL(__tsan_report_race) + call ASM_SYMBOL(__tsan_report_race) # Unalign stack frame back. mov %rbx, %rsp # restore the original rsp @@ -173,25 +170,33 @@ ASM_TSAN_SYMBOL(__tsan_report_race_thunk): CFI_ENDPROC ASM_HIDDEN(__tsan_setjmp) -#if !defined(__APPLE__) +#if defined(__NetBSD__) +.comm _ZN14__interception15real___setjmp14E,8,8 +#elif !defined(__APPLE__) .comm _ZN14__interception11real_setjmpE,8,8 #endif -.globl ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp) -ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp)) -ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp): +#if defined(__NetBSD__) +.globl ASM_SYMBOL_INTERCEPTOR(__setjmp14) +ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(__setjmp14)) +ASM_SYMBOL_INTERCEPTOR(__setjmp14): +#else +.globl ASM_SYMBOL_INTERCEPTOR(setjmp) +ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(setjmp)) +ASM_SYMBOL_INTERCEPTOR(setjmp): +#endif CFI_STARTPROC - _CET_ENDBR // save env parameter push %rdi CFI_ADJUST_CFA_OFFSET(8) CFI_REL_OFFSET(%rdi, 0) // obtain %rsp -#if defined(__FreeBSD__) +#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__) lea 16(%rsp), %rdi mov %rdi, %rsi @@ -201,39 +206,46 @@ ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp): # error "Unknown platform" #endif // call tsan interceptor - call ASM_TSAN_SYMBOL(__tsan_setjmp) + call ASM_SYMBOL(__tsan_setjmp) // restore env parameter pop %rdi CFI_ADJUST_CFA_OFFSET(-8) CFI_RESTORE(%rdi) // tail jump to libc setjmp movl $0, %eax -#if !defined(__APPLE__) +#if defined(__NetBSD__) + movq _ZN14__interception15real___setjmp14E@GOTPCREL(%rip), %rdx + jmp *(%rdx) +#elif !defined(__APPLE__) movq _ZN14__interception11real_setjmpE@GOTPCREL(%rip), %rdx jmp *(%rdx) #else - jmp ASM_TSAN_SYMBOL(setjmp) + jmp ASM_SYMBOL(setjmp) #endif CFI_ENDPROC -ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(setjmp)) +#if defined(__NetBSD__) +ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__setjmp14)) +#else +ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(setjmp)) +#endif .comm _ZN14__interception12real__setjmpE,8,8 -.globl ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp) -ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp)) -ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp): +.globl ASM_SYMBOL_INTERCEPTOR(_setjmp) +ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(_setjmp)) +ASM_SYMBOL_INTERCEPTOR(_setjmp): CFI_STARTPROC - _CET_ENDBR // save env parameter push %rdi CFI_ADJUST_CFA_OFFSET(8) CFI_REL_OFFSET(%rdi, 0) // obtain %rsp -#if defined(__FreeBSD__) +#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__) lea 16(%rsp), %rdi mov %rdi, %rsi @@ -243,7 +255,7 @@ ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp): # error "Unknown platform" #endif // call tsan interceptor - call ASM_TSAN_SYMBOL(__tsan_setjmp) + call ASM_SYMBOL(__tsan_setjmp) // restore env parameter pop %rdi CFI_ADJUST_CFA_OFFSET(-8) @@ -254,17 +266,23 @@ ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp): movq _ZN14__interception12real__setjmpE@GOTPCREL(%rip), %rdx jmp *(%rdx) #else - jmp ASM_TSAN_SYMBOL(_setjmp) + jmp ASM_SYMBOL(_setjmp) #endif CFI_ENDPROC -ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(_setjmp)) +ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(_setjmp)) +#if defined(__NetBSD__) +.comm _ZN14__interception18real___sigsetjmp14E,8,8 +.globl ASM_SYMBOL_INTERCEPTOR(__sigsetjmp14) +ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp14)) +ASM_SYMBOL_INTERCEPTOR(__sigsetjmp14): +#else .comm _ZN14__interception14real_sigsetjmpE,8,8 -.globl ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp) -ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp)) -ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp): +.globl ASM_SYMBOL_INTERCEPTOR(sigsetjmp) +ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(sigsetjmp)) +ASM_SYMBOL_INTERCEPTOR(sigsetjmp): +#endif CFI_STARTPROC - _CET_ENDBR // save env parameter push %rdi CFI_ADJUST_CFA_OFFSET(8) @@ -277,12 +295,13 @@ ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp): sub $8, %rsp CFI_ADJUST_CFA_OFFSET(8) // obtain %rsp -#if defined(__FreeBSD__) +#if defined(__FreeBSD__) || defined(__NetBSD__) lea 24(%rsp), %rdi mov %rdi, %rsi #elif 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 @@ -292,7 +311,7 @@ ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp): # error "Unknown platform" #endif // call tsan interceptor - call ASM_TSAN_SYMBOL(__tsan_setjmp) + call ASM_SYMBOL(__tsan_setjmp) // unalign stack frame add $8, %rsp CFI_ADJUST_CFA_OFFSET(-8) @@ -306,22 +325,28 @@ ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp): CFI_RESTORE(%rdi) // tail jump to libc sigsetjmp movl $0, %eax -#if !defined(__APPLE__) +#if defined(__NetBSD__) + movq _ZN14__interception18real___sigsetjmp14E@GOTPCREL(%rip), %rdx + jmp *(%rdx) +#elif !defined(__APPLE__) movq _ZN14__interception14real_sigsetjmpE@GOTPCREL(%rip), %rdx jmp *(%rdx) #else - jmp ASM_TSAN_SYMBOL(sigsetjmp) + jmp ASM_SYMBOL(sigsetjmp) #endif CFI_ENDPROC -ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(sigsetjmp)) +#if defined(__NetBSD__) +ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp14)) +#else +ASM_SIZE(ASM_SYMBOL_INTERCEPTOR(sigsetjmp)) +#endif -#if !defined(__APPLE__) +#if !defined(__APPLE__) && !defined(__NetBSD__) .comm _ZN14__interception16real___sigsetjmpE,8,8 -.globl ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp) -ASM_TYPE_FUNCTION(ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp)) -ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp): +.globl ASM_SYMBOL_INTERCEPTOR(__sigsetjmp) +ASM_TYPE_FUNCTION(ASM_SYMBOL_INTERCEPTOR(__sigsetjmp)) +ASM_SYMBOL_INTERCEPTOR(__sigsetjmp): CFI_STARTPROC - _CET_ENDBR // save env parameter push %rdi CFI_ADJUST_CFA_OFFSET(8) @@ -344,7 +369,7 @@ ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp): rol $0x11, %rsi #endif // call tsan interceptor - call ASM_TSAN_SYMBOL(__tsan_setjmp) + call ASM_SYMBOL(__tsan_setjmp) // unalign stack frame add $8, %rsp CFI_ADJUST_CFA_OFFSET(-8) @@ -361,11 +386,12 @@ ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp): movq _ZN14__interception16real___sigsetjmpE@GOTPCREL(%rip), %rdx jmp *(%rdx) CFI_ENDPROC -ASM_SIZE(ASM_TSAN_SYMBOL_INTERCEPTOR(__sigsetjmp)) -#endif // !defined(__APPLE__) +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 diff --git a/libsanitizer/tsan/tsan_rtl_mutex.cc b/libsanitizer/tsan/tsan_rtl_mutex.cc index d10a87374ba..6981f98dcb9 100644 --- a/libsanitizer/tsan/tsan_rtl_mutex.cc +++ b/libsanitizer/tsan/tsan_rtl_mutex.cc @@ -82,7 +82,9 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr, u32 flagz) { SyncVar *s = ctx->metamap.GetIfExistsAndLock(addr, true); if (s == 0) return; - if ((flagz & MutexFlagLinkerInit) || s->IsFlagSet(MutexFlagLinkerInit)) { + if ((flagz & MutexFlagLinkerInit) + || s->IsFlagSet(MutexFlagLinkerInit) + || ((flagz & MutexFlagNotStatic) && !s->IsFlagSet(MutexFlagNotStatic))) { // Destroy is no-op for linker-initialized mutexes. s->mtx.Unlock(); return; @@ -100,7 +102,7 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr, u32 flagz) { unlock_locked = true; } u64 mid = s->GetId(); - u32 last_lock = s->last_lock; + u64 last_lock = s->last_lock; if (!unlock_locked) s->Reset(thr->proc()); // must not reset it before the report is printed s->mtx.Unlock(); @@ -110,7 +112,7 @@ void MutexDestroy(ThreadState *thr, uptr pc, uptr addr, u32 flagz) { rep.AddMutex(mid); VarSizeStackTrace trace; ObtainCurrentStack(thr, pc, &trace); - rep.AddStack(trace); + rep.AddStack(trace, true); FastState last(last_lock); RestoreStack(last.tid(), last.epoch(), &trace, 0); rep.AddStack(trace, true); @@ -357,7 +359,7 @@ void MutexReadOrWriteUnlock(ThreadState *thr, uptr pc, uptr addr) { if (s->recursion == 0) { StatInc(thr, StatMutexUnlock); s->owner_tid = SyncVar::kInvalidTid; - ReleaseImpl(thr, pc, &s->clock); + ReleaseStoreImpl(thr, pc, &s->clock); } else { StatInc(thr, StatMutexRecUnlock); } diff --git a/libsanitizer/tsan/tsan_rtl_report.cc b/libsanitizer/tsan/tsan_rtl_report.cc index a961139b61d..18b6cf7fd50 100644 --- a/libsanitizer/tsan/tsan_rtl_report.cc +++ b/libsanitizer/tsan/tsan_rtl_report.cc @@ -141,30 +141,28 @@ static ReportStack *SymbolizeStack(StackTrace trace) { return stack; } -ScopedReport::ScopedReport(ReportType typ, uptr tag) { +ScopedReportBase::ScopedReportBase(ReportType typ, uptr tag) { ctx->thread_registry->CheckLocked(); void *mem = internal_alloc(MBlockReport, sizeof(ReportDesc)); rep_ = new(mem) ReportDesc; rep_->typ = typ; rep_->tag = tag; ctx->report_mtx.Lock(); - CommonSanitizerReportMutex.Lock(); } -ScopedReport::~ScopedReport() { - CommonSanitizerReportMutex.Unlock(); +ScopedReportBase::~ScopedReportBase() { ctx->report_mtx.Unlock(); DestroyAndFree(rep_); } -void ScopedReport::AddStack(StackTrace stack, bool suppressable) { +void ScopedReportBase::AddStack(StackTrace stack, bool suppressable) { ReportStack **rs = rep_->stacks.PushBack(); *rs = SymbolizeStack(stack); (*rs)->suppressable = suppressable; } -void ScopedReport::AddMemoryAccess(uptr addr, uptr external_tag, Shadow s, - StackTrace stack, const MutexSet *mset) { +void ScopedReportBase::AddMemoryAccess(uptr addr, uptr external_tag, Shadow s, + StackTrace stack, const MutexSet *mset) { void *mem = internal_alloc(MBlockReportMop, sizeof(ReportMop)); ReportMop *mop = new(mem) ReportMop; rep_->mops.PushBack(mop); @@ -185,11 +183,11 @@ void ScopedReport::AddMemoryAccess(uptr addr, uptr external_tag, Shadow s, } } -void ScopedReport::AddUniqueTid(int unique_tid) { +void ScopedReportBase::AddUniqueTid(int unique_tid) { rep_->unique_tids.PushBack(unique_tid); } -void ScopedReport::AddThread(const ThreadContext *tctx, bool suppressable) { +void ScopedReportBase::AddThread(const ThreadContext *tctx, bool suppressable) { for (uptr i = 0; i < rep_->threads.Size(); i++) { if ((u32)rep_->threads[i]->id == tctx->tid) return; @@ -253,14 +251,14 @@ ThreadContext *IsThreadStackOrTls(uptr addr, bool *is_stack) { } #endif -void ScopedReport::AddThread(int unique_tid, bool suppressable) { +void ScopedReportBase::AddThread(int unique_tid, bool suppressable) { #if !SANITIZER_GO if (const ThreadContext *tctx = FindThreadByUidLocked(unique_tid)) AddThread(tctx, suppressable); #endif } -void ScopedReport::AddMutex(const SyncVar *s) { +void ScopedReportBase::AddMutex(const SyncVar *s) { for (uptr i = 0; i < rep_->mutexes.Size(); i++) { if (rep_->mutexes[i]->id == s->uid) return; @@ -274,7 +272,7 @@ void ScopedReport::AddMutex(const SyncVar *s) { rm->stack = SymbolizeStackId(s->creation_stack_id); } -u64 ScopedReport::AddMutex(u64 id) { +u64 ScopedReportBase::AddMutex(u64 id) { u64 uid = 0; u64 mid = id; uptr addr = SyncVar::SplitId(id, &uid); @@ -293,7 +291,7 @@ u64 ScopedReport::AddMutex(u64 id) { return mid; } -void ScopedReport::AddDeadMutex(u64 id) { +void ScopedReportBase::AddDeadMutex(u64 id) { for (uptr i = 0; i < rep_->mutexes.Size(); i++) { if (rep_->mutexes[i]->id == id) return; @@ -307,7 +305,7 @@ void ScopedReport::AddDeadMutex(u64 id) { rm->stack = 0; } -void ScopedReport::AddLocation(uptr addr, uptr size) { +void ScopedReportBase::AddLocation(uptr addr, uptr size) { if (addr == 0) return; #if !SANITIZER_GO @@ -362,18 +360,19 @@ void ScopedReport::AddLocation(uptr addr, uptr size) { } #if !SANITIZER_GO -void ScopedReport::AddSleep(u32 stack_id) { +void ScopedReportBase::AddSleep(u32 stack_id) { rep_->sleep = SymbolizeStackId(stack_id); } #endif -void ScopedReport::SetCount(int count) { - rep_->count = count; -} +void ScopedReportBase::SetCount(int count) { rep_->count = count; } -const ReportDesc *ScopedReport::GetReport() const { - return rep_; -} +const ReportDesc *ScopedReportBase::GetReport() const { return rep_; } + +ScopedReport::ScopedReport(ReportType typ, uptr tag) + : ScopedReportBase(typ, tag) {} + +ScopedReport::~ScopedReport() {} void RestoreStack(int tid, const u64 epoch, VarSizeStackTrace *stk, MutexSet *mset, uptr *tag) { @@ -392,7 +391,7 @@ void RestoreStack(int tid, const u64 epoch, VarSizeStackTrace *stk, const u64 ebegin = RoundDown(eend, kTracePartSize); DPrintf("#%d: RestoreStack epoch=%zu ebegin=%zu eend=%zu partidx=%d\n", tid, (uptr)epoch, (uptr)ebegin, (uptr)eend, partidx); - Vector stack(MBlockReportStack); + Vector stack; stack.Resize(hdr->stack0.size + 64); for (uptr i = 0; i < hdr->stack0.size; i++) { stack[i] = hdr->stack0.trace[i]; @@ -648,8 +647,8 @@ void ReportRace(ThreadState *thr) { // callback. Most likely, TraceTopPC will now return a EventTypeFuncExit // event. Later we subtract -1 from it (in GetPreviousInstructionPc) // and the resulting PC has kExternalPCBit set, so we pass it to - // __tsan_symbolize_external. __tsan_symbolize_external is within its rights - // to crash since the PC is completely bogus. + // __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. toppc = 0; } @@ -658,7 +657,7 @@ void ReportRace(ThreadState *thr) { return; // MutexSet is too large to live on stack. - Vector mset_buffer(MBlockScopedBuf); + Vector mset_buffer; mset_buffer.Resize(sizeof(MutexSet) / sizeof(u64) + 1); MutexSet *mset2 = new(&mset_buffer[0]) MutexSet(); diff --git a/libsanitizer/tsan/tsan_rtl_thread.cc b/libsanitizer/tsan/tsan_rtl_thread.cc index e81669d3b77..7a731c4006a 100644 --- a/libsanitizer/tsan/tsan_rtl_thread.cc +++ b/libsanitizer/tsan/tsan_rtl_thread.cc @@ -209,7 +209,7 @@ void ThreadFinalize(ThreadState *thr) { if (!flags()->report_thread_leaks) return; ThreadRegistryLock l(ctx->thread_registry); - Vector leaks(MBlockScopedBuf); + Vector leaks; ctx->thread_registry->RunCallbackForEachThreadLocked( MaybeReportThreadLeak, &leaks); for (uptr i = 0; i < leaks.Size(); i++) { diff --git a/libsanitizer/tsan/tsan_stack_trace.cc b/libsanitizer/tsan/tsan_stack_trace.cc index 3734e0e4975..4ddec965f32 100644 --- a/libsanitizer/tsan/tsan_stack_trace.cc +++ b/libsanitizer/tsan/tsan_stack_trace.cc @@ -41,4 +41,9 @@ void VarSizeStackTrace::Init(const uptr *pcs, uptr cnt, uptr extra_top_pc) { trace_buffer[cnt] = extra_top_pc; } +void VarSizeStackTrace::ReverseOrder() { + for (u32 i = 0; i < (size >> 1); i++) + Swap(trace_buffer[i], trace_buffer[size - 1 - i]); +} + } // namespace __tsan diff --git a/libsanitizer/tsan/tsan_stack_trace.h b/libsanitizer/tsan/tsan_stack_trace.h index b097a9b2696..bc4468f4405 100644 --- a/libsanitizer/tsan/tsan_stack_trace.h +++ b/libsanitizer/tsan/tsan_stack_trace.h @@ -25,6 +25,10 @@ struct VarSizeStackTrace : public StackTrace { ~VarSizeStackTrace(); void Init(const uptr *pcs, uptr cnt, uptr extra_top_pc = 0); + // Reverses the current stack trace order, the top frame goes to the bottom, + // the last frame goes to the top. + void ReverseOrder(); + private: void ResizeBuffer(uptr new_size); diff --git a/libsanitizer/tsan/tsan_suppressions.cc b/libsanitizer/tsan/tsan_suppressions.cc index e40eb70ceec..d48148fed5c 100644 --- a/libsanitizer/tsan/tsan_suppressions.cc +++ b/libsanitizer/tsan/tsan_suppressions.cc @@ -150,7 +150,7 @@ uptr IsSuppressed(ReportType typ, const ReportLocation *loc, Suppression **sp) { } void PrintMatchedSuppressions() { - InternalMmapVector matched(1); + InternalMmapVector matched; CHECK(suppression_ctx); suppression_ctx->GetMatched(&matched); if (!matched.size()) diff --git a/libsanitizer/tsan/tsan_symbolize.cc b/libsanitizer/tsan/tsan_symbolize.cc index 7b04782d1ad..074006be70d 100644 --- a/libsanitizer/tsan/tsan_symbolize.cc +++ b/libsanitizer/tsan/tsan_symbolize.cc @@ -34,6 +34,7 @@ void ExitSymbolizer() { thr->ignore_interceptors--; } +// Legacy API. // May be overriden by JIT/JAVA/etc, // whatever produces PCs marked with kExternalPCBit. SANITIZER_WEAK_DEFAULT_IMPL @@ -43,9 +44,49 @@ bool __tsan_symbolize_external(uptr pc, char *func_buf, uptr func_siz, return false; } +// New API: call __tsan_symbolize_external_ex only when it exists. +// Once old clients are gone, provide dummy implementation. +SANITIZER_WEAK_DEFAULT_IMPL +void __tsan_symbolize_external_ex(uptr pc, + void (*add_frame)(void *, const char *, + const char *, int, int), + void *ctx) {} + +struct SymbolizedStackBuilder { + SymbolizedStack *head; + SymbolizedStack *tail; + uptr addr; +}; + +static void AddFrame(void *ctx, const char *function_name, const char *file, + int line, int column) { + SymbolizedStackBuilder *ssb = (struct SymbolizedStackBuilder *)ctx; + if (ssb->tail) { + ssb->tail->next = SymbolizedStack::New(ssb->addr); + ssb->tail = ssb->tail->next; + } else { + ssb->head = ssb->tail = SymbolizedStack::New(ssb->addr); + } + AddressInfo *info = &ssb->tail->info; + if (function_name) { + info->function = internal_strdup(function_name); + } + if (file) { + info->file = internal_strdup(file); + } + info->line = line; + info->column = column; +} + SymbolizedStack *SymbolizeCode(uptr addr) { // Check if PC comes from non-native land. if (addr & kExternalPCBit) { + SymbolizedStackBuilder ssb = {nullptr, nullptr, addr}; + __tsan_symbolize_external_ex(addr, AddFrame, &ssb); + if (ssb.head) + return ssb.head; + // Legacy code: remove along with the declaration above + // once all clients using this API are gone. // Declare static to not consume too much stack space. // We symbolize reports in a single thread, so this is fine. static char func_buf[1024]; diff --git a/libsanitizer/tsan/tsan_sync.cc b/libsanitizer/tsan/tsan_sync.cc index 0f840de1f11..10ae446e58b 100644 --- a/libsanitizer/tsan/tsan_sync.cc +++ b/libsanitizer/tsan/tsan_sync.cc @@ -174,7 +174,8 @@ void MetaMap::ResetRange(Processor *proc, uptr p, uptr sz) { uptr metap = (uptr)MemToMeta(p0); uptr metasz = sz0 / kMetaRatio; UnmapOrDie((void*)metap, metasz); - MmapFixedNoReserve(metap, metasz); + if (!MmapFixedNoReserve(metap, metasz)) + Die(); } MBlock* MetaMap::GetBlock(uptr p) { diff --git a/libsanitizer/tsan/tsan_sync.h b/libsanitizer/tsan/tsan_sync.h index 195279fc1f2..a4409fe49ae 100644 --- a/libsanitizer/tsan/tsan_sync.h +++ b/libsanitizer/tsan/tsan_sync.h @@ -32,6 +32,7 @@ enum MutexFlags { MutexFlagTryLockFailed = 1 << 5, // __tsan_mutex_try_lock_failed MutexFlagRecursiveLock = 1 << 6, // __tsan_mutex_recursive_lock MutexFlagRecursiveUnlock = 1 << 7, // __tsan_mutex_recursive_unlock + MutexFlagNotStatic = 1 << 8, // __tsan_mutex_not_static // The following flags are runtime private. // Mutex API misuse was detected, so don't report any more. @@ -41,7 +42,8 @@ enum MutexFlags { // Must list all mutex creation flags. MutexCreationFlagMask = MutexFlagLinkerInit | MutexFlagWriteReentrant | - MutexFlagReadReentrant, + MutexFlagReadReentrant | + MutexFlagNotStatic, }; struct SyncVar { diff --git a/libsanitizer/ubsan/ubsan_checks.inc b/libsanitizer/ubsan/ubsan_checks.inc index c4459245f3e..dbe5550a9e4 100644 --- a/libsanitizer/ubsan/ubsan_checks.inc +++ b/libsanitizer/ubsan/ubsan_checks.inc @@ -28,6 +28,12 @@ UBSAN_CHECK(IntegerDivideByZero, "integer-divide-by-zero", "integer-divide-by-zero") UBSAN_CHECK(FloatDivideByZero, "float-divide-by-zero", "float-divide-by-zero") UBSAN_CHECK(InvalidBuiltin, "invalid-builtin-use", "invalid-builtin-use") +UBSAN_CHECK(ImplicitUnsignedIntegerTruncation, + "implicit-unsigned-integer-truncation", + "implicit-unsigned-integer-truncation") +UBSAN_CHECK(ImplicitSignedIntegerTruncation, + "implicit-signed-integer-truncation", + "implicit-signed-integer-truncation") 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.cc index 978d966f1c3..cdf15b70e26 100644 --- a/libsanitizer/ubsan/ubsan_diag.cc +++ b/libsanitizer/ubsan/ubsan_diag.cc @@ -14,6 +14,7 @@ #include "ubsan_diag.h" #include "ubsan_init.h" #include "ubsan_flags.h" +#include "ubsan_monitor.h" #include "sanitizer_common/sanitizer_placement_new.h" #include "sanitizer_common/sanitizer_report_decorator.h" #include "sanitizer_common/sanitizer_stacktrace.h" @@ -24,9 +25,8 @@ using namespace __ubsan; -void __ubsan::GetStackTraceWithPcBpAndContext(BufferedStackTrace *stack, - uptr max_depth, uptr pc, uptr bp, - void *context, bool fast) { +void __ubsan::GetStackTrace(BufferedStackTrace *stack, uptr max_depth, uptr pc, + uptr bp, void *context, bool fast) { uptr top = 0; uptr bottom = 0; if (fast) @@ -41,8 +41,8 @@ static void MaybePrintStackTrace(uptr pc, uptr bp) { return; BufferedStackTrace stack; - GetStackTraceWithPcBpAndContext(&stack, kStackTraceMax, pc, bp, nullptr, - common_flags()->fast_unwind_on_fatal); + GetStackTrace(&stack, kStackTraceMax, pc, bp, nullptr, + common_flags()->fast_unwind_on_fatal); stack.Print(); } @@ -339,6 +339,13 @@ Diag::~Diag() { Decorator Decor; InternalScopedString Buffer(1024); + // Prepare a report that a monitor process can inspect. + if (Level == DL_Error) { + RenderText(&Buffer, Message, Args); + UndefinedBehaviorReport UBR{ConvertTypeToString(ET), Loc, Buffer}; + Buffer.clear(); + } + Buffer.append(Decor.Bold()); RenderLocation(&Buffer, Loc); Buffer.append(":"); diff --git a/libsanitizer/ubsan/ubsan_diag.h b/libsanitizer/ubsan/ubsan_diag.h index e9e5ab67e3e..429a9ecd69d 100644 --- a/libsanitizer/ubsan/ubsan_diag.h +++ b/libsanitizer/ubsan/ubsan_diag.h @@ -119,6 +119,12 @@ public: const char *getName() const { return Name; } }; +enum class ErrorType { +#define UBSAN_CHECK(Name, SummaryKind, FSanitizeFlagName) Name, +#include "ubsan_checks.inc" +#undef UBSAN_CHECK +}; + /// \brief Representation of an in-flight diagnostic. /// /// Temporary \c Diag instances are created by the handler routines to @@ -131,6 +137,9 @@ class Diag { /// The diagnostic level. DiagLevel Level; + /// The error type. + ErrorType ET; + /// The message which will be emitted, with %0, %1, ... placeholders for /// arguments. const char *Message; @@ -167,7 +176,7 @@ public: }; private: - static const unsigned MaxArgs = 5; + static const unsigned MaxArgs = 8; static const unsigned MaxRanges = 1; /// The arguments which have been added to this diagnostic so far. @@ -195,8 +204,9 @@ private: Diag &operator=(const Diag &); public: - Diag(Location Loc, DiagLevel Level, const char *Message) - : Loc(Loc), Level(Level), Message(Message), NumArgs(0), NumRanges(0) {} + Diag(Location Loc, DiagLevel Level, ErrorType ET, const char *Message) + : Loc(Loc), Level(Level), ET(ET), Message(Message), NumArgs(0), + NumRanges(0) {} ~Diag(); Diag &operator<<(const char *Str) { return AddArg(Str); } @@ -217,21 +227,14 @@ struct ReportOptions { uptr bp; }; -enum class ErrorType { -#define UBSAN_CHECK(Name, SummaryKind, FSanitizeFlagName) Name, -#include "ubsan_checks.inc" -#undef UBSAN_CHECK -}; - bool ignoreReport(SourceLocation SLoc, ReportOptions Opts, ErrorType ET); #define GET_REPORT_OPTIONS(unrecoverable_handler) \ GET_CALLER_PC_BP; \ ReportOptions Opts = {unrecoverable_handler, pc, bp} -void GetStackTraceWithPcBpAndContext(BufferedStackTrace *stack, uptr max_depth, - uptr pc, uptr bp, void *context, - bool fast); +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 diff --git a/libsanitizer/ubsan/ubsan_flags.cc b/libsanitizer/ubsan/ubsan_flags.cc index 9a3ea4b51e5..a7ecc755e46 100644 --- a/libsanitizer/ubsan/ubsan_flags.cc +++ b/libsanitizer/ubsan/ubsan_flags.cc @@ -16,12 +16,23 @@ #include "sanitizer_common/sanitizer_flags.h" #include "sanitizer_common/sanitizer_flag_parser.h" +#include + namespace __ubsan { const char *MaybeCallUbsanDefaultOptions() { return (&__ubsan_default_options) ? __ubsan_default_options() : ""; } +static const char *GetFlag(const char *flag) { + // We cannot call getenv() from inside a preinit array initializer + if (SANITIZER_CAN_USE_PREINIT_ARRAY) { + return GetEnv(flag); + } else { + return getenv(flag); + } +} + Flags ubsan_flags; void Flags::SetDefaults() { @@ -43,7 +54,7 @@ void InitializeFlags() { CommonFlags cf; cf.CopyFrom(*common_flags()); cf.print_summary = false; - cf.external_symbolizer_path = GetEnv("UBSAN_SYMBOLIZER_PATH"); + cf.external_symbolizer_path = GetFlag("UBSAN_SYMBOLIZER_PATH"); OverrideCommonFlags(cf); } @@ -57,7 +68,7 @@ void InitializeFlags() { // Override from user-specified string. parser.ParseString(MaybeCallUbsanDefaultOptions()); // Override from environment variable. - parser.ParseString(GetEnv("UBSAN_OPTIONS")); + parser.ParseString(GetFlag("UBSAN_OPTIONS")); InitializeCommonFlags(); if (Verbosity()) ReportUnrecognizedFlags(); diff --git a/libsanitizer/ubsan/ubsan_flags.inc b/libsanitizer/ubsan/ubsan_flags.inc index 170777adf26..438ea0b81be 100644 --- a/libsanitizer/ubsan/ubsan_flags.inc +++ b/libsanitizer/ubsan/ubsan_flags.inc @@ -22,3 +22,6 @@ UBSAN_FLAG(bool, print_stacktrace, false, 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.") diff --git a/libsanitizer/ubsan/ubsan_handlers.cc b/libsanitizer/ubsan/ubsan_handlers.cc index 4d29832ae0d..927ad4c9531 100644 --- a/libsanitizer/ubsan/ubsan_handlers.cc +++ b/libsanitizer/ubsan/ubsan_handlers.cc @@ -13,6 +13,8 @@ #if CAN_SANITIZE_UB #include "ubsan_handlers.h" #include "ubsan_diag.h" +#include "ubsan_flags.h" +#include "ubsan_monitor.h" #include "sanitizer_common/sanitizer_common.h" @@ -36,7 +38,8 @@ bool ignoreReport(SourceLocation SLoc, ReportOptions Opts, ErrorType ET) { const char *TypeCheckKinds[] = { "load of", "store to", "reference binding to", "member access within", "member call on", "constructor call on", "downcast of", "downcast of", - "upcast of", "cast to virtual base of", "_Nonnull binding to"}; + "upcast of", "cast to virtual base of", "_Nonnull binding to", + "dynamic operation on"}; } static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer, @@ -67,17 +70,17 @@ static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer, switch (ET) { case ErrorType::NullPointerUse: - Diag(Loc, DL_Error, "%0 null pointer of type %1") + Diag(Loc, DL_Error, ET, "%0 null pointer of type %1") << TypeCheckKinds[Data->TypeCheckKind] << Data->Type; break; case ErrorType::MisalignedPointerUse: - Diag(Loc, DL_Error, "%0 misaligned address %1 for type %3, " + Diag(Loc, DL_Error, ET, "%0 misaligned address %1 for type %3, " "which requires %2 byte alignment") << TypeCheckKinds[Data->TypeCheckKind] << (void *)Pointer << Alignment << Data->Type; break; case ErrorType::InsufficientObjectSize: - Diag(Loc, DL_Error, "%0 address %1 with insufficient space " + Diag(Loc, DL_Error, ET, "%0 address %1 with insufficient space " "for an object of type %2") << TypeCheckKinds[Data->TypeCheckKind] << (void *)Pointer << Data->Type; break; @@ -86,7 +89,7 @@ static void handleTypeMismatchImpl(TypeMismatchData *Data, ValueHandle Pointer, } if (Pointer) - Diag(Pointer, DL_Note, "pointer points here"); + Diag(Pointer, DL_Note, ET, "pointer points here"); } void __ubsan::__ubsan_handle_type_mismatch_v1(TypeMismatchData *Data, @@ -114,12 +117,15 @@ static void handleIntegerOverflowImpl(OverflowData *Data, ValueHandle LHS, if (ignoreReport(Loc, Opts, ET)) return; + if (!IsSigned && flags()->silence_unsigned_overflow) + return; + ScopedReport R(Opts, Loc, ET); - Diag(Loc, DL_Error, "%0 integer overflow: " - "%1 %2 %3 cannot be represented in type %4") - << (IsSigned ? "signed" : "unsigned") - << Value(Data->Type, LHS) << Operator << RHS << Data->Type; + Diag(Loc, DL_Error, ET, "%0 integer overflow: " + "%1 %2 %3 cannot be represented in type %4") + << (IsSigned ? "signed" : "unsigned") << Value(Data->Type, LHS) + << Operator << RHS << Data->Type; } #define UBSAN_OVERFLOW_HANDLER(handler_name, op, unrecoverable) \ @@ -148,15 +154,18 @@ static void handleNegateOverflowImpl(OverflowData *Data, ValueHandle OldVal, if (ignoreReport(Loc, Opts, ET)) return; + if (!IsSigned && flags()->silence_unsigned_overflow) + return; + ScopedReport R(Opts, Loc, ET); if (IsSigned) - Diag(Loc, DL_Error, + Diag(Loc, DL_Error, ET, "negation of %0 cannot be represented in type %1; " "cast to an unsigned type to negate this value to itself") << Value(Data->Type, OldVal) << Data->Type; else - Diag(Loc, DL_Error, "negation of %0 cannot be represented in type %1") + Diag(Loc, DL_Error, ET, "negation of %0 cannot be represented in type %1") << Value(Data->Type, OldVal) << Data->Type; } @@ -193,11 +202,12 @@ static void handleDivremOverflowImpl(OverflowData *Data, ValueHandle LHS, switch (ET) { case ErrorType::SignedIntegerOverflow: - Diag(Loc, DL_Error, "division of %0 by -1 cannot be represented in type %1") + Diag(Loc, DL_Error, ET, + "division of %0 by -1 cannot be represented in type %1") << LHSVal << Data->Type; break; default: - Diag(Loc, DL_Error, "division by zero"); + Diag(Loc, DL_Error, ET, "division by zero"); break; } } @@ -236,15 +246,16 @@ static void handleShiftOutOfBoundsImpl(ShiftOutOfBoundsData *Data, if (ET == ErrorType::InvalidShiftExponent) { if (RHSVal.isNegative()) - Diag(Loc, DL_Error, "shift exponent %0 is negative") << RHSVal; + Diag(Loc, DL_Error, ET, "shift exponent %0 is negative") << RHSVal; else - Diag(Loc, DL_Error, "shift exponent %0 is too large for %1-bit type %2") + Diag(Loc, DL_Error, ET, + "shift exponent %0 is too large for %1-bit type %2") << RHSVal << Data->LHSType.getIntegerBitWidth() << Data->LHSType; } else { if (LHSVal.isNegative()) - Diag(Loc, DL_Error, "left shift of negative value %0") << LHSVal; + Diag(Loc, DL_Error, ET, "left shift of negative value %0") << LHSVal; else - Diag(Loc, DL_Error, + Diag(Loc, DL_Error, ET, "left shift of %0 by %1 places cannot be represented in type %2") << LHSVal << RHSVal << Data->LHSType; } @@ -276,7 +287,7 @@ static void handleOutOfBoundsImpl(OutOfBoundsData *Data, ValueHandle Index, ScopedReport R(Opts, Loc, ET); Value IndexVal(Data->IndexType, Index); - Diag(Loc, DL_Error, "index %0 out of bounds for type %1") + Diag(Loc, DL_Error, ET, "index %0 out of bounds for type %1") << IndexVal << Data->ArrayType; } @@ -294,8 +305,10 @@ void __ubsan::__ubsan_handle_out_of_bounds_abort(OutOfBoundsData *Data, static void handleBuiltinUnreachableImpl(UnreachableData *Data, ReportOptions Opts) { - ScopedReport R(Opts, Data->Loc, ErrorType::UnreachableCall); - Diag(Data->Loc, DL_Error, "execution reached a __builtin_unreachable() call"); + ErrorType ET = ErrorType::UnreachableCall; + ScopedReport R(Opts, Data->Loc, ET); + Diag(Data->Loc, DL_Error, ET, + "execution reached an unreachable program point"); } void __ubsan::__ubsan_handle_builtin_unreachable(UnreachableData *Data) { @@ -305,8 +318,9 @@ void __ubsan::__ubsan_handle_builtin_unreachable(UnreachableData *Data) { } static void handleMissingReturnImpl(UnreachableData *Data, ReportOptions Opts) { - ScopedReport R(Opts, Data->Loc, ErrorType::MissingReturn); - Diag(Data->Loc, DL_Error, + ErrorType ET = ErrorType::MissingReturn; + ScopedReport R(Opts, Data->Loc, ET); + Diag(Data->Loc, DL_Error, ET, "execution reached the end of a value-returning function " "without returning a value"); } @@ -327,9 +341,9 @@ static void handleVLABoundNotPositive(VLABoundData *Data, ValueHandle Bound, ScopedReport R(Opts, Loc, ET); - Diag(Loc, DL_Error, "variable length array bound evaluates to " - "non-positive value %0") - << Value(Data->Type, Bound); + Diag(Loc, DL_Error, ET, "variable length array bound evaluates to " + "non-positive value %0") + << Value(Data->Type, Bound); } void __ubsan::__ubsan_handle_vla_bound_not_positive(VLABoundData *Data, @@ -387,7 +401,7 @@ static void handleFloatCastOverflow(void *DataPtr, ValueHandle From, ScopedReport R(Opts, Loc, ET); - Diag(Loc, DL_Error, + Diag(Loc, DL_Error, ET, "%0 is outside the range of representable values of type %2") << Value(*FromType, From) << *FromType << *ToType; } @@ -418,9 +432,9 @@ static void handleLoadInvalidValue(InvalidValueData *Data, ValueHandle Val, ScopedReport R(Opts, Loc, ET); - Diag(Loc, DL_Error, + Diag(Loc, DL_Error, ET, "load of value %0, which is not a valid value for type %1") - << Value(Data->Type, Val) << Data->Type; + << Value(Data->Type, Val) << Data->Type; } void __ubsan::__ubsan_handle_load_invalid_value(InvalidValueData *Data, @@ -435,6 +449,66 @@ void __ubsan::__ubsan_handle_load_invalid_value_abort(InvalidValueData *Data, Die(); } +static void handleImplicitConversion(ImplicitConversionData *Data, + ReportOptions Opts, ValueHandle Src, + ValueHandle Dst) { + SourceLocation Loc = Data->Loc.acquire(); + ErrorType ET = ErrorType::GenericUB; + + const TypeDescriptor &SrcTy = Data->FromType; + const TypeDescriptor &DstTy = Data->ToType; + + bool SrcSigned = SrcTy.isSignedIntegerTy(); + bool DstSigned = DstTy.isSignedIntegerTy(); + + switch (Data->Kind) { + case ICCK_IntegerTruncation: { // Legacy, no longer used. + // Let's figure out what it should be as per the new types, and upgrade. + // If both types are unsigned, then it's an unsigned truncation. + // Else, it is a signed truncation. + if (!SrcSigned && !DstSigned) { + ET = ErrorType::ImplicitUnsignedIntegerTruncation; + } else { + ET = ErrorType::ImplicitSignedIntegerTruncation; + } + break; + } + case ICCK_UnsignedIntegerTruncation: + ET = ErrorType::ImplicitUnsignedIntegerTruncation; + break; + case ICCK_SignedIntegerTruncation: + ET = ErrorType::ImplicitSignedIntegerTruncation; + break; + } + + if (ignoreReport(Loc, Opts, ET)) + return; + + ScopedReport R(Opts, Loc, ET); + + // FIXME: is it possible to dump the values as hex with fixed width? + + Diag(Loc, DL_Error, ET, + "implicit conversion from type %0 of value %1 (%2-bit, %3signed) to " + "type %4 changed the value to %5 (%6-bit, %7signed)") + << SrcTy << Value(SrcTy, Src) << SrcTy.getIntegerBitWidth() + << (SrcSigned ? "" : "un") << DstTy << Value(DstTy, Dst) + << DstTy.getIntegerBitWidth() << (DstSigned ? "" : "un"); +} + +void __ubsan::__ubsan_handle_implicit_conversion(ImplicitConversionData *Data, + ValueHandle Src, + ValueHandle Dst) { + GET_REPORT_OPTIONS(false); + handleImplicitConversion(Data, Opts, Src, Dst); +} +void __ubsan::__ubsan_handle_implicit_conversion_abort( + ImplicitConversionData *Data, ValueHandle Src, ValueHandle Dst) { + GET_REPORT_OPTIONS(true); + handleImplicitConversion(Data, Opts, Src, Dst); + Die(); +} + static void handleInvalidBuiltin(InvalidBuiltinData *Data, ReportOptions Opts) { SourceLocation Loc = Data->Loc.acquire(); ErrorType ET = ErrorType::InvalidBuiltin; @@ -444,7 +518,7 @@ static void handleInvalidBuiltin(InvalidBuiltinData *Data, ReportOptions Opts) { ScopedReport R(Opts, Loc, ET); - Diag(Loc, DL_Error, + Diag(Loc, DL_Error, ET, "passing zero to %0, which is not a valid argument") << ((Data->Kind == BCK_CTZPassedZero) ? "ctz()" : "clz()"); } @@ -475,10 +549,10 @@ static void handleFunctionTypeMismatch(FunctionTypeMismatchData *Data, if (!FName) FName = "(unknown)"; - Diag(CallLoc, DL_Error, + Diag(CallLoc, DL_Error, ET, "call to function %0 through pointer to incorrect function type %1") << FName << Data->Type; - Diag(FLoc, DL_Note, "%0 defined here") << FName; + Diag(FLoc, DL_Note, ET, "%0 defined here") << FName; } void @@ -508,10 +582,10 @@ static void handleNonNullReturn(NonNullReturnData *Data, SourceLocation *LocPtr, ScopedReport R(Opts, Loc, ET); - Diag(Loc, DL_Error, "null pointer returned from function declared to never " - "return null"); + Diag(Loc, DL_Error, ET, + "null pointer returned from function declared to never return null"); if (!Data->AttrLoc.isInvalid()) - Diag(Data->AttrLoc, DL_Note, "%0 specified here") + Diag(Data->AttrLoc, DL_Note, ET, "%0 specified here") << (IsAttr ? "returns_nonnull attribute" : "_Nonnull return type annotation"); } @@ -552,12 +626,12 @@ static void handleNonNullArg(NonNullArgData *Data, ReportOptions Opts, ScopedReport R(Opts, Loc, ET); - Diag(Loc, DL_Error, + Diag(Loc, DL_Error, ET, "null pointer passed as argument %0, which is declared to " "never be null") << Data->ArgIndex; if (!Data->AttrLoc.isInvalid()) - Diag(Data->AttrLoc, DL_Note, "%0 specified here") + Diag(Data->AttrLoc, DL_Note, ET, "%0 specified here") << (IsAttr ? "nonnull attribute" : "_Nonnull type annotation"); } @@ -597,14 +671,15 @@ static void handlePointerOverflowImpl(PointerOverflowData *Data, if ((sptr(Base) >= 0) == (sptr(Result) >= 0)) { if (Base > Result) - Diag(Loc, DL_Error, "addition of unsigned offset to %0 overflowed to %1") + Diag(Loc, DL_Error, ET, + "addition of unsigned offset to %0 overflowed to %1") << (void *)Base << (void *)Result; else - Diag(Loc, DL_Error, + Diag(Loc, DL_Error, ET, "subtraction of unsigned offset from %0 overflowed to %1") << (void *)Base << (void *)Result; } else { - Diag(Loc, DL_Error, + Diag(Loc, DL_Error, ET, "pointer index expression with base %0 overflowed to %1") << (void *)Base << (void *)Result; } @@ -627,7 +702,7 @@ void __ubsan::__ubsan_handle_pointer_overflow_abort(PointerOverflowData *Data, static void handleCFIBadIcall(CFICheckFailData *Data, ValueHandle Function, ReportOptions Opts) { - if (Data->CheckKind != CFITCK_ICall) + if (Data->CheckKind != CFITCK_ICall && Data->CheckKind != CFITCK_NVMFCall) Die(); SourceLocation Loc = Data->Loc.acquire(); @@ -638,15 +713,33 @@ static void handleCFIBadIcall(CFICheckFailData *Data, ValueHandle Function, ScopedReport R(Opts, Loc, ET); - Diag(Loc, DL_Error, "control flow integrity check for type %0 failed during " - "indirect function call") - << Data->Type; + const char *CheckKindStr = Data->CheckKind == CFITCK_NVMFCall + ? "non-virtual pointer to member function call" + : "indirect function call"; + Diag(Loc, DL_Error, ET, + "control flow integrity check for type %0 failed during %1") + << Data->Type << CheckKindStr; SymbolizedStackHolder FLoc(getSymbolizedLocation(Function)); const char *FName = FLoc.get()->info.function; if (!FName) FName = "(unknown)"; - Diag(FLoc, DL_Note, "%0 defined here") << FName; + Diag(FLoc, DL_Note, ET, "%0 defined here") << FName; + + // If the failure involved different DSOs for the check location and icall + // target, report the DSO names. + const char *DstModule = FLoc.get()->info.module; + if (!DstModule) + DstModule = "(unknown)"; + + const char *SrcModule = Symbolizer::GetOrInit()->GetModuleNameForPc(Opts.pc); + if (!SrcModule) + SrcModule = "(unknown)"; + + if (internal_strcmp(SrcModule, DstModule)) + Diag(Loc, DL_Note, ET, + "check failed in %0, destination function located in %1") + << SrcModule << DstModule; } namespace __ubsan { @@ -682,7 +775,7 @@ void __ubsan::__ubsan_handle_cfi_check_fail(CFICheckFailData *Data, ValueHandle Value, uptr ValidVtable) { GET_REPORT_OPTIONS(false); - if (Data->CheckKind == CFITCK_ICall) + if (Data->CheckKind == CFITCK_ICall || Data->CheckKind == CFITCK_NVMFCall) handleCFIBadIcall(Data, Value, Opts); else __ubsan_handle_cfi_bad_type(Data, Value, ValidVtable, Opts); @@ -692,7 +785,7 @@ void __ubsan::__ubsan_handle_cfi_check_fail_abort(CFICheckFailData *Data, ValueHandle Value, uptr ValidVtable) { GET_REPORT_OPTIONS(true); - if (Data->CheckKind == CFITCK_ICall) + if (Data->CheckKind == CFITCK_ICall || Data->CheckKind == CFITCK_NVMFCall) handleCFIBadIcall(Data, Value, Opts); else __ubsan_handle_cfi_bad_type(Data, Value, ValidVtable, Opts); diff --git a/libsanitizer/ubsan/ubsan_handlers.h b/libsanitizer/ubsan/ubsan_handlers.h index c5e499cd68e..56e664c751b 100644 --- a/libsanitizer/ubsan/ubsan_handlers.h +++ b/libsanitizer/ubsan/ubsan_handlers.h @@ -120,6 +120,25 @@ struct InvalidValueData { /// \brief Handle a load of an invalid value for the type. RECOVERABLE(load_invalid_value, InvalidValueData *Data, ValueHandle Val) +/// Known implicit conversion check kinds. +/// Keep in sync with the enum of the same name in CGExprScalar.cpp +enum ImplicitConversionCheckKind : unsigned char { + ICCK_IntegerTruncation = 0, // Legacy, was only used by clang 7. + ICCK_UnsignedIntegerTruncation = 1, + ICCK_SignedIntegerTruncation = 2, +}; + +struct ImplicitConversionData { + SourceLocation Loc; + const TypeDescriptor &FromType; + const TypeDescriptor &ToType; + /* ImplicitConversionCheckKind */ unsigned char Kind; +}; + +/// \brief Implict conversion that changed the value. +RECOVERABLE(implicit_conversion, ImplicitConversionData *Data, ValueHandle Src, + ValueHandle Dst) + /// Known builtin check kinds. /// Keep in sync with the enum of the same name in CodeGenFunction.h enum BuiltinCheckKind : unsigned char { @@ -179,6 +198,8 @@ enum CFITypeCheckKind : unsigned char { CFITCK_DerivedCast, CFITCK_UnrelatedCast, CFITCK_ICall, + CFITCK_NVMFCall, + CFITCK_VMFCall, }; struct CFICheckFailData { diff --git a/libsanitizer/ubsan/ubsan_handlers_cxx.cc b/libsanitizer/ubsan/ubsan_handlers_cxx.cc index bf729db6ce0..912617010a8 100644 --- a/libsanitizer/ubsan/ubsan_handlers_cxx.cc +++ b/libsanitizer/ubsan/ubsan_handlers_cxx.cc @@ -48,29 +48,30 @@ static bool HandleDynamicTypeCacheMiss( ScopedReport R(Opts, Loc, ET); - Diag(Loc, DL_Error, + Diag(Loc, DL_Error, ET, "%0 address %1 which does not point to an object of type %2") << TypeCheckKinds[Data->TypeCheckKind] << (void*)Pointer << Data->Type; // If possible, say what type it actually points to. if (!DTI.isValid()) { if (DTI.getOffset() < -VptrMaxOffsetToTop || DTI.getOffset() > VptrMaxOffsetToTop) { - Diag(Pointer, DL_Note, "object has a possibly invalid vptr: abs(offset to top) too big") + Diag(Pointer, DL_Note, ET, + "object has a possibly invalid vptr: abs(offset to top) too big") << TypeName(DTI.getMostDerivedTypeName()) << Range(Pointer, Pointer + sizeof(uptr), "possibly invalid vptr"); } else { - Diag(Pointer, DL_Note, "object has invalid vptr") + Diag(Pointer, DL_Note, ET, "object has invalid vptr") << TypeName(DTI.getMostDerivedTypeName()) << Range(Pointer, Pointer + sizeof(uptr), "invalid vptr"); } } else if (!DTI.getOffset()) - Diag(Pointer, DL_Note, "object is of type %0") + Diag(Pointer, DL_Note, ET, "object is of type %0") << TypeName(DTI.getMostDerivedTypeName()) << Range(Pointer, Pointer + sizeof(uptr), "vptr for %0"); else // FIXME: Find the type at the specified offset, and include that // in the note. - Diag(Pointer - DTI.getOffset(), DL_Note, + Diag(Pointer - DTI.getOffset(), DL_Note, ET, "object is base class subobject at offset %0 within object of type %1") << DTI.getOffset() << TypeName(DTI.getMostDerivedTypeName()) << TypeName(DTI.getSubobjectTypeName()) @@ -120,26 +121,39 @@ void __ubsan_handle_cfi_bad_type(CFICheckFailData *Data, ValueHandle Vtable, case CFITCK_UnrelatedCast: CheckKindStr = "cast to unrelated type"; break; + case CFITCK_VMFCall: + CheckKindStr = "virtual pointer to member function call"; + break; case CFITCK_ICall: - default: + case CFITCK_NVMFCall: Die(); } - Diag(Loc, DL_Error, "control flow integrity check for type %0 failed during " - "%1 (vtable address %2)") + Diag(Loc, DL_Error, ET, + "control flow integrity check for type %0 failed during " + "%1 (vtable address %2)") << Data->Type << CheckKindStr << (void *)Vtable; // If possible, say what type it actually points to. - if (!DTI.isValid()) { - const char *module = Symbolizer::GetOrInit()->GetModuleNameForPc(Vtable); - if (module) - Diag(Vtable, DL_Note, "invalid vtable in module %0") << module; - else - Diag(Vtable, DL_Note, "invalid vtable"); - } else { - Diag(Vtable, DL_Note, "vtable is of type %0") + if (!DTI.isValid()) + Diag(Vtable, DL_Note, ET, "invalid vtable"); + else + Diag(Vtable, DL_Note, ET, "vtable is of type %0") << TypeName(DTI.getMostDerivedTypeName()); - } + + // If the failure involved different DSOs for the check location and vtable, + // report the DSO names. + const char *DstModule = Symbolizer::GetOrInit()->GetModuleNameForPc(Vtable); + if (!DstModule) + DstModule = "(unknown)"; + + const char *SrcModule = Symbolizer::GetOrInit()->GetModuleNameForPc(Opts.pc); + if (!SrcModule) + SrcModule = "(unknown)"; + + if (internal_strcmp(SrcModule, DstModule)) + Diag(Loc, DL_Note, ET, "check failed in %0, vtable located in %1") + << SrcModule << DstModule; } } // namespace __ubsan diff --git a/libsanitizer/ubsan/ubsan_init_standalone_preinit.cc b/libsanitizer/ubsan/ubsan_init_standalone_preinit.cc index 80b2f3c3fd4..fd26b49e4e7 100644 --- a/libsanitizer/ubsan/ubsan_init_standalone_preinit.cc +++ b/libsanitizer/ubsan/ubsan_init_standalone_preinit.cc @@ -1,5 +1,4 @@ -//===-- ubsan_init_standalone_preinit.cc -//------------------------------------------===// +//===-- ubsan_init_standalone_preinit.cc ---------------------------------===// // // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. diff --git a/libsanitizer/ubsan/ubsan_interface.inc b/libsanitizer/ubsan/ubsan_interface.inc index 1b0bc425da7..ef0842d9339 100644 --- a/libsanitizer/ubsan/ubsan_interface.inc +++ b/libsanitizer/ubsan/ubsan_interface.inc @@ -20,6 +20,8 @@ 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_implicit_conversion) +INTERFACE_FUNCTION(__ubsan_handle_implicit_conversion_abort) INTERFACE_FUNCTION(__ubsan_handle_invalid_builtin) INTERFACE_FUNCTION(__ubsan_handle_invalid_builtin_abort) INTERFACE_FUNCTION(__ubsan_handle_load_invalid_value) @@ -50,3 +52,5 @@ INTERFACE_FUNCTION(__ubsan_handle_type_mismatch_v1_abort) INTERFACE_FUNCTION(__ubsan_handle_vla_bound_not_positive) INTERFACE_FUNCTION(__ubsan_handle_vla_bound_not_positive_abort) INTERFACE_WEAK_FUNCTION(__ubsan_default_options) +INTERFACE_FUNCTION(__ubsan_on_report) +INTERFACE_FUNCTION(__ubsan_get_current_report_data) diff --git a/libsanitizer/ubsan/ubsan_monitor.cc b/libsanitizer/ubsan/ubsan_monitor.cc new file mode 100644 index 00000000000..81180a63917 --- /dev/null +++ b/libsanitizer/ubsan/ubsan_monitor.cc @@ -0,0 +1,74 @@ +//===-- ubsan_monitor.cc ----------------------------------------*- C++ -*-===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Hooks which allow a monitor process to inspect UBSan's diagnostics. +// +//===----------------------------------------------------------------------===// + +#include "ubsan_monitor.h" + +using namespace __ubsan; + +UndefinedBehaviorReport::UndefinedBehaviorReport(const char *IssueKind, + Location &Loc, + InternalScopedString &Msg) + : IssueKind(IssueKind), Loc(Loc), Buffer(Msg.length() + 1) { + // We have the common sanitizer reporting lock, so it's safe to register a + // new UB report. + RegisterUndefinedBehaviorReport(this); + + // Make a copy of the diagnostic. + Buffer.append("%s", Msg.data()); + + // Let the monitor know that a report is available. + __ubsan_on_report(); +} + +static UndefinedBehaviorReport *CurrentUBR; + +void __ubsan::RegisterUndefinedBehaviorReport(UndefinedBehaviorReport *UBR) { + CurrentUBR = UBR; +} + +SANITIZER_WEAK_DEFAULT_IMPL +void __ubsan::__ubsan_on_report(void) {} + +void __ubsan::__ubsan_get_current_report_data(const char **OutIssueKind, + const char **OutMessage, + const char **OutFilename, + unsigned *OutLine, + unsigned *OutCol, + char **OutMemoryAddr) { + if (!OutIssueKind || !OutMessage || !OutFilename || !OutLine || !OutCol || + !OutMemoryAddr) + UNREACHABLE("Invalid arguments passed to __ubsan_get_current_report_data"); + + InternalScopedString &Buf = CurrentUBR->Buffer; + + // Ensure that the first character of the diagnostic text can't start with a + // lowercase letter. + char FirstChar = Buf.data()[0]; + if (FirstChar >= 'a' && FirstChar <= 'z') + Buf.data()[0] = FirstChar - 'a' + 'A'; + + *OutIssueKind = CurrentUBR->IssueKind; + *OutMessage = Buf.data(); + if (!CurrentUBR->Loc.isSourceLocation()) { + *OutFilename = ""; + *OutLine = *OutCol = 0; + } else { + SourceLocation SL = CurrentUBR->Loc.getSourceLocation(); + *OutFilename = SL.getFilename(); + *OutLine = SL.getLine(); + *OutCol = SL.getColumn(); + } + + if (CurrentUBR->Loc.isMemoryLocation()) + *OutMemoryAddr = (char *)CurrentUBR->Loc.getMemoryLocation(); + else + *OutMemoryAddr = nullptr; +} diff --git a/libsanitizer/ubsan/ubsan_monitor.h b/libsanitizer/ubsan/ubsan_monitor.h new file mode 100644 index 00000000000..632bd256e7e --- /dev/null +++ b/libsanitizer/ubsan/ubsan_monitor.h @@ -0,0 +1,47 @@ +//===-- ubsan_monitor.h -----------------------------------------*- C++ -*-===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Hooks which allow a monitor process to inspect UBSan's diagnostics. +// +//===----------------------------------------------------------------------===// + +#ifndef UBSAN_MONITOR_H +#define UBSAN_MONITOR_H + +#include "ubsan_diag.h" +#include "ubsan_value.h" + +namespace __ubsan { + +struct UndefinedBehaviorReport { + const char *IssueKind; + Location &Loc; + InternalScopedString Buffer; + + UndefinedBehaviorReport(const char *IssueKind, Location &Loc, + InternalScopedString &Msg); +}; + +SANITIZER_INTERFACE_ATTRIBUTE void +RegisterUndefinedBehaviorReport(UndefinedBehaviorReport *UBR); + +/// Called after a report is prepared. This serves to alert monitor processes +/// that a UB report is available. +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void __ubsan_on_report(void); + +/// Used by the monitor process to extract information from a UB report. The +/// data is only available until the next time __ubsan_on_report is called. The +/// caller is responsible for copying and preserving the data if needed. +extern "C" SANITIZER_INTERFACE_ATTRIBUTE void +__ubsan_get_current_report_data(const char **OutIssueKind, + const char **OutMessage, + const char **OutFilename, unsigned *OutLine, + unsigned *OutCol, char **OutMemoryAddr); + +} // end namespace __ubsan + +#endif // UBSAN_MONITOR_H diff --git a/libsanitizer/ubsan/ubsan_platform.h b/libsanitizer/ubsan/ubsan_platform.h index e73df632302..75d06646ce8 100644 --- a/libsanitizer/ubsan/ubsan_platform.h +++ b/libsanitizer/ubsan/ubsan_platform.h @@ -11,19 +11,14 @@ #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(__x86_64__) || defined(__i386__) || defined(__arm__) || \ - defined(__aarch64__) || defined(__mips__) || defined(__powerpc64__) || \ - defined(__s390__)) -# define CAN_SANITIZE_UB 1 -#elif defined(_WIN32) || defined(__Fuchsia__) +#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \ + defined(__NetBSD__) || defined(__OpenBSD__) || \ + (defined(__sun__) && defined(__svr4__)) || \ + defined(_WIN32) || defined(__Fuchsia__) || defined(__rtems__) # define CAN_SANITIZE_UB 1 #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.cc index eb9b99ce9ac..5e77c60b1db 100644 --- a/libsanitizer/ubsan/ubsan_signals_standalone.cc +++ b/libsanitizer/ubsan/ubsan_signals_standalone.cc @@ -1,6 +1,8 @@ //=-- ubsan_signals_standalone.cc //------------------------------------------------===// // +// The LLVM Compiler Infrastructure +// // This file is distributed under the University of Illinois Open Source // License. See LICENSE.TXT for details. // @@ -11,25 +13,38 @@ //===----------------------------------------------------------------------===// #include "ubsan_platform.h" +#include "sanitizer_common/sanitizer_platform.h" #if CAN_SANITIZE_UB #include "interception/interception.h" #include "sanitizer_common/sanitizer_stacktrace.h" #include "ubsan_diag.h" #include "ubsan_init.h" +// Interception of signals breaks too many things on Android. +// * It requires that ubsan is the first dependency of the main executable for +// the interceptors to work correctly. This complicates deployment, as it +// prevents us from enabling ubsan on random platform modules independently. +// * For this to work with ART VM, ubsan signal handler has to be set after the +// debuggerd handler, but before the ART handler. +// * Interceptors don't work at all when ubsan runtime is loaded late, ex. when +// it is part of an APK that does not use wrap.sh method. +#if SANITIZER_FUCHSIA || SANITIZER_ANDROID + +namespace __ubsan { +void InitializeDeadlySignals() {} +} + +#else + #define COMMON_INTERCEPT_FUNCTION(name) INTERCEPT_FUNCTION(name) #include "sanitizer_common/sanitizer_signal_interceptors.inc" namespace __ubsan { -#if SANITIZER_FUCHSIA -void InitializeDeadlySignals() {} -#else static void OnStackUnwind(const SignalContext &sig, const void *, BufferedStackTrace *stack) { - GetStackTraceWithPcBpAndContext(stack, kStackTraceMax, sig.pc, sig.bp, - sig.context, - common_flags()->fast_unwind_on_fatal); + GetStackTrace(stack, kStackTraceMax, sig.pc, sig.bp, sig.context, + common_flags()->fast_unwind_on_fatal); } static void UBsanOnDeadlySignal(int signo, void *siginfo, void *context) { @@ -45,8 +60,9 @@ void InitializeDeadlySignals() { InitializeSignalInterceptors(); InstallDeadlySignalHandlers(&UBsanOnDeadlySignal); } -#endif } // namespace __ubsan +#endif + #endif // CAN_SANITIZE_UB diff --git a/libsanitizer/ubsan/ubsan_signals_standalone.h b/libsanitizer/ubsan/ubsan_signals_standalone.h index 65e64f205ca..b29c29482ec 100644 --- a/libsanitizer/ubsan/ubsan_signals_standalone.h +++ b/libsanitizer/ubsan/ubsan_signals_standalone.h @@ -1,6 +1,8 @@ //=-- 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. // diff --git a/libsanitizer/ubsan/ubsan_win_weak_interception.cc b/libsanitizer/ubsan/ubsan_win_weak_interception.cc index 98c8c27b2fa..9f0a8f1d38a 100644 --- a/libsanitizer/ubsan/ubsan_win_weak_interception.cc +++ b/libsanitizer/ubsan/ubsan_win_weak_interception.cc @@ -12,6 +12,7 @@ #ifdef SANITIZER_DYNAMIC #include "sanitizer_common/sanitizer_win_weak_interception.h" #include "ubsan_flags.h" +#include "ubsan_monitor.h" // Check if strong definitions for weak functions are present in the main // executable. If that is the case, override dll functions to point to strong // implementations. -- 2.30.2