From: Niklas Therning Date: Wed, 17 Sep 2014 16:09:55 +0000 (+0200) Subject: Modified darwin_stop_world.c to use an arm_unified_thread_state_t struct to X-Git-Tag: gc7_6_0~207 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=73ee11a2a920fafa67f9bd3586f1dbc8f539a6fc;p=gc Modified darwin_stop_world.c to use an arm_unified_thread_state_t struct to store a thread's state when compiling against the iOS 7/8 SDK. Without this patch GC_stack_range_for() crashes when running a 32-bit app on iOS 64-bit. The old code passed an arm_thread_state_t and ARM_THREAD_STATE to thread_get_state(). ARM_THREAD_STATE is the same as ARM_UNIFIED_THREAD_STATE on iOS 7/8 and thread_get_state() actually expects an arm_unified_thread_state_t. On iOS 32-bit it looks like thread_get_state() only touches the first bytes corresponding to the size of arm_thread_state_t so no crash there. On iOS 64-bit however it seems thread_get_state() writes to the full arm_unified_thread_state_t which meant it would overflow the stack allocated struct passed to it and mess up other values on the stack leading to a crash later on. --- diff --git a/darwin_stop_world.c b/darwin_stop_world.c index a6b0a5c7..6ca345a6 100644 --- a/darwin_stop_world.c +++ b/darwin_stop_world.c @@ -228,27 +228,27 @@ STATIC ptr_t GC_stack_range_for(ptr_t *phi, thread_act_t thread, GC_thread p, GC_push_one(state.THREAD_FLD(r31)); # elif defined(ARM32) - lo = (void *)state.__sp; + lo = (void *)state.THREAD_FLD(sp); # ifndef DARWIN_DONT_PARSE_STACK - *phi = GC_FindTopOfStack(state.__sp); + *phi = GC_FindTopOfStack(state.THREAD_FLD(sp)); # endif - GC_push_one(state.__r[0]); - GC_push_one(state.__r[1]); - GC_push_one(state.__r[2]); - GC_push_one(state.__r[3]); - GC_push_one(state.__r[4]); - GC_push_one(state.__r[5]); - GC_push_one(state.__r[6]); - GC_push_one(state.__r[7]); - GC_push_one(state.__r[8]); - GC_push_one(state.__r[9]); - GC_push_one(state.__r[10]); - GC_push_one(state.__r[11]); - GC_push_one(state.__r[12]); - /* GC_push_one(state.__sp); */ - GC_push_one(state.__lr); - /* GC_push_one(state.__pc); */ - GC_push_one(state.__cpsr); + GC_push_one(state.THREAD_FLD(r[0])); + GC_push_one(state.THREAD_FLD(r[1])); + GC_push_one(state.THREAD_FLD(r[2])); + GC_push_one(state.THREAD_FLD(r[3])); + GC_push_one(state.THREAD_FLD(r[4])); + GC_push_one(state.THREAD_FLD(r[5])); + GC_push_one(state.THREAD_FLD(r[6])); + GC_push_one(state.THREAD_FLD(r[7])); + GC_push_one(state.THREAD_FLD(r[8])); + GC_push_one(state.THREAD_FLD(r[9])); + GC_push_one(state.THREAD_FLD(r[10])); + GC_push_one(state.THREAD_FLD(r[11])); + GC_push_one(state.THREAD_FLD(r[12])); + /* GC_push_one(state.THREAD_FLD(sp)); */ + GC_push_one(state.THREAD_FLD(lr)); + /* GC_push_one(state.THREAD_FLD(pc)); */ + GC_push_one(state.THREAD_FLD(cpsr)); # else # error FIXME for non-x86 || ppc || arm architectures diff --git a/include/private/gc_priv.h b/include/private/gc_priv.h index 69c32e9c..113391f2 100644 --- a/include/private/gc_priv.h +++ b/include/private/gc_priv.h @@ -556,6 +556,7 @@ GC_EXTERN GC_warn_proc GC_current_warn_proc; #endif #if defined(DARWIN) +# include # ifndef MAC_OS_X_VERSION_MAX_ALLOWED # include /* Include this header just to import the above macro. */ @@ -588,7 +589,11 @@ GC_EXTERN GC_warn_proc GC_current_warn_proc; # define GC_MACH_THREAD_STATE_COUNT x86_THREAD_STATE64_COUNT # endif # else -# if defined(ARM32) +# if defined(ARM32) && defined(ARM_UNIFIED_THREAD_STATE) +# define GC_THREAD_STATE_T arm_unified_thread_state_t +# define GC_MACH_THREAD_STATE ARM_UNIFIED_THREAD_STATE +# define GC_MACH_THREAD_STATE_COUNT ARM_UNIFIED_THREAD_STATE_COUNT +# elif defined(ARM32) # define GC_THREAD_STATE_T arm_thread_state_t # ifdef ARM_MACHINE_THREAD_STATE_COUNT # define GC_MACH_THREAD_STATE ARM_MACHINE_THREAD_STATE @@ -619,9 +624,17 @@ GC_EXTERN GC_warn_proc GC_current_warn_proc; /* without __, thus hopefully, not breaking any existing */ /* Makefile.direct builds. */ # if __DARWIN_UNIX03 -# define THREAD_FLD(x) __ ## x +# if defined(ARM32) && defined(ARM_UNIFIED_THREAD_STATE) +# define THREAD_FLD(x) ts_32.__ ## x +# else +# define THREAD_FLD(x) __ ## x +# endif # else -# define THREAD_FLD(x) x +# if defined(ARM32) && defined(ARM_UNIFIED_THREAD_STATE) +# define THREAD_FLD(x) ts_32. ## x +# else +# define THREAD_FLD(x) x +# endif # endif #endif /* DARWIN */