diff options
Diffstat (limited to 'gcc/ada/libgnat/s-objrea.ads')
-rw-r--r-- | gcc/ada/libgnat/s-objrea.ads | 451 |
1 files changed, 451 insertions, 0 deletions
diff --git a/gcc/ada/libgnat/s-objrea.ads b/gcc/ada/libgnat/s-objrea.ads new file mode 100644 index 0000000..1d48536 --- /dev/null +++ b/gcc/ada/libgnat/s-objrea.ads @@ -0,0 +1,451 @@ +------------------------------------------------------------------------------ +-- -- +-- 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-2017, 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 files -- + ------------------ + + type Object_File (<>) is private; + + type Object_File_Access is access Object_File; + + --------------------- + -- 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 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; + + 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_Memory_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 in 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; + -- ???Above predicates cause the compiler to crash when instantiating + -- ELF64_Ops (see package body). + + 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_Alloc : Boolean := False; + -- True if the section is mapped in memory by the OS loader + 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; |