annotate gcc/ada/libgnat/s-objrea.adb @ 145:1830386684a0

gcc-9.2.0
author anatofuz
date Thu, 13 Feb 2020 11:34:05 +0900
parents 84e7813d76e9
children
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
rev   line source
111
kono
parents:
diff changeset
1 ------------------------------------------------------------------------------
kono
parents:
diff changeset
2 -- --
kono
parents:
diff changeset
3 -- GNAT COMPILER COMPONENTS --
kono
parents:
diff changeset
4 -- --
kono
parents:
diff changeset
5 -- S Y S T E M . O B J E C T _ R E A D E R --
kono
parents:
diff changeset
6 -- --
kono
parents:
diff changeset
7 -- B o d y --
kono
parents:
diff changeset
8 -- --
145
1830386684a0 gcc-9.2.0
anatofuz
parents: 131
diff changeset
9 -- Copyright (C) 2009-2019, Free Software Foundation, Inc. --
111
kono
parents:
diff changeset
10 -- --
kono
parents:
diff changeset
11 -- GNAT is free software; you can redistribute it and/or modify it under --
kono
parents:
diff changeset
12 -- terms of the GNU General Public License as published by the Free Soft- --
kono
parents:
diff changeset
13 -- ware Foundation; either version 3, or (at your option) any later ver- --
kono
parents:
diff changeset
14 -- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
kono
parents:
diff changeset
15 -- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
kono
parents:
diff changeset
16 -- or FITNESS FOR A PARTICULAR PURPOSE. --
kono
parents:
diff changeset
17 -- --
kono
parents:
diff changeset
18 -- As a special exception under Section 7 of GPL version 3, you are granted --
kono
parents:
diff changeset
19 -- additional permissions described in the GCC Runtime Library Exception, --
kono
parents:
diff changeset
20 -- version 3.1, as published by the Free Software Foundation. --
kono
parents:
diff changeset
21 -- --
kono
parents:
diff changeset
22 -- You should have received a copy of the GNU General Public License and --
kono
parents:
diff changeset
23 -- a copy of the GCC Runtime Library Exception along with this program; --
kono
parents:
diff changeset
24 -- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
kono
parents:
diff changeset
25 -- <http://www.gnu.org/licenses/>. --
kono
parents:
diff changeset
26 -- --
kono
parents:
diff changeset
27 -- GNAT was originally developed by the GNAT team at New York University. --
kono
parents:
diff changeset
28 -- Extensive contributions were provided by Ada Core Technologies Inc. --
kono
parents:
diff changeset
29 -- --
kono
parents:
diff changeset
30 ------------------------------------------------------------------------------
kono
parents:
diff changeset
31
kono
parents:
diff changeset
32 with Ada.Unchecked_Conversion;
kono
parents:
diff changeset
33
kono
parents:
diff changeset
34 with Interfaces.C;
kono
parents:
diff changeset
35
kono
parents:
diff changeset
36 with System.CRTL;
kono
parents:
diff changeset
37
kono
parents:
diff changeset
38 package body System.Object_Reader is
kono
parents:
diff changeset
39 use Interfaces;
kono
parents:
diff changeset
40 use Interfaces.C;
kono
parents:
diff changeset
41 use System.Mmap;
kono
parents:
diff changeset
42
kono
parents:
diff changeset
43 SSU : constant := System.Storage_Unit;
kono
parents:
diff changeset
44
kono
parents:
diff changeset
45 function To_int32 is new Ada.Unchecked_Conversion (uint32, int32);
kono
parents:
diff changeset
46
kono
parents:
diff changeset
47 function Trim_Trailing_Nuls (Str : String) return String;
kono
parents:
diff changeset
48 -- Return a copy of a string with any trailing NUL characters truncated
kono
parents:
diff changeset
49
kono
parents:
diff changeset
50 procedure Check_Read_Offset (S : in out Mapped_Stream; Size : uint32);
kono
parents:
diff changeset
51 -- Check that the SIZE bytes at the current offset are still in the stream
kono
parents:
diff changeset
52
kono
parents:
diff changeset
53 -------------------------------------
kono
parents:
diff changeset
54 -- ELF object file format handling --
kono
parents:
diff changeset
55 -------------------------------------
kono
parents:
diff changeset
56
kono
parents:
diff changeset
57 generic
kono
parents:
diff changeset
58 type uword is mod <>;
kono
parents:
diff changeset
59
kono
parents:
diff changeset
60 package ELF_Ops is
kono
parents:
diff changeset
61
kono
parents:
diff changeset
62 -- ELF version codes
kono
parents:
diff changeset
63
kono
parents:
diff changeset
64 ELFCLASS32 : constant := 1; -- 32 bit ELF
kono
parents:
diff changeset
65 ELFCLASS64 : constant := 2; -- 64 bit ELF
kono
parents:
diff changeset
66
kono
parents:
diff changeset
67 -- ELF machine codes
kono
parents:
diff changeset
68
kono
parents:
diff changeset
69 EM_NONE : constant := 0; -- No machine
kono
parents:
diff changeset
70 EM_SPARC : constant := 2; -- SUN SPARC
kono
parents:
diff changeset
71 EM_386 : constant := 3; -- Intel 80386
kono
parents:
diff changeset
72 EM_MIPS : constant := 8; -- MIPS RS3000 Big-Endian
kono
parents:
diff changeset
73 EM_MIPS_RS3_LE : constant := 10; -- MIPS RS3000 Little-Endian
kono
parents:
diff changeset
74 EM_SPARC32PLUS : constant := 18; -- Sun SPARC 32+
kono
parents:
diff changeset
75 EM_PPC : constant := 20; -- PowerPC
kono
parents:
diff changeset
76 EM_PPC64 : constant := 21; -- PowerPC 64-bit
kono
parents:
diff changeset
77 EM_ARM : constant := 40; -- ARM
kono
parents:
diff changeset
78 EM_SPARCV9 : constant := 43; -- SPARC v9 64-bit
kono
parents:
diff changeset
79 EM_IA_64 : constant := 50; -- Intel Merced
kono
parents:
diff changeset
80 EM_X86_64 : constant := 62; -- AMD x86-64 architecture
kono
parents:
diff changeset
81
kono
parents:
diff changeset
82 EN_NIDENT : constant := 16;
kono
parents:
diff changeset
83
kono
parents:
diff changeset
84 type E_Ident_Type is array (0 .. EN_NIDENT - 1) of uint8;
kono
parents:
diff changeset
85
kono
parents:
diff changeset
86 type Header is record
kono
parents:
diff changeset
87 E_Ident : E_Ident_Type; -- Magic number and other info
kono
parents:
diff changeset
88 E_Type : uint16; -- Object file type
kono
parents:
diff changeset
89 E_Machine : uint16; -- Architecture
kono
parents:
diff changeset
90 E_Version : uint32; -- Object file version
kono
parents:
diff changeset
91 E_Entry : uword; -- Entry point virtual address
kono
parents:
diff changeset
92 E_Phoff : uword; -- Program header table file offset
kono
parents:
diff changeset
93 E_Shoff : uword; -- Section header table file offset
kono
parents:
diff changeset
94 E_Flags : uint32; -- Processor-specific flags
kono
parents:
diff changeset
95 E_Ehsize : uint16; -- ELF header size in bytes
kono
parents:
diff changeset
96 E_Phentsize : uint16; -- Program header table entry size
kono
parents:
diff changeset
97 E_Phnum : uint16; -- Program header table entry count
kono
parents:
diff changeset
98 E_Shentsize : uint16; -- Section header table entry size
kono
parents:
diff changeset
99 E_Shnum : uint16; -- Section header table entry count
kono
parents:
diff changeset
100 E_Shstrndx : uint16; -- Section header string table index
kono
parents:
diff changeset
101 end record;
kono
parents:
diff changeset
102
kono
parents:
diff changeset
103 type Section_Header is record
kono
parents:
diff changeset
104 Sh_Name : uint32; -- Section name string table index
kono
parents:
diff changeset
105 Sh_Type : uint32; -- Section type
kono
parents:
diff changeset
106 Sh_Flags : uword; -- Section flags
kono
parents:
diff changeset
107 Sh_Addr : uword; -- Section virtual addr at execution
kono
parents:
diff changeset
108 Sh_Offset : uword; -- Section file offset
kono
parents:
diff changeset
109 Sh_Size : uword; -- Section size in bytes
kono
parents:
diff changeset
110 Sh_Link : uint32; -- Link to another section
kono
parents:
diff changeset
111 Sh_Info : uint32; -- Additional section information
kono
parents:
diff changeset
112 Sh_Addralign : uword; -- Section alignment
kono
parents:
diff changeset
113 Sh_Entsize : uword; -- Entry size if section holds table
kono
parents:
diff changeset
114 end record;
kono
parents:
diff changeset
115
kono
parents:
diff changeset
116 SHF_ALLOC : constant := 2;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
117 SHF_EXECINSTR : constant := 4;
111
kono
parents:
diff changeset
118
kono
parents:
diff changeset
119 type Symtab_Entry32 is record
kono
parents:
diff changeset
120 St_Name : uint32; -- Name (string table index)
kono
parents:
diff changeset
121 St_Value : uint32; -- Value
kono
parents:
diff changeset
122 St_Size : uint32; -- Size in bytes
kono
parents:
diff changeset
123 St_Info : uint8; -- Type and binding attributes
kono
parents:
diff changeset
124 St_Other : uint8; -- Undefined
kono
parents:
diff changeset
125 St_Shndx : uint16; -- Defining section
kono
parents:
diff changeset
126 end record;
kono
parents:
diff changeset
127
kono
parents:
diff changeset
128 type Symtab_Entry64 is record
kono
parents:
diff changeset
129 St_Name : uint32; -- Name (string table index)
kono
parents:
diff changeset
130 St_Info : uint8; -- Type and binding attributes
kono
parents:
diff changeset
131 St_Other : uint8; -- Undefined
kono
parents:
diff changeset
132 St_Shndx : uint16; -- Defining section
kono
parents:
diff changeset
133 St_Value : uint64; -- Value
kono
parents:
diff changeset
134 St_Size : uint64; -- Size in bytes
kono
parents:
diff changeset
135 end record;
kono
parents:
diff changeset
136
kono
parents:
diff changeset
137 function Read_Header (F : in out Mapped_Stream) return Header;
kono
parents:
diff changeset
138 -- Read a header from an ELF format object
kono
parents:
diff changeset
139
kono
parents:
diff changeset
140 function First_Symbol
kono
parents:
diff changeset
141 (Obj : in out ELF_Object_File) return Object_Symbol;
kono
parents:
diff changeset
142 -- Return the first element in the symbol table, or Null_Symbol if the
kono
parents:
diff changeset
143 -- symbol table is empty.
kono
parents:
diff changeset
144
kono
parents:
diff changeset
145 function Read_Symbol
kono
parents:
diff changeset
146 (Obj : in out ELF_Object_File;
kono
parents:
diff changeset
147 Off : Offset) return Object_Symbol;
kono
parents:
diff changeset
148 -- Read a symbol at offset Off
kono
parents:
diff changeset
149
kono
parents:
diff changeset
150 function Name
kono
parents:
diff changeset
151 (Obj : in out ELF_Object_File;
kono
parents:
diff changeset
152 Sym : Object_Symbol) return String_Ptr_Len;
kono
parents:
diff changeset
153 -- Return the name of the symbol
kono
parents:
diff changeset
154
kono
parents:
diff changeset
155 function Name
kono
parents:
diff changeset
156 (Obj : in out ELF_Object_File;
kono
parents:
diff changeset
157 Sec : Object_Section) return String;
kono
parents:
diff changeset
158 -- Return the name of a section
kono
parents:
diff changeset
159
kono
parents:
diff changeset
160 function Get_Section
kono
parents:
diff changeset
161 (Obj : in out ELF_Object_File;
kono
parents:
diff changeset
162 Shnum : uint32) return Object_Section;
kono
parents:
diff changeset
163 -- Fetch a section by index from zero
kono
parents:
diff changeset
164
kono
parents:
diff changeset
165 function Initialize
kono
parents:
diff changeset
166 (F : Mapped_File;
kono
parents:
diff changeset
167 Hdr : Header;
kono
parents:
diff changeset
168 In_Exception : Boolean) return ELF_Object_File;
kono
parents:
diff changeset
169 -- Initialize an object file
kono
parents:
diff changeset
170
kono
parents:
diff changeset
171 end ELF_Ops;
kono
parents:
diff changeset
172
kono
parents:
diff changeset
173 -----------------------------------
kono
parents:
diff changeset
174 -- PECOFF object format handling --
kono
parents:
diff changeset
175 -----------------------------------
kono
parents:
diff changeset
176
kono
parents:
diff changeset
177 package PECOFF_Ops is
kono
parents:
diff changeset
178
kono
parents:
diff changeset
179 -- Constants and data layout are taken from the document "Microsoft
kono
parents:
diff changeset
180 -- Portable Executable and Common Object File Format Specification"
kono
parents:
diff changeset
181 -- Revision 8.1.
kono
parents:
diff changeset
182
kono
parents:
diff changeset
183 Signature_Loc_Offset : constant := 16#3C#;
kono
parents:
diff changeset
184 -- Offset of pointer to the file signature
kono
parents:
diff changeset
185
kono
parents:
diff changeset
186 Size_Of_Standard_Header_Fields : constant := 16#18#;
kono
parents:
diff changeset
187 -- Length in bytes of the standard header record
kono
parents:
diff changeset
188
kono
parents:
diff changeset
189 Function_Symbol_Type : constant := 16#20#;
kono
parents:
diff changeset
190 -- Type field value indicating a symbol refers to a function
kono
parents:
diff changeset
191
kono
parents:
diff changeset
192 Not_Function_Symbol_Type : constant := 16#00#;
kono
parents:
diff changeset
193 -- Type field value indicating a symbol does not refer to a function
kono
parents:
diff changeset
194
kono
parents:
diff changeset
195 type Magic_Array is array (0 .. 3) of uint8;
kono
parents:
diff changeset
196 -- Array of magic numbers from the header
kono
parents:
diff changeset
197
kono
parents:
diff changeset
198 -- Magic numbers for PECOFF variants
kono
parents:
diff changeset
199
kono
parents:
diff changeset
200 VARIANT_PE32 : constant := 16#010B#;
kono
parents:
diff changeset
201 VARIANT_PE32_PLUS : constant := 16#020B#;
kono
parents:
diff changeset
202
kono
parents:
diff changeset
203 -- PECOFF machine codes
kono
parents:
diff changeset
204
kono
parents:
diff changeset
205 IMAGE_FILE_MACHINE_I386 : constant := 16#014C#;
kono
parents:
diff changeset
206 IMAGE_FILE_MACHINE_IA64 : constant := 16#0200#;
kono
parents:
diff changeset
207 IMAGE_FILE_MACHINE_AMD64 : constant := 16#8664#;
kono
parents:
diff changeset
208
kono
parents:
diff changeset
209 -- PECOFF Data layout
kono
parents:
diff changeset
210
kono
parents:
diff changeset
211 type Header is record
kono
parents:
diff changeset
212 Magics : Magic_Array;
kono
parents:
diff changeset
213 Machine : uint16;
kono
parents:
diff changeset
214 NumberOfSections : uint16;
kono
parents:
diff changeset
215 TimeDateStamp : uint32;
kono
parents:
diff changeset
216 PointerToSymbolTable : uint32;
kono
parents:
diff changeset
217 NumberOfSymbols : uint32;
kono
parents:
diff changeset
218 SizeOfOptionalHeader : uint16;
kono
parents:
diff changeset
219 Characteristics : uint16;
kono
parents:
diff changeset
220 Variant : uint16;
kono
parents:
diff changeset
221 end record;
kono
parents:
diff changeset
222
kono
parents:
diff changeset
223 pragma Pack (Header);
kono
parents:
diff changeset
224
kono
parents:
diff changeset
225 type Optional_Header_PE32 is record
kono
parents:
diff changeset
226 Magic : uint16;
kono
parents:
diff changeset
227 MajorLinkerVersion : uint8;
kono
parents:
diff changeset
228 MinorLinkerVersion : uint8;
kono
parents:
diff changeset
229 SizeOfCode : uint32;
kono
parents:
diff changeset
230 SizeOfInitializedData : uint32;
kono
parents:
diff changeset
231 SizeOfUninitializedData : uint32;
kono
parents:
diff changeset
232 AddressOfEntryPoint : uint32;
kono
parents:
diff changeset
233 BaseOfCode : uint32;
kono
parents:
diff changeset
234 BaseOfData : uint32; -- Note: not in PE32+
kono
parents:
diff changeset
235 ImageBase : uint32;
kono
parents:
diff changeset
236 SectionAlignment : uint32;
kono
parents:
diff changeset
237 FileAlignment : uint32;
kono
parents:
diff changeset
238 MajorOperatingSystemVersion : uint16;
kono
parents:
diff changeset
239 MinorOperationSystemVersion : uint16;
kono
parents:
diff changeset
240 MajorImageVersion : uint16;
kono
parents:
diff changeset
241 MinorImageVersion : uint16;
kono
parents:
diff changeset
242 MajorSubsystemVersion : uint16;
kono
parents:
diff changeset
243 MinorSubsystemVersion : uint16;
kono
parents:
diff changeset
244 Win32VersionValue : uint32;
kono
parents:
diff changeset
245 SizeOfImage : uint32;
kono
parents:
diff changeset
246 SizeOfHeaders : uint32;
kono
parents:
diff changeset
247 Checksum : uint32;
kono
parents:
diff changeset
248 Subsystem : uint16;
kono
parents:
diff changeset
249 DllCharacteristics : uint16;
kono
parents:
diff changeset
250 SizeOfStackReserve : uint32;
kono
parents:
diff changeset
251 SizeOfStackCommit : uint32;
kono
parents:
diff changeset
252 SizeOfHeapReserve : uint32;
kono
parents:
diff changeset
253 SizeOfHeapCommit : uint32;
kono
parents:
diff changeset
254 LoaderFlags : uint32;
kono
parents:
diff changeset
255 NumberOfRvaAndSizes : uint32;
kono
parents:
diff changeset
256 end record;
kono
parents:
diff changeset
257 pragma Pack (Optional_Header_PE32);
kono
parents:
diff changeset
258 pragma Assert (Optional_Header_PE32'Size = 96 * SSU);
kono
parents:
diff changeset
259
kono
parents:
diff changeset
260 type Optional_Header_PE64 is record
kono
parents:
diff changeset
261 Magic : uint16;
kono
parents:
diff changeset
262 MajorLinkerVersion : uint8;
kono
parents:
diff changeset
263 MinorLinkerVersion : uint8;
kono
parents:
diff changeset
264 SizeOfCode : uint32;
kono
parents:
diff changeset
265 SizeOfInitializedData : uint32;
kono
parents:
diff changeset
266 SizeOfUninitializedData : uint32;
kono
parents:
diff changeset
267 AddressOfEntryPoint : uint32;
kono
parents:
diff changeset
268 BaseOfCode : uint32;
kono
parents:
diff changeset
269 ImageBase : uint64;
kono
parents:
diff changeset
270 SectionAlignment : uint32;
kono
parents:
diff changeset
271 FileAlignment : uint32;
kono
parents:
diff changeset
272 MajorOperatingSystemVersion : uint16;
kono
parents:
diff changeset
273 MinorOperationSystemVersion : uint16;
kono
parents:
diff changeset
274 MajorImageVersion : uint16;
kono
parents:
diff changeset
275 MinorImageVersion : uint16;
kono
parents:
diff changeset
276 MajorSubsystemVersion : uint16;
kono
parents:
diff changeset
277 MinorSubsystemVersion : uint16;
kono
parents:
diff changeset
278 Win32VersionValue : uint32;
kono
parents:
diff changeset
279 SizeOfImage : uint32;
kono
parents:
diff changeset
280 SizeOfHeaders : uint32;
kono
parents:
diff changeset
281 Checksum : uint32;
kono
parents:
diff changeset
282 Subsystem : uint16;
kono
parents:
diff changeset
283 DllCharacteristics : uint16;
kono
parents:
diff changeset
284 SizeOfStackReserve : uint64;
kono
parents:
diff changeset
285 SizeOfStackCommit : uint64;
kono
parents:
diff changeset
286 SizeOfHeapReserve : uint64;
kono
parents:
diff changeset
287 SizeOfHeapCommit : uint64;
kono
parents:
diff changeset
288 LoaderFlags : uint32;
kono
parents:
diff changeset
289 NumberOfRvaAndSizes : uint32;
kono
parents:
diff changeset
290 end record;
kono
parents:
diff changeset
291 pragma Pack (Optional_Header_PE64);
kono
parents:
diff changeset
292 pragma Assert (Optional_Header_PE64'Size = 112 * SSU);
kono
parents:
diff changeset
293
kono
parents:
diff changeset
294 subtype Name_Str is String (1 .. 8);
kono
parents:
diff changeset
295
kono
parents:
diff changeset
296 type Section_Header is record
kono
parents:
diff changeset
297 Name : Name_Str;
kono
parents:
diff changeset
298 VirtualSize : uint32;
kono
parents:
diff changeset
299 VirtualAddress : uint32;
kono
parents:
diff changeset
300 SizeOfRawData : uint32;
kono
parents:
diff changeset
301 PointerToRawData : uint32;
kono
parents:
diff changeset
302 PointerToRelocations : uint32;
kono
parents:
diff changeset
303 PointerToLinenumbers : uint32;
kono
parents:
diff changeset
304 NumberOfRelocations : uint16;
kono
parents:
diff changeset
305 NumberOfLinenumbers : uint16;
kono
parents:
diff changeset
306 Characteristics : uint32;
kono
parents:
diff changeset
307 end record;
kono
parents:
diff changeset
308
kono
parents:
diff changeset
309 pragma Pack (Section_Header);
kono
parents:
diff changeset
310
kono
parents:
diff changeset
311 IMAGE_SCN_CNT_CODE : constant := 16#0020#;
kono
parents:
diff changeset
312
kono
parents:
diff changeset
313 type Symtab_Entry is record
kono
parents:
diff changeset
314 Name : Name_Str;
kono
parents:
diff changeset
315 Value : uint32;
kono
parents:
diff changeset
316 SectionNumber : int16;
kono
parents:
diff changeset
317 TypeField : uint16;
kono
parents:
diff changeset
318 StorageClass : uint8;
kono
parents:
diff changeset
319 NumberOfAuxSymbols : uint8;
kono
parents:
diff changeset
320 end record;
kono
parents:
diff changeset
321
kono
parents:
diff changeset
322 pragma Pack (Symtab_Entry);
kono
parents:
diff changeset
323
kono
parents:
diff changeset
324 type Auxent_Section is record
kono
parents:
diff changeset
325 Length : uint32;
kono
parents:
diff changeset
326 NumberOfRelocations : uint16;
kono
parents:
diff changeset
327 NumberOfLinenumbers : uint16;
kono
parents:
diff changeset
328 CheckSum : uint32;
kono
parents:
diff changeset
329 Number : uint16;
kono
parents:
diff changeset
330 Selection : uint8;
kono
parents:
diff changeset
331 Unused1 : uint8;
kono
parents:
diff changeset
332 Unused2 : uint8;
kono
parents:
diff changeset
333 Unused3 : uint8;
kono
parents:
diff changeset
334 end record;
kono
parents:
diff changeset
335
kono
parents:
diff changeset
336 for Auxent_Section'Size use 18 * 8;
kono
parents:
diff changeset
337
kono
parents:
diff changeset
338 function Read_Header (F : in out Mapped_Stream) return Header;
kono
parents:
diff changeset
339 -- Read the object file header
kono
parents:
diff changeset
340
kono
parents:
diff changeset
341 function First_Symbol
kono
parents:
diff changeset
342 (Obj : in out PECOFF_Object_File) return Object_Symbol;
kono
parents:
diff changeset
343 -- Return the first element in the symbol table, or Null_Symbol if the
kono
parents:
diff changeset
344 -- symbol table is empty.
kono
parents:
diff changeset
345
kono
parents:
diff changeset
346 function Read_Symbol
kono
parents:
diff changeset
347 (Obj : in out PECOFF_Object_File;
kono
parents:
diff changeset
348 Off : Offset) return Object_Symbol;
kono
parents:
diff changeset
349 -- Read a symbol at offset Off
kono
parents:
diff changeset
350
kono
parents:
diff changeset
351 function Name
kono
parents:
diff changeset
352 (Obj : in out PECOFF_Object_File;
kono
parents:
diff changeset
353 Sym : Object_Symbol) return String_Ptr_Len;
kono
parents:
diff changeset
354 -- Return the name of the symbol
kono
parents:
diff changeset
355
kono
parents:
diff changeset
356 function Name
kono
parents:
diff changeset
357 (Obj : in out PECOFF_Object_File;
kono
parents:
diff changeset
358 Sec : Object_Section) return String;
kono
parents:
diff changeset
359 -- Return the name of a section
kono
parents:
diff changeset
360
kono
parents:
diff changeset
361 function Get_Section
kono
parents:
diff changeset
362 (Obj : in out PECOFF_Object_File;
kono
parents:
diff changeset
363 Index : uint32) return Object_Section;
kono
parents:
diff changeset
364 -- Fetch a section by index from zero
kono
parents:
diff changeset
365
kono
parents:
diff changeset
366 function Initialize
kono
parents:
diff changeset
367 (F : Mapped_File;
kono
parents:
diff changeset
368 Hdr : Header;
kono
parents:
diff changeset
369 In_Exception : Boolean) return PECOFF_Object_File;
kono
parents:
diff changeset
370 -- Initialize an object file
kono
parents:
diff changeset
371
kono
parents:
diff changeset
372 end PECOFF_Ops;
kono
parents:
diff changeset
373
kono
parents:
diff changeset
374 -------------------------------------
kono
parents:
diff changeset
375 -- XCOFF-32 object format handling --
kono
parents:
diff changeset
376 -------------------------------------
kono
parents:
diff changeset
377
kono
parents:
diff changeset
378 package XCOFF32_Ops is
kono
parents:
diff changeset
379
kono
parents:
diff changeset
380 -- XCOFF Data layout
kono
parents:
diff changeset
381
kono
parents:
diff changeset
382 type Header is record
kono
parents:
diff changeset
383 f_magic : uint16;
kono
parents:
diff changeset
384 f_nscns : uint16;
kono
parents:
diff changeset
385 f_timdat : uint32;
kono
parents:
diff changeset
386 f_symptr : uint32;
kono
parents:
diff changeset
387 f_nsyms : uint32;
kono
parents:
diff changeset
388 f_opthdr : uint16;
kono
parents:
diff changeset
389 f_flags : uint16;
kono
parents:
diff changeset
390 end record;
kono
parents:
diff changeset
391
kono
parents:
diff changeset
392 type Auxiliary_Header is record
kono
parents:
diff changeset
393 o_mflag : uint16;
kono
parents:
diff changeset
394 o_vstamp : uint16;
kono
parents:
diff changeset
395 o_tsize : uint32;
kono
parents:
diff changeset
396 o_dsize : uint32;
kono
parents:
diff changeset
397 o_bsize : uint32;
kono
parents:
diff changeset
398 o_entry : uint32;
kono
parents:
diff changeset
399 o_text_start : uint32;
kono
parents:
diff changeset
400 o_data_start : uint32;
kono
parents:
diff changeset
401 o_toc : uint32;
kono
parents:
diff changeset
402 o_snentry : uint16;
kono
parents:
diff changeset
403 o_sntext : uint16;
kono
parents:
diff changeset
404 o_sndata : uint16;
kono
parents:
diff changeset
405 o_sntoc : uint16;
kono
parents:
diff changeset
406 o_snloader : uint16;
kono
parents:
diff changeset
407 o_snbss : uint16;
kono
parents:
diff changeset
408 o_algntext : uint16;
kono
parents:
diff changeset
409 o_algndata : uint16;
kono
parents:
diff changeset
410 o_modtype : uint16;
kono
parents:
diff changeset
411 o_cpuflag : uint8;
kono
parents:
diff changeset
412 o_cputype : uint8;
kono
parents:
diff changeset
413 o_maxstack : uint32;
kono
parents:
diff changeset
414 o_maxdata : uint32;
kono
parents:
diff changeset
415 o_debugger : uint32;
kono
parents:
diff changeset
416 o_flags : uint8;
kono
parents:
diff changeset
417 o_sntdata : uint16;
kono
parents:
diff changeset
418 o_sntbss : uint16;
kono
parents:
diff changeset
419 end record;
kono
parents:
diff changeset
420 pragma Unreferenced (Auxiliary_Header);
kono
parents:
diff changeset
421 -- Not used, but not removed (just in case)
kono
parents:
diff changeset
422
kono
parents:
diff changeset
423 subtype Name_Str is String (1 .. 8);
kono
parents:
diff changeset
424
kono
parents:
diff changeset
425 type Section_Header is record
kono
parents:
diff changeset
426 s_name : Name_Str;
kono
parents:
diff changeset
427 s_paddr : uint32;
kono
parents:
diff changeset
428 s_vaddr : uint32;
kono
parents:
diff changeset
429 s_size : uint32;
kono
parents:
diff changeset
430 s_scnptr : uint32;
kono
parents:
diff changeset
431 s_relptr : uint32;
kono
parents:
diff changeset
432 s_lnnoptr : uint32;
kono
parents:
diff changeset
433 s_nreloc : uint16;
kono
parents:
diff changeset
434 s_nlnno : uint16;
kono
parents:
diff changeset
435 s_flags : uint32;
kono
parents:
diff changeset
436 end record;
kono
parents:
diff changeset
437
kono
parents:
diff changeset
438 pragma Pack (Section_Header);
kono
parents:
diff changeset
439
kono
parents:
diff changeset
440 STYP_TEXT : constant := 16#0020#;
kono
parents:
diff changeset
441
kono
parents:
diff changeset
442 type Symbol_Entry is record
kono
parents:
diff changeset
443 n_name : Name_Str;
kono
parents:
diff changeset
444 n_value : uint32;
kono
parents:
diff changeset
445 n_scnum : uint16;
kono
parents:
diff changeset
446 n_type : uint16;
kono
parents:
diff changeset
447 n_sclass : uint8;
kono
parents:
diff changeset
448 n_numaux : uint8;
kono
parents:
diff changeset
449 end record;
kono
parents:
diff changeset
450 for Symbol_Entry'Size use 18 * 8;
kono
parents:
diff changeset
451
kono
parents:
diff changeset
452 type Aux_Entry is record
kono
parents:
diff changeset
453 x_scnlen : uint32;
kono
parents:
diff changeset
454 x_parmhash : uint32;
kono
parents:
diff changeset
455 x_snhash : uint16;
kono
parents:
diff changeset
456 x_smtyp : uint8;
kono
parents:
diff changeset
457 x_smclass : uint8;
kono
parents:
diff changeset
458 x_stab : uint32;
kono
parents:
diff changeset
459 x_snstab : uint16;
kono
parents:
diff changeset
460 end record;
kono
parents:
diff changeset
461 for Aux_Entry'Size use 18 * 8;
kono
parents:
diff changeset
462
kono
parents:
diff changeset
463 pragma Pack (Aux_Entry);
kono
parents:
diff changeset
464
kono
parents:
diff changeset
465 C_EXT : constant := 2;
kono
parents:
diff changeset
466 C_HIDEXT : constant := 107;
kono
parents:
diff changeset
467 C_WEAKEXT : constant := 111;
kono
parents:
diff changeset
468
kono
parents:
diff changeset
469 XTY_LD : constant := 2;
kono
parents:
diff changeset
470 -- Magic constant should be documented, especially since it's changed???
kono
parents:
diff changeset
471
kono
parents:
diff changeset
472 function Read_Header (F : in out Mapped_Stream) return Header;
kono
parents:
diff changeset
473 -- Read the object file header
kono
parents:
diff changeset
474
kono
parents:
diff changeset
475 function First_Symbol
kono
parents:
diff changeset
476 (Obj : in out XCOFF32_Object_File) return Object_Symbol;
kono
parents:
diff changeset
477 -- Return the first element in the symbol table, or Null_Symbol if the
kono
parents:
diff changeset
478 -- symbol table is empty.
kono
parents:
diff changeset
479
kono
parents:
diff changeset
480 function Read_Symbol
kono
parents:
diff changeset
481 (Obj : in out XCOFF32_Object_File;
kono
parents:
diff changeset
482 Off : Offset) return Object_Symbol;
kono
parents:
diff changeset
483 -- Read a symbol at offset Off
kono
parents:
diff changeset
484
kono
parents:
diff changeset
485 function Name
kono
parents:
diff changeset
486 (Obj : in out XCOFF32_Object_File;
kono
parents:
diff changeset
487 Sym : Object_Symbol) return String_Ptr_Len;
kono
parents:
diff changeset
488 -- Return the name of the symbol
kono
parents:
diff changeset
489
kono
parents:
diff changeset
490 function Name
kono
parents:
diff changeset
491 (Obj : in out XCOFF32_Object_File;
kono
parents:
diff changeset
492 Sec : Object_Section) return String;
kono
parents:
diff changeset
493 -- Return the name of a section
kono
parents:
diff changeset
494
kono
parents:
diff changeset
495 function Initialize
kono
parents:
diff changeset
496 (F : Mapped_File;
kono
parents:
diff changeset
497 Hdr : Header;
kono
parents:
diff changeset
498 In_Exception : Boolean) return XCOFF32_Object_File;
kono
parents:
diff changeset
499 -- Initialize an object file
kono
parents:
diff changeset
500
kono
parents:
diff changeset
501 function Get_Section
kono
parents:
diff changeset
502 (Obj : in out XCOFF32_Object_File;
kono
parents:
diff changeset
503 Index : uint32) return Object_Section;
kono
parents:
diff changeset
504 -- Fetch a section by index from zero
kono
parents:
diff changeset
505
kono
parents:
diff changeset
506 end XCOFF32_Ops;
kono
parents:
diff changeset
507
kono
parents:
diff changeset
508 -------------
kono
parents:
diff changeset
509 -- ELF_Ops --
kono
parents:
diff changeset
510 -------------
kono
parents:
diff changeset
511
kono
parents:
diff changeset
512 package body ELF_Ops is
kono
parents:
diff changeset
513
kono
parents:
diff changeset
514 function Get_String_Table (Obj : in out ELF_Object_File)
kono
parents:
diff changeset
515 return Object_Section;
kono
parents:
diff changeset
516 -- Fetch the section containing the string table
kono
parents:
diff changeset
517
kono
parents:
diff changeset
518 function Get_Symbol_Table (Obj : in out ELF_Object_File)
kono
parents:
diff changeset
519 return Object_Section;
kono
parents:
diff changeset
520 -- Fetch the section containing the symbol table
kono
parents:
diff changeset
521
kono
parents:
diff changeset
522 function Read_Section_Header
kono
parents:
diff changeset
523 (Obj : in out ELF_Object_File;
kono
parents:
diff changeset
524 Shnum : uint32) return Section_Header;
kono
parents:
diff changeset
525 -- Read the header for an ELF format object section indexed from zero
kono
parents:
diff changeset
526
kono
parents:
diff changeset
527 ------------------
kono
parents:
diff changeset
528 -- First_Symbol --
kono
parents:
diff changeset
529 ------------------
kono
parents:
diff changeset
530
kono
parents:
diff changeset
531 function First_Symbol
kono
parents:
diff changeset
532 (Obj : in out ELF_Object_File) return Object_Symbol
kono
parents:
diff changeset
533 is
kono
parents:
diff changeset
534 begin
kono
parents:
diff changeset
535 if Obj.Symtab_Last = 0 then
kono
parents:
diff changeset
536 return Null_Symbol;
kono
parents:
diff changeset
537 else
kono
parents:
diff changeset
538 return Read_Symbol (Obj, 0);
kono
parents:
diff changeset
539 end if;
kono
parents:
diff changeset
540 end First_Symbol;
kono
parents:
diff changeset
541
kono
parents:
diff changeset
542 -----------------
kono
parents:
diff changeset
543 -- Get_Section --
kono
parents:
diff changeset
544 -----------------
kono
parents:
diff changeset
545
kono
parents:
diff changeset
546 function Get_Section
kono
parents:
diff changeset
547 (Obj : in out ELF_Object_File;
kono
parents:
diff changeset
548 Shnum : uint32) return Object_Section
kono
parents:
diff changeset
549 is
kono
parents:
diff changeset
550 SHdr : constant Section_Header := Read_Section_Header (Obj, Shnum);
kono
parents:
diff changeset
551 begin
kono
parents:
diff changeset
552 return (Shnum,
kono
parents:
diff changeset
553 Offset (SHdr.Sh_Offset),
kono
parents:
diff changeset
554 uint64 (SHdr.Sh_Addr),
kono
parents:
diff changeset
555 uint64 (SHdr.Sh_Size),
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
556 (SHdr.Sh_Flags and SHF_EXECINSTR) /= 0);
111
kono
parents:
diff changeset
557 end Get_Section;
kono
parents:
diff changeset
558
kono
parents:
diff changeset
559 ------------------------
kono
parents:
diff changeset
560 -- Get_String_Table --
kono
parents:
diff changeset
561 ------------------------
kono
parents:
diff changeset
562
kono
parents:
diff changeset
563 function Get_String_Table
kono
parents:
diff changeset
564 (Obj : in out ELF_Object_File) return Object_Section
kono
parents:
diff changeset
565 is
kono
parents:
diff changeset
566 begin
kono
parents:
diff changeset
567 -- All cases except MIPS IRIX, string table located in .strtab
kono
parents:
diff changeset
568
kono
parents:
diff changeset
569 if Obj.Arch /= MIPS then
kono
parents:
diff changeset
570 return Get_Section (Obj, ".strtab");
kono
parents:
diff changeset
571
kono
parents:
diff changeset
572 -- On IRIX only .dynstr is available
kono
parents:
diff changeset
573
kono
parents:
diff changeset
574 else
kono
parents:
diff changeset
575 return Get_Section (Obj, ".dynstr");
kono
parents:
diff changeset
576 end if;
kono
parents:
diff changeset
577 end Get_String_Table;
kono
parents:
diff changeset
578
kono
parents:
diff changeset
579 ------------------------
kono
parents:
diff changeset
580 -- Get_Symbol_Table --
kono
parents:
diff changeset
581 ------------------------
kono
parents:
diff changeset
582
kono
parents:
diff changeset
583 function Get_Symbol_Table
kono
parents:
diff changeset
584 (Obj : in out ELF_Object_File) return Object_Section
kono
parents:
diff changeset
585 is
kono
parents:
diff changeset
586 begin
kono
parents:
diff changeset
587 -- All cases except MIPS IRIX, symbol table located in .symtab
kono
parents:
diff changeset
588
kono
parents:
diff changeset
589 if Obj.Arch /= MIPS then
kono
parents:
diff changeset
590 return Get_Section (Obj, ".symtab");
kono
parents:
diff changeset
591
kono
parents:
diff changeset
592 -- On IRIX, symbol table located somewhere other than .symtab
kono
parents:
diff changeset
593
kono
parents:
diff changeset
594 else
kono
parents:
diff changeset
595 return Get_Section (Obj, ".dynsym");
kono
parents:
diff changeset
596 end if;
kono
parents:
diff changeset
597 end Get_Symbol_Table;
kono
parents:
diff changeset
598
kono
parents:
diff changeset
599 ----------------
kono
parents:
diff changeset
600 -- Initialize --
kono
parents:
diff changeset
601 ----------------
kono
parents:
diff changeset
602
kono
parents:
diff changeset
603 function Initialize
kono
parents:
diff changeset
604 (F : Mapped_File;
kono
parents:
diff changeset
605 Hdr : Header;
kono
parents:
diff changeset
606 In_Exception : Boolean) return ELF_Object_File
kono
parents:
diff changeset
607 is
kono
parents:
diff changeset
608 Res : ELF_Object_File
kono
parents:
diff changeset
609 (Format => (case uword'Size is
kono
parents:
diff changeset
610 when 64 => ELF64,
kono
parents:
diff changeset
611 when 32 => ELF32,
kono
parents:
diff changeset
612 when others => raise Program_Error));
kono
parents:
diff changeset
613 Sec : Object_Section;
kono
parents:
diff changeset
614 begin
kono
parents:
diff changeset
615 Res.MF := F;
kono
parents:
diff changeset
616 Res.In_Exception := In_Exception;
kono
parents:
diff changeset
617 Res.Num_Sections := uint32 (Hdr.E_Shnum);
kono
parents:
diff changeset
618
kono
parents:
diff changeset
619 case Hdr.E_Machine is
kono
parents:
diff changeset
620 when EM_SPARC
kono
parents:
diff changeset
621 | EM_SPARC32PLUS
kono
parents:
diff changeset
622 =>
kono
parents:
diff changeset
623 Res.Arch := SPARC;
kono
parents:
diff changeset
624
kono
parents:
diff changeset
625 when EM_386 =>
kono
parents:
diff changeset
626 Res.Arch := i386;
kono
parents:
diff changeset
627
kono
parents:
diff changeset
628 when EM_MIPS
kono
parents:
diff changeset
629 | EM_MIPS_RS3_LE
kono
parents:
diff changeset
630 =>
kono
parents:
diff changeset
631 Res.Arch := MIPS;
kono
parents:
diff changeset
632
kono
parents:
diff changeset
633 when EM_PPC =>
kono
parents:
diff changeset
634 Res.Arch := PPC;
kono
parents:
diff changeset
635
kono
parents:
diff changeset
636 when EM_PPC64 =>
kono
parents:
diff changeset
637 Res.Arch := PPC64;
kono
parents:
diff changeset
638
kono
parents:
diff changeset
639 when EM_SPARCV9 =>
kono
parents:
diff changeset
640 Res.Arch := SPARC64;
kono
parents:
diff changeset
641
kono
parents:
diff changeset
642 when EM_IA_64 =>
kono
parents:
diff changeset
643 Res.Arch := IA64;
kono
parents:
diff changeset
644
kono
parents:
diff changeset
645 when EM_X86_64 =>
kono
parents:
diff changeset
646 Res.Arch := x86_64;
kono
parents:
diff changeset
647
kono
parents:
diff changeset
648 when others =>
kono
parents:
diff changeset
649 raise Format_Error with "unrecognized architecture";
kono
parents:
diff changeset
650 end case;
kono
parents:
diff changeset
651
kono
parents:
diff changeset
652 -- Map section table and section string table
kono
parents:
diff changeset
653 Res.Sectab_Stream := Create_Stream
kono
parents:
diff changeset
654 (F, File_Size (Hdr.E_Shoff),
kono
parents:
diff changeset
655 File_Size (Hdr.E_Shnum) * File_Size (Hdr.E_Shentsize));
kono
parents:
diff changeset
656 Sec := Get_Section (Res, uint32 (Hdr.E_Shstrndx));
kono
parents:
diff changeset
657 Res.Secstr_Stream := Create_Stream (Res, Sec);
kono
parents:
diff changeset
658
kono
parents:
diff changeset
659 -- Map symbol and string table
kono
parents:
diff changeset
660 Sec := Get_Symbol_Table (Res);
kono
parents:
diff changeset
661 Res.Symtab_Stream := Create_Stream (Res, Sec);
kono
parents:
diff changeset
662 Res.Symtab_Last := Offset (Sec.Size);
kono
parents:
diff changeset
663
kono
parents:
diff changeset
664 Sec := Get_String_Table (Res);
kono
parents:
diff changeset
665 Res.Symstr_Stream := Create_Stream (Res, Sec);
kono
parents:
diff changeset
666
kono
parents:
diff changeset
667 return Res;
kono
parents:
diff changeset
668 end Initialize;
kono
parents:
diff changeset
669
kono
parents:
diff changeset
670 -----------------
kono
parents:
diff changeset
671 -- Read_Header --
kono
parents:
diff changeset
672 -----------------
kono
parents:
diff changeset
673
kono
parents:
diff changeset
674 function Read_Header (F : in out Mapped_Stream) return Header is
kono
parents:
diff changeset
675 Hdr : Header;
kono
parents:
diff changeset
676 begin
kono
parents:
diff changeset
677 Seek (F, 0);
kono
parents:
diff changeset
678 Read_Raw (F, Hdr'Address, uint32 (Hdr'Size / SSU));
kono
parents:
diff changeset
679 return Hdr;
kono
parents:
diff changeset
680 end Read_Header;
kono
parents:
diff changeset
681
kono
parents:
diff changeset
682 -------------------------
kono
parents:
diff changeset
683 -- Read_Section_Header --
kono
parents:
diff changeset
684 -------------------------
kono
parents:
diff changeset
685
kono
parents:
diff changeset
686 function Read_Section_Header
kono
parents:
diff changeset
687 (Obj : in out ELF_Object_File;
kono
parents:
diff changeset
688 Shnum : uint32) return Section_Header
kono
parents:
diff changeset
689 is
kono
parents:
diff changeset
690 Shdr : Section_Header;
kono
parents:
diff changeset
691 begin
kono
parents:
diff changeset
692 Seek (Obj.Sectab_Stream, Offset (Shnum * Section_Header'Size / SSU));
kono
parents:
diff changeset
693 Read_Raw (Obj.Sectab_Stream, Shdr'Address, Section_Header'Size / SSU);
kono
parents:
diff changeset
694 return Shdr;
kono
parents:
diff changeset
695 end Read_Section_Header;
kono
parents:
diff changeset
696
kono
parents:
diff changeset
697 -----------------
kono
parents:
diff changeset
698 -- Read_Symbol --
kono
parents:
diff changeset
699 -----------------
kono
parents:
diff changeset
700
kono
parents:
diff changeset
701 function Read_Symbol
kono
parents:
diff changeset
702 (Obj : in out ELF_Object_File;
kono
parents:
diff changeset
703 Off : Offset) return Object_Symbol
kono
parents:
diff changeset
704 is
kono
parents:
diff changeset
705 ST_Entry32 : Symtab_Entry32;
kono
parents:
diff changeset
706 ST_Entry64 : Symtab_Entry64;
kono
parents:
diff changeset
707 Res : Object_Symbol;
kono
parents:
diff changeset
708
kono
parents:
diff changeset
709 begin
kono
parents:
diff changeset
710 Seek (Obj.Symtab_Stream, Off);
kono
parents:
diff changeset
711
kono
parents:
diff changeset
712 case uword'Size is
kono
parents:
diff changeset
713 when 32 =>
kono
parents:
diff changeset
714 Read_Raw (Obj.Symtab_Stream, ST_Entry32'Address,
kono
parents:
diff changeset
715 uint32 (ST_Entry32'Size / SSU));
kono
parents:
diff changeset
716 Res := (Off,
kono
parents:
diff changeset
717 Off + ST_Entry32'Size / SSU,
kono
parents:
diff changeset
718 uint64 (ST_Entry32.St_Value),
kono
parents:
diff changeset
719 uint64 (ST_Entry32.St_Size));
kono
parents:
diff changeset
720
kono
parents:
diff changeset
721 when 64 =>
kono
parents:
diff changeset
722 Read_Raw (Obj.Symtab_Stream, ST_Entry64'Address,
kono
parents:
diff changeset
723 uint32 (ST_Entry64'Size / SSU));
kono
parents:
diff changeset
724 Res := (Off,
kono
parents:
diff changeset
725 Off + ST_Entry64'Size / SSU,
kono
parents:
diff changeset
726 ST_Entry64.St_Value,
kono
parents:
diff changeset
727 ST_Entry64.St_Size);
kono
parents:
diff changeset
728
kono
parents:
diff changeset
729 when others =>
kono
parents:
diff changeset
730 raise Program_Error;
kono
parents:
diff changeset
731 end case;
kono
parents:
diff changeset
732
kono
parents:
diff changeset
733 return Res;
kono
parents:
diff changeset
734 end Read_Symbol;
kono
parents:
diff changeset
735
kono
parents:
diff changeset
736 ----------
kono
parents:
diff changeset
737 -- Name --
kono
parents:
diff changeset
738 ----------
kono
parents:
diff changeset
739
kono
parents:
diff changeset
740 function Name
kono
parents:
diff changeset
741 (Obj : in out ELF_Object_File;
kono
parents:
diff changeset
742 Sec : Object_Section) return String
kono
parents:
diff changeset
743 is
kono
parents:
diff changeset
744 SHdr : Section_Header;
kono
parents:
diff changeset
745 begin
kono
parents:
diff changeset
746 SHdr := Read_Section_Header (Obj, Sec.Num);
kono
parents:
diff changeset
747 return Offset_To_String (Obj.Secstr_Stream, Offset (SHdr.Sh_Name));
kono
parents:
diff changeset
748 end Name;
kono
parents:
diff changeset
749
kono
parents:
diff changeset
750 function Name
kono
parents:
diff changeset
751 (Obj : in out ELF_Object_File;
kono
parents:
diff changeset
752 Sym : Object_Symbol) return String_Ptr_Len
kono
parents:
diff changeset
753 is
kono
parents:
diff changeset
754 ST_Entry32 : Symtab_Entry32;
kono
parents:
diff changeset
755 ST_Entry64 : Symtab_Entry64;
kono
parents:
diff changeset
756 Name_Off : Offset;
kono
parents:
diff changeset
757
kono
parents:
diff changeset
758 begin
kono
parents:
diff changeset
759 -- Test that this symbol is not null
kono
parents:
diff changeset
760
kono
parents:
diff changeset
761 if Sym = Null_Symbol then
kono
parents:
diff changeset
762 return (null, 0);
kono
parents:
diff changeset
763 end if;
kono
parents:
diff changeset
764
kono
parents:
diff changeset
765 -- Read the symbol table entry
kono
parents:
diff changeset
766
kono
parents:
diff changeset
767 Seek (Obj.Symtab_Stream, Sym.Off);
kono
parents:
diff changeset
768
kono
parents:
diff changeset
769 case uword'Size is
kono
parents:
diff changeset
770 when 32 =>
kono
parents:
diff changeset
771 Read_Raw (Obj.Symtab_Stream, ST_Entry32'Address,
kono
parents:
diff changeset
772 uint32 (ST_Entry32'Size / SSU));
kono
parents:
diff changeset
773 Name_Off := Offset (ST_Entry32.St_Name);
kono
parents:
diff changeset
774
kono
parents:
diff changeset
775 when 64 =>
kono
parents:
diff changeset
776 Read_Raw (Obj.Symtab_Stream, ST_Entry64'Address,
kono
parents:
diff changeset
777 uint32 (ST_Entry64'Size / SSU));
kono
parents:
diff changeset
778 Name_Off := Offset (ST_Entry64.St_Name);
kono
parents:
diff changeset
779
kono
parents:
diff changeset
780 when others =>
kono
parents:
diff changeset
781 raise Program_Error;
kono
parents:
diff changeset
782 end case;
kono
parents:
diff changeset
783
kono
parents:
diff changeset
784 -- Fetch the name from the string table
kono
parents:
diff changeset
785
kono
parents:
diff changeset
786 Seek (Obj.Symstr_Stream, Name_Off);
kono
parents:
diff changeset
787 return Read (Obj.Symstr_Stream);
kono
parents:
diff changeset
788 end Name;
kono
parents:
diff changeset
789
kono
parents:
diff changeset
790 end ELF_Ops;
kono
parents:
diff changeset
791
kono
parents:
diff changeset
792 package ELF32_Ops is new ELF_Ops (uint32);
kono
parents:
diff changeset
793 package ELF64_Ops is new ELF_Ops (uint64);
kono
parents:
diff changeset
794
kono
parents:
diff changeset
795 ----------------
kono
parents:
diff changeset
796 -- PECOFF_Ops --
kono
parents:
diff changeset
797 ----------------
kono
parents:
diff changeset
798
kono
parents:
diff changeset
799 package body PECOFF_Ops is
kono
parents:
diff changeset
800
kono
parents:
diff changeset
801 function Decode_Name
kono
parents:
diff changeset
802 (Obj : in out PECOFF_Object_File;
kono
parents:
diff changeset
803 Raw_Name : String) return String;
kono
parents:
diff changeset
804 -- A section name is an 8 byte field padded on the right with null
kono
parents:
diff changeset
805 -- characters, or a '\' followed by an ASCII decimal string indicating
kono
parents:
diff changeset
806 -- an offset in to the string table. This routine decodes this
kono
parents:
diff changeset
807
kono
parents:
diff changeset
808 function Get_Section_Virtual_Address
kono
parents:
diff changeset
809 (Obj : in out PECOFF_Object_File;
kono
parents:
diff changeset
810 Index : uint32) return uint64;
kono
parents:
diff changeset
811 -- Fetch the address at which a section is loaded
kono
parents:
diff changeset
812
kono
parents:
diff changeset
813 function Read_Section_Header
kono
parents:
diff changeset
814 (Obj : in out PECOFF_Object_File;
kono
parents:
diff changeset
815 Index : uint32) return Section_Header;
kono
parents:
diff changeset
816 -- Read a header from section table
kono
parents:
diff changeset
817
kono
parents:
diff changeset
818 function String_Table
kono
parents:
diff changeset
819 (Obj : in out PECOFF_Object_File;
kono
parents:
diff changeset
820 Index : Offset) return String;
kono
parents:
diff changeset
821 -- Return an entry from the string table
kono
parents:
diff changeset
822
kono
parents:
diff changeset
823 -----------------
kono
parents:
diff changeset
824 -- Decode_Name --
kono
parents:
diff changeset
825 -----------------
kono
parents:
diff changeset
826
kono
parents:
diff changeset
827 function Decode_Name
kono
parents:
diff changeset
828 (Obj : in out PECOFF_Object_File;
kono
parents:
diff changeset
829 Raw_Name : String) return String
kono
parents:
diff changeset
830 is
kono
parents:
diff changeset
831 Name_Or_Ref : constant String := Trim_Trailing_Nuls (Raw_Name);
kono
parents:
diff changeset
832 Off : Offset;
kono
parents:
diff changeset
833
kono
parents:
diff changeset
834 begin
kono
parents:
diff changeset
835 -- We should never find a symbol with a zero length name. If we do it
kono
parents:
diff changeset
836 -- probably means we are not parsing the symbol table correctly. If
kono
parents:
diff changeset
837 -- this happens we raise a fatal error.
kono
parents:
diff changeset
838
kono
parents:
diff changeset
839 if Name_Or_Ref'Length = 0 then
kono
parents:
diff changeset
840 raise Format_Error with
kono
parents:
diff changeset
841 "found zero length symbol in symbol table";
kono
parents:
diff changeset
842 end if;
kono
parents:
diff changeset
843
kono
parents:
diff changeset
844 if Name_Or_Ref (1) /= '/' then
kono
parents:
diff changeset
845 return Name_Or_Ref;
kono
parents:
diff changeset
846 else
kono
parents:
diff changeset
847 Off := Offset'Value (Name_Or_Ref (2 .. Name_Or_Ref'Last));
kono
parents:
diff changeset
848 return String_Table (Obj, Off);
kono
parents:
diff changeset
849 end if;
kono
parents:
diff changeset
850 end Decode_Name;
kono
parents:
diff changeset
851
kono
parents:
diff changeset
852 ------------------
kono
parents:
diff changeset
853 -- First_Symbol --
kono
parents:
diff changeset
854 ------------------
kono
parents:
diff changeset
855
kono
parents:
diff changeset
856 function First_Symbol
kono
parents:
diff changeset
857 (Obj : in out PECOFF_Object_File) return Object_Symbol is
kono
parents:
diff changeset
858 begin
kono
parents:
diff changeset
859 -- Return Null_Symbol in the case that the symbol table is empty
kono
parents:
diff changeset
860
kono
parents:
diff changeset
861 if Obj.Symtab_Last = 0 then
kono
parents:
diff changeset
862 return Null_Symbol;
kono
parents:
diff changeset
863 end if;
kono
parents:
diff changeset
864
kono
parents:
diff changeset
865 return Read_Symbol (Obj, 0);
kono
parents:
diff changeset
866 end First_Symbol;
kono
parents:
diff changeset
867
kono
parents:
diff changeset
868 -----------------
kono
parents:
diff changeset
869 -- Get_Section --
kono
parents:
diff changeset
870 -----------------
kono
parents:
diff changeset
871
kono
parents:
diff changeset
872 function Get_Section
kono
parents:
diff changeset
873 (Obj : in out PECOFF_Object_File;
kono
parents:
diff changeset
874 Index : uint32) return Object_Section
kono
parents:
diff changeset
875 is
kono
parents:
diff changeset
876 Sec : constant Section_Header := Read_Section_Header (Obj, Index);
kono
parents:
diff changeset
877 begin
kono
parents:
diff changeset
878 -- Use VirtualSize instead of SizeOfRawData. The latter is rounded to
kono
parents:
diff changeset
879 -- the page size, so it may add garbage to the content. On the other
kono
parents:
diff changeset
880 -- side, the former may be larger than the latter in case of 0
kono
parents:
diff changeset
881 -- padding.
kono
parents:
diff changeset
882
kono
parents:
diff changeset
883 return (Index,
kono
parents:
diff changeset
884 Offset (Sec.PointerToRawData),
kono
parents:
diff changeset
885 uint64 (Sec.VirtualAddress) + Obj.ImageBase,
kono
parents:
diff changeset
886 uint64 (Sec.VirtualSize),
kono
parents:
diff changeset
887 (Sec.Characteristics and IMAGE_SCN_CNT_CODE) /= 0);
kono
parents:
diff changeset
888 end Get_Section;
kono
parents:
diff changeset
889
kono
parents:
diff changeset
890 ---------------------------------
kono
parents:
diff changeset
891 -- Get_Section_Virtual_Address --
kono
parents:
diff changeset
892 ---------------------------------
kono
parents:
diff changeset
893
kono
parents:
diff changeset
894 function Get_Section_Virtual_Address
kono
parents:
diff changeset
895 (Obj : in out PECOFF_Object_File;
kono
parents:
diff changeset
896 Index : uint32) return uint64
kono
parents:
diff changeset
897 is
kono
parents:
diff changeset
898 Sec : Section_Header;
kono
parents:
diff changeset
899
kono
parents:
diff changeset
900 begin
kono
parents:
diff changeset
901 -- Try cache
kono
parents:
diff changeset
902
kono
parents:
diff changeset
903 if Index = Obj.GSVA_Sec then
kono
parents:
diff changeset
904 return Obj.GSVA_Addr;
kono
parents:
diff changeset
905 end if;
kono
parents:
diff changeset
906
kono
parents:
diff changeset
907 Obj.GSVA_Sec := Index;
kono
parents:
diff changeset
908 Sec := Read_Section_Header (Obj, Index);
kono
parents:
diff changeset
909 Obj.GSVA_Addr := Obj.ImageBase + uint64 (Sec.VirtualAddress);
kono
parents:
diff changeset
910 return Obj.GSVA_Addr;
kono
parents:
diff changeset
911 end Get_Section_Virtual_Address;
kono
parents:
diff changeset
912
kono
parents:
diff changeset
913 ----------------
kono
parents:
diff changeset
914 -- Initialize --
kono
parents:
diff changeset
915 ----------------
kono
parents:
diff changeset
916
kono
parents:
diff changeset
917 function Initialize
kono
parents:
diff changeset
918 (F : Mapped_File;
kono
parents:
diff changeset
919 Hdr : Header;
kono
parents:
diff changeset
920 In_Exception : Boolean) return PECOFF_Object_File
kono
parents:
diff changeset
921 is
kono
parents:
diff changeset
922 Res : PECOFF_Object_File
kono
parents:
diff changeset
923 (Format => (case Hdr.Variant is
kono
parents:
diff changeset
924 when PECOFF_Ops.VARIANT_PE32 => PECOFF,
kono
parents:
diff changeset
925 when PECOFF_Ops.VARIANT_PE32_PLUS => PECOFF_PLUS,
kono
parents:
diff changeset
926 when others => raise Program_Error
kono
parents:
diff changeset
927 with "unrecognized PECOFF variant"));
kono
parents:
diff changeset
928 Symtab_Size : constant Offset :=
kono
parents:
diff changeset
929 Offset (Hdr.NumberOfSymbols) * (Symtab_Entry'Size / SSU);
kono
parents:
diff changeset
930 Strtab_Size : uint32;
kono
parents:
diff changeset
931 Hdr_Offset : Offset;
kono
parents:
diff changeset
932 Opt_Offset : File_Size;
kono
parents:
diff changeset
933 Opt_Stream : Mapped_Stream;
kono
parents:
diff changeset
934 begin
kono
parents:
diff changeset
935 Res.MF := F;
kono
parents:
diff changeset
936 Res.In_Exception := In_Exception;
kono
parents:
diff changeset
937
kono
parents:
diff changeset
938 case Hdr.Machine is
kono
parents:
diff changeset
939 when PECOFF_Ops.IMAGE_FILE_MACHINE_I386 =>
kono
parents:
diff changeset
940 Res.Arch := i386;
kono
parents:
diff changeset
941 when PECOFF_Ops.IMAGE_FILE_MACHINE_IA64 =>
kono
parents:
diff changeset
942 Res.Arch := IA64;
kono
parents:
diff changeset
943 when PECOFF_Ops.IMAGE_FILE_MACHINE_AMD64 =>
kono
parents:
diff changeset
944 Res.Arch := x86_64;
kono
parents:
diff changeset
945 when others =>
kono
parents:
diff changeset
946 raise Format_Error with "unrecognized architecture";
kono
parents:
diff changeset
947 end case;
kono
parents:
diff changeset
948
kono
parents:
diff changeset
949 Res.Num_Sections := uint32 (Hdr.NumberOfSections);
kono
parents:
diff changeset
950
kono
parents:
diff changeset
951 -- Map symbol table and the first following word (which is the length
kono
parents:
diff changeset
952 -- of the string table).
kono
parents:
diff changeset
953
kono
parents:
diff changeset
954 Res.Symtab_Last := Symtab_Size;
kono
parents:
diff changeset
955 Res.Symtab_Stream := Create_Stream
kono
parents:
diff changeset
956 (F,
kono
parents:
diff changeset
957 File_Size (Hdr.PointerToSymbolTable),
kono
parents:
diff changeset
958 File_Size (Symtab_Size + 4));
kono
parents:
diff changeset
959
kono
parents:
diff changeset
960 -- Map string table. The first 4 bytes are the length of the string
kono
parents:
diff changeset
961 -- table and are part of it.
kono
parents:
diff changeset
962
kono
parents:
diff changeset
963 Seek (Res.Symtab_Stream, Symtab_Size);
kono
parents:
diff changeset
964 Strtab_Size := Read (Res.Symtab_Stream);
kono
parents:
diff changeset
965 Res.Symstr_Stream := Create_Stream
kono
parents:
diff changeset
966 (F,
kono
parents:
diff changeset
967 File_Size (Hdr.PointerToSymbolTable) + File_Size (Symtab_Size),
kono
parents:
diff changeset
968 File_Size (Strtab_Size));
kono
parents:
diff changeset
969
kono
parents:
diff changeset
970 -- Map section table
kono
parents:
diff changeset
971
kono
parents:
diff changeset
972 Opt_Stream := Create_Stream (Res.Mf, Signature_Loc_Offset, 4);
kono
parents:
diff changeset
973 Hdr_Offset := Offset (uint32'(Read (Opt_Stream)));
kono
parents:
diff changeset
974 Close (Opt_Stream);
kono
parents:
diff changeset
975 Res.Sectab_Stream := Create_Stream
kono
parents:
diff changeset
976 (F,
kono
parents:
diff changeset
977 File_Size (Hdr_Offset +
kono
parents:
diff changeset
978 Size_Of_Standard_Header_Fields +
kono
parents:
diff changeset
979 Offset (Hdr.SizeOfOptionalHeader)),
kono
parents:
diff changeset
980 File_Size (Res.Num_Sections)
kono
parents:
diff changeset
981 * File_Size (Section_Header'Size / SSU));
kono
parents:
diff changeset
982
kono
parents:
diff changeset
983 -- Read optional header and extract image base
kono
parents:
diff changeset
984
kono
parents:
diff changeset
985 Opt_Offset := File_Size (Hdr_Offset + Size_Of_Standard_Header_Fields);
kono
parents:
diff changeset
986
kono
parents:
diff changeset
987 if Res.Format = PECOFF then
kono
parents:
diff changeset
988 declare
kono
parents:
diff changeset
989 Opt_32 : Optional_Header_PE32;
kono
parents:
diff changeset
990 begin
kono
parents:
diff changeset
991 Opt_Stream := Create_Stream
kono
parents:
diff changeset
992 (Res.Mf, Opt_Offset, Opt_32'Size / SSU);
kono
parents:
diff changeset
993 Read_Raw
kono
parents:
diff changeset
994 (Opt_Stream, Opt_32'Address, uint32 (Opt_32'Size / SSU));
kono
parents:
diff changeset
995 Res.ImageBase := uint64 (Opt_32.ImageBase);
kono
parents:
diff changeset
996 Close (Opt_Stream);
kono
parents:
diff changeset
997 end;
kono
parents:
diff changeset
998
kono
parents:
diff changeset
999 else
kono
parents:
diff changeset
1000 declare
kono
parents:
diff changeset
1001 Opt_64 : Optional_Header_PE64;
kono
parents:
diff changeset
1002 begin
kono
parents:
diff changeset
1003 Opt_Stream := Create_Stream
kono
parents:
diff changeset
1004 (Res.Mf, Opt_Offset, Opt_64'Size / SSU);
kono
parents:
diff changeset
1005 Read_Raw
kono
parents:
diff changeset
1006 (Opt_Stream, Opt_64'Address, uint32 (Opt_64'Size / SSU));
kono
parents:
diff changeset
1007 Res.ImageBase := Opt_64.ImageBase;
kono
parents:
diff changeset
1008 Close (Opt_Stream);
kono
parents:
diff changeset
1009 end;
kono
parents:
diff changeset
1010 end if;
kono
parents:
diff changeset
1011
kono
parents:
diff changeset
1012 return Res;
kono
parents:
diff changeset
1013 end Initialize;
kono
parents:
diff changeset
1014
kono
parents:
diff changeset
1015 -----------------
kono
parents:
diff changeset
1016 -- Read_Symbol --
kono
parents:
diff changeset
1017 -----------------
kono
parents:
diff changeset
1018
kono
parents:
diff changeset
1019 function Read_Symbol
kono
parents:
diff changeset
1020 (Obj : in out PECOFF_Object_File;
kono
parents:
diff changeset
1021 Off : Offset) return Object_Symbol
kono
parents:
diff changeset
1022 is
kono
parents:
diff changeset
1023 ST_Entry : Symtab_Entry;
kono
parents:
diff changeset
1024 ST_Last : Symtab_Entry;
kono
parents:
diff changeset
1025 Aux_Entry : Auxent_Section;
kono
parents:
diff changeset
1026 Sz : constant Offset := ST_Entry'Size / SSU;
kono
parents:
diff changeset
1027 Result : Object_Symbol;
kono
parents:
diff changeset
1028 Noff : Offset;
kono
parents:
diff changeset
1029 Sym_Off : Offset;
kono
parents:
diff changeset
1030
kono
parents:
diff changeset
1031 begin
kono
parents:
diff changeset
1032 -- Seek to the successor of Prev
kono
parents:
diff changeset
1033
kono
parents:
diff changeset
1034 Noff := Off;
kono
parents:
diff changeset
1035
kono
parents:
diff changeset
1036 loop
kono
parents:
diff changeset
1037 Sym_Off := Noff;
kono
parents:
diff changeset
1038
kono
parents:
diff changeset
1039 Seek (Obj.Symtab_Stream, Sym_Off);
kono
parents:
diff changeset
1040 Read_Raw (Obj.Symtab_Stream, ST_Entry'Address, uint32 (Sz));
kono
parents:
diff changeset
1041
kono
parents:
diff changeset
1042 -- Skip AUX entries
kono
parents:
diff changeset
1043
kono
parents:
diff changeset
1044 Noff := Noff + Offset (1 + ST_Entry.NumberOfAuxSymbols) * Sz;
kono
parents:
diff changeset
1045
kono
parents:
diff changeset
1046 exit when ST_Entry.TypeField = Function_Symbol_Type
kono
parents:
diff changeset
1047 and then ST_Entry.SectionNumber > 0;
kono
parents:
diff changeset
1048
kono
parents:
diff changeset
1049 if Noff >= Obj.Symtab_Last then
kono
parents:
diff changeset
1050 return Null_Symbol;
kono
parents:
diff changeset
1051 end if;
kono
parents:
diff changeset
1052 end loop;
kono
parents:
diff changeset
1053
kono
parents:
diff changeset
1054 -- Construct the symbol
kono
parents:
diff changeset
1055
kono
parents:
diff changeset
1056 Result :=
kono
parents:
diff changeset
1057 (Off => Sym_Off,
kono
parents:
diff changeset
1058 Next => Noff,
kono
parents:
diff changeset
1059 Value => uint64 (ST_Entry.Value),
kono
parents:
diff changeset
1060 Size => 0);
kono
parents:
diff changeset
1061
kono
parents:
diff changeset
1062 -- Set the size as accurately as possible
kono
parents:
diff changeset
1063
kono
parents:
diff changeset
1064 -- The size of a symbol is not directly available so we try scanning
kono
parents:
diff changeset
1065 -- to the next function and assuming the code ends there.
kono
parents:
diff changeset
1066
kono
parents:
diff changeset
1067 loop
kono
parents:
diff changeset
1068 -- Read symbol and AUX entries
kono
parents:
diff changeset
1069
kono
parents:
diff changeset
1070 Sym_Off := Noff;
kono
parents:
diff changeset
1071 Seek (Obj.Symtab_Stream, Sym_Off);
kono
parents:
diff changeset
1072 Read_Raw (Obj.Symtab_Stream, ST_Last'Address, uint32 (Sz));
kono
parents:
diff changeset
1073
kono
parents:
diff changeset
1074 for I in 1 .. ST_Last.NumberOfAuxSymbols loop
kono
parents:
diff changeset
1075 Read_Raw (Obj.Symtab_Stream, Aux_Entry'Address, uint32 (Sz));
kono
parents:
diff changeset
1076 end loop;
kono
parents:
diff changeset
1077
kono
parents:
diff changeset
1078 Noff := Noff + Offset (1 + ST_Last.NumberOfAuxSymbols) * Sz;
kono
parents:
diff changeset
1079
kono
parents:
diff changeset
1080 if ST_Last.TypeField = Function_Symbol_Type then
kono
parents:
diff changeset
1081 if ST_Last.SectionNumber = ST_Entry.SectionNumber
kono
parents:
diff changeset
1082 and then ST_Last.Value >= ST_Entry.Value
kono
parents:
diff changeset
1083 then
kono
parents:
diff changeset
1084 -- Symbol is a function past ST_Entry
kono
parents:
diff changeset
1085
kono
parents:
diff changeset
1086 Result.Size := uint64 (ST_Last.Value - ST_Entry.Value);
kono
parents:
diff changeset
1087
kono
parents:
diff changeset
1088 else
kono
parents:
diff changeset
1089 -- Not correlated function
kono
parents:
diff changeset
1090
kono
parents:
diff changeset
1091 Result.Next := Sym_Off;
kono
parents:
diff changeset
1092 end if;
kono
parents:
diff changeset
1093
kono
parents:
diff changeset
1094 exit;
kono
parents:
diff changeset
1095
kono
parents:
diff changeset
1096 elsif ST_Last.SectionNumber = ST_Entry.SectionNumber
kono
parents:
diff changeset
1097 and then ST_Last.TypeField = Not_Function_Symbol_Type
kono
parents:
diff changeset
1098 and then ST_Last.StorageClass = 3
kono
parents:
diff changeset
1099 and then ST_Last.NumberOfAuxSymbols = 1
kono
parents:
diff changeset
1100 then
kono
parents:
diff changeset
1101 -- Symbol is a section
kono
parents:
diff changeset
1102
kono
parents:
diff changeset
1103 Result.Size := uint64 (ST_Last.Value + Aux_Entry.Length
kono
parents:
diff changeset
1104 - ST_Entry.Value);
kono
parents:
diff changeset
1105 Result.Next := Noff;
kono
parents:
diff changeset
1106 exit;
kono
parents:
diff changeset
1107 end if;
kono
parents:
diff changeset
1108
kono
parents:
diff changeset
1109 exit when Noff >= Obj.Symtab_Last;
kono
parents:
diff changeset
1110 end loop;
kono
parents:
diff changeset
1111
kono
parents:
diff changeset
1112 -- Relocate the address
kono
parents:
diff changeset
1113
kono
parents:
diff changeset
1114 Result.Value :=
kono
parents:
diff changeset
1115 Result.Value + Get_Section_Virtual_Address
kono
parents:
diff changeset
1116 (Obj, uint32 (ST_Entry.SectionNumber - 1));
kono
parents:
diff changeset
1117
kono
parents:
diff changeset
1118 return Result;
kono
parents:
diff changeset
1119 end Read_Symbol;
kono
parents:
diff changeset
1120
kono
parents:
diff changeset
1121 ------------------
kono
parents:
diff changeset
1122 -- Read_Header --
kono
parents:
diff changeset
1123 ------------------
kono
parents:
diff changeset
1124
kono
parents:
diff changeset
1125 function Read_Header (F : in out Mapped_Stream) return Header is
kono
parents:
diff changeset
1126 Hdr : Header;
kono
parents:
diff changeset
1127 Off : int32;
kono
parents:
diff changeset
1128
kono
parents:
diff changeset
1129 begin
kono
parents:
diff changeset
1130 -- Skip the MSDOS stub, and seek directly to the file offset
kono
parents:
diff changeset
1131
kono
parents:
diff changeset
1132 Seek (F, Signature_Loc_Offset);
kono
parents:
diff changeset
1133 Off := Read (F);
kono
parents:
diff changeset
1134
kono
parents:
diff changeset
1135 -- Read the COFF file header
kono
parents:
diff changeset
1136
kono
parents:
diff changeset
1137 Seek (F, Offset (Off));
kono
parents:
diff changeset
1138 Read_Raw (F, Hdr'Address, uint32 (Hdr'Size / SSU));
kono
parents:
diff changeset
1139 return Hdr;
kono
parents:
diff changeset
1140 end Read_Header;
kono
parents:
diff changeset
1141
kono
parents:
diff changeset
1142 -------------------------
kono
parents:
diff changeset
1143 -- Read_Section_Header --
kono
parents:
diff changeset
1144 -------------------------
kono
parents:
diff changeset
1145
kono
parents:
diff changeset
1146 function Read_Section_Header
kono
parents:
diff changeset
1147 (Obj : in out PECOFF_Object_File;
kono
parents:
diff changeset
1148 Index : uint32) return Section_Header
kono
parents:
diff changeset
1149 is
kono
parents:
diff changeset
1150 Sec : Section_Header;
kono
parents:
diff changeset
1151 begin
kono
parents:
diff changeset
1152 Seek (Obj.Sectab_Stream, Offset (Index * Section_Header'Size / SSU));
kono
parents:
diff changeset
1153 Read_Raw (Obj.Sectab_Stream, Sec'Address, Section_Header'Size / SSU);
kono
parents:
diff changeset
1154 return Sec;
kono
parents:
diff changeset
1155 end Read_Section_Header;
kono
parents:
diff changeset
1156
kono
parents:
diff changeset
1157 ----------
kono
parents:
diff changeset
1158 -- Name --
kono
parents:
diff changeset
1159 ----------
kono
parents:
diff changeset
1160
kono
parents:
diff changeset
1161 function Name
kono
parents:
diff changeset
1162 (Obj : in out PECOFF_Object_File;
kono
parents:
diff changeset
1163 Sec : Object_Section) return String
kono
parents:
diff changeset
1164 is
kono
parents:
diff changeset
1165 Shdr : constant Section_Header := Read_Section_Header (Obj, Sec.Num);
kono
parents:
diff changeset
1166 begin
kono
parents:
diff changeset
1167 return Decode_Name (Obj, Shdr.Name);
kono
parents:
diff changeset
1168 end Name;
kono
parents:
diff changeset
1169
kono
parents:
diff changeset
1170 -------------------
kono
parents:
diff changeset
1171 -- String_Table --
kono
parents:
diff changeset
1172 -------------------
kono
parents:
diff changeset
1173
kono
parents:
diff changeset
1174 function String_Table
kono
parents:
diff changeset
1175 (Obj : in out PECOFF_Object_File;
kono
parents:
diff changeset
1176 Index : Offset) return String is
kono
parents:
diff changeset
1177 begin
kono
parents:
diff changeset
1178 -- An index of zero is used to represent an empty string, as the
kono
parents:
diff changeset
1179 -- first word of the string table is specified to contain the length
kono
parents:
diff changeset
1180 -- of the table rather than its contents.
kono
parents:
diff changeset
1181
kono
parents:
diff changeset
1182 if Index = 0 then
kono
parents:
diff changeset
1183 return "";
kono
parents:
diff changeset
1184
kono
parents:
diff changeset
1185 else
kono
parents:
diff changeset
1186 return Offset_To_String (Obj.Symstr_Stream, Index);
kono
parents:
diff changeset
1187 end if;
kono
parents:
diff changeset
1188 end String_Table;
kono
parents:
diff changeset
1189
kono
parents:
diff changeset
1190 ----------
kono
parents:
diff changeset
1191 -- Name --
kono
parents:
diff changeset
1192 ----------
kono
parents:
diff changeset
1193
kono
parents:
diff changeset
1194 function Name
kono
parents:
diff changeset
1195 (Obj : in out PECOFF_Object_File;
kono
parents:
diff changeset
1196 Sym : Object_Symbol) return String_Ptr_Len
kono
parents:
diff changeset
1197 is
kono
parents:
diff changeset
1198 ST_Entry : Symtab_Entry;
kono
parents:
diff changeset
1199
kono
parents:
diff changeset
1200 begin
kono
parents:
diff changeset
1201 Seek (Obj.Symtab_Stream, Sym.Off);
kono
parents:
diff changeset
1202 Read_Raw (Obj.Symtab_Stream, ST_Entry'Address, ST_Entry'Size / SSU);
kono
parents:
diff changeset
1203
kono
parents:
diff changeset
1204 declare
kono
parents:
diff changeset
1205 -- Symbol table entries are packed and Table_Entry.Name may not be
kono
parents:
diff changeset
1206 -- sufficiently aligned to interpret as a 32 bit word, so it is
kono
parents:
diff changeset
1207 -- copied to a temporary
kono
parents:
diff changeset
1208
kono
parents:
diff changeset
1209 Aligned_Name : Name_Str := ST_Entry.Name;
kono
parents:
diff changeset
1210 for Aligned_Name'Alignment use 4;
kono
parents:
diff changeset
1211
kono
parents:
diff changeset
1212 First_Word : uint32;
kono
parents:
diff changeset
1213 pragma Import (Ada, First_Word);
kono
parents:
diff changeset
1214 -- Suppress initialization in Normalized_Scalars mode
kono
parents:
diff changeset
1215 for First_Word'Address use Aligned_Name (1)'Address;
kono
parents:
diff changeset
1216
kono
parents:
diff changeset
1217 Second_Word : uint32;
kono
parents:
diff changeset
1218 pragma Import (Ada, Second_Word);
kono
parents:
diff changeset
1219 -- Suppress initialization in Normalized_Scalars mode
kono
parents:
diff changeset
1220 for Second_Word'Address use Aligned_Name (5)'Address;
kono
parents:
diff changeset
1221
kono
parents:
diff changeset
1222 begin
kono
parents:
diff changeset
1223 if First_Word = 0 then
kono
parents:
diff changeset
1224 -- Second word is an offset in the symbol table
kono
parents:
diff changeset
1225 if Second_Word = 0 then
kono
parents:
diff changeset
1226 return (null, 0);
kono
parents:
diff changeset
1227 else
kono
parents:
diff changeset
1228 Seek (Obj.Symstr_Stream, int64 (Second_Word));
kono
parents:
diff changeset
1229 return Read (Obj.Symstr_Stream);
kono
parents:
diff changeset
1230 end if;
kono
parents:
diff changeset
1231 else
kono
parents:
diff changeset
1232 -- Inlined symbol name
kono
parents:
diff changeset
1233 Seek (Obj.Symtab_Stream, Sym.Off);
kono
parents:
diff changeset
1234 return To_String_Ptr_Len (Read (Obj.Symtab_Stream), 8);
kono
parents:
diff changeset
1235 end if;
kono
parents:
diff changeset
1236 end;
kono
parents:
diff changeset
1237 end Name;
kono
parents:
diff changeset
1238
kono
parents:
diff changeset
1239 end PECOFF_Ops;
kono
parents:
diff changeset
1240
kono
parents:
diff changeset
1241 -----------------
kono
parents:
diff changeset
1242 -- XCOFF32_Ops --
kono
parents:
diff changeset
1243 -----------------
kono
parents:
diff changeset
1244
kono
parents:
diff changeset
1245 package body XCOFF32_Ops is
kono
parents:
diff changeset
1246
kono
parents:
diff changeset
1247 function Read_Section_Header
kono
parents:
diff changeset
1248 (Obj : in out XCOFF32_Object_File;
kono
parents:
diff changeset
1249 Index : uint32) return Section_Header;
kono
parents:
diff changeset
1250 -- Read a header from section table
kono
parents:
diff changeset
1251
kono
parents:
diff changeset
1252 -----------------
kono
parents:
diff changeset
1253 -- Read_Symbol --
kono
parents:
diff changeset
1254 -----------------
kono
parents:
diff changeset
1255
kono
parents:
diff changeset
1256 function Read_Symbol
kono
parents:
diff changeset
1257 (Obj : in out XCOFF32_Object_File;
kono
parents:
diff changeset
1258 Off : Offset) return Object_Symbol
kono
parents:
diff changeset
1259 is
kono
parents:
diff changeset
1260 Sym : Symbol_Entry;
kono
parents:
diff changeset
1261 Sz : constant Offset := Symbol_Entry'Size / SSU;
kono
parents:
diff changeset
1262 Aux : Aux_Entry;
kono
parents:
diff changeset
1263 Result : Object_Symbol;
kono
parents:
diff changeset
1264 Noff : Offset;
kono
parents:
diff changeset
1265 Sym_Off : Offset;
kono
parents:
diff changeset
1266
kono
parents:
diff changeset
1267 procedure Read_LD_Symbol;
kono
parents:
diff changeset
1268 -- Read the next LD symbol
kono
parents:
diff changeset
1269
kono
parents:
diff changeset
1270 --------------------
kono
parents:
diff changeset
1271 -- Read_LD_Symbol --
kono
parents:
diff changeset
1272 --------------------
kono
parents:
diff changeset
1273
kono
parents:
diff changeset
1274 procedure Read_LD_Symbol is
kono
parents:
diff changeset
1275 begin
kono
parents:
diff changeset
1276 loop
kono
parents:
diff changeset
1277 Sym_Off := Noff;
kono
parents:
diff changeset
1278
kono
parents:
diff changeset
1279 Read_Raw (Obj.Symtab_Stream, Sym'Address, uint32 (Sz));
kono
parents:
diff changeset
1280
kono
parents:
diff changeset
1281 Noff := Noff + Offset (1 + Sym.n_numaux) * Sz;
kono
parents:
diff changeset
1282
kono
parents:
diff changeset
1283 for J in 1 .. Sym.n_numaux loop
kono
parents:
diff changeset
1284 Read_Raw (Obj.Symtab_Stream, Aux'Address, uint32 (Sz));
kono
parents:
diff changeset
1285 end loop;
kono
parents:
diff changeset
1286
kono
parents:
diff changeset
1287 exit when Noff >= Obj.Symtab_Last;
kono
parents:
diff changeset
1288
kono
parents:
diff changeset
1289 exit when Sym.n_numaux = 1
kono
parents:
diff changeset
1290 and then Sym.n_scnum /= 0
kono
parents:
diff changeset
1291 and then (Sym.n_sclass = C_EXT
kono
parents:
diff changeset
1292 or else Sym.n_sclass = C_HIDEXT
kono
parents:
diff changeset
1293 or else Sym.n_sclass = C_WEAKEXT)
kono
parents:
diff changeset
1294 and then Aux.x_smtyp = XTY_LD;
kono
parents:
diff changeset
1295 end loop;
kono
parents:
diff changeset
1296 end Read_LD_Symbol;
kono
parents:
diff changeset
1297
kono
parents:
diff changeset
1298 -- Start of processing for Read_Symbol
kono
parents:
diff changeset
1299
kono
parents:
diff changeset
1300 begin
kono
parents:
diff changeset
1301 Seek (Obj.Symtab_Stream, Off);
kono
parents:
diff changeset
1302 Noff := Off;
kono
parents:
diff changeset
1303 Read_LD_Symbol;
kono
parents:
diff changeset
1304
kono
parents:
diff changeset
1305 if Noff >= Obj.Symtab_Last then
kono
parents:
diff changeset
1306 return Null_Symbol;
kono
parents:
diff changeset
1307 end if;
kono
parents:
diff changeset
1308
kono
parents:
diff changeset
1309 -- Construct the symbol
kono
parents:
diff changeset
1310
kono
parents:
diff changeset
1311 Result := (Off => Sym_Off,
kono
parents:
diff changeset
1312 Next => Noff,
kono
parents:
diff changeset
1313 Value => uint64 (Sym.n_value),
kono
parents:
diff changeset
1314 Size => 0);
kono
parents:
diff changeset
1315
kono
parents:
diff changeset
1316 -- Look for the next symbol to compute the size
kono
parents:
diff changeset
1317
kono
parents:
diff changeset
1318 Read_LD_Symbol;
kono
parents:
diff changeset
1319
kono
parents:
diff changeset
1320 if Noff >= Obj.Symtab_Last then
kono
parents:
diff changeset
1321 return Null_Symbol;
kono
parents:
diff changeset
1322 end if;
kono
parents:
diff changeset
1323
kono
parents:
diff changeset
1324 Result.Size := uint64 (Sym.n_value) - Result.Value;
kono
parents:
diff changeset
1325 Result.Next := Sym_Off;
kono
parents:
diff changeset
1326 return Result;
kono
parents:
diff changeset
1327 end Read_Symbol;
kono
parents:
diff changeset
1328
kono
parents:
diff changeset
1329 ------------------
kono
parents:
diff changeset
1330 -- First_Symbol --
kono
parents:
diff changeset
1331 ------------------
kono
parents:
diff changeset
1332
kono
parents:
diff changeset
1333 function First_Symbol
kono
parents:
diff changeset
1334 (Obj : in out XCOFF32_Object_File) return Object_Symbol
kono
parents:
diff changeset
1335 is
kono
parents:
diff changeset
1336 begin
kono
parents:
diff changeset
1337 -- Return Null_Symbol in the case that the symbol table is empty
kono
parents:
diff changeset
1338
kono
parents:
diff changeset
1339 if Obj.Symtab_Last = 0 then
kono
parents:
diff changeset
1340 return Null_Symbol;
kono
parents:
diff changeset
1341 end if;
kono
parents:
diff changeset
1342
kono
parents:
diff changeset
1343 return Read_Symbol (Obj, 0);
kono
parents:
diff changeset
1344 end First_Symbol;
kono
parents:
diff changeset
1345
kono
parents:
diff changeset
1346 ----------------
kono
parents:
diff changeset
1347 -- Initialize --
kono
parents:
diff changeset
1348 ----------------
kono
parents:
diff changeset
1349
kono
parents:
diff changeset
1350 function Initialize
kono
parents:
diff changeset
1351 (F : Mapped_File;
kono
parents:
diff changeset
1352 Hdr : Header;
kono
parents:
diff changeset
1353 In_Exception : Boolean) return XCOFF32_Object_File
kono
parents:
diff changeset
1354 is
kono
parents:
diff changeset
1355 Res : XCOFF32_Object_File (Format => XCOFF32);
kono
parents:
diff changeset
1356 Strtab_Sz : uint32;
kono
parents:
diff changeset
1357 begin
kono
parents:
diff changeset
1358 Res.Mf := F;
kono
parents:
diff changeset
1359 Res.In_Exception := In_Exception;
kono
parents:
diff changeset
1360
kono
parents:
diff changeset
1361 Res.Arch := PPC;
kono
parents:
diff changeset
1362
kono
parents:
diff changeset
1363 -- Map sections table
kono
parents:
diff changeset
1364 Res.Num_Sections := uint32 (Hdr.f_nscns);
kono
parents:
diff changeset
1365 Res.Sectab_Stream := Create_Stream
kono
parents:
diff changeset
1366 (F,
kono
parents:
diff changeset
1367 File_Size (Header'Size / SSU) + File_Size (Hdr.f_opthdr),
kono
parents:
diff changeset
1368 File_Size (Hdr.f_nscns) * (Section_Header'Size / SSU));
kono
parents:
diff changeset
1369
kono
parents:
diff changeset
1370 -- Map symbols table
kono
parents:
diff changeset
1371 Res.Symtab_Last := Offset (Hdr.f_nscns) * (Symbol_Entry'Size / SSU);
kono
parents:
diff changeset
1372 Res.Symtab_Stream := Create_Stream
kono
parents:
diff changeset
1373 (F,
kono
parents:
diff changeset
1374 File_Size (Hdr.f_symptr),
kono
parents:
diff changeset
1375 File_Size (Res.Symtab_Last) + 4);
kono
parents:
diff changeset
1376
kono
parents:
diff changeset
1377 -- Map string table
kono
parents:
diff changeset
1378 Seek (Res.Symtab_Stream, Res.Symtab_Last);
kono
parents:
diff changeset
1379 Strtab_Sz := Read (Res.Symtab_Stream);
kono
parents:
diff changeset
1380 Res.Symstr_Stream := Create_Stream
kono
parents:
diff changeset
1381 (F,
kono
parents:
diff changeset
1382 File_Size (Res.Symtab_Last) + 4,
kono
parents:
diff changeset
1383 File_Size (Strtab_Sz) - 4);
kono
parents:
diff changeset
1384
kono
parents:
diff changeset
1385 return Res;
kono
parents:
diff changeset
1386 end Initialize;
kono
parents:
diff changeset
1387
kono
parents:
diff changeset
1388 -----------------
kono
parents:
diff changeset
1389 -- Get_Section --
kono
parents:
diff changeset
1390 -----------------
kono
parents:
diff changeset
1391
kono
parents:
diff changeset
1392 function Get_Section
kono
parents:
diff changeset
1393 (Obj : in out XCOFF32_Object_File;
kono
parents:
diff changeset
1394 Index : uint32) return Object_Section
kono
parents:
diff changeset
1395 is
kono
parents:
diff changeset
1396 Sec : constant Section_Header := Read_Section_Header (Obj, Index);
kono
parents:
diff changeset
1397 begin
kono
parents:
diff changeset
1398 return (Index, Offset (Sec.s_scnptr),
kono
parents:
diff changeset
1399 uint64 (Sec.s_vaddr),
kono
parents:
diff changeset
1400 uint64 (Sec.s_size),
kono
parents:
diff changeset
1401 (Sec.s_flags and STYP_TEXT) /= 0);
kono
parents:
diff changeset
1402 end Get_Section;
kono
parents:
diff changeset
1403
kono
parents:
diff changeset
1404 -----------------
kono
parents:
diff changeset
1405 -- Read_Header --
kono
parents:
diff changeset
1406 -----------------
kono
parents:
diff changeset
1407
kono
parents:
diff changeset
1408 function Read_Header (F : in out Mapped_Stream) return Header is
kono
parents:
diff changeset
1409 Hdr : Header;
kono
parents:
diff changeset
1410 begin
kono
parents:
diff changeset
1411 Seek (F, 0);
kono
parents:
diff changeset
1412 Read_Raw (F, Hdr'Address, uint32 (Hdr'Size / SSU));
kono
parents:
diff changeset
1413 return Hdr;
kono
parents:
diff changeset
1414 end Read_Header;
kono
parents:
diff changeset
1415
kono
parents:
diff changeset
1416 -------------------------
kono
parents:
diff changeset
1417 -- Read_Section_Header --
kono
parents:
diff changeset
1418 -------------------------
kono
parents:
diff changeset
1419
kono
parents:
diff changeset
1420 function Read_Section_Header
kono
parents:
diff changeset
1421 (Obj : in out XCOFF32_Object_File;
kono
parents:
diff changeset
1422 Index : uint32) return Section_Header
kono
parents:
diff changeset
1423 is
kono
parents:
diff changeset
1424 Sec : Section_Header;
kono
parents:
diff changeset
1425
kono
parents:
diff changeset
1426 begin
kono
parents:
diff changeset
1427 -- Seek to the end of the object header
kono
parents:
diff changeset
1428
kono
parents:
diff changeset
1429 Seek (Obj.Sectab_Stream, Offset (Index * Section_Header'Size / SSU));
kono
parents:
diff changeset
1430
kono
parents:
diff changeset
1431 -- Read the section
kono
parents:
diff changeset
1432
kono
parents:
diff changeset
1433 Read_Raw (Obj.Sectab_Stream, Sec'Address, Section_Header'Size / SSU);
kono
parents:
diff changeset
1434
kono
parents:
diff changeset
1435 return Sec;
kono
parents:
diff changeset
1436 end Read_Section_Header;
kono
parents:
diff changeset
1437
kono
parents:
diff changeset
1438 ----------
kono
parents:
diff changeset
1439 -- Name --
kono
parents:
diff changeset
1440 ----------
kono
parents:
diff changeset
1441
kono
parents:
diff changeset
1442 function Name
kono
parents:
diff changeset
1443 (Obj : in out XCOFF32_Object_File;
kono
parents:
diff changeset
1444 Sec : Object_Section) return String
kono
parents:
diff changeset
1445 is
kono
parents:
diff changeset
1446 Hdr : Section_Header;
kono
parents:
diff changeset
1447 begin
kono
parents:
diff changeset
1448 Hdr := Read_Section_Header (Obj, Sec.Num);
kono
parents:
diff changeset
1449 return Trim_Trailing_Nuls (Hdr.s_name);
kono
parents:
diff changeset
1450 end Name;
kono
parents:
diff changeset
1451
kono
parents:
diff changeset
1452 ----------
kono
parents:
diff changeset
1453 -- Name --
kono
parents:
diff changeset
1454 ----------
kono
parents:
diff changeset
1455
kono
parents:
diff changeset
1456 function Name
kono
parents:
diff changeset
1457 (Obj : in out XCOFF32_Object_File;
kono
parents:
diff changeset
1458 Sym : Object_Symbol) return String_Ptr_Len
kono
parents:
diff changeset
1459 is
kono
parents:
diff changeset
1460 Symbol : Symbol_Entry;
kono
parents:
diff changeset
1461
kono
parents:
diff changeset
1462 begin
kono
parents:
diff changeset
1463 Seek (Obj.Symtab_Stream, Sym.Off);
kono
parents:
diff changeset
1464 Read_Raw (Obj.Symtab_Stream, Symbol'Address, Symbol'Size / SSU);
kono
parents:
diff changeset
1465
kono
parents:
diff changeset
1466 declare
kono
parents:
diff changeset
1467 First_Word : uint32;
kono
parents:
diff changeset
1468 pragma Import (Ada, First_Word);
kono
parents:
diff changeset
1469 -- Suppress initialization in Normalized_Scalars mode
kono
parents:
diff changeset
1470 for First_Word'Address use Symbol.n_name (1)'Address;
kono
parents:
diff changeset
1471
kono
parents:
diff changeset
1472 Second_Word : uint32;
kono
parents:
diff changeset
1473 pragma Import (Ada, Second_Word);
kono
parents:
diff changeset
1474 -- Suppress initialization in Normalized_Scalars mode
kono
parents:
diff changeset
1475 for Second_Word'Address use Symbol.n_name (5)'Address;
kono
parents:
diff changeset
1476
kono
parents:
diff changeset
1477 begin
kono
parents:
diff changeset
1478 if First_Word = 0 then
kono
parents:
diff changeset
1479 if Second_Word = 0 then
kono
parents:
diff changeset
1480 return (null, 0);
kono
parents:
diff changeset
1481 else
kono
parents:
diff changeset
1482 Seek (Obj.Symstr_Stream, int64 (Second_Word));
kono
parents:
diff changeset
1483 return Read (Obj.Symstr_Stream);
kono
parents:
diff changeset
1484 end if;
kono
parents:
diff changeset
1485 else
kono
parents:
diff changeset
1486 Seek (Obj.Symtab_Stream, Sym.Off);
kono
parents:
diff changeset
1487 return To_String_Ptr_Len (Read (Obj.Symstr_Stream), 8);
kono
parents:
diff changeset
1488 end if;
kono
parents:
diff changeset
1489 end;
kono
parents:
diff changeset
1490 end Name;
kono
parents:
diff changeset
1491 end XCOFF32_Ops;
kono
parents:
diff changeset
1492
kono
parents:
diff changeset
1493 ----------
kono
parents:
diff changeset
1494 -- Arch --
kono
parents:
diff changeset
1495 ----------
kono
parents:
diff changeset
1496
kono
parents:
diff changeset
1497 function Arch (Obj : Object_File) return Object_Arch is
kono
parents:
diff changeset
1498 begin
kono
parents:
diff changeset
1499 return Obj.Arch;
kono
parents:
diff changeset
1500 end Arch;
kono
parents:
diff changeset
1501
kono
parents:
diff changeset
1502 function Create_Stream
kono
parents:
diff changeset
1503 (Mf : Mapped_File;
kono
parents:
diff changeset
1504 File_Offset : File_Size;
kono
parents:
diff changeset
1505 File_Length : File_Size)
kono
parents:
diff changeset
1506 return Mapped_Stream
kono
parents:
diff changeset
1507 is
kono
parents:
diff changeset
1508 Region : Mapped_Region;
kono
parents:
diff changeset
1509 begin
kono
parents:
diff changeset
1510 Read (Mf, Region, File_Offset, File_Length, False);
kono
parents:
diff changeset
1511 return (Region, 0, Offset (File_Length));
kono
parents:
diff changeset
1512 end Create_Stream;
kono
parents:
diff changeset
1513
kono
parents:
diff changeset
1514 function Create_Stream
kono
parents:
diff changeset
1515 (Obj : Object_File;
kono
parents:
diff changeset
1516 Sec : Object_Section) return Mapped_Stream is
kono
parents:
diff changeset
1517 begin
kono
parents:
diff changeset
1518 return Create_Stream (Obj.Mf, File_Size (Sec.Off), File_Size (Sec.Size));
kono
parents:
diff changeset
1519 end Create_Stream;
kono
parents:
diff changeset
1520
kono
parents:
diff changeset
1521 procedure Tell (Obj : in out Mapped_Stream; Off : out Offset) is
kono
parents:
diff changeset
1522 begin
kono
parents:
diff changeset
1523 Off := Obj.Off;
kono
parents:
diff changeset
1524 end Tell;
kono
parents:
diff changeset
1525
kono
parents:
diff changeset
1526 function Tell (Obj : Mapped_Stream) return Offset is
kono
parents:
diff changeset
1527 begin
kono
parents:
diff changeset
1528 return Obj.Off;
kono
parents:
diff changeset
1529 end Tell;
kono
parents:
diff changeset
1530
kono
parents:
diff changeset
1531 function Length (Obj : Mapped_Stream) return Offset is
kono
parents:
diff changeset
1532 begin
kono
parents:
diff changeset
1533 return Obj.Len;
kono
parents:
diff changeset
1534 end Length;
kono
parents:
diff changeset
1535
kono
parents:
diff changeset
1536 -----------
kono
parents:
diff changeset
1537 -- Close --
kono
parents:
diff changeset
1538 -----------
kono
parents:
diff changeset
1539
kono
parents:
diff changeset
1540 procedure Close (S : in out Mapped_Stream) is
kono
parents:
diff changeset
1541 begin
kono
parents:
diff changeset
1542 Free (S.Region);
kono
parents:
diff changeset
1543 end Close;
kono
parents:
diff changeset
1544
kono
parents:
diff changeset
1545 procedure Close (Obj : in out Object_File) is
kono
parents:
diff changeset
1546 begin
kono
parents:
diff changeset
1547 Close (Obj.Symtab_Stream);
kono
parents:
diff changeset
1548 Close (Obj.Symstr_Stream);
kono
parents:
diff changeset
1549 Close (Obj.Sectab_Stream);
kono
parents:
diff changeset
1550
kono
parents:
diff changeset
1551 case Obj.Format is
kono
parents:
diff changeset
1552 when ELF =>
kono
parents:
diff changeset
1553 Close (Obj.Secstr_Stream);
kono
parents:
diff changeset
1554 when Any_PECOFF =>
kono
parents:
diff changeset
1555 null;
kono
parents:
diff changeset
1556 when XCOFF32 =>
kono
parents:
diff changeset
1557 null;
kono
parents:
diff changeset
1558 end case;
kono
parents:
diff changeset
1559
kono
parents:
diff changeset
1560 Close (Obj.Mf);
kono
parents:
diff changeset
1561 end Close;
kono
parents:
diff changeset
1562
kono
parents:
diff changeset
1563 ------------------------
kono
parents:
diff changeset
1564 -- Strip_Leading_Char --
kono
parents:
diff changeset
1565 ------------------------
kono
parents:
diff changeset
1566
kono
parents:
diff changeset
1567 function Strip_Leading_Char
kono
parents:
diff changeset
1568 (Obj : in out Object_File;
kono
parents:
diff changeset
1569 Sym : String_Ptr_Len) return Positive is
kono
parents:
diff changeset
1570 begin
kono
parents:
diff changeset
1571 if (Obj.Format = PECOFF and then Sym.Ptr (1) = '_')
kono
parents:
diff changeset
1572 or else
kono
parents:
diff changeset
1573 (Obj.Format = XCOFF32 and then Sym.Ptr (1) = '.')
kono
parents:
diff changeset
1574 then
kono
parents:
diff changeset
1575 return 2;
kono
parents:
diff changeset
1576 else
kono
parents:
diff changeset
1577 return 1;
kono
parents:
diff changeset
1578 end if;
kono
parents:
diff changeset
1579 end Strip_Leading_Char;
kono
parents:
diff changeset
1580
kono
parents:
diff changeset
1581 ----------------------
kono
parents:
diff changeset
1582 -- Decoded_Ada_Name --
kono
parents:
diff changeset
1583 ----------------------
kono
parents:
diff changeset
1584
kono
parents:
diff changeset
1585 function Decoded_Ada_Name
kono
parents:
diff changeset
1586 (Obj : in out Object_File;
kono
parents:
diff changeset
1587 Sym : String_Ptr_Len) return String
kono
parents:
diff changeset
1588 is
kono
parents:
diff changeset
1589 procedure gnat_decode
kono
parents:
diff changeset
1590 (Coded_Name_Addr : Address;
kono
parents:
diff changeset
1591 Ada_Name_Addr : Address;
kono
parents:
diff changeset
1592 Verbose : int);
kono
parents:
diff changeset
1593 pragma Import (C, gnat_decode, "__gnat_decode");
kono
parents:
diff changeset
1594
kono
parents:
diff changeset
1595 subtype size_t is Interfaces.C.size_t;
kono
parents:
diff changeset
1596
kono
parents:
diff changeset
1597 Sym_Name : constant String :=
kono
parents:
diff changeset
1598 String (Sym.Ptr (1 .. Sym.Len)) & ASCII.NUL;
kono
parents:
diff changeset
1599 Decoded : char_array (0 .. size_t (Sym.Len) * 2 + 60);
kono
parents:
diff changeset
1600 Off : Natural;
kono
parents:
diff changeset
1601 begin
kono
parents:
diff changeset
1602 -- In the PECOFF case most but not all symbol table entries have an
kono
parents:
diff changeset
1603 -- extra leading underscore. In this case we trim it.
kono
parents:
diff changeset
1604
kono
parents:
diff changeset
1605 Off := Strip_Leading_Char (Obj, Sym);
kono
parents:
diff changeset
1606
kono
parents:
diff changeset
1607 gnat_decode (Sym_Name (Off)'Address, Decoded'Address, 0);
kono
parents:
diff changeset
1608
kono
parents:
diff changeset
1609 return To_Ada (Decoded);
kono
parents:
diff changeset
1610 end Decoded_Ada_Name;
kono
parents:
diff changeset
1611
kono
parents:
diff changeset
1612 ------------------
kono
parents:
diff changeset
1613 -- First_Symbol --
kono
parents:
diff changeset
1614 ------------------
kono
parents:
diff changeset
1615
kono
parents:
diff changeset
1616 function First_Symbol (Obj : in out Object_File) return Object_Symbol is
kono
parents:
diff changeset
1617 begin
kono
parents:
diff changeset
1618 case Obj.Format is
kono
parents:
diff changeset
1619 when ELF32 => return ELF32_Ops.First_Symbol (Obj);
kono
parents:
diff changeset
1620 when ELF64 => return ELF64_Ops.First_Symbol (Obj);
kono
parents:
diff changeset
1621 when Any_PECOFF => return PECOFF_Ops.First_Symbol (Obj);
kono
parents:
diff changeset
1622 when XCOFF32 => return XCOFF32_Ops.First_Symbol (Obj);
kono
parents:
diff changeset
1623 end case;
kono
parents:
diff changeset
1624 end First_Symbol;
kono
parents:
diff changeset
1625
kono
parents:
diff changeset
1626 ------------
kono
parents:
diff changeset
1627 -- Format --
kono
parents:
diff changeset
1628 ------------
kono
parents:
diff changeset
1629
kono
parents:
diff changeset
1630 function Format (Obj : Object_File) return Object_Format is
kono
parents:
diff changeset
1631 begin
kono
parents:
diff changeset
1632 return Obj.Format;
kono
parents:
diff changeset
1633 end Format;
kono
parents:
diff changeset
1634
kono
parents:
diff changeset
1635 ----------------------
kono
parents:
diff changeset
1636 -- Get_Load_Address --
kono
parents:
diff changeset
1637 ----------------------
kono
parents:
diff changeset
1638
kono
parents:
diff changeset
1639 function Get_Load_Address (Obj : Object_File) return uint64 is
kono
parents:
diff changeset
1640 begin
kono
parents:
diff changeset
1641 raise Format_Error with "Get_Load_Address not implemented";
kono
parents:
diff changeset
1642 return 0;
kono
parents:
diff changeset
1643 end Get_Load_Address;
kono
parents:
diff changeset
1644
kono
parents:
diff changeset
1645 -----------------
kono
parents:
diff changeset
1646 -- Get_Section --
kono
parents:
diff changeset
1647 -----------------
kono
parents:
diff changeset
1648
kono
parents:
diff changeset
1649 function Get_Section
kono
parents:
diff changeset
1650 (Obj : in out Object_File;
kono
parents:
diff changeset
1651 Shnum : uint32) return Object_Section is
kono
parents:
diff changeset
1652 begin
kono
parents:
diff changeset
1653 case Obj.Format is
kono
parents:
diff changeset
1654 when ELF32 => return ELF32_Ops.Get_Section (Obj, Shnum);
kono
parents:
diff changeset
1655 when ELF64 => return ELF64_Ops.Get_Section (Obj, Shnum);
kono
parents:
diff changeset
1656 when Any_PECOFF => return PECOFF_Ops.Get_Section (Obj, Shnum);
kono
parents:
diff changeset
1657 when XCOFF32 => return XCOFF32_Ops.Get_Section (Obj, Shnum);
kono
parents:
diff changeset
1658 end case;
kono
parents:
diff changeset
1659 end Get_Section;
kono
parents:
diff changeset
1660
kono
parents:
diff changeset
1661 function Get_Section
kono
parents:
diff changeset
1662 (Obj : in out Object_File;
kono
parents:
diff changeset
1663 Sec_Name : String) return Object_Section
kono
parents:
diff changeset
1664 is
kono
parents:
diff changeset
1665 Sec : Object_Section;
kono
parents:
diff changeset
1666
kono
parents:
diff changeset
1667 begin
kono
parents:
diff changeset
1668 for J in 0 .. Obj.Num_Sections - 1 loop
kono
parents:
diff changeset
1669 Sec := Get_Section (Obj, J);
kono
parents:
diff changeset
1670
kono
parents:
diff changeset
1671 if Name (Obj, Sec) = Sec_Name then
kono
parents:
diff changeset
1672 return Sec;
kono
parents:
diff changeset
1673 end if;
kono
parents:
diff changeset
1674 end loop;
kono
parents:
diff changeset
1675
kono
parents:
diff changeset
1676 if Obj.In_Exception then
kono
parents:
diff changeset
1677 return Null_Section;
kono
parents:
diff changeset
1678 else
kono
parents:
diff changeset
1679 raise Format_Error with "could not find section in object file";
kono
parents:
diff changeset
1680 end if;
kono
parents:
diff changeset
1681 end Get_Section;
kono
parents:
diff changeset
1682
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1683 ----------------------
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1684 -- Get_Xcode_Bounds --
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1685 ----------------------
111
kono
parents:
diff changeset
1686
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1687 procedure Get_Xcode_Bounds
111
kono
parents:
diff changeset
1688 (Obj : in out Object_File;
kono
parents:
diff changeset
1689 Low, High : out uint64) is
kono
parents:
diff changeset
1690 Sec : Object_Section;
kono
parents:
diff changeset
1691 begin
kono
parents:
diff changeset
1692 -- First set as an empty range
kono
parents:
diff changeset
1693 Low := uint64'Last;
kono
parents:
diff changeset
1694 High := uint64'First;
kono
parents:
diff changeset
1695
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1696 -- Now find the lowest and highest offsets
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1697 -- attached to executable code sections
111
kono
parents:
diff changeset
1698 for Idx in 1 .. Num_Sections (Obj) loop
kono
parents:
diff changeset
1699 Sec := Get_Section (Obj, Idx - 1);
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1700 if Sec.Flag_Xcode then
111
kono
parents:
diff changeset
1701 if Sec.Addr < Low then
kono
parents:
diff changeset
1702 Low := Sec.Addr;
kono
parents:
diff changeset
1703 end if;
kono
parents:
diff changeset
1704 if Sec.Addr + Sec.Size > High then
kono
parents:
diff changeset
1705 High := Sec.Addr + Sec.Size;
kono
parents:
diff changeset
1706 end if;
kono
parents:
diff changeset
1707 end if;
kono
parents:
diff changeset
1708 end loop;
131
84e7813d76e9 gcc-8.2
mir3636
parents: 111
diff changeset
1709 end Get_Xcode_Bounds;
111
kono
parents:
diff changeset
1710
kono
parents:
diff changeset
1711 ----------
kono
parents:
diff changeset
1712 -- Name --
kono
parents:
diff changeset
1713 ----------
kono
parents:
diff changeset
1714
kono
parents:
diff changeset
1715 function Name
kono
parents:
diff changeset
1716 (Obj : in out Object_File;
kono
parents:
diff changeset
1717 Sec : Object_Section) return String is
kono
parents:
diff changeset
1718 begin
kono
parents:
diff changeset
1719 case Obj.Format is
kono
parents:
diff changeset
1720 when ELF32 => return ELF32_Ops.Name (Obj, Sec);
kono
parents:
diff changeset
1721 when ELF64 => return ELF64_Ops.Name (Obj, Sec);
kono
parents:
diff changeset
1722 when Any_PECOFF => return PECOFF_Ops.Name (Obj, Sec);
kono
parents:
diff changeset
1723 when XCOFF32 => return XCOFF32_Ops.Name (Obj, Sec);
kono
parents:
diff changeset
1724 end case;
kono
parents:
diff changeset
1725 end Name;
kono
parents:
diff changeset
1726
kono
parents:
diff changeset
1727 function Name
kono
parents:
diff changeset
1728 (Obj : in out Object_File;
kono
parents:
diff changeset
1729 Sym : Object_Symbol) return String_Ptr_Len is
kono
parents:
diff changeset
1730 begin
kono
parents:
diff changeset
1731 case Obj.Format is
kono
parents:
diff changeset
1732 when ELF32 => return ELF32_Ops.Name (Obj, Sym);
kono
parents:
diff changeset
1733 when ELF64 => return ELF64_Ops.Name (Obj, Sym);
kono
parents:
diff changeset
1734 when Any_PECOFF => return PECOFF_Ops.Name (Obj, Sym);
kono
parents:
diff changeset
1735 when XCOFF32 => return XCOFF32_Ops.Name (Obj, Sym);
kono
parents:
diff changeset
1736 end case;
kono
parents:
diff changeset
1737 end Name;
kono
parents:
diff changeset
1738
kono
parents:
diff changeset
1739 -----------------
kono
parents:
diff changeset
1740 -- Next_Symbol --
kono
parents:
diff changeset
1741 -----------------
kono
parents:
diff changeset
1742
kono
parents:
diff changeset
1743 function Next_Symbol
kono
parents:
diff changeset
1744 (Obj : in out Object_File;
kono
parents:
diff changeset
1745 Prev : Object_Symbol) return Object_Symbol is
kono
parents:
diff changeset
1746 begin
kono
parents:
diff changeset
1747 -- Test whether we've reached the end of the symbol table
kono
parents:
diff changeset
1748
kono
parents:
diff changeset
1749 if Prev.Next >= Obj.Symtab_Last then
kono
parents:
diff changeset
1750 return Null_Symbol;
kono
parents:
diff changeset
1751 end if;
kono
parents:
diff changeset
1752
kono
parents:
diff changeset
1753 return Read_Symbol (Obj, Prev.Next);
kono
parents:
diff changeset
1754 end Next_Symbol;
kono
parents:
diff changeset
1755
kono
parents:
diff changeset
1756 ---------
kono
parents:
diff changeset
1757 -- Num --
kono
parents:
diff changeset
1758 ---------
kono
parents:
diff changeset
1759
kono
parents:
diff changeset
1760 function Num (Sec : Object_Section) return uint32 is
kono
parents:
diff changeset
1761 begin
kono
parents:
diff changeset
1762 return Sec.Num;
kono
parents:
diff changeset
1763 end Num;
kono
parents:
diff changeset
1764
kono
parents:
diff changeset
1765 ------------------
kono
parents:
diff changeset
1766 -- Num_Sections --
kono
parents:
diff changeset
1767 ------------------
kono
parents:
diff changeset
1768
kono
parents:
diff changeset
1769 function Num_Sections (Obj : Object_File) return uint32 is
kono
parents:
diff changeset
1770 begin
kono
parents:
diff changeset
1771 return Obj.Num_Sections;
kono
parents:
diff changeset
1772 end Num_Sections;
kono
parents:
diff changeset
1773
kono
parents:
diff changeset
1774 ---------
kono
parents:
diff changeset
1775 -- Off --
kono
parents:
diff changeset
1776 ---------
kono
parents:
diff changeset
1777
kono
parents:
diff changeset
1778 function Off (Sec : Object_Section) return Offset is
kono
parents:
diff changeset
1779 begin
kono
parents:
diff changeset
1780 return Sec.Off;
kono
parents:
diff changeset
1781 end Off;
kono
parents:
diff changeset
1782
kono
parents:
diff changeset
1783 function Off (Sym : Object_Symbol) return Offset is
kono
parents:
diff changeset
1784 begin
kono
parents:
diff changeset
1785 return Sym.Off;
kono
parents:
diff changeset
1786 end Off;
kono
parents:
diff changeset
1787
kono
parents:
diff changeset
1788 ----------------------
kono
parents:
diff changeset
1789 -- Offset_To_String --
kono
parents:
diff changeset
1790 ----------------------
kono
parents:
diff changeset
1791
kono
parents:
diff changeset
1792 function Offset_To_String
kono
parents:
diff changeset
1793 (S : in out Mapped_Stream;
kono
parents:
diff changeset
1794 Off : Offset) return String
kono
parents:
diff changeset
1795 is
kono
parents:
diff changeset
1796 Buf : Buffer;
kono
parents:
diff changeset
1797 begin
kono
parents:
diff changeset
1798 Seek (S, Off);
kono
parents:
diff changeset
1799 Read_C_String (S, Buf);
kono
parents:
diff changeset
1800 return To_String (Buf);
kono
parents:
diff changeset
1801 end Offset_To_String;
kono
parents:
diff changeset
1802
kono
parents:
diff changeset
1803 ----------
kono
parents:
diff changeset
1804 -- Open --
kono
parents:
diff changeset
1805 ----------
kono
parents:
diff changeset
1806
kono
parents:
diff changeset
1807 function Open
kono
parents:
diff changeset
1808 (File_Name : String;
kono
parents:
diff changeset
1809 In_Exception : Boolean := False) return Object_File_Access
kono
parents:
diff changeset
1810 is
kono
parents:
diff changeset
1811 F : Mapped_File;
kono
parents:
diff changeset
1812 Hdr_Stream : Mapped_Stream;
kono
parents:
diff changeset
1813
kono
parents:
diff changeset
1814 begin
kono
parents:
diff changeset
1815 -- Open the file
kono
parents:
diff changeset
1816
kono
parents:
diff changeset
1817 F := Open_Read_No_Exception (File_Name);
kono
parents:
diff changeset
1818
kono
parents:
diff changeset
1819 if F = Invalid_Mapped_File then
kono
parents:
diff changeset
1820 if In_Exception then
kono
parents:
diff changeset
1821 return null;
kono
parents:
diff changeset
1822 else
kono
parents:
diff changeset
1823 raise IO_Error with "could not open object file";
kono
parents:
diff changeset
1824 end if;
kono
parents:
diff changeset
1825 end if;
kono
parents:
diff changeset
1826
kono
parents:
diff changeset
1827 Hdr_Stream := Create_Stream (F, 0, 4096);
kono
parents:
diff changeset
1828
kono
parents:
diff changeset
1829 declare
kono
parents:
diff changeset
1830 Hdr : constant ELF32_Ops.Header := ELF32_Ops.Read_Header (Hdr_Stream);
kono
parents:
diff changeset
1831
kono
parents:
diff changeset
1832 begin
kono
parents:
diff changeset
1833 -- Look for the magic numbers for the ELF case
kono
parents:
diff changeset
1834
kono
parents:
diff changeset
1835 if Hdr.E_Ident (0) = 16#7F# and then
kono
parents:
diff changeset
1836 Hdr.E_Ident (1) = Character'Pos ('E') and then
kono
parents:
diff changeset
1837 Hdr.E_Ident (2) = Character'Pos ('L') and then
kono
parents:
diff changeset
1838 Hdr.E_Ident (3) = Character'Pos ('F') and then
kono
parents:
diff changeset
1839 Hdr.E_Ident (4) = ELF32_Ops.ELFCLASS32
kono
parents:
diff changeset
1840 then
kono
parents:
diff changeset
1841 Close (Hdr_Stream);
kono
parents:
diff changeset
1842 return new Object_File'
kono
parents:
diff changeset
1843 (ELF32_Ops.Initialize (F, Hdr, In_Exception));
kono
parents:
diff changeset
1844 end if;
kono
parents:
diff changeset
1845 end;
kono
parents:
diff changeset
1846
kono
parents:
diff changeset
1847 declare
kono
parents:
diff changeset
1848 Hdr : constant ELF64_Ops.Header :=
kono
parents:
diff changeset
1849 ELF64_Ops.Read_Header (Hdr_Stream);
kono
parents:
diff changeset
1850
kono
parents:
diff changeset
1851 begin
kono
parents:
diff changeset
1852 -- Look for the magic numbers for the ELF case
kono
parents:
diff changeset
1853
kono
parents:
diff changeset
1854 if Hdr.E_Ident (0) = 16#7F# and then
kono
parents:
diff changeset
1855 Hdr.E_Ident (1) = Character'Pos ('E') and then
kono
parents:
diff changeset
1856 Hdr.E_Ident (2) = Character'Pos ('L') and then
kono
parents:
diff changeset
1857 Hdr.E_Ident (3) = Character'Pos ('F') and then
kono
parents:
diff changeset
1858 Hdr.E_Ident (4) = ELF32_Ops.ELFCLASS64
kono
parents:
diff changeset
1859 then
kono
parents:
diff changeset
1860 Close (Hdr_Stream);
kono
parents:
diff changeset
1861 return new Object_File'
kono
parents:
diff changeset
1862 (ELF64_Ops.Initialize (F, Hdr, In_Exception));
kono
parents:
diff changeset
1863 end if;
kono
parents:
diff changeset
1864 end;
kono
parents:
diff changeset
1865
kono
parents:
diff changeset
1866 declare
kono
parents:
diff changeset
1867 Hdr : constant PECOFF_Ops.Header :=
kono
parents:
diff changeset
1868 PECOFF_Ops.Read_Header (Hdr_Stream);
kono
parents:
diff changeset
1869
kono
parents:
diff changeset
1870 begin
kono
parents:
diff changeset
1871 -- Test the magic numbers
kono
parents:
diff changeset
1872
kono
parents:
diff changeset
1873 if Hdr.Magics (0) = Character'Pos ('P') and then
kono
parents:
diff changeset
1874 Hdr.Magics (1) = Character'Pos ('E') and then
kono
parents:
diff changeset
1875 Hdr.Magics (2) = 0 and then
kono
parents:
diff changeset
1876 Hdr.Magics (3) = 0
kono
parents:
diff changeset
1877 then
kono
parents:
diff changeset
1878 Close (Hdr_Stream);
kono
parents:
diff changeset
1879 return new Object_File'
kono
parents:
diff changeset
1880 (PECOFF_Ops.Initialize (F, Hdr, In_Exception));
kono
parents:
diff changeset
1881 end if;
kono
parents:
diff changeset
1882
kono
parents:
diff changeset
1883 exception
kono
parents:
diff changeset
1884 -- If this is not a PECOFF file then we've done a seek and read to a
kono
parents:
diff changeset
1885 -- random address, possibly raising IO_Error
kono
parents:
diff changeset
1886
kono
parents:
diff changeset
1887 when IO_Error =>
kono
parents:
diff changeset
1888 null;
kono
parents:
diff changeset
1889 end;
kono
parents:
diff changeset
1890
kono
parents:
diff changeset
1891 declare
kono
parents:
diff changeset
1892 Hdr : constant XCOFF32_Ops.Header :=
kono
parents:
diff changeset
1893 XCOFF32_Ops.Read_Header (Hdr_Stream);
kono
parents:
diff changeset
1894
kono
parents:
diff changeset
1895 begin
kono
parents:
diff changeset
1896 -- Test the magic numbers
kono
parents:
diff changeset
1897
kono
parents:
diff changeset
1898 if Hdr.f_magic = 8#0737# then
kono
parents:
diff changeset
1899 Close (Hdr_Stream);
kono
parents:
diff changeset
1900 return new Object_File'
kono
parents:
diff changeset
1901 (XCOFF32_Ops.Initialize (F, Hdr, In_Exception));
kono
parents:
diff changeset
1902 end if;
kono
parents:
diff changeset
1903 end;
kono
parents:
diff changeset
1904
kono
parents:
diff changeset
1905 Close (Hdr_Stream);
kono
parents:
diff changeset
1906
kono
parents:
diff changeset
1907 if In_Exception then
kono
parents:
diff changeset
1908 return null;
kono
parents:
diff changeset
1909 else
kono
parents:
diff changeset
1910 raise Format_Error with "unrecognized object format";
kono
parents:
diff changeset
1911 end if;
kono
parents:
diff changeset
1912 end Open;
kono
parents:
diff changeset
1913
kono
parents:
diff changeset
1914 ----------
kono
parents:
diff changeset
1915 -- Read --
kono
parents:
diff changeset
1916 ----------
kono
parents:
diff changeset
1917
kono
parents:
diff changeset
1918 function Read (S : in out Mapped_Stream) return Mmap.Str_Access
kono
parents:
diff changeset
1919 is
kono
parents:
diff changeset
1920 function To_Str_Access is
kono
parents:
diff changeset
1921 new Ada.Unchecked_Conversion (Address, Str_Access);
kono
parents:
diff changeset
1922 begin
kono
parents:
diff changeset
1923 return To_Str_Access (Data (S.Region) (Natural (S.Off + 1))'Address);
kono
parents:
diff changeset
1924 end Read;
kono
parents:
diff changeset
1925
kono
parents:
diff changeset
1926 function Read (S : in out Mapped_Stream) return String_Ptr_Len is
kono
parents:
diff changeset
1927 begin
kono
parents:
diff changeset
1928 return To_String_Ptr_Len (Read (S));
kono
parents:
diff changeset
1929 end Read;
kono
parents:
diff changeset
1930
kono
parents:
diff changeset
1931 procedure Check_Read_Offset (S : in out Mapped_Stream; Size : uint32) is
kono
parents:
diff changeset
1932 begin
kono
parents:
diff changeset
1933 if S.Off + Offset (Size) > Offset (Last (S.Region)) then
kono
parents:
diff changeset
1934 raise IO_Error with "could not read from object file";
kono
parents:
diff changeset
1935 end if;
kono
parents:
diff changeset
1936 end Check_Read_Offset;
kono
parents:
diff changeset
1937
kono
parents:
diff changeset
1938 procedure Read_Raw
kono
parents:
diff changeset
1939 (S : in out Mapped_Stream;
kono
parents:
diff changeset
1940 Addr : Address;
kono
parents:
diff changeset
1941 Size : uint32)
kono
parents:
diff changeset
1942 is
kono
parents:
diff changeset
1943 function To_Str_Access is
kono
parents:
diff changeset
1944 new Ada.Unchecked_Conversion (Address, Str_Access);
kono
parents:
diff changeset
1945
kono
parents:
diff changeset
1946 Sz : constant Offset := Offset (Size);
kono
parents:
diff changeset
1947 begin
kono
parents:
diff changeset
1948 -- Check size
kono
parents:
diff changeset
1949
kono
parents:
diff changeset
1950 pragma Debug (Check_Read_Offset (S, Size));
kono
parents:
diff changeset
1951
kono
parents:
diff changeset
1952 -- Copy data
kono
parents:
diff changeset
1953
kono
parents:
diff changeset
1954 To_Str_Access (Addr) (1 .. Positive (Sz)) :=
kono
parents:
diff changeset
1955 Data (S.Region) (Positive (S.Off + 1) .. Positive (S.Off + Sz));
kono
parents:
diff changeset
1956
kono
parents:
diff changeset
1957 -- Update offset
kono
parents:
diff changeset
1958
kono
parents:
diff changeset
1959 S.Off := S.Off + Sz;
kono
parents:
diff changeset
1960 end Read_Raw;
kono
parents:
diff changeset
1961
kono
parents:
diff changeset
1962 function Read (S : in out Mapped_Stream) return uint8 is
kono
parents:
diff changeset
1963 Data : uint8;
kono
parents:
diff changeset
1964 begin
kono
parents:
diff changeset
1965 Read_Raw (S, Data'Address, Data'Size / SSU);
kono
parents:
diff changeset
1966 return Data;
kono
parents:
diff changeset
1967 end Read;
kono
parents:
diff changeset
1968
kono
parents:
diff changeset
1969 function Read (S : in out Mapped_Stream) return uint16 is
kono
parents:
diff changeset
1970 Data : uint16;
kono
parents:
diff changeset
1971 begin
kono
parents:
diff changeset
1972 Read_Raw (S, Data'Address, Data'Size / SSU);
kono
parents:
diff changeset
1973 return Data;
kono
parents:
diff changeset
1974 end Read;
kono
parents:
diff changeset
1975
kono
parents:
diff changeset
1976 function Read (S : in out Mapped_Stream) return uint32 is
kono
parents:
diff changeset
1977 Data : uint32;
kono
parents:
diff changeset
1978 begin
kono
parents:
diff changeset
1979 Read_Raw (S, Data'Address, Data'Size / SSU);
kono
parents:
diff changeset
1980 return Data;
kono
parents:
diff changeset
1981 end Read;
kono
parents:
diff changeset
1982
kono
parents:
diff changeset
1983 function Read (S : in out Mapped_Stream) return uint64 is
kono
parents:
diff changeset
1984 Data : uint64;
kono
parents:
diff changeset
1985 begin
kono
parents:
diff changeset
1986 Read_Raw (S, Data'Address, Data'Size / SSU);
kono
parents:
diff changeset
1987 return Data;
kono
parents:
diff changeset
1988 end Read;
kono
parents:
diff changeset
1989
kono
parents:
diff changeset
1990 function Read (S : in out Mapped_Stream) return int8 is
kono
parents:
diff changeset
1991 Data : int8;
kono
parents:
diff changeset
1992 begin
kono
parents:
diff changeset
1993 Read_Raw (S, Data'Address, Data'Size / SSU);
kono
parents:
diff changeset
1994 return Data;
kono
parents:
diff changeset
1995 end Read;
kono
parents:
diff changeset
1996
kono
parents:
diff changeset
1997 function Read (S : in out Mapped_Stream) return int16 is
kono
parents:
diff changeset
1998 Data : int16;
kono
parents:
diff changeset
1999 begin
kono
parents:
diff changeset
2000 Read_Raw (S, Data'Address, Data'Size / SSU);
kono
parents:
diff changeset
2001 return Data;
kono
parents:
diff changeset
2002 end Read;
kono
parents:
diff changeset
2003
kono
parents:
diff changeset
2004 function Read (S : in out Mapped_Stream) return int32 is
kono
parents:
diff changeset
2005 Data : int32;
kono
parents:
diff changeset
2006 begin
kono
parents:
diff changeset
2007 Read_Raw (S, Data'Address, Data'Size / SSU);
kono
parents:
diff changeset
2008 return Data;
kono
parents:
diff changeset
2009 end Read;
kono
parents:
diff changeset
2010
kono
parents:
diff changeset
2011 function Read (S : in out Mapped_Stream) return int64 is
kono
parents:
diff changeset
2012 Data : int64;
kono
parents:
diff changeset
2013 begin
kono
parents:
diff changeset
2014 Read_Raw (S, Data'Address, Data'Size / SSU);
kono
parents:
diff changeset
2015 return Data;
kono
parents:
diff changeset
2016 end Read;
kono
parents:
diff changeset
2017
kono
parents:
diff changeset
2018 ------------------
kono
parents:
diff changeset
2019 -- Read_Address --
kono
parents:
diff changeset
2020 ------------------
kono
parents:
diff changeset
2021
kono
parents:
diff changeset
2022 function Read_Address
kono
parents:
diff changeset
2023 (Obj : Object_File; S : in out Mapped_Stream) return uint64 is
kono
parents:
diff changeset
2024 Address_32 : uint32;
kono
parents:
diff changeset
2025 Address_64 : uint64;
kono
parents:
diff changeset
2026
kono
parents:
diff changeset
2027 begin
kono
parents:
diff changeset
2028 case Obj.Arch is
kono
parents:
diff changeset
2029 when i386
kono
parents:
diff changeset
2030 | MIPS
kono
parents:
diff changeset
2031 | PPC
kono
parents:
diff changeset
2032 | SPARC
kono
parents:
diff changeset
2033 =>
kono
parents:
diff changeset
2034 Address_32 := Read (S);
kono
parents:
diff changeset
2035 return uint64 (Address_32);
kono
parents:
diff changeset
2036
kono
parents:
diff changeset
2037 when IA64
kono
parents:
diff changeset
2038 | PPC64
kono
parents:
diff changeset
2039 | SPARC64
kono
parents:
diff changeset
2040 | x86_64
kono
parents:
diff changeset
2041 =>
kono
parents:
diff changeset
2042 Address_64 := Read (S);
kono
parents:
diff changeset
2043 return Address_64;
kono
parents:
diff changeset
2044
kono
parents:
diff changeset
2045 when Unknown =>
kono
parents:
diff changeset
2046 raise Format_Error with "unrecognized machine architecture";
kono
parents:
diff changeset
2047 end case;
kono
parents:
diff changeset
2048 end Read_Address;
kono
parents:
diff changeset
2049
kono
parents:
diff changeset
2050 -------------------
kono
parents:
diff changeset
2051 -- Read_C_String --
kono
parents:
diff changeset
2052 -------------------
kono
parents:
diff changeset
2053
kono
parents:
diff changeset
2054 procedure Read_C_String (S : in out Mapped_Stream; B : out Buffer) is
kono
parents:
diff changeset
2055 J : Integer := 0;
kono
parents:
diff changeset
2056
kono
parents:
diff changeset
2057 begin
kono
parents:
diff changeset
2058 loop
kono
parents:
diff changeset
2059 -- Handle overflow case
kono
parents:
diff changeset
2060
kono
parents:
diff changeset
2061 if J = B'Last then
kono
parents:
diff changeset
2062 B (J) := 0;
kono
parents:
diff changeset
2063 exit;
kono
parents:
diff changeset
2064 end if;
kono
parents:
diff changeset
2065
kono
parents:
diff changeset
2066 B (J) := Read (S);
kono
parents:
diff changeset
2067 exit when B (J) = 0;
kono
parents:
diff changeset
2068 J := J + 1;
kono
parents:
diff changeset
2069 end loop;
kono
parents:
diff changeset
2070 end Read_C_String;
kono
parents:
diff changeset
2071
kono
parents:
diff changeset
2072 -------------------
kono
parents:
diff changeset
2073 -- Read_C_String --
kono
parents:
diff changeset
2074 -------------------
kono
parents:
diff changeset
2075
kono
parents:
diff changeset
2076 function Read_C_String (S : in out Mapped_Stream) return Str_Access is
kono
parents:
diff changeset
2077 Res : constant Str_Access := Read (S);
kono
parents:
diff changeset
2078
kono
parents:
diff changeset
2079 begin
kono
parents:
diff changeset
2080 for J in Res'Range loop
kono
parents:
diff changeset
2081 if S.Off + Offset (J - 1) > Offset (Last (S.Region)) then
kono
parents:
diff changeset
2082 raise IO_Error with "could not read from object file";
kono
parents:
diff changeset
2083 end if;
kono
parents:
diff changeset
2084
kono
parents:
diff changeset
2085 if Res (J) = ASCII.NUL then
kono
parents:
diff changeset
2086 S.Off := S.Off + Offset (J);
kono
parents:
diff changeset
2087 return Res;
kono
parents:
diff changeset
2088 end if;
kono
parents:
diff changeset
2089 end loop;
kono
parents:
diff changeset
2090
kono
parents:
diff changeset
2091 -- Overflow case
kono
parents:
diff changeset
2092 raise Constraint_Error;
kono
parents:
diff changeset
2093 end Read_C_String;
kono
parents:
diff changeset
2094
kono
parents:
diff changeset
2095 -----------------
kono
parents:
diff changeset
2096 -- Read_LEB128 --
kono
parents:
diff changeset
2097 -----------------
kono
parents:
diff changeset
2098
kono
parents:
diff changeset
2099 function Read_LEB128 (S : in out Mapped_Stream) return uint32 is
kono
parents:
diff changeset
2100 B : uint8;
kono
parents:
diff changeset
2101 Shift : Integer := 0;
kono
parents:
diff changeset
2102 Res : uint32 := 0;
kono
parents:
diff changeset
2103
kono
parents:
diff changeset
2104 begin
kono
parents:
diff changeset
2105 loop
kono
parents:
diff changeset
2106 B := Read (S);
kono
parents:
diff changeset
2107 Res := Res or Shift_Left (uint32 (B and 16#7f#), Shift);
kono
parents:
diff changeset
2108 exit when (B and 16#80#) = 0;
kono
parents:
diff changeset
2109 Shift := Shift + 7;
kono
parents:
diff changeset
2110 end loop;
kono
parents:
diff changeset
2111
kono
parents:
diff changeset
2112 return Res;
kono
parents:
diff changeset
2113 end Read_LEB128;
kono
parents:
diff changeset
2114
kono
parents:
diff changeset
2115 function Read_LEB128 (S : in out Mapped_Stream) return int32 is
kono
parents:
diff changeset
2116 B : uint8;
kono
parents:
diff changeset
2117 Shift : Integer := 0;
kono
parents:
diff changeset
2118 Res : uint32 := 0;
kono
parents:
diff changeset
2119
kono
parents:
diff changeset
2120 begin
kono
parents:
diff changeset
2121 loop
kono
parents:
diff changeset
2122 B := Read (S);
kono
parents:
diff changeset
2123 Res := Res or Shift_Left (uint32 (B and 16#7f#), Shift);
kono
parents:
diff changeset
2124 Shift := Shift + 7;
kono
parents:
diff changeset
2125 exit when (B and 16#80#) = 0;
kono
parents:
diff changeset
2126 end loop;
kono
parents:
diff changeset
2127
kono
parents:
diff changeset
2128 if Shift < 32 and then (Res and Shift_Left (1, Shift - 1)) /= 0 then
kono
parents:
diff changeset
2129 Res := Res or Shift_Left (-1, Shift);
kono
parents:
diff changeset
2130 end if;
kono
parents:
diff changeset
2131
kono
parents:
diff changeset
2132 return To_int32 (Res);
kono
parents:
diff changeset
2133 end Read_LEB128;
kono
parents:
diff changeset
2134
kono
parents:
diff changeset
2135 -----------------
kono
parents:
diff changeset
2136 -- Read_Symbol --
kono
parents:
diff changeset
2137 -----------------
kono
parents:
diff changeset
2138
kono
parents:
diff changeset
2139 function Read_Symbol
kono
parents:
diff changeset
2140 (Obj : in out Object_File;
kono
parents:
diff changeset
2141 Off : Offset) return Object_Symbol is
kono
parents:
diff changeset
2142 begin
kono
parents:
diff changeset
2143 case Obj.Format is
kono
parents:
diff changeset
2144 when ELF32 => return ELF32_Ops.Read_Symbol (Obj, Off);
kono
parents:
diff changeset
2145 when ELF64 => return ELF64_Ops.Read_Symbol (Obj, Off);
kono
parents:
diff changeset
2146 when Any_PECOFF => return PECOFF_Ops.Read_Symbol (Obj, Off);
kono
parents:
diff changeset
2147 when XCOFF32 => return XCOFF32_Ops.Read_Symbol (Obj, Off);
kono
parents:
diff changeset
2148 end case;
kono
parents:
diff changeset
2149 end Read_Symbol;
kono
parents:
diff changeset
2150
kono
parents:
diff changeset
2151 ----------
kono
parents:
diff changeset
2152 -- Seek --
kono
parents:
diff changeset
2153 ----------
kono
parents:
diff changeset
2154
kono
parents:
diff changeset
2155 procedure Seek (S : in out Mapped_Stream; Off : Offset) is
kono
parents:
diff changeset
2156 begin
kono
parents:
diff changeset
2157 if Off < 0 or else Off > Offset (Last (S.Region)) then
kono
parents:
diff changeset
2158 raise IO_Error with "could not seek to offset in object file";
kono
parents:
diff changeset
2159 end if;
kono
parents:
diff changeset
2160
kono
parents:
diff changeset
2161 S.Off := Off;
kono
parents:
diff changeset
2162 end Seek;
kono
parents:
diff changeset
2163
kono
parents:
diff changeset
2164 ----------
kono
parents:
diff changeset
2165 -- Size --
kono
parents:
diff changeset
2166 ----------
kono
parents:
diff changeset
2167
kono
parents:
diff changeset
2168 function Size (Sec : Object_Section) return uint64 is
kono
parents:
diff changeset
2169 begin
kono
parents:
diff changeset
2170 return Sec.Size;
kono
parents:
diff changeset
2171 end Size;
kono
parents:
diff changeset
2172
kono
parents:
diff changeset
2173 function Size (Sym : Object_Symbol) return uint64 is
kono
parents:
diff changeset
2174 begin
kono
parents:
diff changeset
2175 return Sym.Size;
kono
parents:
diff changeset
2176 end Size;
kono
parents:
diff changeset
2177
kono
parents:
diff changeset
2178 ------------
kono
parents:
diff changeset
2179 -- Strlen --
kono
parents:
diff changeset
2180 ------------
kono
parents:
diff changeset
2181
kono
parents:
diff changeset
2182 function Strlen (Buf : Buffer) return int32 is
kono
parents:
diff changeset
2183 begin
kono
parents:
diff changeset
2184 return int32 (CRTL.strlen (Buf'Address));
kono
parents:
diff changeset
2185 end Strlen;
kono
parents:
diff changeset
2186
kono
parents:
diff changeset
2187 -----------
kono
parents:
diff changeset
2188 -- Spans --
kono
parents:
diff changeset
2189 -----------
kono
parents:
diff changeset
2190
kono
parents:
diff changeset
2191 function Spans (Sym : Object_Symbol; Addr : uint64) return Boolean is
kono
parents:
diff changeset
2192 begin
kono
parents:
diff changeset
2193 return Addr >= Sym.Value and then Addr < Sym.Value + Sym.Size;
kono
parents:
diff changeset
2194 end Spans;
kono
parents:
diff changeset
2195
kono
parents:
diff changeset
2196 ---------------
kono
parents:
diff changeset
2197 -- To_String --
kono
parents:
diff changeset
2198 ---------------
kono
parents:
diff changeset
2199
kono
parents:
diff changeset
2200 function To_String (Buf : Buffer) return String is
kono
parents:
diff changeset
2201 Result : String (1 .. Integer (CRTL.strlen (Buf'Address)));
kono
parents:
diff changeset
2202 for Result'Address use Buf'Address;
kono
parents:
diff changeset
2203 pragma Import (Ada, Result);
kono
parents:
diff changeset
2204
kono
parents:
diff changeset
2205 begin
kono
parents:
diff changeset
2206 return Result;
kono
parents:
diff changeset
2207 end To_String;
kono
parents:
diff changeset
2208
kono
parents:
diff changeset
2209 -----------------------
kono
parents:
diff changeset
2210 -- To_String_Ptr_Len --
kono
parents:
diff changeset
2211 -----------------------
kono
parents:
diff changeset
2212
kono
parents:
diff changeset
2213 function To_String_Ptr_Len
kono
parents:
diff changeset
2214 (Ptr : Mmap.Str_Access;
kono
parents:
diff changeset
2215 Max_Len : Natural := Natural'Last) return String_Ptr_Len is
kono
parents:
diff changeset
2216 begin
kono
parents:
diff changeset
2217 for I in 1 .. Max_Len loop
kono
parents:
diff changeset
2218 if Ptr (I) = ASCII.NUL then
kono
parents:
diff changeset
2219 return (Ptr, I - 1);
kono
parents:
diff changeset
2220 end if;
kono
parents:
diff changeset
2221 end loop;
kono
parents:
diff changeset
2222 return (Ptr, Max_Len);
kono
parents:
diff changeset
2223 end To_String_Ptr_Len;
kono
parents:
diff changeset
2224
kono
parents:
diff changeset
2225 ------------------------
kono
parents:
diff changeset
2226 -- Trim_Trailing_Nuls --
kono
parents:
diff changeset
2227 ------------------------
kono
parents:
diff changeset
2228
kono
parents:
diff changeset
2229 function Trim_Trailing_Nuls (Str : String) return String is
kono
parents:
diff changeset
2230 begin
kono
parents:
diff changeset
2231 for J in Str'Range loop
kono
parents:
diff changeset
2232 if Str (J) = ASCII.NUL then
kono
parents:
diff changeset
2233 return Str (Str'First .. J - 1);
kono
parents:
diff changeset
2234 end if;
kono
parents:
diff changeset
2235 end loop;
kono
parents:
diff changeset
2236
kono
parents:
diff changeset
2237 return Str;
kono
parents:
diff changeset
2238 end Trim_Trailing_Nuls;
kono
parents:
diff changeset
2239
kono
parents:
diff changeset
2240 -----------
kono
parents:
diff changeset
2241 -- Value --
kono
parents:
diff changeset
2242 -----------
kono
parents:
diff changeset
2243
kono
parents:
diff changeset
2244 function Value (Sym : Object_Symbol) return uint64 is
kono
parents:
diff changeset
2245 begin
kono
parents:
diff changeset
2246 return Sym.Value;
kono
parents:
diff changeset
2247 end Value;
kono
parents:
diff changeset
2248
kono
parents:
diff changeset
2249 end System.Object_Reader;