Index: lib/asan/asan_interceptors.h =================================================================== --- lib/asan/asan_interceptors.h +++ lib/asan/asan_interceptors.h @@ -55,13 +55,14 @@ # define ASAN_INTERCEPT_FORK 0 #endif -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS # define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 1 #else # define ASAN_USE_ALIAS_ATTRIBUTE_FOR_INDEX 0 #endif -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_SOLARIS # define ASAN_INTERCEPT_SWAPCONTEXT 1 #else # define ASAN_INTERCEPT_SWAPCONTEXT 0 @@ -81,7 +82,8 @@ // Android bug: https://code.google.com/p/android/issues/detail?id=61799 #if ASAN_HAS_EXCEPTIONS && !SANITIZER_WINDOWS && \ - !(SANITIZER_ANDROID && defined(__i386)) + !(SANITIZER_ANDROID && defined(__i386)) && \ + !SANITIZER_SOLARIS # define ASAN_INTERCEPT___CXA_THROW 1 #else # define ASAN_INTERCEPT___CXA_THROW 0 Index: lib/asan/asan_linux.cc =================================================================== --- lib/asan/asan_linux.cc +++ lib/asan/asan_linux.cc @@ -13,7 +13,8 @@ //===----------------------------------------------------------------------===// #include "sanitizer_common/sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS #include "asan_interceptors.h" #include "asan_internal.h" @@ -40,7 +41,11 @@ #include #endif -#if SANITIZER_ANDROID || SANITIZER_FREEBSD +#if SANITIZER_SOLARIS +#include +#endif + +#if SANITIZER_ANDROID || SANITIZER_FREEBSD || SANITIZER_SOLARIS #include extern "C" void* _DYNAMIC; #elif SANITIZER_NETBSD @@ -140,6 +145,9 @@ #else static int FindFirstDSOCallback(struct dl_phdr_info *info, size_t size, void *data) { + VReport(2, "info->dlpi_name = %s\tinfo->dlpi_addr = %p\n", + info->dlpi_name, info->dlpi_addr); + // Continue until the first dynamic library is found if (!info->dlpi_name || info->dlpi_name[0] == 0) return 0; @@ -157,6 +165,12 @@ } #endif +#if SANITIZER_SOLARIS + // Ignore executable on Solaris + if (info->dlpi_addr == 0) + return 0; +#endif + *(const char **)data = info->dlpi_name; return 1; } @@ -235,4 +249,5 @@ } // namespace __asan -#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || + // SANITIZER_SOLARIS Index: lib/asan/asan_malloc_linux.cc =================================================================== --- lib/asan/asan_malloc_linux.cc +++ lib/asan/asan_malloc_linux.cc @@ -16,7 +16,7 @@ #include "sanitizer_common/sanitizer_platform.h" #if SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX || \ - SANITIZER_NETBSD + SANITIZER_NETBSD || SANITIZER_SOLARIS #include "sanitizer_common/sanitizer_tls_get_addr.h" #include "asan_allocator.h" @@ -236,4 +236,4 @@ #endif // SANITIZER_ANDROID #endif // SANITIZER_FREEBSD || SANITIZER_FUCHSIA || SANITIZER_LINUX || - // SANITIZER_NETBSD + // SANITIZER_NETBSD || SANITIZER_SOLARIS Index: lib/interception/interception.h =================================================================== --- lib/interception/interception.h +++ lib/interception/interception.h @@ -18,7 +18,8 @@ #include "sanitizer_common/sanitizer_internal_defs.h" #if !SANITIZER_LINUX && !SANITIZER_FREEBSD && !SANITIZER_MAC && \ - !SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA + !SANITIZER_NETBSD && !SANITIZER_WINDOWS && !SANITIZER_FUCHSIA && \ + !SANITIZER_SOLARIS # error "Interception doesn't work on this operating system." #endif @@ -264,7 +265,9 @@ #define INCLUDED_FROM_INTERCEPTION_LIB -#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS + # include "interception_linux.h" # define INTERCEPT_FUNCTION(func) INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) # define INTERCEPT_FUNCTION_VER(func, symver) \ Index: lib/interception/interception_linux.h =================================================================== --- lib/interception/interception_linux.h +++ lib/interception/interception_linux.h @@ -12,7 +12,8 @@ // Linux-specific interception methods. //===----------------------------------------------------------------------===// -#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS #if !defined(INCLUDED_FROM_INTERCEPTION_LIB) # error "interception_linux.h should be included from interception library only" @@ -34,14 +35,16 @@ (::__interception::uptr) & (func), \ (::__interception::uptr) & WRAP(func)) -#if !SANITIZER_ANDROID // android does not have dlvsym +// Android and Solaris do not have dlvsym +#if !SANITIZER_ANDROID && !SANITIZER_SOLARIS #define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \ (::__interception::real_##func = (func##_f)( \ unsigned long)::__interception::GetFuncAddrVer(#func, symver)) #else #define INTERCEPT_FUNCTION_VER_LINUX_OR_FREEBSD(func, symver) \ INTERCEPT_FUNCTION_LINUX_OR_FREEBSD(func) -#endif // !SANITIZER_ANDROID +#endif // !SANITIZER_ANDROID && !SANITIZER_SOLARIS #endif // INTERCEPTION_LINUX_H -#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD +#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || + // SANITIZER_SOLARIS Index: lib/interception/interception_linux.cc =================================================================== --- lib/interception/interception_linux.cc +++ lib/interception/interception_linux.cc @@ -14,7 +14,8 @@ #include "interception.h" -#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS #include // for dlsym() and dlvsym() @@ -41,7 +42,8 @@ return real == wrapper; } -#if !SANITIZER_ANDROID // android does not have dlvsym +// Android and Solaris do not have dlvsym +#if !SANITIZER_ANDROID && !SANITIZER_SOLARIS void *GetFuncAddrVer(const char *func_name, const char *ver) { return dlvsym(RTLD_NEXT, func_name, ver); } @@ -49,4 +51,5 @@ } // namespace __interception -#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD +#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || + // SANITIZER_SOLARIS Index: lib/sanitizer_common/sanitizer_common_interceptors.inc =================================================================== --- lib/sanitizer_common/sanitizer_common_interceptors.inc +++ lib/sanitizer_common/sanitizer_common_interceptors.inc @@ -1217,12 +1217,14 @@ #if SANITIZER_INTERCEPT_LOCALTIME_AND_FRIENDS static void unpoison_tm(void *ctx, __sanitizer_tm *tm) { COMMON_INTERCEPTOR_WRITE_RANGE(ctx, tm, sizeof(*tm)); +#if !SANITIZER_SOLARIS if (tm->tm_zone) { // Can not use COMMON_INTERCEPTOR_WRITE_RANGE here, because tm->tm_zone // can point to shared memory and tsan would report a data race. COMMON_INTERCEPTOR_INITIALIZE_RANGE(tm->tm_zone, REAL(strlen(tm->tm_zone)) + 1); } +#endif } INTERCEPTOR(__sanitizer_tm *, localtime, unsigned long *timep) { void *ctx; @@ -2106,6 +2108,7 @@ } } +#if !SANITIZER_SOLARIS static THREADLOCAL __sanitizer_glob_t *pglob_copy; static void wrapped_gl_closedir(void *dir) { @@ -2140,6 +2143,7 @@ 0, 0, 0, 0, wrapped_gl_closedir, wrapped_gl_readdir, wrapped_gl_opendir, wrapped_gl_lstat, wrapped_gl_stat}; +#endif // SANITIZER_SOLARIS INTERCEPTOR(int, glob, const char *pattern, int flags, int (*errfunc)(const char *epath, int eerrno), @@ -2147,6 +2151,7 @@ void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, glob, pattern, flags, errfunc, pglob); COMMON_INTERCEPTOR_READ_STRING(ctx, pattern, 0); +#if !SANITIZER_SOLARIS __sanitizer_glob_t glob_copy; internal_memcpy(&glob_copy, &kGlobCopy, sizeof(glob_copy)); if (flags & glob_altdirfunc) { @@ -2157,7 +2162,9 @@ Swap(pglob->gl_stat, glob_copy.gl_stat); pglob_copy = &glob_copy; } +#endif int res = REAL(glob)(pattern, flags, errfunc, pglob); +#if !SANITIZER_SOLARIS if (flags & glob_altdirfunc) { Swap(pglob->gl_closedir, glob_copy.gl_closedir); Swap(pglob->gl_readdir, glob_copy.gl_readdir); @@ -2166,10 +2173,17 @@ Swap(pglob->gl_stat, glob_copy.gl_stat); } pglob_copy = 0; +#endif if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); return res; } - +#define INIT_GLOB \ + COMMON_INTERCEPT_FUNCTION(glob); +#else // SANITIZER_INTERCEPT_GLOB +#define INIT_GLOB +#endif // SANITIZER_INTERCEPT_GLOB + +#if SANITIZER_INTERCEPT_GLOB64 INTERCEPTOR(int, glob64, const char *pattern, int flags, int (*errfunc)(const char *epath, int eerrno), __sanitizer_glob_t *pglob) { @@ -2198,12 +2212,11 @@ if ((!res || res == glob_nomatch) && pglob) unpoison_glob_t(ctx, pglob); return res; } -#define INIT_GLOB \ - COMMON_INTERCEPT_FUNCTION(glob); \ +#define INIT_GLOB64 \ COMMON_INTERCEPT_FUNCTION(glob64); -#else // SANITIZER_INTERCEPT_GLOB -#define INIT_GLOB -#endif // SANITIZER_INTERCEPT_GLOB +#else // SANITIZER_INTERCEPT_GLOB64 +#define INIT_GLOB64 +#endif // SANITIZER_INTERCEPT_GLOB64 #if SANITIZER_INTERCEPT_WAIT // According to sys/wait.h, wait(), waitid(), waitpid() may have symbol version @@ -2508,7 +2521,15 @@ if (res) write_hostent(ctx, res); return res; } - +#define INIT_GETHOSTBYNAME \ + COMMON_INTERCEPT_FUNCTION(gethostent); \ + COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \ + COMMON_INTERCEPT_FUNCTION(gethostbyname); +#else +#define INIT_GETHOSTBYNAME +#endif + +#if SANITIZER_INTERCEPT_GETHOSTBYNAME2 INTERCEPTOR(struct __sanitizer_hostent *, gethostbyname2, char *name, int af) { void *ctx; COMMON_INTERCEPTOR_ENTER(ctx, gethostbyname2, name, af); @@ -2516,13 +2537,9 @@ if (res) write_hostent(ctx, res); return res; } -#define INIT_GETHOSTBYNAME \ - COMMON_INTERCEPT_FUNCTION(gethostent); \ - COMMON_INTERCEPT_FUNCTION(gethostbyaddr); \ - COMMON_INTERCEPT_FUNCTION(gethostbyname); \ - COMMON_INTERCEPT_FUNCTION(gethostbyname2); -#else -#define INIT_GETHOSTBYNAME +#define INIT_GETHOSTBYNAME2 COMMON_INTERCEPT_FUNCTION(gethostbyname2); +#else +#define INIT_GETHOSTBYNAME2 #endif #if SANITIZER_INTERCEPT_GETHOSTBYNAME_R @@ -4166,12 +4183,16 @@ int res = REAL(shmctl)(shmid, cmd, buf); if (res >= 0) { unsigned sz = 0; - if (cmd == shmctl_ipc_stat || cmd == shmctl_shm_stat) + if (cmd == shmctl_ipc_stat) + sz = sizeof(__sanitizer_shmid_ds); +#if !SANITIZER_SOLARIS + else if (cmd == shmctl_shm_stat) sz = sizeof(__sanitizer_shmid_ds); else if (cmd == shmctl_ipc_info) sz = struct_shminfo_sz; else if (cmd == shmctl_shm_info) sz = struct_shm_info_sz; +#endif if (sz) COMMON_INTERCEPTOR_WRITE_RANGE(ctx, buf, sz); } return res; @@ -6377,6 +6398,7 @@ INIT_GETITIMER; INIT_TIME; INIT_GLOB; + INIT_GLOB64; INIT_WAIT; INIT_WAIT4; INIT_INET; @@ -6385,6 +6407,7 @@ INIT_GETNAMEINFO; INIT_GETSOCKNAME; INIT_GETHOSTBYNAME; + INIT_GETHOSTBYNAME2; INIT_GETHOSTBYNAME_R; INIT_GETHOSTBYNAME2_R; INIT_GETHOSTBYADDR_R; Index: lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc =================================================================== --- lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc +++ lib/sanitizer_common/sanitizer_common_interceptors_ioctl.inc @@ -57,7 +57,9 @@ _(SIOCGIFCONF, CUSTOM, 0); _(SIOCGPGRP, WRITE, sizeof(int)); _(SIOCSPGRP, READ, sizeof(int)); +#if !SANITIZER_SOLARIS _(TIOCCONS, NONE, 0); +#endif _(TIOCEXCL, NONE, 0); _(TIOCGETD, WRITE, sizeof(int)); _(TIOCGPGRP, WRITE, pid_t_sz); Index: lib/sanitizer_common/sanitizer_errno.h =================================================================== --- lib/sanitizer_common/sanitizer_errno.h +++ lib/sanitizer_common/sanitizer_errno.h @@ -26,6 +26,8 @@ # define __errno_location __error #elif SANITIZER_ANDROID || SANITIZER_NETBSD # define __errno_location __errno +#elif SANITIZER_SOLARIS +# define __errno_location ___errno #elif SANITIZER_WINDOWS # define __errno_location _errno #endif Index: lib/sanitizer_common/sanitizer_internal_defs.h =================================================================== --- lib/sanitizer_common/sanitizer_internal_defs.h +++ lib/sanitizer_common/sanitizer_internal_defs.h @@ -65,7 +65,7 @@ // SANITIZER_SUPPORTS_WEAK_HOOKS means that we support real weak functions that // will evaluate to a null pointer when not defined. #ifndef SANITIZER_SUPPORTS_WEAK_HOOKS -#if (SANITIZER_LINUX || SANITIZER_MAC) && !SANITIZER_GO +#if (SANITIZER_LINUX || SANITIZER_MAC || SANITIZER_SOLARIS) && !SANITIZER_GO # define SANITIZER_SUPPORTS_WEAK_HOOKS 1 #else # define SANITIZER_SUPPORTS_WEAK_HOOKS 0 @@ -91,6 +91,10 @@ // FIXME: do we have anything like this on Mac? #if SANITIZER_LINUX && !SANITIZER_ANDROID && !defined(PIC) # define SANITIZER_CAN_USE_PREINIT_ARRAY 1 +// Before Solaris 11.4, .preinit_array is fully supported only with GNU ld. +// FIXME: Check for those conditions. +#elif SANITIZER_SOLARIS && !defined(PIC) +# define SANITIZER_CAN_USE_PREINIT_ARRAY 1 #else # define SANITIZER_CAN_USE_PREINIT_ARRAY 0 #endif @@ -137,7 +141,11 @@ typedef int fd_t; typedef int error_t; #endif +#if SANITIZER_SOLARIS && !defined(_LP64) +typedef long pid_t; +#else typedef int pid_t; +#endif #if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC || \ (SANITIZER_LINUX && defined(__x86_64__)) Index: lib/sanitizer_common/sanitizer_linux.h =================================================================== --- lib/sanitizer_common/sanitizer_linux.h +++ lib/sanitizer_common/sanitizer_linux.h @@ -14,7 +14,8 @@ #define SANITIZER_LINUX_H #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS #include "sanitizer_common.h" #include "sanitizer_internal_defs.h" #include "sanitizer_platform_limits_netbsd.h" @@ -142,5 +143,6 @@ } // namespace __sanitizer -#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || + // SANITIZER_SOLARIS #endif // SANITIZER_LINUX_H Index: lib/sanitizer_common/sanitizer_linux.cc =================================================================== --- lib/sanitizer_common/sanitizer_linux.cc +++ lib/sanitizer_common/sanitizer_linux.cc @@ -14,7 +14,8 @@ #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS #include "sanitizer_common.h" #include "sanitizer_flags.h" @@ -55,7 +56,9 @@ #include #include #include +#if !SANITIZER_SOLARIS #include +#endif #include #include #include @@ -92,6 +95,14 @@ extern struct ps_strings *__ps_strings; #endif // SANITIZER_NETBSD +#if SANITIZER_SOLARIS +#include +#include + +extern char **_environ; +#define environ _environ +#endif + #if !SANITIZER_ANDROID #include #endif @@ -146,6 +157,7 @@ #endif // --------------- sanitizer_libc.h +#if !SANITIZER_SOLARIS #if !SANITIZER_S390 uptr internal_mmap(void *addr, uptr length, int prot, int flags, int fd, OFF_T offset) { @@ -424,6 +436,7 @@ return internal_syscall_ptr(SYSCALL(execve), (uptr)filename, (uptr)argv, (uptr)envp); } +#endif // !SANITIZER_SOLARIS // ----------------- sanitizer_common.h bool FileExists(const char *filename) { @@ -443,12 +456,17 @@ return (uptr)pthread_self(); #elif SANITIZER_NETBSD return _lwp_self(); +#elif SANITIZER_SOLARIS + return (uptr)thr_self(); #else return internal_syscall(SYSCALL(gettid)); #endif } u64 NanoTime() { +#if SANITIZER_SOLARIS + return gethrtime(); +#else #if SANITIZER_FREEBSD || SANITIZER_NETBSD timeval tv; #else @@ -457,13 +475,14 @@ internal_memset(&tv, 0, sizeof(tv)); internal_syscall_ptr(SYSCALL(gettimeofday), &tv, 0); return (u64)tv.tv_sec * 1000*1000*1000 + tv.tv_usec * 1000; +#endif } // Like getenv, but reads env directly from /proc (on Linux) or parses the -// 'environ' array (on FreeBSD) and does not use libc. This function should be -// called first inside __asan_init. +// 'environ' array (on FreeBSD and Solaris) and does not use libc. This +// function should be called first inside __asan_init. const char *GetEnv(const char *name) { -#if SANITIZER_FREEBSD || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_SOLARIS if (::environ != 0) { uptr NameLen = internal_strlen(name); for (char **Env = ::environ; *Env != 0; Env++) { @@ -586,6 +605,9 @@ len = sizeof(path); if (sysctl(name, ARRAY_SIZE(name), path, &len, NULL, 0) != -1) pathname = path; +#elif SANITIZER_SOLARIS + pathname = getexecname(); + CHECK_NE(pathname, NULL); #endif GetArgsAndEnv(&argv, &envp); @@ -596,6 +618,7 @@ Die(); } +#if !SANITIZER_SOLARIS enum MutexState { MtxUnlocked = 0, MtxLocked = 1, @@ -641,6 +664,7 @@ atomic_uint32_t *m = reinterpret_cast(&opaque_storage_); CHECK_NE(MtxUnlocked, atomic_load(m, memory_order_relaxed)); } +#endif // !SANITIZER_SOLARIS // ----------------- sanitizer_linux.h // The actual size of this structure is specified by d_reclen. @@ -673,6 +697,7 @@ }; #endif +#if !SANITIZER_SOLARIS // Syscall wrappers. uptr internal_ptrace(int request, int pid, void *addr, void *data) { #if SANITIZER_NETBSD @@ -850,6 +875,7 @@ return k_set->sig[idx] & (1 << bit); } #endif // SANITIZER_LINUX +#endif // !SANITIZER_SOLARIS // ThreadLister implementation. ThreadLister::ThreadLister(int pid) @@ -1007,6 +1033,11 @@ } uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { +#if SANITIZER_SOLARIS + const char *default_module_name = getexecname(); + CHECK_NE(default_module_name, NULL); + return internal_snprintf(buf, buf_len, "%s", default_module_name); +#else #if SANITIZER_FREEBSD || SANITIZER_NETBSD #if SANITIZER_FREEBSD const int Mib[4] = {CTL_KERN, KERN_PROC, KERN_PROC_PATHNAME, -1}; @@ -1034,6 +1065,7 @@ CHECK_LT(module_name_len, buf_len); } return module_name_len; +#endif } uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) { @@ -1658,6 +1690,9 @@ uptr err = ucontext->uc_mcontext.mc_err; #elif SANITIZER_NETBSD uptr err = ucontext->uc_mcontext.__gregs[_REG_ERR]; +#elif SANITIZER_SOLARIS && defined(__i386__) +# define ERR 13 + uptr err = ucontext->uc_mcontext.gregs[ERR]; #else uptr err = ucontext->uc_mcontext.gregs[REG_ERR]; #endif @@ -1671,6 +1706,12 @@ u64 esr; if (!Aarch64GetESR(ucontext, &esr)) return UNKNOWN; return esr & ESR_ELx_WNR ? WRITE : READ; +#elif SANITIZER_SOLARIS && defined(__sparc__) + // Decode the instruction to determine the access type. + // From OpenSolaris $SRC/uts/sun4/os/trap.c (get_accesstype). + uptr pc = ucontext->uc_mcontext.gregs[REG_PC]; + u32 instr = *(u32 *)pc; + return (instr >> 21) & 1 ? WRITE: READ; #else (void)ucontext; return UNKNOWN; // FIXME: Implement. @@ -1728,6 +1769,19 @@ *sp = ucontext->uc_mcontext.__gregs[_REG_ESP]; # else ucontext_t *ucontext = (ucontext_t*)context; +# if SANITIZER_SOLARIS + /* Use the numeric values: the symbolic ones are undefined by llvm + include/llvm/Support/Solaris.h. */ +# ifndef REG_EIP +# define REG_EIP 14 // REG_PC +# endif +# ifndef REG_EBP +# define REG_EBP 6 // REG_FP +# endif +# ifndef REG_ESP +# define REG_ESP 17 // REG_SP +# endif +# endif *pc = ucontext->uc_mcontext.gregs[REG_EIP]; *bp = ucontext->uc_mcontext.gregs[REG_EBP]; *sp = ucontext->uc_mcontext.gregs[REG_ESP]; @@ -1742,7 +1796,16 @@ #elif defined(__sparc__) ucontext_t *ucontext = (ucontext_t*)context; uptr *stk_ptr; -# if defined (__arch64__) +# if defined (__sparcv9) +#ifndef MC_PC +# define MC_PC REG_PC +#endif +#ifndef MC_O6 +# define MC_O6 REG_O6 +#endif +#ifdef SANITIZER_SOLARIS +# define mc_gregs gregs +#endif *pc = ucontext->uc_mcontext.mc_gregs[MC_PC]; *sp = ucontext->uc_mcontext.mc_gregs[MC_O6]; stk_ptr = (uptr *) (*sp + 2047); @@ -1831,4 +1894,6 @@ } // namespace __sanitizer -#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || + // SANITIZER_SOLARIS + Index: lib/sanitizer_common/sanitizer_linux_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_linux_libcdep.cc +++ lib/sanitizer_common/sanitizer_linux_libcdep.cc @@ -14,7 +14,8 @@ #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS #include "sanitizer_allocator_internal.h" #include "sanitizer_atomic.h" @@ -45,6 +46,10 @@ #include #endif +#if SANITIZER_SOLARIS +#include +#endif + #if SANITIZER_LINUX #include #endif @@ -114,13 +119,20 @@ *stack_bottom = segment.end - stacksize; return; } + uptr stacksize = 0; + void *stackaddr = nullptr; +#if SANITIZER_SOLARIS + stack_t ss; + CHECK_EQ(thr_stksegment(&ss), 0); + stacksize = ss.ss_size; + stackaddr = (char *)ss.ss_sp - stacksize; +#else // !SANITIZER_SOLARIS pthread_attr_t attr; pthread_attr_init(&attr); CHECK_EQ(pthread_getattr_np(pthread_self(), &attr), 0); - uptr stacksize = 0; - void *stackaddr = nullptr; my_pthread_attr_getstack(&attr, &stackaddr, &stacksize); pthread_attr_destroy(&attr); +#endif *stack_top = (uptr)stackaddr + stacksize; *stack_bottom = (uptr)stackaddr; @@ -161,7 +173,7 @@ } #if !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO && \ - !SANITIZER_NETBSD + !SANITIZER_NETBSD && !SANITIZER_SOLARIS static uptr g_tls_size; #ifdef __i386__ @@ -190,7 +202,7 @@ #else void InitTlsSize() { } #endif // !SANITIZER_FREEBSD && !SANITIZER_ANDROID && !SANITIZER_GO && - // !SANITIZER_NETBSD + // !SANITIZER_NETBSD && !SANITIZER_SOLARIS #if (defined(__x86_64__) || defined(__i386__) || defined(__mips__) \ || defined(__aarch64__) || defined(__powerpc64__) || defined(__s390__) \ @@ -379,6 +391,10 @@ #elif SANITIZER_ANDROID *addr = 0; *size = 0; +#elif SANITIZER_SOLARIS + // FIXME + *addr = 0; + *size = 0; #else # error "Unknown OS" #endif @@ -387,7 +403,8 @@ #if !SANITIZER_GO uptr GetTlsSize() { -#if SANITIZER_FREEBSD || SANITIZER_ANDROID || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_ANDROID || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS uptr addr, size; GetTls(&addr, &size); return size; @@ -547,7 +564,8 @@ return rss * GetPageSizeCached(); } -// sysconf(_SC_NPROCESSORS_{CONF,ONLN}) cannot be used as they allocate memory. +// sysconf(_SC_NPROCESSORS_{CONF,ONLN}) cannot be used on most platforms as +// they allocate memory. u32 GetNumberOfCPUs() { #if SANITIZER_FREEBSD || SANITIZER_NETBSD u32 ncpu; @@ -593,6 +611,8 @@ } internal_close(fd); return n_cpus; +#elif SANITIZER_SOLARIS + return sysconf(_SC_NPROCESSORS_ONLN); #else cpu_set_t CPUs; CHECK_EQ(sched_getaffinity(0, sizeof(cpu_set_t), &CPUs), 0); Index: lib/sanitizer_common/sanitizer_mutex.h =================================================================== --- lib/sanitizer_common/sanitizer_mutex.h +++ lib/sanitizer_common/sanitizer_mutex.h @@ -92,7 +92,12 @@ // checks that the mutex is owned, and assumes callers to be generally // well-behaved. void CheckLocked(); + private: +#ifdef SANITIZER_SOLARIS + // Solaris mutex_t has a member that requires 64-bit alignment. + ALIGNED(8) +#endif uptr opaque_storage_[10]; uptr owner_; // for debugging }; Index: lib/sanitizer_common/sanitizer_platform.h =================================================================== --- lib/sanitizer_common/sanitizer_platform.h +++ lib/sanitizer_common/sanitizer_platform.h @@ -14,7 +14,8 @@ #define SANITIZER_PLATFORM_H #if !defined(__linux__) && !defined(__FreeBSD__) && !defined(__NetBSD__) && \ - !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) + !defined(__APPLE__) && !defined(_WIN32) && !defined(__Fuchsia__) && \ + !(defined(__sun__) && defined(__svr4__)) # error "This operating system is not supported" #endif @@ -36,6 +37,12 @@ # define SANITIZER_NETBSD 0 #endif +#if defined(__sun__) && defined(__svr4__) +# define SANITIZER_SOLARIS 1 +#else +# define SANITIZER_SOLARIS 0 +#endif + #if defined(__APPLE__) # define SANITIZER_MAC 1 # include @@ -92,7 +99,8 @@ #endif #define SANITIZER_POSIX \ - (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || SANITIZER_NETBSD) + (SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || \ + SANITIZER_NETBSD || SANITIZER_SOLARIS) #if __LP64__ || defined(_WIN64) # define SANITIZER_WORDSIZE 64 @@ -181,6 +189,12 @@ # define SANITIZER_ARM 0 #endif +#if SANITIZER_SOLARIS && SANITIZER_WORDSIZE == 32 +# define SANITIZER_SOLARIS32 1 +#else +# define SANITIZER_SOLARIS32 0 +#endif + // By default we allow to use SizeClassAllocator64 on 64-bit platform. // But in some cases (e.g. AArch64's 39-bit address space) SizeClassAllocator64 // does not work well and we need to fallback to SizeClassAllocator32. Index: lib/sanitizer_common/sanitizer_platform_interceptors.h =================================================================== --- lib/sanitizer_common/sanitizer_platform_interceptors.h +++ lib/sanitizer_common/sanitizer_platform_interceptors.h @@ -87,6 +87,18 @@ # define SI_NOT_FUCHSIA 1 #endif +#if SANITIZER_SOLARIS +# define SI_SOLARIS 1 +#else +# define SI_SOLARIS 0 +#endif + +#if SANITIZER_SOLARIS32 +# define SI_SOLARIS32 1 +#else +# define SI_SOLARIS32 0 +#endif + #if SANITIZER_POSIX && !SANITIZER_MAC # define SI_POSIX_NOT_MAC 1 #else @@ -110,7 +122,7 @@ #define SANITIZER_INTERCEPT_STRRCHR SI_NOT_FUCHSIA #define SANITIZER_INTERCEPT_STRSPN SI_NOT_FUCHSIA #define SANITIZER_INTERCEPT_STRPBRK SI_NOT_FUCHSIA -#define SANITIZER_INTERCEPT_TEXTDOMAIN SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_TEXTDOMAIN SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_STRCASECMP SI_POSIX #define SANITIZER_INTERCEPT_MEMSET 1 #define SANITIZER_INTERCEPT_MEMMOVE 1 @@ -138,8 +150,8 @@ #define SANITIZER_INTERCEPT_FREAD SI_POSIX #define SANITIZER_INTERCEPT_FWRITE SI_POSIX -#define SANITIZER_INTERCEPT_PREAD64 SI_LINUX_NOT_ANDROID -#define SANITIZER_INTERCEPT_PWRITE64 SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_PREAD64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32 +#define SANITIZER_INTERCEPT_PWRITE64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32 #define SANITIZER_INTERCEPT_READV SI_POSIX #define SANITIZER_INTERCEPT_WRITEV SI_POSIX @@ -169,17 +181,20 @@ #define SANITIZER_INTERCEPT_GETPWNAM_AND_FRIENDS SI_POSIX #define SANITIZER_INTERCEPT_GETPWNAM_R_AND_FRIENDS \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_GETPWENT \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_FGETPWENT SI_LINUX_NOT_ANDROID + (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) +#define SANITIZER_INTERCEPT_FGETPWENT SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_GETPWENT_R \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_SETPWENT (SI_MAC || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_CLOCK_GETTIME (SI_FREEBSD || SI_NETBSD || SI_LINUX) + (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) +#define SANITIZER_INTERCEPT_SETPWENT \ + (SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) +#define SANITIZER_INTERCEPT_CLOCK_GETTIME \ + (SI_FREEBSD || SI_NETBSD || SI_LINUX || SI_SOLARIS) #define SANITIZER_INTERCEPT_GETITIMER SI_POSIX #define SANITIZER_INTERCEPT_TIME SI_POSIX -#define SANITIZER_INTERCEPT_GLOB SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_GLOB SI_LINUX_NOT_ANDROID || SI_SOLARIS +#define SANITIZER_INTERCEPT_GLOB64 SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_WAIT SI_POSIX #define SANITIZER_INTERCEPT_INET SI_POSIX #define SANITIZER_INTERCEPT_PTHREAD_GETSCHEDPARAM SI_POSIX @@ -187,11 +202,15 @@ #define SANITIZER_INTERCEPT_GETNAMEINFO SI_POSIX #define SANITIZER_INTERCEPT_GETSOCKNAME SI_POSIX #define SANITIZER_INTERCEPT_GETHOSTBYNAME SI_POSIX -#define SANITIZER_INTERCEPT_GETHOSTBYNAME_R (SI_FREEBSD || SI_LINUX) +#define SANITIZER_INTERCEPT_GETHOSTBYNAME2 SI_NOT_WINDOWS && !SI_SOLARIS +#define SANITIZER_INTERCEPT_GETHOSTBYNAME_R \ + (SI_FREEBSD || SI_LINUX || SI_SOLARIS) #define SANITIZER_INTERCEPT_GETHOSTBYNAME2_R \ (SI_FREEBSD || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_GETHOSTBYADDR_R (SI_FREEBSD || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_GETHOSTENT_R (SI_FREEBSD || SI_LINUX_NOT_ANDROID) +#define SANITIZER_INTERCEPT_GETHOSTBYADDR_R \ + (SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) +#define SANITIZER_INTERCEPT_GETHOSTENT_R \ + (SI_FREEBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_GETSOCKOPT SI_POSIX #define SANITIZER_INTERCEPT_ACCEPT SI_POSIX #define SANITIZER_INTERCEPT_ACCEPT4 SI_LINUX_NOT_ANDROID @@ -203,7 +222,7 @@ #define SANITIZER_INTERCEPT_INET_ATON SI_POSIX #define SANITIZER_INTERCEPT_SYSINFO SI_LINUX #define SANITIZER_INTERCEPT_READDIR SI_POSIX -#define SANITIZER_INTERCEPT_READDIR64 SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_READDIR64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32 #if SI_LINUX_NOT_ANDROID && \ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ defined(__powerpc64__) || defined(__aarch64__) || defined(__arm__) || \ @@ -217,43 +236,46 @@ #define SANITIZER_INTERCEPT_GET_CURRENT_DIR_NAME SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_STRTOIMAX SI_POSIX #define SANITIZER_INTERCEPT_MBSTOWCS SI_POSIX -#define SANITIZER_INTERCEPT_MBSNRTOWCS (SI_MAC || SI_LINUX_NOT_ANDROID) +#define SANITIZER_INTERCEPT_MBSNRTOWCS \ + (SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_WCSTOMBS SI_POSIX #define SANITIZER_INTERCEPT_WCSNRTOMBS \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_WCRTOMB \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX_NOT_ANDROID + (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) +#define SANITIZER_INTERCEPT_TCGETATTR SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_REALPATH SI_POSIX -#define SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_CANONICALIZE_FILE_NAME \ + (SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_CONFSTR \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_SCHED_GETAFFINITY SI_LINUX_NOT_ANDROID -#define SANITIZER_INTERCEPT_SCHED_GETPARAM SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_SCHED_GETPARAM SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_STRERROR SI_POSIX #define SANITIZER_INTERCEPT_STRERROR_R SI_POSIX #define SANITIZER_INTERCEPT_XPG_STRERROR_R SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_SCANDIR \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_SCANDIR64 SI_LINUX_NOT_ANDROID + (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) +#define SANITIZER_INTERCEPT_SCANDIR64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32 #define SANITIZER_INTERCEPT_GETGROUPS SI_POSIX #define SANITIZER_INTERCEPT_POLL SI_POSIX -#define SANITIZER_INTERCEPT_PPOLL SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_PPOLL SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_WORDEXP \ - (SI_FREEBSD || SI_NETBSD || (SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || (SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID || \ + SI_SOLARIS) #define SANITIZER_INTERCEPT_SIGWAIT SI_POSIX -#define SANITIZER_INTERCEPT_SIGWAITINFO SI_LINUX_NOT_ANDROID -#define SANITIZER_INTERCEPT_SIGTIMEDWAIT SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_SIGWAITINFO SI_LINUX_NOT_ANDROID || SI_SOLARIS +#define SANITIZER_INTERCEPT_SIGTIMEDWAIT SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_SIGSETOPS \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_SIGPENDING SI_POSIX #define SANITIZER_INTERCEPT_SIGPROCMASK SI_POSIX #define SANITIZER_INTERCEPT_BACKTRACE \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_GETMNTENT SI_LINUX #define SANITIZER_INTERCEPT_GETMNTENT_R SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_STATFS \ - (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_STATFS64 \ ((SI_MAC && !SI_IOS) || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_STATVFS \ @@ -265,63 +287,66 @@ (SI_FREEBSD || SI_MAC || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_ETHER_R (SI_FREEBSD || SI_LINUX_NOT_ANDROID) #define SANITIZER_INTERCEPT_SHMCTL \ - (SI_NETBSD || ((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && \ - SANITIZER_WORDSIZE == 64)) // NOLINT + (SI_NETBSD || SI_SOLARIS || ((SI_FREEBSD || SI_LINUX_NOT_ANDROID) && \ + SANITIZER_WORDSIZE == 64)) // NOLINT #define SANITIZER_INTERCEPT_RANDOM_R SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GET SI_POSIX #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETINHERITSCHED \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_ATTR_GETAFFINITY_NP SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPSHARED SI_POSIX #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETTYPE SI_POSIX #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPROTOCOL \ - (SI_MAC || SI_NETBSD || SI_LINUX_NOT_ANDROID) + (SI_MAC || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETPRIOCEILING \ - (SI_MAC || SI_NETBSD || SI_LINUX_NOT_ANDROID) -#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST SI_LINUX_NOT_ANDROID + (SI_MAC || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) +#define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST \ + (SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_MUTEXATTR_GETROBUST_NP SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETPSHARED SI_POSIX #define SANITIZER_INTERCEPT_PTHREAD_RWLOCKATTR_GETKIND_NP SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETPSHARED SI_POSIX -#define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK SI_LINUX_NOT_ANDROID -#define SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_PTHREAD_CONDATTR_GETCLOCK \ + (SI_LINUX_NOT_ANDROID || SI_SOLARIS) +#define SANITIZER_INTERCEPT_PTHREAD_BARRIERATTR_GETPSHARED \ + (SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_TMPNAM SI_POSIX -#define SANITIZER_INTERCEPT_TMPNAM_R SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_TMPNAM_R SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_TTYNAME_R SI_POSIX #define SANITIZER_INTERCEPT_TEMPNAM SI_POSIX -#define SANITIZER_INTERCEPT_SINCOS SI_LINUX +#define SANITIZER_INTERCEPT_SINCOS SI_LINUX || SI_SOLARIS #define SANITIZER_INTERCEPT_REMQUO SI_POSIX #define SANITIZER_INTERCEPT_LGAMMA SI_POSIX -#define SANITIZER_INTERCEPT_LGAMMA_R (SI_FREEBSD || SI_LINUX) -#define SANITIZER_INTERCEPT_LGAMMAL_R SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_LGAMMA_R (SI_FREEBSD || SI_LINUX || SI_SOLARIS) +#define SANITIZER_INTERCEPT_LGAMMAL_R SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_DRAND48_R SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_RAND_R \ - (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_MAC || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_ICONV \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_TIMES SI_POSIX // FIXME: getline seems to be available on OSX 10.7 #define SANITIZER_INTERCEPT_GETLINE \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT__EXIT \ - (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_MAC) + (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_MAC || SI_SOLARIS) #define SANITIZER_INTERCEPT_PHTREAD_MUTEX SI_POSIX #define SANITIZER_INTERCEPT_PTHREAD_SETNAME_NP \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_TLS_GET_ADDR \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID) + (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_SOLARIS) #define SANITIZER_INTERCEPT_LISTXATTR SI_LINUX #define SANITIZER_INTERCEPT_GETXATTR SI_LINUX #define SANITIZER_INTERCEPT_GETRESID SI_LINUX #define SANITIZER_INTERCEPT_GETIFADDRS \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC) + (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS) #define SANITIZER_INTERCEPT_IF_INDEXTONAME \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC) + (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS) #define SANITIZER_INTERCEPT_CAPGET SI_LINUX_NOT_ANDROID #if SI_LINUX && defined(__arm__) #define SANITIZER_INTERCEPT_AEABI_MEM 1 @@ -330,20 +355,21 @@ #endif #define SANITIZER_INTERCEPT___BZERO SI_MAC #define SANITIZER_INTERCEPT_FTIME (!SI_FREEBSD && !SI_NETBSD && SI_POSIX) -#define SANITIZER_INTERCEPT_XDR SI_LINUX_NOT_ANDROID +#define SANITIZER_INTERCEPT_XDR SI_LINUX_NOT_ANDROID || SI_SOLARIS #define SANITIZER_INTERCEPT_TSEARCH \ - (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD) + (SI_LINUX_NOT_ANDROID || SI_MAC || SI_NETBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_LIBIO_INTERNALS SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_FOPEN SI_POSIX -#define SANITIZER_INTERCEPT_FOPEN64 SI_LINUX_NOT_ANDROID -#define SANITIZER_INTERCEPT_OPEN_MEMSTREAM (SI_LINUX_NOT_ANDROID || SI_NETBSD) +#define SANITIZER_INTERCEPT_FOPEN64 SI_LINUX_NOT_ANDROID || SI_SOLARIS32 +#define SANITIZER_INTERCEPT_OPEN_MEMSTREAM \ + (SI_LINUX_NOT_ANDROID || SI_NETBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_OBSTACK SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT_FFLUSH SI_POSIX #define SANITIZER_INTERCEPT_FCLOSE SI_POSIX #ifndef SANITIZER_INTERCEPT_DLOPEN_DLCLOSE #define SANITIZER_INTERCEPT_DLOPEN_DLCLOSE \ - (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC) + (SI_FREEBSD || SI_NETBSD || SI_LINUX_NOT_ANDROID || SI_MAC || SI_SOLARIS) #endif #define SANITIZER_INTERCEPT_GETPASS \ @@ -352,13 +378,14 @@ #define SANITIZER_INTERCEPT_MLOCKX SI_POSIX #define SANITIZER_INTERCEPT_FOPENCOOKIE SI_LINUX_NOT_ANDROID -#define SANITIZER_INTERCEPT_SEM (SI_LINUX || SI_FREEBSD || SI_NETBSD) +#define SANITIZER_INTERCEPT_SEM \ + (SI_LINUX || SI_FREEBSD || SI_NETBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_PTHREAD_SETCANCEL SI_POSIX -#define SANITIZER_INTERCEPT_MINCORE (SI_LINUX || SI_NETBSD) +#define SANITIZER_INTERCEPT_MINCORE (SI_LINUX || SI_NETBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT_PROCESS_VM_READV SI_LINUX #define SANITIZER_INTERCEPT_CTERMID \ - (SI_LINUX || SI_MAC || SI_FREEBSD || SI_NETBSD) -#define SANITIZER_INTERCEPT_CTERMID_R (SI_MAC || SI_FREEBSD) + (SI_LINUX || SI_MAC || SI_FREEBSD || SI_NETBSD || SI_SOLARIS) +#define SANITIZER_INTERCEPT_CTERMID_R (SI_MAC || SI_FREEBSD || SI_SOLARIS) #define SANITIZER_INTERCEPTOR_HOOKS (SI_LINUX || SI_MAC || SI_WINDOWS) #define SANITIZER_INTERCEPT_RECV_RECVFROM SI_POSIX @@ -366,7 +393,7 @@ #define SANITIZER_INTERCEPT_EVENTFD_READ_WRITE SI_LINUX #define SANITIZER_INTERCEPT_STAT \ - (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD) + (SI_FREEBSD || SI_MAC || SI_ANDROID || SI_NETBSD || SI_SOLARIS) #define SANITIZER_INTERCEPT___XSTAT (!SANITIZER_INTERCEPT_STAT && SI_POSIX) #define SANITIZER_INTERCEPT___XSTAT64 SI_LINUX_NOT_ANDROID #define SANITIZER_INTERCEPT___LXSTAT SANITIZER_INTERCEPT___XSTAT Index: lib/sanitizer_common/sanitizer_platform_limits_posix.h =================================================================== --- lib/sanitizer_common/sanitizer_platform_limits_posix.h +++ lib/sanitizer_common/sanitizer_platform_limits_posix.h @@ -15,7 +15,7 @@ #ifndef SANITIZER_PLATFORM_LIMITS_POSIX_H #define SANITIZER_PLATFORM_LIMITS_POSIX_H -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_MAC || SANITIZER_SOLARIS #include "sanitizer_internal_defs.h" #include "sanitizer_platform.h" @@ -123,6 +123,10 @@ const unsigned struct_kexec_segment_sz = 4 * sizeof(unsigned long); #endif // SANITIZER_LINUX +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS + extern unsigned struct_timespec_sz; +#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS + #if SANITIZER_LINUX || SANITIZER_FREEBSD #if defined(__powerpc64__) || defined(__s390__) @@ -133,7 +137,6 @@ extern unsigned struct_rlimit_sz; extern unsigned struct_utimbuf_sz; - extern unsigned struct_timespec_sz; struct __sanitizer_iocb { u64 aio_data; @@ -172,6 +175,9 @@ }; const unsigned old_sigset_t_sz = sizeof(unsigned long); +#endif // SANITIZER_LINUX || SANITIZER_FREEBSD + +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS struct __sanitizer_sem_t { #if SANITIZER_ANDROID && defined(_LP64) @@ -184,7 +190,7 @@ u32 data[4]; #endif }; -#endif // SANITIZER_LINUX || SANITIZER_FREEBSD +#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS #if SANITIZER_ANDROID struct __sanitizer_mallinfo { @@ -199,7 +205,6 @@ extern unsigned struct_ustat_sz; extern unsigned struct_rlimit64_sz; - extern unsigned struct_statvfs64_sz; struct __sanitizer_ipc_perm { int __key; @@ -327,14 +332,65 @@ unsigned long shm_dtime; unsigned long shm_ctime; }; +#elif SANITIZER_SOLARIS + struct __sanitizer_ipc_perm { + unsigned int uid; // uid_t + unsigned int gid; // gid_t + unsigned int cuid; // uid_t + unsigned int cgid; // gid_t + unsigned int mode; // mode_t + unsigned int seq; // uint_t + int key; // key_t +#if !defined(_LP64) + int pad[4]; +#endif + }; + + struct __sanitizer_shmid_ds { + __sanitizer_ipc_perm shm_perm; + unsigned long shm_segsz; // size_t + unsigned long shm_flags; // uintptr_t + unsigned short shm_lkcnt; // ushort_t + int shm_lpid; // pid_t + int shm_cpid; // pid_t + unsigned long shm_nattch; // shmatt_t + unsigned long shm_cnattch; // ulong_t +#if defined(_LP64) + long shm_atime; // time_t + long shm_dtime; + long shm_ctime; + void *shm_amp; + u64 shm_gransize; // uint64_t + u64 shm_allocated; // uint64_t + u64 shm_pad4[1]; // int64_t +#else + long shm_atime; // time_t + int shm_pad1; // int32_t + long shm_dtime; // time_t + int shm_pad2; // int32_t + long shm_ctime; // time_t + void *shm_amp; + u64 shm_gransize; // uint64_t + u64 shm_allocated; // uint64_t +#endif + }; #endif #if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID extern unsigned struct_msqid_ds_sz; extern unsigned struct_mq_attr_sz; extern unsigned struct_timex_sz; +#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID + +#if (SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS) && \ + !SANITIZER_ANDROID extern unsigned struct_statvfs_sz; -#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID +#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS) && + // !SANITIZER_ANDROID + +#if (SANITIZER_LINUX || SANITIZER_SOLARIS32) && !SANITIZER_ANDROID + extern unsigned struct_statvfs64_sz; +#endif // (SANITIZER_LINUX || SANITIZER_SOLARIS32) && !SANITIZER_ANDROID struct __sanitizer_iovec { void *iov_base; @@ -345,7 +401,12 @@ struct __sanitizer_ifaddrs { struct __sanitizer_ifaddrs *ifa_next; char *ifa_name; +#if SANITIZER_SOLARIS + // uint64_t + u64 ifa_flags; +#else unsigned int ifa_flags; +#endif void *ifa_addr; // (struct sockaddr *) void *ifa_netmask; // (struct sockaddr *) // This is a union on Linux. @@ -363,7 +424,7 @@ typedef unsigned __sanitizer_pthread_key_t; #endif -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_SOLARIS struct __sanitizer_XDR { int x_op; @@ -382,8 +443,15 @@ struct __sanitizer_passwd { char *pw_name; char *pw_passwd; +#if !SANITIZER_SOLARIS int pw_uid; int pw_gid; +#else + unsigned int pw_uid; // uid_t + unsigned int pw_gid; // gid_t + char *pw_age; + char *pw_comment; +#endif #if SANITIZER_MAC || SANITIZER_FREEBSD long pw_change; char *pw_class; @@ -435,8 +503,10 @@ int tm_wday; int tm_yday; int tm_isdst; +#if !SANITIZER_SOLARIS long int tm_gmtoff; const char *tm_zone; +#endif }; #if SANITIZER_LINUX @@ -450,7 +520,7 @@ }; #endif -#if SANITIZER_MAC || SANITIZER_FREEBSD +#if SANITIZER_MAC || SANITIZER_FREEBSD || SANITIZER_SOLARIS struct __sanitizer_msghdr { void *msg_name; unsigned msg_namelen; @@ -500,6 +570,21 @@ unsigned short d_reclen; // more fields that we don't care about }; +#elif SANITIZER_SOLARIS32 && 0 + // FIXME: need to deal with large file and non-large file cases + struct __sanitizer_dirent { + unsigned long long d_ino; + long long d_off; + unsigned short d_reclen; + // more fields that we don't care about + }; +#elif SANITIZER_SOLARIS + struct __sanitizer_dirent { + unsigned long d_ino; + long d_off; + unsigned short d_reclen; + // more fields that we don't care about + }; #elif SANITIZER_ANDROID || defined(__x86_64__) struct __sanitizer_dirent { unsigned long long d_ino; @@ -516,7 +601,7 @@ }; #endif -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_SOLARIS struct __sanitizer_dirent64 { unsigned long long d_ino; unsigned long long d_off; @@ -588,10 +673,10 @@ // The size is determined by looking at sizeof of real sigset_t on linux. uptr val[128 / sizeof(uptr)]; }; -#elif SANITIZER_FREEBSD +#elif SANITIZER_FREEBSD || SANITIZER_SOLARIS struct __sanitizer_sigset_t { - // uint32_t * 4 - unsigned int __bits[4]; + // uint32_t * 4 + unsigned int __bits[4]; }; #endif @@ -638,6 +723,8 @@ struct __sanitizer_sigaction { #if defined(__mips__) && !SANITIZER_FREEBSD unsigned int sa_flags; +#elif SANITIZER_SOLARIS + int sa_flags; #endif union { __sanitizer_sigactionhandler_ptr sigaction; @@ -646,6 +733,8 @@ #if SANITIZER_FREEBSD int sa_flags; __sanitizer_sigset_t sa_mask; +#elif SANITIZER_SOLARIS + __sanitizer_sigset_t sa_mask; #else #if defined(__s390x__) int sa_resv; @@ -679,6 +768,9 @@ #if defined(__s390x__) __sanitizer_sigset_t sa_mask; #endif +#if SANITIZER_SOLARIS && !defined(_LP64) + int sa_resv[2]; +#endif }; #endif // !SANITIZER_ANDROID @@ -730,7 +822,7 @@ extern int af_inet6; uptr __sanitizer_in_addr_sz(int af); -#if SANITIZER_LINUX || SANITIZER_FREEBSD +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS struct __sanitizer_dl_phdr_info { uptr dlpi_addr; const char *dlpi_name; @@ -746,7 +838,10 @@ int ai_family; int ai_socktype; int ai_protocol; -#if SANITIZER_ANDROID || SANITIZER_MAC || SANITIZER_FREEBSD +#if SANITIZER_ANDROID || SANITIZER_MAC || SANITIZER_FREEBSD || SANITIZER_SOLARIS +#if SANITIZER_SOLARIS && defined(__sparcv9) + int _ai_pad; +#endif unsigned ai_addrlen; char *ai_canonname; void *ai_addr; @@ -806,9 +901,17 @@ int (*gl_lstat)(const char*, void* /* struct stat* */); int (*gl_stat)(const char*, void* /* struct stat* */); }; -# endif // SANITIZER_FREEBSD +# elif SANITIZER_SOLARIS + struct __sanitizer_glob_t { + uptr gl_pathc; + char **gl_pathv; + uptr gl_offs; + char **gl_pathp; + int gl_pathn; + }; +# endif // SANITIZER_SOLARIS -# if SANITIZER_LINUX || SANITIZER_FREEBSD +# if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS extern int glob_nomatch; extern int glob_altdirfunc; # endif @@ -824,6 +927,10 @@ char *we_strings; uptr we_nbytes; #endif +#if SANITIZER_SOLARIS + char **we_wordp; + int we_wordn; +#endif }; #if SANITIZER_LINUX && !SANITIZER_ANDROID @@ -877,9 +984,12 @@ extern int ptrace_geteventmsg; #endif -#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID +#if (SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS) && \ + !SANITIZER_ANDROID +#if !SANITIZER_SOLARIS extern unsigned struct_shminfo_sz; extern unsigned struct_shm_info_sz; +#endif extern int shmctl_ipc_stat; extern int shmctl_ipc_info; extern int shmctl_shm_info; @@ -936,6 +1046,7 @@ }; #endif +#if !SANITIZER_SOLARIS #define IOC_NRBITS 8 #define IOC_TYPEBITS 8 #if defined(__powerpc__) || defined(__powerpc64__) || defined(__mips__) || \ @@ -952,6 +1063,22 @@ #define IOC_WRITE 1U #define IOC_READ 2U #endif +#define EVIOC_EV_MAX 0x1f +#define EVIOC_ABS_MAX 0x3f +#endif // !SANITIZER_SOLARIS + +#if SANITIZER_SOLARIS +// +#define IOC_NRBITS 8 +#define IOC_TYPEBITS 8 +#define IOC_SIZEBITS 12 +#define IOC_DIRBITS 4 +#undef IOC_NONE +#define IOC_NONE 2U // IOC_VOID +#define IOC_READ 4U // IOC_OUT +#define IOC_WRITE 8U // IOC_IN +#endif // SANITIZER_SOLARIS + #define IOC_NRMASK ((1 << IOC_NRBITS) - 1) #define IOC_TYPEMASK ((1 << IOC_TYPEBITS) - 1) #define IOC_SIZEMASK ((1 << IOC_SIZEBITS) - 1) @@ -963,8 +1090,6 @@ #define IOC_TYPESHIFT (IOC_NRSHIFT + IOC_NRBITS) #define IOC_SIZESHIFT (IOC_TYPESHIFT + IOC_TYPEBITS) #define IOC_DIRSHIFT (IOC_SIZESHIFT + IOC_SIZEBITS) -#define EVIOC_EV_MAX 0x1f -#define EVIOC_ABS_MAX 0x3f #define IOC_DIR(nr) (((nr) >> IOC_DIRSHIFT) & IOC_DIRMASK) #define IOC_TYPE(nr) (((nr) >> IOC_TYPESHIFT) & IOC_TYPEMASK) @@ -1090,7 +1215,9 @@ extern unsigned IOCTL_SIOCSIFMTU; extern unsigned IOCTL_SIOCSIFNETMASK; extern unsigned IOCTL_SIOCSPGRP; +#if !SANITIZER_SOLARIS extern unsigned IOCTL_TIOCCONS; +#endif extern unsigned IOCTL_TIOCEXCL; extern unsigned IOCTL_TIOCGETD; extern unsigned IOCTL_TIOCGPGRP; @@ -1271,9 +1398,11 @@ extern unsigned IOCTL_VT_RESIZEX; extern unsigned IOCTL_VT_SENDSIG; #endif // SANITIZER_LINUX -#if SANITIZER_LINUX || SANITIZER_FREEBSD +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS extern unsigned IOCTL_MTIOCGET; extern unsigned IOCTL_MTIOCTOP; +#endif +#if SANITIZER_LINUX || SANITIZER_FREEBSD extern unsigned IOCTL_SIOCADDRT; extern unsigned IOCTL_SIOCDELRT; extern unsigned IOCTL_SNDCTL_DSP_GETBLKSIZE; Index: lib/sanitizer_common/sanitizer_platform_limits_posix.cc =================================================================== --- lib/sanitizer_common/sanitizer_platform_limits_posix.cc +++ lib/sanitizer_common/sanitizer_platform_limits_posix.cc @@ -14,7 +14,7 @@ #include "sanitizer_platform.h" -#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_MAC +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_SOLARIS // Tests in this file assume that off_t-dependent data structures match the // libc ABI. For example, struct dirent here is what readdir() function (as // exported from libc) returns, and not the user-facing "dirent", which @@ -192,6 +192,22 @@ #include #endif +#if SANITIZER_SOLARIS +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#endif + // Include these after system headers to avoid name clashes and ambiguities. #include "sanitizer_internal_defs.h" #include "sanitizer_platform_limits_posix.h" @@ -230,6 +246,9 @@ #if !SANITIZER_ANDROID unsigned struct_statfs_sz = sizeof(struct statfs); +#endif + +#if !SANITIZER_ANDROID unsigned struct_sockaddr_sz = sizeof(struct sockaddr); unsigned ucontext_t_sz = sizeof(ucontext_t); #endif // !SANITIZER_ANDROID @@ -245,9 +264,12 @@ unsigned struct_oldold_utsname_sz = sizeof(struct oldold_utsname); #endif // SANITIZER_LINUX +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS + unsigned struct_timespec_sz = sizeof(struct timespec); +#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS + #if SANITIZER_LINUX || SANITIZER_FREEBSD unsigned struct_rlimit_sz = sizeof(struct rlimit); - unsigned struct_timespec_sz = sizeof(struct timespec); unsigned struct_utimbuf_sz = sizeof(struct utimbuf); unsigned struct_itimerspec_sz = sizeof(struct itimerspec); #endif // SANITIZER_LINUX || SANITIZER_FREEBSD @@ -255,15 +277,23 @@ #if SANITIZER_LINUX && !SANITIZER_ANDROID unsigned struct_ustat_sz = sizeof(struct ustat); unsigned struct_rlimit64_sz = sizeof(struct rlimit64); +#endif // SANITIZER_LINUX && !SANITIZER_ANDROID + +#if (SANITIZER_LINUX || SANITIZER_SOLARIS32) && !SANITIZER_ANDROID unsigned struct_statvfs64_sz = sizeof(struct statvfs64); -#endif // SANITIZER_LINUX && !SANITIZER_ANDROID +#endif // (SANITIZER_LINUX || SANITIZER_SOLARIS32) && !SANITIZER_ANDROID #if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID unsigned struct_timex_sz = sizeof(struct timex); unsigned struct_msqid_ds_sz = sizeof(struct msqid_ds); unsigned struct_mq_attr_sz = sizeof(struct mq_attr); +#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID + +#if (SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS) && \ + !SANITIZER_ANDROID unsigned struct_statvfs_sz = sizeof(struct statvfs); -#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID +#endif // (SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS) && + // !SANITIZER_ANDROID const uptr sig_ign = (uptr)SIG_IGN; const uptr sig_dfl = (uptr)SIG_DFL; @@ -278,12 +308,16 @@ #if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID unsigned struct_shminfo_sz = sizeof(struct shminfo); unsigned struct_shm_info_sz = sizeof(struct shm_info); - int shmctl_ipc_stat = (int)IPC_STAT; int shmctl_ipc_info = (int)IPC_INFO; int shmctl_shm_info = (int)SHM_INFO; int shmctl_shm_stat = (int)SHM_STAT; #endif +#if (SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS) && \ + !SANITIZER_ANDROID + int shmctl_ipc_stat = (int)IPC_STAT; +#endif + #if !SANITIZER_MAC && !SANITIZER_FREEBSD unsigned struct_utmp_sz = sizeof(struct utmp); #endif @@ -305,16 +339,19 @@ return 0; } -#if SANITIZER_LINUX +#if SANITIZER_LINUX || SANITIZER_SOLARIS unsigned struct_ElfW_Phdr_sz = sizeof(ElfW(Phdr)); #elif SANITIZER_FREEBSD unsigned struct_ElfW_Phdr_sz = sizeof(Elf_Phdr); #endif -#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID +#if (SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS) && \ + !SANITIZER_ANDROID int glob_nomatch = GLOB_NOMATCH; +#if !SANITIZER_SOLARIS int glob_altdirfunc = GLOB_ALTDIRFUNC; #endif +#endif #if SANITIZER_LINUX && !SANITIZER_ANDROID && \ (defined(__i386) || defined(__x86_64) || defined(__mips64) || \ @@ -518,7 +555,9 @@ unsigned IOCTL_SIOCSIFMTU = SIOCSIFMTU; unsigned IOCTL_SIOCSIFNETMASK = SIOCSIFNETMASK; unsigned IOCTL_SIOCSPGRP = SIOCSPGRP; +#if !SANITIZER_SOLARIS unsigned IOCTL_TIOCCONS = TIOCCONS; +#endif unsigned IOCTL_TIOCEXCL = TIOCEXCL; unsigned IOCTL_TIOCGETD = TIOCGETD; unsigned IOCTL_TIOCGPGRP = TIOCGPGRP; @@ -728,9 +767,12 @@ unsigned IOCTL_VT_SENDSIG = VT_SENDSIG; #endif // SANITIZER_LINUX -#if SANITIZER_LINUX || SANITIZER_FREEBSD +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS unsigned IOCTL_MTIOCGET = MTIOCGET; unsigned IOCTL_MTIOCTOP = MTIOCTOP; +#endif + +#if SANITIZER_LINUX || SANITIZER_FREEBSD unsigned IOCTL_SNDCTL_DSP_GETBLKSIZE = SNDCTL_DSP_GETBLKSIZE; unsigned IOCTL_SNDCTL_DSP_GETFMTS = SNDCTL_DSP_GETFMTS; unsigned IOCTL_SNDCTL_DSP_NONBLOCK = SNDCTL_DSP_NONBLOCK; @@ -968,7 +1010,7 @@ COMPILER_CHECK(IOC_TYPE(0x12345678) == _IOC_TYPE(0x12345678)); #endif // SANITIZER_LINUX -#if SANITIZER_LINUX || SANITIZER_FREEBSD +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS // There are more undocumented fields in dl_phdr_info that we are not interested // in. COMPILER_CHECK(sizeof(__sanitizer_dl_phdr_info) <= sizeof(dl_phdr_info)); @@ -976,13 +1018,15 @@ CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_name); CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phdr); CHECK_SIZE_AND_OFFSET(dl_phdr_info, dlpi_phnum); -#endif // SANITIZER_LINUX || SANITIZER_FREEBSD +#endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS -#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID +#if (SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS) && \ + !SANITIZER_ANDROID CHECK_TYPE_SIZE(glob_t); CHECK_SIZE_AND_OFFSET(glob_t, gl_pathc); CHECK_SIZE_AND_OFFSET(glob_t, gl_pathv); CHECK_SIZE_AND_OFFSET(glob_t, gl_offs); +#if !SANITIZER_SOLARIS CHECK_SIZE_AND_OFFSET(glob_t, gl_flags); CHECK_SIZE_AND_OFFSET(glob_t, gl_closedir); CHECK_SIZE_AND_OFFSET(glob_t, gl_readdir); @@ -990,6 +1034,7 @@ CHECK_SIZE_AND_OFFSET(glob_t, gl_lstat); CHECK_SIZE_AND_OFFSET(glob_t, gl_stat); #endif +#endif CHECK_TYPE_SIZE(addrinfo); CHECK_SIZE_AND_OFFSET(addrinfo, ai_flags); @@ -1037,7 +1082,7 @@ #endif CHECK_SIZE_AND_OFFSET(dirent, d_reclen); -#if SANITIZER_LINUX && !SANITIZER_ANDROID +#if (SANITIZER_LINUX && !SANITIZER_ANDROID) || SANITIZER_SOLARIS32 COMPILER_CHECK(sizeof(__sanitizer_dirent64) <= sizeof(dirent64)); CHECK_SIZE_AND_OFFSET(dirent64, d_ino); CHECK_SIZE_AND_OFFSET(dirent64, d_off); @@ -1112,8 +1157,10 @@ CHECK_SIZE_AND_OFFSET(tm, tm_wday); CHECK_SIZE_AND_OFFSET(tm, tm_yday); CHECK_SIZE_AND_OFFSET(tm, tm_isdst); +#if !SANITIZER_SOLARIS CHECK_SIZE_AND_OFFSET(tm, tm_gmtoff); CHECK_SIZE_AND_OFFSET(tm, tm_zone); +#endif #if SANITIZER_LINUX CHECK_TYPE_SIZE(mntent); @@ -1127,9 +1174,10 @@ CHECK_TYPE_SIZE(ether_addr); -#if (SANITIZER_LINUX || SANITIZER_FREEBSD) && !SANITIZER_ANDROID +#if (SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS) && \ + !SANITIZER_ANDROID CHECK_TYPE_SIZE(ipc_perm); -# if SANITIZER_FREEBSD +# if SANITIZER_FREEBSD || SANITIZER_SOLARIS CHECK_SIZE_AND_OFFSET(ipc_perm, key); CHECK_SIZE_AND_OFFSET(ipc_perm, seq); # else @@ -1168,7 +1216,7 @@ CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_name); CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_addr); CHECK_SIZE_AND_OFFSET(ifaddrs, ifa_netmask); -#if SANITIZER_LINUX || SANITIZER_FREEBSD +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_SOLARIS // Compare against the union, because we can't reach into the union in a // compliant way. #ifdef ifa_dstaddr Index: lib/sanitizer_common/sanitizer_posix_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_posix_libcdep.cc +++ lib/sanitizer_common/sanitizer_posix_libcdep.cc @@ -62,7 +62,13 @@ uptr beg_aligned = RoundUpTo(beg, page_size); uptr end_aligned = RoundDownTo(end, page_size); if (beg_aligned < end_aligned) +#if SANITIZER_SOLARIS + // In the default compilation environment, madvise() is declared to take a + // caddr_t arg; casting it to void* results in an invalid conversion error. + madvise((caddr_t)beg_aligned, end_aligned - beg_aligned, MADV_DONTNEED); +#else madvise((void*)beg_aligned, end_aligned - beg_aligned, MADV_DONTNEED); +#endif } void NoHugePagesInRegion(uptr addr, uptr size) { Index: lib/sanitizer_common/sanitizer_procmaps.h =================================================================== --- lib/sanitizer_common/sanitizer_procmaps.h +++ lib/sanitizer_common/sanitizer_procmaps.h @@ -16,7 +16,8 @@ #include "sanitizer_platform.h" -#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || SANITIZER_MAC +#if SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || \ + SANITIZER_MAC || SANITIZER_SOLARIS #include "sanitizer_common.h" #include "sanitizer_internal_defs.h" @@ -95,5 +96,5 @@ } // namespace __sanitizer #endif // SANITIZER_LINUX || SANITIZER_FREEBSD || SANITIZER_NETBSD || - // SANITIZER_MAC + // SANITIZER_MAC || SANITIZER_SOLARIS #endif // SANITIZER_PROCMAPS_H Index: lib/sanitizer_common/sanitizer_procmaps_common.cc =================================================================== --- lib/sanitizer_common/sanitizer_procmaps_common.cc +++ lib/sanitizer_common/sanitizer_procmaps_common.cc @@ -12,7 +12,8 @@ #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS #include "sanitizer_common.h" #include "sanitizer_placement_new.h" @@ -169,4 +170,5 @@ } // namespace __sanitizer -#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || + // SANITIZER_SOLARIS Index: lib/sanitizer_common/sanitizer_procmaps_solaris.cc =================================================================== --- /dev/null +++ lib/sanitizer_common/sanitizer_procmaps_solaris.cc @@ -0,0 +1,57 @@ +//===-- sanitizer_procmaps_solaris.cc -------------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// Information about the process mappings (Solaris-specific parts). +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" +#if SANITIZER_SOLARIS +#include "sanitizer_common.h" +#include "sanitizer_procmaps.h" + +#include +#include + +namespace __sanitizer { + +void ReadProcMaps(ProcSelfMapsBuff *proc_maps) { + ReadFileToBuffer("/proc/self/xmap", &proc_maps->data, &proc_maps->mmaped_size, + &proc_maps->len); +} + +bool MemoryMappingLayout::Next(MemoryMappedSegment *segment) { + char *last = data_.proc_self_maps.data + data_.proc_self_maps.len; + if (data_.current >= last) return false; + + prxmap_t *xmapentry = (prxmap_t*)data_.current; + + segment->start = (uptr)xmapentry->pr_vaddr; + segment->end = (uptr)(xmapentry->pr_vaddr + xmapentry->pr_size); + segment->offset = (uptr)xmapentry->pr_offset; + + segment->protection = 0; + if ((xmapentry->pr_mflags & MA_READ) != 0) + segment->protection |= kProtectionRead; + if ((xmapentry->pr_mflags & MA_WRITE) != 0) + segment->protection |= kProtectionWrite; + if ((xmapentry->pr_mflags & MA_EXEC) != 0) + segment->protection |= kProtectionExecute; + + if (segment->filename != NULL && segment->filename_size > 0) { + internal_snprintf(segment->filename, + Min(segment->filename_size, (uptr)PATH_MAX), "%s", + xmapentry->pr_mapname); + } + + data_.current += sizeof(prxmap_t); + + return true; +} + +} // namespace __sanitizer + +#endif // SANITIZER_SOLARIS Index: lib/sanitizer_common/sanitizer_solaris.cc =================================================================== --- /dev/null +++ lib/sanitizer_common/sanitizer_solaris.cc @@ -0,0 +1,210 @@ +//===-- sanitizer_solaris.cc ----------------------------------------------===// +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// +// +// This file is shared between various sanitizers' runtime libraries and +// implements Solaris-specific functions. +//===----------------------------------------------------------------------===// + +#include "sanitizer_platform.h" +#if SANITIZER_SOLARIS + +#include + +#include "sanitizer_common.h" +#include "sanitizer_flags.h" +#include "sanitizer_internal_defs.h" +#include "sanitizer_libc.h" +#include "sanitizer_placement_new.h" +#include "sanitizer_platform_limits_posix.h" +#include "sanitizer_procmaps.h" + +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include +#include + +namespace __sanitizer { + +//#include "sanitizer_syscall_generic.inc" + +#define _REAL(func) _ ## func +#define DECLARE__REAL(ret_type, func, ...) \ + extern "C" ret_type _REAL(func)(__VA_ARGS__) +#define DECLARE__REAL_AND_INTERNAL(ret_type, func, ...) \ + DECLARE__REAL(ret_type, func, __VA_ARGS__); \ + ret_type internal_ ## func(__VA_ARGS__) + +// ---------------------- sanitizer_libc.h +DECLARE__REAL_AND_INTERNAL(uptr, mmap, void *addr, uptr /*size_t*/ length, + int prot, int flags, int fd, OFF_T offset) { + return (uptr)_REAL(mmap)(addr, length, prot, flags, fd, offset); +} + +DECLARE__REAL_AND_INTERNAL(uptr, munmap, void *addr, uptr length) { + return _REAL(munmap)(addr, length); +} + +DECLARE__REAL_AND_INTERNAL(int, mprotect, void *addr, uptr length, int prot) { + return _REAL(mprotect)(addr, length, prot); +} + +DECLARE__REAL_AND_INTERNAL(uptr, close, fd_t fd) { + return _REAL(close)(fd); +} + +extern "C" int _REAL(open)(const char *, int, ...); + +uptr internal_open(const char *filename, int flags) { + return _REAL(open)(filename, flags); +} + +uptr internal_open(const char *filename, int flags, u32 mode) { + return _REAL(open)(filename, flags, mode); +} + +uptr OpenFile(const char *filename, bool write) { + return internal_open(filename, + write ? O_WRONLY | O_CREAT : O_RDONLY, 0660); +} + +DECLARE__REAL_AND_INTERNAL(uptr, read, fd_t fd, void *buf, uptr count) { + return _REAL(read)(fd, buf, count); +} + +DECLARE__REAL_AND_INTERNAL(uptr, write, fd_t fd, const void *buf, uptr count) { + return _REAL(write)(fd, buf, count); +} + +// FIXME: There's only _ftruncate64 beginning with Solaris 11. +DECLARE__REAL_AND_INTERNAL(uptr, ftruncate, fd_t fd, uptr size) { + return ftruncate(fd, size); +} + +DECLARE__REAL_AND_INTERNAL(uptr, stat, const char *path, void *buf) { + return _REAL(stat)(path, (struct stat *)buf); +} + +DECLARE__REAL_AND_INTERNAL(uptr, lstat, const char *path, void *buf) { + return _REAL(lstat)(path, (struct stat *)buf); +} + +DECLARE__REAL_AND_INTERNAL(uptr, fstat, fd_t fd, void *buf) { + return _REAL(fstat)(fd, (struct stat *)buf); +} + +uptr internal_filesize(fd_t fd) { + struct stat st; + if (internal_fstat(fd, &st)) + return -1; + return (uptr)st.st_size; +} + +DECLARE__REAL_AND_INTERNAL(uptr, dup2, int oldfd, int newfd) { + return _REAL(dup2)(oldfd, newfd); +} + +DECLARE__REAL_AND_INTERNAL(uptr, readlink, const char *path, char *buf, + uptr bufsize) { + return _REAL(readlink)(path, buf, bufsize); +} + +DECLARE__REAL_AND_INTERNAL(uptr, unlink, const char *path) { + return _REAL(unlink)(path); +} + +DECLARE__REAL_AND_INTERNAL(uptr, rename, const char *oldpath, + const char *newpath) { + return _REAL(rename)(oldpath, newpath); +} + +DECLARE__REAL_AND_INTERNAL(uptr, sched_yield, void) { + return sched_yield(); +} + +DECLARE__REAL_AND_INTERNAL(void, _exit, int exitcode) { + _exit(exitcode); +} + +DECLARE__REAL_AND_INTERNAL(uptr, execve, const char *filename, + char *const argv[], char *const envp[]) { + return _REAL(execve)(filename, argv, envp); +} + +DECLARE__REAL_AND_INTERNAL(uptr, waitpid, int pid, int *status, int options) { + return _REAL(waitpid)(pid, status, options); +} + +DECLARE__REAL_AND_INTERNAL(uptr, getpid, void) { + return _REAL(getpid)(); +} + +// FIXME: This might be wrong: _getdents doesn't take a struct linux_dirent *. +DECLARE__REAL_AND_INTERNAL(uptr, getdents, fd_t fd, struct linux_dirent *dirp, + unsigned int count) { + return _REAL(getdents)(fd, dirp, count); +} + +DECLARE__REAL_AND_INTERNAL(uptr, lseek, fd_t fd, OFF_T offset, int whence) { + return _REAL(lseek)(fd, offset, whence); +} + +// FIXME: This might be wrong: _sigfillset doesn't take a +// __sanitizer_sigset_t *. +DECLARE__REAL_AND_INTERNAL(void, sigfillset, __sanitizer_sigset_t *set) { + _REAL(sigfillset)(set); +} + +// 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) { + return _REAL(sigprocmask)(how, set, oldset); +} + +DECLARE__REAL_AND_INTERNAL(int, fork, void) { + // TODO(glider): this may call user's pthread_atfork() handlers which is bad. + return _REAL(fork)(); +} + +// ----------------- sanitizer_common.h +BlockingMutex::BlockingMutex() { + CHECK(sizeof(mutex_t) <= sizeof(opaque_storage_)); + internal_memset(this, 0, sizeof(*this)); + CHECK_EQ(mutex_init((mutex_t *)&opaque_storage_, USYNC_THREAD, NULL), 0); +} + +void BlockingMutex::Lock() { + CHECK(sizeof(mutex_t) <= sizeof(opaque_storage_)); + CHECK_NE(owner_, (uptr)thr_self()); + CHECK_EQ(mutex_lock((mutex_t *)&opaque_storage_), 0); + CHECK(!owner_); + owner_ = (uptr)thr_self(); +} + +void BlockingMutex::Unlock() { + CHECK(owner_ == (uptr)thr_self()); + owner_ = 0; + CHECK_EQ(mutex_unlock((mutex_t *)&opaque_storage_), 0); +} + +void BlockingMutex::CheckLocked() { + CHECK_EQ((uptr)thr_self(), owner_); +} + +} // namespace __sanitizer + +#endif // SANITIZER_SOLARIS Index: lib/sanitizer_common/sanitizer_syscall_generic.inc =================================================================== --- lib/sanitizer_common/sanitizer_syscall_generic.inc +++ lib/sanitizer_common/sanitizer_syscall_generic.inc @@ -11,7 +11,7 @@ // //===----------------------------------------------------------------------===// -#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_MAC || SANITIZER_NETBSD || SANITIZER_SOLARIS # define SYSCALL(name) SYS_ ## name #else # define SYSCALL(name) __NR_ ## name Index: lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc =================================================================== --- lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc +++ lib/sanitizer_common/sanitizer_unwind_linux_libcdep.cc @@ -8,11 +8,12 @@ //===----------------------------------------------------------------------===// // // This file contains the unwind.h-based (aka "slow") stack unwinding routines -// available to the tools on Linux, Android, NetBSD and FreeBSD. +// available to the tools on Linux, Android, NetBSD, FreeBSD, and Solaris. //===----------------------------------------------------------------------===// #include "sanitizer_platform.h" -#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#if SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || \ + SANITIZER_SOLARIS #include "sanitizer_common.h" #include "sanitizer_stacktrace.h" @@ -166,4 +167,5 @@ } // namespace __sanitizer -#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || + // SANITIZER_SOLARIS Index: lib/ubsan/ubsan_platform.h =================================================================== --- lib/ubsan/ubsan_platform.h +++ lib/ubsan/ubsan_platform.h @@ -18,7 +18,7 @@ defined(__NetBSD__)) && \ (defined(__x86_64__) || defined(__i386__) || defined(__arm__) || \ defined(__aarch64__) || defined(__mips__) || defined(__powerpc64__) || \ - defined(__s390__)) + defined(__s390__)) || (defined(__sun__) && defined(__svr4__)) # define CAN_SANITIZE_UB 1 #elif defined(_WIN32) || defined(__Fuchsia__) # define CAN_SANITIZE_UB 1