summaryrefslogtreecommitdiff
path: root/gnu/llvm
diff options
context:
space:
mode:
authorGreg Steuck <gnezdo@cvs.openbsd.org>2022-02-16 03:48:56 +0000
committerGreg Steuck <gnezdo@cvs.openbsd.org>2022-02-16 03:48:56 +0000
commit5041c863374cf6c9328e3d05853f8a56be24eda5 (patch)
treeca761226369a935070351c43a4c8d067042231c3 /gnu/llvm
parent21b5307c4631b0755fc011f119c3d7cd86bdaa12 (diff)
Add ifdefs to build ubsan_minimal on OpenBSD
ok jca@
Diffstat (limited to 'gnu/llvm')
-rw-r--r--gnu/llvm/compiler-rt/lib/interception/interception.h33
-rw-r--r--gnu/llvm/compiler-rt/lib/interception/interception_linux.h8
-rw-r--r--gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp447
-rw-r--r--gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_linux.h14
-rw-r--r--gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_platform.h67
-rw-r--r--gnu/llvm/compiler-rt/lib/ubsan/ubsan_platform.h8
6 files changed, 379 insertions, 198 deletions
diff --git a/gnu/llvm/compiler-rt/lib/interception/interception.h b/gnu/llvm/compiler-rt/lib/interception/interception.h
index d27a8ccf92a..fb91a4cc32b 100644
--- a/gnu/llvm/compiler-rt/lib/interception/interception.h
+++ b/gnu/llvm/compiler-rt/lib/interception/interception.h
@@ -16,10 +16,10 @@
#include "sanitizer_common/sanitizer_internal_defs.h"
-#if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_MAC && \
- !SANITIZER_NETBSD && !SANITIZER_OPENBSD && !SANITIZER_WINDOWS && \
- !SANITIZER_FUCHSIA && !SANITIZER_RTEMS && !SANITIZER_SOLARIS
-# error "Interception doesn't work on this operating system."
+#if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_MAC && \
+ !SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA && \
+ !SANITIZER_OPENBSD && !SANITIZER_SOLARIS
+# error "Interception doesn't work on this operating system."
#endif
// These typedefs should be used only in the interceptor definitions to replace
@@ -130,11 +130,6 @@ const interpose_substitution substitution_##func_name[] \
extern "C" ret_type func(__VA_ARGS__);
# define DECLARE_WRAPPER_WINAPI(ret_type, func, ...) \
extern "C" __declspec(dllimport) ret_type __stdcall func(__VA_ARGS__);
-#elif SANITIZER_RTEMS
-# define WRAP(x) x
-# define WRAPPER_NAME(x) #x
-# define INTERCEPTOR_ATTRIBUTE
-# define DECLARE_WRAPPER(ret_type, func, ...)
#elif SANITIZER_FREEBSD || SANITIZER_NETBSD
# define WRAP(x) __interceptor_ ## x
# define WRAPPER_NAME(x) "__interceptor_" #x
@@ -162,10 +157,6 @@ const interpose_substitution substitution_##func_name[] \
# define INTERCEPTOR_ATTRIBUTE __attribute__((visibility("default")))
# define REAL(x) __unsanitized_##x
# define DECLARE_REAL(ret_type, func, ...)
-#elif SANITIZER_RTEMS
-# define REAL(x) __real_ ## x
-# define DECLARE_REAL(ret_type, func, ...) \
- extern "C" ret_type REAL(func)(__VA_ARGS__);
#elif !SANITIZER_MAC
# define PTR_TO_REAL(x) real_##x
# define REAL(x) __interception::PTR_TO_REAL(x)
@@ -184,10 +175,10 @@ const interpose_substitution substitution_##func_name[] \
# define ASSIGN_REAL(x, y)
#endif // SANITIZER_MAC
-#if !SANITIZER_FUCHSIA && !SANITIZER_RTEMS
-# define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...) \
- DECLARE_REAL(ret_type, func, __VA_ARGS__) \
- extern "C" ret_type WRAP(func)(__VA_ARGS__);
+#if !SANITIZER_FUCHSIA
+# define DECLARE_REAL_AND_INTERCEPTOR(ret_type, func, ...) \
+ DECLARE_REAL(ret_type, func, __VA_ARGS__) \
+ extern "C" ret_type WRAP(func)(__VA_ARGS__);
// Declare an interceptor and its wrapper defined in a different translation
// unit (ex. asm).
# define DECLARE_EXTERN_INTERCEPTOR_AND_WRAPPER(ret_type, func, ...) \
@@ -202,11 +193,11 @@ const interpose_substitution substitution_##func_name[] \
// macros does its job. In exceptional cases you may need to call REAL(foo)
// without defining INTERCEPTOR(..., foo, ...). For example, if you override
// foo with an interceptor for other function.
-#if !SANITIZER_MAC && !SANITIZER_FUCHSIA && !SANITIZER_RTEMS
-# define DEFINE_REAL(ret_type, func, ...) \
+#if !SANITIZER_MAC && !SANITIZER_FUCHSIA
+# define DEFINE_REAL(ret_type, func, ...) \
typedef ret_type (*FUNC_TYPE(func))(__VA_ARGS__); \
- namespace __interception { \
- FUNC_TYPE(func) PTR_TO_REAL(func); \
+ namespace __interception { \
+ FUNC_TYPE(func) PTR_TO_REAL(func); \
}
#else
# define DEFINE_REAL(ret_type, func, ...)
diff --git a/gnu/llvm/compiler-rt/lib/interception/interception_linux.h b/gnu/llvm/compiler-rt/lib/interception/interception_linux.h
index e578da0cf64..b554b53d1dc 100644
--- a/gnu/llvm/compiler-rt/lib/interception/interception_linux.h
+++ b/gnu/llvm/compiler-rt/lib/interception/interception_linux.h
@@ -35,8 +35,8 @@ bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real,
(::__interception::uptr) & (func), \
(::__interception::uptr) & WRAP(func))
-// Android, Solaris and OpenBSD do not have dlvsym
-#if !SANITIZER_ANDROID && !SANITIZER_SOLARIS && !SANITIZER_OPENBSD
+// dlvsym is a GNU extension supported by some other platforms.
+#if SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD
#define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
::__interception::InterceptFunction( \
#func, symver, \
@@ -46,8 +46,8 @@ bool InterceptFunction(const char *name, const char *ver, uptr *ptr_to_real,
#else
#define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \
INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func)
-#endif // !SANITIZER_ANDROID && !SANITIZER_SOLARIS
+#endif // SANITIZER_GLIBC || SANITIZER_FREEBSD || SANITIZER_NETBSD
#endif // INTERCEPTION_LINUX_H
#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD ||
- // SANITIZER_OPENBSD || SANITIZER_SOLARIS
+ // SANITIZER_SOLARIS
diff --git a/gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp b/gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
index 84453f1bd30..369e5514e3f 100644
--- a/gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
+++ b/gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_linux.cpp
@@ -14,7 +14,7 @@
#include "sanitizer_platform.h"
#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \
- SANITIZER_OPENBSD || SANITIZER_SOLARIS
+ SANITIZER_SOLARIS
#include "sanitizer_common.h"
#include "sanitizer_flags.h"
@@ -26,7 +26,7 @@
#include "sanitizer_placement_new.h"
#include "sanitizer_procmaps.h"
-#if SANITIZER_LINUX
+#if SANITIZER_LINUX && !SANITIZER_GO
#include <asm/param.h>
#endif
@@ -38,6 +38,14 @@
#include <asm/unistd.h>
#include <sys/types.h>
#define stat kernel_stat
+#if SANITIZER_GO
+#undef st_atime
+#undef st_mtime
+#undef st_ctime
+#define st_atime st_atim
+#define st_mtime st_mtim
+#define st_ctime st_ctim
+#endif
#include <asm/stat.h>
#undef stat
#endif
@@ -59,13 +67,7 @@
#include <sys/syscall.h>
#include <sys/time.h>
#include <sys/types.h>
-#if !SANITIZER_OPENBSD
#include <ucontext.h>
-#endif
-#if SANITIZER_OPENBSD
-#include <sys/futex.h>
-#include <sys/sysctl.h>
-#endif
#include <unistd.h>
#if SANITIZER_LINUX
@@ -129,7 +131,7 @@ const int FUTEX_WAKE_PRIVATE = FUTEX_WAKE | FUTEX_PRIVATE_FLAG;
#endif
// Note : FreeBSD had implemented both
-// Linux and OpenBSD apis, available from
+// Linux apis, available from
// future 12.x version most likely
#if SANITIZER_LINUX && defined(__NR_getrandom)
# if !defined(GRND_NONBLOCK)
@@ -140,20 +142,18 @@ const int FUTEX_WAKE_PRIVATE = FUTEX_WAKE | FUTEX_PRIVATE_FLAG;
# define SANITIZER_USE_GETRANDOM 0
#endif // SANITIZER_LINUX && defined(__NR_getrandom)
-#if SANITIZER_OPENBSD
-# define SANITIZER_USE_GETENTROPY 1
+#if SANITIZER_FREEBSD && __FreeBSD_version >= 1200000
+# define SANITIZER_USE_GETENTROPY 1
#else
-# if SANITIZER_FREEBSD && __FreeBSD_version >= 1200000
-# define SANITIZER_USE_GETENTROPY 1
-# else
-# define SANITIZER_USE_GETENTROPY 0
-# endif
-#endif // SANITIZER_USE_GETENTROPY
+# define SANITIZER_USE_GETENTROPY 0
+#endif
namespace __sanitizer {
#if SANITIZER_LINUX && defined(__x86_64__)
#include "sanitizer_syscall_linux_x86_64.inc"
+#elif SANITIZER_LINUX && SANITIZER_RISCV64
+#include "sanitizer_syscall_linux_riscv64.inc"
#elif SANITIZER_LINUX && defined(__aarch64__)
#include "sanitizer_syscall_linux_aarch64.inc"
#elif SANITIZER_LINUX && defined(__arm__)
@@ -164,7 +164,7 @@ namespace __sanitizer {
// --------------- sanitizer_libc.h
#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD
-#if !SANITIZER_S390 && !SANITIZER_OPENBSD
+#if !SANITIZER_S390
uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
u64 offset) {
#if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS
@@ -177,17 +177,27 @@ uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
offset / 4096);
#endif
}
-#endif // !SANITIZER_S390 && !SANITIZER_OPENBSD
+#endif // !SANITIZER_S390
-#if !SANITIZER_OPENBSD
uptr internal_munmap(void *addr, uptr length) {
return internal_syscall(SYSCALL(munmap), (uptr)addr, length);
}
+#if SANITIZER_LINUX
+uptr internal_mremap(void *old_address, uptr old_size, uptr new_size, int flags,
+ void *new_address) {
+ return internal_syscall(SYSCALL(mremap), (uptr)old_address, old_size,
+ new_size, flags, (uptr)new_address);
+}
+#endif
+
int internal_mprotect(void *addr, uptr length, int prot) {
return internal_syscall(SYSCALL(mprotect), (uptr)addr, length, prot);
}
-#endif
+
+int internal_madvise(uptr addr, uptr length, int advice) {
+ return internal_syscall(SYSCALL(madvise), addr, length, advice);
+}
uptr internal_close(fd_t fd) {
return internal_syscall(SYSCALL(close), fd);
@@ -254,9 +264,11 @@ static void stat64_to_stat(struct stat64 *in, struct stat *out) {
// Undefine compatibility macros from <sys/stat.h>
// so that they would not clash with the kernel_stat
// st_[a|m|c]time fields
+#if !SANITIZER_GO
#undef st_atime
#undef st_mtime
#undef st_ctime
+#endif
#if defined(SANITIZER_ANDROID)
// Bionic sys/stat.h defines additional macros
// for compatibility with the old NDKs and
@@ -299,7 +311,7 @@ static void kernel_stat_to_stat(struct kernel_stat *in, struct stat *out) {
#endif
uptr internal_stat(const char *path, void *buf) {
-#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
+#if SANITIZER_FREEBSD
return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf, 0);
#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path, (uptr)buf,
@@ -323,7 +335,7 @@ uptr internal_stat(const char *path, void *buf) {
}
uptr internal_lstat(const char *path, void *buf) {
-#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
+#if SANITIZER_FREEBSD
return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf,
AT_SYMLINK_NOFOLLOW);
#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
@@ -348,9 +360,8 @@ uptr internal_lstat(const char *path, void *buf) {
}
uptr internal_fstat(fd_t fd, void *buf) {
-#if SANITIZER_FREEBSD || SANITIZER_OPENBSD || \
- SANITIZER_LINUX_USES_64BIT_SYSCALLS
-#if SANITIZER_MIPS64 && !SANITIZER_OPENBSD
+#if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS
+#if SANITIZER_MIPS64
// For mips64, fstat syscall fills buffer in the format of kernel_stat
struct kernel_stat kbuf;
int res = internal_syscall(SYSCALL(fstat), fd, &kbuf);
@@ -390,16 +401,13 @@ uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
return internal_syscall(SYSCALL(readlinkat), AT_FDCWD, (uptr)path, (uptr)buf,
bufsize);
-#elif SANITIZER_OPENBSD
- return internal_syscall(SYSCALL(readlinkat), AT_FDCWD, (uptr)path, (uptr)buf,
- bufsize);
#else
return internal_syscall(SYSCALL(readlink), (uptr)path, (uptr)buf, bufsize);
#endif
}
uptr internal_unlink(const char *path) {
-#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS || SANITIZER_OPENBSD
+#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
return internal_syscall(SYSCALL(unlinkat), AT_FDCWD, (uptr)path, 0);
#else
return internal_syscall(SYSCALL(unlink), (uptr)path);
@@ -410,7 +418,7 @@ uptr internal_rename(const char *oldpath, const char *newpath) {
#if defined(__riscv)
return internal_syscall(SYSCALL(renameat2), AT_FDCWD, (uptr)oldpath, AT_FDCWD,
(uptr)newpath, 0);
-#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS || SANITIZER_OPENBSD
+#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
return internal_syscall(SYSCALL(renameat), AT_FDCWD, (uptr)oldpath, AT_FDCWD,
(uptr)newpath);
#else
@@ -422,22 +430,11 @@ uptr internal_sched_yield() {
return internal_syscall(SYSCALL(sched_yield));
}
-void internal__exit(int exitcode) {
-#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
- internal_syscall(SYSCALL(exit), exitcode);
-#else
- internal_syscall(SYSCALL(exit_group), exitcode);
-#endif
- Die(); // Unreachable.
-}
-
-unsigned int internal_sleep(unsigned int seconds) {
+void internal_usleep(u64 useconds) {
struct timespec ts;
- ts.tv_sec = seconds;
- ts.tv_nsec = 0;
- int res = internal_syscall(SYSCALL(nanosleep), &ts, &ts);
- if (res) return ts.tv_sec;
- return 0;
+ ts.tv_sec = useconds / 1000000;
+ ts.tv_nsec = (useconds % 1000000) * 1000;
+ internal_syscall(SYSCALL(nanosleep), &ts, &ts);
}
uptr internal_execve(const char *filename, char *const argv[],
@@ -447,6 +444,17 @@ uptr internal_execve(const char *filename, char *const argv[],
}
#endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD
+#if !SANITIZER_NETBSD
+void internal__exit(int exitcode) {
+#if SANITIZER_FREEBSD || SANITIZER_SOLARIS
+ internal_syscall(SYSCALL(exit), exitcode);
+#else
+ internal_syscall(SYSCALL(exit_group), exitcode);
+#endif
+ Die(); // Unreachable.
+}
+#endif // !SANITIZER_NETBSD
+
// ----------------- sanitizer_common.h
bool FileExists(const char *filename) {
if (ShouldMockFailureToOpen(filename))
@@ -468,8 +476,6 @@ tid_t GetTid() {
long Tid;
thr_self(&Tid);
return Tid;
-#elif SANITIZER_OPENBSD
- return internal_syscall(SYSCALL(getthrid));
#elif SANITIZER_SOLARIS
return thr_self();
#else
@@ -482,9 +488,6 @@ int TgKill(pid_t pid, tid_t tid, int sig) {
return internal_syscall(SYSCALL(tgkill), pid, tid, sig);
#elif SANITIZER_FREEBSD
return internal_syscall(SYSCALL(thr_kill2), pid, tid, sig);
-#elif SANITIZER_OPENBSD
- (void)pid;
- return internal_syscall(SYSCALL(thrkill), tid, sig, nullptr);
#elif SANITIZER_SOLARIS
(void)pid;
return thr_kill(tid, sig);
@@ -492,29 +495,30 @@ int TgKill(pid_t pid, tid_t tid, int sig) {
}
#endif
-#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD
+#if SANITIZER_GLIBC
u64 NanoTime() {
-#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
- timeval tv;
-#else
kernel_timeval tv;
-#endif
internal_memset(&tv, 0, sizeof(tv));
internal_syscall(SYSCALL(gettimeofday), &tv, 0);
- return (u64)tv.tv_sec * 1000*1000*1000 + tv.tv_usec * 1000;
+ return (u64)tv.tv_sec * 1000 * 1000 * 1000 + tv.tv_usec * 1000;
}
-
+// Used by real_clock_gettime.
uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {
return internal_syscall(SYSCALL(clock_gettime), clk_id, tp);
}
-#endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD
+#elif !SANITIZER_SOLARIS && !SANITIZER_NETBSD
+u64 NanoTime() {
+ struct timespec ts;
+ clock_gettime(CLOCK_REALTIME, &ts);
+ return (u64)ts.tv_sec * 1000 * 1000 * 1000 + ts.tv_nsec;
+}
+#endif
// Like getenv, but reads env directly from /proc (on Linux) or parses the
// '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_OPENBSD || \
- SANITIZER_SOLARIS
+#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD || SANITIZER_SOLARIS
if (::environ != 0) {
uptr NameLen = internal_strlen(name);
for (char **Env = ::environ; *Env != 0; Env++) {
@@ -552,14 +556,13 @@ const char *GetEnv(const char *name) {
#endif
}
-#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD && !SANITIZER_OPENBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD && !SANITIZER_GO
extern "C" {
SANITIZER_WEAK_ATTRIBUTE extern void *__libc_stack_end;
}
#endif
-#if !SANITIZER_GO && !SANITIZER_FREEBSD && !SANITIZER_NETBSD && \
- !SANITIZER_OPENBSD
+#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
static void ReadNullSepFileToArray(const char *path, char ***arr,
int arr_size) {
char *buff;
@@ -584,7 +587,6 @@ static void ReadNullSepFileToArray(const char *path, char ***arr,
}
#endif
-#if !SANITIZER_OPENBSD
static void GetArgsAndEnv(char ***argv, char ***envp) {
#if SANITIZER_FREEBSD
// On FreeBSD, retrieving the argument and environment arrays is done via the
@@ -604,16 +606,21 @@ static void GetArgsAndEnv(char ***argv, char ***envp) {
#else // SANITIZER_FREEBSD
#if !SANITIZER_GO
if (&__libc_stack_end) {
-#endif // !SANITIZER_GO
uptr* stack_end = (uptr*)__libc_stack_end;
- int argc = *stack_end;
+ // Normally argc can be obtained from *stack_end, however, on ARM glibc's
+ // _start clobbers it:
+ // https://sourceware.org/git/?p=glibc.git;a=blob;f=sysdeps/arm/start.S;hb=refs/heads/release/2.31/master#l75
+ // Do not special-case ARM and infer argc from argv everywhere.
+ int argc = 0;
+ while (stack_end[argc + 1]) argc++;
*argv = (char**)(stack_end + 1);
*envp = (char**)(stack_end + argc + 2);
-#if !SANITIZER_GO
} else {
+#endif // !SANITIZER_GO
static const int kMaxArgv = 2000, kMaxEnvp = 2000;
ReadNullSepFileToArray("/proc/self/cmdline", argv, kMaxArgv);
ReadNullSepFileToArray("/proc/self/environ", envp, kMaxEnvp);
+#if !SANITIZER_GO
}
#endif // !SANITIZER_GO
#endif // SANITIZER_FREEBSD
@@ -631,14 +638,28 @@ char **GetEnviron() {
return envp;
}
-#endif // !SANITIZER_OPENBSD
-
#if !SANITIZER_SOLARIS
-enum MutexState {
- MtxUnlocked = 0,
- MtxLocked = 1,
- MtxSleeping = 2
-};
+void FutexWait(atomic_uint32_t *p, u32 cmp) {
+# if SANITIZER_FREEBSD
+ _umtx_op(p, UMTX_OP_WAIT_UINT, cmp, 0, 0);
+# elif SANITIZER_NETBSD
+ sched_yield(); /* No userspace futex-like synchronization */
+# else
+ internal_syscall(SYSCALL(futex), (uptr)p, FUTEX_WAIT_PRIVATE, cmp, 0, 0, 0);
+# endif
+}
+
+void FutexWake(atomic_uint32_t *p, u32 count) {
+# if SANITIZER_FREEBSD
+ _umtx_op(p, UMTX_OP_WAKE, count, 0, 0);
+# elif SANITIZER_NETBSD
+ /* No userspace futex-like synchronization */
+# else
+ internal_syscall(SYSCALL(futex), (uptr)p, FUTEX_WAKE_PRIVATE, count, 0, 0, 0);
+# endif
+}
+
+enum { MtxUnlocked = 0, MtxLocked = 1, MtxSleeping = 2 };
BlockingMutex::BlockingMutex() {
internal_memset(this, 0, sizeof(*this));
@@ -676,11 +697,11 @@ void BlockingMutex::Unlock() {
}
}
-void BlockingMutex::CheckLocked() {
- atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&opaque_storage_);
+void BlockingMutex::CheckLocked() const {
+ auto m = reinterpret_cast<atomic_uint32_t const *>(&opaque_storage_);
CHECK_NE(MtxUnlocked, atomic_load(m, memory_order_relaxed));
}
-#endif // !SANITIZER_SOLARIS
+# endif // !SANITIZER_SOLARIS
// ----------------- sanitizer_linux.h
// The actual size of this structure is specified by d_reclen.
@@ -688,19 +709,9 @@ void BlockingMutex::CheckLocked() {
// 32-bit syscall here.
#if SANITIZER_NETBSD
// Not used
-#elif SANITIZER_OPENBSD
-// struct dirent is different for Linux and us. At this moment, we use only
-// d_fileno (Linux call this d_ino), d_reclen, and d_name.
-struct linux_dirent {
- u64 d_ino; // d_fileno
- u16 d_reclen;
- u16 d_namlen; // not used
- u8 d_type; // not used
- char d_name[NAME_MAX + 1];
-};
#else
struct linux_dirent {
-#if SANITIZER_X32 || defined(__aarch64__)
+#if SANITIZER_X32 || defined(__aarch64__) || SANITIZER_RISCV64
u64 d_ino;
u64 d_off;
#else
@@ -708,7 +719,7 @@ struct linux_dirent {
unsigned long d_off;
#endif
unsigned short d_reclen;
-#ifdef __aarch64__
+#if defined(__aarch64__) || SANITIZER_RISCV64
unsigned char d_type;
#endif
char d_name[256];
@@ -735,6 +746,14 @@ uptr internal_getppid() {
return internal_syscall(SYSCALL(getppid));
}
+int internal_dlinfo(void *handle, int request, void *p) {
+#if SANITIZER_FREEBSD
+ return dlinfo(handle, request, p);
+#else
+ UNIMPLEMENTED();
+#endif
+}
+
uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count) {
#if SANITIZER_FREEBSD
return internal_syscall(SYSCALL(getdirentries), fd, (uptr)dirp, count, NULL);
@@ -767,28 +786,39 @@ int internal_fork() {
#endif
}
-#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
+#if SANITIZER_FREEBSD
int internal_sysctl(const int *name, unsigned int namelen, void *oldp,
uptr *oldlenp, const void *newp, uptr newlen) {
-#if SANITIZER_OPENBSD
- return sysctl(name, namelen, oldp, (size_t *)oldlenp, (void *)newp,
- (size_t)newlen);
-#else
return internal_syscall(SYSCALL(__sysctl), name, namelen, oldp,
(size_t *)oldlenp, newp, (size_t)newlen);
-#endif
}
-#if SANITIZER_FREEBSD
int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp,
const void *newp, uptr newlen) {
- static decltype(sysctlbyname) *real = nullptr;
- if (!real)
- real = (decltype(sysctlbyname) *)dlsym(RTLD_NEXT, "sysctlbyname");
- CHECK(real);
- return real(sname, oldp, (size_t *)oldlenp, newp, (size_t)newlen);
-}
+ // Note: this function can be called during startup, so we need to avoid
+ // calling any interceptable functions. On FreeBSD >= 1300045 sysctlbyname()
+ // is a real syscall, but for older versions it calls sysctlnametomib()
+ // followed by sysctl(). To avoid calling the intercepted version and
+ // asserting if this happens during startup, call the real sysctlnametomib()
+ // followed by internal_sysctl() if the syscall is not available.
+#ifdef SYS___sysctlbyname
+ return internal_syscall(SYSCALL(__sysctlbyname), sname,
+ internal_strlen(sname), oldp, (size_t *)oldlenp, newp,
+ (size_t)newlen);
+#else
+ static decltype(sysctlnametomib) *real_sysctlnametomib = nullptr;
+ if (!real_sysctlnametomib)
+ real_sysctlnametomib =
+ (decltype(sysctlnametomib) *)dlsym(RTLD_NEXT, "sysctlnametomib");
+ CHECK(real_sysctlnametomib);
+
+ int oid[CTL_MAXNAME];
+ size_t len = CTL_MAXNAME;
+ if (real_sysctlnametomib(sname, oid, &len) == -1)
+ return (-1);
+ return internal_sysctl(oid, len, oldp, oldlenp, newp, newlen);
#endif
+}
#endif
#if SANITIZER_LINUX
@@ -842,14 +872,13 @@ int internal_sigaction_norestorer(int signum, const void *act, void *oldact) {
uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
__sanitizer_sigset_t *oldset) {
-#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
+#if SANITIZER_FREEBSD
return internal_syscall(SYSCALL(sigprocmask), how, set, oldset);
#else
__sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set;
__sanitizer_kernel_sigset_t *k_oldset = (__sanitizer_kernel_sigset_t *)oldset;
- return internal_syscall(SYSCALL(rt_sigprocmask), (uptr)how,
- (uptr)&k_set->sig[0], (uptr)&k_oldset->sig[0],
- sizeof(__sanitizer_kernel_sigset_t));
+ return internal_syscall(SYSCALL(rt_sigprocmask), (uptr)how, (uptr)k_set,
+ (uptr)k_oldset, sizeof(__sanitizer_kernel_sigset_t));
#endif
}
@@ -869,7 +898,7 @@ void internal_sigdelset(__sanitizer_sigset_t *set, int signum) {
__sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set;
const uptr idx = signum / (sizeof(k_set->sig[0]) * 8);
const uptr bit = signum % (sizeof(k_set->sig[0]) * 8);
- k_set->sig[idx] &= ~(1 << bit);
+ k_set->sig[idx] &= ~((uptr)1 << bit);
}
bool internal_sigismember(__sanitizer_sigset_t *set, int signum) {
@@ -879,7 +908,7 @@ bool internal_sigismember(__sanitizer_sigset_t *set, int signum) {
__sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set;
const uptr idx = signum / (sizeof(k_set->sig[0]) * 8);
const uptr bit = signum % (sizeof(k_set->sig[0]) * 8);
- return k_set->sig[idx] & (1 << bit);
+ return k_set->sig[idx] & ((uptr)1 << bit);
}
#elif SANITIZER_FREEBSD
void internal_sigdelset(__sanitizer_sigset_t *set, int signum) {
@@ -1006,9 +1035,8 @@ static uptr GetKernelAreaSize() {
// is modified (e.g. under schroot) so check this as well.
struct utsname uname_info;
int pers = personality(0xffffffffUL);
- if (!(pers & PER_MASK)
- && uname(&uname_info) == 0
- && internal_strstr(uname_info.machine, "64"))
+ if (!(pers & PER_MASK) && internal_uname(&uname_info) == 0 &&
+ internal_strstr(uname_info.machine, "64"))
return 0;
#endif // SANITIZER_ANDROID
@@ -1021,7 +1049,7 @@ static uptr GetKernelAreaSize() {
#endif // SANITIZER_WORDSIZE == 32
uptr GetMaxVirtualAddress() {
-#if (SANITIZER_NETBSD || SANITIZER_OPENBSD) && defined(__x86_64__)
+#if SANITIZER_NETBSD && defined(__x86_64__)
return 0x7f7ffffff000ULL; // (0x00007f8000000000 - PAGE_SIZE)
#elif SANITIZER_WORDSIZE == 64
# if defined(__powerpc64__) || defined(__aarch64__)
@@ -1033,6 +1061,8 @@ uptr GetMaxVirtualAddress() {
// This should (does) work for both PowerPC64 Endian modes.
// Similarly, aarch64 has multiple address space layouts: 39, 42 and 47-bit.
return (1ULL << (MostSignificantSetBitIndex(GET_CURRENT_FRAME()) + 1)) - 1;
+#elif SANITIZER_RISCV64
+ return (1ULL << 38) - 1;
# elif defined(__mips64)
return (1ULL << 40) - 1; // 0x000000ffffffffffUL;
# elif defined(__s390x__)
@@ -1063,7 +1093,8 @@ uptr GetMaxUserVirtualAddress() {
#if !SANITIZER_ANDROID
uptr GetPageSize() {
-#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__i386__))
+#if SANITIZER_LINUX && (defined(__x86_64__) || defined(__i386__)) && \
+ defined(EXEC_PAGESIZE)
return EXEC_PAGESIZE;
#elif SANITIZER_FREEBSD || SANITIZER_NETBSD
// Use sysctl as sysconf can trigger interceptors internally.
@@ -1081,7 +1112,6 @@ uptr GetPageSize() {
}
#endif // !SANITIZER_ANDROID
-#if !SANITIZER_OPENBSD
uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
#if SANITIZER_SOLARIS
const char *default_module_name = getexecname();
@@ -1118,7 +1148,6 @@ uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) {
return module_name_len;
#endif
}
-#endif // !SANITIZER_OPENBSD
uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) {
#if SANITIZER_LINUX
@@ -1151,10 +1180,10 @@ bool LibraryNameIs(const char *full_name, const char *base_name) {
// Call cb for each region mapped by map.
void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr)) {
CHECK_NE(map, nullptr);
-#if !SANITIZER_FREEBSD && !SANITIZER_OPENBSD
+#if !SANITIZER_FREEBSD
typedef ElfW(Phdr) Elf_Phdr;
typedef ElfW(Ehdr) Elf_Ehdr;
-#endif // !SANITIZER_FREEBSD && !SANITIZER_OPENBSD
+#endif // !SANITIZER_FREEBSD
char *base = (char *)map->l_addr;
Elf_Ehdr *ehdr = (Elf_Ehdr *)base;
char *phdrs = base + ehdr->e_phoff;
@@ -1326,6 +1355,47 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
: "memory", "$29" );
return res;
}
+#elif SANITIZER_RISCV64
+uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
+ int *parent_tidptr, void *newtls, int *child_tidptr) {
+ if (!fn || !child_stack)
+ return -EINVAL;
+
+ CHECK_EQ(0, (uptr)child_stack % 16);
+
+ register int res __asm__("a0");
+ register int __flags __asm__("a0") = flags;
+ register void *__stack __asm__("a1") = child_stack;
+ register int *__ptid __asm__("a2") = parent_tidptr;
+ register void *__tls __asm__("a3") = newtls;
+ register int *__ctid __asm__("a4") = child_tidptr;
+ register int (*__fn)(void *) __asm__("a5") = fn;
+ register void *__arg __asm__("a6") = arg;
+ register int nr_clone __asm__("a7") = __NR_clone;
+
+ __asm__ __volatile__(
+ "ecall\n"
+
+ /* if (a0 != 0)
+ * return a0;
+ */
+ "bnez a0, 1f\n"
+
+ // In the child, now. Call "fn(arg)".
+ "mv a0, a6\n"
+ "jalr a5\n"
+
+ // Call _exit(a0).
+ "addi a7, zero, %9\n"
+ "ecall\n"
+ "1:\n"
+
+ : "=r"(res)
+ : "0"(__flags), "r"(__stack), "r"(__ptid), "r"(__tls), "r"(__ctid),
+ "r"(__fn), "r"(__arg), "r"(nr_clone), "i"(__NR_exit)
+ : "memory");
+ return res;
+}
#elif defined(__aarch64__)
uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
int *parent_tidptr, void *newtls, int *child_tidptr) {
@@ -1619,6 +1689,12 @@ uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
}
#endif // defined(__x86_64__) && SANITIZER_LINUX
+#if SANITIZER_LINUX
+int internal_uname(struct utsname *buf) {
+ return internal_syscall(SYSCALL(uname), buf);
+}
+#endif
+
#if SANITIZER_ANDROID
#if __ANDROID_API__ < 21
extern "C" __attribute__((weak)) int dl_iterate_phdr(
@@ -1701,7 +1777,7 @@ HandleSignalMode GetHandleSignalMode(int signum) {
}
#if !SANITIZER_GO
-void *internal_start_thread(void(*func)(void *arg), void *arg) {
+void *internal_start_thread(void *(*func)(void *arg), void *arg) {
// Start the thread with signals blocked, otherwise it can steal user signals.
__sanitizer_sigset_t set, old;
internal_sigfillset(&set);
@@ -1712,7 +1788,7 @@ void *internal_start_thread(void(*func)(void *arg), void *arg) {
#endif
internal_sigprocmask(SIG_SETMASK, &set, &old);
void *th;
- real_pthread_create(&th, nullptr, (void*(*)(void *arg))func, arg);
+ real_pthread_create(&th, nullptr, func, arg);
internal_sigprocmask(SIG_SETMASK, &old, nullptr);
return th;
}
@@ -1721,7 +1797,7 @@ void internal_join_thread(void *th) {
real_pthread_join(th, nullptr);
}
#else
-void *internal_start_thread(void (*func)(void *), void *arg) { return 0; }
+void *internal_start_thread(void *(*func)(void *), void *arg) { return 0; }
void internal_join_thread(void *th) {}
#endif
@@ -1749,11 +1825,7 @@ static bool Aarch64GetESR(ucontext_t *ucontext, u64 *esr) {
}
#endif
-#if SANITIZER_OPENBSD
-using Context = sigcontext;
-#else
using Context = ucontext_t;
-#endif
SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
Context *ucontext = (Context *)context;
@@ -1763,8 +1835,6 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
uptr err = ucontext->uc_mcontext.mc_err;
#elif SANITIZER_NETBSD
uptr err = ucontext->uc_mcontext.__gregs[_REG_ERR];
-#elif SANITIZER_OPENBSD
- uptr err = ucontext->sc_err;
#elif SANITIZER_SOLARIS && defined(__i386__)
const int Err = 13;
uptr err = ucontext->uc_mcontext.gregs[Err];
@@ -1846,6 +1916,105 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const {
#endif
u32 instr = *(u32 *)pc;
return (instr >> 21) & 1 ? WRITE: READ;
+#elif defined(__riscv)
+ unsigned long pc = ucontext->uc_mcontext.__gregs[REG_PC];
+ unsigned faulty_instruction = *(uint16_t *)pc;
+
+#if defined(__riscv_compressed)
+ if ((faulty_instruction & 0x3) != 0x3) { // it's a compressed instruction
+ // set op_bits to the instruction bits [1, 0, 15, 14, 13]
+ unsigned op_bits =
+ ((faulty_instruction & 0x3) << 3) | (faulty_instruction >> 13);
+ unsigned rd = faulty_instruction & 0xF80; // bits 7-11, inclusive
+ switch (op_bits) {
+ case 0b10'010: // c.lwsp (rd != x0)
+#if __riscv_xlen == 64
+ case 0b10'011: // c.ldsp (rd != x0)
+#endif
+ return rd ? SignalContext::READ : SignalContext::UNKNOWN;
+ case 0b00'010: // c.lw
+#if __riscv_flen >= 32 && __riscv_xlen == 32
+ case 0b10'011: // c.flwsp
+#endif
+#if __riscv_flen >= 32 || __riscv_xlen == 64
+ case 0b00'011: // c.flw / c.ld
+#endif
+#if __riscv_flen == 64
+ case 0b00'001: // c.fld
+ case 0b10'001: // c.fldsp
+#endif
+ return SignalContext::READ;
+ case 0b00'110: // c.sw
+ case 0b10'110: // c.swsp
+#if __riscv_flen >= 32 || __riscv_xlen == 64
+ case 0b00'111: // c.fsw / c.sd
+ case 0b10'111: // c.fswsp / c.sdsp
+#endif
+#if __riscv_flen == 64
+ case 0b00'101: // c.fsd
+ case 0b10'101: // c.fsdsp
+#endif
+ return SignalContext::WRITE;
+ default:
+ return SignalContext::UNKNOWN;
+ }
+ }
+#endif
+
+ unsigned opcode = faulty_instruction & 0x7f; // lower 7 bits
+ unsigned funct3 = (faulty_instruction >> 12) & 0x7; // bits 12-14, inclusive
+ switch (opcode) {
+ case 0b0000011: // loads
+ switch (funct3) {
+ case 0b000: // lb
+ case 0b001: // lh
+ case 0b010: // lw
+#if __riscv_xlen == 64
+ case 0b011: // ld
+#endif
+ case 0b100: // lbu
+ case 0b101: // lhu
+ return SignalContext::READ;
+ default:
+ return SignalContext::UNKNOWN;
+ }
+ case 0b0100011: // stores
+ switch (funct3) {
+ case 0b000: // sb
+ case 0b001: // sh
+ case 0b010: // sw
+#if __riscv_xlen == 64
+ case 0b011: // sd
+#endif
+ return SignalContext::WRITE;
+ default:
+ return SignalContext::UNKNOWN;
+ }
+#if __riscv_flen >= 32
+ case 0b0000111: // floating-point loads
+ switch (funct3) {
+ case 0b010: // flw
+#if __riscv_flen == 64
+ case 0b011: // fld
+#endif
+ return SignalContext::READ;
+ default:
+ return SignalContext::UNKNOWN;
+ }
+ case 0b0100111: // floating-point stores
+ switch (funct3) {
+ case 0b010: // fsw
+#if __riscv_flen == 64
+ case 0b011: // fsd
+#endif
+ return SignalContext::WRITE;
+ default:
+ return SignalContext::UNKNOWN;
+ }
+#endif
+ default:
+ return SignalContext::UNKNOWN;
+ }
#else
(void)ucontext;
return UNKNOWN; // FIXME: Implement.
@@ -1891,11 +2060,6 @@ 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_OPENBSD
- sigcontext *ucontext = (sigcontext *)context;
- *pc = ucontext->sc_rip;
- *bp = ucontext->sc_rbp;
- *sp = ucontext->sc_rsp;
# else
ucontext_t *ucontext = (ucontext_t*)context;
*pc = ucontext->uc_mcontext.gregs[REG_RIP];
@@ -1908,11 +2072,6 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
*pc = ucontext->uc_mcontext.mc_eip;
*bp = ucontext->uc_mcontext.mc_ebp;
*sp = ucontext->uc_mcontext.mc_esp;
-#elif SANITIZER_OPENBSD
- sigcontext *ucontext = (sigcontext *)context;
- *pc = ucontext->sc_eip;
- *bp = ucontext->sc_ebp;
- *sp = ucontext->sc_esp;
# else
ucontext_t *ucontext = (ucontext_t*)context;
# if SANITIZER_SOLARIS
@@ -1924,13 +2083,13 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
# ifndef REG_EBP
# define REG_EBP 6 // REG_FP
# endif
-# ifndef REG_ESP
-# define REG_ESP 17 // REG_SP
+# ifndef REG_UESP
+# define REG_UESP 17 // REG_SP
# endif
# endif
*pc = ucontext->uc_mcontext.gregs[REG_EIP];
*bp = ucontext->uc_mcontext.gregs[REG_EBP];
- *sp = ucontext->uc_mcontext.gregs[REG_ESP];
+ *sp = ucontext->uc_mcontext.gregs[REG_UESP];
# endif
#elif defined(__powerpc__) || defined(__powerpc64__)
ucontext_t *ucontext = (ucontext_t*)context;
@@ -2011,7 +2170,9 @@ void CheckASLR() {
}
if (UNLIKELY(paxflags & CTL_PROC_PAXFLAGS_ASLR)) {
- Printf("This sanitizer is not compatible with enabled ASLR\n");
+ Printf("This sanitizer is not compatible with enabled ASLR.\n"
+ "To disable ASLR, please run \"paxctl +a %s\" and try again.\n",
+ GetArgv()[0]);
Die();
}
#elif SANITIZER_PPC64V2
@@ -2083,14 +2244,12 @@ void CheckMPROTECT() {
#endif
}
-void PrintModuleMap() { }
-
void CheckNoDeepBind(const char *filename, int flag) {
#ifdef RTLD_DEEPBIND
if (flag & RTLD_DEEPBIND) {
Report(
"You are trying to dlopen a %s shared library with RTLD_DEEPBIND flag"
- " which is incompatibe with sanitizer runtime "
+ " which is incompatible with sanitizer runtime "
"(see https://github.com/google/sanitizers/issues/611 for details"
"). If you want to run %s library under sanitizers please remove "
"RTLD_DEEPBIND from dlopen flags.\n",
diff --git a/gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_linux.h b/gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
index c28347ad963..389c53113b1 100644
--- a/gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
+++ b/gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_linux.h
@@ -19,12 +19,12 @@
#include "sanitizer_internal_defs.h"
#include "sanitizer_platform_limits_freebsd.h"
#include "sanitizer_platform_limits_netbsd.h"
-#include "sanitizer_platform_limits_openbsd.h"
#include "sanitizer_platform_limits_posix.h"
#include "sanitizer_platform_limits_solaris.h"
#include "sanitizer_posix.h"
struct link_map; // Opaque type returned by dlopen().
+struct utsname;
namespace __sanitizer {
// Dirent structure for getdents(). Note that this structure is different from
@@ -49,7 +49,9 @@ uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count);
uptr internal_sigaltstack(const void* ss, void* oss);
uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
__sanitizer_sigset_t *oldset);
+#if SANITIZER_GLIBC
uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp);
+#endif
// Linux-only syscalls.
#if SANITIZER_LINUX
@@ -59,12 +61,13 @@ uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5);
// internal_sigaction instead.
int internal_sigaction_norestorer(int signum, const void *act, void *oldact);
void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
-#if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) \
- || defined(__powerpc64__) || defined(__s390__) || defined(__i386__) \
- || defined(__arm__)
+#if defined(__x86_64__) || defined(__mips__) || defined(__aarch64__) || \
+ defined(__powerpc64__) || defined(__s390__) || defined(__i386__) || \
+ defined(__arm__) || SANITIZER_RISCV64
uptr internal_clone(int (*fn)(void *), void *child_stack, int flags, void *arg,
int *parent_tidptr, void *newtls, int *child_tidptr);
#endif
+int internal_uname(struct utsname *buf);
#elif SANITIZER_FREEBSD
void internal_sigdelset(__sanitizer_sigset_t *set, int signum);
#elif SANITIZER_NETBSD
@@ -95,7 +98,6 @@ class ThreadLister {
// Exposed for testing.
uptr ThreadDescriptorSize();
uptr ThreadSelf();
-uptr ThreadSelfOffset();
// Matches a library's file name against a base name (stripping path and version
// information).
@@ -107,7 +109,7 @@ void ForEachMappedRegion(link_map *map, void (*cb)(const void *, uptr));
// Releases memory pages entirely within the [beg, end] address range.
// The pages no longer count toward RSS; reads are guaranteed to return 0.
// Requires (but does not verify!) that pages are MAP_PRIVATE.
-INLINE void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) {
+inline void ReleaseMemoryPagesToOSAndZeroFill(uptr beg, uptr end) {
// man madvise on Linux promises zero-fill for anonymous private pages.
// Testing shows the same behaviour for private (but not anonymous) mappings
// of shm_open() files, as long as the underlying file is untouched.
diff --git a/gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_platform.h b/gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
index c68bfa25875..64dcaaded83 100644
--- a/gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
+++ b/gnu/llvm/compiler-rt/lib/sanitizer_common/sanitizer_platform.h
@@ -13,10 +13,17 @@
#define SANITIZER_PLATFORM_H
#if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \
- !defined(__OpenBSD__) && !defined(__APPLE__) && !defined(_WIN32) && \
- !defined(__Fuchsia__) && !defined(__rtems__) && \
- !(defined(__sun__) && defined(__svr4__))
-# error "This operating system is not supported"
+ !defined(__OpenBSD__) && \
+ !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) && \
+ !(defined(__sun__) && defined(__svr4__))
+# error "This operating system is not supported"
+#endif
+
+// Get __GLIBC__ on a glibc platform. Exclude Android: features.h includes C
+// function declarations into a .S file which doesn't compile.
+// https://crbug.com/1162741
+#if __has_include(<features.h>) && !defined(__ANDROID__)
+#include <features.h>
#endif
#if defined(__linux__)
@@ -25,6 +32,12 @@
# define SANITIZER_LINUX 0
#endif
+#if defined(__GLIBC__)
+# define SANITIZER_GLIBC 1
+#else
+# define SANITIZER_GLIBC 0
+#endif
+
#if defined(__FreeBSD__)
# define SANITIZER_FREEBSD 1
#else
@@ -52,6 +65,11 @@
#if defined(__APPLE__)
# define SANITIZER_MAC 1
# include <TargetConditionals.h>
+# if TARGET_OS_OSX
+# define SANITIZER_OSX 1
+# else
+# define SANITIZER_OSX 0
+# endif
# if TARGET_OS_IPHONE
# define SANITIZER_IOS 1
# else
@@ -66,6 +84,7 @@
# define SANITIZER_MAC 0
# define SANITIZER_IOS 0
# define SANITIZER_IOSSIM 0
+# define SANITIZER_OSX 0
#endif
#if defined(__APPLE__) && TARGET_OS_IPHONE && TARGET_OS_WATCH
@@ -104,12 +123,6 @@
# define SANITIZER_FUCHSIA 0
#endif
-#if defined(__rtems__)
-# define SANITIZER_RTEMS 1
-#else
-# define SANITIZER_RTEMS 0
-#endif
-
#define SANITIZER_POSIX \
(SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \
SANITIZER_NETBSD || SANITIZER_OPENBSD || SANITIZER_SOLARIS)
@@ -132,6 +145,12 @@
# define SANITIZER_X32 0
#endif
+#if defined(__i386__) || defined(_M_IX86)
+# define SANITIZER_I386 1
+#else
+# define SANITIZER_I386 0
+#endif
+
#if defined(__mips__)
# define SANITIZER_MIPS 1
# if defined(__mips64)
@@ -207,10 +226,10 @@
# define SANITIZER_SOLARIS32 0
#endif
-#if defined(__myriad2__)
-# define SANITIZER_MYRIAD2 1
+#if defined(__riscv) && (__riscv_xlen == 64)
+#define SANITIZER_RISCV64 1
#else
-# define SANITIZER_MYRIAD2 0
+#define SANITIZER_RISCV64 0
#endif
// By default we allow to use SizeClassAllocator64 on 64-bit platform.
@@ -232,11 +251,21 @@
// FIXME: this value should be different on different platforms. Larger values
// will still work but will consume more memory for TwoLevelByteMap.
#if defined(__mips__)
+#if SANITIZER_GO && defined(__mips64)
+#define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
+#else
# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 40)
+#endif
+#elif SANITIZER_RISCV64
+#define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 38)
#elif defined(__aarch64__)
# if SANITIZER_MAC
-// Darwin iOS/ARM64 has a 36-bit VMA, 64GiB VM
-# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 36)
+# if SANITIZER_OSX || SANITIZER_IOSSIM
+# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 47)
+# else
+ // Darwin iOS/ARM64 has a 36-bit VMA, 64GiB VM
+# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 36)
+# endif
# else
# define SANITIZER_MMAP_RANGE_SIZE FIRST_32_SECOND_64(1ULL << 32, 1ULL << 48)
# endif
@@ -325,7 +354,7 @@
#endif
#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD || \
- SANITIZER_OPENBSD || SANITIZER_SOLARIS
+ SANITIZER_SOLARIS
# define SANITIZER_MADVISE_DONTNEED MADV_FREE
#else
# define SANITIZER_MADVISE_DONTNEED MADV_DONTNEED
@@ -339,9 +368,9 @@
# define SANITIZER_CACHE_LINE_SIZE 64
#endif
-// Enable offline markup symbolizer for Fuchsia and RTEMS.
-#if SANITIZER_FUCHSIA || SANITIZER_RTEMS
-#define SANITIZER_SYMBOLIZER_MARKUP 1
+// Enable offline markup symbolizer for Fuchsia.
+#if SANITIZER_FUCHSIA
+# define SANITIZER_SYMBOLIZER_MARKUP 1
#else
#define SANITIZER_SYMBOLIZER_MARKUP 0
#endif
diff --git a/gnu/llvm/compiler-rt/lib/ubsan/ubsan_platform.h b/gnu/llvm/compiler-rt/lib/ubsan/ubsan_platform.h
index 71d7fb18c9b..51d29c066f0 100644
--- a/gnu/llvm/compiler-rt/lib/ubsan/ubsan_platform.h
+++ b/gnu/llvm/compiler-rt/lib/ubsan/ubsan_platform.h
@@ -14,10 +14,10 @@
// Other platforms should be easy to add, and probably work as-is.
#if defined(__linux__) || defined(__FreeBSD__) || defined(__APPLE__) || \
- defined(__NetBSD__) || defined(__OpenBSD__) || \
- (defined(__sun__) && defined(__svr4__)) || \
- defined(_WIN32) || defined(__Fuchsia__) || defined(__rtems__)
-# define CAN_SANITIZE_UB 1
+ defined(__NetBSD__) || defined(__DragonFly__) || defined(__OpenBSD__) || \
+ (defined(__sun__) && defined(__svr4__)) || defined(_WIN32) || \
+ defined(__Fuchsia__)
+#define CAN_SANITIZE_UB 1
#else
# define CAN_SANITIZE_UB 0
#endif