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