]> granicus.if.org Git - gc/commitdiff
Modified darwin_stop_world.c to use an arm_unified_thread_state_t struct to
authorNiklas Therning <niklas@therning.org>
Wed, 17 Sep 2014 16:09:55 +0000 (18:09 +0200)
committerNiklas Therning <niklas@therning.org>
Wed, 17 Sep 2014 16:30:38 +0000 (18:30 +0200)
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.

darwin_stop_world.c
include/private/gc_priv.h

index a6b0a5c7e0a4862578eeccbf0d49a7a885fc7bbc..6ca345a67b88865fe98045ac21d7f87856dda1ca 100644 (file)
@@ -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
index 69c32e9c0dbbfef8d97c5a7ef5c6a45b5700797b..113391f2e545bdc984e45f1f4c23c0c0a6aff181 100644 (file)
@@ -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 */