summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorNiklas Therning <niklas@therning.org>2014-09-17 18:09:55 +0200
committerNiklas Therning <niklas@therning.org>2014-09-17 18:30:38 +0200
commit73ee11a2a920fafa67f9bd3586f1dbc8f539a6fc (patch)
tree434e449cc1767e6ccf66e560245413d25537d2e9
parent3d342554dc03af8d27925706a6513080995e1904 (diff)
downloadbdwgc-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.c38
-rw-r--r--include/private/gc_priv.h19
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 */