xref: /illumos-gate/usr/src/lib/libdwarf/common/dwarf_frame.h (revision 66582b606a8194f7f3ba5b3a3a6dca5b0d346361)
1 /*
2 
3   Copyright (C) 2000, 2004, 2006 Silicon Graphics, Inc.  All Rights Reserved.
4 
5   This program is free software; you can redistribute it and/or modify it
6   under the terms of version 2.1 of the GNU Lesser General Public License
7   as published by the Free Software Foundation.
8 
9   This program is distributed in the hope that it would be useful, but
10   WITHOUT ANY WARRANTY; without even the implied warranty of
11   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
12 
13   Further, this software is distributed without any warranty that it is
14   free of the rightful claim of any third person regarding infringement
15   or the like.  Any license provided herein, whether implied or
16   otherwise, applies only to this software file.  Patent licenses, if
17   any, provided herein do not apply to combinations of this program with
18   other software, or any other product whatsoever.
19 
20   You should have received a copy of the GNU Lesser General Public
21   License along with this program; if not, write the Free Software
22   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
23   USA.
24 
25   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
26   Mountain View, CA 94043, or:
27 
28   http://www.sgi.com
29 
30   For further information regarding this notice, see:
31 
32   http://oss.sgi.com/projects/GenInfo/NoticeExplan
33 
34 */
35 
36 
37 
38 /* The dwarf 2.0 standard dictates that only the following
39  * fields can be read when an unexpected augmentation string
40  * (in the cie) is encountered: CIE length, CIE_id, version and
41  * augmentation; FDE: length, CIE pointer, initial location and
42  * address range. Unfortunately, with the above restrictions, it
43  * is impossible to read the instruction table from a CIE or a FDE
44  * when a new augmentation string is encountered.
45  * To fix this problem, the following layout is used, if the
46  * augmentation string starts with the string "z".
47  *   CIE                        FDE
48  *   length                     length
49  *   CIE_id                     CIE_pointer
50  *   version                    initial_location
51  *   augmentation               address_range
52  *                              length_of_augmented_fields (*NEW*)
53  *   code_alignment_factor      Any new fields as necessary
54  *   data_alignment_factor      instruction_table
55  *   return_address
56  *   length_of_augmented fields
57  *   Any new fields as necessary
58  *   initial_instructions
59  *
60  * The type of all the old data items are the same as what is
61  * described in dwarf 2.0 standard. The length_of_augmented_fields
62  * is an LEB128 data item that denotes the size (in bytes) of
63  * the augmented fields (not including the size of
64  * "length_of_augmented_fields" itself).
65 
66  * Handling of cie augmentation strings is necessarly a heuristic.
67  * See dwarf_frame.c for the currently known augmentation strings.
68 
69 
70    ---START SGI-ONLY COMMENT:
71  * SGI-IRIX versions of cie or fde  were intended to use "z1", "z2" as the
72  * augmenter strings if required for new augmentation.
73  * However, that never happened (as of March 2005).
74  *
75  * The fde's augmented by the string "z" have a new field
76  * (signed constant, 4 byte field)
77  * called offset_into_exception_tables, following the
78  * length_of_augmented field.   This field contains an offset
79  * into the "_MIPS_eh_region", which describes
80  * the IRIX CC exception handling tables.
81    ---END SGI-ONLY COMMENT
82 
83 
84  * GNU .eh_frame has an augmentation string of z[RLP]* (gcc 3.4)
85  * The similarity to IRIX 'z' (and proposed but never
86  * implemented IRIX z1, z2 etc) was confusing things.
87  * If the section is .eh_frame then 'z' means GNU exception
88  * information 'Augmentation Data' not IRIX 'z'.
89  * See The Linux Standard Base Core Specification version 3.0
90  */
91 
92 #define DW_DEBUG_FRAME_VERSION                 	1 /* DWARF2 */
93 #define DW_DEBUG_FRAME_VERSION3                	3 /* DWARF3 */
94 #define DW_DEBUG_FRAME_VERSION4                	4 /* DWARF4 */
95 /* The following is SGI/IRIX specific, and probably no longer
96    in use anywhere. */
97 #define DW_DEBUG_FRAME_AUGMENTER_STRING     	"mti v1"
98 
99 /* The value of the offset field for Cie's. */
100 #define DW_CIE_OFFSET		~(0x0)
101 
102 /* The augmentation string may be NULL.	*/
103 #define DW_EMPTY_STRING		""
104 
105 #define DW_FRAME_INSTR_OPCODE_SHIFT		6
106 #define DW_FRAME_INSTR_OFFSET_MASK		0x3f
107 
108 /*
109     This struct denotes the rule for a register in a row of
110     the frame table.  In other words, it is one element of
111     the table.
112 */
113 struct Dwarf_Reg_Rule_s {
114 
115     /*
116        Is a flag indicating whether the rule includes the offset
117        field, ie whether the ru_offset field is valid or not.
118        Applies only if DW_EXPR_OFFSET or DW_EXPR_VAL_OFFSET.
119        It is important, since reg+offset (offset of 0) is different from
120        just 'register' since the former means 'read memory at address
121        given by the sum of register contents plus offset to get the
122        value'. whereas the latter means 'the value is in the register'.
123 
124        The 'register' numbers are either real registers (ie, table
125        columns defined as real registers) or defined entries that are
126        not really hardware registers, such as DW_FRAME_SAME_VAL or
127        DW_FRAME_CFA_COL.
128 
129      */
130     Dwarf_Sbyte ru_is_off;
131 
132     /* DW_EXPR_OFFSET (0, DWARF2)
133        DW_EXPR_VAL_OFFSET 1 (dwarf2/3)
134        DW_EXPR_EXPRESSION 2  (dwarf2/3)
135 	DW_EXPR_VAL_EXPRESSION 3 (dwarf2/3)
136        See dwarf_frame.h. */
137     Dwarf_Sbyte ru_value_type;
138 
139     /* Register involved in this rule. */
140     Dwarf_Half ru_register;
141 
142     /* Offset to add to register, if indicated by ru_is_offset
143        and if DW_EXPR_OFFSET or DW_EXPR_VAL_OFFSET.
144        If DW_EXPR_EXPRESSION or DW_EXPR_VAL_EXPRESSION
145        this is DW_FORM_block block-length, not offset. */
146     Dwarf_Unsigned ru_offset_or_block_len;
147 
148     /* For DW_EXPR_EXPRESSION DW_EXPR_VAL_EXPRESSION these is set,
149        else 0. */
150     Dwarf_Small *ru_block;
151 };
152 
153 typedef struct Dwarf_Frame_s *Dwarf_Frame;
154 
155 /*
156     This structure represents a row of the frame table.
157     Fr_loc is the pc value for this row, and Fr_reg
158     contains the rule for each column.
159 
160     Entry DW_FRAME_CFA_COL of fr_reg was the tradional MIPS
161     way of setting CFA.  cfa_rule is the new one.
162 */
163 struct Dwarf_Frame_s {
164 
165     /* Pc value corresponding to this row of the frame table. */
166     Dwarf_Addr fr_loc;
167 
168     /* Rules for all the registers in this row. */
169     struct Dwarf_Reg_Rule_s fr_cfa_rule;
170 
171 	/* fr_reg_count is the the number of
172 	entries of the fr_reg array. */
173     unsigned long            fr_reg_count;
174     struct Dwarf_Reg_Rule_s *fr_reg;
175 
176     Dwarf_Frame fr_next;
177 };
178 
179 typedef struct Dwarf_Frame_Op_List_s *Dwarf_Frame_Op_List;
180 
181 /* This is used to chain together Dwarf_Frame_Op structures. */
182 struct Dwarf_Frame_Op_List_s {
183     Dwarf_Frame_Op *fl_frame_instr;
184     Dwarf_Frame_Op_List fl_next;
185 };
186 
187 /* See dwarf_frame.c for the heuristics used to set the
188    Dwarf_Cie ci_augmentation_type.
189 
190    This succinctly helps interpret the size and meaning of .debug_frame
191    and (for gcc) .eh_frame.
192 
193    In the case of gcc .eh_frame (gcc 3.3, 3.4)
194    z may be followed by one or more of
195    L R P.
196 
197 */
198 enum Dwarf_augmentation_type {
199         aug_empty_string, /* Default empty augmentation string.  */
200         aug_irix_exception_table,  /* IRIX  plain  "z",
201                    for exception handling, IRIX CC compiler.
202 		   Proposed z1 z2 ... never implemented.  */
203         aug_gcc_eh_z,       /* gcc z augmentation,  (including
204 			L R P variations). gcc 3.3 3.4 exception
205 			handling in eh_frame.  */
206         aug_irix_mti_v1,  /* IRIX "mti v1" augmentation string. Probably
207                              never in any released SGI-IRIX compiler. */
208         aug_eh,           /* For gcc .eh_frame, "eh" is the string.,
209 				gcc 1,2, egcs. Older values.  */
210         aug_armcc,  /* "armcc+" meaning the  cfa calculation
211                     is corrected to be standard (output by
212                     Arm C RVCT 3.0 SP1 and later). See
213                     http://sourceware.org/ml/gdb-patches/2006-12/msg00249.html
214                     for details. */
215         aug_unknown,      /* Unknown augmentation, we cannot do much. */
216         aug_past_last
217 };
218 
219 
220 /*
221     This structure contains all the pertinent info for a Cie. Most
222     of the fields are taken straight from the definition of a Cie.
223     Ci_cie_start points to the address (in .debug_frame) where this
224     Cie begins.  Ci_cie_instr_start points to the first byte of the
225     frame instructions for this Cie.  Ci_dbg points to the associated
226     Dwarf_Debug structure.  Ci_initial_table is a pointer to the table
227     row generated by the instructions for this Cie.
228 */
229 struct Dwarf_Cie_s {
230     Dwarf_Unsigned ci_length;
231     char *ci_augmentation;
232     Dwarf_Small ci_code_alignment_factor;
233     Dwarf_Sbyte ci_data_alignment_factor;
234     Dwarf_Small ci_return_address_register;
235     Dwarf_Small *ci_cie_start;
236     Dwarf_Small *ci_cie_instr_start;
237     Dwarf_Debug ci_dbg;
238     Dwarf_Frame ci_initial_table;
239     Dwarf_Cie ci_next;
240     Dwarf_Small ci_length_size;
241     Dwarf_Small ci_extension_size;
242     Dwarf_Half ci_cie_version_number;
243     enum Dwarf_augmentation_type ci_augmentation_type;
244 
245     /* The following 2 for GNU .eh_frame exception handling
246        Augmentation Data. Set if ci_augmentation_type
247        is aug_gcc_eh_z. Zero if unused. */
248     Dwarf_Unsigned ci_gnu_eh_augmentation_len;
249     Dwarf_Ptr      ci_gnu_eh_augmentation_bytes;
250 
251     /* These are extracted from the gnu eh_frame
252        augmentation if the
253        augmentation begins with 'z'. See Linux LSB documents.
254        Otherwize these are zero. */
255     unsigned char    ci_gnu_personality_handler_encoding;
256     unsigned char    ci_gnu_lsda_encoding;
257     unsigned char    ci_gnu_fde_begin_encoding;
258 
259     /* If 'P' augmentation present, is handler addr. Else
260 	is zero. */
261     Dwarf_Addr     ci_gnu_personality_handler_addr;
262 
263 
264     /* In creating list of cie's (which will become an array)
265        record the position so fde can get it on fde creation. */
266     Dwarf_Unsigned ci_index;
267     Dwarf_Small *  ci_section_ptr;
268     /* DWARF4 adds address size and segment size to the CIE: the .debug_info
269        section may not always be present to allow libdwarf to
270        find address_size from the compilation-unit. */
271     Dwarf_Half   ci_address_size;
272     Dwarf_Half   ci_segment_size;
273 
274 };
275 
276 /*
277 	This structure contains all the pertinent info for a Fde.
278 	Most of the fields are taken straight from the definition.
279 	fd_cie_index is the index of the Cie associated with this
280 	Fde in the list of Cie's for this debug_frame.  Fd_cie
281 	points to the corresponsing Dwarf_Cie structure.  Fd_fde_start
282 	points to the start address of the Fde.  Fd_fde_instr_start
283 	points to the start of the instructions for this Fde.  Fd_dbg
284 	points to the associated Dwarf_Debug structure.
285 */
286 struct Dwarf_Fde_s {
287     Dwarf_Unsigned fd_length;
288     Dwarf_Addr fd_cie_offset;
289     Dwarf_Unsigned fd_cie_index;
290     Dwarf_Cie fd_cie;
291     Dwarf_Addr fd_initial_location;
292     Dwarf_Small *fd_initial_loc_pos;
293     Dwarf_Addr fd_address_range;
294     Dwarf_Small *fd_fde_start;
295     Dwarf_Small *fd_fde_instr_start;
296     Dwarf_Debug fd_dbg;
297 
298 	/* fd_offset_into_exception_tables is SGI/IRIX exception table
299 	   offset. Unused and zero if not IRIX .debug_frame. */
300     Dwarf_Signed fd_offset_into_exception_tables;
301 
302     Dwarf_Fde fd_next;
303     Dwarf_Small fd_length_size;
304     Dwarf_Small fd_extension_size;
305     /* So we know from an fde which 'count' of fde-s in
306        Dwarf_Debug applies:  eh or standard. */
307     Dwarf_Small fd_is_eh;
308     /* The following 2 for GNU .eh_frame exception handling
309        Augmentation Data. Set if CIE ci_augmentation_type
310        is aug_gcc_eh_z. Zero if unused. */
311     Dwarf_Unsigned fd_gnu_eh_augmentation_len;
312     Dwarf_Ptr fd_gnu_eh_augmentation_bytes;
313     Dwarf_Addr fd_gnu_eh_lsda; /* If 'L' augmentation letter
314          present:  is address of the
315          Language Specific Data Area (LSDA). If not 'L" is zero. */
316 
317     /* The following 3 are about the Elf section the FDEs come from. */
318     Dwarf_Small * fd_section_ptr;
319     Dwarf_Unsigned fd_section_length;
320     Dwarf_Unsigned fd_section_index;
321 
322 };
323 
324 
325 int
326   _dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist,
327 			       Dwarf_Off ** offsetlist,
328 			       Dwarf_Signed * returncount,
329 			       Dwarf_Error * err);
330 
331 int
332 _dwarf_get_fde_list_internal(Dwarf_Debug dbg,
333                               Dwarf_Cie ** cie_data,
334                               Dwarf_Signed * cie_element_count,
335                               Dwarf_Fde ** fde_data,
336                               Dwarf_Signed * fde_element_count,
337                               Dwarf_Small * section_ptr,
338                               Dwarf_Unsigned section_index,
339                               Dwarf_Unsigned section_length,
340                               Dwarf_Unsigned cie_id_value,
341                               int use_gnu_cie_calc,  /* If non-zero,
342                                 this is gcc eh_frame. */
343                               Dwarf_Error * error);
344 
345 enum Dwarf_augmentation_type
346 _dwarf_get_augmentation_type(Dwarf_Debug dbg,
347         Dwarf_Small *augmentation_string,
348         int is_gcc_eh_frame);
349 
350 Dwarf_Unsigned _dwarf_get_return_address_reg(Dwarf_Small *frame_ptr,
351                         int version,
352                         unsigned long *size);
353 
354 /* Temporary recording of crucial cie/fde prefix data.
355  * Vastly simplifies some argument lists.
356  */
357 struct cie_fde_prefix_s {
358    /* cf_start_addr is a pointer to the first byte of this fde/cie
359       we are reading now. */
360    Dwarf_Small *  cf_start_addr;
361    Dwarf_Small *  cf_addr_after_prefix;
362    Dwarf_Unsigned cf_length;
363    int            cf_local_length_size;
364    int            cf_local_extension_size;
365    Dwarf_Unsigned cf_cie_id;
366    Dwarf_Small *  cf_cie_id_addr; /* used for eh_frame calculations. */
367 
368    /* Simplifies passing around these values to create fde having
369       these here. */
370    /* cf_section_ptr is a pointer to the first byte
371       of the object section the prefix is read from.  */
372    Dwarf_Small *  cf_section_ptr;
373    Dwarf_Unsigned cf_section_index;
374    Dwarf_Unsigned cf_section_length;
375 };
376 
377 int
378 _dwarf_exec_frame_instr(Dwarf_Bool make_instr,
379                         Dwarf_Frame_Op ** ret_frame_instr,
380                         Dwarf_Bool search_pc,
381                         Dwarf_Addr search_pc_val,
382                         Dwarf_Addr initial_loc,
383                         Dwarf_Small * start_instr_ptr,
384                         Dwarf_Small * final_instr_ptr,
385                         Dwarf_Frame table,
386                         Dwarf_Cie cie,
387                         Dwarf_Debug dbg,
388 			Dwarf_Half reg_num_of_cfa,
389                         Dwarf_Sword * returned_count,
390                         int *returned_error);
391 
392 
393 int dwarf_read_cie_fde_prefix(Dwarf_Debug dbg,
394         Dwarf_Small *frame_ptr_in,
395         Dwarf_Small *section_ptr_in,
396         Dwarf_Unsigned section_index_in,
397 	Dwarf_Unsigned section_length_in,
398         struct cie_fde_prefix_s *prefix_out,
399         Dwarf_Error *error);
400 
401 int dwarf_create_fde_from_after_start(Dwarf_Debug dbg,
402         struct cie_fde_prefix_s *  prefix,
403         Dwarf_Small *section_pointer,
404         Dwarf_Small *frame_ptr,
405         int use_gnu_cie_calc,
406         Dwarf_Cie  cie_ptr_in,
407         Dwarf_Fde *fde_ptr_out,
408         Dwarf_Error *error);
409 
410 int dwarf_create_cie_from_after_start(Dwarf_Debug dbg,
411         struct cie_fde_prefix_s *prefix,
412         Dwarf_Small* section_pointer,
413         Dwarf_Small* frame_ptr,
414         Dwarf_Unsigned cie_count,
415         int use_gnu_cie_calc,
416         Dwarf_Cie *cie_ptr_out,
417         Dwarf_Error *error);
418 
419 
420 int _dwarf_frame_constructor(Dwarf_Debug dbg,void * );
421 void _dwarf_frame_destructor (void *);
422