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