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