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 = ®_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 = ®_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 = ®_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