xref: /aosp_15_r20/external/compiler-rt/lib/asan/asan_debugging.cc (revision 7c3d14c8b49c529e04be81a3ce6f5cc23712e4c6)
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