12de3b87aSKai Wang /*- 22de3b87aSKai Wang * Copyright (c) 2007 John Birrell (jb@freebsd.org) 3*cf781b2eSEd Maste * Copyright (c) 2010,2011,2014 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_info.c 3041 2014-05-18 15:11:03Z kaiwang27 $"); 312de3b87aSKai Wang 322de3b87aSKai Wang int 332de3b87aSKai Wang _dwarf_info_first_cu(Dwarf_Debug dbg, Dwarf_Error *error) 342de3b87aSKai Wang { 352de3b87aSKai Wang Dwarf_CU cu; 362de3b87aSKai Wang int ret; 372de3b87aSKai Wang 382de3b87aSKai Wang assert(dbg->dbg_cu_current == NULL); 392de3b87aSKai Wang cu = STAILQ_FIRST(&dbg->dbg_cu); 402de3b87aSKai Wang if (cu != NULL) { 412de3b87aSKai Wang dbg->dbg_cu_current = cu; 422de3b87aSKai Wang return (DW_DLE_NONE); 432de3b87aSKai Wang } 442de3b87aSKai Wang 452de3b87aSKai Wang if (dbg->dbg_info_loaded) 462de3b87aSKai Wang return (DW_DLE_NO_ENTRY); 472de3b87aSKai Wang 482de3b87aSKai Wang dbg->dbg_info_off = 0; 49*cf781b2eSEd Maste ret = _dwarf_info_load(dbg, 0, 1, error); 502de3b87aSKai Wang if (ret != DW_DLE_NONE) 512de3b87aSKai Wang return (ret); 522de3b87aSKai Wang 532de3b87aSKai Wang dbg->dbg_cu_current = STAILQ_FIRST(&dbg->dbg_cu); 542de3b87aSKai Wang 552de3b87aSKai Wang return (DW_DLE_NONE); 562de3b87aSKai Wang } 572de3b87aSKai Wang 582de3b87aSKai Wang int 59*cf781b2eSEd Maste _dwarf_info_first_tu(Dwarf_Debug dbg, Dwarf_Error *error) 60*cf781b2eSEd Maste { 61*cf781b2eSEd Maste Dwarf_CU tu; 62*cf781b2eSEd Maste int ret; 63*cf781b2eSEd Maste 64*cf781b2eSEd Maste assert(dbg->dbg_tu_current == NULL); 65*cf781b2eSEd Maste tu = STAILQ_FIRST(&dbg->dbg_tu); 66*cf781b2eSEd Maste if (tu != NULL) { 67*cf781b2eSEd Maste dbg->dbg_tu_current = tu; 68*cf781b2eSEd Maste return (DW_DLE_NONE); 69*cf781b2eSEd Maste } 70*cf781b2eSEd Maste 71*cf781b2eSEd Maste if (dbg->dbg_types_loaded) 72*cf781b2eSEd Maste return (DW_DLE_NO_ENTRY); 73*cf781b2eSEd Maste 74*cf781b2eSEd Maste dbg->dbg_types_off = 0; 75*cf781b2eSEd Maste ret = _dwarf_info_load(dbg, 0, 0, error); 76*cf781b2eSEd Maste if (ret != DW_DLE_NONE) 77*cf781b2eSEd Maste return (ret); 78*cf781b2eSEd Maste 79*cf781b2eSEd Maste dbg->dbg_tu_current = STAILQ_FIRST(&dbg->dbg_tu); 80*cf781b2eSEd Maste 81*cf781b2eSEd Maste return (DW_DLE_NONE); 82*cf781b2eSEd Maste } 83*cf781b2eSEd Maste 84*cf781b2eSEd Maste int 852de3b87aSKai Wang _dwarf_info_next_cu(Dwarf_Debug dbg, Dwarf_Error *error) 862de3b87aSKai Wang { 872de3b87aSKai Wang Dwarf_CU cu; 882de3b87aSKai Wang int ret; 892de3b87aSKai Wang 902de3b87aSKai Wang assert(dbg->dbg_cu_current != NULL); 912de3b87aSKai Wang cu = STAILQ_NEXT(dbg->dbg_cu_current, cu_next); 922de3b87aSKai Wang if (cu != NULL) { 932de3b87aSKai Wang dbg->dbg_cu_current = cu; 942de3b87aSKai Wang return (DW_DLE_NONE); 952de3b87aSKai Wang } 962de3b87aSKai Wang 972de3b87aSKai Wang if (dbg->dbg_info_loaded) { 982de3b87aSKai Wang dbg->dbg_cu_current = NULL; 992de3b87aSKai Wang return (DW_DLE_NO_ENTRY); 1002de3b87aSKai Wang } 1012de3b87aSKai Wang 102*cf781b2eSEd Maste ret = _dwarf_info_load(dbg, 0, 1, error); 1032de3b87aSKai Wang if (ret != DW_DLE_NONE) 1042de3b87aSKai Wang return (ret); 1052de3b87aSKai Wang 1062de3b87aSKai Wang dbg->dbg_cu_current = STAILQ_NEXT(dbg->dbg_cu_current, cu_next); 1072de3b87aSKai Wang 1082de3b87aSKai Wang return (DW_DLE_NONE); 1092de3b87aSKai Wang } 1102de3b87aSKai Wang 1112de3b87aSKai Wang int 112*cf781b2eSEd Maste _dwarf_info_next_tu(Dwarf_Debug dbg, Dwarf_Error *error) 113*cf781b2eSEd Maste { 114*cf781b2eSEd Maste Dwarf_CU cu; 115*cf781b2eSEd Maste int ret; 116*cf781b2eSEd Maste 117*cf781b2eSEd Maste assert(dbg->dbg_tu_current != NULL); 118*cf781b2eSEd Maste cu = STAILQ_NEXT(dbg->dbg_tu_current, cu_next); 119*cf781b2eSEd Maste if (cu != NULL) { 120*cf781b2eSEd Maste dbg->dbg_tu_current = cu; 121*cf781b2eSEd Maste return (DW_DLE_NONE); 122*cf781b2eSEd Maste } 123*cf781b2eSEd Maste 124*cf781b2eSEd Maste if (dbg->dbg_types_loaded) { 125*cf781b2eSEd Maste dbg->dbg_tu_current = NULL; 126*cf781b2eSEd Maste return (DW_DLE_NO_ENTRY); 127*cf781b2eSEd Maste } 128*cf781b2eSEd Maste 129*cf781b2eSEd Maste ret = _dwarf_info_load(dbg, 0, 0, error); 130*cf781b2eSEd Maste if (ret != DW_DLE_NONE) 131*cf781b2eSEd Maste return (ret); 132*cf781b2eSEd Maste 133*cf781b2eSEd Maste dbg->dbg_tu_current = STAILQ_NEXT(dbg->dbg_tu_current, cu_next); 134*cf781b2eSEd Maste 135*cf781b2eSEd Maste return (DW_DLE_NONE); 136*cf781b2eSEd Maste } 137*cf781b2eSEd Maste 138*cf781b2eSEd Maste int 139*cf781b2eSEd Maste _dwarf_info_load(Dwarf_Debug dbg, Dwarf_Bool load_all, Dwarf_Bool is_info, 140*cf781b2eSEd Maste Dwarf_Error *error) 1412de3b87aSKai Wang { 1422de3b87aSKai Wang Dwarf_CU cu; 1432de3b87aSKai Wang Dwarf_Section *ds; 1442de3b87aSKai Wang int dwarf_size, ret; 1452de3b87aSKai Wang uint64_t length; 1462de3b87aSKai Wang uint64_t next_offset; 1472de3b87aSKai Wang uint64_t offset; 1482de3b87aSKai Wang 1492de3b87aSKai Wang ret = DW_DLE_NONE; 1502de3b87aSKai Wang 151*cf781b2eSEd Maste if (is_info) { 152*cf781b2eSEd Maste if (dbg->dbg_info_loaded) 153*cf781b2eSEd Maste return (ret); 1542de3b87aSKai Wang offset = dbg->dbg_info_off; 1552de3b87aSKai Wang ds = dbg->dbg_info_sec; 1562de3b87aSKai Wang assert(ds != NULL); 157*cf781b2eSEd Maste } else { 158*cf781b2eSEd Maste if (dbg->dbg_types_loaded) 159*cf781b2eSEd Maste return (ret); 160*cf781b2eSEd Maste offset = dbg->dbg_types_off; 161*cf781b2eSEd Maste ds = dbg->dbg_types_sec; 162*cf781b2eSEd Maste if (ds == NULL) 163*cf781b2eSEd Maste return (DW_DLE_NO_ENTRY); 164*cf781b2eSEd Maste } 165*cf781b2eSEd Maste 1662de3b87aSKai Wang while (offset < ds->ds_size) { 1672de3b87aSKai Wang if ((cu = calloc(1, sizeof(struct _Dwarf_CU))) == NULL) { 1682de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 1692de3b87aSKai Wang return (DW_DLE_MEMORY); 1702de3b87aSKai Wang } 1712de3b87aSKai Wang 1722de3b87aSKai Wang cu->cu_dbg = dbg; 173*cf781b2eSEd Maste cu->cu_is_info = is_info; 1742de3b87aSKai Wang cu->cu_offset = offset; 1752de3b87aSKai Wang 1762de3b87aSKai Wang length = dbg->read(ds->ds_data, &offset, 4); 1772de3b87aSKai Wang if (length == 0xffffffff) { 1782de3b87aSKai Wang length = dbg->read(ds->ds_data, &offset, 8); 1792de3b87aSKai Wang dwarf_size = 8; 1802de3b87aSKai Wang } else 1812de3b87aSKai Wang dwarf_size = 4; 1822de3b87aSKai Wang cu->cu_dwarf_size = dwarf_size; 1832de3b87aSKai Wang 1842de3b87aSKai Wang /* 1852de3b87aSKai Wang * Check if there is enough ELF data for this CU. This assumes 1862de3b87aSKai Wang * that libelf gives us the entire section in one Elf_Data 1872de3b87aSKai Wang * object. 1882de3b87aSKai Wang */ 1892de3b87aSKai Wang if (length > ds->ds_size - offset) { 1902de3b87aSKai Wang free(cu); 1912de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_CU_LENGTH_ERROR); 1922de3b87aSKai Wang return (DW_DLE_CU_LENGTH_ERROR); 1932de3b87aSKai Wang } 1942de3b87aSKai Wang 1952de3b87aSKai Wang /* Compute the offset to the next compilation unit: */ 1962de3b87aSKai Wang next_offset = offset + length; 197*cf781b2eSEd Maste if (is_info) 1982de3b87aSKai Wang dbg->dbg_info_off = next_offset; 199*cf781b2eSEd Maste else 200*cf781b2eSEd Maste dbg->dbg_types_off = next_offset; 2012de3b87aSKai Wang 2022de3b87aSKai Wang /* Initialise the compilation unit. */ 2032de3b87aSKai Wang cu->cu_length = length; 2042de3b87aSKai Wang cu->cu_length_size = (dwarf_size == 4 ? 4 : 12); 2052de3b87aSKai Wang cu->cu_version = dbg->read(ds->ds_data, &offset, 2); 2062de3b87aSKai Wang cu->cu_abbrev_offset = dbg->read(ds->ds_data, &offset, 2072de3b87aSKai Wang dwarf_size); 2082de3b87aSKai Wang cu->cu_abbrev_offset_cur = cu->cu_abbrev_offset; 2092de3b87aSKai Wang cu->cu_pointer_size = dbg->read(ds->ds_data, &offset, 1); 2102de3b87aSKai Wang cu->cu_next_offset = next_offset; 2112de3b87aSKai Wang 212*cf781b2eSEd Maste /* .debug_types extra fields. */ 213*cf781b2eSEd Maste if (!is_info) { 214*cf781b2eSEd Maste memcpy(cu->cu_type_sig.signature, 215*cf781b2eSEd Maste (char *) ds->ds_data + offset, 8); 216*cf781b2eSEd Maste offset += 8; 217*cf781b2eSEd Maste cu->cu_type_offset = dbg->read(ds->ds_data, &offset, 218*cf781b2eSEd Maste dwarf_size); 219*cf781b2eSEd Maste } 220*cf781b2eSEd Maste 2212de3b87aSKai Wang /* Add the compilation unit to the list. */ 222*cf781b2eSEd Maste if (is_info) 2232de3b87aSKai Wang STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next); 224*cf781b2eSEd Maste else 225*cf781b2eSEd Maste STAILQ_INSERT_TAIL(&dbg->dbg_tu, cu, cu_next); 2262de3b87aSKai Wang 2272de3b87aSKai Wang if (cu->cu_version < 2 || cu->cu_version > 4) { 2282de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_VERSION_STAMP_ERROR); 2292de3b87aSKai Wang ret = DW_DLE_VERSION_STAMP_ERROR; 2302de3b87aSKai Wang break; 2312de3b87aSKai Wang } 2322de3b87aSKai Wang 2332de3b87aSKai Wang cu->cu_1st_offset = offset; 2342de3b87aSKai Wang 2352de3b87aSKai Wang offset = next_offset; 2362de3b87aSKai Wang 2372de3b87aSKai Wang if (!load_all) 2382de3b87aSKai Wang break; 2392de3b87aSKai Wang } 2402de3b87aSKai Wang 241*cf781b2eSEd Maste if (is_info) { 2422de3b87aSKai Wang if ((Dwarf_Unsigned) dbg->dbg_info_off >= ds->ds_size) 2432de3b87aSKai Wang dbg->dbg_info_loaded = 1; 244*cf781b2eSEd Maste } else { 245*cf781b2eSEd Maste if ((Dwarf_Unsigned) dbg->dbg_types_off >= ds->ds_size) 246*cf781b2eSEd Maste dbg->dbg_types_loaded = 1; 247*cf781b2eSEd Maste } 2482de3b87aSKai Wang 2492de3b87aSKai Wang return (ret); 2502de3b87aSKai Wang } 2512de3b87aSKai Wang 2522de3b87aSKai Wang void 2532de3b87aSKai Wang _dwarf_info_cleanup(Dwarf_Debug dbg) 2542de3b87aSKai Wang { 2552de3b87aSKai Wang Dwarf_CU cu, tcu; 2562de3b87aSKai Wang 2572de3b87aSKai Wang assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); 2582de3b87aSKai Wang 2592de3b87aSKai Wang STAILQ_FOREACH_SAFE(cu, &dbg->dbg_cu, cu_next, tcu) { 2602de3b87aSKai Wang STAILQ_REMOVE(&dbg->dbg_cu, cu, _Dwarf_CU, cu_next); 2612de3b87aSKai Wang _dwarf_abbrev_cleanup(cu); 2622de3b87aSKai Wang if (cu->cu_lineinfo != NULL) { 2632de3b87aSKai Wang _dwarf_lineno_cleanup(cu->cu_lineinfo); 2642de3b87aSKai Wang cu->cu_lineinfo = NULL; 2652de3b87aSKai Wang } 2662de3b87aSKai Wang free(cu); 2672de3b87aSKai Wang } 268*cf781b2eSEd Maste 269*cf781b2eSEd Maste _dwarf_type_unit_cleanup(dbg); 270*cf781b2eSEd Maste } 271*cf781b2eSEd Maste 272*cf781b2eSEd Maste void 273*cf781b2eSEd Maste _dwarf_type_unit_cleanup(Dwarf_Debug dbg) 274*cf781b2eSEd Maste { 275*cf781b2eSEd Maste Dwarf_CU cu, tcu; 276*cf781b2eSEd Maste 277*cf781b2eSEd Maste assert(dbg != NULL && dbg->dbg_mode == DW_DLC_READ); 278*cf781b2eSEd Maste 279*cf781b2eSEd Maste STAILQ_FOREACH_SAFE(cu, &dbg->dbg_tu, cu_next, tcu) { 280*cf781b2eSEd Maste STAILQ_REMOVE(&dbg->dbg_tu, cu, _Dwarf_CU, cu_next); 281*cf781b2eSEd Maste _dwarf_abbrev_cleanup(cu); 282*cf781b2eSEd Maste free(cu); 283*cf781b2eSEd Maste } 2842de3b87aSKai Wang } 2852de3b87aSKai Wang 2862de3b87aSKai Wang int 2872de3b87aSKai Wang _dwarf_info_gen(Dwarf_P_Debug dbg, Dwarf_Error *error) 2882de3b87aSKai Wang { 2892de3b87aSKai Wang Dwarf_P_Section ds; 2902de3b87aSKai Wang Dwarf_Rel_Section drs; 2912de3b87aSKai Wang Dwarf_Unsigned offset; 2922de3b87aSKai Wang Dwarf_CU cu; 2932de3b87aSKai Wang int ret; 2942de3b87aSKai Wang 2952de3b87aSKai Wang assert(dbg != NULL && dbg->write_alloc != NULL); 2962de3b87aSKai Wang 2972de3b87aSKai Wang if (dbg->dbgp_root_die == NULL) 2982de3b87aSKai Wang return (DW_DLE_NONE); 2992de3b87aSKai Wang 3002de3b87aSKai Wang /* Create the single CU for this debugging object. */ 3012de3b87aSKai Wang if ((cu = calloc(1, sizeof(struct _Dwarf_CU))) == NULL) { 3022de3b87aSKai Wang DWARF_SET_ERROR(dbg, error, DW_DLE_MEMORY); 3032de3b87aSKai Wang return (DW_DLE_MEMORY); 3042de3b87aSKai Wang } 3052de3b87aSKai Wang cu->cu_dbg = dbg; 3062de3b87aSKai Wang cu->cu_version = 2; /* DWARF2 */ 3072de3b87aSKai Wang cu->cu_pointer_size = dbg->dbg_pointer_size; 3082de3b87aSKai Wang STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next); 3092de3b87aSKai Wang 3102de3b87aSKai Wang /* Create .debug_info section. */ 3112de3b87aSKai Wang if ((ret = _dwarf_section_init(dbg, &dbg->dbgp_info, ".debug_info", 0, 3122de3b87aSKai Wang error)) != DW_DLE_NONE) 3132de3b87aSKai Wang goto gen_fail1; 3142de3b87aSKai Wang ds = dbg->dbgp_info; 3152de3b87aSKai Wang 3162de3b87aSKai Wang /* Create relocation section for .debug_init */ 3172de3b87aSKai Wang if ((ret = _dwarf_reloc_section_init(dbg, &drs, ds, error)) != 3182de3b87aSKai Wang DW_DLE_NONE) 3192de3b87aSKai Wang goto gen_fail0; 3202de3b87aSKai Wang 3212de3b87aSKai Wang /* Length placeholder. (We only use 32-bit DWARF format) */ 3222de3b87aSKai Wang RCHECK(WRITE_VALUE(cu->cu_length, 4)); 3232de3b87aSKai Wang 3242de3b87aSKai Wang /* Write CU version */ 3252de3b87aSKai Wang RCHECK(WRITE_VALUE(cu->cu_version, 2)); 3262de3b87aSKai Wang 3272de3b87aSKai Wang /* 3282de3b87aSKai Wang * Write abbrev offset. (always 0, we only support single CU) 3292de3b87aSKai Wang * Also generate a relocation entry for this offset. 3302de3b87aSKai Wang */ 3312de3b87aSKai Wang RCHECK(_dwarf_reloc_entry_add(dbg, drs, ds, dwarf_drt_data_reloc, 4, 3322de3b87aSKai Wang ds->ds_size, 0, cu->cu_abbrev_offset, ".debug_abbrev", error)); 3332de3b87aSKai Wang 3342de3b87aSKai Wang /* Pointer size. */ 3352de3b87aSKai Wang RCHECK(WRITE_VALUE(cu->cu_pointer_size, 1)); 3362de3b87aSKai Wang 3372de3b87aSKai Wang /* Transform the DIE(s) of this CU. */ 3382de3b87aSKai Wang RCHECK(_dwarf_die_gen(dbg, cu, drs, error)); 3392de3b87aSKai Wang 3402de3b87aSKai Wang /* Now we can fill in the length of this CU. */ 3412de3b87aSKai Wang cu->cu_length = ds->ds_size - 4; 3422de3b87aSKai Wang offset = 0; 3432de3b87aSKai Wang dbg->write(ds->ds_data, &offset, cu->cu_length, 4); 3442de3b87aSKai Wang 3452de3b87aSKai Wang /* Inform application the creation of .debug_info ELF section. */ 3462de3b87aSKai Wang RCHECK(_dwarf_section_callback(dbg, ds, SHT_PROGBITS, 0, 0, 0, error)); 3472de3b87aSKai Wang 3482de3b87aSKai Wang /* 3492de3b87aSKai Wang * Inform application the creation of relocation section for 3502de3b87aSKai Wang * .debug_info. 3512de3b87aSKai Wang */ 3522de3b87aSKai Wang RCHECK(_dwarf_reloc_section_finalize(dbg, drs, error)); 3532de3b87aSKai Wang 3542de3b87aSKai Wang return (DW_DLE_NONE); 3552de3b87aSKai Wang 3562de3b87aSKai Wang gen_fail: 3572de3b87aSKai Wang _dwarf_reloc_section_free(dbg, &drs); 3582de3b87aSKai Wang 3592de3b87aSKai Wang gen_fail0: 3602de3b87aSKai Wang _dwarf_section_free(dbg, &dbg->dbgp_info); 3612de3b87aSKai Wang 3622de3b87aSKai Wang gen_fail1: 3632de3b87aSKai Wang STAILQ_REMOVE(&dbg->dbg_cu, cu, _Dwarf_CU, cu_next); 3642de3b87aSKai Wang free(cu); 3652de3b87aSKai Wang 3662de3b87aSKai Wang return (ret); 3672de3b87aSKai Wang } 3682de3b87aSKai Wang 3692de3b87aSKai Wang void 3702de3b87aSKai Wang _dwarf_info_pro_cleanup(Dwarf_P_Debug dbg) 3712de3b87aSKai Wang { 3722de3b87aSKai Wang Dwarf_CU cu; 3732de3b87aSKai Wang 3742de3b87aSKai Wang assert(dbg != NULL && dbg->dbg_mode == DW_DLC_WRITE); 3752de3b87aSKai Wang 3762de3b87aSKai Wang cu = STAILQ_FIRST(&dbg->dbg_cu); 3772de3b87aSKai Wang if (cu != NULL) { 3782de3b87aSKai Wang STAILQ_REMOVE(&dbg->dbg_cu, cu, _Dwarf_CU, cu_next); 3792de3b87aSKai Wang _dwarf_abbrev_cleanup(cu); 3802de3b87aSKai Wang free(cu); 3812de3b87aSKai Wang } 3822de3b87aSKai Wang } 383