[multiple changes]
authorArnaud Charlet <charlet@gcc.gnu.org>
Mon, 18 Apr 2016 09:22:50 +0000 (11:22 +0200)
committerArnaud Charlet <charlet@gcc.gnu.org>
Mon, 18 Apr 2016 09:22:50 +0000 (11:22 +0200)
2016-04-18  Arnaud Charlet  <charlet@adacore.com>

* a-sytaco.adb (Suspension_Object): Aspect Default_Initial_Condition
added.

2016-04-18  Jerome Lambourg  <lambourg@adacore.com>

* affinity.c: Use the proper type for task id.
* init.c (__gnat_inum_to_ivec): ivec is a pointer.

From-SVN: r235101

gcc/ada/ChangeLog
gcc/ada/a-sytaco.ads
gcc/ada/affinity.c
gcc/ada/init.c

index 465294be441c4d930369389d70d9cbf81e33363b..8ebc59102553ac09a82eab27de5a010bff9c1ff5 100644 (file)
@@ -1,3 +1,13 @@
+2016-04-18  Arnaud Charlet  <charlet@adacore.com>
+
+       * a-sytaco.adb (Suspension_Object): Aspect Default_Initial_Condition
+       added.
+
+2016-04-18  Jerome Lambourg  <lambourg@adacore.com>
+
+       * affinity.c: Use the proper type for task id.
+       * init.c (__gnat_inum_to_ivec): ivec is a pointer.
+
 2016-04-18  Arnaud Charlet  <charlet@adacore.com>
 
        * sem_prag.adb (Process_Convention): Relax rule on exporting
index bf1ab8720c9c17b046799dae331383b535718661..733fc764e2339f1853db6041cf3bc302f11eefe3 100644 (file)
@@ -6,7 +6,7 @@
 --                                                                          --
 --                                 S p e c                                  --
 --                                                                          --
---          Copyright (C) 1992-2014, Free Software Foundation, Inc.         --
+--          Copyright (C) 1992-2015, Free Software Foundation, Inc.         --
 --                                                                          --
 -- This specification is derived from the Ada Reference Manual for use with --
 -- GNAT. The copyright notice above, and the license provisions that follow --
@@ -44,7 +44,8 @@ is
    pragma Preelaborate;
    --  In accordance with Ada 2005 AI-362
 
-   type Suspension_Object is limited private;
+   type Suspension_Object is limited private with
+     Default_Initial_Condition;
 
    procedure Set_True (S : in out Suspension_Object) with
      Global  => null,
index 215a6144f03f0455cd34964412c313017f9ef5af..bac8b5aec25feb0e6e1aa13c0f8359054c269de7 100644 (file)
@@ -6,7 +6,7 @@
  *                                                                          *
  *                          C Implementation File                           *
  *                                                                          *
- *            Copyright (C) 2005-2011, Free Software Foundation, Inc.       *
+ *            Copyright (C) 2005-2015, Free Software Foundation, Inc.       *
  *                                                                          *
  * GNAT is free software;  you can  redistribute it  and/or modify it under *
  * terms of the  GNU General Public License as published  by the Free Soft- *
 #include "taskLib.h"
 #include "cpuset.h"
 
-extern int __gnat_set_affinity (int tid, unsigned cpu);
-extern int __gnat_set_affinity_mask (int tid, unsigned mask);
+extern int __gnat_set_affinity (TASK_ID tid, unsigned cpu);
+extern int __gnat_set_affinity_mask (TASK_ID tid, unsigned mask);
 
 int
- __gnat_set_affinity (int tid, unsigned cpu)
+ __gnat_set_affinity (TASK_ID tid, unsigned cpu)
 {
   cpuset_t cpuset;
 
@@ -48,9 +48,9 @@ int
 }
 
 int
-__gnat_set_affinity_mask (int tid, unsigned mask)
+__gnat_set_affinity_mask (TASK_ID tid, unsigned mask)
 {
-  int index;
+  unsigned index;
   cpuset_t cpuset;
 
   CPUSET_ZERO(cpuset);
index 2f01c8dce7cc5e293bea951f950d02d9255abd4a..38907a11af9af556a188daecc255d8b797a5e02a 100644 (file)
@@ -1714,8 +1714,11 @@ __gnat_install_handler (void)
 #include <iv.h>
 #endif
 
-#if defined (ARMEL) && (_WRS_VXWORKS_MAJOR == 6) && !defined(__RTP__)
+#if ((defined (ARMEL) && (_WRS_VXWORKS_MAJOR == 6)) || defined (__x86_64__)) && !defined(__RTP__)
+#define VXWORKS_FORCE_GUARD_PAGE 1
 #include <vmLib.h>
+extern size_t vxIntStackOverflowSize;
+#define INT_OVERFLOW_SIZE vxIntStackOverflowSize
 #endif
 
 #ifdef VTHREADS
@@ -1726,13 +1729,13 @@ __gnat_install_handler (void)
 
 /* Directly vectored Interrupt routines are not supported when using RTPs.  */
 
-extern int __gnat_inum_to_ivec (int);
+extern void * __gnat_inum_to_ivec (int);
 
 /* This is needed by the GNAT run time to handle Vxworks interrupts.  */
-int
+void *
 __gnat_inum_to_ivec (int num)
 {
-  return (int) ((long) INUM_TO_IVEC ((long) num));
+  return (void *) INUM_TO_IVEC (num);
 }
 #endif
 
@@ -1750,6 +1753,69 @@ getpid (void)
 }
 #endif
 
+/* When stack checking is performed by probing a guard page on the stack,
+   sometimes this guard page is not properly reset on VxWorks. We need to
+   manually reset it in this case.
+   This function returns TRUE in case the guard page was hit by the
+   signal. */
+static int
+__gnat_reset_guard_page (int sig, void *sc)
+{
+  /* On ARM VxWorks 6.x and x86_64 VxWorks 7, the guard page is left un-armed
+     by the kernel after being violated, so subsequent violations aren't
+     detected.
+     So we retrieve the address of the guard page from the TCB and compare it
+     with the page that is violated and re-arm that page if there's a match. */
+#if defined (VXWORKS_FORCE_GUARD_PAGE)
+
+  /* Ignore signals that are not stack overflow signals */
+  if (sig != SIGSEGV && sig != SIGBUS && sig != SIGILL) return FALSE;
+
+  /* If the target does not support guard pages, INT_OVERFLOW_SIZE will be 0 */
+  if (INT_OVERFLOW_SIZE == 0) return FALSE;
+
+  TASK_ID tid           = taskIdSelf ();
+  WIND_TCB *pTcb        = taskTcb (tid);
+  REG_SET *pregs        = ((struct sigcontext *) sc)->sc_pregs;
+  VIRT_ADDR guardPage   = (VIRT_ADDR) pTcb->pStackEnd - INT_OVERFLOW_SIZE;
+  UINT stateMask        = VM_STATE_MASK_VALID;
+  UINT state            = VM_STATE_VALID_NOT;
+  size_t probe_distance = 0;
+  VIRT_ADDR sigPage;
+
+#if defined (ARMEL)
+  /* violating address in rip: r12 */
+  sigPage    = pregs->r[12] & ~(INT_OVERFLOW_SIZE - 1);
+#elif defined (__x86_64__)
+  /* violating address in rsp. */
+  probe_distance = 16 * 1024; /* in gcc/config/i386/vxworks7.h */
+  sigPage    = pregs->rsp & ~(INT_OVERFLOW_SIZE - 1);
+  stateMask |= MMU_ATTR_SPL_MSK;
+  state     |= MMU_ATTR_NO_BLOCK;
+#else
+#error "Not Implemented for this CPU"
+#endif
+
+  if (guardPage == (sigPage - probe_distance))
+    {
+      UINT nState;
+      vmStateGet (NULL, guardPage, &nState);
+      if ((nState & VM_STATE_MASK_VALID) != VM_STATE_VALID_NOT) {
+        /* If the guard page has a valid state, we need to reset to
+           invalid state here */
+        vmStateSet (NULL, guardPage, INT_OVERFLOW_SIZE, stateMask, state);
+      }
+
+      return TRUE;
+    }
+  else
+    {
+      return FALSE;
+    }
+#endif /* VXWORKS_FORCE_GUARD_PAGE */
+  return FALSE;
+}
+
 /* VxWorks 653 vThreads expects the field excCnt to be zeroed when a signal is.
    handled. The VxWorks version of longjmp does this; GCC's builtin_longjmp
    doesn't.  */
@@ -1766,8 +1832,7 @@ __gnat_clear_exception_count (void)
 /* Handle different SIGnal to exception mappings in different VxWorks
    versions.  */
 void
-__gnat_map_signal (int sig, siginfo_t *si ATTRIBUTE_UNUSED,
-                  void *sc ATTRIBUTE_UNUSED)
+__gnat_map_signal (int sig, siginfo_t *si ATTRIBUTE_UNUSED, void *sc)
 {
   struct Exception_Data *exception;
   const char *msg;
@@ -1854,49 +1919,25 @@ __gnat_map_signal (int sig, siginfo_t *si ATTRIBUTE_UNUSED,
       msg = "unhandled signal";
     }
 
-  /* On ARM VxWorks 6.x, the guard page is left un-armed by the kernel
-     after being violated, so subsequent violations aren't detected.
-     so we retrieve the address of the guard page from the TCB and compare it
-     with the page that is violated (pREG 12 in the context) and re-arm that
-     page if there's a match.  Additionally we're are assured this is a
-     genuine stack overflow condition and and set the message and exception
-     to that effect.  */
-#if defined (ARMEL) && (_WRS_VXWORKS_MAJOR == 6) && !defined(__RTP__)
-
-  /* We re-arm the guard page by marking it invalid */
-
-#define PAGE_SIZE 4096
-#define REG_IP 12
-
-  if (sig == SIGSEGV || sig == SIGBUS || sig == SIGILL)
+  if (__gnat_reset_guard_page (sig, sc))
     {
-      TASK_ID tid = taskIdSelf ();
-      WIND_TCB *pTcb = taskTcb (tid);
-      unsigned long violated_page
-          = ((struct sigcontext *) sc)->sc_pregs->r[REG_IP] & ~(PAGE_SIZE - 1);
+      /* Set the exception message: we know for sure that we have a
+         stack overflow here */
+      exception = &storage_error;
 
-      if ((unsigned long) (pTcb->pStackEnd - PAGE_SIZE) == violated_page)
+      switch (sig)
         {
-         vmStateSet (NULL, violated_page,
-                     PAGE_SIZE, VM_STATE_MASK_VALID, VM_STATE_VALID_NOT);
-         exception = &storage_error;
-
-         switch (sig)
-         {
-            case SIGSEGV:
-             msg = "SIGSEGV: stack overflow";
-             break;
-            case SIGBUS:
-             msg = "SIGBUS: stack overflow";
-             break;
-            case SIGILL:
-             msg = "SIGILL: stack overflow";
-             break;
-         }
-       }
+        case SIGSEGV:
+          msg = "SIGSEGV: stack overflow";
+          break;
+        case SIGBUS:
+          msg = "SIGBUS: stack overflow";
+          break;
+        case SIGILL:
+          msg = "SIGILL: stack overflow";
+          break;
+        }
     }
-#endif /* defined (ARMEL) && (_WRS_VXWORKS_MAJOR == 6) && !defined(__RTP__) */
-
   __gnat_clear_exception_count ();
   Raise_From_Signal_Handler (exception, msg);
 }
@@ -2115,7 +2156,7 @@ __gnat_init_float (void)
 #endif
 #endif
 
-#if (defined (__i386__) && !defined (VTHREADS))
+#if defined (__i386__) && !defined (VTHREADS)
   /* This is used to properly initialize the FPU on an x86 for each
      process thread. Is this needed for x86_64 ???  */
   asm ("finit");