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
30*cf781b2eSEd Maste ELFTC_VCSID("$Id: libdwarf_die.c 3039 2014-05-18 15:10:56Z kaiwang27 $");
312de3b87aSKai Wang
322de3b87aSKai Wang int
_dwarf_die_alloc(Dwarf_Debug dbg,Dwarf_Die * ret_die,Dwarf_Error * error)332de3b87aSKai Wang _dwarf_die_alloc(Dwarf_Debug dbg, Dwarf_Die *ret_die, Dwarf_Error *error)
342de3b87aSKai Wang {
352de3b87aSKai Wang Dwarf_Die die;
362de3b87aSKai Wang
372de3b87aSKai Wang assert(ret_die != NULL);
382de3b87aSKai Wang
392de3b87aSKai Wang if ((die = calloc(1, sizeof(struct _Dwarf_Die))) == NULL) {
402de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY);
412de3b87aSKai Wang return (DW_DLE_MEMORY);
422de3b87aSKai Wang }
432de3b87aSKai Wang
442de3b87aSKai Wang STAILQ_INIT(&die->die_attr);
452de3b87aSKai Wang
462de3b87aSKai Wang *ret_die = die;
472de3b87aSKai Wang
482de3b87aSKai Wang return (DW_DLE_NONE);
492de3b87aSKai Wang }
502de3b87aSKai Wang
512de3b87aSKai Wang static int
_dwarf_die_add(Dwarf_CU cu,uint64_t offset,uint64_t abnum,Dwarf_Abbrev ab,Dwarf_Die * diep,Dwarf_Error * error)522de3b87aSKai Wang _dwarf_die_add(Dwarf_CU cu, uint64_t offset, uint64_t abnum, Dwarf_Abbrev ab,
532de3b87aSKai Wang Dwarf_Die *diep, Dwarf_Error *error)
542de3b87aSKai Wang {
552de3b87aSKai Wang Dwarf_Debug dbg;
562de3b87aSKai Wang Dwarf_Die die;
572de3b87aSKai Wang int ret;
582de3b87aSKai Wang
592de3b87aSKai Wang assert(cu != NULL);
602de3b87aSKai Wang assert(ab != NULL);
612de3b87aSKai Wang
622de3b87aSKai Wang dbg = cu->cu_dbg;
632de3b87aSKai Wang
642de3b87aSKai Wang if ((ret = _dwarf_die_alloc(dbg, &die, error)) != DW_DLE_NONE)
652de3b87aSKai Wang return (ret);
662de3b87aSKai Wang
672de3b87aSKai Wang die->die_offset = offset;
682de3b87aSKai Wang die->die_abnum = abnum;
692de3b87aSKai Wang die->die_ab = ab;
702de3b87aSKai Wang die->die_cu = cu;
712de3b87aSKai Wang die->die_dbg = cu->cu_dbg;
722de3b87aSKai Wang
732de3b87aSKai Wang *diep = die;
742de3b87aSKai Wang
752de3b87aSKai Wang return (DW_DLE_NONE);
762de3b87aSKai Wang }
772de3b87aSKai Wang
782de3b87aSKai Wang /* Find die at offset 'off' within the same CU. */
792de3b87aSKai Wang Dwarf_Die
_dwarf_die_find(Dwarf_Die die,Dwarf_Unsigned off)802de3b87aSKai Wang _dwarf_die_find(Dwarf_Die die, Dwarf_Unsigned off)
812de3b87aSKai Wang {
822de3b87aSKai Wang Dwarf_Debug dbg;
83*cf781b2eSEd Maste Dwarf_Section *ds;
842de3b87aSKai Wang Dwarf_CU cu;
852de3b87aSKai Wang Dwarf_Die die1;
862de3b87aSKai Wang Dwarf_Error de;
872de3b87aSKai Wang int ret;
882de3b87aSKai Wang
892de3b87aSKai Wang cu = die->die_cu;
902de3b87aSKai Wang dbg = die->die_dbg;
91*cf781b2eSEd Maste ds = cu->cu_is_info ? dbg->dbg_info_sec : dbg->dbg_types_sec;
922de3b87aSKai Wang
93*cf781b2eSEd Maste ret = _dwarf_die_parse(dbg, ds, cu, cu->cu_dwarf_size, off,
94*cf781b2eSEd Maste cu->cu_next_offset, &die1, 0, &de);
952de3b87aSKai Wang
962de3b87aSKai Wang if (ret == DW_DLE_NONE)
972de3b87aSKai Wang return (die1);
982de3b87aSKai Wang else
992de3b87aSKai Wang return (NULL);
1002de3b87aSKai Wang }
1012de3b87aSKai Wang
1022de3b87aSKai Wang int
_dwarf_die_parse(Dwarf_Debug dbg,Dwarf_Section * ds,Dwarf_CU cu,int dwarf_size,uint64_t offset,uint64_t next_offset,Dwarf_Die * ret_die,int search_sibling,Dwarf_Error * error)1032de3b87aSKai Wang _dwarf_die_parse(Dwarf_Debug dbg, Dwarf_Section *ds, Dwarf_CU cu,
1042de3b87aSKai Wang int dwarf_size, uint64_t offset, uint64_t next_offset, Dwarf_Die *ret_die,
1052de3b87aSKai Wang int search_sibling, Dwarf_Error *error)
1062de3b87aSKai Wang {
1072de3b87aSKai Wang Dwarf_Abbrev ab;
1082de3b87aSKai Wang Dwarf_AttrDef ad;
1092de3b87aSKai Wang Dwarf_Die die;
1102de3b87aSKai Wang uint64_t abnum;
1112de3b87aSKai Wang uint64_t die_offset;
1122de3b87aSKai Wang int ret, level;
1132de3b87aSKai Wang
1142de3b87aSKai Wang assert(cu != NULL);
1152de3b87aSKai Wang
1162de3b87aSKai Wang level = 1;
1172de3b87aSKai Wang die = NULL;
1182de3b87aSKai Wang
1192de3b87aSKai Wang while (offset < next_offset && offset < ds->ds_size) {
1202de3b87aSKai Wang
1212de3b87aSKai Wang die_offset = offset;
1222de3b87aSKai Wang
1232de3b87aSKai Wang abnum = _dwarf_read_uleb128(ds->ds_data, &offset);
1242de3b87aSKai Wang
1252de3b87aSKai Wang if (abnum == 0) {
1262de3b87aSKai Wang if (level == 0 || !search_sibling)
1272de3b87aSKai Wang return (DW_DLE_NO_ENTRY);
1282de3b87aSKai Wang
1292de3b87aSKai Wang /*
1302de3b87aSKai Wang * Return to previous DIE level.
1312de3b87aSKai Wang */
1322de3b87aSKai Wang level--;
1332de3b87aSKai Wang continue;
1342de3b87aSKai Wang }
1352de3b87aSKai Wang
1362de3b87aSKai Wang if ((ret = _dwarf_abbrev_find(cu, abnum, &ab, error)) !=
1372de3b87aSKai Wang DW_DLE_NONE)
1382de3b87aSKai Wang return (ret);
1392de3b87aSKai Wang
1402de3b87aSKai Wang if ((ret = _dwarf_die_add(cu, die_offset, abnum, ab, &die,
1412de3b87aSKai Wang error)) != DW_DLE_NONE)
1422de3b87aSKai Wang return (ret);
1432de3b87aSKai Wang
1442de3b87aSKai Wang STAILQ_FOREACH(ad, &ab->ab_attrdef, ad_next) {
1452de3b87aSKai Wang if ((ret = _dwarf_attr_init(dbg, ds, &offset,
1462de3b87aSKai Wang dwarf_size, cu, die, ad, ad->ad_form, 0,
1472de3b87aSKai Wang error)) != DW_DLE_NONE)
1482de3b87aSKai Wang return (ret);
1492de3b87aSKai Wang }
1502de3b87aSKai Wang
1512de3b87aSKai Wang die->die_next_off = offset;
1522de3b87aSKai Wang if (search_sibling && level > 0) {
1532de3b87aSKai Wang dwarf_dealloc(dbg, die, DW_DLA_DIE);
1542de3b87aSKai Wang if (ab->ab_children == DW_CHILDREN_yes) {
1552de3b87aSKai Wang /* Advance to next DIE level. */
1562de3b87aSKai Wang level++;
1572de3b87aSKai Wang }
1582de3b87aSKai Wang } else {
1592de3b87aSKai Wang *ret_die = die;
1602de3b87aSKai Wang return (DW_DLE_NONE);
1612de3b87aSKai Wang }
1622de3b87aSKai Wang }
1632de3b87aSKai Wang
1642de3b87aSKai Wang return (DW_DLE_NO_ENTRY);
1652de3b87aSKai Wang }
1662de3b87aSKai Wang
1672de3b87aSKai Wang void
_dwarf_die_link(Dwarf_P_Die die,Dwarf_P_Die parent,Dwarf_P_Die child,Dwarf_P_Die left_sibling,Dwarf_P_Die right_sibling)1682de3b87aSKai Wang _dwarf_die_link(Dwarf_P_Die die, Dwarf_P_Die parent, Dwarf_P_Die child,
1692de3b87aSKai Wang Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling)
1702de3b87aSKai Wang {
1712de3b87aSKai Wang Dwarf_P_Die last_child;
1722de3b87aSKai Wang
1732de3b87aSKai Wang assert(die != NULL);
1742de3b87aSKai Wang
1752de3b87aSKai Wang if (parent) {
1762de3b87aSKai Wang
1772de3b87aSKai Wang /* Disconnect from old parent. */
1782de3b87aSKai Wang if (die->die_parent) {
1792de3b87aSKai Wang if (die->die_parent != parent) {
1802de3b87aSKai Wang if (die->die_parent->die_child == die)
1812de3b87aSKai Wang die->die_parent->die_child = NULL;
1822de3b87aSKai Wang die->die_parent = NULL;
1832de3b87aSKai Wang }
1842de3b87aSKai Wang }
1852de3b87aSKai Wang
1862de3b87aSKai Wang /* Find the last child of this parent. */
1872de3b87aSKai Wang last_child = parent->die_child;
1882de3b87aSKai Wang if (last_child) {
1892de3b87aSKai Wang while (last_child->die_right != NULL)
1902de3b87aSKai Wang last_child = last_child->die_right;
1912de3b87aSKai Wang }
1922de3b87aSKai Wang
1932de3b87aSKai Wang /* Connect to new parent. */
1942de3b87aSKai Wang die->die_parent = parent;
1952de3b87aSKai Wang
1962de3b87aSKai Wang /*
1972de3b87aSKai Wang * Attach this DIE to the end of sibling list. If new
1982de3b87aSKai Wang * parent doesn't have any child, set this DIE as the
1992de3b87aSKai Wang * first child.
2002de3b87aSKai Wang */
2012de3b87aSKai Wang if (last_child) {
2022de3b87aSKai Wang assert(last_child->die_right == NULL);
2032de3b87aSKai Wang last_child->die_right = die;
2042de3b87aSKai Wang die->die_left = last_child;
2052de3b87aSKai Wang } else
2062de3b87aSKai Wang parent->die_child = die;
2072de3b87aSKai Wang }
2082de3b87aSKai Wang
2092de3b87aSKai Wang if (child) {
2102de3b87aSKai Wang
2112de3b87aSKai Wang /* Disconnect from old child. */
2122de3b87aSKai Wang if (die->die_child) {
2132de3b87aSKai Wang if (die->die_child != child) {
2142de3b87aSKai Wang die->die_child->die_parent = NULL;
2152de3b87aSKai Wang die->die_child = NULL;
2162de3b87aSKai Wang }
2172de3b87aSKai Wang }
2182de3b87aSKai Wang
2192de3b87aSKai Wang /* Connect to new child. */
2202de3b87aSKai Wang die->die_child = child;
2212de3b87aSKai Wang child->die_parent = die;
2222de3b87aSKai Wang }
2232de3b87aSKai Wang
2242de3b87aSKai Wang if (left_sibling) {
2252de3b87aSKai Wang
2262de3b87aSKai Wang /* Disconnect from old left sibling. */
2272de3b87aSKai Wang if (die->die_left) {
2282de3b87aSKai Wang if (die->die_left != left_sibling) {
2292de3b87aSKai Wang die->die_left->die_right = NULL;
2302de3b87aSKai Wang die->die_left = NULL;
2312de3b87aSKai Wang }
2322de3b87aSKai Wang }
2332de3b87aSKai Wang
2342de3b87aSKai Wang /* Connect to new right sibling. */
2352de3b87aSKai Wang die->die_left = left_sibling;
2362de3b87aSKai Wang left_sibling->die_right = die;
2372de3b87aSKai Wang }
2382de3b87aSKai Wang
2392de3b87aSKai Wang if (right_sibling) {
2402de3b87aSKai Wang
2412de3b87aSKai Wang /* Disconnect from old right sibling. */
2422de3b87aSKai Wang if (die->die_right) {
2432de3b87aSKai Wang if (die->die_right != right_sibling) {
2442de3b87aSKai Wang die->die_right->die_left = NULL;
2452de3b87aSKai Wang die->die_right = NULL;
2462de3b87aSKai Wang }
2472de3b87aSKai Wang }
2482de3b87aSKai Wang
2492de3b87aSKai Wang /* Connect to new right sibling. */
2502de3b87aSKai Wang die->die_right = right_sibling;
2512de3b87aSKai Wang right_sibling->die_left = die;
2522de3b87aSKai Wang }
2532de3b87aSKai Wang }
2542de3b87aSKai Wang
2552de3b87aSKai Wang int
_dwarf_die_count_links(Dwarf_P_Die parent,Dwarf_P_Die child,Dwarf_P_Die left_sibling,Dwarf_P_Die right_sibling)2562de3b87aSKai Wang _dwarf_die_count_links(Dwarf_P_Die parent, Dwarf_P_Die child,
2572de3b87aSKai Wang Dwarf_P_Die left_sibling, Dwarf_P_Die right_sibling)
2582de3b87aSKai Wang {
2592de3b87aSKai Wang int count;
2602de3b87aSKai Wang
2612de3b87aSKai Wang count = 0;
2622de3b87aSKai Wang
2632de3b87aSKai Wang if (parent)
2642de3b87aSKai Wang count++;
2652de3b87aSKai Wang if (child)
2662de3b87aSKai Wang count++;
2672de3b87aSKai Wang if (left_sibling)
2682de3b87aSKai Wang count++;
2692de3b87aSKai Wang if (right_sibling)
2702de3b87aSKai Wang count++;
2712de3b87aSKai Wang
2722de3b87aSKai Wang return (count);
2732de3b87aSKai Wang }
2742de3b87aSKai Wang
2752de3b87aSKai Wang static int
_dwarf_die_gen_recursive(Dwarf_P_Debug dbg,Dwarf_CU cu,Dwarf_Rel_Section drs,Dwarf_P_Die die,int pass2,Dwarf_Error * error)2762de3b87aSKai Wang _dwarf_die_gen_recursive(Dwarf_P_Debug dbg, Dwarf_CU cu, Dwarf_Rel_Section drs,
2772de3b87aSKai Wang Dwarf_P_Die die, int pass2, Dwarf_Error *error)
2782de3b87aSKai Wang {
2792de3b87aSKai Wang Dwarf_P_Section ds;
2802de3b87aSKai Wang Dwarf_Abbrev ab;
2812de3b87aSKai Wang Dwarf_Attribute at;
2822de3b87aSKai Wang Dwarf_AttrDef ad;
2832de3b87aSKai Wang int match, ret;
2842de3b87aSKai Wang
2852de3b87aSKai Wang ds = dbg->dbgp_info;
2862de3b87aSKai Wang assert(ds != NULL);
2872de3b87aSKai Wang
2882de3b87aSKai Wang if (pass2)
2892de3b87aSKai Wang goto attr_gen;
2902de3b87aSKai Wang
2912de3b87aSKai Wang /*
2922de3b87aSKai Wang * Add DW_AT_sibling attribute for DIEs with children, so consumers
2932de3b87aSKai Wang * can quickly scan chains of siblings, while ignoring the children
2942de3b87aSKai Wang * of individual siblings.
2952de3b87aSKai Wang */
2962de3b87aSKai Wang if (die->die_child && die->die_right) {
2972de3b87aSKai Wang if (_dwarf_attr_find(die, DW_AT_sibling) == NULL)
2982de3b87aSKai Wang (void) dwarf_add_AT_reference(dbg, die, DW_AT_sibling,
2992de3b87aSKai Wang die->die_right, error);
3002de3b87aSKai Wang }
3012de3b87aSKai Wang
3022de3b87aSKai Wang /*
3032de3b87aSKai Wang * Search abbrev list to find a matching entry.
3042de3b87aSKai Wang */
3052de3b87aSKai Wang die->die_ab = NULL;
3062de3b87aSKai Wang for (ab = cu->cu_abbrev_hash; ab != NULL; ab = ab->ab_hh.next) {
3072de3b87aSKai Wang if (die->die_tag != ab->ab_tag)
3082de3b87aSKai Wang continue;
3092de3b87aSKai Wang if (ab->ab_children == DW_CHILDREN_no && die->die_child != NULL)
3102de3b87aSKai Wang continue;
3112de3b87aSKai Wang if (ab->ab_children == DW_CHILDREN_yes &&
3122de3b87aSKai Wang die->die_child == NULL)
3132de3b87aSKai Wang continue;
3142de3b87aSKai Wang at = STAILQ_FIRST(&die->die_attr);
3152de3b87aSKai Wang ad = STAILQ_FIRST(&ab->ab_attrdef);
3162de3b87aSKai Wang match = 1;
3172de3b87aSKai Wang while (at != NULL && ad != NULL) {
3182de3b87aSKai Wang if (at->at_attrib != ad->ad_attrib ||
3192de3b87aSKai Wang at->at_form != ad->ad_form) {
3202de3b87aSKai Wang match = 0;
3212de3b87aSKai Wang break;
3222de3b87aSKai Wang }
3232de3b87aSKai Wang at = STAILQ_NEXT(at, at_next);
3242de3b87aSKai Wang ad = STAILQ_NEXT(ad, ad_next);
3252de3b87aSKai Wang }
3262de3b87aSKai Wang if ((at == NULL && ad != NULL) || (at != NULL && ad == NULL))
3272de3b87aSKai Wang match = 0;
3282de3b87aSKai Wang if (match) {
3292de3b87aSKai Wang die->die_ab = ab;
3302de3b87aSKai Wang break;
3312de3b87aSKai Wang }
3322de3b87aSKai Wang }
3332de3b87aSKai Wang
3342de3b87aSKai Wang /*
3352de3b87aSKai Wang * Create a new abbrev entry if we can not reuse any existing one.
3362de3b87aSKai Wang */
3372de3b87aSKai Wang if (die->die_ab == NULL) {
3382de3b87aSKai Wang ret = _dwarf_abbrev_add(cu, ++cu->cu_abbrev_cnt, die->die_tag,
3392de3b87aSKai Wang die->die_child != NULL ? DW_CHILDREN_yes : DW_CHILDREN_no,
3402de3b87aSKai Wang 0, &ab, error);
3412de3b87aSKai Wang if (ret != DW_DLE_NONE)
3422de3b87aSKai Wang return (ret);
3432de3b87aSKai Wang STAILQ_FOREACH(at, &die->die_attr, at_next) {
3442de3b87aSKai Wang ret = _dwarf_attrdef_add(dbg, ab, at->at_attrib,
3452de3b87aSKai Wang at->at_form, 0, NULL, error);
3462de3b87aSKai Wang if (ret != DW_DLE_NONE)
3472de3b87aSKai Wang return (ret);
3482de3b87aSKai Wang }
3492de3b87aSKai Wang die->die_ab = ab;
3502de3b87aSKai Wang }
3512de3b87aSKai Wang
3522de3b87aSKai Wang die->die_offset = ds->ds_size;
3532de3b87aSKai Wang
3542de3b87aSKai Wang /*
3552de3b87aSKai Wang * Transform the DIE to bytes stream.
3562de3b87aSKai Wang */
3572de3b87aSKai Wang ret = _dwarf_write_uleb128_alloc(&ds->ds_data, &ds->ds_cap,
3582de3b87aSKai Wang &ds->ds_size, die->die_ab->ab_entry, error);
3592de3b87aSKai Wang if (ret != DW_DLE_NONE)
3602de3b87aSKai Wang return (ret);
3612de3b87aSKai Wang
3622de3b87aSKai Wang attr_gen:
3632de3b87aSKai Wang
3642de3b87aSKai Wang /* Transform the attributes of this DIE. */
3652de3b87aSKai Wang ret = _dwarf_attr_gen(dbg, ds, drs, cu, die, pass2, error);
3662de3b87aSKai Wang if (ret != DW_DLE_NONE)
3672de3b87aSKai Wang return (ret);
3682de3b87aSKai Wang
3692de3b87aSKai Wang /* Proceed to child DIE. */
3702de3b87aSKai Wang if (die->die_child != NULL) {
3712de3b87aSKai Wang ret = _dwarf_die_gen_recursive(dbg, cu, drs, die->die_child,
3722de3b87aSKai Wang pass2, error);
3732de3b87aSKai Wang if (ret != DW_DLE_NONE)
3742de3b87aSKai Wang return (ret);
3752de3b87aSKai Wang }
3762de3b87aSKai Wang
3772de3b87aSKai Wang /* Proceed to sibling DIE. */
3782de3b87aSKai Wang if (die->die_right != NULL) {
3792de3b87aSKai Wang ret = _dwarf_die_gen_recursive(dbg, cu, drs, die->die_right,
3802de3b87aSKai Wang pass2, error);
3812de3b87aSKai Wang if (ret != DW_DLE_NONE)
3822de3b87aSKai Wang return (ret);
3832de3b87aSKai Wang }
3842de3b87aSKai Wang
3852de3b87aSKai Wang /* Write a null DIE indicating the end of current level. */
3862de3b87aSKai Wang if (die->die_right == NULL) {
3872de3b87aSKai Wang ret = _dwarf_write_uleb128_alloc(&ds->ds_data, &ds->ds_cap,
3882de3b87aSKai Wang &ds->ds_size, 0, error);
3892de3b87aSKai Wang if (ret != DW_DLE_NONE)
3902de3b87aSKai Wang return (ret);
3912de3b87aSKai Wang }
3922de3b87aSKai Wang
3932de3b87aSKai Wang return (DW_DLE_NONE);
3942de3b87aSKai Wang }
3952de3b87aSKai Wang
3962de3b87aSKai Wang int
_dwarf_die_gen(Dwarf_P_Debug dbg,Dwarf_CU cu,Dwarf_Rel_Section drs,Dwarf_Error * error)3972de3b87aSKai Wang _dwarf_die_gen(Dwarf_P_Debug dbg, Dwarf_CU cu, Dwarf_Rel_Section drs,
3982de3b87aSKai Wang Dwarf_Error *error)
3992de3b87aSKai Wang {
4002de3b87aSKai Wang Dwarf_Abbrev ab, tab;
4012de3b87aSKai Wang Dwarf_AttrDef ad, tad;
4022de3b87aSKai Wang Dwarf_Die die;
4032de3b87aSKai Wang int ret;
4042de3b87aSKai Wang
4052de3b87aSKai Wang assert(dbg != NULL && cu != NULL);
4062de3b87aSKai Wang assert(dbg->dbgp_root_die != NULL);
4072de3b87aSKai Wang
4082de3b87aSKai Wang die = dbg->dbgp_root_die;
4092de3b87aSKai Wang
4102de3b87aSKai Wang /*
4112de3b87aSKai Wang * Insert a DW_AT_stmt_list attribute into root DIE, if there are
4122de3b87aSKai Wang * line number information.
4132de3b87aSKai Wang */
4142de3b87aSKai Wang if (!STAILQ_EMPTY(&dbg->dbgp_lineinfo->li_lnlist))
4152de3b87aSKai Wang RCHECK(_dwarf_add_AT_dataref(dbg, die, DW_AT_stmt_list, 0, 0,
4162de3b87aSKai Wang ".debug_line", NULL, error));
4172de3b87aSKai Wang
4182de3b87aSKai Wang RCHECK(_dwarf_die_gen_recursive(dbg, cu, drs, die, 0, error));
4192de3b87aSKai Wang
4202de3b87aSKai Wang if (cu->cu_pass2)
4212de3b87aSKai Wang RCHECK(_dwarf_die_gen_recursive(dbg, cu, drs, die, 1, error));
4222de3b87aSKai Wang
4232de3b87aSKai Wang return (DW_DLE_NONE);
4242de3b87aSKai Wang
4252de3b87aSKai Wang gen_fail:
4262de3b87aSKai Wang
4272de3b87aSKai Wang HASH_ITER(ab_hh, cu->cu_abbrev_hash, ab, tab) {
4282de3b87aSKai Wang HASH_DELETE(ab_hh, cu->cu_abbrev_hash, ab);
4292de3b87aSKai Wang STAILQ_FOREACH_SAFE(ad, &ab->ab_attrdef, ad_next, tad) {
4302de3b87aSKai Wang STAILQ_REMOVE(&ab->ab_attrdef, ad, _Dwarf_AttrDef,
4312de3b87aSKai Wang ad_next);
4322de3b87aSKai Wang free(ad);
4332de3b87aSKai Wang }
4342de3b87aSKai Wang free(ab);
4352de3b87aSKai Wang }
4362de3b87aSKai Wang
4372de3b87aSKai Wang return (ret);
4382de3b87aSKai Wang }
4392de3b87aSKai Wang
4402de3b87aSKai Wang void
_dwarf_die_pro_cleanup(Dwarf_P_Debug dbg)4412de3b87aSKai Wang _dwarf_die_pro_cleanup(Dwarf_P_Debug dbg)
4422de3b87aSKai Wang {
4432de3b87aSKai Wang Dwarf_P_Die die, tdie;
4442de3b87aSKai Wang Dwarf_P_Attribute at, tat;
4452de3b87aSKai Wang
4462de3b87aSKai Wang assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE);
4472de3b87aSKai Wang
4482de3b87aSKai Wang STAILQ_FOREACH_SAFE(die, &dbg->dbgp_dielist, die_pro_next, tdie) {
4492de3b87aSKai Wang STAILQ_FOREACH_SAFE(at, &die->die_attr, at_next, tat) {
4502de3b87aSKai Wang STAILQ_REMOVE(&die->die_attr, at, _Dwarf_Attribute,
4512de3b87aSKai Wang at_next);
4522de3b87aSKai Wang free(at);
4532de3b87aSKai Wang }
4542de3b87aSKai Wang free(die);
4552de3b87aSKai Wang }
4562de3b87aSKai Wang }
457