231 lines · cpp
1//===-- sanitizer_solaris.cpp ---------------------------------------------===//2//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-exception6//7//===----------------------------------------------------------------------===//8//9// This file is shared between various sanitizers' runtime libraries and10// implements Solaris-specific functions.11//===----------------------------------------------------------------------===//12 13#include "sanitizer_platform.h"14#if SANITIZER_SOLARIS15 16#include <stdio.h>17 18#include "sanitizer_common.h"19#include "sanitizer_flags.h"20#include "sanitizer_internal_defs.h"21#include "sanitizer_libc.h"22#include "sanitizer_placement_new.h"23#include "sanitizer_platform_limits_posix.h"24#include "sanitizer_procmaps.h"25 26#include <fcntl.h>27#include <pthread.h>28#include <sched.h>29#include <thread.h>30#include <synch.h>31#include <signal.h>32#include <sys/mman.h>33#include <sys/resource.h>34#include <sys/stat.h>35#include <sys/types.h>36#include <dirent.h>37#include <unistd.h>38#include <errno.h>39#include <stdlib.h>40 41namespace __sanitizer {42 43//#include "sanitizer_syscall_generic.inc"44 45#define _REAL(func) _ ## func46#define DECLARE__REAL(ret_type, func, ...) \47 extern "C" ret_type _REAL(func)(__VA_ARGS__)48#define DECLARE__REAL_AND_INTERNAL(ret_type, func, ...) \49 DECLARE__REAL(ret_type, func, __VA_ARGS__); \50 ret_type internal_ ## func(__VA_ARGS__)51 52#if !defined(_LP64) && _FILE_OFFSET_BITS == 6453#define _REAL64(func) _ ## func ## 6454#else55#define _REAL64(func) _REAL(func)56#endif57#define DECLARE__REAL64(ret_type, func, ...) \58 extern "C" ret_type _REAL64(func)(__VA_ARGS__)59#define DECLARE__REAL_AND_INTERNAL64(ret_type, func, ...) \60 DECLARE__REAL64(ret_type, func, __VA_ARGS__); \61 ret_type internal_ ## func(__VA_ARGS__)62 63// ---------------------- sanitizer_libc.h64DECLARE__REAL_AND_INTERNAL64(uptr, mmap, void *addr, uptr /*size_t*/ length,65 int prot, int flags, int fd, OFF_T offset) {66 return (uptr)_REAL64(mmap)(addr, length, prot, flags, fd, offset);67}68 69DECLARE__REAL_AND_INTERNAL(uptr, munmap, void *addr, uptr length) {70 return _REAL(munmap)(addr, length);71}72 73DECLARE__REAL_AND_INTERNAL(int, mprotect, void *addr, uptr length, int prot) {74 return _REAL(mprotect)(addr, length, prot);75}76 77// Illumos' declaration of madvise cannot be made visible if _XOPEN_SOURCE78// is defined as g++ does on Solaris.79//80// This declaration is consistent with Solaris 11.4. Both Illumos and Solaris81// versions older than 11.4 declared madvise with a caddr_t as the first82// argument, but we don't currently support Solaris versions older than 11.4,83// and as mentioned above the declaration is not visible on Illumos so we can84// use any declaration we like on Illumos.85extern "C" int madvise(void *, size_t, int);86 87int internal_madvise(uptr addr, uptr length, int advice) {88 return madvise((void *)addr, length, advice);89}90 91DECLARE__REAL_AND_INTERNAL(uptr, close, fd_t fd) {92 return _REAL(close)(fd);93}94 95extern "C" int _REAL64(open)(const char *, int, ...);96 97uptr internal_open(const char *filename, int flags) {98 return _REAL64(open)(filename, flags);99}100 101uptr internal_open(const char *filename, int flags, u32 mode) {102 return _REAL64(open)(filename, flags, mode);103}104 105DECLARE__REAL_AND_INTERNAL(uptr, read, fd_t fd, void *buf, uptr count) {106 return _REAL(read)(fd, buf, count);107}108 109DECLARE__REAL_AND_INTERNAL(uptr, write, fd_t fd, const void *buf, uptr count) {110 return _REAL(write)(fd, buf, count);111}112 113// FIXME: There's only _ftruncate64 beginning with Solaris 11.114DECLARE__REAL_AND_INTERNAL(uptr, ftruncate, fd_t fd, uptr size) {115 return ftruncate(fd, size);116}117 118DECLARE__REAL_AND_INTERNAL64(uptr, stat, const char *path, void *buf) {119 return _REAL64(stat)(path, (struct stat *)buf);120}121 122DECLARE__REAL_AND_INTERNAL64(uptr, lstat, const char *path, void *buf) {123 return _REAL64(lstat)(path, (struct stat *)buf);124}125 126DECLARE__REAL_AND_INTERNAL64(uptr, fstat, fd_t fd, void *buf) {127 return _REAL64(fstat)(fd, (struct stat *)buf);128}129 130uptr internal_filesize(fd_t fd) {131 struct stat st;132 if (internal_fstat(fd, &st))133 return -1;134 return (uptr)st.st_size;135}136 137DECLARE__REAL_AND_INTERNAL(uptr, dup, int oldfd) {138 return _REAL(dup)(oldfd);139}140 141DECLARE__REAL_AND_INTERNAL(uptr, dup2, int oldfd, int newfd) {142 return _REAL(dup2)(oldfd, newfd);143}144 145DECLARE__REAL_AND_INTERNAL(uptr, readlink, const char *path, char *buf,146 uptr bufsize) {147 return _REAL(readlink)(path, buf, bufsize);148}149 150DECLARE__REAL_AND_INTERNAL(uptr, unlink, const char *path) {151 return _REAL(unlink)(path);152}153 154DECLARE__REAL_AND_INTERNAL(uptr, rename, const char *oldpath,155 const char *newpath) {156 return _REAL(rename)(oldpath, newpath);157}158 159DECLARE__REAL_AND_INTERNAL(uptr, sched_yield, void) {160 return sched_yield();161}162 163DECLARE__REAL_AND_INTERNAL(void, usleep, u64 useconds) {164 struct timespec ts;165 ts.tv_sec = useconds / 1000000;166 ts.tv_nsec = (useconds % 1000000) * 1000;167 nanosleep(&ts, nullptr);168}169 170DECLARE__REAL_AND_INTERNAL(uptr, execve, const char *filename,171 char *const argv[], char *const envp[]) {172 return _REAL(execve)(filename, argv, envp);173}174 175DECLARE__REAL_AND_INTERNAL(uptr, waitpid, int pid, int *status, int options) {176 return _REAL(waitpid)(pid, status, options);177}178 179DECLARE__REAL_AND_INTERNAL(uptr, getpid, void) {180 return _REAL(getpid)();181}182 183// FIXME: This might be wrong: _getdents doesn't take a struct linux_dirent *.184DECLARE__REAL_AND_INTERNAL64(uptr, getdents, fd_t fd, struct linux_dirent *dirp,185 unsigned int count) {186 return _REAL64(getdents)(fd, dirp, count);187}188 189DECLARE__REAL_AND_INTERNAL64(uptr, lseek, fd_t fd, OFF_T offset, int whence) {190 return _REAL64(lseek)(fd, offset, whence);191}192 193// FIXME: This might be wrong: _sigfillset doesn't take a194// __sanitizer_sigset_t *.195DECLARE__REAL_AND_INTERNAL(void, sigfillset, __sanitizer_sigset_t *set) {196 _REAL(sigfillset)(set);197}198 199// FIXME: This might be wrong: _sigprocmask doesn't take __sanitizer_sigset_t *.200DECLARE__REAL_AND_INTERNAL(uptr, sigprocmask, int how,201 __sanitizer_sigset_t *set,202 __sanitizer_sigset_t *oldset) {203 return _REAL(sigprocmask)(how, set, oldset);204}205 206DECLARE__REAL_AND_INTERNAL(int, fork, void) {207 // TODO(glider): this may call user's pthread_atfork() handlers which is bad.208 return _REAL(fork)();209}210 211u64 NanoTime() {212 return gethrtime();213}214 215uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {216 // FIXME: No internal variant.217 return clock_gettime(clk_id, (timespec *)tp);218}219 220// ----------------- sanitizer_common.h221void FutexWait(atomic_uint32_t *p, u32 cmp) {222 // FIXME: implement actual blocking.223 sched_yield();224}225 226void FutexWake(atomic_uint32_t *p, u32 count) {}227 228} // namespace __sanitizer229 230#endif // SANITIZER_SOLARIS231