1------------------------------------------------------------------------------
2--                                                                          --
3--                         GNAT COMPILER COMPONENTS                         --
4--                                                                          --
5--                   S Y S T E M . D W A R F _ L I N E S                    --
6--                                                                          --
7--                                 S p e c                                  --
8--                                                                          --
9--           Copyright (C) 2009-2020, Free Software Foundation, Inc.        --
10--                                                                          --
11-- GNAT is free software;  you can  redistribute it  and/or modify it under --
12-- terms of the  GNU General Public License as published  by the Free Soft- --
13-- ware  Foundation;  either version 3,  or (at your option) any later ver- --
14-- sion.  GNAT is distributed in the hope that it will be useful, but WITH- --
15-- OUT ANY WARRANTY;  without even the  implied warranty of MERCHANTABILITY --
16-- or FITNESS FOR A PARTICULAR PURPOSE.                                     --
17--                                                                          --
18-- As a special exception under Section 7 of GPL version 3, you are granted --
19-- additional permissions described in the GCC Runtime Library Exception,   --
20-- version 3.1, as published by the Free Software Foundation.               --
21--                                                                          --
22-- You should have received a copy of the GNU General Public License and    --
23-- a copy of the GCC Runtime Library Exception along with this program;     --
24-- see the files COPYING3 and COPYING.RUNTIME respectively.  If not, see    --
25-- <http://www.gnu.org/licenses/>.                                          --
26--                                                                          --
27-- GNAT was originally developed  by the GNAT team at  New York University. --
28-- Extensive contributions were provided by Ada Core Technologies Inc.      --
29--                                                                          --
30------------------------------------------------------------------------------
31
32--  This package provides routines to read DWARF line number information from
33--  a binary file with as little overhead as possible. This allows conversions
34--  from PC addresses to human-readable source locations.
35--
36--  Files must be compiled with at least minimal debugging information (-g1).
37
38with System.Bounded_Strings;
39with System.Object_Reader;
40with System.Traceback_Entries;
41
42package System.Dwarf_Lines is
43
44   package STE renames System.Traceback_Entries;
45   package SOR renames System.Object_Reader;
46
47   type Dwarf_Context (In_Exception : Boolean := False) is private;
48   --  Type encapsulating the state of the DWARF reader. When In_Exception is
49   --  True, we are parsing as part of an exception handler decorator so we do
50   --  not want another exception to be raised and the parsing is done safely,
51   --  skipping binary files that cannot be read or have been stripped from
52   --  their debug sections for example.
53
54   procedure Open
55     (File_Name :     String;
56      C         : out Dwarf_Context;
57      Success   : out Boolean);
58   procedure Close (C : in out Dwarf_Context);
59   --  Open and close a file
60
61   procedure Set_Load_Address (C : in out Dwarf_Context; Addr : Address);
62   --  Set the run-time load address of a file. Used to rebase PIE (Position
63   --  Independent Executable) binaries.
64
65   function Is_Inside (C : Dwarf_Context; Addr : Address) return Boolean;
66   pragma Inline (Is_Inside);
67   --  Return whether a run-time address Addr lies within the file
68
69   function Low_Address (C : Dwarf_Context) return Address;
70   pragma Inline (Low_Address);
71   --  Return the lowest run-time address of the file
72
73   procedure Dump (C : in out Dwarf_Context);
74   --  Dump each row found in the object's .debug_lines section to standard out
75
76   procedure Dump_Cache (C : Dwarf_Context);
77   --  Dump the cache (if present)
78
79   procedure Enable_Cache (C : in out Dwarf_Context);
80   --  Read symbol information to speed up Symbolic_Traceback.
81
82   procedure Symbolic_Traceback
83     (Cin          :        Dwarf_Context;
84      Traceback    :        STE.Tracebacks_Array;
85      Suppress_Hex :        Boolean;
86      Symbol_Found :    out Boolean;
87      Res          : in out System.Bounded_Strings.Bounded_String);
88   --  Generate a string for a traceback suitable for displaying to the user.
89   --  If one or more symbols are found, Symbol_Found is set to True. This
90   --  allows the caller to fall back to hexadecimal addresses.
91
92   Dwarf_Error : exception;
93   --  Raised if a problem is encountered parsing DWARF information. Can be a
94   --  result of a logic error or malformed DWARF information.
95
96private
97   --  The following section numbers reference
98
99   --    "DWARF Debugging Information Format, Version 5"
100
101   --  published by the Standards Group, http://freestandards.org.
102
103   --  6.2.2 State Machine Registers
104
105   type Line_Info_Registers is record
106      Address            : SOR.uint64;
107      File               : SOR.uint32;
108      Line               : SOR.uint32;
109      Column             : SOR.uint32;
110      Is_Stmt            : Boolean;
111      Basic_Block        : Boolean;
112      End_Sequence       : Boolean;
113      --  Prologue_End   : Boolean;
114      --  Epilogue_Begin : Boolean;
115      --  ISA            : SOR.uint32;
116      --  Discriminator  : SOR.uint32;  -- DWARF 4/5
117      Is_Row             : Boolean;     -- local
118   end record;
119
120   --  6.2.4 The Line Number Program Header
121
122   MAX_OPCODE : constant := 256;
123
124   type Opcode_Length_Array is array (1 .. MAX_OPCODE) of SOR.uint8;
125
126   MAX_ENTRY : constant := 5;
127
128   type Entry_Format_Pair is record
129      C_Type : SOR.uint32;
130      Form   : SOR.uint32;
131   end record;
132
133   type Entry_Format_Array is array (1 .. MAX_ENTRY) of Entry_Format_Pair;
134
135   type Line_Info_Header is record
136      Unit_Length                  : SOR.Offset;
137      Version                      : SOR.uint16;
138      Address_Size                 : SOR.uint8;           -- DWARF 5
139      Segment_Selector_Size        : SOR.uint8;           -- DWARF 5
140      Header_Length                : SOR.uint32;
141      Minimum_Insn_Length          : SOR.uint8;
142      Maximum_Op_Per_Insn          : SOR.uint8;           -- DWARF 4/5
143      Default_Is_Stmt              : SOR.uint8;
144      Line_Base                    : SOR.int8;
145      Line_Range                   : SOR.uint8;
146      Opcode_Base                  : SOR.uint8;
147      --  Standard_Opcode_Lengths  : Opcode_Length_Array;
148      Directory_Entry_Format_Count : SOR.uint8;           -- DWARF 5
149      Directory_Entry_Format       : Entry_Format_Array;  -- DWARF 5
150      Directories_Count            : SOR.uint32;          -- DWARF 5
151      Directories                  : SOR.Offset;
152      File_Name_Entry_Format_Count : SOR.uint8;           -- DWARF 5
153      File_Name_Entry_Format       : Entry_Format_Array;  -- DWARF 5
154      File_Names_Count             : SOR.uint32;          -- DWARF 5
155      File_Names                   : SOR.Offset;
156      Is64                         : Boolean;             -- local
157   end record;
158
159   type Search_Entry is record
160      First : SOR.uint32;
161      Size  : SOR.uint32;
162      --  Function bounds as offset to the base address.
163
164      Sym : SOR.uint32;
165      --  Symbol offset to get the name.
166
167      Line : SOR.uint32;
168      --  Dwarf line offset.
169   end record;
170
171   type Search_Array is array (Natural range <>) of Search_Entry;
172
173   type Search_Array_Access is access Search_Array;
174
175   type Dwarf_Context (In_Exception : Boolean := False) is record
176      Low, High : Address;
177      --  Address bounds for executable code
178
179      Obj : SOR.Object_File_Access;
180      --  The object file containing dwarf sections
181
182      Load_Address : Address := Null_Address;
183      --  The address at which the object file was loaded at run time
184
185      Has_Debug : Boolean;
186      --  True if all debug sections are available
187
188      Cache : Search_Array_Access;
189      --  Quick access to symbol and debug info (when present).
190
191      Abbrev   : SOR.Mapped_Stream;
192      Aranges  : SOR.Mapped_Stream;
193      Info     : SOR.Mapped_Stream;
194      Lines    : SOR.Mapped_Stream;
195      Line_Str : SOR.Mapped_Stream;  -- DWARF 5
196      --  DWARF sections
197
198      Header      : Line_Info_Header;
199      Registers   : Line_Info_Registers;
200      Next_Header : SOR.Offset;
201      --  State for lines
202   end record;
203
204end System.Dwarf_Lines;
205