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