12de3b87aSKai Wang /*- 22de3b87aSKai Wang * Copyright (c) 2007 John Birrell (jb@freebsd.org) 32de3b87aSKai Wang * Copyright (c) 2009-2011 Kai Wang 42de3b87aSKai Wang * All rights reserved. 52de3b87aSKai Wang * 62de3b87aSKai Wang * Redistribution and use in source and binary forms, with or without 72de3b87aSKai Wang * modification, are permitted provided that the following conditions 82de3b87aSKai Wang * are met: 92de3b87aSKai Wang * 1. Redistributions of source code must retain the above copyright 102de3b87aSKai Wang * notice, this list of conditions and the following disclaimer. 112de3b87aSKai Wang * 2. Redistributions in binary form must reproduce the above copyright 122de3b87aSKai Wang * notice, this list of conditions and the following disclaimer in the 132de3b87aSKai Wang * documentation and/or other materials provided with the distribution. 142de3b87aSKai Wang * 152de3b87aSKai Wang * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND 162de3b87aSKai Wang * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE 172de3b87aSKai Wang * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE 182de3b87aSKai Wang * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE 192de3b87aSKai Wang * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL 202de3b87aSKai Wang * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS 212de3b87aSKai Wang * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) 222de3b87aSKai Wang * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT 232de3b87aSKai Wang * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY 242de3b87aSKai Wang * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF 252de3b87aSKai Wang * SUCH DAMAGE. 262de3b87aSKai Wang */ 272de3b87aSKai Wang 282de3b87aSKai Wang #include "_libdwarf.h" 292de3b87aSKai Wang 30cf781b2eSEd Maste ELFTC_VCSID("$Id: libdwarf_attr.c 3064 2014-06-06 19:35:55Z kaiwang27 $"); 312de3b87aSKai Wang 322de3b87aSKai Wang int 332de3b87aSKai Wang _dwarf_attr_alloc(Dwarf_Die die, Dwarf_Attribute *atp, Dwarf_Error *error) 342de3b87aSKai Wang { 352de3b87aSKai Wang Dwarf_Attribute at; 362de3b87aSKai Wang 372de3b87aSKai Wang assert(die != NULL); 382de3b87aSKai Wang assert(atp != NULL); 392de3b87aSKai Wang 402de3b87aSKai Wang if ((at = calloc(1, sizeof(struct _Dwarf_Attribute))) == NULL) { 412de3b87aSKai Wang DWARF_SET_ERROR(die->die_dbg, error, DW_DLE_MEMORY); 422de3b87aSKai Wang return (DW_DLE_MEMORY); 432de3b87aSKai Wang } 442de3b87aSKai Wang 452de3b87aSKai Wang *atp = at; 462de3b87aSKai Wang 472de3b87aSKai Wang return (DW_DLE_NONE); 482de3b87aSKai Wang } 492de3b87aSKai Wang 502de3b87aSKai Wang static int 512de3b87aSKai Wang _dwarf_attr_add(Dwarf_Die die, Dwarf_Attribute atref, Dwarf_Attribute *atp, 522de3b87aSKai Wang Dwarf_Error *error) 532de3b87aSKai Wang { 542de3b87aSKai Wang Dwarf_Attribute at; 552de3b87aSKai Wang int ret; 562de3b87aSKai Wang 572de3b87aSKai Wang if ((ret = _dwarf_attr_alloc(die, &at, error)) != DW_DLE_NONE) 582de3b87aSKai Wang return (ret); 592de3b87aSKai Wang 602de3b87aSKai Wang memcpy(at, atref, sizeof(struct _Dwarf_Attribute)); 612de3b87aSKai Wang 622de3b87aSKai Wang STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 632de3b87aSKai Wang 642de3b87aSKai Wang /* Save a pointer to the attribute name if this is one. */ 652de3b87aSKai Wang if (at->at_attrib == DW_AT_name) { 662de3b87aSKai Wang switch (at->at_form) { 672de3b87aSKai Wang case DW_FORM_strp: 682de3b87aSKai Wang die->die_name = at->u[1].s; 692de3b87aSKai Wang break; 702de3b87aSKai Wang case DW_FORM_string: 712de3b87aSKai Wang die->die_name = at->u[0].s; 722de3b87aSKai Wang break; 732de3b87aSKai Wang default: 742de3b87aSKai Wang break; 752de3b87aSKai Wang } 762de3b87aSKai Wang } 772de3b87aSKai Wang 782de3b87aSKai Wang if (atp != NULL) 792de3b87aSKai Wang *atp = at; 802de3b87aSKai Wang 812de3b87aSKai Wang return (DW_DLE_NONE); 822de3b87aSKai Wang } 832de3b87aSKai Wang 842de3b87aSKai Wang Dwarf_Attribute 852de3b87aSKai Wang _dwarf_attr_find(Dwarf_Die die, Dwarf_Half attr) 862de3b87aSKai Wang { 872de3b87aSKai Wang Dwarf_Attribute at; 882de3b87aSKai Wang 892de3b87aSKai Wang STAILQ_FOREACH(at, &die->die_attr, at_next) { 902de3b87aSKai Wang if (at->at_attrib == attr) 912de3b87aSKai Wang break; 922de3b87aSKai Wang } 932de3b87aSKai Wang 942de3b87aSKai Wang return (at); 952de3b87aSKai Wang } 962de3b87aSKai Wang 972de3b87aSKai Wang int 982de3b87aSKai Wang _dwarf_attr_init(Dwarf_Debug dbg, Dwarf_Section *ds, uint64_t *offsetp, 992de3b87aSKai Wang int dwarf_size, Dwarf_CU cu, Dwarf_Die die, Dwarf_AttrDef ad, 1002de3b87aSKai Wang uint64_t form, int indirect, Dwarf_Error *error) 1012de3b87aSKai Wang { 1022de3b87aSKai Wang struct _Dwarf_Attribute atref; 1032de3b87aSKai Wang int ret; 1042de3b87aSKai Wang 1052de3b87aSKai Wang ret = DW_DLE_NONE; 1062de3b87aSKai Wang memset(&atref, 0, sizeof(atref)); 1072de3b87aSKai Wang atref.at_die = die; 108cf781b2eSEd Maste atref.at_offset = *offsetp; 1092de3b87aSKai Wang atref.at_attrib = ad->ad_attrib; 1102de3b87aSKai Wang atref.at_form = indirect ? form : ad->ad_form; 1112de3b87aSKai Wang atref.at_indirect = indirect; 1122de3b87aSKai Wang atref.at_ld = NULL; 1132de3b87aSKai Wang 1142de3b87aSKai Wang switch (form) { 1152de3b87aSKai Wang case DW_FORM_addr: 1162de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 1172de3b87aSKai Wang cu->cu_pointer_size); 1182de3b87aSKai Wang break; 1192de3b87aSKai Wang case DW_FORM_block: 1202de3b87aSKai Wang case DW_FORM_exprloc: 1212de3b87aSKai Wang atref.u[0].u64 = _dwarf_read_uleb128(ds->ds_data, offsetp); 1222de3b87aSKai Wang atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, 1232de3b87aSKai Wang atref.u[0].u64); 1242de3b87aSKai Wang break; 1252de3b87aSKai Wang case DW_FORM_block1: 1262de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 1); 1272de3b87aSKai Wang atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, 1282de3b87aSKai Wang atref.u[0].u64); 1292de3b87aSKai Wang break; 1302de3b87aSKai Wang case DW_FORM_block2: 1312de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 2); 1322de3b87aSKai Wang atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, 1332de3b87aSKai Wang atref.u[0].u64); 1342de3b87aSKai Wang break; 1352de3b87aSKai Wang case DW_FORM_block4: 1362de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 4); 1372de3b87aSKai Wang atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, 1382de3b87aSKai Wang atref.u[0].u64); 1392de3b87aSKai Wang break; 1402de3b87aSKai Wang case DW_FORM_data1: 1412de3b87aSKai Wang case DW_FORM_flag: 1422de3b87aSKai Wang case DW_FORM_ref1: 1432de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 1); 1442de3b87aSKai Wang break; 1452de3b87aSKai Wang case DW_FORM_data2: 1462de3b87aSKai Wang case DW_FORM_ref2: 1472de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 2); 1482de3b87aSKai Wang break; 1492de3b87aSKai Wang case DW_FORM_data4: 1502de3b87aSKai Wang case DW_FORM_ref4: 1512de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 4); 1522de3b87aSKai Wang break; 1532de3b87aSKai Wang case DW_FORM_data8: 1542de3b87aSKai Wang case DW_FORM_ref8: 1552de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 8); 1562de3b87aSKai Wang break; 1572de3b87aSKai Wang case DW_FORM_indirect: 1582de3b87aSKai Wang form = _dwarf_read_uleb128(ds->ds_data, offsetp); 1592de3b87aSKai Wang return (_dwarf_attr_init(dbg, ds, offsetp, dwarf_size, cu, die, 1602de3b87aSKai Wang ad, form, 1, error)); 1612de3b87aSKai Wang case DW_FORM_ref_addr: 1622de3b87aSKai Wang if (cu->cu_version == 2) 1632de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 1642de3b87aSKai Wang cu->cu_pointer_size); 165cf781b2eSEd Maste else 1662de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, 1672de3b87aSKai Wang dwarf_size); 1682de3b87aSKai Wang break; 1692de3b87aSKai Wang case DW_FORM_ref_udata: 1702de3b87aSKai Wang case DW_FORM_udata: 1712de3b87aSKai Wang atref.u[0].u64 = _dwarf_read_uleb128(ds->ds_data, offsetp); 1722de3b87aSKai Wang break; 1732de3b87aSKai Wang case DW_FORM_sdata: 1742de3b87aSKai Wang atref.u[0].s64 = _dwarf_read_sleb128(ds->ds_data, offsetp); 1752de3b87aSKai Wang break; 1762de3b87aSKai Wang case DW_FORM_sec_offset: 1772de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size); 1782de3b87aSKai Wang break; 1792de3b87aSKai Wang case DW_FORM_string: 1802de3b87aSKai Wang atref.u[0].s = _dwarf_read_string(ds->ds_data, ds->ds_size, 1812de3b87aSKai Wang offsetp); 1822de3b87aSKai Wang break; 1832de3b87aSKai Wang case DW_FORM_strp: 1842de3b87aSKai Wang atref.u[0].u64 = dbg->read(ds->ds_data, offsetp, dwarf_size); 185*ab69795fSMark Johnston atref.u[1].s = _dwarf_strtab_get_table(dbg) + atref.u[0].u64; 1862de3b87aSKai Wang break; 1872de3b87aSKai Wang case DW_FORM_ref_sig8: 1882de3b87aSKai Wang atref.u[0].u64 = 8; 1892de3b87aSKai Wang atref.u[1].u8p = _dwarf_read_block(ds->ds_data, offsetp, 1902de3b87aSKai Wang atref.u[0].u64); 1912de3b87aSKai Wang break; 1922de3b87aSKai Wang case DW_FORM_flag_present: 1932de3b87aSKai Wang /* This form has no value encoded in the DIE. */ 1942de3b87aSKai Wang atref.u[0].u64 = 1; 1952de3b87aSKai Wang break; 1962de3b87aSKai Wang default: 1972de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); 1982de3b87aSKai Wang ret = DW_DLE_ATTR_FORM_BAD; 1992de3b87aSKai Wang break; 2002de3b87aSKai Wang } 2012de3b87aSKai Wang 2022de3b87aSKai Wang if (ret == DW_DLE_NONE) { 2032de3b87aSKai Wang if (form == DW_FORM_block || form == DW_FORM_block1 || 2042de3b87aSKai Wang form == DW_FORM_block2 || form == DW_FORM_block4) { 2052de3b87aSKai Wang atref.at_block.bl_len = atref.u[0].u64; 2062de3b87aSKai Wang atref.at_block.bl_data = atref.u[1].u8p; 2072de3b87aSKai Wang } 2082de3b87aSKai Wang ret = _dwarf_attr_add(die, &atref, NULL, error); 2092de3b87aSKai Wang } 2102de3b87aSKai Wang 2112de3b87aSKai Wang return (ret); 2122de3b87aSKai Wang } 2132de3b87aSKai Wang 2142de3b87aSKai Wang static int 2152de3b87aSKai Wang _dwarf_attr_write(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_Rel_Section drs, 2162de3b87aSKai Wang Dwarf_CU cu, Dwarf_Attribute at, int pass2, Dwarf_Error *error) 2172de3b87aSKai Wang { 2182de3b87aSKai Wang struct _Dwarf_P_Expr_Entry *ee; 2192de3b87aSKai Wang uint64_t value, offset, bs; 2202de3b87aSKai Wang int ret; 2212de3b87aSKai Wang 2222de3b87aSKai Wang assert(dbg != NULL && ds != NULL && cu != NULL && at != NULL); 2232de3b87aSKai Wang 2242de3b87aSKai Wang /* Fill in reference to other DIE in the second pass. */ 2252de3b87aSKai Wang if (pass2) { 2262de3b87aSKai Wang if (at->at_form != DW_FORM_ref4 && at->at_form != DW_FORM_ref8) 2272de3b87aSKai Wang return (DW_DLE_NONE); 2282de3b87aSKai Wang if (at->at_refdie == NULL || at->at_offset == 0) 2292de3b87aSKai Wang return (DW_DLE_NONE); 2302de3b87aSKai Wang offset = at->at_offset; 2312de3b87aSKai Wang dbg->write(ds->ds_data, &offset, at->at_refdie->die_offset, 2322de3b87aSKai Wang at->at_form == DW_FORM_ref4 ? 4 : 8); 2332de3b87aSKai Wang return (DW_DLE_NONE); 2342de3b87aSKai Wang } 2352de3b87aSKai Wang 2362de3b87aSKai Wang switch (at->at_form) { 2372de3b87aSKai Wang case DW_FORM_addr: 2382de3b87aSKai Wang if (at->at_relsym) 2392de3b87aSKai Wang ret = _dwarf_reloc_entry_add(dbg, drs, ds, 2402de3b87aSKai Wang dwarf_drt_data_reloc, cu->cu_pointer_size, 2412de3b87aSKai Wang ds->ds_size, at->at_relsym, at->u[0].u64, NULL, 2422de3b87aSKai Wang error); 2432de3b87aSKai Wang else 2442de3b87aSKai Wang ret = WRITE_VALUE(at->u[0].u64, cu->cu_pointer_size); 2452de3b87aSKai Wang break; 2462de3b87aSKai Wang case DW_FORM_block: 2472de3b87aSKai Wang case DW_FORM_block1: 2482de3b87aSKai Wang case DW_FORM_block2: 2492de3b87aSKai Wang case DW_FORM_block4: 2502de3b87aSKai Wang /* Write block size. */ 2512de3b87aSKai Wang if (at->at_form == DW_FORM_block) { 2522de3b87aSKai Wang ret = _dwarf_write_uleb128_alloc(&ds->ds_data, 2532de3b87aSKai Wang &ds->ds_cap, &ds->ds_size, at->u[0].u64, error); 2542de3b87aSKai Wang if (ret != DW_DLE_NONE) 2552de3b87aSKai Wang break; 2562de3b87aSKai Wang } else { 2572de3b87aSKai Wang if (at->at_form == DW_FORM_block1) 2582de3b87aSKai Wang bs = 1; 2592de3b87aSKai Wang else if (at->at_form == DW_FORM_block2) 2602de3b87aSKai Wang bs = 2; 2612de3b87aSKai Wang else 2622de3b87aSKai Wang bs = 4; 2632de3b87aSKai Wang ret = WRITE_VALUE(at->u[0].u64, bs); 2642de3b87aSKai Wang if (ret != DW_DLE_NONE) 2652de3b87aSKai Wang break; 2662de3b87aSKai Wang } 2672de3b87aSKai Wang 2682de3b87aSKai Wang /* Keep block data offset for later use. */ 2692de3b87aSKai Wang offset = ds->ds_size; 2702de3b87aSKai Wang 2712de3b87aSKai Wang /* Write block data. */ 2722de3b87aSKai Wang ret = WRITE_BLOCK(at->u[1].u8p, at->u[0].u64); 2732de3b87aSKai Wang if (ret != DW_DLE_NONE) 2742de3b87aSKai Wang break; 2752de3b87aSKai Wang if (at->at_expr == NULL) 2762de3b87aSKai Wang break; 2772de3b87aSKai Wang 2782de3b87aSKai Wang /* Generate relocation entry for DW_OP_addr expressions. */ 2792de3b87aSKai Wang STAILQ_FOREACH(ee, &at->at_expr->pe_eelist, ee_next) { 2802de3b87aSKai Wang if (ee->ee_loc.lr_atom != DW_OP_addr || ee->ee_sym == 0) 2812de3b87aSKai Wang continue; 2822de3b87aSKai Wang ret = _dwarf_reloc_entry_add(dbg, drs, ds, 2832de3b87aSKai Wang dwarf_drt_data_reloc, dbg->dbg_pointer_size, 2842de3b87aSKai Wang offset + ee->ee_loc.lr_offset + 1, ee->ee_sym, 2852de3b87aSKai Wang ee->ee_loc.lr_number, NULL, error); 2862de3b87aSKai Wang if (ret != DW_DLE_NONE) 2872de3b87aSKai Wang break; 2882de3b87aSKai Wang } 2892de3b87aSKai Wang break; 2902de3b87aSKai Wang case DW_FORM_data1: 2912de3b87aSKai Wang case DW_FORM_flag: 2922de3b87aSKai Wang case DW_FORM_ref1: 2932de3b87aSKai Wang ret = WRITE_VALUE(at->u[0].u64, 1); 2942de3b87aSKai Wang break; 2952de3b87aSKai Wang case DW_FORM_data2: 2962de3b87aSKai Wang case DW_FORM_ref2: 2972de3b87aSKai Wang ret = WRITE_VALUE(at->u[0].u64, 2); 2982de3b87aSKai Wang break; 2992de3b87aSKai Wang case DW_FORM_data4: 3002de3b87aSKai Wang if (at->at_relsym || at->at_relsec != NULL) 3012de3b87aSKai Wang ret = _dwarf_reloc_entry_add(dbg, drs, ds, 3022de3b87aSKai Wang dwarf_drt_data_reloc, 4, ds->ds_size, at->at_relsym, 3032de3b87aSKai Wang at->u[0].u64, at->at_relsec, error); 3042de3b87aSKai Wang else 3052de3b87aSKai Wang ret = WRITE_VALUE(at->u[0].u64, 4); 3062de3b87aSKai Wang break; 3072de3b87aSKai Wang case DW_FORM_data8: 3082de3b87aSKai Wang if (at->at_relsym || at->at_relsec != NULL) 3092de3b87aSKai Wang ret = _dwarf_reloc_entry_add(dbg, drs, ds, 3102de3b87aSKai Wang dwarf_drt_data_reloc, 8, ds->ds_size, at->at_relsym, 3112de3b87aSKai Wang at->u[0].u64, at->at_relsec, error); 3122de3b87aSKai Wang else 3132de3b87aSKai Wang ret = WRITE_VALUE(at->u[0].u64, 8); 3142de3b87aSKai Wang break; 3152de3b87aSKai Wang case DW_FORM_ref4: 3162de3b87aSKai Wang case DW_FORM_ref8: 3172de3b87aSKai Wang /* 3182de3b87aSKai Wang * The value of ref4 and ref8 could be a reference to another 3192de3b87aSKai Wang * DIE within the CU. And if we don't know the ref DIE's 3202de3b87aSKai Wang * offset at the moement, then we remember at_offset and fill 3212de3b87aSKai Wang * it in the second pass. 3222de3b87aSKai Wang */ 3232de3b87aSKai Wang if (at->at_refdie) { 3242de3b87aSKai Wang value = at->at_refdie->die_offset; 3252de3b87aSKai Wang if (value == 0) { 3262de3b87aSKai Wang cu->cu_pass2 = 1; 3272de3b87aSKai Wang at->at_offset = ds->ds_size; 3282de3b87aSKai Wang } 3292de3b87aSKai Wang } else 3302de3b87aSKai Wang value = at->u[0].u64; 3312de3b87aSKai Wang ret = WRITE_VALUE(value, at->at_form == DW_FORM_ref4 ? 4 : 8); 3322de3b87aSKai Wang break; 3332de3b87aSKai Wang case DW_FORM_indirect: 3342de3b87aSKai Wang /* TODO. */ 3352de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); 3362de3b87aSKai Wang ret = DW_DLE_ATTR_FORM_BAD; 3372de3b87aSKai Wang break; 3382de3b87aSKai Wang case DW_FORM_ref_addr: 3392de3b87aSKai Wang /* DWARF2 format. */ 3402de3b87aSKai Wang if (at->at_relsym) 3412de3b87aSKai Wang ret = _dwarf_reloc_entry_add(dbg, drs, ds, 3422de3b87aSKai Wang dwarf_drt_data_reloc, cu->cu_pointer_size, 3432de3b87aSKai Wang ds->ds_size, at->at_relsym, at->u[0].u64, NULL, 3442de3b87aSKai Wang error); 3452de3b87aSKai Wang else 3462de3b87aSKai Wang ret = WRITE_VALUE(at->u[0].u64, cu->cu_pointer_size); 3472de3b87aSKai Wang break; 3482de3b87aSKai Wang case DW_FORM_ref_udata: 3492de3b87aSKai Wang case DW_FORM_udata: 3502de3b87aSKai Wang ret = WRITE_ULEB128(at->u[0].u64); 3512de3b87aSKai Wang break; 3522de3b87aSKai Wang case DW_FORM_sdata: 3532de3b87aSKai Wang ret = WRITE_SLEB128(at->u[0].s64); 3542de3b87aSKai Wang break; 3552de3b87aSKai Wang case DW_FORM_string: 3562de3b87aSKai Wang assert(at->u[0].s != NULL); 3572de3b87aSKai Wang ret = WRITE_STRING(at->u[0].s); 3582de3b87aSKai Wang break; 3592de3b87aSKai Wang case DW_FORM_strp: 3602de3b87aSKai Wang ret = _dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, 3612de3b87aSKai Wang 4, ds->ds_size, 0, at->u[0].u64, ".debug_str", error); 3622de3b87aSKai Wang break; 3632de3b87aSKai Wang default: 3642de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ATTR_FORM_BAD); 3652de3b87aSKai Wang ret = DW_DLE_ATTR_FORM_BAD; 3662de3b87aSKai Wang break; 3672de3b87aSKai Wang } 3682de3b87aSKai Wang 3692de3b87aSKai Wang return (ret); 3702de3b87aSKai Wang } 3712de3b87aSKai Wang 3722de3b87aSKai Wang int 3732de3b87aSKai Wang _dwarf_add_AT_dataref(Dwarf_P_Debug dbg, Dwarf_P_Die die, Dwarf_Half attr, 3742de3b87aSKai Wang Dwarf_Unsigned pc_value, Dwarf_Unsigned sym_index, const char *secname, 3752de3b87aSKai Wang Dwarf_P_Attribute *atp, Dwarf_Error *error) 3762de3b87aSKai Wang { 3772de3b87aSKai Wang Dwarf_Attribute at; 3782de3b87aSKai Wang int ret; 3792de3b87aSKai Wang 3802de3b87aSKai Wang assert(dbg != NULL && die != NULL); 3812de3b87aSKai Wang 3822de3b87aSKai Wang if ((ret = _dwarf_attr_alloc(die, &at, error)) != DW_DLE_NONE) 3832de3b87aSKai Wang return (ret); 3842de3b87aSKai Wang 3852de3b87aSKai Wang at->at_die = die; 3862de3b87aSKai Wang at->at_attrib = attr; 3872de3b87aSKai Wang if (dbg->dbg_pointer_size == 4) 3882de3b87aSKai Wang at->at_form = DW_FORM_data4; 3892de3b87aSKai Wang else 3902de3b87aSKai Wang at->at_form = DW_FORM_data8; 3912de3b87aSKai Wang at->at_relsym = sym_index; 3922de3b87aSKai Wang at->at_relsec = secname; 3932de3b87aSKai Wang at->u[0].u64 = pc_value; 3942de3b87aSKai Wang 3952de3b87aSKai Wang STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 3962de3b87aSKai Wang 3972de3b87aSKai Wang if (atp) 3982de3b87aSKai Wang *atp = at; 3992de3b87aSKai Wang 4002de3b87aSKai Wang return (DW_DLE_NONE); 4012de3b87aSKai Wang } 4022de3b87aSKai Wang 4032de3b87aSKai Wang int 4042de3b87aSKai Wang _dwarf_add_string_attr(Dwarf_P_Die die, Dwarf_P_Attribute *atp, Dwarf_Half attr, 4052de3b87aSKai Wang char *string, Dwarf_Error *error) 4062de3b87aSKai Wang { 4072de3b87aSKai Wang Dwarf_Attribute at; 4082de3b87aSKai Wang Dwarf_Debug dbg; 4092de3b87aSKai Wang int ret; 4102de3b87aSKai Wang 4112de3b87aSKai Wang dbg = die != NULL ? die->die_dbg : NULL; 4122de3b87aSKai Wang 4132de3b87aSKai Wang assert(atp != NULL); 4142de3b87aSKai Wang 4152de3b87aSKai Wang if (die == NULL || string == NULL) { 4162de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_ARGUMENT); 4172de3b87aSKai Wang return (DW_DLE_ARGUMENT); 4182de3b87aSKai Wang } 4192de3b87aSKai Wang 4202de3b87aSKai Wang if ((ret = _dwarf_attr_alloc(die, &at, error)) != DW_DLE_NONE) 4212de3b87aSKai Wang return (ret); 4222de3b87aSKai Wang 4232de3b87aSKai Wang at->at_die = die; 4242de3b87aSKai Wang at->at_attrib = attr; 4252de3b87aSKai Wang at->at_form = DW_FORM_strp; 4262de3b87aSKai Wang if ((ret = _dwarf_strtab_add(dbg, string, &at->u[0].u64, 4272de3b87aSKai Wang error)) != DW_DLE_NONE) { 4282de3b87aSKai Wang free(at); 4292de3b87aSKai Wang return (ret); 4302de3b87aSKai Wang } 4312de3b87aSKai Wang at->u[1].s = _dwarf_strtab_get_table(dbg) + at->u[0].u64; 4322de3b87aSKai Wang 4332de3b87aSKai Wang *atp = at; 4342de3b87aSKai Wang 4352de3b87aSKai Wang STAILQ_INSERT_TAIL(&die->die_attr, at, at_next); 4362de3b87aSKai Wang 4372de3b87aSKai Wang return (DW_DLE_NONE); 4382de3b87aSKai Wang } 4392de3b87aSKai Wang 4402de3b87aSKai Wang int 4412de3b87aSKai Wang _dwarf_attr_gen(Dwarf_P_Debug dbg, Dwarf_P_Section ds, Dwarf_Rel_Section drs, 4422de3b87aSKai Wang Dwarf_CU cu, Dwarf_Die die, int pass2, Dwarf_Error *error) 4432de3b87aSKai Wang { 4442de3b87aSKai Wang Dwarf_Attribute at; 4452de3b87aSKai Wang int ret; 4462de3b87aSKai Wang 4472de3b87aSKai Wang assert(dbg != NULL && ds != NULL && cu != NULL && die != NULL); 4482de3b87aSKai Wang 4492de3b87aSKai Wang STAILQ_FOREACH(at, &die->die_attr, at_next) { 4502de3b87aSKai Wang ret = _dwarf_attr_write(dbg, ds, drs, cu, at, pass2, error); 4512de3b87aSKai Wang if (ret != DW_DLE_NONE) 4522de3b87aSKai Wang return (ret); 4532de3b87aSKai Wang } 4542de3b87aSKai Wang 4552de3b87aSKai Wang return (DW_DLE_NONE); 4562de3b87aSKai Wang } 457