mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-23 01:30:29 +08:00
[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:
parent
b9eb3aa8a2
commit
e8c84c8fc3
@ -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
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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:
|
||||
|
||||
|
@ -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
67
gcc/ada/init-vxsim.c
Normal 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);
|
||||
}
|
@ -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;
|
||||
}
|
||||
|
||||
|
@ -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;
|
||||
|
@ -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
|
||||
|
@ -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)));
|
||||
|
||||
|
@ -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
|
||||
|
399
gcc/ada/sigtramp-vxworks-target.inc
Normal file
399
gcc/ada/sigtramp-vxworks-target.inc
Normal 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"));
|
||||
|
146
gcc/ada/sigtramp-vxworks-vxsim.c
Normal file
146
gcc/ada/sigtramp-vxworks-vxsim.c
Normal 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));
|
||||
|
||||
|
@ -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. */
|
||||
|
||||
|
@ -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
|
||||
|
Loading…
x
Reference in New Issue
Block a user