1*7fd79137SRobert Mustacchi /* 2*7fd79137SRobert Mustacchi 3*7fd79137SRobert Mustacchi Copyright (C) 2000,2002,2004,2005 Silicon Graphics, Inc. All Rights Reserved. 4*7fd79137SRobert Mustacchi Portions Copyright 2007-2010 Sun Microsystems, Inc. All rights reserved. 5*7fd79137SRobert Mustacchi Portions Copyright 2008-2010 David Anderson. All rights reserved. 6*7fd79137SRobert Mustacchi 7*7fd79137SRobert Mustacchi This program is free software; you can redistribute it and/or modify it 8*7fd79137SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License 9*7fd79137SRobert Mustacchi as published by the Free Software Foundation. 10*7fd79137SRobert Mustacchi 11*7fd79137SRobert Mustacchi This program is distributed in the hope that it would be useful, but 12*7fd79137SRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of 13*7fd79137SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 14*7fd79137SRobert Mustacchi 15*7fd79137SRobert Mustacchi Further, this software is distributed without any warranty that it is 16*7fd79137SRobert Mustacchi free of the rightful claim of any third person regarding infringement 17*7fd79137SRobert Mustacchi or the like. Any license provided herein, whether implied or 18*7fd79137SRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if 19*7fd79137SRobert Mustacchi any, provided herein do not apply to combinations of this program with 20*7fd79137SRobert Mustacchi other software, or any other product whatsoever. 21*7fd79137SRobert Mustacchi 22*7fd79137SRobert Mustacchi You should have received a copy of the GNU Lesser General Public 23*7fd79137SRobert Mustacchi License along with this program; if not, write the Free Software 24*7fd79137SRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 25*7fd79137SRobert Mustacchi USA. 26*7fd79137SRobert Mustacchi 27*7fd79137SRobert Mustacchi Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, 28*7fd79137SRobert Mustacchi Mountain View, CA 94043, or: 29*7fd79137SRobert Mustacchi 30*7fd79137SRobert Mustacchi http://www.sgi.com 31*7fd79137SRobert Mustacchi 32*7fd79137SRobert Mustacchi For further information regarding this notice, see: 33*7fd79137SRobert Mustacchi 34*7fd79137SRobert Mustacchi http://oss.sgi.com/projects/GenInfo/NoticeExplan 35*7fd79137SRobert Mustacchi 36*7fd79137SRobert Mustacchi */ 37*7fd79137SRobert Mustacchi 38*7fd79137SRobert Mustacchi 39*7fd79137SRobert Mustacchi 40*7fd79137SRobert Mustacchi #include "config.h" 41*7fd79137SRobert Mustacchi #include "dwarf_incl.h" 42*7fd79137SRobert Mustacchi #include "dwarf_die_deliv.h" 43*7fd79137SRobert Mustacchi 44*7fd79137SRobert Mustacchi int 45*7fd79137SRobert Mustacchi dwarf_hasform(Dwarf_Attribute attr, 46*7fd79137SRobert Mustacchi Dwarf_Half form, 47*7fd79137SRobert Mustacchi Dwarf_Bool * return_bool, Dwarf_Error * error) 48*7fd79137SRobert Mustacchi { 49*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0; 50*7fd79137SRobert Mustacchi 51*7fd79137SRobert Mustacchi if (attr == NULL) { 52*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); 53*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 54*7fd79137SRobert Mustacchi } 55*7fd79137SRobert Mustacchi 56*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context; 57*7fd79137SRobert Mustacchi if (cu_context == NULL) { 58*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); 59*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 60*7fd79137SRobert Mustacchi } 61*7fd79137SRobert Mustacchi 62*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) { 63*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); 64*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 65*7fd79137SRobert Mustacchi } 66*7fd79137SRobert Mustacchi 67*7fd79137SRobert Mustacchi *return_bool = (attr->ar_attribute_form == form); 68*7fd79137SRobert Mustacchi return DW_DLV_OK; 69*7fd79137SRobert Mustacchi } 70*7fd79137SRobert Mustacchi 71*7fd79137SRobert Mustacchi /* Not often called, we do not worry about efficiency here. 72*7fd79137SRobert Mustacchi The dwarf_whatform() call does the sanity checks for us. 73*7fd79137SRobert Mustacchi */ 74*7fd79137SRobert Mustacchi int 75*7fd79137SRobert Mustacchi dwarf_whatform_direct(Dwarf_Attribute attr, 76*7fd79137SRobert Mustacchi Dwarf_Half * return_form, Dwarf_Error * error) 77*7fd79137SRobert Mustacchi { 78*7fd79137SRobert Mustacchi int res = dwarf_whatform(attr, return_form, error); 79*7fd79137SRobert Mustacchi 80*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 81*7fd79137SRobert Mustacchi return res; 82*7fd79137SRobert Mustacchi } 83*7fd79137SRobert Mustacchi 84*7fd79137SRobert Mustacchi *return_form = attr->ar_attribute_form_direct; 85*7fd79137SRobert Mustacchi return (DW_DLV_OK); 86*7fd79137SRobert Mustacchi } 87*7fd79137SRobert Mustacchi void * 88*7fd79137SRobert Mustacchi dwarf_uncompress_integer_block( 89*7fd79137SRobert Mustacchi Dwarf_Debug dbg, 90*7fd79137SRobert Mustacchi Dwarf_Bool unit_is_signed, 91*7fd79137SRobert Mustacchi Dwarf_Small unit_length_in_bits, 92*7fd79137SRobert Mustacchi void* input_block, 93*7fd79137SRobert Mustacchi Dwarf_Unsigned input_length_in_bytes, 94*7fd79137SRobert Mustacchi Dwarf_Unsigned* output_length_in_units_ptr, 95*7fd79137SRobert Mustacchi Dwarf_Error* error 96*7fd79137SRobert Mustacchi ) 97*7fd79137SRobert Mustacchi { 98*7fd79137SRobert Mustacchi Dwarf_Unsigned output_length_in_units = 0; 99*7fd79137SRobert Mustacchi void * output_block = 0; 100*7fd79137SRobert Mustacchi int i = 0; 101*7fd79137SRobert Mustacchi char * ptr = 0; 102*7fd79137SRobert Mustacchi int remain = 0; 103*7fd79137SRobert Mustacchi Dwarf_sfixed * array = 0; 104*7fd79137SRobert Mustacchi 105*7fd79137SRobert Mustacchi if (dbg == NULL) { 106*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_DBG_NULL); 107*7fd79137SRobert Mustacchi return((void *)DW_DLV_BADADDR); 108*7fd79137SRobert Mustacchi } 109*7fd79137SRobert Mustacchi 110*7fd79137SRobert Mustacchi if (unit_is_signed == false || 111*7fd79137SRobert Mustacchi unit_length_in_bits != 32 || 112*7fd79137SRobert Mustacchi input_block == NULL || 113*7fd79137SRobert Mustacchi input_length_in_bytes == 0 || 114*7fd79137SRobert Mustacchi output_length_in_units_ptr == NULL) { 115*7fd79137SRobert Mustacchi 116*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_BADBITC); 117*7fd79137SRobert Mustacchi return ((void *) DW_DLV_BADADDR); 118*7fd79137SRobert Mustacchi } 119*7fd79137SRobert Mustacchi 120*7fd79137SRobert Mustacchi /* At this point we assume the format is: signed 32 bit */ 121*7fd79137SRobert Mustacchi 122*7fd79137SRobert Mustacchi /* first uncompress everything to find the total size. */ 123*7fd79137SRobert Mustacchi 124*7fd79137SRobert Mustacchi output_length_in_units = 0; 125*7fd79137SRobert Mustacchi remain = input_length_in_bytes; 126*7fd79137SRobert Mustacchi ptr = input_block; 127*7fd79137SRobert Mustacchi while (remain > 0) { 128*7fd79137SRobert Mustacchi Dwarf_Signed num; 129*7fd79137SRobert Mustacchi Dwarf_Word len; 130*7fd79137SRobert Mustacchi num = _dwarf_decode_s_leb128((unsigned char *)ptr, &len); 131*7fd79137SRobert Mustacchi ptr += len; 132*7fd79137SRobert Mustacchi remain -= len; 133*7fd79137SRobert Mustacchi output_length_in_units++; 134*7fd79137SRobert Mustacchi } 135*7fd79137SRobert Mustacchi 136*7fd79137SRobert Mustacchi if (remain != 0) { 137*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ALLOC_FAIL); 138*7fd79137SRobert Mustacchi return((void *)DW_DLV_BADADDR); 139*7fd79137SRobert Mustacchi } 140*7fd79137SRobert Mustacchi 141*7fd79137SRobert Mustacchi /* then alloc */ 142*7fd79137SRobert Mustacchi 143*7fd79137SRobert Mustacchi output_block = (void *) 144*7fd79137SRobert Mustacchi _dwarf_get_alloc(dbg, 145*7fd79137SRobert Mustacchi DW_DLA_STRING, 146*7fd79137SRobert Mustacchi output_length_in_units * (unit_length_in_bits / 8)); 147*7fd79137SRobert Mustacchi if (output_block == NULL) { 148*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 149*7fd79137SRobert Mustacchi return((void*)DW_DLV_BADADDR); 150*7fd79137SRobert Mustacchi } 151*7fd79137SRobert Mustacchi 152*7fd79137SRobert Mustacchi /* then uncompress again and copy into new buffer */ 153*7fd79137SRobert Mustacchi 154*7fd79137SRobert Mustacchi array = (Dwarf_sfixed *) output_block; 155*7fd79137SRobert Mustacchi remain = input_length_in_bytes; 156*7fd79137SRobert Mustacchi ptr = input_block; 157*7fd79137SRobert Mustacchi for (i=0; i<output_length_in_units && remain>0; i++) { 158*7fd79137SRobert Mustacchi Dwarf_Signed num; 159*7fd79137SRobert Mustacchi Dwarf_Word len; 160*7fd79137SRobert Mustacchi num = _dwarf_decode_s_leb128((unsigned char *)ptr, &len); 161*7fd79137SRobert Mustacchi ptr += len; 162*7fd79137SRobert Mustacchi remain -= len; 163*7fd79137SRobert Mustacchi array[i] = num; 164*7fd79137SRobert Mustacchi } 165*7fd79137SRobert Mustacchi 166*7fd79137SRobert Mustacchi if (remain != 0) { 167*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, (unsigned char *)output_block, DW_DLA_STRING); 168*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 169*7fd79137SRobert Mustacchi return((Dwarf_P_Attribute)DW_DLV_BADADDR); 170*7fd79137SRobert Mustacchi } 171*7fd79137SRobert Mustacchi 172*7fd79137SRobert Mustacchi *output_length_in_units_ptr = output_length_in_units; 173*7fd79137SRobert Mustacchi return output_block; 174*7fd79137SRobert Mustacchi } 175*7fd79137SRobert Mustacchi 176*7fd79137SRobert Mustacchi void 177*7fd79137SRobert Mustacchi dwarf_dealloc_uncompressed_block(Dwarf_Debug dbg, void * space) 178*7fd79137SRobert Mustacchi { 179*7fd79137SRobert Mustacchi dwarf_dealloc(dbg, space, DW_DLA_STRING); 180*7fd79137SRobert Mustacchi } 181*7fd79137SRobert Mustacchi 182*7fd79137SRobert Mustacchi 183*7fd79137SRobert Mustacchi int 184*7fd79137SRobert Mustacchi dwarf_whatform(Dwarf_Attribute attr, 185*7fd79137SRobert Mustacchi Dwarf_Half * return_form, Dwarf_Error * error) 186*7fd79137SRobert Mustacchi { 187*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0; 188*7fd79137SRobert Mustacchi 189*7fd79137SRobert Mustacchi if (attr == NULL) { 190*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); 191*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 192*7fd79137SRobert Mustacchi } 193*7fd79137SRobert Mustacchi 194*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context; 195*7fd79137SRobert Mustacchi if (cu_context == NULL) { 196*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); 197*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 198*7fd79137SRobert Mustacchi } 199*7fd79137SRobert Mustacchi 200*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) { 201*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); 202*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 203*7fd79137SRobert Mustacchi } 204*7fd79137SRobert Mustacchi 205*7fd79137SRobert Mustacchi *return_form = attr->ar_attribute_form; 206*7fd79137SRobert Mustacchi return (DW_DLV_OK); 207*7fd79137SRobert Mustacchi } 208*7fd79137SRobert Mustacchi 209*7fd79137SRobert Mustacchi 210*7fd79137SRobert Mustacchi /* 211*7fd79137SRobert Mustacchi This function is analogous to dwarf_whatform. 212*7fd79137SRobert Mustacchi It returns the attribute in attr instead of 213*7fd79137SRobert Mustacchi the form. 214*7fd79137SRobert Mustacchi */ 215*7fd79137SRobert Mustacchi int 216*7fd79137SRobert Mustacchi dwarf_whatattr(Dwarf_Attribute attr, 217*7fd79137SRobert Mustacchi Dwarf_Half * return_attr, Dwarf_Error * error) 218*7fd79137SRobert Mustacchi { 219*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0; 220*7fd79137SRobert Mustacchi 221*7fd79137SRobert Mustacchi if (attr == NULL) { 222*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); 223*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 224*7fd79137SRobert Mustacchi } 225*7fd79137SRobert Mustacchi 226*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context; 227*7fd79137SRobert Mustacchi if (cu_context == NULL) { 228*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); 229*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 230*7fd79137SRobert Mustacchi } 231*7fd79137SRobert Mustacchi 232*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) { 233*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); 234*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 235*7fd79137SRobert Mustacchi } 236*7fd79137SRobert Mustacchi 237*7fd79137SRobert Mustacchi *return_attr = (attr->ar_attribute); 238*7fd79137SRobert Mustacchi return DW_DLV_OK; 239*7fd79137SRobert Mustacchi } 240*7fd79137SRobert Mustacchi 241*7fd79137SRobert Mustacchi 242*7fd79137SRobert Mustacchi /* 243*7fd79137SRobert Mustacchi A global offset cannot be returned by this interface: 244*7fd79137SRobert Mustacchi see dwarf_global_formref(). 245*7fd79137SRobert Mustacchi 246*7fd79137SRobert Mustacchi DW_FORM_ref_addr is considered an incorrect form 247*7fd79137SRobert Mustacchi for this call because DW_FORM_ref_addr is a global-offset into 248*7fd79137SRobert Mustacchi the debug_info section. 249*7fd79137SRobert Mustacchi 250*7fd79137SRobert Mustacchi For the same reason DW_FORM_data4/data8 are not returned 251*7fd79137SRobert Mustacchi from this function. 252*7fd79137SRobert Mustacchi 253*7fd79137SRobert Mustacchi For the same reason DW_FORM_sec_offset is not returned 254*7fd79137SRobert Mustacchi from this function, DW_FORM_sec_offset is a global offset 255*7fd79137SRobert Mustacchi (to various sections, not a CU relative offset. 256*7fd79137SRobert Mustacchi 257*7fd79137SRobert Mustacchi DW_FORM_ref_addr has a value which was documented in 258*7fd79137SRobert Mustacchi DWARF2 as address-size but which was always an offset 259*7fd79137SRobert Mustacchi so should have always been offset size (wording 260*7fd79137SRobert Mustacchi corrected in DWARF3). 261*7fd79137SRobert Mustacchi 262*7fd79137SRobert Mustacchi 263*7fd79137SRobert Mustacchi */ 264*7fd79137SRobert Mustacchi int 265*7fd79137SRobert Mustacchi dwarf_formref(Dwarf_Attribute attr, 266*7fd79137SRobert Mustacchi Dwarf_Off * ret_offset, Dwarf_Error * error) 267*7fd79137SRobert Mustacchi { 268*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0; 269*7fd79137SRobert Mustacchi Dwarf_Unsigned offset = 0; 270*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0; 271*7fd79137SRobert Mustacchi 272*7fd79137SRobert Mustacchi 273*7fd79137SRobert Mustacchi if (attr == NULL) { 274*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); 275*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 276*7fd79137SRobert Mustacchi } 277*7fd79137SRobert Mustacchi 278*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context; 279*7fd79137SRobert Mustacchi if (cu_context == NULL) { 280*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); 281*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 282*7fd79137SRobert Mustacchi } 283*7fd79137SRobert Mustacchi 284*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) { 285*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); 286*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 287*7fd79137SRobert Mustacchi } 288*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg; 289*7fd79137SRobert Mustacchi 290*7fd79137SRobert Mustacchi switch (attr->ar_attribute_form) { 291*7fd79137SRobert Mustacchi 292*7fd79137SRobert Mustacchi case DW_FORM_ref1: 293*7fd79137SRobert Mustacchi offset = *(Dwarf_Small *) attr->ar_debug_info_ptr; 294*7fd79137SRobert Mustacchi break; 295*7fd79137SRobert Mustacchi 296*7fd79137SRobert Mustacchi case DW_FORM_ref2: 297*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, 298*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Half)); 299*7fd79137SRobert Mustacchi break; 300*7fd79137SRobert Mustacchi 301*7fd79137SRobert Mustacchi case DW_FORM_ref4: 302*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, 303*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed)); 304*7fd79137SRobert Mustacchi break; 305*7fd79137SRobert Mustacchi 306*7fd79137SRobert Mustacchi case DW_FORM_ref8: 307*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, 308*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned)); 309*7fd79137SRobert Mustacchi break; 310*7fd79137SRobert Mustacchi 311*7fd79137SRobert Mustacchi case DW_FORM_ref_udata: 312*7fd79137SRobert Mustacchi offset = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL); 313*7fd79137SRobert Mustacchi break; 314*7fd79137SRobert Mustacchi 315*7fd79137SRobert Mustacchi default: 316*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM); 317*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 318*7fd79137SRobert Mustacchi } 319*7fd79137SRobert Mustacchi 320*7fd79137SRobert Mustacchi /* Check that offset is within current cu portion of .debug_info. */ 321*7fd79137SRobert Mustacchi if (offset >= cu_context->cc_length + 322*7fd79137SRobert Mustacchi cu_context->cc_length_size + cu_context->cc_extension_size) { 323*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD); 324*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 325*7fd79137SRobert Mustacchi } 326*7fd79137SRobert Mustacchi 327*7fd79137SRobert Mustacchi *ret_offset = (offset); 328*7fd79137SRobert Mustacchi return DW_DLV_OK; 329*7fd79137SRobert Mustacchi } 330*7fd79137SRobert Mustacchi 331*7fd79137SRobert Mustacchi /* dwarf_formsig8 returns in the caller-provided 8 byte area 332*7fd79137SRobert Mustacchi the 8 bytes of a DW_FORM_ref_sig8 (copying the bytes 333*7fd79137SRobert Mustacchi directly to the caller). Not a string, an 8 byte 334*7fd79137SRobert Mustacchi MD5 hash. This function is new in DWARF4 libdwarf. 335*7fd79137SRobert Mustacchi */ 336*7fd79137SRobert Mustacchi int dwarf_formsig8(Dwarf_Attribute attr, 337*7fd79137SRobert Mustacchi Dwarf_Sig8 * returned_sig_bytes, 338*7fd79137SRobert Mustacchi Dwarf_Error* error) 339*7fd79137SRobert Mustacchi { 340*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0; 341*7fd79137SRobert Mustacchi Dwarf_Unsigned field_end_offset = 0; 342*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0; 343*7fd79137SRobert Mustacchi 344*7fd79137SRobert Mustacchi 345*7fd79137SRobert Mustacchi if (attr == NULL) { 346*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); 347*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 348*7fd79137SRobert Mustacchi } 349*7fd79137SRobert Mustacchi 350*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context; 351*7fd79137SRobert Mustacchi if (cu_context == NULL) { 352*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); 353*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 354*7fd79137SRobert Mustacchi } 355*7fd79137SRobert Mustacchi 356*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) { 357*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); 358*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 359*7fd79137SRobert Mustacchi } 360*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg; 361*7fd79137SRobert Mustacchi 362*7fd79137SRobert Mustacchi if(attr->ar_attribute_form != DW_FORM_ref_sig8 ) { 363*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_BAD_REF_SIG8_FORM); 364*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 365*7fd79137SRobert Mustacchi } 366*7fd79137SRobert Mustacchi 367*7fd79137SRobert Mustacchi field_end_offset = attr->ar_debug_info_ptr + sizeof(Dwarf_Sig8) - 368*7fd79137SRobert Mustacchi (dbg->de_debug_info.dss_data + cu_context->cc_debug_info_offset); 369*7fd79137SRobert Mustacchi /* Check that offset is within current cu portion of .debug_info. */ 370*7fd79137SRobert Mustacchi if (field_end_offset > cu_context->cc_length + 371*7fd79137SRobert Mustacchi cu_context->cc_length_size + cu_context->cc_extension_size) { 372*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD); 373*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 374*7fd79137SRobert Mustacchi } 375*7fd79137SRobert Mustacchi 376*7fd79137SRobert Mustacchi memcpy(returned_sig_bytes, attr->ar_debug_info_ptr, 377*7fd79137SRobert Mustacchi sizeof(Dwarf_Sig8)); 378*7fd79137SRobert Mustacchi return DW_DLV_OK; 379*7fd79137SRobert Mustacchi } 380*7fd79137SRobert Mustacchi 381*7fd79137SRobert Mustacchi 382*7fd79137SRobert Mustacchi /* 383*7fd79137SRobert Mustacchi Since this returns section-relative debug_info offsets, 384*7fd79137SRobert Mustacchi this can represent all REFERENCE forms correctly 385*7fd79137SRobert Mustacchi and allows all applicable forms. 386*7fd79137SRobert Mustacchi 387*7fd79137SRobert Mustacchi DW_FORM_ref_addr has a value which was documented in 388*7fd79137SRobert Mustacchi DWARF2 as address-size but which was always an offset 389*7fd79137SRobert Mustacchi so should have always been offset size (wording 390*7fd79137SRobert Mustacchi corrected in DWARF3). 391*7fd79137SRobert Mustacchi 392*7fd79137SRobert Mustacchi See the DWARF4 document for the 3 cases fitting 393*7fd79137SRobert Mustacchi reference forms. The caller must determine which section the 394*7fd79137SRobert Mustacchi reference 'points' to. The function added in November 2009, 395*7fd79137SRobert Mustacchi dwarf_get_form_class(), helps in this regard. 396*7fd79137SRobert Mustacchi 397*7fd79137SRobert Mustacchi */ 398*7fd79137SRobert Mustacchi int 399*7fd79137SRobert Mustacchi dwarf_global_formref(Dwarf_Attribute attr, 400*7fd79137SRobert Mustacchi Dwarf_Off * ret_offset, Dwarf_Error * error) 401*7fd79137SRobert Mustacchi { 402*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0; 403*7fd79137SRobert Mustacchi Dwarf_Unsigned offset = 0; 404*7fd79137SRobert Mustacchi Dwarf_Addr ref_addr = 0; 405*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0; 406*7fd79137SRobert Mustacchi Dwarf_Half context_version = 0; 407*7fd79137SRobert Mustacchi 408*7fd79137SRobert Mustacchi if (attr == NULL) { 409*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); 410*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 411*7fd79137SRobert Mustacchi } 412*7fd79137SRobert Mustacchi 413*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context; 414*7fd79137SRobert Mustacchi if (cu_context == NULL) { 415*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); 416*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 417*7fd79137SRobert Mustacchi } 418*7fd79137SRobert Mustacchi context_version = cu_context->cc_version_stamp; 419*7fd79137SRobert Mustacchi 420*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) { 421*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); 422*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 423*7fd79137SRobert Mustacchi } 424*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg; 425*7fd79137SRobert Mustacchi 426*7fd79137SRobert Mustacchi switch (attr->ar_attribute_form) { 427*7fd79137SRobert Mustacchi 428*7fd79137SRobert Mustacchi case DW_FORM_ref1: 429*7fd79137SRobert Mustacchi offset = *(Dwarf_Small *) attr->ar_debug_info_ptr; 430*7fd79137SRobert Mustacchi goto fixoffset; 431*7fd79137SRobert Mustacchi 432*7fd79137SRobert Mustacchi case DW_FORM_ref2: 433*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, 434*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Half)); 435*7fd79137SRobert Mustacchi goto fixoffset; 436*7fd79137SRobert Mustacchi 437*7fd79137SRobert Mustacchi case DW_FORM_ref4: 438*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, 439*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed)); 440*7fd79137SRobert Mustacchi goto fixoffset; 441*7fd79137SRobert Mustacchi 442*7fd79137SRobert Mustacchi case DW_FORM_ref8: 443*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, 444*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned)); 445*7fd79137SRobert Mustacchi goto fixoffset; 446*7fd79137SRobert Mustacchi 447*7fd79137SRobert Mustacchi case DW_FORM_ref_udata: 448*7fd79137SRobert Mustacchi offset = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL); 449*7fd79137SRobert Mustacchi 450*7fd79137SRobert Mustacchi fixoffset: /* we have a local offset, make it 451*7fd79137SRobert Mustacchi global */ 452*7fd79137SRobert Mustacchi 453*7fd79137SRobert Mustacchi /* check legality of offset */ 454*7fd79137SRobert Mustacchi if (offset >= cu_context->cc_length + 455*7fd79137SRobert Mustacchi cu_context->cc_length_size + 456*7fd79137SRobert Mustacchi cu_context->cc_extension_size) { 457*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_OFFSET_BAD); 458*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 459*7fd79137SRobert Mustacchi } 460*7fd79137SRobert Mustacchi 461*7fd79137SRobert Mustacchi /* globalize the offset */ 462*7fd79137SRobert Mustacchi offset += cu_context->cc_debug_info_offset; 463*7fd79137SRobert Mustacchi break; 464*7fd79137SRobert Mustacchi /* The DWARF2 document did not make clear that 465*7fd79137SRobert Mustacchi DW_FORM_data4( and 8) were references with 466*7fd79137SRobert Mustacchi global offsets to some section. 467*7fd79137SRobert Mustacchi That was first clearly documented in DWARF3. 468*7fd79137SRobert Mustacchi In DWARF4 these two forms are no longer references. */ 469*7fd79137SRobert Mustacchi case DW_FORM_data4: 470*7fd79137SRobert Mustacchi if(context_version == DW_CU_VERSION4) { 471*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_NOT_REF_FORM); 472*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 473*7fd79137SRobert Mustacchi } 474*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, 475*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed)); 476*7fd79137SRobert Mustacchi /* The offset is global. */ 477*7fd79137SRobert Mustacchi break; 478*7fd79137SRobert Mustacchi case DW_FORM_data8: 479*7fd79137SRobert Mustacchi if(context_version == DW_CU_VERSION4) { 480*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_NOT_REF_FORM); 481*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 482*7fd79137SRobert Mustacchi } 483*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, 484*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned)); 485*7fd79137SRobert Mustacchi /* The offset is global. */ 486*7fd79137SRobert Mustacchi break; 487*7fd79137SRobert Mustacchi case DW_FORM_ref_addr: 488*7fd79137SRobert Mustacchi case DW_FORM_sec_offset: 489*7fd79137SRobert Mustacchi { 490*7fd79137SRobert Mustacchi /* DW_FORM_sec_offset first exists in DWARF4.*/ 491*7fd79137SRobert Mustacchi /* It is up to the caller to know what the offset 492*7fd79137SRobert Mustacchi of DW_FORM_sec_offset refers to, 493*7fd79137SRobert Mustacchi the offset is not going to refer to .debug_info! */ 494*7fd79137SRobert Mustacchi unsigned length_size = cu_context->cc_length_size; 495*7fd79137SRobert Mustacchi if(length_size == 4) { 496*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, 497*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed)); 498*7fd79137SRobert Mustacchi } else if (length_size == 8) { 499*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, 500*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Unsigned)); 501*7fd79137SRobert Mustacchi } else { 502*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_FORM_SEC_OFFSET_LENGTH_BAD); 503*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 504*7fd79137SRobert Mustacchi } 505*7fd79137SRobert Mustacchi } 506*7fd79137SRobert Mustacchi break; 507*7fd79137SRobert Mustacchi 508*7fd79137SRobert Mustacchi default: 509*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_BAD_REF_FORM); 510*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 511*7fd79137SRobert Mustacchi } 512*7fd79137SRobert Mustacchi 513*7fd79137SRobert Mustacchi /* We do not know what section the offset refers to, so 514*7fd79137SRobert Mustacchi we have no way to check it for correctness. */ 515*7fd79137SRobert Mustacchi *ret_offset = offset; 516*7fd79137SRobert Mustacchi return DW_DLV_OK; 517*7fd79137SRobert Mustacchi } 518*7fd79137SRobert Mustacchi 519*7fd79137SRobert Mustacchi 520*7fd79137SRobert Mustacchi int 521*7fd79137SRobert Mustacchi dwarf_formaddr(Dwarf_Attribute attr, 522*7fd79137SRobert Mustacchi Dwarf_Addr * return_addr, Dwarf_Error * error) 523*7fd79137SRobert Mustacchi { 524*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0; 525*7fd79137SRobert Mustacchi Dwarf_Addr ret_addr = 0; 526*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0; 527*7fd79137SRobert Mustacchi 528*7fd79137SRobert Mustacchi if (attr == NULL) { 529*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); 530*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 531*7fd79137SRobert Mustacchi } 532*7fd79137SRobert Mustacchi 533*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context; 534*7fd79137SRobert Mustacchi if (cu_context == NULL) { 535*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); 536*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 537*7fd79137SRobert Mustacchi } 538*7fd79137SRobert Mustacchi 539*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) { 540*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); 541*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 542*7fd79137SRobert Mustacchi } 543*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg; 544*7fd79137SRobert Mustacchi 545*7fd79137SRobert Mustacchi if (attr->ar_attribute_form == DW_FORM_addr 546*7fd79137SRobert Mustacchi /* || attr->ar_attribute_form == DW_FORM_ref_addr Allowance of 547*7fd79137SRobert Mustacchi DW_FORM_ref_addr was a mistake. The value returned in that 548*7fd79137SRobert Mustacchi case is NOT an address it is a global debug_info offset (ie, 549*7fd79137SRobert Mustacchi not CU-relative offset within the CU in debug_info). The 550*7fd79137SRobert Mustacchi Dwarf document refers to it as an address (misleadingly) in 551*7fd79137SRobert Mustacchi sec 6.5.4 where it describes the reference form. It is 552*7fd79137SRobert Mustacchi address-sized so that the linker can easily update it, but 553*7fd79137SRobert Mustacchi it is a reference inside the debug_info section. No longer 554*7fd79137SRobert Mustacchi allowed. */ 555*7fd79137SRobert Mustacchi ) { 556*7fd79137SRobert Mustacchi 557*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_addr, Dwarf_Addr, 558*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, 559*7fd79137SRobert Mustacchi cu_context->cc_address_size); 560*7fd79137SRobert Mustacchi *return_addr = ret_addr; 561*7fd79137SRobert Mustacchi return (DW_DLV_OK); 562*7fd79137SRobert Mustacchi } 563*7fd79137SRobert Mustacchi 564*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); 565*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 566*7fd79137SRobert Mustacchi } 567*7fd79137SRobert Mustacchi 568*7fd79137SRobert Mustacchi 569*7fd79137SRobert Mustacchi int 570*7fd79137SRobert Mustacchi dwarf_formflag(Dwarf_Attribute attr, 571*7fd79137SRobert Mustacchi Dwarf_Bool * ret_bool, Dwarf_Error * error) 572*7fd79137SRobert Mustacchi { 573*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0; 574*7fd79137SRobert Mustacchi 575*7fd79137SRobert Mustacchi if (attr == NULL) { 576*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); 577*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 578*7fd79137SRobert Mustacchi } 579*7fd79137SRobert Mustacchi 580*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context; 581*7fd79137SRobert Mustacchi if (cu_context == NULL) { 582*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); 583*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 584*7fd79137SRobert Mustacchi } 585*7fd79137SRobert Mustacchi 586*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) { 587*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); 588*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 589*7fd79137SRobert Mustacchi } 590*7fd79137SRobert Mustacchi if (attr->ar_attribute_form == DW_FORM_flag_present) { 591*7fd79137SRobert Mustacchi /* Implicit means we don't read any data at all. Just 592*7fd79137SRobert Mustacchi the existence of the Form does it. DWARF4. */ 593*7fd79137SRobert Mustacchi *ret_bool = 1; 594*7fd79137SRobert Mustacchi return (DW_DLV_OK); 595*7fd79137SRobert Mustacchi } 596*7fd79137SRobert Mustacchi 597*7fd79137SRobert Mustacchi if (attr->ar_attribute_form == DW_FORM_flag) { 598*7fd79137SRobert Mustacchi *ret_bool = (*(Dwarf_Small *) attr->ar_debug_info_ptr != 0); 599*7fd79137SRobert Mustacchi return (DW_DLV_OK); 600*7fd79137SRobert Mustacchi } 601*7fd79137SRobert Mustacchi _dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD); 602*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 603*7fd79137SRobert Mustacchi } 604*7fd79137SRobert Mustacchi 605*7fd79137SRobert Mustacchi 606*7fd79137SRobert Mustacchi int 607*7fd79137SRobert Mustacchi dwarf_formudata(Dwarf_Attribute attr, 608*7fd79137SRobert Mustacchi Dwarf_Unsigned * return_uval, Dwarf_Error * error) 609*7fd79137SRobert Mustacchi { 610*7fd79137SRobert Mustacchi Dwarf_Unsigned ret_value = 0; 611*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0; 612*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0; 613*7fd79137SRobert Mustacchi 614*7fd79137SRobert Mustacchi if (attr == NULL) { 615*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); 616*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 617*7fd79137SRobert Mustacchi } 618*7fd79137SRobert Mustacchi 619*7fd79137SRobert Mustacchi 620*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context; 621*7fd79137SRobert Mustacchi if (cu_context == NULL) { 622*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); 623*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 624*7fd79137SRobert Mustacchi } 625*7fd79137SRobert Mustacchi 626*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg; 627*7fd79137SRobert Mustacchi if (dbg == NULL) { 628*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); 629*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 630*7fd79137SRobert Mustacchi } 631*7fd79137SRobert Mustacchi 632*7fd79137SRobert Mustacchi switch (attr->ar_attribute_form) { 633*7fd79137SRobert Mustacchi 634*7fd79137SRobert Mustacchi case DW_FORM_data1: 635*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, 636*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Small)); 637*7fd79137SRobert Mustacchi *return_uval = ret_value; 638*7fd79137SRobert Mustacchi return DW_DLV_OK; 639*7fd79137SRobert Mustacchi 640*7fd79137SRobert Mustacchi /* READ_UNALIGNED does the right thing as it reads 641*7fd79137SRobert Mustacchi the right number bits and generates host order. 642*7fd79137SRobert Mustacchi So we can just assign to *return_uval. */ 643*7fd79137SRobert Mustacchi case DW_FORM_data2:{ 644*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, 645*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Half)); 646*7fd79137SRobert Mustacchi *return_uval = ret_value; 647*7fd79137SRobert Mustacchi return DW_DLV_OK; 648*7fd79137SRobert Mustacchi } 649*7fd79137SRobert Mustacchi 650*7fd79137SRobert Mustacchi case DW_FORM_data4:{ 651*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, 652*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, 653*7fd79137SRobert Mustacchi sizeof(Dwarf_ufixed)); 654*7fd79137SRobert Mustacchi *return_uval = ret_value; 655*7fd79137SRobert Mustacchi return DW_DLV_OK; 656*7fd79137SRobert Mustacchi } 657*7fd79137SRobert Mustacchi 658*7fd79137SRobert Mustacchi case DW_FORM_data8:{ 659*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Unsigned, 660*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, 661*7fd79137SRobert Mustacchi sizeof(Dwarf_Unsigned)); 662*7fd79137SRobert Mustacchi *return_uval = ret_value; 663*7fd79137SRobert Mustacchi return DW_DLV_OK; 664*7fd79137SRobert Mustacchi } 665*7fd79137SRobert Mustacchi break; 666*7fd79137SRobert Mustacchi case DW_FORM_udata: 667*7fd79137SRobert Mustacchi ret_value = 668*7fd79137SRobert Mustacchi (_dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL)); 669*7fd79137SRobert Mustacchi *return_uval = ret_value; 670*7fd79137SRobert Mustacchi return DW_DLV_OK; 671*7fd79137SRobert Mustacchi 672*7fd79137SRobert Mustacchi 673*7fd79137SRobert Mustacchi /* see bug 583450. We do not allow reading sdata from a udata 674*7fd79137SRobert Mustacchi value. Caller can retry, calling sdata */ 675*7fd79137SRobert Mustacchi 676*7fd79137SRobert Mustacchi 677*7fd79137SRobert Mustacchi default: 678*7fd79137SRobert Mustacchi break; 679*7fd79137SRobert Mustacchi } 680*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); 681*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 682*7fd79137SRobert Mustacchi } 683*7fd79137SRobert Mustacchi 684*7fd79137SRobert Mustacchi 685*7fd79137SRobert Mustacchi int 686*7fd79137SRobert Mustacchi dwarf_formsdata(Dwarf_Attribute attr, 687*7fd79137SRobert Mustacchi Dwarf_Signed * return_sval, Dwarf_Error * error) 688*7fd79137SRobert Mustacchi { 689*7fd79137SRobert Mustacchi Dwarf_Signed ret_value = 0; 690*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0; 691*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0; 692*7fd79137SRobert Mustacchi 693*7fd79137SRobert Mustacchi if (attr == NULL) { 694*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); 695*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 696*7fd79137SRobert Mustacchi } 697*7fd79137SRobert Mustacchi 698*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context; 699*7fd79137SRobert Mustacchi if (cu_context == NULL) { 700*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); 701*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 702*7fd79137SRobert Mustacchi } 703*7fd79137SRobert Mustacchi 704*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg; 705*7fd79137SRobert Mustacchi if (dbg == NULL) { 706*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); 707*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 708*7fd79137SRobert Mustacchi } 709*7fd79137SRobert Mustacchi 710*7fd79137SRobert Mustacchi switch (attr->ar_attribute_form) { 711*7fd79137SRobert Mustacchi 712*7fd79137SRobert Mustacchi case DW_FORM_data1: 713*7fd79137SRobert Mustacchi *return_sval = (*(Dwarf_Sbyte *) attr->ar_debug_info_ptr); 714*7fd79137SRobert Mustacchi return DW_DLV_OK; 715*7fd79137SRobert Mustacchi 716*7fd79137SRobert Mustacchi /* READ_UNALIGNED does not sign extend. 717*7fd79137SRobert Mustacchi So we have to use a cast to get the 718*7fd79137SRobert Mustacchi value sign extended in the right way for each case. */ 719*7fd79137SRobert Mustacchi case DW_FORM_data2:{ 720*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Signed, 721*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, 722*7fd79137SRobert Mustacchi sizeof(Dwarf_Shalf)); 723*7fd79137SRobert Mustacchi *return_sval = (Dwarf_Shalf) ret_value; 724*7fd79137SRobert Mustacchi return DW_DLV_OK; 725*7fd79137SRobert Mustacchi 726*7fd79137SRobert Mustacchi } 727*7fd79137SRobert Mustacchi 728*7fd79137SRobert Mustacchi case DW_FORM_data4:{ 729*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Signed, 730*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, 731*7fd79137SRobert Mustacchi sizeof(Dwarf_sfixed)); 732*7fd79137SRobert Mustacchi *return_sval = (Dwarf_sfixed) ret_value; 733*7fd79137SRobert Mustacchi return DW_DLV_OK; 734*7fd79137SRobert Mustacchi } 735*7fd79137SRobert Mustacchi 736*7fd79137SRobert Mustacchi case DW_FORM_data8:{ 737*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, ret_value, Dwarf_Signed, 738*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, 739*7fd79137SRobert Mustacchi sizeof(Dwarf_Signed)); 740*7fd79137SRobert Mustacchi *return_sval = (Dwarf_Signed) ret_value; 741*7fd79137SRobert Mustacchi return DW_DLV_OK; 742*7fd79137SRobert Mustacchi } 743*7fd79137SRobert Mustacchi 744*7fd79137SRobert Mustacchi case DW_FORM_sdata: 745*7fd79137SRobert Mustacchi ret_value = 746*7fd79137SRobert Mustacchi (_dwarf_decode_s_leb128(attr->ar_debug_info_ptr, NULL)); 747*7fd79137SRobert Mustacchi *return_sval = ret_value; 748*7fd79137SRobert Mustacchi return DW_DLV_OK; 749*7fd79137SRobert Mustacchi 750*7fd79137SRobert Mustacchi 751*7fd79137SRobert Mustacchi /* see bug 583450. We do not allow reading sdata from a udata 752*7fd79137SRobert Mustacchi value. Caller can retry, calling sdata */ 753*7fd79137SRobert Mustacchi 754*7fd79137SRobert Mustacchi 755*7fd79137SRobert Mustacchi default: 756*7fd79137SRobert Mustacchi break; 757*7fd79137SRobert Mustacchi } 758*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); 759*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 760*7fd79137SRobert Mustacchi } 761*7fd79137SRobert Mustacchi 762*7fd79137SRobert Mustacchi 763*7fd79137SRobert Mustacchi int 764*7fd79137SRobert Mustacchi dwarf_formblock(Dwarf_Attribute attr, 765*7fd79137SRobert Mustacchi Dwarf_Block ** return_block, Dwarf_Error * error) 766*7fd79137SRobert Mustacchi { 767*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0; 768*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0; 769*7fd79137SRobert Mustacchi Dwarf_Unsigned length = 0; 770*7fd79137SRobert Mustacchi Dwarf_Small *data = 0; 771*7fd79137SRobert Mustacchi Dwarf_Word leb128_length = 0; 772*7fd79137SRobert Mustacchi Dwarf_Block *ret_block = 0; 773*7fd79137SRobert Mustacchi 774*7fd79137SRobert Mustacchi if (attr == NULL) { 775*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); 776*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 777*7fd79137SRobert Mustacchi } 778*7fd79137SRobert Mustacchi 779*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context; 780*7fd79137SRobert Mustacchi if (cu_context == NULL) { 781*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); 782*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 783*7fd79137SRobert Mustacchi } 784*7fd79137SRobert Mustacchi 785*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) { 786*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); 787*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 788*7fd79137SRobert Mustacchi } 789*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg; 790*7fd79137SRobert Mustacchi 791*7fd79137SRobert Mustacchi switch (attr->ar_attribute_form) { 792*7fd79137SRobert Mustacchi 793*7fd79137SRobert Mustacchi case DW_FORM_block1: 794*7fd79137SRobert Mustacchi length = *(Dwarf_Small *) attr->ar_debug_info_ptr; 795*7fd79137SRobert Mustacchi data = attr->ar_debug_info_ptr + sizeof(Dwarf_Small); 796*7fd79137SRobert Mustacchi break; 797*7fd79137SRobert Mustacchi 798*7fd79137SRobert Mustacchi case DW_FORM_block2: 799*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, length, Dwarf_Unsigned, 800*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_Half)); 801*7fd79137SRobert Mustacchi data = attr->ar_debug_info_ptr + sizeof(Dwarf_Half); 802*7fd79137SRobert Mustacchi break; 803*7fd79137SRobert Mustacchi 804*7fd79137SRobert Mustacchi case DW_FORM_block4: 805*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, length, Dwarf_Unsigned, 806*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, sizeof(Dwarf_ufixed)); 807*7fd79137SRobert Mustacchi data = attr->ar_debug_info_ptr + sizeof(Dwarf_ufixed); 808*7fd79137SRobert Mustacchi break; 809*7fd79137SRobert Mustacchi 810*7fd79137SRobert Mustacchi case DW_FORM_block: 811*7fd79137SRobert Mustacchi length = _dwarf_decode_u_leb128(attr->ar_debug_info_ptr, 812*7fd79137SRobert Mustacchi &leb128_length); 813*7fd79137SRobert Mustacchi data = attr->ar_debug_info_ptr + leb128_length; 814*7fd79137SRobert Mustacchi break; 815*7fd79137SRobert Mustacchi 816*7fd79137SRobert Mustacchi default: 817*7fd79137SRobert Mustacchi _dwarf_error(cu_context->cc_dbg, error, DW_DLE_ATTR_FORM_BAD); 818*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 819*7fd79137SRobert Mustacchi } 820*7fd79137SRobert Mustacchi 821*7fd79137SRobert Mustacchi /* Check that block lies within current cu in .debug_info. */ 822*7fd79137SRobert Mustacchi if (attr->ar_debug_info_ptr + length >= 823*7fd79137SRobert Mustacchi dbg->de_debug_info.dss_data + cu_context->cc_debug_info_offset + 824*7fd79137SRobert Mustacchi cu_context->cc_length + cu_context->cc_length_size + 825*7fd79137SRobert Mustacchi cu_context->cc_extension_size) { 826*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD); 827*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 828*7fd79137SRobert Mustacchi } 829*7fd79137SRobert Mustacchi 830*7fd79137SRobert Mustacchi ret_block = (Dwarf_Block *) _dwarf_get_alloc(dbg, DW_DLA_BLOCK, 1); 831*7fd79137SRobert Mustacchi if (ret_block == NULL) { 832*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ALLOC_FAIL); 833*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 834*7fd79137SRobert Mustacchi } 835*7fd79137SRobert Mustacchi 836*7fd79137SRobert Mustacchi ret_block->bl_len = length; 837*7fd79137SRobert Mustacchi ret_block->bl_data = (Dwarf_Ptr) data; 838*7fd79137SRobert Mustacchi ret_block->bl_from_loclist = 0; 839*7fd79137SRobert Mustacchi ret_block->bl_section_offset = data - dbg->de_debug_info.dss_data; 840*7fd79137SRobert Mustacchi 841*7fd79137SRobert Mustacchi 842*7fd79137SRobert Mustacchi *return_block = ret_block; 843*7fd79137SRobert Mustacchi return (DW_DLV_OK); 844*7fd79137SRobert Mustacchi } 845*7fd79137SRobert Mustacchi 846*7fd79137SRobert Mustacchi 847*7fd79137SRobert Mustacchi /* Contrary to long standing documentation, 848*7fd79137SRobert Mustacchi The string pointer returned thru return_str must 849*7fd79137SRobert Mustacchi never have dwarf_dealloc() applied to it. 850*7fd79137SRobert Mustacchi Documentation fixed July 2005. 851*7fd79137SRobert Mustacchi */ 852*7fd79137SRobert Mustacchi int 853*7fd79137SRobert Mustacchi dwarf_formstring(Dwarf_Attribute attr, 854*7fd79137SRobert Mustacchi char **return_str, Dwarf_Error * error) 855*7fd79137SRobert Mustacchi { 856*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0; 857*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0; 858*7fd79137SRobert Mustacchi Dwarf_Unsigned offset = 0; 859*7fd79137SRobert Mustacchi int res = DW_DLV_ERROR; 860*7fd79137SRobert Mustacchi 861*7fd79137SRobert Mustacchi if (attr == NULL) { 862*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); 863*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 864*7fd79137SRobert Mustacchi } 865*7fd79137SRobert Mustacchi 866*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context; 867*7fd79137SRobert Mustacchi if (cu_context == NULL) { 868*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); 869*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 870*7fd79137SRobert Mustacchi } 871*7fd79137SRobert Mustacchi 872*7fd79137SRobert Mustacchi if (cu_context->cc_dbg == NULL) { 873*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); 874*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 875*7fd79137SRobert Mustacchi } 876*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg; 877*7fd79137SRobert Mustacchi 878*7fd79137SRobert Mustacchi if (attr->ar_attribute_form == DW_FORM_string) { 879*7fd79137SRobert Mustacchi 880*7fd79137SRobert Mustacchi void *begin = attr->ar_debug_info_ptr; 881*7fd79137SRobert Mustacchi 882*7fd79137SRobert Mustacchi if (0 == dbg->de_assume_string_in_bounds) { 883*7fd79137SRobert Mustacchi /* Check that string lies within current cu in .debug_info. 884*7fd79137SRobert Mustacchi */ 885*7fd79137SRobert Mustacchi void *end = dbg->de_debug_info.dss_data + 886*7fd79137SRobert Mustacchi cu_context->cc_debug_info_offset + 887*7fd79137SRobert Mustacchi cu_context->cc_length + cu_context->cc_length_size + 888*7fd79137SRobert Mustacchi cu_context->cc_extension_size; 889*7fd79137SRobert Mustacchi if (0 == _dwarf_string_valid(begin, end)) { 890*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_SIZE_BAD); 891*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 892*7fd79137SRobert Mustacchi } 893*7fd79137SRobert Mustacchi } 894*7fd79137SRobert Mustacchi *return_str = (char *) (begin); 895*7fd79137SRobert Mustacchi return DW_DLV_OK; 896*7fd79137SRobert Mustacchi } 897*7fd79137SRobert Mustacchi 898*7fd79137SRobert Mustacchi if (attr->ar_attribute_form == DW_FORM_strp) { 899*7fd79137SRobert Mustacchi READ_UNALIGNED(dbg, offset, Dwarf_Unsigned, 900*7fd79137SRobert Mustacchi attr->ar_debug_info_ptr, 901*7fd79137SRobert Mustacchi cu_context->cc_length_size); 902*7fd79137SRobert Mustacchi 903*7fd79137SRobert Mustacchi res = _dwarf_load_section(dbg, &dbg->de_debug_str,error); 904*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 905*7fd79137SRobert Mustacchi return res; 906*7fd79137SRobert Mustacchi } 907*7fd79137SRobert Mustacchi if (0 == dbg->de_assume_string_in_bounds) { 908*7fd79137SRobert Mustacchi /* Check that string lies within current cu in .debug_info. 909*7fd79137SRobert Mustacchi */ 910*7fd79137SRobert Mustacchi void *end = dbg->de_debug_str.dss_data + 911*7fd79137SRobert Mustacchi dbg->de_debug_str.dss_size; 912*7fd79137SRobert Mustacchi void*begin = dbg->de_debug_str.dss_data + offset; 913*7fd79137SRobert Mustacchi if (0 == _dwarf_string_valid(begin, end)) { 914*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_STRP_OFFSET_BAD); 915*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 916*7fd79137SRobert Mustacchi } 917*7fd79137SRobert Mustacchi } 918*7fd79137SRobert Mustacchi *return_str = (char *) (dbg->de_debug_str.dss_data + offset); 919*7fd79137SRobert Mustacchi return DW_DLV_OK; 920*7fd79137SRobert Mustacchi } 921*7fd79137SRobert Mustacchi 922*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_FORM_BAD); 923*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 924*7fd79137SRobert Mustacchi } 925*7fd79137SRobert Mustacchi 926*7fd79137SRobert Mustacchi int 927*7fd79137SRobert Mustacchi dwarf_formexprloc(Dwarf_Attribute attr, 928*7fd79137SRobert Mustacchi Dwarf_Unsigned * return_exprlen, 929*7fd79137SRobert Mustacchi Dwarf_Ptr * block_ptr, 930*7fd79137SRobert Mustacchi Dwarf_Error * error) 931*7fd79137SRobert Mustacchi { 932*7fd79137SRobert Mustacchi Dwarf_Debug dbg = 0; 933*7fd79137SRobert Mustacchi Dwarf_CU_Context cu_context = 0; 934*7fd79137SRobert Mustacchi 935*7fd79137SRobert Mustacchi if (attr == NULL) { 936*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NULL); 937*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 938*7fd79137SRobert Mustacchi } 939*7fd79137SRobert Mustacchi 940*7fd79137SRobert Mustacchi cu_context = attr->ar_cu_context; 941*7fd79137SRobert Mustacchi if (cu_context == NULL) { 942*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_NO_CU_CONTEXT); 943*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 944*7fd79137SRobert Mustacchi } 945*7fd79137SRobert Mustacchi 946*7fd79137SRobert Mustacchi dbg = cu_context->cc_dbg; 947*7fd79137SRobert Mustacchi if (dbg == NULL) { 948*7fd79137SRobert Mustacchi _dwarf_error(NULL, error, DW_DLE_ATTR_DBG_NULL); 949*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 950*7fd79137SRobert Mustacchi } 951*7fd79137SRobert Mustacchi 952*7fd79137SRobert Mustacchi if (attr->ar_attribute_form == DW_FORM_exprloc ) { 953*7fd79137SRobert Mustacchi Dwarf_Unsigned exprlen = 954*7fd79137SRobert Mustacchi (_dwarf_decode_u_leb128(attr->ar_debug_info_ptr, NULL)); 955*7fd79137SRobert Mustacchi Dwarf_Small * addr = attr->ar_debug_info_ptr; 956*7fd79137SRobert Mustacchi *return_exprlen = exprlen; 957*7fd79137SRobert Mustacchi *block_ptr = addr + exprlen; 958*7fd79137SRobert Mustacchi return DW_DLV_OK; 959*7fd79137SRobert Mustacchi 960*7fd79137SRobert Mustacchi } 961*7fd79137SRobert Mustacchi _dwarf_error(dbg, error, DW_DLE_ATTR_EXPRLOC_FORM_BAD); 962*7fd79137SRobert Mustacchi return (DW_DLV_ERROR); 963*7fd79137SRobert Mustacchi } 964