1*2de3b87aSKai Wang /*- 2*2de3b87aSKai Wang * Copyright (c) 2007 John Birrell (jb@freebsd.org) 3*2de3b87aSKai Wang * Copyright (c) 2009,2010 Kai Wang 4*2de3b87aSKai Wang * All rights reserved. 5*2de3b87aSKai Wang * 6*2de3b87aSKai Wang * Redistribution and use in source and binary forms, with or without 7*2de3b87aSKai Wang * modification, are permitted provided that the following conditions 8*2de3b87aSKai Wang * are met: 9*2de3b87aSKai Wang * 1. Redistributions of source code must retain the above copyright 10*2de3b87aSKai Wang * notice, this list of conditions and the following disclaimer. 11*2de3b87aSKai Wang * 2. Redistributions in binary form must reproduce the above copyright 12*2de3b87aSKai Wang * notice, this list of conditions and the following disclaimer in the 13*2de3b87aSKai Wang * documentation and/or other materials provided with the distribution. 14*2de3b87aSKai Wang * 15*2de3b87aSKai Wang * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*2de3b87aSKai Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*2de3b87aSKai Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*2de3b87aSKai Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*2de3b87aSKai Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*2de3b87aSKai Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*2de3b87aSKai Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*2de3b87aSKai Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*2de3b87aSKai Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*2de3b87aSKai Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*2de3b87aSKai Wang * SUCH DAMAGE. 26*2de3b87aSKai Wang */ 27*2de3b87aSKai Wang 28*2de3b87aSKai Wang #include "_libdwarf.h" 29*2de3b87aSKai Wang 30*2de3b87aSKai Wang ELFTC_VCSID("$Id: dwarf_form.c 2073 2011-10-27 03:30:47Z jkoshy $"); 31*2de3b87aSKai Wang 32*2de3b87aSKai Wang int 33*2de3b87aSKai Wang dwarf_hasform(Dwarf_Attribute at, Dwarf_Half form, Dwarf_Bool *return_hasform, 34*2de3b87aSKai Wang Dwarf_Error *error) 35*2de3b87aSKai Wang { 36*2de3b87aSKai Wang Dwarf_Debug dbg; 37*2de3b87aSKai Wang 38*2de3b87aSKai Wang dbg = at != NULL ? at->at_die->die_dbg : NULL; 39*2de3b87aSKai Wang 40*2de3b87aSKai Wang if (at == NULL || return_hasform == NULL) { 41*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 42*2de3b87aSKai Wang return (DW_DLV_ERROR); 43*2de3b87aSKai Wang } 44*2de3b87aSKai Wang 45*2de3b87aSKai Wang *return_hasform = (at->at_form == form); 46*2de3b87aSKai Wang 47*2de3b87aSKai Wang return (DW_DLV_OK); 48*2de3b87aSKai Wang } 49*2de3b87aSKai Wang 50*2de3b87aSKai Wang int 51*2de3b87aSKai Wang dwarf_whatform(Dwarf_Attribute at, Dwarf_Half *return_form, Dwarf_Error *error) 52*2de3b87aSKai Wang { 53*2de3b87aSKai Wang Dwarf_Debug dbg; 54*2de3b87aSKai Wang 55*2de3b87aSKai Wang dbg = at != NULL ? at->at_die->die_dbg : NULL; 56*2de3b87aSKai Wang 57*2de3b87aSKai Wang if (at == NULL || return_form == NULL) { 58*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 59*2de3b87aSKai Wang return (DW_DLV_ERROR); 60*2de3b87aSKai Wang } 61*2de3b87aSKai Wang 62*2de3b87aSKai Wang *return_form = at->at_form; 63*2de3b87aSKai Wang 64*2de3b87aSKai Wang return (DW_DLV_OK); 65*2de3b87aSKai Wang } 66*2de3b87aSKai Wang 67*2de3b87aSKai Wang int 68*2de3b87aSKai Wang dwarf_whatform_direct(Dwarf_Attribute at, Dwarf_Half *return_form, 69*2de3b87aSKai Wang Dwarf_Error *error) 70*2de3b87aSKai Wang { 71*2de3b87aSKai Wang Dwarf_Debug dbg; 72*2de3b87aSKai Wang 73*2de3b87aSKai Wang dbg = at != NULL ? at->at_die->die_dbg : NULL; 74*2de3b87aSKai Wang 75*2de3b87aSKai Wang if (at == NULL || return_form == NULL) { 76*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 77*2de3b87aSKai Wang return (DW_DLV_ERROR); 78*2de3b87aSKai Wang } 79*2de3b87aSKai Wang 80*2de3b87aSKai Wang if (at->at_indirect) 81*2de3b87aSKai Wang *return_form = DW_FORM_indirect; 82*2de3b87aSKai Wang else 83*2de3b87aSKai Wang *return_form = (Dwarf_Half) at->at_form; 84*2de3b87aSKai Wang 85*2de3b87aSKai Wang return (DW_DLV_OK); 86*2de3b87aSKai Wang } 87*2de3b87aSKai Wang 88*2de3b87aSKai Wang int 89*2de3b87aSKai Wang dwarf_whatattr(Dwarf_Attribute at, Dwarf_Half *return_attr, Dwarf_Error *error) 90*2de3b87aSKai Wang { 91*2de3b87aSKai Wang Dwarf_Debug dbg; 92*2de3b87aSKai Wang 93*2de3b87aSKai Wang dbg = at != NULL ? at->at_die->die_dbg : NULL; 94*2de3b87aSKai Wang 95*2de3b87aSKai Wang if (at == NULL || return_attr == NULL) { 96*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 97*2de3b87aSKai Wang return (DW_DLV_ERROR); 98*2de3b87aSKai Wang } 99*2de3b87aSKai Wang 100*2de3b87aSKai Wang *return_attr = (Dwarf_Half) at->at_attrib; 101*2de3b87aSKai Wang 102*2de3b87aSKai Wang return (DW_DLV_OK); 103*2de3b87aSKai Wang } 104*2de3b87aSKai Wang 105*2de3b87aSKai Wang int 106*2de3b87aSKai Wang dwarf_formref(Dwarf_Attribute at, Dwarf_Off *return_offset, Dwarf_Error *error) 107*2de3b87aSKai Wang { 108*2de3b87aSKai Wang int ret; 109*2de3b87aSKai Wang Dwarf_Debug dbg; 110*2de3b87aSKai Wang 111*2de3b87aSKai Wang dbg = at != NULL ? at->at_die->die_dbg : NULL; 112*2de3b87aSKai Wang 113*2de3b87aSKai Wang if (at == NULL || return_offset == NULL) { 114*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 115*2de3b87aSKai Wang return (DW_DLV_ERROR); 116*2de3b87aSKai Wang } 117*2de3b87aSKai Wang 118*2de3b87aSKai Wang switch (at->at_form) { 119*2de3b87aSKai Wang case DW_FORM_ref1: 120*2de3b87aSKai Wang case DW_FORM_ref2: 121*2de3b87aSKai Wang case DW_FORM_ref4: 122*2de3b87aSKai Wang case DW_FORM_ref8: 123*2de3b87aSKai Wang case DW_FORM_ref_udata: 124*2de3b87aSKai Wang *return_offset = (Dwarf_Off) at->u[0].u64; 125*2de3b87aSKai Wang ret = DW_DLV_OK; 126*2de3b87aSKai Wang break; 127*2de3b87aSKai Wang default: 128*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); 129*2de3b87aSKai Wang ret = DW_DLV_ERROR; 130*2de3b87aSKai Wang } 131*2de3b87aSKai Wang 132*2de3b87aSKai Wang return (ret); 133*2de3b87aSKai Wang } 134*2de3b87aSKai Wang 135*2de3b87aSKai Wang int 136*2de3b87aSKai Wang dwarf_global_formref(Dwarf_Attribute at, Dwarf_Off *return_offset, 137*2de3b87aSKai Wang Dwarf_Error *error) 138*2de3b87aSKai Wang { 139*2de3b87aSKai Wang int ret; 140*2de3b87aSKai Wang Dwarf_Debug dbg; 141*2de3b87aSKai Wang 142*2de3b87aSKai Wang dbg = at != NULL ? at->at_die->die_dbg : NULL; 143*2de3b87aSKai Wang 144*2de3b87aSKai Wang if (at == NULL || return_offset == NULL) { 145*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 146*2de3b87aSKai Wang return (DW_DLV_ERROR); 147*2de3b87aSKai Wang } 148*2de3b87aSKai Wang 149*2de3b87aSKai Wang switch (at->at_form) { 150*2de3b87aSKai Wang case DW_FORM_ref_addr: 151*2de3b87aSKai Wang case DW_FORM_sec_offset: 152*2de3b87aSKai Wang *return_offset = (Dwarf_Off) at->u[0].u64; 153*2de3b87aSKai Wang ret = DW_DLV_OK; 154*2de3b87aSKai Wang break; 155*2de3b87aSKai Wang case DW_FORM_ref1: 156*2de3b87aSKai Wang case DW_FORM_ref2: 157*2de3b87aSKai Wang case DW_FORM_ref4: 158*2de3b87aSKai Wang case DW_FORM_ref8: 159*2de3b87aSKai Wang case DW_FORM_ref_udata: 160*2de3b87aSKai Wang *return_offset = (Dwarf_Off) at->u[0].u64 + 161*2de3b87aSKai Wang at->at_die->die_cu->cu_offset; 162*2de3b87aSKai Wang ret = DW_DLV_OK; 163*2de3b87aSKai Wang break; 164*2de3b87aSKai Wang default: 165*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); 166*2de3b87aSKai Wang ret = DW_DLV_ERROR; 167*2de3b87aSKai Wang } 168*2de3b87aSKai Wang 169*2de3b87aSKai Wang return (ret); 170*2de3b87aSKai Wang } 171*2de3b87aSKai Wang 172*2de3b87aSKai Wang int 173*2de3b87aSKai Wang dwarf_formaddr(Dwarf_Attribute at, Dwarf_Addr *return_addr, Dwarf_Error *error) 174*2de3b87aSKai Wang { 175*2de3b87aSKai Wang int ret; 176*2de3b87aSKai Wang Dwarf_Debug dbg; 177*2de3b87aSKai Wang 178*2de3b87aSKai Wang dbg = at != NULL ? at->at_die->die_dbg : NULL; 179*2de3b87aSKai Wang 180*2de3b87aSKai Wang if (at == NULL || return_addr == 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 if (at->at_form == DW_FORM_addr) { 186*2de3b87aSKai Wang *return_addr = at->u[0].u64; 187*2de3b87aSKai Wang ret = DW_DLV_OK; 188*2de3b87aSKai Wang } else { 189*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); 190*2de3b87aSKai Wang ret = DW_DLV_ERROR; 191*2de3b87aSKai Wang } 192*2de3b87aSKai Wang 193*2de3b87aSKai Wang return (ret); 194*2de3b87aSKai Wang } 195*2de3b87aSKai Wang 196*2de3b87aSKai Wang int 197*2de3b87aSKai Wang dwarf_formflag(Dwarf_Attribute at, Dwarf_Bool *return_bool, Dwarf_Error *error) 198*2de3b87aSKai Wang { 199*2de3b87aSKai Wang int ret; 200*2de3b87aSKai Wang Dwarf_Debug dbg; 201*2de3b87aSKai Wang 202*2de3b87aSKai Wang dbg = at != NULL ? at->at_die->die_dbg : NULL; 203*2de3b87aSKai Wang 204*2de3b87aSKai Wang if (at == NULL || return_bool == NULL) { 205*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 206*2de3b87aSKai Wang return (DW_DLV_ERROR); 207*2de3b87aSKai Wang } 208*2de3b87aSKai Wang 209*2de3b87aSKai Wang if (at->at_form == DW_FORM_flag || 210*2de3b87aSKai Wang at->at_form == DW_FORM_flag_present) { 211*2de3b87aSKai Wang *return_bool = (Dwarf_Bool) (!!at->u[0].u64); 212*2de3b87aSKai Wang ret = DW_DLV_OK; 213*2de3b87aSKai Wang } else { 214*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); 215*2de3b87aSKai Wang ret = DW_DLV_ERROR; 216*2de3b87aSKai Wang } 217*2de3b87aSKai Wang 218*2de3b87aSKai Wang return (ret); 219*2de3b87aSKai Wang } 220*2de3b87aSKai Wang 221*2de3b87aSKai Wang int 222*2de3b87aSKai Wang dwarf_formudata(Dwarf_Attribute at, Dwarf_Unsigned *return_uvalue, 223*2de3b87aSKai Wang Dwarf_Error *error) 224*2de3b87aSKai Wang { 225*2de3b87aSKai Wang int ret; 226*2de3b87aSKai Wang Dwarf_Debug dbg; 227*2de3b87aSKai Wang 228*2de3b87aSKai Wang dbg = at != NULL ? at->at_die->die_dbg : NULL; 229*2de3b87aSKai Wang 230*2de3b87aSKai Wang if (at == NULL || return_uvalue == NULL) { 231*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 232*2de3b87aSKai Wang return (DW_DLV_ERROR); 233*2de3b87aSKai Wang } 234*2de3b87aSKai Wang 235*2de3b87aSKai Wang switch (at->at_form) { 236*2de3b87aSKai Wang case DW_FORM_data1: 237*2de3b87aSKai Wang case DW_FORM_data2: 238*2de3b87aSKai Wang case DW_FORM_data4: 239*2de3b87aSKai Wang case DW_FORM_data8: 240*2de3b87aSKai Wang case DW_FORM_udata: 241*2de3b87aSKai Wang *return_uvalue = at->u[0].u64; 242*2de3b87aSKai Wang ret = DW_DLV_OK; 243*2de3b87aSKai Wang break; 244*2de3b87aSKai Wang default: 245*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); 246*2de3b87aSKai Wang ret = DW_DLV_ERROR; 247*2de3b87aSKai Wang } 248*2de3b87aSKai Wang 249*2de3b87aSKai Wang return (ret); 250*2de3b87aSKai Wang } 251*2de3b87aSKai Wang 252*2de3b87aSKai Wang int 253*2de3b87aSKai Wang dwarf_formsdata(Dwarf_Attribute at, Dwarf_Signed *return_svalue, 254*2de3b87aSKai Wang Dwarf_Error *error) 255*2de3b87aSKai Wang { 256*2de3b87aSKai Wang int ret; 257*2de3b87aSKai Wang Dwarf_Debug dbg; 258*2de3b87aSKai Wang 259*2de3b87aSKai Wang dbg = at != NULL ? at->at_die->die_dbg : NULL; 260*2de3b87aSKai Wang 261*2de3b87aSKai Wang if (at == NULL || return_svalue == NULL) { 262*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 263*2de3b87aSKai Wang return (DW_DLV_ERROR); 264*2de3b87aSKai Wang } 265*2de3b87aSKai Wang 266*2de3b87aSKai Wang switch (at->at_form) { 267*2de3b87aSKai Wang case DW_FORM_data1: 268*2de3b87aSKai Wang *return_svalue = (int8_t) at->u[0].s64; 269*2de3b87aSKai Wang ret = DW_DLV_OK; 270*2de3b87aSKai Wang break; 271*2de3b87aSKai Wang case DW_FORM_data2: 272*2de3b87aSKai Wang *return_svalue = (int16_t) at->u[0].s64; 273*2de3b87aSKai Wang ret = DW_DLV_OK; 274*2de3b87aSKai Wang break; 275*2de3b87aSKai Wang case DW_FORM_data4: 276*2de3b87aSKai Wang *return_svalue = (int32_t) at->u[0].s64; 277*2de3b87aSKai Wang ret = DW_DLV_OK; 278*2de3b87aSKai Wang break; 279*2de3b87aSKai Wang case DW_FORM_data8: 280*2de3b87aSKai Wang case DW_FORM_sdata: 281*2de3b87aSKai Wang *return_svalue = at->u[0].s64; 282*2de3b87aSKai Wang ret = DW_DLV_OK; 283*2de3b87aSKai Wang break; 284*2de3b87aSKai Wang default: 285*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); 286*2de3b87aSKai Wang ret = DW_DLV_ERROR; 287*2de3b87aSKai Wang } 288*2de3b87aSKai Wang 289*2de3b87aSKai Wang return (ret); 290*2de3b87aSKai Wang } 291*2de3b87aSKai Wang 292*2de3b87aSKai Wang int 293*2de3b87aSKai Wang dwarf_formblock(Dwarf_Attribute at, Dwarf_Block **return_block, 294*2de3b87aSKai Wang Dwarf_Error *error) 295*2de3b87aSKai Wang { 296*2de3b87aSKai Wang int ret; 297*2de3b87aSKai Wang Dwarf_Debug dbg; 298*2de3b87aSKai Wang 299*2de3b87aSKai Wang dbg = at != NULL ? at->at_die->die_dbg : NULL; 300*2de3b87aSKai Wang 301*2de3b87aSKai Wang if (at == NULL || return_block == NULL) { 302*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 303*2de3b87aSKai Wang return (DW_DLV_ERROR); 304*2de3b87aSKai Wang } 305*2de3b87aSKai Wang 306*2de3b87aSKai Wang switch (at->at_form) { 307*2de3b87aSKai Wang case DW_FORM_block: 308*2de3b87aSKai Wang case DW_FORM_block1: 309*2de3b87aSKai Wang case DW_FORM_block2: 310*2de3b87aSKai Wang case DW_FORM_block4: 311*2de3b87aSKai Wang *return_block = &at->at_block; 312*2de3b87aSKai Wang ret = DW_DLV_OK; 313*2de3b87aSKai Wang break; 314*2de3b87aSKai Wang default: 315*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); 316*2de3b87aSKai Wang ret = DW_DLV_ERROR; 317*2de3b87aSKai Wang } 318*2de3b87aSKai Wang 319*2de3b87aSKai Wang return (ret); 320*2de3b87aSKai Wang } 321*2de3b87aSKai Wang 322*2de3b87aSKai Wang int 323*2de3b87aSKai Wang dwarf_formsig8(Dwarf_Attribute at, Dwarf_Sig8 *return_sig8, Dwarf_Error *error) 324*2de3b87aSKai Wang { 325*2de3b87aSKai Wang Dwarf_Debug dbg; 326*2de3b87aSKai Wang 327*2de3b87aSKai Wang dbg = at != NULL ? at->at_die->die_dbg : NULL; 328*2de3b87aSKai Wang 329*2de3b87aSKai Wang if (at == NULL || return_sig8 == NULL) { 330*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 331*2de3b87aSKai Wang return (DW_DLV_ERROR); 332*2de3b87aSKai Wang } 333*2de3b87aSKai Wang 334*2de3b87aSKai Wang if (at->at_form != DW_FORM_ref_sig8) { 335*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); 336*2de3b87aSKai Wang return (DW_DLV_ERROR); 337*2de3b87aSKai Wang } 338*2de3b87aSKai Wang 339*2de3b87aSKai Wang assert(at->u[0].u64 == 8); 340*2de3b87aSKai Wang memcpy(return_sig8->signature, at->u[1].u8p, at->u[0].u64); 341*2de3b87aSKai Wang 342*2de3b87aSKai Wang return (DW_DLV_OK); 343*2de3b87aSKai Wang } 344*2de3b87aSKai Wang 345*2de3b87aSKai Wang int 346*2de3b87aSKai Wang dwarf_formexprloc(Dwarf_Attribute at, Dwarf_Unsigned *return_exprlen, 347*2de3b87aSKai Wang Dwarf_Ptr *return_expr, Dwarf_Error *error) 348*2de3b87aSKai Wang { 349*2de3b87aSKai Wang 350*2de3b87aSKai Wang Dwarf_Debug dbg; 351*2de3b87aSKai Wang 352*2de3b87aSKai Wang dbg = at != NULL ? at->at_die->die_dbg : NULL; 353*2de3b87aSKai Wang 354*2de3b87aSKai Wang if (at == NULL || return_exprlen == NULL || return_expr == NULL) { 355*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 356*2de3b87aSKai Wang return (DW_DLV_ERROR); 357*2de3b87aSKai Wang } 358*2de3b87aSKai Wang 359*2de3b87aSKai Wang if (at->at_form != DW_FORM_exprloc) { 360*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); 361*2de3b87aSKai Wang return (DW_DLV_ERROR); 362*2de3b87aSKai Wang } 363*2de3b87aSKai Wang 364*2de3b87aSKai Wang *return_exprlen = at->u[0].u64; 365*2de3b87aSKai Wang *return_expr = (void *) at->u[1].u8p; 366*2de3b87aSKai Wang 367*2de3b87aSKai Wang return (DW_DLV_OK); 368*2de3b87aSKai Wang } 369*2de3b87aSKai Wang 370*2de3b87aSKai Wang int 371*2de3b87aSKai Wang dwarf_formstring(Dwarf_Attribute at, char **return_string, 372*2de3b87aSKai Wang Dwarf_Error *error) 373*2de3b87aSKai Wang { 374*2de3b87aSKai Wang int ret; 375*2de3b87aSKai Wang Dwarf_Debug dbg; 376*2de3b87aSKai Wang 377*2de3b87aSKai Wang dbg = at != NULL ? at->at_die->die_dbg : NULL; 378*2de3b87aSKai Wang 379*2de3b87aSKai Wang if (at == NULL || return_string == NULL) { 380*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 381*2de3b87aSKai Wang return (DW_DLV_ERROR); 382*2de3b87aSKai Wang } 383*2de3b87aSKai Wang 384*2de3b87aSKai Wang switch (at->at_form) { 385*2de3b87aSKai Wang case DW_FORM_string: 386*2de3b87aSKai Wang *return_string = (char *) at->u[0].s; 387*2de3b87aSKai Wang ret = DW_DLV_OK; 388*2de3b87aSKai Wang break; 389*2de3b87aSKai Wang case DW_FORM_strp: 390*2de3b87aSKai Wang *return_string = (char *) at->u[1].s; 391*2de3b87aSKai Wang ret = DW_DLV_OK; 392*2de3b87aSKai Wang break; 393*2de3b87aSKai Wang default: 394*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); 395*2de3b87aSKai Wang ret = DW_DLV_ERROR; 396*2de3b87aSKai Wang } 397*2de3b87aSKai Wang 398*2de3b87aSKai Wang return (ret); 399*2de3b87aSKai Wang } 400*2de3b87aSKai Wang 401*2de3b87aSKai Wang enum Dwarf_Form_Class 402*2de3b87aSKai Wang dwarf_get_form_class(Dwarf_Half dwversion, Dwarf_Half attr, 403*2de3b87aSKai Wang Dwarf_Half offset_size, Dwarf_Half form) 404*2de3b87aSKai Wang { 405*2de3b87aSKai Wang 406*2de3b87aSKai Wang switch (form) { 407*2de3b87aSKai Wang case DW_FORM_addr: 408*2de3b87aSKai Wang return (DW_FORM_CLASS_ADDRESS); 409*2de3b87aSKai Wang case DW_FORM_block: 410*2de3b87aSKai Wang case DW_FORM_block1: 411*2de3b87aSKai Wang case DW_FORM_block2: 412*2de3b87aSKai Wang case DW_FORM_block4: 413*2de3b87aSKai Wang return (DW_FORM_CLASS_BLOCK); 414*2de3b87aSKai Wang case DW_FORM_string: 415*2de3b87aSKai Wang case DW_FORM_strp: 416*2de3b87aSKai Wang return (DW_FORM_CLASS_STRING); 417*2de3b87aSKai Wang case DW_FORM_flag: 418*2de3b87aSKai Wang case DW_FORM_flag_present: 419*2de3b87aSKai Wang return (DW_FORM_CLASS_FLAG); 420*2de3b87aSKai Wang case DW_FORM_ref_addr: 421*2de3b87aSKai Wang case DW_FORM_ref_sig8: 422*2de3b87aSKai Wang case DW_FORM_ref_udata: 423*2de3b87aSKai Wang case DW_FORM_ref1: 424*2de3b87aSKai Wang case DW_FORM_ref2: 425*2de3b87aSKai Wang case DW_FORM_ref4: 426*2de3b87aSKai Wang case DW_FORM_ref8: 427*2de3b87aSKai Wang return (DW_FORM_CLASS_REFERENCE); 428*2de3b87aSKai Wang case DW_FORM_exprloc: 429*2de3b87aSKai Wang return (DW_FORM_CLASS_EXPRLOC); 430*2de3b87aSKai Wang case DW_FORM_data1: 431*2de3b87aSKai Wang case DW_FORM_data2: 432*2de3b87aSKai Wang case DW_FORM_sdata: 433*2de3b87aSKai Wang case DW_FORM_udata: 434*2de3b87aSKai Wang return (DW_FORM_CLASS_CONSTANT); 435*2de3b87aSKai Wang case DW_FORM_data4: 436*2de3b87aSKai Wang case DW_FORM_data8: 437*2de3b87aSKai Wang if (dwversion > 3) 438*2de3b87aSKai Wang return (DW_FORM_CLASS_CONSTANT); 439*2de3b87aSKai Wang if (form == DW_FORM_data4 && offset_size != 4) 440*2de3b87aSKai Wang return (DW_FORM_CLASS_CONSTANT); 441*2de3b87aSKai Wang if (form == DW_FORM_data8 && offset_size != 8) 442*2de3b87aSKai Wang return (DW_FORM_CLASS_CONSTANT); 443*2de3b87aSKai Wang /* FALLTHROUGH */ 444*2de3b87aSKai Wang case DW_FORM_sec_offset: 445*2de3b87aSKai Wang /* 446*2de3b87aSKai Wang * DW_FORM_data4 and DW_FORM_data8 can be used as 447*2de3b87aSKai Wang * offset/pointer before DWARF4. Newly added 448*2de3b87aSKai Wang * DWARF4 form DW_FORM_sec_offset intents to replace 449*2de3b87aSKai Wang * DW_FORM_data{4,8} for this purpose. Anyway, to 450*2de3b87aSKai Wang * determine the actual class for these forms, we need 451*2de3b87aSKai Wang * to also look at the attribute number. 452*2de3b87aSKai Wang */ 453*2de3b87aSKai Wang switch (attr) { 454*2de3b87aSKai Wang case DW_AT_location: 455*2de3b87aSKai Wang case DW_AT_string_length: 456*2de3b87aSKai Wang case DW_AT_return_addr: 457*2de3b87aSKai Wang case DW_AT_data_member_location: 458*2de3b87aSKai Wang case DW_AT_frame_base: 459*2de3b87aSKai Wang case DW_AT_segment: 460*2de3b87aSKai Wang case DW_AT_static_link: 461*2de3b87aSKai Wang case DW_AT_use_location: 462*2de3b87aSKai Wang case DW_AT_vtable_elem_location: 463*2de3b87aSKai Wang return (DW_FORM_CLASS_LOCLISTPTR); 464*2de3b87aSKai Wang case DW_AT_stmt_list: 465*2de3b87aSKai Wang return (DW_FORM_CLASS_LINEPTR); 466*2de3b87aSKai Wang case DW_AT_start_scope: 467*2de3b87aSKai Wang case DW_AT_ranges: 468*2de3b87aSKai Wang return (DW_FORM_CLASS_RANGELISTPTR); 469*2de3b87aSKai Wang case DW_AT_macro_info: 470*2de3b87aSKai Wang return (DW_FORM_CLASS_MACPTR); 471*2de3b87aSKai Wang default: 472*2de3b87aSKai Wang if (form == DW_FORM_data4 || form == DW_FORM_data8) 473*2de3b87aSKai Wang return (DW_FORM_CLASS_CONSTANT); 474*2de3b87aSKai Wang else 475*2de3b87aSKai Wang return (DW_FORM_CLASS_UNKNOWN); 476*2de3b87aSKai Wang } 477*2de3b87aSKai Wang default: 478*2de3b87aSKai Wang return (DW_FORM_CLASS_UNKNOWN); 479*2de3b87aSKai Wang } 480*2de3b87aSKai Wang } 481