mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-18 19:06:44 +00:00
Switch syscall(2)/__syscall(2) calls to libc calls on NetBSD
Summary: When possible, switch syscall(2)/__syscall(2) calls to direct calls of internal libc symbols. Add a new function to detect address of a libc symbol of a function that could be intercepted. With the address detector in GetRealLibcAddress(), an optional interceptor of libc call will be bypassed. The original approach with syscall(2)/__syscall(2) wasn't portable across supported ABIs and CPU architectures. The indirect syscall interface is also a candidate for removal in future revisions of NetBSD, as the C language ABI is not a good domain for serialization of arbitrary functions arguments. Switch the following functions to libc calls: - internal_mmap() - internal_munmap() - internal_mprotect() - internal_close() - internal_open() - internal_read() - internal_write() - internal_ftruncate() - internal_stat() - internal_lstat() - internal_fstat() - internal_dup2() - internal_readlink() - internal_unlink() - internal_rename() - internal_sched_yield() - internal__exit() - internal_sleep() - internal_execve() - NanoTime() - internal_clock_gettime() - internal_waitpid() - internal_getpid() - internal_getppid() - internal_getdents() - internal_lseek() - internal_sigaltstack() - internal_fork() - internal_sigprocmask() - internal_sysctl() - internal_sigemptyset() - internal_sigfillset() - GetTid() - TgKill() This revision leaves room for refactoring in subsequent commits. Reviewers: vitalybuka, kcc, joerg Reviewed By: vitalybuka Subscribers: mgorny, fedor.sergeev, jfb, loverszhaokai, devnexen, kubamracek, llvm-commits, ro, #sanitizers Tags: #sanitizers Differential Revision: https://reviews.llvm.org/D51419 llvm-svn: 343523
This commit is contained in:
parent
dcf1d97c5c
commit
162aac511a
@ -16,6 +16,7 @@ set(SANITIZER_SOURCES_NOTERMINATION
|
||||
sanitizer_linux.cc
|
||||
sanitizer_linux_s390.cc
|
||||
sanitizer_mac.cc
|
||||
sanitizer_netbsd.cc
|
||||
sanitizer_openbsd.cc
|
||||
sanitizer_persistent_allocator.cc
|
||||
sanitizer_platform_limits_linux.cc
|
||||
|
@ -31,10 +31,6 @@
|
||||
#include <asm/param.h>
|
||||
#endif
|
||||
|
||||
#if SANITIZER_NETBSD
|
||||
#include <lwp.h>
|
||||
#endif
|
||||
|
||||
// For mips64, syscall(__NR_stat) fills the buffer in the 'struct kernel_stat'
|
||||
// format. Struct kernel_stat is defined as 'struct stat' in asm/stat.h. To
|
||||
// access stat from asm/stat.h, without conflicting with definition in
|
||||
@ -174,14 +170,11 @@ namespace __sanitizer {
|
||||
#endif
|
||||
|
||||
// --------------- sanitizer_libc.h
|
||||
#if !SANITIZER_SOLARIS
|
||||
#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD
|
||||
#if !SANITIZER_S390 && !SANITIZER_OPENBSD
|
||||
uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
|
||||
OFF_T offset) {
|
||||
#if SANITIZER_NETBSD
|
||||
return internal_syscall64(SYSCALL(mmap), addr, length, prot, flags, fd,
|
||||
(long)0, offset);
|
||||
#elif SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS
|
||||
#if SANITIZER_FREEBSD || SANITIZER_LINUX_USES_64BIT_SYSCALLS
|
||||
return internal_syscall(SYSCALL(mmap), (uptr)addr, length, prot, flags, fd,
|
||||
offset);
|
||||
#else
|
||||
@ -240,12 +233,8 @@ uptr internal_write(fd_t fd, const void *buf, uptr count) {
|
||||
|
||||
uptr internal_ftruncate(fd_t fd, uptr size) {
|
||||
sptr res;
|
||||
#if SANITIZER_NETBSD
|
||||
HANDLE_EINTR(res, internal_syscall64(SYSCALL(ftruncate), fd, 0, (s64)size));
|
||||
#else
|
||||
HANDLE_EINTR(res, (sptr)internal_syscall(SYSCALL(ftruncate), fd,
|
||||
(OFF_T)size));
|
||||
#endif
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -317,7 +306,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_NETBSD || SANITIZER_OPENBSD
|
||||
#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
|
||||
return internal_syscall_ptr(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf,
|
||||
0);
|
||||
#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
|
||||
@ -342,9 +331,7 @@ uptr internal_stat(const char *path, void *buf) {
|
||||
}
|
||||
|
||||
uptr internal_lstat(const char *path, void *buf) {
|
||||
#if SANITIZER_NETBSD
|
||||
return internal_syscall_ptr(SYSCALL(lstat), path, buf);
|
||||
#elif SANITIZER_FREEBSD || SANITIZER_OPENBSD
|
||||
#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
|
||||
return internal_syscall(SYSCALL(fstatat), AT_FDCWD, (uptr)path, (uptr)buf,
|
||||
AT_SYMLINK_NOFOLLOW);
|
||||
#elif SANITIZER_USES_CANONICAL_LINUX_SYSCALLS
|
||||
@ -369,9 +356,9 @@ uptr internal_lstat(const char *path, void *buf) {
|
||||
}
|
||||
|
||||
uptr internal_fstat(fd_t fd, void *buf) {
|
||||
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD || \
|
||||
#if SANITIZER_FREEBSD || SANITIZER_OPENBSD || \
|
||||
SANITIZER_LINUX_USES_64BIT_SYSCALLS
|
||||
#if SANITIZER_MIPS64 && !SANITIZER_NETBSD && !SANITIZER_OPENBSD
|
||||
#if SANITIZER_MIPS64 && !SANITIZER_OPENBSD
|
||||
// For mips64, fstat syscall fills buffer in the format of kernel_stat
|
||||
struct kernel_stat kbuf;
|
||||
int res = internal_syscall(SYSCALL(fstat), fd, &kbuf);
|
||||
@ -437,7 +424,7 @@ uptr internal_sched_yield() {
|
||||
}
|
||||
|
||||
void internal__exit(int exitcode) {
|
||||
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
|
||||
#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
|
||||
internal_syscall(SYSCALL(exit), exitcode);
|
||||
#else
|
||||
internal_syscall(SYSCALL(exit_group), exitcode);
|
||||
@ -459,7 +446,7 @@ uptr internal_execve(const char *filename, char *const argv[],
|
||||
return internal_syscall_ptr(SYSCALL(execve), (uptr)filename, (uptr)argv,
|
||||
(uptr)envp);
|
||||
}
|
||||
#endif // !SANITIZER_SOLARIS
|
||||
#endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD
|
||||
|
||||
// ----------------- sanitizer_common.h
|
||||
bool FileExists(const char *filename) {
|
||||
@ -474,6 +461,7 @@ bool FileExists(const char *filename) {
|
||||
return S_ISREG(st.st_mode);
|
||||
}
|
||||
|
||||
#if !SANITIZER_NETBSD
|
||||
tid_t GetTid() {
|
||||
#if SANITIZER_FREEBSD
|
||||
long Tid;
|
||||
@ -481,8 +469,6 @@ tid_t GetTid() {
|
||||
return Tid;
|
||||
#elif SANITIZER_OPENBSD
|
||||
return internal_syscall(SYSCALL(getthrid));
|
||||
#elif SANITIZER_NETBSD
|
||||
return _lwp_self();
|
||||
#elif SANITIZER_SOLARIS
|
||||
return thr_self();
|
||||
#else
|
||||
@ -498,18 +484,16 @@ int TgKill(pid_t pid, tid_t tid, int sig) {
|
||||
#elif SANITIZER_OPENBSD
|
||||
(void)pid;
|
||||
return internal_syscall(SYSCALL(thrkill), tid, sig, nullptr);
|
||||
#elif SANITIZER_NETBSD
|
||||
(void)pid;
|
||||
return _lwp_kill(tid, sig);
|
||||
#elif SANITIZER_SOLARIS
|
||||
(void)pid;
|
||||
return thr_kill(tid, sig);
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
|
||||
#if !SANITIZER_SOLARIS
|
||||
#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD
|
||||
u64 NanoTime() {
|
||||
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
|
||||
#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
|
||||
timeval tv;
|
||||
#else
|
||||
kernel_timeval tv;
|
||||
@ -522,13 +506,13 @@ u64 NanoTime() {
|
||||
uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {
|
||||
return internal_syscall_ptr(SYSCALL(clock_gettime), clk_id, tp);
|
||||
}
|
||||
#endif // !SANITIZER_SOLARIS
|
||||
#endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD
|
||||
|
||||
// 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 || \
|
||||
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD || \
|
||||
SANITIZER_SOLARIS
|
||||
if (::environ != 0) {
|
||||
uptr NameLen = internal_strlen(name);
|
||||
@ -721,7 +705,9 @@ void BlockingMutex::CheckLocked() {
|
||||
// The actual size of this structure is specified by d_reclen.
|
||||
// Note that getdents64 uses a different structure format. We only provide the
|
||||
// 32-bit syscall here.
|
||||
#if SANITIZER_NETBSD || SANITIZER_OPENBSD
|
||||
#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 {
|
||||
@ -748,23 +734,11 @@ struct linux_dirent {
|
||||
};
|
||||
#endif
|
||||
|
||||
#if !SANITIZER_SOLARIS
|
||||
#if !SANITIZER_SOLARIS && !SANITIZER_NETBSD
|
||||
// Syscall wrappers.
|
||||
uptr internal_ptrace(int request, int pid, void *addr, void *data) {
|
||||
#if SANITIZER_NETBSD
|
||||
// XXX We need additional work for ptrace:
|
||||
// - for request, we use PT_FOO whereas Linux uses PTRACE_FOO
|
||||
// - data is int for us, but void * for Linux
|
||||
// - Linux sometimes uses data in the case where we use addr instead
|
||||
// At this moment, this function is used only within
|
||||
// "#if SANITIZER_LINUX && defined(__x86_64__)" block in
|
||||
// sanitizer_stoptheworld_linux_libcdep.cc.
|
||||
return internal_syscall_ptr(SYSCALL(ptrace), request, pid, (uptr)addr,
|
||||
(uptr)data);
|
||||
#else
|
||||
return internal_syscall(SYSCALL(ptrace), request, pid, (uptr)addr,
|
||||
(uptr)data);
|
||||
#endif
|
||||
}
|
||||
|
||||
uptr internal_waitpid(int pid, int *status, int options) {
|
||||
@ -791,11 +765,7 @@ uptr internal_getdents(fd_t fd, struct linux_dirent *dirp, unsigned int count) {
|
||||
}
|
||||
|
||||
uptr internal_lseek(fd_t fd, OFF_T offset, int whence) {
|
||||
#if SANITIZER_NETBSD
|
||||
return internal_syscall64(SYSCALL(lseek), fd, 0, offset, whence);
|
||||
#else
|
||||
return internal_syscall(SYSCALL(lseek), fd, offset, whence);
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SANITIZER_LINUX
|
||||
@ -816,7 +786,7 @@ int internal_fork() {
|
||||
#endif
|
||||
}
|
||||
|
||||
#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_OPENBSD
|
||||
#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
|
||||
int internal_sysctl(const int *name, unsigned int namelen, void *oldp,
|
||||
uptr *oldlenp, const void *newp, uptr newlen) {
|
||||
#if SANITIZER_OPENBSD
|
||||
@ -897,7 +867,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 || SANITIZER_OPENBSD
|
||||
#if SANITIZER_FREEBSD || SANITIZER_OPENBSD
|
||||
return internal_syscall_ptr(SYSCALL(sigprocmask), how, set, oldset);
|
||||
#else
|
||||
__sanitizer_kernel_sigset_t *k_set = (__sanitizer_kernel_sigset_t *)set;
|
||||
@ -937,8 +907,9 @@ bool internal_sigismember(__sanitizer_sigset_t *set, int signum) {
|
||||
return k_set->sig[idx] & (1 << bit);
|
||||
}
|
||||
#endif // SANITIZER_LINUX
|
||||
#endif // !SANITIZER_SOLARIS
|
||||
#endif // !SANITIZER_SOLARIS && !SANITIZER_NETBSD
|
||||
|
||||
#if !SANITIZER_NETBSD
|
||||
// ThreadLister implementation.
|
||||
ThreadLister::ThreadLister(pid_t pid) : pid_(pid), buffer_(4096) {
|
||||
char task_directory_path[80];
|
||||
@ -1025,6 +996,7 @@ ThreadLister::~ThreadLister() {
|
||||
if (!internal_iserror(descriptor_))
|
||||
internal_close(descriptor_);
|
||||
}
|
||||
#endif
|
||||
|
||||
#if SANITIZER_WORDSIZE == 32
|
||||
// Take care of unusable kernel area in top gigabyte.
|
||||
|
326
compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cc
Normal file
326
compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cc
Normal file
@ -0,0 +1,326 @@
|
||||
//===-- sanitizer_netbsd.cc -----------------------------------------------===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file is shared between Sanitizer run-time libraries and implements
|
||||
// NetBSD-specific functions from sanitizer_libc.h.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "sanitizer_platform.h"
|
||||
|
||||
#if SANITIZER_NETBSD
|
||||
|
||||
#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/exec.h>
|
||||
#include <sys/mman.h>
|
||||
#include <sys/ptrace.h>
|
||||
#include <sys/resource.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/syscall.h>
|
||||
#include <sys/sysctl.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include <dlfcn.h>
|
||||
#include <errno.h>
|
||||
#include <fcntl.h>
|
||||
#include <limits.h>
|
||||
#include <link.h>
|
||||
#include <lwp.h>
|
||||
#include <pthread.h>
|
||||
#include <sched.h>
|
||||
#include <signal.h>
|
||||
#include <ucontext.h>
|
||||
#include <unistd.h>
|
||||
|
||||
extern "C" void *__mmap(void *, size_t, int, int, int, int,
|
||||
off_t) SANITIZER_WEAK_ATTRIBUTE;
|
||||
extern "C" int __sysctl(const int *, unsigned int, void *, size_t *,
|
||||
const void *, size_t) SANITIZER_WEAK_ATTRIBUTE;
|
||||
extern "C" int _sys_close(int) SANITIZER_WEAK_ATTRIBUTE;
|
||||
extern "C" int _sys_open(const char *, int, ...) SANITIZER_WEAK_ATTRIBUTE;
|
||||
extern "C" ssize_t _sys_read(int, void *, size_t) SANITIZER_WEAK_ATTRIBUTE;
|
||||
extern "C" ssize_t _sys_write(int, const void *,
|
||||
size_t) SANITIZER_WEAK_ATTRIBUTE;
|
||||
extern "C" int __ftruncate(int, int, off_t) SANITIZER_WEAK_ATTRIBUTE;
|
||||
extern "C" ssize_t _sys_readlink(const char *, char *,
|
||||
size_t) SANITIZER_WEAK_ATTRIBUTE;
|
||||
extern "C" int _sys_sched_yield() SANITIZER_WEAK_ATTRIBUTE;
|
||||
extern "C" int _sys___nanosleep50(const void *,
|
||||
void *) SANITIZER_WEAK_ATTRIBUTE;
|
||||
extern "C" int _sys_execve(const char *, char *const[],
|
||||
char *const[]) SANITIZER_WEAK_ATTRIBUTE;
|
||||
extern "C" off_t __lseek(int, int, off_t, int) SANITIZER_WEAK_ATTRIBUTE;
|
||||
extern "C" int __fork() SANITIZER_WEAK_ATTRIBUTE;
|
||||
extern "C" int _sys___sigprocmask14(int, const void *,
|
||||
void *) SANITIZER_WEAK_ATTRIBUTE;
|
||||
extern "C" int _sys___wait450(int wpid, int *, int,
|
||||
void *) SANITIZER_WEAK_ATTRIBUTE;
|
||||
|
||||
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);
|
||||
#define DEFINE_INTERNAL(ret_type, func, ...) \
|
||||
ret_type internal_##func(__VA_ARGS__)
|
||||
|
||||
// --------------- sanitizer_libc.h
|
||||
DEFINE_INTERNAL(uptr, mmap, void *addr, uptr length, int prot, int flags,
|
||||
int fd, OFF_T offset) {
|
||||
CHECK(&__mmap);
|
||||
return (uptr)__mmap(addr, length, prot, flags, fd, 0, offset);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, munmap, void *addr, uptr length) {
|
||||
DEFINE__REAL(int, munmap, void *a, uptr b);
|
||||
return _REAL(munmap, addr, length);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(int, mprotect, void *addr, uptr length, int prot) {
|
||||
DEFINE__REAL(int, mprotect, void *a, uptr b, int c);
|
||||
return _REAL(mprotect, addr, length, prot);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, close, fd_t fd) {
|
||||
CHECK(&_sys_close);
|
||||
return _sys_close(fd);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, open, const char *filename, int flags) {
|
||||
CHECK(&_sys_open);
|
||||
return _sys_open(filename, flags);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, open, const char *filename, int flags, u32 mode) {
|
||||
CHECK(&_sys_open);
|
||||
return _sys_open(filename, flags, mode);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, read, fd_t fd, void *buf, uptr count) {
|
||||
sptr res;
|
||||
CHECK(&_sys_read);
|
||||
HANDLE_EINTR(res, (sptr)_sys_read(fd, buf, (size_t)count));
|
||||
return res;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, write, fd_t fd, const void *buf, uptr count) {
|
||||
sptr res;
|
||||
CHECK(&_sys_write);
|
||||
HANDLE_EINTR(res, (sptr)_sys_write(fd, buf, count));
|
||||
return res;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, ftruncate, fd_t fd, uptr size) {
|
||||
sptr res;
|
||||
CHECK(&__ftruncate);
|
||||
HANDLE_EINTR(res, __ftruncate(fd, 0, (s64)size));
|
||||
return res;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, stat, const char *path, void *buf) {
|
||||
DEFINE__REAL(int, __stat50, const char *a, void *b);
|
||||
return _REAL(__stat50, path, buf);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, lstat, const char *path, void *buf) {
|
||||
DEFINE__REAL(int, __lstat50, const char *a, void *b);
|
||||
return _REAL(__lstat50, path, buf);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, fstat, fd_t fd, void *buf) {
|
||||
DEFINE__REAL(int, __fstat50, int a, void *b);
|
||||
return _REAL(__fstat50, fd, buf);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, filesize, fd_t fd) {
|
||||
struct stat st;
|
||||
if (internal_fstat(fd, &st))
|
||||
return -1;
|
||||
return (uptr)st.st_size;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, dup2, int oldfd, int newfd) {
|
||||
DEFINE__REAL(int, dup2, int a, int b);
|
||||
return _REAL(dup2, oldfd, newfd);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, readlink, const char *path, char *buf, uptr bufsize) {
|
||||
CHECK(&_sys_readlink);
|
||||
return (uptr)_sys_readlink(path, buf, bufsize);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, unlink, const char *path) {
|
||||
DEFINE__REAL(int, unlink, const char *a);
|
||||
return _REAL(unlink, path);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, rename, const char *oldpath, const char *newpath) {
|
||||
DEFINE__REAL(int, rename, const char *a, const char *b);
|
||||
return _REAL(rename, oldpath, newpath);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, sched_yield) {
|
||||
CHECK(&_sys_sched_yield);
|
||||
return _sys_sched_yield();
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(void, _exit, int exitcode) {
|
||||
DEFINE__REAL(void, _exit, int a);
|
||||
_REAL(_exit, exitcode);
|
||||
Die(); // Unreachable.
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(unsigned int, sleep, unsigned int seconds) {
|
||||
struct timespec ts;
|
||||
ts.tv_sec = 1;
|
||||
ts.tv_nsec = 0;
|
||||
CHECK(&_sys___nanosleep50);
|
||||
int res = _sys___nanosleep50(&ts, &ts);
|
||||
if (res)
|
||||
return ts.tv_sec;
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, execve, const char *filename, char *const argv[],
|
||||
char *const envp[]) {
|
||||
CHECK(&_sys_execve);
|
||||
return _sys_execve(filename, argv, envp);
|
||||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, 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);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, ptrace, int request, int pid, void *addr, void *data) {
|
||||
Printf("internal_ptrace not implemented for NetBSD");
|
||||
Die();
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, waitpid, int pid, int *status, int options) {
|
||||
CHECK(&_sys___wait450);
|
||||
return _sys___wait450(pid, status, options, 0 /* rusage */);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, getpid) {
|
||||
DEFINE__REAL(int, getpid);
|
||||
return _REAL(getpid);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, getppid) {
|
||||
DEFINE__REAL(int, getppid);
|
||||
return _REAL(getppid);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, 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);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, lseek, fd_t fd, OFF_T offset, int whence) {
|
||||
CHECK(&__lseek);
|
||||
return __lseek(fd, 0, offset, whence);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, prctl, int option, uptr arg2, uptr arg3, uptr arg4,
|
||||
uptr arg5) {
|
||||
Printf("internal_prctl not implemented for NetBSD");
|
||||
Die();
|
||||
return 0;
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, sigaltstack, const void *ss, void *oss) {
|
||||
DEFINE__REAL(int, __sigaltstack14, const void *a, void *b);
|
||||
return _REAL(__sigaltstack14, ss, oss);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(int, fork) {
|
||||
CHECK(&__fork);
|
||||
return __fork();
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(int, 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);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, sigprocmask, int how, __sanitizer_sigset_t *set,
|
||||
__sanitizer_sigset_t *oldset) {
|
||||
CHECK(&_sys___sigprocmask14);
|
||||
return _sys___sigprocmask14(how, set, oldset);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(void, sigfillset, __sanitizer_sigset_t *set) {
|
||||
DEFINE__REAL(int, __sigfillset14, const void *a);
|
||||
(void)_REAL(__sigfillset14, set);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(void, sigemptyset, __sanitizer_sigset_t *set) {
|
||||
DEFINE__REAL(int, __sigemptyset14, const void *a);
|
||||
(void)_REAL(__sigemptyset14, set);
|
||||
}
|
||||
|
||||
DEFINE_INTERNAL(uptr, clone, int (*fn)(void *), void *child_stack, int flags,
|
||||
void *arg, int *parent_tidptr, void *newtls,
|
||||
int *child_tidptr) {
|
||||
Printf("internal_clone not implemented for NetBSD");
|
||||
Die();
|
||||
return 0;
|
||||
}
|
||||
|
||||
} // namespace __sanitizer
|
||||
|
||||
#endif
|
@ -94,6 +94,7 @@ elif [ "`uname -a | grep NetBSD`" != "" ]; then
|
||||
../../sanitizer_common/sanitizer_procmaps_common.cc
|
||||
../../sanitizer_common/sanitizer_linux.cc
|
||||
../../sanitizer_common/sanitizer_linux_libcdep.cc
|
||||
../../sanitizer_common/sanitizer_netbsd.cc
|
||||
../../sanitizer_common/sanitizer_stoptheworld_linux_libcdep.cc
|
||||
"
|
||||
elif [ "`uname -a | grep Darwin`" != "" ]; then
|
||||
|
Loading…
x
Reference in New Issue
Block a user