1*7c3d14c8STreehugger Robot //===-- asan_debugging.cc -------------------------------------------------===//
2*7c3d14c8STreehugger Robot //
3*7c3d14c8STreehugger Robot // The LLVM Compiler Infrastructure
4*7c3d14c8STreehugger Robot //
5*7c3d14c8STreehugger Robot // This file is distributed under the University of Illinois Open Source
6*7c3d14c8STreehugger Robot // License. See LICENSE.TXT for details.
7*7c3d14c8STreehugger Robot //
8*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
9*7c3d14c8STreehugger Robot //
10*7c3d14c8STreehugger Robot // This file is a part of AddressSanitizer, an address sanity checker.
11*7c3d14c8STreehugger Robot //
12*7c3d14c8STreehugger Robot // This file contains various functions that are generally useful to call when
13*7c3d14c8STreehugger Robot // using a debugger (LLDB, GDB).
14*7c3d14c8STreehugger Robot //===----------------------------------------------------------------------===//
15*7c3d14c8STreehugger Robot
16*7c3d14c8STreehugger Robot #include "asan_allocator.h"
17*7c3d14c8STreehugger Robot #include "asan_flags.h"
18*7c3d14c8STreehugger Robot #include "asan_internal.h"
19*7c3d14c8STreehugger Robot #include "asan_mapping.h"
20*7c3d14c8STreehugger Robot #include "asan_report.h"
21*7c3d14c8STreehugger Robot #include "asan_thread.h"
22*7c3d14c8STreehugger Robot
23*7c3d14c8STreehugger Robot namespace __asan {
24*7c3d14c8STreehugger Robot
GetInfoForStackVar(uptr addr,AddressDescription * descr,AsanThread * t)25*7c3d14c8STreehugger Robot void GetInfoForStackVar(uptr addr, AddressDescription *descr, AsanThread *t) {
26*7c3d14c8STreehugger Robot descr->name[0] = 0;
27*7c3d14c8STreehugger Robot descr->region_address = 0;
28*7c3d14c8STreehugger Robot descr->region_size = 0;
29*7c3d14c8STreehugger Robot descr->region_kind = "stack";
30*7c3d14c8STreehugger Robot
31*7c3d14c8STreehugger Robot AsanThread::StackFrameAccess access;
32*7c3d14c8STreehugger Robot if (!t->GetStackFrameAccessByAddr(addr, &access))
33*7c3d14c8STreehugger Robot return;
34*7c3d14c8STreehugger Robot InternalMmapVector<StackVarDescr> vars(16);
35*7c3d14c8STreehugger Robot if (!ParseFrameDescription(access.frame_descr, &vars)) {
36*7c3d14c8STreehugger Robot return;
37*7c3d14c8STreehugger Robot }
38*7c3d14c8STreehugger Robot
39*7c3d14c8STreehugger Robot for (uptr i = 0; i < vars.size(); i++) {
40*7c3d14c8STreehugger Robot if (access.offset <= vars[i].beg + vars[i].size) {
41*7c3d14c8STreehugger Robot internal_strncat(descr->name, vars[i].name_pos,
42*7c3d14c8STreehugger Robot Min(descr->name_size, vars[i].name_len));
43*7c3d14c8STreehugger Robot descr->region_address = addr - (access.offset - vars[i].beg);
44*7c3d14c8STreehugger Robot descr->region_size = vars[i].size;
45*7c3d14c8STreehugger Robot return;
46*7c3d14c8STreehugger Robot }
47*7c3d14c8STreehugger Robot }
48*7c3d14c8STreehugger Robot }
49*7c3d14c8STreehugger Robot
GetInfoForHeapAddress(uptr addr,AddressDescription * descr)50*7c3d14c8STreehugger Robot void GetInfoForHeapAddress(uptr addr, AddressDescription *descr) {
51*7c3d14c8STreehugger Robot AsanChunkView chunk = FindHeapChunkByAddress(addr);
52*7c3d14c8STreehugger Robot
53*7c3d14c8STreehugger Robot descr->name[0] = 0;
54*7c3d14c8STreehugger Robot descr->region_address = 0;
55*7c3d14c8STreehugger Robot descr->region_size = 0;
56*7c3d14c8STreehugger Robot
57*7c3d14c8STreehugger Robot if (!chunk.IsValid()) {
58*7c3d14c8STreehugger Robot descr->region_kind = "heap-invalid";
59*7c3d14c8STreehugger Robot return;
60*7c3d14c8STreehugger Robot }
61*7c3d14c8STreehugger Robot
62*7c3d14c8STreehugger Robot descr->region_address = chunk.Beg();
63*7c3d14c8STreehugger Robot descr->region_size = chunk.UsedSize();
64*7c3d14c8STreehugger Robot descr->region_kind = "heap";
65*7c3d14c8STreehugger Robot }
66*7c3d14c8STreehugger Robot
AsanLocateAddress(uptr addr,AddressDescription * descr)67*7c3d14c8STreehugger Robot void AsanLocateAddress(uptr addr, AddressDescription *descr) {
68*7c3d14c8STreehugger Robot if (DescribeAddressIfShadow(addr, descr, /* print */ false)) {
69*7c3d14c8STreehugger Robot return;
70*7c3d14c8STreehugger Robot }
71*7c3d14c8STreehugger Robot if (GetInfoForAddressIfGlobal(addr, descr)) {
72*7c3d14c8STreehugger Robot return;
73*7c3d14c8STreehugger Robot }
74*7c3d14c8STreehugger Robot asanThreadRegistry().Lock();
75*7c3d14c8STreehugger Robot AsanThread *thread = FindThreadByStackAddress(addr);
76*7c3d14c8STreehugger Robot asanThreadRegistry().Unlock();
77*7c3d14c8STreehugger Robot if (thread) {
78*7c3d14c8STreehugger Robot GetInfoForStackVar(addr, descr, thread);
79*7c3d14c8STreehugger Robot return;
80*7c3d14c8STreehugger Robot }
81*7c3d14c8STreehugger Robot GetInfoForHeapAddress(addr, descr);
82*7c3d14c8STreehugger Robot }
83*7c3d14c8STreehugger Robot
AsanGetStack(uptr addr,uptr * trace,u32 size,u32 * thread_id,bool alloc_stack)84*7c3d14c8STreehugger Robot static uptr AsanGetStack(uptr addr, uptr *trace, u32 size, u32 *thread_id,
85*7c3d14c8STreehugger Robot bool alloc_stack) {
86*7c3d14c8STreehugger Robot AsanChunkView chunk = FindHeapChunkByAddress(addr);
87*7c3d14c8STreehugger Robot if (!chunk.IsValid()) return 0;
88*7c3d14c8STreehugger Robot
89*7c3d14c8STreehugger Robot StackTrace stack(nullptr, 0);
90*7c3d14c8STreehugger Robot if (alloc_stack) {
91*7c3d14c8STreehugger Robot if (chunk.AllocTid() == kInvalidTid) return 0;
92*7c3d14c8STreehugger Robot stack = chunk.GetAllocStack();
93*7c3d14c8STreehugger Robot if (thread_id) *thread_id = chunk.AllocTid();
94*7c3d14c8STreehugger Robot } else {
95*7c3d14c8STreehugger Robot if (chunk.FreeTid() == kInvalidTid) return 0;
96*7c3d14c8STreehugger Robot stack = chunk.GetFreeStack();
97*7c3d14c8STreehugger Robot if (thread_id) *thread_id = chunk.FreeTid();
98*7c3d14c8STreehugger Robot }
99*7c3d14c8STreehugger Robot
100*7c3d14c8STreehugger Robot if (trace && size) {
101*7c3d14c8STreehugger Robot size = Min(size, Min(stack.size, kStackTraceMax));
102*7c3d14c8STreehugger Robot for (uptr i = 0; i < size; i++)
103*7c3d14c8STreehugger Robot trace[i] = StackTrace::GetPreviousInstructionPc(stack.trace[i]);
104*7c3d14c8STreehugger Robot
105*7c3d14c8STreehugger Robot return size;
106*7c3d14c8STreehugger Robot }
107*7c3d14c8STreehugger Robot
108*7c3d14c8STreehugger Robot return 0;
109*7c3d14c8STreehugger Robot }
110*7c3d14c8STreehugger Robot
111*7c3d14c8STreehugger Robot } // namespace __asan
112*7c3d14c8STreehugger Robot
113*7c3d14c8STreehugger Robot using namespace __asan;
114*7c3d14c8STreehugger Robot
115*7c3d14c8STreehugger Robot SANITIZER_INTERFACE_ATTRIBUTE
__asan_locate_address(uptr addr,char * name,uptr name_size,uptr * region_address,uptr * region_size)116*7c3d14c8STreehugger Robot const char *__asan_locate_address(uptr addr, char *name, uptr name_size,
117*7c3d14c8STreehugger Robot uptr *region_address, uptr *region_size) {
118*7c3d14c8STreehugger Robot AddressDescription descr = { name, name_size, 0, 0, nullptr };
119*7c3d14c8STreehugger Robot AsanLocateAddress(addr, &descr);
120*7c3d14c8STreehugger Robot if (region_address) *region_address = descr.region_address;
121*7c3d14c8STreehugger Robot if (region_size) *region_size = descr.region_size;
122*7c3d14c8STreehugger Robot return descr.region_kind;
123*7c3d14c8STreehugger Robot }
124*7c3d14c8STreehugger Robot
125*7c3d14c8STreehugger Robot SANITIZER_INTERFACE_ATTRIBUTE
__asan_get_alloc_stack(uptr addr,uptr * trace,uptr size,u32 * thread_id)126*7c3d14c8STreehugger Robot uptr __asan_get_alloc_stack(uptr addr, uptr *trace, uptr size, u32 *thread_id) {
127*7c3d14c8STreehugger Robot return AsanGetStack(addr, trace, size, thread_id, /* alloc_stack */ true);
128*7c3d14c8STreehugger Robot }
129*7c3d14c8STreehugger Robot
130*7c3d14c8STreehugger Robot SANITIZER_INTERFACE_ATTRIBUTE
__asan_get_free_stack(uptr addr,uptr * trace,uptr size,u32 * thread_id)131*7c3d14c8STreehugger Robot uptr __asan_get_free_stack(uptr addr, uptr *trace, uptr size, u32 *thread_id) {
132*7c3d14c8STreehugger Robot return AsanGetStack(addr, trace, size, thread_id, /* alloc_stack */ false);
133*7c3d14c8STreehugger Robot }
134*7c3d14c8STreehugger Robot
135*7c3d14c8STreehugger Robot SANITIZER_INTERFACE_ATTRIBUTE
__asan_get_shadow_mapping(uptr * shadow_scale,uptr * shadow_offset)136*7c3d14c8STreehugger Robot void __asan_get_shadow_mapping(uptr *shadow_scale, uptr *shadow_offset) {
137*7c3d14c8STreehugger Robot if (shadow_scale)
138*7c3d14c8STreehugger Robot *shadow_scale = SHADOW_SCALE;
139*7c3d14c8STreehugger Robot if (shadow_offset)
140*7c3d14c8STreehugger Robot *shadow_offset = SHADOW_OFFSET;
141*7c3d14c8STreehugger Robot }
142