diff options
author | kaiw <kaiw@FreeBSD.org> | 2014-01-16 21:52:09 +0000 |
---|---|---|
committer | kaiw <kaiw@FreeBSD.org> | 2014-01-16 21:52:09 +0000 |
commit | 2bbfdc840b66fe8bb2a5d625340b5a4a980cbc4c (patch) | |
tree | 96ea9773e63029731c555c9c8cf8c26b989890d4 /lib/libdwarf/dwarf_init.c | |
parent | b8698ae2b637a3b87e9a1d04abafaad0dca49026 (diff) | |
download | FreeBSD-src-2bbfdc840b66fe8bb2a5d625340b5a4a980cbc4c.zip FreeBSD-src-2bbfdc840b66fe8bb2a5d625340b5a4a980cbc4c.tar.gz |
Remove the old libdwarf and bring in the new libdwarf in contrib/.
Diffstat (limited to 'lib/libdwarf/dwarf_init.c')
-rw-r--r-- | lib/libdwarf/dwarf_init.c | 756 |
1 files changed, 0 insertions, 756 deletions
diff --git a/lib/libdwarf/dwarf_init.c b/lib/libdwarf/dwarf_init.c deleted file mode 100644 index ce85363..0000000 --- a/lib/libdwarf/dwarf_init.c +++ /dev/null @@ -1,756 +0,0 @@ -/*- - * Copyright (c) 2007 John Birrell (jb@freebsd.org) - * All rights reserved. - * - * Redistribution and use in source and binary forms, with or without - * modification, are permitted provided that the following conditions - * are met: - * 1. Redistributions of source code must retain the above copyright - * notice, this list of conditions and the following disclaimer. - * 2. Redistributions in binary form must reproduce the above copyright - * notice, this list of conditions and the following disclaimer in the - * documentation and/or other materials provided with the distribution. - * - * THIS SOFTWARE IS PROVIDED BY THE AUTHOR AND CONTRIBUTORS ``AS IS'' AND - * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE - * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE - * ARE DISCLAIMED. IN NO EVENT SHALL THE AUTHOR OR CONTRIBUTORS BE LIABLE - * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL - * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS - * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) - * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT - * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY - * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF - * SUCH DAMAGE. - * - * $FreeBSD$ - */ - -#include <stdlib.h> -#include <string.h> -#include "_libdwarf.h" - -static const char *debug_snames[DWARF_DEBUG_SNAMES] = { - ".debug_abbrev", - ".debug_aranges", - ".debug_frame", - ".debug_info", - ".debug_line", - ".debug_pubnames", - ".eh_frame", - ".debug_macinfo", - ".debug_str", - ".debug_loc", - ".debug_pubtypes", - ".debug_ranges", - ".debug_static_func", - ".debug_static_vars", - ".debug_types", - ".debug_weaknames", - ".symtab", - ".strtab" -}; - -static uint64_t (*dwarf_read) (Elf_Data **, uint64_t *, int); -static void (*dwarf_write) (Elf_Data **, uint64_t *, uint64_t, int); - -static uint64_t -dwarf_read_lsb(Elf_Data **dp, uint64_t *offsetp, int bytes_to_read) -{ - uint64_t ret = 0; - - uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp; - - switch (bytes_to_read) { - case 8: - ret |= ((uint64_t) src[4]) << 32 | ((uint64_t) src[5]) << 40; - ret |= ((uint64_t) src[6]) << 48 | ((uint64_t) src[7]) << 56; - case 4: - ret |= ((uint64_t) src[2]) << 16 | ((uint64_t) src[3]) << 24; - case 2: - ret |= ((uint64_t) src[1]) << 8; - case 1: - ret |= src[0]; - break; - default: - return 0; - break; - } - - *offsetp += bytes_to_read; - - return ret; -} - -static uint64_t -dwarf_read_msb(Elf_Data **dp, uint64_t *offsetp, int bytes_to_read) -{ - uint64_t ret = 0; - - uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp; - - switch (bytes_to_read) { - case 1: - ret = src[0]; - break; - case 2: - ret = src[1] | ((uint64_t) src[0]) << 8; - break; - case 4: - ret = src[3] | ((uint64_t) src[2]) << 8; - ret |= ((uint64_t) src[1]) << 16 | ((uint64_t) src[0]) << 24; - break; - case 8: - ret = src[7] | ((uint64_t) src[6]) << 8; - ret |= ((uint64_t) src[5]) << 16 | ((uint64_t) src[4]) << 24; - ret |= ((uint64_t) src[3]) << 32 | ((uint64_t) src[2]) << 40; - ret |= ((uint64_t) src[1]) << 48 | ((uint64_t) src[0]) << 56; - break; - default: - return 0; - break; - } - - *offsetp += bytes_to_read; - - return ret; -} - -static void -dwarf_write_lsb(Elf_Data **dp, uint64_t *offsetp, uint64_t value, int bytes_to_write) -{ - uint8_t *dst = (uint8_t *) (*dp)->d_buf + *offsetp; - - switch (bytes_to_write) { - case 8: - dst[7] = (value >> 56) & 0xff; - dst[6] = (value >> 48) & 0xff; - dst[5] = (value >> 40) & 0xff; - dst[4] = (value >> 32) & 0xff; - case 4: - dst[3] = (value >> 24) & 0xff; - dst[2] = (value >> 16) & 0xff; - case 2: - dst[1] = (value >> 8) & 0xff; - case 1: - dst[0] = value & 0xff; - break; - default: - return; - break; - } - - *offsetp += bytes_to_write; -} - -static void -dwarf_write_msb(Elf_Data **dp, uint64_t *offsetp, uint64_t value, int bytes_to_write) -{ - uint8_t *dst = (uint8_t *) (*dp)->d_buf + *offsetp; - - switch (bytes_to_write) { - case 8: - dst[7] = value & 0xff; - dst[6] = (value >> 8) & 0xff; - dst[5] = (value >> 16) & 0xff; - dst[4] = (value >> 24) & 0xff; - value >>= 32; - case 4: - dst[3] = value & 0xff; - dst[2] = (value >> 8) & 0xff; - value >>= 16; - case 2: - dst[1] = value & 0xff; - value >>= 8; - case 1: - dst[0] = value & 0xff; - break; - default: - return; - break; - } - - *offsetp += bytes_to_write; -} - -static int64_t -dwarf_read_sleb128(Elf_Data **dp, uint64_t *offsetp) -{ - int64_t ret = 0; - uint8_t b; - int shift = 0; - - uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp; - - do { - b = *src++; - - ret |= ((b & 0x7f) << shift); - - (*offsetp)++; - - shift += 7; - } while ((b & 0x80) != 0); - - if (shift < 64 && (b & 0x40) != 0) - ret |= (-1 << shift); - - return ret; -} - -static uint64_t -dwarf_read_uleb128(Elf_Data **dp, uint64_t *offsetp) -{ - uint64_t ret = 0; - uint8_t b; - int shift = 0; - - uint8_t *src = (uint8_t *) (*dp)->d_buf + *offsetp; - - do { - b = *src++; - - ret |= ((b & 0x7f) << shift); - - (*offsetp)++; - - shift += 7; - } while ((b & 0x80) != 0); - - return ret; -} - -static const char * -dwarf_read_string(Elf_Data **dp, uint64_t *offsetp) -{ - char *ret; - - char *src = (char *) (*dp)->d_buf + *offsetp; - - ret = src; - - while (*src != '\0' && *offsetp < (*dp)->d_size) { - src++; - (*offsetp)++; - } - - if (*src == '\0' && *offsetp < (*dp)->d_size) - (*offsetp)++; - - return ret; -} - -static uint8_t * -dwarf_read_block(Elf_Data **dp, uint64_t *offsetp, uint64_t length) -{ - uint8_t *ret; - - uint8_t *src = (char *) (*dp)->d_buf + *offsetp; - - ret = src; - - (*offsetp) += length; - - return ret; -} - -static int -dwarf_apply_relocations(Dwarf_Debug dbg, Elf_Data *reld, int secindx) -{ - Elf_Data *d; - GElf_Rela rela; - int indx = 0; - int ret = DWARF_E_NONE; - uint64_t offset; - - /* Point to the data to be relocated: */ - d = dbg->dbg_s[secindx].s_data; - - /* Enter a loop to process each relocation addend: */ - while (gelf_getrela(reld, indx++, &rela) != NULL) { - GElf_Sym sym; - Elf64_Xword symindx = ELF64_R_SYM(rela.r_info); - - if (gelf_getsym(dbg->dbg_s[DWARF_symtab].s_data, symindx, &sym) == NULL) { - printf("Couldn't find symbol index %lu for relocation\n",(u_long) symindx); - continue; - } - - offset = rela.r_offset; - - dwarf_write(&d, &offset, rela.r_addend, dbg->dbg_offsize); - } - - return ret; -} - -static int -dwarf_relocate(Dwarf_Debug dbg, Dwarf_Error *error) -{ - Elf_Scn *scn = NULL; - GElf_Shdr shdr; - int i; - int ret = DWARF_E_NONE; - - /* Look for sections which relocate the debug sections. */ - while ((scn = elf_nextscn(dbg->dbg_elf, scn)) != NULL) { - if (gelf_getshdr(scn, &shdr) == NULL) { - DWARF_SET_ELF_ERROR(error, elf_errno()); - return DWARF_E_ELF; - } - - if (shdr.sh_type != SHT_RELA || shdr.sh_size == 0) - continue; - - for (i = 0; i < DWARF_DEBUG_SNAMES; i++) { - if (dbg->dbg_s[i].s_shnum == shdr.sh_info && - dbg->dbg_s[DWARF_symtab].s_shnum == shdr.sh_link) { - Elf_Data *rd; - - /* Get the relocation data. */ - if ((rd = elf_getdata(scn, NULL)) == NULL) { - DWARF_SET_ELF_ERROR(error, elf_errno()); - return DWARF_E_ELF; - } - - /* Apply the relocations. */ - dwarf_apply_relocations(dbg, rd, i); - break; - } - } - } - - return ret; -} - -static int -dwarf_init_attr(Dwarf_Debug dbg, Elf_Data **dp, uint64_t *offsetp, - Dwarf_CU cu, Dwarf_Die die, Dwarf_Attribute at, uint64_t form, - Dwarf_Error *error) -{ - int ret = DWARF_E_NONE; - struct _Dwarf_AttrValue avref; - - memset(&avref, 0, sizeof(avref)); - avref.av_attrib = at->at_attrib; - avref.av_form = at->at_form; - - switch (form) { - case DW_FORM_addr: - avref.u[0].u64 = dwarf_read(dp, offsetp, cu->cu_pointer_size); - break; - case DW_FORM_block: - avref.u[0].u64 = dwarf_read_uleb128(dp, offsetp); - avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64); - break; - case DW_FORM_block1: - avref.u[0].u64 = dwarf_read(dp, offsetp, 1); - avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64); - break; - case DW_FORM_block2: - avref.u[0].u64 = dwarf_read(dp, offsetp, 2); - avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64); - break; - case DW_FORM_block4: - avref.u[0].u64 = dwarf_read(dp, offsetp, 4); - avref.u[1].u8p = dwarf_read_block(dp, offsetp, avref.u[0].u64); - break; - case DW_FORM_data1: - case DW_FORM_flag: - case DW_FORM_ref1: - avref.u[0].u64 = dwarf_read(dp, offsetp, 1); - break; - case DW_FORM_data2: - case DW_FORM_ref2: - avref.u[0].u64 = dwarf_read(dp, offsetp, 2); - break; - case DW_FORM_data4: - case DW_FORM_ref4: - avref.u[0].u64 = dwarf_read(dp, offsetp, 4); - break; - case DW_FORM_data8: - case DW_FORM_ref8: - avref.u[0].u64 = dwarf_read(dp, offsetp, 8); - break; - case DW_FORM_indirect: - form = dwarf_read_uleb128(dp, offsetp); - return dwarf_init_attr(dbg, dp, offsetp, cu, die, at, form, error); - case DW_FORM_ref_addr: - if (cu->cu_version == 2) - avref.u[0].u64 = dwarf_read(dp, offsetp, cu->cu_pointer_size); - else if (cu->cu_version == 3) - avref.u[0].u64 = dwarf_read(dp, offsetp, dbg->dbg_offsize); - break; - case DW_FORM_ref_udata: - case DW_FORM_udata: - avref.u[0].u64 = dwarf_read_uleb128(dp, offsetp); - break; - case DW_FORM_sdata: - avref.u[0].s64 = dwarf_read_sleb128(dp, offsetp); - break; - case DW_FORM_string: - avref.u[0].s = dwarf_read_string(dp, offsetp); - break; - case DW_FORM_strp: - avref.u[0].u64 = dwarf_read(dp, offsetp, dbg->dbg_offsize); - avref.u[1].s = elf_strptr(dbg->dbg_elf, - dbg->dbg_s[DWARF_debug_str].s_shnum, avref.u[0].u64); - break; - case DW_FORM_flag_present: - /* This form has no value encoded in the DIE. */ - avref.u[0].u64 = 1; - break; - default: - DWARF_SET_ERROR(error, DWARF_E_NOT_IMPLEMENTED); - ret = DWARF_E_NOT_IMPLEMENTED; - break; - } - - if (ret == DWARF_E_NONE) - ret = dwarf_attrval_add(die, &avref, NULL, error); - - return ret; -} - -static int -dwarf_init_abbrev(Dwarf_Debug dbg, Dwarf_CU cu, Dwarf_Error *error) -{ - Dwarf_Abbrev a; - Elf_Data *d; - int ret = DWARF_E_NONE; - uint64_t attr; - uint64_t entry; - uint64_t form; - uint64_t offset; - uint64_t tag; - u_int8_t children; - - d = dbg->dbg_s[DWARF_debug_abbrev].s_data; - - offset = cu->cu_abbrev_offset; - - while (offset < d->d_size) { - - entry = dwarf_read_uleb128(&d, &offset); - - /* Check if this is the end of the data: */ - if (entry == 0) - break; - - tag = dwarf_read_uleb128(&d, &offset); - - children = dwarf_read(&d, &offset, 1); - - if ((ret = dwarf_abbrev_add(cu, entry, tag, children, &a, error)) != DWARF_E_NONE) - break; - - do { - attr = dwarf_read_uleb128(&d, &offset); - form = dwarf_read_uleb128(&d, &offset); - - if (attr != 0) - if ((ret = dwarf_attr_add(a, attr, form, NULL, error)) != DWARF_E_NONE) - return ret; - } while (attr != 0); - } - - return ret; -} - -static int -dwarf_init_info(Dwarf_Debug dbg, Dwarf_Error *error) -{ - Dwarf_CU cu; - Elf_Data *d = NULL; - Elf_Scn *scn; - int i; - int level = 0; - int relocated = 0; - int ret = DWARF_E_NONE; - uint64_t length; - uint64_t next_offset; - uint64_t offset = 0; - - scn = dbg->dbg_s[DWARF_debug_info].s_scn; - - d = dbg->dbg_s[DWARF_debug_info].s_data; - - while (offset < d->d_size) { - /* Allocate memory for the first compilation unit. */ - if ((cu = calloc(sizeof(struct _Dwarf_CU), 1)) == NULL) { - DWARF_SET_ERROR(error, DWARF_E_MEMORY); - return DWARF_E_MEMORY; - } - - /* Save the offet to this compilation unit: */ - cu->cu_offset = offset; - - length = dwarf_read(&d, &offset, 4); - if (length == 0xffffffff) { - length = dwarf_read(&d, &offset, 8); - dbg->dbg_offsize = 8; - } else - dbg->dbg_offsize = 4; - - /* - * Check if there is enough ELF data for this CU. - * This assumes that libelf gives us the entire - * section in one Elf_Data object. - */ - if (length > d->d_size - offset) { - free(cu); - DWARF_SET_ERROR(error, DWARF_E_INVALID_CU); - return DWARF_E_INVALID_CU; - } - - /* Relocate the DWARF sections if necessary: */ - if (!relocated) { - if ((ret = dwarf_relocate(dbg, error)) != DWARF_E_NONE) - return ret; - relocated = 1; - } - - /* Compute the offset to the next compilation unit: */ - next_offset = offset + length; - - /* Initialise the compilation unit. */ - cu->cu_length = length; - cu->cu_header_length = (dbg->dbg_offsize == 4) ? 4 : 12; - cu->cu_version = dwarf_read(&d, &offset, 2); - cu->cu_abbrev_offset = dwarf_read(&d, &offset, dbg->dbg_offsize); - cu->cu_pointer_size = dwarf_read(&d, &offset, 1); - cu->cu_next_offset = next_offset; - - /* Initialise the list of abbrevs. */ - STAILQ_INIT(&cu->cu_abbrev); - - /* Initialise the list of dies. */ - STAILQ_INIT(&cu->cu_die); - - /* Initialise the hash table of dies. */ - for (i = 0; i < DWARF_DIE_HASH_SIZE; i++) - STAILQ_INIT(&cu->cu_die_hash[i]); - - /* Add the compilation unit to the list. */ - STAILQ_INSERT_TAIL(&dbg->dbg_cu, cu, cu_next); - - if (cu->cu_version != 2 && cu->cu_version != 3) { - DWARF_SET_ERROR(error, DWARF_E_CU_VERSION); - ret = DWARF_E_CU_VERSION; - break; - } - - /* Parse the .debug_abbrev info for this CU: */ - if ((ret = dwarf_init_abbrev(dbg, cu, error)) != DWARF_E_NONE) - break; - - level = 0; - - while (offset < next_offset && offset < d->d_size) { - Dwarf_Abbrev a; - Dwarf_Attribute at; - Dwarf_Die die; - uint64_t abnum; - uint64_t die_offset = offset; - - abnum = dwarf_read_uleb128(&d, &offset); - - if (abnum == 0) { - level--; - continue; - } - - if ((a = dwarf_abbrev_find(cu, abnum)) == NULL) { - DWARF_SET_ERROR(error, DWARF_E_MISSING_ABBREV); - return DWARF_E_MISSING_ABBREV; - } - - if ((ret = dwarf_die_add(cu, level, die_offset, - abnum, a, &die, error)) != DWARF_E_NONE) - return ret; - - STAILQ_FOREACH(at, &a->a_attrib, at_next) { - if ((ret = dwarf_init_attr(dbg, &d, &offset, - cu, die, at, at->at_form, error)) != DWARF_E_NONE) - return ret; - } - - if (a->a_children == DW_CHILDREN_yes) - level++; - } - - offset = next_offset; - } - - /* Build the function table. */ - dwarf_build_function_table(dbg); - - return ret; -} - -static int -dwarf_elf_read(Dwarf_Debug dbg, Dwarf_Error *error) -{ - GElf_Shdr shdr; - Elf_Scn *scn = NULL; - char *sname; - int i; - int ret = DWARF_E_NONE; - - /* Get a copy of the ELF header. */ - if (gelf_getehdr(dbg->dbg_elf, &dbg->dbg_ehdr) == NULL) { - DWARF_SET_ELF_ERROR(error, elf_errno()); - return DWARF_E_ELF; - } - - /* Check the ELF data format: */ - switch (dbg->dbg_ehdr.e_ident[EI_DATA]) { - case ELFDATA2MSB: - dwarf_read = dwarf_read_msb; - dwarf_write = dwarf_write_msb; - break; - - case ELFDATA2LSB: - case ELFDATANONE: - default: - dwarf_read = dwarf_read_lsb; - dwarf_write = dwarf_write_lsb; - break; - } - - /* Get the section index to the string table. */ - if (elf_getshstrndx(dbg->dbg_elf, &dbg->dbg_stnum) == 0) { - DWARF_SET_ELF_ERROR(error, elf_errno()); - return DWARF_E_ELF; - } - - /* Look for the debug sections. */ - while ((scn = elf_nextscn(dbg->dbg_elf, scn)) != NULL) { - /* Get a copy of the section header: */ - if (gelf_getshdr(scn, &shdr) == NULL) { - DWARF_SET_ELF_ERROR(error, elf_errno()); - return DWARF_E_ELF; - } - - /* Get a pointer to the section name: */ - if ((sname = elf_strptr(dbg->dbg_elf, dbg->dbg_stnum, shdr.sh_name)) == NULL) { - DWARF_SET_ELF_ERROR(error, elf_errno()); - return DWARF_E_ELF; - } - - /* - * Look up the section name to check if it's - * one we need for DWARF. - */ - for (i = 0; i < DWARF_DEBUG_SNAMES; i++) { - if (strcmp(sname, debug_snames[i]) == 0) { - dbg->dbg_s[i].s_sname = sname; - dbg->dbg_s[i].s_shnum = elf_ndxscn(scn); - dbg->dbg_s[i].s_scn = scn; - memcpy(&dbg->dbg_s[i].s_shdr, &shdr, sizeof(shdr)); - if ((dbg->dbg_s[i].s_data = elf_getdata(scn, NULL)) == NULL) { - DWARF_SET_ELF_ERROR(error, elf_errno()); - return DWARF_E_ELF; - } - break; - } - } - } - - /* Check if any of the required sections are missing: */ - if (dbg->dbg_s[DWARF_debug_abbrev].s_scn == NULL || - dbg->dbg_s[DWARF_debug_info].s_scn == NULL) { - /* Missing debug information. */ - DWARF_SET_ERROR(error, DWARF_E_DEBUG_INFO); - return DWARF_E_DEBUG_INFO; - } - - /* Initialise the compilation-units: */ - ret = dwarf_init_info(dbg, error); - - return ret; -} - -int -dwarf_elf_init(Elf *elf, int mode, Dwarf_Debug *ret_dbg, Dwarf_Error *error) -{ - Dwarf_Debug dbg; - int ret = DWARF_E_NONE; - - if (error == NULL) - /* Can only return a generic error. */ - return DWARF_E_ERROR; - - if (elf == NULL || ret_dbg == NULL) { - DWARF_SET_ERROR(error, DWARF_E_ARGUMENT); - ret = DWARF_E_ARGUMENT; - } else if ((dbg = calloc(sizeof(struct _Dwarf_Debug), 1)) == NULL) { - DWARF_SET_ERROR(error, DWARF_E_MEMORY); - ret = DWARF_E_MEMORY; - } else { - dbg->dbg_elf = elf; - dbg->dbg_elf_close = 0; - dbg->dbg_mode = mode; - - STAILQ_INIT(&dbg->dbg_cu); - STAILQ_INIT(&dbg->dbg_func); - - *ret_dbg = dbg; - - /* Read the ELF sections. */ - ret = dwarf_elf_read(dbg, error); - } - - return ret; -} - -int -dwarf_init(int fd, int mode, Dwarf_Debug *ret_dbg, Dwarf_Error *error) -{ - Dwarf_Error lerror; - Elf *elf; - Elf_Cmd c; - int ret; - - if (error == NULL) - /* Can only return a generic error. */ - return DWARF_E_ERROR; - - if (fd < 0 || ret_dbg == NULL) { - DWARF_SET_ERROR(error, DWARF_E_ARGUMENT); - return DWARF_E_ERROR; - } - - /* Translate the DWARF mode to ELF mode. */ - switch (mode) { - default: - case DW_DLC_READ: - c = ELF_C_READ; - break; - } - - if (elf_version(EV_CURRENT) == EV_NONE) { - DWARF_SET_ELF_ERROR(error, elf_errno()); - return DWARF_E_ERROR; - } - - if ((elf = elf_begin(fd, c, NULL)) == NULL) { - DWARF_SET_ELF_ERROR(error, elf_errno()); - return DWARF_E_ERROR; - } - - ret = dwarf_elf_init(elf, mode, ret_dbg, error); - - if (*ret_dbg != NULL) - /* Remember to close the ELF file. */ - (*ret_dbg)->dbg_elf_close = 1; - - if (ret != DWARF_E_NONE) { - if (*ret_dbg != NULL) { - dwarf_finish(ret_dbg, &lerror); - } else - elf_end(elf); - } - - return ret; -} |