diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt index f319113e5c16..9f8e8334d75b 100644 --- a/compiler-rt/CMakeLists.txt +++ b/compiler-rt/CMakeLists.txt @@ -569,6 +569,10 @@ append_list_if(COMPILER_RT_HAS_LIBC c SANITIZER_COMMON_LINK_LIBS) if("${CMAKE_SYSTEM_NAME}" STREQUAL "Fuchsia") list(APPEND SANITIZER_COMMON_LINK_LIBS zircon) endif() +if("${CMAKE_SYSTEM_NAME}" STREQUAL "Haiku") + list(APPEND SANITIZER_COMMON_LINK_LIBS root) + list(APPEND SANITIZER_COMMON_LINK_LIBS bsd) +endif() if("${CMAKE_SYSTEM_NAME}" STREQUAL "Fuchsia") set(SANITIZER_NO_UNDEFINED_SYMBOLS_DEFAULT ON) diff --git a/compiler-rt/cmake/config-ix.cmake b/compiler-rt/cmake/config-ix.cmake index cf729c3adb1f..e3310b1ff0e2 100644 --- a/compiler-rt/cmake/config-ix.cmake +++ b/compiler-rt/cmake/config-ix.cmake @@ -760,7 +760,7 @@ set(COMPILER_RT_SANITIZERS_TO_BUILD all CACHE STRING 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|Haiku" 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) @@ -875,7 +875,7 @@ else() endif() if (COMPILER_RT_HAS_SANITIZER_COMMON AND UBSAN_SUPPORTED_ARCH AND - OS_NAME MATCHES "Darwin|Linux|FreeBSD|NetBSD|Windows|Android|Fuchsia|SunOS") + OS_NAME MATCHES "Darwin|Linux|FreeBSD|NetBSD|Windows|Android|Fuchsia|SunOS|Haiku") set(COMPILER_RT_HAS_UBSAN TRUE) else() set(COMPILER_RT_HAS_UBSAN FALSE) diff --git a/compiler-rt/lib/asan/asan_linux.cpp b/compiler-rt/lib/asan/asan_linux.cpp index 3b40f76836ef..b5b4d88d1c3c 100644 --- a/compiler-rt/lib/asan/asan_linux.cpp +++ b/compiler-rt/lib/asan/asan_linux.cpp @@ -13,7 +13,11 @@ #include "sanitizer_common/sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS + SANITIZER_SOLARIS || SANITIZER_HAIKU + +# if SANITIZER_HAIKU +# define _DEFAULT_SOURCE +# endif # include # include @@ -22,7 +26,9 @@ # include # include # include -# include +# if !SANITIZER_HAIKU +# include +# endif # include # include # include @@ -37,7 +43,7 @@ # include "sanitizer_common/sanitizer_libc.h" # include "sanitizer_common/sanitizer_procmaps.h" -# if SANITIZER_FREEBSD +# if SANITIZER_FREEBSD || SANITIZER_HAIKU # include # endif @@ -54,6 +60,8 @@ # elif SANITIZER_NETBSD # include # include +# elif SANITIZER_HAIKU +extern "C" void *_DYNAMIC; # else # include # include @@ -162,6 +170,12 @@ static int FindFirstDSOCallback(struct dl_phdr_info *info, size_t size, return 0; } +# if SANITIZER_HAIKU + if (!info->dlpi_name[0] || + internal_strncmp(info->dlpi_name, "/boot/system/runtime_loader", + sizeof("/boot/system/runtime_loader") - 1) == 0) + return 0; +# endif # if SANITIZER_LINUX // Ignore vDSO. glibc versions earlier than 2.15 (and some patched // by distributors) return an empty name for the vDSO entry, so diff --git a/compiler-rt/lib/asan/asan_malloc_linux.cpp b/compiler-rt/lib/asan/asan_malloc_linux.cpp index 3d6b03fefab7..cbcdd9c1be29 100644 --- a/compiler-rt/lib/asan/asan_malloc_linux.cpp +++ b/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_HAIKU # include "asan_allocator.h" # include "asan_interceptors.h" diff --git a/compiler-rt/lib/asan/asan_posix.cpp b/compiler-rt/lib/asan/asan_posix.cpp index 070ba89048f9..fb66c871ea8a 100644 --- a/compiler-rt/lib/asan/asan_posix.cpp +++ b/compiler-rt/lib/asan/asan_posix.cpp @@ -180,7 +180,7 @@ static void AfterFork(bool fork_child) { void InstallAtForkHandler() { # if SANITIZER_SOLARIS || SANITIZER_NETBSD || SANITIZER_APPLE || \ - (SANITIZER_LINUX && SANITIZER_SPARC) + (SANITIZER_LINUX && SANITIZER_SPARC) || SANITIZER_HAIKU // While other Linux targets use clone in internal_fork which doesn't // trigger pthread_atfork handlers, Linux/sparc64 uses __fork, causing a // hang. diff --git a/compiler-rt/lib/asan/tests/CMakeLists.txt b/compiler-rt/lib/asan/tests/CMakeLists.txt index 00dcbf6534e2..9cd9c97bed81 100644 --- a/compiler-rt/lib/asan/tests/CMakeLists.txt +++ b/compiler-rt/lib/asan/tests/CMakeLists.txt @@ -109,6 +109,7 @@ if(NOT APPLE) append_list_if(COMPILER_RT_HAS_LIBM -lm ASAN_UNITTEST_NOINST_LINK_FLAGS) append_list_if(COMPILER_RT_HAS_LIBDL -ldl ASAN_UNITTEST_NOINST_LINK_FLAGS) append_list_if(COMPILER_RT_HAS_LIBRT -lrt ASAN_UNITTEST_NOINST_LINK_FLAGS) + append_list_if(HAIKU -lbsd ASAN_UNITTEST_NOINST_LINK_FLAGS) append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_UNITTEST_NOINST_LINK_FLAGS) append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread ASAN_DYNAMIC_UNITTEST_INSTRUMENTED_LINK_FLAGS) endif() diff --git a/compiler-rt/lib/asan/tests/asan_test.cpp b/compiler-rt/lib/asan/tests/asan_test.cpp index 0d98b1498a82..2d054ee859ed 100644 --- a/compiler-rt/lib/asan/tests/asan_test.cpp +++ b/compiler-rt/lib/asan/tests/asan_test.cpp @@ -1163,7 +1163,7 @@ TEST(AddressSanitizer, DISABLED_StressStackReuseAndExceptionsTest) { } #endif -#if !defined(_WIN32) +#if !defined(_WIN32) && !defined(__HAIKU__) TEST(AddressSanitizer, MlockTest) { EXPECT_EQ(0, mlockall(MCL_CURRENT)); EXPECT_EQ(0, mlock((void *)0x12345, 0x5678)); diff --git a/compiler-rt/lib/interception/interception.h b/compiler-rt/lib/interception/interception.h index 3cb6b446638e..25480120e7ad 100644 --- a/compiler-rt/lib/interception/interception.h +++ b/compiler-rt/lib/interception/interception.h @@ -19,7 +19,7 @@ #if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_APPLE && \ !SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA && \ - !SANITIZER_SOLARIS + !SANITIZER_SOLARIS && !SANITIZER_HAIKU # error "Interception doesn't work on this operating system." #endif @@ -368,7 +368,7 @@ inline void DoesNotSupportStaticLinking() {} #define INCLUDED_FROM_INTERCEPTION_LIB #if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS + SANITIZER_SOLARIS || SANITIZER_HAIKU # include "interception_linux.h" # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) diff --git a/compiler-rt/lib/interception/interception_linux.cpp b/compiler-rt/lib/interception/interception_linux.cpp index ef8136eb4fc7..0a6659d38ae8 100644 --- a/compiler-rt/lib/interception/interception_linux.cpp +++ b/compiler-rt/lib/interception/interception_linux.cpp @@ -14,7 +14,7 @@ #include "interception.h" #if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS + SANITIZER_SOLARIS || SANITIZER_HAIKU #include // for dlsym() and dlvsym() diff --git a/compiler-rt/lib/interception/interception_linux.h b/compiler-rt/lib/interception/interception_linux.h index 2e01ff44578c..52e34d535030 100644 --- a/compiler-rt/lib/interception/interception_linux.h +++ b/compiler-rt/lib/interception/interception_linux.h @@ -12,7 +12,7 @@ //===----------------------------------------------------------------------===// #if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS + SANITIZER_SOLARIS || SANITIZER_HAIKU #if !defined(INCLUDED_FROM_INTERCEPTION_LIB) # error interception_linux.h should be included from interception library only diff --git a/compiler-rt/lib/sanitizer_common/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/CMakeLists.txt index 09391e4f5f37..6e6dfd2f33eb 100644 --- a/compiler-rt/lib/sanitizer_common/CMakeLists.txt +++ b/compiler-rt/lib/sanitizer_common/CMakeLists.txt @@ -11,6 +11,7 @@ set(SANITIZER_SOURCES_NOTERMINATION sanitizer_flags.cpp sanitizer_flag_parser.cpp sanitizer_fuchsia.cpp + sanitizer_haiku.cpp sanitizer_libc.cpp sanitizer_libignore.cpp sanitizer_linux.cpp @@ -28,6 +29,7 @@ set(SANITIZER_SOURCES_NOTERMINATION sanitizer_procmaps_common.cpp sanitizer_procmaps_bsd.cpp sanitizer_procmaps_fuchsia.cpp + sanitizer_procmaps_haiku.cpp sanitizer_procmaps_linux.cpp sanitizer_procmaps_mac.cpp sanitizer_procmaps_solaris.cpp @@ -227,6 +229,9 @@ set(SANITIZER_COMMON_DEFINITIONS # note: L not I, this is nodefaultlibs for msvc append_list_if(MSVC /Zl SANITIZER_COMMON_CFLAGS) +if(HAIKU) + list(APPEND SANITIZER_COMMON_CFLAGS -I/system/develop/headers/private -I/system/develop/headers/private/system/arch/x86_64 -I/system/develop/headers/private/system) +endif() set(SANITIZER_CFLAGS ${SANITIZER_COMMON_CFLAGS}) # Too many existing bugs, needs cleanup. diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc index 49ec4097c900..f88f914b1d14 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc +++ b/compiler-rt/lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc @@ -48,35 +48,39 @@ static void ioctl_table_fill() { ++ioctl_table_size; \ } + _(FIONBIO, READ, sizeof(int)); +#if !SANITIZER_HAIKU _(FIOASYNC, READ, sizeof(int)); _(FIOCLEX, NONE, 0); _(FIOGETOWN, WRITE, sizeof(int)); - _(FIONBIO, READ, sizeof(int)); _(FIONCLEX, NONE, 0); _(FIOSETOWN, READ, sizeof(int)); +#endif _(SIOCATMARK, WRITE, sizeof(int)); _(SIOCGIFCONF, CUSTOM, 0); _(SIOCGPGRP, WRITE, sizeof(int)); _(SIOCSPGRP, READ, sizeof(int)); -#if !SANITIZER_SOLARIS +#if !SANITIZER_SOLARIS && !SANITIZER_HAIKU _(TIOCCONS, NONE, 0); #endif - _(TIOCEXCL, NONE, 0); +#if !SANITIZER_HAIKU _(TIOCGETD, WRITE, sizeof(int)); + _(TIOCNOTTY, NONE, 0); + _(TIOCPKT, READ, sizeof(int)); + _(TIOCSETD, READ, sizeof(int)); + _(TIOCSTI, READ, sizeof(char)); +#endif + _(TIOCEXCL, NONE, 0); _(TIOCGPGRP, WRITE, pid_t_sz); _(TIOCGWINSZ, WRITE, struct_winsize_sz); _(TIOCMBIC, READ, sizeof(int)); _(TIOCMBIS, READ, sizeof(int)); _(TIOCMGET, WRITE, sizeof(int)); _(TIOCMSET, READ, sizeof(int)); - _(TIOCNOTTY, NONE, 0); _(TIOCNXCL, NONE, 0); _(TIOCOUTQ, WRITE, sizeof(int)); - _(TIOCPKT, READ, sizeof(int)); _(TIOCSCTTY, NONE, 0); - _(TIOCSETD, READ, sizeof(int)); _(TIOCSPGRP, READ, pid_t_sz); - _(TIOCSTI, READ, sizeof(char)); _(TIOCSWINSZ, READ, struct_winsize_sz); #if !SANITIZER_IOS diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_errno.h b/compiler-rt/lib/sanitizer_common/sanitizer_errno.h index 46c85364cef5..76919da57d94 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_errno.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_errno.h @@ -29,6 +29,8 @@ # define __errno_location ___errno #elif SANITIZER_WINDOWS # define __errno_location _errno +#elif SANITIZER_HAIKU +# define __errno_location _errnop #endif extern "C" int *__errno_location(); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_errno_codes.h b/compiler-rt/lib/sanitizer_common/sanitizer_errno_codes.h index 9e6e71ec80c1..10a98a9b4e4d 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_errno_codes.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_errno_codes.h @@ -21,12 +21,21 @@ namespace __sanitizer { -#define errno_ENOMEM 12 -#define errno_EBUSY 16 -#define errno_EINVAL 22 -#define errno_ERANGE 34 -#define errno_ENAMETOOLONG 36 -#define errno_ENOSYS 38 +#ifdef __HAIKU__ +# define errno_ENOMEM (0x80000000) +# define errno_EBUSY (0x80000000 + 14) +# define errno_EINVAL (0x80000000 + 5) +# define errno_ERANGE (0x80007000 + 17) +# define errno_ENAMETOOLONG (0x80000000 + 0x6004) +# define errno_ENOSYS (0x80007009) +#else +# define errno_ENOMEM 12 +# define errno_EBUSY 16 +# define errno_EINVAL 22 +# define errno_ERANGE 34 +# define errno_ENAMETOOLONG 36 +# define errno_ENOSYS 38 +#endif // Those might not present or their value differ on different platforms. extern const int errno_EOWNERDEAD; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_haiku.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_haiku.cpp new file mode 100644 index 000000000000..7cf2437d5b75 --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_haiku.cpp @@ -0,0 +1,361 @@ +//===-- sanitizer_haiku.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 Sanitizer run-time libraries and implements +// Haiku-specific functions from sanitizer_libc.h. +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" + +#if SANITIZER_HAIKU + +# 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 "system/vm_defs.h" +# include "system/syscalls.h" +# include "shared/syscall_utils.h" + +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, + u64 offset) { + if ((flags & MAP_ANONYMOUS) != 0) + fd = -1; + + int mapping = + (flags & MAP_SHARED) != 0 ? REGION_NO_PRIVATE_MAP : REGION_PRIVATE_MAP; + + uint32 addressSpec; + if ((flags & MAP_FIXED) != 0) + addressSpec = B_EXACT_ADDRESS; + else if (addr != NULL) + addressSpec = B_BASE_ADDRESS; + else + addressSpec = B_RANDOMIZED_ANY_ADDRESS; + + uint32 areaProtection = 0; + if ((prot & PROT_READ) != 0) + areaProtection |= B_READ_AREA; + if ((prot & PROT_WRITE) != 0) + areaProtection |= B_WRITE_AREA; + if ((prot & PROT_EXEC) != 0) + areaProtection |= B_EXECUTE_AREA; + + if ((flags & MAP_NORESERVE) != 0) + areaProtection |= B_OVERCOMMITTING_AREA; + + area_id area = _kern_map_file("sanitizer mmap", &addr, addressSpec, length, + areaProtection, mapping, true, fd, offset); + if (area < 0) + RETURN_AND_SET_ERRNO(area); + return (uptr)addr; +} + +uptr internal_munmap(void *addr, uptr length) { + DEFINE__REAL(int, munmap, void *a, uptr b); + return _REAL(munmap, addr, length); +} + +uptr internal_mremap(void *old_address, uptr old_size, uptr new_size, int flags, + void *new_address) { + CHECK(false && "internal_mremap is unimplemented on Haiku"); + return 0; +} + +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) { + DEFINE__REAL(int, madvise, void *a, uptr b, int c); + return _REAL(madvise, (void *)addr, length, advice); +} + +uptr internal_close(fd_t fd) { + CHECK(&_kern_close); + RETURN_AND_SET_ERRNO(_kern_close(fd)); +} + +uptr internal_open(const char *filename, int flags) { + CHECK(&_kern_open); + RETURN_AND_SET_ERRNO(_kern_open(-1, filename, flags, 0)); +} + +uptr internal_open(const char *filename, int flags, u32 mode) { + CHECK(&_kern_open); + RETURN_AND_SET_ERRNO(_kern_open(-1, filename, flags, mode)); +} + +uptr internal_read(fd_t fd, void *buf, uptr count) { + sptr res; + CHECK(&_kern_read); + HANDLE_EINTR(res, (sptr)_kern_read(fd, -1, buf, (size_t)count)); + RETURN_AND_SET_ERRNO(res); + return res; +} + +uptr internal_write(fd_t fd, const void *buf, uptr count) { + sptr res; + CHECK(&_kern_write); + HANDLE_EINTR(res, (sptr)_kern_write(fd, -1, buf, count)); + RETURN_AND_SET_ERRNO(res); + return res; +} + +uptr internal_ftruncate(fd_t fd, uptr size) { + sptr res; + DEFINE__REAL(int, ftruncate, int, off_t); + return _REAL(ftruncate, fd, size); + return res; +} + +uptr internal_stat(const char *path, void *buf) { + DEFINE__REAL(int, _stat_current, const char *a, void *b); + return _REAL(_stat_current, path, buf); +} + +uptr internal_lstat(const char *path, void *buf) { + DEFINE__REAL(int, _lstat_current, const char *a, void *b); + return _REAL(_lstat_current, path, buf); +} + +uptr internal_fstat(fd_t fd, void *buf) { + DEFINE__REAL(int, _fstat_current, int a, void *b); + return _REAL(_fstat_current, 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) { + CHECK(&_kern_read_link); + RETURN_AND_SET_ERRNO(_kern_read_link(-1, 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(&_kern_thread_yield); + _kern_thread_yield(); + return 0; +} + +void internal__exit(int exitcode) { + DEFINE__REAL(void, _exit, int a); + _REAL(_exit, exitcode); + Die(); // Unreachable. +} + +void internal_usleep(u64 useconds) { + _kern_snooze_etc(useconds, B_SYSTEM_TIMEBASE, B_RELATIVE_TIMEOUT, NULL); +} + +uptr internal_execve(const char *filename, char *const argv[], + char *const envp[]) { + DEFINE__REAL(int, execve, const char *, char *const[], char *const[]); + return _REAL(execve, filename, argv, envp); +} + +# if 0 +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; +} +# endif + +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, int data) { + DEFINE__REAL(int, ptrace, int a, int b, void *c, int d); + return _REAL(ptrace, request, pid, addr, data); +} + +uptr internal_waitpid(int pid, int *status, int options) { + DEFINE__REAL(int, waitpid, pid_t, int *, int); + return _REAL(waitpid, pid, status, options); +} + +uptr internal_getpid() { + DEFINE__REAL(int, getpid); + return _REAL(getpid); +} + +uptr internal_getppid() { + DEFINE__REAL(int, getppid); + return _REAL(getppid); +} + +int internal_dlinfo(void *handle, int request, void *p) { + DEFINE__REAL(int, dlinfo, void *a, int b, void *c); + return _REAL(dlinfo, handle, request, p); +} + +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(&_kern_seek); + off_t result = _kern_seek(fd, offset, whence); + if (result < 0) { + errno = result; + return -1; + } + return result; +} + +uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5) { + Printf("internal_prctl not implemented for Haiku"); + 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() { + DEFINE__REAL(int, fork); + return _REAL(fork); +} + +# if 0 +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); +} +# endif + +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(&_kern_set_signal_mask); + return _kern_set_signal_mask(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); +} + +void internal_sigdelset(__sanitizer_sigset_t *set, int signo) { + DEFINE__REAL(int, __sigdelset14, const void *a, int b); + (void)_REAL(__sigdelset14, set, signo); +} + +uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, + void *arg) { + DEFINE__REAL(int, clone, int (*a)(void *b), void *c, int d, void *e); + + return _REAL(clone, fn, child_stack, flags, arg); +} + +} // namespace __sanitizer + +#endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp index 19d414b6b365..a06682c3bbe5 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp @@ -14,7 +14,7 @@ #include "sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS + SANITIZER_SOLARIS || SANITIZER_HAIKU # include "sanitizer_common.h" # include "sanitizer_flags.h" @@ -63,15 +63,17 @@ # include # include # include -# if !SANITIZER_SOLARIS +# if !SANITIZER_SOLARIS && !SANITIZER_HAIKU # include # endif # include # include -# include +# if !SANITIZER_HAIKU +# include +# include +# endif # include # include -# include # include # if SANITIZER_LINUX @@ -124,6 +126,13 @@ extern struct ps_strings *__ps_strings; # define environ _environ # endif +# if SANITIZER_HAIKU +# include +# include +# include +extern "C" char **__libc_argv; +# endif + extern char **environ; # if SANITIZER_LINUX @@ -252,7 +261,7 @@ ScopedBlockSignals::~ScopedBlockSignals() { SetSigProcMask(&saved_, nullptr); } # endif // --------------- sanitizer_libc.h -# if !SANITIZER_SOLARIS && !SANITIZER_NETBSD +# if !SANITIZER_SOLARIS && !SANITIZER_NETBSD && !SANITIZER_HAIKU # if !SANITIZER_S390 uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, u64 offset) { @@ -599,7 +608,7 @@ uptr internal_execve(const char *filename, char *const argv[], } # endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD -# if !SANITIZER_NETBSD +# if !SANITIZER_NETBSD && !SANITIZER_HAIKU void internal__exit(int exitcode) { # if SANITIZER_FREEBSD || SANITIZER_SOLARIS internal_syscall(SYSCALL(exit), exitcode); @@ -636,6 +645,8 @@ tid_t GetTid() { return Tid; # elif SANITIZER_SOLARIS return thr_self(); +# elif SANITIZER_HAIKU + return find_thread(NULL); # else return internal_syscall(SYSCALL(gettid)); # endif @@ -651,6 +662,8 @@ int TgKill(pid_t pid, tid_t tid, int sig) { errno = thr_kill(tid, sig); // TgKill is expected to return -1 on error, not an errno. return errno != 0 ? -1 : 0; +# elif SANITIZER_HAIKU + return kill_thread(tid); # endif } # endif @@ -678,7 +691,8 @@ u64 NanoTime() { // '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 || SANITIZER_SOLARIS +# if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_SOLARIS || \ + SANITIZER_HAIKU if (::environ != 0) { uptr NameLen = internal_strlen(name); for (char **Env = ::environ; *Env != 0; Env++) { @@ -716,13 +730,14 @@ const char *GetEnv(const char *name) { # endif } -# if !SANITIZER_FREEBSD && !SANITIZER_NETBSD && !SANITIZER_GO +# if !SANITIZER_HAIKU && !SANITIZER_FREEBSD && !SANITIZER_NETBSD && \ + !SANITIZER_GO extern "C" { SANITIZER_WEAK_ATTRIBUTE extern void *__libc_stack_end; } # endif -# if !SANITIZER_FREEBSD && !SANITIZER_NETBSD +# if !SANITIZER_HAIKU && !SANITIZER_FREEBSD && !SANITIZER_NETBSD static void ReadNullSepFileToArray(const char *path, char ***arr, int arr_size) { char *buff; @@ -749,7 +764,10 @@ static void ReadNullSepFileToArray(const char *path, char ***arr, # endif static void GetArgsAndEnv(char ***argv, char ***envp) { -# if SANITIZER_FREEBSD +# if SANITIZER_HAIKU + *argv = __libc_argv; + *envp = environ; +# elif 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 . @@ -808,7 +826,7 @@ char **GetEnviron() { void FutexWait(atomic_uint32_t *p, u32 cmp) { # if SANITIZER_FREEBSD _umtx_op(p, UMTX_OP_WAIT_UINT, cmp, 0, 0); -# elif SANITIZER_NETBSD +# elif SANITIZER_NETBSD || SANITIZER_HAIKU sched_yield(); /* No userspace futex-like synchronization */ # else internal_syscall(SYSCALL(futex), (uptr)p, FUTEX_WAIT_PRIVATE, cmp, 0, 0, 0); @@ -818,7 +836,7 @@ void FutexWait(atomic_uint32_t *p, u32 cmp) { void FutexWake(atomic_uint32_t *p, u32 count) { # if SANITIZER_FREEBSD _umtx_op(p, UMTX_OP_WAKE, count, 0, 0); -# elif SANITIZER_NETBSD +# elif SANITIZER_NETBSD || SANITIZER_HAIKU /* No userspace futex-like synchronization */ # else internal_syscall(SYSCALL(futex), (uptr)p, FUTEX_WAKE_PRIVATE, count, 0, 0, 0); @@ -850,7 +868,7 @@ struct linux_dirent { }; # endif -# if !SANITIZER_SOLARIS && !SANITIZER_NETBSD +# if !SANITIZER_SOLARIS && !SANITIZER_NETBSD && !SANITIZER_HAIKU // Syscall wrappers. uptr internal_ptrace(int request, int pid, void *addr, void *data) { return internal_syscall(SYSCALL(ptrace), request, pid, (uptr)addr, @@ -1064,7 +1082,7 @@ bool internal_sigismember(__sanitizer_sigset_t *set, int signum) { # endif # endif // !SANITIZER_SOLARIS -# if !SANITIZER_NETBSD +# if !SANITIZER_NETBSD && !SANITIZER_HAIKU // ThreadLister implementation. ThreadLister::ThreadLister(pid_t pid) : buffer_(4096) { task_path_.AppendF("/proc/%d/task", pid); @@ -1268,7 +1286,19 @@ uptr GetPageSize() { # endif uptr ReadBinaryName(/*out*/ char *buf, uptr buf_len) { -# if SANITIZER_SOLARIS +# if SANITIZER_HAIKU + int cookie = 0; + image_info info; + const char *argv0 = ""; + while (get_next_image_info(B_CURRENT_TEAM, &cookie, &info) == B_OK) { + if (info.type != B_APP_IMAGE) + continue; + argv0 = info.name; + break; + } + internal_strncpy(buf, argv0, buf_len); + return internal_strlen(buf); +# elif SANITIZER_SOLARIS const char *default_module_name = getexecname(); CHECK_NE(default_module_name, NULL); return internal_snprintf(buf, buf_len, "%s", default_module_name); @@ -1334,11 +1364,11 @@ bool LibraryNameIs(const char *full_name, const char *base_name) { return (name[base_name_length] == '-' || name[base_name_length] == '.'); } -# if !SANITIZER_ANDROID +# if !SANITIZER_ANDROID && !SANITIZER_HAIKU // 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_HAIKU typedef ElfW(Phdr) Elf_Phdr; typedef ElfW(Ehdr) Elf_Ehdr; # endif // !SANITIZER_FREEBSD @@ -1997,11 +2027,15 @@ using Context = ucontext_t; SignalContext::WriteFlag SignalContext::GetWriteFlag() const { Context *ucontext = (Context *)context; # if defined(__x86_64__) || defined(__i386__) +# if !SANITIZER_HAIKU static const uptr PF_WRITE = 1U << 1; +# endif # if SANITIZER_FREEBSD uptr err = ucontext->uc_mcontext.mc_err; # elif SANITIZER_NETBSD uptr err = ucontext->uc_mcontext.__gregs[_REG_ERR]; +# elif SANITIZER_HAIKU + uptr err = ucontext->uc_mcontext.r13; # elif SANITIZER_SOLARIS && defined(__i386__) const int Err = 13; uptr err = ucontext->uc_mcontext.gregs[Err]; @@ -2614,6 +2648,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_HAIKU + ucontext_t *ucontext = (ucontext_t *)context; + *pc = ucontext->uc_mcontext.rip; + *bp = ucontext->uc_mcontext.rbp; + *sp = ucontext->uc_mcontext.rsp; # else ucontext_t *ucontext = (ucontext_t *)context; *pc = ucontext->uc_mcontext.gregs[REG_RIP]; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h index 8b7874bb5a34..c1562506babf 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux.h @@ -14,7 +14,7 @@ #include "sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS + SANITIZER_SOLARIS || SANITIZER_HAIKU # include "sanitizer_common.h" # include "sanitizer_internal_defs.h" # include "sanitizer_platform_limits_freebsd.h" @@ -31,6 +31,11 @@ namespace __sanitizer { // the one in , which is used by readdir(). struct linux_dirent; +# if SANITIZER_HAIKU +struct MemoryMappingLayoutData { + long signed int cookie; +}; +# else struct ProcSelfMapsBuff { char *data; uptr mmaped_size; @@ -43,6 +48,7 @@ struct MemoryMappingLayoutData { }; void ReadProcMaps(ProcSelfMapsBuff *proc_maps); +# endif // Syscall wrappers. uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp index 16eb8dec63e9..c2e2e290b0ec 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp @@ -14,7 +14,7 @@ #include "sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS + SANITIZER_SOLARIS || SANITIZER_HAIKU # include "sanitizer_allocator_internal.h" # include "sanitizer_atomic.h" @@ -28,6 +28,10 @@ # include "sanitizer_procmaps.h" # include "sanitizer_solaris.h" +# if SANITIZER_HAIKU +# define _DEFAULT_SOURCE +# endif + # if SANITIZER_NETBSD # // for __lwp_gettcb_fast() / __lwp_getprivate_fast() # include @@ -80,6 +84,11 @@ extern "C" int __sys_sigaction(int signum, const struct sigaction *act, # include # endif +# if SANITIZER_HAIKU +# include +# include +# endif + # if !SANITIZER_ANDROID # include # include @@ -643,6 +652,7 @@ static void GetTls(uptr *addr, uptr *size) { *addr = (uptr)tcb->tcb_dtv[1]; } } +# elif SANITIZER_HAIKU # else # error "Unknown OS" # endif @@ -713,8 +723,13 @@ static int AddModuleSegments(const char *module_name, dl_phdr_info *info, if (phdr->p_type == PT_LOAD) { uptr cur_beg = info->dlpi_addr + phdr->p_vaddr; uptr cur_end = cur_beg + phdr->p_memsz; +# if SANITIZER_HAIKU + bool executable = phdr->p_flags & PF_EXECUTE; + bool writable = phdr->p_flags & PF_WRITE; +# else bool executable = phdr->p_flags & PF_X; bool writable = phdr->p_flags & PF_W; +# endif cur_module.addAddressRange(cur_beg, cur_end, executable, writable); } else if (phdr->p_type == PT_NOTE) { # ifdef NT_GNU_BUILD_ID @@ -854,6 +869,10 @@ u32 GetNumberOfCPUs() { # endif CHECK_EQ(internal_sysctl(req, 2, &ncpu, &len, NULL, 0), 0); return ncpu; +# elif SANITIZER_HAIKU + system_info info; + get_system_info(&info); + return info.cpu_count; # elif SANITIZER_SOLARIS return sysconf(_SC_NPROCESSORS_ONLN); # else diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform.h index 57966403c92a..9f5f41cd8551 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform.h +++ b/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(__HAIKU__) # error "This operating system is not supported" #endif @@ -55,6 +55,12 @@ # define SANITIZER_SOLARIS 0 #endif +#if defined(__HAIKU__) +# define SANITIZER_HAIKU 1 +#else +# define SANITIZER_HAIKU 0 +#endif + // - SANITIZER_APPLE: all Apple code // - TARGET_OS_OSX: macOS // - SANITIZER_IOS: devices (iOS and iOS-like) @@ -136,9 +142,9 @@ # define SANITIZER_MUSL 0 #endif -#define SANITIZER_POSIX \ +#define SANITIZER_POSIX \ (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_APPLE || \ - SANITIZER_NETBSD || SANITIZER_SOLARIS) + SANITIZER_NETBSD || SANITIZER_SOLARIS || SANITIZER_HAIKU) #if __LP64__ || defined(_WIN64) # define SANITIZER_WORDSIZE 64 @@ -410,7 +416,8 @@ # define SANITIZER_SUPPRESS_LEAK_ON_PTHREAD_EXIT 0 #endif -#if SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_NETBSD || SANITIZER_SOLARIS +#if SANITIZER_FREEBSD || SANITIZER_APPLE || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS || SANITIZER_HAIKU # define SANITIZER_MADVISE_DONTNEED MADV_FREE #else # define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp index ec5f2edab6a6..edb619f4ddaf 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.cpp @@ -24,7 +24,7 @@ // Must go after undef _FILE_OFFSET_BITS. #include "sanitizer_platform.h" -#if SANITIZER_LINUX || SANITIZER_APPLE +#if SANITIZER_LINUX || SANITIZER_APPLE || SANITIZER_HAIKU // Must go after undef _FILE_OFFSET_BITS. #include "sanitizer_glibc_version.h" @@ -52,7 +52,7 @@ #include #include #include -#if !SANITIZER_APPLE +#if !SANITIZER_APPLE && !SANITIZER_HAIKU #include #endif @@ -61,7 +61,9 @@ #endif #if !SANITIZER_ANDROID +#if !SANITIZER_HAIKU #include +#endif #include #include #endif @@ -111,9 +113,11 @@ typedef struct user_fpregs elf_fpregset_t; #if !SANITIZER_ANDROID #include +#if !SANITIZER_HAIKU #include #include #endif +#endif #if SANITIZER_LINUX #if SANITIZER_GLIBC @@ -163,7 +167,7 @@ typedef struct user_fpregs elf_fpregset_t; #include #include #include -#else +#elif !SANITIZER_HAIKU #include #endif // SANITIZER_LINUX @@ -173,6 +177,11 @@ typedef struct user_fpregs elf_fpregset_t; #include #endif +#if SANITIZER_HAIKU +#include +#include +#endif + // Include these after system headers to avoid name clashes and ambiguities. # include "sanitizer_common.h" # include "sanitizer_internal_defs.h" @@ -217,7 +226,7 @@ namespace __sanitizer { unsigned struct_fstab_sz = sizeof(struct fstab); #endif // SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD || // SANITIZER_APPLE -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_HAIKU unsigned struct_statfs_sz = sizeof(struct statfs); unsigned struct_sockaddr_sz = sizeof(struct sockaddr); @@ -324,7 +333,7 @@ namespace __sanitizer { int shmctl_shm_stat = (int)SHM_STAT; #endif -#if !SANITIZER_APPLE && !SANITIZER_FREEBSD +#if !SANITIZER_APPLE && !SANITIZER_FREEBSD && !SANITIZER_HAIKU unsigned struct_utmp_sz = sizeof(struct utmp); #endif #if !SANITIZER_ANDROID @@ -356,7 +365,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); int glob_altdirfunc = GLOB_ALTDIRFUNC; #endif -# if !SANITIZER_ANDROID +# if !SANITIZER_ANDROID && !SANITIZER_HAIKU const int wordexp_wrde_dooffs = WRDE_DOOFFS; # endif // !SANITIZER_ANDROID @@ -540,7 +549,7 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned struct_sock_fprog_sz = sizeof(struct sock_fprog); # endif // SANITIZER_GLIBC -# if !SANITIZER_ANDROID && !SANITIZER_APPLE +# if !SANITIZER_ANDROID && !SANITIZER_APPLE && !SANITIZER_HAIKU unsigned struct_sioc_sg_req_sz = sizeof(struct sioc_sg_req); unsigned struct_sioc_vif_req_sz = sizeof(struct sioc_vif_req); #endif @@ -551,12 +560,14 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); const unsigned IOCTL_NOT_PRESENT = 0; + unsigned IOCTL_FIONBIO = FIONBIO; +#if !SANITIZER_HAIKU unsigned IOCTL_FIOASYNC = FIOASYNC; unsigned IOCTL_FIOCLEX = FIOCLEX; unsigned IOCTL_FIOGETOWN = FIOGETOWN; - unsigned IOCTL_FIONBIO = FIONBIO; unsigned IOCTL_FIONCLEX = FIONCLEX; unsigned IOCTL_FIOSETOWN = FIOSETOWN; +#endif unsigned IOCTL_SIOCADDMULTI = SIOCADDMULTI; unsigned IOCTL_SIOCATMARK = SIOCATMARK; unsigned IOCTL_SIOCDELMULTI = SIOCDELMULTI; @@ -577,23 +588,27 @@ unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); unsigned IOCTL_SIOCSIFMTU = SIOCSIFMTU; unsigned IOCTL_SIOCSIFNETMASK = SIOCSIFNETMASK; unsigned IOCTL_SIOCSPGRP = SIOCSPGRP; + +#if !SANITIZER_HAIKU unsigned IOCTL_TIOCCONS = TIOCCONS; - unsigned IOCTL_TIOCEXCL = TIOCEXCL; unsigned IOCTL_TIOCGETD = TIOCGETD; + unsigned IOCTL_TIOCNOTTY = TIOCNOTTY; + unsigned IOCTL_TIOCPKT = TIOCPKT; + unsigned IOCTL_TIOCSETD = TIOCSETD; + unsigned IOCTL_TIOCSTI = TIOCSTI; +#endif + + unsigned IOCTL_TIOCEXCL = TIOCEXCL; 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; #if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned IOCTL_SIOCGETSGCNT = SIOCGETSGCNT; @@ -1103,7 +1118,7 @@ COMPILER_CHECK(sizeof(__sanitizer_dirent) <= sizeof(dirent)); CHECK_SIZE_AND_OFFSET(dirent, d_ino); #if SANITIZER_APPLE CHECK_SIZE_AND_OFFSET(dirent, d_seekoff); -#elif SANITIZER_FREEBSD +#elif SANITIZER_FREEBSD || SANITIZER_HAIKU // There is no 'd_off' field on FreeBSD. #else CHECK_SIZE_AND_OFFSET(dirent, d_off); @@ -1119,7 +1134,9 @@ CHECK_SIZE_AND_OFFSET(dirent64, d_reclen); CHECK_TYPE_SIZE(ifconf); CHECK_SIZE_AND_OFFSET(ifconf, ifc_len); +#if !SANITIZER_HAIKU CHECK_SIZE_AND_OFFSET(ifconf, ifc_ifcu); +#endif CHECK_TYPE_SIZE(pollfd); CHECK_SIZE_AND_OFFSET(pollfd, fd); @@ -1174,7 +1191,7 @@ CHECK_TYPE_SIZE(__kernel_loff_t); CHECK_TYPE_SIZE(__kernel_fd_set); #endif -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_HAIKU CHECK_TYPE_SIZE(wordexp_t); CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordc); CHECK_SIZE_AND_OFFSET(wordexp_t, we_wordv); @@ -1204,7 +1221,9 @@ CHECK_SIZE_AND_OFFSET(mntent, mnt_freq); CHECK_SIZE_AND_OFFSET(mntent, mnt_passno); #endif +#if !SANITIZER_HAIKU CHECK_TYPE_SIZE(ether_addr); +#endif #if SANITIZER_GLIBC || SANITIZER_FREEBSD CHECK_TYPE_SIZE(ipc_perm); @@ -1242,7 +1261,7 @@ CHECK_TYPE_SIZE(clock_t); CHECK_TYPE_SIZE(clockid_t); #endif -#if !SANITIZER_ANDROID +#if !SANITIZER_ANDROID && !SANITIZER_HAIKU CHECK_TYPE_SIZE(ifaddrs); CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_next); CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name); diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h index 1f7e3d21b6a6..26de940f931b 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -14,7 +14,7 @@ #ifndef SANITIZER_PLATFORM_LIMITS_POSIX_H #define SANITIZER_PLATFORM_LIMITS_POSIX_H -#if SANITIZER_LINUX || SANITIZER_APPLE +#if SANITIZER_LINUX || SANITIZER_APPLE || SANITIZER_HAIKU #include "sanitizer_internal_defs.h" #include "sanitizer_platform.h" @@ -366,7 +366,7 @@ struct __sanitizer_passwd { long pw_change; char *pw_class; #endif -#if !(SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 32)) +#if !(SANITIZER_ANDROID && (SANITIZER_WORDSIZE == 32)) && !SANITIZER_HAIKU char *pw_gecos; #endif char *pw_dir; @@ -374,6 +374,9 @@ struct __sanitizer_passwd { #if SANITIZER_APPLE long pw_expire; #endif +#if SANITIZER_HAIKU + char *pw_gecos; +#endif }; struct __sanitizer_group { @@ -433,7 +436,11 @@ struct __sanitizer_tm { int tm_wday; int tm_yday; int tm_isdst; +#if SANITIZER_HAIKU + int tm_gmtoff; +#else long int tm_gmtoff; +#endif const char *tm_zone; }; @@ -454,7 +461,7 @@ struct __sanitizer_file_handle { }; #endif -#if SANITIZER_APPLE +#if SANITIZER_APPLE || SANITIZER_HAIKU struct __sanitizer_msghdr { void *msg_name; unsigned msg_namelen; @@ -502,6 +509,15 @@ struct __sanitizer_dirent { unsigned short d_reclen; // more fields that we don't care about }; +#elif SANITIZER_HAIKU +struct __sanitizer_dirent { + int d_dev; + int d_pdev; + unsigned long long d_ino; + unsigned long long d_pino; + unsigned short d_reclen; + // more fields that we don't care about +}; # elif (SANITIZER_LINUX && !SANITIZER_GLIBC) || defined(__x86_64__) || \ defined(__hexagon__) struct __sanitizer_dirent { @@ -529,13 +545,15 @@ struct __sanitizer_dirent64 { extern unsigned struct_sock_fprog_sz; #endif -#if defined(__x86_64__) && !defined(_LP64) +#if SANITIZER_HAIKU +typedef int __sanitizer_clock_t; +#elif defined(__x86_64__) && !defined(_LP64) typedef long long __sanitizer_clock_t; #else typedef long __sanitizer_clock_t; #endif -#if SANITIZER_LINUX +#if SANITIZER_LINUX || SANITIZER_HAIKU typedef int __sanitizer_clockid_t; typedef unsigned long long __sanitizer_eventfd_t; #endif @@ -584,6 +602,8 @@ typedef unsigned long __sanitizer_sigset_t; # endif #elif SANITIZER_APPLE typedef unsigned __sanitizer_sigset_t; +#elif SANITIZER_HAIKU +typedef unsigned long __sanitizer_sigset_t; #elif SANITIZER_LINUX struct __sanitizer_sigset_t { // The size is determined by looking at sizeof of real sigset_t on linux. @@ -692,7 +712,7 @@ struct __sanitizer_sigaction { # endif # endif # endif -# if SANITIZER_LINUX +# if SANITIZER_LINUX || SANITIZER_HAIKU void (*sa_restorer)(); # endif # if defined(__mips__) && (SANITIZER_WORDSIZE == 32) && !SANITIZER_MUSL @@ -779,7 +799,7 @@ struct __sanitizer_addrinfo { int ai_family; int ai_socktype; int ai_protocol; -#if SANITIZER_ANDROID || SANITIZER_APPLE +#if SANITIZER_ANDROID || SANITIZER_APPLE || SANITIZER_HAIKU unsigned ai_addrlen; char *ai_canonname; void *ai_addr; @@ -1128,23 +1148,25 @@ extern unsigned IOCTL_SIOCSIFMETRIC; extern unsigned IOCTL_SIOCSIFMTU; extern unsigned IOCTL_SIOCSIFNETMASK; extern unsigned IOCTL_SIOCSPGRP; +#if !SANITIZER_HAIKU extern unsigned IOCTL_TIOCCONS; -extern unsigned IOCTL_TIOCEXCL; extern unsigned IOCTL_TIOCGETD; +extern unsigned IOCTL_TIOCNOTTY; +extern unsigned IOCTL_TIOCPKT; +extern unsigned IOCTL_TIOCSETD; +extern unsigned IOCTL_TIOCSTI; +#endif +extern unsigned IOCTL_TIOCEXCL; extern unsigned IOCTL_TIOCGPGRP; extern unsigned IOCTL_TIOCGWINSZ; extern unsigned IOCTL_TIOCMBIC; extern unsigned IOCTL_TIOCMBIS; extern unsigned IOCTL_TIOCMGET; extern unsigned IOCTL_TIOCMSET; -extern unsigned IOCTL_TIOCNOTTY; extern unsigned IOCTL_TIOCNXCL; extern unsigned IOCTL_TIOCOUTQ; -extern unsigned IOCTL_TIOCPKT; extern unsigned IOCTL_TIOCSCTTY; -extern unsigned IOCTL_TIOCSETD; extern unsigned IOCTL_TIOCSPGRP; -extern unsigned IOCTL_TIOCSTI; extern unsigned IOCTL_TIOCSWINSZ; #if SANITIZER_LINUX && !SANITIZER_ANDROID extern unsigned IOCTL_SIOCGETSGCNT; diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h index bf3c2c28e32e..d713ddf847df 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h +++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps.h @@ -16,7 +16,7 @@ #include "sanitizer_platform.h" #if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ - SANITIZER_APPLE || SANITIZER_SOLARIS || \ + SANITIZER_APPLE || SANITIZER_SOLARIS || SANITIZER_HAIKU || \ SANITIZER_FUCHSIA #include "sanitizer_common.h" diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_haiku.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_haiku.cpp new file mode 100644 index 000000000000..7a6062a571ba --- /dev/null +++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_haiku.cpp @@ -0,0 +1,94 @@ +//===-- sanitizer_procmaps_haiku.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 +// (Haiku-specific parts). +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" +#if SANITIZER_HAIKU +# include "sanitizer_common.h" +# include "sanitizer_procmaps.h" + +# include + +namespace __sanitizer { + +void MemoryMappedSegment::AddAddressRanges(LoadedModule *module) { + // data_ should be unused on this platform + CHECK(!data_); + module->addAddressRange(start, end, IsExecutable(), IsWritable()); +} + +MemoryMappingLayout::MemoryMappingLayout(bool) { Reset(); } + +void MemoryMappingLayout::Reset() { data_.cookie = 0; } + +MemoryMappingLayout::~MemoryMappingLayout() {} + +// static +void MemoryMappingLayout::CacheMemoryMappings() {} + +bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { + area_info info; + if (get_next_area_info(B_CURRENT_TEAM, &data_.cookie, &info) != B_OK) + return false; + + segment->start = (uptr)info.address; + segment->end = (uptr)info.address + info.size; + segment->offset = 0; + segment->protection = 0; + if (info.protection & B_READ_AREA) + segment->protection |= kProtectionRead; + if (info.protection & B_WRITE_AREA) + segment->protection |= kProtectionWrite; + if (info.protection & B_EXECUTE_AREA) + segment->protection |= kProtectionExecute; + if (segment->filename) { + uptr len = Min((uptr)B_OS_NAME_LENGTH, segment->filename_size - 1); + internal_strncpy(segment->filename, info.name, len); + segment->filename[len] = 0; + } + return true; +} + +bool MemoryMappingLayout::Error() const { return false; } + +void MemoryMappingLayout::DumpListOfModules( + InternalMmapVectorNoCtor *modules) { + Reset(); + InternalMmapVector module_name(kMaxPathLength); + MemoryMappedSegment segment(module_name.data(), module_name.size()); + for (uptr i = 0; Next(&segment); i++) { + const char *cur_name = segment.filename; + if (cur_name[0] == '\0') + continue; + // Don't subtract 'cur_beg' from the first entry: + // * If a binary is compiled w/o -pie, then the first entry in + // process maps is likely the binary itself (all dynamic libs + // are mapped higher in address space). For such a binary, + // instruction offset in binary coincides with the actual + // instruction address in virtual memory (as code section + // is mapped to a fixed memory range). + // * If a binary is compiled with -pie, all the modules are + // mapped high at address space (in particular, higher than + // shadow memory of the tool), so the module can't be the + // first entry. + uptr base_address = (i ? segment.start : 0) - segment.offset; + LoadedModule cur_module; + cur_module.set(cur_name, base_address); + segment.AddAddressRanges(&cur_module); + modules->push_back(cur_module); + } +} + +void GetMemoryProfile(fill_profile_f cb, uptr *stats) {} + +} // namespace __sanitizer + +#endif diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp index 6a8e82e2e213..3f6901a2e7f1 100644 --- a/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp +++ b/compiler-rt/lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cpp @@ -12,7 +12,7 @@ #include "sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ - SANITIZER_SOLARIS + SANITIZER_SOLARIS || SANITIZER_HAIKU #include "sanitizer_common.h" #include "sanitizer_stacktrace.h" @@ -171,4 +171,4 @@ void BufferedStackTrace::UnwindSlow(uptr pc, void *context, u32 max_depth) { } // namespace __sanitizer #endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || - // SANITIZER_SOLARIS + // SANITIZER_SOLARIS || SANITIZER_HAIKU diff --git a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt index fef8bb772e0e..55c7d665e639 100644 --- a/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt +++ b/compiler-rt/lib/sanitizer_common/tests/CMakeLists.txt @@ -134,6 +134,9 @@ append_list_if(COMPILER_RT_HAS_LIBPTHREAD -pthread SANITIZER_TEST_LINK_FLAGS_COM if(CMAKE_SYSTEM MATCHES "FreeBSD-9.2-RELEASE") list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON "-lc++ -lm") endif() +if(CMAKE_SYSTEM MATCHES "Haiku") + list(APPEND SANITIZER_TEST_LINK_FLAGS_COMMON "-lbsd") +endif() include_directories(..) include_directories(../..) diff --git a/compiler-rt/lib/ubsan/ubsan_platform.h b/compiler-rt/lib/ubsan/ubsan_platform.h index d2cc2e10bd2f..c7eb1a967e53 100644 --- a/compiler-rt/lib/ubsan/ubsan_platform.h +++ b/compiler-rt/lib/ubsan/ubsan_platform.h @@ -16,7 +16,7 @@ #if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \ defined(__NetBSD__) || defined(__DragonFly__) || \ (defined(__sun__) && defined(__svr4__)) || defined(_WIN32) || \ - defined(__Fuchsia__) + defined(__Fuchsia__) || defined(__HAIKU__) #define CAN_SANITIZE_UB 1 #else # define CAN_SANITIZE_UB 0 diff --git a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp index a4c6c61e5799..c1dba77c3532 100644 --- a/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp +++ b/llvm/lib/Transforms/Instrumentation/AddressSanitizer.cpp @@ -501,6 +501,7 @@ static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize, bool IsFuchsia = TargetTriple.isOSFuchsia(); bool IsEmscripten = TargetTriple.isOSEmscripten(); bool IsAMDGPU = TargetTriple.isAMDGPU(); + bool IsHaiku = TargetTriple.isOSHaiku(); ShadowMapping Mapping; @@ -574,6 +575,9 @@ static ShadowMapping getShadowMapping(const Triple &TargetTriple, int LongSize, else if (IsAMDGPU) Mapping.Offset = (kSmallX86_64ShadowOffsetBase & (kSmallX86_64ShadowOffsetAlignMask << Mapping.Scale)); + else if (IsHaiku && IsX86_64) + Mapping.Offset = (kSmallX86_64ShadowOffsetBase & + (kSmallX86_64ShadowOffsetAlignMask << Mapping.Scale)); else Mapping.Offset = kDefaultShadowOffset64; }