Reputation: 23500
Is there a way to detect if the code being compiled is in a Framework, a Bundle, or a Dynamic Library?
The reason is because of a crash reporter library that needs to know if a struct variable exists before taking the address of it..
IE:
#ifdef MH_EXECUTE_SYM
return (uint8_t*)&_mh_execute_header;
#else
return (uint8_t*)&_mh_dylib_header;
#endif
The problem is that MH_EXECUTE_SYM
, MH_BUNDLE_SYM
, MH_DYLIB_SYM
is always defined for every kind of executable, bundle, framework..
So I need a way of determining which struct variable to take the address of.. Any ideas?
Upvotes: 3
Views: 328
Reputation: 385500
It looks like you really just want to get a pointer to the appropriate mach_header_64
(or mach_header
on 32-bit systems).
If you have a pointer, you can use the dladdr
function to find out which (if any) mach-o it was loaded from. That function fills in a Dl_info
structure which includes, amongst other things, a pointer to the mach_header_64
for the mach-o.
// For TARGET_RT_64_BIT:
#import <TargetConditionals.h>
// For dladdr:
#import <dlfcn.h>
// For mach_header and mach_header_64:
#import <mach-o/loader.h>
#ifdef TARGET_RT_64_BIT
struct mach_header_64 *mach_header_for_address(const void *address) {
Dl_info info;
if (dladdr(address, &info) == 0) {
// address doesn't point into a mach-o.
return 0;
}
struct mach_header_64 *header = (struct mach_header_64 *)info.dli_fbase;
if (header->magic != MH_MAGIC_64) {
// Something went wrong...
return 0;
}
return header;
}
#else
struct mach_header mach_header_for_address(const void *address) {
Dl_info info;
if (dladdr(address, &info) == 0) {
// address doesn't point into a mach-o.
return 0;
}
struct mach_header *header = (struct mach_header *)info.dli_fbase;
if (header->magic != MH_MAGIC) {
// Something went wrong...
return 0;
}
return header;
}
#endif
Upvotes: 3