File : s-traceb-xi-sparc.adb


   1 ------------------------------------------------------------------------------
   2 --                                                                          --
   3 --                         GNAT COMPILER COMPONENTS                         --
   4 --                                                                          --
   5 --                     S Y S T E M . T R A C E B A C K                      --
   6 --                                                                          --
   7 --                                 B o d y                                  --
   8 --                                                                          --
   9 --          Copyright (C) 1999-2014, Free Software Foundation, Inc.         --
  10 --                                                                          --
  11 -- GNAT is free software;  you can  redistribute it  and/or modify it under --
  12 -- terms of the  GNU General Public License as published  by the Free Soft- --
  13 -- ware  Foundation;  either version 3,  or (at your option) any later ver- --
  14 -- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
  15 -- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
  16 -- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
  17 --                                                                          --
  18 --                                                                          --
  19 --                                                                          --
  20 --                                                                          --
  21 --                                                                          --
  22 -- You should have received a copy of the GNU General Public License and    --
  23 -- a copy of the GCC Runtime Library Exception along with this program;     --
  24 -- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
  25 -- <http://www.gnu.org/licenses/>.                                          --
  26 --                                                                          --
  27 -- GNAT was originally developed  by the GNAT team at  New York University. --
  28 -- It is now maintained by Ada Core Technologies Inc (http://www.gnat.com). --
  29 --                                                                          --
  30 ------------------------------------------------------------------------------
  31 
  32 with System.Address_To_Access_Conversions;
  33 with Interfaces.C;
  34 with System.Machine_Code; use System.Machine_Code;
  35 
  36 --  This is the bare board version of this package for SPARC targets
  37 
  38 package body System.Traceback is
  39 
  40    package Addr is new System.Address_To_Access_Conversions (System.Address);
  41    use Addr;
  42 
  43    procedure Call_Chain
  44      (Traceback   : in out System.Traceback_Entries.Tracebacks_Array;
  45       Max_Len     : Natural;
  46       Len         : out Natural;
  47       Exclude_Min : System.Address := System.Null_Address;
  48       Exclude_Max : System.Address := System.Null_Address;
  49       Skip_Frames : Natural := 1)
  50    is
  51       Frame_Link_Offset : constant System.Address :=
  52         14 * System.Address'Size / System.Storage_Unit;
  53       pragma Assert (Frame_Link_Offset mod System.Address'Alignment = 0);
  54       --  Offset of memory location where address of previous frame is stored,
  55       --  relative to current frame. This must be a multiple of
  56       --  System.Address'Alignment.
  57 
  58       Return_Address_Offset : constant System.Address :=
  59         15 * System.Address'Size / System.Storage_Unit;
  60       pragma Assert (Return_Address_Offset mod System.Address'Alignment = 0);
  61       --  Offset in bytes where the return address of current frame is stored,
  62       --  relative to the current frame. This must be a multiple of
  63       --  System.Address'Alignment.
  64 
  65       PC_Adjust : constant := 0;
  66       --  Size of call instruction to subtract from return address to get the
  67       --  PC for the calling frame.
  68 
  69       Frame : System.Address;
  70       --  Frame being processed
  71 
  72       Last : Integer := Traceback'First - 1;
  73       --  Index of last traceback entry written to the buffer
  74 
  75    begin
  76       Len := 0;
  77 
  78       --  Flush register windows before we attempt to access them on the stack
  79 
  80       Asm ("ta 3", Volatile => True);
  81 
  82       --  Move contents of r30 (fp) to "Frame"
  83 
  84       Asm ("mov %%fp, %0",
  85            Outputs => Address'Asm_Output ("=r", Frame),
  86            Volatile => True);
  87 
  88       --  Exclude Skip_Frames frames from the traceback. The SPARC ABI has
  89       --  System.Null_Address as the back pointer of the shallowest frame in
  90       --  the stack.
  91 
  92       for J in 1 .. Skip_Frames - 1 loop
  93          if Frame = System.Null_Address
  94            or else Frame mod System.Address'Alignment /= 0
  95            or else To_Pointer (Frame + Frame_Link_Offset).all = Null_Address
  96          then
  97             --  Something is wrong.  Skip_Frames is greater than the number of
  98             --  frames on the current stack. Do not return a trace.
  99 
 100             return;
 101          end if;
 102 
 103          Frame := To_Pointer (Frame + Frame_Link_Offset).all;
 104       end loop;
 105 
 106       pragma Assert (Frame /= System.Null_Address);
 107 
 108       while Frame mod System.Address'Alignment = 0
 109         and then To_Pointer (Frame + Frame_Link_Offset).all /= Null_Address
 110         and then Last < Traceback'Last
 111         and then Len < Max_Len
 112       loop
 113          declare
 114             PC : constant System.Address :=
 115                    To_Pointer (Frame + Return_Address_Offset).all - PC_Adjust;
 116 
 117          begin
 118             if PC not in Exclude_Min .. Exclude_Max then
 119 
 120                --  Skip specified routines, if any (e.g. Ada.Exceptions)
 121 
 122                Last := Last + 1;
 123                Len := Len + 1;
 124                Traceback (Last) := PC;
 125             end if;
 126 
 127             Frame := To_Pointer (Frame + Frame_Link_Offset).all;
 128          end;
 129 
 130          pragma Assert (Frame /= System.Null_Address);
 131       end loop;
 132    end Call_Chain;
 133 
 134 end System.Traceback;