Index: lib/asan/asan_globals.cc =================================================================== --- lib/asan/asan_globals.cc +++ lib/asan/asan_globals.cc @@ -212,6 +212,13 @@ // ---------------------- Interface ---------------- {{{1 using namespace __asan; // NOLINT + +// Apply __asan_(un)register_globals to all globals found in the same loaded +// shared object as `needle'. This implementation is platform-specific. +void __asan_apply_to_globals(globals_op_fptr op, void *needle) { + AsanApplyToGlobals(op, needle); +} + // Register an array of globals. void __asan_register_globals(__asan_global *globals, uptr n) { if (!flags()->report_globals) return; Index: lib/asan/asan_interface_internal.h =================================================================== --- lib/asan/asan_interface_internal.h +++ lib/asan/asan_interface_internal.h @@ -56,6 +56,13 @@ // or NULL if it is unknown. }; + // This function can be called on some platforms to find globals in the same + // loaded shared object as `needle' and apply __asan_(un)register_globals + // to them. + typedef void (*globals_op_fptr)(__asan_global *, uptr); + SANITIZER_INTERFACE_ATTRIBUTE + void __asan_apply_to_globals(globals_op_fptr op, void *needle); + // These two functions should be called by the instrumented code. // 'globals' is an array of structures describing 'n' globals. SANITIZER_INTERFACE_ATTRIBUTE Index: lib/asan/asan_internal.h =================================================================== --- lib/asan/asan_internal.h +++ lib/asan/asan_internal.h @@ -78,6 +78,7 @@ void *AsanDoesNotSupportStaticLinkage(); void AsanCheckDynamicRTPrereqs(); void AsanCheckIncompatibleRT(); +void AsanApplyToGlobals(globals_op_fptr op, void *needle); void AsanOnDeadlySignal(int, void *siginfo, void *context); Index: lib/asan/asan_linux.cc =================================================================== --- lib/asan/asan_linux.cc +++ lib/asan/asan_linux.cc @@ -75,6 +75,10 @@ return &_DYNAMIC; // defined in link.h } +void AsanApplyToGlobals(globals_op_fptr op, void *needle) { + UNIMPLEMENTED(); +} + #if SANITIZER_ANDROID // FIXME: should we do anything for Android? void AsanCheckDynamicRTPrereqs() {} Index: lib/asan/asan_mac.cc =================================================================== --- lib/asan/asan_mac.cc +++ lib/asan/asan_mac.cc @@ -24,9 +24,11 @@ #include "sanitizer_common/sanitizer_libc.h" #include "sanitizer_common/sanitizer_mac.h" +#include #include #include #include +#include #include #include #include // for free() @@ -66,6 +68,30 @@ // No-op. Mac does not support static linkage anyway. void AsanCheckIncompatibleRT() {} +void AsanApplyToGlobals(globals_op_fptr op, void *needle) { + // Find the Mach-O header for the image containing the needle + Dl_info info; + int err = dladdr(needle, &info); + if (err == 0) return; + +#if __LP64__ + const struct mach_header_64 *mh = (struct mach_header_64 *)info.dli_fbase; +#else + const struct mach_header *mh = (struct mach_header *)info.dli_fbase; +#endif + + // Look up the __asan_globals section in that image and register its globals + unsigned long size = 0; + __asan_global *globals = (__asan_global *)getsectiondata( + mh, + "__DATA", "__asan_globals", + &size); + + if (!globals) return; + if (size % sizeof(__asan_global) != 0) return; + op(globals, size / sizeof(__asan_global)); +} + void ReadContextStack(void *context, uptr *stack, uptr *ssize) { UNIMPLEMENTED(); } Index: lib/asan/asan_win.cc =================================================================== --- lib/asan/asan_win.cc +++ lib/asan/asan_win.cc @@ -149,6 +149,10 @@ (uptr *)&REAL(NtWaitForWorkViaWorkerFactory))); } +void AsanApplyToGlobals(globals_op_fptr op, void *needle) { + UNIMPLEMENTED(); +} + // ---------------------- TSD ---------------- {{{ static bool tsd_key_inited = false;