1673dc3d4SNico Weber // Checks the ASan memory address type debugging API, makes sure it returns
2673dc3d4SNico Weber // the correct memory type for heap, stack, global and shadow addresses and
3673dc3d4SNico Weber // that it correctly finds out which region (and name and size) the address
4673dc3d4SNico Weber // belongs to.
5673dc3d4SNico Weber // RUN: %clangxx_asan -O0 %s -o %t && %run %t 2>&1
6673dc3d4SNico Weber 
7673dc3d4SNico Weber #include <assert.h>
8673dc3d4SNico Weber #include <sanitizer/asan_interface.h>
9673dc3d4SNico Weber #include <stdio.h>
10673dc3d4SNico Weber #include <stdlib.h>
11673dc3d4SNico Weber #include <string.h>
12673dc3d4SNico Weber 
13673dc3d4SNico Weber int global_var;
14673dc3d4SNico Weber 
main()15673dc3d4SNico Weber int main() {
16673dc3d4SNico Weber   int local_var;
17673dc3d4SNico Weber   char *heap_ptr = (char *)malloc(10);
18673dc3d4SNico Weber 
19673dc3d4SNico Weber   char name[100];
20673dc3d4SNico Weber   void *region_address;
21673dc3d4SNico Weber   size_t region_size;
22673dc3d4SNico Weber   const char *type;
23673dc3d4SNico Weber 
24673dc3d4SNico Weber   type = __asan_locate_address(&global_var, name, 100,
25673dc3d4SNico Weber                                &region_address, &region_size);
26*7b235527SMitch Phillips   assert(nullptr != strstr(name, "global_var"));
27673dc3d4SNico Weber   assert(0 == strcmp(type, "global"));
28673dc3d4SNico Weber   assert(region_address == &global_var);
29673dc3d4SNico Weber   assert(region_size == sizeof(global_var));
30673dc3d4SNico Weber 
31673dc3d4SNico Weber   type = __asan_locate_address((char *)(&global_var)+1, name, 100,
32673dc3d4SNico Weber                                &region_address, &region_size);
33*7b235527SMitch Phillips   assert(nullptr != strstr(name, "global_var"));
34673dc3d4SNico Weber   assert(0 == strcmp(type, "global"));
35673dc3d4SNico Weber   assert(region_address == &global_var);
36673dc3d4SNico Weber   assert(region_size == sizeof(global_var));
37673dc3d4SNico Weber 
38673dc3d4SNico Weber   type = __asan_locate_address(&local_var, name, 100,
39673dc3d4SNico Weber                                &region_address, &region_size);
40673dc3d4SNico Weber   assert(0 == strcmp(name, "local_var"));
41673dc3d4SNico Weber   assert(0 == strcmp(type, "stack"));
42673dc3d4SNico Weber   assert(region_address == &local_var);
43673dc3d4SNico Weber   assert(region_size == sizeof(local_var));
44673dc3d4SNico Weber 
45673dc3d4SNico Weber   type = __asan_locate_address((char *)(&local_var)+1, name, 100,
46673dc3d4SNico Weber                                &region_address, &region_size);
47673dc3d4SNico Weber   assert(0 == strcmp(name, "local_var"));
48673dc3d4SNico Weber   assert(0 == strcmp(type, "stack"));
49673dc3d4SNico Weber   assert(region_address == &local_var);
50673dc3d4SNico Weber   assert(region_size == sizeof(local_var));
51673dc3d4SNico Weber 
52673dc3d4SNico Weber   type = __asan_locate_address(heap_ptr, name, 100,
53673dc3d4SNico Weber                                &region_address, &region_size);
54673dc3d4SNico Weber   assert(0 == strcmp(type, "heap"));
55673dc3d4SNico Weber   assert(region_address == heap_ptr);
56673dc3d4SNico Weber   assert(10 == region_size);
57673dc3d4SNico Weber 
58673dc3d4SNico Weber   type = __asan_locate_address(heap_ptr+1, name, 100,
59673dc3d4SNico Weber                                &region_address, &region_size);
60673dc3d4SNico Weber   assert(0 == strcmp(type, "heap"));
61673dc3d4SNico Weber   assert(region_address == heap_ptr);
62673dc3d4SNico Weber   assert(10 == region_size);
63673dc3d4SNico Weber 
64673dc3d4SNico Weber   size_t shadow_scale;
65673dc3d4SNico Weber   size_t shadow_offset;
66673dc3d4SNico Weber   __asan_get_shadow_mapping(&shadow_scale, &shadow_offset);
67673dc3d4SNico Weber 
68673dc3d4SNico Weber   uintptr_t shadow_ptr = (((uintptr_t)heap_ptr) >> shadow_scale)
69673dc3d4SNico Weber                          + shadow_offset;
70673dc3d4SNico Weber   type = __asan_locate_address((void *)shadow_ptr, NULL, 0, NULL, NULL);
71673dc3d4SNico Weber   assert((0 == strcmp(type, "high shadow")) || 0 == strcmp(type, "low shadow"));
72673dc3d4SNico Weber 
73673dc3d4SNico Weber   uintptr_t shadow_gap = (shadow_ptr >> shadow_scale) + shadow_offset;
74673dc3d4SNico Weber   type = __asan_locate_address((void *)shadow_gap, NULL, 0, NULL, NULL);
75673dc3d4SNico Weber   assert(0 == strcmp(type, "shadow gap"));
76673dc3d4SNico Weber 
77673dc3d4SNico Weber   free(heap_ptr);
78673dc3d4SNico Weber 
79673dc3d4SNico Weber   return 0;
80673dc3d4SNico Weber }
81