1 | // Checks the ASan memory address type debugging API, makes sure it returns |
2 | // the correct memory type for heap, stack, global and shadow addresses and |
3 | // that it correctly finds out which region (and name and size) the address |
4 | // belongs to. |
5 | // RUN: %clangxx_asan -O0 %s -o %t && %run %t 2>&1 |
6 | |
7 | #include <assert.h> |
8 | #include <sanitizer/asan_interface.h> |
9 | #include <stdio.h> |
10 | #include <stdlib.h> |
11 | #include <string.h> |
12 | |
13 | int global_var; |
14 | |
15 | int main() { |
16 | int local_var; |
17 | char *heap_ptr = (char *)malloc(size: 10); |
18 | |
19 | char name[100]; |
20 | void *region_address; |
21 | size_t region_size; |
22 | const char *type; |
23 | |
24 | type = __asan_locate_address(addr: &global_var, name, name_size: 100, |
25 | region_address: ®ion_address, region_size: ®ion_size); |
26 | assert(nullptr != strstr(name, "global_var" )); |
27 | assert(0 == strcmp(type, "global" )); |
28 | assert(region_address == &global_var); |
29 | assert(region_size == sizeof(global_var)); |
30 | |
31 | type = __asan_locate_address(addr: (char *)(&global_var)+1, name, name_size: 100, |
32 | region_address: ®ion_address, region_size: ®ion_size); |
33 | assert(nullptr != strstr(name, "global_var" )); |
34 | assert(0 == strcmp(type, "global" )); |
35 | assert(region_address == &global_var); |
36 | assert(region_size == sizeof(global_var)); |
37 | |
38 | type = __asan_locate_address(addr: &local_var, name, name_size: 100, |
39 | region_address: ®ion_address, region_size: ®ion_size); |
40 | assert(0 == strcmp(name, "local_var" )); |
41 | assert(0 == strcmp(type, "stack" )); |
42 | assert(region_address == &local_var); |
43 | assert(region_size == sizeof(local_var)); |
44 | |
45 | type = __asan_locate_address(addr: (char *)(&local_var)+1, name, name_size: 100, |
46 | region_address: ®ion_address, region_size: ®ion_size); |
47 | assert(0 == strcmp(name, "local_var" )); |
48 | assert(0 == strcmp(type, "stack" )); |
49 | assert(region_address == &local_var); |
50 | assert(region_size == sizeof(local_var)); |
51 | |
52 | type = __asan_locate_address(addr: heap_ptr, name, name_size: 100, |
53 | region_address: ®ion_address, region_size: ®ion_size); |
54 | assert(0 == strcmp(type, "heap" )); |
55 | assert(region_address == heap_ptr); |
56 | assert(10 == region_size); |
57 | |
58 | type = __asan_locate_address(addr: heap_ptr+1, name, name_size: 100, |
59 | region_address: ®ion_address, region_size: ®ion_size); |
60 | assert(0 == strcmp(type, "heap" )); |
61 | assert(region_address == heap_ptr); |
62 | assert(10 == region_size); |
63 | |
64 | size_t shadow_scale; |
65 | size_t shadow_offset; |
66 | __asan_get_shadow_mapping(shadow_scale: &shadow_scale, shadow_offset: &shadow_offset); |
67 | |
68 | uintptr_t shadow_ptr = (((uintptr_t)heap_ptr) >> shadow_scale) |
69 | + shadow_offset; |
70 | type = __asan_locate_address(addr: (void *)shadow_ptr, NULL, name_size: 0, NULL, NULL); |
71 | assert((0 == strcmp(type, "high shadow" )) || 0 == strcmp(type, "low shadow" )); |
72 | |
73 | uintptr_t shadow_gap = (shadow_ptr >> shadow_scale) + shadow_offset; |
74 | type = __asan_locate_address(addr: (void *)shadow_gap, NULL, name_size: 0, NULL, NULL); |
75 | assert(0 == strcmp(type, "shadow gap" )); |
76 | |
77 | free(ptr: heap_ptr); |
78 | |
79 | return 0; |
80 | } |
81 | |