1 //===-- sanitizer_netbsd.cpp ----------------------------------------------===//
3 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4 // See https://llvm.org/LICENSE.txt for license information.
5 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
7 //===----------------------------------------------------------------------===//
9 // This file is shared between Sanitizer run-time libraries and implements
10 // NetBSD-specific functions from sanitizer_libc.h.
11 //===----------------------------------------------------------------------===//
13 #include "sanitizer_platform.h"
17 #include "sanitizer_common.h"
18 #include "sanitizer_flags.h"
19 #include "sanitizer_getauxval.h"
20 #include "sanitizer_internal_defs.h"
21 #include "sanitizer_libc.h"
22 #include "sanitizer_linux.h"
23 #include "sanitizer_mutex.h"
24 #include "sanitizer_placement_new.h"
25 #include "sanitizer_procmaps.h"
27 #include <sys/param.h>
28 #include <sys/types.h>
32 #include <sys/ptrace.h>
33 #include <sys/resource.h>
35 #include <sys/syscall.h>
36 #include <sys/sysctl.h>
51 extern "C" void *__mmap(void *, size_t, int, int, int, int,
52 off_t
) SANITIZER_WEAK_ATTRIBUTE
;
53 extern "C" int __sysctl(const int *, unsigned int, void *, size_t *,
54 const void *, size_t) SANITIZER_WEAK_ATTRIBUTE
;
55 extern "C" int _sys_close(int) SANITIZER_WEAK_ATTRIBUTE
;
56 extern "C" int _sys_open(const char *, int, ...) SANITIZER_WEAK_ATTRIBUTE
;
57 extern "C" ssize_t
_sys_read(int, void *, size_t) SANITIZER_WEAK_ATTRIBUTE
;
58 extern "C" ssize_t
_sys_write(int, const void *,
59 size_t) SANITIZER_WEAK_ATTRIBUTE
;
60 extern "C" int __ftruncate(int, int, off_t
) SANITIZER_WEAK_ATTRIBUTE
;
61 extern "C" ssize_t
_sys_readlink(const char *, char *,
62 size_t) SANITIZER_WEAK_ATTRIBUTE
;
63 extern "C" int _sys_sched_yield() SANITIZER_WEAK_ATTRIBUTE
;
64 extern "C" int _sys___nanosleep50(const void *,
65 void *) SANITIZER_WEAK_ATTRIBUTE
;
66 extern "C" int _sys_execve(const char *, char *const[],
67 char *const[]) SANITIZER_WEAK_ATTRIBUTE
;
68 extern "C" off_t
__lseek(int, int, off_t
, int) SANITIZER_WEAK_ATTRIBUTE
;
69 extern "C" int __fork() SANITIZER_WEAK_ATTRIBUTE
;
70 extern "C" int _sys___sigprocmask14(int, const void *,
71 void *) SANITIZER_WEAK_ATTRIBUTE
;
72 extern "C" int _sys___wait450(int wpid
, int *, int,
73 void *) SANITIZER_WEAK_ATTRIBUTE
;
75 namespace __sanitizer
{
77 static void *GetRealLibcAddress(const char *symbol
) {
78 void *real
= dlsym(RTLD_NEXT
, symbol
);
80 real
= dlsym(RTLD_DEFAULT
, symbol
);
82 Printf("GetRealLibcAddress failed for symbol=%s", symbol
);
88 #define _REAL(func, ...) real##_##func(__VA_ARGS__)
89 #define DEFINE__REAL(ret_type, func, ...) \
90 static ret_type (*real_##func)(__VA_ARGS__) = NULL; \
92 real_##func = (ret_type(*)(__VA_ARGS__))GetRealLibcAddress(#func); \
96 // --------------- sanitizer_libc.h
97 uptr
internal_mmap(void *addr
, uptr length
, int prot
, int flags
, int fd
,
100 return (uptr
)__mmap(addr
, length
, prot
, flags
, fd
, 0, offset
);
103 uptr
internal_munmap(void *addr
, uptr length
) {
104 DEFINE__REAL(int, munmap
, void *a
, uptr b
);
105 return _REAL(munmap
, addr
, length
);
108 uptr
internal_mremap(void *old_address
, uptr old_size
, uptr new_size
, int flags
,
110 CHECK(false && "internal_mremap is unimplemented on NetBSD");
114 int internal_mprotect(void *addr
, uptr length
, int prot
) {
115 DEFINE__REAL(int, mprotect
, void *a
, uptr b
, int c
);
116 return _REAL(mprotect
, addr
, length
, prot
);
119 int internal_madvise(uptr addr
, uptr length
, int advice
) {
120 DEFINE__REAL(int, madvise
, void *a
, uptr b
, int c
);
121 return _REAL(madvise
, (void *)addr
, length
, advice
);
124 uptr
internal_close(fd_t fd
) {
126 return _sys_close(fd
);
129 uptr
internal_open(const char *filename
, int flags
) {
131 return _sys_open(filename
, flags
);
134 uptr
internal_open(const char *filename
, int flags
, u32 mode
) {
136 return _sys_open(filename
, flags
, mode
);
139 uptr
internal_read(fd_t fd
, void *buf
, uptr count
) {
142 HANDLE_EINTR(res
, (sptr
)_sys_read(fd
, buf
, (size_t)count
));
146 uptr
internal_write(fd_t fd
, const void *buf
, uptr count
) {
149 HANDLE_EINTR(res
, (sptr
)_sys_write(fd
, buf
, count
));
153 uptr
internal_ftruncate(fd_t fd
, uptr size
) {
156 HANDLE_EINTR(res
, __ftruncate(fd
, 0, (s64
)size
));
160 uptr
internal_stat(const char *path
, void *buf
) {
161 DEFINE__REAL(int, __stat50
, const char *a
, void *b
);
162 return _REAL(__stat50
, path
, buf
);
165 uptr
internal_lstat(const char *path
, void *buf
) {
166 DEFINE__REAL(int, __lstat50
, const char *a
, void *b
);
167 return _REAL(__lstat50
, path
, buf
);
170 uptr
internal_fstat(fd_t fd
, void *buf
) {
171 DEFINE__REAL(int, __fstat50
, int a
, void *b
);
172 return _REAL(__fstat50
, fd
, buf
);
175 uptr
internal_filesize(fd_t fd
) {
177 if (internal_fstat(fd
, &st
))
179 return (uptr
)st
.st_size
;
182 uptr
internal_dup(int oldfd
) {
183 DEFINE__REAL(int, dup
, int a
);
184 return _REAL(dup
, oldfd
);
187 uptr
internal_dup2(int oldfd
, int newfd
) {
188 DEFINE__REAL(int, dup2
, int a
, int b
);
189 return _REAL(dup2
, oldfd
, newfd
);
192 uptr
internal_readlink(const char *path
, char *buf
, uptr bufsize
) {
193 CHECK(&_sys_readlink
);
194 return (uptr
)_sys_readlink(path
, buf
, bufsize
);
197 uptr
internal_unlink(const char *path
) {
198 DEFINE__REAL(int, unlink
, const char *a
);
199 return _REAL(unlink
, path
);
202 uptr
internal_rename(const char *oldpath
, const char *newpath
) {
203 DEFINE__REAL(int, rename
, const char *a
, const char *b
);
204 return _REAL(rename
, oldpath
, newpath
);
207 uptr
internal_sched_yield() {
208 CHECK(&_sys_sched_yield
);
209 return _sys_sched_yield();
212 void internal__exit(int exitcode
) {
213 DEFINE__REAL(void, _exit
, int a
);
214 _REAL(_exit
, exitcode
);
215 Die(); // Unreachable.
218 void internal_usleep(u64 useconds
) {
220 ts
.tv_sec
= useconds
/ 1000000;
221 ts
.tv_nsec
= (useconds
% 1000000) * 1000;
222 CHECK(&_sys___nanosleep50
);
223 _sys___nanosleep50(&ts
, &ts
);
226 uptr
internal_execve(const char *filename
, char *const argv
[],
227 char *const envp
[]) {
229 return _sys_execve(filename
, argv
, envp
);
233 DEFINE__REAL(int, _lwp_self
);
234 return _REAL(_lwp_self
);
237 int TgKill(pid_t pid
, tid_t tid
, int sig
) {
238 DEFINE__REAL(int, _lwp_kill
, int a
, int b
);
240 return _REAL(_lwp_kill
, tid
, sig
);
245 DEFINE__REAL(int, __gettimeofday50
, void *a
, void *b
);
246 internal_memset(&tv
, 0, sizeof(tv
));
247 _REAL(__gettimeofday50
, &tv
, 0);
248 return (u64
)tv
.tv_sec
* 1000 * 1000 * 1000 + tv
.tv_usec
* 1000;
251 uptr
internal_clock_gettime(__sanitizer_clockid_t clk_id
, void *tp
) {
252 DEFINE__REAL(int, __clock_gettime50
, __sanitizer_clockid_t a
, void *b
);
253 return _REAL(__clock_gettime50
, clk_id
, tp
);
256 uptr
internal_ptrace(int request
, int pid
, void *addr
, int data
) {
257 DEFINE__REAL(int, ptrace
, int a
, int b
, void *c
, int d
);
258 return _REAL(ptrace
, request
, pid
, addr
, data
);
261 uptr
internal_waitpid(int pid
, int *status
, int options
) {
262 CHECK(&_sys___wait450
);
263 return _sys___wait450(pid
, status
, options
, 0 /* rusage */);
266 uptr
internal_getpid() {
267 DEFINE__REAL(int, getpid
);
268 return _REAL(getpid
);
271 uptr
internal_getppid() {
272 DEFINE__REAL(int, getppid
);
273 return _REAL(getppid
);
276 int internal_dlinfo(void *handle
, int request
, void *p
) {
277 DEFINE__REAL(int, dlinfo
, void *a
, int b
, void *c
);
278 return _REAL(dlinfo
, handle
, request
, p
);
281 uptr
internal_getdents(fd_t fd
, void *dirp
, unsigned int count
) {
282 DEFINE__REAL(int, __getdents30
, int a
, void *b
, size_t c
);
283 return _REAL(__getdents30
, fd
, dirp
, count
);
286 uptr
internal_lseek(fd_t fd
, OFF_T offset
, int whence
) {
288 return __lseek(fd
, 0, offset
, whence
);
291 uptr
internal_prctl(int option
, uptr arg2
, uptr arg3
, uptr arg4
, uptr arg5
) {
292 Printf("internal_prctl not implemented for NetBSD");
297 uptr
internal_sigaltstack(const void *ss
, void *oss
) {
298 DEFINE__REAL(int, __sigaltstack14
, const void *a
, void *b
);
299 return _REAL(__sigaltstack14
, ss
, oss
);
302 int internal_fork() {
307 int internal_sysctl(const int *name
, unsigned int namelen
, void *oldp
,
308 uptr
*oldlenp
, const void *newp
, uptr newlen
) {
310 return __sysctl(name
, namelen
, oldp
, (size_t *)oldlenp
, newp
, (size_t)newlen
);
313 int internal_sysctlbyname(const char *sname
, void *oldp
, uptr
*oldlenp
,
314 const void *newp
, uptr newlen
) {
315 DEFINE__REAL(int, sysctlbyname
, const char *a
, void *b
, size_t *c
,
316 const void *d
, size_t e
);
317 return _REAL(sysctlbyname
, sname
, oldp
, (size_t *)oldlenp
, newp
,
321 uptr
internal_sigprocmask(int how
, __sanitizer_sigset_t
*set
,
322 __sanitizer_sigset_t
*oldset
) {
323 CHECK(&_sys___sigprocmask14
);
324 return _sys___sigprocmask14(how
, set
, oldset
);
327 void internal_sigfillset(__sanitizer_sigset_t
*set
) {
328 DEFINE__REAL(int, __sigfillset14
, const void *a
);
329 (void)_REAL(__sigfillset14
, set
);
332 void internal_sigemptyset(__sanitizer_sigset_t
*set
) {
333 DEFINE__REAL(int, __sigemptyset14
, const void *a
);
334 (void)_REAL(__sigemptyset14
, set
);
337 void internal_sigdelset(__sanitizer_sigset_t
*set
, int signo
) {
338 DEFINE__REAL(int, __sigdelset14
, const void *a
, int b
);
339 (void)_REAL(__sigdelset14
, set
, signo
);
342 uptr
internal_clone(int (*fn
)(void *), void *child_stack
, int flags
,
344 DEFINE__REAL(int, clone
, int (*a
)(void *b
), void *c
, int d
, void *e
);
346 return _REAL(clone
, fn
, child_stack
, flags
, arg
);
349 } // namespace __sanitizer