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