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_lock.h"
17 #include "asan_thread.h"
18 #include "asan_thread_registry.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>
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(__x86_64__)
60 ucontext_t
*ucontext
= (ucontext_t
*)context
;
61 *pc
= ucontext
->uc_mcontext
.gregs
[REG_RIP
];
62 *bp
= ucontext
->uc_mcontext
.gregs
[REG_RBP
];
63 *sp
= ucontext
->uc_mcontext
.gregs
[REG_RSP
];
64 # elif defined(__i386__)
65 ucontext_t
*ucontext
= (ucontext_t
*)context
;
66 *pc
= ucontext
->uc_mcontext
.gregs
[REG_EIP
];
67 *bp
= ucontext
->uc_mcontext
.gregs
[REG_EBP
];
68 *sp
= ucontext
->uc_mcontext
.gregs
[REG_ESP
];
69 # elif defined(__powerpc__) || defined(__powerpc64__)
70 ucontext_t
*ucontext
= (ucontext_t
*)context
;
71 *pc
= ucontext
->uc_mcontext
.regs
->nip
;
72 *sp
= ucontext
->uc_mcontext
.regs
->gpr
[PT_R1
];
73 // The powerpc{,64}-linux ABIs do not specify r31 as the frame
74 // pointer, but GCC always uses r31 when we need a frame pointer.
75 *bp
= ucontext
->uc_mcontext
.regs
->gpr
[PT_R31
];
76 # elif defined(__sparc__)
77 ucontext_t
*ucontext
= (ucontext_t
*)context
;
79 # if defined (__arch64__)
80 *pc
= ucontext
->uc_mcontext
.mc_gregs
[MC_PC
];
81 *sp
= ucontext
->uc_mcontext
.mc_gregs
[MC_O6
];
82 stk_ptr
= (uptr
*) (*sp
+ 2047);
85 *pc
= ucontext
->uc_mcontext
.gregs
[REG_PC
];
86 *sp
= ucontext
->uc_mcontext
.gregs
[REG_O6
];
87 stk_ptr
= (uptr
*) *sp
;
91 # error "Unsupported arch"
95 bool AsanInterceptsSignal(int signum
) {
96 return signum
== SIGSEGV
&& flags()->handle_segv
;
99 void AsanPlatformThreadInit() {
100 // Nothing here for now.
103 AsanLock::AsanLock(LinkerInitialized
) {
104 // We assume that pthread_mutex_t initialized to all zeroes is a valid
105 // unlocked mutex. We can not use PTHREAD_MUTEX_INITIALIZER as it triggers
107 // extended initializer lists only available with -std=c++0x or -std=gnu++0x
110 void AsanLock::Lock() {
111 CHECK(sizeof(pthread_mutex_t
) <= sizeof(opaque_storage_
));
112 pthread_mutex_lock((pthread_mutex_t
*)&opaque_storage_
);
114 owner_
= (uptr
)pthread_self();
117 void AsanLock::Unlock() {
118 CHECK(owner_
== (uptr
)pthread_self());
120 pthread_mutex_unlock((pthread_mutex_t
*)&opaque_storage_
);
124 #define UNWIND_STOP _URC_END_OF_STACK
125 #define UNWIND_CONTINUE _URC_NO_REASON
127 #define UNWIND_STOP _URC_NORMAL_STOP
128 #define UNWIND_CONTINUE _URC_NO_REASON
131 uptr
Unwind_GetIP(struct _Unwind_Context
*ctx
) {
134 _Unwind_VRS_Result res
= _Unwind_VRS_Get(ctx
, _UVRSC_CORE
,
135 15 /* r15 = PC */, _UVRSD_UINT32
, &val
);
136 CHECK(res
== _UVRSR_OK
&& "_Unwind_VRS_Get failed");
137 // Clear the Thumb bit.
138 return val
& ~(uptr
)1;
140 return _Unwind_GetIP(ctx
);
144 _Unwind_Reason_Code
Unwind_Trace(struct _Unwind_Context
*ctx
,
146 StackTrace
*b
= (StackTrace
*)param
;
147 CHECK(b
->size
< b
->max_size
);
148 uptr pc
= Unwind_GetIP(ctx
);
149 b
->trace
[b
->size
++] = pc
;
150 if (b
->size
== b
->max_size
) return UNWIND_STOP
;
151 return UNWIND_CONTINUE
;
154 void GetStackTrace(StackTrace
*stack
, uptr max_s
, uptr pc
, uptr bp
) {
156 stack
->trace
[0] = pc
;
158 stack
->max_size
= max_s
;
159 #if defined(__arm__) || \
160 defined(__powerpc__) || defined(__powerpc64__) || \
162 _Unwind_Backtrace(Unwind_Trace
, stack
);
163 // Pop off the two ASAN functions from the backtrace.
164 stack
->PopStackFrames(2);
166 if (!asan_inited
) return;
167 if (AsanThread
*t
= asanThreadRegistry().GetCurrent())
168 stack
->FastUnwindStack(pc
, bp
, t
->stack_top(), t
->stack_bottom());
174 void ClearShadowMemoryForContext(void *context
) {
175 ucontext_t
*ucp
= (ucontext_t
*)context
;
176 uptr sp
= (uptr
)ucp
->uc_stack
.ss_sp
;
177 uptr size
= ucp
->uc_stack
.ss_size
;
178 // Align to page size.
179 uptr PageSize
= GetPageSizeCached();
180 uptr bottom
= sp
& ~(PageSize
- 1);
182 size
= RoundUpTo(size
, PageSize
);
183 PoisonShadow(bottom
, size
, 0);
186 void ClearShadowMemoryForContext(void *context
) {
191 } // namespace __asan