diff options
Diffstat (limited to 'lib/sanitizer_common/sanitizer_linux.cc')
-rw-r--r-- | lib/sanitizer_common/sanitizer_linux.cc | 81 |
1 files changed, 72 insertions, 9 deletions
diff --git a/lib/sanitizer_common/sanitizer_linux.cc b/lib/sanitizer_common/sanitizer_linux.cc index 89c76422c..6c83e8db4 100644 --- a/lib/sanitizer_common/sanitizer_linux.cc +++ b/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 <pthread.h> #include <sched.h> #include <sys/mman.h> +#if !SANITIZER_SOLARIS #include <sys/ptrace.h> +#endif #include <sys/resource.h> #include <sys/stat.h> #include <sys/syscall.h> @@ -92,6 +95,14 @@ extern char **environ; // provided by crt1 extern struct ps_strings *__ps_strings; #endif // SANITIZER_NETBSD +#if SANITIZER_SOLARIS +#include <stdlib.h> +#include <thread.h> + +extern char **_environ; +#define environ _environ +#endif + #if !SANITIZER_ANDROID #include <sys/signal.h> #endif @@ -146,6 +157,7 @@ namespace __sanitizer { #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 @@ uptr internal_execve(const char *filename, char *const argv[], return internal_syscall_ptr(SYSCALL(execve), (uptr)filename, (uptr)argv, (uptr)envp); } +#endif // !SANITIZER_SOLARIS // ----------------- sanitizer_common.h bool FileExists(const char *filename) { @@ -443,11 +456,14 @@ tid_t GetTid() { return (uptr)pthread_self(); #elif SANITIZER_NETBSD return _lwp_self(); +#elif SANITIZER_SOLARIS + return (uptr)thr_self(); #else return internal_syscall(SYSCALL(gettid)); #endif } +#if !SANITIZER_SOLARIS u64 NanoTime() { #if SANITIZER_FREEBSD || SANITIZER_NETBSD timeval tv; @@ -462,12 +478,13 @@ u64 NanoTime() { uptr internal_clock_gettime(__sanitizer_clockid_t clk_id, void *tp) { return internal_syscall_ptr(SYSCALL(clock_gettime), clk_id, tp); } +#endif // !SANITIZER_SOLARIS // 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 some others) 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++) { @@ -590,6 +607,9 @@ void ReExec() { 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); @@ -600,6 +620,7 @@ void ReExec() { Die(); } +#if !SANITIZER_SOLARIS enum MutexState { MtxUnlocked = 0, MtxLocked = 1, @@ -619,7 +640,7 @@ void BlockingMutex::Lock() { #if SANITIZER_FREEBSD _umtx_op(m, UMTX_OP_WAIT_UINT, MtxSleeping, 0, 0); #elif SANITIZER_NETBSD - sched_yield(); /* No userspace futex-like synchromization */ + sched_yield(); /* No userspace futex-like synchronization */ #else internal_syscall(SYSCALL(futex), (uptr)m, FUTEX_WAIT, MtxSleeping, 0, 0, 0); #endif @@ -634,7 +655,7 @@ void BlockingMutex::Unlock() { #if SANITIZER_FREEBSD _umtx_op(m, UMTX_OP_WAKE, 1, 0, 0); #elif SANITIZER_NETBSD - /* No userspace futex-like synchromization */ + /* No userspace futex-like synchronization */ #else internal_syscall(SYSCALL(futex), (uptr)m, FUTEX_WAKE, 1, 0, 0, 0); #endif @@ -645,6 +666,7 @@ void BlockingMutex::CheckLocked() { atomic_uint32_t *m = reinterpret_cast<atomic_uint32_t *>(&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. @@ -677,6 +699,7 @@ struct linux_dirent { }; #endif +#if !SANITIZER_SOLARIS // Syscall wrappers. uptr internal_ptrace(int request, int pid, void *addr, void *data) { #if SANITIZER_NETBSD @@ -854,6 +877,7 @@ bool internal_sigismember(__sanitizer_sigset_t *set, int signum) { return k_set->sig[idx] & (1 << bit); } #endif // SANITIZER_LINUX +#endif // !SANITIZER_SOLARIS // ThreadLister implementation. ThreadLister::ThreadLister(int pid) @@ -1011,6 +1035,11 @@ uptr GetPageSize() { } 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}; @@ -1028,7 +1057,7 @@ uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { default_module_name, buf, buf_len); int readlink_error; bool IsErr = internal_iserror(module_name_len, &readlink_error); -#endif +#endif // SANITIZER_SOLARIS if (IsErr) { // We can't read binary name for some reason, assume it's unknown. Report("WARNING: reading executable name failed with errno %d, " @@ -1038,6 +1067,7 @@ uptr ReadBinaryName(/*out*/char *buf, uptr buf_len) { CHECK_LT(module_name_len, buf_len); } return module_name_len; +#endif } uptr ReadLongProcessName(/*out*/ char *buf, uptr buf_len) { @@ -1662,6 +1692,9 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { 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 @@ -1675,6 +1708,12 @@ SignalContext::WriteFlag SignalContext::GetWriteFlag() const { 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. @@ -1732,6 +1771,19 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { *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]; @@ -1746,7 +1798,16 @@ static void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { #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); @@ -1835,4 +1896,6 @@ bool GetRandom(void *buffer, uptr length, bool blocking) { } // namespace __sanitizer -#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD +#endif // SANITIZER_FREEBSD || SANITIZER_LINUX || SANITIZER_NETBSD || + // SANITIZER_SOLARIS + |