asan_linux.cc revision 83cb7877f608eb9b3d65981095216842f686c527
11e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===-- asan_linux.cc -----------------------------------------------------===// 21e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 31e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// The LLVM Compiler Infrastructure 41e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 51e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is distributed under the University of Illinois Open Source 61e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// License. See LICENSE.TXT for details. 71e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 81e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 91e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 101e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// This file is a part of AddressSanitizer, an address sanity checker. 111e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// 121e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany// Linux-specific details. 131e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany//===----------------------------------------------------------------------===// 14d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany#ifdef __linux__ 151e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 16df499b44de81fc757a789878f07fcaf19ebb0016Kostya Serebryany#include "asan_interceptors.h" 171e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include "asan_internal.h" 18c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany#include "asan_thread.h" 192b939c3abc8b7713ef28000bd768ca6d77445f45Kostya Serebryany#include "asan_thread_registry.h" 20ae4d9caa4f47fa6abcd641719e9f520622940c17Alexey Samsonov#include "sanitizer_common/sanitizer_libc.h" 216895adc39c4e09371154c8037366ad4464163ed0Alexey Samsonov#include "sanitizer_common/sanitizer_procmaps.h" 221e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 23c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany#include <sys/time.h> 24c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany#include <sys/resource.h> 251e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <sys/mman.h> 261e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <sys/syscall.h> 27de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany#include <sys/types.h> 28de496f451bce322b6cde100456591f1f50ab3477Kostya Serebryany#include <fcntl.h> 29c549dd7b5fa5fb97270f57067797224cee0429f2Kostya Serebryany#include <pthread.h> 30df499b44de81fc757a789878f07fcaf19ebb0016Kostya Serebryany#include <stdio.h> 311e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany#include <unistd.h> 329cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov#include <unwind.h> 331e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 3483cb7877f608eb9b3d65981095216842f686c527Evgeniy Stepanov#if !SANITIZER_ANDROID 359107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany// FIXME: where to get ucontext on Android? 369107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany#include <sys/ucontext.h> 379107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany#endif 389107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany 39aa33a50c9d0f3e3f22c8b21fa7309ec91f9d939aEvgeniy Stepanovextern "C" void* _DYNAMIC; 40aa33a50c9d0f3e3f22c8b21fa7309ec91f9d939aEvgeniy Stepanov 411e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanynamespace __asan { 421e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 43eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenkovoid MaybeReexec() { 44eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko // No need to re-exec on Linux. 45eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko} 46eb8c46e419f4c6f01d1b1a0d1b96cc51a61ecbc3Alexander Potapenko 471e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryanyvoid *AsanDoesNotSupportStaticLinkage() { 481e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany // This will fail to link with -static. 49efb3fa36cf421c346e8e54054cdae4fd798edab7Kostya Serebryany return &_DYNAMIC; // defined in link.h 501e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} 511e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany 523f4c3875c42078e22c7e5356c5746fd18756d958Kostya Serebryanyvoid GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) { 5383cb7877f608eb9b3d65981095216842f686c527Evgeniy Stepanov#if SANITIZER_ANDROID 549107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany *pc = *sp = *bp = 0; 559107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany#elif defined(__arm__) 569107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany ucontext_t *ucontext = (ucontext_t*)context; 579107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany *pc = ucontext->uc_mcontext.arm_pc; 589107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany *bp = ucontext->uc_mcontext.arm_fp; 599107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany *sp = ucontext->uc_mcontext.arm_sp; 609107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany# elif defined(__x86_64__) 619107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany ucontext_t *ucontext = (ucontext_t*)context; 629107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany *pc = ucontext->uc_mcontext.gregs[REG_RIP]; 639107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany *bp = ucontext->uc_mcontext.gregs[REG_RBP]; 649107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany *sp = ucontext->uc_mcontext.gregs[REG_RSP]; 659107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany# elif defined(__i386__) 669107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany ucontext_t *ucontext = (ucontext_t*)context; 679107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany *pc = ucontext->uc_mcontext.gregs[REG_EIP]; 689107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany *bp = ucontext->uc_mcontext.gregs[REG_EBP]; 699107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany *sp = ucontext->uc_mcontext.gregs[REG_ESP]; 70d7d4650dd754aafc874e3b8cd5ab5b38005c84ecKostya Serebryany# elif defined(__powerpc__) || defined(__powerpc64__) 71d7d4650dd754aafc874e3b8cd5ab5b38005c84ecKostya Serebryany ucontext_t *ucontext = (ucontext_t*)context; 72d7d4650dd754aafc874e3b8cd5ab5b38005c84ecKostya Serebryany *pc = ucontext->uc_mcontext.regs->nip; 73d7d4650dd754aafc874e3b8cd5ab5b38005c84ecKostya Serebryany *sp = ucontext->uc_mcontext.regs->gpr[PT_R1]; 74d7d4650dd754aafc874e3b8cd5ab5b38005c84ecKostya Serebryany // The powerpc{,64}-linux ABIs do not specify r31 as the frame 75d7d4650dd754aafc874e3b8cd5ab5b38005c84ecKostya Serebryany // pointer, but GCC always uses r31 when we need a frame pointer. 76d7d4650dd754aafc874e3b8cd5ab5b38005c84ecKostya Serebryany *bp = ucontext->uc_mcontext.regs->gpr[PT_R31]; 7716da7947df767cf75874430d4ecfeeee218339bdDmitry Vyukov# elif defined(__sparc__) 7816da7947df767cf75874430d4ecfeeee218339bdDmitry Vyukov ucontext_t *ucontext = (ucontext_t*)context; 7916da7947df767cf75874430d4ecfeeee218339bdDmitry Vyukov uptr *stk_ptr; 8016da7947df767cf75874430d4ecfeeee218339bdDmitry Vyukov# if defined (__arch64__) 8116da7947df767cf75874430d4ecfeeee218339bdDmitry Vyukov *pc = ucontext->uc_mcontext.mc_gregs[MC_PC]; 8216da7947df767cf75874430d4ecfeeee218339bdDmitry Vyukov *sp = ucontext->uc_mcontext.mc_gregs[MC_O6]; 8316da7947df767cf75874430d4ecfeeee218339bdDmitry Vyukov stk_ptr = (uptr *) (*sp + 2047); 8416da7947df767cf75874430d4ecfeeee218339bdDmitry Vyukov *bp = stk_ptr[15]; 8516da7947df767cf75874430d4ecfeeee218339bdDmitry Vyukov# else 8616da7947df767cf75874430d4ecfeeee218339bdDmitry Vyukov *pc = ucontext->uc_mcontext.gregs[REG_PC]; 8716da7947df767cf75874430d4ecfeeee218339bdDmitry Vyukov *sp = ucontext->uc_mcontext.gregs[REG_O6]; 8816da7947df767cf75874430d4ecfeeee218339bdDmitry Vyukov stk_ptr = (uptr *) *sp; 8916da7947df767cf75874430d4ecfeeee218339bdDmitry Vyukov *bp = stk_ptr[15]; 9016da7947df767cf75874430d4ecfeeee218339bdDmitry Vyukov# endif 919107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany#else 929107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany# error "Unsupported arch" 939107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany#endif 949107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany} 959107c26bd88fc9cf44a2cd7d6967eb830ac63be3Kostya Serebryany 964803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryanybool AsanInterceptsSignal(int signum) { 97cb8c4dce691097718d5af41b36899b72ef4b1d84Alexey Samsonov return signum == SIGSEGV && flags()->handle_segv; 984803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany} 994803ab90ead451b55a5833f0fd38b10fd1fc83ebKostya Serebryany 10075b19ebf25af204cf209d108997272822241d6daAlexander Potapenkovoid AsanPlatformThreadInit() { 10175b19ebf25af204cf209d108997272822241d6daAlexander Potapenko // Nothing here for now. 10275b19ebf25af204cf209d108997272822241d6daAlexander Potapenko} 10375b19ebf25af204cf209d108997272822241d6daAlexander Potapenko 104a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryanyvoid GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp, bool fast) { 105a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany#if defined(__arm__) || \ 106a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany defined(__powerpc__) || defined(__powerpc64__) || \ 107a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany defined(__sparc__) 108a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany fast = false; 1099cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov#endif 110a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany if (!fast) 11149d616ec42ab420ce3ebcbe846b21e3729adf5acKostya Serebryany return stack->SlowUnwindStack(pc, max_s); 1122b939c3abc8b7713ef28000bd768ca6d77445f45Kostya Serebryany stack->size = 0; 1132b939c3abc8b7713ef28000bd768ca6d77445f45Kostya Serebryany stack->trace[0] = pc; 114a30c8f9eac981dcf137e84226810b760e35c7be1Kostya Serebryany if (max_s > 1) { 1152b939c3abc8b7713ef28000bd768ca6d77445f45Kostya Serebryany stack->max_size = max_s; 1162b939c3abc8b7713ef28000bd768ca6d77445f45Kostya Serebryany if (!asan_inited) return; 1172b939c3abc8b7713ef28000bd768ca6d77445f45Kostya Serebryany if (AsanThread *t = asanThreadRegistry().GetCurrent()) 1182b939c3abc8b7713ef28000bd768ca6d77445f45Kostya Serebryany stack->FastUnwindStack(pc, bp, t->stack_top(), t->stack_bottom()); 1199cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov } 1209cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov} 1219cfa194cc62026fc7c6e82f7303eee8ad4d10cf4Evgeniy Stepanov 12283cb7877f608eb9b3d65981095216842f686c527Evgeniy Stepanov#if !SANITIZER_ANDROID 12357db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonovvoid ReadContextStack(void *context, uptr *stack, uptr *ssize) { 124f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov ucontext_t *ucp = (ucontext_t*)context; 12557db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov *stack = (uptr)ucp->uc_stack.ss_sp; 12657db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonov *ssize = ucp->uc_stack.ss_size; 127f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov} 128f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov#else 12957db4bae483e7268dd7fc5bc42b0e55564014048Alexey Samsonovvoid ReadContextStack(void *context, uptr *stack, uptr *ssize) { 130ca2849c2819b5c7a8771a1e8bc449cf8f5ef6527Alexey Samsonov UNIMPLEMENTED(); 131f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov} 132f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov#endif 133f3950c6d6acf53fe60735f6d38715c1ea6df814bAlexey Samsonov 1341e172b4bdec57329bf904f063a29f99cddf2d85fKostya Serebryany} // namespace __asan 135d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany 136d6567c5166412f6acdde851e767c26f332d51d3dKostya Serebryany#endif // __linux__ 137