diff --git a/common/include/asan.h b/common/include/asan.h index 217baba2f1..352cfc0f4a 100644 --- a/common/include/asan.h +++ b/common/include/asan.h @@ -255,6 +255,9 @@ void __asan_register_globals(struct __asan_global* globals, size_t n); * implementation does nothing (and we don't even handle `.fini_array`). */ void __asan_unregister_globals(struct __asan_global* globals, size_t n); +void __asan_register_elf_globals(uintptr_t* flag, void* start, void* stop); +void __asan_unregister_elf_globals(uintptr_t* flag, void* start, void* stop); + /* Callbacks for setting the shadow memory to specific values. As with load/store callbacks, LLVM * normally generates inline stores and calls these functions only for bigger areas. This is * controlled by `-mllvm -asan-max-inline-poisoning-size=N`. */ diff --git a/common/src/asan.c b/common/src/asan.c index 561771750b..448822adca 100644 --- a/common/src/asan.c +++ b/common/src/asan.c @@ -359,6 +359,28 @@ void __asan_unregister_globals(struct __asan_global* globals, size_t n) { __UNUSED(n); } +void __asan_register_elf_globals(uintptr_t* flag, void* start, void* stop) { + if (*flag || start == stop) + return; + + assert(IS_ALIGNED((uintptr_t)stop - (uintptr_t)start, sizeof(struct __asan_global))); + struct __asan_global* globals_start = start; + struct __asan_global* globals_stop = stop; + __asan_register_globals(globals_start, globals_stop - globals_start); + *flag = 1; +} + +void __asan_unregister_elf_globals(uintptr_t* flag, void* start, void* stop) { + if (!*flag || start == stop) + return; + + assert(IS_ALIGNED((uintptr_t)stop - (uintptr_t)start, sizeof(struct __asan_global))); + struct __asan_global* globals_start = start; + struct __asan_global* globals_stop = stop; + __asan_unregister_globals(globals_start, globals_stop - globals_start); + *flag = 0; +} + #define DEFINE_ASAN_SET_SHADOW(name, value) \ __attribute__((noinline)) \ void __asan_set_shadow_ ## name (uintptr_t addr, size_t size) { \