[compiler-rt][sanitizer] add Haiku support (#134772)

Co-authored-by: Jérôme Duval <jerome.duval@gmail.com>
This commit is contained in:
Brad Smith 2025-04-11 16:21:00 -04:00 committed by GitHub
parent 90a202f2ff
commit d1fd97737e
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
27 changed files with 693 additions and 80 deletions

View File

@ -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)

View File

@ -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)

View File

@ -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 <dlfcn.h>
# include <fcntl.h>
@ -22,7 +26,9 @@
# include <stdio.h>
# include <sys/mman.h>
# include <sys/resource.h>
# include <sys/syscall.h>
# if !SANITIZER_HAIKU
# include <sys/syscall.h>
# endif
# include <sys/time.h>
# include <sys/types.h>
# include <unistd.h>
@ -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 <sys/link_elf.h>
# endif
@ -54,6 +60,8 @@
# elif SANITIZER_NETBSD
# include <link_elf.h>
# include <ucontext.h>
# elif SANITIZER_HAIKU
extern "C" void *_DYNAMIC;
# else
# include <link.h>
# include <sys/ucontext.h>
@ -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

View File

@ -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"

View File

@ -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.

View File

@ -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()

View File

@ -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));

View File

@ -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)

View File

@ -14,7 +14,7 @@
#include "interception.h"
#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \
SANITIZER_SOLARIS
SANITIZER_SOLARIS || SANITIZER_HAIKU
#include <dlfcn.h> // for dlsym() and dlvsym()

View File

@ -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

View File

@ -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.

View File

@ -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

View File

@ -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();

View File

@ -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;

View File

@ -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 <sys/param.h>
# include <sys/types.h>
# include <sys/mman.h>
# include <sys/resource.h>
# include <sys/stat.h>
# include <sys/time.h>
# include <dlfcn.h>
# include <errno.h>
# include <fcntl.h>
# include <limits.h>
# include <link.h>
# include <pthread.h>
# include <sched.h>
# include <signal.h>
# include <unistd.h>
# 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

View File

@ -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 <sched.h>
# include <signal.h>
# include <sys/mman.h>
# if !SANITIZER_SOLARIS
# if !SANITIZER_SOLARIS && !SANITIZER_HAIKU
# include <sys/ptrace.h>
# endif
# include <sys/resource.h>
# include <sys/stat.h>
# include <sys/syscall.h>
# if !SANITIZER_HAIKU
# include <sys/syscall.h>
# include <ucontext.h>
# endif
# include <sys/time.h>
# include <sys/types.h>
# include <ucontext.h>
# include <unistd.h>
# if SANITIZER_LINUX
@ -124,6 +126,13 @@ extern struct ps_strings *__ps_strings;
# define environ _environ
# endif
# if SANITIZER_HAIKU
# include <OS.h>
# include <elf.h>
# include <image.h>
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 <sys/exec.h>.
@ -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 = "<UNKNOWN>";
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];

View File

@ -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 <dirent.h>, 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);

View File

@ -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 <sys/param.h>
@ -80,6 +84,11 @@ extern "C" int __sys_sigaction(int signum, const struct sigaction *act,
# include <thread.h>
# endif
# if SANITIZER_HAIKU
# include <kernel/OS.h>
# include <sys/link_elf.h>
# endif
# if !SANITIZER_ANDROID
# include <elf.h>
# include <unistd.h>
@ -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

View File

@ -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

View File

@ -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 <time.h>
#include <wchar.h>
#include <regex.h>
#if !SANITIZER_APPLE
#if !SANITIZER_APPLE && !SANITIZER_HAIKU
#include <utmp.h>
#endif
@ -61,7 +61,9 @@
#endif
#if !SANITIZER_ANDROID
#if !SANITIZER_HAIKU
#include <sys/mount.h>
#endif
#include <sys/timeb.h>
#include <utmpx.h>
#endif
@ -111,9 +113,11 @@ typedef struct user_fpregs elf_fpregset_t;
#if !SANITIZER_ANDROID
#include <ifaddrs.h>
#if !SANITIZER_HAIKU
#include <sys/ucontext.h>
#include <wordexp.h>
#endif
#endif
#if SANITIZER_LINUX
#if SANITIZER_GLIBC
@ -163,7 +167,7 @@ typedef struct user_fpregs elf_fpregset_t;
#include <sys/vfs.h>
#include <sys/epoll.h>
#include <linux/capability.h>
#else
#elif !SANITIZER_HAIKU
#include <fstab.h>
#endif // SANITIZER_LINUX
@ -173,6 +177,11 @@ typedef struct user_fpregs elf_fpregset_t;
#include <sys/sockio.h>
#endif
#if SANITIZER_HAIKU
#include <sys/sockio.h>
#include <sys/ioctl.h>
#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);

View File

@ -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;

View File

@ -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"

View File

@ -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 <kernel/OS.h>
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<LoadedModule> *modules) {
Reset();
InternalMmapVector<char> 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

View File

@ -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

View File

@ -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(../..)

View File

@ -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

View File

@ -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;
}