1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 54 55 56 57 58 59 60 61 62 63 64 65 66 67 68 69 70 71 72 73 74 75 76 77 78 79 80 81 82 83 84 85 86 87 88 89 90 91 92 93 94 95 96 97 98 99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116 117 118 119 120 121 122 123 124 125 126 127 128 129 130 131 132 133 134 135 136 137 138 139 140 141 142 143 144 145 146 147 148 149 150 151 152 153 154 155 156 157 158 159 160 161 162 163 164 165 166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183 184 185 186 187 188 189 190 191 192 193 194 195 196 197 198 199 200 201 202 203 204 205 206 207 208 209 210 211 212 213 214 215 216 217 218 219 220 221 222 223 224 225 226 227 228 229 230 231 232 233 234 235 236 237 238 239 240 241 242 243 244 245 246 247 248 249 250 251 252 253 254 255 256 257 258 259 260 261 262 263 264 265 266 267 268 269 270 271 272 273 274 275 276 277 278 279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303 304 305 306 307 308 309 310 311 312 313 314 315 316 317 318 319 320 321 322 323 324 325 326 327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356 357 358 359 360 361 362 363 364 365 366 367 368 369 370 371 372 373 374 375 376 377 378 379 380 381 382 383 384 385 386 387 388 389 390 391 392 393 394 395 396 397 398 399 400 401 402 403 404 405 406 407 408 409 410 411 412 413 414 415 416 417 418 419 420 421 422 423 424 425 426 427 428 429 430 431 432 433 434 435 436 437 438 439 440 441 442 443 444 445 446 447 448 449 450 451 452 453 454 455 456 457 458
|
------------------------------------------------------------------------------
-- --
-- GNAT COMPILER COMPONENTS --
-- --
-- S Y S T E M . O B J E C T _ R E A D E R --
-- --
-- S p e c --
-- --
-- Copyright (C) 2009-2024, Free Software Foundation, Inc. --
-- --
-- GNAT is free software; you can redistribute it and/or modify it under --
-- terms of the GNU General Public License as published by the Free Soft- --
-- ware Foundation; either version 3, or (at your option) any later ver- --
-- sion. GNAT is distributed in the hope that it will be useful, but WITH- --
-- OUT ANY WARRANTY; without even the implied warranty of MERCHANTABILITY --
-- or FITNESS FOR A PARTICULAR PURPOSE. --
-- --
-- As a special exception under Section 7 of GPL version 3, you are granted --
-- additional permissions described in the GCC Runtime Library Exception, --
-- version 3.1, as published by the Free Software Foundation. --
-- --
-- You should have received a copy of the GNU General Public License and --
-- a copy of the GCC Runtime Library Exception along with this program; --
-- see the files COPYING3 and COPYING.RUNTIME respectively. If not, see --
-- <http://www.gnu.org/licenses/>. --
-- --
-- GNAT was originally developed by the GNAT team at New York University. --
-- Extensive contributions were provided by Ada Core Technologies Inc. --
-- --
------------------------------------------------------------------------------
-- This package implements a simple, minimal overhead reader for object files
-- composed of sections of untyped heterogeneous binary data.
with Interfaces;
with System.Mmap;
package System.Object_Reader is
--------------
-- Limits --
--------------
BUFFER_SIZE : constant := 8 * 1024;
---------------------
-- Object sections --
----------------------
type Object_Section is private;
Null_Section : constant Object_Section;
--------------------
-- Object symbols --
--------------------
type Object_Symbol is private;
------------------------
-- Object format type --
------------------------
type Object_Format is
(ELF32,
-- Object format is 32-bit ELF
ELF64,
-- Object format is 64-bit ELF
PECOFF,
-- Object format is Microsoft PECOFF
PECOFF_PLUS,
-- Object format is Microsoft PECOFF+
XCOFF32);
-- Object format is AIX 32-bit XCOFF
-- PECOFF | PECOFF_PLUS appears so often as a case choice, would
-- seem a good idea to have a subtype name covering these two choices ???
------------------
-- Object files --
------------------
type Object_File (Format : Object_Format) is private;
type Object_File_Access is access Object_File;
------------------------------
-- Object architecture type --
------------------------------
type Object_Arch is
(Unknown,
-- The target architecture has not yet been determined
SPARC,
-- 32-bit SPARC
SPARC64,
-- 64-bit SPARC
i386,
-- Intel IA32
MIPS,
-- MIPS Technologies MIPS
x86_64,
-- x86-64 (64-bit AMD/Intel)
IA64,
-- Intel IA64
PPC,
-- 32-bit PowerPC
PPC64,
-- 64-bit PowerPC
ARM,
-- 32-bit ARM
AARCH64);
-- 64-bit ARM
------------------
-- Target types --
------------------
subtype Offset is Interfaces.Integer_64;
subtype uint8 is Interfaces.Unsigned_8;
subtype uint16 is Interfaces.Unsigned_16;
subtype uint32 is Interfaces.Unsigned_32;
subtype uint64 is Interfaces.Unsigned_64;
subtype int8 is Interfaces.Integer_8;
subtype int16 is Interfaces.Integer_16;
subtype int32 is Interfaces.Integer_32;
subtype int64 is Interfaces.Integer_64;
type Buffer is array (0 .. BUFFER_SIZE - 1) of uint8;
type String_Ptr_Len is record
Ptr : Mmap.Str_Access;
Len : Natural;
end record;
-- A string made from a pointer and a length. Not all strings for name
-- are C strings: COFF inlined symbol names have a max length of 8.
-------------------------------------------
-- Operations on buffers of untyped data --
-------------------------------------------
function To_String (Buf : Buffer) return String;
-- Construct string from C style null-terminated string stored in a buffer
function To_String_Ptr_Len
(Ptr : Mmap.Str_Access;
Max_Len : Natural := Natural'Last) return String_Ptr_Len;
-- Convert PTR to a String_Ptr_Len.
function Strlen (Buf : Buffer) return int32;
-- Return the length of a C style null-terminated string
-------------------------
-- Opening and closing --
-------------------------
function Open
(File_Name : String;
In_Exception : Boolean := False) return Object_File_Access;
-- Open the object file and initialize the reader. In_Exception is true
-- when the parsing is done as part of an exception handler decorator. In
-- this mode we do not want to raise an exception.
procedure Close (Obj : in out Object_File);
-- Close the object file
-----------------------
-- Sequential access --
-----------------------
type Mapped_Stream is private;
-- Provide an abstraction of a stream on a memory mapped file
function Create_Stream (MF : System.Mmap.Mapped_File;
File_Offset : System.Mmap.File_Size;
File_Length : System.Mmap.File_Size)
return Mapped_Stream;
-- Create a stream from Mf
procedure Close (S : in out Mapped_Stream);
-- Close the stream (deallocate memory)
procedure Read_Raw
(S : in out Mapped_Stream;
Addr : Address;
Size : uint32);
pragma Inline (Read_Raw);
-- Read a number of fixed sized records
procedure Seek (S : in out Mapped_Stream; Off : Offset);
-- Seek to an absolute offset in bytes
procedure Tell (Obj : in out Mapped_Stream; Off : out Offset)
with Inline;
function Tell (Obj : Mapped_Stream) return Offset
with Inline;
-- Fetch the current offset
function Length (Obj : Mapped_Stream) return Offset
with Inline;
-- Length of the stream
function Read (S : in out Mapped_Stream) return Mmap.Str_Access;
-- Provide a pointer in memory at the current offset
function Read (S : in out Mapped_Stream) return String_Ptr_Len;
-- Provide a pointer in memory at the current offset
function Read (S : in out Mapped_Stream) return uint8;
function Read (S : in out Mapped_Stream) return uint16;
function Read (S : in out Mapped_Stream) return uint32;
function Read (S : in out Mapped_Stream) return uint64;
function Read (S : in out Mapped_Stream) return int8;
function Read (S : in out Mapped_Stream) return int16;
function Read (S : in out Mapped_Stream) return int32;
function Read (S : in out Mapped_Stream) return int64;
-- Read a scalar
function Read_Address
(Obj : Object_File; S : in out Mapped_Stream) return uint64;
-- Read either a 64 or 32 bit address from the file stream depending on the
-- address size of the target architecture and promote it to a 64 bit type.
function Read_LEB128 (S : in out Mapped_Stream) return uint32;
function Read_LEB128 (S : in out Mapped_Stream) return int32;
-- Read a value encoding in Little-Endian Base 128 format
procedure Read_C_String (S : in out Mapped_Stream; B : out Buffer);
function Read_C_String (S : in out Mapped_Stream) return Mmap.Str_Access;
-- Read a C style NULL terminated string
function Offset_To_String
(S : in out Mapped_Stream;
Off : Offset) return String;
-- Construct a string from a C style NULL terminated string located at an
-- offset into the object file.
------------------------
-- Object information --
------------------------
function Arch (Obj : Object_File) return Object_Arch;
-- Return the object architecture
function Format (Obj : Object_File) return Object_Format;
-- Return the object file format
function Get_Load_Address (Obj : Object_File) return uint64;
-- Return the load address defined in Obj. May raise Format_Error if not
-- implemented
function Num_Sections (Obj : Object_File) return uint32;
-- Return the number of sections composing the object file
function Get_Section
(Obj : in out Object_File;
Shnum : uint32) return Object_Section;
-- Return the Nth section (numbered from zero)
function Get_Section
(Obj : in out Object_File;
Sec_Name : String) return Object_Section;
-- Return a section by name
function Create_Stream
(Obj : Object_File;
Sec : Object_Section) return Mapped_Stream;
-- Create a stream for section Sec
procedure Get_Xcode_Bounds
(Obj : in out Object_File;
Low, High : out uint64);
-- Return the low and high addresses of the code for the object file. Can
-- be used to check if an address lies within this object file. This
-- procedure is not efficient and the result should be saved to avoid
-- recomputation.
-------------------------
-- Section information --
-------------------------
function Name
(Obj : in out Object_File;
Sec : Object_Section) return String;
-- Return the name of a section as a string
function Size (Sec : Object_Section) return uint64;
-- Return the size of a section in bytes
function Num (Sec : Object_Section) return uint32;
-- Return the index of a section from zero
function Off (Sec : Object_Section) return Offset;
-- Return the byte offset of the section within the object
------------------------------
-- Symbol table information --
------------------------------
Null_Symbol : constant Object_Symbol;
-- An empty symbol table entry.
function First_Symbol (Obj : in out Object_File) return Object_Symbol;
-- Return the first element in the symbol table or Null_Symbol if the
-- symbol table is empty.
function Next_Symbol
(Obj : in out Object_File;
Prev : Object_Symbol) return Object_Symbol;
-- Return the element following Prev in the symbol table, or Null_Symbol if
-- Prev is the last symbol in the table.
function Read_Symbol
(Obj : in out Object_File;
Off : Offset) return Object_Symbol;
-- Read symbol at Off
function Name
(Obj : in out Object_File;
Sym : Object_Symbol) return String_Ptr_Len;
-- Return the name of the symbol
function Decoded_Ada_Name
(Obj : in out Object_File;
Sym : String_Ptr_Len) return String;
-- Return the decoded name of a symbol encoded as per exp_dbug.ads
function Strip_Leading_Char
(Obj : in out Object_File;
Sym : String_Ptr_Len) return Positive;
-- Return the index of the first character to decode the name. This can
-- strip one character for ABI with a prefix (like x86 for PECOFF).
function Value (Sym : Object_Symbol) return uint64;
-- Return the name of the symbol
function Size (Sym : Object_Symbol) return uint64;
-- Return the size of the symbol in bytes
function Spans (Sym : Object_Symbol; Addr : uint64) return Boolean;
-- Determine whether a particular address corresponds to the range
-- referenced by this symbol.
function Off (Sym : Object_Symbol) return Offset;
-- Return the offset of the symbol.
----------------
-- Exceptions --
----------------
IO_Error : exception;
-- Input/Output error reading file
Format_Error : exception;
-- Encountered a problem parsing the object
private
type Mapped_Stream is record
Region : System.Mmap.Mapped_Region;
Off : Offset;
Len : Offset;
end record;
subtype ELF is Object_Format range ELF32 .. ELF64;
subtype Any_PECOFF is Object_Format range PECOFF .. PECOFF_PLUS;
type Object_File (Format : Object_Format) is record
MF : System.Mmap.Mapped_File := System.Mmap.Invalid_Mapped_File;
Arch : Object_Arch := Unknown;
Num_Sections : uint32 := 0;
-- Number of sections
Symtab_Last : Offset; -- Last offset of symbol table
In_Exception : Boolean := False;
-- True if the parsing is done as part of an exception handler
Sectab_Stream : Mapped_Stream;
-- Section table
Symtab_Stream : Mapped_Stream;
-- Symbol table
Symstr_Stream : Mapped_Stream;
-- Symbol strings
case Format is
when ELF =>
Secstr_Stream : Mapped_Stream;
-- Section strings
when Any_PECOFF =>
ImageBase : uint64; -- ImageBase value from header
-- Cache for latest result of Get_Section_Virtual_Address
GSVA_Sec : uint32 := uint32'Last;
GSVA_Addr : uint64;
when XCOFF32 =>
null;
end case;
end record;
subtype ELF_Object_File is Object_File
with Predicate => ELF_Object_File.Format in ELF;
subtype PECOFF_Object_File is Object_File
with Predicate => PECOFF_Object_File.Format in Any_PECOFF;
subtype XCOFF32_Object_File is Object_File
with Predicate => XCOFF32_Object_File.Format in XCOFF32;
type Object_Section is record
Num : uint32 := 0;
-- Section index in the section table
Off : Offset := 0;
-- First byte of the section in the object file
Addr : uint64 := 0;
-- Load address of the section. Valid only when Flag_Alloc is true.
Size : uint64 := 0;
-- Length of the section in bytes
Flag_Xcode : Boolean := False;
-- True if the section is advertised to contain executable code
end record;
Null_Section : constant Object_Section := (0, 0, 0, 0, False);
type Object_Symbol is record
Off : Offset := 0; -- Offset of underlying symbol on disk
Next : Offset := 0; -- Offset of the following symbol
Value : uint64 := 0; -- Value associated with this symbol
Size : uint64 := 0; -- Size of the referenced entity
end record;
Null_Symbol : constant Object_Symbol := (0, 0, 0, 0);
end System.Object_Reader;
|