1 //===-- asan_linux.cc -----------------------------------------------------===//
3 // This file is distributed under the University of Illinois Open Source
4 // License. See LICENSE.TXT for details.
6 //===----------------------------------------------------------------------===//
8 // This file is a part of AddressSanitizer, an address sanity checker.
10 // Linux-specific details.
11 //===----------------------------------------------------------------------===//
13 #include "sanitizer_common/sanitizer_platform.h"
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"
23 #include <sys/resource.h>
25 #include <sys/syscall.h>
26 #include <sys/types.h>
33 #if !SANITIZER_ANDROID
34 // FIXME: where to get ucontext on Android?
35 #include <sys/ucontext.h>
38 extern "C" void* _DYNAMIC
;
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
) {
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
;
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);
91 *pc
= ucontext
->uc_mcontext
.gregs
[REG_PC
];
92 *sp
= ucontext
->uc_mcontext
.gregs
[REG_O6
];
93 stk_ptr
= (uptr
*) *sp
;
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];
102 # error "Unsupported arch"
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
;
121 void ReadContextStack(void *context
, uptr
*stack
, uptr
*ssize
) {
126 } // namespace __asan
128 #endif // SANITIZER_LINUX