Patchwork Fix PR target/50678

login
register
mail settings
Submitter Eric Botcazou
Date Feb. 7, 2013, 6:08 p.m.
Message ID <3029606.8Ija0WxEQD@polaris>
Download mbox | patch
Permalink /patch/218974/
State New
Headers show

Comments

Eric Botcazou - Feb. 7, 2013, 6:08 p.m.
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.

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
 }