1*7fd79137SRobert Mustacchi /* 2*7fd79137SRobert Mustacchi 3*7fd79137SRobert Mustacchi Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. 4*7fd79137SRobert Mustacchi 5*7fd79137SRobert Mustacchi This program is free software; you can redistribute it and/or modify it 6*7fd79137SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License 7*7fd79137SRobert Mustacchi as published by the Free Software Foundation. 8*7fd79137SRobert Mustacchi 9*7fd79137SRobert Mustacchi This program is distributed in the hope that it would be useful, but 10*7fd79137SRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of 11*7fd79137SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 12*7fd79137SRobert Mustacchi 13*7fd79137SRobert Mustacchi Further, this software is distributed without any warranty that it is 14*7fd79137SRobert Mustacchi free of the rightful claim of any third person regarding infringement 15*7fd79137SRobert Mustacchi or the like. Any license provided herein, whether implied or 16*7fd79137SRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if 17*7fd79137SRobert Mustacchi any, provided herein do not apply to combinations of this program with 18*7fd79137SRobert Mustacchi other software, or any other product whatsoever. 19*7fd79137SRobert Mustacchi 20*7fd79137SRobert Mustacchi You should have received a copy of the GNU Lesser General Public 21*7fd79137SRobert Mustacchi License along with this program; if not, write the Free Software 22*7fd79137SRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 23*7fd79137SRobert Mustacchi USA. 24*7fd79137SRobert Mustacchi 25*7fd79137SRobert Mustacchi Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, 26*7fd79137SRobert Mustacchi Mountain View, CA 94043, or: 27*7fd79137SRobert Mustacchi 28*7fd79137SRobert Mustacchi http://www.sgi.com 29*7fd79137SRobert Mustacchi 30*7fd79137SRobert Mustacchi For further information regarding this notice, see: 31*7fd79137SRobert Mustacchi 32*7fd79137SRobert Mustacchi http://oss.sgi.com/projects/GenInfo/NoticeExplan 33*7fd79137SRobert Mustacchi 34*7fd79137SRobert Mustacchi */ 35*7fd79137SRobert Mustacchi 36*7fd79137SRobert Mustacchi 37*7fd79137SRobert Mustacchi 38*7fd79137SRobert Mustacchi #include "config.h" 39*7fd79137SRobert Mustacchi #include "libdwarfdefs.h" 40*7fd79137SRobert Mustacchi #include <stdio.h> 41*7fd79137SRobert Mustacchi #include <string.h> 42*7fd79137SRobert Mustacchi #include <limits.h> 43*7fd79137SRobert Mustacchi #include "pro_incl.h" 44*7fd79137SRobert Mustacchi #include "pro_frame.h" 45*7fd79137SRobert Mustacchi 46*7fd79137SRobert Mustacchi static void _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, 47*7fd79137SRobert Mustacchi Dwarf_P_Frame_Pgm inst); 48*7fd79137SRobert Mustacchi 49*7fd79137SRobert Mustacchi /*------------------------------------------------------------------------- 50*7fd79137SRobert Mustacchi This function adds a cie struct to the debug pointer. Its in the 51*7fd79137SRobert Mustacchi form of a linked list. 52*7fd79137SRobert Mustacchi augmenter: string reps augmentation (implementation defined) 53*7fd79137SRobert Mustacchi code_align: alignment of code 54*7fd79137SRobert Mustacchi data_align: alignment of data 55*7fd79137SRobert Mustacchi init_bytes: byts having initial instructions 56*7fd79137SRobert Mustacchi init_n_bytes: number of bytes of initial instructions 57*7fd79137SRobert Mustacchi --------------------------------------------------------------------------*/ 58*7fd79137SRobert Mustacchi Dwarf_Unsigned 59*7fd79137SRobert Mustacchi dwarf_add_frame_cie(Dwarf_P_Debug dbg, 60*7fd79137SRobert Mustacchi char *augmenter, 61*7fd79137SRobert Mustacchi Dwarf_Small code_align, 62*7fd79137SRobert Mustacchi Dwarf_Small data_align, 63*7fd79137SRobert Mustacchi Dwarf_Small return_reg, 64*7fd79137SRobert Mustacchi Dwarf_Ptr init_bytes, 65*7fd79137SRobert Mustacchi Dwarf_Unsigned init_n_bytes, Dwarf_Error * error) 66*7fd79137SRobert Mustacchi { 67*7fd79137SRobert Mustacchi Dwarf_P_Cie curcie; 68*7fd79137SRobert Mustacchi 69*7fd79137SRobert Mustacchi if (dbg->de_frame_cies == NULL) { 70*7fd79137SRobert Mustacchi dbg->de_frame_cies = (Dwarf_P_Cie) 71*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s)); 72*7fd79137SRobert Mustacchi if (dbg->de_frame_cies == NULL) { 73*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT); 74*7fd79137SRobert Mustacchi } 75*7fd79137SRobert Mustacchi curcie = dbg->de_frame_cies; 76*7fd79137SRobert Mustacchi dbg->de_n_cie = 1; 77*7fd79137SRobert Mustacchi dbg->de_last_cie = curcie; 78*7fd79137SRobert Mustacchi } else { 79*7fd79137SRobert Mustacchi curcie = dbg->de_last_cie; 80*7fd79137SRobert Mustacchi curcie->cie_next = (Dwarf_P_Cie) 81*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Cie_s)); 82*7fd79137SRobert Mustacchi if (curcie->cie_next == NULL) { 83*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_CIE_ALLOC, DW_DLV_NOCOUNT); 84*7fd79137SRobert Mustacchi } 85*7fd79137SRobert Mustacchi curcie = curcie->cie_next; 86*7fd79137SRobert Mustacchi dbg->de_n_cie++; 87*7fd79137SRobert Mustacchi dbg->de_last_cie = curcie; 88*7fd79137SRobert Mustacchi } 89*7fd79137SRobert Mustacchi curcie->cie_version = DW_CIE_VERSION; 90*7fd79137SRobert Mustacchi curcie->cie_aug = augmenter; 91*7fd79137SRobert Mustacchi curcie->cie_code_align = code_align; 92*7fd79137SRobert Mustacchi curcie->cie_data_align = data_align; 93*7fd79137SRobert Mustacchi curcie->cie_ret_reg = return_reg; 94*7fd79137SRobert Mustacchi curcie->cie_inst = (char *) init_bytes; 95*7fd79137SRobert Mustacchi curcie->cie_inst_bytes = (long) init_n_bytes; 96*7fd79137SRobert Mustacchi curcie->cie_next = NULL; 97*7fd79137SRobert Mustacchi return dbg->de_n_cie; 98*7fd79137SRobert Mustacchi } 99*7fd79137SRobert Mustacchi 100*7fd79137SRobert Mustacchi 101*7fd79137SRobert Mustacchi /*------------------------------------------------------------------------- 102*7fd79137SRobert Mustacchi This functions adds a fde struct to the debug pointer. Its in the 103*7fd79137SRobert Mustacchi form of a linked list. 104*7fd79137SRobert Mustacchi die: subprogram/function die corresponding to this fde 105*7fd79137SRobert Mustacchi cie: cie referred to by this fde, obtained from call to 106*7fd79137SRobert Mustacchi add_frame_cie() routine. 107*7fd79137SRobert Mustacchi virt_addr: beginning address 108*7fd79137SRobert Mustacchi code_len: length of code reps by the fde 109*7fd79137SRobert Mustacchi --------------------------------------------------------------------------*/ 110*7fd79137SRobert Mustacchi /*ARGSUSED*/ /* pretend all args used */ 111*7fd79137SRobert Mustacchi Dwarf_Unsigned 112*7fd79137SRobert Mustacchi dwarf_add_frame_fde(Dwarf_P_Debug dbg, 113*7fd79137SRobert Mustacchi Dwarf_P_Fde fde, 114*7fd79137SRobert Mustacchi Dwarf_P_Die die, 115*7fd79137SRobert Mustacchi Dwarf_Unsigned cie, 116*7fd79137SRobert Mustacchi Dwarf_Unsigned virt_addr, 117*7fd79137SRobert Mustacchi Dwarf_Unsigned code_len, 118*7fd79137SRobert Mustacchi Dwarf_Unsigned symidx, Dwarf_Error * error) 119*7fd79137SRobert Mustacchi { 120*7fd79137SRobert Mustacchi return dwarf_add_frame_fde_b(dbg, fde, die, cie, virt_addr, 121*7fd79137SRobert Mustacchi code_len, symidx, 0, 0, error); 122*7fd79137SRobert Mustacchi } 123*7fd79137SRobert Mustacchi 124*7fd79137SRobert Mustacchi /*ARGSUSED10*/ 125*7fd79137SRobert Mustacchi Dwarf_Unsigned 126*7fd79137SRobert Mustacchi dwarf_add_frame_fde_b(Dwarf_P_Debug dbg, 127*7fd79137SRobert Mustacchi Dwarf_P_Fde fde, 128*7fd79137SRobert Mustacchi Dwarf_P_Die die, 129*7fd79137SRobert Mustacchi Dwarf_Unsigned cie, 130*7fd79137SRobert Mustacchi Dwarf_Unsigned virt_addr, 131*7fd79137SRobert Mustacchi Dwarf_Unsigned code_len, 132*7fd79137SRobert Mustacchi Dwarf_Unsigned symidx, 133*7fd79137SRobert Mustacchi Dwarf_Unsigned symidx_of_end, 134*7fd79137SRobert Mustacchi Dwarf_Addr offset_from_end_sym, 135*7fd79137SRobert Mustacchi Dwarf_Error * error) 136*7fd79137SRobert Mustacchi { 137*7fd79137SRobert Mustacchi Dwarf_P_Fde curfde; 138*7fd79137SRobert Mustacchi 139*7fd79137SRobert Mustacchi fde->fde_die = die; 140*7fd79137SRobert Mustacchi fde->fde_cie = (long) cie; 141*7fd79137SRobert Mustacchi fde->fde_initloc = virt_addr; 142*7fd79137SRobert Mustacchi fde->fde_r_symidx = symidx; 143*7fd79137SRobert Mustacchi fde->fde_addr_range = code_len; 144*7fd79137SRobert Mustacchi fde->fde_offset_into_exception_tables = DW_DLX_NO_EH_OFFSET; 145*7fd79137SRobert Mustacchi fde->fde_exception_table_symbol = 0; 146*7fd79137SRobert Mustacchi fde->fde_end_symbol_offset = offset_from_end_sym; 147*7fd79137SRobert Mustacchi fde->fde_end_symbol = symidx_of_end; 148*7fd79137SRobert Mustacchi fde->fde_dbg = dbg; 149*7fd79137SRobert Mustacchi 150*7fd79137SRobert Mustacchi curfde = dbg->de_last_fde; 151*7fd79137SRobert Mustacchi if (curfde == NULL) { 152*7fd79137SRobert Mustacchi dbg->de_frame_fdes = fde; 153*7fd79137SRobert Mustacchi dbg->de_last_fde = fde; 154*7fd79137SRobert Mustacchi dbg->de_n_fde = 1; 155*7fd79137SRobert Mustacchi } else { 156*7fd79137SRobert Mustacchi curfde->fde_next = fde; 157*7fd79137SRobert Mustacchi dbg->de_last_fde = fde; 158*7fd79137SRobert Mustacchi dbg->de_n_fde++; 159*7fd79137SRobert Mustacchi } 160*7fd79137SRobert Mustacchi return dbg->de_n_fde; 161*7fd79137SRobert Mustacchi } 162*7fd79137SRobert Mustacchi 163*7fd79137SRobert Mustacchi /*------------------------------------------------------------------------- 164*7fd79137SRobert Mustacchi This functions adds information to an fde. The fde is 165*7fd79137SRobert Mustacchi linked into the linked list of fde's maintained in the Dwarf_P_Debug 166*7fd79137SRobert Mustacchi structure. 167*7fd79137SRobert Mustacchi dbg: The debug descriptor. 168*7fd79137SRobert Mustacchi fde: The fde to be added. 169*7fd79137SRobert Mustacchi die: subprogram/function die corresponding to this fde 170*7fd79137SRobert Mustacchi cie: cie referred to by this fde, obtained from call to 171*7fd79137SRobert Mustacchi add_frame_cie() routine. 172*7fd79137SRobert Mustacchi virt_addr: beginning address 173*7fd79137SRobert Mustacchi code_len: length of code reps by the fde 174*7fd79137SRobert Mustacchi symidx: The symbol id of the symbol wrt to which relocation needs 175*7fd79137SRobert Mustacchi to be performed for 'virt_addr'. 176*7fd79137SRobert Mustacchi offset_into_exception_tables: The start of exception tables for 177*7fd79137SRobert Mustacchi this function (indicated as an offset into the exception 178*7fd79137SRobert Mustacchi tables). A value of -1 indicates that there is no exception 179*7fd79137SRobert Mustacchi table entries associated with this function. 180*7fd79137SRobert Mustacchi exception_table_symbol: The symbol id of the section for exception 181*7fd79137SRobert Mustacchi tables wrt to which the offset_into_exception_tables will 182*7fd79137SRobert Mustacchi be relocated. 183*7fd79137SRobert Mustacchi --------------------------------------------------------------------------*/ 184*7fd79137SRobert Mustacchi Dwarf_Unsigned 185*7fd79137SRobert Mustacchi dwarf_add_frame_info(Dwarf_P_Debug dbg, 186*7fd79137SRobert Mustacchi Dwarf_P_Fde fde, 187*7fd79137SRobert Mustacchi Dwarf_P_Die die, 188*7fd79137SRobert Mustacchi Dwarf_Unsigned cie, 189*7fd79137SRobert Mustacchi Dwarf_Unsigned virt_addr, 190*7fd79137SRobert Mustacchi Dwarf_Unsigned code_len, 191*7fd79137SRobert Mustacchi Dwarf_Unsigned symidx, 192*7fd79137SRobert Mustacchi Dwarf_Signed offset_into_exception_tables, 193*7fd79137SRobert Mustacchi Dwarf_Unsigned exception_table_symbol, 194*7fd79137SRobert Mustacchi Dwarf_Error * error) 195*7fd79137SRobert Mustacchi { 196*7fd79137SRobert Mustacchi 197*7fd79137SRobert Mustacchi return dwarf_add_frame_info_b(dbg, fde, die, cie, virt_addr, 198*7fd79137SRobert Mustacchi code_len, symidx, 199*7fd79137SRobert Mustacchi /* end_symbol */ 0, 200*7fd79137SRobert Mustacchi /* offset_from_end */ 0, 201*7fd79137SRobert Mustacchi offset_into_exception_tables, 202*7fd79137SRobert Mustacchi exception_table_symbol, error); 203*7fd79137SRobert Mustacchi 204*7fd79137SRobert Mustacchi } 205*7fd79137SRobert Mustacchi 206*7fd79137SRobert Mustacchi /*ARGSUSED*/ /* pretend all args used */ 207*7fd79137SRobert Mustacchi Dwarf_Unsigned 208*7fd79137SRobert Mustacchi dwarf_add_frame_info_b(Dwarf_P_Debug dbg, 209*7fd79137SRobert Mustacchi Dwarf_P_Fde fde, 210*7fd79137SRobert Mustacchi Dwarf_P_Die die, 211*7fd79137SRobert Mustacchi Dwarf_Unsigned cie, 212*7fd79137SRobert Mustacchi Dwarf_Unsigned virt_addr, 213*7fd79137SRobert Mustacchi Dwarf_Unsigned code_len, 214*7fd79137SRobert Mustacchi Dwarf_Unsigned symidx, 215*7fd79137SRobert Mustacchi Dwarf_Unsigned end_symidx, 216*7fd79137SRobert Mustacchi Dwarf_Unsigned offset_from_end_symbol, 217*7fd79137SRobert Mustacchi Dwarf_Signed offset_into_exception_tables, 218*7fd79137SRobert Mustacchi Dwarf_Unsigned exception_table_symbol, 219*7fd79137SRobert Mustacchi Dwarf_Error * error) 220*7fd79137SRobert Mustacchi { 221*7fd79137SRobert Mustacchi Dwarf_P_Fde curfde; 222*7fd79137SRobert Mustacchi 223*7fd79137SRobert Mustacchi fde->fde_die = die; 224*7fd79137SRobert Mustacchi fde->fde_cie = (long) cie; 225*7fd79137SRobert Mustacchi fde->fde_initloc = virt_addr; 226*7fd79137SRobert Mustacchi fde->fde_r_symidx = symidx; 227*7fd79137SRobert Mustacchi fde->fde_addr_range = code_len; 228*7fd79137SRobert Mustacchi fde->fde_offset_into_exception_tables = 229*7fd79137SRobert Mustacchi offset_into_exception_tables; 230*7fd79137SRobert Mustacchi fde->fde_exception_table_symbol = exception_table_symbol; 231*7fd79137SRobert Mustacchi fde->fde_end_symbol_offset = offset_from_end_symbol; 232*7fd79137SRobert Mustacchi fde->fde_end_symbol = end_symidx; 233*7fd79137SRobert Mustacchi fde->fde_dbg = dbg; 234*7fd79137SRobert Mustacchi 235*7fd79137SRobert Mustacchi curfde = dbg->de_last_fde; 236*7fd79137SRobert Mustacchi if (curfde == NULL) { 237*7fd79137SRobert Mustacchi dbg->de_frame_fdes = fde; 238*7fd79137SRobert Mustacchi dbg->de_last_fde = fde; 239*7fd79137SRobert Mustacchi dbg->de_n_fde = 1; 240*7fd79137SRobert Mustacchi } else { 241*7fd79137SRobert Mustacchi curfde->fde_next = fde; 242*7fd79137SRobert Mustacchi dbg->de_last_fde = fde; 243*7fd79137SRobert Mustacchi dbg->de_n_fde++; 244*7fd79137SRobert Mustacchi } 245*7fd79137SRobert Mustacchi return dbg->de_n_fde; 246*7fd79137SRobert Mustacchi } 247*7fd79137SRobert Mustacchi 248*7fd79137SRobert Mustacchi /* This is an alternate to inserting frame instructions 249*7fd79137SRobert Mustacchi one instruction at a time. But use either this 250*7fd79137SRobert Mustacchi or instruction level, not both in one fde. */ 251*7fd79137SRobert Mustacchi int 252*7fd79137SRobert Mustacchi dwarf_insert_fde_inst_bytes(Dwarf_P_Debug dbg, 253*7fd79137SRobert Mustacchi Dwarf_P_Fde fde,Dwarf_Unsigned len, Dwarf_Ptr ibytes, 254*7fd79137SRobert Mustacchi Dwarf_Error *error) 255*7fd79137SRobert Mustacchi { 256*7fd79137SRobert Mustacchi if( len == 0) { 257*7fd79137SRobert Mustacchi return DW_DLV_OK; 258*7fd79137SRobert Mustacchi } 259*7fd79137SRobert Mustacchi if(fde->fde_block || fde->fde_inst) { 260*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_DUPLICATE_INST_BLOCK, 261*7fd79137SRobert Mustacchi (int)DW_DLV_BADADDR); 262*7fd79137SRobert Mustacchi } 263*7fd79137SRobert Mustacchi fde->fde_block = (Dwarf_Ptr)_dwarf_p_get_alloc(dbg, len); 264*7fd79137SRobert Mustacchi memcpy(fde->fde_block,ibytes,len); 265*7fd79137SRobert Mustacchi fde->fde_inst_block_size = len; 266*7fd79137SRobert Mustacchi fde->fde_n_bytes += len; 267*7fd79137SRobert Mustacchi return DW_DLV_OK; 268*7fd79137SRobert Mustacchi } 269*7fd79137SRobert Mustacchi 270*7fd79137SRobert Mustacchi 271*7fd79137SRobert Mustacchi 272*7fd79137SRobert Mustacchi /*------------------------------------------------------------------- 273*7fd79137SRobert Mustacchi Create a new fde. 274*7fd79137SRobert Mustacchi ---------------------------------------------------------------------*/ 275*7fd79137SRobert Mustacchi Dwarf_P_Fde 276*7fd79137SRobert Mustacchi dwarf_new_fde(Dwarf_P_Debug dbg, Dwarf_Error * error) 277*7fd79137SRobert Mustacchi { 278*7fd79137SRobert Mustacchi Dwarf_P_Fde fde; 279*7fd79137SRobert Mustacchi 280*7fd79137SRobert Mustacchi fde = (Dwarf_P_Fde) 281*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Fde_s)); 282*7fd79137SRobert Mustacchi if (fde == NULL) { 283*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_FDE_ALLOC, 284*7fd79137SRobert Mustacchi (Dwarf_P_Fde) DW_DLV_BADADDR); 285*7fd79137SRobert Mustacchi } 286*7fd79137SRobert Mustacchi 287*7fd79137SRobert Mustacchi fde->fde_uwordb_size = dbg->de_offset_size; 288*7fd79137SRobert Mustacchi 289*7fd79137SRobert Mustacchi return fde; 290*7fd79137SRobert Mustacchi } 291*7fd79137SRobert Mustacchi 292*7fd79137SRobert Mustacchi 293*7fd79137SRobert Mustacchi /*------------------------------------------------------------------------ 294*7fd79137SRobert Mustacchi Add a cfe_offset instruction to the fde passed in. 295*7fd79137SRobert Mustacchi -------------------------------------------------------------------------*/ 296*7fd79137SRobert Mustacchi Dwarf_P_Fde 297*7fd79137SRobert Mustacchi dwarf_fde_cfa_offset(Dwarf_P_Fde fde, 298*7fd79137SRobert Mustacchi Dwarf_Unsigned reg, 299*7fd79137SRobert Mustacchi Dwarf_Signed offset, Dwarf_Error * error) 300*7fd79137SRobert Mustacchi { 301*7fd79137SRobert Mustacchi Dwarf_Ubyte opc, regno; 302*7fd79137SRobert Mustacchi char *ptr; 303*7fd79137SRobert Mustacchi Dwarf_P_Frame_Pgm curinst; 304*7fd79137SRobert Mustacchi int nbytes; 305*7fd79137SRobert Mustacchi int res; 306*7fd79137SRobert Mustacchi char buff1[ENCODE_SPACE_NEEDED]; 307*7fd79137SRobert Mustacchi Dwarf_P_Debug dbg = fde->fde_dbg; 308*7fd79137SRobert Mustacchi 309*7fd79137SRobert Mustacchi curinst = (Dwarf_P_Frame_Pgm) 310*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s)); 311*7fd79137SRobert Mustacchi if (curinst == NULL) { 312*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_FPGM_ALLOC, 313*7fd79137SRobert Mustacchi (Dwarf_P_Fde) DW_DLV_BADADDR); 314*7fd79137SRobert Mustacchi } 315*7fd79137SRobert Mustacchi opc = DW_CFA_offset; 316*7fd79137SRobert Mustacchi regno = reg; 317*7fd79137SRobert Mustacchi if (regno & 0xc0) { 318*7fd79137SRobert Mustacchi DWARF_P_DBG_ERROR(dbg, DW_DLE_REGNO_OVFL, 319*7fd79137SRobert Mustacchi (Dwarf_P_Fde) DW_DLV_BADADDR); 320*7fd79137SRobert Mustacchi } 321*7fd79137SRobert Mustacchi opc = opc | regno; /* lower 6 bits are register number */ 322*7fd79137SRobert Mustacchi curinst->dfp_opcode = opc; 323*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(offset, &nbytes, 324*7fd79137SRobert Mustacchi buff1, sizeof(buff1)); 325*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 326*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 327*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR); 328*7fd79137SRobert Mustacchi } 329*7fd79137SRobert Mustacchi ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); 330*7fd79137SRobert Mustacchi if (ptr == NULL) { 331*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 332*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR); 333*7fd79137SRobert Mustacchi } 334*7fd79137SRobert Mustacchi memcpy(ptr, buff1, nbytes); 335*7fd79137SRobert Mustacchi 336*7fd79137SRobert Mustacchi curinst->dfp_args = ptr; 337*7fd79137SRobert Mustacchi curinst->dfp_nbytes = nbytes; 338*7fd79137SRobert Mustacchi curinst->dfp_next = NULL; 339*7fd79137SRobert Mustacchi 340*7fd79137SRobert Mustacchi _dwarf_pro_add_to_fde(fde, curinst); 341*7fd79137SRobert Mustacchi return fde; 342*7fd79137SRobert Mustacchi } 343*7fd79137SRobert Mustacchi 344*7fd79137SRobert Mustacchi /* 345*7fd79137SRobert Mustacchi Generic routine to add opcode to fde instructions. val1 and 346*7fd79137SRobert Mustacchi val2 are parameters whose interpretation depends on the 'op'. 347*7fd79137SRobert Mustacchi 348*7fd79137SRobert Mustacchi This does not work properly for DW_DLC_SYMBOLIC_RELOCATIONS 349*7fd79137SRobert Mustacchi for DW_CFA_set_loc or DW_DVA_advance_loc* 'op', as 350*7fd79137SRobert Mustacchi these ops normally are addresses or (DW_CFA_set_loc) 351*7fd79137SRobert Mustacchi or code lengths (DW_DVA_advance_loc*) and such must be 352*7fd79137SRobert Mustacchi represented with relocations and symbol indices for 353*7fd79137SRobert Mustacchi DW_DLC_SYMBOLIC_RELOCATIONS. 354*7fd79137SRobert Mustacchi 355*7fd79137SRobert Mustacchi This does not treat all DW_CFA instructions yet. 356*7fd79137SRobert Mustacchi 357*7fd79137SRobert Mustacchi For certain operations a val? value must be 358*7fd79137SRobert Mustacchi signed (though passed in as unsigned here). 359*7fd79137SRobert Mustacchi 360*7fd79137SRobert Mustacchi Currently this does not check that the frame 361*7fd79137SRobert Mustacchi version is 3(for dwarf3) or 4 (for dwarf4) 362*7fd79137SRobert Mustacchi when applying operations that are only valid for 363*7fd79137SRobert Mustacchi dwarf3 or dwarf4. 364*7fd79137SRobert Mustacchi 365*7fd79137SRobert Mustacchi */ 366*7fd79137SRobert Mustacchi Dwarf_P_Fde 367*7fd79137SRobert Mustacchi dwarf_add_fde_inst(Dwarf_P_Fde fde, 368*7fd79137SRobert Mustacchi Dwarf_Small op, 369*7fd79137SRobert Mustacchi Dwarf_Unsigned val1, 370*7fd79137SRobert Mustacchi Dwarf_Unsigned val2, Dwarf_Error * error) 371*7fd79137SRobert Mustacchi { 372*7fd79137SRobert Mustacchi Dwarf_P_Frame_Pgm curinst; 373*7fd79137SRobert Mustacchi int nbytes, nbytes1, nbytes2; 374*7fd79137SRobert Mustacchi Dwarf_Ubyte db; 375*7fd79137SRobert Mustacchi Dwarf_Half dh; 376*7fd79137SRobert Mustacchi Dwarf_Word dw; 377*7fd79137SRobert Mustacchi Dwarf_Unsigned du; 378*7fd79137SRobert Mustacchi char *ptr; 379*7fd79137SRobert Mustacchi int res; 380*7fd79137SRobert Mustacchi char buff1[ENCODE_SPACE_NEEDED]; 381*7fd79137SRobert Mustacchi char buff2[ENCODE_SPACE_NEEDED]; 382*7fd79137SRobert Mustacchi Dwarf_P_Debug dbg = fde->fde_dbg; 383*7fd79137SRobert Mustacchi /* This is a hack telling the code when to transform 384*7fd79137SRobert Mustacchi a value to a signed leb number. */ 385*7fd79137SRobert Mustacchi int signed_second = 0; 386*7fd79137SRobert Mustacchi int signed_first = 0; 387*7fd79137SRobert Mustacchi 388*7fd79137SRobert Mustacchi 389*7fd79137SRobert Mustacchi nbytes = 0; 390*7fd79137SRobert Mustacchi ptr = NULL; 391*7fd79137SRobert Mustacchi curinst = (Dwarf_P_Frame_Pgm) 392*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Frame_Pgm_s)); 393*7fd79137SRobert Mustacchi if (curinst == NULL) { 394*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_FPGM_ALLOC); 395*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR); 396*7fd79137SRobert Mustacchi } 397*7fd79137SRobert Mustacchi 398*7fd79137SRobert Mustacchi switch (op) { 399*7fd79137SRobert Mustacchi 400*7fd79137SRobert Mustacchi case DW_CFA_advance_loc: 401*7fd79137SRobert Mustacchi if (val1 <= 0x3f) { 402*7fd79137SRobert Mustacchi db = val1; 403*7fd79137SRobert Mustacchi op |= db; 404*7fd79137SRobert Mustacchi } 405*7fd79137SRobert Mustacchi /* test not portable FIX */ 406*7fd79137SRobert Mustacchi else if (val1 <= UCHAR_MAX) { 407*7fd79137SRobert Mustacchi op = DW_CFA_advance_loc1; 408*7fd79137SRobert Mustacchi db = val1; 409*7fd79137SRobert Mustacchi ptr = (char *) _dwarf_p_get_alloc(dbg, 1); 410*7fd79137SRobert Mustacchi if (ptr == NULL) { 411*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 412*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR); 413*7fd79137SRobert Mustacchi } 414*7fd79137SRobert Mustacchi memcpy((void *) ptr, (const void *) &db, 1); 415*7fd79137SRobert Mustacchi nbytes = 1; 416*7fd79137SRobert Mustacchi } 417*7fd79137SRobert Mustacchi /* test not portable FIX */ 418*7fd79137SRobert Mustacchi else if (val1 <= USHRT_MAX) { 419*7fd79137SRobert Mustacchi op = DW_CFA_advance_loc2; 420*7fd79137SRobert Mustacchi dh = val1; 421*7fd79137SRobert Mustacchi ptr = (char *) _dwarf_p_get_alloc(dbg, 2); 422*7fd79137SRobert Mustacchi if (ptr == NULL) { 423*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 424*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR); 425*7fd79137SRobert Mustacchi } 426*7fd79137SRobert Mustacchi memcpy((void *) ptr, (const void *) &dh, 2); 427*7fd79137SRobert Mustacchi nbytes = 2; 428*7fd79137SRobert Mustacchi } 429*7fd79137SRobert Mustacchi /* test not portable FIX */ 430*7fd79137SRobert Mustacchi else if (val1 <= ULONG_MAX) { 431*7fd79137SRobert Mustacchi op = DW_CFA_advance_loc4; 432*7fd79137SRobert Mustacchi dw = (Dwarf_Word) val1; 433*7fd79137SRobert Mustacchi ptr = (char *) _dwarf_p_get_alloc(dbg, 4); 434*7fd79137SRobert Mustacchi if (ptr == NULL) { 435*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 436*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR); 437*7fd79137SRobert Mustacchi } 438*7fd79137SRobert Mustacchi memcpy((void *) ptr, (const void *) &dw, 4); 439*7fd79137SRobert Mustacchi nbytes = 4; 440*7fd79137SRobert Mustacchi } else { 441*7fd79137SRobert Mustacchi op = DW_CFA_MIPS_advance_loc8; 442*7fd79137SRobert Mustacchi du = val1; 443*7fd79137SRobert Mustacchi ptr = 444*7fd79137SRobert Mustacchi (char *) _dwarf_p_get_alloc(dbg, 445*7fd79137SRobert Mustacchi sizeof(Dwarf_Unsigned)); 446*7fd79137SRobert Mustacchi if (ptr == NULL) { 447*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 448*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR); 449*7fd79137SRobert Mustacchi } 450*7fd79137SRobert Mustacchi memcpy((void *) ptr, (const void *) &du, 8); 451*7fd79137SRobert Mustacchi nbytes = 8; 452*7fd79137SRobert Mustacchi } 453*7fd79137SRobert Mustacchi break; 454*7fd79137SRobert Mustacchi 455*7fd79137SRobert Mustacchi case DW_CFA_offset: 456*7fd79137SRobert Mustacchi if (val1 <= MAX_6_BIT_VALUE) { 457*7fd79137SRobert Mustacchi db = val1; 458*7fd79137SRobert Mustacchi op |= db; 459*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val2, &nbytes, 460*7fd79137SRobert Mustacchi buff1, sizeof(buff1)); 461*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 462*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 463*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR); 464*7fd79137SRobert Mustacchi } 465*7fd79137SRobert Mustacchi ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); 466*7fd79137SRobert Mustacchi if (ptr == NULL) { 467*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 468*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR); 469*7fd79137SRobert Mustacchi } 470*7fd79137SRobert Mustacchi memcpy(ptr, buff1, nbytes); 471*7fd79137SRobert Mustacchi 472*7fd79137SRobert Mustacchi } else { 473*7fd79137SRobert Mustacchi op = DW_CFA_offset_extended; 474*7fd79137SRobert Mustacchi goto two_leb; 475*7fd79137SRobert Mustacchi } 476*7fd79137SRobert Mustacchi break; 477*7fd79137SRobert Mustacchi case DW_CFA_offset_extended_sf: /* DWARF3 */ 478*7fd79137SRobert Mustacchi signed_second = 1; 479*7fd79137SRobert Mustacchi goto two_leb; 480*7fd79137SRobert Mustacchi case DW_CFA_offset_extended: 481*7fd79137SRobert Mustacchi goto two_leb; 482*7fd79137SRobert Mustacchi 483*7fd79137SRobert Mustacchi case DW_CFA_undefined: 484*7fd79137SRobert Mustacchi case DW_CFA_same_value: 485*7fd79137SRobert Mustacchi goto one_leb; 486*7fd79137SRobert Mustacchi 487*7fd79137SRobert Mustacchi case DW_CFA_val_offset: 488*7fd79137SRobert Mustacchi goto two_leb; 489*7fd79137SRobert Mustacchi case DW_CFA_val_offset_sf: 490*7fd79137SRobert Mustacchi signed_second = 1; 491*7fd79137SRobert Mustacchi goto two_leb; 492*7fd79137SRobert Mustacchi case DW_CFA_def_cfa_sf: 493*7fd79137SRobert Mustacchi signed_second = 1; 494*7fd79137SRobert Mustacchi goto two_leb; 495*7fd79137SRobert Mustacchi case DW_CFA_register: 496*7fd79137SRobert Mustacchi case DW_CFA_def_cfa: 497*7fd79137SRobert Mustacchi two_leb: 498*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val1, &nbytes1, 499*7fd79137SRobert Mustacchi buff1, sizeof(buff1)); 500*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 501*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 502*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR); 503*7fd79137SRobert Mustacchi } 504*7fd79137SRobert Mustacchi if (!signed_second) { 505*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, 506*7fd79137SRobert Mustacchi buff2, sizeof(buff2)); 507*7fd79137SRobert Mustacchi } else { 508*7fd79137SRobert Mustacchi Dwarf_Signed val2s = val2; 509*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_signed_leb128_nm(val2s, &nbytes2, 510*7fd79137SRobert Mustacchi buff2, sizeof(buff2)); 511*7fd79137SRobert Mustacchi } 512*7fd79137SRobert Mustacchi 513*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val2, &nbytes2, 514*7fd79137SRobert Mustacchi buff2, sizeof(buff2)); 515*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 516*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 517*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR); 518*7fd79137SRobert Mustacchi } 519*7fd79137SRobert Mustacchi 520*7fd79137SRobert Mustacchi ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes1 + nbytes2); 521*7fd79137SRobert Mustacchi if (ptr == NULL) { 522*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 523*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR); 524*7fd79137SRobert Mustacchi } 525*7fd79137SRobert Mustacchi memcpy(ptr, buff1, nbytes1); 526*7fd79137SRobert Mustacchi memcpy(ptr + nbytes1, buff2, nbytes2); 527*7fd79137SRobert Mustacchi nbytes = nbytes1 + nbytes2; 528*7fd79137SRobert Mustacchi break; 529*7fd79137SRobert Mustacchi 530*7fd79137SRobert Mustacchi case DW_CFA_def_cfa_offset_sf: /* DWARF3 */ 531*7fd79137SRobert Mustacchi signed_first = 1; 532*7fd79137SRobert Mustacchi goto one_leb; 533*7fd79137SRobert Mustacchi case DW_CFA_def_cfa_register: 534*7fd79137SRobert Mustacchi case DW_CFA_def_cfa_offset: 535*7fd79137SRobert Mustacchi one_leb: 536*7fd79137SRobert Mustacchi if(!signed_first) { 537*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(val1, &nbytes, 538*7fd79137SRobert Mustacchi buff1, sizeof(buff1)); 539*7fd79137SRobert Mustacchi } else { 540*7fd79137SRobert Mustacchi Dwarf_Signed val1s = val1; 541*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_signed_leb128_nm(val1s, &nbytes, 542*7fd79137SRobert Mustacchi buff1, sizeof(buff1)); 543*7fd79137SRobert Mustacchi } 544*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 545*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 546*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR); 547*7fd79137SRobert Mustacchi } 548*7fd79137SRobert Mustacchi ptr = (char *) _dwarf_p_get_alloc(dbg, nbytes); 549*7fd79137SRobert Mustacchi if (ptr == NULL) { 550*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_STRING_ALLOC); 551*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR); 552*7fd79137SRobert Mustacchi } 553*7fd79137SRobert Mustacchi memcpy(ptr, buff1, nbytes); 554*7fd79137SRobert Mustacchi break; 555*7fd79137SRobert Mustacchi case DW_CFA_def_cfa_expression: /* DWARF3 */ 556*7fd79137SRobert Mustacchi /* FIXME: argument is dwarf expr, not handled yet. */ 557*7fd79137SRobert Mustacchi case DW_CFA_expression: /* DWARF3 */ 558*7fd79137SRobert Mustacchi /* First arg: ULEB reg num. 2nd arg dwarf expr in form block. 559*7fd79137SRobert Mustacchi FIXME: not handled yet. */ 560*7fd79137SRobert Mustacchi case DW_CFA_val_expression: /* DWARF3f */ 561*7fd79137SRobert Mustacchi /* First arg: ULEB reg num. 2nd arg dwarf expr in form block. 562*7fd79137SRobert Mustacchi FIXME: not handled yet. */ 563*7fd79137SRobert Mustacchi default: 564*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_DEBUGFRAME_ERROR); 565*7fd79137SRobert Mustacchi return ((Dwarf_P_Fde) DW_DLV_BADADDR); 566*7fd79137SRobert Mustacchi } 567*7fd79137SRobert Mustacchi 568*7fd79137SRobert Mustacchi curinst->dfp_opcode = op; 569*7fd79137SRobert Mustacchi curinst->dfp_args = ptr; 570*7fd79137SRobert Mustacchi curinst->dfp_nbytes = nbytes; 571*7fd79137SRobert Mustacchi curinst->dfp_next = NULL; 572*7fd79137SRobert Mustacchi 573*7fd79137SRobert Mustacchi _dwarf_pro_add_to_fde(fde, curinst); 574*7fd79137SRobert Mustacchi return fde; 575*7fd79137SRobert Mustacchi } 576*7fd79137SRobert Mustacchi 577*7fd79137SRobert Mustacchi 578*7fd79137SRobert Mustacchi /*------------------------------------------------------------------------ 579*7fd79137SRobert Mustacchi Instructions are added to an fde in the form of a linked 580*7fd79137SRobert Mustacchi list. This function manages the linked list. 581*7fd79137SRobert Mustacchi -------------------------------------------------------------------------*/ 582*7fd79137SRobert Mustacchi void 583*7fd79137SRobert Mustacchi _dwarf_pro_add_to_fde(Dwarf_P_Fde fde, Dwarf_P_Frame_Pgm curinst) 584*7fd79137SRobert Mustacchi { 585*7fd79137SRobert Mustacchi if (fde->fde_last_inst) { 586*7fd79137SRobert Mustacchi fde->fde_last_inst->dfp_next = curinst; 587*7fd79137SRobert Mustacchi fde->fde_last_inst = curinst; 588*7fd79137SRobert Mustacchi fde->fde_n_inst++; 589*7fd79137SRobert Mustacchi fde->fde_n_bytes += 590*7fd79137SRobert Mustacchi (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte)); 591*7fd79137SRobert Mustacchi } else { 592*7fd79137SRobert Mustacchi fde->fde_last_inst = curinst; 593*7fd79137SRobert Mustacchi fde->fde_inst = curinst; 594*7fd79137SRobert Mustacchi fde->fde_n_inst = 1; 595*7fd79137SRobert Mustacchi fde->fde_n_bytes = 596*7fd79137SRobert Mustacchi (long) (curinst->dfp_nbytes + sizeof(Dwarf_Ubyte)); 597*7fd79137SRobert Mustacchi } 598*7fd79137SRobert Mustacchi } 599