[multiple changes]

2015-05-26  Ed Schonberg  <schonberg@adacore.com>

	* sem_ch7.adb (Install_Private_Declarations,
	Swap_Private_Dependents): Ensure that both views of the dependent
	subtype are immediately visible if we are within their scope. This
	may be needed when a procedure body is both the parent of an
	instantiated child unit, and is itself used to inline a local
	function.

2015-05-26  Gary Dismukes  <dismukes@adacore.com>

	* exp_prag.adb, gnat1drv.adb: Minor reformatting.

2015-05-26  Eric Botcazou  <ebotcazou@adacore.com>

	* exp_ch4.adb (Expand_N_Indexed_Component): In the circuit
	detecting exceptions to the rewriting, deal with implicit
	dereferences in the selected component case.

2015-05-26  Bob Duff  <duff@adacore.com>

	* sem_ch13.adb (Analyze_One_Aspect): Do not
	require the expression of the Disable_Controlled aspect to be
	static in a generic template, because 'Enabled is not known
	until the instance.

2015-05-26  Doug Rupp  <rupp@adacore.com>

	* init-vxsim.c: New file for vxsim ZCX
	* sigtramp-vxworks-vxsim.c: Likewise.
	* sigtramp-vxworks.c: Factor out target dependent bits into ...
	* sigtramp-vxworks-target.inc: ... here.
	* sigtramp.h: Add vxsim zcx protos.
	* init.c [vxworks...] (sysLib.h): Include.
	(__gnat_map_signal): Make global.
	 [...i386] (__gnat_error_handler): Call __gnat_vxsim_error_handler if
	on vxsim.
	[...i386] (__gnat_install_handler): Test if on vxsim.

2015-05-26  Ed Schonberg  <schonberg@adacore.com>

	* sem_ch5.adb (Analyze_Iterator_Specification): For an element
	iterator over an array, if the component is aliased, the loop
	variable is aliased as well.

2015-05-26  Ed Schonberg  <schonberg@adacore.com>

	* exp_ch6.adb (Expand_Actuals): For a function call with in-out
	parameters that is rewritten as an expression_with_actions,
	we preserve the original function call node for further use by
	the caller (typically Expand_Call). In the presence of validity
	checks, that function call, though it is labelled Analyzed to
	prevent an infinite recursion, may be rewritten as a temporary
	by Remove_Side_Effects.  Ensure that the caller has access to
	the original function call to continue expansion.
	* atree.ads: Minor typo in comment.

2015-05-26  Javier Miranda  <miranda@adacore.com>

	* sem_util.adb (Check_Function_Writable_Actuals):
	Add missing support to check the violation of writable actuals
	in array aggregates that have a nonstatic range.

From-SVN: r223672
This commit is contained in:
Arnaud Charlet 2015-05-26 11:28:14 +02:00
parent b9eb3aa8a2
commit e8c84c8fc3
16 changed files with 858 additions and 285 deletions

View File

@ -1,3 +1,66 @@
2015-05-26 Ed Schonberg <schonberg@adacore.com>
* sem_ch7.adb (Install_Private_Declarations,
Swap_Private_Dependents): Ensure that both views of the dependent
subtype are immediately visible if we are within their scope. This
may be needed when a procedure body is both the parent of an
instantiated child unit, and is itself used to inline a local
function.
2015-05-26 Gary Dismukes <dismukes@adacore.com>
* exp_prag.adb, gnat1drv.adb: Minor reformatting.
2015-05-26 Eric Botcazou <ebotcazou@adacore.com>
* exp_ch4.adb (Expand_N_Indexed_Component): In the circuit
detecting exceptions to the rewriting, deal with implicit
dereferences in the selected component case.
2015-05-26 Bob Duff <duff@adacore.com>
* sem_ch13.adb (Analyze_One_Aspect): Do not
require the expression of the Disable_Controlled aspect to be
static in a generic template, because 'Enabled is not known
until the instance.
2015-05-26 Doug Rupp <rupp@adacore.com>
* init-vxsim.c: New file for vxsim ZCX
* sigtramp-vxworks-vxsim.c: Likewise.
* sigtramp-vxworks.c: Factor out target dependent bits into ...
* sigtramp-vxworks-target.inc: ... here.
* sigtramp.h: Add vxsim zcx protos.
* init.c [vxworks...] (sysLib.h): Include.
(__gnat_map_signal): Make global.
[...i386] (__gnat_error_handler): Call __gnat_vxsim_error_handler if
on vxsim.
[...i386] (__gnat_install_handler): Test if on vxsim.
2015-05-26 Ed Schonberg <schonberg@adacore.com>
* sem_ch5.adb (Analyze_Iterator_Specification): For an element
iterator over an array, if the component is aliased, the loop
variable is aliased as well.
2015-05-26 Ed Schonberg <schonberg@adacore.com>
* exp_ch6.adb (Expand_Actuals): For a function call with in-out
parameters that is rewritten as an expression_with_actions,
we preserve the original function call node for further use by
the caller (typically Expand_Call). In the presence of validity
checks, that function call, though it is labelled Analyzed to
prevent an infinite recursion, may be rewritten as a temporary
by Remove_Side_Effects. Ensure that the caller has access to
the original function call to continue expansion.
* atree.ads: Minor typo in comment.
2015-05-26 Javier Miranda <miranda@adacore.com>
* sem_util.adb (Check_Function_Writable_Actuals):
Add missing support to check the violation of writable actuals
in array aggregates that have a nonstatic range.
2015-05-26 Hristian Kirtchev <kirtchev@adacore.com>
* exp_ch6.adb (Process_Contract_Cases_For): Update the call to

View File

@ -730,7 +730,7 @@ package Atree is
-----------------------
-- Utility functions to test whether an Entity_Kind value, either given
-- directly as the first argument, or the Ekind field of an Entity give
-- directly as the first argument, or the Ekind field of an Entity given
-- as the first argument, matches any of the given list of Entity_Kind
-- values. Return True if any match, False if no match.

View File

@ -6299,7 +6299,10 @@ package body Exp_Ch4 is
-- The prefix of an address or bit or size attribute reference
-- The following circuit detects these exceptions
-- The following circuit detects these exceptions. Note that we need to
-- deal with implicit dereferences when climbing up the parent chain,
-- with the additional difficulty that the type of parents may have yet
-- to be resolved since prefixes are usually resolved first.
declare
Child : Node_Id := N;
@ -6351,11 +6354,22 @@ package body Exp_Ch4 is
then
return;
elsif Nkind_In (Parnt, N_Indexed_Component, N_Selected_Component)
elsif Nkind (Parnt) = N_Indexed_Component
and then Prefix (Parnt) = Child
then
null;
elsif Nkind (Parnt) = N_Selected_Component
and then Prefix (Parnt) = Child
and then not (Present (Etype (Selector_Name (Parnt)))
and then
Is_Access_Type (Etype (Selector_Name (Parnt))))
then
null;
-- If the parent is a dereference, either implicit or explicit,
-- then the packed reference needs to be expanded.
else
Expand_Packed_Element_Reference (N);
return;

View File

@ -997,10 +997,6 @@ package body Exp_Ch6 is
-- Expand_Actuals --
--------------------
--------------------
-- Expand_Actuals --
--------------------
procedure Expand_Actuals (N : in out Node_Id; Subp : Entity_Id) is
Loc : constant Source_Ptr := Sloc (N);
Actual : Node_Id;
@ -2018,9 +2014,12 @@ package body Exp_Ch6 is
-- Reset calling argument to point to function call inside
-- the expression with actions so the caller can continue
-- to process the call.
-- to process the call. In spite of the fact that it is
-- marked Analyzed above, it may be rewritten by Remove_
-- Side_Effects if validity checks are present, so go back
-- to original call.
N := Name;
N := Original_Node (Name);
end;
-- If not the special Ada 2012 case of a function call, then

View File

@ -165,7 +165,7 @@ package body Exp_Prag is
begin
-- Rewrite pragma ignored by Ignore_Pragma to null statement, so that
-- the back end or the expander here does not get over-enthusiastic and
-- the back end or the expander here does not get overenthusiastic and
-- start processing such a pragma!
if Get_Name_Table_Boolean3 (Pname) then
@ -318,7 +318,7 @@ package body Exp_Prag is
end if;
-- Since this check is active, we rewrite the pragma into a
-- corresponding if statement, and then analyze the statement
-- corresponding if statement, and then analyze the statement.
-- The normal case expansion transforms:

View File

@ -205,7 +205,7 @@ procedure Gnat1drv is
-- Turn off C tree generation, not compatible with CodePeer mode. We
-- do not expect this to happen in normal use, since both modes are
-- enabled by special tools, but it is useful to turn off these flags
-- this way when we are doing codepeer tests on existing test suites
-- this way when we are doing CodePeer tests on existing test suites
-- that may have -gnatd.V set, to avoid the need for special casing.
Modify_Tree_For_C := False;

67
gcc/ada/init-vxsim.c Normal file
View File

@ -0,0 +1,67 @@
/****************************************************************************
* *
* GNAT COMPILER COMPONENTS *
* *
* I N I T - V X S I M *
* *
* C Implementation File *
* *
* Copyright (C) 1992-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- *
* ware Foundation; either version 3, or (at your option) any later ver- *
* sion. GNAT is distributed in the hope that it will be useful, but WITH- *
* OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
* or FITNESS FOR A PARTICULAR PURPOSE. *
* *
* As a special exception under Section 7 of GPL version 3, you are granted *
* additional permissions described in the GCC Runtime Library Exception, *
* version 3.1, as published by the Free Software Foundation. *
* *
* You should have received a copy of the GNU General Public License and *
* a copy of the GCC Runtime Library Exception along with this program; *
* see the files COPYING3 and COPYING.RUNTIME respectively. If not, see *
* <http://www.gnu.org/licenses/>. *
* *
* GNAT was originally developed by the GNAT team at New York University. *
* Extensive contributions were provided by Ada Core Technologies Inc. *
* *
****************************************************************************/
/* This file is an addition to init.c that must be compiled with the CPU
specified for running under vxsim for x86-vxworks6, as the signal context
structure is different for vxsim vs. real hardware. */
#undef CPU
#ifndef __RTP__
#define CPU SIMNT
#else
#define CPU SIMPENTIUM
#endif
#include "vxWorks.h"
#include "tconfig.h"
#include <signal.h>
#include <taskLib.h>
#ifndef __RTP__
#include <intLib.h>
#include <iv.h>
#endif
extern void
__gnat_map_signal (int sig, siginfo_t *si ATTRIBUTE_UNUSED,
void *sc ATTRIBUTE_UNUSED);
/* Process the vxsim signal context. */
void
__gnat_vxsim_error_handler (int sig, siginfo_t *si, void *sc)
{
#include "sigtramp.h"
__gnat_sigtramp_vxsim (sig, (void *)si, (void *)sc,
(__sigtramphandler_t *)&__gnat_map_signal);
}

View File

@ -1702,6 +1702,7 @@ __gnat_install_handler ()
#include <signal.h>
#include <taskLib.h>
#include <sysLib.h>
#ifndef __RTP__
#include <intLib.h>
@ -1758,8 +1759,8 @@ __gnat_clear_exception_count (void)
}
/* Handle different SIGnal to exception mappings in different VxWorks
versions. */
static void
versions. */
void
__gnat_map_signal (int sig, siginfo_t *si ATTRIBUTE_UNUSED,
void *sc ATTRIBUTE_UNUSED)
{
@ -1895,6 +1896,13 @@ __gnat_map_signal (int sig, siginfo_t *si ATTRIBUTE_UNUSED,
Raise_From_Signal_Handler (exception, msg);
}
#if defined (i386) || defined (__i386__)
extern void
__gnat_vxsim_error_handler (int sig, siginfo_t *si, void *sc);
static int is_vxsim = 0;
#endif
/* Tasking and Non-tasking signal handler. Map SIGnal to Ada exception
propagation after the required low level adjustments. */
@ -1911,14 +1919,22 @@ __gnat_error_handler (int sig, siginfo_t *si, void *sc)
sigdelset (&mask, sig);
sigprocmask (SIG_SETMASK, &mask, NULL);
#if defined (__ARMEL__) || defined (__PPC__)
/* On ARM and PowerPC, kernel mode, we process signals through a Call Frame
#if defined (__ARMEL__) || defined (__PPC__) || defined (i386) || defined (__i386__)
/* On certain targets, kernel mode, we process signals through a Call Frame
Info trampoline, voiding the need for myriads of fallback_frame_state
variants in the ZCX runtime. We have no simple way to distinguish ZCX
from SJLJ here, so we do this for SJLJ as well even though this is not
necessary. This only incurs a few extra instructions and a tiny
amount of extra stack usage. */
#if defined (i386) || defined (__i386__)
/* On x86, the vxsim signal context is subtly different and is processeed
by a handler compiled especially for vxsim. */
if (is_vxsim)
__gnat_vxsim_error_handler (sig, si, sc);
#endif
#include "sigtramp.h"
__gnat_sigtramp (sig, (void *)si, (void *)sc,
@ -1952,6 +1968,7 @@ void
__gnat_install_handler (void)
{
struct sigaction act;
char *model ATTRIBUTE_UNUSED;
/* Setup signal handler to map synchronous signals to appropriate
exceptions. Make sure that the handler isn't interrupted by another
@ -2002,6 +2019,15 @@ __gnat_install_handler (void)
trap_0_entry->inst_fourth = 0xa1480000;
#endif
#if defined (i386) || defined (__i386__)
/* By experiment, found that sysModel () returns the following string
prefix for vxsim when running on Linux and Windows. */
model = sysModel ();
if ((strncmp (model, "Linux", 5) == 0)
|| (strncmp (model, "Windows", 7) == 0))
is_vxsim = 1;
#endif
__gnat_handler_installed = 1;
}

View File

@ -3156,10 +3156,20 @@ package body Sem_Ch13 is
goto Continue;
end if;
if not Present (Expr)
or else Is_True (Static_Boolean (Expr))
then
Set_Disable_Controlled (E);
Analyze_And_Resolve (Expr, Standard_Boolean);
-- If we're in a generic template, we don't want to try
-- to disable controlled types, because typical usage is
-- "Disable_Controlled => not <some_check>'Enabled", and
-- the value of Enabled is not known until we see a
-- particular instance.
if Expander_Active then
if not Present (Expr)
or else Is_True (Static_Boolean (Expr))
then
Set_Disable_Controlled (E);
end if;
end if;
goto Continue;

View File

@ -2010,6 +2010,11 @@ package body Sem_Ch5 is
if Of_Present (N) then
Set_Etype (Def_Id, Component_Type (Typ));
-- The loop variable is aliased if the array components are
-- aliased.
Set_Is_Aliased (Def_Id, Has_Aliased_Components (Typ));
-- AI12-0151 stipulates that the container cannot be a component
-- that depends on a discriminant if the enclosing object is
-- mutable, to prevent a modification of the container in the

View File

@ -2221,9 +2221,16 @@ package body Sem_Ch7 is
-- swap them out in End_Package_Scope.
Replace_Elmt (Priv_Elmt, Full_View (Priv));
-- Ensure that both views of the dependent private subtype are
-- immediately visible if within some open scope.
if In_Open_Scopes (Scope (Full_View (Priv))) then
Set_Is_Immediately_Visible (Priv);
Set_Is_Immediately_Visible (Full_View (Priv));
end if;
Exchange_Declarations (Priv);
Set_Is_Immediately_Visible
(Priv, In_Open_Scopes (Scope (Priv)));
Set_Is_Potentially_Use_Visible
(Priv, Is_Potentially_Use_Visible (Node (Priv_Elmt)));

View File

@ -2062,6 +2062,7 @@ package body Sem_Util is
procedure Check_Function_Writable_Actuals (N : Node_Id) is
Writable_Actuals_List : Elist_Id := No_Elist;
Identifiers_List : Elist_Id := No_Elist;
Aggr_Error_Node : Node_Id := Empty;
Error_Node : Node_Id := Empty;
procedure Collect_Identifiers (N : Node_Id);
@ -2119,6 +2120,14 @@ package body Sem_Util is
then
return Skip;
-- For rewriten nodes we continue the traversal in the original
-- subtree. Needed to handle in aggregates original expressions
-- extracted from the tree by Remove_Side_Effects.
elsif Is_Rewrite_Substitution (N) then
Collect_Identifiers (Original_Node (N));
return Skip;
-- For now we skip aggregate discriminants, since they require
-- performing the analysis in two phases to identify conflicts:
-- first one analyzing discriminants and second one analyzing
@ -2600,6 +2609,75 @@ package body Sem_Util is
end if;
end if;
end;
-- For an array aggregate a discrete_choice_list that has a
-- nonstatic range, is considered as two or more separate
-- occurrences of the expression (RM 6.20/3)
elsif Is_Array_Type (Etype (N))
and then Nkind (N) = N_Aggregate
and then Present (Aggregate_Bounds (N))
and then not Compile_Time_Known_Bounds (Etype (N))
then
-- Collect identifiers found in the dynamic bounds
declare
Count_Components : Natural := 0;
Low, High : Node_Id;
begin
Assoc := First (Component_Associations (N));
while Present (Assoc) loop
Choice := First (Choices (Assoc));
while Present (Choice) loop
if Nkind_In (Choice, N_Range,
N_Subtype_Indication)
or else (Is_Entity_Name (Choice)
and then Is_Type (Entity (Choice)))
then
Get_Index_Bounds (Choice, Low, High);
if not Compile_Time_Known_Value (Low) then
Collect_Identifiers (Low);
if No (Aggr_Error_Node) then
Aggr_Error_Node := Low;
end if;
end if;
if not Compile_Time_Known_Value (High) then
Collect_Identifiers (High);
if No (Aggr_Error_Node) then
Aggr_Error_Node := High;
end if;
end if;
-- For the purposes of this check it is enough to
-- consider that we cover a single component since
-- since the RM rule is violated as far as I find
-- more than one component.
else
Count_Components := Count_Components + 1;
if No (Aggr_Error_Node)
and then Count_Components > 1
then
Aggr_Error_Node := Choice;
end if;
if not Compile_Time_Known_Value (Choice) then
Collect_Identifiers (Choice);
end if;
end if;
Next (Choice);
end loop;
Next (Assoc);
end loop;
end;
end if;
-- Handle ancestor part of extension aggregates
@ -2679,6 +2757,18 @@ package body Sem_Util is
return;
end if;
-- Check violation of RM 6.20/3 in aggregates
if Present (Aggr_Error_Node)
and then Writable_Actuals_List /= No_Elist
then
Error_Msg_N
("value may be affected by call in other component because they "
& "are evaluated in unspecified order",
Node (First_Elmt (Writable_Actuals_List)));
return;
end if;
-- Check if some writable argument of a function is referenced
if Writable_Actuals_List /= No_Elist

View File

@ -0,0 +1,399 @@
/****************************************************************************
* *
* GNAT COMPILER COMPONENTS *
* *
* S I G T R A M P - T A R G E T *
* *
* Asm Implementation Include File *
* *
* Copyright (C) 2011-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- *
* ware Foundation; either version 3, or (at your option) any later ver- *
* sion. GNAT is distributed in the hope that it will be useful, but WITH- *
* OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
* or FITNESS FOR A PARTICULAR PURPOSE. *
* *
* As a special exception under Section 7 of GPL version 3, you are granted *
* additional permissions described in the GCC Runtime Library Exception, *
* version 3.1, as published by the Free Software Foundation. *
* *
* In particular, you can freely distribute your programs built with the *
* GNAT Pro compiler, including any required library run-time units, using *
* any licensing terms of your choosing. See the AdaCore Software License *
* for full details. *
* *
* GNAT was originally developed by the GNAT team at New York University. *
* Extensive contributions were provided by Ada Core Technologies Inc. *
* *
****************************************************************************/
/***************************************************************
* VxWorks target specific part of the __gnat_sigtramp service *
***************************************************************/
/* Note: This target specific part is kept in a separate file to avoid
duplication of its code for the vxworks and vxworks-vxsim asm
implementation files. */
/* ---------------------------
-- And now the asm stubs --
---------------------------
They all have a common structure with blocks of asm sequences queued one
after the others. Typically:
SYMBOL_START
CFI_DIRECTIVES
CFI_DEF_CFA,
CFI_COMMON_REGISTERS,
...
STUB_BODY
asm code to establish frame, setup the cfa reg value,
call the real signal handler, ...
SYMBOL_END
*/
/*--------------------------------
-- Misc constants and helpers --
-------------------------------- */
/* asm string construction helpers. */
#define STR(TEXT) #TEXT
/* stringify expanded TEXT, surrounding it with double quotes. */
#define S(E) STR(E)
/* stringify E, which will resolve as text but may contain macros
still to be expanded. */
/* asm (TEXT) outputs <tab>TEXT. These facilitate the output of
multine contents: */
#define TAB(S) "\t" S
#define CR(S) S "\n"
#undef TCR
#define TCR(S) TAB(CR(S))
/* REGNO constants, dwarf column numbers for registers of interest. */
#if defined (__PPC__)
#define REGNO_LR 65
#define REGNO_CTR 66
#define REGNO_CR 70
#define REGNO_XER 76
#define REGNO_GR(N) (N)
#define REGNO_PC 67 /* ARG_POINTER_REGNUM */
#define FUNCTION "@function"
#elif defined (__ARMEL__)
#define REGNO_G_REG_OFFSET(N) (N)
#define REGNO_PC_OFFSET 15 /* PC_REGNUM */
#define FUNCTION "%function"
#elif defined (i386)
/* These are the cfi colunm numbers */
#define REGNO_EDI 7
#define REGNO_ESI 6
#define REGNO_EBP 5
#define REGNO_ESP 4
#define REGNO_EBX 3
#define REGNO_EDX 2
#define REGNO_ECX 1
#define REGNO_EAX 0
#define REGNO_EFLAGS 9
#define REGNO_SET_PC 8 /* aka %eip */
#define FUNCTION "@function"
/* Mapping of CFI Column, Gcc Regno, Signal context offset for 32bit
Name CFI GCC SCTX
%eax 0 0 7
%ecx 1 2 6
%edx 2 1 5
%ebx 3 3 4
%esp 4 7 3
%ebp 5 6 2
%esi 6 4 1
%edi 7 5 0
%eflags 9 17 8
%eip 8 n/a 9
In general:
There is no unique numbering for the x86 architecture. It's parameterized
by DWARF_FRAME_REGNUM, which is DBX_REGISTER_NUMBER except for Windows, and
the latter depends on the platform.
*/
#else
Not_implemented;
#endif /* REGNO constants */
/*------------------------------
-- Stub construction blocks --
------------------------------ */
/* CFA setup block
---------------
Only non-volatile registers are suitable for a CFA base. These are the
only ones we can expect to be able retrieve from the unwinding context
while walking up the chain, saved by at least the bottom-most exception
propagation services. We set a non-volatile register to the value we
need in the stub body that follows. */
#if defined (__PPC__)
/* Use r15 for PPC. Note that r14 is inappropriate here, even though it
is non-volatile according to the ABI, because GCC uses it as an extra
SCRATCH on SPE targets. */
#define CFA_REG 15
#elif defined (__ARMEL__)
/* Use r8 for ARM. Any of r4-r8 should work. */
#define CFA_REG 8
#elif defined (i386)
#define CFA_REG 7
#else
Not_implemented;
#endif /* CFA setup block */
#define CFI_DEF_CFA \
CR(".cfi_def_cfa " S(CFA_REG) ", 0")
/* Register location blocks
------------------------
Rules to find registers of interest from the CFA. This should comprise
all the non-volatile registers relevant to the interrupted context.
Note that we include r1 in this set, unlike the libgcc unwinding
fallbacks. This is useful for fallbacks to allow the use of r1 in CFI
expressions and the absence of rule for r1 gets compensated by using the
target CFA instead. We don't need the expression facility here and
setup a fake CFA to allow very simple offset expressions, so having a
rule for r1 is the proper thing to do. We for sure have observed
crashes in some cases without it. */
#if defined (__PPC__)
#define COMMON_CFI(REG) \
".cfi_offset " S(REGNO_##REG) "," S(REG_SET_##REG)
#define CFI_COMMON_REGS \
CR("# CFI for common registers\n") \
TCR(COMMON_CFI(GR(0))) \
TCR(COMMON_CFI(GR(1))) \
TCR(COMMON_CFI(GR(2))) \
TCR(COMMON_CFI(GR(3))) \
TCR(COMMON_CFI(GR(4))) \
TCR(COMMON_CFI(GR(5))) \
TCR(COMMON_CFI(GR(6))) \
TCR(COMMON_CFI(GR(7))) \
TCR(COMMON_CFI(GR(8))) \
TCR(COMMON_CFI(GR(9))) \
TCR(COMMON_CFI(GR(10))) \
TCR(COMMON_CFI(GR(11))) \
TCR(COMMON_CFI(GR(12))) \
TCR(COMMON_CFI(GR(13))) \
TCR(COMMON_CFI(GR(14))) \
TCR(COMMON_CFI(GR(15))) \
TCR(COMMON_CFI(GR(16))) \
TCR(COMMON_CFI(GR(17))) \
TCR(COMMON_CFI(GR(18))) \
TCR(COMMON_CFI(GR(19))) \
TCR(COMMON_CFI(GR(20))) \
TCR(COMMON_CFI(GR(21))) \
TCR(COMMON_CFI(GR(22))) \
TCR(COMMON_CFI(GR(23))) \
TCR(COMMON_CFI(GR(24))) \
TCR(COMMON_CFI(GR(25))) \
TCR(COMMON_CFI(GR(26))) \
TCR(COMMON_CFI(GR(27))) \
TCR(COMMON_CFI(GR(28))) \
TCR(COMMON_CFI(GR(29))) \
TCR(COMMON_CFI(GR(30))) \
TCR(COMMON_CFI(GR(31))) \
TCR(COMMON_CFI(LR)) \
TCR(COMMON_CFI(CR)) \
TCR(COMMON_CFI(CTR)) \
TCR(COMMON_CFI(XER)) \
TCR(COMMON_CFI(PC)) \
TCR(".cfi_return_column " S(REGNO_PC))
/* Trampoline body block
--------------------- */
#define SIGTRAMP_BODY \
CR("") \
TCR("# Allocate frame and save the non-volatile") \
TCR("# registers we're going to modify") \
TCR("stwu %r1,-16(%r1)") \
TCR("mflr %r0") \
TCR("stw %r0,20(%r1)") \
TCR("stw %r" S(CFA_REG) ",8(%r1)") \
TCR("") \
TCR("# Setup CFA_REG = context, which we'll retrieve as our CFA value") \
TCR("mr %r" S(CFA_REG) ", %r7") \
TCR("") \
TCR("# Call the real handler. The signo, siginfo and sigcontext") \
TCR("# arguments are the same as those we received in r3, r4 and r5") \
TCR("mtctr %r6") \
TCR("bctrl") \
TCR("") \
TCR("# Restore our callee-saved items, release our frame and return") \
TCR("lwz %r" S(CFA_REG) ",8(%r1)") \
TCR("lwz %r0,20(%r1)") \
TCR("mtlr %r0") \
TCR("") \
TCR("addi %r1,%r1,16") \
TCR("blr")
#elif defined (__ARMEL__)
#define COMMON_CFI(REG) \
".cfi_offset " S(REGNO_##REG) "," S(REG_SET_##REG)
#define CFI_COMMON_REGS \
CR("# CFI for common registers\n") \
TCR(COMMON_CFI(G_REG_OFFSET(0))) \
TCR(COMMON_CFI(G_REG_OFFSET(1))) \
TCR(COMMON_CFI(G_REG_OFFSET(2))) \
TCR(COMMON_CFI(G_REG_OFFSET(3))) \
TCR(COMMON_CFI(G_REG_OFFSET(4))) \
TCR(COMMON_CFI(G_REG_OFFSET(5))) \
TCR(COMMON_CFI(G_REG_OFFSET(6))) \
TCR(COMMON_CFI(G_REG_OFFSET(7))) \
TCR(COMMON_CFI(G_REG_OFFSET(8))) \
TCR(COMMON_CFI(G_REG_OFFSET(9))) \
TCR(COMMON_CFI(G_REG_OFFSET(10))) \
TCR(COMMON_CFI(G_REG_OFFSET(11))) \
TCR(COMMON_CFI(G_REG_OFFSET(12))) \
TCR(COMMON_CFI(G_REG_OFFSET(13))) \
TCR(COMMON_CFI(G_REG_OFFSET(14))) \
TCR(COMMON_CFI(PC_OFFSET)) \
TCR(".cfi_return_column " S(REGNO_PC_OFFSET))
/* Trampoline body block
--------------------- */
#define SIGTRAMP_BODY \
CR("") \
TCR("# Allocate frame and save the non-volatile") \
TCR("# registers we're going to modify") \
TCR("mov ip, sp") \
TCR("stmfd sp!, {r"S(CFA_REG)", fp, ip, lr, pc}") \
TCR("# Setup CFA_REG = context, which we'll retrieve as our CFA value") \
TCR("ldr r"S(CFA_REG)", [ip]") \
TCR("") \
TCR("# Call the real handler. The signo, siginfo and sigcontext") \
TCR("# arguments are the same as those we received in r0, r1 and r2") \
TCR("sub fp, ip, #4") \
TCR("blx r3") \
TCR("# Restore our callee-saved items, release our frame and return") \
TCR("ldmfd sp, {r"S(CFA_REG)", fp, sp, pc}")
#elif defined (i386)
#if CPU == SIMNT || CPU == SIMPENTIUM
#define COMMON_CFI(REG) \
".cfi_offset " S(REGNO_##REG) "," S(REG_SET_##REG)
#else
#define COMMON_CFI(REG) \
".cfi_offset " S(REGNO_##REG) "," S(REG_##REG)
#endif
#define PC_CFI(REG) \
".cfi_offset " S(REGNO_##REG) "," S(REG_##REG)
#define CFI_COMMON_REGS \
CR("# CFI for common registers\n") \
TCR(COMMON_CFI(EDI)) \
TCR(COMMON_CFI(ESI)) \
TCR(COMMON_CFI(EBP)) \
TCR(COMMON_CFI(ESP)) \
TCR(COMMON_CFI(EBX)) \
TCR(COMMON_CFI(EDX)) \
TCR(COMMON_CFI(ECX)) \
TCR(COMMON_CFI(EAX)) \
TCR(COMMON_CFI(EFLAGS)) \
TCR(PC_CFI(SET_PC)) \
TCR(".cfi_return_column " S(REGNO_SET_PC))
/* Trampoline body block
--------------------- */
#define SIGTRAMP_BODY \
CR("") \
TCR("# Allocate frame and save the non-volatile") \
TCR("# registers we're going to modify") \
TCR("pushl %ebp") \
TCR("movl %esp, %ebp") \
TCR("pushl %edi") \
TCR("subl $24, %esp") \
TCR("# Setup CFA_REG = context, which we'll retrieve as our CFA value") \
TCR("movl 24(%ebp), %edi") \
TCR("# Call the real handler. The signo, siginfo and sigcontext") \
TCR("# arguments are the same as those we received") \
TCR("movl 16(%ebp), %eax") \
TCR("movl %eax, 8(%esp)") \
TCR("movl 12(%ebp), %eax") \
TCR("movl %eax, 4(%esp)") \
TCR("movl 8(%ebp), %eax") \
TCR("movl %eax, (%esp)") \
TCR("call *20(%ebp)") \
TCR("# Restore our callee-saved items, release our frame and return") \
TCR("popl %edi") \
TCR("leave") \
TCR("ret")
#else
Not_implemented;
#endif /* CFI_COMMON_REGS and SIGTRAMP_BODY */
/* Symbol definition block
----------------------- */
#define SIGTRAMP_START(SYM) \
CR("# " S(SYM) " cfi trampoline") \
TCR(".type " S(SYM) ", "FUNCTION) \
CR("") \
CR(S(SYM) ":") \
TCR(".cfi_startproc") \
TCR(".cfi_signal_frame")
/* Symbol termination block
------------------------ */
#define SIGTRAMP_END(SYM) \
CR(".cfi_endproc") \
TCR(".size " S(SYM) ", .-" S(SYM))
/*----------------------------
-- And now, the real code --
---------------------------- */
/* Text section start. The compiler isn't aware of that switch. */
asm (".text\n"
TCR(".align 2"));

View File

@ -0,0 +1,146 @@
/****************************************************************************
* *
* GNAT COMPILER COMPONENTS *
* *
* S I G T R A M P *
* *
* Asm Implementation File *
* *
* Copyright (C) 2011-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- *
* ware Foundation; either version 3, or (at your option) any later ver- *
* sion. GNAT is distributed in the hope that it will be useful, but WITH- *
* OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY *
* or FITNESS FOR A PARTICULAR PURPOSE. *
* *
* As a special exception under Section 7 of GPL version 3, you are granted *
* additional permissions described in the GCC Runtime Library Exception, *
* version 3.1, as published by the Free Software Foundation. *
* *
* In particular, you can freely distribute your programs built with the *
* GNAT Pro compiler, including any required library run-time units, using *
* any licensing terms of your choosing. See the AdaCore Software License *
* for full details. *
* *
* GNAT was originally developed by the GNAT team at New York University. *
* Extensive contributions were provided by Ada Core Technologies Inc. *
* *
****************************************************************************/
/********************************************************
* VxWorks VXSIM version of the __gnat_sigtramp service *
********************************************************/
#undef CPU
#ifndef __RTP__
#define CPU SIMNT
#else
#define CPU SIMPENTIUM
#endif
#include "sigtramp.h"
/* See sigtramp.h for a general explanation of functionality. */
#include <vxWorks.h>
#include <arch/../regs.h>
#ifndef __RTP__
#include <sigLib.h>
#else
#include <signal.h>
#include <regs.h>
typedef struct mcontext
{
REG_SET regs;
} mcontext_t;
typedef struct ucontext
{
mcontext_t uc_mcontext; /* register set */
struct ucontext * uc_link; /* not used */
sigset_t uc_sigmask; /* set of signals blocked */
stack_t uc_stack; /* stack of context signaled */
} ucontext_t;
#endif
/* ----------------------
-- General comments --
----------------------
Stubs are generated from toplevel asms and .cfi directives, much simpler
to use and check for correctness than manual encodings of CFI byte
sequences. The general idea is to establish CFA as sigcontext->sc_pregs
(for DKM) and mcontext (for RTP) and state where to find the registers as
offsets from there.
As of today, we support a stub providing CFI info for common
registers (GPRs, LR, ...). We might need variants with support for floating
point or altivec registers as well at some point.
Checking which variant should apply and getting at sc_pregs / mcontext
is simpler to express in C (we can't use offsetof in toplevel asms and
hardcoding constants is not workable with the flurry of VxWorks variants),
so this is the choice for our toplevel interface.
Note that the registers we "restore" here are those to which we have
direct access through the system sigcontext structure, which includes
only a partial set of the non-volatiles ABI-wise. */
/* -------------------------------------------
-- Prototypes for our internal asm stubs --
-------------------------------------------
Eventhough our symbols will remain local, the prototype claims "extern"
and not "static" to prevent compiler complaints about a symbol used but
never defined. */
/* sigtramp stub providing CFI info for common registers. */
extern void __gnat_sigtramp_vxsim_common
(int signo, void *siginfo, void *sigcontext,
__sigtramphandler_t * handler, void * sc_pregs);
/* -------------------------------------
-- Common interface implementation --
-------------------------------------
We enforce optimization to minimize the overhead of the extra layer. */
void __gnat_sigtramp_vxsim (int signo, void *si, void *sc,
__sigtramphandler_t * handler)
__attribute__((optimize(2)));
void __gnat_sigtramp_vxsim (int signo, void *si, void *sc,
__sigtramphandler_t * handler)
{
#ifdef __RTP__
mcontext_t *mcontext = &((ucontext_t *) sc)->uc_mcontext;
/* Pass MCONTEXT in the fifth position so that the assembly code can find
it at the same stack location or in the same register as SC_PREGS. */
__gnat_sigtramp_vxsim_common (signo, si, mcontext, handler, mcontext);
#else
struct sigcontext * sctx = (struct sigcontext *) sc;
__gnat_sigtramp_vxsim_common (signo, si, sctx, handler, sctx->sc_pregs);
#endif
}
/* Include the target specific bits. */
#include "sigtramp-vxworks-target.inc"
/* sigtramp stub for common registers. */
#define TRAMP_COMMON __gnat_sigtramp_vxsim_common
asm (SIGTRAMP_START(TRAMP_COMMON));
asm (CFI_DEF_CFA);
asm (CFI_COMMON_REGS);
asm (SIGTRAMP_BODY);
asm (SIGTRAMP_END(TRAMP_COMMON));

View File

@ -6,7 +6,7 @@
* *
* Asm Implementation File *
* *
* Copyright (C) 2011-2014, Free Software Foundation, Inc. *
* Copyright (C) 2011-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- *
@ -122,267 +122,8 @@ void __gnat_sigtramp (int signo, void *si, void *sc,
#endif
}
/* ---------------------------
-- And now the asm stubs --
---------------------------
They all have a common structure with blocks of asm sequences queued one
after the others. Typically:
SYMBOL_START
CFI_DIRECTIVES
CFI_DEF_CFA,
CFI_COMMON_REGISTERS,
...
STUB_BODY
asm code to establish frame, setup the cfa reg value,
call the real signal handler, ...
SYMBOL_END
*/
/*--------------------------------
-- Misc constants and helpers --
-------------------------------- */
/* asm string construction helpers. */
#define STR(TEXT) #TEXT
/* stringify expanded TEXT, surrounding it with double quotes. */
#define S(E) STR(E)
/* stringify E, which will resolve as text but may contain macros
still to be expanded. */
/* asm (TEXT) outputs <tab>TEXT. These facilitate the output of
multine contents: */
#define TAB(S) "\t" S
#define CR(S) S "\n"
#undef TCR
#define TCR(S) TAB(CR(S))
/* REGNO constants, dwarf column numbers for registers of interest. */
#if defined (__PPC__)
#define REGNO_LR 65
#define REGNO_CTR 66
#define REGNO_CR 70
#define REGNO_XER 76
#define REGNO_GR(N) (N)
#define REGNO_PC 67 /* ARG_POINTER_REGNUM */
#define FUNCTION "@function"
#elif defined (__ARMEL__)
#define REGNO_G_REG_OFFSET(N) (N)
#define REGNO_PC_OFFSET 15 /* PC_REGNUM */
#define FUNCTION "%function"
#else
Not_implemented;
#endif /* REGNO constants */
/*------------------------------
-- Stub construction blocks --
------------------------------ */
/* CFA setup block
---------------
Only non-volatile registers are suitable for a CFA base. These are the
only ones we can expect to be able retrieve from the unwinding context
while walking up the chain, saved by at least the bottom-most exception
propagation services. We set a non-volatile register to the value we
need in the stub body that follows. */
#if defined (__PPC__)
/* Use r15 for PPC. Note that r14 is inappropriate here, even though it
is non-volatile according to the ABI, because GCC uses it as an extra
SCRATCH on SPE targets. */
#define CFA_REG 15
#elif defined (__ARMEL__)
/* Use r8 for ARM. Any of r4-r8 should work. */
#define CFA_REG 8
#else
Not_implemented;
#endif /* CFA setup block */
#define CFI_DEF_CFA \
CR(".cfi_def_cfa " S(CFA_REG) ", 0")
/* Register location blocks
------------------------
Rules to find registers of interest from the CFA. This should comprise
all the non-volatile registers relevant to the interrupted context.
Note that we include r1 in this set, unlike the libgcc unwinding
fallbacks. This is useful for fallbacks to allow the use of r1 in CFI
expressions and the absence of rule for r1 gets compensated by using the
target CFA instead. We don't need the expression facility here and
setup a fake CFA to allow very simple offset expressions, so having a
rule for r1 is the proper thing to do. We for sure have observed
crashes in some cases without it. */
#define COMMON_CFI(REG) \
".cfi_offset " S(REGNO_##REG) "," S(REG_SET_##REG)
#if defined (__PPC__)
#define CFI_COMMON_REGS \
CR("# CFI for common registers\n") \
TCR(COMMON_CFI(GR(0))) \
TCR(COMMON_CFI(GR(1))) \
TCR(COMMON_CFI(GR(2))) \
TCR(COMMON_CFI(GR(3))) \
TCR(COMMON_CFI(GR(4))) \
TCR(COMMON_CFI(GR(5))) \
TCR(COMMON_CFI(GR(6))) \
TCR(COMMON_CFI(GR(7))) \
TCR(COMMON_CFI(GR(8))) \
TCR(COMMON_CFI(GR(9))) \
TCR(COMMON_CFI(GR(10))) \
TCR(COMMON_CFI(GR(11))) \
TCR(COMMON_CFI(GR(12))) \
TCR(COMMON_CFI(GR(13))) \
TCR(COMMON_CFI(GR(14))) \
TCR(COMMON_CFI(GR(15))) \
TCR(COMMON_CFI(GR(16))) \
TCR(COMMON_CFI(GR(17))) \
TCR(COMMON_CFI(GR(18))) \
TCR(COMMON_CFI(GR(19))) \
TCR(COMMON_CFI(GR(20))) \
TCR(COMMON_CFI(GR(21))) \
TCR(COMMON_CFI(GR(22))) \
TCR(COMMON_CFI(GR(23))) \
TCR(COMMON_CFI(GR(24))) \
TCR(COMMON_CFI(GR(25))) \
TCR(COMMON_CFI(GR(26))) \
TCR(COMMON_CFI(GR(27))) \
TCR(COMMON_CFI(GR(28))) \
TCR(COMMON_CFI(GR(29))) \
TCR(COMMON_CFI(GR(30))) \
TCR(COMMON_CFI(GR(31))) \
TCR(COMMON_CFI(LR)) \
TCR(COMMON_CFI(CR)) \
TCR(COMMON_CFI(CTR)) \
TCR(COMMON_CFI(XER)) \
TCR(COMMON_CFI(PC)) \
TCR(".cfi_return_column " S(REGNO_PC))
/* Trampoline body block
--------------------- */
#define SIGTRAMP_BODY \
CR("") \
TCR("# Allocate frame and save the non-volatile") \
TCR("# registers we're going to modify") \
TCR("stwu %r1,-16(%r1)") \
TCR("mflr %r0") \
TCR("stw %r0,20(%r1)") \
TCR("stw %r" S(CFA_REG) ",8(%r1)") \
TCR("") \
TCR("# Setup CFA_REG = context, which we'll retrieve as our CFA value") \
TCR("mr %r" S(CFA_REG) ", %r7") \
TCR("") \
TCR("# Call the real handler. The signo, siginfo and sigcontext") \
TCR("# arguments are the same as those we received in r3, r4 and r5") \
TCR("mtctr %r6") \
TCR("bctrl") \
TCR("") \
TCR("# Restore our callee-saved items, release our frame and return") \
TCR("lwz %r" S(CFA_REG) ",8(%r1)") \
TCR("lwz %r0,20(%r1)") \
TCR("mtlr %r0") \
TCR("") \
TCR("addi %r1,%r1,16") \
TCR("blr")
#elif defined (__ARMEL__)
#define CFI_COMMON_REGS \
CR("# CFI for common registers\n") \
TCR(COMMON_CFI(G_REG_OFFSET(0))) \
TCR(COMMON_CFI(G_REG_OFFSET(1))) \
TCR(COMMON_CFI(G_REG_OFFSET(2))) \
TCR(COMMON_CFI(G_REG_OFFSET(3))) \
TCR(COMMON_CFI(G_REG_OFFSET(4))) \
TCR(COMMON_CFI(G_REG_OFFSET(5))) \
TCR(COMMON_CFI(G_REG_OFFSET(6))) \
TCR(COMMON_CFI(G_REG_OFFSET(7))) \
TCR(COMMON_CFI(G_REG_OFFSET(8))) \
TCR(COMMON_CFI(G_REG_OFFSET(9))) \
TCR(COMMON_CFI(G_REG_OFFSET(10))) \
TCR(COMMON_CFI(G_REG_OFFSET(11))) \
TCR(COMMON_CFI(G_REG_OFFSET(12))) \
TCR(COMMON_CFI(G_REG_OFFSET(13))) \
TCR(COMMON_CFI(G_REG_OFFSET(14))) \
TCR(COMMON_CFI(PC_OFFSET)) \
TCR(".cfi_return_column " S(REGNO_PC_OFFSET))
/* Trampoline body block
--------------------- */
#define SIGTRAMP_BODY \
CR("") \
TCR("# Allocate frame and save the non-volatile") \
TCR("# registers we're going to modify") \
TCR("mov ip, sp") \
TCR("stmfd sp!, {r" S(CFA_REG)", fp, ip, lr, pc}") \
TCR("# Setup CFA_REG = context, which we'll retrieve as our CFA value") \
TCR("ldr r" S(CFA_REG)", [ip]") \
TCR("") \
TCR("# Call the real handler. The signo, siginfo and sigcontext") \
TCR("# arguments are the same as those we received in r0, r1 and r2") \
TCR("sub fp, ip, #4") \
TCR("blx r3") \
TCR("# Restore our callee-saved items, release our frame and return") \
TCR("ldmfd sp, {r" S(CFA_REG)", fp, sp, pc}")
#else
Not_implemented;
#endif /* CFI_COMMON_REGS and SIGTRAMP_BODY */
/* Symbol definition block
----------------------- */
#define SIGTRAMP_START(SYM) \
CR("# " S(SYM) " cfi trampoline") \
TCR(".type " S(SYM) ", "FUNCTION) \
CR("") \
CR(S(SYM) ":") \
TCR(".cfi_startproc") \
TCR(".cfi_signal_frame")
/* Symbol termination block
------------------------ */
#define SIGTRAMP_END(SYM) \
CR(".cfi_endproc") \
TCR(".size " S(SYM) ", .-" S(SYM))
/*----------------------------
-- And now, the real code --
---------------------------- */
/* Text section start. The compiler isn't aware of that switch. */
asm (".text\n"
TCR(".align 2"));
/* Include the target specific bits. */
#include "sigtramp-vxworks-target.inc"
/* sigtramp stub for common registers. */

View File

@ -6,7 +6,7 @@
* *
* C Header File *
* *
* Copyright (C) 2011-2014, Free Software Foundation, Inc. *
* Copyright (C) 2011-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- *
@ -62,8 +62,14 @@ typedef struct ucontext
system headers so call it something unique. */
typedef void __sigtramphandler_t (int signo, void *siginfo, void *sigcontext);
#if CPU == SIMNT || CPU == SIMPENTIUM
/* Vxsim requires a specially compiled handler. */
void __gnat_sigtramp_vxsim (int signo, void *siginfo, void *sigcontext,
__sigtramphandler_t * handler);
#else
void __gnat_sigtramp (int signo, void *siginfo, void *sigcontext,
__sigtramphandler_t * handler);
#endif
/* To be called from an established signal handler. Setup the DWARF CFI
bits letting unwinders walk through the signal frame up into the