1//===-asan_abi_shim.cpp - ASan Stable ABI Shim-----------------------------===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8
9#include "../asan/asan_interface_internal.h"
10#include "asan_abi.h"
11#include <assert.h>
12
13extern "C" {
14// Functions concerning instrumented global variables
15void __asan_register_image_globals(uptr *flag) {
16 __asan_abi_register_image_globals();
17}
18void __asan_unregister_image_globals(uptr *flag) {
19 __asan_abi_unregister_image_globals();
20}
21void __asan_register_elf_globals(uptr *flag, void *start, void *stop) {
22 bool bFlag = *flag;
23 __asan_abi_register_elf_globals(flag: &bFlag, start, stop);
24 *flag = bFlag;
25}
26void __asan_unregister_elf_globals(uptr *flag, void *start, void *stop) {
27 bool bFlag = *flag;
28 __asan_abi_unregister_elf_globals(flag: &bFlag, start, stop);
29 *flag = bFlag;
30}
31void __asan_register_globals(__asan_global *globals, uptr n) {
32 __asan_abi_register_globals(globals, n);
33}
34void __asan_unregister_globals(__asan_global *globals, uptr n) {
35 __asan_abi_unregister_globals(globals, n);
36}
37
38// Functions concerning dynamic library initialization
39void __asan_before_dynamic_init(const char *module_name) {
40 __asan_abi_before_dynamic_init(module_name);
41}
42void __asan_after_dynamic_init(void) { __asan_abi_after_dynamic_init(); }
43
44// Functions concerning block memory destinations
45void *__asan_memcpy(void *dst, const void *src, uptr size) {
46 return __asan_abi_memcpy(d: dst, s: src, n: size);
47}
48void *__asan_memset(void *s, int c, uptr n) {
49 return __asan_abi_memset(p: s, c, n);
50}
51void *__asan_memmove(void *dest, const void *src, uptr n) {
52 return __asan_abi_memmove(d: dest, s: src, n);
53}
54
55// Functions concerning RTL startup and initialization
56void __asan_init(void) {
57 static_assert(sizeof(uptr) == 8 || sizeof(uptr) == 4);
58 static_assert(sizeof(u64) == 8);
59 static_assert(sizeof(u32) == 4);
60
61 __asan_abi_init();
62}
63
64void __asan_handle_no_return(void) { __asan_abi_handle_no_return(); }
65
66// Variables concerning RTL state. These provisionally exist for completeness
67// but will likely move into the Stable ABI implementation and not in the shim.
68uptr __asan_shadow_memory_dynamic_address = (uptr)0L;
69int __asan_option_detect_stack_use_after_return = 1;
70
71// Functions concerning memory load and store reporting
72void __asan_report_load1(uptr addr) {
73 __asan_abi_report_load_n(p: (void *)addr, n: 1, abort: true);
74}
75void __asan_report_load2(uptr addr) {
76 __asan_abi_report_load_n(p: (void *)addr, n: 2, abort: true);
77}
78void __asan_report_load4(uptr addr) {
79 __asan_abi_report_load_n(p: (void *)addr, n: 4, abort: true);
80}
81void __asan_report_load8(uptr addr) {
82 __asan_abi_report_load_n(p: (void *)addr, n: 8, abort: true);
83}
84void __asan_report_load16(uptr addr) {
85 __asan_abi_report_load_n(p: (void *)addr, n: 16, abort: true);
86}
87void __asan_report_load_n(uptr addr, uptr size) {
88 __asan_abi_report_load_n(p: (void *)addr, n: size, abort: true);
89}
90void __asan_report_store1(uptr addr) {
91 __asan_abi_report_store_n(p: (void *)addr, n: 1, abort: true);
92}
93void __asan_report_store2(uptr addr) {
94 __asan_abi_report_store_n(p: (void *)addr, n: 2, abort: true);
95}
96void __asan_report_store4(uptr addr) {
97 __asan_abi_report_store_n(p: (void *)addr, n: 4, abort: true);
98}
99void __asan_report_store8(uptr addr) {
100 __asan_abi_report_store_n(p: (void *)addr, n: 8, abort: true);
101}
102void __asan_report_store16(uptr addr) {
103 __asan_abi_report_store_n(p: (void *)addr, n: 16, abort: true);
104}
105void __asan_report_store_n(uptr addr, uptr size) {
106 __asan_abi_report_store_n(p: (void *)addr, n: size, abort: true);
107}
108
109// Functions concerning memory load and store reporting (experimental variants)
110void __asan_report_exp_load1(uptr addr, u32 exp) {
111 __asan_abi_report_exp_load_n(p: (void *)addr, n: exp, exp: 1, abort: true);
112}
113void __asan_report_exp_load2(uptr addr, u32 exp) {
114 __asan_abi_report_exp_load_n(p: (void *)addr, n: exp, exp: 2, abort: true);
115}
116void __asan_report_exp_load4(uptr addr, u32 exp) {
117 __asan_abi_report_exp_load_n(p: (void *)addr, n: exp, exp: 4, abort: true);
118}
119void __asan_report_exp_load8(uptr addr, u32 exp) {
120 __asan_abi_report_exp_load_n(p: (void *)addr, n: exp, exp: 8, abort: true);
121}
122void __asan_report_exp_load16(uptr addr, u32 exp) {
123 __asan_abi_report_exp_load_n(p: (void *)addr, n: exp, exp: 16, abort: true);
124}
125void __asan_report_exp_load_n(uptr addr, uptr size, u32 exp) {
126 __asan_abi_report_exp_load_n(p: (void *)addr, n: size, exp, abort: true);
127}
128void __asan_report_exp_store1(uptr addr, u32 exp) {
129 __asan_abi_report_exp_store_n(p: (void *)addr, n: exp, exp: 1, abort: true);
130}
131void __asan_report_exp_store2(uptr addr, u32 exp) {
132 __asan_abi_report_exp_store_n(p: (void *)addr, n: exp, exp: 2, abort: true);
133}
134void __asan_report_exp_store4(uptr addr, u32 exp) {
135 __asan_abi_report_exp_store_n(p: (void *)addr, n: exp, exp: 4, abort: true);
136}
137void __asan_report_exp_store8(uptr addr, u32 exp) {
138 __asan_abi_report_exp_store_n(p: (void *)addr, n: exp, exp: 8, abort: true);
139}
140void __asan_report_exp_store16(uptr addr, u32 exp) {
141 __asan_abi_report_exp_store_n(p: (void *)addr, n: exp, exp: 16, abort: true);
142}
143void __asan_report_exp_store_n(uptr addr, uptr size, u32 exp) {
144 __asan_abi_report_exp_store_n(p: (void *)addr, n: size, exp, abort: true);
145}
146
147// Functions concerning memory load and store reporting (noabort variants)
148void __asan_report_load1_noabort(uptr addr) {
149 __asan_abi_report_load_n(p: (void *)addr, n: 1, abort: false);
150}
151void __asan_report_load2_noabort(uptr addr) {
152 __asan_abi_report_load_n(p: (void *)addr, n: 2, abort: false);
153}
154void __asan_report_load4_noabort(uptr addr) {
155 __asan_abi_report_load_n(p: (void *)addr, n: 4, abort: false);
156}
157void __asan_report_load8_noabort(uptr addr) {
158 __asan_abi_report_load_n(p: (void *)addr, n: 8, abort: false);
159}
160void __asan_report_load16_noabort(uptr addr) {
161 __asan_abi_report_load_n(p: (void *)addr, n: 16, abort: false);
162}
163void __asan_report_load_n_noabort(uptr addr, uptr size) {
164 __asan_abi_report_load_n(p: (void *)addr, n: size, abort: false);
165}
166void __asan_report_store1_noabort(uptr addr) {
167 __asan_abi_report_store_n(p: (void *)addr, n: 1, abort: false);
168}
169void __asan_report_store2_noabort(uptr addr) {
170 __asan_abi_report_store_n(p: (void *)addr, n: 2, abort: false);
171}
172void __asan_report_store4_noabort(uptr addr) {
173 __asan_abi_report_store_n(p: (void *)addr, n: 4, abort: false);
174}
175void __asan_report_store8_noabort(uptr addr) {
176 __asan_abi_report_store_n(p: (void *)addr, n: 8, abort: false);
177}
178void __asan_report_store16_noabort(uptr addr) {
179 __asan_abi_report_store_n(p: (void *)addr, n: 16, abort: false);
180}
181void __asan_report_store_n_noabort(uptr addr, uptr size) {
182 __asan_abi_report_store_n(p: (void *)addr, n: size, abort: false);
183}
184
185// Functions concerning memory load and store
186void __asan_load1(uptr addr) { __asan_abi_load_n(p: (void *)addr, n: 1, abort: true); }
187void __asan_load2(uptr addr) { __asan_abi_load_n(p: (void *)addr, n: 2, abort: true); }
188void __asan_load4(uptr addr) { __asan_abi_load_n(p: (void *)addr, n: 4, abort: true); }
189void __asan_load8(uptr addr) { __asan_abi_load_n(p: (void *)addr, n: 8, abort: true); }
190void __asan_load16(uptr addr) { __asan_abi_load_n(p: (void *)addr, n: 16, abort: true); }
191void __asan_loadN(uptr addr, uptr size) {
192 __asan_abi_load_n(p: (void *)addr, n: size, abort: true);
193}
194void __asan_store1(uptr addr) { __asan_abi_store_n(p: (void *)addr, n: 1, abort: true); }
195void __asan_store2(uptr addr) { __asan_abi_store_n(p: (void *)addr, n: 2, abort: true); }
196void __asan_store4(uptr addr) { __asan_abi_store_n(p: (void *)addr, n: 4, abort: true); }
197void __asan_store8(uptr addr) { __asan_abi_store_n(p: (void *)addr, n: 8, abort: true); }
198void __asan_store16(uptr addr) { __asan_abi_store_n(p: (void *)addr, n: 16, abort: true); }
199void __asan_storeN(uptr addr, uptr size) {
200 __asan_abi_store_n(p: (void *)addr, n: size, abort: true);
201}
202
203// Functions concerning memory load and store (experimental variants)
204void __asan_exp_load1(uptr addr, u32 exp) {
205 __asan_abi_exp_load_n(p: (void *)addr, n: 1, exp, abort: true);
206}
207void __asan_exp_load2(uptr addr, u32 exp) {
208 __asan_abi_exp_load_n(p: (void *)addr, n: 2, exp, abort: true);
209}
210void __asan_exp_load4(uptr addr, u32 exp) {
211 __asan_abi_exp_load_n(p: (void *)addr, n: 4, exp, abort: true);
212}
213void __asan_exp_load8(uptr addr, u32 exp) {
214 __asan_abi_exp_load_n(p: (void *)addr, n: 8, exp, abort: true);
215}
216void __asan_exp_load16(uptr addr, u32 exp) {
217 __asan_abi_exp_load_n(p: (void *)addr, n: 16, exp, abort: true);
218}
219void __asan_exp_loadN(uptr addr, uptr size, u32 exp) {
220 __asan_abi_exp_load_n(p: (void *)addr, n: size, exp, abort: true);
221}
222void __asan_exp_store1(uptr addr, u32 exp) {
223 __asan_abi_exp_store_n(p: (void *)addr, n: 1, exp, abort: true);
224}
225void __asan_exp_store2(uptr addr, u32 exp) {
226 __asan_abi_exp_store_n(p: (void *)addr, n: 2, exp, abort: true);
227}
228void __asan_exp_store4(uptr addr, u32 exp) {
229 __asan_abi_exp_store_n(p: (void *)addr, n: 4, exp, abort: true);
230}
231void __asan_exp_store8(uptr addr, u32 exp) {
232 __asan_abi_exp_store_n(p: (void *)addr, n: 8, exp, abort: true);
233}
234void __asan_exp_store16(uptr addr, u32 exp) {
235 __asan_abi_exp_store_n(p: (void *)addr, n: 16, exp, abort: true);
236}
237void __asan_exp_storeN(uptr addr, uptr size, u32 exp) {
238 __asan_abi_exp_store_n(p: (void *)addr, n: size, exp, abort: true);
239}
240
241// Functions concerning memory load and store (noabort variants)
242void __asan_load1_noabort(uptr addr) {
243 __asan_abi_load_n(p: (void *)addr, n: 1, abort: false);
244}
245void __asan_load2_noabort(uptr addr) {
246 __asan_abi_load_n(p: (void *)addr, n: 2, abort: false);
247}
248void __asan_load4_noabort(uptr addr) {
249 __asan_abi_load_n(p: (void *)addr, n: 4, abort: false);
250}
251void __asan_load8_noabort(uptr addr) {
252 __asan_abi_load_n(p: (void *)addr, n: 8, abort: false);
253}
254void __asan_load16_noabort(uptr addr) {
255 __asan_abi_load_n(p: (void *)addr, n: 16, abort: false);
256}
257void __asan_loadN_noabort(uptr addr, uptr size) {
258 __asan_abi_load_n(p: (void *)addr, n: size, abort: false);
259}
260void __asan_store1_noabort(uptr addr) {
261 __asan_abi_store_n(p: (void *)addr, n: 1, abort: false);
262}
263void __asan_store2_noabort(uptr addr) {
264 __asan_abi_store_n(p: (void *)addr, n: 2, abort: false);
265}
266void __asan_store4_noabort(uptr addr) {
267 __asan_abi_store_n(p: (void *)addr, n: 4, abort: false);
268}
269void __asan_store8_noabort(uptr addr) {
270 __asan_abi_store_n(p: (void *)addr, n: 8, abort: false);
271}
272void __asan_store16_noabort(uptr addr) {
273 __asan_abi_store_n(p: (void *)addr, n: 16, abort: false);
274}
275void __asan_storeN_noabort(uptr addr, uptr size) {
276 __asan_abi_store_n(p: (void *)addr, n: size, abort: false);
277}
278
279// Functions concerning query about whether memory is poisoned
280int __asan_address_is_poisoned(void const volatile *addr) {
281 return __asan_abi_address_is_poisoned(p: addr);
282}
283uptr __asan_region_is_poisoned(uptr beg, uptr size) {
284 return (uptr)__asan_abi_region_is_poisoned(p: (void *)beg, size);
285}
286
287// Functions concerning the poisoning of memory
288void __asan_poison_memory_region(void const volatile *addr, uptr size) {
289 __asan_abi_poison_memory_region(p: addr, n: size);
290}
291void __asan_unpoison_memory_region(void const volatile *addr, uptr size) {
292 __asan_abi_unpoison_memory_region(p: addr, n: size);
293}
294
295// Functions concerning the partial poisoning of memory
296void __asan_set_shadow_00(uptr addr, uptr size) {
297 __asan_abi_set_shadow_xx_n(p: (void *)addr, xx: 0x00, n: size);
298}
299void __asan_set_shadow_01(uptr addr, uptr size) {
300 __asan_abi_set_shadow_xx_n(p: (void *)addr, xx: 0x01, n: size);
301}
302void __asan_set_shadow_02(uptr addr, uptr size) {
303 __asan_abi_set_shadow_xx_n(p: (void *)addr, xx: 0x02, n: size);
304}
305void __asan_set_shadow_03(uptr addr, uptr size) {
306 __asan_abi_set_shadow_xx_n(p: (void *)addr, xx: 0x03, n: size);
307}
308void __asan_set_shadow_04(uptr addr, uptr size) {
309 __asan_abi_set_shadow_xx_n(p: (void *)addr, xx: 0x04, n: size);
310}
311void __asan_set_shadow_05(uptr addr, uptr size) {
312 __asan_abi_set_shadow_xx_n(p: (void *)addr, xx: 0x05, n: size);
313}
314void __asan_set_shadow_06(uptr addr, uptr size) {
315 __asan_abi_set_shadow_xx_n(p: (void *)addr, xx: 0x06, n: size);
316}
317void __asan_set_shadow_07(uptr addr, uptr size) {
318 __asan_abi_set_shadow_xx_n(p: (void *)addr, xx: 0x07, n: size);
319}
320void __asan_set_shadow_f1(uptr addr, uptr size) {
321 __asan_abi_set_shadow_xx_n(p: (void *)addr, xx: 0xf1, n: size);
322}
323void __asan_set_shadow_f2(uptr addr, uptr size) {
324 __asan_abi_set_shadow_xx_n(p: (void *)addr, xx: 0xf2, n: size);
325}
326void __asan_set_shadow_f3(uptr addr, uptr size) {
327 __asan_abi_set_shadow_xx_n(p: (void *)addr, xx: 0xf3, n: size);
328}
329void __asan_set_shadow_f5(uptr addr, uptr size) {
330 __asan_abi_set_shadow_xx_n(p: (void *)addr, xx: 0xf5, n: size);
331}
332void __asan_set_shadow_f8(uptr addr, uptr size) {
333 __asan_abi_set_shadow_xx_n(p: (void *)addr, xx: 0xf8, n: size);
334}
335
336// Functions concerning stack poisoning
337void __asan_poison_stack_memory(uptr addr, uptr size) {
338 __asan_abi_poison_stack_memory(p: (void *)addr, n: size);
339}
340void __asan_unpoison_stack_memory(uptr addr, uptr size) {
341 __asan_abi_unpoison_stack_memory(p: (void *)addr, n: size);
342}
343
344// Functions concerning redzone poisoning
345void __asan_poison_intra_object_redzone(uptr p, uptr size) {
346 __asan_abi_poison_intra_object_redzone(p: (void *)p, size);
347}
348void __asan_unpoison_intra_object_redzone(uptr p, uptr size) {
349 __asan_abi_unpoison_intra_object_redzone(p: (void *)p, size);
350}
351
352// Functions concerning array cookie poisoning
353void __asan_poison_cxx_array_cookie(uptr p) {
354 __asan_abi_poison_cxx_array_cookie(p: (void *)p);
355}
356uptr __asan_load_cxx_array_cookie(uptr *p) {
357 return (uptr)__asan_abi_load_cxx_array_cookie(p: (void **)p);
358}
359
360// Functions concerning fake stacks
361void *__asan_get_current_fake_stack(void) {
362 return __asan_abi_get_current_fake_stack();
363}
364void *__asan_addr_is_in_fake_stack(void *fake_stack, void *addr, void **beg,
365 void **end) {
366 return __asan_abi_addr_is_in_fake_stack(fake_stack, addr, beg, end);
367}
368
369// Functions concerning poisoning and unpoisoning fake stack alloca
370void __asan_alloca_poison(uptr addr, uptr size) {
371 __asan_abi_alloca_poison(addr: (void *)addr, size);
372}
373void __asan_allocas_unpoison(uptr top, uptr bottom) {
374 __asan_abi_allocas_unpoison(top: (void *)top, bottom: (void *)bottom);
375}
376
377// Functions concerning fake stack malloc
378uptr __asan_stack_malloc_0(uptr size) {
379 return (uptr)__asan_abi_stack_malloc_n(scale: 0, size);
380}
381uptr __asan_stack_malloc_1(uptr size) {
382 return (uptr)__asan_abi_stack_malloc_n(scale: 1, size);
383}
384uptr __asan_stack_malloc_2(uptr size) {
385 return (uptr)__asan_abi_stack_malloc_n(scale: 2, size);
386}
387uptr __asan_stack_malloc_3(uptr size) {
388 return (uptr)__asan_abi_stack_malloc_n(scale: 3, size);
389}
390uptr __asan_stack_malloc_4(uptr size) {
391 return (uptr)__asan_abi_stack_malloc_n(scale: 4, size);
392}
393uptr __asan_stack_malloc_5(uptr size) {
394 return (uptr)__asan_abi_stack_malloc_n(scale: 5, size);
395}
396uptr __asan_stack_malloc_6(uptr size) {
397 return (uptr)__asan_abi_stack_malloc_n(scale: 6, size);
398}
399uptr __asan_stack_malloc_7(uptr size) {
400 return (uptr)__asan_abi_stack_malloc_n(scale: 7, size);
401}
402uptr __asan_stack_malloc_8(uptr size) {
403 return (uptr)__asan_abi_stack_malloc_n(scale: 8, size);
404}
405uptr __asan_stack_malloc_9(uptr size) {
406 return (uptr)__asan_abi_stack_malloc_n(scale: 9, size);
407}
408uptr __asan_stack_malloc_10(uptr size) {
409 return (uptr)__asan_abi_stack_malloc_n(scale: 10, size);
410}
411
412// Functions concerning fake stack malloc (always variants)
413uptr __asan_stack_malloc_always_0(uptr size) {
414 return (uptr)__asan_abi_stack_malloc_always_n(scale: 0, size);
415}
416uptr __asan_stack_malloc_always_1(uptr size) {
417 return (uptr)__asan_abi_stack_malloc_always_n(scale: 1, size);
418}
419uptr __asan_stack_malloc_always_2(uptr size) {
420 return (uptr)__asan_abi_stack_malloc_always_n(scale: 2, size);
421}
422uptr __asan_stack_malloc_always_3(uptr size) {
423 return (uptr)__asan_abi_stack_malloc_always_n(scale: 3, size);
424}
425uptr __asan_stack_malloc_always_4(uptr size) {
426 return (uptr)__asan_abi_stack_malloc_always_n(scale: 4, size);
427}
428uptr __asan_stack_malloc_always_5(uptr size) {
429 return (uptr)__asan_abi_stack_malloc_always_n(scale: 5, size);
430}
431uptr __asan_stack_malloc_always_6(uptr size) {
432 return (uptr)__asan_abi_stack_malloc_always_n(scale: 6, size);
433}
434uptr __asan_stack_malloc_always_7(uptr size) {
435 return (uptr)__asan_abi_stack_malloc_always_n(scale: 7, size);
436}
437uptr __asan_stack_malloc_always_8(uptr size) {
438 return (uptr)__asan_abi_stack_malloc_always_n(scale: 8, size);
439}
440uptr __asan_stack_malloc_always_9(uptr size) {
441 return (uptr)__asan_abi_stack_malloc_always_n(scale: 9, size);
442}
443uptr __asan_stack_malloc_always_10(uptr size) {
444 return (uptr)__asan_abi_stack_malloc_always_n(scale: 10, size);
445}
446
447// Functions concerning fake stack free
448void __asan_stack_free_0(uptr ptr, uptr size) {
449 __asan_abi_stack_free_n(scale: 0, p: (void *)ptr, n: size);
450}
451void __asan_stack_free_1(uptr ptr, uptr size) {
452 __asan_abi_stack_free_n(scale: 1, p: (void *)ptr, n: size);
453}
454void __asan_stack_free_2(uptr ptr, uptr size) {
455 __asan_abi_stack_free_n(scale: 2, p: (void *)ptr, n: size);
456}
457void __asan_stack_free_3(uptr ptr, uptr size) {
458 __asan_abi_stack_free_n(scale: 3, p: (void *)ptr, n: size);
459}
460void __asan_stack_free_4(uptr ptr, uptr size) {
461 __asan_abi_stack_free_n(scale: 4, p: (void *)ptr, n: size);
462}
463void __asan_stack_free_5(uptr ptr, uptr size) {
464 __asan_abi_stack_free_n(scale: 5, p: (void *)ptr, n: size);
465}
466void __asan_stack_free_6(uptr ptr, uptr size) {
467 __asan_abi_stack_free_n(scale: 6, p: (void *)ptr, n: size);
468}
469void __asan_stack_free_7(uptr ptr, uptr size) {
470 __asan_abi_stack_free_n(scale: 7, p: (void *)ptr, n: size);
471}
472void __asan_stack_free_8(uptr ptr, uptr size) {
473 __asan_abi_stack_free_n(scale: 8, p: (void *)ptr, n: size);
474}
475void __asan_stack_free_9(uptr ptr, uptr size) {
476 __asan_abi_stack_free_n(scale: 9, p: (void *)ptr, n: size);
477}
478void __asan_stack_free_10(uptr ptr, uptr size) {
479 __asan_abi_stack_free_n(scale: 10, p: (void *)ptr, n: size);
480}
481}
482

source code of compiler-rt/lib/asan_abi/asan_abi_shim.cpp