xref: /illumos-gate/usr/src/lib/libdwarf/common/dwarf_line.h (revision 66582b606a8194f7f3ba5b3a3a6dca5b0d346361)
1 /*
2 
3   Copyright (C) 2000, 2004, 2006 Silicon Graphics, Inc.  All Rights Reserved.
4   Portions Copyright (C) 2009-2010 David Anderson. All Rights Reserved.
5 
6   This program is free software; you can redistribute it and/or modify it
7   under the terms of version 2.1 of the GNU Lesser General Public License
8   as published by the Free Software Foundation.
9 
10   This program is distributed in the hope that it would be useful, but
11   WITHOUT ANY WARRANTY; without even the implied warranty of
12   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13 
14   Further, this software is distributed without any warranty that it is
15   free of the rightful claim of any third person regarding infringement
16   or the like.  Any license provided herein, whether implied or
17   otherwise, applies only to this software file.  Patent licenses, if
18   any, provided herein do not apply to combinations of this program with
19   other software, or any other product whatsoever.
20 
21   You should have received a copy of the GNU Lesser General Public
22   License along with this program; if not, write the Free Software
23   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24   USA.
25 
26   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
27   Mountain View, CA 94043, or:
28 
29   http://www.sgi.com
30 
31   For further information regarding this notice, see:
32 
33   http://oss.sgi.com/projects/GenInfo/NoticeExplan
34 
35 */
36 
37 
38 
39 #define DW_EXTENDED_OPCODE	0
40 
41 /*
42     This is used as the starting value for an algorithm
43     to get the minimum difference between 2 values.
44     UINT_MAX is used as our approximation to infinity.
45 */
46 #define MAX_LINE_DIFF       UINT_MAX
47 
48 /* This is for a sanity check on line
49    table extended opcodes.
50    It is entirely arbitrary, and 100 is surely too small if
51    someone was inserting strings in the opcode. */
52 #define DW_LNE_LEN_MAX   100
53 
54 
55 /*
56     This structure is used to build a list of all the
57     files that are used in the current compilation unit.
58     All of the fields execpt fi_next have meanings that
59     are obvious from section 6.2.4 of the Libdwarf Doc.
60 */
61 struct Dwarf_File_Entry_s {
62     /* Points to string naming the file. */
63     Dwarf_Small *fi_file_name;
64 
65     /*
66        Index into the list of directories of the directory in which
67        this file exits. */
68     Dwarf_Sword fi_dir_index;
69 
70     /* Time of last modification of the file. */
71     Dwarf_Unsigned fi_time_last_mod;
72 
73     /* Length in bytes of the file. */
74     Dwarf_Unsigned fi_file_length;
75 
76     /* Pointer for chaining file entries. */
77     Dwarf_File_Entry fi_next;
78 };
79 
80 
81 typedef struct Dwarf_Line_Context_s *Dwarf_Line_Context;
82 
83 /*
84     This structure provides the context in which the fields of
85     a Dwarf_Line structure are interpreted.  They come from the
86     statement program prologue.  **Updated by dwarf_srclines in
87     dwarf_line.c.
88 */
89 struct Dwarf_Line_Context_s {
90     /*
91        Points to a chain of entries providing info about source files
92        for the current set of Dwarf_Line structures. File number
93        'li_file 1' is last on the list, the first list entry is the
94        file numbered lc_file_entry_count. The numbering of the file
95        names matches the dwarf2/3 line table specification file table
96        and DW_LNE_define_file numbering rules.  */
97     Dwarf_File_Entry lc_file_entries;
98     /*
99        Count of number of source files for this set of Dwarf_Line
100        structures. */
101     Dwarf_Sword lc_file_entry_count;
102     /*
103        Points to the portion of .debug_line section that contains a
104        list of strings naming the included directories. */
105     Dwarf_Small *lc_include_directories;
106 
107     /* Count of the number of included directories. */
108     Dwarf_Sword lc_include_directories_count;
109 
110     /* Count of the number of lines for this cu. */
111     Dwarf_Sword lc_line_count;
112 
113     /* Points to name of compilation directory. */
114     Dwarf_Small *lc_compilation_directory;
115 
116     Dwarf_Debug lc_dbg;
117 
118     Dwarf_Half lc_version_number;	/* DWARF2/3 version number, 2
119 					   for DWARF2, 3 for DWARF3. */
120 };
121 
122 
123 /*
124     This structure defines a row of the line table.
125     All of the fields except li_offset have the exact
126     same meaning that is defined in Section 6.2.2
127     of the Libdwarf Document.
128 
129     li_offset is used by _dwarf_addr_finder() which is called
130     by rqs(1), an sgi utility for 'moving' shared libraries
131     as if the static linker (ld) had linked the shared library
132     at the newly-specified address.  Most libdwarf-using
133     apps will ignore li_offset and _dwarf_addr_finder().
134 
135 */
136 struct Dwarf_Line_s {
137     Dwarf_Addr li_address;	/* pc value of machine instr */
138     union addr_or_line_s {
139 	struct li_inner_s {
140 	    Dwarf_Sword li_file;	/* int identifying src file */
141 	    /* li_file is a number 1-N, indexing into a conceptual
142 	       source file table as described in dwarf2/3 spec line
143 	       table doc. (see Dwarf_File_Entry lc_file_entries; and
144 	       Dwarf_Sword lc_file_entry_count;) */
145 
146 	    Dwarf_Sword li_line;	/* source file line number. */
147 	    Dwarf_Half li_column;	/* source file column number */
148 	    Dwarf_Small li_isa;
149 
150 	    /* To save space, use bit flags. */
151 	    /* indicate start of stmt */
152 	    unsigned char li_is_stmt:1;
153 
154 	    /* indicate start basic block */
155 	    unsigned char li_basic_block:1;
156 
157 	    /* first post sequence instr */
158 	    unsigned char li_end_sequence:1;
159 
160 	    unsigned char li_prologue_end:1;
161 	    unsigned char li_epilogue_begin:1;
162 	} li_l_data;
163 	Dwarf_Off li_offset;	/* for rqs */
164     } li_addr_line;
165     Dwarf_Line_Context li_context;	/* assoc Dwarf_Line_Context_s */
166 };
167 
168 
169 int _dwarf_line_address_offsets(Dwarf_Debug dbg,
170 				Dwarf_Die die,
171 				Dwarf_Addr ** addrs,
172 				Dwarf_Off ** offs,
173 				Dwarf_Unsigned * returncount,
174 				Dwarf_Error * err);
175 int _dwarf_internal_srclines(Dwarf_Die die,
176 			     Dwarf_Line ** linebuf,
177 			     Dwarf_Signed * count,
178 			     Dwarf_Bool doaddrs,
179 			     Dwarf_Bool dolines, Dwarf_Error * error);
180 
181 
182 
183 /* The LOP, WHAT_IS_OPCODE stuff is here so it can
184    be reused in 3 places.  Seemed hard to keep
185    the 3 places the same without an inline func or
186    a macro.
187 
188    Handling the line section where the header and the
189    file being processed do not match (unusual, but
190    planned for in the  design of .debug_line)
191    is too tricky to recode this several times and keep
192    it right.
193 
194    As it is the code starting up line-reading is duplicated
195    and that is just wrong to do. FIXME!
196 */
197 #define LOP_EXTENDED 1
198 #define LOP_DISCARD  2
199 #define LOP_STANDARD 3
200 #define LOP_SPECIAL  4
201 
202 #define WHAT_IS_OPCODE(type,opcode,base,opcode_length,line_ptr,highest_std) \
203         if( (opcode) < (base) ) {                          \
204            /* we know we must treat as a standard op       \
205                 or a special case.                         \
206            */                                              \
207            if((opcode) == DW_EXTENDED_OPCODE) {            \
208                 type = LOP_EXTENDED;                       \
209            } else  if( ((highest_std)+1) >=  (base)) {     \
210                 /* == Standard case: compile of            \
211                    dwarf_line.c and object                 \
212                    have same standard op codes set.        \
213                                                            \
214                    >  Special case: compile of dwarf_line.c\
215                    has things in standard op codes list    \
216                    in dwarf.h header not                   \
217                    in the object: handle this as a standard\
218                    op code in switch below.                \
219                    The header special ops overlap the      \
220                    object standard ops.                    \
221                    The new standard op codes will not      \
222                    appear in the object.                   \
223                 */                                         \
224                 type = LOP_STANDARD;                       \
225            } else  {                                       \
226                 /* These are standard opcodes in the object\
227                 ** that were not defined  in the header    \
228                 ** at the time dwarf_line.c                \
229                 ** was compiled. Provides the ability of   \
230                 ** out-of-date dwarf reader to read newer  \
231                 ** line table data transparently.          \
232                 */                                         \
233                 type = LOP_DISCARD;                         \
234            }                                                \
235                                                             \
236         } else {                                            \
237 	   /* Is  a special op code.                        \
238 	   */                                               \
239            type =  LOP_SPECIAL;                             \
240         }
241 
242 /* The following is from  the dwarf definition of 'ubyte'
243    and is specifically  mentioned in section  6.2.5.1, page 54
244    of the Rev 2.0.0 dwarf specification.
245 */
246 
247 #define MAX_LINE_OP_CODE  255
248 
249 
250 /* The following structs (Line_Table_File_Entry_s,Line_Table_Prefix_s)
251    and functions allow refactoring common code into a single
252    reader routine.
253 */
254 /* There can be zero of more of these needed for 1 line prologue. */
255 struct Line_Table_File_Entry_s {
256     Dwarf_Small *lte_filename;
257     Dwarf_Unsigned lte_directory_index;
258     Dwarf_Unsigned lte_last_modification_time;
259     Dwarf_Unsigned lte_length_of_file;
260 };
261 
262 /* Data  picked up from the line table prologue for a single
263 CU. */
264 struct Line_Table_Prefix_s {
265 
266     /* pf_total_length is the value of the length field for the line
267        table of this CU. So it does not count the length of itself (the
268        length value) for consistency with the say lenghts recorded in
269        DWARF2/3. */
270     Dwarf_Unsigned pf_total_length;
271 
272     /* Length of the initial length field itself. */
273     Dwarf_Half pf_length_field_length;
274 
275     /* The version is 2 for DWARF2, 3 for DWARF3 */
276     Dwarf_Half pf_version;
277 
278     Dwarf_Unsigned pf_prologue_length;
279     Dwarf_Small pf_minimum_instruction_length;
280 
281     /* Start and end of this CU line area. pf_line_ptr_start +
282        pf_total_length + pf_length_field_length == pf_line_ptr_end.
283        Meaning pf_line_ptr_start is before the length info. */
284     Dwarf_Small *pf_line_ptr_start;
285     Dwarf_Small *pf_line_ptr_end;
286 
287     /* Used to check that decoding of the line prologue is done right. */
288     Dwarf_Small *pf_line_prologue_start;
289 
290     Dwarf_Small pf_default_is_stmt;
291     Dwarf_Sbyte pf_line_base;
292     Dwarf_Small pf_line_range;
293 
294     /* Highest std opcode (+1).  */
295     Dwarf_Small pf_opcode_base;
296 
297     /* pf_opcode_base -1 entries (each a count, normally the value of
298        each entry is 0 or 1). */
299     Dwarf_Small *pf_opcode_length_table;
300 
301     Dwarf_Unsigned pf_include_directories_count;
302     /* Array of pointers to dir strings. pf_include_directories_count
303        entriesin the array. */
304     Dwarf_Small **pf_include_directories;
305 
306     /* Count of entries in line_table_file_entries array. */
307     Dwarf_Unsigned pf_files_count;
308     struct Line_Table_File_Entry_s *pf_line_table_file_entries;
309 
310     /* The number to treat as standard ops. This is a special
311        accomodation of gcc using the new standard opcodes but not
312        updating the version number. It's legal dwarf2, but much better
313        for the user to understand as dwarf3 when 'it looks ok'. */
314     Dwarf_Bool pf_std_op_count;
315 
316 };
317 
318 void dwarf_init_line_table_prefix(struct Line_Table_Prefix_s *pf);
319 void dwarf_free_line_table_prefix(struct Line_Table_Prefix_s *pf);
320 
321 int dwarf_read_line_table_prefix(Dwarf_Debug dbg,
322     Dwarf_Small * data_start,
323     Dwarf_Unsigned data_length,
324     Dwarf_Small ** updated_data_start_out,
325     struct Line_Table_Prefix_s *prefix_out,
326     /* The following 2 arguments are solely for warning users
327      * when there is a surprising 'gap' in the .debug_line info. */
328     Dwarf_Small ** bogus_bytes_ptr,
329     Dwarf_Unsigned * bogus_bytes_count,
330     Dwarf_Error * err,
331     int * err_count_out);
332