xref: /titanic_44/usr/src/tools/ctf/dwarf/common/dwarf_frame.c (revision 07dc1947c362e187fb955d283b692f8769dd5def)
149d3bc91SRichard Lowe /*
249d3bc91SRichard Lowe 
3*07dc1947SRichard Lowe   Copyright (C) 2000-2006 Silicon Graphics, Inc.  All Rights Reserved.
4*07dc1947SRichard Lowe   Portions Copyright (C) 2007-2010 David Anderson. All Rights Reserved.
549d3bc91SRichard Lowe 
649d3bc91SRichard Lowe   This program is free software; you can redistribute it and/or modify it
749d3bc91SRichard Lowe   under the terms of version 2.1 of the GNU Lesser General Public License
849d3bc91SRichard Lowe   as published by the Free Software Foundation.
949d3bc91SRichard Lowe 
1049d3bc91SRichard Lowe   This program is distributed in the hope that it would be useful, but
1149d3bc91SRichard Lowe   WITHOUT ANY WARRANTY; without even the implied warranty of
1249d3bc91SRichard Lowe   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
1349d3bc91SRichard Lowe 
1449d3bc91SRichard Lowe   Further, this software is distributed without any warranty that it is
1549d3bc91SRichard Lowe   free of the rightful claim of any third person regarding infringement
1649d3bc91SRichard Lowe   or the like.  Any license provided herein, whether implied or
1749d3bc91SRichard Lowe   otherwise, applies only to this software file.  Patent licenses, if
1849d3bc91SRichard Lowe   any, provided herein do not apply to combinations of this program with
1949d3bc91SRichard Lowe   other software, or any other product whatsoever.
2049d3bc91SRichard Lowe 
2149d3bc91SRichard Lowe   You should have received a copy of the GNU Lesser General Public
2249d3bc91SRichard Lowe   License along with this program; if not, write the Free Software
23*07dc1947SRichard Lowe   Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301,
2449d3bc91SRichard Lowe   USA.
2549d3bc91SRichard Lowe 
26*07dc1947SRichard Lowe   Contact information:  Silicon Graphics, Inc., 1500 Crittenden Lane,
2749d3bc91SRichard Lowe   Mountain View, CA 94043, or:
2849d3bc91SRichard Lowe 
2949d3bc91SRichard Lowe   http://www.sgi.com
3049d3bc91SRichard Lowe 
3149d3bc91SRichard Lowe   For further information regarding this notice, see:
3249d3bc91SRichard Lowe 
3349d3bc91SRichard Lowe   http://oss.sgi.com/projects/GenInfo/NoticeExplan
3449d3bc91SRichard Lowe 
3549d3bc91SRichard Lowe */
36*07dc1947SRichard Lowe /* The address of the Free Software Foundation is
37*07dc1947SRichard Lowe    Free Software Foundation, Inc., 51 Franklin St, Fifth Floor,
38*07dc1947SRichard Lowe    Boston, MA 02110-1301, USA.
39*07dc1947SRichard Lowe    SGI has moved from the Crittenden Lane address.
40*07dc1947SRichard Lowe */
41*07dc1947SRichard Lowe 
42*07dc1947SRichard Lowe 
4349d3bc91SRichard Lowe 
4449d3bc91SRichard Lowe 
4549d3bc91SRichard Lowe 
4649d3bc91SRichard Lowe #include "config.h"
4749d3bc91SRichard Lowe #include "dwarf_incl.h"
4849d3bc91SRichard Lowe #include <stdio.h>
4949d3bc91SRichard Lowe #include <stdlib.h>
50*07dc1947SRichard Lowe #include <sys/types.h>
5149d3bc91SRichard Lowe #include "dwarf_frame.h"
52*07dc1947SRichard Lowe #include "dwarf_arange.h"       /* Using Arange as a way to build a
5349d3bc91SRichard Lowe                                    list */
5449d3bc91SRichard Lowe 
55*07dc1947SRichard Lowe #define FDE_NULL_CHECKS_AND_SET_DBG(fde,dbg )          \
56*07dc1947SRichard Lowe     do {                                               \
57*07dc1947SRichard Lowe      if ((fde) == NULL) {                              \
58*07dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_FDE_NULL);    \
59*07dc1947SRichard Lowe         return (DW_DLV_ERROR);                         \
60*07dc1947SRichard Lowe     }                                                  \
61*07dc1947SRichard Lowe     (dbg)= (fde)->fd_dbg;                              \
62*07dc1947SRichard Lowe     if ((dbg) == NULL) {                               \
63*07dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);\
64*07dc1947SRichard Lowe         return (DW_DLV_ERROR);                         \
65*07dc1947SRichard Lowe     } } while (0)
6649d3bc91SRichard Lowe 
67*07dc1947SRichard Lowe 
68*07dc1947SRichard Lowe #define MIN(a,b)  (((a) < (b))? a:b)
69*07dc1947SRichard Lowe 
70*07dc1947SRichard Lowe static void _dwarf_init_regrule_table(struct Dwarf_Reg_Rule_s *t1reg,
71*07dc1947SRichard Lowe                                       int last_reg_num,
72*07dc1947SRichard Lowe                                       int initial_value);
73*07dc1947SRichard Lowe static int dwarf_initialize_fde_table(Dwarf_Debug dbg,
74*07dc1947SRichard Lowe                                       struct Dwarf_Frame_s *fde_table,
75*07dc1947SRichard Lowe                                       unsigned table_real_data_size,
7649d3bc91SRichard Lowe                                       Dwarf_Error * error);
77*07dc1947SRichard Lowe static void dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table);
78*07dc1947SRichard Lowe 
79*07dc1947SRichard Lowe #if 0
80*07dc1947SRichard Lowe /* Only used for debugging libdwarf. */
81*07dc1947SRichard Lowe static void dump_frame_rule(char *msg,
82*07dc1947SRichard Lowe                             struct Dwarf_Reg_Rule_s *reg_rule);
83*07dc1947SRichard Lowe #endif
84*07dc1947SRichard Lowe 
85*07dc1947SRichard Lowe 
8649d3bc91SRichard Lowe 
8749d3bc91SRichard Lowe /*
8849d3bc91SRichard Lowe     This function is the heart of the debug_frame stuff.  Don't even
8949d3bc91SRichard Lowe     think of reading this without reading both the Libdwarf and
9049d3bc91SRichard Lowe     consumer API carefully first.  This function basically executes
9149d3bc91SRichard Lowe     frame instructions contained in a Cie or an Fde, but does in a
9249d3bc91SRichard Lowe     number of different ways depending on the information sought.
9349d3bc91SRichard Lowe     Start_instr_ptr points to the first byte of the frame instruction
9449d3bc91SRichard Lowe     stream, and final_instr_ptr to the to the first byte after the
9549d3bc91SRichard Lowe     last.
9649d3bc91SRichard Lowe 
9749d3bc91SRichard Lowe     The offsets returned in the frame instructions are factored.  That
9849d3bc91SRichard Lowe     is they need to be multiplied by either the code_alignment_factor
9949d3bc91SRichard Lowe     or the data_alignment_factor, as appropriate to obtain the actual
10049d3bc91SRichard Lowe     offset.  This makes it possible to expand an instruction stream
10149d3bc91SRichard Lowe     without the corresponding Cie.  However, when an Fde frame instr
10249d3bc91SRichard Lowe     sequence is being expanded there must be a valid Cie with a pointer
10349d3bc91SRichard Lowe     to an initial table row.
10449d3bc91SRichard Lowe 
10549d3bc91SRichard Lowe 
10649d3bc91SRichard Lowe     If successful, returns DW_DLV_OK
10749d3bc91SRichard Lowe                 And sets returned_count thru the pointer
10849d3bc91SRichard Lowe                  if make_instr is true.
10949d3bc91SRichard Lowe                 If make_instr is false returned_count
11049d3bc91SRichard Lowe                  should NOT be used by the caller (returned_count
11149d3bc91SRichard Lowe                  is set to 0 thru the pointer by this routine...)
11249d3bc91SRichard Lowe     If unsuccessful, returns DW_DLV_ERROR
11349d3bc91SRichard Lowe                 and sets returned_error to the error code
11449d3bc91SRichard Lowe 
11549d3bc91SRichard Lowe     It does not do a whole lot of input validation being a private
11649d3bc91SRichard Lowe     function.  Please make sure inputs are valid.
11749d3bc91SRichard Lowe 
11849d3bc91SRichard Lowe     (1) If make_instr is true, it makes a list of pointers to
11949d3bc91SRichard Lowe     Dwarf_Frame_Op structures containing the frame instructions
12049d3bc91SRichard Lowe     executed.  A pointer to this list is returned in ret_frame_instr.
12149d3bc91SRichard Lowe     Make_instr is true only when a list of frame instructions is to be
12249d3bc91SRichard Lowe     returned.  In this case since we are not interested in the contents
12349d3bc91SRichard Lowe     of the table, the input Cie can be NULL.  This is the only case
12449d3bc91SRichard Lowe     where the inpute Cie can be NULL.
12549d3bc91SRichard Lowe 
12649d3bc91SRichard Lowe     (2) If search_pc is true, frame instructions are executed till
12749d3bc91SRichard Lowe     either a location is reached that is greater than the search_pc_val
12849d3bc91SRichard Lowe     provided, or all instructions are executed.  At this point the
12949d3bc91SRichard Lowe     last row of the table generated is returned in a structure.
13049d3bc91SRichard Lowe     A pointer to this structure is supplied in table.
13149d3bc91SRichard Lowe 
13249d3bc91SRichard Lowe     (3) This function is also used to create the initial table row
13349d3bc91SRichard Lowe     defined by a Cie.  In this case, the Dwarf_Cie pointer cie, is
13449d3bc91SRichard Lowe     NULL.  For an FDE, however, cie points to the associated Cie.
135*07dc1947SRichard Lowe 
136*07dc1947SRichard Lowe     make_instr - make list of frame instr? 0/1
137*07dc1947SRichard Lowe     ret_frame_instr -  Ptr to list of ptrs to frame instrs
138*07dc1947SRichard Lowe     search_pc  - Search for a pc value?  0/1
139*07dc1947SRichard Lowe      search_pc_val -  Search for this pc value
140*07dc1947SRichard Lowe     initial_loc - Initial code location value.
141*07dc1947SRichard Lowe     start_instr_ptr -   Ptr to start of frame instrs.
142*07dc1947SRichard Lowe     final_instr_ptr -   Ptr just past frame instrs.
143*07dc1947SRichard Lowe     table       -     Ptr to struct with last row.
144*07dc1947SRichard Lowe     cie     -   Ptr to Cie used by the Fde.
145*07dc1947SRichard Lowe        Different cies may have distinct address-sizes, so the cie
146*07dc1947SRichard Lowe        is used, not de_pointer_size.
147*07dc1947SRichard Lowe 
14849d3bc91SRichard Lowe */
149*07dc1947SRichard Lowe 
150*07dc1947SRichard Lowe 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*07dc1947SRichard Lowe _dwarf_exec_frame_instr(Dwarf_Bool make_instr,
152*07dc1947SRichard Lowe     Dwarf_Frame_Op ** ret_frame_instr,
153*07dc1947SRichard Lowe     Dwarf_Bool search_pc,
154*07dc1947SRichard Lowe     Dwarf_Addr search_pc_val,
155*07dc1947SRichard Lowe     Dwarf_Addr initial_loc,
156*07dc1947SRichard Lowe     Dwarf_Small * start_instr_ptr,
157*07dc1947SRichard Lowe     Dwarf_Small * final_instr_ptr,
158*07dc1947SRichard Lowe     Dwarf_Frame table,
159*07dc1947SRichard Lowe     Dwarf_Cie cie,
160*07dc1947SRichard Lowe     Dwarf_Debug dbg,
161*07dc1947SRichard Lowe     Dwarf_Half reg_num_of_cfa,
16249d3bc91SRichard Lowe     Dwarf_Sword * returned_count,
16349d3bc91SRichard Lowe     int *returned_error)
16449d3bc91SRichard Lowe {
165*07dc1947SRichard Lowe #define ERROR_IF_REG_NUM_TOO_HIGH(macreg,machigh_reg)               \
166*07dc1947SRichard Lowe      do {                                             \
167*07dc1947SRichard Lowe        if ((macreg) >= (machigh_reg) || (macreg) < 0) {            \
168*07dc1947SRichard Lowe         SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH); \
169*07dc1947SRichard Lowe        }                                              \
170*07dc1947SRichard Lowe      } /*CONSTCOND */ while(0)
171*07dc1947SRichard Lowe #define SIMPLE_ERROR_RETURN(code) \
172*07dc1947SRichard Lowe         free(localregtab); \
173*07dc1947SRichard Lowe         *returned_error = code; \
174*07dc1947SRichard Lowe         return DW_DLV_ERROR
175*07dc1947SRichard Lowe 
17649d3bc91SRichard Lowe     /* Sweeps the frame instructions. */
17749d3bc91SRichard Lowe     Dwarf_Small *instr_ptr;
17849d3bc91SRichard Lowe 
179*07dc1947SRichard Lowe     /* Register numbers not limited to just 255, thus not using
180*07dc1947SRichard Lowe        Dwarf_Small. */
181*07dc1947SRichard Lowe     typedef int reg_num_type;
18249d3bc91SRichard Lowe 
183*07dc1947SRichard Lowe     Dwarf_Unsigned factored_N_value;
184*07dc1947SRichard Lowe     Dwarf_Signed signed_factored_N_value;
185*07dc1947SRichard Lowe     Dwarf_Addr current_loc = initial_loc;       /* code location/
186*07dc1947SRichard Lowe                                                    pc-value
187*07dc1947SRichard Lowe                                                    corresponding to the
188*07dc1947SRichard Lowe                                                    frame instructions.
189*07dc1947SRichard Lowe                                                    Starts at zero when
190*07dc1947SRichard Lowe                                                    the caller has no
191*07dc1947SRichard Lowe                                                    value to pass in. */
192*07dc1947SRichard Lowe 
193*07dc1947SRichard Lowe     /* Must be min de_pointer_size bytes and must be at least sizeof
194*07dc1947SRichard Lowe        Dwarf_ufixed */
195*07dc1947SRichard Lowe     Dwarf_Unsigned adv_loc = 0;
196*07dc1947SRichard Lowe 
197*07dc1947SRichard Lowe     int reg_count = dbg->de_frame_reg_rules_entry_count;
198*07dc1947SRichard Lowe     struct Dwarf_Reg_Rule_s *localregtab = calloc(reg_count,
199*07dc1947SRichard Lowe                                           sizeof(struct
200*07dc1947SRichard Lowe                                                  Dwarf_Reg_Rule_s));
201*07dc1947SRichard Lowe 
202*07dc1947SRichard Lowe     struct Dwarf_Reg_Rule_s cfa_reg;
20349d3bc91SRichard Lowe 
20449d3bc91SRichard Lowe 
20549d3bc91SRichard Lowe     /* This is used to end executing frame instructions.  */
206*07dc1947SRichard Lowe     /* Becomes true when search_pc is true and current_loc */
20749d3bc91SRichard Lowe     /* is greater than search_pc_val.  */
20849d3bc91SRichard Lowe     Dwarf_Bool search_over = false;
20949d3bc91SRichard Lowe 
21049d3bc91SRichard Lowe     /* Used by the DW_FRAME_advance_loc instr */
21149d3bc91SRichard Lowe     /* to hold the increment in pc value.  */
21249d3bc91SRichard Lowe     Dwarf_Addr adv_pc;
21349d3bc91SRichard Lowe 
21449d3bc91SRichard Lowe     /* Contains the length in bytes of */
21549d3bc91SRichard Lowe     /* an leb128 encoded number.  */
21649d3bc91SRichard Lowe     Dwarf_Word leb128_length;
21749d3bc91SRichard Lowe 
218*07dc1947SRichard Lowe     Dwarf_Half address_size = (cie)? cie->ci_address_size:
219*07dc1947SRichard Lowe         dbg->de_pointer_size;
220*07dc1947SRichard Lowe 
22149d3bc91SRichard Lowe     /* Counts the number of frame instructions executed.  */
22249d3bc91SRichard Lowe     Dwarf_Word instr_count = 0;
22349d3bc91SRichard Lowe 
22449d3bc91SRichard Lowe     /*
22549d3bc91SRichard Lowe        These contain the current fields of the current frame
22649d3bc91SRichard Lowe        instruction. */
22749d3bc91SRichard Lowe     Dwarf_Small fp_base_op = 0;
22849d3bc91SRichard Lowe     Dwarf_Small fp_extended_op;
229*07dc1947SRichard Lowe     reg_num_type fp_register;
230*07dc1947SRichard Lowe 
231*07dc1947SRichard Lowe     /* The value in fp_offset may be signed, though we call it
232*07dc1947SRichard Lowe        unsigned. This works ok for 2-s complement arithmetic. */
23349d3bc91SRichard Lowe     Dwarf_Unsigned fp_offset;
23449d3bc91SRichard Lowe     Dwarf_Off fp_instr_offset;
23549d3bc91SRichard Lowe 
23649d3bc91SRichard Lowe     /*
23749d3bc91SRichard Lowe        Stack_table points to the row (Dwarf_Frame ie) being pushed or
23849d3bc91SRichard Lowe        popped by a remember or restore instruction. Top_stack points to
23949d3bc91SRichard Lowe        the top of the stack of rows. */
240*07dc1947SRichard Lowe     Dwarf_Frame stack_table = NULL;
24149d3bc91SRichard Lowe     Dwarf_Frame top_stack = NULL;
24249d3bc91SRichard Lowe 
24349d3bc91SRichard Lowe     /*
24449d3bc91SRichard Lowe        These are used only when make_instr is true. Curr_instr is a
24549d3bc91SRichard Lowe        pointer to the current frame instruction executed.
246*07dc1947SRichard Lowe        Curr_instr_ptr, head_instr_list, and curr_instr_list are used to
247*07dc1947SRichard Lowe        form a chain of Dwarf_Frame_Op structs. Dealloc_instr_ptr is
248*07dc1947SRichard Lowe        used to deallocate the structs used to form the chain.
24949d3bc91SRichard Lowe        Head_instr_block points to a contiguous list of pointers to the
25049d3bc91SRichard Lowe        Dwarf_Frame_Op structs executed. */
25149d3bc91SRichard Lowe     Dwarf_Frame_Op *curr_instr;
25249d3bc91SRichard Lowe     Dwarf_Chain curr_instr_item, dealloc_instr_item;
25349d3bc91SRichard Lowe     Dwarf_Chain head_instr_chain = NULL;
25449d3bc91SRichard Lowe     Dwarf_Chain tail_instr_chain = NULL;
25549d3bc91SRichard Lowe     Dwarf_Frame_Op *head_instr_block;
25649d3bc91SRichard Lowe 
25749d3bc91SRichard Lowe     /*
25849d3bc91SRichard Lowe        These are the alignment_factors taken from the Cie provided.
25949d3bc91SRichard Lowe        When no input Cie is provided they are set to 1, because only
26049d3bc91SRichard Lowe        factored offsets are required. */
26149d3bc91SRichard Lowe     Dwarf_Sword code_alignment_factor = 1;
26249d3bc91SRichard Lowe     Dwarf_Sword data_alignment_factor = 1;
26349d3bc91SRichard Lowe 
26449d3bc91SRichard Lowe     /*
26549d3bc91SRichard Lowe        This flag indicates when an actual alignment factor is needed.
26649d3bc91SRichard Lowe        So if a frame instruction that computes an offset using an
26749d3bc91SRichard Lowe        alignment factor is encountered when this flag is set, an error
26849d3bc91SRichard Lowe        is returned because the Cie did not have a valid augmentation. */
26949d3bc91SRichard Lowe     Dwarf_Bool need_augmentation = false;
27049d3bc91SRichard Lowe 
27149d3bc91SRichard Lowe     Dwarf_Word i;
27249d3bc91SRichard Lowe 
27349d3bc91SRichard Lowe     /* Initialize first row from associated Cie. Using temp regs
27449d3bc91SRichard Lowe        explicity */
27549d3bc91SRichard Lowe 
276*07dc1947SRichard Lowe     if (localregtab == 0) {
277*07dc1947SRichard Lowe         SIMPLE_ERROR_RETURN(DW_DLE_ALLOC_FAIL);
278*07dc1947SRichard Lowe     }
279*07dc1947SRichard Lowe     {
280*07dc1947SRichard Lowe         struct Dwarf_Reg_Rule_s *t1reg = localregtab;
281*07dc1947SRichard Lowe         struct Dwarf_Reg_Rule_s *t1end = t1reg + reg_count;
28249d3bc91SRichard Lowe 
28349d3bc91SRichard Lowe         if (cie != NULL && cie->ci_initial_table != NULL) {
284*07dc1947SRichard Lowe             struct Dwarf_Reg_Rule_s *t2reg =
285*07dc1947SRichard Lowe                 cie->ci_initial_table->fr_reg;
286*07dc1947SRichard Lowe 
287*07dc1947SRichard Lowe             if (reg_count != cie->ci_initial_table->fr_reg_count) {
288*07dc1947SRichard Lowe                 /* Should never happen, it makes no sense to have the
289*07dc1947SRichard Lowe                    table sizes change. There is no real allowance for
290*07dc1947SRichard Lowe                    the set of registers to change dynamically in a
291*07dc1947SRichard Lowe                    single Dwarf_Debug (except the size can be set near
292*07dc1947SRichard Lowe                    initial Dwarf_Debug creation time). */
293*07dc1947SRichard Lowe                 SIMPLE_ERROR_RETURN
294*07dc1947SRichard Lowe                     (DW_DLE_FRAME_REGISTER_COUNT_MISMATCH);
295*07dc1947SRichard Lowe             }
296*07dc1947SRichard Lowe 
29749d3bc91SRichard Lowe             for (; t1reg < t1end; t1reg++, t2reg++) {
29849d3bc91SRichard Lowe                 *t1reg = *t2reg;
29949d3bc91SRichard Lowe             }
300*07dc1947SRichard Lowe             cfa_reg = cie->ci_initial_table->fr_cfa_rule;
301*07dc1947SRichard Lowe         } else {
302*07dc1947SRichard Lowe             _dwarf_init_regrule_table(t1reg,
303*07dc1947SRichard Lowe                                       reg_count,
304*07dc1947SRichard Lowe                                       dbg->de_frame_rule_initial_value);
305*07dc1947SRichard Lowe             _dwarf_init_regrule_table(&cfa_reg, 1,
306*07dc1947SRichard Lowe                                       dbg->de_frame_rule_initial_value);
30749d3bc91SRichard Lowe         }
30849d3bc91SRichard Lowe     }
30949d3bc91SRichard Lowe 
31049d3bc91SRichard Lowe     /*
31149d3bc91SRichard Lowe        The idea here is that the code_alignment_factor and
31249d3bc91SRichard Lowe        data_alignment_factor which are needed for certain instructions
313*07dc1947SRichard Lowe        are valid only when the Cie has a proper augmentation string. So
314*07dc1947SRichard Lowe        if the augmentation is not right, only Frame instruction can be
315*07dc1947SRichard Lowe        read. */
31649d3bc91SRichard Lowe     if (cie != NULL && cie->ci_augmentation != NULL) {
31749d3bc91SRichard Lowe         code_alignment_factor = cie->ci_code_alignment_factor;
31849d3bc91SRichard Lowe         data_alignment_factor = cie->ci_data_alignment_factor;
319*07dc1947SRichard Lowe     } else {
32049d3bc91SRichard Lowe         need_augmentation = !make_instr;
321*07dc1947SRichard Lowe     }
32249d3bc91SRichard Lowe 
32349d3bc91SRichard Lowe     instr_ptr = start_instr_ptr;
32449d3bc91SRichard Lowe     while ((instr_ptr < final_instr_ptr) && (!search_over)) {
325*07dc1947SRichard Lowe         Dwarf_Small instr = 0;
326*07dc1947SRichard Lowe         Dwarf_Small opcode = 0;
327*07dc1947SRichard Lowe         reg_num_type reg_no = 0;
32849d3bc91SRichard Lowe 
32949d3bc91SRichard Lowe         fp_instr_offset = instr_ptr - start_instr_ptr;
33049d3bc91SRichard Lowe         instr = *(Dwarf_Small *) instr_ptr;
33149d3bc91SRichard Lowe         instr_ptr += sizeof(Dwarf_Small);
33249d3bc91SRichard Lowe 
33349d3bc91SRichard Lowe         fp_base_op = (instr & 0xc0) >> 6;
33449d3bc91SRichard Lowe         if ((instr & 0xc0) == 0x00) {
33549d3bc91SRichard Lowe             opcode = instr;     /* is really extended op */
33649d3bc91SRichard Lowe             fp_extended_op = (instr & (~(0xc0))) & 0xff;
33749d3bc91SRichard Lowe         } else {
33849d3bc91SRichard Lowe             opcode = instr & 0xc0;      /* is base op */
33949d3bc91SRichard Lowe             fp_extended_op = 0;
34049d3bc91SRichard Lowe         }
34149d3bc91SRichard Lowe 
34249d3bc91SRichard Lowe         fp_register = 0;
34349d3bc91SRichard Lowe         fp_offset = 0;
34449d3bc91SRichard Lowe         switch (opcode) {
345*07dc1947SRichard Lowe         case DW_CFA_advance_loc:
346*07dc1947SRichard Lowe             {
34749d3bc91SRichard Lowe                 /* base op */
34849d3bc91SRichard Lowe                 fp_offset = adv_pc = instr & DW_FRAME_INSTR_OFFSET_MASK;
34949d3bc91SRichard Lowe 
35049d3bc91SRichard Lowe                 if (need_augmentation) {
351*07dc1947SRichard Lowe                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
35249d3bc91SRichard Lowe                 }
35349d3bc91SRichard Lowe                 adv_pc = adv_pc * code_alignment_factor;
35449d3bc91SRichard Lowe 
35549d3bc91SRichard Lowe                 search_over = search_pc &&
356*07dc1947SRichard Lowe                     (current_loc + adv_pc > search_pc_val);
35749d3bc91SRichard Lowe                 /* If gone past pc needed, retain old pc.  */
358*07dc1947SRichard Lowe                 if (!search_over) {
359*07dc1947SRichard Lowe                     current_loc = current_loc + adv_pc;
360*07dc1947SRichard Lowe                 }
36149d3bc91SRichard Lowe                 break;
36249d3bc91SRichard Lowe             }
36349d3bc91SRichard Lowe 
364*07dc1947SRichard Lowe         case DW_CFA_offset:
365*07dc1947SRichard Lowe             {                   /* base op */
366*07dc1947SRichard Lowe                 reg_no =
367*07dc1947SRichard Lowe                     (reg_num_type) (instr & DW_FRAME_INSTR_OFFSET_MASK);
368*07dc1947SRichard Lowe                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
36949d3bc91SRichard Lowe 
37049d3bc91SRichard Lowe                 factored_N_value =
37149d3bc91SRichard Lowe                     _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
37249d3bc91SRichard Lowe                 instr_ptr = instr_ptr + leb128_length;
37349d3bc91SRichard Lowe 
37449d3bc91SRichard Lowe                 fp_register = reg_no;
37549d3bc91SRichard Lowe                 fp_offset = factored_N_value;
37649d3bc91SRichard Lowe 
37749d3bc91SRichard Lowe                 if (need_augmentation) {
378*07dc1947SRichard Lowe                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
37949d3bc91SRichard Lowe                 }
38049d3bc91SRichard Lowe 
381*07dc1947SRichard Lowe                 localregtab[reg_no].ru_is_off = 1;
382*07dc1947SRichard Lowe                 localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
383*07dc1947SRichard Lowe                 localregtab[reg_no].ru_register = reg_num_of_cfa;
384*07dc1947SRichard Lowe                 localregtab[reg_no].ru_offset_or_block_len =
385*07dc1947SRichard Lowe                     factored_N_value * data_alignment_factor;
38649d3bc91SRichard Lowe 
38749d3bc91SRichard Lowe                 break;
38849d3bc91SRichard Lowe             }
38949d3bc91SRichard Lowe 
390*07dc1947SRichard Lowe         case DW_CFA_restore:
391*07dc1947SRichard Lowe             {                   /* base op */
39249d3bc91SRichard Lowe                 reg_no = (instr & DW_FRAME_INSTR_OFFSET_MASK);
393*07dc1947SRichard Lowe                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
39449d3bc91SRichard Lowe 
39549d3bc91SRichard Lowe                 fp_register = reg_no;
39649d3bc91SRichard Lowe 
39749d3bc91SRichard Lowe                 if (cie != NULL && cie->ci_initial_table != NULL)
398*07dc1947SRichard Lowe                     localregtab[reg_no] =
399*07dc1947SRichard Lowe                        cie->ci_initial_table->fr_reg[reg_no];
40049d3bc91SRichard Lowe                 else if (!make_instr) {
401*07dc1947SRichard Lowe                     SIMPLE_ERROR_RETURN(DW_DLE_DF_MAKE_INSTR_NO_INIT);
40249d3bc91SRichard Lowe                 }
40349d3bc91SRichard Lowe 
40449d3bc91SRichard Lowe                 break;
40549d3bc91SRichard Lowe             }
406*07dc1947SRichard Lowe         case DW_CFA_set_loc:
407*07dc1947SRichard Lowe             {
408*07dc1947SRichard Lowe                 Dwarf_Addr new_loc = 0;
409*07dc1947SRichard Lowe 
41049d3bc91SRichard Lowe                 READ_UNALIGNED(dbg, new_loc, Dwarf_Addr,
411*07dc1947SRichard Lowe                                instr_ptr, address_size);
412*07dc1947SRichard Lowe                 instr_ptr += address_size;
413*07dc1947SRichard Lowe                 if (new_loc != 0 && current_loc != 0) {
414*07dc1947SRichard Lowe                     /* Pre-relocation or before current_loc is set the
415*07dc1947SRichard Lowe                        test comparing new_loc and current_loc makes no
416*07dc1947SRichard Lowe                        sense. Testing for non-zero (above) is a way
417*07dc1947SRichard Lowe                        (fallible) to check that current_loc, new_loc
418*07dc1947SRichard Lowe                        are already relocated.  */
419*07dc1947SRichard Lowe                     if (new_loc <= current_loc) {
420*07dc1947SRichard Lowe                         /* Within a frame, address must increase.
421*07dc1947SRichard Lowe                            Seemingly it has not. Seems to be an error. */
422*07dc1947SRichard Lowe 
423*07dc1947SRichard Lowe                         SIMPLE_ERROR_RETURN
424*07dc1947SRichard Lowe                             (DW_DLE_DF_NEW_LOC_LESS_OLD_LOC);
425*07dc1947SRichard Lowe                     }
42649d3bc91SRichard Lowe                 }
42749d3bc91SRichard Lowe 
42849d3bc91SRichard Lowe                 search_over = search_pc && (new_loc > search_pc_val);
42949d3bc91SRichard Lowe 
43049d3bc91SRichard Lowe                 /* If gone past pc needed, retain old pc.  */
431*07dc1947SRichard Lowe                 if (!search_over) {
432*07dc1947SRichard Lowe                     current_loc = new_loc;
433*07dc1947SRichard Lowe                 }
43449d3bc91SRichard Lowe                 fp_offset = new_loc;
43549d3bc91SRichard Lowe                 break;
43649d3bc91SRichard Lowe             }
43749d3bc91SRichard Lowe 
438*07dc1947SRichard Lowe         case DW_CFA_advance_loc1:
439*07dc1947SRichard Lowe             {
44049d3bc91SRichard Lowe                 fp_offset = adv_loc = *(Dwarf_Small *) instr_ptr;
44149d3bc91SRichard Lowe                 instr_ptr += sizeof(Dwarf_Small);
44249d3bc91SRichard Lowe 
44349d3bc91SRichard Lowe                 if (need_augmentation) {
444*07dc1947SRichard Lowe                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
44549d3bc91SRichard Lowe                 }
44649d3bc91SRichard Lowe                 adv_loc *= code_alignment_factor;
44749d3bc91SRichard Lowe 
44849d3bc91SRichard Lowe                 search_over = search_pc &&
449*07dc1947SRichard Lowe                     (current_loc + adv_loc > search_pc_val);
45049d3bc91SRichard Lowe 
45149d3bc91SRichard Lowe                 /* If gone past pc needed, retain old pc.  */
452*07dc1947SRichard Lowe                 if (!search_over) {
453*07dc1947SRichard Lowe                     current_loc = current_loc + adv_loc;
454*07dc1947SRichard Lowe                 }
45549d3bc91SRichard Lowe                 break;
45649d3bc91SRichard Lowe             }
45749d3bc91SRichard Lowe 
458*07dc1947SRichard Lowe         case DW_CFA_advance_loc2:
459*07dc1947SRichard Lowe             {
46049d3bc91SRichard Lowe                 READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
46149d3bc91SRichard Lowe                                instr_ptr, sizeof(Dwarf_Half));
46249d3bc91SRichard Lowe                 instr_ptr += sizeof(Dwarf_Half);
46349d3bc91SRichard Lowe                 fp_offset = adv_loc;
46449d3bc91SRichard Lowe 
46549d3bc91SRichard Lowe                 if (need_augmentation) {
466*07dc1947SRichard Lowe                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
46749d3bc91SRichard Lowe                 }
46849d3bc91SRichard Lowe                 adv_loc *= code_alignment_factor;
46949d3bc91SRichard Lowe 
47049d3bc91SRichard Lowe                 search_over = search_pc &&
471*07dc1947SRichard Lowe                     (current_loc + adv_loc > search_pc_val);
47249d3bc91SRichard Lowe 
47349d3bc91SRichard Lowe                 /* If gone past pc needed, retain old pc.  */
474*07dc1947SRichard Lowe                 if (!search_over) {
475*07dc1947SRichard Lowe                     current_loc = current_loc + adv_loc;
476*07dc1947SRichard Lowe                 }
47749d3bc91SRichard Lowe                 break;
47849d3bc91SRichard Lowe             }
47949d3bc91SRichard Lowe 
480*07dc1947SRichard Lowe         case DW_CFA_advance_loc4:
481*07dc1947SRichard Lowe             {
48249d3bc91SRichard Lowe                 READ_UNALIGNED(dbg, adv_loc, Dwarf_Unsigned,
48349d3bc91SRichard Lowe                                instr_ptr, sizeof(Dwarf_ufixed));
48449d3bc91SRichard Lowe                 instr_ptr += sizeof(Dwarf_ufixed);
48549d3bc91SRichard Lowe                 fp_offset = adv_loc;
48649d3bc91SRichard Lowe 
48749d3bc91SRichard Lowe                 if (need_augmentation) {
488*07dc1947SRichard Lowe                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
48949d3bc91SRichard Lowe                 }
49049d3bc91SRichard Lowe                 adv_loc *= code_alignment_factor;
49149d3bc91SRichard Lowe 
49249d3bc91SRichard Lowe                 search_over = search_pc &&
493*07dc1947SRichard Lowe                     (current_loc + adv_loc > search_pc_val);
49449d3bc91SRichard Lowe 
49549d3bc91SRichard Lowe                 /* If gone past pc needed, retain old pc.  */
496*07dc1947SRichard Lowe                 if (!search_over) {
497*07dc1947SRichard Lowe                     current_loc = current_loc + adv_loc;
498*07dc1947SRichard Lowe                 }
49949d3bc91SRichard Lowe                 break;
50049d3bc91SRichard Lowe             }
50149d3bc91SRichard Lowe 
502*07dc1947SRichard Lowe         case DW_CFA_offset_extended:
503*07dc1947SRichard Lowe             {
50449d3bc91SRichard Lowe                 Dwarf_Unsigned lreg;
50549d3bc91SRichard Lowe 
506*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, lreg);
507*07dc1947SRichard Lowe                 reg_no = (reg_num_type) lreg;
508*07dc1947SRichard Lowe                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);;
50949d3bc91SRichard Lowe                 factored_N_value =
51049d3bc91SRichard Lowe                     _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
51149d3bc91SRichard Lowe                 instr_ptr += leb128_length;
51249d3bc91SRichard Lowe 
51349d3bc91SRichard Lowe                 if (need_augmentation) {
514*07dc1947SRichard Lowe                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
51549d3bc91SRichard Lowe                 }
516*07dc1947SRichard Lowe                 localregtab[reg_no].ru_is_off = 1;
517*07dc1947SRichard Lowe                 localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
518*07dc1947SRichard Lowe                 localregtab[reg_no].ru_register = reg_num_of_cfa;
519*07dc1947SRichard Lowe                 localregtab[reg_no].ru_offset_or_block_len = factored_N_value *
52049d3bc91SRichard Lowe                     data_alignment_factor;
52149d3bc91SRichard Lowe 
52249d3bc91SRichard Lowe                 fp_register = reg_no;
52349d3bc91SRichard Lowe                 fp_offset = factored_N_value;
52449d3bc91SRichard Lowe                 break;
52549d3bc91SRichard Lowe             }
52649d3bc91SRichard Lowe 
527*07dc1947SRichard Lowe         case DW_CFA_restore_extended:
528*07dc1947SRichard Lowe             {
52949d3bc91SRichard Lowe                 Dwarf_Unsigned lreg;
53049d3bc91SRichard Lowe 
531*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, lreg);
532*07dc1947SRichard Lowe                 reg_no = (reg_num_type) lreg;
53349d3bc91SRichard Lowe 
534*07dc1947SRichard Lowe                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
53549d3bc91SRichard Lowe 
53649d3bc91SRichard Lowe                 if (cie != NULL && cie->ci_initial_table != NULL) {
537*07dc1947SRichard Lowe                     localregtab[reg_no] = cie->ci_initial_table->fr_reg[reg_no];
53849d3bc91SRichard Lowe                 } else {
53949d3bc91SRichard Lowe                     if (!make_instr) {
540*07dc1947SRichard Lowe                         SIMPLE_ERROR_RETURN
54149d3bc91SRichard Lowe                             (DW_DLE_DF_MAKE_INSTR_NO_INIT);
54249d3bc91SRichard Lowe                     }
54349d3bc91SRichard Lowe                 }
54449d3bc91SRichard Lowe 
54549d3bc91SRichard Lowe                 fp_register = reg_no;
54649d3bc91SRichard Lowe                 break;
54749d3bc91SRichard Lowe             }
54849d3bc91SRichard Lowe 
549*07dc1947SRichard Lowe         case DW_CFA_undefined:
550*07dc1947SRichard Lowe             {
55149d3bc91SRichard Lowe                 Dwarf_Unsigned lreg;
55249d3bc91SRichard Lowe 
553*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, lreg);
554*07dc1947SRichard Lowe                 reg_no = (reg_num_type) lreg;
555*07dc1947SRichard Lowe                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
55649d3bc91SRichard Lowe 
557*07dc1947SRichard Lowe                 localregtab[reg_no].ru_is_off = 0;
558*07dc1947SRichard Lowe                 localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
559*07dc1947SRichard Lowe                 localregtab[reg_no].ru_register =
560*07dc1947SRichard Lowe                     dbg->de_frame_undefined_value_number;
561*07dc1947SRichard Lowe                 localregtab[reg_no].ru_offset_or_block_len = 0;
56249d3bc91SRichard Lowe 
56349d3bc91SRichard Lowe                 fp_register = reg_no;
56449d3bc91SRichard Lowe                 break;
56549d3bc91SRichard Lowe             }
56649d3bc91SRichard Lowe 
567*07dc1947SRichard Lowe         case DW_CFA_same_value:
568*07dc1947SRichard Lowe             {
56949d3bc91SRichard Lowe                 Dwarf_Unsigned lreg;
57049d3bc91SRichard Lowe 
571*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, lreg);
572*07dc1947SRichard Lowe                 reg_no = (reg_num_type) lreg;
573*07dc1947SRichard Lowe                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
57449d3bc91SRichard Lowe 
575*07dc1947SRichard Lowe                 localregtab[reg_no].ru_is_off = 0;
576*07dc1947SRichard Lowe                 localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
577*07dc1947SRichard Lowe                 localregtab[reg_no].ru_register =
578*07dc1947SRichard Lowe                     dbg->de_frame_same_value_number;
579*07dc1947SRichard Lowe                 localregtab[reg_no].ru_offset_or_block_len = 0;
58049d3bc91SRichard Lowe                 fp_register = reg_no;
58149d3bc91SRichard Lowe                 break;
58249d3bc91SRichard Lowe             }
58349d3bc91SRichard Lowe 
584*07dc1947SRichard Lowe         case DW_CFA_register:
585*07dc1947SRichard Lowe             {
58649d3bc91SRichard Lowe                 Dwarf_Unsigned lreg;
587*07dc1947SRichard Lowe                 reg_num_type reg_noA = 0;
588*07dc1947SRichard Lowe                 reg_num_type reg_noB = 0;
58949d3bc91SRichard Lowe 
590*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, lreg);
591*07dc1947SRichard Lowe                 reg_noA = (reg_num_type) lreg;
59249d3bc91SRichard Lowe 
593*07dc1947SRichard Lowe                 ERROR_IF_REG_NUM_TOO_HIGH(reg_noA, reg_count);
59449d3bc91SRichard Lowe 
595*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, lreg);
596*07dc1947SRichard Lowe                 reg_noB = (reg_num_type) lreg;
59749d3bc91SRichard Lowe 
598*07dc1947SRichard Lowe                 if (reg_noB > reg_count) {
599*07dc1947SRichard Lowe                     SIMPLE_ERROR_RETURN(DW_DLE_DF_REG_NUM_TOO_HIGH);
60049d3bc91SRichard Lowe                 }
60149d3bc91SRichard Lowe 
60249d3bc91SRichard Lowe 
603*07dc1947SRichard Lowe                 localregtab[reg_noA].ru_is_off = 0;
604*07dc1947SRichard Lowe                 localregtab[reg_noA].ru_value_type = DW_EXPR_OFFSET;
605*07dc1947SRichard Lowe                 localregtab[reg_noA].ru_register = reg_noB;
606*07dc1947SRichard Lowe                 localregtab[reg_noA].ru_offset_or_block_len = 0;
60749d3bc91SRichard Lowe 
60849d3bc91SRichard Lowe                 fp_register = reg_noA;
60949d3bc91SRichard Lowe                 fp_offset = reg_noB;
61049d3bc91SRichard Lowe                 break;
61149d3bc91SRichard Lowe             }
61249d3bc91SRichard Lowe 
613*07dc1947SRichard Lowe         case DW_CFA_remember_state:
614*07dc1947SRichard Lowe             {
61549d3bc91SRichard Lowe                 stack_table = (Dwarf_Frame)
61649d3bc91SRichard Lowe                     _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
61749d3bc91SRichard Lowe                 if (stack_table == NULL) {
618*07dc1947SRichard Lowe                     SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
61949d3bc91SRichard Lowe                 }
62049d3bc91SRichard Lowe 
621*07dc1947SRichard Lowe                 for (i = 0; i < reg_count; i++)
622*07dc1947SRichard Lowe                     stack_table->fr_reg[i] = localregtab[i];
623*07dc1947SRichard Lowe                 stack_table->fr_cfa_rule = cfa_reg;
62449d3bc91SRichard Lowe 
62549d3bc91SRichard Lowe                 if (top_stack != NULL)
62649d3bc91SRichard Lowe                     stack_table->fr_next = top_stack;
62749d3bc91SRichard Lowe                 top_stack = stack_table;
62849d3bc91SRichard Lowe 
62949d3bc91SRichard Lowe                 break;
63049d3bc91SRichard Lowe             }
63149d3bc91SRichard Lowe 
632*07dc1947SRichard Lowe         case DW_CFA_restore_state:
633*07dc1947SRichard Lowe             {
63449d3bc91SRichard Lowe                 if (top_stack == NULL) {
635*07dc1947SRichard Lowe                     SIMPLE_ERROR_RETURN(DW_DLE_DF_POP_EMPTY_STACK);
63649d3bc91SRichard Lowe                 }
63749d3bc91SRichard Lowe                 stack_table = top_stack;
63849d3bc91SRichard Lowe                 top_stack = stack_table->fr_next;
63949d3bc91SRichard Lowe 
640*07dc1947SRichard Lowe                 for (i = 0; i < reg_count; i++)
641*07dc1947SRichard Lowe                     localregtab[i] = stack_table->fr_reg[i];
642*07dc1947SRichard Lowe                 cfa_reg = stack_table->fr_cfa_rule;
64349d3bc91SRichard Lowe 
64449d3bc91SRichard Lowe                 dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
64549d3bc91SRichard Lowe                 break;
64649d3bc91SRichard Lowe             }
64749d3bc91SRichard Lowe 
648*07dc1947SRichard Lowe         case DW_CFA_def_cfa:
649*07dc1947SRichard Lowe             {
65049d3bc91SRichard Lowe                 Dwarf_Unsigned lreg;
65149d3bc91SRichard Lowe 
652*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, lreg);
653*07dc1947SRichard Lowe                 reg_no = (reg_num_type) lreg;
65449d3bc91SRichard Lowe 
655*07dc1947SRichard Lowe                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
65649d3bc91SRichard Lowe 
65749d3bc91SRichard Lowe                 factored_N_value =
65849d3bc91SRichard Lowe                     _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
65949d3bc91SRichard Lowe                 instr_ptr += leb128_length;
66049d3bc91SRichard Lowe 
66149d3bc91SRichard Lowe                 if (need_augmentation) {
662*07dc1947SRichard Lowe                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
66349d3bc91SRichard Lowe                 }
664*07dc1947SRichard Lowe                 cfa_reg.ru_is_off = 1;
665*07dc1947SRichard Lowe                 cfa_reg.ru_value_type = DW_EXPR_OFFSET;
666*07dc1947SRichard Lowe                 cfa_reg.ru_register = reg_no;
667*07dc1947SRichard Lowe                 cfa_reg.ru_offset_or_block_len = factored_N_value;
66849d3bc91SRichard Lowe 
66949d3bc91SRichard Lowe                 fp_register = reg_no;
67049d3bc91SRichard Lowe                 fp_offset = factored_N_value;
67149d3bc91SRichard Lowe                 break;
67249d3bc91SRichard Lowe             }
67349d3bc91SRichard Lowe 
674*07dc1947SRichard Lowe         case DW_CFA_def_cfa_register:
675*07dc1947SRichard Lowe             {
67649d3bc91SRichard Lowe                 Dwarf_Unsigned lreg;
67749d3bc91SRichard Lowe 
678*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, lreg);
679*07dc1947SRichard Lowe                 reg_no = (reg_num_type) lreg;
680*07dc1947SRichard Lowe                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
68149d3bc91SRichard Lowe 
682*07dc1947SRichard Lowe                 cfa_reg.ru_register = reg_no;
683*07dc1947SRichard Lowe                 /* Do NOT set ru_offset_or_block_len or ru_is_off here.
684*07dc1947SRichard Lowe                    See dwarf2/3 spec.  */
68549d3bc91SRichard Lowe                 fp_register = reg_no;
68649d3bc91SRichard Lowe                 break;
68749d3bc91SRichard Lowe             }
68849d3bc91SRichard Lowe 
689*07dc1947SRichard Lowe         case DW_CFA_def_cfa_offset:
690*07dc1947SRichard Lowe             {
69149d3bc91SRichard Lowe                 factored_N_value =
69249d3bc91SRichard Lowe                     _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
69349d3bc91SRichard Lowe                 instr_ptr += leb128_length;
69449d3bc91SRichard Lowe 
69549d3bc91SRichard Lowe                 if (need_augmentation) {
696*07dc1947SRichard Lowe                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
69749d3bc91SRichard Lowe                 }
698*07dc1947SRichard Lowe                 /* Do set ru_is_off here, as here factored_N_value
699*07dc1947SRichard Lowe                    counts.  */
700*07dc1947SRichard Lowe                 cfa_reg.ru_is_off = 1;
701*07dc1947SRichard Lowe                 cfa_reg.ru_value_type = DW_EXPR_OFFSET;
702*07dc1947SRichard Lowe                 cfa_reg.ru_offset_or_block_len = factored_N_value;
70349d3bc91SRichard Lowe 
70449d3bc91SRichard Lowe                 fp_offset = factored_N_value;
70549d3bc91SRichard Lowe                 break;
70649d3bc91SRichard Lowe             }
707*07dc1947SRichard Lowe         case DW_CFA_nop:
708*07dc1947SRichard Lowe             {
70949d3bc91SRichard Lowe                 break;
71049d3bc91SRichard Lowe             }
711*07dc1947SRichard Lowe             /* DWARF3 ops begin here. */
712*07dc1947SRichard Lowe         case DW_CFA_def_cfa_expression:
713*07dc1947SRichard Lowe             {
714*07dc1947SRichard Lowe                 /* A single DW_FORM_block representing a dwarf
715*07dc1947SRichard Lowe                    expression. The form block establishes the way to
716*07dc1947SRichard Lowe                    compute the CFA. */
717*07dc1947SRichard Lowe                 Dwarf_Unsigned block_len = 0;
718*07dc1947SRichard Lowe 
719*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, block_len);
720*07dc1947SRichard Lowe                 cfa_reg.ru_is_off = 0;  /* arbitrary */
721*07dc1947SRichard Lowe                 cfa_reg.ru_value_type = DW_EXPR_EXPRESSION;
722*07dc1947SRichard Lowe                 cfa_reg.ru_offset_or_block_len = block_len;
723*07dc1947SRichard Lowe                 cfa_reg.ru_block = instr_ptr;
724*07dc1947SRichard Lowe                 fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr;
725*07dc1947SRichard Lowe                 instr_ptr += block_len;
726*07dc1947SRichard Lowe             }
727*07dc1947SRichard Lowe             break;
728*07dc1947SRichard Lowe         case DW_CFA_expression:
729*07dc1947SRichard Lowe             {
730*07dc1947SRichard Lowe                 /* An unsigned leb128 value is the first operand (a
731*07dc1947SRichard Lowe                    register number). The second operand is single
732*07dc1947SRichard Lowe                    DW_FORM_block representing a dwarf expression. The
733*07dc1947SRichard Lowe                    evaluator pushes the CFA on the evaluation stack
734*07dc1947SRichard Lowe                    then evaluates the expression to compute the value
735*07dc1947SRichard Lowe                    of the register contents. */
736*07dc1947SRichard Lowe                 Dwarf_Unsigned lreg = 0;
737*07dc1947SRichard Lowe                 Dwarf_Unsigned block_len = 0;
738*07dc1947SRichard Lowe 
739*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, lreg);
740*07dc1947SRichard Lowe                 reg_no = (reg_num_type) lreg;
741*07dc1947SRichard Lowe                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
742*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, block_len);
743*07dc1947SRichard Lowe                 localregtab[lreg].ru_is_off = 0;        /* arbitrary */
744*07dc1947SRichard Lowe                 localregtab[lreg].ru_value_type = DW_EXPR_EXPRESSION;
745*07dc1947SRichard Lowe                 localregtab[lreg].ru_offset_or_block_len = block_len;
746*07dc1947SRichard Lowe                 localregtab[lreg].ru_block = instr_ptr;
747*07dc1947SRichard Lowe                 fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr;
748*07dc1947SRichard Lowe                 fp_register = reg_no;
749*07dc1947SRichard Lowe                 instr_ptr += block_len;
750*07dc1947SRichard Lowe             }
751*07dc1947SRichard Lowe             break;
752*07dc1947SRichard Lowe         case DW_CFA_offset_extended_sf:
753*07dc1947SRichard Lowe             {
754*07dc1947SRichard Lowe                 /* The first operand is an unsigned leb128 register
755*07dc1947SRichard Lowe                    number. The second is a signed factored offset.
756*07dc1947SRichard Lowe                    Identical to DW_CFA_offset_extended except the
757*07dc1947SRichard Lowe                    secondoperand is signed */
758*07dc1947SRichard Lowe                 Dwarf_Unsigned lreg;
759*07dc1947SRichard Lowe 
760*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, lreg);
761*07dc1947SRichard Lowe                 reg_no = (reg_num_type) lreg;
762*07dc1947SRichard Lowe                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
763*07dc1947SRichard Lowe                 signed_factored_N_value =
764*07dc1947SRichard Lowe                     _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
765*07dc1947SRichard Lowe                 instr_ptr += leb128_length;
766*07dc1947SRichard Lowe 
767*07dc1947SRichard Lowe                 if (need_augmentation) {
768*07dc1947SRichard Lowe                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
769*07dc1947SRichard Lowe                 }
770*07dc1947SRichard Lowe                 localregtab[reg_no].ru_is_off = 1;
771*07dc1947SRichard Lowe                 localregtab[reg_no].ru_value_type = DW_EXPR_OFFSET;
772*07dc1947SRichard Lowe                 localregtab[reg_no].ru_register = reg_num_of_cfa;
773*07dc1947SRichard Lowe                 localregtab[reg_no].ru_offset_or_block_len =
774*07dc1947SRichard Lowe                     signed_factored_N_value * data_alignment_factor;
775*07dc1947SRichard Lowe 
776*07dc1947SRichard Lowe                 fp_register = reg_no;
777*07dc1947SRichard Lowe                 fp_offset = signed_factored_N_value;
778*07dc1947SRichard Lowe             }
779*07dc1947SRichard Lowe             break;
780*07dc1947SRichard Lowe         case DW_CFA_def_cfa_sf:
781*07dc1947SRichard Lowe             {
782*07dc1947SRichard Lowe                 /* The first operand is an unsigned leb128 register
783*07dc1947SRichard Lowe                    number. The second is a signed leb128 factored
784*07dc1947SRichard Lowe                    offset. Identical to DW_CFA_def_cfa except that the
785*07dc1947SRichard Lowe                    second operand is signed and factored. */
786*07dc1947SRichard Lowe                 Dwarf_Unsigned lreg;
787*07dc1947SRichard Lowe 
788*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, lreg);
789*07dc1947SRichard Lowe                 reg_no = (reg_num_type) lreg;
790*07dc1947SRichard Lowe                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
791*07dc1947SRichard Lowe 
792*07dc1947SRichard Lowe                 signed_factored_N_value =
793*07dc1947SRichard Lowe                     _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
794*07dc1947SRichard Lowe                 instr_ptr += leb128_length;
795*07dc1947SRichard Lowe 
796*07dc1947SRichard Lowe                 if (need_augmentation) {
797*07dc1947SRichard Lowe                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
798*07dc1947SRichard Lowe                 }
799*07dc1947SRichard Lowe                 cfa_reg.ru_is_off = 1;
800*07dc1947SRichard Lowe                 cfa_reg.ru_value_type = DW_EXPR_OFFSET;
801*07dc1947SRichard Lowe                 cfa_reg.ru_register = reg_no;
802*07dc1947SRichard Lowe                 cfa_reg.ru_offset_or_block_len =
803*07dc1947SRichard Lowe                     signed_factored_N_value * data_alignment_factor;
804*07dc1947SRichard Lowe 
805*07dc1947SRichard Lowe                 fp_register = reg_no;
806*07dc1947SRichard Lowe                 fp_offset = signed_factored_N_value;
807*07dc1947SRichard Lowe             }
808*07dc1947SRichard Lowe             break;
809*07dc1947SRichard Lowe         case DW_CFA_def_cfa_offset_sf:
810*07dc1947SRichard Lowe             {
811*07dc1947SRichard Lowe                 /* The operand is a signed leb128 operand representing
812*07dc1947SRichard Lowe                    a factored offset.  Identical to
813*07dc1947SRichard Lowe                    DW_CFA_def_cfa_offset excep the operand is signed
814*07dc1947SRichard Lowe                    and factored. */
815*07dc1947SRichard Lowe 
816*07dc1947SRichard Lowe                 signed_factored_N_value =
817*07dc1947SRichard Lowe                     _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
818*07dc1947SRichard Lowe                 instr_ptr += leb128_length;
819*07dc1947SRichard Lowe 
820*07dc1947SRichard Lowe                 if (need_augmentation) {
821*07dc1947SRichard Lowe                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
822*07dc1947SRichard Lowe                 }
823*07dc1947SRichard Lowe                 /* Do set ru_is_off here, as here factored_N_value
824*07dc1947SRichard Lowe                    counts.  */
825*07dc1947SRichard Lowe                 cfa_reg.ru_is_off = 1;
826*07dc1947SRichard Lowe                 cfa_reg.ru_value_type = DW_EXPR_OFFSET;
827*07dc1947SRichard Lowe                 cfa_reg.ru_offset_or_block_len =
828*07dc1947SRichard Lowe                     signed_factored_N_value * data_alignment_factor;
829*07dc1947SRichard Lowe 
830*07dc1947SRichard Lowe                 fp_offset = signed_factored_N_value;
831*07dc1947SRichard Lowe             }
832*07dc1947SRichard Lowe             break;
833*07dc1947SRichard Lowe         case DW_CFA_val_offset:
834*07dc1947SRichard Lowe             {
835*07dc1947SRichard Lowe                 /* The first operand is an unsigned leb128 register
836*07dc1947SRichard Lowe                    number. The second is a factored unsigned offset.
837*07dc1947SRichard Lowe                    Makes the register be a val_offset(N) rule with N =
838*07dc1947SRichard Lowe                    factored_offset*data_alignment_factor. */
839*07dc1947SRichard Lowe 
840*07dc1947SRichard Lowe                 Dwarf_Unsigned lreg;
841*07dc1947SRichard Lowe 
842*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, lreg);
843*07dc1947SRichard Lowe                 reg_no = (reg_num_type) lreg;
844*07dc1947SRichard Lowe 
845*07dc1947SRichard Lowe                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
846*07dc1947SRichard Lowe 
847*07dc1947SRichard Lowe                 factored_N_value =
848*07dc1947SRichard Lowe                     _dwarf_decode_u_leb128(instr_ptr, &leb128_length);
849*07dc1947SRichard Lowe                 instr_ptr += leb128_length;
850*07dc1947SRichard Lowe 
851*07dc1947SRichard Lowe                 if (need_augmentation) {
852*07dc1947SRichard Lowe                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
853*07dc1947SRichard Lowe                 }
854*07dc1947SRichard Lowe                 /* Do set ru_is_off here, as here factored_N_value
855*07dc1947SRichard Lowe                    counts.  */
856*07dc1947SRichard Lowe                 localregtab[reg_no].ru_is_off = 1;
857*07dc1947SRichard Lowe                 localregtab[reg_no].ru_register = reg_num_of_cfa;
858*07dc1947SRichard Lowe                 localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET;
859*07dc1947SRichard Lowe                 localregtab[reg_no].ru_offset_or_block_len =
860*07dc1947SRichard Lowe                     factored_N_value * data_alignment_factor;
861*07dc1947SRichard Lowe 
862*07dc1947SRichard Lowe                 fp_offset = factored_N_value;
863*07dc1947SRichard Lowe                 break;
864*07dc1947SRichard Lowe             }
865*07dc1947SRichard Lowe         case DW_CFA_val_offset_sf:
866*07dc1947SRichard Lowe             {
867*07dc1947SRichard Lowe                 /* The first operand is an unsigned leb128 register
868*07dc1947SRichard Lowe                    number. The second is a factored signed offset.
869*07dc1947SRichard Lowe                    Makes the register be a val_offset(N) rule with N =
870*07dc1947SRichard Lowe                    factored_offset*data_alignment_factor. */
871*07dc1947SRichard Lowe                 Dwarf_Unsigned lreg;
872*07dc1947SRichard Lowe 
873*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, lreg);
874*07dc1947SRichard Lowe                 reg_no = (reg_num_type) lreg;
875*07dc1947SRichard Lowe 
876*07dc1947SRichard Lowe                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
877*07dc1947SRichard Lowe                 signed_factored_N_value =
878*07dc1947SRichard Lowe                     _dwarf_decode_s_leb128(instr_ptr, &leb128_length);
879*07dc1947SRichard Lowe                 instr_ptr += leb128_length;
880*07dc1947SRichard Lowe 
881*07dc1947SRichard Lowe                 if (need_augmentation) {
882*07dc1947SRichard Lowe                     SIMPLE_ERROR_RETURN(DW_DLE_DF_NO_CIE_AUGMENTATION);
883*07dc1947SRichard Lowe                 }
884*07dc1947SRichard Lowe                 /* Do set ru_is_off here, as here factored_N_value
885*07dc1947SRichard Lowe                    counts.  */
886*07dc1947SRichard Lowe                 localregtab[reg_no].ru_is_off = 1;
887*07dc1947SRichard Lowe                 localregtab[reg_no].ru_value_type = DW_EXPR_VAL_OFFSET;
888*07dc1947SRichard Lowe                 localregtab[reg_no].ru_offset_or_block_len =
889*07dc1947SRichard Lowe                     signed_factored_N_value * data_alignment_factor;
890*07dc1947SRichard Lowe 
891*07dc1947SRichard Lowe                 fp_offset = signed_factored_N_value;
892*07dc1947SRichard Lowe 
893*07dc1947SRichard Lowe             }
894*07dc1947SRichard Lowe             break;
895*07dc1947SRichard Lowe         case DW_CFA_val_expression:
896*07dc1947SRichard Lowe             {
897*07dc1947SRichard Lowe                 /* The first operand is an unsigned leb128 register
898*07dc1947SRichard Lowe                    number. The second is a DW_FORM_block representing a
899*07dc1947SRichard Lowe                    DWARF expression. The rule for the register number
900*07dc1947SRichard Lowe                    becomes a val_expression(E) rule. */
901*07dc1947SRichard Lowe                 Dwarf_Unsigned lreg = 0;
902*07dc1947SRichard Lowe                 Dwarf_Unsigned block_len = 0;
903*07dc1947SRichard Lowe 
904*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, lreg);
905*07dc1947SRichard Lowe                 reg_no = (reg_num_type) lreg;
906*07dc1947SRichard Lowe                 ERROR_IF_REG_NUM_TOO_HIGH(reg_no, reg_count);
907*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, block_len);
908*07dc1947SRichard Lowe                 localregtab[lreg].ru_is_off = 0;        /* arbitrary */
909*07dc1947SRichard Lowe                 localregtab[lreg].ru_value_type = DW_EXPR_VAL_EXPRESSION;
910*07dc1947SRichard Lowe                 localregtab[lreg].ru_offset_or_block_len = block_len;
911*07dc1947SRichard Lowe                 localregtab[lreg].ru_block = instr_ptr;
912*07dc1947SRichard Lowe                 fp_offset = (Dwarf_Unsigned)(uintptr_t)instr_ptr;
913*07dc1947SRichard Lowe 
914*07dc1947SRichard Lowe                 instr_ptr += block_len;
915*07dc1947SRichard Lowe                 fp_register = reg_no;
916*07dc1947SRichard Lowe 
917*07dc1947SRichard Lowe             }
918*07dc1947SRichard Lowe             break;
919*07dc1947SRichard Lowe 
920*07dc1947SRichard Lowe             /* END DWARF3 new ops. */
921*07dc1947SRichard Lowe 
92249d3bc91SRichard Lowe 
92349d3bc91SRichard Lowe #ifdef DW_CFA_GNU_window_save
924*07dc1947SRichard Lowe         case DW_CFA_GNU_window_save:
925*07dc1947SRichard Lowe             {
92649d3bc91SRichard Lowe                 /* no information: this just tells unwinder to restore
92749d3bc91SRichard Lowe                    the window registers from the previous frame's
92849d3bc91SRichard Lowe                    window save area */
92949d3bc91SRichard Lowe                 break;
93049d3bc91SRichard Lowe             }
93149d3bc91SRichard Lowe #endif
93249d3bc91SRichard Lowe #ifdef  DW_CFA_GNU_args_size
93349d3bc91SRichard Lowe             /* single uleb128 is the current arg area size in bytes. No
93449d3bc91SRichard Lowe                register exists yet to save this in */
935*07dc1947SRichard Lowe         case DW_CFA_GNU_args_size:
936*07dc1947SRichard Lowe             {
93749d3bc91SRichard Lowe                 Dwarf_Unsigned lreg;
93849d3bc91SRichard Lowe 
939*07dc1947SRichard Lowe                 DECODE_LEB128_UWORD(instr_ptr, lreg);
940*07dc1947SRichard Lowe                 reg_no = (reg_num_type) lreg;
94149d3bc91SRichard Lowe 
94249d3bc91SRichard Lowe                 break;
94349d3bc91SRichard Lowe             }
94449d3bc91SRichard Lowe #endif
945*07dc1947SRichard Lowe         default:
946*07dc1947SRichard Lowe             /* ERROR, we have an opcode we know nothing about. Memory
947*07dc1947SRichard Lowe                leak here, but an error like this is not supposed to
948*07dc1947SRichard Lowe                happen so we ignore the leak. These used to be ignored,
949*07dc1947SRichard Lowe                now we notice and report. */
950*07dc1947SRichard Lowe             SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR);
951*07dc1947SRichard Lowe 
95249d3bc91SRichard Lowe         }
95349d3bc91SRichard Lowe 
95449d3bc91SRichard Lowe         if (make_instr) {
95549d3bc91SRichard Lowe             instr_count++;
95649d3bc91SRichard Lowe 
95749d3bc91SRichard Lowe             curr_instr = (Dwarf_Frame_Op *)
95849d3bc91SRichard Lowe                 _dwarf_get_alloc(dbg, DW_DLA_FRAME_OP, 1);
95949d3bc91SRichard Lowe             if (curr_instr == NULL) {
960*07dc1947SRichard Lowe                 SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
96149d3bc91SRichard Lowe             }
96249d3bc91SRichard Lowe 
96349d3bc91SRichard Lowe             curr_instr->fp_base_op = fp_base_op;
96449d3bc91SRichard Lowe             curr_instr->fp_extended_op = fp_extended_op;
96549d3bc91SRichard Lowe             curr_instr->fp_register = fp_register;
96649d3bc91SRichard Lowe             curr_instr->fp_offset = fp_offset;
96749d3bc91SRichard Lowe             curr_instr->fp_instr_offset = fp_instr_offset;
96849d3bc91SRichard Lowe 
96949d3bc91SRichard Lowe             curr_instr_item = (Dwarf_Chain)
97049d3bc91SRichard Lowe                 _dwarf_get_alloc(dbg, DW_DLA_CHAIN, 1);
97149d3bc91SRichard Lowe             if (curr_instr_item == NULL) {
972*07dc1947SRichard Lowe                 SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
97349d3bc91SRichard Lowe             }
97449d3bc91SRichard Lowe 
97549d3bc91SRichard Lowe             curr_instr_item->ch_item = curr_instr;
97649d3bc91SRichard Lowe             if (head_instr_chain == NULL)
97749d3bc91SRichard Lowe                 head_instr_chain = tail_instr_chain = curr_instr_item;
97849d3bc91SRichard Lowe             else {
97949d3bc91SRichard Lowe                 tail_instr_chain->ch_next = curr_instr_item;
98049d3bc91SRichard Lowe                 tail_instr_chain = curr_instr_item;
98149d3bc91SRichard Lowe             }
98249d3bc91SRichard Lowe         }
98349d3bc91SRichard Lowe     }
98449d3bc91SRichard Lowe 
98549d3bc91SRichard Lowe     /*
986*07dc1947SRichard Lowe        If frame instruction decoding was right we would stop exactly at
987*07dc1947SRichard Lowe        final_instr_ptr. */
98849d3bc91SRichard Lowe     if (instr_ptr > final_instr_ptr) {
989*07dc1947SRichard Lowe         SIMPLE_ERROR_RETURN(DW_DLE_DF_FRAME_DECODING_ERROR);
99049d3bc91SRichard Lowe     }
99149d3bc91SRichard Lowe 
992*07dc1947SRichard Lowe     /* Fill in the actual output table, the space the caller passed in. */
99349d3bc91SRichard Lowe     if (table != NULL) {
994*07dc1947SRichard Lowe 
995*07dc1947SRichard Lowe         struct Dwarf_Reg_Rule_s *t2reg = table->fr_reg;
996*07dc1947SRichard Lowe         struct Dwarf_Reg_Rule_s *t3reg = localregtab;
997*07dc1947SRichard Lowe         struct Dwarf_Reg_Rule_s *t3end = t3reg + reg_count;
998*07dc1947SRichard Lowe 
999*07dc1947SRichard Lowe         table->fr_loc = current_loc;
1000*07dc1947SRichard Lowe         for (; t3reg < t3end; t3reg++, t2reg++) {
1001*07dc1947SRichard Lowe             *t2reg = *t3reg;
100249d3bc91SRichard Lowe         }
1003*07dc1947SRichard Lowe 
1004*07dc1947SRichard Lowe         /* CONSTCOND */
1005*07dc1947SRichard Lowe         /* Do not update the main table with the cfa_reg.
1006*07dc1947SRichard Lowe            Just leave cfa_reg as cfa_reg. */
1007*07dc1947SRichard Lowe         table->fr_cfa_rule = cfa_reg;
100849d3bc91SRichard Lowe     }
100949d3bc91SRichard Lowe 
101049d3bc91SRichard Lowe     /* Dealloc anything remaining on stack. */
101149d3bc91SRichard Lowe     for (; top_stack != NULL;) {
101249d3bc91SRichard Lowe         stack_table = top_stack;
101349d3bc91SRichard Lowe         top_stack = top_stack->fr_next;
101449d3bc91SRichard Lowe         dwarf_dealloc(dbg, stack_table, DW_DLA_FRAME);
101549d3bc91SRichard Lowe     }
101649d3bc91SRichard Lowe 
101749d3bc91SRichard Lowe     if (make_instr) {
101849d3bc91SRichard Lowe         /* Allocate list of pointers to Dwarf_Frame_Op's.  */
101949d3bc91SRichard Lowe         head_instr_block = (Dwarf_Frame_Op *)
102049d3bc91SRichard Lowe             _dwarf_get_alloc(dbg, DW_DLA_FRAME_BLOCK, instr_count);
102149d3bc91SRichard Lowe         if (head_instr_block == NULL) {
1022*07dc1947SRichard Lowe             SIMPLE_ERROR_RETURN(DW_DLE_DF_ALLOC_FAIL);
102349d3bc91SRichard Lowe         }
102449d3bc91SRichard Lowe 
102549d3bc91SRichard Lowe         /*
102649d3bc91SRichard Lowe            Store pointers to Dwarf_Frame_Op's in this list and
102749d3bc91SRichard Lowe            deallocate the structs that chain the Dwarf_Frame_Op's. */
102849d3bc91SRichard Lowe         curr_instr_item = head_instr_chain;
102949d3bc91SRichard Lowe         for (i = 0; i < instr_count; i++) {
103049d3bc91SRichard Lowe             *(head_instr_block + i) =
103149d3bc91SRichard Lowe                 *(Dwarf_Frame_Op *) curr_instr_item->ch_item;
103249d3bc91SRichard Lowe             dealloc_instr_item = curr_instr_item;
103349d3bc91SRichard Lowe             curr_instr_item = curr_instr_item->ch_next;
103449d3bc91SRichard Lowe             dwarf_dealloc(dbg, dealloc_instr_item->ch_item,
103549d3bc91SRichard Lowe                           DW_DLA_FRAME_OP);
103649d3bc91SRichard Lowe             dwarf_dealloc(dbg, dealloc_instr_item, DW_DLA_CHAIN);
103749d3bc91SRichard Lowe         }
103849d3bc91SRichard Lowe         *ret_frame_instr = head_instr_block;
103949d3bc91SRichard Lowe 
104049d3bc91SRichard Lowe         *returned_count = (Dwarf_Sword) instr_count;
104149d3bc91SRichard Lowe     } else {
104249d3bc91SRichard Lowe         *returned_count = 0;
104349d3bc91SRichard Lowe     }
1044*07dc1947SRichard Lowe     free(localregtab);
104549d3bc91SRichard Lowe     return DW_DLV_OK;
1046*07dc1947SRichard Lowe #undef ERROR_IF_REG_NUM_TOO_HIGH
1047*07dc1947SRichard Lowe #undef SIMPLE_ERROR_RETURN
104849d3bc91SRichard Lowe }
104949d3bc91SRichard Lowe 
1050*07dc1947SRichard Lowe /*  Depending on version, either read the return address register
1051*07dc1947SRichard Lowe     as a ubyte or as an leb number.
1052*07dc1947SRichard Lowe     The form of this value changed for DWARF3.
105349d3bc91SRichard Lowe */
1054*07dc1947SRichard Lowe Dwarf_Unsigned
_dwarf_get_return_address_reg(Dwarf_Small * frame_ptr,int version,unsigned long * size)1055*07dc1947SRichard Lowe _dwarf_get_return_address_reg(Dwarf_Small * frame_ptr,
1056*07dc1947SRichard Lowe     int version, unsigned long *size)
105749d3bc91SRichard Lowe {
1058*07dc1947SRichard Lowe     Dwarf_Unsigned uvalue = 0;
1059*07dc1947SRichard Lowe     Dwarf_Word leb128_length = 0;
106049d3bc91SRichard Lowe 
1061*07dc1947SRichard Lowe     if (version == 1) {
1062*07dc1947SRichard Lowe         *size = 1;
1063*07dc1947SRichard Lowe         uvalue = *(unsigned char *) frame_ptr;
1064*07dc1947SRichard Lowe         return uvalue;
106549d3bc91SRichard Lowe     }
1066*07dc1947SRichard Lowe     uvalue = _dwarf_decode_u_leb128(frame_ptr, &leb128_length);
1067*07dc1947SRichard Lowe     *size = leb128_length;
1068*07dc1947SRichard Lowe     return uvalue;
106949d3bc91SRichard Lowe }
107049d3bc91SRichard Lowe 
107149d3bc91SRichard Lowe 
1072*07dc1947SRichard Lowe /* Trivial consumer function.
1073*07dc1947SRichard Lowe */
107449d3bc91SRichard Lowe int
dwarf_get_cie_of_fde(Dwarf_Fde fde,Dwarf_Cie * cie_returned,Dwarf_Error * error)107549d3bc91SRichard Lowe dwarf_get_cie_of_fde(Dwarf_Fde fde,
107649d3bc91SRichard Lowe     Dwarf_Cie * cie_returned, Dwarf_Error * error)
107749d3bc91SRichard Lowe {
107849d3bc91SRichard Lowe     if (fde == NULL) {
107949d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
108049d3bc91SRichard Lowe         return (DW_DLV_ERROR);
108149d3bc91SRichard Lowe     }
108249d3bc91SRichard Lowe 
108349d3bc91SRichard Lowe     *cie_returned = fde->fd_cie;
108449d3bc91SRichard Lowe     return DW_DLV_OK;
108549d3bc91SRichard Lowe 
108649d3bc91SRichard Lowe }
108749d3bc91SRichard Lowe 
dwarf_get_cie_index(Dwarf_Cie cie,Dwarf_Signed * index,Dwarf_Error * error)1088*07dc1947SRichard Lowe int dwarf_get_cie_index(
1089*07dc1947SRichard Lowe     Dwarf_Cie cie,
1090*07dc1947SRichard Lowe     Dwarf_Signed* index,
1091*07dc1947SRichard Lowe     Dwarf_Error* error )
1092*07dc1947SRichard Lowe {
1093*07dc1947SRichard Lowe     if( cie == NULL )
1094*07dc1947SRichard Lowe     {
1095*07dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
1096*07dc1947SRichard Lowe         return (DW_DLV_ERROR);
1097*07dc1947SRichard Lowe     }
1098*07dc1947SRichard Lowe 
1099*07dc1947SRichard Lowe     *index = cie->ci_index;
1100*07dc1947SRichard Lowe     return (DW_DLV_OK);
1101*07dc1947SRichard Lowe }
1102*07dc1947SRichard Lowe 
1103*07dc1947SRichard Lowe 
110449d3bc91SRichard Lowe /*
110549d3bc91SRichard Lowe   For g++ .eh_frame fde and cie.
110649d3bc91SRichard Lowe   the cie id is different as the
110749d3bc91SRichard Lowe   definition of the cie_id in an fde
110849d3bc91SRichard Lowe         is the distance back from the address of the
110949d3bc91SRichard Lowe         value to the cie.
111049d3bc91SRichard Lowe   Or 0 if this is a true cie.
111149d3bc91SRichard Lowe   Non standard dwarf, designed this way to be
111249d3bc91SRichard Lowe   convenient at run time for an allocated
111349d3bc91SRichard Lowe   (mapped into memory as part of the running image) section.
111449d3bc91SRichard Lowe */
111549d3bc91SRichard Lowe 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)111649d3bc91SRichard Lowe dwarf_get_fde_list_eh(Dwarf_Debug dbg,
111749d3bc91SRichard Lowe     Dwarf_Cie ** cie_data,
111849d3bc91SRichard Lowe     Dwarf_Signed * cie_element_count,
111949d3bc91SRichard Lowe     Dwarf_Fde ** fde_data,
112049d3bc91SRichard Lowe     Dwarf_Signed * fde_element_count,
112149d3bc91SRichard Lowe     Dwarf_Error * error)
112249d3bc91SRichard Lowe {
1123*07dc1947SRichard Lowe     int res = _dwarf_load_section(dbg, &dbg->de_debug_frame_eh_gnu,error);
112449d3bc91SRichard Lowe     if (res != DW_DLV_OK) {
112549d3bc91SRichard Lowe         return res;
112649d3bc91SRichard Lowe     }
112749d3bc91SRichard Lowe 
1128*07dc1947SRichard Lowe     res = _dwarf_get_fde_list_internal(dbg,
112949d3bc91SRichard Lowe         cie_data,
113049d3bc91SRichard Lowe         cie_element_count,
113149d3bc91SRichard Lowe         fde_data,
113249d3bc91SRichard Lowe         fde_element_count,
1133*07dc1947SRichard Lowe         dbg->de_debug_frame_eh_gnu.dss_data,
1134*07dc1947SRichard Lowe         dbg->de_debug_frame_eh_gnu.dss_index,
1135*07dc1947SRichard Lowe         dbg->de_debug_frame_eh_gnu.dss_size,
113649d3bc91SRichard Lowe         /* cie_id_value */ 0,
113749d3bc91SRichard Lowe         /* use_gnu_cie_calc= */ 1,
113849d3bc91SRichard Lowe         error);
113949d3bc91SRichard Lowe     return res;
114049d3bc91SRichard Lowe }
114149d3bc91SRichard Lowe 
114249d3bc91SRichard Lowe 
114349d3bc91SRichard Lowe 
114449d3bc91SRichard Lowe /*
114549d3bc91SRichard Lowe   For standard dwarf .debug_frame
114649d3bc91SRichard Lowe   cie_id is -1  in a cie, and
114749d3bc91SRichard Lowe   is the section offset in the .debug_frame section
114849d3bc91SRichard Lowe   of the cie otherwise.  Standard dwarf
114949d3bc91SRichard Lowe */
115049d3bc91SRichard Lowe 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)115149d3bc91SRichard Lowe dwarf_get_fde_list(Dwarf_Debug dbg,
115249d3bc91SRichard Lowe     Dwarf_Cie ** cie_data,
115349d3bc91SRichard Lowe     Dwarf_Signed * cie_element_count,
115449d3bc91SRichard Lowe     Dwarf_Fde ** fde_data,
115549d3bc91SRichard Lowe     Dwarf_Signed * fde_element_count,
115649d3bc91SRichard Lowe     Dwarf_Error * error)
115749d3bc91SRichard Lowe {
1158*07dc1947SRichard Lowe     int res = _dwarf_load_section(dbg, &dbg->de_debug_frame,error);
115949d3bc91SRichard Lowe     if (res != DW_DLV_OK) {
116049d3bc91SRichard Lowe         return res;
116149d3bc91SRichard Lowe     }
116249d3bc91SRichard Lowe 
1163*07dc1947SRichard Lowe     res = _dwarf_get_fde_list_internal(dbg, cie_data,
116449d3bc91SRichard Lowe         cie_element_count,
116549d3bc91SRichard Lowe         fde_data,
116649d3bc91SRichard Lowe         fde_element_count,
1167*07dc1947SRichard Lowe         dbg->de_debug_frame.dss_data,
1168*07dc1947SRichard Lowe         dbg->de_debug_frame.dss_index,
1169*07dc1947SRichard Lowe         dbg->de_debug_frame.dss_size,
117049d3bc91SRichard Lowe         DW_CIE_ID,
117149d3bc91SRichard Lowe         /* use_gnu_cie_calc= */ 0,
117249d3bc91SRichard Lowe         error);
1173*07dc1947SRichard Lowe 
117449d3bc91SRichard Lowe     return res;
117549d3bc91SRichard Lowe }
117649d3bc91SRichard Lowe 
117749d3bc91SRichard Lowe 
117849d3bc91SRichard Lowe /*
117949d3bc91SRichard Lowe    Only works on dwarf sections, not eh_frame
1180*07dc1947SRichard Lowe    Given a Dwarf_Die, see if it has a
1181*07dc1947SRichard Lowe    DW_AT_MIPS_fde attribute and if so use that
1182*07dc1947SRichard Lowe    to get an fde offset.
1183*07dc1947SRichard Lowe    Then create a Dwarf_Fde to return thru the ret_fde pointer.
1184*07dc1947SRichard Lowe    Also creates a cie (pointed at from the Dwarf_Fde).
118549d3bc91SRichard Lowe */
118649d3bc91SRichard Lowe int
dwarf_get_fde_for_die(Dwarf_Debug dbg,Dwarf_Die die,Dwarf_Fde * ret_fde,Dwarf_Error * error)118749d3bc91SRichard Lowe dwarf_get_fde_for_die(Dwarf_Debug dbg,
118849d3bc91SRichard Lowe     Dwarf_Die die,
118949d3bc91SRichard Lowe     Dwarf_Fde * ret_fde, Dwarf_Error * error)
119049d3bc91SRichard Lowe {
119149d3bc91SRichard Lowe     Dwarf_Attribute attr;
1192*07dc1947SRichard Lowe     Dwarf_Unsigned fde_offset = 0;
1193*07dc1947SRichard Lowe     Dwarf_Signed signdval = 0;
1194*07dc1947SRichard Lowe     Dwarf_Fde new_fde = 0;
1195*07dc1947SRichard Lowe     unsigned char *fde_ptr = 0;
1196*07dc1947SRichard Lowe     unsigned char *cie_ptr = 0;
1197*07dc1947SRichard Lowe     Dwarf_Unsigned cie_id = 0;
119849d3bc91SRichard Lowe 
119949d3bc91SRichard Lowe     /* Fields for the current Cie being read. */
1200*07dc1947SRichard Lowe     int res = 0;
1201*07dc1947SRichard Lowe     int resattr = 0;
1202*07dc1947SRichard Lowe     int sdatares = 0;
120349d3bc91SRichard Lowe 
1204*07dc1947SRichard Lowe     struct cie_fde_prefix_s prefix;
1205*07dc1947SRichard Lowe     struct cie_fde_prefix_s prefix_c;
120649d3bc91SRichard Lowe 
120749d3bc91SRichard Lowe     if (die == NULL) {
120849d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DIE_NULL);
120949d3bc91SRichard Lowe         return (DW_DLV_ERROR);
121049d3bc91SRichard Lowe     }
121149d3bc91SRichard Lowe 
121249d3bc91SRichard Lowe     resattr = dwarf_attr(die, DW_AT_MIPS_fde, &attr, error);
121349d3bc91SRichard Lowe     if (resattr != DW_DLV_OK) {
121449d3bc91SRichard Lowe         return resattr;
121549d3bc91SRichard Lowe     }
121649d3bc91SRichard Lowe 
121749d3bc91SRichard Lowe     /* why is this formsdata? FIX */
121849d3bc91SRichard Lowe     sdatares = dwarf_formsdata(attr, &signdval, error);
121949d3bc91SRichard Lowe     if (sdatares != DW_DLV_OK) {
122049d3bc91SRichard Lowe         return sdatares;
122149d3bc91SRichard Lowe     }
122249d3bc91SRichard Lowe 
1223*07dc1947SRichard Lowe     res = _dwarf_load_section(dbg, &dbg->de_debug_frame,error);
122449d3bc91SRichard Lowe     if (res != DW_DLV_OK) {
122549d3bc91SRichard Lowe         return res;
122649d3bc91SRichard Lowe     }
122749d3bc91SRichard Lowe 
122849d3bc91SRichard Lowe     fde_offset = signdval;
1229*07dc1947SRichard Lowe     fde_ptr = (dbg->de_debug_frame.dss_data + fde_offset);
123049d3bc91SRichard Lowe 
123149d3bc91SRichard Lowe 
1232*07dc1947SRichard Lowe     /* First read in the 'common prefix' to figure out what * we are to
1233*07dc1947SRichard Lowe        do with this entry. */
1234*07dc1947SRichard Lowe     memset(&prefix_c, 0, sizeof(prefix_c));
1235*07dc1947SRichard Lowe     memset(&prefix, 0, sizeof(prefix));
1236*07dc1947SRichard Lowe     res = dwarf_read_cie_fde_prefix(dbg, fde_ptr,
1237*07dc1947SRichard Lowe         dbg->de_debug_frame.dss_data,
1238*07dc1947SRichard Lowe         dbg->de_debug_frame.dss_index,
1239*07dc1947SRichard Lowe         dbg->de_debug_frame.dss_size,
1240*07dc1947SRichard Lowe         &prefix,
1241*07dc1947SRichard Lowe         error);
1242*07dc1947SRichard Lowe     if (res == DW_DLV_ERROR) {
124349d3bc91SRichard Lowe         return res;
124449d3bc91SRichard Lowe     }
1245*07dc1947SRichard Lowe     if (res == DW_DLV_NO_ENTRY)
1246*07dc1947SRichard Lowe         return res;
1247*07dc1947SRichard Lowe     fde_ptr = prefix.cf_addr_after_prefix;
1248*07dc1947SRichard Lowe     cie_id = prefix.cf_cie_id;
1249*07dc1947SRichard Lowe     /* Pass NULL, not section pointer, for 3rd argument.
1250*07dc1947SRichard Lowe        de_debug_frame.dss_data has no eh_frame relevance. */
1251*07dc1947SRichard Lowe     res = dwarf_create_fde_from_after_start(dbg, &prefix,
1252*07dc1947SRichard Lowe         (Dwarf_Small *) NULL,
1253*07dc1947SRichard Lowe         fde_ptr,
1254*07dc1947SRichard Lowe         /* use_gnu_cie_calc= */ 0,
1255*07dc1947SRichard Lowe         /* Dwarf_Cie = */ 0,
1256*07dc1947SRichard Lowe         &new_fde, error);
1257*07dc1947SRichard Lowe     if (res == DW_DLV_ERROR) {
1258*07dc1947SRichard Lowe         return res;
1259*07dc1947SRichard Lowe     } else if (res == DW_DLV_NO_ENTRY) {
1260*07dc1947SRichard Lowe         return res;
126149d3bc91SRichard Lowe     }
1262*07dc1947SRichard Lowe     /* DW_DLV_OK */
126349d3bc91SRichard Lowe 
126449d3bc91SRichard Lowe     /* now read the cie corresponding to the fde */
1265*07dc1947SRichard Lowe     cie_ptr = new_fde->fd_section_ptr + cie_id;
1266*07dc1947SRichard Lowe     res = dwarf_read_cie_fde_prefix(dbg, cie_ptr,
1267*07dc1947SRichard Lowe         dbg->de_debug_frame.dss_data,
1268*07dc1947SRichard Lowe         dbg->de_debug_frame.dss_index,
1269*07dc1947SRichard Lowe         dbg->de_debug_frame.dss_size,
1270*07dc1947SRichard Lowe         &prefix_c, error);
1271*07dc1947SRichard Lowe     if (res == DW_DLV_ERROR) {
1272*07dc1947SRichard Lowe         return res;
127349d3bc91SRichard Lowe     }
1274*07dc1947SRichard Lowe     if (res == DW_DLV_NO_ENTRY)
1275*07dc1947SRichard Lowe         return res;
127649d3bc91SRichard Lowe 
1277*07dc1947SRichard Lowe     cie_ptr = prefix_c.cf_addr_after_prefix;
1278*07dc1947SRichard Lowe     cie_id = prefix_c.cf_cie_id;
127949d3bc91SRichard Lowe 
1280*07dc1947SRichard Lowe     if (cie_id == DW_CIE_ID) {
1281*07dc1947SRichard Lowe         int res2 = 0;
1282*07dc1947SRichard Lowe         Dwarf_Cie new_cie = 0;
128349d3bc91SRichard Lowe 
1284*07dc1947SRichard Lowe         /* Pass NULL, not section pointer, for 3rd argument.
1285*07dc1947SRichard Lowe            de_debug_frame.dss_data has no eh_frame relevance. */
1286*07dc1947SRichard Lowe         res2 = dwarf_create_cie_from_after_start(dbg,
1287*07dc1947SRichard Lowe             &prefix_c,
1288*07dc1947SRichard Lowe             (Dwarf_Small *) NULL,
1289*07dc1947SRichard Lowe             cie_ptr,
1290*07dc1947SRichard Lowe             /* cie_count= */ 0,
1291*07dc1947SRichard Lowe             /* use_gnu_cie_calc= */
1292*07dc1947SRichard Lowe             0, &new_cie, error);
1293*07dc1947SRichard Lowe         if (res2 == DW_DLV_ERROR) {
1294*07dc1947SRichard Lowe             dwarf_dealloc(dbg, new_fde, DW_DLA_FDE);
1295*07dc1947SRichard Lowe             return res;
1296*07dc1947SRichard Lowe         } else if (res2 == DW_DLV_NO_ENTRY) {
1297*07dc1947SRichard Lowe             dwarf_dealloc(dbg, new_fde, DW_DLA_FDE);
1298*07dc1947SRichard Lowe             return res;
129949d3bc91SRichard Lowe         }
1300*07dc1947SRichard Lowe         new_fde->fd_cie = new_cie;
130149d3bc91SRichard Lowe     } else {
130249d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_NO_CIE_FOR_FDE);
130349d3bc91SRichard Lowe         return (DW_DLV_ERROR);
130449d3bc91SRichard Lowe     }
130549d3bc91SRichard Lowe 
130649d3bc91SRichard Lowe     *ret_fde = new_fde;
130749d3bc91SRichard Lowe     return DW_DLV_OK;
130849d3bc91SRichard Lowe }
130949d3bc91SRichard Lowe 
1310*07dc1947SRichard Lowe /* A dwarf consumer operation, see the consumer library documentation.
1311*07dc1947SRichard Lowe */
131249d3bc91SRichard Lowe 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)131349d3bc91SRichard Lowe dwarf_get_fde_range(Dwarf_Fde fde,
131449d3bc91SRichard Lowe     Dwarf_Addr * low_pc,
131549d3bc91SRichard Lowe     Dwarf_Unsigned * func_length,
131649d3bc91SRichard Lowe     Dwarf_Ptr * fde_bytes,
131749d3bc91SRichard Lowe     Dwarf_Unsigned * fde_byte_length,
131849d3bc91SRichard Lowe     Dwarf_Off * cie_offset,
131949d3bc91SRichard Lowe     Dwarf_Signed * cie_index,
132049d3bc91SRichard Lowe     Dwarf_Off * fde_offset, Dwarf_Error * error)
132149d3bc91SRichard Lowe {
132249d3bc91SRichard Lowe     Dwarf_Debug dbg;
132349d3bc91SRichard Lowe 
132449d3bc91SRichard Lowe     if (fde == NULL) {
132549d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
132649d3bc91SRichard Lowe         return (DW_DLV_ERROR);
132749d3bc91SRichard Lowe     }
132849d3bc91SRichard Lowe 
132949d3bc91SRichard Lowe     dbg = fde->fd_dbg;
133049d3bc91SRichard Lowe     if (dbg == NULL) {
133149d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
133249d3bc91SRichard Lowe         return (DW_DLV_ERROR);
133349d3bc91SRichard Lowe     }
133449d3bc91SRichard Lowe 
1335*07dc1947SRichard Lowe 
1336*07dc1947SRichard Lowe     /* We have always already done the section load here, so no need to
1337*07dc1947SRichard Lowe        load the section. We did the section load in order to create the
1338*07dc1947SRichard Lowe        Dwarf_Fde pointer passed in here. */
1339*07dc1947SRichard Lowe 
134049d3bc91SRichard Lowe 
134149d3bc91SRichard Lowe     if (low_pc != NULL)
134249d3bc91SRichard Lowe         *low_pc = fde->fd_initial_location;
134349d3bc91SRichard Lowe     if (func_length != NULL)
134449d3bc91SRichard Lowe         *func_length = fde->fd_address_range;
134549d3bc91SRichard Lowe     if (fde_bytes != NULL)
134649d3bc91SRichard Lowe         *fde_bytes = fde->fd_fde_start;
134749d3bc91SRichard Lowe     if (fde_byte_length != NULL)
134849d3bc91SRichard Lowe         *fde_byte_length = fde->fd_length;
134949d3bc91SRichard Lowe     if (cie_offset != NULL)
135049d3bc91SRichard Lowe         *cie_offset = fde->fd_cie_offset;
135149d3bc91SRichard Lowe     if (cie_index != NULL)
135249d3bc91SRichard Lowe         *cie_index = fde->fd_cie_index;
135349d3bc91SRichard Lowe     if (fde_offset != NULL)
1354*07dc1947SRichard Lowe         *fde_offset = fde->fd_fde_start - fde->fd_section_ptr;
135549d3bc91SRichard Lowe 
135649d3bc91SRichard Lowe     return DW_DLV_OK;
135749d3bc91SRichard Lowe }
135849d3bc91SRichard Lowe 
1359*07dc1947SRichard Lowe /* IRIX specific function.   The exception tables
1360*07dc1947SRichard Lowe    have C++ destructor information and are
1361*07dc1947SRichard Lowe    at present undocumented.  */
136249d3bc91SRichard Lowe int
dwarf_get_fde_exception_info(Dwarf_Fde fde,Dwarf_Signed * offset_into_exception_tables,Dwarf_Error * error)136349d3bc91SRichard Lowe dwarf_get_fde_exception_info(Dwarf_Fde fde,
136449d3bc91SRichard Lowe     Dwarf_Signed *
136549d3bc91SRichard Lowe     offset_into_exception_tables,
136649d3bc91SRichard Lowe     Dwarf_Error * error)
136749d3bc91SRichard Lowe {
136849d3bc91SRichard Lowe     Dwarf_Debug dbg;
136949d3bc91SRichard Lowe 
137049d3bc91SRichard Lowe     dbg = fde->fd_dbg;
137149d3bc91SRichard Lowe     if (dbg == NULL) {
137249d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
137349d3bc91SRichard Lowe         return (DW_DLV_ERROR);
137449d3bc91SRichard Lowe     }
137549d3bc91SRichard Lowe     *offset_into_exception_tables =
137649d3bc91SRichard Lowe         fde->fd_offset_into_exception_tables;
137749d3bc91SRichard Lowe     return DW_DLV_OK;
137849d3bc91SRichard Lowe }
137949d3bc91SRichard Lowe 
138049d3bc91SRichard Lowe 
1381*07dc1947SRichard Lowe /* A consumer code function.
1382*07dc1947SRichard Lowe    Given a CIE pointer, return the normal CIE data thru
1383*07dc1947SRichard Lowe    pointers.
1384*07dc1947SRichard Lowe    Special augmentation data is not returned here.
1385*07dc1947SRichard Lowe */
138649d3bc91SRichard Lowe 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)138749d3bc91SRichard Lowe dwarf_get_cie_info(Dwarf_Cie cie,
138849d3bc91SRichard Lowe     Dwarf_Unsigned * bytes_in_cie,
1389*07dc1947SRichard Lowe     Dwarf_Small * ptr_to_version,
139049d3bc91SRichard Lowe     char **augmenter,
139149d3bc91SRichard Lowe     Dwarf_Unsigned * code_alignment_factor,
139249d3bc91SRichard Lowe     Dwarf_Signed * data_alignment_factor,
139349d3bc91SRichard Lowe     Dwarf_Half * return_address_register,
139449d3bc91SRichard Lowe     Dwarf_Ptr * initial_instructions,
139549d3bc91SRichard Lowe     Dwarf_Unsigned * initial_instructions_length,
139649d3bc91SRichard Lowe     Dwarf_Error * error)
139749d3bc91SRichard Lowe {
139849d3bc91SRichard Lowe     Dwarf_Debug dbg;
139949d3bc91SRichard Lowe 
140049d3bc91SRichard Lowe     if (cie == NULL) {
140149d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
140249d3bc91SRichard Lowe         return (DW_DLV_ERROR);
140349d3bc91SRichard Lowe     }
140449d3bc91SRichard Lowe 
140549d3bc91SRichard Lowe     dbg = cie->ci_dbg;
140649d3bc91SRichard Lowe     if (dbg == NULL) {
140749d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_CIE_DBG_NULL);
140849d3bc91SRichard Lowe         return (DW_DLV_ERROR);
140949d3bc91SRichard Lowe     }
141049d3bc91SRichard Lowe 
1411*07dc1947SRichard Lowe     if (ptr_to_version != NULL)
1412*07dc1947SRichard Lowe         *ptr_to_version = cie->ci_cie_version_number;
141349d3bc91SRichard Lowe     if (augmenter != NULL)
141449d3bc91SRichard Lowe         *augmenter = cie->ci_augmentation;
141549d3bc91SRichard Lowe     if (code_alignment_factor != NULL)
141649d3bc91SRichard Lowe         *code_alignment_factor = cie->ci_code_alignment_factor;
141749d3bc91SRichard Lowe     if (data_alignment_factor != NULL)
141849d3bc91SRichard Lowe         *data_alignment_factor = cie->ci_data_alignment_factor;
141949d3bc91SRichard Lowe     if (return_address_register != NULL)
142049d3bc91SRichard Lowe         *return_address_register = cie->ci_return_address_register;
142149d3bc91SRichard Lowe     if (initial_instructions != NULL)
142249d3bc91SRichard Lowe         *initial_instructions = cie->ci_cie_instr_start;
142349d3bc91SRichard Lowe     if (initial_instructions_length != NULL) {
142449d3bc91SRichard Lowe         *initial_instructions_length = cie->ci_length +
142549d3bc91SRichard Lowe             cie->ci_length_size +
142649d3bc91SRichard Lowe             cie->ci_extension_size -
142749d3bc91SRichard Lowe             (cie->ci_cie_instr_start - cie->ci_cie_start);
142849d3bc91SRichard Lowe 
142949d3bc91SRichard Lowe     }
143049d3bc91SRichard Lowe     *bytes_in_cie = (cie->ci_length);
143149d3bc91SRichard Lowe     return (DW_DLV_OK);
143249d3bc91SRichard Lowe }
143349d3bc91SRichard Lowe 
1434*07dc1947SRichard Lowe /* Return the register rules for all registers at a given pc.
1435*07dc1947SRichard Lowe */
143649d3bc91SRichard Lowe 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)143749d3bc91SRichard Lowe _dwarf_get_fde_info_for_a_pc_row(Dwarf_Fde fde,
143849d3bc91SRichard Lowe     Dwarf_Addr pc_requested,
1439*07dc1947SRichard Lowe     Dwarf_Frame table,
1440*07dc1947SRichard Lowe     Dwarf_Half cfa_reg_col_num,
1441*07dc1947SRichard Lowe     Dwarf_Error * error)
144249d3bc91SRichard Lowe {
1443*07dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
1444*07dc1947SRichard Lowe     Dwarf_Cie cie = 0;
1445*07dc1947SRichard Lowe     int dw_err = 0;
1446*07dc1947SRichard Lowe     Dwarf_Sword icount = 0;
1447*07dc1947SRichard Lowe     int res = 0;
144849d3bc91SRichard Lowe 
144949d3bc91SRichard Lowe     if (fde == NULL) {
145049d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
145149d3bc91SRichard Lowe         return (DW_DLV_ERROR);
145249d3bc91SRichard Lowe     }
145349d3bc91SRichard Lowe 
145449d3bc91SRichard Lowe     dbg = fde->fd_dbg;
145549d3bc91SRichard Lowe     if (dbg == NULL) {
145649d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
145749d3bc91SRichard Lowe         return (DW_DLV_ERROR);
145849d3bc91SRichard Lowe     }
145949d3bc91SRichard Lowe 
146049d3bc91SRichard Lowe     if (pc_requested < fde->fd_initial_location ||
146149d3bc91SRichard Lowe         pc_requested >=
146249d3bc91SRichard Lowe         fde->fd_initial_location + fde->fd_address_range) {
146349d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE);
146449d3bc91SRichard Lowe         return (DW_DLV_ERROR);
146549d3bc91SRichard Lowe     }
146649d3bc91SRichard Lowe 
146749d3bc91SRichard Lowe     cie = fde->fd_cie;
146849d3bc91SRichard Lowe     if (cie->ci_initial_table == NULL) {
146949d3bc91SRichard Lowe         cie->ci_initial_table = _dwarf_get_alloc(dbg, DW_DLA_FRAME, 1);
1470*07dc1947SRichard Lowe 
147149d3bc91SRichard Lowe         if (cie->ci_initial_table == NULL) {
147249d3bc91SRichard Lowe             _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL);
147349d3bc91SRichard Lowe             return (DW_DLV_ERROR);
147449d3bc91SRichard Lowe         }
1475*07dc1947SRichard Lowe         _dwarf_init_regrule_table(cie->ci_initial_table->fr_reg,
1476*07dc1947SRichard Lowe             dbg->de_frame_reg_rules_entry_count,
1477*07dc1947SRichard Lowe             dbg->de_frame_rule_initial_value);
1478*07dc1947SRichard Lowe         _dwarf_init_regrule_table(&cie->ci_initial_table->fr_cfa_rule,
1479*07dc1947SRichard Lowe             1, dbg->de_frame_rule_initial_value);
148049d3bc91SRichard Lowe         res = _dwarf_exec_frame_instr( /* make_instr= */ false,
148149d3bc91SRichard Lowe             /* ret_frame_instr= */ NULL,
148249d3bc91SRichard Lowe             /* search_pc */ false,
148349d3bc91SRichard Lowe             /* search_pc_val */ 0,
148449d3bc91SRichard Lowe             /* location */ 0,
148549d3bc91SRichard Lowe             cie->ci_cie_instr_start,
1486*07dc1947SRichard Lowe             cie->ci_cie_instr_start + (cie->ci_length +
148749d3bc91SRichard Lowe                 cie->ci_length_size +
148849d3bc91SRichard Lowe                 cie->ci_extension_size -
148949d3bc91SRichard Lowe                 (cie->ci_cie_instr_start -
149049d3bc91SRichard Lowe                 cie->ci_cie_start)),
149149d3bc91SRichard Lowe             cie->ci_initial_table, cie, dbg,
1492*07dc1947SRichard Lowe             cfa_reg_col_num, &icount,
1493*07dc1947SRichard Lowe             &dw_err);
149449d3bc91SRichard Lowe         if (res == DW_DLV_ERROR) {
149549d3bc91SRichard Lowe             _dwarf_error(dbg, error, dw_err);
149649d3bc91SRichard Lowe             return (res);
149749d3bc91SRichard Lowe         } else if (res == DW_DLV_NO_ENTRY) {
149849d3bc91SRichard Lowe             return res;
149949d3bc91SRichard Lowe         }
150049d3bc91SRichard Lowe     }
150149d3bc91SRichard Lowe 
1502*07dc1947SRichard Lowe     {
1503*07dc1947SRichard Lowe         Dwarf_Small *instr_end = fde->fd_fde_instr_start +
1504*07dc1947SRichard Lowe             fde->fd_length +
1505*07dc1947SRichard Lowe             fde->fd_length_size +
1506*07dc1947SRichard Lowe             fde->fd_extension_size - (fde->fd_fde_instr_start -
1507*07dc1947SRichard Lowe                                       fde->fd_fde_start);
1508*07dc1947SRichard Lowe 
150949d3bc91SRichard Lowe         res = _dwarf_exec_frame_instr( /* make_instr= */ false,
151049d3bc91SRichard Lowe             /* ret_frame_instr= */ NULL,
151149d3bc91SRichard Lowe             /* search_pc */ true,
151249d3bc91SRichard Lowe             /* search_pc_val */ pc_requested,
151349d3bc91SRichard Lowe             fde->fd_initial_location,
151449d3bc91SRichard Lowe             fde->fd_fde_instr_start,
1515*07dc1947SRichard Lowe             instr_end,
1516*07dc1947SRichard Lowe             table,
1517*07dc1947SRichard Lowe             cie, dbg,
1518*07dc1947SRichard Lowe             cfa_reg_col_num, &icount,
1519*07dc1947SRichard Lowe             &dw_err);
1520*07dc1947SRichard Lowe     }
152149d3bc91SRichard Lowe     if (res == DW_DLV_ERROR) {
152249d3bc91SRichard Lowe         _dwarf_error(dbg, error, dw_err);
152349d3bc91SRichard Lowe         return (res);
152449d3bc91SRichard Lowe     } else if (res == DW_DLV_NO_ENTRY) {
152549d3bc91SRichard Lowe         return res;
152649d3bc91SRichard Lowe     }
152749d3bc91SRichard Lowe 
152849d3bc91SRichard Lowe     return DW_DLV_OK;
152949d3bc91SRichard Lowe }
153049d3bc91SRichard Lowe 
1531*07dc1947SRichard Lowe /* A consumer call for efficiently getting the register info
1532*07dc1947SRichard Lowe    for all registers in one call.
1533*07dc1947SRichard Lowe 
1534*07dc1947SRichard Lowe    The output table rules array is size DW_REG_TABLE_SIZE.
1535*07dc1947SRichard Lowe    The frame info  rules array in fde_table is of size
1536*07dc1947SRichard Lowe    DW_REG_TABLE_SIZE too.
1537*07dc1947SRichard Lowe 
1538*07dc1947SRichard Lowe    This interface  really only works well with MIPS/IRIX
1539*07dc1947SRichard Lowe    where DW_FRAME_CFA_COL is zero (in that case it's safe).
1540*07dc1947SRichard Lowe 
1541*07dc1947SRichard Lowe    It is also restricted to the case  where
1542*07dc1947SRichard Lowe    DW_REG_TABLE_SIZE == DW_FRAME_LAST_REG_NUM  ==
1543*07dc1947SRichard Lowe    dbg->de_frame_reg_rules_entry_count (true for MIPS/IRIX).
1544*07dc1947SRichard Lowe    If this condition is not met calling this routine can result in
1545*07dc1947SRichard Lowe    incorrect output or in memory corruption.
1546*07dc1947SRichard Lowe 
1547*07dc1947SRichard Lowe    It is much better to use dwarf_get_fde_info_for_all_regs3()
1548*07dc1947SRichard Lowe    instead of this interface.
1549*07dc1947SRichard Lowe */
155049d3bc91SRichard Lowe 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)155149d3bc91SRichard Lowe dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde,
155249d3bc91SRichard Lowe     Dwarf_Addr pc_requested,
155349d3bc91SRichard Lowe     Dwarf_Regtable * reg_table,
155449d3bc91SRichard Lowe     Dwarf_Addr * row_pc,
155549d3bc91SRichard Lowe     Dwarf_Error * error)
155649d3bc91SRichard Lowe {
155749d3bc91SRichard Lowe 
1558*07dc1947SRichard Lowe     /* Table size: DW_REG_TABLE_SIZE */
155949d3bc91SRichard Lowe     struct Dwarf_Frame_s fde_table;
1560*07dc1947SRichard Lowe     Dwarf_Sword i = 0;
1561*07dc1947SRichard Lowe     struct Dwarf_Reg_Rule_s *rule = NULL;
1562*07dc1947SRichard Lowe     struct Dwarf_Regtable_Entry_s *out_rule = NULL;
1563*07dc1947SRichard Lowe     int res = 0;
1564*07dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
1565*07dc1947SRichard Lowe 
1566*07dc1947SRichard Lowe     /* For this interface the size is fixed at compile time. */
1567*07dc1947SRichard Lowe     int output_table_real_data_size = DW_REG_TABLE_SIZE;
1568*07dc1947SRichard Lowe 
1569*07dc1947SRichard Lowe     FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1570*07dc1947SRichard Lowe 
1571*07dc1947SRichard Lowe     res = dwarf_initialize_fde_table(dbg, &fde_table,
1572*07dc1947SRichard Lowe         output_table_real_data_size,
1573*07dc1947SRichard Lowe         error);
1574*07dc1947SRichard Lowe     if (res != DW_DLV_OK)
1575*07dc1947SRichard Lowe         return res;
157649d3bc91SRichard Lowe 
157749d3bc91SRichard Lowe     /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks
157849d3bc91SRichard Lowe      */
157949d3bc91SRichard Lowe     res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested,
1580*07dc1947SRichard Lowe         &fde_table, dbg->de_frame_cfa_col_number, error);
158149d3bc91SRichard Lowe     if (res != DW_DLV_OK) {
1582*07dc1947SRichard Lowe         dwarf_free_fde_table(&fde_table);
158349d3bc91SRichard Lowe         return res;
158449d3bc91SRichard Lowe     }
158549d3bc91SRichard Lowe 
1586*07dc1947SRichard Lowe     out_rule = &reg_table->rules[0];
1587*07dc1947SRichard Lowe     rule = &fde_table.fr_reg[0];
1588*07dc1947SRichard Lowe     for (i = 0; i < output_table_real_data_size;
1589*07dc1947SRichard Lowe          i++, ++out_rule, ++rule) {
1590*07dc1947SRichard Lowe         out_rule->dw_offset_relevant = rule->ru_is_off;
1591*07dc1947SRichard Lowe         out_rule->dw_value_type = rule->ru_value_type;
1592*07dc1947SRichard Lowe         out_rule->dw_regnum = rule->ru_register;
1593*07dc1947SRichard Lowe         out_rule->dw_offset = rule->ru_offset_or_block_len;
1594*07dc1947SRichard Lowe     }
1595*07dc1947SRichard Lowe     for (; i < DW_REG_TABLE_SIZE; ++i, ++out_rule) {
1596*07dc1947SRichard Lowe         out_rule->dw_offset_relevant = 0;
1597*07dc1947SRichard Lowe         out_rule->dw_value_type = DW_EXPR_OFFSET;
1598*07dc1947SRichard Lowe         out_rule->dw_regnum = dbg->de_frame_undefined_value_number;
1599*07dc1947SRichard Lowe         out_rule->dw_offset = 0;
1600*07dc1947SRichard Lowe     }
1601*07dc1947SRichard Lowe 
1602*07dc1947SRichard Lowe     /* The test is just in case it's not inside the table. For non-MIPS
1603*07dc1947SRichard Lowe        it could be outside the table and that is just fine, it was
1604*07dc1947SRichard Lowe        really a mistake to put it in the table in 1993.  */
1605*07dc1947SRichard Lowe     /* CONSTCOND */
1606*07dc1947SRichard Lowe     if (dbg->de_frame_cfa_col_number < DW_REG_TABLE_SIZE) {
1607*07dc1947SRichard Lowe         out_rule = &reg_table->rules[dbg->de_frame_cfa_col_number];
1608*07dc1947SRichard Lowe         out_rule->dw_offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
1609*07dc1947SRichard Lowe         out_rule->dw_value_type = fde_table.fr_cfa_rule.ru_value_type;
1610*07dc1947SRichard Lowe         out_rule->dw_regnum = fde_table.fr_cfa_rule.ru_register;
1611*07dc1947SRichard Lowe         out_rule->dw_offset =
1612*07dc1947SRichard Lowe             fde_table.fr_cfa_rule.ru_offset_or_block_len;
161349d3bc91SRichard Lowe     }
161449d3bc91SRichard Lowe 
161549d3bc91SRichard Lowe     if (row_pc != NULL)
161649d3bc91SRichard Lowe         *row_pc = fde_table.fr_loc;
1617*07dc1947SRichard Lowe     dwarf_free_fde_table(&fde_table);
1618*07dc1947SRichard Lowe     return DW_DLV_OK;
1619*07dc1947SRichard Lowe }
162049d3bc91SRichard Lowe 
1621*07dc1947SRichard Lowe /* A consumer call for efficiently getting the register info
1622*07dc1947SRichard Lowe    for all registers in one call.
1623*07dc1947SRichard Lowe 
1624*07dc1947SRichard Lowe    The output table rules array is size output_table_real_data_size.
1625*07dc1947SRichard Lowe    (normally  DW_REG_TABLE_SIZE).
1626*07dc1947SRichard Lowe    The frame info  rules array in fde_table is normally of size
1627*07dc1947SRichard Lowe    DW_FRAME_LAST_REG_NUM.
1628*07dc1947SRichard Lowe */
1629*07dc1947SRichard Lowe 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*07dc1947SRichard Lowe dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde,
1631*07dc1947SRichard Lowe     Dwarf_Addr pc_requested,
1632*07dc1947SRichard Lowe     Dwarf_Regtable3 * reg_table,
1633*07dc1947SRichard Lowe     Dwarf_Addr * row_pc,
1634*07dc1947SRichard Lowe     Dwarf_Error * error)
1635*07dc1947SRichard Lowe {
1636*07dc1947SRichard Lowe 
1637*07dc1947SRichard Lowe     struct Dwarf_Frame_s fde_table;
1638*07dc1947SRichard Lowe     Dwarf_Sword i = 0;
1639*07dc1947SRichard Lowe     int res = 0;
1640*07dc1947SRichard Lowe     struct Dwarf_Reg_Rule_s *rule = NULL;
1641*07dc1947SRichard Lowe     struct Dwarf_Regtable_Entry3_s *out_rule = NULL;
1642*07dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
1643*07dc1947SRichard Lowe     int output_table_real_data_size = reg_table->rt3_reg_table_size;
1644*07dc1947SRichard Lowe 
1645*07dc1947SRichard Lowe     FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1646*07dc1947SRichard Lowe 
1647*07dc1947SRichard Lowe     output_table_real_data_size =
1648*07dc1947SRichard Lowe         MIN(output_table_real_data_size,
1649*07dc1947SRichard Lowe             dbg->de_frame_reg_rules_entry_count);
1650*07dc1947SRichard Lowe 
1651*07dc1947SRichard Lowe     res = dwarf_initialize_fde_table(dbg, &fde_table,
1652*07dc1947SRichard Lowe        output_table_real_data_size,
1653*07dc1947SRichard Lowe        error);
1654*07dc1947SRichard Lowe 
1655*07dc1947SRichard Lowe     /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks
1656*07dc1947SRichard Lowe      */
1657*07dc1947SRichard Lowe     res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested,
1658*07dc1947SRichard Lowe         &fde_table,
1659*07dc1947SRichard Lowe         dbg->de_frame_cfa_col_number,
1660*07dc1947SRichard Lowe         error);
1661*07dc1947SRichard Lowe     if (res != DW_DLV_OK) {
1662*07dc1947SRichard Lowe         dwarf_free_fde_table(&fde_table);
1663*07dc1947SRichard Lowe         return res;
1664*07dc1947SRichard Lowe     }
1665*07dc1947SRichard Lowe 
1666*07dc1947SRichard Lowe     out_rule = &reg_table->rt3_rules[0];
1667*07dc1947SRichard Lowe     rule = &fde_table.fr_reg[0];
1668*07dc1947SRichard Lowe     for (i = 0; i < output_table_real_data_size;
1669*07dc1947SRichard Lowe          i++, ++out_rule, ++rule) {
1670*07dc1947SRichard Lowe         out_rule->dw_offset_relevant = rule->ru_is_off;
1671*07dc1947SRichard Lowe         out_rule->dw_value_type = rule->ru_value_type;
1672*07dc1947SRichard Lowe         out_rule->dw_regnum = rule->ru_register;
1673*07dc1947SRichard Lowe         out_rule->dw_offset_or_block_len = rule->ru_offset_or_block_len;
1674*07dc1947SRichard Lowe         out_rule->dw_block_ptr = rule->ru_block;
1675*07dc1947SRichard Lowe     }
1676*07dc1947SRichard Lowe     for (; i < reg_table->rt3_reg_table_size; i++, ++out_rule) {
1677*07dc1947SRichard Lowe         out_rule->dw_offset_relevant = 0;
1678*07dc1947SRichard Lowe         out_rule->dw_value_type = DW_EXPR_OFFSET;
1679*07dc1947SRichard Lowe         out_rule->dw_regnum = dbg->de_frame_undefined_value_number;
1680*07dc1947SRichard Lowe         out_rule->dw_offset_or_block_len = 0;
1681*07dc1947SRichard Lowe         out_rule->dw_block_ptr = 0;
1682*07dc1947SRichard Lowe     }
1683*07dc1947SRichard Lowe     reg_table->rt3_cfa_rule.dw_offset_relevant =
1684*07dc1947SRichard Lowe         fde_table.fr_cfa_rule.ru_is_off;
1685*07dc1947SRichard Lowe     reg_table->rt3_cfa_rule.dw_value_type =
1686*07dc1947SRichard Lowe         fde_table.fr_cfa_rule.ru_value_type;
1687*07dc1947SRichard Lowe     reg_table->rt3_cfa_rule.dw_regnum =
1688*07dc1947SRichard Lowe         fde_table.fr_cfa_rule.ru_register;
1689*07dc1947SRichard Lowe     reg_table->rt3_cfa_rule.dw_offset_or_block_len =
1690*07dc1947SRichard Lowe         fde_table.fr_cfa_rule.ru_offset_or_block_len;
1691*07dc1947SRichard Lowe     reg_table->rt3_cfa_rule.dw_block_ptr =
1692*07dc1947SRichard Lowe         fde_table.fr_cfa_rule.ru_block;
1693*07dc1947SRichard Lowe 
1694*07dc1947SRichard Lowe     if (row_pc != NULL)
1695*07dc1947SRichard Lowe         *row_pc = fde_table.fr_loc;
1696*07dc1947SRichard Lowe 
1697*07dc1947SRichard Lowe     dwarf_free_fde_table(&fde_table);
169849d3bc91SRichard Lowe     return DW_DLV_OK;
169949d3bc91SRichard Lowe }
170049d3bc91SRichard Lowe 
170149d3bc91SRichard Lowe 
1702*07dc1947SRichard Lowe /* Gets the register info for a single register at a given PC value
1703*07dc1947SRichard Lowe    for the FDE specified.
1704*07dc1947SRichard Lowe 
1705*07dc1947SRichard Lowe    This is the old MIPS interface and should no longer be used.
1706*07dc1947SRichard Lowe    Use dwarf_get_fde_info_for_reg3() instead.
1707*07dc1947SRichard Lowe */
170849d3bc91SRichard Lowe 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)170949d3bc91SRichard Lowe dwarf_get_fde_info_for_reg(Dwarf_Fde fde,
171049d3bc91SRichard Lowe     Dwarf_Half table_column,
171149d3bc91SRichard Lowe     Dwarf_Addr pc_requested,
171249d3bc91SRichard Lowe     Dwarf_Signed * offset_relevant,
171349d3bc91SRichard Lowe     Dwarf_Signed * register_num,
171449d3bc91SRichard Lowe     Dwarf_Signed * offset,
171549d3bc91SRichard Lowe     Dwarf_Addr * row_pc, Dwarf_Error * error)
171649d3bc91SRichard Lowe {
171749d3bc91SRichard Lowe     struct Dwarf_Frame_s fde_table;
1718*07dc1947SRichard Lowe     int res = DW_DLV_ERROR;
1719*07dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
1720*07dc1947SRichard Lowe     int output_table_real_data_size = 0;
172149d3bc91SRichard Lowe 
1722*07dc1947SRichard Lowe     FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1723*07dc1947SRichard Lowe     output_table_real_data_size = dbg->de_frame_reg_rules_entry_count;
172449d3bc91SRichard Lowe 
1725*07dc1947SRichard Lowe     res = dwarf_initialize_fde_table(dbg, &fde_table,
1726*07dc1947SRichard Lowe         output_table_real_data_size,
1727*07dc1947SRichard Lowe         error);
1728*07dc1947SRichard Lowe     if (res != DW_DLV_OK)
1729*07dc1947SRichard Lowe         return res;
1730*07dc1947SRichard Lowe 
1731*07dc1947SRichard Lowe     if (table_column >= output_table_real_data_size) {
1732*07dc1947SRichard Lowe         dwarf_free_fde_table(&fde_table);
1733*07dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
173449d3bc91SRichard Lowe         return (DW_DLV_ERROR);
173549d3bc91SRichard Lowe     }
173649d3bc91SRichard Lowe 
173749d3bc91SRichard Lowe     /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks
173849d3bc91SRichard Lowe      */
173949d3bc91SRichard Lowe     res =
174049d3bc91SRichard Lowe         _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
1741*07dc1947SRichard Lowe             dbg->de_frame_cfa_col_number, error);
1742*07dc1947SRichard Lowe     if (res != DW_DLV_OK) {
1743*07dc1947SRichard Lowe         dwarf_free_fde_table(&fde_table);
1744*07dc1947SRichard Lowe         return res;
1745*07dc1947SRichard Lowe     }
1746*07dc1947SRichard Lowe 
1747*07dc1947SRichard Lowe     if (fde_table.fr_reg[table_column].ru_value_type != DW_EXPR_OFFSET) {
1748*07dc1947SRichard Lowe         /* The problem here is that this interface cannot deal with
1749*07dc1947SRichard Lowe            other sorts of (newer) dwarf frame values.  Code must
1750*07dc1947SRichard Lowe            use dwarf_get_fde_info_for_reg3() to get these
1751*07dc1947SRichard Lowe            values correctly.  We error rather than return
1752*07dc1947SRichard Lowe            misleading incomplete data. */
1753*07dc1947SRichard Lowe         dwarf_free_fde_table(&fde_table);
1754*07dc1947SRichard Lowe         _dwarf_error(NULL, error,
1755*07dc1947SRichard Lowe             DW_DLE_FRAME_REGISTER_UNREPRESENTABLE);
1756*07dc1947SRichard Lowe         return (DW_DLV_ERROR);
1757*07dc1947SRichard Lowe     }
1758*07dc1947SRichard Lowe     if(table_column == dbg->de_frame_cfa_col_number) {
1759*07dc1947SRichard Lowe         if (register_num != NULL)
1760*07dc1947SRichard Lowe             *register_num = fde_table.fr_cfa_rule.ru_register;
1761*07dc1947SRichard Lowe         if (offset != NULL)
1762*07dc1947SRichard Lowe             *offset = fde_table.fr_cfa_rule.ru_offset_or_block_len;
1763*07dc1947SRichard Lowe         if (row_pc != NULL)
1764*07dc1947SRichard Lowe             *row_pc = fde_table.fr_loc;
1765*07dc1947SRichard Lowe         *offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
1766*07dc1947SRichard Lowe 
1767*07dc1947SRichard Lowe     } else {
1768*07dc1947SRichard Lowe         if (register_num != NULL)
1769*07dc1947SRichard Lowe             *register_num = fde_table.fr_reg[table_column].ru_register;
1770*07dc1947SRichard Lowe         if (offset != NULL)
1771*07dc1947SRichard Lowe             *offset = fde_table.fr_reg[table_column].ru_offset_or_block_len;
1772*07dc1947SRichard Lowe         if (row_pc != NULL)
1773*07dc1947SRichard Lowe             *row_pc = fde_table.fr_loc;
1774*07dc1947SRichard Lowe 
1775*07dc1947SRichard Lowe         *offset_relevant = fde_table.fr_reg[table_column].ru_is_off;
1776*07dc1947SRichard Lowe     }
1777*07dc1947SRichard Lowe     dwarf_free_fde_table(&fde_table);
1778*07dc1947SRichard Lowe     return DW_DLV_OK;
1779*07dc1947SRichard Lowe }
1780*07dc1947SRichard Lowe 
1781*07dc1947SRichard Lowe /* In this interface, table_column of DW_FRAME_CFA_COL
1782*07dc1947SRichard Lowe    is not meaningful.
1783*07dc1947SRichard Lowe    Use  dwarf_get_fde_info_for_cfa_reg3() to get the CFA.
1784*07dc1947SRichard Lowe    Call dwarf_set_frame_cfa_value() to set the correct column
1785*07dc1947SRichard Lowe    after calling dwarf_init()
1786*07dc1947SRichard Lowe    (DW_FRAME_CFA_COL3 is a sensible column to use).
1787*07dc1947SRichard Lowe */
1788*07dc1947SRichard Lowe 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*07dc1947SRichard Lowe dwarf_get_fde_info_for_reg3(Dwarf_Fde fde,
1790*07dc1947SRichard Lowe     Dwarf_Half table_column,
1791*07dc1947SRichard Lowe     Dwarf_Addr pc_requested,
1792*07dc1947SRichard Lowe     Dwarf_Small * value_type,
1793*07dc1947SRichard Lowe     Dwarf_Signed * offset_relevant,
1794*07dc1947SRichard Lowe     Dwarf_Signed * register_num,
1795*07dc1947SRichard Lowe     Dwarf_Signed * offset_or_block_len,
1796*07dc1947SRichard Lowe     Dwarf_Ptr * block_ptr,
1797*07dc1947SRichard Lowe     Dwarf_Addr * row_pc_out,
1798*07dc1947SRichard Lowe     Dwarf_Error * error)
1799*07dc1947SRichard Lowe {
1800*07dc1947SRichard Lowe     struct Dwarf_Frame_s fde_table;
1801*07dc1947SRichard Lowe     int res = DW_DLV_ERROR;
1802*07dc1947SRichard Lowe 
1803*07dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
1804*07dc1947SRichard Lowe     int table_real_data_size = 0;
1805*07dc1947SRichard Lowe 
1806*07dc1947SRichard Lowe     FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1807*07dc1947SRichard Lowe     table_real_data_size = dbg->de_frame_reg_rules_entry_count;
1808*07dc1947SRichard Lowe     res = dwarf_initialize_fde_table(dbg, &fde_table,
1809*07dc1947SRichard Lowe         table_real_data_size, error);
1810*07dc1947SRichard Lowe     if (res != DW_DLV_OK)
1811*07dc1947SRichard Lowe         return res;
1812*07dc1947SRichard Lowe     if (table_column >= table_real_data_size) {
1813*07dc1947SRichard Lowe         dwarf_free_fde_table(&fde_table);
1814*07dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD);
1815*07dc1947SRichard Lowe         return (DW_DLV_ERROR);
1816*07dc1947SRichard Lowe     }
1817*07dc1947SRichard Lowe 
1818*07dc1947SRichard Lowe     /* _dwarf_get_fde_info_for_a_pc_row will perform more sanity checks
1819*07dc1947SRichard Lowe      */
1820*07dc1947SRichard Lowe     res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
1821*07dc1947SRichard Lowe         dbg->de_frame_cfa_col_number,
182249d3bc91SRichard Lowe         error);
182349d3bc91SRichard Lowe     if (res != DW_DLV_OK) {
1824*07dc1947SRichard Lowe         dwarf_free_fde_table(&fde_table);
182549d3bc91SRichard Lowe         return res;
182649d3bc91SRichard Lowe     }
182749d3bc91SRichard Lowe 
182849d3bc91SRichard Lowe     if (register_num != NULL)
182949d3bc91SRichard Lowe         *register_num = fde_table.fr_reg[table_column].ru_register;
1830*07dc1947SRichard Lowe     if (offset_or_block_len != NULL)
1831*07dc1947SRichard Lowe         *offset_or_block_len =
1832*07dc1947SRichard Lowe             fde_table.fr_reg[table_column].ru_offset_or_block_len;
1833*07dc1947SRichard Lowe     if (row_pc_out != NULL)
1834*07dc1947SRichard Lowe         *row_pc_out = fde_table.fr_loc;
1835*07dc1947SRichard Lowe     if (block_ptr)
1836*07dc1947SRichard Lowe         *block_ptr = fde_table.fr_reg[table_column].ru_block;
183749d3bc91SRichard Lowe 
1838*07dc1947SRichard Lowe     /* Without value_type the data cannot be understood, so we insist
1839*07dc1947SRichard Lowe        on it being present, we don't test it. */
1840*07dc1947SRichard Lowe     *value_type = fde_table.fr_reg[table_column].ru_value_type;
184149d3bc91SRichard Lowe     *offset_relevant = (fde_table.fr_reg[table_column].ru_is_off);
1842*07dc1947SRichard Lowe     dwarf_free_fde_table(&fde_table);
1843*07dc1947SRichard Lowe     return DW_DLV_OK;
1844*07dc1947SRichard Lowe 
1845*07dc1947SRichard Lowe }
1846*07dc1947SRichard Lowe 
1847*07dc1947SRichard Lowe /* For latest DWARF, this is the preferred interface.
1848*07dc1947SRichard Lowe    It more portably deals with the  CFA by not
1849*07dc1947SRichard Lowe    making the CFA a column number, which means
1850*07dc1947SRichard Lowe    DW_FRAME_CFA_COL3 becomes, like DW_CFA_SAME_VALUE,
1851*07dc1947SRichard Lowe    a special value, not something one uses as an index.
1852*07dc1947SRichard Lowe 
1853*07dc1947SRichard Lowe    Call dwarf_set_frame_cfa_value() to set the correct column
1854*07dc1947SRichard Lowe    after calling dwarf_init()
1855*07dc1947SRichard Lowe    (DW_FRAME_CFA_COL3 is a sensible column to use, and
1856*07dc1947SRichard Lowe    is the default unless '--enable-oldframecol'
1857*07dc1947SRichard Lowe    is used to configure libdwarf).  */
1858*07dc1947SRichard Lowe 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*07dc1947SRichard Lowe dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde,
1860*07dc1947SRichard Lowe     Dwarf_Addr pc_requested,
1861*07dc1947SRichard Lowe     Dwarf_Small * value_type,
1862*07dc1947SRichard Lowe     Dwarf_Signed * offset_relevant,
1863*07dc1947SRichard Lowe     Dwarf_Signed * register_num,
1864*07dc1947SRichard Lowe     Dwarf_Signed * offset_or_block_len,
1865*07dc1947SRichard Lowe     Dwarf_Ptr * block_ptr,
1866*07dc1947SRichard Lowe     Dwarf_Addr * row_pc_out,
1867*07dc1947SRichard Lowe     Dwarf_Error * error)
1868*07dc1947SRichard Lowe {
1869*07dc1947SRichard Lowe     struct Dwarf_Frame_s fde_table;
1870*07dc1947SRichard Lowe     int res = DW_DLV_ERROR;
1871*07dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
1872*07dc1947SRichard Lowe 
1873*07dc1947SRichard Lowe     int table_real_data_size = 0;
1874*07dc1947SRichard Lowe 
1875*07dc1947SRichard Lowe     FDE_NULL_CHECKS_AND_SET_DBG(fde, dbg);
1876*07dc1947SRichard Lowe 
1877*07dc1947SRichard Lowe     table_real_data_size = dbg->de_frame_reg_rules_entry_count;
1878*07dc1947SRichard Lowe     res = dwarf_initialize_fde_table(dbg, &fde_table,
1879*07dc1947SRichard Lowe         table_real_data_size, error);
1880*07dc1947SRichard Lowe     if (res != DW_DLV_OK)
1881*07dc1947SRichard Lowe         return res;
1882*07dc1947SRichard Lowe     res = _dwarf_get_fde_info_for_a_pc_row(fde, pc_requested, &fde_table,
1883*07dc1947SRichard Lowe           dbg->de_frame_cfa_col_number,error);
1884*07dc1947SRichard Lowe     if (res != DW_DLV_OK) {
1885*07dc1947SRichard Lowe         dwarf_free_fde_table(&fde_table);
1886*07dc1947SRichard Lowe         return res;
1887*07dc1947SRichard Lowe     }
1888*07dc1947SRichard Lowe 
1889*07dc1947SRichard Lowe     if (register_num != NULL)
1890*07dc1947SRichard Lowe         *register_num = fde_table.fr_cfa_rule.ru_register;
1891*07dc1947SRichard Lowe     if (offset_or_block_len != NULL)
1892*07dc1947SRichard Lowe         *offset_or_block_len =
1893*07dc1947SRichard Lowe             fde_table.fr_cfa_rule.ru_offset_or_block_len;
1894*07dc1947SRichard Lowe     if (row_pc_out != NULL)
1895*07dc1947SRichard Lowe         *row_pc_out = fde_table.fr_loc;
1896*07dc1947SRichard Lowe     if (block_ptr)
1897*07dc1947SRichard Lowe         *block_ptr = fde_table.fr_cfa_rule.ru_block;
1898*07dc1947SRichard Lowe 
1899*07dc1947SRichard Lowe     /* Without value_type the data cannot be understood, so we insist
1900*07dc1947SRichard Lowe        on it being present, we don't test it. */
1901*07dc1947SRichard Lowe     *value_type = fde_table.fr_cfa_rule.ru_value_type;
1902*07dc1947SRichard Lowe     *offset_relevant = fde_table.fr_cfa_rule.ru_is_off;
1903*07dc1947SRichard Lowe     dwarf_free_fde_table(&fde_table);
190449d3bc91SRichard Lowe     return DW_DLV_OK;
190549d3bc91SRichard Lowe }
190649d3bc91SRichard Lowe 
1907*07dc1947SRichard Lowe 
1908*07dc1947SRichard Lowe 
190949d3bc91SRichard Lowe /*
191049d3bc91SRichard Lowe         Return pointer to the instructions in the dwarf
191149d3bc91SRichard Lowe         fde.
191249d3bc91SRichard Lowe */
191349d3bc91SRichard Lowe int
dwarf_get_fde_instr_bytes(Dwarf_Fde inFde,Dwarf_Ptr * outinstraddr,Dwarf_Unsigned * outaddrlen,Dwarf_Error * error)191449d3bc91SRichard Lowe dwarf_get_fde_instr_bytes(Dwarf_Fde inFde, Dwarf_Ptr * outinstraddr,
191549d3bc91SRichard Lowe     Dwarf_Unsigned * outaddrlen,
191649d3bc91SRichard Lowe     Dwarf_Error * error)
191749d3bc91SRichard Lowe {
1918*07dc1947SRichard Lowe     Dwarf_Unsigned len = 0;
1919*07dc1947SRichard Lowe     unsigned char *instrs = 0;
1920*07dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
192149d3bc91SRichard Lowe 
192249d3bc91SRichard Lowe     if (inFde == NULL) {
1923*07dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_FDE_NULL);
192449d3bc91SRichard Lowe         return (DW_DLV_ERROR);
192549d3bc91SRichard Lowe     }
192649d3bc91SRichard Lowe 
192749d3bc91SRichard Lowe     dbg = inFde->fd_dbg;
192849d3bc91SRichard Lowe     if (dbg == NULL) {
1929*07dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_FDE_DBG_NULL);
193049d3bc91SRichard Lowe         return (DW_DLV_ERROR);
193149d3bc91SRichard Lowe     }
193249d3bc91SRichard Lowe 
1933*07dc1947SRichard Lowe     instrs = inFde->fd_fde_instr_start;
1934*07dc1947SRichard Lowe 
193549d3bc91SRichard Lowe     len = (inFde->fd_fde_start + inFde->fd_length +
1936*07dc1947SRichard Lowe            inFde->fd_length_size + inFde->fd_extension_size) - instrs;
193749d3bc91SRichard Lowe 
193849d3bc91SRichard Lowe     *outinstraddr = instrs;
193949d3bc91SRichard Lowe     *outaddrlen = len;
194049d3bc91SRichard Lowe     return DW_DLV_OK;
194149d3bc91SRichard Lowe }
194249d3bc91SRichard Lowe 
1943*07dc1947SRichard Lowe /* Allows getting an fde from its table via an index.
1944*07dc1947SRichard Lowe    With more error checking than simply indexing oneself.
1945*07dc1947SRichard Lowe */
194649d3bc91SRichard Lowe int
dwarf_get_fde_n(Dwarf_Fde * fde_data,Dwarf_Unsigned fde_index,Dwarf_Fde * returned_fde,Dwarf_Error * error)194749d3bc91SRichard Lowe dwarf_get_fde_n(Dwarf_Fde * fde_data,
194849d3bc91SRichard Lowe     Dwarf_Unsigned fde_index,
194949d3bc91SRichard Lowe     Dwarf_Fde * returned_fde, Dwarf_Error * error)
195049d3bc91SRichard Lowe {
1951*07dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
1952*07dc1947SRichard Lowe     Dwarf_Signed fdecount = 0;
195349d3bc91SRichard Lowe 
195449d3bc91SRichard Lowe     if (fde_data == NULL) {
1955*07dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_FDE_PTR_NULL);
195649d3bc91SRichard Lowe         return (DW_DLV_ERROR);
195749d3bc91SRichard Lowe     }
195849d3bc91SRichard Lowe 
1959*07dc1947SRichard Lowe     FDE_NULL_CHECKS_AND_SET_DBG(*fde_data, dbg);
1960*07dc1947SRichard Lowe     /* Assumes fde_data table has at least one entry. */
1961*07dc1947SRichard Lowe     fdecount = fde_data[0]->fd_is_eh?
1962*07dc1947SRichard Lowe         dbg->de_fde_count_eh:dbg->de_fde_count;
1963*07dc1947SRichard Lowe     if (fde_index >= fdecount) {
196449d3bc91SRichard Lowe         return (DW_DLV_NO_ENTRY);
196549d3bc91SRichard Lowe     }
196649d3bc91SRichard Lowe     *returned_fde = (*(fde_data + fde_index));
196749d3bc91SRichard Lowe     return DW_DLV_OK;
196849d3bc91SRichard Lowe }
196949d3bc91SRichard Lowe 
197049d3bc91SRichard Lowe 
197149d3bc91SRichard Lowe /*
197249d3bc91SRichard Lowe     Lopc and hipc are extensions to the interface to
197349d3bc91SRichard Lowe     return the range of addresses that are described
197449d3bc91SRichard Lowe     by the returned fde.
197549d3bc91SRichard Lowe */
197649d3bc91SRichard Lowe 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)197749d3bc91SRichard Lowe dwarf_get_fde_at_pc(Dwarf_Fde * fde_data,
197849d3bc91SRichard Lowe     Dwarf_Addr pc_of_interest,
197949d3bc91SRichard Lowe     Dwarf_Fde * returned_fde,
198049d3bc91SRichard Lowe     Dwarf_Addr * lopc,
198149d3bc91SRichard Lowe     Dwarf_Addr * hipc, Dwarf_Error * error)
198249d3bc91SRichard Lowe {
1983*07dc1947SRichard Lowe     Dwarf_Debug dbg = NULL;
198449d3bc91SRichard Lowe     Dwarf_Fde fde = NULL;
1985*07dc1947SRichard Lowe     Dwarf_Fde entryfde = NULL;
1986*07dc1947SRichard Lowe     Dwarf_Signed fdecount = 0;
198749d3bc91SRichard Lowe 
198849d3bc91SRichard Lowe     if (fde_data == NULL) {
198949d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_FDE_PTR_NULL);
199049d3bc91SRichard Lowe         return (DW_DLV_ERROR);
199149d3bc91SRichard Lowe     }
199249d3bc91SRichard Lowe 
1993*07dc1947SRichard Lowe     /* Assumes fde_data table has at least one entry. */
1994*07dc1947SRichard Lowe     entryfde = *fde_data;
1995*07dc1947SRichard Lowe     FDE_NULL_CHECKS_AND_SET_DBG(entryfde, dbg);
199649d3bc91SRichard Lowe 
199749d3bc91SRichard Lowe     if (dbg == NULL) {
199849d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_FDE_DBG_NULL);
199949d3bc91SRichard Lowe         return (DW_DLV_ERROR);
200049d3bc91SRichard Lowe     }
2001*07dc1947SRichard Lowe     fdecount = entryfde->fd_is_eh?
2002*07dc1947SRichard Lowe         dbg->de_fde_count_eh:dbg->de_fde_count;
200349d3bc91SRichard Lowe     {
200449d3bc91SRichard Lowe         /* The fde's are sorted by their addresses. Binary search to
200549d3bc91SRichard Lowe            find correct fde. */
2006*07dc1947SRichard Lowe         Dwarf_Signed low = 0;
2007*07dc1947SRichard Lowe         Dwarf_Signed high = fdecount - 1L;
2008*07dc1947SRichard Lowe         Dwarf_Signed middle = 0;
200949d3bc91SRichard Lowe         Dwarf_Fde cur_fde;
201049d3bc91SRichard Lowe 
201149d3bc91SRichard Lowe         while (low <= high) {
201249d3bc91SRichard Lowe             middle = (low + high) / 2;
201349d3bc91SRichard Lowe             cur_fde = fde_data[middle];
201449d3bc91SRichard Lowe             if (pc_of_interest < cur_fde->fd_initial_location) {
201549d3bc91SRichard Lowe                 high = middle - 1;
201649d3bc91SRichard Lowe             } else if (pc_of_interest >=
201749d3bc91SRichard Lowe                        (cur_fde->fd_initial_location +
201849d3bc91SRichard Lowe                         cur_fde->fd_address_range)) {
201949d3bc91SRichard Lowe                 low = middle + 1;
202049d3bc91SRichard Lowe             } else {
202149d3bc91SRichard Lowe                 fde = fde_data[middle];
202249d3bc91SRichard Lowe                 break;
202349d3bc91SRichard Lowe             }
202449d3bc91SRichard Lowe         }
202549d3bc91SRichard Lowe     }
202649d3bc91SRichard Lowe 
202749d3bc91SRichard Lowe     if (fde) {
202849d3bc91SRichard Lowe         if (lopc != NULL)
202949d3bc91SRichard Lowe             *lopc = fde->fd_initial_location;
203049d3bc91SRichard Lowe         if (hipc != NULL)
2031*07dc1947SRichard Lowe             *hipc =
2032*07dc1947SRichard Lowe                 fde->fd_initial_location + fde->fd_address_range - 1;
203349d3bc91SRichard Lowe         *returned_fde = fde;
203449d3bc91SRichard Lowe         return (DW_DLV_OK);
203549d3bc91SRichard Lowe     }
203649d3bc91SRichard Lowe 
203749d3bc91SRichard Lowe     return (DW_DLV_NO_ENTRY);
203849d3bc91SRichard Lowe }
203949d3bc91SRichard Lowe 
204049d3bc91SRichard Lowe 
2041*07dc1947SRichard Lowe /* Expands a single frame instruction block
2042*07dc1947SRichard Lowe    from a specific cie
2043*07dc1947SRichard Lowe    into a n array of Dwarf_Frame_Op-s.
2044*07dc1947SRichard Lowe    This depends on having the cfa column set sensibly.
2045*07dc1947SRichard Lowe 
2046*07dc1947SRichard Lowe    Call dwarf_set_frame_cfa_value() to set the correct column
2047*07dc1947SRichard Lowe    after calling dwarf_init() unless you are using
2048*07dc1947SRichard Lowe    the old MIPS frame interfaces (in which case the default
2049*07dc1947SRichard Lowe    will be ok). (DW_FRAME_CFA_COL3 is a sensible column to use ).
2050*07dc1947SRichard Lowe */
205149d3bc91SRichard Lowe 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*07dc1947SRichard Lowe dwarf_expand_frame_instructions(Dwarf_Cie cie,
205349d3bc91SRichard Lowe     Dwarf_Ptr instruction,
205449d3bc91SRichard Lowe     Dwarf_Unsigned i_length,
205549d3bc91SRichard Lowe     Dwarf_Frame_Op ** returned_op_list,
205649d3bc91SRichard Lowe     Dwarf_Signed * returned_op_count,
205749d3bc91SRichard Lowe     Dwarf_Error * error)
205849d3bc91SRichard Lowe {
205949d3bc91SRichard Lowe     Dwarf_Sword instr_count;
2060*07dc1947SRichard Lowe     int res = DW_DLV_ERROR;
206149d3bc91SRichard Lowe     int dw_err;
2062*07dc1947SRichard Lowe     Dwarf_Debug dbg = 0;
206349d3bc91SRichard Lowe 
2064*07dc1947SRichard Lowe     if (cie == 0) {
206549d3bc91SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_DBG_NULL);
206649d3bc91SRichard Lowe         return (DW_DLV_ERROR);
206749d3bc91SRichard Lowe     }
2068*07dc1947SRichard Lowe     dbg = cie->ci_dbg;
206949d3bc91SRichard Lowe 
207049d3bc91SRichard Lowe     if (returned_op_list == 0 || returned_op_count == 0) {
207149d3bc91SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_RET_OP_LIST_NULL);
207249d3bc91SRichard Lowe         return (DW_DLV_ERROR);
207349d3bc91SRichard Lowe     }
207449d3bc91SRichard Lowe 
207549d3bc91SRichard Lowe     /* The cast to Dwarf_Ptr may get a compiler warning, but it is safe
207649d3bc91SRichard Lowe        as it is just an i_length offset from 'instruction' itself. A
207749d3bc91SRichard Lowe        caller has made a big mistake if the result is not a valid
207849d3bc91SRichard Lowe        pointer. */
207949d3bc91SRichard Lowe     res = _dwarf_exec_frame_instr( /* make_instr= */ true,
208049d3bc91SRichard Lowe         returned_op_list,
208149d3bc91SRichard Lowe         /* search_pc */ false,
208249d3bc91SRichard Lowe         /* search_pc_val */ 0,
208349d3bc91SRichard Lowe         /* location */ 0,
208449d3bc91SRichard Lowe         instruction,
208549d3bc91SRichard Lowe         (Dwarf_Ptr)((char *)instruction + i_length),
208649d3bc91SRichard Lowe         /* Dwarf_Frame */ NULL,
2087*07dc1947SRichard Lowe         cie,
2088*07dc1947SRichard Lowe         dbg,
2089*07dc1947SRichard Lowe         dbg->de_frame_cfa_col_number, &instr_count,
2090*07dc1947SRichard Lowe         &dw_err);
209149d3bc91SRichard Lowe     if (res != DW_DLV_OK) {
209249d3bc91SRichard Lowe         if (res == DW_DLV_ERROR) {
209349d3bc91SRichard Lowe             _dwarf_error(dbg, error, dw_err);
209449d3bc91SRichard Lowe         }
209549d3bc91SRichard Lowe         return (res);
209649d3bc91SRichard Lowe     }
209749d3bc91SRichard Lowe 
209849d3bc91SRichard Lowe     *returned_op_count = instr_count;
209949d3bc91SRichard Lowe     return DW_DLV_OK;
210049d3bc91SRichard Lowe }
210149d3bc91SRichard Lowe 
210249d3bc91SRichard Lowe 
210349d3bc91SRichard Lowe /* Used by dwarfdump -v to print offsets, for debugging
2104*07dc1947SRichard Lowe    dwarf info.
2105*07dc1947SRichard Lowe    The dwarf_ version is preferred over the obsolete _dwarf version.
2106*07dc1947SRichard Lowe    _dwarf version kept for compatibility.
210749d3bc91SRichard Lowe */
210849d3bc91SRichard Lowe /* ARGSUSED 4 */
210949d3bc91SRichard Lowe int
_dwarf_fde_section_offset(Dwarf_Debug dbg,Dwarf_Fde in_fde,Dwarf_Off * fde_off,Dwarf_Off * cie_off,Dwarf_Error * err)211049d3bc91SRichard Lowe _dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde,
211149d3bc91SRichard Lowe     Dwarf_Off * fde_off, Dwarf_Off * cie_off,
211249d3bc91SRichard Lowe     Dwarf_Error * err)
211349d3bc91SRichard Lowe {
2114*07dc1947SRichard Lowe   return dwarf_fde_section_offset(dbg,in_fde,fde_off,
2115*07dc1947SRichard Lowe      cie_off,err);
211649d3bc91SRichard Lowe }
2117*07dc1947SRichard Lowe /* ARGSUSED 4 */
2118*07dc1947SRichard Lowe int
dwarf_fde_section_offset(Dwarf_Debug dbg,Dwarf_Fde in_fde,Dwarf_Off * fde_off,Dwarf_Off * cie_off,Dwarf_Error * err)2119*07dc1947SRichard Lowe dwarf_fde_section_offset(Dwarf_Debug dbg, Dwarf_Fde in_fde,
2120*07dc1947SRichard Lowe     Dwarf_Off * fde_off, Dwarf_Off * cie_off,
2121*07dc1947SRichard Lowe     Dwarf_Error * err)
2122*07dc1947SRichard Lowe {
2123*07dc1947SRichard Lowe     char *start = 0;
2124*07dc1947SRichard Lowe     char *loc = 0;
212549d3bc91SRichard Lowe 
2126*07dc1947SRichard Lowe 
2127*07dc1947SRichard Lowe 
2128*07dc1947SRichard Lowe     start = (char *) in_fde->fd_section_ptr;
212949d3bc91SRichard Lowe     loc = (char *) in_fde->fd_fde_start;
213049d3bc91SRichard Lowe 
213149d3bc91SRichard Lowe     *fde_off = (loc - start);
213249d3bc91SRichard Lowe     *cie_off = in_fde->fd_cie_offset;
213349d3bc91SRichard Lowe     return DW_DLV_OK;
213449d3bc91SRichard Lowe }
213549d3bc91SRichard Lowe 
213649d3bc91SRichard Lowe /* Used by dwarfdump -v to print offsets, for debugging
2137*07dc1947SRichard Lowe    dwarf info.
2138*07dc1947SRichard Lowe    The dwarf_ version is preferred over the obsolete _dwarf version.
2139*07dc1947SRichard Lowe    _dwarf version kept for compatibility.
214049d3bc91SRichard Lowe */
214149d3bc91SRichard Lowe /* ARGSUSED 4 */
214249d3bc91SRichard Lowe int
_dwarf_cie_section_offset(Dwarf_Debug dbg,Dwarf_Cie in_cie,Dwarf_Off * cie_off,Dwarf_Error * err)214349d3bc91SRichard Lowe _dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie,
214449d3bc91SRichard Lowe     Dwarf_Off * cie_off, Dwarf_Error * err)
214549d3bc91SRichard Lowe {
2146*07dc1947SRichard Lowe     return dwarf_cie_section_offset(dbg,in_cie,cie_off,err);
214749d3bc91SRichard Lowe }
2148*07dc1947SRichard Lowe /* ARGSUSED 4 */
2149*07dc1947SRichard Lowe int
dwarf_cie_section_offset(Dwarf_Debug dbg,Dwarf_Cie in_cie,Dwarf_Off * cie_off,Dwarf_Error * err)2150*07dc1947SRichard Lowe dwarf_cie_section_offset(Dwarf_Debug dbg, Dwarf_Cie in_cie,
2151*07dc1947SRichard Lowe     Dwarf_Off * cie_off, Dwarf_Error * err)
2152*07dc1947SRichard Lowe {
2153*07dc1947SRichard Lowe     char *start = 0;
2154*07dc1947SRichard Lowe     char *loc = 0;
215549d3bc91SRichard Lowe 
2156*07dc1947SRichard Lowe     start = (char *) in_cie->ci_section_ptr;
215749d3bc91SRichard Lowe     loc = (char *) in_cie->ci_cie_start;
215849d3bc91SRichard Lowe 
215949d3bc91SRichard Lowe     *cie_off = (loc - start);
216049d3bc91SRichard Lowe     return DW_DLV_OK;
216149d3bc91SRichard Lowe }
2162*07dc1947SRichard Lowe 
2163*07dc1947SRichard Lowe /* Returns  a pointer to target-specific augmentation data thru augdata
2164*07dc1947SRichard Lowe    and returns the length of the data thru augdata_len.
2165*07dc1947SRichard Lowe 
2166*07dc1947SRichard Lowe    It's up to the consumer code to know how to interpret the bytes
2167*07dc1947SRichard Lowe    of target-specific data (endian issues apply too, these
2168*07dc1947SRichard Lowe    are just raw bytes pointed to).
2169*07dc1947SRichard Lowe    See  Linux Standard Base Core Specification version 3.0 for
2170*07dc1947SRichard Lowe    the details on .eh_frame info.
2171*07dc1947SRichard Lowe 
2172*07dc1947SRichard Lowe    Returns DW_DLV_ERROR if fde is NULL or some other serious
2173*07dc1947SRichard Lowe    error.
2174*07dc1947SRichard Lowe    Returns DW_DLV_NO_ENTRY if there is no target-specific
2175*07dc1947SRichard Lowe    augmentation data.
2176*07dc1947SRichard Lowe 
2177*07dc1947SRichard Lowe    The bytes pointed to are in the Dwarf_Cie, and as long as that
2178*07dc1947SRichard Lowe    is valid the bytes are there. No 'dealloc' call is needed
2179*07dc1947SRichard Lowe    for the bytes.
2180*07dc1947SRichard Lowe */
2181*07dc1947SRichard Lowe int
dwarf_get_cie_augmentation_data(Dwarf_Cie cie,Dwarf_Small ** augdata,Dwarf_Unsigned * augdata_len,Dwarf_Error * error)2182*07dc1947SRichard Lowe dwarf_get_cie_augmentation_data(Dwarf_Cie cie,
2183*07dc1947SRichard Lowe     Dwarf_Small ** augdata,
2184*07dc1947SRichard Lowe     Dwarf_Unsigned * augdata_len,
2185*07dc1947SRichard Lowe     Dwarf_Error * error)
2186*07dc1947SRichard Lowe {
2187*07dc1947SRichard Lowe     if (cie == NULL) {
2188*07dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
2189*07dc1947SRichard Lowe         return (DW_DLV_ERROR);
2190*07dc1947SRichard Lowe     }
2191*07dc1947SRichard Lowe     if (cie->ci_gnu_eh_augmentation_len == 0) {
2192*07dc1947SRichard Lowe         return DW_DLV_NO_ENTRY;
2193*07dc1947SRichard Lowe     }
2194*07dc1947SRichard Lowe     *augdata = (Dwarf_Small *) (cie->ci_gnu_eh_augmentation_bytes);
2195*07dc1947SRichard Lowe     *augdata_len = cie->ci_gnu_eh_augmentation_len;
2196*07dc1947SRichard Lowe     return DW_DLV_OK;
2197*07dc1947SRichard Lowe }
2198*07dc1947SRichard Lowe 
2199*07dc1947SRichard Lowe 
2200*07dc1947SRichard Lowe /* Returns  a pointer to target-specific augmentation data thru augdata
2201*07dc1947SRichard Lowe    and returns the length of the data thru augdata_len.
2202*07dc1947SRichard Lowe 
2203*07dc1947SRichard Lowe    It's up to the consumer code to know how to interpret the bytes
2204*07dc1947SRichard Lowe    of target-specific data (endian issues apply too, these
2205*07dc1947SRichard Lowe    are just raw bytes pointed to).
2206*07dc1947SRichard Lowe    See  Linux Standard Base Core Specification version 3.0 for
2207*07dc1947SRichard Lowe    the details on .eh_frame info.
2208*07dc1947SRichard Lowe 
2209*07dc1947SRichard Lowe    Returns DW_DLV_ERROR if fde is NULL or some other serious
2210*07dc1947SRichard Lowe    error.
2211*07dc1947SRichard Lowe    Returns DW_DLV_NO_ENTRY if there is no target-specific
2212*07dc1947SRichard Lowe    augmentation data.
2213*07dc1947SRichard Lowe 
2214*07dc1947SRichard Lowe    The bytes pointed to are in the Dwarf_Fde, and as long as that
2215*07dc1947SRichard Lowe    is valid the bytes are there. No 'dealloc' call is needed
2216*07dc1947SRichard Lowe    for the bytes.
2217*07dc1947SRichard Lowe 
2218*07dc1947SRichard Lowe */
2219*07dc1947SRichard Lowe int
dwarf_get_fde_augmentation_data(Dwarf_Fde fde,Dwarf_Small ** augdata,Dwarf_Unsigned * augdata_len,Dwarf_Error * error)2220*07dc1947SRichard Lowe dwarf_get_fde_augmentation_data(Dwarf_Fde fde,
2221*07dc1947SRichard Lowe     Dwarf_Small * *augdata,
2222*07dc1947SRichard Lowe     Dwarf_Unsigned * augdata_len,
2223*07dc1947SRichard Lowe     Dwarf_Error * error)
2224*07dc1947SRichard Lowe {
2225*07dc1947SRichard Lowe     Dwarf_Cie cie = 0;
2226*07dc1947SRichard Lowe 
2227*07dc1947SRichard Lowe     if (fde == NULL) {
2228*07dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_FDE_NULL);
2229*07dc1947SRichard Lowe         return (DW_DLV_ERROR);
2230*07dc1947SRichard Lowe     }
2231*07dc1947SRichard Lowe     cie = fde->fd_cie;
2232*07dc1947SRichard Lowe     if (cie == NULL) {
2233*07dc1947SRichard Lowe         _dwarf_error(NULL, error, DW_DLE_CIE_NULL);
2234*07dc1947SRichard Lowe         return (DW_DLV_ERROR);
2235*07dc1947SRichard Lowe     }
2236*07dc1947SRichard Lowe     if (cie->ci_gnu_eh_augmentation_len == 0) {
2237*07dc1947SRichard Lowe         return DW_DLV_NO_ENTRY;
2238*07dc1947SRichard Lowe     }
2239*07dc1947SRichard Lowe     *augdata = (Dwarf_Small *) fde->fd_gnu_eh_augmentation_bytes;
2240*07dc1947SRichard Lowe     *augdata_len = fde->fd_gnu_eh_augmentation_len;
2241*07dc1947SRichard Lowe     return DW_DLV_OK;
2242*07dc1947SRichard Lowe }
2243*07dc1947SRichard Lowe 
2244*07dc1947SRichard Lowe 
2245*07dc1947SRichard Lowe /* Initialize with same_value , a value which makes sense
2246*07dc1947SRichard Lowe    for IRIX/MIPS.
2247*07dc1947SRichard Lowe    The correct value to use is ABI dependent.
2248*07dc1947SRichard Lowe    For register-windows machines most
2249*07dc1947SRichard Lowe    or all registers should get DW_FRAME_UNDEFINED_VAL as the
2250*07dc1947SRichard Lowe    correct initial value.
2251*07dc1947SRichard Lowe    Some think DW_FRAME_UNDEFINED_VAL is always the
2252*07dc1947SRichard Lowe    right value.
2253*07dc1947SRichard Lowe 
2254*07dc1947SRichard Lowe    For some ABIs a setting which varies by register
2255*07dc1947SRichard Lowe    would be more appropriate.
2256*07dc1947SRichard Lowe 
2257*07dc1947SRichard Lowe    FIXME. */
2258*07dc1947SRichard Lowe 
2259*07dc1947SRichard Lowe static void
_dwarf_init_regrule_table(struct Dwarf_Reg_Rule_s * t1reg,int last_reg_num,int initial_value)2260*07dc1947SRichard Lowe _dwarf_init_regrule_table(struct Dwarf_Reg_Rule_s *t1reg,
2261*07dc1947SRichard Lowe     int last_reg_num, int initial_value)
2262*07dc1947SRichard Lowe {
2263*07dc1947SRichard Lowe     struct Dwarf_Reg_Rule_s *t1end = t1reg + last_reg_num;
2264*07dc1947SRichard Lowe 
2265*07dc1947SRichard Lowe     for (; t1reg < t1end; t1reg++) {
2266*07dc1947SRichard Lowe         t1reg->ru_is_off = 0;
2267*07dc1947SRichard Lowe         t1reg->ru_value_type = DW_EXPR_OFFSET;
2268*07dc1947SRichard Lowe         t1reg->ru_register = initial_value;
2269*07dc1947SRichard Lowe         t1reg->ru_offset_or_block_len = 0;
2270*07dc1947SRichard Lowe         t1reg->ru_block = 0;
2271*07dc1947SRichard Lowe     }
2272*07dc1947SRichard Lowe }
2273*07dc1947SRichard Lowe 
2274*07dc1947SRichard Lowe #if 0
2275*07dc1947SRichard Lowe /* Used solely for debugging libdwarf. */
2276*07dc1947SRichard Lowe static void
2277*07dc1947SRichard Lowe dump_frame_rule(char *msg, struct Dwarf_Reg_Rule_s *reg_rule)
2278*07dc1947SRichard Lowe {
2279*07dc1947SRichard Lowe     printf
2280*07dc1947SRichard Lowe         ("%s type %s (" DW_PR_DUx "), is_off "
2281*07dc1947SRichard Lowe          DW_PR_DUu " reg " DW_PR_DUu " offset " DW_PR_DUx " blockp "
2282*07dc1947SRichard Lowe          DW_PR_DUx "\n",
2283*07dc1947SRichard Lowe          msg,
2284*07dc1947SRichard Lowe          (reg_rule->ru_value_type == DW_EXPR_OFFSET) ?
2285*07dc1947SRichard Lowe              "DW_EXPR_OFFSET" :
2286*07dc1947SRichard Lowe           (reg_rule->ru_value_type == DW_EXPR_VAL_OFFSET) ?
2287*07dc1947SRichard Lowe              "DW_EXPR_VAL_OFFSET" :
2288*07dc1947SRichard Lowe           (reg_rule->ru_value_type == DW_EXPR_VAL_EXPRESSION) ?
2289*07dc1947SRichard Lowe              "DW_EXPR_VAL_EXPRESSION" :
2290*07dc1947SRichard Lowe           (reg_rule->ru_value_type == DW_EXPR_EXPRESSION) ?
2291*07dc1947SRichard Lowe              "DW_EXPR_EXPRESSION" : "Unknown",
2292*07dc1947SRichard Lowe          (Dwarf_Unsigned) reg_rule->ru_value_type,
2293*07dc1947SRichard Lowe          (Dwarf_Unsigned) reg_rule->ru_is_off,
2294*07dc1947SRichard Lowe          (Dwarf_Unsigned) reg_rule->ru_register,
2295*07dc1947SRichard Lowe          (Dwarf_Unsigned) reg_rule->ru_offset_or_block_len,
2296*07dc1947SRichard Lowe          (Dwarf_Unsigned) reg_rule->ru_block);
2297*07dc1947SRichard Lowe     return;
2298*07dc1947SRichard Lowe }
2299*07dc1947SRichard Lowe #endif
2300*07dc1947SRichard Lowe 
2301*07dc1947SRichard Lowe /* This allows consumers to set the 'initial value' so that
2302*07dc1947SRichard Lowe    an ISA/ABI specific default can be used, dynamically,
2303*07dc1947SRichard Lowe    at run time.  Useful for dwarfdump and non-MIPS architectures..
2304*07dc1947SRichard Lowe    The value  defaults to one of
2305*07dc1947SRichard Lowe         DW_FRAME_SAME_VALUE or DW_FRAME_UNKNOWN_VALUE
2306*07dc1947SRichard Lowe    but dwarfdump can dump multiple ISA/ABI objects so
2307*07dc1947SRichard Lowe    we may want to get this set to what the ABI says is correct.
2308*07dc1947SRichard Lowe 
2309*07dc1947SRichard Lowe    Returns the value that was present before we changed it here.
2310*07dc1947SRichard Lowe */
2311*07dc1947SRichard Lowe Dwarf_Half
dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg,Dwarf_Half value)2312*07dc1947SRichard Lowe dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg, Dwarf_Half value)
2313*07dc1947SRichard Lowe {
2314*07dc1947SRichard Lowe     Dwarf_Half orig = dbg->de_frame_rule_initial_value;
2315*07dc1947SRichard Lowe     dbg->de_frame_rule_initial_value = value;
2316*07dc1947SRichard Lowe     return orig;
2317*07dc1947SRichard Lowe }
2318*07dc1947SRichard Lowe 
2319*07dc1947SRichard Lowe /* The following spelling for backwards compatibility. */
2320*07dc1947SRichard Lowe Dwarf_Half
dwarf_set_frame_rule_inital_value(Dwarf_Debug dbg,Dwarf_Half value)2321*07dc1947SRichard Lowe dwarf_set_frame_rule_inital_value(Dwarf_Debug dbg, Dwarf_Half value)
2322*07dc1947SRichard Lowe {
2323*07dc1947SRichard Lowe     return dwarf_set_frame_rule_initial_value(dbg,value);
2324*07dc1947SRichard Lowe }
2325*07dc1947SRichard Lowe 
2326*07dc1947SRichard Lowe /* This allows consumers to set the array size of the  reg rules
2327*07dc1947SRichard Lowe    table so that
2328*07dc1947SRichard Lowe    an ISA/ABI specific value can be used, dynamically,
2329*07dc1947SRichard Lowe    at run time.  Useful for non-MIPS archtectures.
2330*07dc1947SRichard Lowe    The value  defaults  to DW_FRAME_LAST_REG_NUM.
2331*07dc1947SRichard Lowe    but dwarfdump can dump multiple ISA/ABI objects so
2332*07dc1947SRichard Lowe    consumers want to get this set to what the ABI says is correct.
2333*07dc1947SRichard Lowe 
2334*07dc1947SRichard Lowe    Returns the value that was present before we changed it here.
2335*07dc1947SRichard Lowe */
2336*07dc1947SRichard Lowe 
2337*07dc1947SRichard Lowe Dwarf_Half
dwarf_set_frame_rule_table_size(Dwarf_Debug dbg,Dwarf_Half value)2338*07dc1947SRichard Lowe dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, Dwarf_Half value)
2339*07dc1947SRichard Lowe {
2340*07dc1947SRichard Lowe     Dwarf_Half orig = dbg->de_frame_reg_rules_entry_count;
2341*07dc1947SRichard Lowe     dbg->de_frame_reg_rules_entry_count = value;
2342*07dc1947SRichard Lowe     return orig;
2343*07dc1947SRichard Lowe }
2344*07dc1947SRichard Lowe /* This allows consumers to set the CFA register value
2345*07dc1947SRichard Lowe  * so that an ISA/ABI specific value can be used, dynamically,
2346*07dc1947SRichard Lowe  * at run time.  Useful for non-MIPS archtectures.
2347*07dc1947SRichard Lowe  * The value  defaults  to DW_FRAME_CFA_COL3 and should be
2348*07dc1947SRichard Lowe  * higher than any real register in the ABI.
2349*07dc1947SRichard Lowe  * Dwarfdump can dump multiple ISA/ABI objects so
2350*07dc1947SRichard Lowe  * consumers want to get this set to what the ABI says is correct.
2351*07dc1947SRichard Lowe 
2352*07dc1947SRichard Lowe  * Returns the value that was present before we changed it here.
2353*07dc1947SRichard Lowe  * */
2354*07dc1947SRichard Lowe 
2355*07dc1947SRichard Lowe Dwarf_Half
dwarf_set_frame_cfa_value(Dwarf_Debug dbg,Dwarf_Half value)2356*07dc1947SRichard Lowe dwarf_set_frame_cfa_value(Dwarf_Debug dbg, Dwarf_Half value)
2357*07dc1947SRichard Lowe {
2358*07dc1947SRichard Lowe     Dwarf_Half orig = dbg->de_frame_cfa_col_number;
2359*07dc1947SRichard Lowe     dbg->de_frame_cfa_col_number = value;
2360*07dc1947SRichard Lowe     return orig;
2361*07dc1947SRichard Lowe }
2362*07dc1947SRichard Lowe /* Similar to above, but for the other crucial fields for frames. */
2363*07dc1947SRichard Lowe Dwarf_Half
dwarf_set_frame_same_value(Dwarf_Debug dbg,Dwarf_Half value)2364*07dc1947SRichard Lowe dwarf_set_frame_same_value(Dwarf_Debug dbg, Dwarf_Half value)
2365*07dc1947SRichard Lowe {
2366*07dc1947SRichard Lowe     Dwarf_Half orig = dbg->de_frame_same_value_number;
2367*07dc1947SRichard Lowe     dbg->de_frame_same_value_number = value;
2368*07dc1947SRichard Lowe     return orig;
2369*07dc1947SRichard Lowe }
2370*07dc1947SRichard Lowe Dwarf_Half
dwarf_set_frame_undefined_value(Dwarf_Debug dbg,Dwarf_Half value)2371*07dc1947SRichard Lowe dwarf_set_frame_undefined_value(Dwarf_Debug dbg, Dwarf_Half value)
2372*07dc1947SRichard Lowe {
2373*07dc1947SRichard Lowe     Dwarf_Half orig = dbg->de_frame_same_value_number;
2374*07dc1947SRichard Lowe     dbg->de_frame_undefined_value_number = value;
2375*07dc1947SRichard Lowe     return orig;
2376*07dc1947SRichard Lowe }
2377*07dc1947SRichard Lowe 
2378*07dc1947SRichard Lowe 
2379*07dc1947SRichard Lowe 
2380*07dc1947SRichard Lowe 
2381*07dc1947SRichard Lowe 
2382*07dc1947SRichard Lowe static int
dwarf_initialize_fde_table(Dwarf_Debug dbg,struct Dwarf_Frame_s * fde_table,unsigned table_real_data_size,Dwarf_Error * error)2383*07dc1947SRichard Lowe dwarf_initialize_fde_table(Dwarf_Debug dbg,
2384*07dc1947SRichard Lowe     struct Dwarf_Frame_s *fde_table,
2385*07dc1947SRichard Lowe     unsigned table_real_data_size,
2386*07dc1947SRichard Lowe     Dwarf_Error * error)
2387*07dc1947SRichard Lowe {
2388*07dc1947SRichard Lowe     unsigned entry_size = sizeof(struct Dwarf_Frame_s);
2389*07dc1947SRichard Lowe 
2390*07dc1947SRichard Lowe     fde_table->fr_loc = 0;
2391*07dc1947SRichard Lowe     fde_table->fr_reg_count = table_real_data_size;
2392*07dc1947SRichard Lowe     fde_table->fr_next = 0;
2393*07dc1947SRichard Lowe 
2394*07dc1947SRichard Lowe     fde_table->fr_reg = (struct Dwarf_Reg_Rule_s *)
2395*07dc1947SRichard Lowe         calloc(entry_size, table_real_data_size);
2396*07dc1947SRichard Lowe     if (fde_table->fr_reg == 0) {
2397*07dc1947SRichard Lowe         _dwarf_error(dbg, error, DW_DLE_DF_ALLOC_FAIL);
2398*07dc1947SRichard Lowe         return (DW_DLV_ERROR);
2399*07dc1947SRichard Lowe     }
2400*07dc1947SRichard Lowe     return DW_DLV_OK;
2401*07dc1947SRichard Lowe 
2402*07dc1947SRichard Lowe }
2403*07dc1947SRichard Lowe static void
dwarf_free_fde_table(struct Dwarf_Frame_s * fde_table)2404*07dc1947SRichard Lowe dwarf_free_fde_table(struct Dwarf_Frame_s *fde_table)
2405*07dc1947SRichard Lowe {
2406*07dc1947SRichard Lowe     free(fde_table->fr_reg);
2407*07dc1947SRichard Lowe     fde_table->fr_reg_count = 0;
2408*07dc1947SRichard Lowe     fde_table->fr_reg = 0;
2409*07dc1947SRichard Lowe }
2410*07dc1947SRichard Lowe 
2411*07dc1947SRichard Lowe 
2412*07dc1947SRichard Lowe /* Return DW_DLV_OK if we succeed. else return DW_DLV_ERROR.
2413*07dc1947SRichard Lowe */
2414*07dc1947SRichard Lowe int
_dwarf_frame_constructor(Dwarf_Debug dbg,void * frame)2415*07dc1947SRichard Lowe _dwarf_frame_constructor(Dwarf_Debug dbg, void *frame)
2416*07dc1947SRichard Lowe {
2417*07dc1947SRichard Lowe     struct Dwarf_Frame_s *fp = frame;
2418*07dc1947SRichard Lowe 
2419*07dc1947SRichard Lowe     if (!dbg) {
2420*07dc1947SRichard Lowe         return DW_DLV_ERROR;
2421*07dc1947SRichard Lowe     }
2422*07dc1947SRichard Lowe 
2423*07dc1947SRichard Lowe     fp->fr_reg = calloc(dbg->de_frame_reg_rules_entry_count,
2424*07dc1947SRichard Lowe                         sizeof(struct Dwarf_Reg_Rule_s));
2425*07dc1947SRichard Lowe     if (!fp->fr_reg) {
2426*07dc1947SRichard Lowe         return DW_DLV_ERROR;
2427*07dc1947SRichard Lowe     }
2428*07dc1947SRichard Lowe     fp->fr_reg_count = dbg->de_frame_reg_rules_entry_count;
2429*07dc1947SRichard Lowe     return DW_DLV_OK;
2430*07dc1947SRichard Lowe }
2431*07dc1947SRichard Lowe 
2432*07dc1947SRichard Lowe void
_dwarf_frame_destructor(void * frame)2433*07dc1947SRichard Lowe _dwarf_frame_destructor(void *frame)
2434*07dc1947SRichard Lowe {
2435*07dc1947SRichard Lowe     struct Dwarf_Frame_s *fp = frame;
2436*07dc1947SRichard Lowe 
2437*07dc1947SRichard Lowe     if (fp->fr_reg) {
2438*07dc1947SRichard Lowe         free(fp->fr_reg);
2439*07dc1947SRichard Lowe     }
2440*07dc1947SRichard Lowe     fp->fr_reg = 0;
2441*07dc1947SRichard Lowe     fp->fr_reg_count = 0;
2442*07dc1947SRichard Lowe }
2443