Remove the old libdwarf and bring in the new libdwarf in contrib/.

This commit is contained in:
Kai Wang 2014-01-16 21:52:09 +00:00
parent 1ecdb6d49d
commit fbb4c451b3
Notes: svn2git 2020-12-20 02:59:44 +00:00
svn path=/projects/elftoolchain/; revision=260794
18 changed files with 311 additions and 4342 deletions

View file

@ -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}

View file

@ -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_ */

View file

@ -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_ */

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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);
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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);
}
}

View file

@ -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;
}

View file

@ -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;
}

View file

@ -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_ */