mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 19:16:43 +00:00
Add NetBSD improvements in sanitizers
Summary: Changes: * Add initial msan stub support. * Handle NetBSD specific pthread_setname_np(3). * NetBSD supports __attribute__((tls_model("initial-exec"))), define it in SANITIZER_TLS_INITIAL_EXEC_ATTRIBUTE. * Add ReExec() specific bits for NetBSD. * Simplify code and add syscall64 and syscall_ptr for !NetBSD. * Correct bunch of syscall wrappers for NetBSD. * Disable test/tsan/map32bit on NetBSD as not applicable. * Port test/tsan/strerror_r to a POSIX-compliant OSes. * Disable __libc_stack_end on NetBSD. * Disable ReadNullSepFileToArray() on NetBSD. * Define struct_ElfW_Phdr_sz, detected missing symbol by msan. * Change type of __sanitizer_FILE from void to char. This helps to reuse this type as an array. Long term it will be properly implemented along with SANITIZER_HAS_STRUCT_FILE setting to 1. * Add initial NetBSD support in lib/tsan/go/buildgo.sh. * Correct referencing stdout and stderr in tsan_interceptors.cc on NetBSD. * Document NetBSD x86_64 specific virtual memory layout in tsan_platform.h. * Port tests/rtl/tsan_test_util_posix.cc to NetBSD. * Enable NetBSD tests in test/msan/lit.cfg. * Enable NetBSD tests in test/tsan/lit.cfg. Sponsored by <The NetBSD Foundation> Reviewers: joerg, vitalybuka, eugenis, kcc, dvyukov Reviewed By: dvyukov Subscribers: #sanitizers, llvm-commits, kubamracek Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D39124 llvm-svn: 316591
This commit is contained in:
parent
cff1155035
commit
9c1eeaca80
@ -118,7 +118,7 @@ static void *AllocateFromLocalPool(uptr size_in_bytes) {
|
||||
#define CHECK_UNPOISONED_STRING(x, n) \
|
||||
CHECK_UNPOISONED_STRING_OF_LEN((x), internal_strlen(x), (n))
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(SIZE_T, fread_unlocked, void *ptr, SIZE_T size, SIZE_T nmemb,
|
||||
void *file) {
|
||||
ENSURE_MSAN_INITED();
|
||||
@ -168,7 +168,7 @@ INTERCEPTOR(int, posix_memalign, void **memptr, SIZE_T alignment, SIZE_T size) {
|
||||
return res;
|
||||
}
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(void *, memalign, SIZE_T alignment, SIZE_T size) {
|
||||
GET_MALLOC_STACK_TRACE;
|
||||
return msan_memalign(alignment, size, &stack);
|
||||
@ -196,7 +196,7 @@ INTERCEPTOR(void *, valloc, SIZE_T size) {
|
||||
return msan_valloc(size, &stack);
|
||||
}
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(void *, pvalloc, SIZE_T size) {
|
||||
GET_MALLOC_STACK_TRACE;
|
||||
return msan_pvalloc(size, &stack);
|
||||
@ -212,7 +212,7 @@ INTERCEPTOR(void, free, void *ptr) {
|
||||
MsanDeallocate(&stack, ptr);
|
||||
}
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(void, cfree, void *ptr) {
|
||||
GET_MALLOC_STACK_TRACE;
|
||||
if (!ptr || UNLIKELY(IsInDlsymAllocPool(ptr))) return;
|
||||
@ -227,7 +227,7 @@ INTERCEPTOR(uptr, malloc_usable_size, void *ptr) {
|
||||
return __sanitizer_get_allocated_size(ptr);
|
||||
}
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
// This function actually returns a struct by value, but we can't unpoison a
|
||||
// temporary! The following is equivalent on all supported platforms but
|
||||
// aarch64 (which uses a different register for sret value). We have a test
|
||||
@ -246,7 +246,7 @@ INTERCEPTOR(void, mallinfo, __sanitizer_mallinfo *sret) {
|
||||
#define MSAN_MAYBE_INTERCEPT_MALLINFO
|
||||
#endif
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(int, mallopt, int cmd, int value) {
|
||||
return -1;
|
||||
}
|
||||
@ -255,7 +255,7 @@ INTERCEPTOR(int, mallopt, int cmd, int value) {
|
||||
#define MSAN_MAYBE_INTERCEPT_MALLOPT
|
||||
#endif
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(void, malloc_stats, void) {
|
||||
// FIXME: implement, but don't call REAL(malloc_stats)!
|
||||
}
|
||||
@ -308,7 +308,7 @@ INTERCEPTOR(char *, strdup, char *src) {
|
||||
return res;
|
||||
}
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(char *, __strdup, char *src) {
|
||||
ENSURE_MSAN_INITED();
|
||||
GET_STORE_STACK_TRACE;
|
||||
@ -473,7 +473,7 @@ INTERCEPTOR(SIZE_T, strftime_l, char *s, SIZE_T max, const char *format,
|
||||
INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, strftime_l, s, max, format, tm, loc);
|
||||
}
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(SIZE_T, __strftime_l, char *s, SIZE_T max, const char *format,
|
||||
__sanitizer_tm *tm, void *loc) {
|
||||
INTERCEPTOR_STRFTIME_BODY(char, SIZE_T, __strftime_l, s, max, format, tm,
|
||||
@ -495,7 +495,7 @@ INTERCEPTOR(SIZE_T, wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,
|
||||
loc);
|
||||
}
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(SIZE_T, __wcsftime_l, wchar_t *s, SIZE_T max, const wchar_t *format,
|
||||
__sanitizer_tm *tm, void *loc) {
|
||||
INTERCEPTOR_STRFTIME_BODY(wchar_t, SIZE_T, __wcsftime_l, s, max, format, tm,
|
||||
@ -614,7 +614,7 @@ INTERCEPTOR(int, putenv, char *string) {
|
||||
return res;
|
||||
}
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {
|
||||
ENSURE_MSAN_INITED();
|
||||
int res = REAL(__fxstat)(magic, fd, buf);
|
||||
@ -627,7 +627,7 @@ INTERCEPTOR(int, __fxstat, int magic, int fd, void *buf) {
|
||||
#define MSAN_MAYBE_INTERCEPT___FXSTAT
|
||||
#endif
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) {
|
||||
ENSURE_MSAN_INITED();
|
||||
int res = REAL(__fxstat64)(magic, fd, buf);
|
||||
@ -640,7 +640,7 @@ INTERCEPTOR(int, __fxstat64, int magic, int fd, void *buf) {
|
||||
#define MSAN_MAYBE_INTERCEPT___FXSTAT64
|
||||
#endif
|
||||
|
||||
#if SANITIZER_FREEBSD
|
||||
#if SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(int, fstatat, int fd, char *pathname, void *buf, int flags) {
|
||||
ENSURE_MSAN_INITED();
|
||||
int res = REAL(fstatat)(fd, pathname, buf, flags);
|
||||
@ -659,7 +659,7 @@ INTERCEPTOR(int, __fxstatat, int magic, int fd, char *pathname, void *buf,
|
||||
# define MSAN_INTERCEPT_FSTATAT INTERCEPT_FUNCTION(__fxstatat)
|
||||
#endif
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(int, __fxstatat64, int magic, int fd, char *pathname, void *buf,
|
||||
int flags) {
|
||||
ENSURE_MSAN_INITED();
|
||||
@ -706,7 +706,7 @@ INTERCEPTOR(char *, fgets, char *s, int size, void *stream) {
|
||||
return res;
|
||||
}
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(char *, fgets_unlocked, char *s, int size, void *stream) {
|
||||
ENSURE_MSAN_INITED();
|
||||
char *res = REAL(fgets_unlocked)(s, size, stream);
|
||||
@ -729,7 +729,7 @@ INTERCEPTOR(int, getrlimit, int resource, void *rlim) {
|
||||
return res;
|
||||
}
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(int, getrlimit64, int resource, void *rlim) {
|
||||
if (msan_init_is_running) return REAL(getrlimit64)(resource, rlim);
|
||||
ENSURE_MSAN_INITED();
|
||||
@ -805,7 +805,7 @@ INTERCEPTOR(int, gethostname, char *name, SIZE_T len) {
|
||||
return res;
|
||||
}
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(int, epoll_wait, int epfd, void *events, int maxevents,
|
||||
int timeout) {
|
||||
ENSURE_MSAN_INITED();
|
||||
@ -820,7 +820,7 @@ INTERCEPTOR(int, epoll_wait, int epfd, void *events, int maxevents,
|
||||
#define MSAN_MAYBE_INTERCEPT_EPOLL_WAIT
|
||||
#endif
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(int, epoll_pwait, int epfd, void *events, int maxevents,
|
||||
int timeout, void *sigmask) {
|
||||
ENSURE_MSAN_INITED();
|
||||
@ -909,7 +909,7 @@ INTERCEPTOR(void *, mmap, void *addr, SIZE_T length, int prot, int flags,
|
||||
return res;
|
||||
}
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(void *, mmap64, void *addr, SIZE_T length, int prot, int flags,
|
||||
int fd, OFF64_T offset) {
|
||||
ENSURE_MSAN_INITED();
|
||||
|
@ -9,11 +9,11 @@
|
||||
//
|
||||
// This file is a part of MemorySanitizer.
|
||||
//
|
||||
// Linux- and FreeBSD-specific code.
|
||||
// Linux-, NetBSD- and FreeBSD-specific code.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "sanitizer_common/sanitizer_platform.h"
|
||||
#if SANITIZER_FREEBSD || SANITIZER_LINUX
|
||||
#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
|
||||
|
||||
#include "msan.h"
|
||||
#include "msan_thread.h"
|
||||
@ -213,4 +213,4 @@ void MsanTSDDtor(void *tsd) {
|
||||
|
||||
} // namespace __msan
|
||||
|
||||
#endif // SANITIZER_FREEBSD || SANITIZER_LINUX
|
||||
#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD
|
||||
|
@ -4405,7 +4405,7 @@ INTERCEPTOR(char *, tempnam, char *dir, char *pfx) {
|
||||
#define INIT_TEMPNAM
|
||||
#endif
|
||||
|
||||
#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP
|
||||
#if SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && !SANITIZER_NETBSD
|
||||
INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
|
||||
void *ctx;
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name);
|
||||
@ -4414,6 +4414,17 @@ INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name) {
|
||||
return REAL(pthread_setname_np)(thread, name);
|
||||
}
|
||||
#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
|
||||
#elif SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP && SANITIZER_NETBSD
|
||||
INTERCEPTOR(int, pthread_setname_np, uptr thread, const char *name, void *arg) {
|
||||
void *ctx;
|
||||
char newname[32]; // PTHREAD_MAX_NAMELEN_NP=32
|
||||
COMMON_INTERCEPTOR_ENTER(ctx, pthread_setname_np, thread, name, arg);
|
||||
COMMON_INTERCEPTOR_READ_STRING(ctx, name, 0);
|
||||
internal_snprintf(newname, sizeof(newname), name, arg);
|
||||
COMMON_INTERCEPTOR_SET_PTHREAD_NAME(ctx, thread, newname);
|
||||
return REAL(pthread_setname_np)(thread, name, arg);
|
||||
}
|
||||
#define INIT_PTHREAD_SETNAME_NP COMMON_INTERCEPT_FUNCTION(pthread_setname_np);
|
||||
#else
|
||||
#define INIT_PTHREAD_SETNAME_NP
|
||||
#endif
|
||||
|
@ -36,7 +36,7 @@
|
||||
#endif
|
||||
|
||||
// TLS is handled differently on different platforms
|
||||
#if SANITIZER_LINUX
|
||||
#if SANITIZER_LINUX || SANITIZER_NETBSD
|
||||
# define SANITIZER_TLS_INITIAL_EXEC_ATTRIBUTE \
|
||||
__attribute__((tls_model("initial-exec"))) thread_local
|
||||
#else
|
||||
|
@ -87,7 +87,9 @@ extern char **environ; // provided by crt1
|
||||
#include <limits.h> // For NAME_MAX
|
||||
#include <sys/sysctl.h>
|
||||
extern char **environ; // provided by crt1
|
||||
#endif // SANITIZER_NETBSD
|
||||
#include <sys/exec.h>
|
||||
extern struct ps_strings *__ps_strings;
|
||||
#endif // SANITIZER_NETBSD
|
||||
|
||||
#if !SANITIZER_ANDROID
|
||||
#include <sys/signal.h>
|
||||
@ -174,11 +176,11 @@ uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
|
||||
#endif // !SANITIZER_S390
|
||||
|
||||
uptr internal_munmap(void *addr, uptr length) {
|
||||
return internal_syscall(SYSCALL(munmap), (uptr)addr, length);
|
||||
return internal_syscall_ptr(SYSCALL(munmap), (uptr)addr, length);
|
||||
}
|
||||
|
||||
int internal_mprotect(void *addr, uptr length, int prot) {
|
||||
return internal_syscall(SYSCALL(mprotect), (uptr)addr, length, prot);
|
||||
return internal_syscall_ptr(SYSCALL(mprotect), (uptr)addr, length, prot);
|
||||
}
|
||||
|
||||
uptr internal_close(fd_t fd) {
|
||||
@ -189,7 +191,7 @@ uptr internal_open(const char *filename, int flags) {
|
||||
#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
|
||||
return internal_syscall(SYSCALL(openat), AT_FDCWD, (uptr)filename, flags);
|
||||
#else
|
||||
return internal_syscall(SYSCALL(open), (uptr)filename, flags);
|
||||
return internal_syscall_ptr(SYSCALL(open), (uptr)filename, flags);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -198,36 +200,28 @@ uptr internal_open(const char *filename, int flags, u32 mode) {
|
||||
return internal_syscall(SYSCALL(openat), AT_FDCWD, (uptr)filename, flags,
|
||||
mode);
|
||||
#else
|
||||
return internal_syscall(SYSCALL(open), (uptr)filename, flags, mode);
|
||||
return internal_syscall_ptr(SYSCALL(open), (uptr)filename, flags, mode);
|
||||
#endif
|
||||
}
|
||||
|
||||
uptr internal_read(fd_t fd, void *buf, uptr count) {
|
||||
sptr res;
|
||||
#if SANITIZER_NETBSD
|
||||
HANDLE_EINTR(res, internal_syscall_ptr(SYSCALL(read), fd, buf, count));
|
||||
#else
|
||||
HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(read), fd, (uptr)buf,
|
||||
HANDLE_EINTR(res, (sptr)internal_syscall_ptr(SYSCALL(read), fd, (uptr)buf,
|
||||
count));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
uptr internal_write(fd_t fd, const void *buf, uptr count) {
|
||||
sptr res;
|
||||
#if SANITIZER_NETBSD
|
||||
HANDLE_EINTR(res, internal_syscall_ptr(SYSCALL(write), fd, buf, count));
|
||||
#else
|
||||
HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(write), fd, (uptr)buf,
|
||||
HANDLE_EINTR(res, (sptr)internal_syscall_ptr(SYSCALL(write), fd, (uptr)buf,
|
||||
count));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
uptr internal_ftruncate(fd_t fd, uptr size) {
|
||||
sptr res;
|
||||
#if SANITIZER_NETBSD
|
||||
HANDLE_EINTR(res, internal_syscall(SYSCALL(ftruncate), fd, 0, (s64)size));
|
||||
HANDLE_EINTR(res, internal_syscall64(SYSCALL(ftruncate), fd, 0, (s64)size));
|
||||
#else
|
||||
HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(ftruncate), fd,
|
||||
(OFF_T)size));
|
||||
@ -304,7 +298,7 @@ static void kernel_stat_to_stat(struct kernel_stat *in, struct stat *out) {
|
||||
|
||||
uptr internal_stat(const char *path, void *buf) {
|
||||
#if SANITIZER_FREEBSD || SANITIZER_NETBSD
|
||||
return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path,
|
||||
return internal_syscall_ptr(SYSCALL(fstatat), AT_FDCWD, (uptr)path,
|
||||
(uptr)buf, 0);
|
||||
#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
|
||||
return internal_syscall(SYSCALL(newfstatat), AT_FDCWD, (uptr)path,
|
||||
@ -329,7 +323,7 @@ uptr internal_stat(const char *path, void *buf) {
|
||||
|
||||
uptr internal_lstat(const char *path, void *buf) {
|
||||
#if SANITIZER_NETBSD
|
||||
return internal_syscall(SYSCALL(lstat), path, buf);
|
||||
return internal_syscall_ptr(SYSCALL(lstat), path, buf);
|
||||
#elif SANITIZER_FREEBSD
|
||||
return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path,
|
||||
(uptr)buf, AT_SYMLINK_NOFOLLOW);
|
||||
@ -355,15 +349,15 @@ uptr internal_lstat(const char *path, void *buf) {
|
||||
}
|
||||
|
||||
uptr internal_fstat(fd_t fd, void *buf) {
|
||||
#if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS || SANITIZER_NETBSD
|
||||
# if SANITIZER_MIPS64
|
||||
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS
|
||||
# if SANITIZER_MIPS64 && !SANITIZER_NETBSD
|
||||
// For mips64, fstat syscall fills buffer in the format of kernel_stat
|
||||
struct kernel_stat kbuf;
|
||||
int res = internal_syscall(SYSCALL(fstat), fd, &kbuf);
|
||||
kernel_stat_to_stat(&kbuf, (struct stat *)buf);
|
||||
return res;
|
||||
# else
|
||||
return internal_syscall(SYSCALL(fstat), fd, (uptr)buf);
|
||||
return internal_syscall_ptr(SYSCALL(fstat), fd, (uptr)buf);
|
||||
# endif
|
||||
#else
|
||||
struct stat64 buf64;
|
||||
@ -389,13 +383,11 @@ uptr internal_dup2(int oldfd, int newfd) {
|
||||
}
|
||||
|
||||
uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
|
||||
#if SANITIZER_NETBSD
|
||||
return internal_syscall_ptr(SYSCALL(readlink), path, buf, bufsize);
|
||||
#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
|
||||
#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
|
||||
return internal_syscall(SYSCALL(readlinkat), AT_FDCWD,
|
||||
(uptr)path, (uptr)buf, bufsize);
|
||||
#else
|
||||
return internal_syscall(SYSCALL(readlink), (uptr)path, (uptr)buf, bufsize);
|
||||
return internal_syscall_ptr(SYSCALL(readlink), path, buf, bufsize);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -403,7 +395,7 @@ uptr internal_unlink(const char *path) {
|
||||
#if SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
|
||||
return internal_syscall(SYSCALL(unlinkat), AT_FDCWD, (uptr)path, 0);
|
||||
#else
|
||||
return internal_syscall(SYSCALL(unlink), (uptr)path);
|
||||
return internal_syscall_ptr(SYSCALL(unlink), (uptr)path);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -412,7 +404,7 @@ uptr internal_rename(const char *oldpath, const char *newpath) {
|
||||
return internal_syscall(SYSCALL(renameat), AT_FDCWD, (uptr)oldpath, AT_FDCWD,
|
||||
(uptr)newpath);
|
||||
#else
|
||||
return internal_syscall(SYSCALL(rename), (uptr)oldpath, (uptr)newpath);
|
||||
return internal_syscall_ptr(SYSCALL(rename), (uptr)oldpath, (uptr)newpath);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -433,14 +425,14 @@ unsigned int internal_sleep(unsigned int seconds) {
|
||||
struct timespec ts;
|
||||
ts.tv_sec = 1;
|
||||
ts.tv_nsec = 0;
|
||||
int res = internal_syscall(SYSCALL(nanosleep), &ts, &ts);
|
||||
int res = internal_syscall_ptr(SYSCALL(nanosleep), &ts, &ts);
|
||||
if (res) return ts.tv_sec;
|
||||
return 0;
|
||||
}
|
||||
|
||||
uptr internal_execve(const char *filename, char *const argv[],
|
||||
char *const envp[]) {
|
||||
return internal_syscall(SYSCALL(execve), (uptr)filename, (uptr)argv,
|
||||
return internal_syscall_ptr(SYSCALL(execve), (uptr)filename, (uptr)argv,
|
||||
(uptr)envp);
|
||||
}
|
||||
|
||||
@ -474,11 +466,7 @@ u64 NanoTime() {
|
||||
kernel_timeval tv;
|
||||
#endif
|
||||
internal_memset(&tv, 0, sizeof(tv));
|
||||
#if SANITIZER_NETBSD
|
||||
internal_syscall_ptr(SYSCALL(gettimeofday), &tv, NULL);
|
||||
#else
|
||||
internal_syscall(SYSCALL(gettimeofday), (uptr)&tv, 0);
|
||||
#endif
|
||||
internal_syscall_ptr(SYSCALL(gettimeofday), &tv, 0);
|
||||
return (u64)tv.tv_sec * 1000*1000*1000 + tv.tv_usec * 1000;
|
||||
}
|
||||
|
||||
@ -524,13 +512,13 @@ const char *GetEnv(const char *name) {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
extern "C" {
|
||||
SANITIZER_WEAK_ATTRIBUTE extern void *__libc_stack_end;
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !SANITIZER_GO && !SANITIZER_FREEBSD
|
||||
#if !SANITIZER_GO && !SANITIZER_FREEBSD && !SANITIZER_NETBSD
|
||||
static void ReadNullSepFileToArray(const char *path, char ***arr,
|
||||
int arr_size) {
|
||||
char *buff;
|
||||
@ -556,7 +544,22 @@ static void ReadNullSepFileToArray(const char *path, char ***arr,
|
||||
#endif
|
||||
|
||||
static void GetArgsAndEnv(char ***argv, char ***envp) {
|
||||
#if !SANITIZER_FREEBSD
|
||||
#if 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>.
|
||||
ps_strings *pss;
|
||||
size_t sz = sizeof(pss);
|
||||
if (sysctlbyname("kern.ps_strings", &pss, &sz, NULL, 0) == -1) {
|
||||
Printf("sysctl kern.ps_strings failed\n");
|
||||
Die();
|
||||
}
|
||||
*argv = pss->ps_argvstr;
|
||||
*envp = pss->ps_envstr;
|
||||
#elif SANITIZER_NETBSD
|
||||
*argv = __ps_strings->ps_argvstr;
|
||||
*argv = __ps_strings->ps_envstr;
|
||||
#else
|
||||
#if !SANITIZER_GO
|
||||
if (&__libc_stack_end) {
|
||||
#endif
|
||||
@ -571,18 +574,6 @@ static void GetArgsAndEnv(char ***argv, char ***envp) {
|
||||
ReadNullSepFileToArray("/proc/self/environ", envp, kMaxEnvp);
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
// 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>.
|
||||
ps_strings *pss;
|
||||
size_t sz = sizeof(pss);
|
||||
if (sysctlbyname("kern.ps_strings", &pss, &sz, NULL, 0) == -1) {
|
||||
Printf("sysctl kern.ps_strings failed\n");
|
||||
Die();
|
||||
}
|
||||
*argv = pss->ps_argvstr;
|
||||
*envp = pss->ps_envstr;
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -594,8 +585,22 @@ char **GetArgv() {
|
||||
|
||||
void ReExec() {
|
||||
char **argv, **envp;
|
||||
const char *pathname = "/proc/self/exe";
|
||||
|
||||
#if SANITIZER_NETBSD
|
||||
static const int name[] = {
|
||||
CTL_KERN, KERN_PROC_ARGS, -1, KERN_PROC_PATHNAME,
|
||||
};
|
||||
char path[400];
|
||||
size_t len;
|
||||
|
||||
len = sizeof(path);
|
||||
if (sysctl(name, ARRAY_SIZE(name), path, &len, NULL, 0) != -1)
|
||||
pathname = path;
|
||||
#endif
|
||||
|
||||
GetArgsAndEnv(&argv, &envp);
|
||||
uptr rv = internal_execve("/proc/self/exe", argv, envp);
|
||||
uptr rv = internal_execve(pathname, argv, envp);
|
||||
int rverrno;
|
||||
CHECK_EQ(internal_iserror(rv, &rverrno), true);
|
||||
Printf("execve failed, errno %d\n", rverrno);
|
||||
@ -698,13 +703,8 @@ uptr internal_ptrace(int request, int pid, void *addr, void *data) {
|
||||
}
|
||||
|
||||
uptr internal_waitpid(int pid, int *status, int options) {
|
||||
#if SANITIZER_NETBSD
|
||||
return internal_syscall(SYSCALL(wait4), pid, status, options,
|
||||
NULL /* rusage */);
|
||||
#else
|
||||
return internal_syscall(SYSCALL(wait4), pid, (uptr)status, options,
|
||||
return internal_syscall_ptr(SYSCALL(wait4), pid, (uptr)status, options,
|
||||
0 /* rusage */);
|
||||
#endif
|
||||
}
|
||||
|
||||
uptr internal_getpid() {
|
||||
@ -716,14 +716,12 @@ uptr internal_getppid() {
|
||||
}
|
||||
|
||||
uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count) {
|
||||
#if SANITIZER_NETBSD
|
||||
return internal_syscall(SYSCALL(getdents), fd, dirp, (uptr)count);
|
||||
#elif SANITIZER_FREEBSD
|
||||
#if SANITIZER_FREEBSD
|
||||
return internal_syscall(SYSCALL(getdirentries), fd, (uptr)dirp, count, NULL);
|
||||
#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
|
||||
return internal_syscall(SYSCALL(getdents64), fd, (uptr)dirp, count);
|
||||
#else
|
||||
return internal_syscall(SYSCALL(getdents), fd, (uptr)dirp, count);
|
||||
return internal_syscall_ptr(SYSCALL(getdents), fd, (uptr)dirp, count);
|
||||
#endif
|
||||
}
|
||||
|
||||
@ -742,7 +740,7 @@ uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5) {
|
||||
#endif
|
||||
|
||||
uptr internal_sigaltstack(const void *ss, void *oss) {
|
||||
return internal_syscall(SYSCALL(sigaltstack), (uptr)ss, (uptr)oss);
|
||||
return internal_syscall_ptr(SYSCALL(sigaltstack), (uptr)ss, (uptr)oss);
|
||||
}
|
||||
|
||||
int internal_fork() {
|
||||
@ -824,7 +822,7 @@ int internal_sigaction_syscall(int signum, const void *act, void *oldact) {
|
||||
uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
|
||||
__sanitizer_sigset_t *oldset) {
|
||||
#if SANITIZER_FREEBSD || SANITIZER_NETBSD
|
||||
return internal_syscall(SYSCALL(sigprocmask), how, set, oldset);
|
||||
return internal_syscall_ptr(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;
|
||||
|
@ -128,6 +128,8 @@ uptr __sanitizer_in_addr_sz(int af) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr);
|
||||
|
||||
int glob_nomatch = GLOB_NOMATCH;
|
||||
int glob_altdirfunc = GLOB_ALTDIRFUNC;
|
||||
|
||||
|
@ -313,7 +313,7 @@ struct __sanitizer_wordexp_t {
|
||||
uptr we_nbytes;
|
||||
};
|
||||
|
||||
typedef void __sanitizer_FILE;
|
||||
typedef char __sanitizer_FILE;
|
||||
#define SANITIZER_HAS_STRUCT_FILE 0
|
||||
|
||||
extern int shmctl_ipc_stat;
|
||||
|
@ -43,8 +43,12 @@
|
||||
# endif
|
||||
#elif defined(__x86_64__) && (SANITIZER_FREEBSD || SANITIZER_MAC)
|
||||
# define internal_syscall __syscall
|
||||
# define internal_syscall64 __syscall
|
||||
# define internal_syscall_ptr __syscall
|
||||
# else
|
||||
# define internal_syscall syscall
|
||||
# define internal_syscall64 syscall
|
||||
# define internal_syscall_ptr syscall
|
||||
#endif
|
||||
|
||||
bool internal_iserror(uptr retval, int *rverrno) {
|
||||
|
@ -68,6 +68,21 @@ elif [ "`uname -a | grep FreeBSD`" != "" ]; then
|
||||
../../sanitizer_common/sanitizer_linux_libcdep.cc
|
||||
../../sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
|
||||
"
|
||||
elif [ "`uname -a | grep NetBSD`" != "" ]; then
|
||||
SUFFIX="netbsd_amd64"
|
||||
OSCFLAGS="-fno-strict-aliasing -fPIC -Werror"
|
||||
OSLDFLAGS="-lpthread -fPIC -fpie"
|
||||
SRCS="
|
||||
$SRCS
|
||||
../rtl/tsan_platform_linux.cc
|
||||
../../sanitizer_common/sanitizer_posix.cc
|
||||
../../sanitizer_common/sanitizer_posix_libcdep.cc
|
||||
../../sanitizer_common/sanitizer_procmaps_common.cc
|
||||
../../sanitizer_common/sanitizer_procmaps_freebsd.cc
|
||||
../../sanitizer_common/sanitizer_linux.cc
|
||||
../../sanitizer_common/sanitizer_linux_libcdep.cc
|
||||
../../sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
|
||||
"
|
||||
elif [ "`uname -a | grep Darwin`" != "" ]; then
|
||||
SUFFIX="darwin_amd64"
|
||||
OSCFLAGS="-fPIC -Wno-unused-const-variable -Wno-unknown-warning-option -isysroot $(xcodebuild -version -sdk macosx Path) -mmacosx-version-min=10.7"
|
||||
|
@ -43,8 +43,16 @@ using namespace __tsan; // NOLINT
|
||||
#if SANITIZER_NETBSD
|
||||
#define dirfd(dirp) (*(int *)(dirp))
|
||||
#define fileno_unlocked fileno
|
||||
#define stdout __sF[1]
|
||||
#define stderr __sF[2]
|
||||
|
||||
#if _LP64
|
||||
#define __sF_size 152
|
||||
#else
|
||||
#define __sF_size 88
|
||||
#endif
|
||||
|
||||
#define stdout ((char*)&__sF + (__sF_size * 1))
|
||||
#define stderr ((char*)&__sF + (__sF_size * 2))
|
||||
|
||||
#endif
|
||||
|
||||
#if SANITIZER_ANDROID
|
||||
@ -99,7 +107,7 @@ extern "C" int dirfd(void *dirp);
|
||||
extern "C" int mallopt(int param, int value);
|
||||
#endif
|
||||
#if SANITIZER_NETBSD
|
||||
extern __sanitizer_FILE **__sF;
|
||||
extern __sanitizer_FILE __sF[];
|
||||
#else
|
||||
extern __sanitizer_FILE *stdout, *stderr;
|
||||
#endif
|
||||
|
@ -42,6 +42,19 @@ C/C++ on linux/x86_64 and freebsd/x86_64
|
||||
7b00 0000 0000 - 7c00 0000 0000: heap
|
||||
7c00 0000 0000 - 7e80 0000 0000: -
|
||||
7e80 0000 0000 - 8000 0000 0000: modules and main thread stack
|
||||
|
||||
C/C++ on netbsd/amd64 can reuse the same mapping:
|
||||
* The address space starts from 0x1000 (option with 0x0) and ends with
|
||||
0x7f7ffffff000.
|
||||
* LoAppMem-kHeapMemEnd can be reused as it is.
|
||||
* No VDSO support.
|
||||
* No MidAppMem region.
|
||||
* No additional HeapMem region.
|
||||
* HiAppMem contains the stack, loader, shared libraries and heap.
|
||||
* Stack on NetBSD/amd64 has prereserved 128MB.
|
||||
* Heap grows downwards (top-down).
|
||||
* ASLR must be disabled per-process or globally.
|
||||
|
||||
*/
|
||||
struct Mapping {
|
||||
static const uptr kMetaShadowBeg = 0x300000000000ull;
|
||||
|
@ -14,11 +14,12 @@
|
||||
|
||||
|
||||
#include "sanitizer_common/sanitizer_platform.h"
|
||||
#if SANITIZER_LINUX || SANITIZER_FREEBSD
|
||||
#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD
|
||||
|
||||
#include "sanitizer_common/sanitizer_common.h"
|
||||
#include "sanitizer_common/sanitizer_libc.h"
|
||||
#include "sanitizer_common/sanitizer_linux.h"
|
||||
#include "sanitizer_common/sanitizer_platform_limits_netbsd.h"
|
||||
#include "sanitizer_common/sanitizer_platform_limits_posix.h"
|
||||
#include "sanitizer_common/sanitizer_posix.h"
|
||||
#include "sanitizer_common/sanitizer_procmaps.h"
|
||||
@ -401,4 +402,4 @@ void cur_thread_finalize() {
|
||||
|
||||
} // namespace __tsan
|
||||
|
||||
#endif // SANITIZER_LINUX || SANITIZER_FREEBSD
|
||||
#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD
|
||||
|
@ -9,7 +9,7 @@
|
||||
//
|
||||
// This file is a part of ThreadSanitizer (TSan), a race detector.
|
||||
//
|
||||
// Test utils, Linux, FreeBSD and Darwin implementation.
|
||||
// Test utils, Linux, FreeBSD, NetBSD and Darwin implementation.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "sanitizer_common/sanitizer_atomic.h"
|
||||
@ -270,7 +270,7 @@ void ScopedThread::Impl::HandleEvent(Event *ev) {
|
||||
}
|
||||
}
|
||||
CHECK_NE(tsan_mop, 0);
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__)
|
||||
#if defined(__FreeBSD__) || defined(__APPLE__) || defined(__NetBSD__)
|
||||
const int ErrCode = ESOCKTNOSUPPORT;
|
||||
#else
|
||||
const int ErrCode = ECHRNG;
|
||||
|
@ -29,8 +29,7 @@ config.substitutions.append( ("%clangxx_msan ", build_invocation(clang_msan_cxxf
|
||||
# Default test suffixes.
|
||||
config.suffixes = ['.c', '.cc', '.cpp']
|
||||
|
||||
# MemorySanitizer tests are currently supported on Linux only.
|
||||
if config.host_os not in ['Linux']:
|
||||
if config.host_os not in ['Linux', 'NetBSD']:
|
||||
config.unsupported = True
|
||||
|
||||
# For mips64, mips64el we have forced store_context_size to 1 because these
|
||||
|
@ -79,8 +79,7 @@ config.substitutions.append( ("%deflake ", os.path.join(os.path.dirname(__file__
|
||||
# Default test suffixes.
|
||||
config.suffixes = ['.c', '.cc', '.cpp', '.m', '.mm']
|
||||
|
||||
# ThreadSanitizer tests are currently supported on FreeBSD, Linux and Darwin.
|
||||
if config.host_os not in ['FreeBSD', 'Linux', 'Darwin']:
|
||||
if config.host_os not in ['FreeBSD', 'Linux', 'Darwin', 'NetBSD']:
|
||||
config.unsupported = True
|
||||
|
||||
if config.android:
|
||||
|
@ -12,8 +12,8 @@
|
||||
// XFAIL: aarch64
|
||||
// XFAIL: powerpc64
|
||||
|
||||
// MAP_32BIT doesn't exist on OS X.
|
||||
// UNSUPPORTED: darwin
|
||||
// MAP_32BIT doesn't exist on OS X and NetBSD.
|
||||
// UNSUPPORTED: darwin,netbsd
|
||||
|
||||
void *Thread(void *ptr) {
|
||||
*(int*)ptr = 42;
|
||||
@ -45,4 +45,3 @@ int main() {
|
||||
|
||||
// CHECK: WARNING: ThreadSanitizer: data race
|
||||
// CHECK: DONE
|
||||
|
||||
|
@ -11,7 +11,8 @@
|
||||
char buffer[1000];
|
||||
|
||||
void *Thread(void *p) {
|
||||
return strerror_r(TEST_ERROR, buffer, sizeof(buffer));
|
||||
strerror_r(TEST_ERROR, buffer, sizeof(buffer));
|
||||
return buffer;
|
||||
}
|
||||
|
||||
int main() {
|
||||
|
Loading…
x
Reference in New Issue
Block a user