Remove the old libdwarf and bring in the new libdwarf in contrib/.
This commit is contained in:
parent
1ecdb6d49d
commit
fbb4c451b3
@ -1,9 +1,16 @@
|
||||
# $FreeBSD$
|
||||
.include <bsd.own.mk>
|
||||
|
||||
TOP= ${.CURDIR}/../../contrib/elftoolchain
|
||||
SRCDIR= ${TOP}/libdwarf
|
||||
|
||||
.PATH: ${SRCDIR}
|
||||
|
||||
LIB= dwarf
|
||||
|
||||
SRCS= \
|
||||
dwarf_abbrev.c \
|
||||
dwarf_arange.c \
|
||||
dwarf_attr.c \
|
||||
dwarf_attrval.c \
|
||||
dwarf_cu.c \
|
||||
@ -11,19 +18,317 @@ SRCS= \
|
||||
dwarf_die.c \
|
||||
dwarf_dump.c \
|
||||
dwarf_errmsg.c \
|
||||
dwarf_errno.c \
|
||||
dwarf_finish.c \
|
||||
dwarf_form.c \
|
||||
dwarf_func.c \
|
||||
dwarf_frame.c \
|
||||
dwarf_funcs.c \
|
||||
dwarf_init.c \
|
||||
dwarf_loc.c
|
||||
dwarf_lineno.c \
|
||||
dwarf_loclist.c \
|
||||
dwarf_macinfo.c \
|
||||
dwarf_pro_arange.c \
|
||||
dwarf_pro_attr.c \
|
||||
dwarf_pro_die.c \
|
||||
dwarf_pro_expr.c \
|
||||
dwarf_pro_finish.c \
|
||||
dwarf_pro_frame.c \
|
||||
dwarf_pro_funcs.c \
|
||||
dwarf_pro_init.c \
|
||||
dwarf_pro_lineno.c \
|
||||
dwarf_pro_macinfo.c \
|
||||
dwarf_pro_pubnames.c \
|
||||
dwarf_pro_reloc.c \
|
||||
dwarf_pro_sections.c \
|
||||
dwarf_pro_types.c \
|
||||
dwarf_pro_vars.c \
|
||||
dwarf_pro_weaks.c \
|
||||
dwarf_pubnames.c \
|
||||
dwarf_pubtypes.c \
|
||||
dwarf_ranges.c \
|
||||
dwarf_reloc.c \
|
||||
dwarf_seterror.c \
|
||||
dwarf_str.c \
|
||||
dwarf_types.c \
|
||||
dwarf_vars.c \
|
||||
dwarf_weaks.c \
|
||||
libdwarf.c \
|
||||
libdwarf_abbrev.c \
|
||||
libdwarf_arange.c \
|
||||
libdwarf_attr.c \
|
||||
libdwarf_die.c \
|
||||
libdwarf_error.c \
|
||||
libdwarf_elf_access.c \
|
||||
libdwarf_elf_init.c \
|
||||
libdwarf_frame.c \
|
||||
libdwarf_info.c \
|
||||
libdwarf_init.c \
|
||||
libdwarf_lineno.c \
|
||||
libdwarf_loc.c \
|
||||
libdwarf_loclist.c \
|
||||
libdwarf_macinfo.c \
|
||||
libdwarf_nametbl.c \
|
||||
libdwarf_ranges.c \
|
||||
libdwarf_reloc.c \
|
||||
libdwarf_rw.c \
|
||||
libdwarf_sections.c \
|
||||
libdwarf_str.c
|
||||
|
||||
INCS= dwarf.h libdwarf.h
|
||||
INCS= dwarf.h libdwarf.h
|
||||
INCSDIR= /usr/include
|
||||
|
||||
CFLAGS+= -I${.CURDIR}
|
||||
GENSRCS= dwarf_pubnames.c dwarf_pubtypes.c dwarf_weaks.c \
|
||||
dwarf_funcs.c dwarf_vars.c dwarf_types.c \
|
||||
dwarf_pro_pubnames.c dwarf_pro_weaks.c \
|
||||
dwarf_pro_funcs.c dwarf_pro_types.c \
|
||||
dwarf_pro_vars.c
|
||||
CLEANFILES= ${GENSRCS}
|
||||
CFLAGS+= -I. -I${SRCDIR} -I${TOP}/common -I${TOP}/libelf
|
||||
|
||||
LDADD+= -lelf
|
||||
DPADD+= ${LIBELF}
|
||||
|
||||
SHLIB_MAJOR= 3
|
||||
|
||||
WITHOUT_MAN=
|
||||
MAN= dwarf.3 \
|
||||
dwarf_add_arange.3 \
|
||||
dwarf_add_AT_comp_dir.3 \
|
||||
dwarf_add_AT_const_value_string.3 \
|
||||
dwarf_add_AT_dataref.3 \
|
||||
dwarf_add_AT_flag.3 \
|
||||
dwarf_add_AT_location_expr.3 \
|
||||
dwarf_add_AT_name.3 \
|
||||
dwarf_add_AT_producer.3 \
|
||||
dwarf_add_AT_ref_address.3 \
|
||||
dwarf_add_AT_reference.3 \
|
||||
dwarf_add_AT_signed_const.3 \
|
||||
dwarf_add_AT_string.3 \
|
||||
dwarf_add_AT_targ_address.3 \
|
||||
dwarf_add_die_to_debug.3 \
|
||||
dwarf_add_directory_decl.3 \
|
||||
dwarf_add_expr_addr.3 \
|
||||
dwarf_add_expr_gen.3 \
|
||||
dwarf_add_fde_inst.3 \
|
||||
dwarf_add_file_decl.3 \
|
||||
dwarf_add_frame_cie.3 \
|
||||
dwarf_add_frame_fde.3 \
|
||||
dwarf_add_funcname.3 \
|
||||
dwarf_add_line_entry.3 \
|
||||
dwarf_add_pubname.3 \
|
||||
dwarf_add_typename.3 \
|
||||
dwarf_add_varname.3 \
|
||||
dwarf_add_weakname.3 \
|
||||
dwarf_attr.3 \
|
||||
dwarf_attrlist.3 \
|
||||
dwarf_attrval_signed.3 \
|
||||
dwarf_child.3 \
|
||||
dwarf_dealloc.3 \
|
||||
dwarf_def_macro.3 \
|
||||
dwarf_die_abbrev_code.3 \
|
||||
dwarf_die_link.3 \
|
||||
dwarf_diename.3 \
|
||||
dwarf_dieoffset.3 \
|
||||
dwarf_end_macro_file.3 \
|
||||
dwarf_errmsg.3 \
|
||||
dwarf_errno.3 \
|
||||
dwarf_expand_frame_instructions.3 \
|
||||
dwarf_expr_current_offset.3 \
|
||||
dwarf_expr_into_block.3 \
|
||||
dwarf_fde_cfa_offset.3 \
|
||||
dwarf_find_macro_value_start.3 \
|
||||
dwarf_finish.3 \
|
||||
dwarf_formaddr.3 \
|
||||
dwarf_formblock.3 \
|
||||
dwarf_formexprloc.3 \
|
||||
dwarf_formflag.3 \
|
||||
dwarf_formref.3 \
|
||||
dwarf_formsig8.3 \
|
||||
dwarf_formstring.3 \
|
||||
dwarf_formudata.3 \
|
||||
dwarf_get_abbrev.3 \
|
||||
dwarf_get_abbrev_children_flag.3 \
|
||||
dwarf_get_abbrev_code.3 \
|
||||
dwarf_get_abbrev_entry.3 \
|
||||
dwarf_get_abbrev_tag.3 \
|
||||
dwarf_get_address_size.3 \
|
||||
dwarf_get_arange.3 \
|
||||
dwarf_get_arange_info.3 \
|
||||
dwarf_get_aranges.3 \
|
||||
dwarf_get_AT_name.3 \
|
||||
dwarf_get_cie_index.3 \
|
||||
dwarf_get_cie_info.3 \
|
||||
dwarf_get_cie_of_fde.3 \
|
||||
dwarf_get_cu_die_offset.3 \
|
||||
dwarf_get_elf.3 \
|
||||
dwarf_get_fde_at_pc.3 \
|
||||
dwarf_get_fde_info_for_all_regs.3 \
|
||||
dwarf_get_fde_info_for_all_regs3.3 \
|
||||
dwarf_get_fde_info_for_cfa_reg3.3 \
|
||||
dwarf_get_fde_info_for_reg.3 \
|
||||
dwarf_get_fde_info_for_reg3.3 \
|
||||
dwarf_get_fde_instr_bytes.3 \
|
||||
dwarf_get_fde_list.3 \
|
||||
dwarf_get_fde_n.3 \
|
||||
dwarf_get_fde_range.3 \
|
||||
dwarf_get_form_class.3 \
|
||||
dwarf_get_funcs.3 \
|
||||
dwarf_get_globals.3 \
|
||||
dwarf_get_loclist_entry.3 \
|
||||
dwarf_get_macro_details.3 \
|
||||
dwarf_get_pubtypes.3 \
|
||||
dwarf_get_ranges.3 \
|
||||
dwarf_get_relocation_info.3 \
|
||||
dwarf_get_relocation_info_count.3 \
|
||||
dwarf_get_section_bytes.3 \
|
||||
dwarf_get_str.3 \
|
||||
dwarf_get_types.3 \
|
||||
dwarf_get_vars.3 \
|
||||
dwarf_get_weaks.3 \
|
||||
dwarf_hasattr.3 \
|
||||
dwarf_hasform.3 \
|
||||
dwarf_highpc.3 \
|
||||
dwarf_init.3 \
|
||||
dwarf_lineno.3 \
|
||||
dwarf_lne_end_sequence.3 \
|
||||
dwarf_lne_set_address.3 \
|
||||
dwarf_loclist.3 \
|
||||
dwarf_loclist_from_expr.3 \
|
||||
dwarf_new_die.3 \
|
||||
dwarf_new_expr.3 \
|
||||
dwarf_new_fde.3 \
|
||||
dwarf_next_cu_header.3 \
|
||||
dwarf_object_init.3 \
|
||||
dwarf_producer_init.3 \
|
||||
dwarf_producer_set_isa.3 \
|
||||
dwarf_reset_section_bytes.3 \
|
||||
dwarf_seterrarg.3 \
|
||||
dwarf_set_frame_cfa_value.3 \
|
||||
dwarf_set_reloc_application.3 \
|
||||
dwarf_srcfiles.3 \
|
||||
dwarf_srclines.3 \
|
||||
dwarf_start_macro_file.3 \
|
||||
dwarf_tag.3 \
|
||||
dwarf_transform_to_disk_form.3 \
|
||||
dwarf_undef_macro.3 \
|
||||
dwarf_vendor_ext.3 \
|
||||
dwarf_whatattr.3
|
||||
|
||||
MLINKS+= \
|
||||
dwarf_add_AT_const_value_string.3 dwarf_add_AT_const_value_signedint.3 \
|
||||
dwarf_add_AT_const_value_string.3 dwarf_add_AT_const_value_unsignedint.3 \
|
||||
dwarf_add_AT_signed_const.3 dwarf_add_AT_unsigned_const.3 \
|
||||
dwarf_add_AT_targ_address.3 dwarf_add_AT_targ_address_b.3 \
|
||||
dwarf_add_arange.3 dwarf_add_arange_b.3 \
|
||||
dwarf_add_expr_addr.3 dwarf_add_expr_addr_b.3 \
|
||||
dwarf_add_frame_fde.3 dwarf_add_frame_fde_b.3 \
|
||||
dwarf_attrval_signed.3 dwarf_attrval_flag.3 \
|
||||
dwarf_attrval_signed.3 dwarf_attrval_string.3 \
|
||||
dwarf_attrval_signed.3 dwarf_attrval_unsigned.3 \
|
||||
dwarf_child.3 dwarf_offdie.3 \
|
||||
dwarf_child.3 dwarf_siblingof.3 \
|
||||
dwarf_dealloc.3 dwarf_fde_cie_list_dealloc.3 \
|
||||
dwarf_dealloc.3 dwarf_funcs_dealloc.3 \
|
||||
dwarf_dealloc.3 dwarf_globals_dealloc.3 \
|
||||
dwarf_dealloc.3 dwarf_pubtypes_dealloc.3 \
|
||||
dwarf_dealloc.3 dwarf_types_dealloc.3 \
|
||||
dwarf_dealloc.3 dwarf_vars_dealloc.3 \
|
||||
dwarf_dealloc.3 dwarf_weaks_dealloc.3 \
|
||||
dwarf_dealloc.3 dwarf_ranges_dealloc.3 \
|
||||
dwarf_dealloc.3 dwarf_srclines_dealloc.3 \
|
||||
dwarf_init.3 dwarf_elf_init.3 \
|
||||
dwarf_dieoffset.3 dwarf_die_CU_offset.3 \
|
||||
dwarf_dieoffset.3 dwarf_die_CU_offset_range.3 \
|
||||
dwarf_dieoffset.3 dwarf_get_cu_die_offset_given_cu_header_offset.3 \
|
||||
dwarf_finish.3 dwarf_object_finish.3 \
|
||||
dwarf_formref.3 dwarf_global_formref.3 \
|
||||
dwarf_formudata.3 dwarf_formsdata.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_ACCESS_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_ATE_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_CC_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_CFA_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_CHILDREN_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_DS_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_DSC_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_EH_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_END_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_FORM_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_ID_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_INL_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_LANG_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_LNE_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_LNS_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_MACINFO_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_OP_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_ORD_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_TAG_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_VIRTUALITY_name.3 \
|
||||
dwarf_get_AT_name.3 dwarf_get_VIS_name.3 \
|
||||
dwarf_get_cu_die_offset.3 dwarf_get_arange_cu_header_offset.3 \
|
||||
dwarf_get_fde_list.3 dwarf_get_fde_list_eh.3 \
|
||||
dwarf_get_funcs.3 dwarf_func_die_offset.3 \
|
||||
dwarf_get_funcs.3 dwarf_func_cu_offset.3 \
|
||||
dwarf_get_funcs.3 dwarf_func_name_offsets.3 \
|
||||
dwarf_get_funcs.3 dwarf_funcname.3 \
|
||||
dwarf_get_globals.3 dwarf_global_die_offset.3 \
|
||||
dwarf_get_globals.3 dwarf_global_cu_offset.3 \
|
||||
dwarf_get_globals.3 dwarf_global_name_offsets.3 \
|
||||
dwarf_get_globals.3 dwarf_globname.3 \
|
||||
dwarf_get_pubtypes.3 dwarf_pubtype_die_offset.3 \
|
||||
dwarf_get_pubtypes.3 dwarf_pubtype_cu_offset.3 \
|
||||
dwarf_get_pubtypes.3 dwarf_pubtype_name_offsets.3 \
|
||||
dwarf_get_pubtypes.3 dwarf_pubtypename.3 \
|
||||
dwarf_get_ranges.3 dwarf_get_ranges_a.3 \
|
||||
dwarf_get_types.3 dwarf_type_die_offset.3 \
|
||||
dwarf_get_types.3 dwarf_type_cu_offset.3 \
|
||||
dwarf_get_types.3 dwarf_type_name_offsets.3 \
|
||||
dwarf_get_types.3 dwarf_typename.3 \
|
||||
dwarf_get_vars.3 dwarf_var_die_offset.3 \
|
||||
dwarf_get_vars.3 dwarf_var_cu_offset.3 \
|
||||
dwarf_get_vars.3 dwarf_var_name_offsets.3 \
|
||||
dwarf_get_vars.3 dwarf_varname.3 \
|
||||
dwarf_get_weaks.3 dwarf_weak_die_offset.3 \
|
||||
dwarf_get_weaks.3 dwarf_weak_cu_offset.3 \
|
||||
dwarf_get_weaks.3 dwarf_weak_name_offsets.3 \
|
||||
dwarf_get_weaks.3 dwarf_weakname.3 \
|
||||
dwarf_hasform.3 dwarf_whatform.3 \
|
||||
dwarf_hasform.3 dwarf_whatform_direct.3 \
|
||||
dwarf_highpc.3 dwarf_arrayorder.3 \
|
||||
dwarf_highpc.3 dwarf_bitoffset.3 \
|
||||
dwarf_highpc.3 dwarf_bitsize.3 \
|
||||
dwarf_highpc.3 dwarf_bytesize.3 \
|
||||
dwarf_highpc.3 dwarf_lowpc.3 \
|
||||
dwarf_highpc.3 dwarf_srclang.3 \
|
||||
dwarf_lineno.3 dwarf_lineaddr.3 \
|
||||
dwarf_lineno.3 dwarf_linebeginstatement.3 \
|
||||
dwarf_lineno.3 dwarf_lineblock.3 \
|
||||
dwarf_lineno.3 dwarf_lineendsequence.3 \
|
||||
dwarf_lineno.3 dwarf_lineoff.3 \
|
||||
dwarf_lineno.3 dwarf_linesrc.3 \
|
||||
dwarf_lineno.3 dwarf_line_srcfileno.3 \
|
||||
dwarf_loclist.3 dwarf_loclist_n.3 \
|
||||
dwarf_loclist_from_expr.3 dwarf_loclist_from_expr_a.3 \
|
||||
dwarf_producer_init.3 dwarf_producer_init_b.3 \
|
||||
dwarf_seterrarg.3 dwarf_seterrhand.3 \
|
||||
dwarf_set_frame_cfa_value.3 dwarf_set_frame_rule_initial_value.3 \
|
||||
dwarf_set_frame_cfa_value.3 dwarf_set_frame_rule_table_size.3 \
|
||||
dwarf_set_frame_cfa_value.3 dwarf_set_frame_same_value.3 \
|
||||
dwarf_set_frame_cfa_value.3 dwarf_set_frame_undefined_value.3
|
||||
|
||||
dwarf_pubnames.c: dwarf_nametbl.m4 dwarf_pubnames.m4
|
||||
dwarf_pubtypes.c: dwarf_nametbl.m4 dwarf_pubtypes.m4
|
||||
dwarf_weaks.c: dwarf_nametbl.m4 dwarf_weaks.m4
|
||||
dwarf_funcs.c: dwarf_nametbl.m4 dwarf_funcs.m4
|
||||
dwarf_vars.c: dwarf_nametbl.m4 dwarf_vars.m4
|
||||
dwarf_types.c: dwarf_nametbl.m4 dwarf_types.m4
|
||||
dwarf_pro_pubnames.c: dwarf_pro_nametbl.m4 dwarf_pro_pubnames.m4
|
||||
dwarf_pro_weaks.c: dwarf_pro_nametbl.m4 dwarf_pro_weaks.m4
|
||||
dwarf_pro_funcs.c: dwarf_pro_nametbl.m4 dwarf_pro_funcs.m4
|
||||
dwarf_pro_types.c: dwarf_pro_nametbl.m4 dwarf_pro_types.m4
|
||||
dwarf_pro_vars.c: dwarf_pro_nametbl.m4 dwarf_pro_vars.m4
|
||||
|
||||
.include <bsd.lib.mk>
|
||||
|
||||
# Keep the .SUFFIXES line after the include of bsd.lib.mk
|
||||
.SUFFIXES: .m4 .c
|
||||
.m4.c:
|
||||
m4 -D SRCDIR=${SRCDIR} ${M4FLAGS} ${.IMPSRC} > ${.TARGET}
|
||||
|
||||
|
@ -1,199 +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$
|
||||
*/
|
||||
|
||||
#ifndef __LIBDWARF_H_
|
||||
#define __LIBDWARF_H_
|
||||
|
||||
#include <sys/param.h>
|
||||
#include <sys/queue.h>
|
||||
#include <stdio.h>
|
||||
#include <gelf.h>
|
||||
#include "dwarf.h"
|
||||
#include "libdwarf.h"
|
||||
|
||||
#define DWARF_debug_abbrev 0
|
||||
#define DWARF_debug_aranges 1
|
||||
#define DWARF_debug_frame 2
|
||||
#define DWARF_debug_info 3
|
||||
#define DWARF_debug_line 4
|
||||
#define DWARF_debug_pubnames 5
|
||||
#define DWARF_eh_frame 6
|
||||
#define DWARF_debug_macinfo 7
|
||||
#define DWARF_debug_str 8
|
||||
#define DWARF_debug_loc 9
|
||||
#define DWARF_debug_pubtypes 10
|
||||
#define DWARF_debug_ranges 11
|
||||
#define DWARF_debug_static_func 12
|
||||
#define DWARF_debug_static_vars 13
|
||||
#define DWARF_debug_types 14
|
||||
#define DWARF_debug_weaknames 15
|
||||
#define DWARF_symtab 16
|
||||
#define DWARF_strtab 17
|
||||
#define DWARF_DEBUG_SNAMES 18
|
||||
|
||||
#define DWARF_DIE_HASH_SIZE 8191
|
||||
|
||||
#define DWARF_SET_ERROR(_e, _err) do { \
|
||||
_e->err_error = _err; \
|
||||
_e->elf_error = 0; \
|
||||
_e->err_func = __func__; \
|
||||
_e->err_line = __LINE__; \
|
||||
_e->err_msg[0] = '\0'; \
|
||||
} while (0)
|
||||
|
||||
#define DWARF_SET_ELF_ERROR(_e, _err) do { \
|
||||
_e->err_error = DWARF_E_ELF; \
|
||||
_e->elf_error = _err; \
|
||||
_e->err_func = __func__; \
|
||||
_e->err_line = __LINE__; \
|
||||
_e->err_msg[0] = '\0'; \
|
||||
} while (0)
|
||||
|
||||
struct _Dwarf_AttrValue {
|
||||
uint64_t av_attrib; /* DW_AT_ */
|
||||
uint64_t av_form; /* DW_FORM_ */
|
||||
union {
|
||||
uint64_t u64;
|
||||
int64_t s64;
|
||||
const char *s;
|
||||
uint8_t *u8p;
|
||||
} u[2]; /* Value. */
|
||||
STAILQ_ENTRY(_Dwarf_AttrValue)
|
||||
av_next; /* Next attribute value. */
|
||||
};
|
||||
|
||||
struct _Dwarf_Die {
|
||||
int die_level; /* Parent-child level. */
|
||||
uint64_t die_offset; /* DIE offset in section. */
|
||||
uint64_t die_abnum; /* Abbrev number. */
|
||||
Dwarf_Abbrev die_a; /* Abbrev pointer. */
|
||||
Dwarf_CU die_cu; /* Compilation unit pointer. */
|
||||
const char *die_name; /* Ptr to the name string. */
|
||||
STAILQ_HEAD(, _Dwarf_AttrValue)
|
||||
die_attrval; /* List of attribute values. */
|
||||
STAILQ_ENTRY(_Dwarf_Die)
|
||||
die_next; /* Next die in list. */
|
||||
STAILQ_ENTRY(_Dwarf_Die)
|
||||
die_hash; /* Next die in hash table. */
|
||||
};
|
||||
|
||||
struct _Dwarf_Attribute {
|
||||
uint64_t at_attrib; /* DW_AT_ */
|
||||
uint64_t at_form; /* DW_FORM_ */
|
||||
STAILQ_ENTRY(_Dwarf_Attribute)
|
||||
at_next; /* Next attribute. */
|
||||
};
|
||||
|
||||
struct _Dwarf_Abbrev {
|
||||
uint64_t a_entry; /* Abbrev entry. */
|
||||
uint64_t a_tag; /* Tag: DW_TAG_ */
|
||||
uint8_t a_children; /* DW_CHILDREN_no or DW_CHILDREN_yes */
|
||||
STAILQ_HEAD(, _Dwarf_Attribute)
|
||||
a_attrib; /* List of attributes. */
|
||||
STAILQ_ENTRY(_Dwarf_Abbrev)
|
||||
a_next; /* Next abbrev. */
|
||||
};
|
||||
|
||||
struct _Dwarf_CU {
|
||||
uint64_t cu_offset; /* Offset to the this compilation unit. */
|
||||
uint32_t cu_length; /* Length of CU data. */
|
||||
uint32_t cu_header_length;
|
||||
/* Length of the CU header. */
|
||||
uint16_t cu_version; /* DWARF version. */
|
||||
uint64_t cu_abbrev_offset;
|
||||
/* Offset into .debug_abbrev. */
|
||||
uint8_t cu_pointer_size;
|
||||
/* Number of bytes in pointer. */
|
||||
uint64_t cu_next_offset;
|
||||
/* Offset to the next compilation unit. */
|
||||
STAILQ_HEAD(, _Dwarf_Abbrev)
|
||||
cu_abbrev; /* List of abbrevs. */
|
||||
STAILQ_HEAD(, _Dwarf_Die)
|
||||
cu_die; /* List of dies. */
|
||||
STAILQ_HEAD(, _Dwarf_Die)
|
||||
cu_die_hash[DWARF_DIE_HASH_SIZE];
|
||||
/* Hash of dies. */
|
||||
STAILQ_ENTRY(_Dwarf_CU)
|
||||
cu_next; /* Next compilation unit. */
|
||||
};
|
||||
|
||||
typedef struct _Dwarf_section {
|
||||
Elf_Scn *s_scn; /* Section pointer. */
|
||||
GElf_Shdr s_shdr; /* Copy of the section header. */
|
||||
char *s_sname; /* Ptr to the section name. */
|
||||
uint32_t s_shnum; /* Section number. */
|
||||
Elf_Data *s_data; /* Section data. */
|
||||
} Dwarf_section;
|
||||
|
||||
struct _Dwarf_Debug {
|
||||
Elf *dbg_elf; /* Ptr to the ELF handle. */
|
||||
GElf_Ehdr dbg_ehdr; /* Copy of the ELF header. */
|
||||
int dbg_elf_close; /* True if elf_end() required. */
|
||||
int dbg_mode; /* Access mode. */
|
||||
size_t dbg_stnum; /* Section header string table section number. */
|
||||
int dbg_offsize; /* DWARF offset size. */
|
||||
Dwarf_section dbg_s[DWARF_DEBUG_SNAMES];
|
||||
/* Array of section information. */
|
||||
STAILQ_HEAD(, _Dwarf_CU)
|
||||
dbg_cu; /* List of compilation units. */
|
||||
Dwarf_CU dbg_cu_current;
|
||||
/* Ptr to the current compilation unit. */
|
||||
|
||||
STAILQ_HEAD(, _Dwarf_Func) dbg_func; /* List of functions */
|
||||
};
|
||||
|
||||
struct _Dwarf_Func {
|
||||
Dwarf_Die func_die;
|
||||
const char *func_name;
|
||||
Dwarf_Addr func_low_pc;
|
||||
Dwarf_Addr func_high_pc;
|
||||
int func_is_inlined;
|
||||
/* inlined instance */
|
||||
STAILQ_HEAD(, _Dwarf_Inlined_Func) func_inlined_instances;
|
||||
STAILQ_ENTRY(_Dwarf_Func) func_next;
|
||||
};
|
||||
|
||||
struct _Dwarf_Inlined_Func {
|
||||
struct _Dwarf_Func *ifunc_origin;
|
||||
Dwarf_Die ifunc_abstract;
|
||||
Dwarf_Die ifunc_concrete;
|
||||
Dwarf_Addr ifunc_low_pc;
|
||||
Dwarf_Addr ifunc_high_pc;
|
||||
STAILQ_ENTRY(_Dwarf_Inlined_Func) ifunc_next;
|
||||
};
|
||||
|
||||
void dwarf_build_function_table(Dwarf_Debug dbg);
|
||||
|
||||
#ifdef DWARF_DEBUG
|
||||
#include <assert.h>
|
||||
#define DWARF_ASSERT(x) assert(x)
|
||||
#else
|
||||
#define DWARF_ASSERT(x)
|
||||
#endif
|
||||
|
||||
#endif /* !__LIBDWARF_H_ */
|
@ -1,479 +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$
|
||||
*/
|
||||
|
||||
#ifndef _DWARF_H_
|
||||
#define _DWARF_H_
|
||||
|
||||
#define DW_TAG_array_type 0x01
|
||||
#define DW_TAG_class_type 0x02
|
||||
#define DW_TAG_entry_point 0x03
|
||||
#define DW_TAG_enumeration_type 0x04
|
||||
#define DW_TAG_formal_parameter 0x05
|
||||
#define DW_TAG_imported_declaration 0x08
|
||||
#define DW_TAG_label 0x0a
|
||||
#define DW_TAG_lexical_block 0x0b
|
||||
#define DW_TAG_member 0x0d
|
||||
#define DW_TAG_pointer_type 0x0f
|
||||
#define DW_TAG_reference_type 0x10
|
||||
#define DW_TAG_compile_unit 0x11
|
||||
#define DW_TAG_string_type 0x12
|
||||
#define DW_TAG_structure_type 0x13
|
||||
#define DW_TAG_subroutine_type 0x15
|
||||
#define DW_TAG_typedef 0x16
|
||||
#define DW_TAG_union_type 0x17
|
||||
#define DW_TAG_unspecified_parameters 0x18
|
||||
#define DW_TAG_variant 0x19
|
||||
#define DW_TAG_common_block 0x1a
|
||||
#define DW_TAG_common_inclusion 0x1b
|
||||
#define DW_TAG_inheritance 0x1c
|
||||
#define DW_TAG_inlined_subroutine 0x1d
|
||||
#define DW_TAG_module 0x1e
|
||||
#define DW_TAG_ptr_to_member_type 0x1f
|
||||
#define DW_TAG_set_type 0x20
|
||||
#define DW_TAG_subrange_type 0x21
|
||||
#define DW_TAG_with_stmt 0x22
|
||||
#define DW_TAG_access_declaration 0x23
|
||||
#define DW_TAG_base_type 0x24
|
||||
#define DW_TAG_catch_block 0x25
|
||||
#define DW_TAG_const_type 0x26
|
||||
#define DW_TAG_constant 0x27
|
||||
#define DW_TAG_enumerator 0x28
|
||||
#define DW_TAG_friend 0x2a
|
||||
#define DW_TAG_namelist 0x2b
|
||||
#define DW_TAG_namelist_item 0x2c
|
||||
#define DW_TAG_packed_type 0x2d
|
||||
#define DW_TAG_subprogram 0x2e
|
||||
#define DW_TAG_template_type_parameter 0x2f
|
||||
#define DW_TAG_template_type_param 0x2f
|
||||
#define DW_TAG_template_value_parameter 0x30
|
||||
#define DW_TAG_template_value_param 0x30
|
||||
#define DW_TAG_thrown_type 0x31
|
||||
#define DW_TAG_try_block 0x32
|
||||
#define DW_TAG_variant_part 0x33
|
||||
#define DW_TAG_variable 0x34
|
||||
#define DW_TAG_volatile_type 0x35
|
||||
#define DW_TAG_dwarf_procedure 0x36
|
||||
#define DW_TAG_restrict_type 0x37
|
||||
#define DW_TAG_interface_type 0x38
|
||||
#define DW_TAG_namespace 0x39
|
||||
#define DW_TAG_imported_module 0x3a
|
||||
#define DW_TAG_unspecified_type 0x3b
|
||||
#define DW_TAG_partial_unit 0x3c
|
||||
#define DW_TAG_imported_unit 0x3d
|
||||
#define DW_TAG_condition 0x3f
|
||||
#define DW_TAG_shared_type 0x40
|
||||
|
||||
#define DW_TAG_lo_user 0x4080
|
||||
|
||||
#define DW_TAG_hi_user 0xffff
|
||||
|
||||
#define DW_CHILDREN_no 0x00
|
||||
#define DW_CHILDREN_yes 0x01
|
||||
|
||||
#define DW_AT_sibling 0x01
|
||||
#define DW_AT_location 0x02
|
||||
#define DW_AT_name 0x03
|
||||
#define DW_AT_ordering 0x09
|
||||
#define DW_AT_subscr_data 0x0a
|
||||
#define DW_AT_byte_size 0x0b
|
||||
#define DW_AT_bit_offset 0x0c
|
||||
#define DW_AT_bit_size 0x0d
|
||||
#define DW_AT_element_list 0x0f
|
||||
#define DW_AT_stmt_list 0x10
|
||||
#define DW_AT_low_pc 0x11
|
||||
#define DW_AT_high_pc 0x12
|
||||
#define DW_AT_language 0x13
|
||||
#define DW_AT_member 0x14
|
||||
#define DW_AT_discr 0x15
|
||||
#define DW_AT_discr_value 0x16
|
||||
#define DW_AT_visibility 0x17
|
||||
#define DW_AT_import 0x18
|
||||
#define DW_AT_string_length 0x19
|
||||
#define DW_AT_common_reference 0x1a
|
||||
#define DW_AT_comp_dir 0x1b
|
||||
#define DW_AT_const_value 0x1c
|
||||
#define DW_AT_containing_type 0x1d
|
||||
#define DW_AT_default_value 0x1e
|
||||
#define DW_AT_inline 0x20
|
||||
#define DW_AT_is_optional 0x21
|
||||
#define DW_AT_lower_bound 0x22
|
||||
#define DW_AT_producer 0x25
|
||||
#define DW_AT_prototyped 0x27
|
||||
#define DW_AT_return_addr 0x2a
|
||||
#define DW_AT_start_scope 0x2c
|
||||
#define DW_AT_bit_stride 0x2e
|
||||
#define DW_AT_stride_size 0x2e
|
||||
#define DW_AT_upper_bound 0x2f
|
||||
#define DW_AT_abstract_origin 0x31
|
||||
#define DW_AT_accessibility 0x32
|
||||
#define DW_AT_address_class 0x33
|
||||
#define DW_AT_artificial 0x34
|
||||
#define DW_AT_base_types 0x35
|
||||
#define DW_AT_calling_convention 0x36
|
||||
#define DW_AT_count 0x37
|
||||
#define DW_AT_data_member_location 0x38
|
||||
#define DW_AT_decl_column 0x39
|
||||
#define DW_AT_decl_file 0x3a
|
||||
#define DW_AT_decl_line 0x3b
|
||||
#define DW_AT_declaration 0x3c
|
||||
#define DW_AT_discr_list 0x3d
|
||||
#define DW_AT_encoding 0x3e
|
||||
#define DW_AT_external 0x3f
|
||||
#define DW_AT_frame_base 0x40
|
||||
#define DW_AT_friend 0x41
|
||||
#define DW_AT_identifier_case 0x42
|
||||
#define DW_AT_macro_info 0x43
|
||||
#define DW_AT_namelist_item 0x44
|
||||
#define DW_AT_priority 0x45
|
||||
#define DW_AT_segment 0x46
|
||||
#define DW_AT_specification 0x47
|
||||
#define DW_AT_static_link 0x48
|
||||
#define DW_AT_type 0x49
|
||||
#define DW_AT_use_location 0x4a
|
||||
#define DW_AT_variable_parameter 0x4b
|
||||
#define DW_AT_virtuality 0x4c
|
||||
#define DW_AT_vtable_elem_location 0x4d
|
||||
|
||||
#define DW_AT_lo_user 0x2000
|
||||
|
||||
#define DW_AT_hi_user 0x3fff
|
||||
|
||||
#define DW_FORM_addr 0x01
|
||||
#define DW_FORM_block2 0x03
|
||||
#define DW_FORM_block4 0x04
|
||||
#define DW_FORM_data2 0x05
|
||||
#define DW_FORM_data4 0x06
|
||||
#define DW_FORM_data8 0x07
|
||||
#define DW_FORM_string 0x08
|
||||
#define DW_FORM_block 0x09
|
||||
#define DW_FORM_block1 0x0a
|
||||
#define DW_FORM_data1 0x0b
|
||||
#define DW_FORM_flag 0x0c
|
||||
#define DW_FORM_sdata 0x0d
|
||||
#define DW_FORM_strp 0x0e
|
||||
#define DW_FORM_udata 0x0f
|
||||
#define DW_FORM_ref_addr 0x10
|
||||
#define DW_FORM_ref1 0x11
|
||||
#define DW_FORM_ref2 0x12
|
||||
#define DW_FORM_ref4 0x13
|
||||
#define DW_FORM_ref8 0x14
|
||||
#define DW_FORM_ref_udata 0x15
|
||||
#define DW_FORM_indirect 0x16
|
||||
#define DW_FORM_flag_present 0x19
|
||||
|
||||
#define DW_OP_addr 0x03
|
||||
#define DW_OP_deref 0x06
|
||||
#define DW_OP_const1u 0x08
|
||||
#define DW_OP_const1s 0x09
|
||||
#define DW_OP_const2u 0x0a
|
||||
#define DW_OP_const2s 0x0b
|
||||
#define DW_OP_const4u 0x0c
|
||||
#define DW_OP_const4s 0x0d
|
||||
#define DW_OP_const8u 0x0e
|
||||
#define DW_OP_const8s 0x0f
|
||||
#define DW_OP_constu 0x10
|
||||
#define DW_OP_consts 0x11
|
||||
#define DW_OP_dup 0x12
|
||||
#define DW_OP_drop 0x13
|
||||
#define DW_OP_over 0x14
|
||||
#define DW_OP_pick 0x15
|
||||
#define DW_OP_swap 0x16
|
||||
#define DW_OP_rot 0x17
|
||||
#define DW_OP_xderef 0x18
|
||||
#define DW_OP_abs 0x19
|
||||
#define DW_OP_and 0x1a
|
||||
#define DW_OP_div 0x1b
|
||||
#define DW_OP_minus 0x1c
|
||||
#define DW_OP_mod 0x1d
|
||||
#define DW_OP_mul 0x1e
|
||||
#define DW_OP_neg 0x1f
|
||||
#define DW_OP_not 0x20
|
||||
#define DW_OP_or 0x21
|
||||
#define DW_OP_plus 0x22
|
||||
#define DW_OP_plus_uconst 0x23
|
||||
#define DW_OP_shl 0x24
|
||||
#define DW_OP_shr 0x25
|
||||
#define DW_OP_shra 0x26
|
||||
#define DW_OP_xor 0x27
|
||||
#define DW_OP_bra 0x28
|
||||
#define DW_OP_eq 0x29
|
||||
#define DW_OP_ge 0x2a
|
||||
#define DW_OP_gt 0x2b
|
||||
#define DW_OP_le 0x2c
|
||||
#define DW_OP_lt 0x2d
|
||||
#define DW_OP_ne 0x2e
|
||||
#define DW_OP_skip 0x2f
|
||||
#define DW_OP_lit0 0x30
|
||||
#define DW_OP_lit1 0x31
|
||||
#define DW_OP_lit2 0x32
|
||||
#define DW_OP_lit3 0x33
|
||||
#define DW_OP_lit4 0x34
|
||||
#define DW_OP_lit5 0x35
|
||||
#define DW_OP_lit6 0x36
|
||||
#define DW_OP_lit7 0x37
|
||||
#define DW_OP_lit8 0x38
|
||||
#define DW_OP_lit9 0x39
|
||||
#define DW_OP_lit10 0x3a
|
||||
#define DW_OP_lit11 0x3b
|
||||
#define DW_OP_lit12 0x3c
|
||||
#define DW_OP_lit13 0x3d
|
||||
#define DW_OP_lit14 0x3e
|
||||
#define DW_OP_lit15 0x3f
|
||||
#define DW_OP_lit16 0x40
|
||||
#define DW_OP_lit17 0x41
|
||||
#define DW_OP_lit18 0x42
|
||||
#define DW_OP_lit19 0x43
|
||||
#define DW_OP_lit20 0x44
|
||||
#define DW_OP_lit21 0x45
|
||||
#define DW_OP_lit22 0x46
|
||||
#define DW_OP_lit23 0x47
|
||||
#define DW_OP_lit24 0x48
|
||||
#define DW_OP_lit25 0x49
|
||||
#define DW_OP_lit26 0x4a
|
||||
#define DW_OP_lit27 0x4b
|
||||
#define DW_OP_lit28 0x4c
|
||||
#define DW_OP_lit29 0x4d
|
||||
#define DW_OP_lit30 0x4e
|
||||
#define DW_OP_lit31 0x4f
|
||||
#define DW_OP_reg0 0x50
|
||||
#define DW_OP_reg1 0x51
|
||||
#define DW_OP_reg2 0x52
|
||||
#define DW_OP_reg3 0x53
|
||||
#define DW_OP_reg4 0x54
|
||||
#define DW_OP_reg5 0x55
|
||||
#define DW_OP_reg6 0x56
|
||||
#define DW_OP_reg7 0x57
|
||||
#define DW_OP_reg8 0x58
|
||||
#define DW_OP_reg9 0x59
|
||||
#define DW_OP_reg10 0x5a
|
||||
#define DW_OP_reg11 0x5b
|
||||
#define DW_OP_reg12 0x5c
|
||||
#define DW_OP_reg13 0x5d
|
||||
#define DW_OP_reg14 0x5e
|
||||
#define DW_OP_reg15 0x5f
|
||||
#define DW_OP_reg16 0x60
|
||||
#define DW_OP_reg17 0x61
|
||||
#define DW_OP_reg18 0x62
|
||||
#define DW_OP_reg19 0x63
|
||||
#define DW_OP_reg20 0x64
|
||||
#define DW_OP_reg21 0x65
|
||||
#define DW_OP_reg22 0x66
|
||||
#define DW_OP_reg23 0x67
|
||||
#define DW_OP_reg24 0x68
|
||||
#define DW_OP_reg25 0x69
|
||||
#define DW_OP_reg26 0x6a
|
||||
#define DW_OP_reg27 0x6b
|
||||
#define DW_OP_reg28 0x6c
|
||||
#define DW_OP_reg29 0x6d
|
||||
#define DW_OP_reg30 0x6e
|
||||
#define DW_OP_reg31 0x6f
|
||||
#define DW_OP_breg0 0x70
|
||||
#define DW_OP_breg1 0x71
|
||||
#define DW_OP_breg2 0x72
|
||||
#define DW_OP_breg3 0x73
|
||||
#define DW_OP_breg4 0x74
|
||||
#define DW_OP_breg5 0x75
|
||||
#define DW_OP_breg6 0x76
|
||||
#define DW_OP_breg7 0x77
|
||||
#define DW_OP_breg8 0x78
|
||||
#define DW_OP_breg9 0x79
|
||||
#define DW_OP_breg10 0x7a
|
||||
#define DW_OP_breg11 0x7b
|
||||
#define DW_OP_breg12 0x7c
|
||||
#define DW_OP_breg13 0x7d
|
||||
#define DW_OP_breg14 0x7e
|
||||
#define DW_OP_breg15 0x7f
|
||||
#define DW_OP_breg16 0x80
|
||||
#define DW_OP_breg17 0x81
|
||||
#define DW_OP_breg18 0x82
|
||||
#define DW_OP_breg19 0x83
|
||||
#define DW_OP_breg20 0x84
|
||||
#define DW_OP_breg21 0x85
|
||||
#define DW_OP_breg22 0x86
|
||||
#define DW_OP_breg23 0x87
|
||||
#define DW_OP_breg24 0x88
|
||||
#define DW_OP_breg25 0x89
|
||||
#define DW_OP_breg26 0x8a
|
||||
#define DW_OP_breg27 0x8b
|
||||
#define DW_OP_breg28 0x8c
|
||||
#define DW_OP_breg29 0x8d
|
||||
#define DW_OP_breg30 0x8e
|
||||
#define DW_OP_breg31 0x8f
|
||||
#define DW_OP_regx 0x90
|
||||
#define DW_OP_fbreg 0x91
|
||||
#define DW_OP_bregx 0x92
|
||||
#define DW_OP_piece 0x93
|
||||
#define DW_OP_deref_size 0x94
|
||||
#define DW_OP_xderef_size 0x95
|
||||
#define DW_OP_nop 0x96
|
||||
|
||||
#define DW_OP_lo_user 0xe0
|
||||
|
||||
#define DW_OP_hi_user 0xff
|
||||
|
||||
#define DW_ATE_address 0x1
|
||||
#define DW_ATE_boolean 0x2
|
||||
#define DW_ATE_complex_float 0x3
|
||||
#define DW_ATE_float 0x4
|
||||
#define DW_ATE_signed 0x5
|
||||
#define DW_ATE_signed_char 0x6
|
||||
#define DW_ATE_unsigned 0x7
|
||||
#define DW_ATE_unsigned_char 0x8
|
||||
#define DW_ATE_imaginary_float 0x9
|
||||
#define DW_ATE_packed_decimal 0xa
|
||||
#define DW_ATE_numeric_string 0xb
|
||||
#define DW_ATE_edited 0xc
|
||||
#define DW_ATE_signed_fixed 0xd
|
||||
#define DW_ATE_unsigned_fixed 0xe
|
||||
#define DW_ATE_decimal_float 0xf
|
||||
|
||||
#define DW_ATE_lo_user 0x80
|
||||
|
||||
#define DW_ATE_hi_user 0xff
|
||||
|
||||
#define DW_ACCESS_public 0x01
|
||||
#define DW_ACCESS_protected 0x02
|
||||
#define DW_ACCESS_private 0x03
|
||||
|
||||
#define DW_VIS_local 0x01
|
||||
#define DW_VIS_exported 0x02
|
||||
#define DW_VIS_qualified 0x03
|
||||
|
||||
#define DW_VIRTUALITY_none 0x00
|
||||
#define DW_VIRTUALITY_virtual 0x01
|
||||
#define DW_VIRTUALITY_pure_virtual 0x02
|
||||
|
||||
#define DW_LANG_C89 0x0001
|
||||
#define DW_LANG_C 0x0002
|
||||
#define DW_LANG_Ada83 0x0003
|
||||
#define DW_LANG_C_plus_plus 0x0004
|
||||
#define DW_LANG_Cobol74 0x0005
|
||||
#define DW_LANG_Cobol85 0x0006
|
||||
#define DW_LANG_Fortran77 0x0007
|
||||
#define DW_LANG_Fortran90 0x0008
|
||||
#define DW_LANG_Pascal83 0x0009
|
||||
#define DW_LANG_Modula2 0x000a
|
||||
#define DW_LANG_Java 0x000b
|
||||
#define DW_LANG_C99 0x000c
|
||||
#define DW_LANG_Ada95 0x000d
|
||||
#define DW_LANG_Fortran95 0x000e
|
||||
#define DW_LANG_PLI 0x000f
|
||||
#define DW_LANG_ObjC 0x0010
|
||||
#define DW_LANG_ObjC_plus_plus 0x0011
|
||||
#define DW_LANG_UPC 0x0012
|
||||
#define DW_LANG_D 0x0013
|
||||
|
||||
#define DW_LANG_lo_user 0x8000
|
||||
|
||||
#define DW_LANG_hi_user 0xffff
|
||||
|
||||
#define DW_ID_case_sensitive 0x00
|
||||
#define DW_ID_up_case 0x01
|
||||
#define DW_ID_down_case 0x02
|
||||
#define DW_ID_case_insensitive 0x03
|
||||
|
||||
#define DW_CC_normal 0x01
|
||||
#define DW_CC_program 0x02
|
||||
#define DW_CC_nocall 0x03
|
||||
|
||||
#define DW_CC_lo_user 0x40
|
||||
|
||||
#define DW_CC_hi_user 0xff
|
||||
|
||||
#define DW_INL_not_inlined 0x00
|
||||
#define DW_INL_inlined 0x01
|
||||
#define DW_INL_declared_not_inlined 0x02
|
||||
#define DW_INL_declared_inlined 0x03
|
||||
|
||||
#define DW_ORD_row_major 0x00
|
||||
#define DW_ORD_col_major 0x01
|
||||
|
||||
#define DW_DSC_label 0x00
|
||||
#define DW_DSC_range 0x01
|
||||
|
||||
#define DW_LNS_copy 0x01
|
||||
#define DW_LNS_advance_pc 0x02
|
||||
#define DW_LNS_advance_line 0x03
|
||||
#define DW_LNS_set_file 0x04
|
||||
#define DW_LNS_set_column 0x05
|
||||
#define DW_LNS_negate_stmt 0x06
|
||||
#define DW_LNS_set_basic_block 0x07
|
||||
#define DW_LNS_const_add_pc 0x08
|
||||
#define DW_LNS_fixed_advance_pc 0x09
|
||||
#define DW_LNS_set_prologue_end 0x0a
|
||||
#define DW_LNS_set_epilogue_begin 0x0b
|
||||
#define DW_LNS_set_isa 0x0c
|
||||
|
||||
#define DW_LNE_end_sequence 0x01
|
||||
#define DW_LNE_set_address 0x02
|
||||
#define DW_LNE_define_file 0x03
|
||||
|
||||
#define DW_LNE_lo_user 0x80
|
||||
|
||||
#define DW_LNE_hi_user 0xff
|
||||
|
||||
#define DW_MACINFO_define 0x01
|
||||
#define DW_MACINFO_undef 0x02
|
||||
#define DW_MACINFO_start_file 0x03
|
||||
#define DW_MACINFO_end_file 0x04
|
||||
#define DW_MACINFO_vendor_ext 0xff
|
||||
|
||||
#define DW_CFA_advance_loc 0x40
|
||||
#define DW_CFA_offset 0x80
|
||||
#define DW_CFA_restore 0xc0
|
||||
#define DW_CFA_extended 0
|
||||
|
||||
#define DW_CFA_nop 0x00
|
||||
#define DW_CFA_set_loc 0x01
|
||||
#define DW_CFA_advance_loc1 0x02
|
||||
#define DW_CFA_advance_loc2 0x03
|
||||
#define DW_CFA_advance_loc4 0x04
|
||||
#define DW_CFA_offset_extended 0x05
|
||||
#define DW_CFA_restore_extended 0x06
|
||||
#define DW_CFA_undefined 0x07
|
||||
#define DW_CFA_same_value 0x08
|
||||
#define DW_CFA_register 0x09
|
||||
#define DW_CFA_remember_state 0x0a
|
||||
#define DW_CFA_restore_state 0x0b
|
||||
#define DW_CFA_def_cfa 0x0c
|
||||
#define DW_CFA_def_cfa_register 0x0d
|
||||
#define DW_CFA_def_cfa_offset 0x0e
|
||||
#define DW_CFA_def_cfa_expression 0x0f
|
||||
#define DW_CFA_expression 0x10
|
||||
#define DW_CFA_cfa_offset_extended_sf 0x11
|
||||
#define DW_CFA_def_cfa_sf 0x12
|
||||
#define DW_CFA_def_cfa_offset_sf 0x13
|
||||
#define DW_CFA_val_offset 0x14
|
||||
#define DW_CFA_val_offset_sf 0x15
|
||||
#define DW_CFA_val_expression 0x16
|
||||
|
||||
#define DW_CFA_lo_user 0x1c
|
||||
|
||||
#define DW_CFA_high_user 0x3f
|
||||
|
||||
#endif /* !_DWARF_H_ */
|
@ -1,71 +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 "_libdwarf.h"
|
||||
|
||||
int
|
||||
dwarf_abbrev_add(Dwarf_CU cu, uint64_t entry, uint64_t tag, uint8_t children, Dwarf_Abbrev *ap, Dwarf_Error *error)
|
||||
{
|
||||
Dwarf_Abbrev a;
|
||||
int ret = DWARF_E_NONE;
|
||||
|
||||
if ((a = malloc(sizeof(struct _Dwarf_Abbrev))) == NULL) {
|
||||
DWARF_SET_ERROR(error, DWARF_E_MEMORY);
|
||||
return DWARF_E_MEMORY;
|
||||
}
|
||||
|
||||
/* Initialise the abbrev structure. */
|
||||
a->a_entry = entry;
|
||||
a->a_tag = tag;
|
||||
a->a_children = children;
|
||||
|
||||
/* Initialise the list of attributes. */
|
||||
STAILQ_INIT(&a->a_attrib);
|
||||
|
||||
/* Add the abbrev to the list in the compilation unit. */
|
||||
STAILQ_INSERT_TAIL(&cu->cu_abbrev, a, a_next);
|
||||
|
||||
if (ap != NULL)
|
||||
*ap = a;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Dwarf_Abbrev
|
||||
dwarf_abbrev_find(Dwarf_CU cu, uint64_t entry)
|
||||
{
|
||||
Dwarf_Abbrev a = NULL;
|
||||
|
||||
STAILQ_FOREACH(a, &cu->cu_abbrev, a_next) {
|
||||
if (a->a_entry == entry)
|
||||
break;
|
||||
}
|
||||
|
||||
return a;
|
||||
}
|
@ -1,92 +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"
|
||||
|
||||
int
|
||||
dwarf_attr(Dwarf_Die die, Dwarf_Half attr, Dwarf_Attribute *atp, Dwarf_Error *err)
|
||||
{
|
||||
Dwarf_Attribute at;
|
||||
Dwarf_Abbrev a;
|
||||
int ret = DWARF_E_NONE;
|
||||
|
||||
if (err == NULL)
|
||||
return DWARF_E_ERROR;
|
||||
|
||||
if (die == NULL || atp == NULL || (a = die->die_a) == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
|
||||
return DWARF_E_ARGUMENT;
|
||||
}
|
||||
|
||||
STAILQ_FOREACH(at, &a->a_attrib, at_next)
|
||||
if (at->at_attrib == attr)
|
||||
break;
|
||||
|
||||
*atp = at;
|
||||
|
||||
if (at == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
|
||||
ret = DWARF_E_NO_ENTRY;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dwarf_attr_add(Dwarf_Abbrev a, uint64_t attr, uint64_t form, Dwarf_Attribute *atp, Dwarf_Error *error)
|
||||
{
|
||||
Dwarf_Attribute at;
|
||||
int ret = DWARF_E_NONE;
|
||||
|
||||
if (error == NULL)
|
||||
return DWARF_E_ERROR;
|
||||
|
||||
if (a == NULL) {
|
||||
DWARF_SET_ERROR(error, DWARF_E_ARGUMENT);
|
||||
return DWARF_E_ARGUMENT;
|
||||
}
|
||||
|
||||
if ((at = malloc(sizeof(struct _Dwarf_Attribute))) == NULL) {
|
||||
DWARF_SET_ERROR(error, DWARF_E_MEMORY);
|
||||
return DWARF_E_MEMORY;
|
||||
}
|
||||
|
||||
/* Initialise the attribute structure. */
|
||||
at->at_attrib = attr;
|
||||
at->at_form = form;
|
||||
|
||||
/* Add the attribute to the list in the abbrev. */
|
||||
STAILQ_INSERT_TAIL(&a->a_attrib, at, at_next);
|
||||
|
||||
if (atp != NULL)
|
||||
*atp = at;
|
||||
|
||||
return ret;
|
||||
}
|
@ -1,271 +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 <unistd.h>
|
||||
#include "_libdwarf.h"
|
||||
|
||||
Dwarf_AttrValue
|
||||
dwarf_attrval_find(Dwarf_Die die, Dwarf_Half attr)
|
||||
{
|
||||
Dwarf_AttrValue av;
|
||||
|
||||
STAILQ_FOREACH(av, &die->die_attrval, av_next) {
|
||||
if (av->av_attrib == attr)
|
||||
break;
|
||||
}
|
||||
|
||||
return av;
|
||||
}
|
||||
|
||||
int
|
||||
dwarf_attrval_add(Dwarf_Die die, Dwarf_AttrValue avref, Dwarf_AttrValue *avp, Dwarf_Error *error)
|
||||
{
|
||||
Dwarf_AttrValue av;
|
||||
int ret = DWARF_E_NONE;
|
||||
|
||||
if ((av = malloc(sizeof(struct _Dwarf_AttrValue))) == NULL) {
|
||||
DWARF_SET_ERROR(error, DWARF_E_MEMORY);
|
||||
return DWARF_E_MEMORY;
|
||||
}
|
||||
|
||||
memcpy(av, avref, sizeof(struct _Dwarf_AttrValue));
|
||||
|
||||
/* Add the attribute value to the list in the die. */
|
||||
STAILQ_INSERT_TAIL(&die->die_attrval, av, av_next);
|
||||
|
||||
/* Save a pointer to the attribute name if this is one. */
|
||||
if (av->av_attrib == DW_AT_name)
|
||||
switch (av->av_form) {
|
||||
case DW_FORM_strp:
|
||||
die->die_name = av->u[1].s;
|
||||
break;
|
||||
case DW_FORM_string:
|
||||
die->die_name = av->u[0].s;
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
if (avp != NULL)
|
||||
*avp = av;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dwarf_attrval_flag(Dwarf_Die die, uint64_t attr, Dwarf_Bool *valp, Dwarf_Error *err)
|
||||
{
|
||||
Dwarf_AttrValue av;
|
||||
int ret = DWARF_E_NONE;
|
||||
|
||||
if (err == NULL)
|
||||
return DWARF_E_ERROR;
|
||||
|
||||
if (die == NULL || valp == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
|
||||
return DWARF_E_ARGUMENT;
|
||||
}
|
||||
|
||||
*valp = 0;
|
||||
|
||||
if ((av = dwarf_attrval_find(die, attr)) == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
|
||||
ret = DWARF_E_NO_ENTRY;
|
||||
} else {
|
||||
switch (av->av_form) {
|
||||
case DW_FORM_flag:
|
||||
case DW_FORM_flag_present:
|
||||
*valp = (Dwarf_Bool) av->u[0].u64;
|
||||
break;
|
||||
default:
|
||||
printf("%s(%d): av->av_form '%s' (0x%lx) not handled\n",
|
||||
__func__,__LINE__,get_form_desc(av->av_form),
|
||||
(u_long) av->av_form);
|
||||
DWARF_SET_ERROR(err, DWARF_E_BAD_FORM);
|
||||
ret = DWARF_E_BAD_FORM;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dwarf_attrval_string(Dwarf_Die die, uint64_t attr, const char **strp, Dwarf_Error *err)
|
||||
{
|
||||
Dwarf_AttrValue av;
|
||||
int ret = DWARF_E_NONE;
|
||||
|
||||
if (err == NULL)
|
||||
return DWARF_E_ERROR;
|
||||
|
||||
if (die == NULL || strp == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
|
||||
return DWARF_E_ARGUMENT;
|
||||
}
|
||||
|
||||
*strp = NULL;
|
||||
|
||||
if (attr == DW_AT_name)
|
||||
*strp = die->die_name;
|
||||
else if ((av = dwarf_attrval_find(die, attr)) == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
|
||||
ret = DWARF_E_NO_ENTRY;
|
||||
} else {
|
||||
switch (av->av_form) {
|
||||
case DW_FORM_strp:
|
||||
*strp = av->u[1].s;
|
||||
break;
|
||||
case DW_FORM_string:
|
||||
*strp = av->u[0].s;
|
||||
break;
|
||||
default:
|
||||
printf("%s(%d): av->av_form '%s' (0x%lx) not handled\n",
|
||||
__func__,__LINE__,get_form_desc(av->av_form),
|
||||
(u_long) av->av_form);
|
||||
DWARF_SET_ERROR(err, DWARF_E_BAD_FORM);
|
||||
ret = DWARF_E_BAD_FORM;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dwarf_attrval_signed(Dwarf_Die die, uint64_t attr, Dwarf_Signed *valp, Dwarf_Error *err)
|
||||
{
|
||||
Dwarf_AttrValue av;
|
||||
int ret = DWARF_E_NONE;
|
||||
|
||||
if (err == NULL)
|
||||
return DWARF_E_ERROR;
|
||||
|
||||
if (die == NULL || valp == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
|
||||
return DWARF_E_ARGUMENT;
|
||||
}
|
||||
|
||||
*valp = 0;
|
||||
|
||||
if ((av = dwarf_attrval_find(die, attr)) == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
|
||||
ret = DWARF_E_NO_ENTRY;
|
||||
} else {
|
||||
switch (av->av_form) {
|
||||
case DW_FORM_data1:
|
||||
case DW_FORM_sdata:
|
||||
*valp = av->u[0].s64;
|
||||
break;
|
||||
default:
|
||||
printf("%s(%d): av->av_form '%s' (0x%lx) not handled\n",
|
||||
__func__,__LINE__,get_form_desc(av->av_form),
|
||||
(u_long) av->av_form);
|
||||
DWARF_SET_ERROR(err, DWARF_E_BAD_FORM);
|
||||
ret = DWARF_E_BAD_FORM;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dwarf_attrval_unsigned(Dwarf_Die die, uint64_t attr, Dwarf_Unsigned *valp, Dwarf_Error *err)
|
||||
{
|
||||
Dwarf_AttrValue av;
|
||||
int ret = DWARF_E_NONE;
|
||||
|
||||
if (err == NULL)
|
||||
return DWARF_E_ERROR;
|
||||
|
||||
if (die == NULL || valp == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
|
||||
return DWARF_E_ARGUMENT;
|
||||
}
|
||||
|
||||
*valp = 0;
|
||||
|
||||
if ((av = dwarf_attrval_find(die, attr)) == NULL && attr != DW_AT_type) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
|
||||
ret = DWARF_E_NO_ENTRY;
|
||||
} else if (av == NULL && (av = dwarf_attrval_find(die,
|
||||
DW_AT_abstract_origin)) != NULL) {
|
||||
Dwarf_Die die1;
|
||||
Dwarf_Unsigned val;
|
||||
|
||||
switch (av->av_form) {
|
||||
case DW_FORM_data1:
|
||||
case DW_FORM_data2:
|
||||
case DW_FORM_data4:
|
||||
case DW_FORM_data8:
|
||||
case DW_FORM_ref1:
|
||||
case DW_FORM_ref2:
|
||||
case DW_FORM_ref4:
|
||||
case DW_FORM_ref8:
|
||||
case DW_FORM_ref_udata:
|
||||
val = av->u[0].u64;
|
||||
|
||||
if ((die1 = dwarf_die_find(die, val)) == NULL ||
|
||||
(av = dwarf_attrval_find(die1, attr)) == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
|
||||
ret = DWARF_E_NO_ENTRY;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
printf("%s(%d): av->av_form '%s' (0x%lx) not handled\n",
|
||||
__func__,__LINE__,get_form_desc(av->av_form),
|
||||
(u_long) av->av_form);
|
||||
DWARF_SET_ERROR(err, DWARF_E_BAD_FORM);
|
||||
ret = DWARF_E_BAD_FORM;
|
||||
}
|
||||
}
|
||||
|
||||
if (ret == DWARF_E_NONE) {
|
||||
switch (av->av_form) {
|
||||
case DW_FORM_data1:
|
||||
case DW_FORM_data2:
|
||||
case DW_FORM_data4:
|
||||
case DW_FORM_data8:
|
||||
case DW_FORM_ref1:
|
||||
case DW_FORM_ref2:
|
||||
case DW_FORM_ref4:
|
||||
case DW_FORM_ref8:
|
||||
case DW_FORM_ref_udata:
|
||||
*valp = av->u[0].u64;
|
||||
break;
|
||||
default:
|
||||
printf("%s(%d): av->av_form '%s' (0x%lx) not handled\n",
|
||||
__func__,__LINE__,get_form_desc(av->av_form),
|
||||
(u_long) av->av_form);
|
||||
DWARF_SET_ERROR(err, DWARF_E_BAD_FORM);
|
||||
ret = DWARF_E_BAD_FORM;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
@ -1,68 +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 "_libdwarf.h"
|
||||
|
||||
int
|
||||
dwarf_next_cu_header(Dwarf_Debug dbg, Dwarf_Unsigned *cu_header_length,
|
||||
Dwarf_Half *cu_version, Dwarf_Unsigned *cu_abbrev_offset,
|
||||
Dwarf_Half *cu_pointer_size, Dwarf_Unsigned *cu_next_offset, Dwarf_Error *error)
|
||||
{
|
||||
Dwarf_CU next;
|
||||
|
||||
if (error == NULL)
|
||||
return DWARF_E_ERROR;
|
||||
|
||||
if (dbg == NULL || cu_header_length == NULL || cu_version == NULL ||
|
||||
cu_abbrev_offset == NULL || cu_pointer_size == NULL ||
|
||||
cu_next_offset == NULL) {
|
||||
DWARF_SET_ERROR(error, DWARF_E_ARGUMENT);
|
||||
return DWARF_E_ERROR;
|
||||
}
|
||||
|
||||
if (dbg->dbg_cu_current == NULL)
|
||||
dbg->dbg_cu_current = STAILQ_FIRST(&dbg->dbg_cu);
|
||||
else if ((next = STAILQ_NEXT(dbg->dbg_cu_current, cu_next)) == NULL) {
|
||||
DWARF_SET_ERROR(error, DWARF_E_NO_ENTRY);
|
||||
return DWARF_E_NO_ENTRY;
|
||||
} else
|
||||
dbg->dbg_cu_current = next;
|
||||
|
||||
if (dbg->dbg_cu_current == NULL) {
|
||||
DWARF_SET_ERROR(error, DWARF_E_NO_ENTRY);
|
||||
return DWARF_E_NO_ENTRY;
|
||||
}
|
||||
|
||||
*cu_header_length = dbg->dbg_cu_current->cu_header_length;
|
||||
*cu_version = dbg->dbg_cu_current->cu_version;
|
||||
*cu_abbrev_offset = dbg->dbg_cu_current->cu_abbrev_offset;
|
||||
*cu_pointer_size = dbg->dbg_cu_current->cu_pointer_size;
|
||||
*cu_next_offset = dbg->dbg_cu_current->cu_next_offset;
|
||||
|
||||
return DWARF_E_NONE;
|
||||
}
|
@ -1,41 +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 "_libdwarf.h"
|
||||
|
||||
void
|
||||
dwarf_dealloc(Dwarf_Debug dbg __unused, Dwarf_Ptr p __unused, Dwarf_Unsigned alloc_type __unused)
|
||||
{
|
||||
/*
|
||||
* This libdwarf implementation doesn't use this style
|
||||
* of memory allocation. It doesn't copy things to return
|
||||
* them to the client, so the client doesn't need to
|
||||
* remember to free them.
|
||||
*/
|
||||
return;
|
||||
}
|
@ -1,189 +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 "_libdwarf.h"
|
||||
|
||||
int
|
||||
dwarf_die_add(Dwarf_CU cu, int level, uint64_t offset, uint64_t abnum, Dwarf_Abbrev a, Dwarf_Die *diep, Dwarf_Error *err)
|
||||
{
|
||||
Dwarf_Die die;
|
||||
uint64_t key;
|
||||
int ret = DWARF_E_NONE;
|
||||
|
||||
if (err == NULL)
|
||||
return DWARF_E_ERROR;
|
||||
|
||||
if (cu == NULL || a == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
|
||||
return DWARF_E_ARGUMENT;
|
||||
}
|
||||
|
||||
if ((die = malloc(sizeof(struct _Dwarf_Die))) == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_MEMORY);
|
||||
return DWARF_E_MEMORY;
|
||||
}
|
||||
|
||||
/* Initialise the abbrev structure. */
|
||||
die->die_level = level;
|
||||
die->die_offset = offset;
|
||||
die->die_abnum = abnum;
|
||||
die->die_a = a;
|
||||
die->die_cu = cu;
|
||||
die->die_name = "";
|
||||
|
||||
/* Initialise the list of attribute values. */
|
||||
STAILQ_INIT(&die->die_attrval);
|
||||
|
||||
/* Add the die to the list in the compilation unit. */
|
||||
STAILQ_INSERT_TAIL(&cu->cu_die, die, die_next);
|
||||
|
||||
/* Add the die to the hash table in the compilation unit. */
|
||||
key = offset % DWARF_DIE_HASH_SIZE;
|
||||
STAILQ_INSERT_TAIL(&cu->cu_die_hash[key], die, die_hash);
|
||||
|
||||
if (diep != NULL)
|
||||
*diep = die;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dwarf_dieoffset(Dwarf_Die die, Dwarf_Off *ret_offset, Dwarf_Error *err __unused)
|
||||
{
|
||||
*ret_offset = die->die_offset;
|
||||
|
||||
return DWARF_E_NONE;
|
||||
}
|
||||
|
||||
int
|
||||
dwarf_child(Dwarf_Die die, Dwarf_Die *ret_die, Dwarf_Error *err)
|
||||
{
|
||||
Dwarf_Die next;
|
||||
int ret = DWARF_E_NONE;
|
||||
|
||||
if (err == NULL)
|
||||
return DWARF_E_ERROR;
|
||||
|
||||
if (die == NULL || ret_die == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
|
||||
return DWARF_E_ARGUMENT;
|
||||
}
|
||||
|
||||
if ((next = STAILQ_NEXT(die, die_next)) == NULL ||
|
||||
next->die_level != die->die_level + 1) {
|
||||
*ret_die = NULL;
|
||||
DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
|
||||
ret = DWARF_E_NO_ENTRY;
|
||||
} else
|
||||
*ret_die = next;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dwarf_tag(Dwarf_Die die, Dwarf_Half *tag, Dwarf_Error *err)
|
||||
{
|
||||
Dwarf_Abbrev a;
|
||||
|
||||
if (err == NULL)
|
||||
return DWARF_E_ERROR;
|
||||
|
||||
if (die == NULL || tag == NULL || (a = die->die_a) == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
|
||||
return DWARF_E_ARGUMENT;
|
||||
}
|
||||
|
||||
*tag = a->a_tag;
|
||||
|
||||
return DWARF_E_NONE;
|
||||
}
|
||||
|
||||
int
|
||||
dwarf_siblingof(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Die *caller_ret_die, Dwarf_Error *err)
|
||||
{
|
||||
Dwarf_Die next;
|
||||
Dwarf_CU cu;
|
||||
int ret = DWARF_E_NONE;
|
||||
|
||||
if (err == NULL)
|
||||
return DWARF_E_ERROR;
|
||||
|
||||
if (dbg == NULL || caller_ret_die == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
|
||||
return DWARF_E_ARGUMENT;
|
||||
}
|
||||
|
||||
if ((cu = dbg->dbg_cu_current) == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_CU_CURRENT);
|
||||
return DWARF_E_CU_CURRENT;
|
||||
}
|
||||
|
||||
if (die == NULL) {
|
||||
*caller_ret_die = STAILQ_FIRST(&cu->cu_die);
|
||||
|
||||
if (*caller_ret_die == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
|
||||
ret = DWARF_E_NO_ENTRY;
|
||||
}
|
||||
} else {
|
||||
next = die;
|
||||
while ((next = STAILQ_NEXT(next, die_next)) != NULL) {
|
||||
if (next->die_level < die->die_level) {
|
||||
next = NULL;
|
||||
break;
|
||||
}
|
||||
if (next->die_level == die->die_level) {
|
||||
*caller_ret_die = next;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (next == NULL) {
|
||||
*caller_ret_die = NULL;
|
||||
DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
|
||||
ret = DWARF_E_NO_ENTRY;
|
||||
}
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
Dwarf_Die
|
||||
dwarf_die_find(Dwarf_Die die, Dwarf_Unsigned off)
|
||||
{
|
||||
Dwarf_CU cu = die->die_cu;
|
||||
Dwarf_Die die1;
|
||||
|
||||
STAILQ_FOREACH(die1, &cu->cu_die, die_next) {
|
||||
if (die1->die_offset == off)
|
||||
return (die1);
|
||||
}
|
||||
|
||||
return (NULL);
|
||||
}
|
@ -1,895 +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"
|
||||
|
||||
const char *
|
||||
get_sht_desc(uint32_t sh_type)
|
||||
{
|
||||
switch (sh_type) {
|
||||
case SHT_NULL:
|
||||
return "inactive";
|
||||
case SHT_PROGBITS:
|
||||
return "program defined information";
|
||||
case SHT_SYMTAB:
|
||||
return "symbol table section";
|
||||
case SHT_STRTAB:
|
||||
return "string table section";
|
||||
case SHT_RELA:
|
||||
return "relocation section with addends";
|
||||
case SHT_HASH:
|
||||
return "symbol hash table section";
|
||||
case SHT_DYNAMIC:
|
||||
return "dynamic section";
|
||||
case SHT_NOTE:
|
||||
return "note section";
|
||||
case SHT_NOBITS:
|
||||
return "no space section";
|
||||
case SHT_REL:
|
||||
return "relocation section - no addends";
|
||||
case SHT_SHLIB:
|
||||
return "reserved - purpose unknown";
|
||||
case SHT_DYNSYM:
|
||||
return "dynamic symbol table section";
|
||||
case SHT_INIT_ARRAY:
|
||||
return "Initialization function pointers.";
|
||||
case SHT_FINI_ARRAY:
|
||||
return "Termination function pointers.";
|
||||
case SHT_PREINIT_ARRAY:
|
||||
return "Pre-initialization function ptrs.";
|
||||
case SHT_GROUP:
|
||||
return "Section group.";
|
||||
case SHT_SYMTAB_SHNDX:
|
||||
return "Section indexes (see SHN_XINDEX).";
|
||||
case SHT_GNU_verdef:
|
||||
return "Symbol versions provided";
|
||||
case SHT_GNU_verneed:
|
||||
return "Symbol versions required";
|
||||
case SHT_GNU_versym:
|
||||
return "Symbol version table";
|
||||
case SHT_AMD64_UNWIND:
|
||||
return "AMD64 unwind";
|
||||
default:
|
||||
return "Unknown";
|
||||
}
|
||||
}
|
||||
|
||||
const char *
|
||||
get_attr_desc(uint32_t attr)
|
||||
{
|
||||
switch (attr) {
|
||||
case DW_AT_abstract_origin:
|
||||
return "DW_AT_abstract_origin";
|
||||
case DW_AT_accessibility:
|
||||
return "DW_AT_accessibility";
|
||||
case DW_AT_address_class:
|
||||
return "DW_AT_address_class";
|
||||
case DW_AT_artificial:
|
||||
return "DW_AT_artificial";
|
||||
case DW_AT_base_types:
|
||||
return "DW_AT_base_types";
|
||||
case DW_AT_bit_offset:
|
||||
return "DW_AT_bit_offset";
|
||||
case DW_AT_bit_size:
|
||||
return "DW_AT_bit_size";
|
||||
case DW_AT_byte_size:
|
||||
return "DW_AT_byte_size";
|
||||
case DW_AT_calling_convention:
|
||||
return "DW_AT_calling_convention";
|
||||
case DW_AT_common_reference:
|
||||
return "DW_AT_common_reference";
|
||||
case DW_AT_comp_dir:
|
||||
return "DW_AT_comp_dir";
|
||||
case DW_AT_const_value:
|
||||
return "DW_AT_const_value";
|
||||
case DW_AT_containing_type:
|
||||
return "DW_AT_containing_type";
|
||||
case DW_AT_count:
|
||||
return "DW_AT_count";
|
||||
case DW_AT_data_member_location:
|
||||
return "DW_AT_data_member_location";
|
||||
case DW_AT_decl_column:
|
||||
return "DW_AT_decl_column";
|
||||
case DW_AT_decl_file:
|
||||
return "DW_AT_decl_file";
|
||||
case DW_AT_decl_line:
|
||||
return "DW_AT_decl_line";
|
||||
case DW_AT_declaration:
|
||||
return "DW_AT_declaration";
|
||||
case DW_AT_default_value:
|
||||
return "DW_AT_default_value";
|
||||
case DW_AT_discr:
|
||||
return "DW_AT_discr";
|
||||
case DW_AT_discr_list:
|
||||
return "DW_AT_discr_list";
|
||||
case DW_AT_discr_value:
|
||||
return "DW_AT_discr_value";
|
||||
case DW_AT_element_list:
|
||||
return "DW_AT_element_list";
|
||||
case DW_AT_encoding:
|
||||
return "DW_AT_encoding";
|
||||
case DW_AT_external:
|
||||
return "DW_AT_external";
|
||||
case DW_AT_frame_base:
|
||||
return "DW_AT_frame_base";
|
||||
case DW_AT_friend:
|
||||
return "DW_AT_friend";
|
||||
case DW_AT_high_pc:
|
||||
return "DW_AT_high_pc";
|
||||
case DW_AT_identifier_case:
|
||||
return "DW_AT_identifier_case";
|
||||
case DW_AT_import:
|
||||
return "DW_AT_import";
|
||||
case DW_AT_inline:
|
||||
return "DW_AT_inline";
|
||||
case DW_AT_is_optional:
|
||||
return "DW_AT_is_optional";
|
||||
case DW_AT_language:
|
||||
return "DW_AT_language";
|
||||
case DW_AT_location:
|
||||
return "DW_AT_location";
|
||||
case DW_AT_low_pc:
|
||||
return "DW_AT_low_pc";
|
||||
case DW_AT_lower_bound:
|
||||
return "DW_AT_lower_bound";
|
||||
case DW_AT_macro_info:
|
||||
return "DW_AT_macro_info";
|
||||
case DW_AT_member:
|
||||
return "DW_AT_member";
|
||||
case DW_AT_name:
|
||||
return "DW_AT_name";
|
||||
case DW_AT_namelist_item:
|
||||
return "DW_AT_namelist_item";
|
||||
case DW_AT_ordering:
|
||||
return "DW_AT_ordering";
|
||||
case DW_AT_priority:
|
||||
return "DW_AT_priority";
|
||||
case DW_AT_producer:
|
||||
return "DW_AT_producer";
|
||||
case DW_AT_prototyped:
|
||||
return "DW_AT_prototyped";
|
||||
case DW_AT_return_addr:
|
||||
return "DW_AT_return_addr";
|
||||
case DW_AT_segment:
|
||||
return "DW_AT_segment";
|
||||
case DW_AT_sibling:
|
||||
return "DW_AT_sibling";
|
||||
case DW_AT_specification:
|
||||
return "DW_AT_specification";
|
||||
case DW_AT_start_scope:
|
||||
return "DW_AT_start_scope";
|
||||
case DW_AT_static_link:
|
||||
return "DW_AT_static_link";
|
||||
case DW_AT_stmt_list:
|
||||
return "DW_AT_stmt_list";
|
||||
case DW_AT_stride_size:
|
||||
return "DW_AT_stride_size";
|
||||
case DW_AT_string_length:
|
||||
return "DW_AT_string_length";
|
||||
case DW_AT_subscr_data:
|
||||
return "DW_AT_subscr_data";
|
||||
case DW_AT_type:
|
||||
return "DW_AT_type";
|
||||
case DW_AT_upper_bound:
|
||||
return "DW_AT_upper_bound";
|
||||
case DW_AT_use_location:
|
||||
return "DW_AT_use_location";
|
||||
case DW_AT_variable_parameter:
|
||||
return "DW_AT_variable_parameter";
|
||||
case DW_AT_virtuality:
|
||||
return "DW_AT_virtuality";
|
||||
case DW_AT_visibility:
|
||||
return "DW_AT_visibility";
|
||||
case DW_AT_vtable_elem_location:
|
||||
return "DW_AT_vtable_elem_location";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "Unknown attribute";
|
||||
}
|
||||
|
||||
const char *
|
||||
get_form_desc(uint32_t form)
|
||||
{
|
||||
switch (form) {
|
||||
case DW_FORM_addr:
|
||||
return "DW_FORM_addr";
|
||||
case DW_FORM_block:
|
||||
return "DW_FORM_block";
|
||||
case DW_FORM_block1:
|
||||
return "DW_FORM_block1";
|
||||
case DW_FORM_block2:
|
||||
return "DW_FORM_block2";
|
||||
case DW_FORM_block4:
|
||||
return "DW_FORM_block4";
|
||||
case DW_FORM_data1:
|
||||
return "DW_FORM_data1";
|
||||
case DW_FORM_data2:
|
||||
return "DW_FORM_data2";
|
||||
case DW_FORM_data4:
|
||||
return "DW_FORM_data4";
|
||||
case DW_FORM_data8:
|
||||
return "DW_FORM_data8";
|
||||
case DW_FORM_flag:
|
||||
return "DW_FORM_flag";
|
||||
case DW_FORM_flag_present:
|
||||
return "DW_FORM_flag_present";
|
||||
case DW_FORM_indirect:
|
||||
return "DW_FORM_indirect";
|
||||
case DW_FORM_ref1:
|
||||
return "DW_FORM_ref1";
|
||||
case DW_FORM_ref2:
|
||||
return "DW_FORM_ref2";
|
||||
case DW_FORM_ref4:
|
||||
return "DW_FORM_ref4";
|
||||
case DW_FORM_ref8:
|
||||
return "DW_FORM_ref8";
|
||||
case DW_FORM_ref_addr:
|
||||
return "DW_FORM_ref_addr";
|
||||
case DW_FORM_ref_udata:
|
||||
return "DW_FORM_ref_udata";
|
||||
case DW_FORM_sdata:
|
||||
return "DW_FORM_sdata";
|
||||
case DW_FORM_string:
|
||||
return "DW_FORM_string";
|
||||
case DW_FORM_strp:
|
||||
return "DW_FORM_strp";
|
||||
case DW_FORM_udata:
|
||||
return "DW_FORM_udata";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "Unknown attribute";
|
||||
}
|
||||
|
||||
const char *
|
||||
get_tag_desc(uint32_t tag)
|
||||
{
|
||||
switch (tag) {
|
||||
case DW_TAG_access_declaration:
|
||||
return "DW_TAG_access_declaration";
|
||||
case DW_TAG_array_type:
|
||||
return "DW_TAG_array_type";
|
||||
case DW_TAG_base_type:
|
||||
return "DW_TAG_base_type";
|
||||
case DW_TAG_catch_block:
|
||||
return "DW_TAG_catch_block";
|
||||
case DW_TAG_class_type:
|
||||
return "DW_TAG_class_type";
|
||||
case DW_TAG_common_block:
|
||||
return "DW_TAG_common_block";
|
||||
case DW_TAG_common_inclusion:
|
||||
return "DW_TAG_common_inclusion";
|
||||
case DW_TAG_compile_unit:
|
||||
return "DW_TAG_compile_unit";
|
||||
case DW_TAG_condition:
|
||||
return "DW_TAG_condition";
|
||||
case DW_TAG_const_type:
|
||||
return "DW_TAG_const_type";
|
||||
case DW_TAG_constant:
|
||||
return "DW_TAG_constant";
|
||||
case DW_TAG_dwarf_procedure:
|
||||
return "DW_TAG_dwarf_procedure";
|
||||
case DW_TAG_entry_point:
|
||||
return "DW_TAG_entry_point";
|
||||
case DW_TAG_enumeration_type:
|
||||
return "DW_TAG_enumeration_type";
|
||||
case DW_TAG_enumerator:
|
||||
return "DW_TAG_enumerator";
|
||||
case DW_TAG_formal_parameter:
|
||||
return "DW_TAG_formal_parameter";
|
||||
case DW_TAG_friend:
|
||||
return "DW_TAG_friend";
|
||||
case DW_TAG_imported_declaration:
|
||||
return "DW_TAG_imported_declaration";
|
||||
case DW_TAG_imported_module:
|
||||
return "DW_TAG_imported_module";
|
||||
case DW_TAG_imported_unit:
|
||||
return "DW_TAG_imported_unit";
|
||||
case DW_TAG_inheritance:
|
||||
return "DW_TAG_inheritance";
|
||||
case DW_TAG_inlined_subroutine:
|
||||
return "DW_TAG_inlined_subroutine";
|
||||
case DW_TAG_interface_type:
|
||||
return "DW_TAG_interface_type";
|
||||
case DW_TAG_label:
|
||||
return "DW_TAG_label";
|
||||
case DW_TAG_lexical_block:
|
||||
return "DW_TAG_lexical_block";
|
||||
case DW_TAG_member:
|
||||
return "DW_TAG_member";
|
||||
case DW_TAG_module:
|
||||
return "DW_TAG_module";
|
||||
case DW_TAG_namelist:
|
||||
return "DW_TAG_namelist";
|
||||
case DW_TAG_namelist_item:
|
||||
return "DW_TAG_namelist_item";
|
||||
case DW_TAG_namespace:
|
||||
return "DW_TAG_namespace";
|
||||
case DW_TAG_packed_type:
|
||||
return "DW_TAG_packed_type";
|
||||
case DW_TAG_partial_unit:
|
||||
return "DW_TAG_partial_unit";
|
||||
case DW_TAG_pointer_type:
|
||||
return "DW_TAG_pointer_type";
|
||||
case DW_TAG_ptr_to_member_type:
|
||||
return "DW_TAG_ptr_to_member_type";
|
||||
case DW_TAG_reference_type:
|
||||
return "DW_TAG_reference_type";
|
||||
case DW_TAG_restrict_type:
|
||||
return "DW_TAG_restrict_type";
|
||||
case DW_TAG_set_type:
|
||||
return "DW_TAG_set_type";
|
||||
case DW_TAG_shared_type:
|
||||
return "DW_TAG_shared_type";
|
||||
case DW_TAG_string_type:
|
||||
return "DW_TAG_string_type";
|
||||
case DW_TAG_structure_type:
|
||||
return "DW_TAG_structure_type";
|
||||
case DW_TAG_subprogram:
|
||||
return "DW_TAG_subprogram";
|
||||
case DW_TAG_subrange_type:
|
||||
return "DW_TAG_subrange_type";
|
||||
case DW_TAG_subroutine_type:
|
||||
return "DW_TAG_subroutine_type";
|
||||
case DW_TAG_template_type_parameter:
|
||||
return "DW_TAG_template_type_parameter";
|
||||
case DW_TAG_template_value_parameter:
|
||||
return "DW_TAG_template_value_parameter";
|
||||
case DW_TAG_thrown_type:
|
||||
return "DW_TAG_thrown_type";
|
||||
case DW_TAG_try_block:
|
||||
return "DW_TAG_try_block";
|
||||
case DW_TAG_typedef:
|
||||
return "DW_TAG_typedef";
|
||||
case DW_TAG_union_type:
|
||||
return "DW_TAG_union_type";
|
||||
case DW_TAG_unspecified_parameters:
|
||||
return "DW_TAG_unspecified_parameters";
|
||||
case DW_TAG_unspecified_type:
|
||||
return "DW_TAG_unspecified_type";
|
||||
case DW_TAG_variable:
|
||||
return "DW_TAG_variable";
|
||||
case DW_TAG_variant:
|
||||
return "DW_TAG_variant";
|
||||
case DW_TAG_variant_part:
|
||||
return "DW_TAG_variant_part";
|
||||
case DW_TAG_volatile_type:
|
||||
return "DW_TAG_volatile_type";
|
||||
case DW_TAG_with_stmt:
|
||||
return "DW_TAG_with_stmt";
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
return "Unknown tag";
|
||||
}
|
||||
|
||||
void
|
||||
dwarf_dump_abbrev(Dwarf_Debug dbg)
|
||||
{
|
||||
Dwarf_Abbrev a;
|
||||
Dwarf_Attribute at;
|
||||
Dwarf_CU cu;
|
||||
|
||||
printf("Contents of the .debug_abbrev section:\n\nEntry Tag\n");
|
||||
|
||||
STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
|
||||
STAILQ_FOREACH(a, &cu->cu_abbrev, a_next) {
|
||||
printf("%5lu %-30s [%s children]\n",
|
||||
(u_long) a->a_entry, get_tag_desc(a->a_tag),
|
||||
(a->a_children == DW_CHILDREN_yes) ? "has" : "no");
|
||||
|
||||
STAILQ_FOREACH(at, &a->a_attrib, at_next)
|
||||
printf(" %-30s %s\n", get_attr_desc(at->at_attrib),
|
||||
get_form_desc(at->at_form));
|
||||
}
|
||||
}
|
||||
}
|
||||
#ifdef DOODAD
|
||||
case DW_AT_inline:
|
||||
switch (uvalue)
|
||||
{
|
||||
case DW_INL_not_inlined:
|
||||
printf (_("(not inlined)"));
|
||||
break;
|
||||
case DW_INL_inlined:
|
||||
printf (_("(inlined)"));
|
||||
break;
|
||||
case DW_INL_declared_not_inlined:
|
||||
printf (_("(declared as inline but ignored)"));
|
||||
break;
|
||||
case DW_INL_declared_inlined:
|
||||
printf (_("(declared as inline and inlined)"));
|
||||
break;
|
||||
default:
|
||||
printf (_(" (Unknown inline attribute value: %lx)"), uvalue);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case DW_AT_language:
|
||||
switch (uvalue)
|
||||
{
|
||||
case DW_LANG_C: printf ("(non-ANSI C)"); break;
|
||||
case DW_LANG_C89: printf ("(ANSI C)"); break;
|
||||
case DW_LANG_C_plus_plus: printf ("(C++)"); break;
|
||||
case DW_LANG_Fortran77: printf ("(FORTRAN 77)"); break;
|
||||
case DW_LANG_Fortran90: printf ("(Fortran 90)"); break;
|
||||
case DW_LANG_Modula2: printf ("(Modula 2)"); break;
|
||||
case DW_LANG_Pascal83: printf ("(ANSI Pascal)"); break;
|
||||
case DW_LANG_Ada83: printf ("(Ada)"); break;
|
||||
case DW_LANG_Cobol74: printf ("(Cobol 74)"); break;
|
||||
case DW_LANG_Cobol85: printf ("(Cobol 85)"); break;
|
||||
/* DWARF 2.1 values. */
|
||||
case DW_LANG_C99: printf ("(ANSI C99)"); break;
|
||||
case DW_LANG_Ada95: printf ("(ADA 95)"); break;
|
||||
case DW_LANG_Fortran95: printf ("(Fortran 95)"); break;
|
||||
/* MIPS extension. */
|
||||
case DW_LANG_Mips_Assembler: printf ("(MIPS assembler)"); break;
|
||||
/* UPC extension. */
|
||||
case DW_LANG_Upc: printf ("(Unified Parallel C)"); break;
|
||||
default:
|
||||
printf ("(Unknown: %lx)", uvalue);
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case DW_AT_encoding:
|
||||
switch (uvalue)
|
||||
{
|
||||
case DW_ATE_void: printf ("(void)"); break;
|
||||
case DW_ATE_address: printf ("(machine address)"); break;
|
||||
case DW_ATE_boolean: printf ("(boolean)"); break;
|
||||
case DW_ATE_complex_float: printf ("(complex float)"); break;
|
||||
case DW_ATE_float: printf ("(float)"); break;
|
||||
case DW_ATE_signed: printf ("(signed)"); break;
|
||||
case DW_ATE_signed_char: printf ("(signed char)"); break;
|
||||
case DW_ATE_unsigned: printf ("(unsigned)"); break;
|
||||
case DW_ATE_unsigned_char: printf ("(unsigned char)"); break;
|
||||
/* DWARF 2.1 value. */
|
||||
case DW_ATE_imaginary_float: printf ("(imaginary float)"); break;
|
||||
default:
|
||||
if (uvalue >= DW_ATE_lo_user
|
||||
&& uvalue <= DW_ATE_hi_user)
|
||||
printf ("(user defined type)");
|
||||
else
|
||||
printf ("(unknown type)");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case DW_AT_accessibility:
|
||||
switch (uvalue)
|
||||
{
|
||||
case DW_ACCESS_public: printf ("(public)"); break;
|
||||
case DW_ACCESS_protected: printf ("(protected)"); break;
|
||||
case DW_ACCESS_private: printf ("(private)"); break;
|
||||
default:
|
||||
printf ("(unknown accessibility)");
|
||||
break;
|
||||
}
|
||||
break;
|
||||
|
||||
case DW_AT_visibility:
|
||||
switch (uvalue)
|
||||
{
|
||||
case DW_VIS_local: printf ("(local)"); break;
|
||||
case DW_VIS_exported: printf ("(exported)"); break;
|
||||
case DW_VIS_qualified: printf ("(qualified)"); break;
|
||||
default: printf ("(unknown visibility)"); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case DW_AT_virtuality:
|
||||
switch (uvalue)
|
||||
{
|
||||
case DW_VIRTUALITY_none: printf ("(none)"); break;
|
||||
case DW_VIRTUALITY_virtual: printf ("(virtual)"); break;
|
||||
case DW_VIRTUALITY_pure_virtual:printf ("(pure_virtual)"); break;
|
||||
default: printf ("(unknown virtuality)"); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case DW_AT_identifier_case:
|
||||
switch (uvalue)
|
||||
{
|
||||
case DW_ID_case_sensitive: printf ("(case_sensitive)"); break;
|
||||
case DW_ID_up_case: printf ("(up_case)"); break;
|
||||
case DW_ID_down_case: printf ("(down_case)"); break;
|
||||
case DW_ID_case_insensitive: printf ("(case_insensitive)"); break;
|
||||
default: printf ("(unknown case)"); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case DW_AT_calling_convention:
|
||||
switch (uvalue)
|
||||
{
|
||||
case DW_CC_normal: printf ("(normal)"); break;
|
||||
case DW_CC_program: printf ("(program)"); break;
|
||||
case DW_CC_nocall: printf ("(nocall)"); break;
|
||||
default:
|
||||
if (uvalue >= DW_CC_lo_user
|
||||
&& uvalue <= DW_CC_hi_user)
|
||||
printf ("(user defined)");
|
||||
else
|
||||
printf ("(unknown convention)");
|
||||
}
|
||||
break;
|
||||
|
||||
case DW_AT_ordering:
|
||||
switch (uvalue)
|
||||
{
|
||||
case -1: printf ("(undefined)"); break;
|
||||
case 0: printf ("(row major)"); break;
|
||||
case 1: printf ("(column major)"); break;
|
||||
}
|
||||
break;
|
||||
|
||||
case DW_AT_frame_base:
|
||||
case DW_AT_location:
|
||||
case DW_AT_data_member_location:
|
||||
case DW_AT_vtable_elem_location:
|
||||
case DW_AT_allocated:
|
||||
case DW_AT_associated:
|
||||
case DW_AT_data_location:
|
||||
case DW_AT_stride:
|
||||
case DW_AT_upper_bound:
|
||||
case DW_AT_lower_bound:
|
||||
if (block_start)
|
||||
{
|
||||
printf ("(");
|
||||
decode_location_expression (block_start, pointer_size, uvalue);
|
||||
printf (")");
|
||||
}
|
||||
else if (form == DW_FORM_data4 || form == DW_FORM_data8)
|
||||
{
|
||||
printf ("(");
|
||||
printf ("location list");
|
||||
printf (")");
|
||||
}
|
||||
break;
|
||||
#endif
|
||||
|
||||
static void
|
||||
dwarf_dump_av_attr(Dwarf_Die die __unused, Dwarf_AttrValue av)
|
||||
{
|
||||
switch (av->av_attrib) {
|
||||
case DW_AT_accessibility:
|
||||
break;
|
||||
|
||||
case DW_AT_calling_convention:
|
||||
break;
|
||||
|
||||
case DW_AT_encoding:
|
||||
break;
|
||||
|
||||
case DW_AT_identifier_case:
|
||||
break;
|
||||
|
||||
case DW_AT_inline:
|
||||
break;
|
||||
|
||||
case DW_AT_language:
|
||||
break;
|
||||
|
||||
case DW_AT_ordering:
|
||||
break;
|
||||
|
||||
case DW_AT_virtuality:
|
||||
break;
|
||||
|
||||
case DW_AT_visibility:
|
||||
break;
|
||||
|
||||
case DW_AT_frame_base:
|
||||
case DW_AT_location:
|
||||
case DW_AT_data_member_location:
|
||||
case DW_AT_vtable_elem_location:
|
||||
case DW_AT_upper_bound:
|
||||
case DW_AT_lower_bound:
|
||||
break;
|
||||
|
||||
default:
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dwarf_dump_av(Dwarf_Die die, Dwarf_AttrValue av)
|
||||
{
|
||||
uint64_t i;
|
||||
|
||||
printf(" %-30s : %-16s ",
|
||||
get_attr_desc(av->av_attrib),
|
||||
get_form_desc(av->av_form));
|
||||
|
||||
switch (av->av_form) {
|
||||
case DW_FORM_addr:
|
||||
printf("0x%llx", (unsigned long long) av->u[0].u64);
|
||||
break;
|
||||
case DW_FORM_block:
|
||||
case DW_FORM_block1:
|
||||
case DW_FORM_block2:
|
||||
case DW_FORM_block4:
|
||||
printf("%lu byte block:", (u_long) av->u[0].u64);
|
||||
for (i = 0; i < av->u[0].u64; i++)
|
||||
printf(" %02x", av->u[1].u8p[i]);
|
||||
break;
|
||||
case DW_FORM_data1:
|
||||
case DW_FORM_data2:
|
||||
case DW_FORM_data4:
|
||||
case DW_FORM_data8:
|
||||
case DW_FORM_flag:
|
||||
case DW_FORM_flag_present:
|
||||
printf("%llu", (unsigned long long) av->u[0].u64);
|
||||
break;
|
||||
case DW_FORM_ref1:
|
||||
case DW_FORM_ref2:
|
||||
case DW_FORM_ref4:
|
||||
case DW_FORM_ref8:
|
||||
case DW_FORM_ref_udata:
|
||||
printf("<%llx>", (unsigned long long) (av->u[0].u64 +
|
||||
die->die_cu->cu_offset));
|
||||
break;
|
||||
case DW_FORM_string:
|
||||
printf("%s", av->u[0].s);
|
||||
break;
|
||||
case DW_FORM_strp:
|
||||
printf("(indirect string, offset 0x%llx): %s",
|
||||
(unsigned long long) av->u[0].u64, av->u[1].s);
|
||||
break;
|
||||
default:
|
||||
printf("unknown form");
|
||||
break;
|
||||
}
|
||||
|
||||
/* Dump any extra attribute-specific information. */
|
||||
dwarf_dump_av_attr(die, av);
|
||||
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
void
|
||||
dwarf_dump_die_at_offset(Dwarf_Debug dbg, Dwarf_Off off)
|
||||
{
|
||||
Dwarf_CU cu;
|
||||
Dwarf_Die die;
|
||||
|
||||
if (dbg == NULL)
|
||||
return;
|
||||
|
||||
STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
|
||||
STAILQ_FOREACH(die, &cu->cu_die, die_next) {
|
||||
if ((off_t) die->die_offset == off) {
|
||||
dwarf_dump_die(die);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dwarf_dump_die(Dwarf_Die die)
|
||||
{
|
||||
Dwarf_AttrValue av;
|
||||
|
||||
printf("<%d><%llx>: Abbrev number: %llu (%s)\n",
|
||||
die->die_level, (unsigned long long) die->die_offset,
|
||||
(unsigned long long) die->die_abnum,
|
||||
get_tag_desc(die->die_a->a_tag));
|
||||
|
||||
STAILQ_FOREACH(av, &die->die_attrval, av_next)
|
||||
dwarf_dump_av(die, av);
|
||||
}
|
||||
|
||||
void
|
||||
dwarf_dump_raw(Dwarf_Debug dbg)
|
||||
{
|
||||
Dwarf_CU cu;
|
||||
char *p = (char *) dbg;
|
||||
int i;
|
||||
|
||||
printf("dbg %p\n",dbg);
|
||||
|
||||
if (dbg == NULL)
|
||||
return;
|
||||
|
||||
for (i = 0; i < (int) sizeof(*dbg); i++) {
|
||||
if (*p >= 0x20 && *p < 0x7f) {
|
||||
printf(" %c",*p++ & 0xff);
|
||||
} else {
|
||||
printf(" %02x",*p++ & 0xff);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
|
||||
STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
|
||||
p = (char *) cu;
|
||||
printf("cu %p\n",cu);
|
||||
for (i = 0; i < (int) sizeof(*cu); i++) {
|
||||
if (*p >= 0x20 && *p < 0x7f) {
|
||||
printf(" %c",*p++ & 0xff);
|
||||
} else {
|
||||
printf(" %02x",*p++ & 0xff);
|
||||
}
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
}
|
||||
|
||||
static void
|
||||
dwarf_dump_tree_dies(Dwarf_Debug dbg, Dwarf_Die die, Dwarf_Error *error)
|
||||
{
|
||||
Dwarf_Die child;
|
||||
int ret;
|
||||
|
||||
do {
|
||||
dwarf_dump_die(die);
|
||||
|
||||
if ((ret = dwarf_child(die, &child, error) == DWARF_E_NO_ENTRY)) {
|
||||
/* No children. */
|
||||
} else if (ret != DWARF_E_NONE) {
|
||||
printf("Error %s\n", dwarf_errmsg(error));
|
||||
return;
|
||||
} else
|
||||
dwarf_dump_tree_dies(dbg, child, error);
|
||||
|
||||
if (dwarf_siblingof(dbg, die, &die, error) != DWARF_E_NONE)
|
||||
die = NULL;
|
||||
|
||||
} while (die != NULL);
|
||||
}
|
||||
|
||||
void
|
||||
dwarf_dump_tree(Dwarf_Debug dbg)
|
||||
{
|
||||
Dwarf_CU cu;
|
||||
Dwarf_Die die;
|
||||
Dwarf_Error error;
|
||||
Dwarf_Half cu_pointer_size;
|
||||
Dwarf_Half cu_version;
|
||||
Dwarf_Unsigned cu_abbrev_offset;
|
||||
Dwarf_Unsigned cu_header_length;
|
||||
Dwarf_Unsigned cu_next_offset;
|
||||
|
||||
STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
|
||||
printf ("\nCompilation Unit @ offset %llx:\n",
|
||||
(unsigned long long) cu->cu_offset);
|
||||
printf (" Length: %lu\n", (u_long) cu->cu_length);
|
||||
printf (" Version: %hu\n", cu->cu_version);
|
||||
printf (" Abbrev Offset: %lu\n", (u_long) cu->cu_abbrev_offset);
|
||||
printf (" Pointer Size: %u\n", (u_int) cu->cu_pointer_size);
|
||||
|
||||
if (dwarf_next_cu_header(dbg, &cu_header_length,
|
||||
&cu_version, &cu_abbrev_offset, &cu_pointer_size,
|
||||
&cu_next_offset, &error) != DWARF_E_NONE) {
|
||||
printf("Error %s\n", dwarf_errmsg(&error));
|
||||
return;
|
||||
}
|
||||
|
||||
if (dwarf_siblingof(dbg, NULL, &die, &error) != DWARF_E_NONE) {
|
||||
printf("Error %s\n", dwarf_errmsg(&error));
|
||||
return;
|
||||
}
|
||||
|
||||
dwarf_dump_tree_dies(dbg, die, &error);
|
||||
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dwarf_dump_info(Dwarf_Debug dbg)
|
||||
{
|
||||
Dwarf_CU cu;
|
||||
Dwarf_Die die;
|
||||
|
||||
printf("Contents of the .debug_info section:\n");
|
||||
|
||||
STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
|
||||
printf ("\nCompilation Unit @ offset %llx:\n",
|
||||
(unsigned long long) cu->cu_offset);
|
||||
printf (" Length: %lu\n", (u_long) cu->cu_length);
|
||||
printf (" Version: %hu\n", cu->cu_version);
|
||||
printf (" Abbrev Offset: %lu\n", (u_long) cu->cu_abbrev_offset);
|
||||
printf (" Pointer Size: %u\n", (u_int) cu->cu_pointer_size);
|
||||
|
||||
STAILQ_FOREACH(die, &cu->cu_die, die_next)
|
||||
dwarf_dump_die(die);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
void
|
||||
dwarf_dump_shstrtab(Dwarf_Debug dbg)
|
||||
{
|
||||
char *name;
|
||||
int indx = 0;
|
||||
|
||||
printf("---------------------\nSection header string table contents:\n");
|
||||
while ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_stnum, indx)) != NULL) {
|
||||
printf("%5d '%s'\n",indx,name);
|
||||
indx += strlen(name) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dwarf_dump_strtab(Dwarf_Debug dbg)
|
||||
{
|
||||
char *name;
|
||||
int indx = 0;
|
||||
|
||||
printf("---------------------\nString table contents:\n");
|
||||
while ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_s[DWARF_strtab].s_shnum, indx)) != NULL) {
|
||||
printf("%5d '%s'\n",indx,name);
|
||||
indx += strlen(name) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dwarf_dump_dbgstr(Dwarf_Debug dbg)
|
||||
{
|
||||
char *name;
|
||||
int indx = 0;
|
||||
|
||||
printf("---------------------\nDebug string table contents:\n");
|
||||
while ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_s[DWARF_debug_str].s_shnum, indx)) != NULL) {
|
||||
printf("%5d '%s'\n",indx,name);
|
||||
indx += strlen(name) + 1;
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dwarf_dump_symtab(Dwarf_Debug dbg)
|
||||
{
|
||||
GElf_Sym sym;
|
||||
char *name;
|
||||
int indx = 0;
|
||||
|
||||
printf("---------------------\nSymbol table contents:\n");
|
||||
while (gelf_getsym(dbg->dbg_s[DWARF_symtab].s_data, indx++, &sym) != NULL) {
|
||||
if ((name = elf_strptr(dbg->dbg_elf, dbg->dbg_s[DWARF_strtab].s_shnum, sym.st_name)) == NULL)
|
||||
printf("sym.st_name %u indx %d sym.st_size %lu\n",sym.st_name,indx,(u_long) sym.st_size);
|
||||
else
|
||||
printf("'%s' sym.st_name %u indx %d sym.st_size %lu\n",name,sym.st_name,indx,(u_long) sym.st_size);
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dwarf_dump(Dwarf_Debug dbg)
|
||||
{
|
||||
dwarf_dump_strtab(dbg);
|
||||
dwarf_dump_shstrtab(dbg);
|
||||
dwarf_dump_dbgstr(dbg);
|
||||
dwarf_dump_symtab(dbg);
|
||||
dwarf_dump_info(dbg);
|
||||
}
|
@ -1,76 +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 <stdio.h>
|
||||
#include "_libdwarf.h"
|
||||
|
||||
static const char *_libdwarf_errors[] = {
|
||||
#define DEFINE_ERROR(N,S) [DWARF_E_##N] = S
|
||||
DEFINE_ERROR(NONE, "No Error"),
|
||||
DEFINE_ERROR(ERROR, "An error"),
|
||||
DEFINE_ERROR(NO_ENTRY, "No entry found"),
|
||||
DEFINE_ERROR(ARGUMENT, "Invalid argument"),
|
||||
DEFINE_ERROR(DEBUG_INFO, "Debug info NULL"),
|
||||
DEFINE_ERROR(MEMORY, "Insufficient memory"),
|
||||
DEFINE_ERROR(ELF, "ELF error"),
|
||||
DEFINE_ERROR(INVALID_CU, "Invalid compilation unit data"),
|
||||
DEFINE_ERROR(CU_VERSION, "Wrong CU version. Only 2 and 3 supported"),
|
||||
DEFINE_ERROR(MISSING_ABBREV, "Abbrev not found"),
|
||||
DEFINE_ERROR(NOT_IMPLEMENTED, "Unimplemented code at"),
|
||||
DEFINE_ERROR(CU_CURRENT, "No current compilation unit"),
|
||||
DEFINE_ERROR(BAD_FORM, "Wrong form type for attribute value"),
|
||||
DEFINE_ERROR(INVALID_EXPR, "Invalid DWARF expression"),
|
||||
DEFINE_ERROR(NUM, "Unknown DWARF error")
|
||||
#undef DEFINE_ERROR
|
||||
};
|
||||
|
||||
const char *
|
||||
dwarf_errmsg(Dwarf_Error *error)
|
||||
{
|
||||
const char *p;
|
||||
|
||||
if (error == NULL)
|
||||
return NULL;
|
||||
|
||||
if (error->err_error < 0 || error->err_error >= DWARF_E_NUM)
|
||||
return _libdwarf_errors[DWARF_E_NUM];
|
||||
else if (error->err_error == DWARF_E_NONE)
|
||||
return _libdwarf_errors[DWARF_E_NONE];
|
||||
else
|
||||
p = _libdwarf_errors[error->err_error];
|
||||
|
||||
if (error->err_error == DWARF_E_ELF)
|
||||
snprintf(error->err_msg, sizeof(error->err_msg),
|
||||
"ELF error : %s [%s(%d)]", elf_errmsg(error->elf_error),
|
||||
error->err_func, error->err_line);
|
||||
else
|
||||
snprintf(error->err_msg, sizeof(error->err_msg),
|
||||
"%s [%s(%d)]", p, error->err_func, error->err_line);
|
||||
|
||||
return (const char *) error->err_msg;
|
||||
}
|
@ -1,38 +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 "_libdwarf.h"
|
||||
|
||||
int
|
||||
dwarf_errno(Dwarf_Error *err)
|
||||
{
|
||||
if (err == NULL)
|
||||
return -1;
|
||||
|
||||
return (err->err_error);
|
||||
}
|
@ -1,98 +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 "_libdwarf.h"
|
||||
|
||||
int
|
||||
dwarf_finish(Dwarf_Debug *dbgp, Dwarf_Error *error)
|
||||
{
|
||||
Dwarf_Abbrev ab;
|
||||
Dwarf_Abbrev tab;
|
||||
Dwarf_Attribute at;
|
||||
Dwarf_Attribute tat;
|
||||
Dwarf_AttrValue av;
|
||||
Dwarf_AttrValue tav;
|
||||
Dwarf_CU cu;
|
||||
Dwarf_CU tcu;
|
||||
Dwarf_Debug dbg;
|
||||
Dwarf_Die die;
|
||||
Dwarf_Die tdie;
|
||||
|
||||
if (error == NULL)
|
||||
/* Can only return a generic error. */
|
||||
return DWARF_E_ERROR;
|
||||
|
||||
if (dbgp == NULL) {
|
||||
DWARF_SET_ERROR(error, DWARF_E_ARGUMENT);
|
||||
return DWARF_E_ERROR;
|
||||
}
|
||||
|
||||
if ((dbg = *dbgp) == NULL)
|
||||
return DWARF_E_NONE;
|
||||
|
||||
/* Free entries in the compilation unit list. */
|
||||
STAILQ_FOREACH_SAFE(cu, &dbg->dbg_cu, cu_next, tcu) {
|
||||
/* Free entries in the die list */
|
||||
STAILQ_FOREACH_SAFE(die, &cu->cu_die, die_next, tdie) {
|
||||
/* Free entries in the attribute value list */
|
||||
STAILQ_FOREACH_SAFE(av, &die->die_attrval, av_next, tav) {
|
||||
STAILQ_REMOVE(&die->die_attrval, av, _Dwarf_AttrValue, av_next);
|
||||
free(av);
|
||||
}
|
||||
|
||||
STAILQ_REMOVE(&cu->cu_die, die, _Dwarf_Die, die_next);
|
||||
free(die);
|
||||
}
|
||||
|
||||
/* Free entries in the abbrev list */
|
||||
STAILQ_FOREACH_SAFE(ab, &cu->cu_abbrev, a_next, tab) {
|
||||
/* Free entries in the attribute list */
|
||||
STAILQ_FOREACH_SAFE(at, &ab->a_attrib, at_next, tat) {
|
||||
STAILQ_REMOVE(&ab->a_attrib, at, _Dwarf_Attribute, at_next);
|
||||
free(at);
|
||||
}
|
||||
|
||||
STAILQ_REMOVE(&cu->cu_abbrev, ab, _Dwarf_Abbrev, a_next);
|
||||
free(ab);
|
||||
}
|
||||
|
||||
STAILQ_REMOVE(&dbg->dbg_cu, cu, _Dwarf_CU, cu_next);
|
||||
free(cu);
|
||||
}
|
||||
|
||||
if (dbg->dbg_elf_close)
|
||||
/* Free resources associated with the ELF file. */
|
||||
elf_end(dbg->dbg_elf);
|
||||
|
||||
free(dbg);
|
||||
|
||||
*dbgp = NULL;
|
||||
|
||||
return DWARF_E_NONE;
|
||||
}
|
@ -1,47 +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 "_libdwarf.h"
|
||||
|
||||
int
|
||||
dwarf_whatform(Dwarf_Attribute at, Dwarf_Half *return_form, Dwarf_Error *err)
|
||||
{
|
||||
int ret = DWARF_E_NONE;
|
||||
|
||||
if (err == NULL)
|
||||
return DWARF_E_ERROR;
|
||||
|
||||
if (at == NULL || return_form == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
|
||||
return DWARF_E_ARGUMENT;
|
||||
}
|
||||
|
||||
*return_form = at->at_form;
|
||||
|
||||
return ret;
|
||||
}
|
@ -1,227 +0,0 @@
|
||||
/*-
|
||||
* Copyright (c) 2008-2009, 2011, Juniper Networks, Inc.
|
||||
* 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 COPYRIGHT HOLDERS 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 REGENTS 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.
|
||||
*
|
||||
* JNPR: dwarf_func.c 336441 2009-10-17 09:19:54Z deo
|
||||
*/
|
||||
|
||||
#include <sys/cdefs.h>
|
||||
__FBSDID("$FreeBSD$");
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include <libdwarf.h>
|
||||
#include <_libdwarf.h>
|
||||
|
||||
static void
|
||||
dwarf_add_function(Dwarf_Debug dbg, Dwarf_Func func)
|
||||
{
|
||||
|
||||
STAILQ_INSERT_TAIL(&dbg->dbg_func, func, func_next);
|
||||
}
|
||||
|
||||
int
|
||||
dwarf_function_get_addr_range(Dwarf_Func f, Dwarf_Addr *low_pc,
|
||||
Dwarf_Addr *high_pc)
|
||||
{
|
||||
|
||||
*low_pc = f->func_low_pc;
|
||||
*high_pc = f->func_high_pc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
dwarf_inlined_function_get_addr_range(Dwarf_Inlined_Func f, Dwarf_Addr *low_pc,
|
||||
Dwarf_Addr *high_pc)
|
||||
{
|
||||
|
||||
*low_pc = f->ifunc_low_pc;
|
||||
*high_pc = f->ifunc_high_pc;
|
||||
return 0;
|
||||
}
|
||||
|
||||
int
|
||||
dwarf_function_is_inlined(Dwarf_Func f)
|
||||
{
|
||||
|
||||
if (f->func_is_inlined == DW_INL_inlined ||
|
||||
f->func_is_inlined == DW_INL_declared_inlined)
|
||||
return 1;
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
Dwarf_Func
|
||||
dwarf_find_function_by_name(Dwarf_Debug dbg, const char *name)
|
||||
{
|
||||
/* XXX: replace with a fast version */
|
||||
|
||||
Dwarf_Func func;
|
||||
STAILQ_FOREACH(func, &dbg->dbg_func, func_next) {
|
||||
if (strcmp(name, func->func_name) == 0)
|
||||
return func;
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
Dwarf_Func
|
||||
dwarf_find_function_by_offset(Dwarf_Debug dbg, Dwarf_Off off)
|
||||
{
|
||||
|
||||
Dwarf_Func func;
|
||||
Dwarf_Die die;
|
||||
/* printf("look for %llx\n", off); */
|
||||
STAILQ_FOREACH(func, &dbg->dbg_func, func_next) {
|
||||
die = func->func_die;
|
||||
if ((off_t)die->die_offset == off) {
|
||||
return func;
|
||||
}
|
||||
}
|
||||
return NULL;
|
||||
}
|
||||
|
||||
void
|
||||
dwarf_build_function_table(Dwarf_Debug dbg)
|
||||
{
|
||||
Dwarf_CU cu;
|
||||
Dwarf_AttrValue av;
|
||||
Dwarf_Die die, origin_die;
|
||||
Dwarf_Func func, origin_func;
|
||||
Dwarf_Inlined_Func ifunc;
|
||||
unsigned long long offset;
|
||||
const char *name;
|
||||
Dwarf_Error error;
|
||||
|
||||
/*
|
||||
* find out all the functions
|
||||
*/
|
||||
STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
|
||||
STAILQ_FOREACH(die, &cu->cu_die, die_next) {
|
||||
if (die->die_a->a_tag == DW_TAG_subprogram) {
|
||||
/*
|
||||
* Some function has multiple entries, i.e.
|
||||
* if a function is inlined, it has many
|
||||
* abstract/concrete instances, the abstract
|
||||
* instances are with DW_TAG_subprogram.
|
||||
*/
|
||||
dwarf_attrval_string(die, DW_AT_name, &name,
|
||||
&error);
|
||||
func = dwarf_find_function_by_name(dbg, name);
|
||||
if (func == NULL) {
|
||||
func = malloc(
|
||||
sizeof(struct _Dwarf_Func));
|
||||
DWARF_ASSERT(func);
|
||||
|
||||
func->func_die = die;
|
||||
func->func_name = name;
|
||||
STAILQ_INIT(
|
||||
&func->func_inlined_instances);
|
||||
|
||||
dwarf_add_function(dbg, func);
|
||||
STAILQ_FOREACH(av, &die->die_attrval,
|
||||
av_next) {
|
||||
switch (av->av_attrib) {
|
||||
case DW_AT_low_pc:
|
||||
func->func_low_pc =
|
||||
av->u[0].u64;
|
||||
break;
|
||||
case DW_AT_high_pc:
|
||||
func->func_high_pc =
|
||||
av->u[0].u64;
|
||||
break;
|
||||
case DW_AT_inline:
|
||||
func->func_is_inlined =
|
||||
av->u[0].u64;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Now check the concrete inlined instances.
|
||||
*/
|
||||
STAILQ_FOREACH(cu, &dbg->dbg_cu, cu_next) {
|
||||
STAILQ_FOREACH(die, &cu->cu_die, die_next) {
|
||||
if (die->die_a->a_tag == DW_TAG_inlined_subroutine) {
|
||||
ifunc = malloc(
|
||||
sizeof(struct _Dwarf_Inlined_Func));
|
||||
DWARF_ASSERT(ifunc);
|
||||
STAILQ_FOREACH(av, &die->die_attrval, av_next) {
|
||||
switch (av->av_attrib) {
|
||||
case DW_AT_abstract_origin:
|
||||
offset = av->u[0].u64 +
|
||||
die->die_cu->cu_offset;
|
||||
origin_die = dwarf_die_find(
|
||||
die, offset);
|
||||
DWARF_ASSERT(origin_die != 0);
|
||||
|
||||
/*
|
||||
* the abstract origin must
|
||||
* have been merged with
|
||||
* another die
|
||||
*/
|
||||
dwarf_attrval_string(
|
||||
origin_die, DW_AT_name,
|
||||
&name, &error);
|
||||
origin_func =
|
||||
dwarf_find_function_by_name
|
||||
(dbg, name);
|
||||
DWARF_ASSERT(origin_func != 0);
|
||||
|
||||
STAILQ_INSERT_TAIL(
|
||||
&origin_func->
|
||||
func_inlined_instances,
|
||||
ifunc, ifunc_next);
|
||||
|
||||
break;
|
||||
case DW_AT_low_pc:
|
||||
ifunc->ifunc_low_pc =
|
||||
av->u[0].u64;
|
||||
break;
|
||||
case DW_AT_high_pc:
|
||||
ifunc->ifunc_high_pc =
|
||||
av->u[0].u64;
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void
|
||||
dwarf_function_iterate_inlined_instance(Dwarf_Func func,
|
||||
Dwarf_Inlined_Callback f, void *data)
|
||||
{
|
||||
Dwarf_Inlined_Func ifunc;
|
||||
|
||||
if (!dwarf_function_is_inlined(func))
|
||||
return;
|
||||
STAILQ_FOREACH(ifunc, &func->func_inlined_instances, ifunc_next) {
|
||||
f(ifunc, data);
|
||||
}
|
||||
}
|
@ -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;
|
||||
}
|
@ -1,613 +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 "_libdwarf.h"
|
||||
|
||||
static int64_t
|
||||
dwarf_decode_sleb128(uint8_t **dp)
|
||||
{
|
||||
int64_t ret = 0;
|
||||
uint8_t b;
|
||||
int shift = 0;
|
||||
|
||||
uint8_t *src = *dp;
|
||||
|
||||
do {
|
||||
b = *src++;
|
||||
|
||||
ret |= ((b & 0x7f) << shift);
|
||||
|
||||
shift += 7;
|
||||
} while ((b & 0x80) != 0);
|
||||
|
||||
if (shift < 64 && (b & 0x40) != 0)
|
||||
ret |= (-1 << shift);
|
||||
|
||||
*dp = src;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
static uint64_t
|
||||
dwarf_decode_uleb128(uint8_t **dp)
|
||||
{
|
||||
uint64_t ret = 0;
|
||||
uint8_t b;
|
||||
int shift = 0;
|
||||
|
||||
uint8_t *src = *dp;
|
||||
|
||||
do {
|
||||
b = *src++;
|
||||
|
||||
ret |= ((b & 0x7f) << shift);
|
||||
|
||||
shift += 7;
|
||||
} while ((b & 0x80) != 0);
|
||||
|
||||
*dp = src;
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
/*
|
||||
* Given an array of bytes of length 'len' representing a
|
||||
* DWARF expression, compute the number of operations based
|
||||
* on there being one byte describing the operation and
|
||||
* zero or more bytes of operands as defined in the standard
|
||||
* for each operation type.
|
||||
*/
|
||||
int
|
||||
dwarf_op_num(uint8_t pointer_size, uint8_t *p, int len)
|
||||
{
|
||||
int count = 0;
|
||||
int64_t sval;
|
||||
uint64_t uval;
|
||||
uint8_t *last = p + len;
|
||||
|
||||
/*
|
||||
* Process each byte. If an error occurs, then the
|
||||
* count will be set to -1.
|
||||
*/
|
||||
while (p < last && count >= 0) {
|
||||
count++;
|
||||
|
||||
switch (*p++) {
|
||||
/* Operations with no operands. */
|
||||
case DW_OP_deref:
|
||||
case DW_OP_reg0:
|
||||
case DW_OP_reg1:
|
||||
case DW_OP_reg2:
|
||||
case DW_OP_reg3:
|
||||
case DW_OP_reg4:
|
||||
case DW_OP_reg5:
|
||||
case DW_OP_reg6:
|
||||
case DW_OP_reg7:
|
||||
case DW_OP_reg8:
|
||||
case DW_OP_reg9:
|
||||
case DW_OP_reg10:
|
||||
case DW_OP_reg11:
|
||||
case DW_OP_reg12:
|
||||
case DW_OP_reg13:
|
||||
case DW_OP_reg14:
|
||||
case DW_OP_reg15:
|
||||
case DW_OP_reg16:
|
||||
case DW_OP_reg17:
|
||||
case DW_OP_reg18:
|
||||
case DW_OP_reg19:
|
||||
case DW_OP_reg20:
|
||||
case DW_OP_reg21:
|
||||
case DW_OP_reg22:
|
||||
case DW_OP_reg23:
|
||||
case DW_OP_reg24:
|
||||
case DW_OP_reg25:
|
||||
case DW_OP_reg26:
|
||||
case DW_OP_reg27:
|
||||
case DW_OP_reg28:
|
||||
case DW_OP_reg29:
|
||||
case DW_OP_reg30:
|
||||
case DW_OP_reg31:
|
||||
|
||||
case DW_OP_lit0:
|
||||
case DW_OP_lit1:
|
||||
case DW_OP_lit2:
|
||||
case DW_OP_lit3:
|
||||
case DW_OP_lit4:
|
||||
case DW_OP_lit5:
|
||||
case DW_OP_lit6:
|
||||
case DW_OP_lit7:
|
||||
case DW_OP_lit8:
|
||||
case DW_OP_lit9:
|
||||
case DW_OP_lit10:
|
||||
case DW_OP_lit11:
|
||||
case DW_OP_lit12:
|
||||
case DW_OP_lit13:
|
||||
case DW_OP_lit14:
|
||||
case DW_OP_lit15:
|
||||
case DW_OP_lit16:
|
||||
case DW_OP_lit17:
|
||||
case DW_OP_lit18:
|
||||
case DW_OP_lit19:
|
||||
case DW_OP_lit20:
|
||||
case DW_OP_lit21:
|
||||
case DW_OP_lit22:
|
||||
case DW_OP_lit23:
|
||||
case DW_OP_lit24:
|
||||
case DW_OP_lit25:
|
||||
case DW_OP_lit26:
|
||||
case DW_OP_lit27:
|
||||
case DW_OP_lit28:
|
||||
case DW_OP_lit29:
|
||||
case DW_OP_lit30:
|
||||
case DW_OP_lit31:
|
||||
|
||||
case DW_OP_dup:
|
||||
case DW_OP_drop:
|
||||
|
||||
case DW_OP_over:
|
||||
|
||||
case DW_OP_swap:
|
||||
case DW_OP_rot:
|
||||
case DW_OP_xderef:
|
||||
|
||||
case DW_OP_abs:
|
||||
case DW_OP_and:
|
||||
case DW_OP_div:
|
||||
case DW_OP_minus:
|
||||
case DW_OP_mod:
|
||||
case DW_OP_mul:
|
||||
case DW_OP_neg:
|
||||
case DW_OP_not:
|
||||
case DW_OP_or:
|
||||
case DW_OP_plus:
|
||||
|
||||
case DW_OP_shl:
|
||||
case DW_OP_shr:
|
||||
case DW_OP_shra:
|
||||
case DW_OP_xor:
|
||||
|
||||
case DW_OP_eq:
|
||||
case DW_OP_ge:
|
||||
case DW_OP_gt:
|
||||
case DW_OP_le:
|
||||
case DW_OP_lt:
|
||||
case DW_OP_ne:
|
||||
|
||||
case DW_OP_nop:
|
||||
break;
|
||||
|
||||
/* Operations with 1-byte operands. */
|
||||
case DW_OP_const1u:
|
||||
case DW_OP_const1s:
|
||||
case DW_OP_pick:
|
||||
case DW_OP_deref_size:
|
||||
case DW_OP_xderef_size:
|
||||
p++;
|
||||
break;
|
||||
|
||||
/* Operations with 2-byte operands. */
|
||||
case DW_OP_const2u:
|
||||
case DW_OP_const2s:
|
||||
case DW_OP_bra:
|
||||
case DW_OP_skip:
|
||||
p += 2;
|
||||
break;
|
||||
|
||||
/* Operations with 4-byte operands. */
|
||||
case DW_OP_const4u:
|
||||
case DW_OP_const4s:
|
||||
p += 4;
|
||||
break;
|
||||
|
||||
/* Operations with 8-byte operands. */
|
||||
case DW_OP_const8u:
|
||||
case DW_OP_const8s:
|
||||
p += 8;
|
||||
break;
|
||||
|
||||
/* Operations with an unsigned LEB128 operand. */
|
||||
case DW_OP_constu:
|
||||
case DW_OP_plus_uconst:
|
||||
case DW_OP_regx:
|
||||
case DW_OP_piece:
|
||||
uval = dwarf_decode_uleb128(&p);
|
||||
break;
|
||||
|
||||
/* Operations with a signed LEB128 operand. */
|
||||
case DW_OP_consts:
|
||||
case DW_OP_breg0:
|
||||
case DW_OP_breg1:
|
||||
case DW_OP_breg2:
|
||||
case DW_OP_breg3:
|
||||
case DW_OP_breg4:
|
||||
case DW_OP_breg5:
|
||||
case DW_OP_breg6:
|
||||
case DW_OP_breg7:
|
||||
case DW_OP_breg8:
|
||||
case DW_OP_breg9:
|
||||
case DW_OP_breg10:
|
||||
case DW_OP_breg11:
|
||||
case DW_OP_breg12:
|
||||
case DW_OP_breg13:
|
||||
case DW_OP_breg14:
|
||||
case DW_OP_breg15:
|
||||
case DW_OP_breg16:
|
||||
case DW_OP_breg17:
|
||||
case DW_OP_breg18:
|
||||
case DW_OP_breg19:
|
||||
case DW_OP_breg20:
|
||||
case DW_OP_breg21:
|
||||
case DW_OP_breg22:
|
||||
case DW_OP_breg23:
|
||||
case DW_OP_breg24:
|
||||
case DW_OP_breg25:
|
||||
case DW_OP_breg26:
|
||||
case DW_OP_breg27:
|
||||
case DW_OP_breg28:
|
||||
case DW_OP_breg29:
|
||||
case DW_OP_breg30:
|
||||
case DW_OP_breg31:
|
||||
case DW_OP_fbreg:
|
||||
sval = dwarf_decode_sleb128(&p);
|
||||
break;
|
||||
|
||||
/*
|
||||
* Operations with an unsigned LEB128 operand
|
||||
* followed by a signed LEB128 operand.
|
||||
*/
|
||||
case DW_OP_bregx:
|
||||
uval = dwarf_decode_uleb128(&p);
|
||||
sval = dwarf_decode_sleb128(&p);
|
||||
break;
|
||||
|
||||
/* Target address size operand. */
|
||||
case DW_OP_addr:
|
||||
p += pointer_size;
|
||||
break;
|
||||
|
||||
/* All other operations cause an error. */
|
||||
default:
|
||||
count = -1;
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
return count;
|
||||
}
|
||||
|
||||
static int
|
||||
dwarf_loc_fill(Dwarf_Locdesc *lbuf, uint8_t pointer_size, uint8_t *p, int len)
|
||||
{
|
||||
int count = 0;
|
||||
int ret = DWARF_E_NONE;
|
||||
uint64_t operand1;
|
||||
uint64_t operand2;
|
||||
uint8_t *last = p + len;
|
||||
|
||||
/*
|
||||
* Process each byte. If an error occurs, then the
|
||||
* count will be set to -1.
|
||||
*/
|
||||
while (p < last && ret == DWARF_E_NONE) {
|
||||
operand1 = 0;
|
||||
operand2 = 0;
|
||||
|
||||
lbuf->ld_s[count].lr_atom = *p;
|
||||
|
||||
switch (*p++) {
|
||||
/* Operations with no operands. */
|
||||
case DW_OP_deref:
|
||||
case DW_OP_reg0:
|
||||
case DW_OP_reg1:
|
||||
case DW_OP_reg2:
|
||||
case DW_OP_reg3:
|
||||
case DW_OP_reg4:
|
||||
case DW_OP_reg5:
|
||||
case DW_OP_reg6:
|
||||
case DW_OP_reg7:
|
||||
case DW_OP_reg8:
|
||||
case DW_OP_reg9:
|
||||
case DW_OP_reg10:
|
||||
case DW_OP_reg11:
|
||||
case DW_OP_reg12:
|
||||
case DW_OP_reg13:
|
||||
case DW_OP_reg14:
|
||||
case DW_OP_reg15:
|
||||
case DW_OP_reg16:
|
||||
case DW_OP_reg17:
|
||||
case DW_OP_reg18:
|
||||
case DW_OP_reg19:
|
||||
case DW_OP_reg20:
|
||||
case DW_OP_reg21:
|
||||
case DW_OP_reg22:
|
||||
case DW_OP_reg23:
|
||||
case DW_OP_reg24:
|
||||
case DW_OP_reg25:
|
||||
case DW_OP_reg26:
|
||||
case DW_OP_reg27:
|
||||
case DW_OP_reg28:
|
||||
case DW_OP_reg29:
|
||||
case DW_OP_reg30:
|
||||
case DW_OP_reg31:
|
||||
|
||||
case DW_OP_lit0:
|
||||
case DW_OP_lit1:
|
||||
case DW_OP_lit2:
|
||||
case DW_OP_lit3:
|
||||
case DW_OP_lit4:
|
||||
case DW_OP_lit5:
|
||||
case DW_OP_lit6:
|
||||
case DW_OP_lit7:
|
||||
case DW_OP_lit8:
|
||||
case DW_OP_lit9:
|
||||
case DW_OP_lit10:
|
||||
case DW_OP_lit11:
|
||||
case DW_OP_lit12:
|
||||
case DW_OP_lit13:
|
||||
case DW_OP_lit14:
|
||||
case DW_OP_lit15:
|
||||
case DW_OP_lit16:
|
||||
case DW_OP_lit17:
|
||||
case DW_OP_lit18:
|
||||
case DW_OP_lit19:
|
||||
case DW_OP_lit20:
|
||||
case DW_OP_lit21:
|
||||
case DW_OP_lit22:
|
||||
case DW_OP_lit23:
|
||||
case DW_OP_lit24:
|
||||
case DW_OP_lit25:
|
||||
case DW_OP_lit26:
|
||||
case DW_OP_lit27:
|
||||
case DW_OP_lit28:
|
||||
case DW_OP_lit29:
|
||||
case DW_OP_lit30:
|
||||
case DW_OP_lit31:
|
||||
|
||||
case DW_OP_dup:
|
||||
case DW_OP_drop:
|
||||
|
||||
case DW_OP_over:
|
||||
|
||||
case DW_OP_swap:
|
||||
case DW_OP_rot:
|
||||
case DW_OP_xderef:
|
||||
|
||||
case DW_OP_abs:
|
||||
case DW_OP_and:
|
||||
case DW_OP_div:
|
||||
case DW_OP_minus:
|
||||
case DW_OP_mod:
|
||||
case DW_OP_mul:
|
||||
case DW_OP_neg:
|
||||
case DW_OP_not:
|
||||
case DW_OP_or:
|
||||
case DW_OP_plus:
|
||||
|
||||
case DW_OP_shl:
|
||||
case DW_OP_shr:
|
||||
case DW_OP_shra:
|
||||
case DW_OP_xor:
|
||||
|
||||
case DW_OP_eq:
|
||||
case DW_OP_ge:
|
||||
case DW_OP_gt:
|
||||
case DW_OP_le:
|
||||
case DW_OP_lt:
|
||||
case DW_OP_ne:
|
||||
|
||||
case DW_OP_nop:
|
||||
break;
|
||||
|
||||
/* Operations with 1-byte operands. */
|
||||
case DW_OP_const1u:
|
||||
case DW_OP_const1s:
|
||||
case DW_OP_pick:
|
||||
case DW_OP_deref_size:
|
||||
case DW_OP_xderef_size:
|
||||
operand1 = *p++;
|
||||
break;
|
||||
|
||||
/* Operations with 2-byte operands. */
|
||||
case DW_OP_const2u:
|
||||
case DW_OP_const2s:
|
||||
case DW_OP_bra:
|
||||
case DW_OP_skip:
|
||||
p += 2;
|
||||
break;
|
||||
|
||||
/* Operations with 4-byte operands. */
|
||||
case DW_OP_const4u:
|
||||
case DW_OP_const4s:
|
||||
p += 4;
|
||||
break;
|
||||
|
||||
/* Operations with 8-byte operands. */
|
||||
case DW_OP_const8u:
|
||||
case DW_OP_const8s:
|
||||
p += 8;
|
||||
break;
|
||||
|
||||
/* Operations with an unsigned LEB128 operand. */
|
||||
case DW_OP_constu:
|
||||
case DW_OP_plus_uconst:
|
||||
case DW_OP_regx:
|
||||
case DW_OP_piece:
|
||||
operand1 = dwarf_decode_uleb128(&p);
|
||||
break;
|
||||
|
||||
/* Operations with a signed LEB128 operand. */
|
||||
case DW_OP_consts:
|
||||
case DW_OP_breg0:
|
||||
case DW_OP_breg1:
|
||||
case DW_OP_breg2:
|
||||
case DW_OP_breg3:
|
||||
case DW_OP_breg4:
|
||||
case DW_OP_breg5:
|
||||
case DW_OP_breg6:
|
||||
case DW_OP_breg7:
|
||||
case DW_OP_breg8:
|
||||
case DW_OP_breg9:
|
||||
case DW_OP_breg10:
|
||||
case DW_OP_breg11:
|
||||
case DW_OP_breg12:
|
||||
case DW_OP_breg13:
|
||||
case DW_OP_breg14:
|
||||
case DW_OP_breg15:
|
||||
case DW_OP_breg16:
|
||||
case DW_OP_breg17:
|
||||
case DW_OP_breg18:
|
||||
case DW_OP_breg19:
|
||||
case DW_OP_breg20:
|
||||
case DW_OP_breg21:
|
||||
case DW_OP_breg22:
|
||||
case DW_OP_breg23:
|
||||
case DW_OP_breg24:
|
||||
case DW_OP_breg25:
|
||||
case DW_OP_breg26:
|
||||
case DW_OP_breg27:
|
||||
case DW_OP_breg28:
|
||||
case DW_OP_breg29:
|
||||
case DW_OP_breg30:
|
||||
case DW_OP_breg31:
|
||||
case DW_OP_fbreg:
|
||||
operand1 = dwarf_decode_sleb128(&p);
|
||||
break;
|
||||
|
||||
/*
|
||||
* Operations with an unsigned LEB128 operand
|
||||
* followed by a signed LEB128 operand.
|
||||
*/
|
||||
case DW_OP_bregx:
|
||||
operand1 = dwarf_decode_uleb128(&p);
|
||||
operand2 = dwarf_decode_sleb128(&p);
|
||||
break;
|
||||
|
||||
/* Target address size operand. */
|
||||
case DW_OP_addr:
|
||||
p += pointer_size;
|
||||
break;
|
||||
|
||||
/* All other operations cause an error. */
|
||||
default:
|
||||
break;
|
||||
}
|
||||
|
||||
lbuf->ld_s[count].lr_number = operand1;
|
||||
lbuf->ld_s[count].lr_number2 = operand2;
|
||||
|
||||
count++;
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dwarf_locdesc(Dwarf_Die die, uint64_t attr, Dwarf_Locdesc **llbuf, Dwarf_Signed *lenp, Dwarf_Error *err)
|
||||
{
|
||||
Dwarf_AttrValue av;
|
||||
Dwarf_Locdesc *lbuf;
|
||||
int num;
|
||||
int ret = DWARF_E_NONE;
|
||||
|
||||
if (err == NULL)
|
||||
return DWARF_E_ERROR;
|
||||
|
||||
if (die == NULL || llbuf == NULL || lenp == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
|
||||
return DWARF_E_ARGUMENT;
|
||||
}
|
||||
|
||||
if ((av = dwarf_attrval_find(die, attr)) == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_NO_ENTRY);
|
||||
ret = DWARF_E_NO_ENTRY;
|
||||
} else if ((lbuf = calloc(sizeof(Dwarf_Locdesc), 1)) == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_MEMORY);
|
||||
ret = DWARF_E_MEMORY;
|
||||
} else {
|
||||
*lenp = 0;
|
||||
switch (av->av_form) {
|
||||
case DW_FORM_block:
|
||||
case DW_FORM_block1:
|
||||
case DW_FORM_block2:
|
||||
case DW_FORM_block4:
|
||||
/* Compute the number of locations: */
|
||||
if ((num = dwarf_op_num(die->die_cu->cu_pointer_size,
|
||||
av->u[1].u8p, av->u[0].u64)) < 0) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_INVALID_EXPR);
|
||||
ret = DWARF_E_INVALID_EXPR;
|
||||
|
||||
/* Allocate an array of location structures. */
|
||||
} else if ((lbuf->ld_s =
|
||||
calloc(sizeof(Dwarf_Loc), num)) == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_MEMORY);
|
||||
ret = DWARF_E_MEMORY;
|
||||
|
||||
/* Fill the array of location structures. */
|
||||
} else if ((ret = dwarf_loc_fill(lbuf,
|
||||
die->die_cu->cu_pointer_size,
|
||||
av->u[1].u8p, av->u[0].u64)) != DWARF_E_NONE) {
|
||||
free(lbuf->ld_s);
|
||||
} else
|
||||
/* Only one descriptor is returned. */
|
||||
*lenp = 1;
|
||||
break;
|
||||
default:
|
||||
printf("%s(%d): form %s not handled\n",__func__,
|
||||
__LINE__,get_form_desc(av->av_form));
|
||||
DWARF_SET_ERROR(err, DWARF_E_NOT_IMPLEMENTED);
|
||||
ret = DWARF_E_ERROR;
|
||||
}
|
||||
|
||||
if (ret == DWARF_E_NONE) {
|
||||
*llbuf = lbuf;
|
||||
} else
|
||||
free(lbuf);
|
||||
}
|
||||
|
||||
return ret;
|
||||
}
|
||||
|
||||
int
|
||||
dwarf_locdesc_free(Dwarf_Locdesc *lbuf, Dwarf_Error *err)
|
||||
{
|
||||
if (err == NULL)
|
||||
return DWARF_E_ERROR;
|
||||
|
||||
if (lbuf == NULL) {
|
||||
DWARF_SET_ERROR(err, DWARF_E_ARGUMENT);
|
||||
return DWARF_E_ARGUMENT;
|
||||
}
|
||||
|
||||
if (lbuf->ld_s != NULL)
|
||||
free(lbuf->ld_s);
|
||||
|
||||
free(lbuf);
|
||||
|
||||
return DWARF_E_NONE;
|
||||
}
|
@ -1,176 +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$
|
||||
*/
|
||||
|
||||
#ifndef _LIBDWARF_H_
|
||||
#define _LIBDWARF_H_
|
||||
|
||||
#include <libelf.h>
|
||||
|
||||
typedef int Dwarf_Bool;
|
||||
typedef off_t Dwarf_Off;
|
||||
typedef uint64_t Dwarf_Unsigned;
|
||||
typedef uint16_t Dwarf_Half;
|
||||
typedef uint8_t Dwarf_Small;
|
||||
typedef int64_t Dwarf_Signed;
|
||||
typedef uint64_t Dwarf_Addr;
|
||||
typedef void *Dwarf_Ptr;
|
||||
|
||||
/* Forward definitions. */
|
||||
typedef struct _Dwarf_Abbrev *Dwarf_Abbrev;
|
||||
typedef struct _Dwarf_Arange *Dwarf_Arange;
|
||||
typedef struct _Dwarf_Attribute *Dwarf_Attribute;
|
||||
typedef struct _Dwarf_AttrValue *Dwarf_AttrValue;
|
||||
typedef struct _Dwarf_CU *Dwarf_CU;
|
||||
typedef struct _Dwarf_Cie *Dwarf_Cie;
|
||||
typedef struct _Dwarf_Debug *Dwarf_Debug;
|
||||
typedef struct _Dwarf_Die *Dwarf_Die;
|
||||
typedef struct _Dwarf_Fde *Dwarf_Fde;
|
||||
typedef struct _Dwarf_Func *Dwarf_Func;
|
||||
typedef struct _Dwarf_Inlined_Func *Dwarf_Inlined_Func;
|
||||
typedef struct _Dwarf_Global *Dwarf_Global;
|
||||
typedef struct _Dwarf_Line *Dwarf_Line;
|
||||
typedef struct _Dwarf_Type *Dwarf_Type;
|
||||
typedef struct _Dwarf_Var *Dwarf_Var;
|
||||
typedef struct _Dwarf_Weak *Dwarf_Weak;
|
||||
|
||||
typedef struct {
|
||||
Dwarf_Small lr_atom;
|
||||
Dwarf_Unsigned lr_number;
|
||||
Dwarf_Unsigned lr_number2;
|
||||
Dwarf_Unsigned lr_offset;
|
||||
} Dwarf_Loc;
|
||||
|
||||
typedef struct {
|
||||
Dwarf_Addr ld_lopc;
|
||||
Dwarf_Addr ld_hipc;
|
||||
Dwarf_Half ld_cents;
|
||||
Dwarf_Loc *ld_s;
|
||||
} Dwarf_Locdesc;
|
||||
|
||||
/* receiver function for dwarf_function_iterate_inlined_instance() API */
|
||||
typedef void (*Dwarf_Inlined_Callback)(Dwarf_Inlined_Func, void *);
|
||||
|
||||
/*
|
||||
* Error numbers which are specific to this implementation.
|
||||
*/
|
||||
enum {
|
||||
DWARF_E_NONE, /* No error. */
|
||||
DWARF_E_ERROR, /* An error! */
|
||||
DWARF_E_NO_ENTRY, /* No entry. */
|
||||
DWARF_E_ARGUMENT, /* Invalid argument. */
|
||||
DWARF_E_DEBUG_INFO, /* Debug info NULL. */
|
||||
DWARF_E_MEMORY, /* Insufficient memory. */
|
||||
DWARF_E_ELF, /* ELF error. */
|
||||
DWARF_E_INVALID_CU, /* Invalid compilation unit data. */
|
||||
DWARF_E_CU_VERSION, /* Wrong CU version. */
|
||||
DWARF_E_MISSING_ABBREV, /* Abbrev not found. */
|
||||
DWARF_E_NOT_IMPLEMENTED, /* Not implemented. */
|
||||
DWARF_E_CU_CURRENT, /* No current compilation unit. */
|
||||
DWARF_E_BAD_FORM, /* Wrong form type for attribute value. */
|
||||
DWARF_E_INVALID_EXPR, /* Invalid DWARF expression. */
|
||||
DWARF_E_NUM /* Max error number. */
|
||||
};
|
||||
|
||||
typedef struct _Dwarf_Error {
|
||||
int err_error; /* DWARF error. */
|
||||
int elf_error; /* ELF error. */
|
||||
const char *err_func; /* Function name where error occurred. */
|
||||
int err_line; /* Line number where error occurred. */
|
||||
char err_msg[1024]; /* Formatted error message. */
|
||||
} Dwarf_Error;
|
||||
|
||||
/*
|
||||
* Return values which have to be compatible with other
|
||||
* implementations of libdwarf.
|
||||
*/
|
||||
#define DW_DLV_NO_ENTRY DWARF_E_NO_ENTRY
|
||||
#define DW_DLV_OK DWARF_E_NONE
|
||||
#define DW_DLE_DEBUG_INFO_NULL DWARF_E_DEBUG_INFO
|
||||
|
||||
#define DW_DLC_READ 0 /* read only access */
|
||||
|
||||
/* Function prototype definitions. */
|
||||
__BEGIN_DECLS
|
||||
Dwarf_Abbrev dwarf_abbrev_find(Dwarf_CU, uint64_t);
|
||||
Dwarf_AttrValue dwarf_attrval_find(Dwarf_Die, Dwarf_Half);
|
||||
Dwarf_Die dwarf_die_find(Dwarf_Die, Dwarf_Unsigned);
|
||||
const char *dwarf_errmsg(Dwarf_Error *);
|
||||
const char *get_sht_desc(uint32_t);
|
||||
const char *get_attr_desc(uint32_t);
|
||||
const char *get_form_desc(uint32_t);
|
||||
const char *get_tag_desc(uint32_t);
|
||||
int dwarf_abbrev_add(Dwarf_CU, uint64_t, uint64_t, uint8_t, Dwarf_Abbrev *, Dwarf_Error *);
|
||||
int dwarf_attr(Dwarf_Die, Dwarf_Half, Dwarf_Attribute *, Dwarf_Error *);
|
||||
int dwarf_attr_add(Dwarf_Abbrev, uint64_t, uint64_t, Dwarf_Attribute *, Dwarf_Error *);
|
||||
int dwarf_attrval(Dwarf_Die, Dwarf_Half, Dwarf_AttrValue *, Dwarf_Error *);
|
||||
int dwarf_attrval_add(Dwarf_Die, Dwarf_AttrValue, Dwarf_AttrValue *, Dwarf_Error *);
|
||||
int dwarf_attrval_flag(Dwarf_Die, uint64_t, Dwarf_Bool *, Dwarf_Error *);
|
||||
int dwarf_attrval_signed(Dwarf_Die, uint64_t, Dwarf_Signed *, Dwarf_Error *);
|
||||
int dwarf_attrval_string(Dwarf_Die, uint64_t, const char **, Dwarf_Error *);
|
||||
int dwarf_attrval_unsigned(Dwarf_Die, uint64_t, Dwarf_Unsigned *, Dwarf_Error *);
|
||||
int dwarf_child(Dwarf_Die, Dwarf_Die *, Dwarf_Error *);
|
||||
int dwarf_die_add(Dwarf_CU, int, uint64_t, uint64_t, Dwarf_Abbrev, Dwarf_Die *, Dwarf_Error *);
|
||||
int dwarf_dieoffset(Dwarf_Die, Dwarf_Off *, Dwarf_Error *);
|
||||
int dwarf_elf_init(Elf *, int, Dwarf_Debug *, Dwarf_Error *);
|
||||
int dwarf_errno(Dwarf_Error *);
|
||||
int dwarf_finish(Dwarf_Debug *, Dwarf_Error *);
|
||||
int dwarf_locdesc(Dwarf_Die, uint64_t, Dwarf_Locdesc **, Dwarf_Signed *, Dwarf_Error *);
|
||||
int dwarf_locdesc_free(Dwarf_Locdesc *, Dwarf_Error *);
|
||||
int dwarf_init(int, int, Dwarf_Debug *, Dwarf_Error *);
|
||||
int dwarf_next_cu_header(Dwarf_Debug, Dwarf_Unsigned *, Dwarf_Half *,
|
||||
Dwarf_Unsigned *, Dwarf_Half *, Dwarf_Unsigned *, Dwarf_Error *);
|
||||
int dwarf_op_num(uint8_t, uint8_t *, int);
|
||||
int dwarf_siblingof(Dwarf_Debug, Dwarf_Die, Dwarf_Die *, Dwarf_Error *);
|
||||
int dwarf_tag(Dwarf_Die, Dwarf_Half *, Dwarf_Error *);
|
||||
int dwarf_whatform(Dwarf_Attribute, Dwarf_Half *, Dwarf_Error *);
|
||||
void dwarf_dealloc(Dwarf_Debug, Dwarf_Ptr, Dwarf_Unsigned);
|
||||
void dwarf_dump(Dwarf_Debug);
|
||||
void dwarf_dump_abbrev(Dwarf_Debug);
|
||||
void dwarf_dump_av(Dwarf_Die, Dwarf_AttrValue);
|
||||
void dwarf_dump_dbgstr(Dwarf_Debug);
|
||||
void dwarf_dump_die(Dwarf_Die);
|
||||
void dwarf_dump_die_at_offset(Dwarf_Debug, Dwarf_Off);
|
||||
void dwarf_dump_info(Dwarf_Debug);
|
||||
void dwarf_dump_shstrtab(Dwarf_Debug);
|
||||
void dwarf_dump_strtab(Dwarf_Debug);
|
||||
void dwarf_dump_symtab(Dwarf_Debug);
|
||||
void dwarf_dump_raw(Dwarf_Debug);
|
||||
void dwarf_dump_tree(Dwarf_Debug);
|
||||
Dwarf_Func dwarf_find_function_by_offset(Dwarf_Debug dbg, Dwarf_Off off);
|
||||
Dwarf_Func dwarf_find_function_by_name(Dwarf_Debug dbg, const char *name);
|
||||
int dwarf_function_get_addr_range(Dwarf_Func f,
|
||||
Dwarf_Addr *low_pc, Dwarf_Addr *high_pc);
|
||||
int dwarf_function_is_inlined(Dwarf_Func f);
|
||||
void dwarf_function_iterate_inlined_instance(Dwarf_Func func,
|
||||
Dwarf_Inlined_Callback f, void *data);
|
||||
int dwarf_inlined_function_get_addr_range(Dwarf_Inlined_Func f,
|
||||
Dwarf_Addr *low_pc, Dwarf_Addr *high_pc);
|
||||
|
||||
__END_DECLS
|
||||
|
||||
#endif /* !_LIBDWARF_H_ */
|
Loading…
Reference in New Issue
Block a user