1*2de3b87aSKai Wang /*- 2*2de3b87aSKai Wang * Copyright (c) 2009,2011 Kai Wang 3*2de3b87aSKai Wang * All rights reserved. 4*2de3b87aSKai Wang * 5*2de3b87aSKai Wang * Redistribution and use in source and binary forms, with or without 6*2de3b87aSKai Wang * modification, are permitted provided that the following conditions 7*2de3b87aSKai Wang * are met: 8*2de3b87aSKai Wang * 1. Redistributions of source code must retain the above copyright 9*2de3b87aSKai Wang * notice, this list of conditions and the following disclaimer. 10*2de3b87aSKai Wang * 2. Redistributions in binary form must reproduce the above copyright 11*2de3b87aSKai Wang * notice, this list of conditions and the following disclaimer in the 12*2de3b87aSKai Wang * documentation and/or other materials provided with the distribution. 13*2de3b87aSKai Wang * 14*2de3b87aSKai Wang * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 15*2de3b87aSKai Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 16*2de3b87aSKai Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 17*2de3b87aSKai Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 18*2de3b87aSKai Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 19*2de3b87aSKai Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 20*2de3b87aSKai Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 21*2de3b87aSKai Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 22*2de3b87aSKai Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 23*2de3b87aSKai Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 24*2de3b87aSKai Wang * SUCH DAMAGE. 25*2de3b87aSKai Wang */ 26*2de3b87aSKai Wang 27*2de3b87aSKai Wang #include "_libdwarf.h" 28*2de3b87aSKai Wang 29*2de3b87aSKai Wang ELFTC_VCSID("$Id: dwarf_frame.c 2073 2011-10-27 03:30:47Z jkoshy $"); 30*2de3b87aSKai Wang 31*2de3b87aSKai Wang int 32*2de3b87aSKai Wang dwarf_get_fde_list(Dwarf_Debug dbg, Dwarf_Cie **cie_list, 33*2de3b87aSKai Wang Dwarf_Signed *cie_count, Dwarf_Fde **fde_list, Dwarf_Signed *fde_count, 34*2de3b87aSKai Wang Dwarf_Error *error) 35*2de3b87aSKai Wang { 36*2de3b87aSKai Wang 37*2de3b87aSKai Wang if (dbg == NULL || cie_list == NULL || cie_count == NULL || 38*2de3b87aSKai Wang fde_list == NULL || fde_count == NULL) { 39*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 40*2de3b87aSKai Wang return (DW_DLV_ERROR); 41*2de3b87aSKai Wang } 42*2de3b87aSKai Wang 43*2de3b87aSKai Wang if (dbg->dbg_internal_reg_table == NULL) { 44*2de3b87aSKai Wang if (_dwarf_frame_interal_table_init(dbg, error) != DW_DLE_NONE) 45*2de3b87aSKai Wang return (DW_DLV_ERROR); 46*2de3b87aSKai Wang } 47*2de3b87aSKai Wang 48*2de3b87aSKai Wang if (dbg->dbg_frame == NULL) { 49*2de3b87aSKai Wang if (_dwarf_frame_section_load(dbg, error) != DW_DLE_NONE) 50*2de3b87aSKai Wang return (DW_DLV_ERROR); 51*2de3b87aSKai Wang if (dbg->dbg_frame == NULL) { 52*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 53*2de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 54*2de3b87aSKai Wang } 55*2de3b87aSKai Wang } 56*2de3b87aSKai Wang 57*2de3b87aSKai Wang if (dbg->dbg_frame->fs_ciearray == NULL || 58*2de3b87aSKai Wang dbg->dbg_frame->fs_fdearray == NULL) { 59*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 60*2de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 61*2de3b87aSKai Wang } 62*2de3b87aSKai Wang 63*2de3b87aSKai Wang *cie_list = dbg->dbg_frame->fs_ciearray; 64*2de3b87aSKai Wang *cie_count = dbg->dbg_frame->fs_cielen; 65*2de3b87aSKai Wang *fde_list = dbg->dbg_frame->fs_fdearray; 66*2de3b87aSKai Wang *fde_count = dbg->dbg_frame->fs_fdelen; 67*2de3b87aSKai Wang 68*2de3b87aSKai Wang return (DW_DLV_OK); 69*2de3b87aSKai Wang } 70*2de3b87aSKai Wang 71*2de3b87aSKai Wang int 72*2de3b87aSKai Wang dwarf_get_fde_list_eh(Dwarf_Debug dbg, Dwarf_Cie **cie_list, 73*2de3b87aSKai Wang Dwarf_Signed *cie_count, Dwarf_Fde **fde_list, Dwarf_Signed *fde_count, 74*2de3b87aSKai Wang Dwarf_Error *error) 75*2de3b87aSKai Wang { 76*2de3b87aSKai Wang 77*2de3b87aSKai Wang if (dbg == NULL || cie_list == NULL || cie_count == NULL || 78*2de3b87aSKai Wang fde_list == NULL || fde_count == NULL) { 79*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 80*2de3b87aSKai Wang return (DW_DLV_ERROR); 81*2de3b87aSKai Wang } 82*2de3b87aSKai Wang 83*2de3b87aSKai Wang if (dbg->dbg_internal_reg_table == NULL) { 84*2de3b87aSKai Wang if (_dwarf_frame_interal_table_init(dbg, error) != DW_DLE_NONE) 85*2de3b87aSKai Wang return (DW_DLV_ERROR); 86*2de3b87aSKai Wang } 87*2de3b87aSKai Wang 88*2de3b87aSKai Wang if (dbg->dbg_eh_frame == NULL) { 89*2de3b87aSKai Wang if (_dwarf_frame_section_load_eh(dbg, error) != DW_DLE_NONE) 90*2de3b87aSKai Wang return (DW_DLV_ERROR); 91*2de3b87aSKai Wang if (dbg->dbg_eh_frame == NULL) { 92*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 93*2de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 94*2de3b87aSKai Wang } 95*2de3b87aSKai Wang } 96*2de3b87aSKai Wang 97*2de3b87aSKai Wang if (dbg->dbg_eh_frame->fs_ciearray == NULL || 98*2de3b87aSKai Wang dbg->dbg_eh_frame->fs_fdearray == NULL) { 99*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 100*2de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 101*2de3b87aSKai Wang } 102*2de3b87aSKai Wang 103*2de3b87aSKai Wang *cie_list = dbg->dbg_eh_frame->fs_ciearray; 104*2de3b87aSKai Wang *cie_count = dbg->dbg_eh_frame->fs_cielen; 105*2de3b87aSKai Wang *fde_list = dbg->dbg_eh_frame->fs_fdearray; 106*2de3b87aSKai Wang *fde_count = dbg->dbg_eh_frame->fs_fdelen; 107*2de3b87aSKai Wang 108*2de3b87aSKai Wang return (DW_DLV_OK); 109*2de3b87aSKai Wang } 110*2de3b87aSKai Wang 111*2de3b87aSKai Wang int 112*2de3b87aSKai Wang dwarf_get_fde_n(Dwarf_Fde *fdelist, Dwarf_Unsigned fde_index, 113*2de3b87aSKai Wang Dwarf_Fde *ret_fde, Dwarf_Error *error) 114*2de3b87aSKai Wang { 115*2de3b87aSKai Wang Dwarf_FrameSec fs; 116*2de3b87aSKai Wang Dwarf_Debug dbg; 117*2de3b87aSKai Wang 118*2de3b87aSKai Wang dbg = fdelist != NULL ? (*fdelist)->fde_dbg : NULL; 119*2de3b87aSKai Wang 120*2de3b87aSKai Wang if (fdelist == NULL || ret_fde == NULL) { 121*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 122*2de3b87aSKai Wang return (DW_DLV_ERROR); 123*2de3b87aSKai Wang } 124*2de3b87aSKai Wang 125*2de3b87aSKai Wang fs = fdelist[0]->fde_fs; 126*2de3b87aSKai Wang assert(fs != NULL); 127*2de3b87aSKai Wang 128*2de3b87aSKai Wang if (fde_index >= fs->fs_fdelen) { 129*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 130*2de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 131*2de3b87aSKai Wang } 132*2de3b87aSKai Wang 133*2de3b87aSKai Wang *ret_fde = fdelist[fde_index]; 134*2de3b87aSKai Wang 135*2de3b87aSKai Wang return (DW_DLV_OK); 136*2de3b87aSKai Wang } 137*2de3b87aSKai Wang 138*2de3b87aSKai Wang int 139*2de3b87aSKai Wang dwarf_get_fde_at_pc(Dwarf_Fde *fdelist, Dwarf_Addr pc, Dwarf_Fde *ret_fde, 140*2de3b87aSKai Wang Dwarf_Addr *lopc, Dwarf_Addr *hipc, Dwarf_Error *error) 141*2de3b87aSKai Wang { 142*2de3b87aSKai Wang Dwarf_FrameSec fs; 143*2de3b87aSKai Wang Dwarf_Debug dbg; 144*2de3b87aSKai Wang Dwarf_Fde fde; 145*2de3b87aSKai Wang int i; 146*2de3b87aSKai Wang 147*2de3b87aSKai Wang dbg = fdelist != NULL ? (*fdelist)->fde_dbg : NULL; 148*2de3b87aSKai Wang 149*2de3b87aSKai Wang if (fdelist == NULL || ret_fde == NULL || lopc == NULL || 150*2de3b87aSKai Wang hipc == NULL) { 151*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 152*2de3b87aSKai Wang return (DW_DLV_ERROR); 153*2de3b87aSKai Wang } 154*2de3b87aSKai Wang 155*2de3b87aSKai Wang fs = fdelist[0]->fde_fs; 156*2de3b87aSKai Wang assert(fs != NULL); 157*2de3b87aSKai Wang 158*2de3b87aSKai Wang for (i = 0; (Dwarf_Unsigned)i < fs->fs_fdelen; i++) { 159*2de3b87aSKai Wang fde = fdelist[i]; 160*2de3b87aSKai Wang if (pc >= fde->fde_initloc && pc < fde->fde_initloc + 161*2de3b87aSKai Wang fde->fde_adrange) { 162*2de3b87aSKai Wang *ret_fde = fde; 163*2de3b87aSKai Wang *lopc = fde->fde_initloc; 164*2de3b87aSKai Wang *hipc = fde->fde_initloc + fde->fde_adrange - 1; 165*2de3b87aSKai Wang return (DW_DLV_OK); 166*2de3b87aSKai Wang } 167*2de3b87aSKai Wang } 168*2de3b87aSKai Wang 169*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_NO_ENTRY); 170*2de3b87aSKai Wang return (DW_DLV_NO_ENTRY); 171*2de3b87aSKai Wang } 172*2de3b87aSKai Wang 173*2de3b87aSKai Wang int 174*2de3b87aSKai Wang dwarf_get_cie_of_fde(Dwarf_Fde fde, Dwarf_Cie *ret_cie, Dwarf_Error *error) 175*2de3b87aSKai Wang { 176*2de3b87aSKai Wang Dwarf_Debug dbg; 177*2de3b87aSKai Wang 178*2de3b87aSKai Wang dbg = fde != NULL ? fde->fde_dbg : NULL; 179*2de3b87aSKai Wang 180*2de3b87aSKai Wang if (fde == NULL || ret_cie == NULL) { 181*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 182*2de3b87aSKai Wang return (DW_DLV_ERROR); 183*2de3b87aSKai Wang } 184*2de3b87aSKai Wang 185*2de3b87aSKai Wang *ret_cie = fde->fde_cie; 186*2de3b87aSKai Wang 187*2de3b87aSKai Wang return (DW_DLV_OK); 188*2de3b87aSKai Wang } 189*2de3b87aSKai Wang 190*2de3b87aSKai Wang int 191*2de3b87aSKai Wang dwarf_get_fde_range(Dwarf_Fde fde, Dwarf_Addr *low_pc, Dwarf_Unsigned *func_len, 192*2de3b87aSKai Wang Dwarf_Ptr *fde_bytes, Dwarf_Unsigned *fde_byte_len, Dwarf_Off *cie_offset, 193*2de3b87aSKai Wang Dwarf_Signed *cie_index, Dwarf_Off *fde_offset, Dwarf_Error *error) 194*2de3b87aSKai Wang { 195*2de3b87aSKai Wang Dwarf_Debug dbg; 196*2de3b87aSKai Wang 197*2de3b87aSKai Wang dbg = fde != NULL ? fde->fde_dbg : NULL; 198*2de3b87aSKai Wang 199*2de3b87aSKai Wang if (fde == NULL || low_pc == NULL || func_len == NULL || 200*2de3b87aSKai Wang fde_bytes == NULL || fde_byte_len == NULL || cie_offset == NULL || 201*2de3b87aSKai Wang cie_index == NULL || fde_offset == NULL) { 202*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 203*2de3b87aSKai Wang return (DW_DLV_ERROR); 204*2de3b87aSKai Wang } 205*2de3b87aSKai Wang 206*2de3b87aSKai Wang *low_pc = fde->fde_initloc; 207*2de3b87aSKai Wang *func_len = fde->fde_adrange; 208*2de3b87aSKai Wang *fde_bytes = fde->fde_addr; 209*2de3b87aSKai Wang *fde_byte_len = fde->fde_length; 210*2de3b87aSKai Wang *cie_offset = fde->fde_cieoff; 211*2de3b87aSKai Wang *cie_index = fde->fde_cie->cie_index; 212*2de3b87aSKai Wang *fde_offset = fde->fde_offset; 213*2de3b87aSKai Wang 214*2de3b87aSKai Wang return (DW_DLV_OK); 215*2de3b87aSKai Wang } 216*2de3b87aSKai Wang 217*2de3b87aSKai Wang int 218*2de3b87aSKai Wang dwarf_get_cie_info(Dwarf_Cie cie, Dwarf_Unsigned *bytes_in_cie, 219*2de3b87aSKai Wang Dwarf_Small *version, char **augmenter, Dwarf_Unsigned *caf, 220*2de3b87aSKai Wang Dwarf_Unsigned *daf, Dwarf_Half *ra, Dwarf_Ptr *initinst, 221*2de3b87aSKai Wang Dwarf_Unsigned *inst_len, Dwarf_Error *error) 222*2de3b87aSKai Wang { 223*2de3b87aSKai Wang 224*2de3b87aSKai Wang if (cie == NULL || bytes_in_cie == NULL || version == NULL || 225*2de3b87aSKai Wang augmenter == NULL || caf == NULL || daf == NULL || ra == NULL || 226*2de3b87aSKai Wang initinst == NULL || inst_len == NULL) { 227*2de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 228*2de3b87aSKai Wang return (DW_DLV_ERROR); 229*2de3b87aSKai Wang } 230*2de3b87aSKai Wang 231*2de3b87aSKai Wang *bytes_in_cie = cie->cie_length; 232*2de3b87aSKai Wang *version = cie->cie_version; 233*2de3b87aSKai Wang *augmenter = (char *) cie->cie_augment; 234*2de3b87aSKai Wang *caf = cie->cie_caf; 235*2de3b87aSKai Wang *daf = cie->cie_daf; 236*2de3b87aSKai Wang *ra = cie->cie_ra; 237*2de3b87aSKai Wang *initinst = cie->cie_initinst; 238*2de3b87aSKai Wang *inst_len = cie->cie_instlen; 239*2de3b87aSKai Wang 240*2de3b87aSKai Wang return (DW_DLV_OK); 241*2de3b87aSKai Wang } 242*2de3b87aSKai Wang 243*2de3b87aSKai Wang int 244*2de3b87aSKai Wang dwarf_get_cie_index(Dwarf_Cie cie, Dwarf_Signed *cie_index, Dwarf_Error *error) 245*2de3b87aSKai Wang { 246*2de3b87aSKai Wang 247*2de3b87aSKai Wang if (cie == NULL || cie_index == NULL) { 248*2de3b87aSKai Wang DWARF_SET_ERROR(NULL, error, DW_DLE_ARGUMENT); 249*2de3b87aSKai Wang return (DW_DLV_ERROR); 250*2de3b87aSKai Wang } 251*2de3b87aSKai Wang 252*2de3b87aSKai Wang *cie_index = cie->cie_index; 253*2de3b87aSKai Wang 254*2de3b87aSKai Wang return (DW_DLV_OK); 255*2de3b87aSKai Wang } 256*2de3b87aSKai Wang 257*2de3b87aSKai Wang int 258*2de3b87aSKai Wang dwarf_get_fde_instr_bytes(Dwarf_Fde fde, Dwarf_Ptr *ret_inst, 259*2de3b87aSKai Wang Dwarf_Unsigned *ret_len, Dwarf_Error *error) 260*2de3b87aSKai Wang { 261*2de3b87aSKai Wang Dwarf_Debug dbg; 262*2de3b87aSKai Wang 263*2de3b87aSKai Wang dbg = fde != NULL ? fde->fde_dbg : NULL; 264*2de3b87aSKai Wang 265*2de3b87aSKai Wang if (fde == NULL || ret_inst == NULL || ret_len == NULL) { 266*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 267*2de3b87aSKai Wang return (DW_DLV_ERROR); 268*2de3b87aSKai Wang } 269*2de3b87aSKai Wang 270*2de3b87aSKai Wang *ret_inst = fde->fde_inst; 271*2de3b87aSKai Wang *ret_len = fde->fde_instlen; 272*2de3b87aSKai Wang 273*2de3b87aSKai Wang return (DW_DLV_OK); 274*2de3b87aSKai Wang } 275*2de3b87aSKai Wang 276*2de3b87aSKai Wang #define RL rt->rt3_rules[table_column] 277*2de3b87aSKai Wang #define CFA rt->rt3_cfa_rule 278*2de3b87aSKai Wang 279*2de3b87aSKai Wang int 280*2de3b87aSKai Wang dwarf_get_fde_info_for_reg(Dwarf_Fde fde, Dwarf_Half table_column, 281*2de3b87aSKai Wang Dwarf_Addr pc_requested, Dwarf_Signed *offset_relevant, 282*2de3b87aSKai Wang Dwarf_Signed *register_num, Dwarf_Signed *offset, Dwarf_Addr *row_pc, 283*2de3b87aSKai Wang Dwarf_Error *error) 284*2de3b87aSKai Wang { 285*2de3b87aSKai Wang Dwarf_Regtable3 *rt; 286*2de3b87aSKai Wang Dwarf_Debug dbg; 287*2de3b87aSKai Wang Dwarf_Addr pc; 288*2de3b87aSKai Wang int ret; 289*2de3b87aSKai Wang 290*2de3b87aSKai Wang dbg = fde != NULL ? fde->fde_dbg : NULL; 291*2de3b87aSKai Wang 292*2de3b87aSKai Wang if (fde == NULL || offset_relevant == NULL || register_num == NULL || 293*2de3b87aSKai Wang offset == NULL || row_pc == NULL) { 294*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 295*2de3b87aSKai Wang return (DW_DLV_ERROR); 296*2de3b87aSKai Wang } 297*2de3b87aSKai Wang 298*2de3b87aSKai Wang if (pc_requested < fde->fde_initloc || 299*2de3b87aSKai Wang pc_requested >= fde->fde_initloc + fde->fde_adrange) { 300*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); 301*2de3b87aSKai Wang return (DW_DLV_ERROR); 302*2de3b87aSKai Wang } 303*2de3b87aSKai Wang 304*2de3b87aSKai Wang ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc, 305*2de3b87aSKai Wang error); 306*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 307*2de3b87aSKai Wang return (DW_DLV_ERROR); 308*2de3b87aSKai Wang 309*2de3b87aSKai Wang if (table_column == dbg->dbg_frame_cfa_value) { 310*2de3b87aSKai Wang /* Application ask for CFA. */ 311*2de3b87aSKai Wang *offset_relevant = CFA.dw_offset_relevant; 312*2de3b87aSKai Wang *register_num = CFA.dw_regnum; 313*2de3b87aSKai Wang *offset = CFA.dw_offset_or_block_len; 314*2de3b87aSKai Wang } else { 315*2de3b87aSKai Wang /* Application ask for normal registers. */ 316*2de3b87aSKai Wang if (table_column >= dbg->dbg_frame_rule_table_size || 317*2de3b87aSKai Wang table_column >= DW_REG_TABLE_SIZE) { 318*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD); 319*2de3b87aSKai Wang return (DW_DLV_ERROR); 320*2de3b87aSKai Wang } 321*2de3b87aSKai Wang 322*2de3b87aSKai Wang *offset_relevant = RL.dw_offset_relevant; 323*2de3b87aSKai Wang *register_num = RL.dw_regnum; 324*2de3b87aSKai Wang *offset = RL.dw_offset_or_block_len; 325*2de3b87aSKai Wang } 326*2de3b87aSKai Wang 327*2de3b87aSKai Wang *row_pc = pc; 328*2de3b87aSKai Wang 329*2de3b87aSKai Wang return (DW_DLV_OK); 330*2de3b87aSKai Wang } 331*2de3b87aSKai Wang 332*2de3b87aSKai Wang int 333*2de3b87aSKai Wang dwarf_get_fde_info_for_all_regs(Dwarf_Fde fde, Dwarf_Addr pc_requested, 334*2de3b87aSKai Wang Dwarf_Regtable *reg_table, Dwarf_Addr *row_pc, Dwarf_Error *error) 335*2de3b87aSKai Wang { 336*2de3b87aSKai Wang Dwarf_Debug dbg; 337*2de3b87aSKai Wang Dwarf_Regtable3 *rt; 338*2de3b87aSKai Wang Dwarf_Addr pc; 339*2de3b87aSKai Wang Dwarf_Half cfa; 340*2de3b87aSKai Wang int i, ret; 341*2de3b87aSKai Wang 342*2de3b87aSKai Wang dbg = fde != NULL ? fde->fde_dbg : NULL; 343*2de3b87aSKai Wang 344*2de3b87aSKai Wang if (fde == NULL || reg_table == NULL || row_pc == NULL) { 345*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 346*2de3b87aSKai Wang return (DW_DLV_ERROR); 347*2de3b87aSKai Wang } 348*2de3b87aSKai Wang 349*2de3b87aSKai Wang assert(dbg != NULL); 350*2de3b87aSKai Wang 351*2de3b87aSKai Wang if (pc_requested < fde->fde_initloc || 352*2de3b87aSKai Wang pc_requested >= fde->fde_initloc + fde->fde_adrange) { 353*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); 354*2de3b87aSKai Wang return (DW_DLV_ERROR); 355*2de3b87aSKai Wang } 356*2de3b87aSKai Wang 357*2de3b87aSKai Wang ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc, 358*2de3b87aSKai Wang error); 359*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 360*2de3b87aSKai Wang return (DW_DLV_ERROR); 361*2de3b87aSKai Wang 362*2de3b87aSKai Wang /* 363*2de3b87aSKai Wang * Copy the CFA rule to the column intended for holding the CFA, 364*2de3b87aSKai Wang * if it's within the range of regtable. 365*2de3b87aSKai Wang */ 366*2de3b87aSKai Wang cfa = dbg->dbg_frame_cfa_value; 367*2de3b87aSKai Wang if (cfa < DW_REG_TABLE_SIZE) { 368*2de3b87aSKai Wang reg_table->rules[cfa].dw_offset_relevant = 369*2de3b87aSKai Wang CFA.dw_offset_relevant; 370*2de3b87aSKai Wang reg_table->rules[cfa].dw_regnum = CFA.dw_regnum; 371*2de3b87aSKai Wang reg_table->rules[cfa].dw_offset = CFA.dw_offset_or_block_len; 372*2de3b87aSKai Wang } 373*2de3b87aSKai Wang 374*2de3b87aSKai Wang /* 375*2de3b87aSKai Wang * Copy other columns. 376*2de3b87aSKai Wang */ 377*2de3b87aSKai Wang for (i = 0; i < DW_REG_TABLE_SIZE && i < dbg->dbg_frame_rule_table_size; 378*2de3b87aSKai Wang i++) { 379*2de3b87aSKai Wang 380*2de3b87aSKai Wang /* Do not overwrite CFA column */ 381*2de3b87aSKai Wang if (i == cfa) 382*2de3b87aSKai Wang continue; 383*2de3b87aSKai Wang 384*2de3b87aSKai Wang reg_table->rules[i].dw_offset_relevant = 385*2de3b87aSKai Wang rt->rt3_rules[i].dw_offset_relevant; 386*2de3b87aSKai Wang reg_table->rules[i].dw_regnum = rt->rt3_rules[i].dw_regnum; 387*2de3b87aSKai Wang reg_table->rules[i].dw_offset = 388*2de3b87aSKai Wang rt->rt3_rules[i].dw_offset_or_block_len; 389*2de3b87aSKai Wang } 390*2de3b87aSKai Wang 391*2de3b87aSKai Wang *row_pc = pc; 392*2de3b87aSKai Wang 393*2de3b87aSKai Wang return (DW_DLV_OK); 394*2de3b87aSKai Wang } 395*2de3b87aSKai Wang 396*2de3b87aSKai Wang int 397*2de3b87aSKai Wang dwarf_get_fde_info_for_reg3(Dwarf_Fde fde, Dwarf_Half table_column, 398*2de3b87aSKai Wang Dwarf_Addr pc_requested, Dwarf_Small *value_type, 399*2de3b87aSKai Wang Dwarf_Signed *offset_relevant, Dwarf_Signed *register_num, 400*2de3b87aSKai Wang Dwarf_Signed *offset_or_block_len, Dwarf_Ptr *block_ptr, 401*2de3b87aSKai Wang Dwarf_Addr *row_pc, Dwarf_Error *error) 402*2de3b87aSKai Wang { 403*2de3b87aSKai Wang Dwarf_Regtable3 *rt; 404*2de3b87aSKai Wang Dwarf_Debug dbg; 405*2de3b87aSKai Wang Dwarf_Addr pc; 406*2de3b87aSKai Wang int ret; 407*2de3b87aSKai Wang 408*2de3b87aSKai Wang dbg = fde != NULL ? fde->fde_dbg : NULL; 409*2de3b87aSKai Wang 410*2de3b87aSKai Wang if (fde == NULL || value_type == NULL || offset_relevant == NULL || 411*2de3b87aSKai Wang register_num == NULL || offset_or_block_len == NULL || 412*2de3b87aSKai Wang block_ptr == NULL || row_pc == NULL) { 413*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 414*2de3b87aSKai Wang return (DW_DLV_ERROR); 415*2de3b87aSKai Wang } 416*2de3b87aSKai Wang 417*2de3b87aSKai Wang if (pc_requested < fde->fde_initloc || 418*2de3b87aSKai Wang pc_requested >= fde->fde_initloc + fde->fde_adrange) { 419*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); 420*2de3b87aSKai Wang return (DW_DLV_ERROR); 421*2de3b87aSKai Wang } 422*2de3b87aSKai Wang 423*2de3b87aSKai Wang ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc, 424*2de3b87aSKai Wang error); 425*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 426*2de3b87aSKai Wang return (DW_DLV_ERROR); 427*2de3b87aSKai Wang 428*2de3b87aSKai Wang if (table_column >= dbg->dbg_frame_rule_table_size) { 429*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_FRAME_TABLE_COL_BAD); 430*2de3b87aSKai Wang return (DW_DLV_ERROR); 431*2de3b87aSKai Wang } 432*2de3b87aSKai Wang 433*2de3b87aSKai Wang *value_type = RL.dw_value_type; 434*2de3b87aSKai Wang *offset_relevant = RL.dw_offset_relevant; 435*2de3b87aSKai Wang *register_num = RL.dw_regnum; 436*2de3b87aSKai Wang *offset_or_block_len = RL.dw_offset_or_block_len; 437*2de3b87aSKai Wang *block_ptr = RL.dw_block_ptr; 438*2de3b87aSKai Wang *row_pc = pc; 439*2de3b87aSKai Wang 440*2de3b87aSKai Wang return (DW_DLV_OK); 441*2de3b87aSKai Wang } 442*2de3b87aSKai Wang 443*2de3b87aSKai Wang int 444*2de3b87aSKai Wang dwarf_get_fde_info_for_cfa_reg3(Dwarf_Fde fde, Dwarf_Addr pc_requested, 445*2de3b87aSKai Wang Dwarf_Small *value_type, Dwarf_Signed *offset_relevant, 446*2de3b87aSKai Wang Dwarf_Signed *register_num, Dwarf_Signed *offset_or_block_len, 447*2de3b87aSKai Wang Dwarf_Ptr *block_ptr, Dwarf_Addr *row_pc, Dwarf_Error *error) 448*2de3b87aSKai Wang { 449*2de3b87aSKai Wang Dwarf_Regtable3 *rt; 450*2de3b87aSKai Wang Dwarf_Debug dbg; 451*2de3b87aSKai Wang Dwarf_Addr pc; 452*2de3b87aSKai Wang int ret; 453*2de3b87aSKai Wang 454*2de3b87aSKai Wang dbg = fde != NULL ? fde->fde_dbg : NULL; 455*2de3b87aSKai Wang 456*2de3b87aSKai Wang if (fde == NULL || value_type == NULL || offset_relevant == NULL || 457*2de3b87aSKai Wang register_num == NULL || offset_or_block_len == NULL || 458*2de3b87aSKai Wang block_ptr == NULL || row_pc == NULL) { 459*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 460*2de3b87aSKai Wang return (DW_DLV_ERROR); 461*2de3b87aSKai Wang } 462*2de3b87aSKai Wang 463*2de3b87aSKai Wang if (pc_requested < fde->fde_initloc || 464*2de3b87aSKai Wang pc_requested >= fde->fde_initloc + fde->fde_adrange) { 465*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); 466*2de3b87aSKai Wang return (DW_DLV_ERROR); 467*2de3b87aSKai Wang } 468*2de3b87aSKai Wang 469*2de3b87aSKai Wang ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc, 470*2de3b87aSKai Wang error); 471*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 472*2de3b87aSKai Wang return (DW_DLV_ERROR); 473*2de3b87aSKai Wang 474*2de3b87aSKai Wang *value_type = CFA.dw_value_type; 475*2de3b87aSKai Wang *offset_relevant = CFA.dw_offset_relevant; 476*2de3b87aSKai Wang *register_num = CFA.dw_regnum; 477*2de3b87aSKai Wang *offset_or_block_len = CFA.dw_offset_or_block_len; 478*2de3b87aSKai Wang *block_ptr = CFA.dw_block_ptr; 479*2de3b87aSKai Wang *row_pc = pc; 480*2de3b87aSKai Wang 481*2de3b87aSKai Wang return (DW_DLV_OK); 482*2de3b87aSKai Wang } 483*2de3b87aSKai Wang 484*2de3b87aSKai Wang #undef RL 485*2de3b87aSKai Wang #undef CFA 486*2de3b87aSKai Wang 487*2de3b87aSKai Wang int 488*2de3b87aSKai Wang dwarf_get_fde_info_for_all_regs3(Dwarf_Fde fde, Dwarf_Addr pc_requested, 489*2de3b87aSKai Wang Dwarf_Regtable3 *reg_table, Dwarf_Addr *row_pc, Dwarf_Error *error) 490*2de3b87aSKai Wang { 491*2de3b87aSKai Wang Dwarf_Regtable3 *rt; 492*2de3b87aSKai Wang Dwarf_Debug dbg; 493*2de3b87aSKai Wang Dwarf_Addr pc; 494*2de3b87aSKai Wang int ret; 495*2de3b87aSKai Wang 496*2de3b87aSKai Wang dbg = fde != NULL ? fde->fde_dbg : NULL; 497*2de3b87aSKai Wang 498*2de3b87aSKai Wang if (fde == NULL || reg_table == NULL || reg_table->rt3_rules == NULL || 499*2de3b87aSKai Wang row_pc == NULL) { 500*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 501*2de3b87aSKai Wang return (DW_DLV_ERROR); 502*2de3b87aSKai Wang } 503*2de3b87aSKai Wang 504*2de3b87aSKai Wang assert(dbg != NULL); 505*2de3b87aSKai Wang 506*2de3b87aSKai Wang if (pc_requested < fde->fde_initloc || 507*2de3b87aSKai Wang pc_requested >= fde->fde_initloc + fde->fde_adrange) { 508*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_PC_NOT_IN_FDE_RANGE); 509*2de3b87aSKai Wang return (DW_DLV_ERROR); 510*2de3b87aSKai Wang } 511*2de3b87aSKai Wang 512*2de3b87aSKai Wang ret = _dwarf_frame_get_internal_table(fde, pc_requested, &rt, &pc, 513*2de3b87aSKai Wang error); 514*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 515*2de3b87aSKai Wang return (DW_DLV_ERROR); 516*2de3b87aSKai Wang 517*2de3b87aSKai Wang ret = _dwarf_frame_regtable_copy(dbg, ®_table, rt, error); 518*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 519*2de3b87aSKai Wang return (DW_DLV_ERROR); 520*2de3b87aSKai Wang 521*2de3b87aSKai Wang *row_pc = pc; 522*2de3b87aSKai Wang 523*2de3b87aSKai Wang return (DW_DLV_OK); 524*2de3b87aSKai Wang } 525*2de3b87aSKai Wang 526*2de3b87aSKai Wang int 527*2de3b87aSKai Wang dwarf_expand_frame_instructions(Dwarf_Cie cie, Dwarf_Ptr instruction, 528*2de3b87aSKai Wang Dwarf_Unsigned len, Dwarf_Frame_Op **ret_oplist, Dwarf_Signed *ret_opcnt, 529*2de3b87aSKai Wang Dwarf_Error *error) 530*2de3b87aSKai Wang { 531*2de3b87aSKai Wang Dwarf_Debug dbg; 532*2de3b87aSKai Wang int ret; 533*2de3b87aSKai Wang 534*2de3b87aSKai Wang dbg = cie != NULL ? cie->cie_dbg : NULL; 535*2de3b87aSKai Wang 536*2de3b87aSKai Wang if (cie == NULL || instruction == NULL || len == 0 || 537*2de3b87aSKai Wang ret_oplist == NULL || ret_opcnt == NULL) { 538*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 539*2de3b87aSKai Wang return (DW_DLV_ERROR); 540*2de3b87aSKai Wang } 541*2de3b87aSKai Wang 542*2de3b87aSKai Wang ret = _dwarf_frame_get_fop(dbg, instruction, len, ret_oplist, ret_opcnt, 543*2de3b87aSKai Wang error); 544*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 545*2de3b87aSKai Wang return (DW_DLV_ERROR); 546*2de3b87aSKai Wang 547*2de3b87aSKai Wang return (DW_DLV_OK); 548*2de3b87aSKai Wang } 549*2de3b87aSKai Wang 550*2de3b87aSKai Wang Dwarf_Half 551*2de3b87aSKai Wang dwarf_set_frame_rule_table_size(Dwarf_Debug dbg, Dwarf_Half value) 552*2de3b87aSKai Wang { 553*2de3b87aSKai Wang Dwarf_Half old_value; 554*2de3b87aSKai Wang 555*2de3b87aSKai Wang old_value = dbg->dbg_frame_rule_table_size; 556*2de3b87aSKai Wang dbg->dbg_frame_rule_table_size = value; 557*2de3b87aSKai Wang 558*2de3b87aSKai Wang return (old_value); 559*2de3b87aSKai Wang } 560*2de3b87aSKai Wang 561*2de3b87aSKai Wang Dwarf_Half 562*2de3b87aSKai Wang dwarf_set_frame_rule_initial_value(Dwarf_Debug dbg, Dwarf_Half value) 563*2de3b87aSKai Wang { 564*2de3b87aSKai Wang Dwarf_Half old_value; 565*2de3b87aSKai Wang 566*2de3b87aSKai Wang old_value = dbg->dbg_frame_rule_initial_value; 567*2de3b87aSKai Wang dbg->dbg_frame_rule_initial_value = value; 568*2de3b87aSKai Wang 569*2de3b87aSKai Wang return (old_value); 570*2de3b87aSKai Wang } 571*2de3b87aSKai Wang 572*2de3b87aSKai Wang Dwarf_Half 573*2de3b87aSKai Wang dwarf_set_frame_cfa_value(Dwarf_Debug dbg, Dwarf_Half value) 574*2de3b87aSKai Wang { 575*2de3b87aSKai Wang Dwarf_Half old_value; 576*2de3b87aSKai Wang 577*2de3b87aSKai Wang old_value = dbg->dbg_frame_cfa_value; 578*2de3b87aSKai Wang dbg->dbg_frame_cfa_value = value; 579*2de3b87aSKai Wang 580*2de3b87aSKai Wang return (old_value); 581*2de3b87aSKai Wang } 582*2de3b87aSKai Wang 583*2de3b87aSKai Wang Dwarf_Half 584*2de3b87aSKai Wang dwarf_set_frame_same_value(Dwarf_Debug dbg, Dwarf_Half value) 585*2de3b87aSKai Wang { 586*2de3b87aSKai Wang Dwarf_Half old_value; 587*2de3b87aSKai Wang 588*2de3b87aSKai Wang old_value = dbg->dbg_frame_same_value; 589*2de3b87aSKai Wang dbg->dbg_frame_same_value = value; 590*2de3b87aSKai Wang 591*2de3b87aSKai Wang return (old_value); 592*2de3b87aSKai Wang } 593*2de3b87aSKai Wang 594*2de3b87aSKai Wang Dwarf_Half 595*2de3b87aSKai Wang dwarf_set_frame_undefined_value(Dwarf_Debug dbg, Dwarf_Half value) 596*2de3b87aSKai Wang { 597*2de3b87aSKai Wang Dwarf_Half old_value; 598*2de3b87aSKai Wang 599*2de3b87aSKai Wang old_value = dbg->dbg_frame_undefined_value; 600*2de3b87aSKai Wang dbg->dbg_frame_undefined_value = value; 601*2de3b87aSKai Wang 602*2de3b87aSKai Wang return (old_value); 603*2de3b87aSKai Wang } 604