xref: /freebsd-src/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_netbsd.cpp (revision 68d75eff68281c1b445e3010bb975eae07aac225)
1*68d75effSDimitry Andric //===-- sanitizer_netbsd.cpp ----------------------------------------------===//
2*68d75effSDimitry Andric //
3*68d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*68d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*68d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*68d75effSDimitry Andric //
7*68d75effSDimitry Andric //===----------------------------------------------------------------------===//
8*68d75effSDimitry Andric //
9*68d75effSDimitry Andric // This file is shared between Sanitizer run-time libraries and implements
10*68d75effSDimitry Andric // NetBSD-specific functions from sanitizer_libc.h.
11*68d75effSDimitry Andric //===----------------------------------------------------------------------===//
12*68d75effSDimitry Andric 
13*68d75effSDimitry Andric #include "sanitizer_platform.h"
14*68d75effSDimitry Andric 
15*68d75effSDimitry Andric #if SANITIZER_NETBSD
16*68d75effSDimitry Andric 
17*68d75effSDimitry Andric #include "sanitizer_common.h"
18*68d75effSDimitry Andric #include "sanitizer_flags.h"
19*68d75effSDimitry Andric #include "sanitizer_getauxval.h"
20*68d75effSDimitry Andric #include "sanitizer_internal_defs.h"
21*68d75effSDimitry Andric #include "sanitizer_libc.h"
22*68d75effSDimitry Andric #include "sanitizer_linux.h"
23*68d75effSDimitry Andric #include "sanitizer_mutex.h"
24*68d75effSDimitry Andric #include "sanitizer_placement_new.h"
25*68d75effSDimitry Andric #include "sanitizer_procmaps.h"
26*68d75effSDimitry Andric 
27*68d75effSDimitry Andric #include <sys/param.h>
28*68d75effSDimitry Andric #include <sys/types.h>
29*68d75effSDimitry Andric 
30*68d75effSDimitry Andric #include <sys/exec.h>
31*68d75effSDimitry Andric #include <sys/mman.h>
32*68d75effSDimitry Andric #include <sys/ptrace.h>
33*68d75effSDimitry Andric #include <sys/resource.h>
34*68d75effSDimitry Andric #include <sys/stat.h>
35*68d75effSDimitry Andric #include <sys/syscall.h>
36*68d75effSDimitry Andric #include <sys/sysctl.h>
37*68d75effSDimitry Andric #include <sys/time.h>
38*68d75effSDimitry Andric 
39*68d75effSDimitry Andric #include <dlfcn.h>
40*68d75effSDimitry Andric #include <errno.h>
41*68d75effSDimitry Andric #include <fcntl.h>
42*68d75effSDimitry Andric #include <limits.h>
43*68d75effSDimitry Andric #include <link.h>
44*68d75effSDimitry Andric #include <lwp.h>
45*68d75effSDimitry Andric #include <pthread.h>
46*68d75effSDimitry Andric #include <sched.h>
47*68d75effSDimitry Andric #include <signal.h>
48*68d75effSDimitry Andric #include <ucontext.h>
49*68d75effSDimitry Andric #include <unistd.h>
50*68d75effSDimitry Andric 
51*68d75effSDimitry Andric extern "C" void *__mmap(void *, size_t, int, int, int, int,
52*68d75effSDimitry Andric                         off_t) SANITIZER_WEAK_ATTRIBUTE;
53*68d75effSDimitry Andric extern "C" int __sysctl(const int *, unsigned int, void *, size_t *,
54*68d75effSDimitry Andric                         const void *, size_t) SANITIZER_WEAK_ATTRIBUTE;
55*68d75effSDimitry Andric extern "C" int _sys_close(int) SANITIZER_WEAK_ATTRIBUTE;
56*68d75effSDimitry Andric extern "C" int _sys_open(const char *, int, ...) SANITIZER_WEAK_ATTRIBUTE;
57*68d75effSDimitry Andric extern "C" ssize_t _sys_read(int, void *, size_t) SANITIZER_WEAK_ATTRIBUTE;
58*68d75effSDimitry Andric extern "C" ssize_t _sys_write(int, const void *,
59*68d75effSDimitry Andric                               size_t) SANITIZER_WEAK_ATTRIBUTE;
60*68d75effSDimitry Andric extern "C" int __ftruncate(int, int, off_t) SANITIZER_WEAK_ATTRIBUTE;
61*68d75effSDimitry Andric extern "C" ssize_t _sys_readlink(const char *, char *,
62*68d75effSDimitry Andric                                  size_t) SANITIZER_WEAK_ATTRIBUTE;
63*68d75effSDimitry Andric extern "C" int _sys_sched_yield() SANITIZER_WEAK_ATTRIBUTE;
64*68d75effSDimitry Andric extern "C" int _sys___nanosleep50(const void *,
65*68d75effSDimitry Andric                                   void *) SANITIZER_WEAK_ATTRIBUTE;
66*68d75effSDimitry Andric extern "C" int _sys_execve(const char *, char *const[],
67*68d75effSDimitry Andric                            char *const[]) SANITIZER_WEAK_ATTRIBUTE;
68*68d75effSDimitry Andric extern "C" off_t __lseek(int, int, off_t, int) SANITIZER_WEAK_ATTRIBUTE;
69*68d75effSDimitry Andric extern "C" int __fork() SANITIZER_WEAK_ATTRIBUTE;
70*68d75effSDimitry Andric extern "C" int _sys___sigprocmask14(int, const void *,
71*68d75effSDimitry Andric                                     void *) SANITIZER_WEAK_ATTRIBUTE;
72*68d75effSDimitry Andric extern "C" int _sys___wait450(int wpid, int *, int,
73*68d75effSDimitry Andric                               void *) SANITIZER_WEAK_ATTRIBUTE;
74*68d75effSDimitry Andric 
75*68d75effSDimitry Andric namespace __sanitizer {
76*68d75effSDimitry Andric 
77*68d75effSDimitry Andric static void *GetRealLibcAddress(const char *symbol) {
78*68d75effSDimitry Andric   void *real = dlsym(RTLD_NEXT, symbol);
79*68d75effSDimitry Andric   if (!real)
80*68d75effSDimitry Andric     real = dlsym(RTLD_DEFAULT, symbol);
81*68d75effSDimitry Andric   if (!real) {
82*68d75effSDimitry Andric     Printf("GetRealLibcAddress failed for symbol=%s", symbol);
83*68d75effSDimitry Andric     Die();
84*68d75effSDimitry Andric   }
85*68d75effSDimitry Andric   return real;
86*68d75effSDimitry Andric }
87*68d75effSDimitry Andric 
88*68d75effSDimitry Andric #define _REAL(func, ...) real##_##func(__VA_ARGS__)
89*68d75effSDimitry Andric #define DEFINE__REAL(ret_type, func, ...)                              \
90*68d75effSDimitry Andric   static ret_type (*real_##func)(__VA_ARGS__) = NULL;                  \
91*68d75effSDimitry Andric   if (!real_##func) {                                                  \
92*68d75effSDimitry Andric     real_##func = (ret_type(*)(__VA_ARGS__))GetRealLibcAddress(#func); \
93*68d75effSDimitry Andric   }                                                                    \
94*68d75effSDimitry Andric   CHECK(real_##func);
95*68d75effSDimitry Andric 
96*68d75effSDimitry Andric // --------------- sanitizer_libc.h
97*68d75effSDimitry Andric uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd,
98*68d75effSDimitry Andric                    OFF_T offset) {
99*68d75effSDimitry Andric   CHECK(&__mmap);
100*68d75effSDimitry Andric   return (uptr)__mmap(addr, length, prot, flags, fd, 0, offset);
101*68d75effSDimitry Andric }
102*68d75effSDimitry Andric 
103*68d75effSDimitry Andric uptr internal_munmap(void *addr, uptr length) {
104*68d75effSDimitry Andric   DEFINE__REAL(int, munmap, void *a, uptr b);
105*68d75effSDimitry Andric   return _REAL(munmap, addr, length);
106*68d75effSDimitry Andric }
107*68d75effSDimitry Andric 
108*68d75effSDimitry Andric int internal_mprotect(void *addr, uptr length, int prot) {
109*68d75effSDimitry Andric   DEFINE__REAL(int, mprotect, void *a, uptr b, int c);
110*68d75effSDimitry Andric   return _REAL(mprotect, addr, length, prot);
111*68d75effSDimitry Andric }
112*68d75effSDimitry Andric 
113*68d75effSDimitry Andric uptr internal_close(fd_t fd) {
114*68d75effSDimitry Andric   CHECK(&_sys_close);
115*68d75effSDimitry Andric   return _sys_close(fd);
116*68d75effSDimitry Andric }
117*68d75effSDimitry Andric 
118*68d75effSDimitry Andric uptr internal_open(const char *filename, int flags) {
119*68d75effSDimitry Andric   CHECK(&_sys_open);
120*68d75effSDimitry Andric   return _sys_open(filename, flags);
121*68d75effSDimitry Andric }
122*68d75effSDimitry Andric 
123*68d75effSDimitry Andric uptr internal_open(const char *filename, int flags, u32 mode) {
124*68d75effSDimitry Andric   CHECK(&_sys_open);
125*68d75effSDimitry Andric   return _sys_open(filename, flags, mode);
126*68d75effSDimitry Andric }
127*68d75effSDimitry Andric 
128*68d75effSDimitry Andric uptr internal_read(fd_t fd, void *buf, uptr count) {
129*68d75effSDimitry Andric   sptr res;
130*68d75effSDimitry Andric   CHECK(&_sys_read);
131*68d75effSDimitry Andric   HANDLE_EINTR(res, (sptr)_sys_read(fd, buf, (size_t)count));
132*68d75effSDimitry Andric   return res;
133*68d75effSDimitry Andric }
134*68d75effSDimitry Andric 
135*68d75effSDimitry Andric uptr internal_write(fd_t fd, const void *buf, uptr count) {
136*68d75effSDimitry Andric   sptr res;
137*68d75effSDimitry Andric   CHECK(&_sys_write);
138*68d75effSDimitry Andric   HANDLE_EINTR(res, (sptr)_sys_write(fd, buf, count));
139*68d75effSDimitry Andric   return res;
140*68d75effSDimitry Andric }
141*68d75effSDimitry Andric 
142*68d75effSDimitry Andric uptr internal_ftruncate(fd_t fd, uptr size) {
143*68d75effSDimitry Andric   sptr res;
144*68d75effSDimitry Andric   CHECK(&__ftruncate);
145*68d75effSDimitry Andric   HANDLE_EINTR(res, __ftruncate(fd, 0, (s64)size));
146*68d75effSDimitry Andric   return res;
147*68d75effSDimitry Andric }
148*68d75effSDimitry Andric 
149*68d75effSDimitry Andric uptr internal_stat(const char *path, void *buf) {
150*68d75effSDimitry Andric   DEFINE__REAL(int, __stat50, const char *a, void *b);
151*68d75effSDimitry Andric   return _REAL(__stat50, path, buf);
152*68d75effSDimitry Andric }
153*68d75effSDimitry Andric 
154*68d75effSDimitry Andric uptr internal_lstat(const char *path, void *buf) {
155*68d75effSDimitry Andric   DEFINE__REAL(int, __lstat50, const char *a, void *b);
156*68d75effSDimitry Andric   return _REAL(__lstat50, path, buf);
157*68d75effSDimitry Andric }
158*68d75effSDimitry Andric 
159*68d75effSDimitry Andric uptr internal_fstat(fd_t fd, void *buf) {
160*68d75effSDimitry Andric   DEFINE__REAL(int, __fstat50, int a, void *b);
161*68d75effSDimitry Andric   return _REAL(__fstat50, fd, buf);
162*68d75effSDimitry Andric }
163*68d75effSDimitry Andric 
164*68d75effSDimitry Andric uptr internal_filesize(fd_t fd) {
165*68d75effSDimitry Andric   struct stat st;
166*68d75effSDimitry Andric   if (internal_fstat(fd, &st))
167*68d75effSDimitry Andric     return -1;
168*68d75effSDimitry Andric   return (uptr)st.st_size;
169*68d75effSDimitry Andric }
170*68d75effSDimitry Andric 
171*68d75effSDimitry Andric uptr internal_dup(int oldfd) {
172*68d75effSDimitry Andric   DEFINE__REAL(int, dup, int a);
173*68d75effSDimitry Andric   return _REAL(dup, oldfd);
174*68d75effSDimitry Andric }
175*68d75effSDimitry Andric 
176*68d75effSDimitry Andric uptr internal_dup2(int oldfd, int newfd) {
177*68d75effSDimitry Andric   DEFINE__REAL(int, dup2, int a, int b);
178*68d75effSDimitry Andric   return _REAL(dup2, oldfd, newfd);
179*68d75effSDimitry Andric }
180*68d75effSDimitry Andric 
181*68d75effSDimitry Andric uptr internal_readlink(const char *path, char *buf, uptr bufsize) {
182*68d75effSDimitry Andric   CHECK(&_sys_readlink);
183*68d75effSDimitry Andric   return (uptr)_sys_readlink(path, buf, bufsize);
184*68d75effSDimitry Andric }
185*68d75effSDimitry Andric 
186*68d75effSDimitry Andric uptr internal_unlink(const char *path) {
187*68d75effSDimitry Andric   DEFINE__REAL(int, unlink, const char *a);
188*68d75effSDimitry Andric   return _REAL(unlink, path);
189*68d75effSDimitry Andric }
190*68d75effSDimitry Andric 
191*68d75effSDimitry Andric uptr internal_rename(const char *oldpath, const char *newpath) {
192*68d75effSDimitry Andric   DEFINE__REAL(int, rename, const char *a, const char *b);
193*68d75effSDimitry Andric   return _REAL(rename, oldpath, newpath);
194*68d75effSDimitry Andric }
195*68d75effSDimitry Andric 
196*68d75effSDimitry Andric uptr internal_sched_yield() {
197*68d75effSDimitry Andric   CHECK(&_sys_sched_yield);
198*68d75effSDimitry Andric   return _sys_sched_yield();
199*68d75effSDimitry Andric }
200*68d75effSDimitry Andric 
201*68d75effSDimitry Andric void internal__exit(int exitcode) {
202*68d75effSDimitry Andric   DEFINE__REAL(void, _exit, int a);
203*68d75effSDimitry Andric   _REAL(_exit, exitcode);
204*68d75effSDimitry Andric   Die();  // Unreachable.
205*68d75effSDimitry Andric }
206*68d75effSDimitry Andric 
207*68d75effSDimitry Andric unsigned int internal_sleep(unsigned int seconds) {
208*68d75effSDimitry Andric   struct timespec ts;
209*68d75effSDimitry Andric   ts.tv_sec = seconds;
210*68d75effSDimitry Andric   ts.tv_nsec = 0;
211*68d75effSDimitry Andric   CHECK(&_sys___nanosleep50);
212*68d75effSDimitry Andric   int res = _sys___nanosleep50(&ts, &ts);
213*68d75effSDimitry Andric   if (res)
214*68d75effSDimitry Andric     return ts.tv_sec;
215*68d75effSDimitry Andric   return 0;
216*68d75effSDimitry Andric }
217*68d75effSDimitry Andric 
218*68d75effSDimitry Andric uptr internal_execve(const char *filename, char *const argv[],
219*68d75effSDimitry Andric                      char *const envp[]) {
220*68d75effSDimitry Andric   CHECK(&_sys_execve);
221*68d75effSDimitry Andric   return _sys_execve(filename, argv, envp);
222*68d75effSDimitry Andric }
223*68d75effSDimitry Andric 
224*68d75effSDimitry Andric tid_t GetTid() {
225*68d75effSDimitry Andric   DEFINE__REAL(int, _lwp_self);
226*68d75effSDimitry Andric   return _REAL(_lwp_self);
227*68d75effSDimitry Andric }
228*68d75effSDimitry Andric 
229*68d75effSDimitry Andric int TgKill(pid_t pid, tid_t tid, int sig) {
230*68d75effSDimitry Andric   DEFINE__REAL(int, _lwp_kill, int a, int b);
231*68d75effSDimitry Andric   (void)pid;
232*68d75effSDimitry Andric   return _REAL(_lwp_kill, tid, sig);
233*68d75effSDimitry Andric }
234*68d75effSDimitry Andric 
235*68d75effSDimitry Andric u64 NanoTime() {
236*68d75effSDimitry Andric   timeval tv;
237*68d75effSDimitry Andric   DEFINE__REAL(int, __gettimeofday50, void *a, void *b);
238*68d75effSDimitry Andric   internal_memset(&tv, 0, sizeof(tv));
239*68d75effSDimitry Andric   _REAL(__gettimeofday50, &tv, 0);
240*68d75effSDimitry Andric   return (u64)tv.tv_sec * 1000 * 1000 * 1000 + tv.tv_usec * 1000;
241*68d75effSDimitry Andric }
242*68d75effSDimitry Andric 
243*68d75effSDimitry Andric uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {
244*68d75effSDimitry Andric   DEFINE__REAL(int, __clock_gettime50, __sanitizer_clockid_t a, void *b);
245*68d75effSDimitry Andric   return _REAL(__clock_gettime50, clk_id, tp);
246*68d75effSDimitry Andric }
247*68d75effSDimitry Andric 
248*68d75effSDimitry Andric uptr internal_ptrace(int request, int pid, void *addr, int data) {
249*68d75effSDimitry Andric   DEFINE__REAL(int, ptrace, int a, int b, void *c, int d);
250*68d75effSDimitry Andric   return _REAL(ptrace, request, pid, addr, data);
251*68d75effSDimitry Andric }
252*68d75effSDimitry Andric 
253*68d75effSDimitry Andric uptr internal_waitpid(int pid, int *status, int options) {
254*68d75effSDimitry Andric   CHECK(&_sys___wait450);
255*68d75effSDimitry Andric   return _sys___wait450(pid, status, options, 0 /* rusage */);
256*68d75effSDimitry Andric }
257*68d75effSDimitry Andric 
258*68d75effSDimitry Andric uptr internal_getpid() {
259*68d75effSDimitry Andric   DEFINE__REAL(int, getpid);
260*68d75effSDimitry Andric   return _REAL(getpid);
261*68d75effSDimitry Andric }
262*68d75effSDimitry Andric 
263*68d75effSDimitry Andric uptr internal_getppid() {
264*68d75effSDimitry Andric   DEFINE__REAL(int, getppid);
265*68d75effSDimitry Andric   return _REAL(getppid);
266*68d75effSDimitry Andric }
267*68d75effSDimitry Andric 
268*68d75effSDimitry Andric uptr internal_getdents(fd_t fd, void *dirp, unsigned int count) {
269*68d75effSDimitry Andric   DEFINE__REAL(int, __getdents30, int a, void *b, size_t c);
270*68d75effSDimitry Andric   return _REAL(__getdents30, fd, dirp, count);
271*68d75effSDimitry Andric }
272*68d75effSDimitry Andric 
273*68d75effSDimitry Andric uptr internal_lseek(fd_t fd, OFF_T offset, int whence) {
274*68d75effSDimitry Andric   CHECK(&__lseek);
275*68d75effSDimitry Andric   return __lseek(fd, 0, offset, whence);
276*68d75effSDimitry Andric }
277*68d75effSDimitry Andric 
278*68d75effSDimitry Andric uptr internal_prctl(int option, uptr arg2, uptr arg3, uptr arg4, uptr arg5) {
279*68d75effSDimitry Andric   Printf("internal_prctl not implemented for NetBSD");
280*68d75effSDimitry Andric   Die();
281*68d75effSDimitry Andric   return 0;
282*68d75effSDimitry Andric }
283*68d75effSDimitry Andric 
284*68d75effSDimitry Andric uptr internal_sigaltstack(const void *ss, void *oss) {
285*68d75effSDimitry Andric   DEFINE__REAL(int, __sigaltstack14, const void *a, void *b);
286*68d75effSDimitry Andric   return _REAL(__sigaltstack14, ss, oss);
287*68d75effSDimitry Andric }
288*68d75effSDimitry Andric 
289*68d75effSDimitry Andric int internal_fork() {
290*68d75effSDimitry Andric   CHECK(&__fork);
291*68d75effSDimitry Andric   return __fork();
292*68d75effSDimitry Andric }
293*68d75effSDimitry Andric 
294*68d75effSDimitry Andric int internal_sysctl(const int *name, unsigned int namelen, void *oldp,
295*68d75effSDimitry Andric                     uptr *oldlenp, const void *newp, uptr newlen) {
296*68d75effSDimitry Andric   CHECK(&__sysctl);
297*68d75effSDimitry Andric   return __sysctl(name, namelen, oldp, (size_t *)oldlenp, newp, (size_t)newlen);
298*68d75effSDimitry Andric }
299*68d75effSDimitry Andric 
300*68d75effSDimitry Andric int internal_sysctlbyname(const char *sname, void *oldp, uptr *oldlenp,
301*68d75effSDimitry Andric                           const void *newp, uptr newlen) {
302*68d75effSDimitry Andric   DEFINE__REAL(int, sysctlbyname, const char *a, void *b, size_t *c,
303*68d75effSDimitry Andric                const void *d, size_t e);
304*68d75effSDimitry Andric   return _REAL(sysctlbyname, sname, oldp, (size_t *)oldlenp, newp,
305*68d75effSDimitry Andric                (size_t)newlen);
306*68d75effSDimitry Andric }
307*68d75effSDimitry Andric 
308*68d75effSDimitry Andric uptr internal_sigprocmask(int how, __sanitizer_sigset_t *set,
309*68d75effSDimitry Andric                           __sanitizer_sigset_t *oldset) {
310*68d75effSDimitry Andric   CHECK(&_sys___sigprocmask14);
311*68d75effSDimitry Andric   return _sys___sigprocmask14(how, set, oldset);
312*68d75effSDimitry Andric }
313*68d75effSDimitry Andric 
314*68d75effSDimitry Andric void internal_sigfillset(__sanitizer_sigset_t *set) {
315*68d75effSDimitry Andric   DEFINE__REAL(int, __sigfillset14, const void *a);
316*68d75effSDimitry Andric   (void)_REAL(__sigfillset14, set);
317*68d75effSDimitry Andric }
318*68d75effSDimitry Andric 
319*68d75effSDimitry Andric void internal_sigemptyset(__sanitizer_sigset_t *set) {
320*68d75effSDimitry Andric   DEFINE__REAL(int, __sigemptyset14, const void *a);
321*68d75effSDimitry Andric   (void)_REAL(__sigemptyset14, set);
322*68d75effSDimitry Andric }
323*68d75effSDimitry Andric 
324*68d75effSDimitry Andric void internal_sigdelset(__sanitizer_sigset_t *set, int signo) {
325*68d75effSDimitry Andric   DEFINE__REAL(int, __sigdelset14, const void *a, int b);
326*68d75effSDimitry Andric   (void)_REAL(__sigdelset14, set, signo);
327*68d75effSDimitry Andric }
328*68d75effSDimitry Andric 
329*68d75effSDimitry Andric uptr internal_clone(int (*fn)(void *), void *child_stack, int flags,
330*68d75effSDimitry Andric                     void *arg) {
331*68d75effSDimitry Andric   DEFINE__REAL(int, clone, int (*a)(void *b), void *c, int d, void *e);
332*68d75effSDimitry Andric 
333*68d75effSDimitry Andric   return _REAL(clone, fn, child_stack, flags, arg);
334*68d75effSDimitry Andric }
335*68d75effSDimitry Andric 
336*68d75effSDimitry Andric }  // namespace __sanitizer
337*68d75effSDimitry Andric 
338*68d75effSDimitry Andric #endif
339