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