1*2de3b87aSKai Wang /*- 2*2de3b87aSKai Wang * Copyright (c) 2007 John Birrell (jb@freebsd.org) 3*2de3b87aSKai Wang * Copyright (c) 2009-2011 Kai Wang 4*2de3b87aSKai Wang * All rights reserved. 5*2de3b87aSKai Wang * 6*2de3b87aSKai Wang * Redistribution and use in source and binary forms, with or without 7*2de3b87aSKai Wang * modification, are permitted provided that the following conditions 8*2de3b87aSKai Wang * are met: 9*2de3b87aSKai Wang * 1. Redistributions of source code must retain the above copyright 10*2de3b87aSKai Wang * notice, this list of conditions and the following disclaimer. 11*2de3b87aSKai Wang * 2. Redistributions in binary form must reproduce the above copyright 12*2de3b87aSKai Wang * notice, this list of conditions and the following disclaimer in the 13*2de3b87aSKai Wang * documentation and/or other materials provided with the distribution. 14*2de3b87aSKai Wang * 15*2de3b87aSKai Wang * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 16*2de3b87aSKai Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 17*2de3b87aSKai Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 18*2de3b87aSKai Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 19*2de3b87aSKai Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 20*2de3b87aSKai Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 21*2de3b87aSKai Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 22*2de3b87aSKai Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 23*2de3b87aSKai Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 24*2de3b87aSKai Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 25*2de3b87aSKai Wang * SUCH DAMAGE. 26*2de3b87aSKai Wang */ 27*2de3b87aSKai Wang 28*2de3b87aSKai Wang #include "_libdwarf.h" 29*2de3b87aSKai Wang 30*2de3b87aSKai Wang ELFTC_VCSID("$Id: libdwarf_attr.c 2966 2013-09-21 14:40:14Z kaiwang27 $"); 31*2de3b87aSKai Wang 32*2de3b87aSKai Wang int 33*2de3b87aSKai Wang _dwarf_attr_alloc(Dwarf_Die die, Dwarf_Attribute *atp, Dwarf_Error *error) 34*2de3b87aSKai Wang { 35*2de3b87aSKai Wang Dwarf_Attribute at; 36*2de3b87aSKai Wang 37*2de3b87aSKai Wang assert(die != NULL); 38*2de3b87aSKai Wang assert(atp != NULL); 39*2de3b87aSKai Wang 40*2de3b87aSKai Wang if ((at = calloc(1, sizeof(struct _Dwarf_Attribute))) == NULL) { 41*2de3b87aSKai Wang DWARF_SET_ERROR(die->die_dbg, error, DW_DLE_MEMORY); 42*2de3b87aSKai Wang return (DW_DLE_MEMORY); 43*2de3b87aSKai Wang } 44*2de3b87aSKai Wang 45*2de3b87aSKai Wang *atp = at; 46*2de3b87aSKai Wang 47*2de3b87aSKai Wang return (DW_DLE_NONE); 48*2de3b87aSKai Wang } 49*2de3b87aSKai Wang 50*2de3b87aSKai Wang static int 51*2de3b87aSKai Wang _dwarf_attr_add(Dwarf_Die die, Dwarf_Attribute atref, Dwarf_Attribute *atp, 52*2de3b87aSKai Wang Dwarf_Error *error) 53*2de3b87aSKai Wang { 54*2de3b87aSKai Wang Dwarf_Attribute at; 55*2de3b87aSKai Wang int ret; 56*2de3b87aSKai Wang 57*2de3b87aSKai Wang if ((ret = _dwarf_attr_alloc(die, &at, error)) != DW_DLE_NONE) 58*2de3b87aSKai Wang return (ret); 59*2de3b87aSKai Wang 60*2de3b87aSKai Wang memcpy(at, atref, sizeof(struct _Dwarf_Attribute)); 61*2de3b87aSKai Wang 62*2de3b87aSKai Wang STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 63*2de3b87aSKai Wang 64*2de3b87aSKai Wang /* Save a pointer to the attribute name if this is one. */ 65*2de3b87aSKai Wang if (at->at_attrib == DW_AT_name) { 66*2de3b87aSKai Wang switch (at->at_form) { 67*2de3b87aSKai Wang case DW_FORM_strp: 68*2de3b87aSKai Wang die->die_name = at->u[1].s; 69*2de3b87aSKai Wang break; 70*2de3b87aSKai Wang case DW_FORM_string: 71*2de3b87aSKai Wang die->die_name = at->u[0].s; 72*2de3b87aSKai Wang break; 73*2de3b87aSKai Wang default: 74*2de3b87aSKai Wang break; 75*2de3b87aSKai Wang } 76*2de3b87aSKai Wang } 77*2de3b87aSKai Wang 78*2de3b87aSKai Wang if (atp != NULL) 79*2de3b87aSKai Wang *atp = at; 80*2de3b87aSKai Wang 81*2de3b87aSKai Wang return (DW_DLE_NONE); 82*2de3b87aSKai Wang } 83*2de3b87aSKai Wang 84*2de3b87aSKai Wang Dwarf_Attribute 85*2de3b87aSKai Wang _dwarf_attr_find(Dwarf_Die die, Dwarf_Half attr) 86*2de3b87aSKai Wang { 87*2de3b87aSKai Wang Dwarf_Attribute at; 88*2de3b87aSKai Wang 89*2de3b87aSKai Wang STAILQ_FOREACH(at, &die->die_attr, at_next) { 90*2de3b87aSKai Wang if (at->at_attrib == attr) 91*2de3b87aSKai Wang break; 92*2de3b87aSKai Wang } 93*2de3b87aSKai Wang 94*2de3b87aSKai Wang return (at); 95*2de3b87aSKai Wang } 96*2de3b87aSKai Wang 97*2de3b87aSKai Wang int 98*2de3b87aSKai Wang _dwarf_attr_init(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *offsetp, 99*2de3b87aSKai Wang int dwarf_size, Dwarf_CU cu, Dwarf_Die die, Dwarf_AttrDef ad, 100*2de3b87aSKai Wang uint64_t form, int indirect, Dwarf_Error *error) 101*2de3b87aSKai Wang { 102*2de3b87aSKai Wang struct _Dwarf_Attribute atref; 103*2de3b87aSKai Wang Dwarf_Section *str; 104*2de3b87aSKai Wang int ret; 105*2de3b87aSKai Wang 106*2de3b87aSKai Wang ret = DW_DLE_NONE; 107*2de3b87aSKai Wang memset(&atref, 0, sizeof(atref)); 108*2de3b87aSKai Wang atref.at_die = die; 109*2de3b87aSKai Wang atref.at_attrib = ad->ad_attrib; 110*2de3b87aSKai Wang atref.at_form = indirect ? form : ad->ad_form; 111*2de3b87aSKai Wang atref.at_indirect = indirect; 112*2de3b87aSKai Wang atref.at_ld = NULL; 113*2de3b87aSKai Wang 114*2de3b87aSKai Wang switch (form) { 115*2de3b87aSKai Wang case DW_FORM_addr: 116*2de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 117*2de3b87aSKai Wang cu->cu_pointer_size); 118*2de3b87aSKai Wang break; 119*2de3b87aSKai Wang case DW_FORM_block: 120*2de3b87aSKai Wang case DW_FORM_exprloc: 121*2de3b87aSKai Wang atref.u[0].u64 = _dwarf_read_uleb128(ds->ds_data, offsetp); 122*2de3b87aSKai Wang atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, 123*2de3b87aSKai Wang atref.u[0].u64); 124*2de3b87aSKai Wang break; 125*2de3b87aSKai Wang case DW_FORM_block1: 126*2de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 1); 127*2de3b87aSKai Wang atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, 128*2de3b87aSKai Wang atref.u[0].u64); 129*2de3b87aSKai Wang break; 130*2de3b87aSKai Wang case DW_FORM_block2: 131*2de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 2); 132*2de3b87aSKai Wang atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, 133*2de3b87aSKai Wang atref.u[0].u64); 134*2de3b87aSKai Wang break; 135*2de3b87aSKai Wang case DW_FORM_block4: 136*2de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 4); 137*2de3b87aSKai Wang atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, 138*2de3b87aSKai Wang atref.u[0].u64); 139*2de3b87aSKai Wang break; 140*2de3b87aSKai Wang case DW_FORM_data1: 141*2de3b87aSKai Wang case DW_FORM_flag: 142*2de3b87aSKai Wang case DW_FORM_ref1: 143*2de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 1); 144*2de3b87aSKai Wang break; 145*2de3b87aSKai Wang case DW_FORM_data2: 146*2de3b87aSKai Wang case DW_FORM_ref2: 147*2de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 2); 148*2de3b87aSKai Wang break; 149*2de3b87aSKai Wang case DW_FORM_data4: 150*2de3b87aSKai Wang case DW_FORM_ref4: 151*2de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 4); 152*2de3b87aSKai Wang break; 153*2de3b87aSKai Wang case DW_FORM_data8: 154*2de3b87aSKai Wang case DW_FORM_ref8: 155*2de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 8); 156*2de3b87aSKai Wang break; 157*2de3b87aSKai Wang case DW_FORM_indirect: 158*2de3b87aSKai Wang form = _dwarf_read_uleb128(ds->ds_data, offsetp); 159*2de3b87aSKai Wang return (_dwarf_attr_init(dbg, ds, offsetp, dwarf_size, cu, die, 160*2de3b87aSKai Wang ad, form, 1, error)); 161*2de3b87aSKai Wang case DW_FORM_ref_addr: 162*2de3b87aSKai Wang if (cu->cu_version == 2) 163*2de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 164*2de3b87aSKai Wang cu->cu_pointer_size); 165*2de3b87aSKai Wang else if (cu->cu_version == 3) 166*2de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 167*2de3b87aSKai Wang dwarf_size); 168*2de3b87aSKai Wang break; 169*2de3b87aSKai Wang case DW_FORM_ref_udata: 170*2de3b87aSKai Wang case DW_FORM_udata: 171*2de3b87aSKai Wang atref.u[0].u64 = _dwarf_read_uleb128(ds->ds_data, offsetp); 172*2de3b87aSKai Wang break; 173*2de3b87aSKai Wang case DW_FORM_sdata: 174*2de3b87aSKai Wang atref.u[0].s64 = _dwarf_read_sleb128(ds->ds_data, offsetp); 175*2de3b87aSKai Wang break; 176*2de3b87aSKai Wang case DW_FORM_sec_offset: 177*2de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size); 178*2de3b87aSKai Wang break; 179*2de3b87aSKai Wang case DW_FORM_string: 180*2de3b87aSKai Wang atref.u[0].s = _dwarf_read_string(ds->ds_data, ds->ds_size, 181*2de3b87aSKai Wang offsetp); 182*2de3b87aSKai Wang break; 183*2de3b87aSKai Wang case DW_FORM_strp: 184*2de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size); 185*2de3b87aSKai Wang str = _dwarf_find_section(dbg, ".debug_str"); 186*2de3b87aSKai Wang assert(str != NULL); 187*2de3b87aSKai Wang atref.u[1].s = (char *) str->ds_data + atref.u[0].u64; 188*2de3b87aSKai Wang break; 189*2de3b87aSKai Wang case DW_FORM_ref_sig8: 190*2de3b87aSKai Wang atref.u[0].u64 = 8; 191*2de3b87aSKai Wang atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, 192*2de3b87aSKai Wang atref.u[0].u64); 193*2de3b87aSKai Wang break; 194*2de3b87aSKai Wang case DW_FORM_flag_present: 195*2de3b87aSKai Wang /* This form has no value encoded in the DIE. */ 196*2de3b87aSKai Wang atref.u[0].u64 = 1; 197*2de3b87aSKai Wang break; 198*2de3b87aSKai Wang default: 199*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); 200*2de3b87aSKai Wang ret = DW_DLE_ATTR_FORM_BAD; 201*2de3b87aSKai Wang break; 202*2de3b87aSKai Wang } 203*2de3b87aSKai Wang 204*2de3b87aSKai Wang if (ret == DW_DLE_NONE) { 205*2de3b87aSKai Wang if (form == DW_FORM_block || form == DW_FORM_block1 || 206*2de3b87aSKai Wang form == DW_FORM_block2 || form == DW_FORM_block4) { 207*2de3b87aSKai Wang atref.at_block.bl_len = atref.u[0].u64; 208*2de3b87aSKai Wang atref.at_block.bl_data = atref.u[1].u8p; 209*2de3b87aSKai Wang } 210*2de3b87aSKai Wang ret = _dwarf_attr_add(die, &atref, NULL, error); 211*2de3b87aSKai Wang } 212*2de3b87aSKai Wang 213*2de3b87aSKai Wang return (ret); 214*2de3b87aSKai Wang } 215*2de3b87aSKai Wang 216*2de3b87aSKai Wang static int 217*2de3b87aSKai Wang _dwarf_attr_write(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_Rel_Section drs, 218*2de3b87aSKai Wang Dwarf_CU cu, Dwarf_Attribute at, int pass2, Dwarf_Error *error) 219*2de3b87aSKai Wang { 220*2de3b87aSKai Wang struct _Dwarf_P_Expr_Entry *ee; 221*2de3b87aSKai Wang uint64_t value, offset, bs; 222*2de3b87aSKai Wang int ret; 223*2de3b87aSKai Wang 224*2de3b87aSKai Wang assert(dbg != NULL && ds != NULL && cu != NULL && at != NULL); 225*2de3b87aSKai Wang 226*2de3b87aSKai Wang /* Fill in reference to other DIE in the second pass. */ 227*2de3b87aSKai Wang if (pass2) { 228*2de3b87aSKai Wang if (at->at_form != DW_FORM_ref4 && at->at_form != DW_FORM_ref8) 229*2de3b87aSKai Wang return (DW_DLE_NONE); 230*2de3b87aSKai Wang if (at->at_refdie == NULL || at->at_offset == 0) 231*2de3b87aSKai Wang return (DW_DLE_NONE); 232*2de3b87aSKai Wang offset = at->at_offset; 233*2de3b87aSKai Wang dbg->write(ds->ds_data, &offset, at->at_refdie->die_offset, 234*2de3b87aSKai Wang at->at_form == DW_FORM_ref4 ? 4 : 8); 235*2de3b87aSKai Wang return (DW_DLE_NONE); 236*2de3b87aSKai Wang } 237*2de3b87aSKai Wang 238*2de3b87aSKai Wang switch (at->at_form) { 239*2de3b87aSKai Wang case DW_FORM_addr: 240*2de3b87aSKai Wang if (at->at_relsym) 241*2de3b87aSKai Wang ret = _dwarf_reloc_entry_add(dbg, drs, ds, 242*2de3b87aSKai Wang dwarf_drt_data_reloc, cu->cu_pointer_size, 243*2de3b87aSKai Wang ds->ds_size, at->at_relsym, at->u[0].u64, NULL, 244*2de3b87aSKai Wang error); 245*2de3b87aSKai Wang else 246*2de3b87aSKai Wang ret = WRITE_VALUE(at->u[0].u64, cu->cu_pointer_size); 247*2de3b87aSKai Wang break; 248*2de3b87aSKai Wang case DW_FORM_block: 249*2de3b87aSKai Wang case DW_FORM_block1: 250*2de3b87aSKai Wang case DW_FORM_block2: 251*2de3b87aSKai Wang case DW_FORM_block4: 252*2de3b87aSKai Wang /* Write block size. */ 253*2de3b87aSKai Wang if (at->at_form == DW_FORM_block) { 254*2de3b87aSKai Wang ret = _dwarf_write_uleb128_alloc(&ds->ds_data, 255*2de3b87aSKai Wang &ds->ds_cap, &ds->ds_size, at->u[0].u64, error); 256*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 257*2de3b87aSKai Wang break; 258*2de3b87aSKai Wang } else { 259*2de3b87aSKai Wang if (at->at_form == DW_FORM_block1) 260*2de3b87aSKai Wang bs = 1; 261*2de3b87aSKai Wang else if (at->at_form == DW_FORM_block2) 262*2de3b87aSKai Wang bs = 2; 263*2de3b87aSKai Wang else 264*2de3b87aSKai Wang bs = 4; 265*2de3b87aSKai Wang ret = WRITE_VALUE(at->u[0].u64, bs); 266*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 267*2de3b87aSKai Wang break; 268*2de3b87aSKai Wang } 269*2de3b87aSKai Wang 270*2de3b87aSKai Wang /* Keep block data offset for later use. */ 271*2de3b87aSKai Wang offset = ds->ds_size; 272*2de3b87aSKai Wang 273*2de3b87aSKai Wang /* Write block data. */ 274*2de3b87aSKai Wang ret = WRITE_BLOCK(at->u[1].u8p, at->u[0].u64); 275*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 276*2de3b87aSKai Wang break; 277*2de3b87aSKai Wang if (at->at_expr == NULL) 278*2de3b87aSKai Wang break; 279*2de3b87aSKai Wang 280*2de3b87aSKai Wang /* Generate relocation entry for DW_OP_addr expressions. */ 281*2de3b87aSKai Wang STAILQ_FOREACH(ee, &at->at_expr->pe_eelist, ee_next) { 282*2de3b87aSKai Wang if (ee->ee_loc.lr_atom != DW_OP_addr || ee->ee_sym == 0) 283*2de3b87aSKai Wang continue; 284*2de3b87aSKai Wang ret = _dwarf_reloc_entry_add(dbg, drs, ds, 285*2de3b87aSKai Wang dwarf_drt_data_reloc, dbg->dbg_pointer_size, 286*2de3b87aSKai Wang offset + ee->ee_loc.lr_offset + 1, ee->ee_sym, 287*2de3b87aSKai Wang ee->ee_loc.lr_number, NULL, error); 288*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 289*2de3b87aSKai Wang break; 290*2de3b87aSKai Wang } 291*2de3b87aSKai Wang break; 292*2de3b87aSKai Wang case DW_FORM_data1: 293*2de3b87aSKai Wang case DW_FORM_flag: 294*2de3b87aSKai Wang case DW_FORM_ref1: 295*2de3b87aSKai Wang ret = WRITE_VALUE(at->u[0].u64, 1); 296*2de3b87aSKai Wang break; 297*2de3b87aSKai Wang case DW_FORM_data2: 298*2de3b87aSKai Wang case DW_FORM_ref2: 299*2de3b87aSKai Wang ret = WRITE_VALUE(at->u[0].u64, 2); 300*2de3b87aSKai Wang break; 301*2de3b87aSKai Wang case DW_FORM_data4: 302*2de3b87aSKai Wang if (at->at_relsym || at->at_relsec != NULL) 303*2de3b87aSKai Wang ret = _dwarf_reloc_entry_add(dbg, drs, ds, 304*2de3b87aSKai Wang dwarf_drt_data_reloc, 4, ds->ds_size, at->at_relsym, 305*2de3b87aSKai Wang at->u[0].u64, at->at_relsec, error); 306*2de3b87aSKai Wang else 307*2de3b87aSKai Wang ret = WRITE_VALUE(at->u[0].u64, 4); 308*2de3b87aSKai Wang break; 309*2de3b87aSKai Wang case DW_FORM_data8: 310*2de3b87aSKai Wang if (at->at_relsym || at->at_relsec != NULL) 311*2de3b87aSKai Wang ret = _dwarf_reloc_entry_add(dbg, drs, ds, 312*2de3b87aSKai Wang dwarf_drt_data_reloc, 8, ds->ds_size, at->at_relsym, 313*2de3b87aSKai Wang at->u[0].u64, at->at_relsec, error); 314*2de3b87aSKai Wang else 315*2de3b87aSKai Wang ret = WRITE_VALUE(at->u[0].u64, 8); 316*2de3b87aSKai Wang break; 317*2de3b87aSKai Wang case DW_FORM_ref4: 318*2de3b87aSKai Wang case DW_FORM_ref8: 319*2de3b87aSKai Wang /* 320*2de3b87aSKai Wang * The value of ref4 and ref8 could be a reference to another 321*2de3b87aSKai Wang * DIE within the CU. And if we don't know the ref DIE's 322*2de3b87aSKai Wang * offset at the moement, then we remember at_offset and fill 323*2de3b87aSKai Wang * it in the second pass. 324*2de3b87aSKai Wang */ 325*2de3b87aSKai Wang if (at->at_refdie) { 326*2de3b87aSKai Wang value = at->at_refdie->die_offset; 327*2de3b87aSKai Wang if (value == 0) { 328*2de3b87aSKai Wang cu->cu_pass2 = 1; 329*2de3b87aSKai Wang at->at_offset = ds->ds_size; 330*2de3b87aSKai Wang } 331*2de3b87aSKai Wang } else 332*2de3b87aSKai Wang value = at->u[0].u64; 333*2de3b87aSKai Wang ret = WRITE_VALUE(value, at->at_form == DW_FORM_ref4 ? 4 : 8); 334*2de3b87aSKai Wang break; 335*2de3b87aSKai Wang case DW_FORM_indirect: 336*2de3b87aSKai Wang /* TODO. */ 337*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); 338*2de3b87aSKai Wang ret = DW_DLE_ATTR_FORM_BAD; 339*2de3b87aSKai Wang break; 340*2de3b87aSKai Wang case DW_FORM_ref_addr: 341*2de3b87aSKai Wang /* DWARF2 format. */ 342*2de3b87aSKai Wang if (at->at_relsym) 343*2de3b87aSKai Wang ret = _dwarf_reloc_entry_add(dbg, drs, ds, 344*2de3b87aSKai Wang dwarf_drt_data_reloc, cu->cu_pointer_size, 345*2de3b87aSKai Wang ds->ds_size, at->at_relsym, at->u[0].u64, NULL, 346*2de3b87aSKai Wang error); 347*2de3b87aSKai Wang else 348*2de3b87aSKai Wang ret = WRITE_VALUE(at->u[0].u64, cu->cu_pointer_size); 349*2de3b87aSKai Wang break; 350*2de3b87aSKai Wang case DW_FORM_ref_udata: 351*2de3b87aSKai Wang case DW_FORM_udata: 352*2de3b87aSKai Wang ret = WRITE_ULEB128(at->u[0].u64); 353*2de3b87aSKai Wang break; 354*2de3b87aSKai Wang case DW_FORM_sdata: 355*2de3b87aSKai Wang ret = WRITE_SLEB128(at->u[0].s64); 356*2de3b87aSKai Wang break; 357*2de3b87aSKai Wang case DW_FORM_string: 358*2de3b87aSKai Wang assert(at->u[0].s != NULL); 359*2de3b87aSKai Wang ret = WRITE_STRING(at->u[0].s); 360*2de3b87aSKai Wang break; 361*2de3b87aSKai Wang case DW_FORM_strp: 362*2de3b87aSKai Wang ret = _dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, 363*2de3b87aSKai Wang 4, ds->ds_size, 0, at->u[0].u64, ".debug_str", error); 364*2de3b87aSKai Wang break; 365*2de3b87aSKai Wang default: 366*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); 367*2de3b87aSKai Wang ret = DW_DLE_ATTR_FORM_BAD; 368*2de3b87aSKai Wang break; 369*2de3b87aSKai Wang } 370*2de3b87aSKai Wang 371*2de3b87aSKai Wang return (ret); 372*2de3b87aSKai Wang } 373*2de3b87aSKai Wang 374*2de3b87aSKai Wang int 375*2de3b87aSKai Wang _dwarf_add_AT_dataref(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 376*2de3b87aSKai Wang Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, const char *secname, 377*2de3b87aSKai Wang Dwarf_P_Attribute *atp, Dwarf_Error *error) 378*2de3b87aSKai Wang { 379*2de3b87aSKai Wang Dwarf_Attribute at; 380*2de3b87aSKai Wang int ret; 381*2de3b87aSKai Wang 382*2de3b87aSKai Wang assert(dbg != NULL && die != NULL); 383*2de3b87aSKai Wang 384*2de3b87aSKai Wang if ((ret = _dwarf_attr_alloc(die, &at, error)) != DW_DLE_NONE) 385*2de3b87aSKai Wang return (ret); 386*2de3b87aSKai Wang 387*2de3b87aSKai Wang at->at_die = die; 388*2de3b87aSKai Wang at->at_attrib = attr; 389*2de3b87aSKai Wang if (dbg->dbg_pointer_size == 4) 390*2de3b87aSKai Wang at->at_form = DW_FORM_data4; 391*2de3b87aSKai Wang else 392*2de3b87aSKai Wang at->at_form = DW_FORM_data8; 393*2de3b87aSKai Wang at->at_relsym = sym_index; 394*2de3b87aSKai Wang at->at_relsec = secname; 395*2de3b87aSKai Wang at->u[0].u64 = pc_value; 396*2de3b87aSKai Wang 397*2de3b87aSKai Wang STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 398*2de3b87aSKai Wang 399*2de3b87aSKai Wang if (atp) 400*2de3b87aSKai Wang *atp = at; 401*2de3b87aSKai Wang 402*2de3b87aSKai Wang return (DW_DLE_NONE); 403*2de3b87aSKai Wang } 404*2de3b87aSKai Wang 405*2de3b87aSKai Wang int 406*2de3b87aSKai Wang _dwarf_add_string_attr(Dwarf_P_Die die, Dwarf_P_Attribute *atp, Dwarf_Half attr, 407*2de3b87aSKai Wang char *string, Dwarf_Error *error) 408*2de3b87aSKai Wang { 409*2de3b87aSKai Wang Dwarf_Attribute at; 410*2de3b87aSKai Wang Dwarf_Debug dbg; 411*2de3b87aSKai Wang int ret; 412*2de3b87aSKai Wang 413*2de3b87aSKai Wang dbg = die != NULL ? die->die_dbg : NULL; 414*2de3b87aSKai Wang 415*2de3b87aSKai Wang assert(atp != NULL); 416*2de3b87aSKai Wang 417*2de3b87aSKai Wang if (die == NULL || string == NULL) { 418*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 419*2de3b87aSKai Wang return (DW_DLE_ARGUMENT); 420*2de3b87aSKai Wang } 421*2de3b87aSKai Wang 422*2de3b87aSKai Wang if ((ret = _dwarf_attr_alloc(die, &at, error)) != DW_DLE_NONE) 423*2de3b87aSKai Wang return (ret); 424*2de3b87aSKai Wang 425*2de3b87aSKai Wang at->at_die = die; 426*2de3b87aSKai Wang at->at_attrib = attr; 427*2de3b87aSKai Wang at->at_form = DW_FORM_strp; 428*2de3b87aSKai Wang if ((ret = _dwarf_strtab_add(dbg, string, &at->u[0].u64, 429*2de3b87aSKai Wang error)) != DW_DLE_NONE) { 430*2de3b87aSKai Wang free(at); 431*2de3b87aSKai Wang return (ret); 432*2de3b87aSKai Wang } 433*2de3b87aSKai Wang at->u[1].s = _dwarf_strtab_get_table(dbg) + at->u[0].u64; 434*2de3b87aSKai Wang 435*2de3b87aSKai Wang *atp = at; 436*2de3b87aSKai Wang 437*2de3b87aSKai Wang STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 438*2de3b87aSKai Wang 439*2de3b87aSKai Wang return (DW_DLE_NONE); 440*2de3b87aSKai Wang } 441*2de3b87aSKai Wang 442*2de3b87aSKai Wang int 443*2de3b87aSKai Wang _dwarf_attr_gen(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_Rel_Section drs, 444*2de3b87aSKai Wang Dwarf_CU cu, Dwarf_Die die, int pass2, Dwarf_Error *error) 445*2de3b87aSKai Wang { 446*2de3b87aSKai Wang Dwarf_Attribute at; 447*2de3b87aSKai Wang int ret; 448*2de3b87aSKai Wang 449*2de3b87aSKai Wang assert(dbg != NULL && ds != NULL && cu != NULL && die != NULL); 450*2de3b87aSKai Wang 451*2de3b87aSKai Wang STAILQ_FOREACH(at, &die->die_attr, at_next) { 452*2de3b87aSKai Wang ret = _dwarf_attr_write(dbg, ds, drs, cu, at, pass2, error); 453*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 454*2de3b87aSKai Wang return (ret); 455*2de3b87aSKai Wang } 456*2de3b87aSKai Wang 457*2de3b87aSKai Wang return (DW_DLE_NONE); 458*2de3b87aSKai Wang } 459