import less(1)
[unleashed/tickless.git] / usr / src / lib / libdwarf / common / dwarf_frame.h
blobceb686335bf411cf9890d361d8b4ee30b6ef8eac
1 /*
3 Copyright (C) 2000, 2004, 2006 Silicon Graphics, Inc. All Rights Reserved.
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.
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.
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.
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.
25 Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane,
26 Mountain View, CA 94043, or:
28 http://www.sgi.com
30 For further information regarding this notice, see:
32 http://oss.sgi.com/projects/GenInfo/NoticeExplan
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
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).
66 * Handling of cie augmentation strings is necessarly a heuristic.
67 * See dwarf_frame.c for the currently known augmentation strings.
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).
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
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
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"
99 /* The value of the offset field for Cie's. */
100 #define DW_CIE_OFFSET ~(0x0)
102 /* The augmentation string may be NULL. */
103 #define DW_EMPTY_STRING ""
105 #define DW_FRAME_INSTR_OPCODE_SHIFT 6
106 #define DW_FRAME_INSTR_OFFSET_MASK 0x3f
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.
113 struct Dwarf_Reg_Rule_s {
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'.
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.
130 Dwarf_Sbyte ru_is_off;
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;
139 /* Register involved in this rule. */
140 Dwarf_Half ru_register;
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;
148 /* For DW_EXPR_EXPRESSION DW_EXPR_VAL_EXPRESSION these is set,
149 else 0. */
150 Dwarf_Small *ru_block;
153 typedef struct Dwarf_Frame_s *Dwarf_Frame;
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.
160 Entry DW_FRAME_CFA_COL of fr_reg was the tradional MIPS
161 way of setting CFA. cfa_rule is the new one.
163 struct Dwarf_Frame_s {
165 /* Pc value corresponding to this row of the frame table. */
166 Dwarf_Addr fr_loc;
168 /* Rules for all the registers in this row. */
169 struct Dwarf_Reg_Rule_s fr_cfa_rule;
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;
176 Dwarf_Frame fr_next;
179 typedef struct Dwarf_Frame_Op_List_s *Dwarf_Frame_Op_List;
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;
187 /* See dwarf_frame.c for the heuristics used to set the
188 Dwarf_Cie ci_augmentation_type.
190 This succinctly helps interpret the size and meaning of .debug_frame
191 and (for gcc) .eh_frame.
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.
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
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.
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;
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;
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;
259 /* If 'P' augmentation present, is handler addr. Else
260 is zero. */
261 Dwarf_Addr ci_gnu_personality_handler_addr;
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;
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.
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;
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;
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. */
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;
326 _dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist,
327 Dwarf_Off ** offsetlist,
328 Dwarf_Signed * returncount,
329 Dwarf_Error * err);
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);
345 enum Dwarf_augmentation_type
346 _dwarf_get_augmentation_type(Dwarf_Debug dbg,
347 Dwarf_Small *augmentation_string,
348 int is_gcc_eh_frame);
350 Dwarf_Unsigned _dwarf_get_return_address_reg(Dwarf_Small *frame_ptr,
351 int version,
352 unsigned long *size);
354 /* Temporary recording of crucial cie/fde prefix data.
355 * Vastly simplifies some argument lists.
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. */
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;
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);
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);
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);
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);
420 int _dwarf_frame_constructor(Dwarf_Debug dbg,void * );
421 void _dwarf_frame_destructor (void *);