asan_linux.cc revision 83cb7877f608eb9b3d65981095216842f686c527
1//===-- asan_linux.cc -----------------------------------------------------===// 2// 3// The LLVM Compiler Infrastructure 4// 5// This file is distributed under the University of Illinois Open Source 6// License. See LICENSE.TXT for details. 7// 8//===----------------------------------------------------------------------===// 9// 10// This file is a part of AddressSanitizer, an address sanity checker. 11// 12// Linux-specific details. 13//===----------------------------------------------------------------------===// 14#ifdef __linux__ 15 16#include "asan_interceptors.h" 17#include "asan_internal.h" 18#include "asan_thread.h" 19#include "asan_thread_registry.h" 20#include "sanitizer_common/sanitizer_libc.h" 21#include "sanitizer_common/sanitizer_procmaps.h" 22 23#include <sys/time.h> 24#include <sys/resource.h> 25#include <sys/mman.h> 26#include <sys/syscall.h> 27#include <sys/types.h> 28#include <fcntl.h> 29#include <pthread.h> 30#include <stdio.h> 31#include <unistd.h> 32#include <unwind.h> 33 34#if !SANITIZER_ANDROID 35// FIXME: where to get ucontext on Android? 36#include <sys/ucontext.h> 37#endif 38 39extern "C" void* _DYNAMIC; 40 41namespace __asan { 42 43void MaybeReexec() { 44 // No need to re-exec on Linux. 45} 46 47void *AsanDoesNotSupportStaticLinkage() { 48 // This will fail to link with -static. 49 return &_DYNAMIC; // defined in link.h 50} 51 52void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { 53#if SANITIZER_ANDROID 54 *pc = *sp = *bp = 0; 55#elif defined(__arm__) 56 ucontext_t *ucontext = (ucontext_t*)context; 57 *pc = ucontext->uc_mcontext.arm_pc; 58 *bp = ucontext->uc_mcontext.arm_fp; 59 *sp = ucontext->uc_mcontext.arm_sp; 60# elif defined(__x86_64__) 61 ucontext_t *ucontext = (ucontext_t*)context; 62 *pc = ucontext->uc_mcontext.gregs[REG_RIP]; 63 *bp = ucontext->uc_mcontext.gregs[REG_RBP]; 64 *sp = ucontext->uc_mcontext.gregs[REG_RSP]; 65# elif defined(__i386__) 66 ucontext_t *ucontext = (ucontext_t*)context; 67 *pc = ucontext->uc_mcontext.gregs[REG_EIP]; 68 *bp = ucontext->uc_mcontext.gregs[REG_EBP]; 69 *sp = ucontext->uc_mcontext.gregs[REG_ESP]; 70# elif defined(__powerpc__) || defined(__powerpc64__) 71 ucontext_t *ucontext = (ucontext_t*)context; 72 *pc = ucontext->uc_mcontext.regs->nip; 73 *sp = ucontext->uc_mcontext.regs->gpr[PT_R1]; 74 // The powerpc{,64}-linux ABIs do not specify r31 as the frame 75 // pointer, but GCC always uses r31 when we need a frame pointer. 76 *bp = ucontext->uc_mcontext.regs->gpr[PT_R31]; 77# elif defined(__sparc__) 78 ucontext_t *ucontext = (ucontext_t*)context; 79 uptr *stk_ptr; 80# if defined (__arch64__) 81 *pc = ucontext->uc_mcontext.mc_gregs[MC_PC]; 82 *sp = ucontext->uc_mcontext.mc_gregs[MC_O6]; 83 stk_ptr = (uptr *) (*sp + 2047); 84 *bp = stk_ptr[15]; 85# else 86 *pc = ucontext->uc_mcontext.gregs[REG_PC]; 87 *sp = ucontext->uc_mcontext.gregs[REG_O6]; 88 stk_ptr = (uptr *) *sp; 89 *bp = stk_ptr[15]; 90# endif 91#else 92# error "Unsupported arch" 93#endif 94} 95 96bool AsanInterceptsSignal(int signum) { 97 return signum == SIGSEGV && flags()->handle_segv; 98} 99 100void AsanPlatformThreadInit() { 101 // Nothing here for now. 102} 103 104void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp, bool fast) { 105#if defined(__arm__) || \ 106 defined(__powerpc__) || defined(__powerpc64__) || \ 107 defined(__sparc__) 108 fast = false; 109#endif 110 if (!fast) 111 return stack->SlowUnwindStack(pc, max_s); 112 stack->size = 0; 113 stack->trace[0] = pc; 114 if (max_s > 1) { 115 stack->max_size = max_s; 116 if (!asan_inited) return; 117 if (AsanThread *t = asanThreadRegistry().GetCurrent()) 118 stack->FastUnwindStack(pc, bp, t->stack_top(), t->stack_bottom()); 119 } 120} 121 122#if !SANITIZER_ANDROID 123void ReadContextStack(void *context, uptr *stack, uptr *ssize) { 124 ucontext_t *ucp = (ucontext_t*)context; 125 *stack = (uptr)ucp->uc_stack.ss_sp; 126 *ssize = ucp->uc_stack.ss_size; 127} 128#else 129void ReadContextStack(void *context, uptr *stack, uptr *ssize) { 130 UNIMPLEMENTED(); 131} 132#endif 133 134} // namespace __asan 135 136#endif // __linux__ 137