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_die.c 2948 2013-05-30 21:25:52Z kaiwang27 $"); 31*2de3b87aSKai Wang 32*2de3b87aSKai Wang int 33*2de3b87aSKai Wang _dwarf_die_alloc(Dwarf_Debug dbg, Dwarf_Die *ret_die, Dwarf_Error *error) 34*2de3b87aSKai Wang { 35*2de3b87aSKai Wang Dwarf_Die die; 36*2de3b87aSKai Wang 37*2de3b87aSKai Wang assert(ret_die != NULL); 38*2de3b87aSKai Wang 39*2de3b87aSKai Wang if ((die = calloc(1, sizeof(struct _Dwarf_Die))) == NULL) { 40*2de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 41*2de3b87aSKai Wang return (DW_DLE_MEMORY); 42*2de3b87aSKai Wang } 43*2de3b87aSKai Wang 44*2de3b87aSKai Wang STAILQ_INIT(&die->die_attr); 45*2de3b87aSKai Wang 46*2de3b87aSKai Wang *ret_die = die; 47*2de3b87aSKai Wang 48*2de3b87aSKai Wang return (DW_DLE_NONE); 49*2de3b87aSKai Wang } 50*2de3b87aSKai Wang 51*2de3b87aSKai Wang static int 52*2de3b87aSKai Wang _dwarf_die_add(Dwarf_CU cu, uint64_t offset, uint64_t abnum, Dwarf_Abbrev ab, 53*2de3b87aSKai Wang Dwarf_Die *diep, Dwarf_Error *error) 54*2de3b87aSKai Wang { 55*2de3b87aSKai Wang Dwarf_Debug dbg; 56*2de3b87aSKai Wang Dwarf_Die die; 57*2de3b87aSKai Wang int ret; 58*2de3b87aSKai Wang 59*2de3b87aSKai Wang assert(cu != NULL); 60*2de3b87aSKai Wang assert(ab != NULL); 61*2de3b87aSKai Wang 62*2de3b87aSKai Wang dbg = cu->cu_dbg; 63*2de3b87aSKai Wang 64*2de3b87aSKai Wang if ((ret = _dwarf_die_alloc(dbg, &die, error)) != DW_DLE_NONE) 65*2de3b87aSKai Wang return (ret); 66*2de3b87aSKai Wang 67*2de3b87aSKai Wang die->die_offset = offset; 68*2de3b87aSKai Wang die->die_abnum = abnum; 69*2de3b87aSKai Wang die->die_ab = ab; 70*2de3b87aSKai Wang die->die_cu = cu; 71*2de3b87aSKai Wang die->die_dbg = cu->cu_dbg; 72*2de3b87aSKai Wang 73*2de3b87aSKai Wang if (diep != NULL) 74*2de3b87aSKai Wang *diep = die; 75*2de3b87aSKai Wang 76*2de3b87aSKai Wang return (DW_DLE_NONE); 77*2de3b87aSKai Wang } 78*2de3b87aSKai Wang 79*2de3b87aSKai Wang /* Find die at offset 'off' within the same CU. */ 80*2de3b87aSKai Wang Dwarf_Die 81*2de3b87aSKai Wang _dwarf_die_find(Dwarf_Die die, Dwarf_Unsigned off) 82*2de3b87aSKai Wang { 83*2de3b87aSKai Wang Dwarf_Debug dbg; 84*2de3b87aSKai Wang Dwarf_CU cu; 85*2de3b87aSKai Wang Dwarf_Die die1; 86*2de3b87aSKai Wang Dwarf_Error de; 87*2de3b87aSKai Wang int ret; 88*2de3b87aSKai Wang 89*2de3b87aSKai Wang cu = die->die_cu; 90*2de3b87aSKai Wang dbg = die->die_dbg; 91*2de3b87aSKai Wang 92*2de3b87aSKai Wang ret = _dwarf_die_parse(dbg, dbg->dbg_info_sec, cu, cu->cu_dwarf_size, 93*2de3b87aSKai Wang off, cu->cu_next_offset, &die1, 0, &de); 94*2de3b87aSKai Wang 95*2de3b87aSKai Wang if (ret == DW_DLE_NONE) 96*2de3b87aSKai Wang return (die1); 97*2de3b87aSKai Wang else 98*2de3b87aSKai Wang return (NULL); 99*2de3b87aSKai Wang } 100*2de3b87aSKai Wang 101*2de3b87aSKai Wang int 102*2de3b87aSKai Wang _dwarf_die_parse(Dwarf_Debug dbg, Dwarf_Section *ds, Dwarf_CU cu, 103*2de3b87aSKai Wang int dwarf_size, uint64_t offset, uint64_t next_offset, Dwarf_Die *ret_die, 104*2de3b87aSKai Wang int search_sibling, Dwarf_Error *error) 105*2de3b87aSKai Wang { 106*2de3b87aSKai Wang Dwarf_Abbrev ab; 107*2de3b87aSKai Wang Dwarf_AttrDef ad; 108*2de3b87aSKai Wang Dwarf_Die die; 109*2de3b87aSKai Wang uint64_t abnum; 110*2de3b87aSKai Wang uint64_t die_offset; 111*2de3b87aSKai Wang int ret, level; 112*2de3b87aSKai Wang 113*2de3b87aSKai Wang assert(cu != NULL); 114*2de3b87aSKai Wang 115*2de3b87aSKai Wang level = 1; 116*2de3b87aSKai Wang die = NULL; 117*2de3b87aSKai Wang 118*2de3b87aSKai Wang while (offset < next_offset && offset < ds->ds_size) { 119*2de3b87aSKai Wang 120*2de3b87aSKai Wang die_offset = offset; 121*2de3b87aSKai Wang 122*2de3b87aSKai Wang abnum = _dwarf_read_uleb128(ds->ds_data, &offset); 123*2de3b87aSKai Wang 124*2de3b87aSKai Wang if (abnum == 0) { 125*2de3b87aSKai Wang if (level == 0 || !search_sibling) 126*2de3b87aSKai Wang return (DW_DLE_NO_ENTRY); 127*2de3b87aSKai Wang 128*2de3b87aSKai Wang /* 129*2de3b87aSKai Wang * Return to previous DIE level. 130*2de3b87aSKai Wang */ 131*2de3b87aSKai Wang level--; 132*2de3b87aSKai Wang continue; 133*2de3b87aSKai Wang } 134*2de3b87aSKai Wang 135*2de3b87aSKai Wang if ((ret = _dwarf_abbrev_find(cu, abnum, &ab, error)) != 136*2de3b87aSKai Wang DW_DLE_NONE) 137*2de3b87aSKai Wang return (ret); 138*2de3b87aSKai Wang 139*2de3b87aSKai Wang if ((ret = _dwarf_die_add(cu, die_offset, abnum, ab, &die, 140*2de3b87aSKai Wang error)) != DW_DLE_NONE) 141*2de3b87aSKai Wang return (ret); 142*2de3b87aSKai Wang 143*2de3b87aSKai Wang STAILQ_FOREACH(ad, &ab->ab_attrdef, ad_next) { 144*2de3b87aSKai Wang if ((ret = _dwarf_attr_init(dbg, ds, &offset, 145*2de3b87aSKai Wang dwarf_size, cu, die, ad, ad->ad_form, 0, 146*2de3b87aSKai Wang error)) != DW_DLE_NONE) 147*2de3b87aSKai Wang return (ret); 148*2de3b87aSKai Wang } 149*2de3b87aSKai Wang 150*2de3b87aSKai Wang die->die_next_off = offset; 151*2de3b87aSKai Wang if (search_sibling && level > 0) { 152*2de3b87aSKai Wang dwarf_dealloc(dbg, die, DW_DLA_DIE); 153*2de3b87aSKai Wang if (ab->ab_children == DW_CHILDREN_yes) { 154*2de3b87aSKai Wang /* Advance to next DIE level. */ 155*2de3b87aSKai Wang level++; 156*2de3b87aSKai Wang } 157*2de3b87aSKai Wang } else { 158*2de3b87aSKai Wang *ret_die = die; 159*2de3b87aSKai Wang return (DW_DLE_NONE); 160*2de3b87aSKai Wang } 161*2de3b87aSKai Wang } 162*2de3b87aSKai Wang 163*2de3b87aSKai Wang return (DW_DLE_NO_ENTRY); 164*2de3b87aSKai Wang } 165*2de3b87aSKai Wang 166*2de3b87aSKai Wang void 167*2de3b87aSKai Wang _dwarf_die_link(Dwarf_P_Die die, Dwarf_P_Die parent, Dwarf_P_Die child, 168*2de3b87aSKai Wang Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling) 169*2de3b87aSKai Wang { 170*2de3b87aSKai Wang Dwarf_P_Die last_child; 171*2de3b87aSKai Wang 172*2de3b87aSKai Wang assert(die != NULL); 173*2de3b87aSKai Wang 174*2de3b87aSKai Wang if (parent) { 175*2de3b87aSKai Wang 176*2de3b87aSKai Wang /* Disconnect from old parent. */ 177*2de3b87aSKai Wang if (die->die_parent) { 178*2de3b87aSKai Wang if (die->die_parent != parent) { 179*2de3b87aSKai Wang if (die->die_parent->die_child == die) 180*2de3b87aSKai Wang die->die_parent->die_child = NULL; 181*2de3b87aSKai Wang die->die_parent = NULL; 182*2de3b87aSKai Wang } 183*2de3b87aSKai Wang } 184*2de3b87aSKai Wang 185*2de3b87aSKai Wang /* Find the last child of this parent. */ 186*2de3b87aSKai Wang last_child = parent->die_child; 187*2de3b87aSKai Wang if (last_child) { 188*2de3b87aSKai Wang while (last_child->die_right != NULL) 189*2de3b87aSKai Wang last_child = last_child->die_right; 190*2de3b87aSKai Wang } 191*2de3b87aSKai Wang 192*2de3b87aSKai Wang /* Connect to new parent. */ 193*2de3b87aSKai Wang die->die_parent = parent; 194*2de3b87aSKai Wang 195*2de3b87aSKai Wang /* 196*2de3b87aSKai Wang * Attach this DIE to the end of sibling list. If new 197*2de3b87aSKai Wang * parent doesn't have any child, set this DIE as the 198*2de3b87aSKai Wang * first child. 199*2de3b87aSKai Wang */ 200*2de3b87aSKai Wang if (last_child) { 201*2de3b87aSKai Wang assert(last_child->die_right == NULL); 202*2de3b87aSKai Wang last_child->die_right = die; 203*2de3b87aSKai Wang die->die_left = last_child; 204*2de3b87aSKai Wang } else 205*2de3b87aSKai Wang parent->die_child = die; 206*2de3b87aSKai Wang } 207*2de3b87aSKai Wang 208*2de3b87aSKai Wang if (child) { 209*2de3b87aSKai Wang 210*2de3b87aSKai Wang /* Disconnect from old child. */ 211*2de3b87aSKai Wang if (die->die_child) { 212*2de3b87aSKai Wang if (die->die_child != child) { 213*2de3b87aSKai Wang die->die_child->die_parent = NULL; 214*2de3b87aSKai Wang die->die_child = NULL; 215*2de3b87aSKai Wang } 216*2de3b87aSKai Wang } 217*2de3b87aSKai Wang 218*2de3b87aSKai Wang /* Connect to new child. */ 219*2de3b87aSKai Wang die->die_child = child; 220*2de3b87aSKai Wang child->die_parent = die; 221*2de3b87aSKai Wang } 222*2de3b87aSKai Wang 223*2de3b87aSKai Wang if (left_sibling) { 224*2de3b87aSKai Wang 225*2de3b87aSKai Wang /* Disconnect from old left sibling. */ 226*2de3b87aSKai Wang if (die->die_left) { 227*2de3b87aSKai Wang if (die->die_left != left_sibling) { 228*2de3b87aSKai Wang die->die_left->die_right = NULL; 229*2de3b87aSKai Wang die->die_left = NULL; 230*2de3b87aSKai Wang } 231*2de3b87aSKai Wang } 232*2de3b87aSKai Wang 233*2de3b87aSKai Wang /* Connect to new right sibling. */ 234*2de3b87aSKai Wang die->die_left = left_sibling; 235*2de3b87aSKai Wang left_sibling->die_right = die; 236*2de3b87aSKai Wang } 237*2de3b87aSKai Wang 238*2de3b87aSKai Wang if (right_sibling) { 239*2de3b87aSKai Wang 240*2de3b87aSKai Wang /* Disconnect from old right sibling. */ 241*2de3b87aSKai Wang if (die->die_right) { 242*2de3b87aSKai Wang if (die->die_right != right_sibling) { 243*2de3b87aSKai Wang die->die_right->die_left = NULL; 244*2de3b87aSKai Wang die->die_right = NULL; 245*2de3b87aSKai Wang } 246*2de3b87aSKai Wang } 247*2de3b87aSKai Wang 248*2de3b87aSKai Wang /* Connect to new right sibling. */ 249*2de3b87aSKai Wang die->die_right = right_sibling; 250*2de3b87aSKai Wang right_sibling->die_left = die; 251*2de3b87aSKai Wang } 252*2de3b87aSKai Wang } 253*2de3b87aSKai Wang 254*2de3b87aSKai Wang int 255*2de3b87aSKai Wang _dwarf_die_count_links(Dwarf_P_Die parent, Dwarf_P_Die child, 256*2de3b87aSKai Wang Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling) 257*2de3b87aSKai Wang { 258*2de3b87aSKai Wang int count; 259*2de3b87aSKai Wang 260*2de3b87aSKai Wang count = 0; 261*2de3b87aSKai Wang 262*2de3b87aSKai Wang if (parent) 263*2de3b87aSKai Wang count++; 264*2de3b87aSKai Wang if (child) 265*2de3b87aSKai Wang count++; 266*2de3b87aSKai Wang if (left_sibling) 267*2de3b87aSKai Wang count++; 268*2de3b87aSKai Wang if (right_sibling) 269*2de3b87aSKai Wang count++; 270*2de3b87aSKai Wang 271*2de3b87aSKai Wang return (count); 272*2de3b87aSKai Wang } 273*2de3b87aSKai Wang 274*2de3b87aSKai Wang static int 275*2de3b87aSKai Wang _dwarf_die_gen_recursive(Dwarf_P_Debug dbg, Dwarf_CU cu, Dwarf_Rel_Section drs, 276*2de3b87aSKai Wang Dwarf_P_Die die, int pass2, Dwarf_Error *error) 277*2de3b87aSKai Wang { 278*2de3b87aSKai Wang Dwarf_P_Section ds; 279*2de3b87aSKai Wang Dwarf_Abbrev ab; 280*2de3b87aSKai Wang Dwarf_Attribute at; 281*2de3b87aSKai Wang Dwarf_AttrDef ad; 282*2de3b87aSKai Wang int match, ret; 283*2de3b87aSKai Wang 284*2de3b87aSKai Wang ds = dbg->dbgp_info; 285*2de3b87aSKai Wang assert(ds != NULL); 286*2de3b87aSKai Wang 287*2de3b87aSKai Wang if (pass2) 288*2de3b87aSKai Wang goto attr_gen; 289*2de3b87aSKai Wang 290*2de3b87aSKai Wang /* 291*2de3b87aSKai Wang * Add DW_AT_sibling attribute for DIEs with children, so consumers 292*2de3b87aSKai Wang * can quickly scan chains of siblings, while ignoring the children 293*2de3b87aSKai Wang * of individual siblings. 294*2de3b87aSKai Wang */ 295*2de3b87aSKai Wang if (die->die_child && die->die_right) { 296*2de3b87aSKai Wang if (_dwarf_attr_find(die, DW_AT_sibling) == NULL) 297*2de3b87aSKai Wang (void) dwarf_add_AT_reference(dbg, die, DW_AT_sibling, 298*2de3b87aSKai Wang die->die_right, error); 299*2de3b87aSKai Wang } 300*2de3b87aSKai Wang 301*2de3b87aSKai Wang /* 302*2de3b87aSKai Wang * Search abbrev list to find a matching entry. 303*2de3b87aSKai Wang */ 304*2de3b87aSKai Wang die->die_ab = NULL; 305*2de3b87aSKai Wang for (ab = cu->cu_abbrev_hash; ab != NULL; ab = ab->ab_hh.next) { 306*2de3b87aSKai Wang if (die->die_tag != ab->ab_tag) 307*2de3b87aSKai Wang continue; 308*2de3b87aSKai Wang if (ab->ab_children == DW_CHILDREN_no && die->die_child != NULL) 309*2de3b87aSKai Wang continue; 310*2de3b87aSKai Wang if (ab->ab_children == DW_CHILDREN_yes && 311*2de3b87aSKai Wang die->die_child == NULL) 312*2de3b87aSKai Wang continue; 313*2de3b87aSKai Wang at = STAILQ_FIRST(&die->die_attr); 314*2de3b87aSKai Wang ad = STAILQ_FIRST(&ab->ab_attrdef); 315*2de3b87aSKai Wang match = 1; 316*2de3b87aSKai Wang while (at != NULL && ad != NULL) { 317*2de3b87aSKai Wang if (at->at_attrib != ad->ad_attrib || 318*2de3b87aSKai Wang at->at_form != ad->ad_form) { 319*2de3b87aSKai Wang match = 0; 320*2de3b87aSKai Wang break; 321*2de3b87aSKai Wang } 322*2de3b87aSKai Wang at = STAILQ_NEXT(at, at_next); 323*2de3b87aSKai Wang ad = STAILQ_NEXT(ad, ad_next); 324*2de3b87aSKai Wang } 325*2de3b87aSKai Wang if ((at == NULL && ad != NULL) || (at != NULL && ad == NULL)) 326*2de3b87aSKai Wang match = 0; 327*2de3b87aSKai Wang if (match) { 328*2de3b87aSKai Wang die->die_ab = ab; 329*2de3b87aSKai Wang break; 330*2de3b87aSKai Wang } 331*2de3b87aSKai Wang } 332*2de3b87aSKai Wang 333*2de3b87aSKai Wang /* 334*2de3b87aSKai Wang * Create a new abbrev entry if we can not reuse any existing one. 335*2de3b87aSKai Wang */ 336*2de3b87aSKai Wang if (die->die_ab == NULL) { 337*2de3b87aSKai Wang ret = _dwarf_abbrev_add(cu, ++cu->cu_abbrev_cnt, die->die_tag, 338*2de3b87aSKai Wang die->die_child != NULL ? DW_CHILDREN_yes : DW_CHILDREN_no, 339*2de3b87aSKai Wang 0, &ab, error); 340*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 341*2de3b87aSKai Wang return (ret); 342*2de3b87aSKai Wang STAILQ_FOREACH(at, &die->die_attr, at_next) { 343*2de3b87aSKai Wang ret = _dwarf_attrdef_add(dbg, ab, at->at_attrib, 344*2de3b87aSKai Wang at->at_form, 0, NULL, error); 345*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 346*2de3b87aSKai Wang return (ret); 347*2de3b87aSKai Wang } 348*2de3b87aSKai Wang die->die_ab = ab; 349*2de3b87aSKai Wang } 350*2de3b87aSKai Wang 351*2de3b87aSKai Wang die->die_offset = ds->ds_size; 352*2de3b87aSKai Wang 353*2de3b87aSKai Wang /* 354*2de3b87aSKai Wang * Transform the DIE to bytes stream. 355*2de3b87aSKai Wang */ 356*2de3b87aSKai Wang ret = _dwarf_write_uleb128_alloc(&ds->ds_data, &ds->ds_cap, 357*2de3b87aSKai Wang &ds->ds_size, die->die_ab->ab_entry, error); 358*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 359*2de3b87aSKai Wang return (ret); 360*2de3b87aSKai Wang 361*2de3b87aSKai Wang attr_gen: 362*2de3b87aSKai Wang 363*2de3b87aSKai Wang /* Transform the attributes of this DIE. */ 364*2de3b87aSKai Wang ret = _dwarf_attr_gen(dbg, ds, drs, cu, die, pass2, error); 365*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 366*2de3b87aSKai Wang return (ret); 367*2de3b87aSKai Wang 368*2de3b87aSKai Wang /* Proceed to child DIE. */ 369*2de3b87aSKai Wang if (die->die_child != NULL) { 370*2de3b87aSKai Wang ret = _dwarf_die_gen_recursive(dbg, cu, drs, die->die_child, 371*2de3b87aSKai Wang pass2, error); 372*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 373*2de3b87aSKai Wang return (ret); 374*2de3b87aSKai Wang } 375*2de3b87aSKai Wang 376*2de3b87aSKai Wang /* Proceed to sibling DIE. */ 377*2de3b87aSKai Wang if (die->die_right != NULL) { 378*2de3b87aSKai Wang ret = _dwarf_die_gen_recursive(dbg, cu, drs, die->die_right, 379*2de3b87aSKai Wang pass2, error); 380*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 381*2de3b87aSKai Wang return (ret); 382*2de3b87aSKai Wang } 383*2de3b87aSKai Wang 384*2de3b87aSKai Wang /* Write a null DIE indicating the end of current level. */ 385*2de3b87aSKai Wang if (die->die_right == NULL) { 386*2de3b87aSKai Wang ret = _dwarf_write_uleb128_alloc(&ds->ds_data, &ds->ds_cap, 387*2de3b87aSKai Wang &ds->ds_size, 0, error); 388*2de3b87aSKai Wang if (ret != DW_DLE_NONE) 389*2de3b87aSKai Wang return (ret); 390*2de3b87aSKai Wang } 391*2de3b87aSKai Wang 392*2de3b87aSKai Wang return (DW_DLE_NONE); 393*2de3b87aSKai Wang } 394*2de3b87aSKai Wang 395*2de3b87aSKai Wang int 396*2de3b87aSKai Wang _dwarf_die_gen(Dwarf_P_Debug dbg, Dwarf_CU cu, Dwarf_Rel_Section drs, 397*2de3b87aSKai Wang Dwarf_Error *error) 398*2de3b87aSKai Wang { 399*2de3b87aSKai Wang Dwarf_Abbrev ab, tab; 400*2de3b87aSKai Wang Dwarf_AttrDef ad, tad; 401*2de3b87aSKai Wang Dwarf_Die die; 402*2de3b87aSKai Wang int ret; 403*2de3b87aSKai Wang 404*2de3b87aSKai Wang assert(dbg != NULL && cu != NULL); 405*2de3b87aSKai Wang assert(dbg->dbgp_root_die != NULL); 406*2de3b87aSKai Wang 407*2de3b87aSKai Wang die = dbg->dbgp_root_die; 408*2de3b87aSKai Wang 409*2de3b87aSKai Wang /* 410*2de3b87aSKai Wang * Insert a DW_AT_stmt_list attribute into root DIE, if there are 411*2de3b87aSKai Wang * line number information. 412*2de3b87aSKai Wang */ 413*2de3b87aSKai Wang if (!STAILQ_EMPTY(&dbg->dbgp_lineinfo->li_lnlist)) 414*2de3b87aSKai Wang RCHECK(_dwarf_add_AT_dataref(dbg, die, DW_AT_stmt_list, 0, 0, 415*2de3b87aSKai Wang ".debug_line", NULL, error)); 416*2de3b87aSKai Wang 417*2de3b87aSKai Wang RCHECK(_dwarf_die_gen_recursive(dbg, cu, drs, die, 0, error)); 418*2de3b87aSKai Wang 419*2de3b87aSKai Wang if (cu->cu_pass2) 420*2de3b87aSKai Wang RCHECK(_dwarf_die_gen_recursive(dbg, cu, drs, die, 1, error)); 421*2de3b87aSKai Wang 422*2de3b87aSKai Wang return (DW_DLE_NONE); 423*2de3b87aSKai Wang 424*2de3b87aSKai Wang gen_fail: 425*2de3b87aSKai Wang 426*2de3b87aSKai Wang HASH_ITER(ab_hh, cu->cu_abbrev_hash, ab, tab) { 427*2de3b87aSKai Wang HASH_DELETE(ab_hh, cu->cu_abbrev_hash, ab); 428*2de3b87aSKai Wang STAILQ_FOREACH_SAFE(ad, &ab->ab_attrdef, ad_next, tad) { 429*2de3b87aSKai Wang STAILQ_REMOVE(&ab->ab_attrdef, ad, _Dwarf_AttrDef, 430*2de3b87aSKai Wang ad_next); 431*2de3b87aSKai Wang free(ad); 432*2de3b87aSKai Wang } 433*2de3b87aSKai Wang free(ab); 434*2de3b87aSKai Wang } 435*2de3b87aSKai Wang 436*2de3b87aSKai Wang return (ret); 437*2de3b87aSKai Wang } 438*2de3b87aSKai Wang 439*2de3b87aSKai Wang void 440*2de3b87aSKai Wang _dwarf_die_pro_cleanup(Dwarf_P_Debug dbg) 441*2de3b87aSKai Wang { 442*2de3b87aSKai Wang Dwarf_P_Die die, tdie; 443*2de3b87aSKai Wang Dwarf_P_Attribute at, tat; 444*2de3b87aSKai Wang 445*2de3b87aSKai Wang assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); 446*2de3b87aSKai Wang 447*2de3b87aSKai Wang STAILQ_FOREACH_SAFE(die, &dbg->dbgp_dielist, die_pro_next, tdie) { 448*2de3b87aSKai Wang STAILQ_FOREACH_SAFE(at, &die->die_attr, at_next, tat) { 449*2de3b87aSKai Wang STAILQ_REMOVE(&die->die_attr, at, _Dwarf_Attribute, 450*2de3b87aSKai Wang at_next); 451*2de3b87aSKai Wang free(at); 452*2de3b87aSKai Wang } 453*2de3b87aSKai Wang free(die); 454*2de3b87aSKai Wang } 455*2de3b87aSKai Wang } 456