diff mbox

Fix PR target/50678

Message ID 3029606.8Ija0WxEQD@polaris
State New
Headers show

Commit Message

Eric Botcazou Feb. 7, 2013, 6:08 p.m. UTC
This is hopefully the final nail in the coffin for PR target/50678, which is 
the failure of ACATS c52104y at -O2 on x86-64/Darwin.  The root cause was 
tracked down to a bug in the unwind info of the system sigtramp and a ticket 
was opened with Apple (radar #10302855).  Pending its resolution, a workaround 
was added in the Ada runtime on all active branches.

Simon reports that the bug has been fixed in Darwin 12.x, which makes c52104y 
fail again on this system because of the workaround.  So he has devised the 
attached patch to disable the workaround at run time.

Tested by Simon on Darwin 12 and Dominique on Darwin 10, applied on all active 
branches.


2013-02-07  Simon Wright  <simon@pushface.org>

	PR target/50678
	* init.c (__darwin_major_version): New function for x86-64/Darwin.
	(__gnat_adjust_context_for_raise) [Darwin]: Disable the workaround
	on Darwin 12 and above.
diff mbox

Patch

Index: init.c
===================================================================
--- init.c	(revision 195841)
+++ init.c	(working copy)
@@ -2056,7 +2056,9 @@  __gnat_install_handler(void)
 #elif defined(__APPLE__)
 
 #include <signal.h>
+#include <stdlib.h>
 #include <sys/syscall.h>
+#include <sys/sysctl.h>
 #include <mach/mach_vm.h>
 #include <mach/mach_init.h>
 #include <mach/vm_statistics.h>
@@ -2095,20 +2097,52 @@  __gnat_is_stack_guard (mach_vm_address_t
 
 #define HAVE_GNAT_ADJUST_CONTEXT_FOR_RAISE
 
+#if defined (__x86_64__)
+static int
+__darwin_major_version (void)
+{
+  static int cache = -1;
+  if (cache < 0)
+    {
+      int mib[2] = {CTL_KERN, KERN_OSRELEASE};
+      size_t len;
+
+      /* Find out how big the buffer needs to be (and set cache to 0
+         on failure).  */
+      if (sysctl (mib, 2, NULL, &len, NULL, 0) == 0)
+        {
+          char release[len];
+          sysctl (mib, 2, release, &len, NULL, 0);
+          /* Darwin releases are of the form L.M.N where L is the major
+             version, so strtol will return L.  */
+          cache = (int) strtol (release, NULL, 10);
+        }
+      else
+        {
+          cache = 0;
+        }
+    }
+  return cache;
+}
+#endif
+
 void
 __gnat_adjust_context_for_raise (int signo ATTRIBUTE_UNUSED,
 				 void *ucontext ATTRIBUTE_UNUSED)
 {
 #if defined (__x86_64__)
-  /* Work around radar #10302855/pr50678, where the unwinders (libunwind or
-     libgcc_s depending on the system revision) and the DWARF unwind data for
-     the sigtramp have different ideas about register numbering (causing rbx
-     and rdx to be transposed)..  */
-  ucontext_t *uc = (ucontext_t *)ucontext ;
-  unsigned long t = uc->uc_mcontext->__ss.__rbx;
-
-  uc->uc_mcontext->__ss.__rbx = uc->uc_mcontext->__ss.__rdx;
-  uc->uc_mcontext->__ss.__rdx = t;
+  if (__darwin_major_version () < 12)
+    {
+      /* Work around radar #10302855, where the unwinders (libunwind or
+	 libgcc_s depending on the system revision) and the DWARF unwind
+	 data for sigtramp have different ideas about register numbering,
+	 causing rbx and rdx to be transposed.  */
+      ucontext_t *uc = (ucontext_t *)ucontext;
+      unsigned long t = uc->uc_mcontext->__ss.__rbx;
+
+      uc->uc_mcontext->__ss.__rbx = uc->uc_mcontext->__ss.__rdx;
+      uc->uc_mcontext->__ss.__rdx = t;
+    }
 #endif
 }