diff options
author | Niklas Therning <niklas@therning.org> | 2014-09-17 18:09:55 +0200 |
---|---|---|
committer | Niklas Therning <niklas@therning.org> | 2014-09-17 18:30:38 +0200 |
commit | 73ee11a2a920fafa67f9bd3586f1dbc8f539a6fc (patch) | |
tree | 434e449cc1767e6ccf66e560245413d25537d2e9 | |
parent | 3d342554dc03af8d27925706a6513080995e1904 (diff) | |
download | bdwgc-73ee11a2a920fafa67f9bd3586f1dbc8f539a6fc.tar.gz |
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.
-rw-r--r-- | darwin_stop_world.c | 38 | ||||
-rw-r--r-- | include/private/gc_priv.h | 19 |
2 files changed, 35 insertions, 22 deletions
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 <mach/thread_status.h> # ifndef MAC_OS_X_VERSION_MAX_ALLOWED # include <AvailabilityMacros.h> /* 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 */ |