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