aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada')
-rw-r--r--gcc/ada/ChangeLog10
-rw-r--r--gcc/ada/a-sytaco.ads5
-rw-r--r--gcc/ada/affinity.c12
-rw-r--r--gcc/ada/init.c133
4 files changed, 106 insertions, 54 deletions
diff --git a/gcc/ada/ChangeLog b/gcc/ada/ChangeLog
index 465294b..8ebc591 100644
--- a/gcc/ada/ChangeLog
+++ b/gcc/ada/ChangeLog
@@ -1,5 +1,15 @@
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
Intrinsic types if Relaxed_RM_Semantics is True.
diff --git a/gcc/ada/a-sytaco.ads b/gcc/ada/a-sytaco.ads
index bf1ab87..733fc76 100644
--- a/gcc/ada/a-sytaco.ads
+++ b/gcc/ada/a-sytaco.ads
@@ -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,
diff --git a/gcc/ada/affinity.c b/gcc/ada/affinity.c
index 215a614..bac8b5a 100644
--- a/gcc/ada/affinity.c
+++ b/gcc/ada/affinity.c
@@ -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- *
@@ -34,11 +34,11 @@
#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);
diff --git a/gcc/ada/init.c b/gcc/ada/init.c
index 2f01c8d..38907a1 100644
--- a/gcc/ada/init.c
+++ b/gcc/ada/init.c
@@ -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");