File : s-objrea.ads
1 ------------------------------------------------------------------------------
2 -- --
3 -- GNAT COMPILER COMPONENTS --
4 -- --
5 -- S Y S T E M . O B J E C T _ R E A D E R --
6 -- --
7 -- S p e c --
8 -- --
9 -- Copyright (C) 2009-2015, 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 -- Extensive contributions were provided by Ada Core Technologies Inc. --
29 -- --
30 ------------------------------------------------------------------------------
31
32 -- This package implements a simple, minimal overhead reader for object files
33 -- composed of sections of untyped heterogeneous binary data.
34
35 with Interfaces.C_Streams;
36
37 package System.Object_Reader is
38
39 --------------
40 -- Limits --
41 --------------
42
43 BUFFER_SIZE : constant := 8 * 1024;
44
45 ------------------
46 -- Object files --
47 ------------------
48
49 type Object_File (<>) is private;
50
51 type Object_File_Access is access Object_File;
52
53 ---------------------
54 -- Object sections --
55 ----------------------
56
57 type Object_Section is private;
58
59 Null_Section : constant Object_Section;
60
61 --------------------
62 -- Object symbols --
63 --------------------
64
65 type Object_Symbol is private;
66
67 ------------------------
68 -- Object format type --
69 ------------------------
70
71 type Object_Format is
72 (ELF32,
73 -- Object format is 32-bit ELF
74
75 ELF64,
76 -- Object format is 64-bit ELF
77
78 PECOFF,
79 -- Object format is Microsoft PECOFF
80
81 PECOFF_PLUS,
82 -- Object format is Microsoft PECOFF+
83
84 XCOFF32);
85 -- Object format is AIX 32-bit XCOFF
86
87 -- PECOFF | PECOFF_PLUS appears so often as a case choice, would
88 -- seem a good idea to have a subtype name covering these two choices ???
89
90 ------------------------------
91 -- Object architecture type --
92 ------------------------------
93
94 type Object_Arch is
95 (Unknown,
96 -- The target architecture has not yet been determined
97
98 SPARC,
99 -- 32-bit SPARC
100
101 SPARC64,
102 -- 64-bit SPARC
103
104 i386,
105 -- Intel IA32
106
107 MIPS,
108 -- MIPS Technologies MIPS
109
110 x86_64,
111 -- x86-64 (64-bit AMD/Intel)
112
113 IA64,
114 -- Intel IA64
115
116 PPC,
117 -- 32-bit PowerPC
118
119 PPC64);
120 -- 64-bit PowerPC
121
122 ------------------
123 -- Target types --
124 ------------------
125
126 subtype Offset is Interfaces.Integer_64;
127
128 subtype uint8 is Interfaces.Unsigned_8;
129 subtype uint16 is Interfaces.Unsigned_16;
130 subtype uint32 is Interfaces.Unsigned_32;
131 subtype uint64 is Interfaces.Unsigned_64;
132
133 subtype int8 is Interfaces.Integer_8;
134 subtype int16 is Interfaces.Integer_16;
135 subtype int32 is Interfaces.Integer_32;
136 subtype int64 is Interfaces.Integer_64;
137
138 type Buffer is array (0 .. BUFFER_SIZE - 1) of uint8;
139
140 -------------------------------------------
141 -- Operations on buffers of untyped data --
142 -------------------------------------------
143
144 function To_String (Buf : Buffer) return String;
145 -- Construct string from C style null-terminated string stored in a buffer
146
147 function Strlen (Buf : Buffer) return int32;
148 -- Return the length of a C style null-terminated string
149
150 -------------------------
151 -- Opening and closing --
152 -------------------------
153
154 function Open
155 (File_Name : String;
156 In_Exception : Boolean := False) return Object_File_Access;
157 -- Open the object file and initialize the reader. In_Exception is true
158 -- when the parsing is done as part of an exception handler decorator. In
159 -- this mode we do not want to raise an exception.
160
161 procedure Close (Obj : in out Object_File);
162 -- Close the object file
163
164 -----------------------
165 -- Sequential access --
166 -----------------------
167
168 procedure Read
169 (Obj : Object_File;
170 Addr : Address;
171 Size : uint32);
172 -- Read a number of fixed sized records
173
174 function Read (Obj : Object_File) return uint8;
175 function Read (Obj : Object_File) return uint16;
176 function Read (Obj : Object_File) return uint32;
177 function Read (Obj : Object_File) return uint64;
178 function Read (Obj : Object_File) return int8;
179 function Read (Obj : Object_File) return int16;
180 function Read (Obj : Object_File) return int32;
181 function Read (Obj : Object_File) return int64;
182 -- Read a scalar
183
184 function Read_Address (Obj : Object_File) return uint64;
185 -- Read either a 64 or 32 bit address from the file stream depending on the
186 -- address size of the target architecture and promote it to a 64 bit type.
187
188 function Read_LEB128 (Obj : Object_File) return uint32;
189 function Read_LEB128 (Obj : Object_File) return int32;
190 -- Read a value encoding in Little-Endian Base 128 format
191
192 procedure Read_C_String (Obj : Object_File; B : out Buffer);
193 -- Read a C style NULL terminated string at an offset
194
195 function Offset_To_String
196 (Obj : Object_File;
197 Off : Offset) return String;
198 -- Construct a string from a C style NULL terminated string located at an
199 -- offset into the object file.
200
201 -------------------
202 -- Random access --
203 -------------------
204
205 procedure Seek (Obj : Object_File; Off : Offset);
206 -- Seek to an absolute offset in bytes
207
208 procedure Tell (Obj : Object_File; Off : out Offset);
209 -- Fetch the current offset
210
211 ------------------------
212 -- Object information --
213 ------------------------
214
215 function Arch (Obj : Object_File) return Object_Arch;
216 -- Return the object architecture
217
218 function Format (Obj : Object_File) return Object_Format;
219 -- Return the object file format
220
221 function Get_Load_Address (Obj : Object_File) return uint64;
222 -- Return the load address defined in Obj. May raise Format_Error if not
223 -- implemented
224
225 function Num_Sections (Obj : Object_File) return uint32;
226 -- Return the number of sections composing the object file
227
228 function Get_Section
229 (Obj : Object_File;
230 Shnum : uint32) return Object_Section;
231 -- Return the Nth section (numbered from zero)
232
233 function Get_Section
234 (Obj : Object_File;
235 Sec_Name : String) return Object_Section;
236 -- Return a section by name
237
238 -------------------------
239 -- Section information --
240 -------------------------
241
242 procedure Seek (Obj : Object_File; Sec : Object_Section);
243 -- Seek to a section
244
245 function Name
246 (Obj : Object_File;
247 Sec : Object_Section) return String;
248 -- Return the name of a section as a string
249
250 function Size (Sec : Object_Section) return uint64;
251 -- Return the size of a section in bytes
252
253 function Num (Sec : Object_Section) return uint32;
254 -- Return the index of a section from zero
255
256 function Off (Sec : Object_Section) return Offset;
257 -- Return the byte offset of the section within the object
258
259 ------------------------------
260 -- Symbol table information --
261 ------------------------------
262
263 Null_Symbol : constant Object_Symbol;
264 -- An empty symbol table entry.
265
266 function Num_Symbols (Obj : Object_File) return uint64;
267 -- The number of symbols in the symbol table
268
269 function First_Symbol (Obj : in out Object_File) return Object_Symbol;
270 -- Return the first element in the symbol table or Null_Symbol if the
271 -- symbol table is empty.
272
273 function Next_Symbol
274 (Obj : in out Object_File;
275 Prev : Object_Symbol) return Object_Symbol;
276 -- Return the element following Prev in the symbol table, or Null_Symbol if
277 -- Prev is the last symbol in the table.
278
279 function Name
280 (Obj : Object_File;
281 Sym : Object_Symbol) return String;
282 -- Return the name of the symbol
283
284 function Decoded_Ada_Name
285 (Obj : Object_File;
286 Sym : Object_Symbol) return String;
287 -- Return the decoded name of a symbol encoded as per exp_dbug.ads
288
289 function Value (Sym : Object_Symbol) return uint64;
290 -- Return the name of the symbol
291
292 function Size (Sym : Object_Symbol) return uint64;
293 -- Return the size of the symbol in bytes
294
295 function Spans (Sym : Object_Symbol; Addr : uint64) return Boolean;
296 -- Determine whether a particular address corresponds to the range
297 -- referenced by this symbol.
298
299 ----------------
300 -- Exceptions --
301 ----------------
302
303 IO_Error : exception;
304 -- Input/Output error reading file
305
306 Format_Error : exception;
307 -- Encountered a problem parsing the object
308
309 private
310
311 package ICS renames Interfaces.C_Streams;
312
313 subtype ELF is Object_Format range ELF32 .. ELF64;
314 subtype Any_PECOFF is Object_Format range PECOFF .. PECOFF_PLUS;
315
316 type Object_File (Format : Object_Format) is record
317 fp : ICS.FILEs := ICS.NULL_Stream;
318 Arch : Object_Arch := Unknown;
319
320 Num_Sections : uint32 := 0;
321 Num_Symbols : uint64 := 0;
322
323 In_Exception : Boolean := False;
324 -- True if the parsing is done as part of an exception handler
325
326 Sectab : Offset := 0; -- Offset of the section table (XCOFF for XCOFF32)
327 Symtab : Offset := 0; -- Offset of the symbol table (All for XCOFF32)
328
329 case Format is
330 when ELF =>
331 Strtab : Offset := 0; -- Offset of the string table
332 when Any_PECOFF =>
333 Symtab_Last : Offset := 0; -- Offset past the symbol table
334
335 ImageBase : uint64; -- ImageBase value from header
336
337 -- Cache for latest result of Get_Section_Virtual_Address
338
339 GSVA_Sec : uint32 := uint32'Last;
340 GSVA_Addr : uint64;
341 when XCOFF32 =>
342 null;
343 end case;
344 end record;
345
346 subtype ELF_Object_File is Object_File; -- with
347 -- Predicate => ELF_Object_File.Format in ELF;
348 subtype PECOFF_Object_File is Object_File; -- with
349 -- Predicate => PECOFF_Object_File.Format in Any_PECOFF;
350 subtype XCOFF32_Object_File is Object_File; -- with
351 -- Predicate => XCOFF32_Object_File.Format in XCOFF32;
352 -- ???Above predicates cause the compiler to crash when instantiating
353 -- ELF64_Ops (see package body).
354
355 type Object_Section is record
356 Num : uint32 := 0; -- Index of this section in the section table
357 Off : Offset := 0; -- First byte of the section
358 Size : uint64 := 0; -- Length of the section in bytes
359 end record;
360
361 Null_Section : constant Object_Section := (0, 0, 0);
362
363 type Object_Symbol is record
364 Num : uint64 := 0; -- Index of this symbol in the symbol table
365 Off : Offset := 0; -- Offset of underlying symbol on disk
366 Next : Offset := 0; -- Offset of the following symbol
367 Value : uint64 := 0; -- Value associated with this symbol
368 Size : uint64 := 0; -- Size of the referenced entity
369 end record;
370
371 Null_Symbol : constant Object_Symbol := (0, 0, 0, 0, 0);
372
373 end System.Object_Reader;