------------------------------------------------------------------------------ -- -- -- 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-2012, 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. -- -- -- -- -- -- -- -- -- -- -- -- 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.C_Streams; with Interfaces; with System; package System.Object_Reader is -------------- -- Limits -- -------------- BUFFER_SIZE : constant := 8 * 1024; ------------------ -- Object files -- ------------------ type Object_File is abstract tagged private; type Object_File_Access is access Object_File'Class; --------------------- -- Object sections -- ---------------------- type Object_Section is private; -------------------- -- Object symbols -- -------------------- type Object_Symbol is private; ------------------------ -- Object format type -- ------------------------ type Object_Format is (Unknown, -- Object format has not yet been determined 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 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 ------------------ -- 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; ------------------------------------------- -- 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 Strlen (Buf : Buffer) return int32; -- Return the length of a C style null-terminated string ------------------------- -- Opening and closing -- ------------------------- function Open (File_Name : String) return Object_File'Class; -- Open the object file and initialize the reader procedure Close (Obj : in out Object_File); -- Close the object file ----------------------- -- Sequential access -- ----------------------- procedure Read (Obj : Object_File'Class; Addr : Address; Size : uint32); -- Read a number of fixed sized records function Read (Obj : Object_File'Class) return uint8; function Read (Obj : Object_File'Class) return uint16; function Read (Obj : Object_File'Class) return uint32; function Read (Obj : Object_File'Class) return uint64; function Read (Obj : Object_File'Class) return int8; function Read (Obj : Object_File'Class) return int16; function Read (Obj : Object_File'Class) return int32; function Read (Obj : Object_File'Class) return int64; -- Read a scalar function Read_Address (Obj : Object_File'Class) 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 (Obj : Object_File'Class) return uint32; function Read_LEB128 (Obj : Object_File'Class) return int32; -- Read a value encoding in Little-Endian Base 128 format procedure Read_C_String (Obj : Object_File'Class; B : out Buffer); -- Read a C style NULL terminated string at an offset function Offset_To_String (Obj : Object_File'Class; Off : Offset) return String; -- Construct a string from a C style NULL terminated string located at an -- offset into the object file. ------------------- -- Random access -- ------------------- procedure Seek (Obj : Object_File'Class; Off : Offset); -- Seek to an absolute offset in bytes procedure Tell (Obj : Object_File'Class; Off : out Offset); -- Fetch the current offset ------------------------ -- Object information -- ------------------------ function Arch (Obj : Object_File'Class) return Object_Arch; -- Return the object architecture function Format (Obj : Object_File'Class) return Object_Format; -- Return the object file format function Num_Sections (Obj : Object_File'Class) return uint32; -- Return the number of sections composing the object file function Get_Section (Obj : Object_File; Shnum : uint32) return Object_Section is abstract; -- Return the Nth section (numbered from zero) function Get_Section (Obj : Object_File'Class; Sec_Name : String) return Object_Section; -- Return a section by name ------------------------- -- Section information -- ------------------------- procedure Seek (Obj : Object_File'Class; Sec : Object_Section); -- Seek to a section function Name (Obj : Object_File; Sec : Object_Section) return String is abstract; -- 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 Num_Symbols (Obj : Object_File'Class) return uint64; -- The number of symbols in the symbol table function First_Symbol (Obj : in out Object_File) return Object_Symbol is abstract; -- 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 is abstract; -- Return the element following Prev in the symbol table, or Null_Symbol if -- Prev is the last symbol in the table. function Name (Obj : Object_File; Sym : Object_Symbol) return String is abstract; -- Return the name of the symbol function Decoded_Ada_Name (Obj : Object_File'Class; Sym : Object_Symbol) return String; -- Return the the decoded name of a symbol encoded as per exp_dbug.ads 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. ---------------- -- Exceptions -- ---------------- IO_Error : exception; -- Input/Output error reading file Format_Error : exception; -- Encountered a problem parsing the object private package ICS renames Interfaces.C_Streams; type Object_File is abstract tagged record fp : ICS.FILEs := ICS.NULL_Stream; Arch : Object_Arch := Unknown; Format : Object_Format := Unknown; Num_Sections : uint32 := 0; Num_Symbols : uint64 := 0; end record; type Object_Section is record Num : uint32 := 0; -- Index of this section in the section table Off : Offset := 0; -- First byte of the section Size : uint64 := 0; -- Length of the section in bytes end record; type Object_Symbol is record Num : uint64 := 0; -- Index of this symbol in the symbol table 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, 0); end System.Object_Reader;