#include <stdlib.h>
#include <string.h>
#include <mach-o/loader.h>
#include <unistd.h>
#include <stdio.h>
#include <stdbool.h>
#include <stdarg.h>
#include <pthread.h>
#include <Availability.h>
#include "mach-o/dyld_priv.h"
#include "dyldLibSystemInterface.h"
extern void _ZN4dyld3logEPKcz(const char*, ...);
extern struct LibSystemHelpers* _ZN4dyld17gLibSystemHelpersE;
#if __LP64__
#define LC_SEGMENT_COMMAND LC_SEGMENT_64
#define macho_header mach_header_64
#define macho_segment_command segment_command_64
#define macho_section section_64
#define getsectdatafromheader getsectdatafromheader_64
#else
#define LC_SEGMENT_COMMAND LC_SEGMENT
#define macho_header mach_header
#define macho_segment_command segment_command
#define macho_section section
#endif
static pthread_key_t sCxaKey = 0;
static char sPreMainCxaGlobals[2*sizeof(long)];
char* __cxa_get_globals()
{
if ( (_ZN4dyld17gLibSystemHelpersE == NULL) || (_ZN4dyld17gLibSystemHelpersE->version < 7) )
return sPreMainCxaGlobals;
if ( sCxaKey == 0 ) {
_ZN4dyld17gLibSystemHelpersE->pthread_key_create(&sCxaKey, &free);
}
char* data = (char*)_ZN4dyld17gLibSystemHelpersE->pthread_getspecific(sCxaKey);
if ( data == NULL ) {
data = calloc(2,sizeof(void*));
_ZN4dyld17gLibSystemHelpersE->pthread_setspecific(sCxaKey, data);
}
return data;
}
char* __cxa_get_globals_fast()
{
if ( (_ZN4dyld17gLibSystemHelpersE == NULL) || (_ZN4dyld17gLibSystemHelpersE->version < 7) )
return sPreMainCxaGlobals;
return _ZN4dyld17gLibSystemHelpersE->pthread_getspecific(sCxaKey);
}
#if !__arm__
extern void* ehStart __asm("section$start$__TEXT$__eh_frame");
extern void* ehEnd __asm("section$end$__TEXT$__eh_frame");
extern void* uwStart __asm("section$start$__TEXT$__unwind_info");
extern void* uwEnd __asm("section$end$__TEXT$__unwind_info");
extern void* textStart __asm("section$start$__TEXT$__text");
extern void* textEnd __asm("section$end$__TEXT$__text");
extern void* __dso_handle;
bool _dyld_find_unwind_sections(void* addr, struct dyld_unwind_sections* info)
{
if ( ((void*)&textStart < addr) && (addr < (void*)&textEnd) ) {
info->mh = (struct mach_header*)&__dso_handle;
info->dwarf_section = &ehStart;
info->dwarf_section_length = ((char*)&ehEnd - (char*)&ehStart);
info->compact_unwind_section = &uwStart;
info->compact_unwind_section_length = ((char*)&uwEnd - (char*)&uwStart);
return true;
}
else {
return false;
}
}
#endif // !__arm__
#if __arm__
struct _Unwind_FunctionContext
{
struct _Unwind_FunctionContext* prev;
};
static pthread_key_t sThreadChainKey = 0;
static struct _Unwind_FunctionContext* sStaticThreadChain = NULL;
void __Unwind_SjLj_SetThreadKey(pthread_key_t key)
{
sThreadChainKey = key;
_ZN4dyld17gLibSystemHelpersE->pthread_setspecific(sThreadChainKey, sStaticThreadChain);
sStaticThreadChain = NULL;
}
struct _Unwind_FunctionContext* __Unwind_SjLj_GetTopOfFunctionStack()
{
if ( sThreadChainKey != 0 ) {
return (struct _Unwind_FunctionContext*)pthread_getspecific(sThreadChainKey);
}
else {
return sStaticThreadChain;
}
}
void __Unwind_SjLj_SetTopOfFunctionStack(struct _Unwind_FunctionContext* fc)
{
if ( sThreadChainKey != 0 )
_ZN4dyld17gLibSystemHelpersE->pthread_setspecific(sThreadChainKey, fc);
else
sStaticThreadChain = fc;
}
#endif