Index: compiler-rt/cmake/config-ix.cmake =================================================================== --- compiler-rt/cmake/config-ix.cmake +++ compiler-rt/cmake/config-ix.cmake @@ -673,7 +673,7 @@ list_replace(COMPILER_RT_SANITIZERS_TO_BUILD all "${ALL_SANITIZERS}") if (SANITIZER_COMMON_SUPPORTED_ARCH AND NOT LLVM_USE_SANITIZER AND - (OS_NAME MATCHES "Android|Darwin|Linux|FreeBSD|NetBSD|Fuchsia|SunOS" OR + (OS_NAME MATCHES "Android|Darwin|Linux|FreeBSD|NetBSD|Fuchsia|SunOS|VxWorks" OR (OS_NAME MATCHES "Windows" AND NOT CYGWIN AND (NOT MINGW OR CMAKE_CXX_COMPILER_ID MATCHES "Clang")))) set(COMPILER_RT_HAS_SANITIZER_COMMON TRUE) Index: compiler-rt/lib/asan/CMakeLists.txt =================================================================== --- compiler-rt/lib/asan/CMakeLists.txt +++ compiler-rt/lib/asan/CMakeLists.txt @@ -15,6 +15,7 @@ asan_interceptors_memintrinsics.cpp asan_linux.cpp asan_mac.cpp + asan_vxworks.cpp asan_malloc_linux.cpp asan_malloc_mac.cpp asan_malloc_win.cpp @@ -73,6 +74,7 @@ asan_internal.h asan_lock.h asan_mapping.h + asan_mapping_vxworks.h asan_poisoning.h asan_premap_shadow.h asan_report.h Index: compiler-rt/lib/asan/asan_allocator.h =================================================================== --- compiler-rt/lib/asan/asan_allocator.h +++ compiler-rt/lib/asan/asan_allocator.h @@ -122,38 +122,42 @@ const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x40000000000ULL; // 4T. typedef DefaultSizeClassMap SizeClassMap; -# elif defined(__powerpc64__) +# elif SANITIZER_VXWORKS +const uptr kAllocatorSpace = 0x7DC00000000ULL; +const uptr kAllocatorSize = 0x2000000000ULL; // 128G. +typedef VeryCompactSizeClassMap SizeClassMap; +# elif defined(__powerpc64__) const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x20000000000ULL; // 2T. typedef DefaultSizeClassMap SizeClassMap; -# elif defined(__aarch64__) && SANITIZER_ANDROID +# elif defined(__aarch64__) && SANITIZER_ANDROID // Android needs to support 39, 42 and 48 bit VMA. const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x2000000000ULL; // 128G. typedef VeryCompactSizeClassMap SizeClassMap; -#elif SANITIZER_RISCV64 +# elif SANITIZER_RISCV64 const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x2000000000ULL; // 128G. typedef VeryDenseSizeClassMap SizeClassMap; -# elif defined(__aarch64__) +# elif defined(__aarch64__) // AArch64/SANITIZER_CAN_USE_ALLOCATOR64 is only for 42-bit VMA // so no need to different values for different VMA. const uptr kAllocatorSpace = 0x10000000000ULL; const uptr kAllocatorSize = 0x10000000000ULL; // 3T. typedef DefaultSizeClassMap SizeClassMap; -#elif defined(__sparc__) +# elif defined(__sparc__) const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x20000000000ULL; // 2T. typedef DefaultSizeClassMap SizeClassMap; -# elif SANITIZER_WINDOWS +# elif SANITIZER_WINDOWS const uptr kAllocatorSpace = ~(uptr)0; const uptr kAllocatorSize = 0x8000000000ULL; // 500G typedef DefaultSizeClassMap SizeClassMap; -# else +# else const uptr kAllocatorSpace = 0x600000000000ULL; const uptr kAllocatorSize = 0x40000000000ULL; // 4T. typedef DefaultSizeClassMap SizeClassMap; -# endif +# endif template struct AP64 { // Allocator64 parameters. Deliberately using a short name. static const uptr kSpaceBeg = kAllocatorSpace; Index: compiler-rt/lib/asan/asan_malloc_linux.cpp =================================================================== --- compiler-rt/lib/asan/asan_malloc_linux.cpp +++ compiler-rt/lib/asan/asan_malloc_linux.cpp @@ -15,7 +15,7 @@ #include "sanitizer_common/sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX || \ - SANITIZER_NETBSD || SANITIZER_SOLARIS + SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_VXWORKS # include "asan_allocator.h" # include "asan_interceptors.h" Index: compiler-rt/lib/asan/asan_mapping.h =================================================================== --- compiler-rt/lib/asan/asan_mapping.h +++ compiler-rt/lib/asan/asan_mapping.h @@ -149,6 +149,13 @@ // || `[0x30000000, 0x35ffffff]` || LowShadow || // || `[0x00000000, 0x2fffffff]` || LowMem || +// Shadow mapping on VxWorks/x86_64 with SHADOW_OFFSET == 0x80000000000: +// || `[0x0000780000000000, 0x00007fffffffffff]` || HighMem || +// || `[0x0000170000000000, 0x000017ffffffffff]` || HighShadow || +// || `[ ]` || ShadowGap || +// || `[0x0000080000040000, 0x000008ffffffffff]` || LowShadow || +// || `[0x0000000000200000, 0x000007ffffffffff]` || LowMem || + #define ASAN_SHADOW_SCALE 3 #if SANITIZER_FUCHSIA @@ -174,6 +181,8 @@ # define ASAN_SHADOW_OFFSET_DYNAMIC # elif SANITIZER_MAC && defined(__aarch64__) # define ASAN_SHADOW_OFFSET_DYNAMIC +# elif SANITIZER_VXWORKS +# define ASAN_SHADOW_OFFSET_DYNAMIC # elif SANITIZER_RISCV64 # define ASAN_SHADOW_OFFSET_CONST 0x0000000d55550000 # elif defined(__aarch64__) @@ -256,6 +265,8 @@ # if defined(__sparc__) && SANITIZER_WORDSIZE == 64 # include "asan_mapping_sparc64.h" +# elif SANITIZER_VXWORKS +# include "asan_mapping_vxworks.h" # else # define MEM_TO_SHADOW(mem) \ (((mem) >> ASAN_SHADOW_SCALE) + (ASAN_SHADOW_OFFSET)) Index: compiler-rt/lib/asan/asan_mapping_vxworks.h =================================================================== --- /dev/null +++ compiler-rt/lib/asan/asan_mapping_vxworks.h @@ -0,0 +1,86 @@ +//===-- asan_mapping_vxworks.h -----------------------------------*- C++ +//-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// VxWorks-specific definitions for ASan memory mapping. +//===----------------------------------------------------------------------===// +#ifndef ASAN_MAPPING_VXWORKS_H +#define ASAN_MAPPING_VXWORKS_H + +#define MEM_TO_SHADOW(mem) (((mem) >> ASAN_SHADOW_SCALE) + (ASAN_SHADOW_OFFSET)) + +#if defined(__riscv) && !defined(_WRS_CONFIG_SATP_MODE_SV48) +# define kLowMemBeg 0x0000000000200000UL +# define kLowMemEnd (kLowMemBeg + 0x00000007ffe00000 - 1) +# define kHighMemBeg 0x0000003800000000UL +#else +# define kLowMemBeg 0x0000000000200000UL +# define kLowMemEnd (kLowMemBeg + 0x000007ffffe00000 - 1) +# define kHighMemBeg 0x0000780000000000UL +#endif + +#define kLowShadowBeg MEM_TO_SHADOW(kLowMemBeg) +#define kLowShadowEnd MEM_TO_SHADOW(kLowMemEnd) + +#define kHighShadowBeg MEM_TO_SHADOW(kHighMemBeg) +#define kHighShadowEnd MEM_TO_SHADOW(kHighMemEnd) + +#define kMidShadowBeg 0 +#define kMidShadowEnd 0 + +#define kShadowGapBeg 0 +#define kShadowGapEnd 0 + +#define kShadowGap2Beg 0 +#define kShadowGap2End 0 + +#define kShadowGap3Beg 0 +#define kShadowGap3End 0 + +namespace __asan { + +static inline bool AddrIsInLowMem(uptr a) { + PROFILE_ASAN_MAPPING(); + return a >= kLowMemBeg && a <= kLowMemEnd; +} + +static inline bool AddrIsInLowShadow(uptr a) { + PROFILE_ASAN_MAPPING(); + 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 a >= kHighMemBeg && a <= kHighMemEnd; +} + +static inline bool AddrIsInHighShadow(uptr a) { + PROFILE_ASAN_MAPPING(); + return a >= kHighShadowBeg && a <= kHighShadowEnd; +} + +static inline bool AddrIsInShadowGap(uptr a) { + PROFILE_ASAN_MAPPING(); + return a >= kShadowGapBeg && a <= kShadowGapEnd; +} + +} // namespace __asan + +#endif // ASAN_MAPPING_VXWORKS_H Index: compiler-rt/lib/asan/asan_posix.cpp =================================================================== --- compiler-rt/lib/asan/asan_posix.cpp +++ compiler-rt/lib/asan/asan_posix.cpp @@ -31,6 +31,12 @@ #include #include +# if SANITIZER_VXWORKS +# include +# include +# include +# endif + namespace __asan { void AsanOnDeadlySignal(int signo, void *siginfo, void *context) { @@ -111,7 +117,81 @@ atomic_signal_fence(memory_order_seq_cst); AsanThread::TSDDtor(tsd); } -#else +# elif SANITIZER_VXWORKS +// The intercepted malloc may use TSD before __createTLSArea_GD and the +// intercepted free may use TSD even after _FreeModuleTLSArea. It is +// impossible to use the standard thread local storage "_thread". So we define +// a simple two dimensional array here to simulate the thread local storage +// model. + +static void (*tsd_destructor)(void *tsd) = nullptr; + +struct TSD_KEY { + TASK_ID taskId; + void *key; +}; + +# define TSD_KEY_COUNT 32 +SEMAPHORE tsdKeySem; +static struct TSD_KEY tsdKey[TSD_KEY_COUNT] = {}; + +static STATUS resetTSDHook(TASK_ID taskId) { + for (int i = 0; i < TSD_KEY_COUNT; i++) + if (tsdKey[i].taskId == taskId) { + tsdKey[i].taskId = TASK_ID_NULL; + tsdKey[i].key = nullptr; + } + + return OK; +} + +void AsanTSDInit(void (*destructor)(void *tsd)) { + CHECK(!tsd_destructor); + tsd_destructor = destructor; + (void)semMInit(&tsdKeySem, SEM_Q_PRIORITY); + (void)taskDeleteHookAdd(resetTSDHook); +} + +void *AsanTSDGet() { + CHECK(tsd_destructor); + + TASK_ID curTask = taskIdSelf(); + + (void)semTake(&tsdKeySem, WAIT_FOREVER); + for (int i = 0; i < TSD_KEY_COUNT; i++) + if (tsdKey[i].taskId == curTask) { + (void)semGive(&tsdKeySem); + return tsdKey[i].key; + } + (void)semGive(&tsdKeySem); + + return nullptr; +} + +void AsanTSDSet(void *tsd) { + TASK_ID curTask = taskIdSelf(); + + (void)semTake(&tsdKeySem, WAIT_FOREVER); + for (int i = 0; i < TSD_KEY_COUNT; i++) + if (tsdKey[i].taskId == TASK_ID_NULL) { + tsdKey[i].taskId = curTask; + tsdKey[i].key = tsd; + (void)semGive(&tsdKeySem); + return; + } + (void)semGive(&tsdKeySem); +} + +void PlatformTSDDtor(void *tsd) { + CHECK(tsd_destructor); + CHECK_EQ(AsanTSDGet(), tsd); + AsanTSDSet(nullptr); + // Make sure that signal handler can not see a stale current thread pointer. + atomic_signal_fence(memory_order_seq_cst); + AsanThread::TSDDtor(tsd); +} + +# else static pthread_key_t tsd_key; static bool tsd_key_inited = false; void AsanTSDInit(void (*destructor)(void *tsd)) { @@ -139,7 +219,7 @@ } AsanThread::TSDDtor(tsd); } -#endif +# endif } // namespace __asan #endif // SANITIZER_POSIX Index: compiler-rt/lib/asan/asan_shadow_setup.cpp =================================================================== --- compiler-rt/lib/asan/asan_shadow_setup.cpp +++ compiler-rt/lib/asan/asan_shadow_setup.cpp @@ -14,7 +14,7 @@ #include "sanitizer_common/sanitizer_platform.h" // asan_fuchsia.cpp has their own InitializeShadowMemory implementation. -#if !SANITIZER_FUCHSIA +#if !SANITIZER_FUCHSIA && !SANITIZER_VXWORKS # include "asan_internal.h" # include "asan_mapping.h" Index: compiler-rt/lib/asan/asan_vxworks.cpp =================================================================== --- /dev/null +++ compiler-rt/lib/asan/asan_vxworks.cpp @@ -0,0 +1,218 @@ +//===-- asan_VxWorks.cpp +//------------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is a part of AddressSanitizer, an address sanity checker. +// +// VxWorks-specific details. +//===----------------------------------------------------------------------===// + +#include "sanitizer_common/sanitizer_platform.h" + +#if SANITIZER_VXWORKS +# include +# include +# include +# include // for free() +# include +# include +# include +# include +# include +# include + +# include "asan_interceptors.h" +# include "asan_internal.h" +# include "asan_mapping.h" +# include "asan_stack.h" +# include "asan_thread.h" +# include "sanitizer_common/sanitizer_atomic.h" +# include "sanitizer_common/sanitizer_libc.h" + +namespace __asan { + +void InitializeShadowMemory() { +# if defined(__riscv) && !defined(_WRS_CONFIG_SATP_MODE_SV48) + __asan_shadow_memory_dynamic_address = 0x800000000; +# else + __asan_shadow_memory_dynamic_address = 0x80000000000; +# endif + + // vxWorks system will handle all shadow memory allocation automatically, but + // we need a way to tell vxworks that current process is configured with asan. + // The way is to mmap a memory starting at kLowShadowBeg no matter whatever + // the size is. + + ReserveShadowMemoryRange(kLowShadowBeg, kLowShadowBeg + 0x1000 - 1, + "low shadow"); + ReserveShadowMemoryRange(kHighShadowBeg, kHighShadowBeg + 0x1000 - 1, + "high shadow"); +} + +void InitializePlatformExceptionHandlers() {} +bool IsSystemHeapAddress(uptr addr) { return false; } + +// No-op. VxWorks does not support static linkage anyway. +void *AsanDoesNotSupportStaticLinkage() { return 0; } + +// No-op. VxWorks does not support static linkage anyway. +void AsanCheckDynamicRTPrereqs() {} + +// No-op. VxWorks does not support static linkage anyway. +void AsanCheckIncompatibleRT() {} + +void AsanApplyToGlobals(globals_op_fptr op, const void *needle) { + UNIMPLEMENTED(); +} + +void FlushUnneededASanShadowMemory(uptr p, uptr size) { + // Since asan's mapping is compacting, the shadow chunk may be + // not page-aligned, so we only flush the page-aligned portion. + ReleaseMemoryPagesToOS(MemToShadow(p), MemToShadow(p + size)); +} + +void ReadContextStack(void *context, uptr *stack, uptr *ssize) { + UNIMPLEMENTED(); +} + +struct task_spawn_arg { + FUNCPTR entryPt; + _Vx_usr_arg_t arg1; + _Vx_usr_arg_t arg2; + _Vx_usr_arg_t arg3; + _Vx_usr_arg_t arg4; + _Vx_usr_arg_t arg5; + _Vx_usr_arg_t arg6; + _Vx_usr_arg_t arg7; + _Vx_usr_arg_t arg8; + _Vx_usr_arg_t arg9; + _Vx_usr_arg_t arg10; +}; + +static thread_return_t asan_entry_wrap(void *arg) { + struct task_spawn_arg *wrap_arg = (task_spawn_arg *)arg; + (wrap_arg->entryPt)(wrap_arg->arg1, wrap_arg->arg2, wrap_arg->arg3, + wrap_arg->arg4, wrap_arg->arg5, wrap_arg->arg6, + wrap_arg->arg7, wrap_arg->arg8, wrap_arg->arg9, + wrap_arg->arg10); + free(wrap_arg); + return 0; +} + +static void init_asan_entry_wrap(struct task_spawn_arg *arg, FUNCPTR entryPt, + _Vx_usr_arg_t arg1, _Vx_usr_arg_t arg2, + _Vx_usr_arg_t arg3, _Vx_usr_arg_t arg4, + _Vx_usr_arg_t arg5, _Vx_usr_arg_t arg6, + _Vx_usr_arg_t arg7, _Vx_usr_arg_t arg8, + _Vx_usr_arg_t arg9, _Vx_usr_arg_t arg10) { + arg->entryPt = entryPt; + arg->arg1 = arg1; + arg->arg2 = arg2; + arg->arg3 = arg3; + arg->arg4 = arg4; + arg->arg5 = arg4; + arg->arg6 = arg6; + arg->arg7 = arg7; + arg->arg8 = arg8; + arg->arg9 = arg9; + arg->arg10 = arg10; +} + +static int asan_thread_start(_Vx_usr_arg_t arg) { + AsanThread *t = (AsanThread *)arg; + SetCurrentThread(t); + t->ThreadStart(GetTid()); + return 0; +} + +INTERCEPTOR(TASK_ID, taskCreate, char *name, int priority, int options, + size_t stackSize, FUNCPTR entryPt, _Vx_usr_arg_t arg1, + _Vx_usr_arg_t arg2, _Vx_usr_arg_t arg3, _Vx_usr_arg_t arg4, + _Vx_usr_arg_t arg5, _Vx_usr_arg_t arg6, _Vx_usr_arg_t arg7, + _Vx_usr_arg_t arg8, _Vx_usr_arg_t arg9, _Vx_usr_arg_t arg10) { + TASK_ID tid; + + // Strict init-order checking is thread-hostile. + if (flags()->strict_init_order) + StopInitOrderChecking(); + GET_STACK_TRACE_THREAD; + bool detached = false; // FIXME: how can we determine it on VxWorks? + u32 current_tid = GetCurrentTidOrInvalid(); + struct task_spawn_arg *wrap_arg; + + wrap_arg = (struct task_spawn_arg *)malloc(sizeof(struct task_spawn_arg)); + init_asan_entry_wrap(wrap_arg, entryPt, arg1, arg2, arg3, arg4, arg5, arg6, + arg7, arg8, arg9, arg10); + + AsanThread *t = AsanThread::Create(asan_entry_wrap, wrap_arg, current_tid, + &stack, detached); + + if (t) + asanThreadRegistry().SetThreadName(t->tid(), name); + + tid = REAL(taskCreate)(name, priority, options, stackSize, + (FUNCPTR)asan_thread_start, (_Vx_usr_arg_t)t, 0, 0, 0, + 0, 0, 0, 0, 0, 0); + + if (tid == TASK_ID_NULL) { + t->Destroy(); + } + + return tid; +} + +INTERCEPTOR(TASK_ID, taskOpen, const char *name, int priority, int options, + int mode, char *pStackBase, size_t stackSize, void *context, + FUNCPTR entryPt, _Vx_usr_arg_t arg1, _Vx_usr_arg_t arg2, + _Vx_usr_arg_t arg3, _Vx_usr_arg_t arg4, _Vx_usr_arg_t arg5, + _Vx_usr_arg_t arg6, _Vx_usr_arg_t arg7, _Vx_usr_arg_t arg8, + _Vx_usr_arg_t arg9, _Vx_usr_arg_t arg10) { + TASK_ID tid; + + // Strict init-order checking is thread-hostile. + if (flags()->strict_init_order) + StopInitOrderChecking(); + GET_STACK_TRACE_THREAD; + bool detached = false; // FIXME: how can we determine it on VxWorks? + u32 current_tid = GetCurrentTidOrInvalid(); + struct task_spawn_arg *wrap_arg; + + wrap_arg = (struct task_spawn_arg *)malloc(sizeof(struct task_spawn_arg)); + init_asan_entry_wrap(wrap_arg, entryPt, arg1, arg2, arg3, arg4, arg5, arg6, + arg7, arg8, arg9, arg10); + + AsanThread *t = AsanThread::Create(asan_entry_wrap, wrap_arg, current_tid, + &stack, detached); + + if (t) + asanThreadRegistry().SetThreadName(t->tid(), name); + + tid = REAL(taskOpen)(name, priority, options, mode, pStackBase, stackSize, + context, (FUNCPTR)asan_thread_start, (_Vx_usr_arg_t)t, 0, + 0, 0, 0, 0, 0, 0, 0, 0); + + if (tid == TASK_ID_NULL) { + t->Destroy(); + } + + return tid; +} + +INTERCEPTOR(STATUS, taskActivate, TASK_ID tid) { + return REAL(taskActivate)(tid); +} + +void InitializePlatformInterceptors() { + // Inteception to taskSpawn is not needed because it will call + // taskCreate/taskActivate internallly + ASAN_INTERCEPT_FUNC(taskCreate); + ASAN_INTERCEPT_FUNC(taskActivate); + ASAN_INTERCEPT_FUNC(taskOpen); +} +} // namespace __asan +#endif // SANITIZER_VXWORKS Index: compiler-rt/lib/interception/interception.h =================================================================== --- compiler-rt/lib/interception/interception.h +++ compiler-rt/lib/interception/interception.h @@ -18,7 +18,7 @@ #if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_MAC && \ !SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA && \ - !SANITIZER_SOLARIS + !SANITIZER_SOLARIS && !SANITIZER_VXWORKS # error "Interception doesn't work on this operating system." #endif @@ -272,11 +272,11 @@ #define INCLUDED_FROM_INTERCEPTION_LIB #if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS + SANITIZER_SOLARIS || SANITIZER_VXWORKS -# include "interception_linux.h" -# define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) -# define INTERCEPT_FUNCTION_VER(func, symver) \ +# 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 SANITIZER_MAC # include "interception_mac.h" Index: compiler-rt/lib/interception/interception_linux.h =================================================================== --- compiler-rt/lib/interception/interception_linux.h +++ compiler-rt/lib/interception/interception_linux.h @@ -12,14 +12,15 @@ //===----------------------------------------------------------------------===// #if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS + SANITIZER_SOLARIS || SANITIZER_VXWORKS -#if !defined(INCLUDED_FROM_INTERCEPTION_LIB) -# error "interception_linux.h should be included from interception library only" -#endif +# if !defined(INCLUDED_FROM_INTERCEPTION_LIB) +# error \ + "interception_linux.h should be included from interception library only" +# endif -#ifndef INTERCEPTION_LINUX_H -#define INTERCEPTION_LINUX_H +# ifndef INTERCEPTION_LINUX_H +# define INTERCEPTION_LINUX_H namespace __interception { bool InterceptFunction(const char *name, uptr *ptr_to_real, uptr func, Index: compiler-rt/lib/interception/interception_linux.cpp =================================================================== --- compiler-rt/lib/interception/interception_linux.cpp +++ compiler-rt/lib/interception/interception_linux.cpp @@ -14,9 +14,9 @@ #include "interception.h" #if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS + SANITIZER_SOLARIS || SANITIZER_VXWORKS -#include // for dlsym() and dlvsym() +# include // for dlsym() and dlvsym() namespace __interception { Index: compiler-rt/lib/sanitizer_common/CMakeLists.txt =================================================================== --- compiler-rt/lib/sanitizer_common/CMakeLists.txt +++ compiler-rt/lib/sanitizer_common/CMakeLists.txt @@ -16,6 +16,7 @@ sanitizer_linux.cpp sanitizer_linux_s390.cpp sanitizer_mac.cpp + sanitizer_vxworks.cpp sanitizer_mutex.cpp sanitizer_netbsd.cpp sanitizer_platform_limits_freebsd.cpp @@ -31,6 +32,7 @@ sanitizer_procmaps_linux.cpp sanitizer_procmaps_mac.cpp sanitizer_procmaps_solaris.cpp + sanitizer_procmaps_vxworks.cpp sanitizer_solaris.cpp sanitizer_stoptheworld_fuchsia.cpp sanitizer_stoptheworld_mac.cpp @@ -84,6 +86,7 @@ sanitizer_symbolizer_libbacktrace.cpp sanitizer_symbolizer_libcdep.cpp sanitizer_symbolizer_mac.cpp + sanitizer_symbolizer_vxworks.cpp sanitizer_symbolizer_markup.cpp sanitizer_symbolizer_posix_libcdep.cpp sanitizer_symbolizer_report.cpp Index: compiler-rt/lib/sanitizer_common/sanitizer_common.h =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_common.h +++ compiler-rt/lib/sanitizer_common/sanitizer_common.h @@ -948,6 +948,11 @@ #endif } +#if SANITIZER_VXWORKS +# undef READ +# undef WRITE +#endif + struct SignalContext { void *siginfo; void *context; Index: compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc +++ compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc @@ -49,11 +49,15 @@ } _(FIOASYNC, READ, sizeof(int)); + #if !SANITIZER_VXWORKS _(FIOCLEX, NONE, 0); _(FIOGETOWN, WRITE, sizeof(int)); + #endif _(FIONBIO, READ, sizeof(int)); + #if !SANITIZER_VXWORKS _(FIONCLEX, NONE, 0); _(FIOSETOWN, READ, sizeof(int)); + #endif _(SIOCATMARK, WRITE, sizeof(int)); _(SIOCGIFCONF, CUSTOM, 0); _(SIOCGPGRP, WRITE, sizeof(int)); Index: compiler-rt/lib/sanitizer_common/sanitizer_errno.h =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_errno.h +++ compiler-rt/lib/sanitizer_common/sanitizer_errno.h @@ -23,7 +23,7 @@ #if SANITIZER_FREEBSD || SANITIZER_MAC # define __errno_location __error -#elif SANITIZER_ANDROID || SANITIZER_NETBSD +#elif SANITIZER_ANDROID || SANITIZER_NETBSD || SANITIZER_VXWORKS # define __errno_location __errno #elif SANITIZER_SOLARIS # define __errno_location ___errno Index: compiler-rt/lib/sanitizer_common/sanitizer_linux.h =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -13,15 +13,15 @@ #define SANITIZER_LINUX_H #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS -#include "sanitizer_common.h" -#include "sanitizer_internal_defs.h" -#include "sanitizer_platform_limits_freebsd.h" -#include "sanitizer_platform_limits_netbsd.h" -#include "sanitizer_platform_limits_posix.h" -#include "sanitizer_platform_limits_solaris.h" -#include "sanitizer_posix.h" +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS || SANITIZER_VXWORKS +# include "sanitizer_common.h" +# include "sanitizer_internal_defs.h" +# include "sanitizer_platform_limits_freebsd.h" +# include "sanitizer_platform_limits_netbsd.h" +# include "sanitizer_platform_limits_posix.h" +# include "sanitizer_platform_limits_solaris.h" +# include "sanitizer_posix.h" struct link_map; // Opaque type returned by dlopen(). struct utsname; Index: compiler-rt/lib/sanitizer_common/sanitizer_mutex.h =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_mutex.h +++ compiler-rt/lib/sanitizer_common/sanitizer_mutex.h @@ -100,8 +100,9 @@ // Disable checked locks on Darwin. Although Darwin platforms support // THREADLOCAL variables they are not usable early on during process init when // `__sanitizer::Mutex` is used. -#define SANITIZER_CHECK_DEADLOCKS \ - (SANITIZER_DEBUG && !SANITIZER_GO && SANITIZER_SUPPORTS_THREADLOCAL && !SANITIZER_MAC) +#define SANITIZER_CHECK_DEADLOCKS \ + (SANITIZER_DEBUG && !SANITIZER_GO && SANITIZER_SUPPORTS_THREADLOCAL && \ + !SANITIZER_MAC && !SANITIZER_VXWORKS) #if SANITIZER_CHECK_DEADLOCKS struct MutexMeta { Index: compiler-rt/lib/sanitizer_common/sanitizer_platform.h =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ compiler-rt/lib/sanitizer_common/sanitizer_platform.h @@ -14,7 +14,7 @@ #if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \ !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) && \ - !(defined(__sun__) && defined(__svr4__)) + !(defined(__sun__) && defined(__svr4__)) && !defined(__vxworks) # error "This operating system is not supported" #endif @@ -25,6 +25,13 @@ # include #endif +#if defined(__vxworks) +# define SANITIZER_VXWORKS 1 +# include +#else +# define SANITIZER_VXWORKS 0 +#endif + #if defined(__linux__) # define SANITIZER_LINUX 1 #else @@ -118,7 +125,7 @@ #define SANITIZER_POSIX \ (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \ - SANITIZER_NETBSD || SANITIZER_SOLARIS) + SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_VXWORKS) #if __LP64__ || defined(_WIN64) # define SANITIZER_WORDSIZE 64 @@ -247,6 +254,8 @@ # define SANITIZER_CAN_USE_ALLOCATOR64 1 # elif defined(__mips64) || defined(__aarch64__) # define SANITIZER_CAN_USE_ALLOCATOR64 0 +# elif SANITIZER_VXWORKS && defined(__riscv) && !_WRS_CONFIG_SATP_MODE_SV48 +# define SANITIZER_CAN_USE_ALLOCATOR64 0 # else # define SANITIZER_CAN_USE_ALLOCATOR64 (SANITIZER_WORDSIZE == 64) # endif @@ -363,6 +372,8 @@ #if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD || SANITIZER_SOLARIS # define SANITIZER_MADVISE_DONTNEED MADV_FREE +#elif SANITIZER_VXWORKS +# define SANITIZER_MADVISE_DONTNEED 0 #else # define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED #endif Index: compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h +++ compiler-rt/lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -126,6 +126,12 @@ #define SI_SOLARIS32 0 #endif +#if SANITIZER_VXWORKS +# define SI_VXWORKS 1 +#else +# define SI_VXWORKS 0 +#endif + #if SANITIZER_POSIX && !SANITIZER_MAC #define SI_POSIX_NOT_MAC 1 #else @@ -376,8 +382,8 @@ #define SANITIZER_INTERCEPT_SINCOS SI_LINUX || SI_SOLARIS #define SANITIZER_INTERCEPT_REMQUO SI_POSIX #define SANITIZER_INTERCEPT_REMQUOL (SI_POSIX && !SI_NETBSD) -#define SANITIZER_INTERCEPT_LGAMMA SI_POSIX -#define SANITIZER_INTERCEPT_LGAMMAL (SI_POSIX && !SI_NETBSD) +#define SANITIZER_INTERCEPT_LGAMMA (SI_POSIX && !SI_VXWORKS) +#define SANITIZER_INTERCEPT_LGAMMAL (SI_POSIX && !SI_NETBSD && !SI_VXWORKS) #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_GLIBC Index: compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -14,12 +14,12 @@ #ifndef SANITIZER_PLATFORM_LIMITS_POSIX_H #define SANITIZER_PLATFORM_LIMITS_POSIX_H -#if SANITIZER_LINUX || SANITIZER_MAC +#if SANITIZER_LINUX || SANITIZER_MAC || SANITIZER_VXWORKS -#include "sanitizer_internal_defs.h" -#include "sanitizer_platform.h" +# include "sanitizer_internal_defs.h" +# include "sanitizer_platform.h" -#if defined(__sparc__) +# if defined(__sparc__) // FIXME: This can't be included from tsan which does not support sparc yet. #include "sanitizer_glibc_version.h" #endif @@ -322,7 +322,7 @@ }; #endif // !SANITIZER_ANDROID -#if SANITIZER_MAC +# if SANITIZER_MAC || SANITIZER_VXWORKS typedef unsigned long __sanitizer_pthread_key_t; #else typedef unsigned __sanitizer_pthread_key_t; @@ -430,7 +430,7 @@ }; #endif -#if SANITIZER_MAC +# if SANITIZER_MAC || SANITIZER_VXWORKS struct __sanitizer_msghdr { void *msg_name; unsigned msg_namelen; @@ -509,7 +509,7 @@ typedef long __sanitizer_clock_t; #endif -#if SANITIZER_LINUX +# if SANITIZER_LINUX || SANITIZER_VXWORKS typedef int __sanitizer_clockid_t; #endif @@ -562,7 +562,9 @@ // The size is determined by looking at sizeof of real sigset_t on linux. uptr val[128 / sizeof(uptr)]; }; -#endif +# elif SANITIZER_VXWORKS +typedef unsigned long long __sanitizer_sigset_t; +# endif struct __sanitizer_siginfo { // The size is determined by looking at sizeof of real siginfo_t on linux. @@ -753,7 +755,7 @@ short revents; }; -#if SANITIZER_ANDROID || SANITIZER_MAC +# if SANITIZER_ANDROID || SANITIZER_MAC || SANITIZER_VXWORKS typedef unsigned __sanitizer_nfds_t; #else typedef unsigned long __sanitizer_nfds_t; Index: compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -23,7 +23,7 @@ // Must go after undef _FILE_OFFSET_BITS. #include "sanitizer_platform.h" -#if SANITIZER_LINUX || SANITIZER_MAC +#if SANITIZER_LINUX || SANITIZER_MAC || SANITIZER_VXWORKS // Must go after undef _FILE_OFFSET_BITS. #include "sanitizer_glibc_version.h" @@ -51,46 +51,46 @@ #include #include #include -#if !SANITIZER_MAC -#include -#endif +# if !SANITIZER_MAC && !SANITIZER_VXWORKS +# include +# endif -#if !SANITIZER_IOS -#include -#endif +# if !SANITIZER_IOS +# include +# endif -#if !SANITIZER_ANDROID -#include -#include -#include -#endif +# if !SANITIZER_ANDROID && !SANITIZER_VXWORKS +# include +# include +# include +# endif -#if SANITIZER_LINUX -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif +# if SANITIZER_LINUX +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# endif -#if SANITIZER_IOS -#undef IOC_DIRMASK -#endif +# if SANITIZER_IOS +# undef IOC_DIRMASK +# endif -#if SANITIZER_LINUX -# include -# include +# if SANITIZER_LINUX +# include +# include # if defined(__mips64) || defined(__aarch64__) || defined(__arm__) || \ defined(__hexagon__) || SANITIZER_RISCV64 # include @@ -105,69 +105,79 @@ # include #endif -#if !SANITIZER_ANDROID -#include -#include -#include -#endif +# if !SANITIZER_ANDROID && !SANITIZER_VXWORKS +# include +# include +# include +# endif -#if SANITIZER_LINUX -#if SANITIZER_GLIBC -#include -#include -#include -#include -#include -#include -#if HAVE_RPC_XDR_H -# include -#endif -#include -#else -#include -#include -#include -#endif // SANITIZER_GLIBC +# if SANITIZER_LINUX +# if SANITIZER_GLIBC +# include +# include +# include +# include +# include +# include +# if HAVE_RPC_XDR_H +# include +# endif +# include +# else +# include +# include +# include +# endif // SANITIZER_GLIBC -#if SANITIZER_ANDROID -#include -#else -#include -#include -#include -#include -#include -#include -#include -#if defined(__mips64) -# include -#endif -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#include -#endif // SANITIZER_ANDROID - -#include -#include -#include -#include -#else -#include -#endif // SANITIZER_LINUX +# if SANITIZER_ANDROID +# include +# else +# include +# include +# include +# include +# include +# include +# include +# if defined(__mips64) +# include +# endif +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# endif // SANITIZER_ANDROID + +# include +# include +# include +# include +# else +# if !SANITIZER_VXWORKS +# include +# endif +# endif // SANITIZER_LINUX -#if SANITIZER_MAC -#include -#include -#include -#endif +# if SANITIZER_MAC +# include +# include +# include +# endif + +# if SANITIZER_VXWORKS +# include +# include +# include +# include +# include +# endif // Include these after system headers to avoid name clashes and ambiguities. # include "sanitizer_common.h" @@ -177,12 +187,15 @@ namespace __sanitizer { unsigned struct_utsname_sz = sizeof(struct utsname); unsigned struct_stat_sz = sizeof(struct stat); -#if !SANITIZER_IOS && !(SANITIZER_MAC && TARGET_CPU_ARM64) +# if !SANITIZER_IOS && !(SANITIZER_MAC && TARGET_CPU_ARM64) && \ + !SANITIZER_VXWORKS unsigned struct_stat64_sz = sizeof(struct stat64); #endif // !SANITIZER_IOS && !(SANITIZER_MAC && TARGET_CPU_ARM64) unsigned struct_rusage_sz = sizeof(struct rusage); unsigned struct_tm_sz = sizeof(struct tm); +# if !SANITIZER_VXWORKS unsigned struct_passwd_sz = sizeof(struct passwd); +# endif unsigned struct_group_sz = sizeof(struct group); unsigned siginfo_t_sz = sizeof(siginfo_t); unsigned struct_sigaction_sz = sizeof(struct sigaction); @@ -197,7 +210,9 @@ unsigned gid_t_sz = sizeof(gid_t); unsigned mbstate_t_sz = sizeof(mbstate_t); unsigned sigset_t_sz = sizeof(sigset_t); +# if !SANITIZER_VXWORKS unsigned struct_timezone_sz = sizeof(struct timezone); +# endif unsigned struct_tms_sz = sizeof(struct tms); unsigned struct_sigevent_sz = sizeof(struct sigevent); unsigned struct_sched_param_sz = sizeof(struct sched_param); @@ -296,10 +311,10 @@ int shmctl_shm_stat = (int)SHM_STAT; #endif -#if !SANITIZER_MAC && !SANITIZER_FREEBSD +# if !SANITIZER_MAC && !SANITIZER_FREEBSD && !SANITIZER_VXWORKS unsigned struct_utmp_sz = sizeof(struct utmp); #endif -#if !SANITIZER_ANDROID +# if !SANITIZER_ANDROID && !SANITIZER_VXWORKS unsigned struct_utmpx_sz = sizeof(struct utmpx); #endif @@ -328,7 +343,7 @@ int glob_altdirfunc = GLOB_ALTDIRFUNC; #endif -# if !SANITIZER_ANDROID +# if !SANITIZER_ANDROID && !SANITIZER_VXWORKS const int wordexp_wrde_dooffs = WRDE_DOOFFS; # endif // !SANITIZER_ANDROID @@ -504,7 +519,7 @@ unsigned struct_ppp_stats_sz = sizeof(struct ppp_stats); #endif // SANITIZER_GLIBC -#if !SANITIZER_ANDROID && !SANITIZER_MAC +# if !SANITIZER_ANDROID && !SANITIZER_MAC && !SANITIZER_VXWORKS unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req); unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req); #endif @@ -514,11 +529,15 @@ const unsigned IOCTL_NOT_PRESENT = 0; unsigned IOCTL_FIOASYNC = FIOASYNC; +# if !SANITIZER_VXWORKS unsigned IOCTL_FIOCLEX = FIOCLEX; unsigned IOCTL_FIOGETOWN = FIOGETOWN; +# endif unsigned IOCTL_FIONBIO = FIONBIO; +# if !SANITIZER_VXWORKS unsigned IOCTL_FIONCLEX = FIONCLEX; unsigned IOCTL_FIOSETOWN = FIOSETOWN; +# endif unsigned IOCTL_SIOCADDMULTI = SIOCADDMULTI; unsigned IOCTL_SIOCATMARK = SIOCATMARK; unsigned IOCTL_SIOCDELMULTI = SIOCDELMULTI; @@ -1008,9 +1027,11 @@ CHECK_SIZE_AND_OFFSET(addrinfo, ai_socktype); CHECK_SIZE_AND_OFFSET(addrinfo, ai_protocol); CHECK_SIZE_AND_OFFSET(addrinfo, ai_protocol); +# if !SANITIZER_VXWORKS CHECK_SIZE_AND_OFFSET(addrinfo, ai_addrlen); CHECK_SIZE_AND_OFFSET(addrinfo, ai_canonname); CHECK_SIZE_AND_OFFSET(addrinfo, ai_addr); +# endif CHECK_TYPE_SIZE(hostent); CHECK_SIZE_AND_OFFSET(hostent, h_name); @@ -1057,14 +1078,16 @@ CHECK_SIZE_AND_OFFSET(dirent, d_ino); #if SANITIZER_MAC CHECK_SIZE_AND_OFFSET(dirent, d_seekoff); -#elif SANITIZER_FREEBSD +# elif SANITIZER_FREEBSD || SANITIZER_VXWORKS // There is no 'd_off' field on FreeBSD. -#else +# else CHECK_SIZE_AND_OFFSET(dirent, d_off); -#endif +# endif +# if !SANITIZER_VXWORKS CHECK_SIZE_AND_OFFSET(dirent, d_reclen); +# endif -#if SANITIZER_LINUX && !SANITIZER_ANDROID +# if SANITIZER_LINUX && !SANITIZER_ANDROID COMPILER_CHECK(sizeof(__sanitizer_dirent64) <= sizeof(dirent64)); CHECK_SIZE_AND_OFFSET(dirent64, d_ino); CHECK_SIZE_AND_OFFSET(dirent64, d_off); @@ -1119,13 +1142,14 @@ CHECK_TYPE_SIZE(__kernel_fd_set); #endif -#if !SANITIZER_ANDROID +# if !SANITIZER_ANDROID && !SANITIZER_VXWORKS 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); #endif +# if !SANITIZER_VXWORKS CHECK_TYPE_SIZE(tm); CHECK_SIZE_AND_OFFSET(tm, tm_sec); CHECK_SIZE_AND_OFFSET(tm, tm_min); @@ -1138,8 +1162,9 @@ CHECK_SIZE_AND_OFFSET(tm, tm_isdst); CHECK_SIZE_AND_OFFSET(tm, tm_gmtoff); CHECK_SIZE_AND_OFFSET(tm, tm_zone); +# endif -#if SANITIZER_LINUX +# if SANITIZER_LINUX CHECK_TYPE_SIZE(mntent); CHECK_SIZE_AND_OFFSET(mntent, mnt_fsname); CHECK_SIZE_AND_OFFSET(mntent, mnt_dir); @@ -1187,7 +1212,7 @@ CHECK_TYPE_SIZE(clockid_t); #endif -#if !SANITIZER_ANDROID +# if !SANITIZER_ANDROID && !SANITIZER_VXWORKS CHECK_TYPE_SIZE(ifaddrs); CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_next); CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name); @@ -1217,7 +1242,7 @@ COMPILER_CHECK(sizeof(__sanitizer_struct_mallinfo) == sizeof(struct mallinfo)); #endif -#if !SANITIZER_ANDROID +# if !SANITIZER_ANDROID && !SANITIZER_VXWORKS CHECK_TYPE_SIZE(timeb); CHECK_SIZE_AND_OFFSET(timeb, time); CHECK_SIZE_AND_OFFSET(timeb, millitm); @@ -1225,6 +1250,7 @@ CHECK_SIZE_AND_OFFSET(timeb, dstflag); #endif +# if !SANITIZER_VXWORKS CHECK_TYPE_SIZE(passwd); CHECK_SIZE_AND_OFFSET(passwd, pw_name); CHECK_SIZE_AND_OFFSET(passwd, pw_passwd); @@ -1242,7 +1268,7 @@ CHECK_SIZE_AND_OFFSET(passwd, pw_expire); CHECK_SIZE_AND_OFFSET(passwd, pw_class); #endif - +# endif CHECK_TYPE_SIZE(group); CHECK_SIZE_AND_OFFSET(group, gr_name); Index: compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp +++ compiler-rt/lib/sanitizer_common/sanitizer_posix.cpp @@ -27,7 +27,7 @@ #include #include -#if SANITIZER_FREEBSD +# if SANITIZER_FREEBSD || SANITIZER_VXWORKS // 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 @@ -239,7 +239,7 @@ return true; } -#if !SANITIZER_MAC +# if !SANITIZER_MAC && !SANITIZER_VXWORKS void DumpProcessMap() { MemoryMappingLayout proc_maps(/*cache_enabled*/true); const sptr kBufSize = 4095; Index: compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp +++ compiler-rt/lib/sanitizer_common/sanitizer_posix_libcdep.cpp @@ -36,7 +36,7 @@ #include #include -#if SANITIZER_FREEBSD +# if SANITIZER_FREEBSD || SANITIZER_VXWORKS // 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 @@ -51,9 +51,11 @@ return getuid(); } +# if !SANITIZER_VXWORKS uptr GetThreadSelf() { return (uptr)pthread_self(); } +# endif void ReleaseMemoryPagesToOS(uptr beg, uptr end) { uptr page_size = GetPageSizeCached(); @@ -103,9 +105,11 @@ } void DisableCoreDumperIfNecessary() { +# if !SANITIZER_VXWORKS /* getprlimitSc doesn't support RLIMIT_CORE */ if (common_flags()->disable_coredump) { setlim(RLIMIT_CORE, 0); } +# endif } bool StackSizeIsUnlimited() { @@ -119,13 +123,19 @@ } bool AddressSpaceIsUnlimited() { +# if !SANITIZER_VXWORKS /* getprlimitSc doesn't support RLIMIT_AS */ rlim_t as_size = getlim(RLIMIT_AS); return (as_size == RLIM_INFINITY); +# else + return false; +# endif } void SetAddressSpaceUnlimited() { +# if !SANITIZER_VXWORKS /* getprlimitSc doesn't support RLIMIT_AS */ setlim(RLIMIT_AS, RLIM_INFINITY); CHECK(AddressSpaceIsUnlimited()); +# endif } void Abort() { Index: compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h +++ compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h @@ -16,15 +16,15 @@ #include "sanitizer_platform.h" #if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ - SANITIZER_MAC || SANITIZER_SOLARIS || \ - SANITIZER_FUCHSIA - -#include "sanitizer_common.h" -#include "sanitizer_internal_defs.h" -#include "sanitizer_fuchsia.h" -#include "sanitizer_linux.h" -#include "sanitizer_mac.h" -#include "sanitizer_mutex.h" + SANITIZER_MAC || SANITIZER_SOLARIS || SANITIZER_FUCHSIA || \ + SANITIZER_VXWORKS + +# include "sanitizer_common.h" +# include "sanitizer_fuchsia.h" +# include "sanitizer_internal_defs.h" +# include "sanitizer_linux.h" +# include "sanitizer_mac.h" +# include "sanitizer_mutex.h" namespace __sanitizer { Index: compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp +++ compiler-rt/lib/sanitizer_common/sanitizer_procmaps_common.cpp @@ -11,12 +11,12 @@ #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS || SANITIZER_VXWORKS -#include "sanitizer_common.h" -#include "sanitizer_placement_new.h" -#include "sanitizer_procmaps.h" +# include "sanitizer_common.h" +# include "sanitizer_placement_new.h" +# include "sanitizer_procmaps.h" namespace __sanitizer { Index: compiler-rt/lib/sanitizer_common/sanitizer_procmaps_vxworks.cpp =================================================================== --- /dev/null +++ compiler-rt/lib/sanitizer_common/sanitizer_procmaps_vxworks.cpp @@ -0,0 +1,26 @@ +//===-- sanitizer_procmaps_vxworks.cpp +//--------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// Information about the process mappings (VxWorks-specific parts). +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" +#if SANITIZER_VXWORKS +# include "sanitizer_common.h" +# include "sanitizer_procmaps.h" + +namespace __sanitizer { + +void ReadProcMaps(ProcSelfMapsBuff *proc_maps) { return; } + +bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { return false; } + +} // namespace __sanitizer + +#endif // SANITIZER_VXWORKS Index: compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h +++ compiler-rt/lib/sanitizer_common/sanitizer_stacktrace.h @@ -33,7 +33,7 @@ // 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_VXWORKS # define SANITIZER_CAN_SLOW_UNWIND 0 #else # define SANITIZER_CAN_SLOW_UNWIND 1 Index: compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp +++ compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_posix_libcdep.cpp @@ -13,25 +13,26 @@ #include "sanitizer_platform.h" #if SANITIZER_POSIX -#include "sanitizer_allocator_internal.h" -#include "sanitizer_common.h" -#include "sanitizer_file.h" -#include "sanitizer_flags.h" -#include "sanitizer_internal_defs.h" -#include "sanitizer_linux.h" -#include "sanitizer_placement_new.h" -#include "sanitizer_posix.h" -#include "sanitizer_procmaps.h" -#include "sanitizer_symbolizer_internal.h" -#include "sanitizer_symbolizer_libbacktrace.h" -#include "sanitizer_symbolizer_mac.h" - -#include // for dlsym() -#include -#include -#include -#include -#include +# include // for dlsym() +# include +# include +# include +# include +# include + +# include "sanitizer_allocator_internal.h" +# include "sanitizer_common.h" +# include "sanitizer_file.h" +# include "sanitizer_flags.h" +# include "sanitizer_internal_defs.h" +# include "sanitizer_linux.h" +# include "sanitizer_placement_new.h" +# include "sanitizer_posix.h" +# include "sanitizer_procmaps.h" +# include "sanitizer_symbolizer_internal.h" +# include "sanitizer_symbolizer_libbacktrace.h" +# include "sanitizer_symbolizer_mac.h" +# include "sanitizer_symbolizer_vxworks.h" // C++ demangling function, as required by Itanium C++ ABI. This is weak, // because we do not require a C++ ABI library to be linked to a program @@ -488,7 +489,7 @@ list->push_back(tool); } -#if SANITIZER_MAC +# if SANITIZER_MAC || SANITIZER_VXWORKS VReport(2, "Using dladdr symbolizer.\n"); list->push_back(new(*allocator) DlAddrSymbolizer()); #endif // SANITIZER_MAC Index: compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_vxworks.h =================================================================== --- /dev/null +++ compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_vxworks.h @@ -0,0 +1,37 @@ +//===-- sanitizer_symbolizer_vxworks.h ------------------------------*- C++ +//-*-===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is shared between various sanitizers' runtime libraries. +// +// Header for VxWorks-specific symbolizer. +//===----------------------------------------------------------------------===// + +#ifndef SANITIZER_SYMBOLIZER_VXWORKS_H +#define SANITIZER_SYMBOLIZER_VXWORKS_H + +#include "sanitizer_platform.h" +#if SANITIZER_VXWORKS + +# include "sanitizer_symbolizer_internal.h" + +namespace __sanitizer { + +class DlAddrSymbolizer final : public SymbolizerTool { + public: + explicit DlAddrSymbolizer(){}; + + bool SymbolizePC(uptr addr, SymbolizedStack *stack) override; + bool SymbolizeData(uptr addr, DataInfo *info) override; +}; + +} // namespace __sanitizer + +#endif // SANITIZER_VXWORKS + +#endif // SANITIZER_SYMBOLIZER_VXWORKS_H Index: compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_vxworks.cpp =================================================================== --- /dev/null +++ compiler-rt/lib/sanitizer_common/sanitizer_symbolizer_vxworks.cpp @@ -0,0 +1,51 @@ +//===-- sanitizer_symbolizer_vxworks.cpp +//--------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is shared between various sanitizers' runtime libraries. +// +// Implementation of VxWorks-specific symbolizer. +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" +#if SANITIZER_VXWORKS + +# include +# include +# include + +# include "sanitizer_allocator_internal.h" +# include "sanitizer_symbolizer_vxworks.h" + +namespace __sanitizer { + +bool DlAddrSymbolizer::SymbolizePC(uptr addr, SymbolizedStack *stack) { + Dl_info info; + int result = dladdr((void *)addr, &info); + if (!result) + return false; + + uptr sym_addr = reinterpret_cast(info.dli_saddr); + if (addr >= sym_addr) { + stack->info.function_offset = addr - sym_addr; + } + + const char *demangled = DemangleSwiftAndCXX(info.dli_sname); + if (!demangled) + return false; + stack->info.function = internal_strdup(demangled); + return true; +} + +bool DlAddrSymbolizer::SymbolizeData(uptr addr, DataInfo *datainfo) { + return true; +} + +} // namespace __sanitizer + +#endif // SANITIZER_VXWORKS Index: compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp =================================================================== --- compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp +++ compiler-rt/lib/sanitizer_common/sanitizer_thread_registry.cpp @@ -222,7 +222,8 @@ ThreadRegistryLock l(this); ThreadContextBase *tctx = threads_[tid]; CHECK_NE(tctx, 0); - CHECK_EQ(SANITIZER_FUCHSIA ? ThreadStatusCreated : ThreadStatusRunning, + CHECK_EQ(SANITIZER_FUCHSIA || SANITIZER_VXWORKS ? ThreadStatusCreated + : ThreadStatusRunning, tctx->status); tctx->SetName(name); } Index: compiler-rt/lib/sanitizer_common/sanitizer_vxworks.cpp =================================================================== --- /dev/null +++ compiler-rt/lib/sanitizer_common/sanitizer_vxworks.cpp @@ -0,0 +1,494 @@ +//===-- sanitizer_VxWorks.cpp +//-------------------------------------------------===// +// +// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. +// See https://llvm.org/LICENSE.txt for license information. +// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception +// +//===----------------------------------------------------------------------===// +// +// This file is shared between various sanitizers' runtime libraries and +// implements VxWorks-specific functions. +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" +#if SANITIZER_VXWORKS +# include + +# include "interception/interception.h" +# include "sanitizer_common.h" +# include "sanitizer_file.h" +# include "sanitizer_flags.h" +# include "sanitizer_internal_defs.h" +# include "sanitizer_libc.h" +# include "sanitizer_platform_limits_posix.h" +# include "sanitizer_procmaps.h" +# include "sanitizer_ptrauth.h" + +# if defined(__has_include) && __has_include() +# define SANITIZER_OS_TRACE 1 +# include +# else +# define SANITIZER_OS_TRACE 0 +# endif + +# include +# include // for dladdr() +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include +# include + +/* for VxWorks */ +# include +# include +# include +# include +# include + +# include "../asan/asan_mapping.h" + +# ifndef _WRS_CONFIG_LP64 +# define Elf_Phdr Elf32_Phdr +# else +# define Elf_Phdr Elf64_Phdr +# endif + +int usleep(useconds_t usecs) { + struct timespec tp; + tp.tv_sec = 0; + tp.tv_nsec = usecs * 1000; + return nanosleep(&tp, NULL); +} + +namespace __sanitizer { + +# include "sanitizer_syscall_generic.inc" + +// On VxWorks, many system call functions are included in the libc directly +// which is very suitable for implementing the internal_* functions used by +// ASAN. +static void *GetRealLibcAddress(const char *symbol) { + void *real = dlsym(RTLD_NEXT, 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); + +uptr internal_mmap(void *addr, size_t length, int prot, int flags, int fd, + u64 offset) { + DEFINE__REAL(uptr, mmap, void *a, size_t b, int c, int d, int e, u64 f); + return _REAL(mmap, addr, length, prot, flags, fd, 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); +} + +int internal_madvise(uptr addr, uptr length, int advice) { + // FIXME: VxWorks doesn't support madvise + // shadow memory allocate/deallocate is managed by VxWorks OS + return 0; +} + +uptr internal_close(fd_t fd) { + DEFINE__REAL(int, close, fd_t a); + return _REAL(close, fd); +} + +uptr internal_open(const char *filename, int flags) { + DEFINE__REAL(int, open, const char *a, int b); + return _REAL(open, filename, flags); +} + +uptr internal_open(const char *filename, int flags, u32 mode) { + DEFINE__REAL(int, open, const char *filename, int flags, u32 mode); + return _REAL(open, filename, flags, mode); +} + +uptr internal_read(fd_t fd, void *buf, uptr count) { + DEFINE__REAL(uptr, read, fd_t a, void *b, uptr c); + return _REAL(read, fd, buf, count); +} + +uptr internal_write(fd_t fd, const void *buf, uptr count) { + DEFINE__REAL(uptr, write, fd_t a, const void *b, uptr c); + return _REAL(write, fd, buf, count); +} + +uptr internal_stat(const char *path, void *buf) { + DEFINE__REAL(int, stat, const char *a, void *b); + return _REAL(stat, path, buf); +} + +uptr internal_lstat(const char *path, void *buf) { + DEFINE__REAL(int, lstat, const char *a, void *b); + return _REAL(lstat, path, buf); +} + +uptr internal_fstat(fd_t fd, void *buf) { + DEFINE__REAL(int, fstat, int a, void *b); + return _REAL(fstat, 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_dup(int oldfd) { + DEFINE__REAL(int, dup, int a); + return _REAL(dup, oldfd); +} + +uptr internal_dup2(int oldfd, int newfd) { + DEFINE__REAL(int, dup2, int a, int b); + return _REAL(dup2, oldfd, newfd); +} + +uptr internal_readlink(const char *path, char *buf, uptr bufsize) { + DEFINE__REAL(uptr, readlink, const char *a, char *b, uptr c); + return _REAL(readlink, path, buf, bufsize); +} + +uptr internal_unlink(const char *path) { + DEFINE__REAL(uptr, unlink, const char *a); + return _REAL(unlink, path); +} + +uptr internal_sched_yield() { + DEFINE__REAL(uptr, sched_yield); + return _REAL(sched_yield); +} + +uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) { + DEFINE__REAL(int, clock_gettime, __sanitizer_clockid_t a, void *b); + return _REAL(clock_gettime, clk_id, tp); +} + +void internal__exit(int exitcode) { + DEFINE__REAL(void, _exit, int a); + _REAL(_exit, exitcode); + Die(); // Unreachable. +} + +void internal_usleep(u64 useconds) { usleep(useconds); } + +uptr internal_getpid() { + DEFINE__REAL(int, getpid); + return _REAL(getpid); +} + +int internal_dlinfo(void *handle, int request, void *p) { UNIMPLEMENTED(); } + +int internal_sigaction(int signum, const void *act, void *oldact) { + return sigaction(signum, (const struct sigaction *)act, + (struct sigaction *)oldact); +} + +void internal_sigfillset(__sanitizer_sigset_t *set) { sigfillset(set); } + +uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set, + __sanitizer_sigset_t *oldset) { + // Don't use sigprocmask here, because it affects all threads. + return pthread_sigmask(how, set, oldset); +} + +int internal_fork() { + // VxWorks doesn't support fork + return -1; +} + +uptr internal_execve(const char *filename, char *const argv[], + char *const envp[]) { + // VxWorks doesn't support execve + return -1; +} + +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_ftruncate(fd_t fd, uptr size) { return ftruncate(fd, size); } + +uptr internal_waitpid(int pid, int *status, int options) { + DEFINE__REAL(uptr, waitpid, int a, int *b, int c); + return _REAL(waitpid, pid, status, options); +} + +// ----------------- sanitizer_common.h +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); +} + +tid_t GetTid() { return taskIdSelf(); } + +uptr GetThreadSelf() { return GetTid(); } + +void GetThreadStackTopAndBottom(bool at_initialization, uptr *stack_top, + uptr *stack_bottom) { + TASK_DESC taskDesc; + + taskInfoGet(TASK_ID_NULL, &taskDesc); + *stack_top = (uptr)taskDesc.td_pStackBase; + *stack_bottom = (uptr)taskDesc.td_pStackEnd; +} + +char **GetArgv() { return nullptr; } + +char **GetEnviron() { return nullptr; } + +const char *GetEnv(const char *name) { return getenv(name); } + +uptr ReadBinaryName(/*out*/ char *buf, uptr buf_len) { + // FIXME: Actually implement this function. + buf[0] = 0; + return 0; +} + +uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) { + return ReadBinaryName(buf, buf_len); +} + +void ReExec() { UNIMPLEMENTED(); } + +void CheckASLR() { + // Do nothing +} + +void CheckMPROTECT() { + // Do nothing +} + +uptr GetPageSize() { return sysconf(_SC_PAGESIZE); } + +void FutexWait(atomic_uint32_t *p, u32 cmp) { sched_yield(); } + +void FutexWake(atomic_uint32_t *p, u32 count) {} + +u64 NanoTime() { + timeval tv; + internal_memset(&tv, 0, sizeof(tv)); + gettimeofday(&tv, 0); + return (u64)tv.tv_sec * 1000 * 1000 * 1000 + tv.tv_usec * 1000; +} + +u64 MonotonicNanoTime() { + timespec ts; + internal_clock_gettime(CLOCK_MONOTONIC, &ts); + return (u64)ts.tv_sec * (1000ULL * 1000 * 1000) + ts.tv_nsec; +} + +uptr GetTlsBaseAddr() { return 0; } + +uptr GetTlsSize() { return 0; } + +void InitTlsSize() {} + +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 = GetTlsBaseAddr(); + *tls_size = GetTlsSize(); +} + +struct DlIteratePhdrData { + InternalMmapVectorNoCtor *modules; + bool first; +}; + +static int dl_iterate_phdr_cb(dl_phdr_info *info, size_t size, void *arg) { + DlIteratePhdrData *data = (DlIteratePhdrData *)arg; + InternalScopedString module_name; + if (data->first) { + data->first = false; + // First module is the binary itself. + /*ReadBinaryNameCached(module_name.data(), module_name.size());*/ + module_name.append("%s", info->dlpi_name); + } else if (info->dlpi_name) { + module_name.append("%s", info->dlpi_name); + } + + LoadedModule cur_module; + cur_module.set(module_name.data(), info->dlpi_addr); + 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; + uptr cur_end = cur_beg + phdr->p_memsz; + bool executable = phdr->p_flags & PF_X; + bool writable = phdr->p_flags & PF_W; + cur_module.addAddressRange(cur_beg, cur_end, executable, writable); + } + } + data->modules->push_back(cur_module); + return 0; +} + +void ListOfModules::init() { + clearOrInit(); + DlIteratePhdrData data = {&modules_, true}; + dl_iterate_phdr(dl_iterate_phdr_cb, &data); +} + +void ListOfModules::fallbackInit() { clear(); } + +static HandleSignalMode GetHandleSignalModeImpl(int signum) { + switch (signum) { + case SIGABRT: + 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: + return common_flags()->handle_segv; + case SIGBUS: + return common_flags()->handle_sigbus; + } + return kHandleSignalNo; +} + +HandleSignalMode GetHandleSignalMode(int signum) { + HandleSignalMode result = GetHandleSignalModeImpl(signum); + + if (result == kHandleSignalYes && !common_flags()->allow_user_segv_handler) + return kHandleSignalExclusive; + + return result; +} + +uptr GetRSS() { return 0; } + +void *internal_start_thread(void *(*func)(void *arg), void *arg) { return 0; } + +void internal_join_thread(void *th) {} + +SignalContext::WriteFlag SignalContext::GetWriteFlag() const { return UNKNOWN; } + +bool SignalContext::IsTrueFaultingAddress() const { + auto si = static_cast(siginfo); + // "Real" SIGSEGV codes (e.g., SEGV_MAPERR, SEGV_MAPERR) are non-zero. + return si->si_signo == SIGSEGV && si->si_code != 0; +} + +# if defined(__aarch64__) && defined(arm_thread_state64_get_sp) +# define AARCH64_GET_REG(r) \ + (uptr) ptrauth_strip( \ + (void *)arm_thread_state64_get_##r(ucontext->uc_mcontext->__ss), 0) +# else +# define AARCH64_GET_REG(r) ucontext->uc_mcontext->__ss.__##r +# endif + +static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { + ucontext_t *ucontext = (ucontext_t *)context; +# if defined(__aarch64__) + *pc = (uptr)ucontext->uc_mcontext.regs.pc; + *bp = ucontext->uc_mcontext.regs.r[29]; + *sp = ucontext->uc_mcontext.regs.sp; +# elif defined(__x86_64__) + *pc = (uptr)ucontext->uc_mcontext.regs.pc; + *bp = ucontext->uc_mcontext.regs.rbp; + *sp = ucontext->uc_mcontext.regs.rsp; +# elif defined(__riscv) + *pc = (uptr)ucontext->uc_mcontext.regs.pc; + *bp = ucontext->uc_mcontext.regs.gpr[8]; + *sp = ucontext->uc_mcontext.regs.gpr[2]; +# else +# error "Unknown architecture" +# endif +} + +void SignalContext::InitPcSpBp() { + addr = (uptr)ptrauth_strip((void *)addr, 0); + GetPcSpBp(context, &pc, &sp, &bp); +} + +void InitializePlatformEarly() { + // does nothing +} + +bool ReexecDisabled() { return false; } + +void MaybeReexec() {} + +uptr GetMaxUserVirtualAddress() { +# if SANITIZER_WORDSIZE == 64 + return (1ULL << 47) - 1; // 0x00007fffffffffffUL; +# else // SANITIZER_WORDSIZE == 32 + static_assert(SANITIZER_WORDSIZE == 32, "Wrong wordsize"); + return (1ULL << 32) - 1; // 0xffffffff; +# endif +} + +uptr GetMaxVirtualAddress() { return GetMaxUserVirtualAddress(); } + +void SignalContext::DumpAllRegisters(void *context) { UNIMPLEMENTED(); } + +void DumpProcessMap() { + Printf("Process module map:\n"); + ListOfModules modules; + modules.init(); + for (uptr i = 0; i < modules.size(); ++i) { + for (const LoadedModule::AddressRange &r : modules[i].ranges()) { + Printf("\t%p-%p\tr%c%c\t%s\n", r.beg, r.end, r.writable ? 'w' : '-', + r.executable ? 'x' : '-', modules[i].full_name()); + } + } + Printf("End of module map.\n"); +} + +void CheckNoDeepBind(const char *filename, int flag) { UNIMPLEMENTED(); } + +bool GetRandom(void *buffer, uptr length, bool blocking) { UNIMPLEMENTED(); } + +u32 GetNumberOfCPUs() { UNIMPLEMENTED(); } + +void InitializePlatformCommonFlags(CommonFlags *cf) {} + +} // namespace __sanitizer + +#endif // SANITIZER_VXWORKS