2013-02-04 Paul Thomas <pault@gcc.gnu.org>
[official-gcc.git] / libsanitizer / asan / asan_linux.cc
bloba030fcd397298696c078488fa51a14e50c95b8f1
1 //===-- asan_linux.cc -----------------------------------------------------===//
2 //
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
5 //
6 //===----------------------------------------------------------------------===//
7 //
8 // This file is a part of AddressSanitizer, an address sanity checker.
9 //
10 // Linux-specific details.
11 //===----------------------------------------------------------------------===//
12 #ifdef __linux__
14 #include "asan_interceptors.h"
15 #include "asan_internal.h"
16 #include "asan_thread.h"
17 #include "asan_thread_registry.h"
18 #include "sanitizer_common/sanitizer_libc.h"
19 #include "sanitizer_common/sanitizer_procmaps.h"
21 #include <sys/time.h>
22 #include <sys/resource.h>
23 #include <sys/mman.h>
24 #include <sys/syscall.h>
25 #include <sys/types.h>
26 #include <fcntl.h>
27 #include <pthread.h>
28 #include <stdio.h>
29 #include <unistd.h>
30 #include <unwind.h>
32 #if !ASAN_ANDROID
33 // FIXME: where to get ucontext on Android?
34 #include <sys/ucontext.h>
35 #endif
37 extern "C" void* _DYNAMIC;
39 namespace __asan {
41 void MaybeReexec() {
42 // No need to re-exec on Linux.
45 void *AsanDoesNotSupportStaticLinkage() {
46 // This will fail to link with -static.
47 return &_DYNAMIC; // defined in link.h
50 void GetPcSpBp(void *context, uptr *pc, uptr *sp, uptr *bp) {
51 #if ASAN_ANDROID
52 *pc = *sp = *bp = 0;
53 #elif defined(__arm__)
54 ucontext_t *ucontext = (ucontext_t*)context;
55 *pc = ucontext->uc_mcontext.arm_pc;
56 *bp = ucontext->uc_mcontext.arm_fp;
57 *sp = ucontext->uc_mcontext.arm_sp;
58 # elif defined(__x86_64__)
59 ucontext_t *ucontext = (ucontext_t*)context;
60 *pc = ucontext->uc_mcontext.gregs[REG_RIP];
61 *bp = ucontext->uc_mcontext.gregs[REG_RBP];
62 *sp = ucontext->uc_mcontext.gregs[REG_RSP];
63 # elif defined(__i386__)
64 ucontext_t *ucontext = (ucontext_t*)context;
65 *pc = ucontext->uc_mcontext.gregs[REG_EIP];
66 *bp = ucontext->uc_mcontext.gregs[REG_EBP];
67 *sp = ucontext->uc_mcontext.gregs[REG_ESP];
68 # elif defined(__powerpc__) || defined(__powerpc64__)
69 ucontext_t *ucontext = (ucontext_t*)context;
70 *pc = ucontext->uc_mcontext.regs->nip;
71 *sp = ucontext->uc_mcontext.regs->gpr[PT_R1];
72 // The powerpc{,64}-linux ABIs do not specify r31 as the frame
73 // pointer, but GCC always uses r31 when we need a frame pointer.
74 *bp = ucontext->uc_mcontext.regs->gpr[PT_R31];
75 # elif defined(__sparc__)
76 ucontext_t *ucontext = (ucontext_t*)context;
77 uptr *stk_ptr;
78 # if defined (__arch64__)
79 *pc = ucontext->uc_mcontext.mc_gregs[MC_PC];
80 *sp = ucontext->uc_mcontext.mc_gregs[MC_O6];
81 stk_ptr = (uptr *) (*sp + 2047);
82 *bp = stk_ptr[15];
83 # else
84 *pc = ucontext->uc_mcontext.gregs[REG_PC];
85 *sp = ucontext->uc_mcontext.gregs[REG_O6];
86 stk_ptr = (uptr *) *sp;
87 *bp = stk_ptr[15];
88 # endif
89 #else
90 # error "Unsupported arch"
91 #endif
94 bool AsanInterceptsSignal(int signum) {
95 return signum == SIGSEGV && flags()->handle_segv;
98 void AsanPlatformThreadInit() {
99 // Nothing here for now.
102 void GetStackTrace(StackTrace *stack, uptr max_s, uptr pc, uptr bp, bool fast) {
103 #if defined(__arm__) || \
104 defined(__powerpc__) || defined(__powerpc64__) || \
105 defined(__sparc__)
106 fast = false;
107 #endif
108 if (!fast)
109 return stack->SlowUnwindStack(pc, max_s);
110 stack->size = 0;
111 stack->trace[0] = pc;
112 if (max_s > 1) {
113 stack->max_size = max_s;
114 if (!asan_inited) return;
115 if (AsanThread *t = asanThreadRegistry().GetCurrent())
116 stack->FastUnwindStack(pc, bp, t->stack_top(), t->stack_bottom());
120 #if !ASAN_ANDROID
121 void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
122 ucontext_t *ucp = (ucontext_t*)context;
123 *stack = (uptr)ucp->uc_stack.ss_sp;
124 *ssize = ucp->uc_stack.ss_size;
126 #else
127 void ReadContextStack(void *context, uptr *stack, uptr *ssize) {
128 UNIMPLEMENTED();
130 #endif
132 } // namespace __asan
134 #endif // __linux__