gcc:
[official-gcc.git] / gcc / ada / symbols-processing-vms-ia64.adb
blob5d62c3ce790c1d0035f5f95a7dd515a8b70c4bab
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- S Y M B O L S . P R O C E S S I N G --
6 -- --
7 -- B o d y --
8 -- --
9 -- Copyright (C) 2004-2006, 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 2, 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. See the GNU General Public License --
17 -- for more details. You should have received a copy of the GNU General --
18 -- Public License distributed with GNAT; see file COPYING. If not, write --
19 -- to the Free Software Foundation, 51 Franklin Street, Fifth Floor, --
20 -- Boston, MA 02110-1301, USA. --
21 -- --
22 -- GNAT was originally developed by the GNAT team at New York University. --
23 -- Extensive contributions were provided by Ada Core Technologies Inc. --
24 -- --
25 ------------------------------------------------------------------------------
27 -- This is the VMS/IA64 version of this package
29 with Ada.IO_Exceptions;
31 with Ada.Unchecked_Deallocation;
33 separate (Symbols)
34 package body Processing is
36 type String_Array is array (Positive range <>) of String_Access;
37 type Strings_Ptr is access String_Array;
39 procedure Free is
40 new Ada.Unchecked_Deallocation (String_Array, Strings_Ptr);
42 type Section_Header is record
43 Shname : Integer;
44 Shtype : Integer;
45 Shoffset : Integer;
46 Shsize : Integer;
47 Shlink : Integer;
48 end record;
50 type Section_Header_Array is array (Natural range <>) of Section_Header;
51 type Section_Header_Ptr is access Section_Header_Array;
53 procedure Free is
54 new Ada.Unchecked_Deallocation (Section_Header_Array, Section_Header_Ptr);
56 -------------
57 -- Process --
58 -------------
60 procedure Process
61 (Object_File : String;
62 Success : out Boolean)
64 B : Byte;
65 H : Integer;
66 W : Integer;
68 Str : String (1 .. 1000) := (others => ' ');
69 Str_Last : Natural;
71 Strings : Strings_Ptr;
73 Shoff : Integer;
74 Shnum : Integer;
75 Shentsize : Integer;
77 Shname : Integer;
78 Shtype : Integer;
79 Shoffset : Integer;
80 Shsize : Integer;
81 Shlink : Integer;
83 Symtab_Index : Natural := 0;
84 String_Table_Index : Natural := 0;
86 End_Symtab : Integer;
88 Stname : Integer;
89 Stinfo : Character;
90 Sttype : Integer;
91 Stbind : Integer;
92 Stshndx : Integer;
94 Section_Headers : Section_Header_Ptr;
96 Offset : Natural := 0;
97 OK : Boolean := True;
99 procedure Get_Byte (B : out Byte);
100 procedure Get_Half (H : out Integer);
101 procedure Get_Word (W : out Integer);
102 procedure Reset;
103 -- All the above require comments ???
105 --------------
106 -- Get_Byte --
107 --------------
109 procedure Get_Byte (B : out Byte) is
110 begin
111 Byte_IO.Read (File, B);
112 Offset := Offset + 1;
113 end Get_Byte;
115 --------------
116 -- Get_Half --
117 --------------
119 procedure Get_Half (H : out Integer) is
120 C1, C2 : Character;
121 begin
122 Get_Byte (C1); Get_Byte (C2);
123 H :=
124 Integer'(Character'Pos (C2)) * 256 + Integer'(Character'Pos (C1));
125 end Get_Half;
127 --------------
128 -- Get_Word --
129 --------------
131 procedure Get_Word (W : out Integer) is
132 H1, H2 : Integer;
133 begin
134 Get_Half (H1); Get_Half (H2);
135 W := H2 * 256 * 256 + H1;
136 end Get_Word;
138 -----------
139 -- Reset --
140 -----------
142 procedure Reset is
143 begin
144 Offset := 0;
145 Byte_IO.Reset (File);
146 end Reset;
148 -- Start of processing for Process
150 begin
151 -- Open the object file with Byte_IO. Return with Success = False if
152 -- this fails.
154 begin
155 Open (File, In_File, Object_File);
156 exception
157 when others =>
158 Put_Line
159 ("*** Unable to open object file """ & Object_File & """");
160 Success := False;
161 return;
162 end;
164 -- Assume that the object file has a correct format
166 Success := True;
168 -- Skip ELF identification
170 while Offset < 16 loop
171 Get_Byte (B);
172 end loop;
174 -- Skip e_type
176 Get_Half (H);
178 -- Skip e_machine
180 Get_Half (H);
182 -- Skip e_version
184 Get_Word (W);
186 -- Skip e_entry
188 for J in 1 .. 8 loop
189 Get_Byte (B);
190 end loop;
192 -- Skip e_phoff
194 for J in 1 .. 8 loop
195 Get_Byte (B);
196 end loop;
198 Get_Word (Shoff);
200 -- Skip upper half of Shoff
202 for J in 1 .. 4 loop
203 Get_Byte (B);
204 end loop;
206 -- Skip e_flags
208 Get_Word (W);
210 -- Skip e_ehsize
212 Get_Half (H);
214 -- Skip e_phentsize
216 Get_Half (H);
218 -- Skip e_phnum
220 Get_Half (H);
222 Get_Half (Shentsize);
224 Get_Half (Shnum);
226 Section_Headers := new Section_Header_Array (0 .. Shnum - 1);
228 -- Go to Section Headers
230 while Offset < Shoff loop
231 Get_Byte (B);
232 end loop;
234 -- Reset Symtab_Index
236 Symtab_Index := 0;
238 for J in Section_Headers'Range loop
240 -- Get the data for each Section Header
242 Get_Word (Shname);
243 Get_Word (Shtype);
245 for K in 1 .. 16 loop
246 Get_Byte (B);
247 end loop;
249 Get_Word (Shoffset);
250 Get_Word (W);
252 Get_Word (Shsize);
253 Get_Word (W);
255 Get_Word (Shlink);
257 while (Offset - Shoff) mod Shentsize /= 0 loop
258 Get_Byte (B);
259 end loop;
261 -- If this is the Symbol Table Section Header, record its index
263 if Shtype = 2 then
264 Symtab_Index := J;
265 end if;
267 Section_Headers (J) := (Shname, Shtype, Shoffset, Shsize, Shlink);
268 end loop;
270 if Symtab_Index = 0 then
271 Success := False;
272 return;
273 end if;
275 End_Symtab :=
276 Section_Headers (Symtab_Index).Shoffset +
277 Section_Headers (Symtab_Index).Shsize;
279 String_Table_Index := Section_Headers (Symtab_Index).Shlink;
280 Strings :=
281 new String_Array (1 .. Section_Headers (String_Table_Index).Shsize);
283 -- Go get the String Table section for the Symbol Table
285 Reset;
287 while Offset < Section_Headers (String_Table_Index).Shoffset loop
288 Get_Byte (B);
289 end loop;
291 Offset := 0;
293 Get_Byte (B); -- zero
295 while Offset < Section_Headers (String_Table_Index).Shsize loop
296 Str_Last := 0;
298 loop
299 Get_Byte (B);
300 if B /= ASCII.NUL then
301 Str_Last := Str_Last + 1;
302 Str (Str_Last) := B;
304 else
305 Strings (Offset - Str_Last - 1) :=
306 new String'(Str (1 .. Str_Last));
307 exit;
308 end if;
309 end loop;
310 end loop;
312 -- Go get the Symbol Table
314 Reset;
316 while Offset < Section_Headers (Symtab_Index).Shoffset loop
317 Get_Byte (B);
318 end loop;
320 while Offset < End_Symtab loop
321 Get_Word (Stname);
322 Get_Byte (Stinfo);
323 Get_Byte (B);
324 Get_Half (Stshndx);
325 for J in 1 .. 4 loop
326 Get_Word (W);
327 end loop;
329 Sttype := Integer'(Character'Pos (Stinfo)) mod 16;
330 Stbind := Integer'(Character'Pos (Stinfo)) / 16;
332 if (Sttype = 1 or else Sttype = 2)
333 and then Stbind /= 0
334 and then Stshndx /= 0
335 then
336 -- Check if this is a symbol from a generic body
338 OK := True;
340 for J in Strings (Stname)'First .. Strings (Stname)'Last - 2 loop
341 if Strings (Stname) (J) = 'G'
342 and then Strings (Stname) (J + 1) = 'P'
343 and then Strings (Stname) (J + 2) in '0' .. '9'
344 then
345 OK := False;
346 exit;
347 end if;
348 end loop;
350 if OK then
351 declare
352 S_Data : Symbol_Data;
353 begin
354 S_Data.Name := new String'(Strings (Stname).all);
356 if Sttype = 1 then
357 S_Data.Kind := Data;
359 else
360 S_Data.Kind := Proc;
361 end if;
363 -- Put the new symbol in the table
365 Symbol_Table.Increment_Last (Complete_Symbols);
366 Complete_Symbols.Table
367 (Symbol_Table.Last (Complete_Symbols)) := S_Data;
368 end;
369 end if;
370 end if;
371 end loop;
373 -- The object file has been processed, close it
375 Close (File);
377 -- Free the allocated memory
379 Free (Section_Headers);
381 for J in Strings'Range loop
382 if Strings (J) /= null then
383 Free (Strings (J));
384 end if;
385 end loop;
387 Free (Strings);
389 exception
390 -- For any exception, output an error message, close the object file
391 -- and return with Success = False.
393 when Ada.IO_Exceptions.End_Error =>
394 Close (File);
396 when X : others =>
397 Put_Line ("unexpected exception raised while processing """
398 & Object_File & """");
399 Put_Line (Exception_Information (X));
400 Close (File);
401 Success := False;
402 end Process;
404 end Processing;