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 !ASAN_ANDROID 35 // FIXME: where to get ucontext on Android? 36 #include <sys/ucontext.h> 37 #endif 38 39 extern "C" void* _DYNAMIC; 40 41 namespace __asan { 42 43 void MaybeReexec() { 44 // No need to re-exec on Linux. 45 } 46 47 void *AsanDoesNotSupportStaticLinkage() { 48 // This will fail to link with -static. 49 return &_DYNAMIC; // defined in link.h 50 } 51 52 void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { 53 #if ASAN_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 96 bool AsanInterceptsSignal(int signum) { 97 return signum == SIGSEGV && flags()->handle_segv; 98 } 99 100 void AsanPlatformThreadInit() { 101 // Nothing here for now. 102 } 103 104 void 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 !ASAN_ANDROID 123 void 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 129 void ReadContextStack(void *context, uptr *stack, uptr *ssize) { 130 UNIMPLEMENTED(); 131 } 132 #endif 133 134 } // namespace __asan 135 136 #endif // __linux__ 137