asan_linux.cc revision 7f790caa37ec1c9807c877297d30e040e83ed215
11320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//===-- asan_linux.cc -----------------------------------------------------===// 21320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// 31320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// The LLVM Compiler Infrastructure 41320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// 51320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// This file is distributed under the University of Illinois Open Source 61320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// License. See LICENSE.TXT for details. 71320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// 81320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//===----------------------------------------------------------------------===// 91320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// 101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// This file is a part of AddressSanitizer, an address sanity checker. 111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// 121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// Linux-specific details. 131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci//===----------------------------------------------------------------------===// 141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "sanitizer_common/sanitizer_platform.h" 161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if SANITIZER_LINUX 171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "asan_interceptors.h" 191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "asan_internal.h" 201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "asan_thread.h" 211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "sanitizer_common/sanitizer_libc.h" 221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include "sanitizer_common/sanitizer_procmaps.h" 231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <sys/time.h> 251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <sys/resource.h> 261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <sys/mman.h> 271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <sys/syscall.h> 281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <sys/types.h> 291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <fcntl.h> 301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <pthread.h> 311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <stdio.h> 321320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <unistd.h> 331320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <unwind.h> 341320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 351320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if !SANITIZER_ANDROID 361320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci// FIXME: where to get ucontext on Android? 371320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#include <sys/ucontext.h> 381320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 391320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 401320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucciextern "C" void* _DYNAMIC; 411320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 421320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccinamespace __asan { 431320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 441320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid MaybeReexec() { 451320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // No need to re-exec on Linux. 461320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 471320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 481320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid *AsanDoesNotSupportStaticLinkage() { 491320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // This will fail to link with -static. 501320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return &_DYNAMIC; // defined in link.h 511320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 521320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 531320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { 541320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if SANITIZER_ANDROID 551320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *pc = *sp = *bp = 0; 561320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#elif defined(__arm__) 571320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ucontext_t *ucontext = (ucontext_t*)context; 581320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *pc = ucontext->uc_mcontext.arm_pc; 591320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *bp = ucontext->uc_mcontext.arm_fp; 601320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *sp = ucontext->uc_mcontext.arm_sp; 611320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# elif defined(__hppa__) 621320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ucontext_t *ucontext = (ucontext_t*)context; 631320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *pc = ucontext->uc_mcontext.sc_iaoq[0]; 641320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci /* GCC uses %r3 whenever a frame pointer is needed. */ 651320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *bp = ucontext->uc_mcontext.sc_gr[3]; 661320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *sp = ucontext->uc_mcontext.sc_gr[30]; 671320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# elif defined(__x86_64__) 681320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ucontext_t *ucontext = (ucontext_t*)context; 691320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *pc = ucontext->uc_mcontext.gregs[REG_RIP]; 701320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *bp = ucontext->uc_mcontext.gregs[REG_RBP]; 711320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *sp = ucontext->uc_mcontext.gregs[REG_RSP]; 721320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# elif defined(__i386__) 731320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ucontext_t *ucontext = (ucontext_t*)context; 741320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *pc = ucontext->uc_mcontext.gregs[REG_EIP]; 751320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *bp = ucontext->uc_mcontext.gregs[REG_EBP]; 761320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *sp = ucontext->uc_mcontext.gregs[REG_ESP]; 771320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# elif defined(__powerpc__) || defined(__powerpc64__) 781320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ucontext_t *ucontext = (ucontext_t*)context; 791320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *pc = ucontext->uc_mcontext.regs->nip; 801320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *sp = ucontext->uc_mcontext.regs->gpr[PT_R1]; 811320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // The powerpc{,64}-linux ABIs do not specify r31 as the frame 821320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // pointer, but GCC always uses r31 when we need a frame pointer. 831320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *bp = ucontext->uc_mcontext.regs->gpr[PT_R31]; 841320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# elif defined(__sparc__) 851320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ucontext_t *ucontext = (ucontext_t*)context; 861320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci uptr *stk_ptr; 871320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# if defined (__arch64__) 881320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *pc = ucontext->uc_mcontext.mc_gregs[MC_PC]; 891320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *sp = ucontext->uc_mcontext.mc_gregs[MC_O6]; 901320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stk_ptr = (uptr *) (*sp + 2047); 911320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *bp = stk_ptr[15]; 921320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# else 931320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *pc = ucontext->uc_mcontext.gregs[REG_PC]; 941320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *sp = ucontext->uc_mcontext.gregs[REG_O6]; 951320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci stk_ptr = (uptr *) *sp; 961320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *bp = stk_ptr[15]; 971320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# endif 981320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# elif defined(__mips__) 991320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ucontext_t *ucontext = (ucontext_t*)context; 1001320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *pc = ucontext->uc_mcontext.gregs[31]; 1011320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *bp = ucontext->uc_mcontext.gregs[30]; 1021320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *sp = ucontext->uc_mcontext.gregs[29]; 1031320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#else 1041320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci# error "Unsupported arch" 1051320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 1061320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1071320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1081320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccibool AsanInterceptsSignal(int signum) { 1091320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci return signum == SIGSEGV && flags()->handle_segv; 1101320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1111320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1121320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid AsanPlatformThreadInit() { 1131320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci // Nothing here for now. 1141320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1151320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1161320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#if !SANITIZER_ANDROID 1171320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ReadContextStack(void *context, uptr *stack, uptr *ssize) { 1181320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci ucontext_t *ucp = (ucontext_t*)context; 1191320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *stack = (uptr)ucp->uc_stack.ss_sp; 1201320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci *ssize = ucp->uc_stack.ss_size; 1211320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1221320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#else 1231320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tuccivoid ReadContextStack(void *context, uptr *stack, uptr *ssize) { 1241320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci UNIMPLEMENTED(); 1251320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} 1261320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif 1271320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1281320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci} // namespace __asan 1291320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci 1301320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci#endif // SANITIZER_LINUX 1311320f92c476a1ad9d19dba2a48c72b75566198e9Primiano Tucci