[compiler-rt] [llvm] [compiler-rt][sanitizer] add Haiku support (PR #134772)
Brad Smith via llvm-commits
llvm-commits at lists.llvm.org
Mon Apr 7 19:58:39 PDT 2025
https://github.com/brad0 created https://github.com/llvm/llvm-project/pull/134772
None
>From a9431ad89f86ee926bb3b8360a7c0f5e872f84b5 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?J=C3=A9r=C3=B4me=20Duval?= <jerome.duval at gmail.com>
Date: Fri, 21 Mar 2025 03:05:58 -0400
Subject: [PATCH] [compiler-rt][sanitizer] add Haiku support
---
compiler-rt/CMakeLists.txt | 4 +
compiler-rt/cmake/config-ix.cmake | 4 +-
compiler-rt/lib/asan/asan_linux.cpp | 18 +-
compiler-rt/lib/asan/asan_malloc_linux.cpp | 2 +-
compiler-rt/lib/asan/asan_posix.cpp | 2 +-
compiler-rt/lib/asan/tests/CMakeLists.txt | 1 +
compiler-rt/lib/asan/tests/asan_test.cpp | 2 +-
compiler-rt/lib/interception/interception.h | 4 +-
.../lib/interception/interception_linux.cpp | 2 +-
.../lib/interception/interception_linux.h | 2 +-
.../lib/sanitizer_common/CMakeLists.txt | 5 +
.../sanitizer_common_interceptors_ioctl.inc | 18 +-
.../lib/sanitizer_common/sanitizer_errno.h | 2 +
.../sanitizer_common/sanitizer_errno_codes.h | 9 +
.../lib/sanitizer_common/sanitizer_haiku.cpp | 361 ++++++++++++++++++
.../lib/sanitizer_common/sanitizer_linux.cpp | 71 +++-
.../lib/sanitizer_common/sanitizer_linux.h | 8 +-
.../sanitizer_linux_libcdep.cpp | 21 +-
.../lib/sanitizer_common/sanitizer_platform.h | 13 +-
.../sanitizer_platform_limits_posix.cpp | 51 ++-
.../sanitizer_platform_limits_posix.h | 46 ++-
.../lib/sanitizer_common/sanitizer_procmaps.h | 2 +-
.../sanitizer_procmaps_haiku.cpp | 97 +++++
.../sanitizer_unwind_linux_libcdep.cpp | 4 +-
.../lib/sanitizer_common/tests/CMakeLists.txt | 3 +
compiler-rt/lib/ubsan/ubsan_platform.h | 2 +-
.../Instrumentation/AddressSanitizer.cpp | 4 +
27 files changed, 686 insertions(+), 72 deletions(-)
create mode 100644 compiler-rt/lib/sanitizer_common/sanitizer_haiku.cpp
create mode 100644 compiler-rt/lib/sanitizer_common/sanitizer_procmaps_haiku.cpp
diff --git a/compiler-rt/CMakeLists.txt b/compiler-rt/CMakeLists.txt
index f319113e5c16e..9f8e8334d75ba 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 cf729c3adb1f5..e3310b1ff0e2c 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 3b40f76836efe..b3aa3ead187bc 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 <dlfcn.h>
# include <fcntl.h>
@@ -22,7 +26,9 @@
# include <stdio.h>
# include <sys/mman.h>
# include <sys/resource.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
diff --git a/compiler-rt/lib/asan/asan_malloc_linux.cpp b/compiler-rt/lib/asan/asan_malloc_linux.cpp
index 3d6b03fefab70..cbcdd9c1be29d 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 39685696a0d0d..401df415096dd 100644
--- a/compiler-rt/lib/asan/asan_posix.cpp
+++ b/compiler-rt/lib/asan/asan_posix.cpp
@@ -174,7 +174,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 00dcbf6534e28..9cd9c97bed813 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 0d98b1498a821..2d054ee859ed4 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 3cb6b446638e0..25480120e7ad6 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 ef8136eb4fc70..0a6659d38ae83 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 <dlfcn.h> // for dlsym() and dlvsym()
diff --git a/compiler-rt/lib/interception/interception_linux.h b/compiler-rt/lib/interception/interception_linux.h
index 2e01ff44578c3..52e34d535030e 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 09391e4f5f370..6e6dfd2f33ebf 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 49ec4097c900b..f88f914b1d149 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 46c85364cef56..76919da57d942 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 9e6e71ec80c15..c2ea52b84dfc3 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 {
+#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 0000000000000..9b721775422ee
--- /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 <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
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
index 1fa75214f4205..cadd79de9db87 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 <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
@@ -120,6 +122,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
@@ -248,7 +257,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) {
@@ -595,7 +604,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);
@@ -632,6 +641,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
@@ -647,6 +658,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
@@ -674,7 +687,7 @@ 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++) {
@@ -712,13 +725,13 @@ 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;
@@ -745,7 +758,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>.
@@ -804,7 +820,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);
@@ -814,7 +830,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);
@@ -846,7 +862,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,
@@ -1060,7 +1076,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);
@@ -1264,7 +1280,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);
@@ -1330,11 +1358,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
@@ -1993,11 +2021,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];
@@ -2610,6 +2642,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 8b7874bb5a349..c1562506babf3 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 <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);
diff --git a/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp b/compiler-rt/lib/sanitizer_common/sanitizer_linux_libcdep.cpp
index e5e79d4e0521c..bf3b70365432e 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
# define _RTLD_SOURCE // for __lwp_gettcb_fast() / __lwp_getprivate_fast()
# endif
@@ -74,6 +78,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>
@@ -636,6 +645,7 @@ static void GetTls(uptr *addr, uptr *size) {
*addr = (uptr)tcb->tcb_dtv[1];
}
}
+# elif SANITIZER_HAIKU
# else
# error "Unknown OS"
# endif
@@ -706,8 +716,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
@@ -843,6 +858,10 @@ u32 GetNumberOfCPUs() {
req[1] = HW_NCPU;
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 57966403c92a9..af79e99165f97 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)
@@ -138,7 +144,7 @@
#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 a5311d266b0c4..28503ff487867 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 <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);
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 1f7e3d21b6a6f..26de940f931b5 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 bf3c2c28e32e3..a9be974c12b19 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 0000000000000..befb55720626a
--- /dev/null
+++ b/compiler-rt/lib/sanitizer_common/sanitizer_procmaps_haiku.cpp
@@ -0,0 +1,97 @@
+//===-- 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
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 6a8e82e2e213c..3f6901a2e7f1b 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 fef8bb772e0e0..55c7d665e639f 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 d2cc2e10bd2f0..c7eb1a967e53f 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 a4c6c61e57998..c1dba77c3532b 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;
}
More information about the llvm-commits
mailing list