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