xref: /freebsd-src/contrib/llvm-project/compiler-rt/lib/sanitizer_common/sanitizer_solaris.cpp (revision 349cc55c9796c4596a5b9904cd3281af295f878f)
168d75effSDimitry Andric //===-- sanitizer_solaris.cpp ---------------------------------------------===//
268d75effSDimitry Andric //
368d75effSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
468d75effSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
568d75effSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
668d75effSDimitry Andric //
768d75effSDimitry Andric //===----------------------------------------------------------------------===//
868d75effSDimitry Andric //
968d75effSDimitry Andric // This file is shared between various sanitizers' runtime libraries and
1068d75effSDimitry Andric // implements Solaris-specific functions.
1168d75effSDimitry Andric //===----------------------------------------------------------------------===//
1268d75effSDimitry Andric 
1368d75effSDimitry Andric #include "sanitizer_platform.h"
1468d75effSDimitry Andric #if SANITIZER_SOLARIS
1568d75effSDimitry Andric 
1668d75effSDimitry Andric #include <stdio.h>
1768d75effSDimitry Andric 
1868d75effSDimitry Andric #include "sanitizer_common.h"
1968d75effSDimitry Andric #include "sanitizer_flags.h"
2068d75effSDimitry Andric #include "sanitizer_internal_defs.h"
2168d75effSDimitry Andric #include "sanitizer_libc.h"
2268d75effSDimitry Andric #include "sanitizer_placement_new.h"
2368d75effSDimitry Andric #include "sanitizer_platform_limits_posix.h"
2468d75effSDimitry Andric #include "sanitizer_procmaps.h"
2568d75effSDimitry Andric 
2668d75effSDimitry Andric #include <fcntl.h>
2768d75effSDimitry Andric #include <pthread.h>
2868d75effSDimitry Andric #include <sched.h>
2968d75effSDimitry Andric #include <thread.h>
3068d75effSDimitry Andric #include <synch.h>
3168d75effSDimitry Andric #include <signal.h>
3268d75effSDimitry Andric #include <sys/mman.h>
3368d75effSDimitry Andric #include <sys/resource.h>
3468d75effSDimitry Andric #include <sys/stat.h>
3568d75effSDimitry Andric #include <sys/types.h>
3668d75effSDimitry Andric #include <dirent.h>
3768d75effSDimitry Andric #include <unistd.h>
3868d75effSDimitry Andric #include <errno.h>
3968d75effSDimitry Andric #include <stdlib.h>
4068d75effSDimitry Andric 
4168d75effSDimitry Andric namespace __sanitizer {
4268d75effSDimitry Andric 
4368d75effSDimitry Andric //#include "sanitizer_syscall_generic.inc"
4468d75effSDimitry Andric 
4568d75effSDimitry Andric #define _REAL(func) _ ## func
4668d75effSDimitry Andric #define DECLARE__REAL(ret_type, func, ...) \
4768d75effSDimitry Andric   extern "C" ret_type _REAL(func)(__VA_ARGS__)
4868d75effSDimitry Andric #define DECLARE__REAL_AND_INTERNAL(ret_type, func, ...) \
4968d75effSDimitry Andric   DECLARE__REAL(ret_type, func, __VA_ARGS__); \
5068d75effSDimitry Andric   ret_type internal_ ## func(__VA_ARGS__)
5168d75effSDimitry Andric 
5268d75effSDimitry Andric #if !defined(_LP64) && _FILE_OFFSET_BITS == 64
5368d75effSDimitry Andric #define _REAL64(func) _ ## func ## 64
5468d75effSDimitry Andric #else
5568d75effSDimitry Andric #define _REAL64(func) _REAL(func)
5668d75effSDimitry Andric #endif
5768d75effSDimitry Andric #define DECLARE__REAL64(ret_type, func, ...) \
5868d75effSDimitry Andric   extern "C" ret_type _REAL64(func)(__VA_ARGS__)
5968d75effSDimitry Andric #define DECLARE__REAL_AND_INTERNAL64(ret_type, func, ...) \
6068d75effSDimitry Andric   DECLARE__REAL64(ret_type, func, __VA_ARGS__); \
6168d75effSDimitry Andric   ret_type internal_ ## func(__VA_ARGS__)
6268d75effSDimitry Andric 
6368d75effSDimitry Andric // ---------------------- sanitizer_libc.h
DECLARE__REAL_AND_INTERNAL64(uptr,mmap,void * addr,uptr length,int prot,int flags,int fd,OFF_T offset)6468d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL64(uptr, mmap, void *addr, uptr /*size_t*/ length,
6568d75effSDimitry Andric                              int prot, int flags, int fd, OFF_T offset) {
6668d75effSDimitry Andric   return (uptr)_REAL64(mmap)(addr, length, prot, flags, fd, offset);
6768d75effSDimitry Andric }
6868d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL(uptr,munmap,void * addr,uptr length)6968d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(uptr, munmap, void *addr, uptr length) {
7068d75effSDimitry Andric   return _REAL(munmap)(addr, length);
7168d75effSDimitry Andric }
7268d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL(int,mprotect,void * addr,uptr length,int prot)7368d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(int, mprotect, void *addr, uptr length, int prot) {
7468d75effSDimitry Andric   return _REAL(mprotect)(addr, length, prot);
7568d75effSDimitry Andric }
7668d75effSDimitry Andric 
77e8d8bef9SDimitry Andric // Illumos' declaration of madvise cannot be made visible if _XOPEN_SOURCE
78e8d8bef9SDimitry Andric // is defined as g++ does on Solaris.
79e8d8bef9SDimitry Andric //
80e8d8bef9SDimitry Andric // This declaration is consistent with Solaris 11.4. Both Illumos and Solaris
81e8d8bef9SDimitry Andric // versions older than 11.4 declared madvise with a caddr_t as the first
82e8d8bef9SDimitry Andric // argument, but we don't currently support Solaris versions older than 11.4,
83e8d8bef9SDimitry Andric // and as mentioned above the declaration is not visible on Illumos so we can
84e8d8bef9SDimitry Andric // use any declaration we like on Illumos.
85e8d8bef9SDimitry Andric extern "C" int madvise(void *, size_t, int);
86e8d8bef9SDimitry Andric 
internal_madvise(uptr addr,uptr length,int advice)87e8d8bef9SDimitry Andric int internal_madvise(uptr addr, uptr length, int advice) {
88e8d8bef9SDimitry Andric   return madvise((void *)addr, length, advice);
89e8d8bef9SDimitry Andric }
90e8d8bef9SDimitry Andric 
DECLARE__REAL_AND_INTERNAL(uptr,close,fd_t fd)9168d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(uptr, close, fd_t fd) {
9268d75effSDimitry Andric   return _REAL(close)(fd);
9368d75effSDimitry Andric }
9468d75effSDimitry Andric 
9568d75effSDimitry Andric extern "C" int _REAL64(open)(const char *, int, ...);
9668d75effSDimitry Andric 
internal_open(const char * filename,int flags)9768d75effSDimitry Andric uptr internal_open(const char *filename, int flags) {
9868d75effSDimitry Andric   return _REAL64(open)(filename, flags);
9968d75effSDimitry Andric }
10068d75effSDimitry Andric 
internal_open(const char * filename,int flags,u32 mode)10168d75effSDimitry Andric uptr internal_open(const char *filename, int flags, u32 mode) {
10268d75effSDimitry Andric   return _REAL64(open)(filename, flags, mode);
10368d75effSDimitry Andric }
10468d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL(uptr,read,fd_t fd,void * buf,uptr count)10568d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(uptr, read, fd_t fd, void *buf, uptr count) {
10668d75effSDimitry Andric   return _REAL(read)(fd, buf, count);
10768d75effSDimitry Andric }
10868d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL(uptr,write,fd_t fd,const void * buf,uptr count)10968d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(uptr, write, fd_t fd, const void *buf, uptr count) {
11068d75effSDimitry Andric   return _REAL(write)(fd, buf, count);
11168d75effSDimitry Andric }
11268d75effSDimitry Andric 
11368d75effSDimitry Andric // FIXME: There's only _ftruncate64 beginning with Solaris 11.
DECLARE__REAL_AND_INTERNAL(uptr,ftruncate,fd_t fd,uptr size)11468d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(uptr, ftruncate, fd_t fd, uptr size) {
11568d75effSDimitry Andric   return ftruncate(fd, size);
11668d75effSDimitry Andric }
11768d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL64(uptr,stat,const char * path,void * buf)11868d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL64(uptr, stat, const char *path, void *buf) {
11968d75effSDimitry Andric   return _REAL64(stat)(path, (struct stat *)buf);
12068d75effSDimitry Andric }
12168d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL64(uptr,lstat,const char * path,void * buf)12268d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL64(uptr, lstat, const char *path, void *buf) {
12368d75effSDimitry Andric   return _REAL64(lstat)(path, (struct stat *)buf);
12468d75effSDimitry Andric }
12568d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL64(uptr,fstat,fd_t fd,void * buf)12668d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL64(uptr, fstat, fd_t fd, void *buf) {
12768d75effSDimitry Andric   return _REAL64(fstat)(fd, (struct stat *)buf);
12868d75effSDimitry Andric }
12968d75effSDimitry Andric 
internal_filesize(fd_t fd)13068d75effSDimitry Andric uptr internal_filesize(fd_t fd) {
13168d75effSDimitry Andric   struct stat st;
13268d75effSDimitry Andric   if (internal_fstat(fd, &st))
13368d75effSDimitry Andric     return -1;
13468d75effSDimitry Andric   return (uptr)st.st_size;
13568d75effSDimitry Andric }
13668d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL(uptr,dup,int oldfd)13768d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(uptr, dup, int oldfd) {
13868d75effSDimitry Andric   return _REAL(dup)(oldfd);
13968d75effSDimitry Andric }
14068d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL(uptr,dup2,int oldfd,int newfd)14168d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(uptr, dup2, int oldfd, int newfd) {
14268d75effSDimitry Andric   return _REAL(dup2)(oldfd, newfd);
14368d75effSDimitry Andric }
14468d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL(uptr,readlink,const char * path,char * buf,uptr bufsize)14568d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(uptr, readlink, const char *path, char *buf,
14668d75effSDimitry Andric                            uptr bufsize) {
14768d75effSDimitry Andric   return _REAL(readlink)(path, buf, bufsize);
14868d75effSDimitry Andric }
14968d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL(uptr,unlink,const char * path)15068d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(uptr, unlink, const char *path) {
15168d75effSDimitry Andric   return _REAL(unlink)(path);
15268d75effSDimitry Andric }
15368d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL(uptr,rename,const char * oldpath,const char * newpath)15468d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(uptr, rename, const char *oldpath,
15568d75effSDimitry Andric                            const char *newpath) {
15668d75effSDimitry Andric   return _REAL(rename)(oldpath, newpath);
15768d75effSDimitry Andric }
15868d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL(uptr,sched_yield,void)15968d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(uptr, sched_yield, void) {
16068d75effSDimitry Andric   return sched_yield();
16168d75effSDimitry Andric }
16268d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL(void,usleep,u64 useconds)163*fe6060f1SDimitry Andric DECLARE__REAL_AND_INTERNAL(void, usleep, u64 useconds) {
164*fe6060f1SDimitry Andric   struct timespec ts;
165*fe6060f1SDimitry Andric   ts.tv_sec = useconds / 1000000;
166*fe6060f1SDimitry Andric   ts.tv_nsec = (useconds % 1000000) * 1000;
167*fe6060f1SDimitry Andric   nanosleep(&ts, nullptr);
168*fe6060f1SDimitry Andric }
169*fe6060f1SDimitry Andric 
DECLARE__REAL_AND_INTERNAL(uptr,execve,const char * filename,char * const argv[],char * const envp[])17068d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(uptr, execve, const char *filename,
17168d75effSDimitry Andric                            char *const argv[], char *const envp[]) {
17268d75effSDimitry Andric   return _REAL(execve)(filename, argv, envp);
17368d75effSDimitry Andric }
17468d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL(uptr,waitpid,int pid,int * status,int options)17568d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(uptr, waitpid, int pid, int *status, int options) {
17668d75effSDimitry Andric   return _REAL(waitpid)(pid, status, options);
17768d75effSDimitry Andric }
17868d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL(uptr,getpid,void)17968d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(uptr, getpid, void) {
18068d75effSDimitry Andric   return _REAL(getpid)();
18168d75effSDimitry Andric }
18268d75effSDimitry Andric 
18368d75effSDimitry Andric // FIXME: This might be wrong: _getdents doesn't take a struct linux_dirent *.
DECLARE__REAL_AND_INTERNAL64(uptr,getdents,fd_t fd,struct linux_dirent * dirp,unsigned int count)18468d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL64(uptr, getdents, fd_t fd, struct linux_dirent *dirp,
18568d75effSDimitry Andric                              unsigned int count) {
18668d75effSDimitry Andric   return _REAL64(getdents)(fd, dirp, count);
18768d75effSDimitry Andric }
18868d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL64(uptr,lseek,fd_t fd,OFF_T offset,int whence)18968d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL64(uptr, lseek, fd_t fd, OFF_T offset, int whence) {
19068d75effSDimitry Andric   return _REAL64(lseek)(fd, offset, whence);
19168d75effSDimitry Andric }
19268d75effSDimitry Andric 
19368d75effSDimitry Andric // FIXME: This might be wrong: _sigfillset doesn't take a
19468d75effSDimitry Andric // __sanitizer_sigset_t *.
DECLARE__REAL_AND_INTERNAL(void,sigfillset,__sanitizer_sigset_t * set)19568d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(void, sigfillset, __sanitizer_sigset_t *set) {
19668d75effSDimitry Andric   _REAL(sigfillset)(set);
19768d75effSDimitry Andric }
19868d75effSDimitry Andric 
19968d75effSDimitry Andric // FIXME: This might be wrong: _sigprocmask doesn't take __sanitizer_sigset_t *.
DECLARE__REAL_AND_INTERNAL(uptr,sigprocmask,int how,__sanitizer_sigset_t * set,__sanitizer_sigset_t * oldset)20068d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(uptr, sigprocmask, int how,
20168d75effSDimitry Andric                            __sanitizer_sigset_t *set,
20268d75effSDimitry Andric                            __sanitizer_sigset_t *oldset) {
20368d75effSDimitry Andric   return _REAL(sigprocmask)(how, set, oldset);
20468d75effSDimitry Andric }
20568d75effSDimitry Andric 
DECLARE__REAL_AND_INTERNAL(int,fork,void)20668d75effSDimitry Andric DECLARE__REAL_AND_INTERNAL(int, fork, void) {
20768d75effSDimitry Andric   // TODO(glider): this may call user's pthread_atfork() handlers which is bad.
20868d75effSDimitry Andric   return _REAL(fork)();
20968d75effSDimitry Andric }
21068d75effSDimitry Andric 
NanoTime()21168d75effSDimitry Andric u64 NanoTime() {
21268d75effSDimitry Andric   return gethrtime();
21368d75effSDimitry Andric }
21468d75effSDimitry Andric 
internal_clock_gettime(__sanitizer_clockid_t clk_id,void * tp)21568d75effSDimitry Andric uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) {
21668d75effSDimitry Andric   // FIXME: No internal variant.
21768d75effSDimitry Andric   return clock_gettime(clk_id, (timespec *)tp);
21868d75effSDimitry Andric }
21968d75effSDimitry Andric 
22068d75effSDimitry Andric // ----------------- sanitizer_common.h
FutexWait(atomic_uint32_t * p,u32 cmp)221*fe6060f1SDimitry Andric void FutexWait(atomic_uint32_t *p, u32 cmp) {
222*fe6060f1SDimitry Andric   // FIXME: implement actual blocking.
223*fe6060f1SDimitry Andric   sched_yield();
224*fe6060f1SDimitry Andric }
225*fe6060f1SDimitry Andric 
FutexWake(atomic_uint32_t * p,u32 count)226*fe6060f1SDimitry Andric void FutexWake(atomic_uint32_t *p, u32 count) {}
227*fe6060f1SDimitry Andric 
22868d75effSDimitry Andric }  // namespace __sanitizer
22968d75effSDimitry Andric 
23068d75effSDimitry Andric #endif  // SANITIZER_SOLARIS
231