Commit 230ad369 by Arnaud Charlet

[multiple changes]

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
parent d9d25d04
2016-04-18 Arnaud Charlet <charlet@adacore.com> 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 * sem_prag.adb (Process_Convention): Relax rule on exporting
Intrinsic types if Relaxed_RM_Semantics is True. Intrinsic types if Relaxed_RM_Semantics is True.
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
-- -- -- --
-- S p e c -- -- 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 -- -- This specification is derived from the Ada Reference Manual for use with --
-- GNAT. The copyright notice above, and the license provisions that follow -- -- GNAT. The copyright notice above, and the license provisions that follow --
...@@ -44,7 +44,8 @@ is ...@@ -44,7 +44,8 @@ is
pragma Preelaborate; pragma Preelaborate;
-- In accordance with Ada 2005 AI-362 -- 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 procedure Set_True (S : in out Suspension_Object) with
Global => null, Global => null,
......
...@@ -6,7 +6,7 @@ ...@@ -6,7 +6,7 @@
* * * *
* C Implementation File * * 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 * * 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- * * terms of the GNU General Public License as published by the Free Soft- *
...@@ -34,11 +34,11 @@ ...@@ -34,11 +34,11 @@
#include "taskLib.h" #include "taskLib.h"
#include "cpuset.h" #include "cpuset.h"
extern int __gnat_set_affinity (int tid, unsigned cpu); extern int __gnat_set_affinity (TASK_ID tid, unsigned cpu);
extern int __gnat_set_affinity_mask (int tid, unsigned mask); extern int __gnat_set_affinity_mask (TASK_ID tid, unsigned mask);
int int
__gnat_set_affinity (int tid, unsigned cpu) __gnat_set_affinity (TASK_ID tid, unsigned cpu)
{ {
cpuset_t cpuset; cpuset_t cpuset;
...@@ -48,9 +48,9 @@ int ...@@ -48,9 +48,9 @@ int
} }
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_t cpuset;
CPUSET_ZERO(cpuset); CPUSET_ZERO(cpuset);
......
...@@ -1714,8 +1714,11 @@ __gnat_install_handler (void) ...@@ -1714,8 +1714,11 @@ __gnat_install_handler (void)
#include <iv.h> #include <iv.h>
#endif #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> #include <vmLib.h>
extern size_t vxIntStackOverflowSize;
#define INT_OVERFLOW_SIZE vxIntStackOverflowSize
#endif #endif
#ifdef VTHREADS #ifdef VTHREADS
...@@ -1726,13 +1729,13 @@ __gnat_install_handler (void) ...@@ -1726,13 +1729,13 @@ __gnat_install_handler (void)
/* Directly vectored Interrupt routines are not supported when using RTPs. */ /* 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. */ /* This is needed by the GNAT run time to handle Vxworks interrupts. */
int void *
__gnat_inum_to_ivec (int num) __gnat_inum_to_ivec (int num)
{ {
return (int) ((long) INUM_TO_IVEC ((long) num)); return (void *) INUM_TO_IVEC (num);
} }
#endif #endif
...@@ -1750,6 +1753,69 @@ getpid (void) ...@@ -1750,6 +1753,69 @@ getpid (void)
} }
#endif #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. /* 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 handled. The VxWorks version of longjmp does this; GCC's builtin_longjmp
doesn't. */ doesn't. */
...@@ -1766,8 +1832,7 @@ __gnat_clear_exception_count (void) ...@@ -1766,8 +1832,7 @@ __gnat_clear_exception_count (void)
/* Handle different SIGnal to exception mappings in different VxWorks /* Handle different SIGnal to exception mappings in different VxWorks
versions. */ versions. */
void void
__gnat_map_signal (int sig, siginfo_t *si ATTRIBUTE_UNUSED, __gnat_map_signal (int sig, siginfo_t *si ATTRIBUTE_UNUSED, void *sc)
void *sc ATTRIBUTE_UNUSED)
{ {
struct Exception_Data *exception; struct Exception_Data *exception;
const char *msg; const char *msg;
...@@ -1854,49 +1919,25 @@ __gnat_map_signal (int sig, siginfo_t *si ATTRIBUTE_UNUSED, ...@@ -1854,49 +1919,25 @@ __gnat_map_signal (int sig, siginfo_t *si ATTRIBUTE_UNUSED,
msg = "unhandled signal"; msg = "unhandled signal";
} }
/* On ARM VxWorks 6.x, the guard page is left un-armed by the kernel if (__gnat_reset_guard_page (sig, sc))
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)
{ {
TASK_ID tid = taskIdSelf (); /* Set the exception message: we know for sure that we have a
WIND_TCB *pTcb = taskTcb (tid); stack overflow here */
unsigned long violated_page exception = &storage_error;
= ((struct sigcontext *) sc)->sc_pregs->r[REG_IP] & ~(PAGE_SIZE - 1);
if ((unsigned long) (pTcb->pStackEnd - PAGE_SIZE) == violated_page) switch (sig)
{ {
vmStateSet (NULL, violated_page, case SIGSEGV:
PAGE_SIZE, VM_STATE_MASK_VALID, VM_STATE_VALID_NOT); msg = "SIGSEGV: stack overflow";
exception = &storage_error; break;
case SIGBUS:
switch (sig) msg = "SIGBUS: stack overflow";
{ break;
case SIGSEGV: case SIGILL:
msg = "SIGSEGV: stack overflow"; msg = "SIGILL: stack overflow";
break; 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 (); __gnat_clear_exception_count ();
Raise_From_Signal_Handler (exception, msg); Raise_From_Signal_Handler (exception, msg);
} }
...@@ -2115,7 +2156,7 @@ __gnat_init_float (void) ...@@ -2115,7 +2156,7 @@ __gnat_init_float (void)
#endif #endif
#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 /* This is used to properly initialize the FPU on an x86 for each
process thread. Is this needed for x86_64 ??? */ process thread. Is this needed for x86_64 ??? */
asm ("finit"); asm ("finit");
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment