1*7fd79137SRobert Mustacchi /* 2*7fd79137SRobert Mustacchi Copyright (C) 2000,2004 Silicon Graphics, Inc. All Rights Reserved. 3*7fd79137SRobert Mustacchi Portions Copyright 2002-2010 Sun Microsystems, Inc. All rights reserved. 4*7fd79137SRobert Mustacchi Portions Copyright 2007-2010 David Anderson. All rights reserved. 5*7fd79137SRobert Mustacchi 6*7fd79137SRobert Mustacchi This program is free software; you can redistribute it and/or modify it 7*7fd79137SRobert Mustacchi under the terms of version 2.1 of the GNU Lesser General Public License 8*7fd79137SRobert Mustacchi as published by the Free Software Foundation. 9*7fd79137SRobert Mustacchi 10*7fd79137SRobert Mustacchi This program is distributed in the hope that it would be useful, but 11*7fd79137SRobert Mustacchi WITHOUT ANY WARRANTY; without even the implied warranty of 12*7fd79137SRobert Mustacchi MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. 13*7fd79137SRobert Mustacchi 14*7fd79137SRobert Mustacchi Further, this software is distributed without any warranty that it is 15*7fd79137SRobert Mustacchi free of the rightful claim of any third person regarding infringement 16*7fd79137SRobert Mustacchi or the like. Any license provided herein, whether implied or 17*7fd79137SRobert Mustacchi otherwise, applies only to this software file. Patent licenses, if 18*7fd79137SRobert Mustacchi any, provided herein do not apply to combinations of this program with 19*7fd79137SRobert Mustacchi other software, or any other product whatsoever. 20*7fd79137SRobert Mustacchi 21*7fd79137SRobert Mustacchi You should have received a copy of the GNU Lesser General Public 22*7fd79137SRobert Mustacchi License along with this program; if not, write the Free Software 23*7fd79137SRobert Mustacchi Foundation, Inc., 51 Franklin Street - Fifth Floor, Boston MA 02110-1301, 24*7fd79137SRobert Mustacchi USA. 25*7fd79137SRobert Mustacchi 26*7fd79137SRobert Mustacchi Contact information: Silicon Graphics, Inc., 1500 Crittenden Lane, 27*7fd79137SRobert Mustacchi Mountain View, CA 94043, or: 28*7fd79137SRobert Mustacchi 29*7fd79137SRobert Mustacchi http://www.sgi.com 30*7fd79137SRobert Mustacchi 31*7fd79137SRobert Mustacchi For further information regarding this notice, see: 32*7fd79137SRobert Mustacchi 33*7fd79137SRobert Mustacchi http://oss.sgi.com/projects/GenInfo/NoticeExplan 34*7fd79137SRobert Mustacchi 35*7fd79137SRobert Mustacchi */ 36*7fd79137SRobert Mustacchi 37*7fd79137SRobert Mustacchi 38*7fd79137SRobert Mustacchi 39*7fd79137SRobert Mustacchi #include "config.h" 40*7fd79137SRobert Mustacchi #include "libdwarfdefs.h" 41*7fd79137SRobert Mustacchi #include <stdio.h> 42*7fd79137SRobert Mustacchi #include <string.h> 43*7fd79137SRobert Mustacchi #include <limits.h> 44*7fd79137SRobert Mustacchi #include "pro_incl.h" 45*7fd79137SRobert Mustacchi #include "pro_expr.h" 46*7fd79137SRobert Mustacchi 47*7fd79137SRobert Mustacchi #ifndef R_MIPS_NONE 48*7fd79137SRobert Mustacchi #define R_MIPS_NONE 0 49*7fd79137SRobert Mustacchi #endif 50*7fd79137SRobert Mustacchi 51*7fd79137SRobert Mustacchi 52*7fd79137SRobert Mustacchi /* Indicates no relocation needed. */ 53*7fd79137SRobert Mustacchi #define NO_ELF_SYM_INDEX 0 54*7fd79137SRobert Mustacchi 55*7fd79137SRobert Mustacchi 56*7fd79137SRobert Mustacchi /* adds an attribute to a die */ 57*7fd79137SRobert Mustacchi extern void _dwarf_pro_add_at_to_die(Dwarf_P_Die die, 58*7fd79137SRobert Mustacchi Dwarf_P_Attribute attr); 59*7fd79137SRobert Mustacchi 60*7fd79137SRobert Mustacchi /* 61*7fd79137SRobert Mustacchi This function adds an attribute whose value is 62*7fd79137SRobert Mustacchi a target address to the given die. The attribute 63*7fd79137SRobert Mustacchi is given the name provided by attr. The address 64*7fd79137SRobert Mustacchi is given in pc_value. 65*7fd79137SRobert Mustacchi */ 66*7fd79137SRobert Mustacchi 67*7fd79137SRobert Mustacchi static Dwarf_P_Attribute 68*7fd79137SRobert Mustacchi local_add_AT_address(Dwarf_P_Debug dbg, 69*7fd79137SRobert Mustacchi Dwarf_P_Die ownerdie, 70*7fd79137SRobert Mustacchi Dwarf_Half attr, 71*7fd79137SRobert Mustacchi Dwarf_Signed form, 72*7fd79137SRobert Mustacchi Dwarf_Unsigned pc_value, 73*7fd79137SRobert Mustacchi Dwarf_Unsigned sym_index, 74*7fd79137SRobert Mustacchi Dwarf_Error * error); 75*7fd79137SRobert Mustacchi 76*7fd79137SRobert Mustacchi /* old interface */ 77*7fd79137SRobert Mustacchi Dwarf_P_Attribute 78*7fd79137SRobert Mustacchi dwarf_add_AT_targ_address(Dwarf_P_Debug dbg, 79*7fd79137SRobert Mustacchi Dwarf_P_Die ownerdie, 80*7fd79137SRobert Mustacchi Dwarf_Half attr, 81*7fd79137SRobert Mustacchi Dwarf_Unsigned pc_value, 82*7fd79137SRobert Mustacchi Dwarf_Signed sym_index, Dwarf_Error * error) 83*7fd79137SRobert Mustacchi { 84*7fd79137SRobert Mustacchi return 85*7fd79137SRobert Mustacchi dwarf_add_AT_targ_address_b(dbg, 86*7fd79137SRobert Mustacchi ownerdie, 87*7fd79137SRobert Mustacchi attr, 88*7fd79137SRobert Mustacchi pc_value, 89*7fd79137SRobert Mustacchi (Dwarf_Unsigned) sym_index, error); 90*7fd79137SRobert Mustacchi } 91*7fd79137SRobert Mustacchi 92*7fd79137SRobert Mustacchi /* New interface, replacing dwarf_add_AT_targ_address. 93*7fd79137SRobert Mustacchi Essentially just makes sym_index a Dwarf_Unsigned 94*7fd79137SRobert Mustacchi so for symbolic relocations it can be a full address. 95*7fd79137SRobert Mustacchi */ 96*7fd79137SRobert Mustacchi Dwarf_P_Attribute 97*7fd79137SRobert Mustacchi dwarf_add_AT_targ_address_b(Dwarf_P_Debug dbg, 98*7fd79137SRobert Mustacchi Dwarf_P_Die ownerdie, 99*7fd79137SRobert Mustacchi Dwarf_Half attr, 100*7fd79137SRobert Mustacchi Dwarf_Unsigned pc_value, 101*7fd79137SRobert Mustacchi Dwarf_Unsigned sym_index, 102*7fd79137SRobert Mustacchi Dwarf_Error * error) 103*7fd79137SRobert Mustacchi { 104*7fd79137SRobert Mustacchi switch (attr) { 105*7fd79137SRobert Mustacchi case DW_AT_low_pc: 106*7fd79137SRobert Mustacchi case DW_AT_high_pc: 107*7fd79137SRobert Mustacchi 108*7fd79137SRobert Mustacchi /* added to support location lists */ 109*7fd79137SRobert Mustacchi /* no way to check that this is a loclist-style address though */ 110*7fd79137SRobert Mustacchi case DW_AT_location: 111*7fd79137SRobert Mustacchi case DW_AT_string_length: 112*7fd79137SRobert Mustacchi case DW_AT_return_addr: 113*7fd79137SRobert Mustacchi case DW_AT_frame_base: 114*7fd79137SRobert Mustacchi case DW_AT_segment: 115*7fd79137SRobert Mustacchi case DW_AT_static_link: 116*7fd79137SRobert Mustacchi case DW_AT_use_location: 117*7fd79137SRobert Mustacchi case DW_AT_vtable_elem_location: 118*7fd79137SRobert Mustacchi case DW_AT_const_value: /* Gcc can generate this as address. */ 119*7fd79137SRobert Mustacchi case DW_AT_entry_pc: 120*7fd79137SRobert Mustacchi break; 121*7fd79137SRobert Mustacchi default: 122*7fd79137SRobert Mustacchi if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { 123*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); 124*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 125*7fd79137SRobert Mustacchi } 126*7fd79137SRobert Mustacchi break; 127*7fd79137SRobert Mustacchi } 128*7fd79137SRobert Mustacchi 129*7fd79137SRobert Mustacchi return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_addr, 130*7fd79137SRobert Mustacchi pc_value, sym_index, error); 131*7fd79137SRobert Mustacchi } 132*7fd79137SRobert Mustacchi 133*7fd79137SRobert Mustacchi Dwarf_P_Attribute 134*7fd79137SRobert Mustacchi dwarf_add_AT_ref_address(Dwarf_P_Debug dbg, 135*7fd79137SRobert Mustacchi Dwarf_P_Die ownerdie, 136*7fd79137SRobert Mustacchi Dwarf_Half attr, 137*7fd79137SRobert Mustacchi Dwarf_Unsigned pc_value, 138*7fd79137SRobert Mustacchi Dwarf_Unsigned sym_index, 139*7fd79137SRobert Mustacchi Dwarf_Error * error) 140*7fd79137SRobert Mustacchi { 141*7fd79137SRobert Mustacchi switch (attr) { 142*7fd79137SRobert Mustacchi case DW_AT_type: 143*7fd79137SRobert Mustacchi case DW_AT_import: 144*7fd79137SRobert Mustacchi break; 145*7fd79137SRobert Mustacchi 146*7fd79137SRobert Mustacchi default: 147*7fd79137SRobert Mustacchi if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { 148*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); 149*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 150*7fd79137SRobert Mustacchi } 151*7fd79137SRobert Mustacchi break; 152*7fd79137SRobert Mustacchi } 153*7fd79137SRobert Mustacchi 154*7fd79137SRobert Mustacchi return local_add_AT_address(dbg, ownerdie, attr, DW_FORM_ref_addr, 155*7fd79137SRobert Mustacchi pc_value, sym_index, error); 156*7fd79137SRobert Mustacchi } 157*7fd79137SRobert Mustacchi 158*7fd79137SRobert Mustacchi 159*7fd79137SRobert Mustacchi /* Make sure attribute types are checked before entering here. */ 160*7fd79137SRobert Mustacchi static Dwarf_P_Attribute 161*7fd79137SRobert Mustacchi local_add_AT_address(Dwarf_P_Debug dbg, 162*7fd79137SRobert Mustacchi Dwarf_P_Die ownerdie, 163*7fd79137SRobert Mustacchi Dwarf_Half attr, 164*7fd79137SRobert Mustacchi Dwarf_Signed form, 165*7fd79137SRobert Mustacchi Dwarf_Unsigned pc_value, 166*7fd79137SRobert Mustacchi Dwarf_Unsigned sym_index, 167*7fd79137SRobert Mustacchi Dwarf_Error * error) 168*7fd79137SRobert Mustacchi { 169*7fd79137SRobert Mustacchi Dwarf_P_Attribute new_attr; 170*7fd79137SRobert Mustacchi int upointer_size = dbg->de_pointer_size; 171*7fd79137SRobert Mustacchi 172*7fd79137SRobert Mustacchi if (dbg == NULL) { 173*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 174*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 175*7fd79137SRobert Mustacchi } 176*7fd79137SRobert Mustacchi 177*7fd79137SRobert Mustacchi if (ownerdie == NULL) { 178*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); 179*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 180*7fd79137SRobert Mustacchi } 181*7fd79137SRobert Mustacchi 182*7fd79137SRobert Mustacchi /* attribute types have already been checked */ 183*7fd79137SRobert Mustacchi /* switch (attr) { ... } */ 184*7fd79137SRobert Mustacchi 185*7fd79137SRobert Mustacchi new_attr = (Dwarf_P_Attribute) 186*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); 187*7fd79137SRobert Mustacchi if (new_attr == NULL) { 188*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 189*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 190*7fd79137SRobert Mustacchi } 191*7fd79137SRobert Mustacchi 192*7fd79137SRobert Mustacchi new_attr->ar_attribute = attr; 193*7fd79137SRobert Mustacchi new_attr->ar_attribute_form = form; 194*7fd79137SRobert Mustacchi new_attr->ar_nbytes = upointer_size; 195*7fd79137SRobert Mustacchi new_attr->ar_rel_symidx = sym_index; 196*7fd79137SRobert Mustacchi new_attr->ar_reloc_len = upointer_size; 197*7fd79137SRobert Mustacchi new_attr->ar_next = 0; 198*7fd79137SRobert Mustacchi if (sym_index != NO_ELF_SYM_INDEX) 199*7fd79137SRobert Mustacchi new_attr->ar_rel_type = dbg->de_ptr_reloc; 200*7fd79137SRobert Mustacchi else 201*7fd79137SRobert Mustacchi new_attr->ar_rel_type = R_MIPS_NONE; 202*7fd79137SRobert Mustacchi 203*7fd79137SRobert Mustacchi new_attr->ar_data = (char *) 204*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, upointer_size); 205*7fd79137SRobert Mustacchi if (new_attr->ar_data == NULL) { 206*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 207*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 208*7fd79137SRobert Mustacchi } 209*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, new_attr->ar_data, 210*7fd79137SRobert Mustacchi (const void *) &pc_value, 211*7fd79137SRobert Mustacchi sizeof(pc_value), upointer_size); 212*7fd79137SRobert Mustacchi 213*7fd79137SRobert Mustacchi /* add attribute to the die */ 214*7fd79137SRobert Mustacchi _dwarf_pro_add_at_to_die(ownerdie, new_attr); 215*7fd79137SRobert Mustacchi return new_attr; 216*7fd79137SRobert Mustacchi } 217*7fd79137SRobert Mustacchi 218*7fd79137SRobert Mustacchi /* 219*7fd79137SRobert Mustacchi * Functions to compress and uncompress data from normal 220*7fd79137SRobert Mustacchi * arrays of integral types into arrays of LEB128 numbers. 221*7fd79137SRobert Mustacchi * Extend these functions as needed to handle wider input 222*7fd79137SRobert Mustacchi * variety. Return values should be freed with _dwarf_p_dealloc 223*7fd79137SRobert Mustacchi * after they aren't needed any more. 224*7fd79137SRobert Mustacchi */ 225*7fd79137SRobert Mustacchi 226*7fd79137SRobert Mustacchi /* return value points to an array of LEB number */ 227*7fd79137SRobert Mustacchi 228*7fd79137SRobert Mustacchi void * 229*7fd79137SRobert Mustacchi dwarf_compress_integer_block( 230*7fd79137SRobert Mustacchi Dwarf_P_Debug dbg, 231*7fd79137SRobert Mustacchi Dwarf_Bool unit_is_signed, 232*7fd79137SRobert Mustacchi Dwarf_Small unit_length_in_bits, 233*7fd79137SRobert Mustacchi void* input_block, 234*7fd79137SRobert Mustacchi Dwarf_Unsigned input_length_in_units, 235*7fd79137SRobert Mustacchi Dwarf_Unsigned* output_length_in_bytes_ptr, 236*7fd79137SRobert Mustacchi Dwarf_Error* error 237*7fd79137SRobert Mustacchi ) 238*7fd79137SRobert Mustacchi { 239*7fd79137SRobert Mustacchi Dwarf_Unsigned output_length_in_bytes = 0; 240*7fd79137SRobert Mustacchi char * output_block = 0; 241*7fd79137SRobert Mustacchi char encode_buffer[ENCODE_SPACE_NEEDED]; 242*7fd79137SRobert Mustacchi int i = 0; 243*7fd79137SRobert Mustacchi char * ptr = 0; 244*7fd79137SRobert Mustacchi int remain = 0; 245*7fd79137SRobert Mustacchi int result = 0; 246*7fd79137SRobert Mustacchi 247*7fd79137SRobert Mustacchi if (dbg == NULL) { 248*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 249*7fd79137SRobert Mustacchi return((void *)DW_DLV_BADADDR); 250*7fd79137SRobert Mustacchi } 251*7fd79137SRobert Mustacchi 252*7fd79137SRobert Mustacchi if (unit_is_signed == false || 253*7fd79137SRobert Mustacchi unit_length_in_bits != 32 || 254*7fd79137SRobert Mustacchi input_block == NULL || 255*7fd79137SRobert Mustacchi input_length_in_units == 0 || 256*7fd79137SRobert Mustacchi output_length_in_bytes_ptr == NULL) { 257*7fd79137SRobert Mustacchi 258*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_BADBITC); 259*7fd79137SRobert Mustacchi return ((void *) DW_DLV_BADADDR); 260*7fd79137SRobert Mustacchi } 261*7fd79137SRobert Mustacchi 262*7fd79137SRobert Mustacchi /* At this point we assume the format is: signed 32 bit */ 263*7fd79137SRobert Mustacchi 264*7fd79137SRobert Mustacchi /* first compress everything to find the total size. */ 265*7fd79137SRobert Mustacchi 266*7fd79137SRobert Mustacchi output_length_in_bytes = 0; 267*7fd79137SRobert Mustacchi for (i=0; i<input_length_in_units; i++) { 268*7fd79137SRobert Mustacchi int unit_encoded_size; 269*7fd79137SRobert Mustacchi Dwarf_sfixed unit; /* this is fixed at signed-32-bits */ 270*7fd79137SRobert Mustacchi 271*7fd79137SRobert Mustacchi unit = ((Dwarf_sfixed*)input_block)[i]; 272*7fd79137SRobert Mustacchi 273*7fd79137SRobert Mustacchi result = _dwarf_pro_encode_signed_leb128_nm(unit, &unit_encoded_size, 274*7fd79137SRobert Mustacchi encode_buffer,sizeof(encode_buffer)); 275*7fd79137SRobert Mustacchi if (result != DW_DLV_OK) { 276*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 277*7fd79137SRobert Mustacchi return((Dwarf_P_Attribute)DW_DLV_BADADDR); 278*7fd79137SRobert Mustacchi } 279*7fd79137SRobert Mustacchi output_length_in_bytes += unit_encoded_size; 280*7fd79137SRobert Mustacchi } 281*7fd79137SRobert Mustacchi 282*7fd79137SRobert Mustacchi 283*7fd79137SRobert Mustacchi /* then alloc */ 284*7fd79137SRobert Mustacchi 285*7fd79137SRobert Mustacchi output_block = (void *) 286*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, output_length_in_bytes); 287*7fd79137SRobert Mustacchi if (output_block == NULL) { 288*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 289*7fd79137SRobert Mustacchi return((void*)DW_DLV_BADADDR); 290*7fd79137SRobert Mustacchi } 291*7fd79137SRobert Mustacchi 292*7fd79137SRobert Mustacchi /* then compress again and copy into new buffer */ 293*7fd79137SRobert Mustacchi 294*7fd79137SRobert Mustacchi ptr = output_block; 295*7fd79137SRobert Mustacchi remain = output_length_in_bytes; 296*7fd79137SRobert Mustacchi for (i=0; i<input_length_in_units; i++) { 297*7fd79137SRobert Mustacchi int unit_encoded_size; 298*7fd79137SRobert Mustacchi Dwarf_sfixed unit; /* this is fixed at signed-32-bits */ 299*7fd79137SRobert Mustacchi 300*7fd79137SRobert Mustacchi unit = ((Dwarf_sfixed*)input_block)[i]; 301*7fd79137SRobert Mustacchi 302*7fd79137SRobert Mustacchi result = _dwarf_pro_encode_signed_leb128_nm(unit, &unit_encoded_size, 303*7fd79137SRobert Mustacchi ptr, remain); 304*7fd79137SRobert Mustacchi if (result != DW_DLV_OK) { 305*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 306*7fd79137SRobert Mustacchi return((Dwarf_P_Attribute)DW_DLV_BADADDR); 307*7fd79137SRobert Mustacchi } 308*7fd79137SRobert Mustacchi remain -= unit_encoded_size; 309*7fd79137SRobert Mustacchi ptr += unit_encoded_size; 310*7fd79137SRobert Mustacchi } 311*7fd79137SRobert Mustacchi 312*7fd79137SRobert Mustacchi if (remain != 0) { 313*7fd79137SRobert Mustacchi _dwarf_p_dealloc(dbg, (unsigned char *)output_block); 314*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 315*7fd79137SRobert Mustacchi return((Dwarf_P_Attribute)DW_DLV_BADADDR); 316*7fd79137SRobert Mustacchi } 317*7fd79137SRobert Mustacchi 318*7fd79137SRobert Mustacchi *output_length_in_bytes_ptr = output_length_in_bytes; 319*7fd79137SRobert Mustacchi return (void*) output_block; 320*7fd79137SRobert Mustacchi 321*7fd79137SRobert Mustacchi } 322*7fd79137SRobert Mustacchi 323*7fd79137SRobert Mustacchi void 324*7fd79137SRobert Mustacchi dwarf_dealloc_compressed_block(Dwarf_P_Debug dbg, void * space) 325*7fd79137SRobert Mustacchi { 326*7fd79137SRobert Mustacchi _dwarf_p_dealloc(dbg, space); 327*7fd79137SRobert Mustacchi } 328*7fd79137SRobert Mustacchi 329*7fd79137SRobert Mustacchi /* This is very similar to targ_address but results in a different FORM */ 330*7fd79137SRobert Mustacchi /* dbg->de_ar_data_attribute_form is data4 or data8 331*7fd79137SRobert Mustacchi and dwarf4 changes the definition for such on DW_AT_high_pc. 332*7fd79137SRobert Mustacchi DWARF 3: the FORM here has no defined meaning for dwarf3. 333*7fd79137SRobert Mustacchi DWARF 4: the FORM here means that for DW_AT_high_pc the value 334*7fd79137SRobert Mustacchi is not a high address but is instead an offset 335*7fd79137SRobert Mustacchi from a (separate) DW_AT_low_pc. 336*7fd79137SRobert Mustacchi The intent for DWARF4 is that this is not a relocated 337*7fd79137SRobert Mustacchi address at all. Instead a simple offset. 338*7fd79137SRobert Mustacchi But this should NOT be called for a simple non-relocated offset. 339*7fd79137SRobert Mustacchi So do not call this with an attr of DW_AT_high_pc. 340*7fd79137SRobert Mustacchi Use dwarf_add_AT_unsigned_const() (for example) instead of 341*7fd79137SRobert Mustacchi dwarf_add_AT_dataref when the value is a simple offset . 342*7fd79137SRobert Mustacchi */ 343*7fd79137SRobert Mustacchi Dwarf_P_Attribute 344*7fd79137SRobert Mustacchi dwarf_add_AT_dataref( 345*7fd79137SRobert Mustacchi Dwarf_P_Debug dbg, 346*7fd79137SRobert Mustacchi Dwarf_P_Die ownerdie, 347*7fd79137SRobert Mustacchi Dwarf_Half attr, 348*7fd79137SRobert Mustacchi Dwarf_Unsigned pc_value, 349*7fd79137SRobert Mustacchi Dwarf_Unsigned sym_index, 350*7fd79137SRobert Mustacchi Dwarf_Error * error) 351*7fd79137SRobert Mustacchi { 352*7fd79137SRobert Mustacchi /* TODO: Add checking here */ 353*7fd79137SRobert Mustacchi return local_add_AT_address(dbg, ownerdie, attr, 354*7fd79137SRobert Mustacchi dbg->de_ar_data_attribute_form, 355*7fd79137SRobert Mustacchi pc_value, 356*7fd79137SRobert Mustacchi sym_index, 357*7fd79137SRobert Mustacchi error); 358*7fd79137SRobert Mustacchi } 359*7fd79137SRobert Mustacchi 360*7fd79137SRobert Mustacchi 361*7fd79137SRobert Mustacchi 362*7fd79137SRobert Mustacchi Dwarf_P_Attribute 363*7fd79137SRobert Mustacchi dwarf_add_AT_block( 364*7fd79137SRobert Mustacchi Dwarf_P_Debug dbg, 365*7fd79137SRobert Mustacchi Dwarf_P_Die ownerdie, 366*7fd79137SRobert Mustacchi Dwarf_Half attr, 367*7fd79137SRobert Mustacchi Dwarf_Small *block_data, 368*7fd79137SRobert Mustacchi Dwarf_Unsigned block_size, 369*7fd79137SRobert Mustacchi Dwarf_Error *error 370*7fd79137SRobert Mustacchi ) 371*7fd79137SRobert Mustacchi { 372*7fd79137SRobert Mustacchi Dwarf_P_Attribute new_attr; 373*7fd79137SRobert Mustacchi int result; 374*7fd79137SRobert Mustacchi char encode_buffer[ENCODE_SPACE_NEEDED]; 375*7fd79137SRobert Mustacchi int len_size; 376*7fd79137SRobert Mustacchi char * attrdata; 377*7fd79137SRobert Mustacchi 378*7fd79137SRobert Mustacchi if (dbg == NULL) { 379*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 380*7fd79137SRobert Mustacchi return((Dwarf_P_Attribute)DW_DLV_BADADDR); 381*7fd79137SRobert Mustacchi } 382*7fd79137SRobert Mustacchi 383*7fd79137SRobert Mustacchi if (ownerdie == NULL) { 384*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); 385*7fd79137SRobert Mustacchi return((Dwarf_P_Attribute)DW_DLV_BADADDR); 386*7fd79137SRobert Mustacchi } 387*7fd79137SRobert Mustacchi 388*7fd79137SRobert Mustacchi /* I don't mess with block1, block2, block4, not worth the effort */ 389*7fd79137SRobert Mustacchi 390*7fd79137SRobert Mustacchi /* So, encode the length into LEB128 */ 391*7fd79137SRobert Mustacchi result = _dwarf_pro_encode_leb128_nm(block_size, &len_size, 392*7fd79137SRobert Mustacchi encode_buffer,sizeof(encode_buffer)); 393*7fd79137SRobert Mustacchi if (result != DW_DLV_OK) { 394*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 395*7fd79137SRobert Mustacchi return((Dwarf_P_Attribute)DW_DLV_BADADDR); 396*7fd79137SRobert Mustacchi } 397*7fd79137SRobert Mustacchi 398*7fd79137SRobert Mustacchi /* Allocate the new attribute */ 399*7fd79137SRobert Mustacchi new_attr = (Dwarf_P_Attribute) 400*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); 401*7fd79137SRobert Mustacchi if (new_attr == NULL) { 402*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 403*7fd79137SRobert Mustacchi return((Dwarf_P_Attribute)DW_DLV_BADADDR); 404*7fd79137SRobert Mustacchi } 405*7fd79137SRobert Mustacchi 406*7fd79137SRobert Mustacchi /* Fill in the attribute */ 407*7fd79137SRobert Mustacchi new_attr->ar_attribute = attr; 408*7fd79137SRobert Mustacchi new_attr->ar_attribute_form = DW_FORM_block; 409*7fd79137SRobert Mustacchi new_attr->ar_nbytes = len_size + block_size; 410*7fd79137SRobert Mustacchi new_attr->ar_next = 0; 411*7fd79137SRobert Mustacchi 412*7fd79137SRobert Mustacchi new_attr->ar_data = attrdata = (char *) 413*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, len_size + block_size); 414*7fd79137SRobert Mustacchi if (new_attr->ar_data == NULL) { 415*7fd79137SRobert Mustacchi /* free the block we got earlier */ 416*7fd79137SRobert Mustacchi _dwarf_p_dealloc(dbg, (unsigned char *) new_attr); 417*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 418*7fd79137SRobert Mustacchi return((Dwarf_P_Attribute)DW_DLV_BADADDR); 419*7fd79137SRobert Mustacchi } 420*7fd79137SRobert Mustacchi 421*7fd79137SRobert Mustacchi /* write length and data to attribute data buffer */ 422*7fd79137SRobert Mustacchi memcpy(attrdata, encode_buffer, len_size); 423*7fd79137SRobert Mustacchi attrdata += len_size; 424*7fd79137SRobert Mustacchi memcpy(attrdata, block_data, block_size); 425*7fd79137SRobert Mustacchi 426*7fd79137SRobert Mustacchi /* add attribute to the die */ 427*7fd79137SRobert Mustacchi _dwarf_pro_add_at_to_die(ownerdie, new_attr); 428*7fd79137SRobert Mustacchi 429*7fd79137SRobert Mustacchi return new_attr; 430*7fd79137SRobert Mustacchi } 431*7fd79137SRobert Mustacchi 432*7fd79137SRobert Mustacchi 433*7fd79137SRobert Mustacchi /* 434*7fd79137SRobert Mustacchi This function adds attributes whose value 435*7fd79137SRobert Mustacchi is an unsigned constant. It determines the 436*7fd79137SRobert Mustacchi size of the value field from the value of 437*7fd79137SRobert Mustacchi the constant. 438*7fd79137SRobert Mustacchi */ 439*7fd79137SRobert Mustacchi Dwarf_P_Attribute 440*7fd79137SRobert Mustacchi dwarf_add_AT_unsigned_const(Dwarf_P_Debug dbg, 441*7fd79137SRobert Mustacchi Dwarf_P_Die ownerdie, 442*7fd79137SRobert Mustacchi Dwarf_Half attr, 443*7fd79137SRobert Mustacchi Dwarf_Unsigned value, Dwarf_Error * error) 444*7fd79137SRobert Mustacchi { 445*7fd79137SRobert Mustacchi Dwarf_P_Attribute new_attr; 446*7fd79137SRobert Mustacchi Dwarf_Half attr_form; 447*7fd79137SRobert Mustacchi Dwarf_Small size; 448*7fd79137SRobert Mustacchi 449*7fd79137SRobert Mustacchi if (dbg == NULL) { 450*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 451*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 452*7fd79137SRobert Mustacchi } 453*7fd79137SRobert Mustacchi 454*7fd79137SRobert Mustacchi if (ownerdie == NULL) { 455*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); 456*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 457*7fd79137SRobert Mustacchi } 458*7fd79137SRobert Mustacchi 459*7fd79137SRobert Mustacchi switch (attr) { 460*7fd79137SRobert Mustacchi case DW_AT_ordering: 461*7fd79137SRobert Mustacchi case DW_AT_byte_size: 462*7fd79137SRobert Mustacchi case DW_AT_bit_offset: 463*7fd79137SRobert Mustacchi case DW_AT_bit_size: 464*7fd79137SRobert Mustacchi case DW_AT_inline: 465*7fd79137SRobert Mustacchi case DW_AT_language: 466*7fd79137SRobert Mustacchi case DW_AT_visibility: 467*7fd79137SRobert Mustacchi case DW_AT_virtuality: 468*7fd79137SRobert Mustacchi case DW_AT_accessibility: 469*7fd79137SRobert Mustacchi case DW_AT_address_class: 470*7fd79137SRobert Mustacchi case DW_AT_calling_convention: 471*7fd79137SRobert Mustacchi case DW_AT_encoding: 472*7fd79137SRobert Mustacchi case DW_AT_identifier_case: 473*7fd79137SRobert Mustacchi case DW_AT_MIPS_loop_unroll_factor: 474*7fd79137SRobert Mustacchi case DW_AT_MIPS_software_pipeline_depth: 475*7fd79137SRobert Mustacchi break; 476*7fd79137SRobert Mustacchi 477*7fd79137SRobert Mustacchi case DW_AT_decl_column: 478*7fd79137SRobert Mustacchi case DW_AT_decl_file: 479*7fd79137SRobert Mustacchi case DW_AT_decl_line: 480*7fd79137SRobert Mustacchi case DW_AT_const_value: 481*7fd79137SRobert Mustacchi case DW_AT_start_scope: 482*7fd79137SRobert Mustacchi case DW_AT_stride_size: 483*7fd79137SRobert Mustacchi case DW_AT_count: 484*7fd79137SRobert Mustacchi case DW_AT_associated: 485*7fd79137SRobert Mustacchi case DW_AT_allocated: 486*7fd79137SRobert Mustacchi case DW_AT_upper_bound: 487*7fd79137SRobert Mustacchi case DW_AT_lower_bound: 488*7fd79137SRobert Mustacchi case DW_AT_call_file: 489*7fd79137SRobert Mustacchi case DW_AT_call_line: 490*7fd79137SRobert Mustacchi break; 491*7fd79137SRobert Mustacchi 492*7fd79137SRobert Mustacchi default: { 493*7fd79137SRobert Mustacchi if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { 494*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); 495*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 496*7fd79137SRobert Mustacchi } 497*7fd79137SRobert Mustacchi break; 498*7fd79137SRobert Mustacchi } 499*7fd79137SRobert Mustacchi } 500*7fd79137SRobert Mustacchi 501*7fd79137SRobert Mustacchi /* 502*7fd79137SRobert Mustacchi Compute the number of bytes needed to hold constant. */ 503*7fd79137SRobert Mustacchi if (value <= UCHAR_MAX) { 504*7fd79137SRobert Mustacchi attr_form = DW_FORM_data1; 505*7fd79137SRobert Mustacchi size = 1; 506*7fd79137SRobert Mustacchi } else if (value <= USHRT_MAX) { 507*7fd79137SRobert Mustacchi attr_form = DW_FORM_data2; 508*7fd79137SRobert Mustacchi size = 2; 509*7fd79137SRobert Mustacchi } else if (value <= UINT_MAX) { 510*7fd79137SRobert Mustacchi attr_form = DW_FORM_data4; 511*7fd79137SRobert Mustacchi size = 4; 512*7fd79137SRobert Mustacchi } else { 513*7fd79137SRobert Mustacchi attr_form = DW_FORM_data8; 514*7fd79137SRobert Mustacchi size = 8; 515*7fd79137SRobert Mustacchi } 516*7fd79137SRobert Mustacchi 517*7fd79137SRobert Mustacchi new_attr = (Dwarf_P_Attribute) 518*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); 519*7fd79137SRobert Mustacchi if (new_attr == NULL) { 520*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 521*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 522*7fd79137SRobert Mustacchi } 523*7fd79137SRobert Mustacchi 524*7fd79137SRobert Mustacchi new_attr->ar_attribute = attr; 525*7fd79137SRobert Mustacchi new_attr->ar_attribute_form = attr_form; 526*7fd79137SRobert Mustacchi new_attr->ar_rel_type = R_MIPS_NONE; 527*7fd79137SRobert Mustacchi new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */ 528*7fd79137SRobert Mustacchi new_attr->ar_nbytes = size; 529*7fd79137SRobert Mustacchi new_attr->ar_next = 0; 530*7fd79137SRobert Mustacchi 531*7fd79137SRobert Mustacchi new_attr->ar_data = (char *) 532*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, size); 533*7fd79137SRobert Mustacchi if (new_attr->ar_data == NULL) { 534*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 535*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 536*7fd79137SRobert Mustacchi } 537*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, new_attr->ar_data, 538*7fd79137SRobert Mustacchi (const void *) &value, sizeof(value), size); 539*7fd79137SRobert Mustacchi 540*7fd79137SRobert Mustacchi /* add attribute to the die */ 541*7fd79137SRobert Mustacchi _dwarf_pro_add_at_to_die(ownerdie, new_attr); 542*7fd79137SRobert Mustacchi return new_attr; 543*7fd79137SRobert Mustacchi } 544*7fd79137SRobert Mustacchi 545*7fd79137SRobert Mustacchi 546*7fd79137SRobert Mustacchi /* 547*7fd79137SRobert Mustacchi This function adds attributes whose value 548*7fd79137SRobert Mustacchi is an signed constant. It determines the 549*7fd79137SRobert Mustacchi size of the value field from the value of 550*7fd79137SRobert Mustacchi the constant. 551*7fd79137SRobert Mustacchi */ 552*7fd79137SRobert Mustacchi Dwarf_P_Attribute 553*7fd79137SRobert Mustacchi dwarf_add_AT_signed_const(Dwarf_P_Debug dbg, 554*7fd79137SRobert Mustacchi Dwarf_P_Die ownerdie, 555*7fd79137SRobert Mustacchi Dwarf_Half attr, 556*7fd79137SRobert Mustacchi Dwarf_Signed value, Dwarf_Error * error) 557*7fd79137SRobert Mustacchi { 558*7fd79137SRobert Mustacchi Dwarf_P_Attribute new_attr; 559*7fd79137SRobert Mustacchi Dwarf_Half attr_form; 560*7fd79137SRobert Mustacchi Dwarf_Small size; 561*7fd79137SRobert Mustacchi 562*7fd79137SRobert Mustacchi if (dbg == NULL) { 563*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 564*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 565*7fd79137SRobert Mustacchi } 566*7fd79137SRobert Mustacchi 567*7fd79137SRobert Mustacchi if (ownerdie == NULL) { 568*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); 569*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 570*7fd79137SRobert Mustacchi } 571*7fd79137SRobert Mustacchi 572*7fd79137SRobert Mustacchi switch (attr) { 573*7fd79137SRobert Mustacchi case DW_AT_lower_bound: 574*7fd79137SRobert Mustacchi case DW_AT_upper_bound: 575*7fd79137SRobert Mustacchi case DW_AT_const_value: 576*7fd79137SRobert Mustacchi case DW_AT_bit_offset: 577*7fd79137SRobert Mustacchi case DW_AT_bit_size: 578*7fd79137SRobert Mustacchi case DW_AT_byte_size: 579*7fd79137SRobert Mustacchi case DW_AT_count: 580*7fd79137SRobert Mustacchi case DW_AT_byte_stride: 581*7fd79137SRobert Mustacchi case DW_AT_bit_stride: 582*7fd79137SRobert Mustacchi case DW_AT_allocated: 583*7fd79137SRobert Mustacchi case DW_AT_associated: 584*7fd79137SRobert Mustacchi break; 585*7fd79137SRobert Mustacchi 586*7fd79137SRobert Mustacchi default:{ 587*7fd79137SRobert Mustacchi if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { 588*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); 589*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 590*7fd79137SRobert Mustacchi } 591*7fd79137SRobert Mustacchi } 592*7fd79137SRobert Mustacchi break; 593*7fd79137SRobert Mustacchi } 594*7fd79137SRobert Mustacchi 595*7fd79137SRobert Mustacchi /* 596*7fd79137SRobert Mustacchi Compute the number of bytes needed to hold constant. */ 597*7fd79137SRobert Mustacchi if (value >= SCHAR_MIN && value <= SCHAR_MAX) { 598*7fd79137SRobert Mustacchi attr_form = DW_FORM_data1; 599*7fd79137SRobert Mustacchi size = 1; 600*7fd79137SRobert Mustacchi } else if (value >= SHRT_MIN && value <= SHRT_MAX) { 601*7fd79137SRobert Mustacchi attr_form = DW_FORM_data2; 602*7fd79137SRobert Mustacchi size = 2; 603*7fd79137SRobert Mustacchi } else if (value >= INT_MIN && value <= INT_MAX) { 604*7fd79137SRobert Mustacchi attr_form = DW_FORM_data4; 605*7fd79137SRobert Mustacchi size = 4; 606*7fd79137SRobert Mustacchi } else { 607*7fd79137SRobert Mustacchi attr_form = DW_FORM_data8; 608*7fd79137SRobert Mustacchi size = 8; 609*7fd79137SRobert Mustacchi } 610*7fd79137SRobert Mustacchi 611*7fd79137SRobert Mustacchi new_attr = (Dwarf_P_Attribute) 612*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); 613*7fd79137SRobert Mustacchi if (new_attr == NULL) { 614*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 615*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 616*7fd79137SRobert Mustacchi } 617*7fd79137SRobert Mustacchi 618*7fd79137SRobert Mustacchi new_attr->ar_attribute = attr; 619*7fd79137SRobert Mustacchi new_attr->ar_attribute_form = attr_form; 620*7fd79137SRobert Mustacchi new_attr->ar_rel_type = R_MIPS_NONE; 621*7fd79137SRobert Mustacchi new_attr->ar_reloc_len = 0; /* irrelevant: unused with R_MIPS_NONE */ 622*7fd79137SRobert Mustacchi new_attr->ar_nbytes = size; 623*7fd79137SRobert Mustacchi new_attr->ar_next = 0; 624*7fd79137SRobert Mustacchi 625*7fd79137SRobert Mustacchi new_attr->ar_data = (char *) 626*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, size); 627*7fd79137SRobert Mustacchi if (new_attr->ar_data == NULL) { 628*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 629*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 630*7fd79137SRobert Mustacchi } 631*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, new_attr->ar_data, 632*7fd79137SRobert Mustacchi (const void *) &value, sizeof(value), size); 633*7fd79137SRobert Mustacchi 634*7fd79137SRobert Mustacchi /* add attribute to the die */ 635*7fd79137SRobert Mustacchi _dwarf_pro_add_at_to_die(ownerdie, new_attr); 636*7fd79137SRobert Mustacchi return new_attr; 637*7fd79137SRobert Mustacchi } 638*7fd79137SRobert Mustacchi 639*7fd79137SRobert Mustacchi 640*7fd79137SRobert Mustacchi /* 641*7fd79137SRobert Mustacchi This function adds attributes whose value 642*7fd79137SRobert Mustacchi is a location expression. 643*7fd79137SRobert Mustacchi */ 644*7fd79137SRobert Mustacchi Dwarf_P_Attribute 645*7fd79137SRobert Mustacchi dwarf_add_AT_location_expr(Dwarf_P_Debug dbg, 646*7fd79137SRobert Mustacchi Dwarf_P_Die ownerdie, 647*7fd79137SRobert Mustacchi Dwarf_Half attr, 648*7fd79137SRobert Mustacchi Dwarf_P_Expr loc_expr, Dwarf_Error * error) 649*7fd79137SRobert Mustacchi { 650*7fd79137SRobert Mustacchi char encode_buffer[ENCODE_SPACE_NEEDED]; 651*7fd79137SRobert Mustacchi int res; 652*7fd79137SRobert Mustacchi Dwarf_P_Attribute new_attr; 653*7fd79137SRobert Mustacchi Dwarf_Half attr_form; 654*7fd79137SRobert Mustacchi char *len_str = 0; 655*7fd79137SRobert Mustacchi int len_size; 656*7fd79137SRobert Mustacchi int block_size; 657*7fd79137SRobert Mustacchi char *block_dest_ptr; 658*7fd79137SRobert Mustacchi int do_len_as_int = 0; 659*7fd79137SRobert Mustacchi 660*7fd79137SRobert Mustacchi if (dbg == NULL) { 661*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 662*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 663*7fd79137SRobert Mustacchi } 664*7fd79137SRobert Mustacchi 665*7fd79137SRobert Mustacchi if (ownerdie == NULL) { 666*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); 667*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 668*7fd79137SRobert Mustacchi } 669*7fd79137SRobert Mustacchi 670*7fd79137SRobert Mustacchi if (loc_expr == NULL) { 671*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_EXPR_NULL); 672*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 673*7fd79137SRobert Mustacchi } 674*7fd79137SRobert Mustacchi 675*7fd79137SRobert Mustacchi if (loc_expr->ex_dbg != dbg) { 676*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_LOC_EXPR_BAD); 677*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 678*7fd79137SRobert Mustacchi } 679*7fd79137SRobert Mustacchi block_size = loc_expr->ex_next_byte_offset; 680*7fd79137SRobert Mustacchi 681*7fd79137SRobert Mustacchi switch (attr) { 682*7fd79137SRobert Mustacchi case DW_AT_location: 683*7fd79137SRobert Mustacchi case DW_AT_string_length: 684*7fd79137SRobert Mustacchi case DW_AT_const_value: 685*7fd79137SRobert Mustacchi case DW_AT_use_location: 686*7fd79137SRobert Mustacchi case DW_AT_return_addr: 687*7fd79137SRobert Mustacchi case DW_AT_data_member_location: 688*7fd79137SRobert Mustacchi case DW_AT_frame_base: 689*7fd79137SRobert Mustacchi case DW_AT_static_link: 690*7fd79137SRobert Mustacchi case DW_AT_vtable_elem_location: 691*7fd79137SRobert Mustacchi case DW_AT_lower_bound: 692*7fd79137SRobert Mustacchi case DW_AT_upper_bound: 693*7fd79137SRobert Mustacchi case DW_AT_count: 694*7fd79137SRobert Mustacchi case DW_AT_associated: 695*7fd79137SRobert Mustacchi case DW_AT_allocated: 696*7fd79137SRobert Mustacchi case DW_AT_data_location: 697*7fd79137SRobert Mustacchi case DW_AT_byte_stride: 698*7fd79137SRobert Mustacchi case DW_AT_bit_stride: 699*7fd79137SRobert Mustacchi case DW_AT_byte_size: 700*7fd79137SRobert Mustacchi case DW_AT_bit_size: 701*7fd79137SRobert Mustacchi break; 702*7fd79137SRobert Mustacchi 703*7fd79137SRobert Mustacchi default: 704*7fd79137SRobert Mustacchi if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { 705*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); 706*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 707*7fd79137SRobert Mustacchi } 708*7fd79137SRobert Mustacchi break; 709*7fd79137SRobert Mustacchi } 710*7fd79137SRobert Mustacchi 711*7fd79137SRobert Mustacchi /* 712*7fd79137SRobert Mustacchi Compute the number of bytes needed to hold constant. */ 713*7fd79137SRobert Mustacchi if (block_size <= UCHAR_MAX) { 714*7fd79137SRobert Mustacchi attr_form = DW_FORM_block1; 715*7fd79137SRobert Mustacchi len_size = 1; 716*7fd79137SRobert Mustacchi do_len_as_int = 1; 717*7fd79137SRobert Mustacchi } else if (block_size <= USHRT_MAX) { 718*7fd79137SRobert Mustacchi attr_form = DW_FORM_block2; 719*7fd79137SRobert Mustacchi len_size = 2; 720*7fd79137SRobert Mustacchi do_len_as_int = 1; 721*7fd79137SRobert Mustacchi } else if (block_size <= UINT_MAX) { 722*7fd79137SRobert Mustacchi attr_form = DW_FORM_block4; 723*7fd79137SRobert Mustacchi len_size = 4; 724*7fd79137SRobert Mustacchi do_len_as_int = 1; 725*7fd79137SRobert Mustacchi } else { 726*7fd79137SRobert Mustacchi attr_form = DW_FORM_block; 727*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(block_size, &len_size, 728*7fd79137SRobert Mustacchi encode_buffer, 729*7fd79137SRobert Mustacchi sizeof(encode_buffer)); 730*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 731*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 732*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 733*7fd79137SRobert Mustacchi } 734*7fd79137SRobert Mustacchi len_str = (char *) encode_buffer; 735*7fd79137SRobert Mustacchi } 736*7fd79137SRobert Mustacchi 737*7fd79137SRobert Mustacchi new_attr = (Dwarf_P_Attribute) 738*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); 739*7fd79137SRobert Mustacchi if (new_attr == NULL) { 740*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 741*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 742*7fd79137SRobert Mustacchi } 743*7fd79137SRobert Mustacchi 744*7fd79137SRobert Mustacchi new_attr->ar_attribute = attr; 745*7fd79137SRobert Mustacchi new_attr->ar_attribute_form = attr_form; 746*7fd79137SRobert Mustacchi new_attr->ar_reloc_len = dbg->de_pointer_size; 747*7fd79137SRobert Mustacchi if (loc_expr->ex_reloc_sym_index != NO_ELF_SYM_INDEX) { 748*7fd79137SRobert Mustacchi new_attr->ar_rel_type = dbg->de_ptr_reloc; 749*7fd79137SRobert Mustacchi } else { 750*7fd79137SRobert Mustacchi new_attr->ar_rel_type = R_MIPS_NONE; 751*7fd79137SRobert Mustacchi } 752*7fd79137SRobert Mustacchi new_attr->ar_rel_symidx = loc_expr->ex_reloc_sym_index; 753*7fd79137SRobert Mustacchi new_attr->ar_rel_offset = 754*7fd79137SRobert Mustacchi (Dwarf_Word) loc_expr->ex_reloc_offset + len_size; 755*7fd79137SRobert Mustacchi 756*7fd79137SRobert Mustacchi new_attr->ar_nbytes = block_size + len_size; 757*7fd79137SRobert Mustacchi 758*7fd79137SRobert Mustacchi new_attr->ar_next = 0; 759*7fd79137SRobert Mustacchi new_attr->ar_data = block_dest_ptr = 760*7fd79137SRobert Mustacchi (char *) _dwarf_p_get_alloc(dbg, block_size + len_size); 761*7fd79137SRobert Mustacchi if (new_attr->ar_data == NULL) { 762*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 763*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 764*7fd79137SRobert Mustacchi } 765*7fd79137SRobert Mustacchi 766*7fd79137SRobert Mustacchi if (do_len_as_int) { 767*7fd79137SRobert Mustacchi WRITE_UNALIGNED(dbg, block_dest_ptr, (const void *) &block_size, 768*7fd79137SRobert Mustacchi sizeof(block_size), len_size); 769*7fd79137SRobert Mustacchi } else { 770*7fd79137SRobert Mustacchi /* Is uleb number form, DW_FORM_block. See above. */ 771*7fd79137SRobert Mustacchi memcpy(block_dest_ptr, len_str, len_size); 772*7fd79137SRobert Mustacchi } 773*7fd79137SRobert Mustacchi block_dest_ptr += len_size; 774*7fd79137SRobert Mustacchi memcpy(block_dest_ptr, &(loc_expr->ex_byte_stream[0]), block_size); 775*7fd79137SRobert Mustacchi 776*7fd79137SRobert Mustacchi /* add attribute to the die */ 777*7fd79137SRobert Mustacchi _dwarf_pro_add_at_to_die(ownerdie, new_attr); 778*7fd79137SRobert Mustacchi return new_attr; 779*7fd79137SRobert Mustacchi } 780*7fd79137SRobert Mustacchi 781*7fd79137SRobert Mustacchi 782*7fd79137SRobert Mustacchi /* 783*7fd79137SRobert Mustacchi This function adds attributes of reference class. 784*7fd79137SRobert Mustacchi The references here are local CU references, 785*7fd79137SRobert Mustacchi not DW_FORM_ref_addr. 786*7fd79137SRobert Mustacchi The offset field is 4 bytes for 32-bit objects, 787*7fd79137SRobert Mustacchi and 8-bytes for 64-bit objects. Otherdie is the 788*7fd79137SRobert Mustacchi that is referenced by ownerdie. 789*7fd79137SRobert Mustacchi 790*7fd79137SRobert Mustacchi For reference attributes, the ar_data and ar_nbytes 791*7fd79137SRobert Mustacchi are not needed. Instead, the ar_ref_die points to 792*7fd79137SRobert Mustacchi the other die, and its di_offset value is used as 793*7fd79137SRobert Mustacchi the reference value. 794*7fd79137SRobert Mustacchi */ 795*7fd79137SRobert Mustacchi Dwarf_P_Attribute 796*7fd79137SRobert Mustacchi dwarf_add_AT_reference(Dwarf_P_Debug dbg, 797*7fd79137SRobert Mustacchi Dwarf_P_Die ownerdie, 798*7fd79137SRobert Mustacchi Dwarf_Half attr, 799*7fd79137SRobert Mustacchi Dwarf_P_Die otherdie, Dwarf_Error * error) 800*7fd79137SRobert Mustacchi { 801*7fd79137SRobert Mustacchi Dwarf_P_Attribute new_attr; 802*7fd79137SRobert Mustacchi 803*7fd79137SRobert Mustacchi if (dbg == NULL) { 804*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 805*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 806*7fd79137SRobert Mustacchi } 807*7fd79137SRobert Mustacchi 808*7fd79137SRobert Mustacchi if (ownerdie == NULL) { 809*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); 810*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 811*7fd79137SRobert Mustacchi } 812*7fd79137SRobert Mustacchi 813*7fd79137SRobert Mustacchi if (otherdie == NULL) { 814*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); 815*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 816*7fd79137SRobert Mustacchi } 817*7fd79137SRobert Mustacchi 818*7fd79137SRobert Mustacchi switch (attr) { 819*7fd79137SRobert Mustacchi case DW_AT_specification: 820*7fd79137SRobert Mustacchi case DW_AT_discr: 821*7fd79137SRobert Mustacchi case DW_AT_common_reference: 822*7fd79137SRobert Mustacchi case DW_AT_import: 823*7fd79137SRobert Mustacchi case DW_AT_containing_type: 824*7fd79137SRobert Mustacchi case DW_AT_default_value: 825*7fd79137SRobert Mustacchi case DW_AT_abstract_origin: 826*7fd79137SRobert Mustacchi case DW_AT_friend: 827*7fd79137SRobert Mustacchi case DW_AT_priority: 828*7fd79137SRobert Mustacchi case DW_AT_type: 829*7fd79137SRobert Mustacchi case DW_AT_lower_bound: 830*7fd79137SRobert Mustacchi case DW_AT_upper_bound: 831*7fd79137SRobert Mustacchi case DW_AT_count: 832*7fd79137SRobert Mustacchi case DW_AT_associated: 833*7fd79137SRobert Mustacchi case DW_AT_allocated: 834*7fd79137SRobert Mustacchi case DW_AT_bit_offset: 835*7fd79137SRobert Mustacchi case DW_AT_bit_size: 836*7fd79137SRobert Mustacchi case DW_AT_byte_size: 837*7fd79137SRobert Mustacchi case DW_AT_sibling: 838*7fd79137SRobert Mustacchi case DW_AT_bit_stride: 839*7fd79137SRobert Mustacchi case DW_AT_byte_stride: 840*7fd79137SRobert Mustacchi case DW_AT_namelist_item: 841*7fd79137SRobert Mustacchi break; 842*7fd79137SRobert Mustacchi 843*7fd79137SRobert Mustacchi default: 844*7fd79137SRobert Mustacchi if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { 845*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); 846*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 847*7fd79137SRobert Mustacchi } 848*7fd79137SRobert Mustacchi break; 849*7fd79137SRobert Mustacchi } 850*7fd79137SRobert Mustacchi 851*7fd79137SRobert Mustacchi new_attr = (Dwarf_P_Attribute) 852*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); 853*7fd79137SRobert Mustacchi if (new_attr == NULL) { 854*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 855*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 856*7fd79137SRobert Mustacchi } 857*7fd79137SRobert Mustacchi 858*7fd79137SRobert Mustacchi new_attr->ar_attribute = attr; 859*7fd79137SRobert Mustacchi new_attr->ar_attribute_form = dbg->de_ar_ref_attr_form; 860*7fd79137SRobert Mustacchi new_attr->ar_nbytes = dbg->de_offset_size; 861*7fd79137SRobert Mustacchi new_attr->ar_reloc_len = dbg->de_offset_size; 862*7fd79137SRobert Mustacchi new_attr->ar_ref_die = otherdie; 863*7fd79137SRobert Mustacchi new_attr->ar_rel_type = R_MIPS_NONE; 864*7fd79137SRobert Mustacchi new_attr->ar_next = 0; 865*7fd79137SRobert Mustacchi 866*7fd79137SRobert Mustacchi /* add attribute to the die */ 867*7fd79137SRobert Mustacchi _dwarf_pro_add_at_to_die(ownerdie, new_attr); 868*7fd79137SRobert Mustacchi return new_attr; 869*7fd79137SRobert Mustacchi } 870*7fd79137SRobert Mustacchi 871*7fd79137SRobert Mustacchi 872*7fd79137SRobert Mustacchi /* 873*7fd79137SRobert Mustacchi This function adds attributes of the flag class. 874*7fd79137SRobert Mustacchi */ 875*7fd79137SRobert Mustacchi Dwarf_P_Attribute 876*7fd79137SRobert Mustacchi dwarf_add_AT_flag(Dwarf_P_Debug dbg, 877*7fd79137SRobert Mustacchi Dwarf_P_Die ownerdie, 878*7fd79137SRobert Mustacchi Dwarf_Half attr, 879*7fd79137SRobert Mustacchi Dwarf_Small flag, Dwarf_Error * error) 880*7fd79137SRobert Mustacchi { 881*7fd79137SRobert Mustacchi Dwarf_P_Attribute new_attr; 882*7fd79137SRobert Mustacchi 883*7fd79137SRobert Mustacchi if (dbg == NULL) { 884*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 885*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 886*7fd79137SRobert Mustacchi } 887*7fd79137SRobert Mustacchi 888*7fd79137SRobert Mustacchi if (ownerdie == NULL) { 889*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); 890*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 891*7fd79137SRobert Mustacchi } 892*7fd79137SRobert Mustacchi 893*7fd79137SRobert Mustacchi #if 0 894*7fd79137SRobert Mustacchi switch (attr) { 895*7fd79137SRobert Mustacchi case DW_AT_is_optional: 896*7fd79137SRobert Mustacchi case DW_AT_artificial: 897*7fd79137SRobert Mustacchi case DW_AT_declaration: 898*7fd79137SRobert Mustacchi case DW_AT_external: 899*7fd79137SRobert Mustacchi case DW_AT_prototyped: 900*7fd79137SRobert Mustacchi case DW_AT_variable_parameter: 901*7fd79137SRobert Mustacchi break; 902*7fd79137SRobert Mustacchi 903*7fd79137SRobert Mustacchi default: 904*7fd79137SRobert Mustacchi if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { 905*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); 906*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 907*7fd79137SRobert Mustacchi } 908*7fd79137SRobert Mustacchi break; 909*7fd79137SRobert Mustacchi } 910*7fd79137SRobert Mustacchi #endif 911*7fd79137SRobert Mustacchi 912*7fd79137SRobert Mustacchi new_attr = (Dwarf_P_Attribute) 913*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); 914*7fd79137SRobert Mustacchi if (new_attr == NULL) { 915*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 916*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 917*7fd79137SRobert Mustacchi } 918*7fd79137SRobert Mustacchi 919*7fd79137SRobert Mustacchi new_attr->ar_attribute = attr; 920*7fd79137SRobert Mustacchi new_attr->ar_attribute_form = DW_FORM_flag; 921*7fd79137SRobert Mustacchi new_attr->ar_nbytes = 1; 922*7fd79137SRobert Mustacchi new_attr->ar_reloc_len = 0; /* not used */ 923*7fd79137SRobert Mustacchi new_attr->ar_rel_type = R_MIPS_NONE; 924*7fd79137SRobert Mustacchi new_attr->ar_next = 0; 925*7fd79137SRobert Mustacchi 926*7fd79137SRobert Mustacchi new_attr->ar_data = (char *) 927*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, 1); 928*7fd79137SRobert Mustacchi if (new_attr->ar_data == NULL) { 929*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 930*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 931*7fd79137SRobert Mustacchi } 932*7fd79137SRobert Mustacchi memcpy(new_attr->ar_data, &flag, 1); 933*7fd79137SRobert Mustacchi 934*7fd79137SRobert Mustacchi /* add attribute to the die */ 935*7fd79137SRobert Mustacchi _dwarf_pro_add_at_to_die(ownerdie, new_attr); 936*7fd79137SRobert Mustacchi return new_attr; 937*7fd79137SRobert Mustacchi } 938*7fd79137SRobert Mustacchi 939*7fd79137SRobert Mustacchi 940*7fd79137SRobert Mustacchi /* 941*7fd79137SRobert Mustacchi This function adds values of attributes 942*7fd79137SRobert Mustacchi belonging to the string class. 943*7fd79137SRobert Mustacchi */ 944*7fd79137SRobert Mustacchi Dwarf_P_Attribute 945*7fd79137SRobert Mustacchi dwarf_add_AT_string(Dwarf_P_Debug dbg, 946*7fd79137SRobert Mustacchi Dwarf_P_Die ownerdie, 947*7fd79137SRobert Mustacchi Dwarf_Half attr, char *string, Dwarf_Error * error) 948*7fd79137SRobert Mustacchi { 949*7fd79137SRobert Mustacchi Dwarf_P_Attribute new_attr; 950*7fd79137SRobert Mustacchi 951*7fd79137SRobert Mustacchi if (dbg == NULL) { 952*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DBG_NULL); 953*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 954*7fd79137SRobert Mustacchi } 955*7fd79137SRobert Mustacchi 956*7fd79137SRobert Mustacchi if (ownerdie == NULL) { 957*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_DIE_NULL); 958*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 959*7fd79137SRobert Mustacchi } 960*7fd79137SRobert Mustacchi 961*7fd79137SRobert Mustacchi new_attr = (Dwarf_P_Attribute) 962*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(dbg, sizeof(struct Dwarf_P_Attribute_s)); 963*7fd79137SRobert Mustacchi if (new_attr == NULL) { 964*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 965*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 966*7fd79137SRobert Mustacchi } 967*7fd79137SRobert Mustacchi 968*7fd79137SRobert Mustacchi switch (attr) { 969*7fd79137SRobert Mustacchi case DW_AT_name: 970*7fd79137SRobert Mustacchi case DW_AT_comp_dir: 971*7fd79137SRobert Mustacchi case DW_AT_const_value: 972*7fd79137SRobert Mustacchi case DW_AT_producer: 973*7fd79137SRobert Mustacchi break; 974*7fd79137SRobert Mustacchi 975*7fd79137SRobert Mustacchi default: 976*7fd79137SRobert Mustacchi if ( attr < DW_AT_lo_user || attr > DW_AT_hi_user ) { 977*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_INPUT_ATTR_BAD); 978*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 979*7fd79137SRobert Mustacchi } 980*7fd79137SRobert Mustacchi break; 981*7fd79137SRobert Mustacchi } 982*7fd79137SRobert Mustacchi 983*7fd79137SRobert Mustacchi new_attr->ar_attribute = attr; 984*7fd79137SRobert Mustacchi new_attr->ar_attribute_form = DW_FORM_string; 985*7fd79137SRobert Mustacchi new_attr->ar_nbytes = strlen(string) + 1; 986*7fd79137SRobert Mustacchi new_attr->ar_next = 0; 987*7fd79137SRobert Mustacchi 988*7fd79137SRobert Mustacchi new_attr->ar_data = 989*7fd79137SRobert Mustacchi (char *) _dwarf_p_get_alloc(dbg, strlen(string)+1); 990*7fd79137SRobert Mustacchi if (new_attr->ar_data == NULL) { 991*7fd79137SRobert Mustacchi _dwarf_p_error(dbg, error, DW_DLE_ALLOC_FAIL); 992*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 993*7fd79137SRobert Mustacchi } 994*7fd79137SRobert Mustacchi 995*7fd79137SRobert Mustacchi strcpy(new_attr->ar_data, string); 996*7fd79137SRobert Mustacchi new_attr->ar_rel_type = R_MIPS_NONE; 997*7fd79137SRobert Mustacchi new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ 998*7fd79137SRobert Mustacchi 999*7fd79137SRobert Mustacchi /* add attribute to the die */ 1000*7fd79137SRobert Mustacchi _dwarf_pro_add_at_to_die(ownerdie, new_attr); 1001*7fd79137SRobert Mustacchi return new_attr; 1002*7fd79137SRobert Mustacchi } 1003*7fd79137SRobert Mustacchi 1004*7fd79137SRobert Mustacchi 1005*7fd79137SRobert Mustacchi Dwarf_P_Attribute 1006*7fd79137SRobert Mustacchi dwarf_add_AT_const_value_string(Dwarf_P_Die ownerdie, 1007*7fd79137SRobert Mustacchi char *string_value, Dwarf_Error * error) 1008*7fd79137SRobert Mustacchi { 1009*7fd79137SRobert Mustacchi Dwarf_P_Attribute new_attr; 1010*7fd79137SRobert Mustacchi 1011*7fd79137SRobert Mustacchi if (ownerdie == NULL) { 1012*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); 1013*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 1014*7fd79137SRobert Mustacchi } 1015*7fd79137SRobert Mustacchi 1016*7fd79137SRobert Mustacchi new_attr = (Dwarf_P_Attribute) 1017*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); 1018*7fd79137SRobert Mustacchi if (new_attr == NULL) { 1019*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 1020*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 1021*7fd79137SRobert Mustacchi } 1022*7fd79137SRobert Mustacchi 1023*7fd79137SRobert Mustacchi new_attr->ar_attribute = DW_AT_const_value; 1024*7fd79137SRobert Mustacchi new_attr->ar_attribute_form = DW_FORM_string; 1025*7fd79137SRobert Mustacchi new_attr->ar_nbytes = strlen(string_value) + 1; 1026*7fd79137SRobert Mustacchi new_attr->ar_next = 0; 1027*7fd79137SRobert Mustacchi 1028*7fd79137SRobert Mustacchi new_attr->ar_data = 1029*7fd79137SRobert Mustacchi (char *) _dwarf_p_get_alloc(ownerdie->di_dbg, strlen(string_value)+1); 1030*7fd79137SRobert Mustacchi if (new_attr->ar_data == NULL) { 1031*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 1032*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 1033*7fd79137SRobert Mustacchi } 1034*7fd79137SRobert Mustacchi 1035*7fd79137SRobert Mustacchi strcpy(new_attr->ar_data, string_value); 1036*7fd79137SRobert Mustacchi new_attr->ar_rel_type = R_MIPS_NONE; 1037*7fd79137SRobert Mustacchi new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ 1038*7fd79137SRobert Mustacchi 1039*7fd79137SRobert Mustacchi /* add attribute to the die */ 1040*7fd79137SRobert Mustacchi _dwarf_pro_add_at_to_die(ownerdie, new_attr); 1041*7fd79137SRobert Mustacchi return new_attr; 1042*7fd79137SRobert Mustacchi } 1043*7fd79137SRobert Mustacchi 1044*7fd79137SRobert Mustacchi 1045*7fd79137SRobert Mustacchi Dwarf_P_Attribute 1046*7fd79137SRobert Mustacchi dwarf_add_AT_producer(Dwarf_P_Die ownerdie, 1047*7fd79137SRobert Mustacchi char *producer_string, Dwarf_Error * error) 1048*7fd79137SRobert Mustacchi { 1049*7fd79137SRobert Mustacchi Dwarf_P_Attribute new_attr; 1050*7fd79137SRobert Mustacchi 1051*7fd79137SRobert Mustacchi if (ownerdie == NULL) { 1052*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); 1053*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 1054*7fd79137SRobert Mustacchi } 1055*7fd79137SRobert Mustacchi 1056*7fd79137SRobert Mustacchi new_attr = (Dwarf_P_Attribute) 1057*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); 1058*7fd79137SRobert Mustacchi if (new_attr == NULL) { 1059*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 1060*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 1061*7fd79137SRobert Mustacchi } 1062*7fd79137SRobert Mustacchi 1063*7fd79137SRobert Mustacchi new_attr->ar_attribute = DW_AT_producer; 1064*7fd79137SRobert Mustacchi new_attr->ar_attribute_form = DW_FORM_string; 1065*7fd79137SRobert Mustacchi new_attr->ar_nbytes = strlen(producer_string) + 1; 1066*7fd79137SRobert Mustacchi new_attr->ar_next = 0; 1067*7fd79137SRobert Mustacchi 1068*7fd79137SRobert Mustacchi new_attr->ar_data = 1069*7fd79137SRobert Mustacchi (char *) _dwarf_p_get_alloc(ownerdie->di_dbg, strlen(producer_string)+1); 1070*7fd79137SRobert Mustacchi if (new_attr->ar_data == NULL) { 1071*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 1072*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 1073*7fd79137SRobert Mustacchi } 1074*7fd79137SRobert Mustacchi 1075*7fd79137SRobert Mustacchi strcpy(new_attr->ar_data, producer_string); 1076*7fd79137SRobert Mustacchi new_attr->ar_rel_type = R_MIPS_NONE; 1077*7fd79137SRobert Mustacchi new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ 1078*7fd79137SRobert Mustacchi 1079*7fd79137SRobert Mustacchi /* add attribute to the die */ 1080*7fd79137SRobert Mustacchi _dwarf_pro_add_at_to_die(ownerdie, new_attr); 1081*7fd79137SRobert Mustacchi return new_attr; 1082*7fd79137SRobert Mustacchi } 1083*7fd79137SRobert Mustacchi 1084*7fd79137SRobert Mustacchi 1085*7fd79137SRobert Mustacchi Dwarf_P_Attribute 1086*7fd79137SRobert Mustacchi dwarf_add_AT_const_value_signedint(Dwarf_P_Die ownerdie, 1087*7fd79137SRobert Mustacchi Dwarf_Signed signed_value, 1088*7fd79137SRobert Mustacchi Dwarf_Error * error) 1089*7fd79137SRobert Mustacchi { 1090*7fd79137SRobert Mustacchi Dwarf_P_Attribute new_attr; 1091*7fd79137SRobert Mustacchi int leb_size; 1092*7fd79137SRobert Mustacchi char encode_buffer[ENCODE_SPACE_NEEDED]; 1093*7fd79137SRobert Mustacchi int res; 1094*7fd79137SRobert Mustacchi 1095*7fd79137SRobert Mustacchi if (ownerdie == NULL) { 1096*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); 1097*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 1098*7fd79137SRobert Mustacchi } 1099*7fd79137SRobert Mustacchi 1100*7fd79137SRobert Mustacchi new_attr = (Dwarf_P_Attribute) 1101*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); 1102*7fd79137SRobert Mustacchi if (new_attr == NULL) { 1103*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 1104*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 1105*7fd79137SRobert Mustacchi } 1106*7fd79137SRobert Mustacchi 1107*7fd79137SRobert Mustacchi new_attr->ar_attribute = DW_AT_const_value; 1108*7fd79137SRobert Mustacchi new_attr->ar_attribute_form = DW_FORM_sdata; 1109*7fd79137SRobert Mustacchi new_attr->ar_rel_type = R_MIPS_NONE; 1110*7fd79137SRobert Mustacchi new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ 1111*7fd79137SRobert Mustacchi new_attr->ar_next = 0; 1112*7fd79137SRobert Mustacchi 1113*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_signed_leb128_nm(signed_value, &leb_size, 1114*7fd79137SRobert Mustacchi encode_buffer, 1115*7fd79137SRobert Mustacchi sizeof(encode_buffer)); 1116*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 1117*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 1118*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 1119*7fd79137SRobert Mustacchi } 1120*7fd79137SRobert Mustacchi new_attr->ar_data = (char *) 1121*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(ownerdie->di_dbg, leb_size); 1122*7fd79137SRobert Mustacchi if (new_attr->ar_data == NULL) { 1123*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 1124*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 1125*7fd79137SRobert Mustacchi } 1126*7fd79137SRobert Mustacchi memcpy(new_attr->ar_data, encode_buffer, leb_size); 1127*7fd79137SRobert Mustacchi new_attr->ar_nbytes = leb_size; 1128*7fd79137SRobert Mustacchi 1129*7fd79137SRobert Mustacchi /* add attribute to the die */ 1130*7fd79137SRobert Mustacchi _dwarf_pro_add_at_to_die(ownerdie, new_attr); 1131*7fd79137SRobert Mustacchi return new_attr; 1132*7fd79137SRobert Mustacchi } 1133*7fd79137SRobert Mustacchi 1134*7fd79137SRobert Mustacchi 1135*7fd79137SRobert Mustacchi Dwarf_P_Attribute 1136*7fd79137SRobert Mustacchi dwarf_add_AT_const_value_unsignedint(Dwarf_P_Die ownerdie, 1137*7fd79137SRobert Mustacchi Dwarf_Unsigned unsigned_value, 1138*7fd79137SRobert Mustacchi Dwarf_Error * error) 1139*7fd79137SRobert Mustacchi { 1140*7fd79137SRobert Mustacchi Dwarf_P_Attribute new_attr; 1141*7fd79137SRobert Mustacchi int leb_size; 1142*7fd79137SRobert Mustacchi char encode_buffer[ENCODE_SPACE_NEEDED]; 1143*7fd79137SRobert Mustacchi int res; 1144*7fd79137SRobert Mustacchi 1145*7fd79137SRobert Mustacchi if (ownerdie == NULL) { 1146*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_DIE_NULL); 1147*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 1148*7fd79137SRobert Mustacchi } 1149*7fd79137SRobert Mustacchi 1150*7fd79137SRobert Mustacchi new_attr = (Dwarf_P_Attribute) 1151*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(ownerdie->di_dbg, sizeof(struct Dwarf_P_Attribute_s)); 1152*7fd79137SRobert Mustacchi if (new_attr == NULL) { 1153*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 1154*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 1155*7fd79137SRobert Mustacchi } 1156*7fd79137SRobert Mustacchi 1157*7fd79137SRobert Mustacchi new_attr->ar_attribute = DW_AT_const_value; 1158*7fd79137SRobert Mustacchi new_attr->ar_attribute_form = DW_FORM_udata; 1159*7fd79137SRobert Mustacchi new_attr->ar_rel_type = R_MIPS_NONE; 1160*7fd79137SRobert Mustacchi new_attr->ar_reloc_len = 0; /* unused for R_MIPS_NONE */ 1161*7fd79137SRobert Mustacchi new_attr->ar_next = 0; 1162*7fd79137SRobert Mustacchi 1163*7fd79137SRobert Mustacchi res = _dwarf_pro_encode_leb128_nm(unsigned_value, &leb_size, 1164*7fd79137SRobert Mustacchi encode_buffer, 1165*7fd79137SRobert Mustacchi sizeof(encode_buffer)); 1166*7fd79137SRobert Mustacchi if (res != DW_DLV_OK) { 1167*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 1168*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 1169*7fd79137SRobert Mustacchi } 1170*7fd79137SRobert Mustacchi new_attr->ar_data = (char *) 1171*7fd79137SRobert Mustacchi _dwarf_p_get_alloc(ownerdie->di_dbg, leb_size); 1172*7fd79137SRobert Mustacchi if (new_attr->ar_data == NULL) { 1173*7fd79137SRobert Mustacchi _dwarf_p_error(NULL, error, DW_DLE_ALLOC_FAIL); 1174*7fd79137SRobert Mustacchi return ((Dwarf_P_Attribute) DW_DLV_BADADDR); 1175*7fd79137SRobert Mustacchi } 1176*7fd79137SRobert Mustacchi memcpy(new_attr->ar_data, encode_buffer, leb_size); 1177*7fd79137SRobert Mustacchi new_attr->ar_nbytes = leb_size; 1178*7fd79137SRobert Mustacchi 1179*7fd79137SRobert Mustacchi /* add attribute to the die */ 1180*7fd79137SRobert Mustacchi _dwarf_pro_add_at_to_die(ownerdie, new_attr); 1181*7fd79137SRobert Mustacchi return new_attr; 1182*7fd79137SRobert Mustacchi } 1183