xref: /titanic_44/usr/src/tools/ctf/dwarf/common/dwarf_frame.h (revision ed22c7109fc5dd9e1b7a5d0333bdc7ad2718e2ab)
1 /*
2 
3   Copyright (C) 2000 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., 59 Temple Place - Suite 330, Boston MA 02111-1307,
23   USA.
24 
25   Contact information:  Silicon Graphics, Inc., 1600 Amphitheatre Pky,
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  * This implementation of libdwarf will assume that the length of
66  * augmented fields follow the augmenter string when the augmentation
67  * starts with the string "z". It will skip over any augmented fields
68  * that it does not understand to the start of  initial instructions
69  * (in case of CIE) or the instruction table (in case of FDE).
70  *
71  * Future sgi versions of cie or fde should use "z1", "z2" as the
72  * augmenter strings and it should guarantee that all the above fields
73  * are laid out in the same fashion. Older libraries will continue to be able
74  * to read all the old data, skipping over newly added data items.
75  *
76  * The fde's augmented by the string "z" have a new field (signed constant, 4
77    byte field)
78  * called offset_into_exception_tables, following the length_of_augmented field.
79  * This field contains an offset into the "_MIPS_eh_region", which describes
80  * the exception handling tables.
81  */
82 
83 #define DW_DEBUG_FRAME_VERSION                 	1
84 #define DW_DEBUG_FRAME_AUGMENTER_STRING     	"mti v1"
85 
86 /* The value of the offset field for Cie's. */
87 #define DW_CIE_OFFSET		~(0x0)
88 
89 /* The augmentation string may be NULL.	*/
90 #define DW_EMPTY_STRING		""
91 
92 #define DW_FRAME_INSTR_OPCODE_SHIFT		6
93 #define DW_FRAME_INSTR_OFFSET_MASK		0x3f
94 
95 /*
96     This struct denotes the rule for a register in a row of
97     the frame table.  In other words, it is one element of
98     the table.
99 */
100 struct Dwarf_Reg_Rule_s {
101 
102     /*
103        Is a flag indicating whether the rule includes the offset
104        field, ie whether the ru_offset field is valid or not. It is
105        important, since reg+offset (offset of 0) is different from
106        just 'register' since the former means 'read memory at address
107        given by the sum of register contents plus offset to get the
108        value'. whereas the latter means 'the value is in the register'.
109 
110        The 'register' numbers are either real registers (ie, table
111        columns defined as real registers) or defined entries that are
112        not really hardware registers, such as DW_FRAME_SAME_VAL or
113        DW_FRAME_CFA_COL.
114 
115      */
116     Dwarf_Sbyte ru_is_off;
117 
118     /* Register involved in this rule. */
119     Dwarf_Half ru_register;
120 
121     /* Offset to add to register, if indicated by ru_is_offset. */
122     Dwarf_Addr ru_offset;
123 };
124 
125 typedef struct Dwarf_Frame_s *Dwarf_Frame;
126 
127 /*
128     This structure represents a row of the frame table.
129     Fr_loc is the pc value for this row, and Fr_reg
130     contains the rule for each column.
131 */
132 struct Dwarf_Frame_s {
133 
134     /* Pc value corresponding to this row of the frame table. */
135     Dwarf_Addr fr_loc;
136 
137     /* Rules for all the registers in this row. */
138     struct Dwarf_Reg_Rule_s fr_reg[DW_FRAME_LAST_REG_NUM];
139 
140     Dwarf_Frame fr_next;
141 };
142 
143 typedef struct Dwarf_Frame_Op_List_s *Dwarf_Frame_Op_List;
144 
145 /* This is used to chain together Dwarf_Frame_Op structures. */
146 struct Dwarf_Frame_Op_List_s {
147     Dwarf_Frame_Op *fl_frame_instr;
148     Dwarf_Frame_Op_List fl_next;
149 };
150 
151 /*
152     This structure contains all the pertinent info for a Cie. Most
153     of the fields are taken straight from the definition of a Cie.
154     Ci_cie_start points to the address (in .debug_frame) where this
155     Cie begins.  Ci_cie_instr_start points to the first byte of the
156     frame instructions for this Cie.  Ci_dbg points to the associated
157     Dwarf_Debug structure.  Ci_initial_table is a pointer to the table
158     row generated by the instructions for this Cie.
159 */
160 struct Dwarf_Cie_s {
161     Dwarf_Word ci_length;
162     char *ci_augmentation;
163     Dwarf_Small ci_code_alignment_factor;
164     Dwarf_Sbyte ci_data_alignment_factor;
165     Dwarf_Small ci_return_address_register;
166     Dwarf_Small *ci_cie_start;
167     Dwarf_Small *ci_cie_instr_start;
168     Dwarf_Debug ci_dbg;
169     Dwarf_Frame ci_initial_table;
170     Dwarf_Cie ci_next;
171     Dwarf_Small ci_length_size;
172     Dwarf_Small ci_extension_size;
173 };
174 
175 /*
176 	This structure contains all the pertinent info for a Fde.
177 	Most of the fields are taken straight from the definition.
178 	fd_cie_index is the index of the Cie associated with this
179 	Fde in the list of Cie's for this debug_frame.  Fd_cie
180 	points to the corresponsing Dwarf_Cie structure.  Fd_fde_start
181 	points to the start address of the Fde.  Fd_fde_instr_start
182 	points to the start of the instructions for this Fde.  Fd_dbg
183 	points to the associated Dwarf_Debug structure.
184 */
185 struct Dwarf_Fde_s {
186     Dwarf_Word fd_length;
187     Dwarf_Addr fd_cie_offset;
188     Dwarf_Sword fd_cie_index;
189     Dwarf_Cie fd_cie;
190     Dwarf_Addr fd_initial_location;
191     Dwarf_Small *fd_initial_loc_pos;
192     Dwarf_Addr fd_address_range;
193     Dwarf_Small *fd_fde_start;
194     Dwarf_Small *fd_fde_instr_start;
195     Dwarf_Debug fd_dbg;
196     Dwarf_Signed fd_offset_into_exception_tables;
197     Dwarf_Fde fd_next;
198     Dwarf_Small fd_length_size;
199     Dwarf_Small fd_extension_size;
200 };
201 
202 
203 int
204   _dwarf_frame_address_offsets(Dwarf_Debug dbg, Dwarf_Addr ** addrlist,
205 			       Dwarf_Off ** offsetlist,
206 			       Dwarf_Signed * returncount,
207 			       Dwarf_Error * err);
208