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;