/** * Helpers for determining TLS memory ranges on OS X. * * This unfortunately cannot be entirely done in D, as the OS X API uses * the Apple-specific blocks C extension. * * Copyright: David Nadlinger, 2012. * License: Boost License 1.0. * Authors: David Nadlinger */ #ifndef __APPLE__ #ifndef __BLOCKS__ #error "Need a C compiler with Apple Blocks support – not building on OS X with Clang?" #endif #endif #include #include #include /* * Declarations from dyld_priv.h, available on 10.7+. */ enum dyld_tlv_states { dyld_tlv_state_allocated = 10, dyld_tlv_state_deallocated = 20 }; typedef struct { size_t info_size; void * tlv_addr; size_t tlv_size; } dyld_tlv_info; typedef void (^dyld_tlv_state_change_handler)(enum dyld_tlv_states state, const dyld_tlv_info *info); extern void dyld_register_tlv_state_change_handler(enum dyld_tlv_states state, dyld_tlv_state_change_handler handler); extern void dyld_enumerate_tlv_storage(dyld_tlv_state_change_handler handler); void _d_dyld_getTLSRange(void* arbitraryTLSSymbol, void** start, size_t* size) { dyld_enumerate_tlv_storage( ^(enum dyld_tlv_states state, const dyld_tlv_info *info) { assert(state == dyld_tlv_state_allocated); if (info->tlv_addr <= arbitraryTLSSymbol && arbitraryTLSSymbol < (info->tlv_addr + info->tlv_size) ) { // Found the range. *start = info->tlv_addr; *size = info->tlv_size; } } ); }