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 //===----------------------------------------------------------------------===//
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"
22 #include <sys/resource.h>
24 #include <sys/syscall.h>
25 #include <sys/types.h>
33 // FIXME: where to get ucontext on Android?
34 #include <sys/ucontext.h>
37 extern "C" void* _DYNAMIC
;
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
) {
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
;
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);
84 *pc
= ucontext
->uc_mcontext
.gregs
[REG_PC
];
85 *sp
= ucontext
->uc_mcontext
.gregs
[REG_O6
];
86 stk_ptr
= (uptr
*) *sp
;
90 # error "Unsupported arch"
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__) || \
109 return stack
->SlowUnwindStack(pc
, max_s
);
111 stack
->trace
[0] = pc
;
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());
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
;
127 void ReadContextStack(void *context
, uptr
*stack
, uptr
*ssize
) {
132 } // namespace __asan