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