aboutsummaryrefslogtreecommitdiff
path: root/gcc/ada/libgnat/s-objrea.ads
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/ada/libgnat/s-objrea.ads')
-rw-r--r--gcc/ada/libgnat/s-objrea.ads451
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;