xref: /titanic_51/usr/src/lib/libdwarf/common/dwarf_frame.c (revision 7fd791373689a6af05e27efec3b1ab556e02aa23)
1*7fd79137SRobert Mustacchi /*
2*7fd79137SRobert Mustacchi 
3*7fd79137SRobert Mustacchi   Copyright (C) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
4*7fd79137SRobert Mustacchi   Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
5*7fd79137SRobert Mustacchi 
6*7fd79137SRobert Mustacchi   This program is free software; you can redistribute it and/or modify it
7*7fd79137SRobert Mustacchi   under the terms of version 2.1 of the GNU Lesser General Public License
8*7fd79137SRobert Mustacchi   as published by the Free Software Foundation.
9*7fd79137SRobert Mustacchi 
10*7fd79137SRobert Mustacchi   This program is distributed in the hope that it would be useful, but
11*7fd79137SRobert Mustacchi   WITHOUT ANY WARRANTY; without even the implied warranty of
12*7fd79137SRobert Mustacchi   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
13*7fd79137SRobert Mustacchi 
14*7fd79137SRobert Mustacchi   Further, this software is distributed without any warranty that it is
15*7fd79137SRobert Mustacchi   free of the rightful claim of any third person regarding infringement
16*7fd79137SRobert Mustacchi   or the like.  Any license provided herein, whether implied or
17*7fd79137SRobert Mustacchi   otherwise, applies only to this software file.  Patent licenses, if
18*7fd79137SRobert Mustacchi   any, provided herein do not apply to combinations of this program with
19*7fd79137SRobert Mustacchi   other software, or any other product whatsoever.
20*7fd79137SRobert Mustacchi 
21*7fd79137SRobert Mustacchi   You should have received a copy of the GNU Lesser General Public
22*7fd79137SRobert Mustacchi   License along with this program; if not, write the Free Software
23*7fd79137SRobert Mustacchi   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
24*7fd79137SRobert Mustacchi   USA.
25*7fd79137SRobert Mustacchi 
26*7fd79137SRobert Mustacchi   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
27*7fd79137SRobert Mustacchi   Mountain View, CA 94043, or:
28*7fd79137SRobert Mustacchi 
29*7fd79137SRobert Mustacchi   http://www.sgi.com
30*7fd79137SRobert Mustacchi 
31*7fd79137SRobert Mustacchi   For further information regarding this notice, see:
32*7fd79137SRobert Mustacchi 
33*7fd79137SRobert Mustacchi   http://oss.sgi.com/projects/GenInfo/NoticeExplan
34*7fd79137SRobert Mustacchi 
35*7fd79137SRobert Mustacchi */
36*7fd79137SRobert Mustacchi /* The address of the Free Software Foundation is
37*7fd79137SRobert Mustacchi    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
38*7fd79137SRobert Mustacchi    Boston, MA 02110-1301, USA.
39*7fd79137SRobert Mustacchi    SGI has moved from the Crittenden Lane address.
40*7fd79137SRobert Mustacchi */
41*7fd79137SRobert Mustacchi 
42*7fd79137SRobert Mustacchi 
43*7fd79137SRobert Mustacchi 
44*7fd79137SRobert Mustacchi 
45*7fd79137SRobert Mustacchi 
46*7fd79137SRobert Mustacchi #include "config.h"
47*7fd79137SRobert Mustacchi #include "dwarf_incl.h"
48*7fd79137SRobert Mustacchi #include <stdio.h>
49*7fd79137SRobert Mustacchi #include <stdlib.h>
50*7fd79137SRobert Mustacchi #include <sys/types.h>
51*7fd79137SRobert Mustacchi #include "dwarf_frame.h"
52*7fd79137SRobert Mustacchi #include "dwarf_arange.h"       /* Using Arange as a way to build a
53*7fd79137SRobert Mustacchi                                    list */
54*7fd79137SRobert Mustacchi 
55*7fd79137SRobert Mustacchi #define FDE_NULL_CHECKS_AND_SET_DBG(fde,dbg )          \
56*7fd79137SRobert Mustacchi     do {                                               \
57*7fd79137SRobert Mustacchi      if ((fde) == NULL) {                              \
58*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_FDE_NULL);    \
59*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);                         \
60*7fd79137SRobert Mustacchi     }                                                  \
61*7fd79137SRobert Mustacchi     (dbg)= (fde)->fd_dbg;                              \
62*7fd79137SRobert Mustacchi     if ((dbg) == NULL) {                               \
63*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);\
64*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);                         \
65*7fd79137SRobert Mustacchi     } } while (0)
66*7fd79137SRobert Mustacchi 
67*7fd79137SRobert Mustacchi 
68*7fd79137SRobert Mustacchi #define MIN(a,b)  (((a) < (b))? a:b)
69*7fd79137SRobert Mustacchi 
70*7fd79137SRobert Mustacchi static void _dwarf_init_regrule_table(struct Dwarf_Reg_Rule_s *t1reg,
71*7fd79137SRobert Mustacchi                                       int last_reg_num,
72*7fd79137SRobert Mustacchi                                       int initial_value);
73*7fd79137SRobert Mustacchi static int dwarf_initialize_fde_table(Dwarf_Debug dbg,
74*7fd79137SRobert Mustacchi                                       struct Dwarf_Frame_s *fde_table,
75*7fd79137SRobert Mustacchi                                       unsigned table_real_data_size,
76*7fd79137SRobert Mustacchi                                       Dwarf_Error * error);
77*7fd79137SRobert Mustacchi static void dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table);
78*7fd79137SRobert Mustacchi 
79*7fd79137SRobert Mustacchi #if 0
80*7fd79137SRobert Mustacchi /* Only used for debugging libdwarf. */
81*7fd79137SRobert Mustacchi static void dump_frame_rule(char *msg,
82*7fd79137SRobert Mustacchi                             struct Dwarf_Reg_Rule_s *reg_rule);
83*7fd79137SRobert Mustacchi #endif
84*7fd79137SRobert Mustacchi 
85*7fd79137SRobert Mustacchi 
86*7fd79137SRobert Mustacchi 
87*7fd79137SRobert Mustacchi /*
88*7fd79137SRobert Mustacchi     This function is the heart of the debug_frame stuff.  Don't even
89*7fd79137SRobert Mustacchi     think of reading this without reading both the Libdwarf and
90*7fd79137SRobert Mustacchi     consumer API carefully first.  This function basically executes
91*7fd79137SRobert Mustacchi     frame instructions contained in a Cie or an Fde, but does in a
92*7fd79137SRobert Mustacchi     number of different ways depending on the information sought.
93*7fd79137SRobert Mustacchi     Start_instr_ptr points to the first byte of the frame instruction
94*7fd79137SRobert Mustacchi     stream, and final_instr_ptr to the to the first byte after the
95*7fd79137SRobert Mustacchi     last.
96*7fd79137SRobert Mustacchi 
97*7fd79137SRobert Mustacchi     The offsets returned in the frame instructions are factored.  That
98*7fd79137SRobert Mustacchi     is they need to be multiplied by either the code_alignment_factor
99*7fd79137SRobert Mustacchi     or the data_alignment_factor, as appropriate to obtain the actual
100*7fd79137SRobert Mustacchi     offset.  This makes it possible to expand an instruction stream
101*7fd79137SRobert Mustacchi     without the corresponding Cie.  However, when an Fde frame instr
102*7fd79137SRobert Mustacchi     sequence is being expanded there must be a valid Cie with a pointer
103*7fd79137SRobert Mustacchi     to an initial table row.
104*7fd79137SRobert Mustacchi 
105*7fd79137SRobert Mustacchi 
106*7fd79137SRobert Mustacchi     If successful, returns DW_DLV_OK
107*7fd79137SRobert Mustacchi                 And sets returned_count thru the pointer
108*7fd79137SRobert Mustacchi                  if make_instr is true.
109*7fd79137SRobert Mustacchi                 If make_instr is false returned_count
110*7fd79137SRobert Mustacchi                  should NOT be used by the caller (returned_count
111*7fd79137SRobert Mustacchi                  is set to 0 thru the pointer by this routine...)
112*7fd79137SRobert Mustacchi     If unsuccessful, returns DW_DLV_ERROR
113*7fd79137SRobert Mustacchi                 and sets returned_error to the error code
114*7fd79137SRobert Mustacchi 
115*7fd79137SRobert Mustacchi     It does not do a whole lot of input validation being a private
116*7fd79137SRobert Mustacchi     function.  Please make sure inputs are valid.
117*7fd79137SRobert Mustacchi 
118*7fd79137SRobert Mustacchi     (1) If make_instr is true, it makes a list of pointers to
119*7fd79137SRobert Mustacchi     Dwarf_Frame_Op structures containing the frame instructions
120*7fd79137SRobert Mustacchi     executed.  A pointer to this list is returned in ret_frame_instr.
121*7fd79137SRobert Mustacchi     Make_instr is true only when a list of frame instructions is to be
122*7fd79137SRobert Mustacchi     returned.  In this case since we are not interested in the contents
123*7fd79137SRobert Mustacchi     of the table, the input Cie can be NULL.  This is the only case
124*7fd79137SRobert Mustacchi     where the inpute Cie can be NULL.
125*7fd79137SRobert Mustacchi 
126*7fd79137SRobert Mustacchi     (2) If search_pc is true, frame instructions are executed till
127*7fd79137SRobert Mustacchi     either a location is reached that is greater than the search_pc_val
128*7fd79137SRobert Mustacchi     provided, or all instructions are executed.  At this point the
129*7fd79137SRobert Mustacchi     last row of the table generated is returned in a structure.
130*7fd79137SRobert Mustacchi     A pointer to this structure is supplied in table.
131*7fd79137SRobert Mustacchi 
132*7fd79137SRobert Mustacchi     (3) This function is also used to create the initial table row
133*7fd79137SRobert Mustacchi     defined by a Cie.  In this case, the Dwarf_Cie pointer cie, is
134*7fd79137SRobert Mustacchi     NULL.  For an FDE, however, cie points to the associated Cie.
135*7fd79137SRobert Mustacchi 
136*7fd79137SRobert Mustacchi     make_instr - make list of frame instr? 0/1
137*7fd79137SRobert Mustacchi     ret_frame_instr -  Ptr to list of ptrs to frame instrs
138*7fd79137SRobert Mustacchi     search_pc  - Search for a pc value?  0/1
139*7fd79137SRobert Mustacchi      search_pc_val -  Search for this pc value
140*7fd79137SRobert Mustacchi     initial_loc - Initial code location value.
141*7fd79137SRobert Mustacchi     start_instr_ptr -   Ptr to start of frame instrs.
142*7fd79137SRobert Mustacchi     final_instr_ptr -   Ptr just past frame instrs.
143*7fd79137SRobert Mustacchi     table       -     Ptr to struct with last row.
144*7fd79137SRobert Mustacchi     cie     -   Ptr to Cie used by the Fde.
145*7fd79137SRobert Mustacchi        Different cies may have distinct address-sizes, so the cie
146*7fd79137SRobert Mustacchi        is used, not de_pointer_size.
147*7fd79137SRobert Mustacchi 
148*7fd79137SRobert Mustacchi */
149*7fd79137SRobert Mustacchi 
150*7fd79137SRobert Mustacchi int
151*7fd79137SRobert Mustacchi _dwarf_exec_frame_instr(Dwarf_Bool make_instr,
152*7fd79137SRobert Mustacchi     Dwarf_Frame_Op ** ret_frame_instr,
153*7fd79137SRobert Mustacchi     Dwarf_Bool search_pc,
154*7fd79137SRobert Mustacchi     Dwarf_Addr search_pc_val,
155*7fd79137SRobert Mustacchi     Dwarf_Addr initial_loc,
156*7fd79137SRobert Mustacchi     Dwarf_Small * start_instr_ptr,
157*7fd79137SRobert Mustacchi     Dwarf_Small * final_instr_ptr,
158*7fd79137SRobert Mustacchi     Dwarf_Frame table,
159*7fd79137SRobert Mustacchi     Dwarf_Cie cie,
160*7fd79137SRobert Mustacchi     Dwarf_Debug dbg,
161*7fd79137SRobert Mustacchi     Dwarf_Half reg_num_of_cfa,
162*7fd79137SRobert Mustacchi     Dwarf_Sword * returned_count,
163*7fd79137SRobert Mustacchi     int *returned_error)
164*7fd79137SRobert Mustacchi {
165*7fd79137SRobert Mustacchi #define ERROR_IF_REG_NUM_TOO_HIGH(macreg,machigh_reg)               \
166*7fd79137SRobert Mustacchi      do {                                             \
167*7fd79137SRobert Mustacchi        if ((macreg) >= (machigh_reg) || (macreg) < 0) {            \
168*7fd79137SRobert Mustacchi         SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH); \
169*7fd79137SRobert Mustacchi        }                                              \
170*7fd79137SRobert Mustacchi      } /*CONSTCOND */ while(0)
171*7fd79137SRobert Mustacchi #define SIMPLE_ERROR_RETURN(code) \
172*7fd79137SRobert Mustacchi         free(localregtab); \
173*7fd79137SRobert Mustacchi         *returned_error = code; \
174*7fd79137SRobert Mustacchi         return DW_DLV_ERROR
175*7fd79137SRobert Mustacchi 
176*7fd79137SRobert Mustacchi     /* Sweeps the frame instructions. */
177*7fd79137SRobert Mustacchi     Dwarf_Small *instr_ptr;
178*7fd79137SRobert Mustacchi 
179*7fd79137SRobert Mustacchi     /* Register numbers not limited to just 255, thus not using
180*7fd79137SRobert Mustacchi        Dwarf_Small. */
181*7fd79137SRobert Mustacchi     typedef int reg_num_type;
182*7fd79137SRobert Mustacchi 
183*7fd79137SRobert Mustacchi     Dwarf_Unsigned factored_N_value;
184*7fd79137SRobert Mustacchi     Dwarf_Signed signed_factored_N_value;
185*7fd79137SRobert Mustacchi     Dwarf_Addr current_loc = initial_loc;       /* code location/
186*7fd79137SRobert Mustacchi                                                    pc-value
187*7fd79137SRobert Mustacchi                                                    corresponding to the
188*7fd79137SRobert Mustacchi                                                    frame instructions.
189*7fd79137SRobert Mustacchi                                                    Starts at zero when
190*7fd79137SRobert Mustacchi                                                    the caller has no
191*7fd79137SRobert Mustacchi                                                    value to pass in. */
192*7fd79137SRobert Mustacchi 
193*7fd79137SRobert Mustacchi     /* Must be min de_pointer_size bytes and must be at least sizeof
194*7fd79137SRobert Mustacchi        Dwarf_ufixed */
195*7fd79137SRobert Mustacchi     Dwarf_Unsigned adv_loc = 0;
196*7fd79137SRobert Mustacchi 
197*7fd79137SRobert Mustacchi     int reg_count = dbg->de_frame_reg_rules_entry_count;
198*7fd79137SRobert Mustacchi     struct Dwarf_Reg_Rule_s *localregtab = calloc(reg_count,
199*7fd79137SRobert Mustacchi                                           sizeof(struct
200*7fd79137SRobert Mustacchi                                                  Dwarf_Reg_Rule_s));
201*7fd79137SRobert Mustacchi 
202*7fd79137SRobert Mustacchi     struct Dwarf_Reg_Rule_s cfa_reg;
203*7fd79137SRobert Mustacchi 
204*7fd79137SRobert Mustacchi 
205*7fd79137SRobert Mustacchi     /* This is used to end executing frame instructions.  */
206*7fd79137SRobert Mustacchi     /* Becomes true when search_pc is true and current_loc */
207*7fd79137SRobert Mustacchi     /* is greater than search_pc_val.  */
208*7fd79137SRobert Mustacchi     Dwarf_Bool search_over = false;
209*7fd79137SRobert Mustacchi 
210*7fd79137SRobert Mustacchi     /* Used by the DW_FRAME_advance_loc instr */
211*7fd79137SRobert Mustacchi     /* to hold the increment in pc value.  */
212*7fd79137SRobert Mustacchi     Dwarf_Addr adv_pc;
213*7fd79137SRobert Mustacchi 
214*7fd79137SRobert Mustacchi     /* Contains the length in bytes of */
215*7fd79137SRobert Mustacchi     /* an leb128 encoded number.  */
216*7fd79137SRobert Mustacchi     Dwarf_Word leb128_length;
217*7fd79137SRobert Mustacchi 
218*7fd79137SRobert Mustacchi     Dwarf_Half address_size = (cie)? cie->ci_address_size:
219*7fd79137SRobert Mustacchi         dbg->de_pointer_size;
220*7fd79137SRobert Mustacchi 
221*7fd79137SRobert Mustacchi     /* Counts the number of frame instructions executed.  */
222*7fd79137SRobert Mustacchi     Dwarf_Word instr_count = 0;
223*7fd79137SRobert Mustacchi 
224*7fd79137SRobert Mustacchi     /*
225*7fd79137SRobert Mustacchi        These contain the current fields of the current frame
226*7fd79137SRobert Mustacchi        instruction. */
227*7fd79137SRobert Mustacchi     Dwarf_Small fp_base_op = 0;
228*7fd79137SRobert Mustacchi     Dwarf_Small fp_extended_op;
229*7fd79137SRobert Mustacchi     reg_num_type fp_register;
230*7fd79137SRobert Mustacchi 
231*7fd79137SRobert Mustacchi     /* The value in fp_offset may be signed, though we call it
232*7fd79137SRobert Mustacchi        unsigned. This works ok for 2-s complement arithmetic. */
233*7fd79137SRobert Mustacchi     Dwarf_Unsigned fp_offset;
234*7fd79137SRobert Mustacchi     Dwarf_Off fp_instr_offset;
235*7fd79137SRobert Mustacchi 
236*7fd79137SRobert Mustacchi     /*
237*7fd79137SRobert Mustacchi        Stack_table points to the row (Dwarf_Frame ie) being pushed or
238*7fd79137SRobert Mustacchi        popped by a remember or restore instruction. Top_stack points to
239*7fd79137SRobert Mustacchi        the top of the stack of rows. */
240*7fd79137SRobert Mustacchi     Dwarf_Frame stack_table = NULL;
241*7fd79137SRobert Mustacchi     Dwarf_Frame top_stack = NULL;
242*7fd79137SRobert Mustacchi 
243*7fd79137SRobert Mustacchi     /*
244*7fd79137SRobert Mustacchi        These are used only when make_instr is true. Curr_instr is a
245*7fd79137SRobert Mustacchi        pointer to the current frame instruction executed.
246*7fd79137SRobert Mustacchi        Curr_instr_ptr, head_instr_list, and curr_instr_list are used to
247*7fd79137SRobert Mustacchi        form a chain of Dwarf_Frame_Op structs. Dealloc_instr_ptr is
248*7fd79137SRobert Mustacchi        used to deallocate the structs used to form the chain.
249*7fd79137SRobert Mustacchi        Head_instr_block points to a contiguous list of pointers to the
250*7fd79137SRobert Mustacchi        Dwarf_Frame_Op structs executed. */
251*7fd79137SRobert Mustacchi     Dwarf_Frame_Op *curr_instr;
252*7fd79137SRobert Mustacchi     Dwarf_Chain curr_instr_item, dealloc_instr_item;
253*7fd79137SRobert Mustacchi     Dwarf_Chain head_instr_chain = NULL;
254*7fd79137SRobert Mustacchi     Dwarf_Chain tail_instr_chain = NULL;
255*7fd79137SRobert Mustacchi     Dwarf_Frame_Op *head_instr_block;
256*7fd79137SRobert Mustacchi 
257*7fd79137SRobert Mustacchi     /*
258*7fd79137SRobert Mustacchi        These are the alignment_factors taken from the Cie provided.
259*7fd79137SRobert Mustacchi        When no input Cie is provided they are set to 1, because only
260*7fd79137SRobert Mustacchi        factored offsets are required. */
261*7fd79137SRobert Mustacchi     Dwarf_Sword code_alignment_factor = 1;
262*7fd79137SRobert Mustacchi     Dwarf_Sword data_alignment_factor = 1;
263*7fd79137SRobert Mustacchi 
264*7fd79137SRobert Mustacchi     /*
265*7fd79137SRobert Mustacchi        This flag indicates when an actual alignment factor is needed.
266*7fd79137SRobert Mustacchi        So if a frame instruction that computes an offset using an
267*7fd79137SRobert Mustacchi        alignment factor is encountered when this flag is set, an error
268*7fd79137SRobert Mustacchi        is returned because the Cie did not have a valid augmentation. */
269*7fd79137SRobert Mustacchi     Dwarf_Bool need_augmentation = false;
270*7fd79137SRobert Mustacchi 
271*7fd79137SRobert Mustacchi     Dwarf_Word i;
272*7fd79137SRobert Mustacchi 
273*7fd79137SRobert Mustacchi     /* Initialize first row from associated Cie. Using temp regs
274*7fd79137SRobert Mustacchi        explicity */
275*7fd79137SRobert Mustacchi 
276*7fd79137SRobert Mustacchi     if (localregtab == 0) {
277*7fd79137SRobert Mustacchi         SIMPLE_ERROR_RETURN(DW_DLE_ALLOC_FAIL);
278*7fd79137SRobert Mustacchi     }
279*7fd79137SRobert Mustacchi     {
280*7fd79137SRobert Mustacchi         struct Dwarf_Reg_Rule_s *t1reg = localregtab;
281*7fd79137SRobert Mustacchi         struct Dwarf_Reg_Rule_s *t1end = t1reg + reg_count;
282*7fd79137SRobert Mustacchi 
283*7fd79137SRobert Mustacchi         if (cie != NULL && cie->ci_initial_table != NULL) {
284*7fd79137SRobert Mustacchi             struct Dwarf_Reg_Rule_s *t2reg =
285*7fd79137SRobert Mustacchi                 cie->ci_initial_table->fr_reg;
286*7fd79137SRobert Mustacchi 
287*7fd79137SRobert Mustacchi             if (reg_count != cie->ci_initial_table->fr_reg_count) {
288*7fd79137SRobert Mustacchi                 /* Should never happen, it makes no sense to have the
289*7fd79137SRobert Mustacchi                    table sizes change. There is no real allowance for
290*7fd79137SRobert Mustacchi                    the set of registers to change dynamically in a
291*7fd79137SRobert Mustacchi                    single Dwarf_Debug (except the size can be set near
292*7fd79137SRobert Mustacchi                    initial Dwarf_Debug creation time). */
293*7fd79137SRobert Mustacchi                 SIMPLE_ERROR_RETURN
294*7fd79137SRobert Mustacchi                     (DW_DLE_FRAME_REGISTER_COUNT_MISMATCH);
295*7fd79137SRobert Mustacchi             }
296*7fd79137SRobert Mustacchi 
297*7fd79137SRobert Mustacchi             for (; t1reg < t1end; t1reg++, t2reg++) {
298*7fd79137SRobert Mustacchi                 *t1reg = *t2reg;
299*7fd79137SRobert Mustacchi             }
300*7fd79137SRobert Mustacchi             cfa_reg = cie->ci_initial_table->fr_cfa_rule;
301*7fd79137SRobert Mustacchi         } else {
302*7fd79137SRobert Mustacchi             _dwarf_init_regrule_table(t1reg,
303*7fd79137SRobert Mustacchi                                       reg_count,
304*7fd79137SRobert Mustacchi                                       dbg->de_frame_rule_initial_value);
305*7fd79137SRobert Mustacchi             _dwarf_init_regrule_table(&cfa_reg, 1,
306*7fd79137SRobert Mustacchi                                       dbg->de_frame_rule_initial_value);
307*7fd79137SRobert Mustacchi         }
308*7fd79137SRobert Mustacchi     }
309*7fd79137SRobert Mustacchi 
310*7fd79137SRobert Mustacchi     /*
311*7fd79137SRobert Mustacchi        The idea here is that the code_alignment_factor and
312*7fd79137SRobert Mustacchi        data_alignment_factor which are needed for certain instructions
313*7fd79137SRobert Mustacchi        are valid only when the Cie has a proper augmentation string. So
314*7fd79137SRobert Mustacchi        if the augmentation is not right, only Frame instruction can be
315*7fd79137SRobert Mustacchi        read. */
316*7fd79137SRobert Mustacchi     if (cie != NULL && cie->ci_augmentation != NULL) {
317*7fd79137SRobert Mustacchi         code_alignment_factor = cie->ci_code_alignment_factor;
318*7fd79137SRobert Mustacchi         data_alignment_factor = cie->ci_data_alignment_factor;
319*7fd79137SRobert Mustacchi     } else {
320*7fd79137SRobert Mustacchi         need_augmentation = !make_instr;
321*7fd79137SRobert Mustacchi     }
322*7fd79137SRobert Mustacchi 
323*7fd79137SRobert Mustacchi     instr_ptr = start_instr_ptr;
324*7fd79137SRobert Mustacchi     while ((instr_ptr < final_instr_ptr) && (!search_over)) {
325*7fd79137SRobert Mustacchi         Dwarf_Small instr = 0;
326*7fd79137SRobert Mustacchi         Dwarf_Small opcode = 0;
327*7fd79137SRobert Mustacchi         reg_num_type reg_no = 0;
328*7fd79137SRobert Mustacchi 
329*7fd79137SRobert Mustacchi         fp_instr_offset = instr_ptr - start_instr_ptr;
330*7fd79137SRobert Mustacchi         instr = *(Dwarf_Small *) instr_ptr;
331*7fd79137SRobert Mustacchi         instr_ptr += sizeof(Dwarf_Small);
332*7fd79137SRobert Mustacchi 
333*7fd79137SRobert Mustacchi         fp_base_op = (instr & 0xc0) >> 6;
334*7fd79137SRobert Mustacchi         if ((instr & 0xc0) == 0x00) {
335*7fd79137SRobert Mustacchi             opcode = instr;     /* is really extended op */
336*7fd79137SRobert Mustacchi             fp_extended_op = (instr & (~(0xc0))) & 0xff;
337*7fd79137SRobert Mustacchi         } else {
338*7fd79137SRobert Mustacchi             opcode = instr & 0xc0;      /* is base op */
339*7fd79137SRobert Mustacchi             fp_extended_op = 0;
340*7fd79137SRobert Mustacchi         }
341*7fd79137SRobert Mustacchi 
342*7fd79137SRobert Mustacchi         fp_register = 0;
343*7fd79137SRobert Mustacchi         fp_offset = 0;
344*7fd79137SRobert Mustacchi         switch (opcode) {
345*7fd79137SRobert Mustacchi         case DW_CFA_advance_loc:
346*7fd79137SRobert Mustacchi             {
347*7fd79137SRobert Mustacchi                 /* base op */
348*7fd79137SRobert Mustacchi                 fp_offset = adv_pc = instr & DW_FRAME_INSTR_OFFSET_MASK;
349*7fd79137SRobert Mustacchi 
350*7fd79137SRobert Mustacchi                 if (need_augmentation) {
351*7fd79137SRobert Mustacchi                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
352*7fd79137SRobert Mustacchi                 }
353*7fd79137SRobert Mustacchi                 adv_pc = adv_pc * code_alignment_factor;
354*7fd79137SRobert Mustacchi 
355*7fd79137SRobert Mustacchi                 search_over = search_pc &&
356*7fd79137SRobert Mustacchi                     (current_loc + adv_pc > search_pc_val);
357*7fd79137SRobert Mustacchi                 /* If gone past pc needed, retain old pc.  */
358*7fd79137SRobert Mustacchi                 if (!search_over) {
359*7fd79137SRobert Mustacchi                     current_loc = current_loc + adv_pc;
360*7fd79137SRobert Mustacchi                 }
361*7fd79137SRobert Mustacchi                 break;
362*7fd79137SRobert Mustacchi             }
363*7fd79137SRobert Mustacchi 
364*7fd79137SRobert Mustacchi         case DW_CFA_offset:
365*7fd79137SRobert Mustacchi             {                   /* base op */
366*7fd79137SRobert Mustacchi                 reg_no =
367*7fd79137SRobert Mustacchi                     (reg_num_type) (instr & DW_FRAME_INSTR_OFFSET_MASK);
368*7fd79137SRobert Mustacchi                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
369*7fd79137SRobert Mustacchi 
370*7fd79137SRobert Mustacchi                 factored_N_value =
371*7fd79137SRobert Mustacchi                     _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
372*7fd79137SRobert Mustacchi                 instr_ptr = instr_ptr + leb128_length;
373*7fd79137SRobert Mustacchi 
374*7fd79137SRobert Mustacchi                 fp_register = reg_no;
375*7fd79137SRobert Mustacchi                 fp_offset = factored_N_value;
376*7fd79137SRobert Mustacchi 
377*7fd79137SRobert Mustacchi                 if (need_augmentation) {
378*7fd79137SRobert Mustacchi                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
379*7fd79137SRobert Mustacchi                 }
380*7fd79137SRobert Mustacchi 
381*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_is_off = 1;
382*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
383*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_register = reg_num_of_cfa;
384*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_offset_or_block_len =
385*7fd79137SRobert Mustacchi                     factored_N_value * data_alignment_factor;
386*7fd79137SRobert Mustacchi 
387*7fd79137SRobert Mustacchi                 break;
388*7fd79137SRobert Mustacchi             }
389*7fd79137SRobert Mustacchi 
390*7fd79137SRobert Mustacchi         case DW_CFA_restore:
391*7fd79137SRobert Mustacchi             {                   /* base op */
392*7fd79137SRobert Mustacchi                 reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK);
393*7fd79137SRobert Mustacchi                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
394*7fd79137SRobert Mustacchi 
395*7fd79137SRobert Mustacchi                 fp_register = reg_no;
396*7fd79137SRobert Mustacchi 
397*7fd79137SRobert Mustacchi                 if (cie != NULL && cie->ci_initial_table != NULL)
398*7fd79137SRobert Mustacchi                     localregtab[reg_no] =
399*7fd79137SRobert Mustacchi                        cie->ci_initial_table->fr_reg[reg_no];
400*7fd79137SRobert Mustacchi                 else if (!make_instr) {
401*7fd79137SRobert Mustacchi                     SIMPLE_ERROR_RETURN(DW_DLE_DF_MAKE_INSTR_NO_INIT);
402*7fd79137SRobert Mustacchi                 }
403*7fd79137SRobert Mustacchi 
404*7fd79137SRobert Mustacchi                 break;
405*7fd79137SRobert Mustacchi             }
406*7fd79137SRobert Mustacchi         case DW_CFA_set_loc:
407*7fd79137SRobert Mustacchi             {
408*7fd79137SRobert Mustacchi                 Dwarf_Addr new_loc = 0;
409*7fd79137SRobert Mustacchi 
410*7fd79137SRobert Mustacchi                 READ_UNALIGNED(dbg, new_loc, Dwarf_Addr,
411*7fd79137SRobert Mustacchi                                instr_ptr, address_size);
412*7fd79137SRobert Mustacchi                 instr_ptr += address_size;
413*7fd79137SRobert Mustacchi                 if (new_loc != 0 && current_loc != 0) {
414*7fd79137SRobert Mustacchi                     /* Pre-relocation or before current_loc is set the
415*7fd79137SRobert Mustacchi                        test comparing new_loc and current_loc makes no
416*7fd79137SRobert Mustacchi                        sense. Testing for non-zero (above) is a way
417*7fd79137SRobert Mustacchi                        (fallible) to check that current_loc, new_loc
418*7fd79137SRobert Mustacchi                        are already relocated.  */
419*7fd79137SRobert Mustacchi                     if (new_loc <= current_loc) {
420*7fd79137SRobert Mustacchi                         /* Within a frame, address must increase.
421*7fd79137SRobert Mustacchi                            Seemingly it has not. Seems to be an error. */
422*7fd79137SRobert Mustacchi 
423*7fd79137SRobert Mustacchi                         SIMPLE_ERROR_RETURN
424*7fd79137SRobert Mustacchi                             (DW_DLE_DF_NEW_LOC_LESS_OLD_LOC);
425*7fd79137SRobert Mustacchi                     }
426*7fd79137SRobert Mustacchi                 }
427*7fd79137SRobert Mustacchi 
428*7fd79137SRobert Mustacchi                 search_over = search_pc && (new_loc > search_pc_val);
429*7fd79137SRobert Mustacchi 
430*7fd79137SRobert Mustacchi                 /* If gone past pc needed, retain old pc.  */
431*7fd79137SRobert Mustacchi                 if (!search_over) {
432*7fd79137SRobert Mustacchi                     current_loc = new_loc;
433*7fd79137SRobert Mustacchi                 }
434*7fd79137SRobert Mustacchi                 fp_offset = new_loc;
435*7fd79137SRobert Mustacchi                 break;
436*7fd79137SRobert Mustacchi             }
437*7fd79137SRobert Mustacchi 
438*7fd79137SRobert Mustacchi         case DW_CFA_advance_loc1:
439*7fd79137SRobert Mustacchi             {
440*7fd79137SRobert Mustacchi                 fp_offset = adv_loc = *(Dwarf_Small *) instr_ptr;
441*7fd79137SRobert Mustacchi                 instr_ptr += sizeof(Dwarf_Small);
442*7fd79137SRobert Mustacchi 
443*7fd79137SRobert Mustacchi                 if (need_augmentation) {
444*7fd79137SRobert Mustacchi                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
445*7fd79137SRobert Mustacchi                 }
446*7fd79137SRobert Mustacchi                 adv_loc *= code_alignment_factor;
447*7fd79137SRobert Mustacchi 
448*7fd79137SRobert Mustacchi                 search_over = search_pc &&
449*7fd79137SRobert Mustacchi                     (current_loc + adv_loc > search_pc_val);
450*7fd79137SRobert Mustacchi 
451*7fd79137SRobert Mustacchi                 /* If gone past pc needed, retain old pc.  */
452*7fd79137SRobert Mustacchi                 if (!search_over) {
453*7fd79137SRobert Mustacchi                     current_loc = current_loc + adv_loc;
454*7fd79137SRobert Mustacchi                 }
455*7fd79137SRobert Mustacchi                 break;
456*7fd79137SRobert Mustacchi             }
457*7fd79137SRobert Mustacchi 
458*7fd79137SRobert Mustacchi         case DW_CFA_advance_loc2:
459*7fd79137SRobert Mustacchi             {
460*7fd79137SRobert Mustacchi                 READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
461*7fd79137SRobert Mustacchi                                instr_ptr, sizeof(Dwarf_Half));
462*7fd79137SRobert Mustacchi                 instr_ptr += sizeof(Dwarf_Half);
463*7fd79137SRobert Mustacchi                 fp_offset = adv_loc;
464*7fd79137SRobert Mustacchi 
465*7fd79137SRobert Mustacchi                 if (need_augmentation) {
466*7fd79137SRobert Mustacchi                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
467*7fd79137SRobert Mustacchi                 }
468*7fd79137SRobert Mustacchi                 adv_loc *= code_alignment_factor;
469*7fd79137SRobert Mustacchi 
470*7fd79137SRobert Mustacchi                 search_over = search_pc &&
471*7fd79137SRobert Mustacchi                     (current_loc + adv_loc > search_pc_val);
472*7fd79137SRobert Mustacchi 
473*7fd79137SRobert Mustacchi                 /* If gone past pc needed, retain old pc.  */
474*7fd79137SRobert Mustacchi                 if (!search_over) {
475*7fd79137SRobert Mustacchi                     current_loc = current_loc + adv_loc;
476*7fd79137SRobert Mustacchi                 }
477*7fd79137SRobert Mustacchi                 break;
478*7fd79137SRobert Mustacchi             }
479*7fd79137SRobert Mustacchi 
480*7fd79137SRobert Mustacchi         case DW_CFA_advance_loc4:
481*7fd79137SRobert Mustacchi             {
482*7fd79137SRobert Mustacchi                 READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
483*7fd79137SRobert Mustacchi                                instr_ptr, sizeof(Dwarf_ufixed));
484*7fd79137SRobert Mustacchi                 instr_ptr += sizeof(Dwarf_ufixed);
485*7fd79137SRobert Mustacchi                 fp_offset = adv_loc;
486*7fd79137SRobert Mustacchi 
487*7fd79137SRobert Mustacchi                 if (need_augmentation) {
488*7fd79137SRobert Mustacchi                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
489*7fd79137SRobert Mustacchi                 }
490*7fd79137SRobert Mustacchi                 adv_loc *= code_alignment_factor;
491*7fd79137SRobert Mustacchi 
492*7fd79137SRobert Mustacchi                 search_over = search_pc &&
493*7fd79137SRobert Mustacchi                     (current_loc + adv_loc > search_pc_val);
494*7fd79137SRobert Mustacchi 
495*7fd79137SRobert Mustacchi                 /* If gone past pc needed, retain old pc.  */
496*7fd79137SRobert Mustacchi                 if (!search_over) {
497*7fd79137SRobert Mustacchi                     current_loc = current_loc + adv_loc;
498*7fd79137SRobert Mustacchi                 }
499*7fd79137SRobert Mustacchi                 break;
500*7fd79137SRobert Mustacchi             }
501*7fd79137SRobert Mustacchi 
502*7fd79137SRobert Mustacchi         case DW_CFA_offset_extended:
503*7fd79137SRobert Mustacchi             {
504*7fd79137SRobert Mustacchi                 Dwarf_Unsigned lreg;
505*7fd79137SRobert Mustacchi 
506*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, lreg);
507*7fd79137SRobert Mustacchi                 reg_no = (reg_num_type) lreg;
508*7fd79137SRobert Mustacchi                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);;
509*7fd79137SRobert Mustacchi                 factored_N_value =
510*7fd79137SRobert Mustacchi                     _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
511*7fd79137SRobert Mustacchi                 instr_ptr += leb128_length;
512*7fd79137SRobert Mustacchi 
513*7fd79137SRobert Mustacchi                 if (need_augmentation) {
514*7fd79137SRobert Mustacchi                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
515*7fd79137SRobert Mustacchi                 }
516*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_is_off = 1;
517*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
518*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_register = reg_num_of_cfa;
519*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_offset_or_block_len = factored_N_value *
520*7fd79137SRobert Mustacchi                     data_alignment_factor;
521*7fd79137SRobert Mustacchi 
522*7fd79137SRobert Mustacchi                 fp_register = reg_no;
523*7fd79137SRobert Mustacchi                 fp_offset = factored_N_value;
524*7fd79137SRobert Mustacchi                 break;
525*7fd79137SRobert Mustacchi             }
526*7fd79137SRobert Mustacchi 
527*7fd79137SRobert Mustacchi         case DW_CFA_restore_extended:
528*7fd79137SRobert Mustacchi             {
529*7fd79137SRobert Mustacchi                 Dwarf_Unsigned lreg;
530*7fd79137SRobert Mustacchi 
531*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, lreg);
532*7fd79137SRobert Mustacchi                 reg_no = (reg_num_type) lreg;
533*7fd79137SRobert Mustacchi 
534*7fd79137SRobert Mustacchi                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
535*7fd79137SRobert Mustacchi 
536*7fd79137SRobert Mustacchi                 if (cie != NULL && cie->ci_initial_table != NULL) {
537*7fd79137SRobert Mustacchi                     localregtab[reg_no] = cie->ci_initial_table->fr_reg[reg_no];
538*7fd79137SRobert Mustacchi                 } else {
539*7fd79137SRobert Mustacchi                     if (!make_instr) {
540*7fd79137SRobert Mustacchi                         SIMPLE_ERROR_RETURN
541*7fd79137SRobert Mustacchi                             (DW_DLE_DF_MAKE_INSTR_NO_INIT);
542*7fd79137SRobert Mustacchi                     }
543*7fd79137SRobert Mustacchi                 }
544*7fd79137SRobert Mustacchi 
545*7fd79137SRobert Mustacchi                 fp_register = reg_no;
546*7fd79137SRobert Mustacchi                 break;
547*7fd79137SRobert Mustacchi             }
548*7fd79137SRobert Mustacchi 
549*7fd79137SRobert Mustacchi         case DW_CFA_undefined:
550*7fd79137SRobert Mustacchi             {
551*7fd79137SRobert Mustacchi                 Dwarf_Unsigned lreg;
552*7fd79137SRobert Mustacchi 
553*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, lreg);
554*7fd79137SRobert Mustacchi                 reg_no = (reg_num_type) lreg;
555*7fd79137SRobert Mustacchi                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
556*7fd79137SRobert Mustacchi 
557*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_is_off = 0;
558*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
559*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_register =
560*7fd79137SRobert Mustacchi                     dbg->de_frame_undefined_value_number;
561*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_offset_or_block_len = 0;
562*7fd79137SRobert Mustacchi 
563*7fd79137SRobert Mustacchi                 fp_register = reg_no;
564*7fd79137SRobert Mustacchi                 break;
565*7fd79137SRobert Mustacchi             }
566*7fd79137SRobert Mustacchi 
567*7fd79137SRobert Mustacchi         case DW_CFA_same_value:
568*7fd79137SRobert Mustacchi             {
569*7fd79137SRobert Mustacchi                 Dwarf_Unsigned lreg;
570*7fd79137SRobert Mustacchi 
571*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, lreg);
572*7fd79137SRobert Mustacchi                 reg_no = (reg_num_type) lreg;
573*7fd79137SRobert Mustacchi                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
574*7fd79137SRobert Mustacchi 
575*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_is_off = 0;
576*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
577*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_register =
578*7fd79137SRobert Mustacchi                     dbg->de_frame_same_value_number;
579*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_offset_or_block_len = 0;
580*7fd79137SRobert Mustacchi                 fp_register = reg_no;
581*7fd79137SRobert Mustacchi                 break;
582*7fd79137SRobert Mustacchi             }
583*7fd79137SRobert Mustacchi 
584*7fd79137SRobert Mustacchi         case DW_CFA_register:
585*7fd79137SRobert Mustacchi             {
586*7fd79137SRobert Mustacchi                 Dwarf_Unsigned lreg;
587*7fd79137SRobert Mustacchi                 reg_num_type reg_noA = 0;
588*7fd79137SRobert Mustacchi                 reg_num_type reg_noB = 0;
589*7fd79137SRobert Mustacchi 
590*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, lreg);
591*7fd79137SRobert Mustacchi                 reg_noA = (reg_num_type) lreg;
592*7fd79137SRobert Mustacchi 
593*7fd79137SRobert Mustacchi                 ERROR_IF_REG_NUM_TOO_HIGH(reg_noA, reg_count);
594*7fd79137SRobert Mustacchi 
595*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, lreg);
596*7fd79137SRobert Mustacchi                 reg_noB = (reg_num_type) lreg;
597*7fd79137SRobert Mustacchi 
598*7fd79137SRobert Mustacchi                 if (reg_noB > reg_count) {
599*7fd79137SRobert Mustacchi                     SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH);
600*7fd79137SRobert Mustacchi                 }
601*7fd79137SRobert Mustacchi 
602*7fd79137SRobert Mustacchi 
603*7fd79137SRobert Mustacchi                 localregtab[reg_noA].ru_is_off = 0;
604*7fd79137SRobert Mustacchi                 localregtab[reg_noA].ru_value_type = DW_EXPR_OFFSET;
605*7fd79137SRobert Mustacchi                 localregtab[reg_noA].ru_register = reg_noB;
606*7fd79137SRobert Mustacchi                 localregtab[reg_noA].ru_offset_or_block_len = 0;
607*7fd79137SRobert Mustacchi 
608*7fd79137SRobert Mustacchi                 fp_register = reg_noA;
609*7fd79137SRobert Mustacchi                 fp_offset = reg_noB;
610*7fd79137SRobert Mustacchi                 break;
611*7fd79137SRobert Mustacchi             }
612*7fd79137SRobert Mustacchi 
613*7fd79137SRobert Mustacchi         case DW_CFA_remember_state:
614*7fd79137SRobert Mustacchi             {
615*7fd79137SRobert Mustacchi                 stack_table = (Dwarf_Frame)
616*7fd79137SRobert Mustacchi                     _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
617*7fd79137SRobert Mustacchi                 if (stack_table == NULL) {
618*7fd79137SRobert Mustacchi                     SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
619*7fd79137SRobert Mustacchi                 }
620*7fd79137SRobert Mustacchi 
621*7fd79137SRobert Mustacchi                 for (i = 0; i < reg_count; i++)
622*7fd79137SRobert Mustacchi                     stack_table->fr_reg[i] = localregtab[i];
623*7fd79137SRobert Mustacchi                 stack_table->fr_cfa_rule = cfa_reg;
624*7fd79137SRobert Mustacchi 
625*7fd79137SRobert Mustacchi                 if (top_stack != NULL)
626*7fd79137SRobert Mustacchi                     stack_table->fr_next = top_stack;
627*7fd79137SRobert Mustacchi                 top_stack = stack_table;
628*7fd79137SRobert Mustacchi 
629*7fd79137SRobert Mustacchi                 break;
630*7fd79137SRobert Mustacchi             }
631*7fd79137SRobert Mustacchi 
632*7fd79137SRobert Mustacchi         case DW_CFA_restore_state:
633*7fd79137SRobert Mustacchi             {
634*7fd79137SRobert Mustacchi                 if (top_stack == NULL) {
635*7fd79137SRobert Mustacchi                     SIMPLE_ERROR_RETURN(DW_DLE_DF_POP_EMPTY_STACK);
636*7fd79137SRobert Mustacchi                 }
637*7fd79137SRobert Mustacchi                 stack_table = top_stack;
638*7fd79137SRobert Mustacchi                 top_stack = stack_table->fr_next;
639*7fd79137SRobert Mustacchi 
640*7fd79137SRobert Mustacchi                 for (i = 0; i < reg_count; i++)
641*7fd79137SRobert Mustacchi                     localregtab[i] = stack_table->fr_reg[i];
642*7fd79137SRobert Mustacchi                 cfa_reg = stack_table->fr_cfa_rule;
643*7fd79137SRobert Mustacchi 
644*7fd79137SRobert Mustacchi                 dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
645*7fd79137SRobert Mustacchi                 break;
646*7fd79137SRobert Mustacchi             }
647*7fd79137SRobert Mustacchi 
648*7fd79137SRobert Mustacchi         case DW_CFA_def_cfa:
649*7fd79137SRobert Mustacchi             {
650*7fd79137SRobert Mustacchi                 Dwarf_Unsigned lreg;
651*7fd79137SRobert Mustacchi 
652*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, lreg);
653*7fd79137SRobert Mustacchi                 reg_no = (reg_num_type) lreg;
654*7fd79137SRobert Mustacchi 
655*7fd79137SRobert Mustacchi                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
656*7fd79137SRobert Mustacchi 
657*7fd79137SRobert Mustacchi                 factored_N_value =
658*7fd79137SRobert Mustacchi                     _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
659*7fd79137SRobert Mustacchi                 instr_ptr += leb128_length;
660*7fd79137SRobert Mustacchi 
661*7fd79137SRobert Mustacchi                 if (need_augmentation) {
662*7fd79137SRobert Mustacchi                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
663*7fd79137SRobert Mustacchi                 }
664*7fd79137SRobert Mustacchi                 cfa_reg.ru_is_off = 1;
665*7fd79137SRobert Mustacchi                 cfa_reg.ru_value_type = DW_EXPR_OFFSET;
666*7fd79137SRobert Mustacchi                 cfa_reg.ru_register = reg_no;
667*7fd79137SRobert Mustacchi                 cfa_reg.ru_offset_or_block_len = factored_N_value;
668*7fd79137SRobert Mustacchi 
669*7fd79137SRobert Mustacchi                 fp_register = reg_no;
670*7fd79137SRobert Mustacchi                 fp_offset = factored_N_value;
671*7fd79137SRobert Mustacchi                 break;
672*7fd79137SRobert Mustacchi             }
673*7fd79137SRobert Mustacchi 
674*7fd79137SRobert Mustacchi         case DW_CFA_def_cfa_register:
675*7fd79137SRobert Mustacchi             {
676*7fd79137SRobert Mustacchi                 Dwarf_Unsigned lreg;
677*7fd79137SRobert Mustacchi 
678*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, lreg);
679*7fd79137SRobert Mustacchi                 reg_no = (reg_num_type) lreg;
680*7fd79137SRobert Mustacchi                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
681*7fd79137SRobert Mustacchi 
682*7fd79137SRobert Mustacchi                 cfa_reg.ru_register = reg_no;
683*7fd79137SRobert Mustacchi                 /* Do NOT set ru_offset_or_block_len or ru_is_off here.
684*7fd79137SRobert Mustacchi                    See dwarf2/3 spec.  */
685*7fd79137SRobert Mustacchi                 fp_register = reg_no;
686*7fd79137SRobert Mustacchi                 break;
687*7fd79137SRobert Mustacchi             }
688*7fd79137SRobert Mustacchi 
689*7fd79137SRobert Mustacchi         case DW_CFA_def_cfa_offset:
690*7fd79137SRobert Mustacchi             {
691*7fd79137SRobert Mustacchi                 factored_N_value =
692*7fd79137SRobert Mustacchi                     _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
693*7fd79137SRobert Mustacchi                 instr_ptr += leb128_length;
694*7fd79137SRobert Mustacchi 
695*7fd79137SRobert Mustacchi                 if (need_augmentation) {
696*7fd79137SRobert Mustacchi                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
697*7fd79137SRobert Mustacchi                 }
698*7fd79137SRobert Mustacchi                 /* Do set ru_is_off here, as here factored_N_value
699*7fd79137SRobert Mustacchi                    counts.  */
700*7fd79137SRobert Mustacchi                 cfa_reg.ru_is_off = 1;
701*7fd79137SRobert Mustacchi                 cfa_reg.ru_value_type = DW_EXPR_OFFSET;
702*7fd79137SRobert Mustacchi                 cfa_reg.ru_offset_or_block_len = factored_N_value;
703*7fd79137SRobert Mustacchi 
704*7fd79137SRobert Mustacchi                 fp_offset = factored_N_value;
705*7fd79137SRobert Mustacchi                 break;
706*7fd79137SRobert Mustacchi             }
707*7fd79137SRobert Mustacchi         case DW_CFA_nop:
708*7fd79137SRobert Mustacchi             {
709*7fd79137SRobert Mustacchi                 break;
710*7fd79137SRobert Mustacchi             }
711*7fd79137SRobert Mustacchi             /* DWARF3 ops begin here. */
712*7fd79137SRobert Mustacchi         case DW_CFA_def_cfa_expression:
713*7fd79137SRobert Mustacchi             {
714*7fd79137SRobert Mustacchi                 /* A single DW_FORM_block representing a dwarf
715*7fd79137SRobert Mustacchi                    expression. The form block establishes the way to
716*7fd79137SRobert Mustacchi                    compute the CFA. */
717*7fd79137SRobert Mustacchi                 Dwarf_Unsigned block_len = 0;
718*7fd79137SRobert Mustacchi 
719*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, block_len);
720*7fd79137SRobert Mustacchi                 cfa_reg.ru_is_off = 0;  /* arbitrary */
721*7fd79137SRobert Mustacchi                 cfa_reg.ru_value_type = DW_EXPR_EXPRESSION;
722*7fd79137SRobert Mustacchi                 cfa_reg.ru_offset_or_block_len = block_len;
723*7fd79137SRobert Mustacchi                 cfa_reg.ru_block = instr_ptr;
724*7fd79137SRobert Mustacchi                 fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr;
725*7fd79137SRobert Mustacchi                 instr_ptr += block_len;
726*7fd79137SRobert Mustacchi             }
727*7fd79137SRobert Mustacchi             break;
728*7fd79137SRobert Mustacchi         case DW_CFA_expression:
729*7fd79137SRobert Mustacchi             {
730*7fd79137SRobert Mustacchi                 /* An unsigned leb128 value is the first operand (a
731*7fd79137SRobert Mustacchi                    register number). The second operand is single
732*7fd79137SRobert Mustacchi                    DW_FORM_block representing a dwarf expression. The
733*7fd79137SRobert Mustacchi                    evaluator pushes the CFA on the evaluation stack
734*7fd79137SRobert Mustacchi                    then evaluates the expression to compute the value
735*7fd79137SRobert Mustacchi                    of the register contents. */
736*7fd79137SRobert Mustacchi                 Dwarf_Unsigned lreg = 0;
737*7fd79137SRobert Mustacchi                 Dwarf_Unsigned block_len = 0;
738*7fd79137SRobert Mustacchi 
739*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, lreg);
740*7fd79137SRobert Mustacchi                 reg_no = (reg_num_type) lreg;
741*7fd79137SRobert Mustacchi                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
742*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, block_len);
743*7fd79137SRobert Mustacchi                 localregtab[lreg].ru_is_off = 0;        /* arbitrary */
744*7fd79137SRobert Mustacchi                 localregtab[lreg].ru_value_type = DW_EXPR_EXPRESSION;
745*7fd79137SRobert Mustacchi                 localregtab[lreg].ru_offset_or_block_len = block_len;
746*7fd79137SRobert Mustacchi                 localregtab[lreg].ru_block = instr_ptr;
747*7fd79137SRobert Mustacchi                 fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr;
748*7fd79137SRobert Mustacchi                 fp_register = reg_no;
749*7fd79137SRobert Mustacchi                 instr_ptr += block_len;
750*7fd79137SRobert Mustacchi             }
751*7fd79137SRobert Mustacchi             break;
752*7fd79137SRobert Mustacchi         case DW_CFA_offset_extended_sf:
753*7fd79137SRobert Mustacchi             {
754*7fd79137SRobert Mustacchi                 /* The first operand is an unsigned leb128 register
755*7fd79137SRobert Mustacchi                    number. The second is a signed factored offset.
756*7fd79137SRobert Mustacchi                    Identical to DW_CFA_offset_extended except the
757*7fd79137SRobert Mustacchi                    secondoperand is signed */
758*7fd79137SRobert Mustacchi                 Dwarf_Unsigned lreg;
759*7fd79137SRobert Mustacchi 
760*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, lreg);
761*7fd79137SRobert Mustacchi                 reg_no = (reg_num_type) lreg;
762*7fd79137SRobert Mustacchi                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
763*7fd79137SRobert Mustacchi                 signed_factored_N_value =
764*7fd79137SRobert Mustacchi                     _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
765*7fd79137SRobert Mustacchi                 instr_ptr += leb128_length;
766*7fd79137SRobert Mustacchi 
767*7fd79137SRobert Mustacchi                 if (need_augmentation) {
768*7fd79137SRobert Mustacchi                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
769*7fd79137SRobert Mustacchi                 }
770*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_is_off = 1;
771*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
772*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_register = reg_num_of_cfa;
773*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_offset_or_block_len =
774*7fd79137SRobert Mustacchi                     signed_factored_N_value * data_alignment_factor;
775*7fd79137SRobert Mustacchi 
776*7fd79137SRobert Mustacchi                 fp_register = reg_no;
777*7fd79137SRobert Mustacchi                 fp_offset = signed_factored_N_value;
778*7fd79137SRobert Mustacchi             }
779*7fd79137SRobert Mustacchi             break;
780*7fd79137SRobert Mustacchi         case DW_CFA_def_cfa_sf:
781*7fd79137SRobert Mustacchi             {
782*7fd79137SRobert Mustacchi                 /* The first operand is an unsigned leb128 register
783*7fd79137SRobert Mustacchi                    number. The second is a signed leb128 factored
784*7fd79137SRobert Mustacchi                    offset. Identical to DW_CFA_def_cfa except that the
785*7fd79137SRobert Mustacchi                    second operand is signed and factored. */
786*7fd79137SRobert Mustacchi                 Dwarf_Unsigned lreg;
787*7fd79137SRobert Mustacchi 
788*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, lreg);
789*7fd79137SRobert Mustacchi                 reg_no = (reg_num_type) lreg;
790*7fd79137SRobert Mustacchi                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
791*7fd79137SRobert Mustacchi 
792*7fd79137SRobert Mustacchi                 signed_factored_N_value =
793*7fd79137SRobert Mustacchi                     _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
794*7fd79137SRobert Mustacchi                 instr_ptr += leb128_length;
795*7fd79137SRobert Mustacchi 
796*7fd79137SRobert Mustacchi                 if (need_augmentation) {
797*7fd79137SRobert Mustacchi                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
798*7fd79137SRobert Mustacchi                 }
799*7fd79137SRobert Mustacchi                 cfa_reg.ru_is_off = 1;
800*7fd79137SRobert Mustacchi                 cfa_reg.ru_value_type = DW_EXPR_OFFSET;
801*7fd79137SRobert Mustacchi                 cfa_reg.ru_register = reg_no;
802*7fd79137SRobert Mustacchi                 cfa_reg.ru_offset_or_block_len =
803*7fd79137SRobert Mustacchi                     signed_factored_N_value * data_alignment_factor;
804*7fd79137SRobert Mustacchi 
805*7fd79137SRobert Mustacchi                 fp_register = reg_no;
806*7fd79137SRobert Mustacchi                 fp_offset = signed_factored_N_value;
807*7fd79137SRobert Mustacchi             }
808*7fd79137SRobert Mustacchi             break;
809*7fd79137SRobert Mustacchi         case DW_CFA_def_cfa_offset_sf:
810*7fd79137SRobert Mustacchi             {
811*7fd79137SRobert Mustacchi                 /* The operand is a signed leb128 operand representing
812*7fd79137SRobert Mustacchi                    a factored offset.  Identical to
813*7fd79137SRobert Mustacchi                    DW_CFA_def_cfa_offset excep the operand is signed
814*7fd79137SRobert Mustacchi                    and factored. */
815*7fd79137SRobert Mustacchi 
816*7fd79137SRobert Mustacchi                 signed_factored_N_value =
817*7fd79137SRobert Mustacchi                     _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
818*7fd79137SRobert Mustacchi                 instr_ptr += leb128_length;
819*7fd79137SRobert Mustacchi 
820*7fd79137SRobert Mustacchi                 if (need_augmentation) {
821*7fd79137SRobert Mustacchi                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
822*7fd79137SRobert Mustacchi                 }
823*7fd79137SRobert Mustacchi                 /* Do set ru_is_off here, as here factored_N_value
824*7fd79137SRobert Mustacchi                    counts.  */
825*7fd79137SRobert Mustacchi                 cfa_reg.ru_is_off = 1;
826*7fd79137SRobert Mustacchi                 cfa_reg.ru_value_type = DW_EXPR_OFFSET;
827*7fd79137SRobert Mustacchi                 cfa_reg.ru_offset_or_block_len =
828*7fd79137SRobert Mustacchi                     signed_factored_N_value * data_alignment_factor;
829*7fd79137SRobert Mustacchi 
830*7fd79137SRobert Mustacchi                 fp_offset = signed_factored_N_value;
831*7fd79137SRobert Mustacchi             }
832*7fd79137SRobert Mustacchi             break;
833*7fd79137SRobert Mustacchi         case DW_CFA_val_offset:
834*7fd79137SRobert Mustacchi             {
835*7fd79137SRobert Mustacchi                 /* The first operand is an unsigned leb128 register
836*7fd79137SRobert Mustacchi                    number. The second is a factored unsigned offset.
837*7fd79137SRobert Mustacchi                    Makes the register be a val_offset(N) rule with N =
838*7fd79137SRobert Mustacchi                    factored_offset*data_alignment_factor. */
839*7fd79137SRobert Mustacchi 
840*7fd79137SRobert Mustacchi                 Dwarf_Unsigned lreg;
841*7fd79137SRobert Mustacchi 
842*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, lreg);
843*7fd79137SRobert Mustacchi                 reg_no = (reg_num_type) lreg;
844*7fd79137SRobert Mustacchi 
845*7fd79137SRobert Mustacchi                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
846*7fd79137SRobert Mustacchi 
847*7fd79137SRobert Mustacchi                 factored_N_value =
848*7fd79137SRobert Mustacchi                     _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
849*7fd79137SRobert Mustacchi                 instr_ptr += leb128_length;
850*7fd79137SRobert Mustacchi 
851*7fd79137SRobert Mustacchi                 if (need_augmentation) {
852*7fd79137SRobert Mustacchi                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
853*7fd79137SRobert Mustacchi                 }
854*7fd79137SRobert Mustacchi                 /* Do set ru_is_off here, as here factored_N_value
855*7fd79137SRobert Mustacchi                    counts.  */
856*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_is_off = 1;
857*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_register = reg_num_of_cfa;
858*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET;
859*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_offset_or_block_len =
860*7fd79137SRobert Mustacchi                     factored_N_value * data_alignment_factor;
861*7fd79137SRobert Mustacchi 
862*7fd79137SRobert Mustacchi                 fp_offset = factored_N_value;
863*7fd79137SRobert Mustacchi                 break;
864*7fd79137SRobert Mustacchi             }
865*7fd79137SRobert Mustacchi         case DW_CFA_val_offset_sf:
866*7fd79137SRobert Mustacchi             {
867*7fd79137SRobert Mustacchi                 /* The first operand is an unsigned leb128 register
868*7fd79137SRobert Mustacchi                    number. The second is a factored signed offset.
869*7fd79137SRobert Mustacchi                    Makes the register be a val_offset(N) rule with N =
870*7fd79137SRobert Mustacchi                    factored_offset*data_alignment_factor. */
871*7fd79137SRobert Mustacchi                 Dwarf_Unsigned lreg;
872*7fd79137SRobert Mustacchi 
873*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, lreg);
874*7fd79137SRobert Mustacchi                 reg_no = (reg_num_type) lreg;
875*7fd79137SRobert Mustacchi 
876*7fd79137SRobert Mustacchi                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
877*7fd79137SRobert Mustacchi                 signed_factored_N_value =
878*7fd79137SRobert Mustacchi                     _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
879*7fd79137SRobert Mustacchi                 instr_ptr += leb128_length;
880*7fd79137SRobert Mustacchi 
881*7fd79137SRobert Mustacchi                 if (need_augmentation) {
882*7fd79137SRobert Mustacchi                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
883*7fd79137SRobert Mustacchi                 }
884*7fd79137SRobert Mustacchi                 /* Do set ru_is_off here, as here factored_N_value
885*7fd79137SRobert Mustacchi                    counts.  */
886*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_is_off = 1;
887*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET;
888*7fd79137SRobert Mustacchi                 localregtab[reg_no].ru_offset_or_block_len =
889*7fd79137SRobert Mustacchi                     signed_factored_N_value * data_alignment_factor;
890*7fd79137SRobert Mustacchi 
891*7fd79137SRobert Mustacchi                 fp_offset = signed_factored_N_value;
892*7fd79137SRobert Mustacchi 
893*7fd79137SRobert Mustacchi             }
894*7fd79137SRobert Mustacchi             break;
895*7fd79137SRobert Mustacchi         case DW_CFA_val_expression:
896*7fd79137SRobert Mustacchi             {
897*7fd79137SRobert Mustacchi                 /* The first operand is an unsigned leb128 register
898*7fd79137SRobert Mustacchi                    number. The second is a DW_FORM_block representing a
899*7fd79137SRobert Mustacchi                    DWARF expression. The rule for the register number
900*7fd79137SRobert Mustacchi                    becomes a val_expression(E) rule. */
901*7fd79137SRobert Mustacchi                 Dwarf_Unsigned lreg = 0;
902*7fd79137SRobert Mustacchi                 Dwarf_Unsigned block_len = 0;
903*7fd79137SRobert Mustacchi 
904*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, lreg);
905*7fd79137SRobert Mustacchi                 reg_no = (reg_num_type) lreg;
906*7fd79137SRobert Mustacchi                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
907*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, block_len);
908*7fd79137SRobert Mustacchi                 localregtab[lreg].ru_is_off = 0;        /* arbitrary */
909*7fd79137SRobert Mustacchi                 localregtab[lreg].ru_value_type = DW_EXPR_VAL_EXPRESSION;
910*7fd79137SRobert Mustacchi                 localregtab[lreg].ru_offset_or_block_len = block_len;
911*7fd79137SRobert Mustacchi                 localregtab[lreg].ru_block = instr_ptr;
912*7fd79137SRobert Mustacchi                 fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr;
913*7fd79137SRobert Mustacchi 
914*7fd79137SRobert Mustacchi                 instr_ptr += block_len;
915*7fd79137SRobert Mustacchi                 fp_register = reg_no;
916*7fd79137SRobert Mustacchi 
917*7fd79137SRobert Mustacchi             }
918*7fd79137SRobert Mustacchi             break;
919*7fd79137SRobert Mustacchi 
920*7fd79137SRobert Mustacchi             /* END DWARF3 new ops. */
921*7fd79137SRobert Mustacchi 
922*7fd79137SRobert Mustacchi 
923*7fd79137SRobert Mustacchi #ifdef DW_CFA_GNU_window_save
924*7fd79137SRobert Mustacchi         case DW_CFA_GNU_window_save:
925*7fd79137SRobert Mustacchi             {
926*7fd79137SRobert Mustacchi                 /* no information: this just tells unwinder to restore
927*7fd79137SRobert Mustacchi                    the window registers from the previous frame's
928*7fd79137SRobert Mustacchi                    window save area */
929*7fd79137SRobert Mustacchi                 break;
930*7fd79137SRobert Mustacchi             }
931*7fd79137SRobert Mustacchi #endif
932*7fd79137SRobert Mustacchi #ifdef  DW_CFA_GNU_args_size
933*7fd79137SRobert Mustacchi             /* single uleb128 is the current arg area size in bytes. No
934*7fd79137SRobert Mustacchi                register exists yet to save this in */
935*7fd79137SRobert Mustacchi         case DW_CFA_GNU_args_size:
936*7fd79137SRobert Mustacchi             {
937*7fd79137SRobert Mustacchi                 Dwarf_Unsigned lreg;
938*7fd79137SRobert Mustacchi 
939*7fd79137SRobert Mustacchi                 DECODE_LEB128_UWORD(instr_ptr, lreg);
940*7fd79137SRobert Mustacchi                 reg_no = (reg_num_type) lreg;
941*7fd79137SRobert Mustacchi 
942*7fd79137SRobert Mustacchi                 break;
943*7fd79137SRobert Mustacchi             }
944*7fd79137SRobert Mustacchi #endif
945*7fd79137SRobert Mustacchi         default:
946*7fd79137SRobert Mustacchi             /* ERROR, we have an opcode we know nothing about. Memory
947*7fd79137SRobert Mustacchi                leak here, but an error like this is not supposed to
948*7fd79137SRobert Mustacchi                happen so we ignore the leak. These used to be ignored,
949*7fd79137SRobert Mustacchi                now we notice and report. */
950*7fd79137SRobert Mustacchi             SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR);
951*7fd79137SRobert Mustacchi 
952*7fd79137SRobert Mustacchi         }
953*7fd79137SRobert Mustacchi 
954*7fd79137SRobert Mustacchi         if (make_instr) {
955*7fd79137SRobert Mustacchi             instr_count++;
956*7fd79137SRobert Mustacchi 
957*7fd79137SRobert Mustacchi             curr_instr = (Dwarf_Frame_Op *)
958*7fd79137SRobert Mustacchi                 _dwarf_get_alloc(dbg, DW_DLA_FRAME_OP, 1);
959*7fd79137SRobert Mustacchi             if (curr_instr == NULL) {
960*7fd79137SRobert Mustacchi                 SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
961*7fd79137SRobert Mustacchi             }
962*7fd79137SRobert Mustacchi 
963*7fd79137SRobert Mustacchi             curr_instr->fp_base_op = fp_base_op;
964*7fd79137SRobert Mustacchi             curr_instr->fp_extended_op = fp_extended_op;
965*7fd79137SRobert Mustacchi             curr_instr->fp_register = fp_register;
966*7fd79137SRobert Mustacchi             curr_instr->fp_offset = fp_offset;
967*7fd79137SRobert Mustacchi             curr_instr->fp_instr_offset = fp_instr_offset;
968*7fd79137SRobert Mustacchi 
969*7fd79137SRobert Mustacchi             curr_instr_item = (Dwarf_Chain)
970*7fd79137SRobert Mustacchi                 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
971*7fd79137SRobert Mustacchi             if (curr_instr_item == NULL) {
972*7fd79137SRobert Mustacchi                 SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
973*7fd79137SRobert Mustacchi             }
974*7fd79137SRobert Mustacchi 
975*7fd79137SRobert Mustacchi             curr_instr_item->ch_item = curr_instr;
976*7fd79137SRobert Mustacchi             if (head_instr_chain == NULL)
977*7fd79137SRobert Mustacchi                 head_instr_chain = tail_instr_chain = curr_instr_item;
978*7fd79137SRobert Mustacchi             else {
979*7fd79137SRobert Mustacchi                 tail_instr_chain->ch_next = curr_instr_item;
980*7fd79137SRobert Mustacchi                 tail_instr_chain = curr_instr_item;
981*7fd79137SRobert Mustacchi             }
982*7fd79137SRobert Mustacchi         }
983*7fd79137SRobert Mustacchi     }
984*7fd79137SRobert Mustacchi 
985*7fd79137SRobert Mustacchi     /*
986*7fd79137SRobert Mustacchi        If frame instruction decoding was right we would stop exactly at
987*7fd79137SRobert Mustacchi        final_instr_ptr. */
988*7fd79137SRobert Mustacchi     if (instr_ptr > final_instr_ptr) {
989*7fd79137SRobert Mustacchi         SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR);
990*7fd79137SRobert Mustacchi     }
991*7fd79137SRobert Mustacchi 
992*7fd79137SRobert Mustacchi     /* Fill in the actual output table, the space the caller passed in. */
993*7fd79137SRobert Mustacchi     if (table != NULL) {
994*7fd79137SRobert Mustacchi 
995*7fd79137SRobert Mustacchi         struct Dwarf_Reg_Rule_s *t2reg = table->fr_reg;
996*7fd79137SRobert Mustacchi         struct Dwarf_Reg_Rule_s *t3reg = localregtab;
997*7fd79137SRobert Mustacchi         struct Dwarf_Reg_Rule_s *t3end = t3reg + reg_count;
998*7fd79137SRobert Mustacchi 
999*7fd79137SRobert Mustacchi         table->fr_loc = current_loc;
1000*7fd79137SRobert Mustacchi         for (; t3reg < t3end; t3reg++, t2reg++) {
1001*7fd79137SRobert Mustacchi             *t2reg = *t3reg;
1002*7fd79137SRobert Mustacchi         }
1003*7fd79137SRobert Mustacchi 
1004*7fd79137SRobert Mustacchi         /* CONSTCOND */
1005*7fd79137SRobert Mustacchi         /* Do not update the main table with the cfa_reg.
1006*7fd79137SRobert Mustacchi            Just leave cfa_reg as cfa_reg. */
1007*7fd79137SRobert Mustacchi         table->fr_cfa_rule = cfa_reg;
1008*7fd79137SRobert Mustacchi     }
1009*7fd79137SRobert Mustacchi 
1010*7fd79137SRobert Mustacchi     /* Dealloc anything remaining on stack. */
1011*7fd79137SRobert Mustacchi     for (; top_stack != NULL;) {
1012*7fd79137SRobert Mustacchi         stack_table = top_stack;
1013*7fd79137SRobert Mustacchi         top_stack = top_stack->fr_next;
1014*7fd79137SRobert Mustacchi         dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
1015*7fd79137SRobert Mustacchi     }
1016*7fd79137SRobert Mustacchi 
1017*7fd79137SRobert Mustacchi     if (make_instr) {
1018*7fd79137SRobert Mustacchi         /* Allocate list of pointers to Dwarf_Frame_Op's.  */
1019*7fd79137SRobert Mustacchi         head_instr_block = (Dwarf_Frame_Op *)
1020*7fd79137SRobert Mustacchi             _dwarf_get_alloc(dbg, DW_DLA_FRAME_BLOCK, instr_count);
1021*7fd79137SRobert Mustacchi         if (head_instr_block == NULL) {
1022*7fd79137SRobert Mustacchi             SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
1023*7fd79137SRobert Mustacchi         }
1024*7fd79137SRobert Mustacchi 
1025*7fd79137SRobert Mustacchi         /*
1026*7fd79137SRobert Mustacchi            Store pointers to Dwarf_Frame_Op's in this list and
1027*7fd79137SRobert Mustacchi            deallocate the structs that chain the Dwarf_Frame_Op's. */
1028*7fd79137SRobert Mustacchi         curr_instr_item = head_instr_chain;
1029*7fd79137SRobert Mustacchi         for (i = 0; i < instr_count; i++) {
1030*7fd79137SRobert Mustacchi             *(head_instr_block + i) =
1031*7fd79137SRobert Mustacchi                 *(Dwarf_Frame_Op *) curr_instr_item->ch_item;
1032*7fd79137SRobert Mustacchi             dealloc_instr_item = curr_instr_item;
1033*7fd79137SRobert Mustacchi             curr_instr_item = curr_instr_item->ch_next;
1034*7fd79137SRobert Mustacchi             dwarf_dealloc(dbg, dealloc_instr_item->ch_item,
1035*7fd79137SRobert Mustacchi                           DW_DLA_FRAME_OP);
1036*7fd79137SRobert Mustacchi             dwarf_dealloc(dbg, dealloc_instr_item, DW_DLA_CHAIN);
1037*7fd79137SRobert Mustacchi         }
1038*7fd79137SRobert Mustacchi         *ret_frame_instr = head_instr_block;
1039*7fd79137SRobert Mustacchi 
1040*7fd79137SRobert Mustacchi         *returned_count = (Dwarf_Sword) instr_count;
1041*7fd79137SRobert Mustacchi     } else {
1042*7fd79137SRobert Mustacchi         *returned_count = 0;
1043*7fd79137SRobert Mustacchi     }
1044*7fd79137SRobert Mustacchi     free(localregtab);
1045*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1046*7fd79137SRobert Mustacchi #undef ERROR_IF_REG_NUM_TOO_HIGH
1047*7fd79137SRobert Mustacchi #undef SIMPLE_ERROR_RETURN
1048*7fd79137SRobert Mustacchi }
1049*7fd79137SRobert Mustacchi 
1050*7fd79137SRobert Mustacchi /*  Depending on version, either read the return address register
1051*7fd79137SRobert Mustacchi     as a ubyte or as an leb number.
1052*7fd79137SRobert Mustacchi     The form of this value changed for DWARF3.
1053*7fd79137SRobert Mustacchi */
1054*7fd79137SRobert Mustacchi Dwarf_Unsigned
1055*7fd79137SRobert Mustacchi _dwarf_get_return_address_reg(Dwarf_Small * frame_ptr,
1056*7fd79137SRobert Mustacchi     int version, unsigned long *size)
1057*7fd79137SRobert Mustacchi {
1058*7fd79137SRobert Mustacchi     Dwarf_Unsigned uvalue = 0;
1059*7fd79137SRobert Mustacchi     Dwarf_Word leb128_length = 0;
1060*7fd79137SRobert Mustacchi 
1061*7fd79137SRobert Mustacchi     if (version == 1) {
1062*7fd79137SRobert Mustacchi         *size = 1;
1063*7fd79137SRobert Mustacchi         uvalue = *(unsigned char *) frame_ptr;
1064*7fd79137SRobert Mustacchi         return uvalue;
1065*7fd79137SRobert Mustacchi     }
1066*7fd79137SRobert Mustacchi     uvalue = _dwarf_decode_u_leb128(frame_ptr, &leb128_length);
1067*7fd79137SRobert Mustacchi     *size = leb128_length;
1068*7fd79137SRobert Mustacchi     return uvalue;
1069*7fd79137SRobert Mustacchi }
1070*7fd79137SRobert Mustacchi 
1071*7fd79137SRobert Mustacchi 
1072*7fd79137SRobert Mustacchi /* Trivial consumer function.
1073*7fd79137SRobert Mustacchi */
1074*7fd79137SRobert Mustacchi int
1075*7fd79137SRobert Mustacchi dwarf_get_cie_of_fde(Dwarf_Fde fde,
1076*7fd79137SRobert Mustacchi     Dwarf_Cie * cie_returned, Dwarf_Error * error)
1077*7fd79137SRobert Mustacchi {
1078*7fd79137SRobert Mustacchi     if (fde == NULL) {
1079*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
1080*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1081*7fd79137SRobert Mustacchi     }
1082*7fd79137SRobert Mustacchi 
1083*7fd79137SRobert Mustacchi     *cie_returned = fde->fd_cie;
1084*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1085*7fd79137SRobert Mustacchi 
1086*7fd79137SRobert Mustacchi }
1087*7fd79137SRobert Mustacchi 
1088*7fd79137SRobert Mustacchi int dwarf_get_cie_index(
1089*7fd79137SRobert Mustacchi     Dwarf_Cie cie,
1090*7fd79137SRobert Mustacchi     Dwarf_Signed* index,
1091*7fd79137SRobert Mustacchi     Dwarf_Error* error )
1092*7fd79137SRobert Mustacchi {
1093*7fd79137SRobert Mustacchi     if( cie == NULL )
1094*7fd79137SRobert Mustacchi     {
1095*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
1096*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1097*7fd79137SRobert Mustacchi     }
1098*7fd79137SRobert Mustacchi 
1099*7fd79137SRobert Mustacchi     *index = cie->ci_index;
1100*7fd79137SRobert Mustacchi     return (DW_DLV_OK);
1101*7fd79137SRobert Mustacchi }
1102*7fd79137SRobert Mustacchi 
1103*7fd79137SRobert Mustacchi 
1104*7fd79137SRobert Mustacchi /*
1105*7fd79137SRobert Mustacchi   For g++ .eh_frame fde and cie.
1106*7fd79137SRobert Mustacchi   the cie id is different as the
1107*7fd79137SRobert Mustacchi   definition of the cie_id in an fde
1108*7fd79137SRobert Mustacchi         is the distance back from the address of the
1109*7fd79137SRobert Mustacchi         value to the cie.
1110*7fd79137SRobert Mustacchi   Or 0 if this is a true cie.
1111*7fd79137SRobert Mustacchi   Non standard dwarf, designed this way to be
1112*7fd79137SRobert Mustacchi   convenient at run time for an allocated
1113*7fd79137SRobert Mustacchi   (mapped into memory as part of the running image) section.
1114*7fd79137SRobert Mustacchi */
1115*7fd79137SRobert Mustacchi int
1116*7fd79137SRobert Mustacchi dwarf_get_fde_list_eh(Dwarf_Debug dbg,
1117*7fd79137SRobert Mustacchi     Dwarf_Cie ** cie_data,
1118*7fd79137SRobert Mustacchi     Dwarf_Signed * cie_element_count,
1119*7fd79137SRobert Mustacchi     Dwarf_Fde ** fde_data,
1120*7fd79137SRobert Mustacchi     Dwarf_Signed * fde_element_count,
1121*7fd79137SRobert Mustacchi     Dwarf_Error * error)
1122*7fd79137SRobert Mustacchi {
1123*7fd79137SRobert Mustacchi     int res = _dwarf_load_section(dbg, &dbg->de_debug_frame_eh_gnu,error);
1124*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK) {
1125*7fd79137SRobert Mustacchi         return res;
1126*7fd79137SRobert Mustacchi     }
1127*7fd79137SRobert Mustacchi 
1128*7fd79137SRobert Mustacchi     res = _dwarf_get_fde_list_internal(dbg,
1129*7fd79137SRobert Mustacchi         cie_data,
1130*7fd79137SRobert Mustacchi         cie_element_count,
1131*7fd79137SRobert Mustacchi         fde_data,
1132*7fd79137SRobert Mustacchi         fde_element_count,
1133*7fd79137SRobert Mustacchi         dbg->de_debug_frame_eh_gnu.dss_data,
1134*7fd79137SRobert Mustacchi         dbg->de_debug_frame_eh_gnu.dss_index,
1135*7fd79137SRobert Mustacchi         dbg->de_debug_frame_eh_gnu.dss_size,
1136*7fd79137SRobert Mustacchi         /* cie_id_value */ 0,
1137*7fd79137SRobert Mustacchi         /* use_gnu_cie_calc= */ 1,
1138*7fd79137SRobert Mustacchi         error);
1139*7fd79137SRobert Mustacchi     return res;
1140*7fd79137SRobert Mustacchi }
1141*7fd79137SRobert Mustacchi 
1142*7fd79137SRobert Mustacchi 
1143*7fd79137SRobert Mustacchi 
1144*7fd79137SRobert Mustacchi /*
1145*7fd79137SRobert Mustacchi   For standard dwarf .debug_frame
1146*7fd79137SRobert Mustacchi   cie_id is -1  in a cie, and
1147*7fd79137SRobert Mustacchi   is the section offset in the .debug_frame section
1148*7fd79137SRobert Mustacchi   of the cie otherwise.  Standard dwarf
1149*7fd79137SRobert Mustacchi */
1150*7fd79137SRobert Mustacchi int
1151*7fd79137SRobert Mustacchi dwarf_get_fde_list(Dwarf_Debug dbg,
1152*7fd79137SRobert Mustacchi     Dwarf_Cie ** cie_data,
1153*7fd79137SRobert Mustacchi     Dwarf_Signed * cie_element_count,
1154*7fd79137SRobert Mustacchi     Dwarf_Fde ** fde_data,
1155*7fd79137SRobert Mustacchi     Dwarf_Signed * fde_element_count,
1156*7fd79137SRobert Mustacchi     Dwarf_Error * error)
1157*7fd79137SRobert Mustacchi {
1158*7fd79137SRobert Mustacchi     int res = _dwarf_load_section(dbg, &dbg->de_debug_frame,error);
1159*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK) {
1160*7fd79137SRobert Mustacchi         return res;
1161*7fd79137SRobert Mustacchi     }
1162*7fd79137SRobert Mustacchi 
1163*7fd79137SRobert Mustacchi     res = _dwarf_get_fde_list_internal(dbg, cie_data,
1164*7fd79137SRobert Mustacchi         cie_element_count,
1165*7fd79137SRobert Mustacchi         fde_data,
1166*7fd79137SRobert Mustacchi         fde_element_count,
1167*7fd79137SRobert Mustacchi         dbg->de_debug_frame.dss_data,
1168*7fd79137SRobert Mustacchi         dbg->de_debug_frame.dss_index,
1169*7fd79137SRobert Mustacchi         dbg->de_debug_frame.dss_size,
1170*7fd79137SRobert Mustacchi         DW_CIE_ID,
1171*7fd79137SRobert Mustacchi         /* use_gnu_cie_calc= */ 0,
1172*7fd79137SRobert Mustacchi         error);
1173*7fd79137SRobert Mustacchi 
1174*7fd79137SRobert Mustacchi     return res;
1175*7fd79137SRobert Mustacchi }
1176*7fd79137SRobert Mustacchi 
1177*7fd79137SRobert Mustacchi 
1178*7fd79137SRobert Mustacchi /*
1179*7fd79137SRobert Mustacchi    Only works on dwarf sections, not eh_frame
1180*7fd79137SRobert Mustacchi    Given a Dwarf_Die, see if it has a
1181*7fd79137SRobert Mustacchi    DW_AT_MIPS_fde attribute and if so use that
1182*7fd79137SRobert Mustacchi    to get an fde offset.
1183*7fd79137SRobert Mustacchi    Then create a Dwarf_Fde to return thru the ret_fde pointer.
1184*7fd79137SRobert Mustacchi    Also creates a cie (pointed at from the Dwarf_Fde).
1185*7fd79137SRobert Mustacchi */
1186*7fd79137SRobert Mustacchi int
1187*7fd79137SRobert Mustacchi dwarf_get_fde_for_die(Dwarf_Debug dbg,
1188*7fd79137SRobert Mustacchi     Dwarf_Die die,
1189*7fd79137SRobert Mustacchi     Dwarf_Fde * ret_fde, Dwarf_Error * error)
1190*7fd79137SRobert Mustacchi {
1191*7fd79137SRobert Mustacchi     Dwarf_Attribute attr;
1192*7fd79137SRobert Mustacchi     Dwarf_Unsigned fde_offset = 0;
1193*7fd79137SRobert Mustacchi     Dwarf_Signed signdval = 0;
1194*7fd79137SRobert Mustacchi     Dwarf_Fde new_fde = 0;
1195*7fd79137SRobert Mustacchi     unsigned char *fde_ptr = 0;
1196*7fd79137SRobert Mustacchi     unsigned char *cie_ptr = 0;
1197*7fd79137SRobert Mustacchi     Dwarf_Unsigned cie_id = 0;
1198*7fd79137SRobert Mustacchi 
1199*7fd79137SRobert Mustacchi     /* Fields for the current Cie being read. */
1200*7fd79137SRobert Mustacchi     int res = 0;
1201*7fd79137SRobert Mustacchi     int resattr = 0;
1202*7fd79137SRobert Mustacchi     int sdatares = 0;
1203*7fd79137SRobert Mustacchi 
1204*7fd79137SRobert Mustacchi     struct cie_fde_prefix_s prefix;
1205*7fd79137SRobert Mustacchi     struct cie_fde_prefix_s prefix_c;
1206*7fd79137SRobert Mustacchi 
1207*7fd79137SRobert Mustacchi     if (die == NULL) {
1208*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DIE_NULL);
1209*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1210*7fd79137SRobert Mustacchi     }
1211*7fd79137SRobert Mustacchi 
1212*7fd79137SRobert Mustacchi     resattr = dwarf_attr(die, DW_AT_MIPS_fde, &attr, error);
1213*7fd79137SRobert Mustacchi     if (resattr != DW_DLV_OK) {
1214*7fd79137SRobert Mustacchi         return resattr;
1215*7fd79137SRobert Mustacchi     }
1216*7fd79137SRobert Mustacchi 
1217*7fd79137SRobert Mustacchi     /* why is this formsdata? FIX */
1218*7fd79137SRobert Mustacchi     sdatares = dwarf_formsdata(attr, &signdval, error);
1219*7fd79137SRobert Mustacchi     if (sdatares != DW_DLV_OK) {
1220*7fd79137SRobert Mustacchi         return sdatares;
1221*7fd79137SRobert Mustacchi     }
1222*7fd79137SRobert Mustacchi 
1223*7fd79137SRobert Mustacchi     res = _dwarf_load_section(dbg, &dbg->de_debug_frame,error);
1224*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK) {
1225*7fd79137SRobert Mustacchi         return res;
1226*7fd79137SRobert Mustacchi     }
1227*7fd79137SRobert Mustacchi 
1228*7fd79137SRobert Mustacchi     fde_offset = signdval;
1229*7fd79137SRobert Mustacchi     fde_ptr = (dbg->de_debug_frame.dss_data + fde_offset);
1230*7fd79137SRobert Mustacchi 
1231*7fd79137SRobert Mustacchi 
1232*7fd79137SRobert Mustacchi     /* First read in the 'common prefix' to figure out what * we are to
1233*7fd79137SRobert Mustacchi        do with this entry. */
1234*7fd79137SRobert Mustacchi     memset(&prefix_c, 0, sizeof(prefix_c));
1235*7fd79137SRobert Mustacchi     memset(&prefix, 0, sizeof(prefix));
1236*7fd79137SRobert Mustacchi     res = dwarf_read_cie_fde_prefix(dbg, fde_ptr,
1237*7fd79137SRobert Mustacchi         dbg->de_debug_frame.dss_data,
1238*7fd79137SRobert Mustacchi         dbg->de_debug_frame.dss_index,
1239*7fd79137SRobert Mustacchi         dbg->de_debug_frame.dss_size,
1240*7fd79137SRobert Mustacchi         &prefix,
1241*7fd79137SRobert Mustacchi         error);
1242*7fd79137SRobert Mustacchi     if (res == DW_DLV_ERROR) {
1243*7fd79137SRobert Mustacchi         return res;
1244*7fd79137SRobert Mustacchi     }
1245*7fd79137SRobert Mustacchi     if (res == DW_DLV_NO_ENTRY)
1246*7fd79137SRobert Mustacchi         return res;
1247*7fd79137SRobert Mustacchi     fde_ptr = prefix.cf_addr_after_prefix;
1248*7fd79137SRobert Mustacchi     cie_id = prefix.cf_cie_id;
1249*7fd79137SRobert Mustacchi     /* Pass NULL, not section pointer, for 3rd argument.
1250*7fd79137SRobert Mustacchi        de_debug_frame.dss_data has no eh_frame relevance. */
1251*7fd79137SRobert Mustacchi     res = dwarf_create_fde_from_after_start(dbg, &prefix,
1252*7fd79137SRobert Mustacchi         (Dwarf_Small *) NULL,
1253*7fd79137SRobert Mustacchi         fde_ptr,
1254*7fd79137SRobert Mustacchi         /* use_gnu_cie_calc= */ 0,
1255*7fd79137SRobert Mustacchi         /* Dwarf_Cie = */ 0,
1256*7fd79137SRobert Mustacchi         &new_fde, error);
1257*7fd79137SRobert Mustacchi     if (res == DW_DLV_ERROR) {
1258*7fd79137SRobert Mustacchi         return res;
1259*7fd79137SRobert Mustacchi     } else if (res == DW_DLV_NO_ENTRY) {
1260*7fd79137SRobert Mustacchi         return res;
1261*7fd79137SRobert Mustacchi     }
1262*7fd79137SRobert Mustacchi     /* DW_DLV_OK */
1263*7fd79137SRobert Mustacchi 
1264*7fd79137SRobert Mustacchi     /* now read the cie corresponding to the fde */
1265*7fd79137SRobert Mustacchi     cie_ptr = new_fde->fd_section_ptr + cie_id;
1266*7fd79137SRobert Mustacchi     res = dwarf_read_cie_fde_prefix(dbg, cie_ptr,
1267*7fd79137SRobert Mustacchi         dbg->de_debug_frame.dss_data,
1268*7fd79137SRobert Mustacchi         dbg->de_debug_frame.dss_index,
1269*7fd79137SRobert Mustacchi         dbg->de_debug_frame.dss_size,
1270*7fd79137SRobert Mustacchi         &prefix_c, error);
1271*7fd79137SRobert Mustacchi     if (res == DW_DLV_ERROR) {
1272*7fd79137SRobert Mustacchi         return res;
1273*7fd79137SRobert Mustacchi     }
1274*7fd79137SRobert Mustacchi     if (res == DW_DLV_NO_ENTRY)
1275*7fd79137SRobert Mustacchi         return res;
1276*7fd79137SRobert Mustacchi 
1277*7fd79137SRobert Mustacchi     cie_ptr = prefix_c.cf_addr_after_prefix;
1278*7fd79137SRobert Mustacchi     cie_id = prefix_c.cf_cie_id;
1279*7fd79137SRobert Mustacchi 
1280*7fd79137SRobert Mustacchi     if (cie_id == DW_CIE_ID) {
1281*7fd79137SRobert Mustacchi         int res2 = 0;
1282*7fd79137SRobert Mustacchi         Dwarf_Cie new_cie = 0;
1283*7fd79137SRobert Mustacchi 
1284*7fd79137SRobert Mustacchi         /* Pass NULL, not section pointer, for 3rd argument.
1285*7fd79137SRobert Mustacchi            de_debug_frame.dss_data has no eh_frame relevance. */
1286*7fd79137SRobert Mustacchi         res2 = dwarf_create_cie_from_after_start(dbg,
1287*7fd79137SRobert Mustacchi             &prefix_c,
1288*7fd79137SRobert Mustacchi             (Dwarf_Small *) NULL,
1289*7fd79137SRobert Mustacchi             cie_ptr,
1290*7fd79137SRobert Mustacchi             /* cie_count= */ 0,
1291*7fd79137SRobert Mustacchi             /* use_gnu_cie_calc= */
1292*7fd79137SRobert Mustacchi             0, &new_cie, error);
1293*7fd79137SRobert Mustacchi         if (res2 == DW_DLV_ERROR) {
1294*7fd79137SRobert Mustacchi             dwarf_dealloc(dbg, new_fde, DW_DLA_FDE);
1295*7fd79137SRobert Mustacchi             return res;
1296*7fd79137SRobert Mustacchi         } else if (res2 == DW_DLV_NO_ENTRY) {
1297*7fd79137SRobert Mustacchi             dwarf_dealloc(dbg, new_fde, DW_DLA_FDE);
1298*7fd79137SRobert Mustacchi             return res;
1299*7fd79137SRobert Mustacchi         }
1300*7fd79137SRobert Mustacchi         new_fde->fd_cie = new_cie;
1301*7fd79137SRobert Mustacchi     } else {
1302*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE);
1303*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1304*7fd79137SRobert Mustacchi     }
1305*7fd79137SRobert Mustacchi 
1306*7fd79137SRobert Mustacchi     *ret_fde = new_fde;
1307*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1308*7fd79137SRobert Mustacchi }
1309*7fd79137SRobert Mustacchi 
1310*7fd79137SRobert Mustacchi /* A dwarf consumer operation, see the consumer library documentation.
1311*7fd79137SRobert Mustacchi */
1312*7fd79137SRobert Mustacchi int
1313*7fd79137SRobert Mustacchi dwarf_get_fde_range(Dwarf_Fde fde,
1314*7fd79137SRobert Mustacchi     Dwarf_Addr * low_pc,
1315*7fd79137SRobert Mustacchi     Dwarf_Unsigned * func_length,
1316*7fd79137SRobert Mustacchi     Dwarf_Ptr * fde_bytes,
1317*7fd79137SRobert Mustacchi     Dwarf_Unsigned * fde_byte_length,
1318*7fd79137SRobert Mustacchi     Dwarf_Off * cie_offset,
1319*7fd79137SRobert Mustacchi     Dwarf_Signed * cie_index,
1320*7fd79137SRobert Mustacchi     Dwarf_Off * fde_offset, Dwarf_Error * error)
1321*7fd79137SRobert Mustacchi {
1322*7fd79137SRobert Mustacchi     Dwarf_Debug dbg;
1323*7fd79137SRobert Mustacchi 
1324*7fd79137SRobert Mustacchi     if (fde == NULL) {
1325*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
1326*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1327*7fd79137SRobert Mustacchi     }
1328*7fd79137SRobert Mustacchi 
1329*7fd79137SRobert Mustacchi     dbg = fde->fd_dbg;
1330*7fd79137SRobert Mustacchi     if (dbg == NULL) {
1331*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
1332*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1333*7fd79137SRobert Mustacchi     }
1334*7fd79137SRobert Mustacchi 
1335*7fd79137SRobert Mustacchi 
1336*7fd79137SRobert Mustacchi     /* We have always already done the section load here, so no need to
1337*7fd79137SRobert Mustacchi        load the section. We did the section load in order to create the
1338*7fd79137SRobert Mustacchi        Dwarf_Fde pointer passed in here. */
1339*7fd79137SRobert Mustacchi 
1340*7fd79137SRobert Mustacchi 
1341*7fd79137SRobert Mustacchi     if (low_pc != NULL)
1342*7fd79137SRobert Mustacchi         *low_pc = fde->fd_initial_location;
1343*7fd79137SRobert Mustacchi     if (func_length != NULL)
1344*7fd79137SRobert Mustacchi         *func_length = fde->fd_address_range;
1345*7fd79137SRobert Mustacchi     if (fde_bytes != NULL)
1346*7fd79137SRobert Mustacchi         *fde_bytes = fde->fd_fde_start;
1347*7fd79137SRobert Mustacchi     if (fde_byte_length != NULL)
1348*7fd79137SRobert Mustacchi         *fde_byte_length = fde->fd_length;
1349*7fd79137SRobert Mustacchi     if (cie_offset != NULL)
1350*7fd79137SRobert Mustacchi         *cie_offset = fde->fd_cie_offset;
1351*7fd79137SRobert Mustacchi     if (cie_index != NULL)
1352*7fd79137SRobert Mustacchi         *cie_index = fde->fd_cie_index;
1353*7fd79137SRobert Mustacchi     if (fde_offset != NULL)
1354*7fd79137SRobert Mustacchi         *fde_offset = fde->fd_fde_start - fde->fd_section_ptr;
1355*7fd79137SRobert Mustacchi 
1356*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1357*7fd79137SRobert Mustacchi }
1358*7fd79137SRobert Mustacchi 
1359*7fd79137SRobert Mustacchi /* IRIX specific function.   The exception tables
1360*7fd79137SRobert Mustacchi    have C++ destructor information and are
1361*7fd79137SRobert Mustacchi    at present undocumented.  */
1362*7fd79137SRobert Mustacchi int
1363*7fd79137SRobert Mustacchi dwarf_get_fde_exception_info(Dwarf_Fde fde,
1364*7fd79137SRobert Mustacchi     Dwarf_Signed *
1365*7fd79137SRobert Mustacchi     offset_into_exception_tables,
1366*7fd79137SRobert Mustacchi     Dwarf_Error * error)
1367*7fd79137SRobert Mustacchi {
1368*7fd79137SRobert Mustacchi     Dwarf_Debug dbg;
1369*7fd79137SRobert Mustacchi 
1370*7fd79137SRobert Mustacchi     dbg = fde->fd_dbg;
1371*7fd79137SRobert Mustacchi     if (dbg == NULL) {
1372*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
1373*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1374*7fd79137SRobert Mustacchi     }
1375*7fd79137SRobert Mustacchi     *offset_into_exception_tables =
1376*7fd79137SRobert Mustacchi         fde->fd_offset_into_exception_tables;
1377*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1378*7fd79137SRobert Mustacchi }
1379*7fd79137SRobert Mustacchi 
1380*7fd79137SRobert Mustacchi 
1381*7fd79137SRobert Mustacchi /* A consumer code function.
1382*7fd79137SRobert Mustacchi    Given a CIE pointer, return the normal CIE data thru
1383*7fd79137SRobert Mustacchi    pointers.
1384*7fd79137SRobert Mustacchi    Special augmentation data is not returned here.
1385*7fd79137SRobert Mustacchi */
1386*7fd79137SRobert Mustacchi int
1387*7fd79137SRobert Mustacchi dwarf_get_cie_info(Dwarf_Cie cie,
1388*7fd79137SRobert Mustacchi     Dwarf_Unsigned * bytes_in_cie,
1389*7fd79137SRobert Mustacchi     Dwarf_Small * ptr_to_version,
1390*7fd79137SRobert Mustacchi     char **augmenter,
1391*7fd79137SRobert Mustacchi     Dwarf_Unsigned * code_alignment_factor,
1392*7fd79137SRobert Mustacchi     Dwarf_Signed * data_alignment_factor,
1393*7fd79137SRobert Mustacchi     Dwarf_Half * return_address_register,
1394*7fd79137SRobert Mustacchi     Dwarf_Ptr * initial_instructions,
1395*7fd79137SRobert Mustacchi     Dwarf_Unsigned * initial_instructions_length,
1396*7fd79137SRobert Mustacchi     Dwarf_Error * error)
1397*7fd79137SRobert Mustacchi {
1398*7fd79137SRobert Mustacchi     Dwarf_Debug dbg;
1399*7fd79137SRobert Mustacchi 
1400*7fd79137SRobert Mustacchi     if (cie == NULL) {
1401*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
1402*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1403*7fd79137SRobert Mustacchi     }
1404*7fd79137SRobert Mustacchi 
1405*7fd79137SRobert Mustacchi     dbg = cie->ci_dbg;
1406*7fd79137SRobert Mustacchi     if (dbg == NULL) {
1407*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_CIE_DBG_NULL);
1408*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1409*7fd79137SRobert Mustacchi     }
1410*7fd79137SRobert Mustacchi 
1411*7fd79137SRobert Mustacchi     if (ptr_to_version != NULL)
1412*7fd79137SRobert Mustacchi         *ptr_to_version = cie->ci_cie_version_number;
1413*7fd79137SRobert Mustacchi     if (augmenter != NULL)
1414*7fd79137SRobert Mustacchi         *augmenter = cie->ci_augmentation;
1415*7fd79137SRobert Mustacchi     if (code_alignment_factor != NULL)
1416*7fd79137SRobert Mustacchi         *code_alignment_factor = cie->ci_code_alignment_factor;
1417*7fd79137SRobert Mustacchi     if (data_alignment_factor != NULL)
1418*7fd79137SRobert Mustacchi         *data_alignment_factor = cie->ci_data_alignment_factor;
1419*7fd79137SRobert Mustacchi     if (return_address_register != NULL)
1420*7fd79137SRobert Mustacchi         *return_address_register = cie->ci_return_address_register;
1421*7fd79137SRobert Mustacchi     if (initial_instructions != NULL)
1422*7fd79137SRobert Mustacchi         *initial_instructions = cie->ci_cie_instr_start;
1423*7fd79137SRobert Mustacchi     if (initial_instructions_length != NULL) {
1424*7fd79137SRobert Mustacchi         *initial_instructions_length = cie->ci_length +
1425*7fd79137SRobert Mustacchi             cie->ci_length_size +
1426*7fd79137SRobert Mustacchi             cie->ci_extension_size -
1427*7fd79137SRobert Mustacchi             (cie->ci_cie_instr_start - cie->ci_cie_start);
1428*7fd79137SRobert Mustacchi 
1429*7fd79137SRobert Mustacchi     }
1430*7fd79137SRobert Mustacchi     *bytes_in_cie = (cie->ci_length);
1431*7fd79137SRobert Mustacchi     return (DW_DLV_OK);
1432*7fd79137SRobert Mustacchi }
1433*7fd79137SRobert Mustacchi 
1434*7fd79137SRobert Mustacchi /* Return the register rules for all registers at a given pc.
1435*7fd79137SRobert Mustacchi */
1436*7fd79137SRobert Mustacchi static int
1437*7fd79137SRobert Mustacchi _dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde,
1438*7fd79137SRobert Mustacchi     Dwarf_Addr pc_requested,
1439*7fd79137SRobert Mustacchi     Dwarf_Frame table,
1440*7fd79137SRobert Mustacchi     Dwarf_Half cfa_reg_col_num,
1441*7fd79137SRobert Mustacchi     Dwarf_Error * error)
1442*7fd79137SRobert Mustacchi {
1443*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
1444*7fd79137SRobert Mustacchi     Dwarf_Cie cie = 0;
1445*7fd79137SRobert Mustacchi     int dw_err = 0;
1446*7fd79137SRobert Mustacchi     Dwarf_Sword icount = 0;
1447*7fd79137SRobert Mustacchi     int res = 0;
1448*7fd79137SRobert Mustacchi 
1449*7fd79137SRobert Mustacchi     if (fde == NULL) {
1450*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
1451*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1452*7fd79137SRobert Mustacchi     }
1453*7fd79137SRobert Mustacchi 
1454*7fd79137SRobert Mustacchi     dbg = fde->fd_dbg;
1455*7fd79137SRobert Mustacchi     if (dbg == NULL) {
1456*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
1457*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1458*7fd79137SRobert Mustacchi     }
1459*7fd79137SRobert Mustacchi 
1460*7fd79137SRobert Mustacchi     if (pc_requested < fde->fd_initial_location ||
1461*7fd79137SRobert Mustacchi         pc_requested >=
1462*7fd79137SRobert Mustacchi         fde->fd_initial_location + fde->fd_address_range) {
1463*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
1464*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1465*7fd79137SRobert Mustacchi     }
1466*7fd79137SRobert Mustacchi 
1467*7fd79137SRobert Mustacchi     cie = fde->fd_cie;
1468*7fd79137SRobert Mustacchi     if (cie->ci_initial_table == NULL) {
1469*7fd79137SRobert Mustacchi         cie->ci_initial_table = _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
1470*7fd79137SRobert Mustacchi 
1471*7fd79137SRobert Mustacchi         if (cie->ci_initial_table == NULL) {
1472*7fd79137SRobert Mustacchi             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
1473*7fd79137SRobert Mustacchi             return (DW_DLV_ERROR);
1474*7fd79137SRobert Mustacchi         }
1475*7fd79137SRobert Mustacchi         _dwarf_init_regrule_table(cie->ci_initial_table->fr_reg,
1476*7fd79137SRobert Mustacchi             dbg->de_frame_reg_rules_entry_count,
1477*7fd79137SRobert Mustacchi             dbg->de_frame_rule_initial_value);
1478*7fd79137SRobert Mustacchi         _dwarf_init_regrule_table(&cie->ci_initial_table->fr_cfa_rule,
1479*7fd79137SRobert Mustacchi             1, dbg->de_frame_rule_initial_value);
1480*7fd79137SRobert Mustacchi         res = _dwarf_exec_frame_instr( /* make_instr= */ false,
1481*7fd79137SRobert Mustacchi             /* ret_frame_instr= */ NULL,
1482*7fd79137SRobert Mustacchi             /* search_pc */ false,
1483*7fd79137SRobert Mustacchi             /* search_pc_val */ 0,
1484*7fd79137SRobert Mustacchi             /* location */ 0,
1485*7fd79137SRobert Mustacchi             cie->ci_cie_instr_start,
1486*7fd79137SRobert Mustacchi             cie->ci_cie_instr_start + (cie->ci_length +
1487*7fd79137SRobert Mustacchi                 cie->ci_length_size +
1488*7fd79137SRobert Mustacchi                 cie->ci_extension_size -
1489*7fd79137SRobert Mustacchi                 (cie->ci_cie_instr_start -
1490*7fd79137SRobert Mustacchi                 cie->ci_cie_start)),
1491*7fd79137SRobert Mustacchi             cie->ci_initial_table, cie, dbg,
1492*7fd79137SRobert Mustacchi             cfa_reg_col_num, &icount,
1493*7fd79137SRobert Mustacchi             &dw_err);
1494*7fd79137SRobert Mustacchi         if (res == DW_DLV_ERROR) {
1495*7fd79137SRobert Mustacchi             _dwarf_error(dbg, error, dw_err);
1496*7fd79137SRobert Mustacchi             return (res);
1497*7fd79137SRobert Mustacchi         } else if (res == DW_DLV_NO_ENTRY) {
1498*7fd79137SRobert Mustacchi             return res;
1499*7fd79137SRobert Mustacchi         }
1500*7fd79137SRobert Mustacchi     }
1501*7fd79137SRobert Mustacchi 
1502*7fd79137SRobert Mustacchi     {
1503*7fd79137SRobert Mustacchi         Dwarf_Small *instr_end = fde->fd_fde_instr_start +
1504*7fd79137SRobert Mustacchi             fde->fd_length +
1505*7fd79137SRobert Mustacchi             fde->fd_length_size +
1506*7fd79137SRobert Mustacchi             fde->fd_extension_size - (fde->fd_fde_instr_start -
1507*7fd79137SRobert Mustacchi                                       fde->fd_fde_start);
1508*7fd79137SRobert Mustacchi 
1509*7fd79137SRobert Mustacchi         res = _dwarf_exec_frame_instr( /* make_instr= */ false,
1510*7fd79137SRobert Mustacchi             /* ret_frame_instr= */ NULL,
1511*7fd79137SRobert Mustacchi             /* search_pc */ true,
1512*7fd79137SRobert Mustacchi             /* search_pc_val */ pc_requested,
1513*7fd79137SRobert Mustacchi             fde->fd_initial_location,
1514*7fd79137SRobert Mustacchi             fde->fd_fde_instr_start,
1515*7fd79137SRobert Mustacchi             instr_end,
1516*7fd79137SRobert Mustacchi             table,
1517*7fd79137SRobert Mustacchi             cie, dbg,
1518*7fd79137SRobert Mustacchi             cfa_reg_col_num, &icount,
1519*7fd79137SRobert Mustacchi             &dw_err);
1520*7fd79137SRobert Mustacchi     }
1521*7fd79137SRobert Mustacchi     if (res == DW_DLV_ERROR) {
1522*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, dw_err);
1523*7fd79137SRobert Mustacchi         return (res);
1524*7fd79137SRobert Mustacchi     } else if (res == DW_DLV_NO_ENTRY) {
1525*7fd79137SRobert Mustacchi         return res;
1526*7fd79137SRobert Mustacchi     }
1527*7fd79137SRobert Mustacchi 
1528*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1529*7fd79137SRobert Mustacchi }
1530*7fd79137SRobert Mustacchi 
1531*7fd79137SRobert Mustacchi /* A consumer call for efficiently getting the register info
1532*7fd79137SRobert Mustacchi    for all registers in one call.
1533*7fd79137SRobert Mustacchi 
1534*7fd79137SRobert Mustacchi    The output table rules array is size DW_REG_TABLE_SIZE.
1535*7fd79137SRobert Mustacchi    The frame info  rules array in fde_table is of size
1536*7fd79137SRobert Mustacchi    DW_REG_TABLE_SIZE too.
1537*7fd79137SRobert Mustacchi 
1538*7fd79137SRobert Mustacchi    This interface  really only works well with MIPS/IRIX
1539*7fd79137SRobert Mustacchi    where DW_FRAME_CFA_COL is zero (in that case it's safe).
1540*7fd79137SRobert Mustacchi 
1541*7fd79137SRobert Mustacchi    It is also restricted to the case  where
1542*7fd79137SRobert Mustacchi    DW_REG_TABLE_SIZE == DW_FRAME_LAST_REG_NUM  ==
1543*7fd79137SRobert Mustacchi    dbg->de_frame_reg_rules_entry_count (true for MIPS/IRIX).
1544*7fd79137SRobert Mustacchi    If this condition is not met calling this routine can result in
1545*7fd79137SRobert Mustacchi    incorrect output or in memory corruption.
1546*7fd79137SRobert Mustacchi 
1547*7fd79137SRobert Mustacchi    It is much better to use dwarf_get_fde_info_for_all_regs3()
1548*7fd79137SRobert Mustacchi    instead of this interface.
1549*7fd79137SRobert Mustacchi */
1550*7fd79137SRobert Mustacchi int
1551*7fd79137SRobert Mustacchi dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde,
1552*7fd79137SRobert Mustacchi     Dwarf_Addr pc_requested,
1553*7fd79137SRobert Mustacchi     Dwarf_Regtable * reg_table,
1554*7fd79137SRobert Mustacchi     Dwarf_Addr * row_pc,
1555*7fd79137SRobert Mustacchi     Dwarf_Error * error)
1556*7fd79137SRobert Mustacchi {
1557*7fd79137SRobert Mustacchi 
1558*7fd79137SRobert Mustacchi     /* Table size: DW_REG_TABLE_SIZE */
1559*7fd79137SRobert Mustacchi     struct Dwarf_Frame_s fde_table;
1560*7fd79137SRobert Mustacchi     Dwarf_Sword i = 0;
1561*7fd79137SRobert Mustacchi     struct Dwarf_Reg_Rule_s *rule = NULL;
1562*7fd79137SRobert Mustacchi     struct Dwarf_Regtable_Entry_s *out_rule = NULL;
1563*7fd79137SRobert Mustacchi     int res = 0;
1564*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
1565*7fd79137SRobert Mustacchi 
1566*7fd79137SRobert Mustacchi     /* For this interface the size is fixed at compile time. */
1567*7fd79137SRobert Mustacchi     int output_table_real_data_size = DW_REG_TABLE_SIZE;
1568*7fd79137SRobert Mustacchi 
1569*7fd79137SRobert Mustacchi     FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1570*7fd79137SRobert Mustacchi 
1571*7fd79137SRobert Mustacchi     res = dwarf_initialize_fde_table(dbg, &fde_table,
1572*7fd79137SRobert Mustacchi         output_table_real_data_size,
1573*7fd79137SRobert Mustacchi         error);
1574*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK)
1575*7fd79137SRobert Mustacchi         return res;
1576*7fd79137SRobert Mustacchi 
1577*7fd79137SRobert Mustacchi     /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks
1578*7fd79137SRobert Mustacchi      */
1579*7fd79137SRobert Mustacchi     res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested,
1580*7fd79137SRobert Mustacchi         &fde_table, dbg->de_frame_cfa_col_number, error);
1581*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK) {
1582*7fd79137SRobert Mustacchi         dwarf_free_fde_table(&fde_table);
1583*7fd79137SRobert Mustacchi         return res;
1584*7fd79137SRobert Mustacchi     }
1585*7fd79137SRobert Mustacchi 
1586*7fd79137SRobert Mustacchi     out_rule = &reg_table->rules[0];
1587*7fd79137SRobert Mustacchi     rule = &fde_table.fr_reg[0];
1588*7fd79137SRobert Mustacchi     for (i = 0; i < output_table_real_data_size;
1589*7fd79137SRobert Mustacchi          i++, ++out_rule, ++rule) {
1590*7fd79137SRobert Mustacchi         out_rule->dw_offset_relevant = rule->ru_is_off;
1591*7fd79137SRobert Mustacchi         out_rule->dw_value_type = rule->ru_value_type;
1592*7fd79137SRobert Mustacchi         out_rule->dw_regnum = rule->ru_register;
1593*7fd79137SRobert Mustacchi         out_rule->dw_offset = rule->ru_offset_or_block_len;
1594*7fd79137SRobert Mustacchi     }
1595*7fd79137SRobert Mustacchi     for (; i < DW_REG_TABLE_SIZE; ++i, ++out_rule) {
1596*7fd79137SRobert Mustacchi         out_rule->dw_offset_relevant = 0;
1597*7fd79137SRobert Mustacchi         out_rule->dw_value_type = DW_EXPR_OFFSET;
1598*7fd79137SRobert Mustacchi         out_rule->dw_regnum = dbg->de_frame_undefined_value_number;
1599*7fd79137SRobert Mustacchi         out_rule->dw_offset = 0;
1600*7fd79137SRobert Mustacchi     }
1601*7fd79137SRobert Mustacchi 
1602*7fd79137SRobert Mustacchi     /* The test is just in case it's not inside the table. For non-MIPS
1603*7fd79137SRobert Mustacchi        it could be outside the table and that is just fine, it was
1604*7fd79137SRobert Mustacchi        really a mistake to put it in the table in 1993.  */
1605*7fd79137SRobert Mustacchi     /* CONSTCOND */
1606*7fd79137SRobert Mustacchi     if (dbg->de_frame_cfa_col_number < DW_REG_TABLE_SIZE) {
1607*7fd79137SRobert Mustacchi         out_rule = &reg_table->rules[dbg->de_frame_cfa_col_number];
1608*7fd79137SRobert Mustacchi         out_rule->dw_offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
1609*7fd79137SRobert Mustacchi         out_rule->dw_value_type = fde_table.fr_cfa_rule.ru_value_type;
1610*7fd79137SRobert Mustacchi         out_rule->dw_regnum = fde_table.fr_cfa_rule.ru_register;
1611*7fd79137SRobert Mustacchi         out_rule->dw_offset =
1612*7fd79137SRobert Mustacchi             fde_table.fr_cfa_rule.ru_offset_or_block_len;
1613*7fd79137SRobert Mustacchi     }
1614*7fd79137SRobert Mustacchi 
1615*7fd79137SRobert Mustacchi     if (row_pc != NULL)
1616*7fd79137SRobert Mustacchi         *row_pc = fde_table.fr_loc;
1617*7fd79137SRobert Mustacchi     dwarf_free_fde_table(&fde_table);
1618*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1619*7fd79137SRobert Mustacchi }
1620*7fd79137SRobert Mustacchi 
1621*7fd79137SRobert Mustacchi /* A consumer call for efficiently getting the register info
1622*7fd79137SRobert Mustacchi    for all registers in one call.
1623*7fd79137SRobert Mustacchi 
1624*7fd79137SRobert Mustacchi    The output table rules array is size output_table_real_data_size.
1625*7fd79137SRobert Mustacchi    (normally  DW_REG_TABLE_SIZE).
1626*7fd79137SRobert Mustacchi    The frame info  rules array in fde_table is normally of size
1627*7fd79137SRobert Mustacchi    DW_FRAME_LAST_REG_NUM.
1628*7fd79137SRobert Mustacchi */
1629*7fd79137SRobert Mustacchi int
1630*7fd79137SRobert Mustacchi dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde,
1631*7fd79137SRobert Mustacchi     Dwarf_Addr pc_requested,
1632*7fd79137SRobert Mustacchi     Dwarf_Regtable3 * reg_table,
1633*7fd79137SRobert Mustacchi     Dwarf_Addr * row_pc,
1634*7fd79137SRobert Mustacchi     Dwarf_Error * error)
1635*7fd79137SRobert Mustacchi {
1636*7fd79137SRobert Mustacchi 
1637*7fd79137SRobert Mustacchi     struct Dwarf_Frame_s fde_table;
1638*7fd79137SRobert Mustacchi     Dwarf_Sword i = 0;
1639*7fd79137SRobert Mustacchi     int res = 0;
1640*7fd79137SRobert Mustacchi     struct Dwarf_Reg_Rule_s *rule = NULL;
1641*7fd79137SRobert Mustacchi     struct Dwarf_Regtable_Entry3_s *out_rule = NULL;
1642*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
1643*7fd79137SRobert Mustacchi     int output_table_real_data_size = reg_table->rt3_reg_table_size;
1644*7fd79137SRobert Mustacchi 
1645*7fd79137SRobert Mustacchi     FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1646*7fd79137SRobert Mustacchi 
1647*7fd79137SRobert Mustacchi     output_table_real_data_size =
1648*7fd79137SRobert Mustacchi         MIN(output_table_real_data_size,
1649*7fd79137SRobert Mustacchi             dbg->de_frame_reg_rules_entry_count);
1650*7fd79137SRobert Mustacchi 
1651*7fd79137SRobert Mustacchi     res = dwarf_initialize_fde_table(dbg, &fde_table,
1652*7fd79137SRobert Mustacchi        output_table_real_data_size,
1653*7fd79137SRobert Mustacchi        error);
1654*7fd79137SRobert Mustacchi 
1655*7fd79137SRobert Mustacchi     /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks
1656*7fd79137SRobert Mustacchi      */
1657*7fd79137SRobert Mustacchi     res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested,
1658*7fd79137SRobert Mustacchi         &fde_table,
1659*7fd79137SRobert Mustacchi         dbg->de_frame_cfa_col_number,
1660*7fd79137SRobert Mustacchi         error);
1661*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK) {
1662*7fd79137SRobert Mustacchi         dwarf_free_fde_table(&fde_table);
1663*7fd79137SRobert Mustacchi         return res;
1664*7fd79137SRobert Mustacchi     }
1665*7fd79137SRobert Mustacchi 
1666*7fd79137SRobert Mustacchi     out_rule = &reg_table->rt3_rules[0];
1667*7fd79137SRobert Mustacchi     rule = &fde_table.fr_reg[0];
1668*7fd79137SRobert Mustacchi     for (i = 0; i < output_table_real_data_size;
1669*7fd79137SRobert Mustacchi          i++, ++out_rule, ++rule) {
1670*7fd79137SRobert Mustacchi         out_rule->dw_offset_relevant = rule->ru_is_off;
1671*7fd79137SRobert Mustacchi         out_rule->dw_value_type = rule->ru_value_type;
1672*7fd79137SRobert Mustacchi         out_rule->dw_regnum = rule->ru_register;
1673*7fd79137SRobert Mustacchi         out_rule->dw_offset_or_block_len = rule->ru_offset_or_block_len;
1674*7fd79137SRobert Mustacchi         out_rule->dw_block_ptr = rule->ru_block;
1675*7fd79137SRobert Mustacchi     }
1676*7fd79137SRobert Mustacchi     for (; i < reg_table->rt3_reg_table_size; i++, ++out_rule) {
1677*7fd79137SRobert Mustacchi         out_rule->dw_offset_relevant = 0;
1678*7fd79137SRobert Mustacchi         out_rule->dw_value_type = DW_EXPR_OFFSET;
1679*7fd79137SRobert Mustacchi         out_rule->dw_regnum = dbg->de_frame_undefined_value_number;
1680*7fd79137SRobert Mustacchi         out_rule->dw_offset_or_block_len = 0;
1681*7fd79137SRobert Mustacchi         out_rule->dw_block_ptr = 0;
1682*7fd79137SRobert Mustacchi     }
1683*7fd79137SRobert Mustacchi     reg_table->rt3_cfa_rule.dw_offset_relevant =
1684*7fd79137SRobert Mustacchi         fde_table.fr_cfa_rule.ru_is_off;
1685*7fd79137SRobert Mustacchi     reg_table->rt3_cfa_rule.dw_value_type =
1686*7fd79137SRobert Mustacchi         fde_table.fr_cfa_rule.ru_value_type;
1687*7fd79137SRobert Mustacchi     reg_table->rt3_cfa_rule.dw_regnum =
1688*7fd79137SRobert Mustacchi         fde_table.fr_cfa_rule.ru_register;
1689*7fd79137SRobert Mustacchi     reg_table->rt3_cfa_rule.dw_offset_or_block_len =
1690*7fd79137SRobert Mustacchi         fde_table.fr_cfa_rule.ru_offset_or_block_len;
1691*7fd79137SRobert Mustacchi     reg_table->rt3_cfa_rule.dw_block_ptr =
1692*7fd79137SRobert Mustacchi         fde_table.fr_cfa_rule.ru_block;
1693*7fd79137SRobert Mustacchi 
1694*7fd79137SRobert Mustacchi     if (row_pc != NULL)
1695*7fd79137SRobert Mustacchi         *row_pc = fde_table.fr_loc;
1696*7fd79137SRobert Mustacchi 
1697*7fd79137SRobert Mustacchi     dwarf_free_fde_table(&fde_table);
1698*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1699*7fd79137SRobert Mustacchi }
1700*7fd79137SRobert Mustacchi 
1701*7fd79137SRobert Mustacchi 
1702*7fd79137SRobert Mustacchi /* Gets the register info for a single register at a given PC value
1703*7fd79137SRobert Mustacchi    for the FDE specified.
1704*7fd79137SRobert Mustacchi 
1705*7fd79137SRobert Mustacchi    This is the old MIPS interface and should no longer be used.
1706*7fd79137SRobert Mustacchi    Use dwarf_get_fde_info_for_reg3() instead.
1707*7fd79137SRobert Mustacchi */
1708*7fd79137SRobert Mustacchi int
1709*7fd79137SRobert Mustacchi dwarf_get_fde_info_for_reg(Dwarf_Fde fde,
1710*7fd79137SRobert Mustacchi     Dwarf_Half table_column,
1711*7fd79137SRobert Mustacchi     Dwarf_Addr pc_requested,
1712*7fd79137SRobert Mustacchi     Dwarf_Signed * offset_relevant,
1713*7fd79137SRobert Mustacchi     Dwarf_Signed * register_num,
1714*7fd79137SRobert Mustacchi     Dwarf_Signed * offset,
1715*7fd79137SRobert Mustacchi     Dwarf_Addr * row_pc, Dwarf_Error * error)
1716*7fd79137SRobert Mustacchi {
1717*7fd79137SRobert Mustacchi     struct Dwarf_Frame_s fde_table;
1718*7fd79137SRobert Mustacchi     int res = DW_DLV_ERROR;
1719*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
1720*7fd79137SRobert Mustacchi     int output_table_real_data_size = 0;
1721*7fd79137SRobert Mustacchi 
1722*7fd79137SRobert Mustacchi     FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1723*7fd79137SRobert Mustacchi     output_table_real_data_size = dbg->de_frame_reg_rules_entry_count;
1724*7fd79137SRobert Mustacchi 
1725*7fd79137SRobert Mustacchi     res = dwarf_initialize_fde_table(dbg, &fde_table,
1726*7fd79137SRobert Mustacchi         output_table_real_data_size,
1727*7fd79137SRobert Mustacchi         error);
1728*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK)
1729*7fd79137SRobert Mustacchi         return res;
1730*7fd79137SRobert Mustacchi 
1731*7fd79137SRobert Mustacchi     if (table_column >= output_table_real_data_size) {
1732*7fd79137SRobert Mustacchi         dwarf_free_fde_table(&fde_table);
1733*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
1734*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1735*7fd79137SRobert Mustacchi     }
1736*7fd79137SRobert Mustacchi 
1737*7fd79137SRobert Mustacchi     /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks
1738*7fd79137SRobert Mustacchi      */
1739*7fd79137SRobert Mustacchi     res =
1740*7fd79137SRobert Mustacchi         _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
1741*7fd79137SRobert Mustacchi             dbg->de_frame_cfa_col_number, error);
1742*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK) {
1743*7fd79137SRobert Mustacchi         dwarf_free_fde_table(&fde_table);
1744*7fd79137SRobert Mustacchi         return res;
1745*7fd79137SRobert Mustacchi     }
1746*7fd79137SRobert Mustacchi 
1747*7fd79137SRobert Mustacchi     if (fde_table.fr_reg[table_column].ru_value_type != DW_EXPR_OFFSET) {
1748*7fd79137SRobert Mustacchi         /* The problem here is that this interface cannot deal with
1749*7fd79137SRobert Mustacchi            other sorts of (newer) dwarf frame values.  Code must
1750*7fd79137SRobert Mustacchi            use dwarf_get_fde_info_for_reg3() to get these
1751*7fd79137SRobert Mustacchi            values correctly.  We error rather than return
1752*7fd79137SRobert Mustacchi            misleading incomplete data. */
1753*7fd79137SRobert Mustacchi         dwarf_free_fde_table(&fde_table);
1754*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error,
1755*7fd79137SRobert Mustacchi             DW_DLE_FRAME_REGISTER_UNREPRESENTABLE);
1756*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1757*7fd79137SRobert Mustacchi     }
1758*7fd79137SRobert Mustacchi     if(table_column == dbg->de_frame_cfa_col_number) {
1759*7fd79137SRobert Mustacchi         if (register_num != NULL)
1760*7fd79137SRobert Mustacchi             *register_num = fde_table.fr_cfa_rule.ru_register;
1761*7fd79137SRobert Mustacchi         if (offset != NULL)
1762*7fd79137SRobert Mustacchi             *offset = fde_table.fr_cfa_rule.ru_offset_or_block_len;
1763*7fd79137SRobert Mustacchi         if (row_pc != NULL)
1764*7fd79137SRobert Mustacchi             *row_pc = fde_table.fr_loc;
1765*7fd79137SRobert Mustacchi         *offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
1766*7fd79137SRobert Mustacchi 
1767*7fd79137SRobert Mustacchi     } else {
1768*7fd79137SRobert Mustacchi         if (register_num != NULL)
1769*7fd79137SRobert Mustacchi             *register_num = fde_table.fr_reg[table_column].ru_register;
1770*7fd79137SRobert Mustacchi         if (offset != NULL)
1771*7fd79137SRobert Mustacchi             *offset = fde_table.fr_reg[table_column].ru_offset_or_block_len;
1772*7fd79137SRobert Mustacchi         if (row_pc != NULL)
1773*7fd79137SRobert Mustacchi             *row_pc = fde_table.fr_loc;
1774*7fd79137SRobert Mustacchi 
1775*7fd79137SRobert Mustacchi         *offset_relevant = fde_table.fr_reg[table_column].ru_is_off;
1776*7fd79137SRobert Mustacchi     }
1777*7fd79137SRobert Mustacchi     dwarf_free_fde_table(&fde_table);
1778*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1779*7fd79137SRobert Mustacchi }
1780*7fd79137SRobert Mustacchi 
1781*7fd79137SRobert Mustacchi /* In this interface, table_column of DW_FRAME_CFA_COL
1782*7fd79137SRobert Mustacchi    is not meaningful.
1783*7fd79137SRobert Mustacchi    Use  dwarf_get_fde_info_for_cfa_reg3() to get the CFA.
1784*7fd79137SRobert Mustacchi    Call dwarf_set_frame_cfa_value() to set the correct column
1785*7fd79137SRobert Mustacchi    after calling dwarf_init()
1786*7fd79137SRobert Mustacchi    (DW_FRAME_CFA_COL3 is a sensible column to use).
1787*7fd79137SRobert Mustacchi */
1788*7fd79137SRobert Mustacchi int
1789*7fd79137SRobert Mustacchi dwarf_get_fde_info_for_reg3(Dwarf_Fde fde,
1790*7fd79137SRobert Mustacchi     Dwarf_Half table_column,
1791*7fd79137SRobert Mustacchi     Dwarf_Addr pc_requested,
1792*7fd79137SRobert Mustacchi     Dwarf_Small * value_type,
1793*7fd79137SRobert Mustacchi     Dwarf_Signed * offset_relevant,
1794*7fd79137SRobert Mustacchi     Dwarf_Signed * register_num,
1795*7fd79137SRobert Mustacchi     Dwarf_Signed * offset_or_block_len,
1796*7fd79137SRobert Mustacchi     Dwarf_Ptr * block_ptr,
1797*7fd79137SRobert Mustacchi     Dwarf_Addr * row_pc_out,
1798*7fd79137SRobert Mustacchi     Dwarf_Error * error)
1799*7fd79137SRobert Mustacchi {
1800*7fd79137SRobert Mustacchi     struct Dwarf_Frame_s fde_table;
1801*7fd79137SRobert Mustacchi     int res = DW_DLV_ERROR;
1802*7fd79137SRobert Mustacchi 
1803*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
1804*7fd79137SRobert Mustacchi     int table_real_data_size = 0;
1805*7fd79137SRobert Mustacchi 
1806*7fd79137SRobert Mustacchi     FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1807*7fd79137SRobert Mustacchi     table_real_data_size = dbg->de_frame_reg_rules_entry_count;
1808*7fd79137SRobert Mustacchi     res = dwarf_initialize_fde_table(dbg, &fde_table,
1809*7fd79137SRobert Mustacchi         table_real_data_size, error);
1810*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK)
1811*7fd79137SRobert Mustacchi         return res;
1812*7fd79137SRobert Mustacchi     if (table_column >= table_real_data_size) {
1813*7fd79137SRobert Mustacchi         dwarf_free_fde_table(&fde_table);
1814*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
1815*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1816*7fd79137SRobert Mustacchi     }
1817*7fd79137SRobert Mustacchi 
1818*7fd79137SRobert Mustacchi     /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks
1819*7fd79137SRobert Mustacchi      */
1820*7fd79137SRobert Mustacchi     res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
1821*7fd79137SRobert Mustacchi         dbg->de_frame_cfa_col_number,
1822*7fd79137SRobert Mustacchi         error);
1823*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK) {
1824*7fd79137SRobert Mustacchi         dwarf_free_fde_table(&fde_table);
1825*7fd79137SRobert Mustacchi         return res;
1826*7fd79137SRobert Mustacchi     }
1827*7fd79137SRobert Mustacchi 
1828*7fd79137SRobert Mustacchi     if (register_num != NULL)
1829*7fd79137SRobert Mustacchi         *register_num = fde_table.fr_reg[table_column].ru_register;
1830*7fd79137SRobert Mustacchi     if (offset_or_block_len != NULL)
1831*7fd79137SRobert Mustacchi         *offset_or_block_len =
1832*7fd79137SRobert Mustacchi             fde_table.fr_reg[table_column].ru_offset_or_block_len;
1833*7fd79137SRobert Mustacchi     if (row_pc_out != NULL)
1834*7fd79137SRobert Mustacchi         *row_pc_out = fde_table.fr_loc;
1835*7fd79137SRobert Mustacchi     if (block_ptr)
1836*7fd79137SRobert Mustacchi         *block_ptr = fde_table.fr_reg[table_column].ru_block;
1837*7fd79137SRobert Mustacchi 
1838*7fd79137SRobert Mustacchi     /* Without value_type the data cannot be understood, so we insist
1839*7fd79137SRobert Mustacchi        on it being present, we don't test it. */
1840*7fd79137SRobert Mustacchi     *value_type = fde_table.fr_reg[table_column].ru_value_type;
1841*7fd79137SRobert Mustacchi     *offset_relevant = (fde_table.fr_reg[table_column].ru_is_off);
1842*7fd79137SRobert Mustacchi     dwarf_free_fde_table(&fde_table);
1843*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1844*7fd79137SRobert Mustacchi 
1845*7fd79137SRobert Mustacchi }
1846*7fd79137SRobert Mustacchi 
1847*7fd79137SRobert Mustacchi /* For latest DWARF, this is the preferred interface.
1848*7fd79137SRobert Mustacchi    It more portably deals with the  CFA by not
1849*7fd79137SRobert Mustacchi    making the CFA a column number, which means
1850*7fd79137SRobert Mustacchi    DW_FRAME_CFA_COL3 becomes, like DW_CFA_SAME_VALUE,
1851*7fd79137SRobert Mustacchi    a special value, not something one uses as an index.
1852*7fd79137SRobert Mustacchi 
1853*7fd79137SRobert Mustacchi    Call dwarf_set_frame_cfa_value() to set the correct column
1854*7fd79137SRobert Mustacchi    after calling dwarf_init()
1855*7fd79137SRobert Mustacchi    (DW_FRAME_CFA_COL3 is a sensible column to use, and
1856*7fd79137SRobert Mustacchi    is the default unless '--enable-oldframecol'
1857*7fd79137SRobert Mustacchi    is used to configure libdwarf).  */
1858*7fd79137SRobert Mustacchi int
1859*7fd79137SRobert Mustacchi dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde,
1860*7fd79137SRobert Mustacchi     Dwarf_Addr pc_requested,
1861*7fd79137SRobert Mustacchi     Dwarf_Small * value_type,
1862*7fd79137SRobert Mustacchi     Dwarf_Signed * offset_relevant,
1863*7fd79137SRobert Mustacchi     Dwarf_Signed * register_num,
1864*7fd79137SRobert Mustacchi     Dwarf_Signed * offset_or_block_len,
1865*7fd79137SRobert Mustacchi     Dwarf_Ptr * block_ptr,
1866*7fd79137SRobert Mustacchi     Dwarf_Addr * row_pc_out,
1867*7fd79137SRobert Mustacchi     Dwarf_Error * error)
1868*7fd79137SRobert Mustacchi {
1869*7fd79137SRobert Mustacchi     struct Dwarf_Frame_s fde_table;
1870*7fd79137SRobert Mustacchi     int res = DW_DLV_ERROR;
1871*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
1872*7fd79137SRobert Mustacchi 
1873*7fd79137SRobert Mustacchi     int table_real_data_size = 0;
1874*7fd79137SRobert Mustacchi 
1875*7fd79137SRobert Mustacchi     FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1876*7fd79137SRobert Mustacchi 
1877*7fd79137SRobert Mustacchi     table_real_data_size = dbg->de_frame_reg_rules_entry_count;
1878*7fd79137SRobert Mustacchi     res = dwarf_initialize_fde_table(dbg, &fde_table,
1879*7fd79137SRobert Mustacchi         table_real_data_size, error);
1880*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK)
1881*7fd79137SRobert Mustacchi         return res;
1882*7fd79137SRobert Mustacchi     res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
1883*7fd79137SRobert Mustacchi           dbg->de_frame_cfa_col_number,error);
1884*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK) {
1885*7fd79137SRobert Mustacchi         dwarf_free_fde_table(&fde_table);
1886*7fd79137SRobert Mustacchi         return res;
1887*7fd79137SRobert Mustacchi     }
1888*7fd79137SRobert Mustacchi 
1889*7fd79137SRobert Mustacchi     if (register_num != NULL)
1890*7fd79137SRobert Mustacchi         *register_num = fde_table.fr_cfa_rule.ru_register;
1891*7fd79137SRobert Mustacchi     if (offset_or_block_len != NULL)
1892*7fd79137SRobert Mustacchi         *offset_or_block_len =
1893*7fd79137SRobert Mustacchi             fde_table.fr_cfa_rule.ru_offset_or_block_len;
1894*7fd79137SRobert Mustacchi     if (row_pc_out != NULL)
1895*7fd79137SRobert Mustacchi         *row_pc_out = fde_table.fr_loc;
1896*7fd79137SRobert Mustacchi     if (block_ptr)
1897*7fd79137SRobert Mustacchi         *block_ptr = fde_table.fr_cfa_rule.ru_block;
1898*7fd79137SRobert Mustacchi 
1899*7fd79137SRobert Mustacchi     /* Without value_type the data cannot be understood, so we insist
1900*7fd79137SRobert Mustacchi        on it being present, we don't test it. */
1901*7fd79137SRobert Mustacchi     *value_type = fde_table.fr_cfa_rule.ru_value_type;
1902*7fd79137SRobert Mustacchi     *offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
1903*7fd79137SRobert Mustacchi     dwarf_free_fde_table(&fde_table);
1904*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1905*7fd79137SRobert Mustacchi }
1906*7fd79137SRobert Mustacchi 
1907*7fd79137SRobert Mustacchi 
1908*7fd79137SRobert Mustacchi 
1909*7fd79137SRobert Mustacchi /*
1910*7fd79137SRobert Mustacchi         Return pointer to the instructions in the dwarf
1911*7fd79137SRobert Mustacchi         fde.
1912*7fd79137SRobert Mustacchi */
1913*7fd79137SRobert Mustacchi int
1914*7fd79137SRobert Mustacchi dwarf_get_fde_instr_bytes(Dwarf_Fde inFde, Dwarf_Ptr * outinstraddr,
1915*7fd79137SRobert Mustacchi     Dwarf_Unsigned * outaddrlen,
1916*7fd79137SRobert Mustacchi     Dwarf_Error * error)
1917*7fd79137SRobert Mustacchi {
1918*7fd79137SRobert Mustacchi     Dwarf_Unsigned len = 0;
1919*7fd79137SRobert Mustacchi     unsigned char *instrs = 0;
1920*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
1921*7fd79137SRobert Mustacchi 
1922*7fd79137SRobert Mustacchi     if (inFde == NULL) {
1923*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_FDE_NULL);
1924*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1925*7fd79137SRobert Mustacchi     }
1926*7fd79137SRobert Mustacchi 
1927*7fd79137SRobert Mustacchi     dbg = inFde->fd_dbg;
1928*7fd79137SRobert Mustacchi     if (dbg == NULL) {
1929*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_FDE_DBG_NULL);
1930*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1931*7fd79137SRobert Mustacchi     }
1932*7fd79137SRobert Mustacchi 
1933*7fd79137SRobert Mustacchi     instrs = inFde->fd_fde_instr_start;
1934*7fd79137SRobert Mustacchi 
1935*7fd79137SRobert Mustacchi     len = (inFde->fd_fde_start + inFde->fd_length +
1936*7fd79137SRobert Mustacchi            inFde->fd_length_size + inFde->fd_extension_size) - instrs;
1937*7fd79137SRobert Mustacchi 
1938*7fd79137SRobert Mustacchi     *outinstraddr = instrs;
1939*7fd79137SRobert Mustacchi     *outaddrlen = len;
1940*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1941*7fd79137SRobert Mustacchi }
1942*7fd79137SRobert Mustacchi 
1943*7fd79137SRobert Mustacchi /* Allows getting an fde from its table via an index.
1944*7fd79137SRobert Mustacchi    With more error checking than simply indexing oneself.
1945*7fd79137SRobert Mustacchi */
1946*7fd79137SRobert Mustacchi int
1947*7fd79137SRobert Mustacchi dwarf_get_fde_n(Dwarf_Fde * fde_data,
1948*7fd79137SRobert Mustacchi     Dwarf_Unsigned fde_index,
1949*7fd79137SRobert Mustacchi     Dwarf_Fde * returned_fde, Dwarf_Error * error)
1950*7fd79137SRobert Mustacchi {
1951*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
1952*7fd79137SRobert Mustacchi     Dwarf_Signed fdecount = 0;
1953*7fd79137SRobert Mustacchi 
1954*7fd79137SRobert Mustacchi     if (fde_data == NULL) {
1955*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_FDE_PTR_NULL);
1956*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1957*7fd79137SRobert Mustacchi     }
1958*7fd79137SRobert Mustacchi 
1959*7fd79137SRobert Mustacchi     FDE_NULL_CHECKS_AND_SET_DBG(*fde_data, dbg);
1960*7fd79137SRobert Mustacchi     /* Assumes fde_data table has at least one entry. */
1961*7fd79137SRobert Mustacchi     fdecount = fde_data[0]->fd_is_eh?
1962*7fd79137SRobert Mustacchi         dbg->de_fde_count_eh:dbg->de_fde_count;
1963*7fd79137SRobert Mustacchi     if (fde_index >= fdecount) {
1964*7fd79137SRobert Mustacchi         return (DW_DLV_NO_ENTRY);
1965*7fd79137SRobert Mustacchi     }
1966*7fd79137SRobert Mustacchi     *returned_fde = (*(fde_data + fde_index));
1967*7fd79137SRobert Mustacchi     return DW_DLV_OK;
1968*7fd79137SRobert Mustacchi }
1969*7fd79137SRobert Mustacchi 
1970*7fd79137SRobert Mustacchi 
1971*7fd79137SRobert Mustacchi /*
1972*7fd79137SRobert Mustacchi     Lopc and hipc are extensions to the interface to
1973*7fd79137SRobert Mustacchi     return the range of addresses that are described
1974*7fd79137SRobert Mustacchi     by the returned fde.
1975*7fd79137SRobert Mustacchi */
1976*7fd79137SRobert Mustacchi int
1977*7fd79137SRobert Mustacchi dwarf_get_fde_at_pc(Dwarf_Fde * fde_data,
1978*7fd79137SRobert Mustacchi     Dwarf_Addr pc_of_interest,
1979*7fd79137SRobert Mustacchi     Dwarf_Fde * returned_fde,
1980*7fd79137SRobert Mustacchi     Dwarf_Addr * lopc,
1981*7fd79137SRobert Mustacchi     Dwarf_Addr * hipc, Dwarf_Error * error)
1982*7fd79137SRobert Mustacchi {
1983*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = NULL;
1984*7fd79137SRobert Mustacchi     Dwarf_Fde fde = NULL;
1985*7fd79137SRobert Mustacchi     Dwarf_Fde entryfde = NULL;
1986*7fd79137SRobert Mustacchi     Dwarf_Signed fdecount = 0;
1987*7fd79137SRobert Mustacchi 
1988*7fd79137SRobert Mustacchi     if (fde_data == NULL) {
1989*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_FDE_PTR_NULL);
1990*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
1991*7fd79137SRobert Mustacchi     }
1992*7fd79137SRobert Mustacchi 
1993*7fd79137SRobert Mustacchi     /* Assumes fde_data table has at least one entry. */
1994*7fd79137SRobert Mustacchi     entryfde = *fde_data;
1995*7fd79137SRobert Mustacchi     FDE_NULL_CHECKS_AND_SET_DBG(entryfde, dbg);
1996*7fd79137SRobert Mustacchi 
1997*7fd79137SRobert Mustacchi     if (dbg == NULL) {
1998*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
1999*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
2000*7fd79137SRobert Mustacchi     }
2001*7fd79137SRobert Mustacchi     fdecount = entryfde->fd_is_eh?
2002*7fd79137SRobert Mustacchi         dbg->de_fde_count_eh:dbg->de_fde_count;
2003*7fd79137SRobert Mustacchi     {
2004*7fd79137SRobert Mustacchi         /* The fde's are sorted by their addresses. Binary search to
2005*7fd79137SRobert Mustacchi            find correct fde. */
2006*7fd79137SRobert Mustacchi         Dwarf_Signed low = 0;
2007*7fd79137SRobert Mustacchi         Dwarf_Signed high = fdecount - 1L;
2008*7fd79137SRobert Mustacchi         Dwarf_Signed middle = 0;
2009*7fd79137SRobert Mustacchi         Dwarf_Fde cur_fde;
2010*7fd79137SRobert Mustacchi 
2011*7fd79137SRobert Mustacchi         while (low <= high) {
2012*7fd79137SRobert Mustacchi             middle = (low + high) / 2;
2013*7fd79137SRobert Mustacchi             cur_fde = fde_data[middle];
2014*7fd79137SRobert Mustacchi             if (pc_of_interest < cur_fde->fd_initial_location) {
2015*7fd79137SRobert Mustacchi                 high = middle - 1;
2016*7fd79137SRobert Mustacchi             } else if (pc_of_interest >=
2017*7fd79137SRobert Mustacchi                        (cur_fde->fd_initial_location +
2018*7fd79137SRobert Mustacchi                         cur_fde->fd_address_range)) {
2019*7fd79137SRobert Mustacchi                 low = middle + 1;
2020*7fd79137SRobert Mustacchi             } else {
2021*7fd79137SRobert Mustacchi                 fde = fde_data[middle];
2022*7fd79137SRobert Mustacchi                 break;
2023*7fd79137SRobert Mustacchi             }
2024*7fd79137SRobert Mustacchi         }
2025*7fd79137SRobert Mustacchi     }
2026*7fd79137SRobert Mustacchi 
2027*7fd79137SRobert Mustacchi     if (fde) {
2028*7fd79137SRobert Mustacchi         if (lopc != NULL)
2029*7fd79137SRobert Mustacchi             *lopc = fde->fd_initial_location;
2030*7fd79137SRobert Mustacchi         if (hipc != NULL)
2031*7fd79137SRobert Mustacchi             *hipc =
2032*7fd79137SRobert Mustacchi                 fde->fd_initial_location + fde->fd_address_range - 1;
2033*7fd79137SRobert Mustacchi         *returned_fde = fde;
2034*7fd79137SRobert Mustacchi         return (DW_DLV_OK);
2035*7fd79137SRobert Mustacchi     }
2036*7fd79137SRobert Mustacchi 
2037*7fd79137SRobert Mustacchi     return (DW_DLV_NO_ENTRY);
2038*7fd79137SRobert Mustacchi }
2039*7fd79137SRobert Mustacchi 
2040*7fd79137SRobert Mustacchi 
2041*7fd79137SRobert Mustacchi /* Expands a single frame instruction block
2042*7fd79137SRobert Mustacchi    from a specific cie
2043*7fd79137SRobert Mustacchi    into a n array of Dwarf_Frame_Op-s.
2044*7fd79137SRobert Mustacchi    This depends on having the cfa column set sensibly.
2045*7fd79137SRobert Mustacchi 
2046*7fd79137SRobert Mustacchi    Call dwarf_set_frame_cfa_value() to set the correct column
2047*7fd79137SRobert Mustacchi    after calling dwarf_init() unless you are using
2048*7fd79137SRobert Mustacchi    the old MIPS frame interfaces (in which case the default
2049*7fd79137SRobert Mustacchi    will be ok). (DW_FRAME_CFA_COL3 is a sensible column to use ).
2050*7fd79137SRobert Mustacchi */
2051*7fd79137SRobert Mustacchi int
2052*7fd79137SRobert Mustacchi dwarf_expand_frame_instructions(Dwarf_Cie cie,
2053*7fd79137SRobert Mustacchi     Dwarf_Ptr instruction,
2054*7fd79137SRobert Mustacchi     Dwarf_Unsigned i_length,
2055*7fd79137SRobert Mustacchi     Dwarf_Frame_Op ** returned_op_list,
2056*7fd79137SRobert Mustacchi     Dwarf_Signed * returned_op_count,
2057*7fd79137SRobert Mustacchi     Dwarf_Error * error)
2058*7fd79137SRobert Mustacchi {
2059*7fd79137SRobert Mustacchi     Dwarf_Sword instr_count;
2060*7fd79137SRobert Mustacchi     int res = DW_DLV_ERROR;
2061*7fd79137SRobert Mustacchi     int dw_err;
2062*7fd79137SRobert Mustacchi     Dwarf_Debug dbg = 0;
2063*7fd79137SRobert Mustacchi 
2064*7fd79137SRobert Mustacchi     if (cie == 0) {
2065*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
2066*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
2067*7fd79137SRobert Mustacchi     }
2068*7fd79137SRobert Mustacchi     dbg = cie->ci_dbg;
2069*7fd79137SRobert Mustacchi 
2070*7fd79137SRobert Mustacchi     if (returned_op_list == 0 || returned_op_count == 0) {
2071*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_RET_OP_LIST_NULL);
2072*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
2073*7fd79137SRobert Mustacchi     }
2074*7fd79137SRobert Mustacchi 
2075*7fd79137SRobert Mustacchi     /* The cast to Dwarf_Ptr may get a compiler warning, but it is safe
2076*7fd79137SRobert Mustacchi        as it is just an i_length offset from 'instruction' itself. A
2077*7fd79137SRobert Mustacchi        caller has made a big mistake if the result is not a valid
2078*7fd79137SRobert Mustacchi        pointer. */
2079*7fd79137SRobert Mustacchi     res = _dwarf_exec_frame_instr( /* make_instr= */ true,
2080*7fd79137SRobert Mustacchi         returned_op_list,
2081*7fd79137SRobert Mustacchi         /* search_pc */ false,
2082*7fd79137SRobert Mustacchi         /* search_pc_val */ 0,
2083*7fd79137SRobert Mustacchi         /* location */ 0,
2084*7fd79137SRobert Mustacchi         instruction,
2085*7fd79137SRobert Mustacchi         (Dwarf_Ptr)((char *)instruction + i_length),
2086*7fd79137SRobert Mustacchi         /* Dwarf_Frame */ NULL,
2087*7fd79137SRobert Mustacchi         cie,
2088*7fd79137SRobert Mustacchi         dbg,
2089*7fd79137SRobert Mustacchi         dbg->de_frame_cfa_col_number, &instr_count,
2090*7fd79137SRobert Mustacchi         &dw_err);
2091*7fd79137SRobert Mustacchi     if (res != DW_DLV_OK) {
2092*7fd79137SRobert Mustacchi         if (res == DW_DLV_ERROR) {
2093*7fd79137SRobert Mustacchi             _dwarf_error(dbg, error, dw_err);
2094*7fd79137SRobert Mustacchi         }
2095*7fd79137SRobert Mustacchi         return (res);
2096*7fd79137SRobert Mustacchi     }
2097*7fd79137SRobert Mustacchi 
2098*7fd79137SRobert Mustacchi     *returned_op_count = instr_count;
2099*7fd79137SRobert Mustacchi     return DW_DLV_OK;
2100*7fd79137SRobert Mustacchi }
2101*7fd79137SRobert Mustacchi 
2102*7fd79137SRobert Mustacchi 
2103*7fd79137SRobert Mustacchi /* Used by dwarfdump -v to print offsets, for debugging
2104*7fd79137SRobert Mustacchi    dwarf info.
2105*7fd79137SRobert Mustacchi    The dwarf_ version is preferred over the obsolete _dwarf version.
2106*7fd79137SRobert Mustacchi    _dwarf version kept for compatibility.
2107*7fd79137SRobert Mustacchi */
2108*7fd79137SRobert Mustacchi /* ARGSUSED 4 */
2109*7fd79137SRobert Mustacchi int
2110*7fd79137SRobert Mustacchi _dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde,
2111*7fd79137SRobert Mustacchi     Dwarf_Off * fde_off, Dwarf_Off * cie_off,
2112*7fd79137SRobert Mustacchi     Dwarf_Error * err)
2113*7fd79137SRobert Mustacchi {
2114*7fd79137SRobert Mustacchi   return dwarf_fde_section_offset(dbg,in_fde,fde_off,
2115*7fd79137SRobert Mustacchi      cie_off,err);
2116*7fd79137SRobert Mustacchi }
2117*7fd79137SRobert Mustacchi /* ARGSUSED 4 */
2118*7fd79137SRobert Mustacchi int
2119*7fd79137SRobert Mustacchi dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde,
2120*7fd79137SRobert Mustacchi     Dwarf_Off * fde_off, Dwarf_Off * cie_off,
2121*7fd79137SRobert Mustacchi     Dwarf_Error * err)
2122*7fd79137SRobert Mustacchi {
2123*7fd79137SRobert Mustacchi     char *start = 0;
2124*7fd79137SRobert Mustacchi     char *loc = 0;
2125*7fd79137SRobert Mustacchi 
2126*7fd79137SRobert Mustacchi 
2127*7fd79137SRobert Mustacchi 
2128*7fd79137SRobert Mustacchi     start = (char *) in_fde->fd_section_ptr;
2129*7fd79137SRobert Mustacchi     loc = (char *) in_fde->fd_fde_start;
2130*7fd79137SRobert Mustacchi 
2131*7fd79137SRobert Mustacchi     *fde_off = (loc - start);
2132*7fd79137SRobert Mustacchi     *cie_off = in_fde->fd_cie_offset;
2133*7fd79137SRobert Mustacchi     return DW_DLV_OK;
2134*7fd79137SRobert Mustacchi }
2135*7fd79137SRobert Mustacchi 
2136*7fd79137SRobert Mustacchi /* Used by dwarfdump -v to print offsets, for debugging
2137*7fd79137SRobert Mustacchi    dwarf info.
2138*7fd79137SRobert Mustacchi    The dwarf_ version is preferred over the obsolete _dwarf version.
2139*7fd79137SRobert Mustacchi    _dwarf version kept for compatibility.
2140*7fd79137SRobert Mustacchi */
2141*7fd79137SRobert Mustacchi /* ARGSUSED 4 */
2142*7fd79137SRobert Mustacchi int
2143*7fd79137SRobert Mustacchi _dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie,
2144*7fd79137SRobert Mustacchi     Dwarf_Off * cie_off, Dwarf_Error * err)
2145*7fd79137SRobert Mustacchi {
2146*7fd79137SRobert Mustacchi     return dwarf_cie_section_offset(dbg,in_cie,cie_off,err);
2147*7fd79137SRobert Mustacchi }
2148*7fd79137SRobert Mustacchi /* ARGSUSED 4 */
2149*7fd79137SRobert Mustacchi int
2150*7fd79137SRobert Mustacchi dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie,
2151*7fd79137SRobert Mustacchi     Dwarf_Off * cie_off, Dwarf_Error * err)
2152*7fd79137SRobert Mustacchi {
2153*7fd79137SRobert Mustacchi     char *start = 0;
2154*7fd79137SRobert Mustacchi     char *loc = 0;
2155*7fd79137SRobert Mustacchi 
2156*7fd79137SRobert Mustacchi     start = (char *) in_cie->ci_section_ptr;
2157*7fd79137SRobert Mustacchi     loc = (char *) in_cie->ci_cie_start;
2158*7fd79137SRobert Mustacchi 
2159*7fd79137SRobert Mustacchi     *cie_off = (loc - start);
2160*7fd79137SRobert Mustacchi     return DW_DLV_OK;
2161*7fd79137SRobert Mustacchi }
2162*7fd79137SRobert Mustacchi 
2163*7fd79137SRobert Mustacchi /* Returns  a pointer to target-specific augmentation data thru augdata
2164*7fd79137SRobert Mustacchi    and returns the length of the data thru augdata_len.
2165*7fd79137SRobert Mustacchi 
2166*7fd79137SRobert Mustacchi    It's up to the consumer code to know how to interpret the bytes
2167*7fd79137SRobert Mustacchi    of target-specific data (endian issues apply too, these
2168*7fd79137SRobert Mustacchi    are just raw bytes pointed to).
2169*7fd79137SRobert Mustacchi    See  Linux Standard Base Core Specification version 3.0 for
2170*7fd79137SRobert Mustacchi    the details on .eh_frame info.
2171*7fd79137SRobert Mustacchi 
2172*7fd79137SRobert Mustacchi    Returns DW_DLV_ERROR if fde is NULL or some other serious
2173*7fd79137SRobert Mustacchi    error.
2174*7fd79137SRobert Mustacchi    Returns DW_DLV_NO_ENTRY if there is no target-specific
2175*7fd79137SRobert Mustacchi    augmentation data.
2176*7fd79137SRobert Mustacchi 
2177*7fd79137SRobert Mustacchi    The bytes pointed to are in the Dwarf_Cie, and as long as that
2178*7fd79137SRobert Mustacchi    is valid the bytes are there. No 'dealloc' call is needed
2179*7fd79137SRobert Mustacchi    for the bytes.
2180*7fd79137SRobert Mustacchi */
2181*7fd79137SRobert Mustacchi int
2182*7fd79137SRobert Mustacchi dwarf_get_cie_augmentation_data(Dwarf_Cie cie,
2183*7fd79137SRobert Mustacchi     Dwarf_Small ** augdata,
2184*7fd79137SRobert Mustacchi     Dwarf_Unsigned * augdata_len,
2185*7fd79137SRobert Mustacchi     Dwarf_Error * error)
2186*7fd79137SRobert Mustacchi {
2187*7fd79137SRobert Mustacchi     if (cie == NULL) {
2188*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
2189*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
2190*7fd79137SRobert Mustacchi     }
2191*7fd79137SRobert Mustacchi     if (cie->ci_gnu_eh_augmentation_len == 0) {
2192*7fd79137SRobert Mustacchi         return DW_DLV_NO_ENTRY;
2193*7fd79137SRobert Mustacchi     }
2194*7fd79137SRobert Mustacchi     *augdata = (Dwarf_Small *) (cie->ci_gnu_eh_augmentation_bytes);
2195*7fd79137SRobert Mustacchi     *augdata_len = cie->ci_gnu_eh_augmentation_len;
2196*7fd79137SRobert Mustacchi     return DW_DLV_OK;
2197*7fd79137SRobert Mustacchi }
2198*7fd79137SRobert Mustacchi 
2199*7fd79137SRobert Mustacchi 
2200*7fd79137SRobert Mustacchi /* Returns  a pointer to target-specific augmentation data thru augdata
2201*7fd79137SRobert Mustacchi    and returns the length of the data thru augdata_len.
2202*7fd79137SRobert Mustacchi 
2203*7fd79137SRobert Mustacchi    It's up to the consumer code to know how to interpret the bytes
2204*7fd79137SRobert Mustacchi    of target-specific data (endian issues apply too, these
2205*7fd79137SRobert Mustacchi    are just raw bytes pointed to).
2206*7fd79137SRobert Mustacchi    See  Linux Standard Base Core Specification version 3.0 for
2207*7fd79137SRobert Mustacchi    the details on .eh_frame info.
2208*7fd79137SRobert Mustacchi 
2209*7fd79137SRobert Mustacchi    Returns DW_DLV_ERROR if fde is NULL or some other serious
2210*7fd79137SRobert Mustacchi    error.
2211*7fd79137SRobert Mustacchi    Returns DW_DLV_NO_ENTRY if there is no target-specific
2212*7fd79137SRobert Mustacchi    augmentation data.
2213*7fd79137SRobert Mustacchi 
2214*7fd79137SRobert Mustacchi    The bytes pointed to are in the Dwarf_Fde, and as long as that
2215*7fd79137SRobert Mustacchi    is valid the bytes are there. No 'dealloc' call is needed
2216*7fd79137SRobert Mustacchi    for the bytes.
2217*7fd79137SRobert Mustacchi 
2218*7fd79137SRobert Mustacchi */
2219*7fd79137SRobert Mustacchi int
2220*7fd79137SRobert Mustacchi dwarf_get_fde_augmentation_data(Dwarf_Fde fde,
2221*7fd79137SRobert Mustacchi     Dwarf_Small * *augdata,
2222*7fd79137SRobert Mustacchi     Dwarf_Unsigned * augdata_len,
2223*7fd79137SRobert Mustacchi     Dwarf_Error * error)
2224*7fd79137SRobert Mustacchi {
2225*7fd79137SRobert Mustacchi     Dwarf_Cie cie = 0;
2226*7fd79137SRobert Mustacchi 
2227*7fd79137SRobert Mustacchi     if (fde == NULL) {
2228*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
2229*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
2230*7fd79137SRobert Mustacchi     }
2231*7fd79137SRobert Mustacchi     cie = fde->fd_cie;
2232*7fd79137SRobert Mustacchi     if (cie == NULL) {
2233*7fd79137SRobert Mustacchi         _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
2234*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
2235*7fd79137SRobert Mustacchi     }
2236*7fd79137SRobert Mustacchi     if (cie->ci_gnu_eh_augmentation_len == 0) {
2237*7fd79137SRobert Mustacchi         return DW_DLV_NO_ENTRY;
2238*7fd79137SRobert Mustacchi     }
2239*7fd79137SRobert Mustacchi     *augdata = (Dwarf_Small *) fde->fd_gnu_eh_augmentation_bytes;
2240*7fd79137SRobert Mustacchi     *augdata_len = fde->fd_gnu_eh_augmentation_len;
2241*7fd79137SRobert Mustacchi     return DW_DLV_OK;
2242*7fd79137SRobert Mustacchi }
2243*7fd79137SRobert Mustacchi 
2244*7fd79137SRobert Mustacchi 
2245*7fd79137SRobert Mustacchi /* Initialize with same_value , a value which makes sense
2246*7fd79137SRobert Mustacchi    for IRIX/MIPS.
2247*7fd79137SRobert Mustacchi    The correct value to use is ABI dependent.
2248*7fd79137SRobert Mustacchi    For register-windows machines most
2249*7fd79137SRobert Mustacchi    or all registers should get DW_FRAME_UNDEFINED_VAL as the
2250*7fd79137SRobert Mustacchi    correct initial value.
2251*7fd79137SRobert Mustacchi    Some think DW_FRAME_UNDEFINED_VAL is always the
2252*7fd79137SRobert Mustacchi    right value.
2253*7fd79137SRobert Mustacchi 
2254*7fd79137SRobert Mustacchi    For some ABIs a setting which varies by register
2255*7fd79137SRobert Mustacchi    would be more appropriate.
2256*7fd79137SRobert Mustacchi 
2257*7fd79137SRobert Mustacchi    FIXME. */
2258*7fd79137SRobert Mustacchi 
2259*7fd79137SRobert Mustacchi static void
2260*7fd79137SRobert Mustacchi _dwarf_init_regrule_table(struct Dwarf_Reg_Rule_s *t1reg,
2261*7fd79137SRobert Mustacchi     int last_reg_num, int initial_value)
2262*7fd79137SRobert Mustacchi {
2263*7fd79137SRobert Mustacchi     struct Dwarf_Reg_Rule_s *t1end = t1reg + last_reg_num;
2264*7fd79137SRobert Mustacchi 
2265*7fd79137SRobert Mustacchi     for (; t1reg < t1end; t1reg++) {
2266*7fd79137SRobert Mustacchi         t1reg->ru_is_off = 0;
2267*7fd79137SRobert Mustacchi         t1reg->ru_value_type = DW_EXPR_OFFSET;
2268*7fd79137SRobert Mustacchi         t1reg->ru_register = initial_value;
2269*7fd79137SRobert Mustacchi         t1reg->ru_offset_or_block_len = 0;
2270*7fd79137SRobert Mustacchi         t1reg->ru_block = 0;
2271*7fd79137SRobert Mustacchi     }
2272*7fd79137SRobert Mustacchi }
2273*7fd79137SRobert Mustacchi 
2274*7fd79137SRobert Mustacchi #if 0
2275*7fd79137SRobert Mustacchi /* Used solely for debugging libdwarf. */
2276*7fd79137SRobert Mustacchi static void
2277*7fd79137SRobert Mustacchi dump_frame_rule(char *msg, struct Dwarf_Reg_Rule_s *reg_rule)
2278*7fd79137SRobert Mustacchi {
2279*7fd79137SRobert Mustacchi     printf
2280*7fd79137SRobert Mustacchi         ("%s type %s (" DW_PR_DUx "), is_off "
2281*7fd79137SRobert Mustacchi          DW_PR_DUu " reg " DW_PR_DUu " offset " DW_PR_DUx " blockp "
2282*7fd79137SRobert Mustacchi          DW_PR_DUx "\n",
2283*7fd79137SRobert Mustacchi          msg,
2284*7fd79137SRobert Mustacchi          (reg_rule->ru_value_type == DW_EXPR_OFFSET) ?
2285*7fd79137SRobert Mustacchi              "DW_EXPR_OFFSET" :
2286*7fd79137SRobert Mustacchi           (reg_rule->ru_value_type == DW_EXPR_VAL_OFFSET) ?
2287*7fd79137SRobert Mustacchi              "DW_EXPR_VAL_OFFSET" :
2288*7fd79137SRobert Mustacchi           (reg_rule->ru_value_type == DW_EXPR_VAL_EXPRESSION) ?
2289*7fd79137SRobert Mustacchi              "DW_EXPR_VAL_EXPRESSION" :
2290*7fd79137SRobert Mustacchi           (reg_rule->ru_value_type == DW_EXPR_EXPRESSION) ?
2291*7fd79137SRobert Mustacchi              "DW_EXPR_EXPRESSION" : "Unknown",
2292*7fd79137SRobert Mustacchi          (Dwarf_Unsigned) reg_rule->ru_value_type,
2293*7fd79137SRobert Mustacchi          (Dwarf_Unsigned) reg_rule->ru_is_off,
2294*7fd79137SRobert Mustacchi          (Dwarf_Unsigned) reg_rule->ru_register,
2295*7fd79137SRobert Mustacchi          (Dwarf_Unsigned) reg_rule->ru_offset_or_block_len,
2296*7fd79137SRobert Mustacchi          (Dwarf_Unsigned) reg_rule->ru_block);
2297*7fd79137SRobert Mustacchi     return;
2298*7fd79137SRobert Mustacchi }
2299*7fd79137SRobert Mustacchi #endif
2300*7fd79137SRobert Mustacchi 
2301*7fd79137SRobert Mustacchi /* This allows consumers to set the 'initial value' so that
2302*7fd79137SRobert Mustacchi    an ISA/ABI specific default can be used, dynamically,
2303*7fd79137SRobert Mustacchi    at run time.  Useful for dwarfdump and non-MIPS architectures..
2304*7fd79137SRobert Mustacchi    The value  defaults to one of
2305*7fd79137SRobert Mustacchi         DW_FRAME_SAME_VALUE or DW_FRAME_UNKNOWN_VALUE
2306*7fd79137SRobert Mustacchi    but dwarfdump can dump multiple ISA/ABI objects so
2307*7fd79137SRobert Mustacchi    we may want to get this set to what the ABI says is correct.
2308*7fd79137SRobert Mustacchi 
2309*7fd79137SRobert Mustacchi    Returns the value that was present before we changed it here.
2310*7fd79137SRobert Mustacchi */
2311*7fd79137SRobert Mustacchi Dwarf_Half
2312*7fd79137SRobert Mustacchi dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg, Dwarf_Half value)
2313*7fd79137SRobert Mustacchi {
2314*7fd79137SRobert Mustacchi     Dwarf_Half orig = dbg->de_frame_rule_initial_value;
2315*7fd79137SRobert Mustacchi     dbg->de_frame_rule_initial_value = value;
2316*7fd79137SRobert Mustacchi     return orig;
2317*7fd79137SRobert Mustacchi }
2318*7fd79137SRobert Mustacchi 
2319*7fd79137SRobert Mustacchi /* The following spelling for backwards compatibility. */
2320*7fd79137SRobert Mustacchi Dwarf_Half
2321*7fd79137SRobert Mustacchi dwarf_set_frame_rule_inital_value(Dwarf_Debug dbg, Dwarf_Half value)
2322*7fd79137SRobert Mustacchi {
2323*7fd79137SRobert Mustacchi     return dwarf_set_frame_rule_initial_value(dbg,value);
2324*7fd79137SRobert Mustacchi }
2325*7fd79137SRobert Mustacchi 
2326*7fd79137SRobert Mustacchi /* This allows consumers to set the array size of the  reg rules
2327*7fd79137SRobert Mustacchi    table so that
2328*7fd79137SRobert Mustacchi    an ISA/ABI specific value can be used, dynamically,
2329*7fd79137SRobert Mustacchi    at run time.  Useful for non-MIPS archtectures.
2330*7fd79137SRobert Mustacchi    The value  defaults  to DW_FRAME_LAST_REG_NUM.
2331*7fd79137SRobert Mustacchi    but dwarfdump can dump multiple ISA/ABI objects so
2332*7fd79137SRobert Mustacchi    consumers want to get this set to what the ABI says is correct.
2333*7fd79137SRobert Mustacchi 
2334*7fd79137SRobert Mustacchi    Returns the value that was present before we changed it here.
2335*7fd79137SRobert Mustacchi */
2336*7fd79137SRobert Mustacchi 
2337*7fd79137SRobert Mustacchi Dwarf_Half
2338*7fd79137SRobert Mustacchi dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, Dwarf_Half value)
2339*7fd79137SRobert Mustacchi {
2340*7fd79137SRobert Mustacchi     Dwarf_Half orig = dbg->de_frame_reg_rules_entry_count;
2341*7fd79137SRobert Mustacchi     dbg->de_frame_reg_rules_entry_count = value;
2342*7fd79137SRobert Mustacchi     return orig;
2343*7fd79137SRobert Mustacchi }
2344*7fd79137SRobert Mustacchi /* This allows consumers to set the CFA register value
2345*7fd79137SRobert Mustacchi  * so that an ISA/ABI specific value can be used, dynamically,
2346*7fd79137SRobert Mustacchi  * at run time.  Useful for non-MIPS archtectures.
2347*7fd79137SRobert Mustacchi  * The value  defaults  to DW_FRAME_CFA_COL3 and should be
2348*7fd79137SRobert Mustacchi  * higher than any real register in the ABI.
2349*7fd79137SRobert Mustacchi  * Dwarfdump can dump multiple ISA/ABI objects so
2350*7fd79137SRobert Mustacchi  * consumers want to get this set to what the ABI says is correct.
2351*7fd79137SRobert Mustacchi 
2352*7fd79137SRobert Mustacchi  * Returns the value that was present before we changed it here.
2353*7fd79137SRobert Mustacchi  * */
2354*7fd79137SRobert Mustacchi 
2355*7fd79137SRobert Mustacchi Dwarf_Half
2356*7fd79137SRobert Mustacchi dwarf_set_frame_cfa_value(Dwarf_Debug dbg, Dwarf_Half value)
2357*7fd79137SRobert Mustacchi {
2358*7fd79137SRobert Mustacchi     Dwarf_Half orig = dbg->de_frame_cfa_col_number;
2359*7fd79137SRobert Mustacchi     dbg->de_frame_cfa_col_number = value;
2360*7fd79137SRobert Mustacchi     return orig;
2361*7fd79137SRobert Mustacchi }
2362*7fd79137SRobert Mustacchi /* Similar to above, but for the other crucial fields for frames. */
2363*7fd79137SRobert Mustacchi Dwarf_Half
2364*7fd79137SRobert Mustacchi dwarf_set_frame_same_value(Dwarf_Debug dbg, Dwarf_Half value)
2365*7fd79137SRobert Mustacchi {
2366*7fd79137SRobert Mustacchi     Dwarf_Half orig = dbg->de_frame_same_value_number;
2367*7fd79137SRobert Mustacchi     dbg->de_frame_same_value_number = value;
2368*7fd79137SRobert Mustacchi     return orig;
2369*7fd79137SRobert Mustacchi }
2370*7fd79137SRobert Mustacchi Dwarf_Half
2371*7fd79137SRobert Mustacchi dwarf_set_frame_undefined_value(Dwarf_Debug dbg, Dwarf_Half value)
2372*7fd79137SRobert Mustacchi {
2373*7fd79137SRobert Mustacchi     Dwarf_Half orig = dbg->de_frame_same_value_number;
2374*7fd79137SRobert Mustacchi     dbg->de_frame_undefined_value_number = value;
2375*7fd79137SRobert Mustacchi     return orig;
2376*7fd79137SRobert Mustacchi }
2377*7fd79137SRobert Mustacchi 
2378*7fd79137SRobert Mustacchi 
2379*7fd79137SRobert Mustacchi 
2380*7fd79137SRobert Mustacchi 
2381*7fd79137SRobert Mustacchi 
2382*7fd79137SRobert Mustacchi static int
2383*7fd79137SRobert Mustacchi dwarf_initialize_fde_table(Dwarf_Debug dbg,
2384*7fd79137SRobert Mustacchi     struct Dwarf_Frame_s *fde_table,
2385*7fd79137SRobert Mustacchi     unsigned table_real_data_size,
2386*7fd79137SRobert Mustacchi     Dwarf_Error * error)
2387*7fd79137SRobert Mustacchi {
2388*7fd79137SRobert Mustacchi     unsigned entry_size = sizeof(struct Dwarf_Frame_s);
2389*7fd79137SRobert Mustacchi 
2390*7fd79137SRobert Mustacchi     fde_table->fr_loc = 0;
2391*7fd79137SRobert Mustacchi     fde_table->fr_reg_count = table_real_data_size;
2392*7fd79137SRobert Mustacchi     fde_table->fr_next = 0;
2393*7fd79137SRobert Mustacchi 
2394*7fd79137SRobert Mustacchi     fde_table->fr_reg = (struct Dwarf_Reg_Rule_s *)
2395*7fd79137SRobert Mustacchi         calloc(entry_size, table_real_data_size);
2396*7fd79137SRobert Mustacchi     if (fde_table->fr_reg == 0) {
2397*7fd79137SRobert Mustacchi         _dwarf_error(dbg, error, DW_DLE_DF_ALLOC_FAIL);
2398*7fd79137SRobert Mustacchi         return (DW_DLV_ERROR);
2399*7fd79137SRobert Mustacchi     }
2400*7fd79137SRobert Mustacchi     return DW_DLV_OK;
2401*7fd79137SRobert Mustacchi 
2402*7fd79137SRobert Mustacchi }
2403*7fd79137SRobert Mustacchi static void
2404*7fd79137SRobert Mustacchi dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table)
2405*7fd79137SRobert Mustacchi {
2406*7fd79137SRobert Mustacchi     free(fde_table->fr_reg);
2407*7fd79137SRobert Mustacchi     fde_table->fr_reg_count = 0;
2408*7fd79137SRobert Mustacchi     fde_table->fr_reg = 0;
2409*7fd79137SRobert Mustacchi }
2410*7fd79137SRobert Mustacchi 
2411*7fd79137SRobert Mustacchi 
2412*7fd79137SRobert Mustacchi /* Return DW_DLV_OK if we succeed. else return DW_DLV_ERROR.
2413*7fd79137SRobert Mustacchi */
2414*7fd79137SRobert Mustacchi int
2415*7fd79137SRobert Mustacchi _dwarf_frame_constructor(Dwarf_Debug dbg, void *frame)
2416*7fd79137SRobert Mustacchi {
2417*7fd79137SRobert Mustacchi     struct Dwarf_Frame_s *fp = frame;
2418*7fd79137SRobert Mustacchi 
2419*7fd79137SRobert Mustacchi     if (!dbg) {
2420*7fd79137SRobert Mustacchi         return DW_DLV_ERROR;
2421*7fd79137SRobert Mustacchi     }
2422*7fd79137SRobert Mustacchi 
2423*7fd79137SRobert Mustacchi     fp->fr_reg = calloc(dbg->de_frame_reg_rules_entry_count,
2424*7fd79137SRobert Mustacchi                         sizeof(struct Dwarf_Reg_Rule_s));
2425*7fd79137SRobert Mustacchi     if (!fp->fr_reg) {
2426*7fd79137SRobert Mustacchi         return DW_DLV_ERROR;
2427*7fd79137SRobert Mustacchi     }
2428*7fd79137SRobert Mustacchi     fp->fr_reg_count = dbg->de_frame_reg_rules_entry_count;
2429*7fd79137SRobert Mustacchi     return DW_DLV_OK;
2430*7fd79137SRobert Mustacchi }
2431*7fd79137SRobert Mustacchi 
2432*7fd79137SRobert Mustacchi void
2433*7fd79137SRobert Mustacchi _dwarf_frame_destructor(void *frame)
2434*7fd79137SRobert Mustacchi {
2435*7fd79137SRobert Mustacchi     struct Dwarf_Frame_s *fp = frame;
2436*7fd79137SRobert Mustacchi 
2437*7fd79137SRobert Mustacchi     if (fp->fr_reg) {
2438*7fd79137SRobert Mustacchi         free(fp->fr_reg);
2439*7fd79137SRobert Mustacchi     }
2440*7fd79137SRobert Mustacchi     fp->fr_reg = 0;
2441*7fd79137SRobert Mustacchi     fp->fr_reg_count = 0;
2442*7fd79137SRobert Mustacchi }
2443