Home | History | Annotate | Line # | Download | only in sanitizer_common
      1 //===-- sanitizer_solaris.cc ----------------------------------------------===//
      2 //
      3 // This file is distributed under the University of Illinois Open Source
      4 // License. See LICENSE.TXT for details.
      5 //
      6 //===----------------------------------------------------------------------===//
      7 //
      8 // This file is shared between various sanitizers' runtime libraries and
      9 // implements Solaris-specific functions.
     10 //===----------------------------------------------------------------------===//
     11 
     12 #include "sanitizer_platform.h"
     13 #if SANITIZER_SOLARIS
     14 
     15 #include <stdio.h>
     16 
     17 #include "sanitizer_common.h"
     18 #include "sanitizer_flags.h"
     19 #include "sanitizer_internal_defs.h"
     20 #include "sanitizer_libc.h"
     21 #include "sanitizer_placement_new.h"
     22 #include "sanitizer_platform_limits_posix.h"
     23 #include "sanitizer_procmaps.h"
     24 
     25 #include <fcntl.h>
     26 #include <pthread.h>
     27 #include <sched.h>
     28 #include <thread.h>
     29 #include <synch.h>
     30 #include <signal.h>
     31 #include <sys/mman.h>
     32 #include <sys/resource.h>
     33 #include <sys/stat.h>
     34 #include <sys/types.h>
     35 #include <dirent.h>
     36 #include <unistd.h>
     37 #include <errno.h>
     38 #include <stdlib.h>
     39 
     40 namespace __sanitizer {
     41 
     42 //#include "sanitizer_syscall_generic.inc"
     43 
     44 #define _REAL(func) _ ## func
     45 #define DECLARE__REAL(ret_type, func, ...) \
     46   extern "C" ret_type _REAL(func)(__VA_ARGS__)
     47 #define DECLARE__REAL_AND_INTERNAL(ret_type, func, ...) \
     48   DECLARE__REAL(ret_type, func, __VA_ARGS__); \
     49   ret_type internal_ ## func(__VA_ARGS__)
     50 
     51 #if !defined(_LP64) && _FILE_OFFSET_BITS == 64
     52 #define _REAL64(func) _ ## func ## 64
     53 #else
     54 #define _REAL64(func) _REAL(func)
     55 #endif
     56 #define DECLARE__REAL64(ret_type, func, ...) \
     57   extern "C" ret_type _REAL64(func)(__VA_ARGS__)
     58 #define DECLARE__REAL_AND_INTERNAL64(ret_type, func, ...) \
     59   DECLARE__REAL64(ret_type, func, __VA_ARGS__); \
     60   ret_type internal_ ## func(__VA_ARGS__)
     61 
     62 // ---------------------- sanitizer_libc.h
     63 DECLARE__REAL_AND_INTERNAL64(uptr, mmap, void *addr, uptr /*size_t*/ length,
     64                              int prot, int flags, int fd, OFF_T offset) {
     65   return (uptr)_REAL64(mmap)(addr, length, prot, flags, fd, offset);
     66 }
     67 
     68 DECLARE__REAL_AND_INTERNAL(uptr, munmap, void *addr, uptr length) {
     69   return _REAL(munmap)(addr, length);
     70 }
     71 
     72 DECLARE__REAL_AND_INTERNAL(int, mprotect, void *addr, uptr length, int prot) {
     73   return _REAL(mprotect)(addr, length, prot);
     74 }
     75 
     76 DECLARE__REAL_AND_INTERNAL(uptr, close, fd_t fd) {
     77   return _REAL(close)(fd);
     78 }
     79 
     80 extern "C" int _REAL64(open)(const char *, int, ...);
     81 
     82 uptr internal_open(const char *filename, int flags) {
     83   return _REAL64(open)(filename, flags);
     84 }
     85 
     86 uptr internal_open(const char *filename, int flags, u32 mode) {
     87   return _REAL64(open)(filename, flags, mode);
     88 }
     89 
     90 uptr OpenFile(const char *filename, bool write) {
     91   return ReserveStandardFds(
     92       internal_open(filename, write ? O_WRONLY | O_CREAT : O_RDONLY, 0660));
     93 }
     94 
     95 DECLARE__REAL_AND_INTERNAL(uptr, read, fd_t fd, void *buf, uptr count) {
     96   return _REAL(read)(fd, buf, count);
     97 }
     98 
     99 DECLARE__REAL_AND_INTERNAL(uptr, write, fd_t fd, const void *buf, uptr count) {
    100   return _REAL(write)(fd, buf, count);
    101 }
    102 
    103 // FIXME: There's only _ftruncate64 beginning with Solaris 11.
    104 DECLARE__REAL_AND_INTERNAL(uptr, ftruncate, fd_t fd, uptr size) {
    105   return ftruncate(fd, size);
    106 }
    107 
    108 DECLARE__REAL_AND_INTERNAL64(uptr, stat, const char *path, void *buf) {
    109   return _REAL64(stat)(path, (struct stat *)buf);
    110 }
    111 
    112 DECLARE__REAL_AND_INTERNAL64(uptr, lstat, const char *path, void *buf) {
    113   return _REAL64(lstat)(path, (struct stat *)buf);
    114 }
    115 
    116 DECLARE__REAL_AND_INTERNAL64(uptr, fstat, fd_t fd, void *buf) {
    117   return _REAL64(fstat)(fd, (struct stat *)buf);
    118 }
    119 
    120 uptr internal_filesize(fd_t fd) {
    121   struct stat st;
    122   if (internal_fstat(fd, &st))
    123     return -1;
    124   return (uptr)st.st_size;
    125 }
    126 
    127 DECLARE__REAL_AND_INTERNAL(uptr, dup2, int oldfd, int newfd) {
    128   return _REAL(dup2)(oldfd, newfd);
    129 }
    130 
    131 DECLARE__REAL_AND_INTERNAL(uptr, readlink, const char *path, char *buf,
    132                            uptr bufsize) {
    133   return _REAL(readlink)(path, buf, bufsize);
    134 }
    135 
    136 DECLARE__REAL_AND_INTERNAL(uptr, unlink, const char *path) {
    137   return _REAL(unlink)(path);
    138 }
    139 
    140 DECLARE__REAL_AND_INTERNAL(uptr, rename, const char *oldpath,
    141                            const char *newpath) {
    142   return _REAL(rename)(oldpath, newpath);
    143 }
    144 
    145 DECLARE__REAL_AND_INTERNAL(uptr, sched_yield, void) {
    146   return sched_yield();
    147 }
    148 
    149 DECLARE__REAL_AND_INTERNAL(void, _exit, int exitcode) {
    150   _exit(exitcode);
    151 }
    152 
    153 DECLARE__REAL_AND_INTERNAL(uptr, execve, const char *filename,
    154                            char *const argv[], char *const envp[]) {
    155   return _REAL(execve)(filename, argv, envp);
    156 }
    157 
    158 DECLARE__REAL_AND_INTERNAL(uptr, waitpid, int pid, int *status, int options) {
    159   return _REAL(waitpid)(pid, status, options);
    160 }
    161 
    162 DECLARE__REAL_AND_INTERNAL(uptr, getpid, void) {
    163   return _REAL(getpid)();
    164 }
    165 
    166 // FIXME: This might be wrong: _getdents doesn't take a struct linux_dirent *.
    167 DECLARE__REAL_AND_INTERNAL64(uptr, getdents, fd_t fd, struct linux_dirent *dirp,
    168                              unsigned int count) {
    169   return _REAL64(getdents)(fd, dirp, count);
    170 }
    171 
    172 DECLARE__REAL_AND_INTERNAL64(uptr, lseek, fd_t fd, OFF_T offset, int whence) {
    173   return _REAL64(lseek)(fd, offset, whence);
    174 }
    175 
    176 // FIXME: This might be wrong: _sigfillset doesn't take a
    177 // __sanitizer_sigset_t *.
    178 DECLARE__REAL_AND_INTERNAL(void, sigfillset, __sanitizer_sigset_t *set) {
    179   _REAL(sigfillset)(set);
    180 }
    181 
    182 // FIXME: This might be wrong: _sigprocmask doesn't take __sanitizer_sigset_t *.
    183 DECLARE__REAL_AND_INTERNAL(uptr, sigprocmask, int how,
    184                            __sanitizer_sigset_t *set,
    185                            __sanitizer_sigset_t *oldset) {
    186   return _REAL(sigprocmask)(how, set, oldset);
    187 }
    188 
    189 DECLARE__REAL_AND_INTERNAL(int, fork, void) {
    190   // TODO(glider): this may call user's pthread_atfork() handlers which is bad.
    191   return _REAL(fork)();
    192 }
    193 
    194 u64 NanoTime() {
    195   return gethrtime();
    196 }
    197 
    198 uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {
    199   // FIXME: No internal variant.
    200   return clock_gettime(clk_id, (timespec *)tp);
    201 }
    202 
    203 // ----------------- sanitizer_common.h
    204 BlockingMutex::BlockingMutex() {
    205   CHECK(sizeof(mutex_t) <= sizeof(opaque_storage_));
    206   internal_memset(this, 0, sizeof(*this));
    207   CHECK_EQ(mutex_init((mutex_t *)&opaque_storage_, USYNC_THREAD, NULL), 0);
    208 }
    209 
    210 void BlockingMutex::Lock() {
    211   CHECK(sizeof(mutex_t) <= sizeof(opaque_storage_));
    212   CHECK_NE(owner_, (uptr)thr_self());
    213   CHECK_EQ(mutex_lock((mutex_t *)&opaque_storage_), 0);
    214   CHECK(!owner_);
    215   owner_ = (uptr)thr_self();
    216 }
    217 
    218 void BlockingMutex::Unlock() {
    219   CHECK(owner_ == (uptr)thr_self());
    220   owner_ = 0;
    221   CHECK_EQ(mutex_unlock((mutex_t *)&opaque_storage_), 0);
    222 }
    223 
    224 void BlockingMutex::CheckLocked() {
    225   CHECK_EQ((uptr)thr_self(), owner_);
    226 }
    227 
    228 }  // namespace __sanitizer
    229 
    230 #endif  // SANITIZER_SOLARIS
    231