summaryrefslogtreecommitdiffstats
path: root/libdwarf
diff options
context:
space:
mode:
Diffstat (limited to 'libdwarf')
-rw-r--r--libdwarf/.cvsignore1
-rw-r--r--libdwarf/AVAILABLE136
-rw-r--r--libdwarf/ChangeLog3
-rw-r--r--libdwarf/Makefile.am103
-rw-r--r--libdwarf/dwarf.h549
-rw-r--r--libdwarf/dwarf_abbrev_hash.c29
-rw-r--r--libdwarf/dwarf_abbrev_hash.h24
-rw-r--r--libdwarf/dwarf_arrayorder.c31
-rw-r--r--libdwarf/dwarf_attr.c113
-rw-r--r--libdwarf/dwarf_attrlist.c182
-rw-r--r--libdwarf/dwarf_bitoffset.c31
-rw-r--r--libdwarf/dwarf_bitsize.c31
-rw-r--r--libdwarf/dwarf_bytesize.c31
-rw-r--r--libdwarf/dwarf_child.c123
-rw-r--r--libdwarf/dwarf_dealloc.c32
-rw-r--r--libdwarf/dwarf_die_CU_offset.c33
-rw-r--r--libdwarf/dwarf_diename.c139
-rw-r--r--libdwarf/dwarf_dieoffset.c31
-rw-r--r--libdwarf/dwarf_elf_init.c197
-rw-r--r--libdwarf/dwarf_errmsg.c67
-rw-r--r--libdwarf/dwarf_errno.c26
-rw-r--r--libdwarf/dwarf_error.c52
-rw-r--r--libdwarf/dwarf_find_macro_value_start.c45
-rw-r--r--libdwarf/dwarf_finish.c40
-rw-r--r--libdwarf/dwarf_form.c107
-rw-r--r--libdwarf/dwarf_formaddr.c42
-rw-r--r--libdwarf/dwarf_formblock.c76
-rw-r--r--libdwarf/dwarf_formflag.c39
-rw-r--r--libdwarf/dwarf_formref.c67
-rw-r--r--libdwarf/dwarf_formsdata.c72
-rw-r--r--libdwarf/dwarf_formstring.c51
-rw-r--r--libdwarf/dwarf_formudata.c72
-rw-r--r--libdwarf/dwarf_get_abbrev.c111
-rw-r--r--libdwarf/dwarf_get_abbrev_children_flag.c29
-rw-r--r--libdwarf/dwarf_get_abbrev_code.c29
-rw-r--r--libdwarf/dwarf_get_abbrev_entry.c63
-rw-r--r--libdwarf/dwarf_get_abbrev_tag.c29
-rw-r--r--libdwarf/dwarf_get_address_size.c30
-rw-r--r--libdwarf/dwarf_get_arange.c41
-rw-r--r--libdwarf/dwarf_get_arange_info.c48
-rw-r--r--libdwarf/dwarf_get_aranges.c186
-rw-r--r--libdwarf/dwarf_get_cie_info.c53
-rw-r--r--libdwarf/dwarf_get_cie_of_fde.c30
-rw-r--r--libdwarf/dwarf_get_cu_die_offset.c43
-rw-r--r--libdwarf/dwarf_get_elf.c33
-rw-r--r--libdwarf/dwarf_get_fde_at_pc.c57
-rw-r--r--libdwarf/dwarf_get_fde_instr_bytes.c33
-rw-r--r--libdwarf/dwarf_get_fde_list_eh.c363
-rw-r--r--libdwarf/dwarf_get_fde_n.c36
-rw-r--r--libdwarf/dwarf_get_fde_range.c44
-rw-r--r--libdwarf/dwarf_get_globals.c176
-rw-r--r--libdwarf/dwarf_get_loclist_entry.c88
-rw-r--r--libdwarf/dwarf_get_str.c43
-rw-r--r--libdwarf/dwarf_getabbrev.c73
-rw-r--r--libdwarf/dwarf_getconstant.c125
-rw-r--r--libdwarf/dwarf_global_cu_offset.c44
-rw-r--r--libdwarf/dwarf_global_die_offset.c33
-rw-r--r--libdwarf/dwarf_global_formref.c73
-rw-r--r--libdwarf/dwarf_global_name_offsets.c64
-rw-r--r--libdwarf/dwarf_globname.c38
-rw-r--r--libdwarf/dwarf_hasattr.c98
-rw-r--r--libdwarf/dwarf_hasform.c31
-rw-r--r--libdwarf/dwarf_highpc.c108
-rw-r--r--libdwarf/dwarf_init.c92
-rw-r--r--libdwarf/dwarf_lineaddr.c30
-rw-r--r--libdwarf/dwarf_linebeginstatement.c30
-rw-r--r--libdwarf/dwarf_lineblock.c30
-rw-r--r--libdwarf/dwarf_lineendsequence.c30
-rw-r--r--libdwarf/dwarf_lineepiloguebegin.c30
-rw-r--r--libdwarf/dwarf_lineno.c30
-rw-r--r--libdwarf/dwarf_lineoff.c30
-rw-r--r--libdwarf/dwarf_lineprologueend.c30
-rw-r--r--libdwarf/dwarf_linesrc.c44
-rw-r--r--libdwarf/dwarf_loclist.c470
-rw-r--r--libdwarf/dwarf_lowpc.c108
-rw-r--r--libdwarf/dwarf_next_cu_header.c234
-rw-r--r--libdwarf/dwarf_offdie.c123
-rw-r--r--libdwarf/dwarf_seterrarg.c30
-rw-r--r--libdwarf/dwarf_seterrhand.c30
-rw-r--r--libdwarf/dwarf_siblingof.c257
-rw-r--r--libdwarf/dwarf_srcfiles.c344
-rw-r--r--libdwarf/dwarf_srclang.c31
-rw-r--r--libdwarf/dwarf_srclines.c745
-rw-r--r--libdwarf/dwarf_tag.c30
-rw-r--r--libdwarf/dwarf_whatattr.c30
-rw-r--r--libdwarf/dwarf_whatform.c30
-rw-r--r--libdwarf/libdwarf.h514
-rw-r--r--libdwarf/libdwarf.map81
-rw-r--r--libdwarf/libdwarfP.h319
-rw-r--r--libdwarf/memory-access.h207
90 files changed, 8786 insertions, 0 deletions
diff --git a/libdwarf/.cvsignore b/libdwarf/.cvsignore
new file mode 100644
index 00000000..70845e08
--- /dev/null
+++ b/libdwarf/.cvsignore
@@ -0,0 +1 @@
+Makefile.in
diff --git a/libdwarf/AVAILABLE b/libdwarf/AVAILABLE
new file mode 100644
index 00000000..642dd27e
--- /dev/null
+++ b/libdwarf/AVAILABLE
@@ -0,0 +1,136 @@
+Data Types:
+
+ Dwarf_Bool
+ Dwarf_Off
+ Dwarf_Unsigned
+ Dwarf_Half
+ Dwarf_Small
+ Dwarf_Signed
+ Dwarf_Addr
+ Dwarf_Ptr
+ Dwarf_Handler
+
+ Dwarf_Debug
+ Dwarf_Die
+ Dwarf_Line
+ Dwarf_Global
+ Dwarf_Loc
+ Dwarf_Locdesc
+ Dwarf_Block
+ Dwarf_Error
+ Dwarf_Attribute
+ Dwarf_Fde
+ Dwarf_Cie
+ Dwarf_Arange
+
+ NOT!!!:
+
+ Dwarf_Frame_Op
+ Dwarf_Macro_Details
+
+ Dwarf_Weak
+ Dwarf_Func
+ Dwarf_Type
+ Dwarf_Var
+ Dwarf_Abbrev
+
+Functions:
+
+ dwarf_init()
+ dwarf_elf_init()
+ dwarf_get_elf()
+ dwarf_finish()
+ dwarf_next_cu_header()
+ dwarf_siblingof()
+ dwarf_child()
+ dwarf_offdie()
+ dwarf_tag()
+ dwarf_dieoffset()
+ dwarf_die_CU_offset()
+ dwarf_diename()
+ dwarf_attrlist()
+ dwarf_srclang()
+ dwarf_arrayorder()
+ dwarf_hasform()
+ dwarf_whatattr()
+ dwarf_formref()
+ dwarf_global_formref()
+ dwarf_formaddr()
+ dwarf_formflag()
+ dwarf_hasattr()
+ dwarf_attr()
+ dwarf_lowpc()
+ dwarf_highpc()
+ dwarf_bytesize()
+ dwarf_bitsize()
+ dwarf_bitoffset()
+ dwarf_formudata()
+ dwarf_formblock()
+ dwarf_formstring()
+ dwarf_loclist()
+ dwarf_srclines()
+ dwarf_srcfiles()
+ dwarf_linebeginstatement()
+ dwarf_lineendsequence()
+ dwarf_lineno()
+ dwarf_lineaddr()
+ dwarf_lineoff()
+ dwarf_linesrc()
+ dwarf_lineblock()
+ dwarf_get_globals()
+ dwarf_globname()
+ dwarf_global_die_offset()
+ dwarf_global_cu_offset()
+ dwarf_global_name_offsets()
+ dwarf_find_macro_value_start()
+ dwarf_get_fde_list_eh()
+ dwarf_get_fde_range()
+ dwarf_get_cie_of_fde()
+ dwarf_get_cie_info()
+ dwarf_get_fde_instr_bytes()
+ dwarf_get_fde_n()
+ dwarf_get_fde_at_pc()
+ dwarf_get_str()
+ dwarf_get_aranges()
+ dwarf_get_cu_die_offset()
+ dwarf_get_loclist_entry()
+ dwarf_get_abbrev()
+ dwarf_get_abbrev_tag()
+ dwarf_get_abbrev_code()
+ dwarf_get_abbrev_children_flag()
+ dwarf_get_abbrev_entry()
+ dwarf_get_arange_info()
+ dwarf_get_address_size()
+ dwarf_errno()
+ dwarf_errmsg()
+ dwarf_seterrhand()
+ dwarf_seterrarg()
+ dwarf_dealloc()
+
+ NOT!!!:
+
+ dwarf_get_weaks()
+ dwarf_weakname()
+ dwarf_weak_die_offset()
+ dwarf_weak_cu_offset()
+ dwarf_weak_name_offsets()
+ dwarf_get_funcs()
+ dwarf_funcname()
+ dwarf_func_die_offset()
+ dwarf_func_cu_offset()
+ dwarf_func_name_offsets()
+ dwarf_get_types()
+ dwarf_typename()
+ dwarf_type_die_offset()
+ dwarf_type_cu_offset()
+ dwarf_type_name_offsets()
+ dwarf_get_vars()
+ dwarf_varname()
+ dwarf_var_die_offset()
+ dwarf_var_cu_offset()
+ dwarf_var_name_offsets()
+ dwarf_get_fde_list()
+ dwarf_get_fde_for_die()
+ dwarf_get_fde_info_for_reg() <<-------
+ dwarf_get_fde_info_for_all_regs()
+ dwarf_expand_frame_instructions() <<-------
diff --git a/libdwarf/ChangeLog b/libdwarf/ChangeLog
new file mode 100644
index 00000000..c46ffcb6
--- /dev/null
+++ b/libdwarf/ChangeLog
@@ -0,0 +1,3 @@
+2003-08-11 Ulrich Drepper <drepper@redhat.com>
+
+ * Moved to CVS archive.
diff --git a/libdwarf/Makefile.am b/libdwarf/Makefile.am
new file mode 100644
index 00000000..8af7a674
--- /dev/null
+++ b/libdwarf/Makefile.am
@@ -0,0 +1,103 @@
+## Process this file with automake to create Makefile.in -*-Makefile-*-
+## Configure input file for elfutils.
+##
+## Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+##
+## This program is Open Source software; you can redistribute it and/or
+## modify it under the terms of the Open Software License version 1.0 as
+## published by the Open Source Initiative.
+##
+## You should have received a copy of the Open Software License along
+## with this program; if not, you may obtain a copy of the Open Software
+## License version 1.0 from http://www.opensource.org/licenses/osl.php or
+## by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+## 3001 King Ranch Road, Ukiah, CA 95482.
+##
+DEFS = -D_GNU_SOURCE -DHAVE_CONFIG_H -DDWARF_DEBUG
+AM_CFLAGS = -Wall -Werror
+INCLUDES = -I. -I$(srcdir) -I$(srcdir)/../libelf -I.. -I$(srcdir)/../lib
+VERSION = 1
+
+lib_LIBRARIES = libdwarf.a
+noinst_LIBRARIES = libdwarf_pic.a
+noinst_PROGRAMS = $(noinst_LIBRARIES:_pic.a=.so)
+include_HEADERS = dwarf.h
+euincludedir = ${includedir}/elfutils
+euinclude_HEADERS = libdwarf.h
+
+libdwarf_a_SOURCES = dwarf_init.c dwarf_elf_init.c dwarf_get_elf.c \
+ dwarf_finish.c \
+ dwarf_next_cu_header.c dwarf_siblingof.c dwarf_child.c \
+ dwarf_offdie.c \
+ dwarf_tag.c dwarf_dieoffset.c dwarf_die_CU_offset.c \
+ dwarf_diename.c dwarf_attrlist.c dwarf_hasattr.c \
+ dwarf_attr.c dwarf_lowpc.c dwarf_highpc.c \
+ dwarf_getconstant.c \
+ dwarf_bytesize.c dwarf_bitsize.c dwarf_bitoffset.c \
+ dwarf_srclang.c dwarf_whatattr.c dwarf_arrayorder.c \
+ dwarf_hasform.c dwarf_whatform.c dwarf_formref.c \
+ dwarf_global_formref.c dwarf_formaddr.c \
+ dwarf_formstring.c dwarf_loclist.c \
+ dwarf_formflag.c dwarf_formudata.c dwarf_formsdata.c \
+ dwarf_formblock.c \
+ dwarf_srclines.c dwarf_srcfiles.c \
+ dwarf_linebeginstatement.c dwarf_lineendsequence.c \
+ dwarf_lineno.c dwarf_lineaddr.c dwarf_lineoff.c \
+ dwarf_linesrc.c dwarf_lineblock.c \
+ dwarf_lineprologueend.c dwarf_lineepiloguebegin.c \
+ dwarf_get_globals.c dwarf_globname.c \
+ dwarf_global_die_offset.c dwarf_global_cu_offset.c \
+ dwarf_global_name_offsets.c \
+ dwarf_error.c dwarf_errno.c dwarf_errmsg.c \
+ dwarf_abbrev_hash.c dwarf_getabbrev.c dwarf_form.c \
+ dwarf_find_macro_value_start.c dwarf_get_str.c \
+ dwarf_get_aranges.c dwarf_get_arange.c \
+ dwarf_get_cu_die_offset.c dwarf_get_arange_info.c \
+ dwarf_get_fde_list_eh.c dwarf_get_cie_of_fde.c \
+ dwarf_get_cie_info.c dwarf_get_fde_instr_bytes.c \
+ dwarf_get_fde_range.c dwarf_get_fde_n.c \
+ dwarf_get_fde_at_pc.c \
+ dwarf_get_loclist_entry.c \
+ dwarf_get_abbrev.c dwarf_get_abbrev_tag.c \
+ dwarf_get_abbrev_code.c dwarf_get_abbrev_children_flag.c\
+ dwarf_get_abbrev_entry.c \
+ dwarf_get_address_size.c \
+ dwarf_seterrhand.c dwarf_seterrarg.c \
+ dwarf_dealloc.c
+
+libdwarf_pic_a_SOURCES =
+am_libdwarf_pic_a_OBJECTS = $(libdwarf_a_SOURCES:.c=.os)
+
+libdwarf_so_SOURCES =
+libdwarf.so: libdwarf_pic.a libdwarf.map
+ $(CC) -shared -o $@ -Wl,--whole-archive,$<,--no-whole-archive \
+ -Wl,--version-script,$(srcdir)/libdwarf.map,--no-undefined \
+ -Wl,--soname,$@.$(VERSION),-z,defs \
+ ../libelf/libelf.so
+ ln -fs $@ $@.$(VERSION)
+
+
+%.os: %.c %.o
+ if $(COMPILE) -c -o $@ -fpic -DPIC -DSHARED -MT $@ -MD -MP \
+ -MF "$(DEPDIR)/$*.Tpo" `test -f '$<' || echo '$(srcdir)/'`$<; \
+ then cat "$(DEPDIR)/$*.Tpo" >> "$(DEPDIR)/$*.Po"; \
+ rm -f "$(DEPDIR)/$*.Tpo"; \
+ else rm -f "$(DEPDIR)/$*.Tpo"; exit 1; \
+ fi
+
+install: install-am libdwarf.so
+ $(mkinstalldirs) $(DESTDIR)$(libdir)
+ $(INSTALL_PROGRAM) libdwarf.so $(DESTDIR)$(libdir)/libdwarf-$(PACKAGE_VERSION).so
+ ln -fs libdwarf-$(PACKAGE_VERSION).so $(DESTDIR)$(libdir)/libdwarf.so.$(VERSION)
+ ln -fs libdwarf.so.$(VERSION) $(DESTDIR)$(libdir)/libdwarf.so
+
+uninstall: uninstall-am
+ rm -f $(DESTDIR)$(libdir)/libdwarf-$(PACKAGE_VERSION).so
+ rm -f $(DESTDIR)$(libdir)/libdwarf.so.$(VERSION)
+ rm -f $(DESTDIR)$(libdir)/libdwarf.so
+ rmdir --ignore-fail-on-non-empty $(DESTDIR)$(includedir)/elfutils
+
+noinst_HEADERS = libdwarfP.h memory-access.h dwarf_abbrev_hash.h
+EXTRA_DIST = AVAILABLE libdwarf.map
+
+CLEANFILES = $(am_libdwarf_pic_a_OBJECTS)
diff --git a/libdwarf/dwarf.h b/libdwarf/dwarf.h
new file mode 100644
index 00000000..81bdcc45
--- /dev/null
+++ b/libdwarf/dwarf.h
@@ -0,0 +1,549 @@
+/* This file defines standard DWARF types, structures, and macros.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifndef _DWARF_H
+#define _DWARF_H 1
+
+/* DWARF tags. */
+enum
+ {
+ DW_TAG_array_type = 0x01,
+ DW_TAG_class_type = 0x02,
+ DW_TAG_entry_point = 0x03,
+ DW_TAG_enumeration_type = 0x04,
+ DW_TAG_formal_parameter = 0x05,
+ DW_TAG_imported_declaration = 0x08,
+ DW_TAG_label = 0x0a,
+ DW_TAG_lexical_block = 0x0b,
+ DW_TAG_member = 0x0d,
+ DW_TAG_pointer_type = 0x0f,
+ DW_TAG_reference_type = 0x10,
+ DW_TAG_compile_unit = 0x11,
+ DW_TAG_string_type = 0x12,
+ DW_TAG_structure_type = 0x13,
+ DW_TAG_subroutine_type = 0x15,
+ DW_TAG_typedef = 0x16,
+ DW_TAG_union_type = 0x17,
+ DW_TAG_unspecified_parameters = 0x18,
+ DW_TAG_variant = 0x19,
+ DW_TAG_common_block = 0x1a,
+ DW_TAG_common_inclusion = 0x1b,
+ DW_TAG_inheritance = 0x1c,
+ DW_TAG_inlined_subroutine = 0x1d,
+ DW_TAG_module = 0x1e,
+ DW_TAG_ptr_to_member_type = 0x1f,
+ DW_TAG_set_type = 0x20,
+ DW_TAG_subrange_type = 0x21,
+ DW_TAG_with_stmt = 0x22,
+ DW_TAG_access_declaration = 0x23,
+ DW_TAG_base_type = 0x24,
+ DW_TAG_catch_block = 0x25,
+ DW_TAG_const_type = 0x26,
+ DW_TAG_constant = 0x27,
+ DW_TAG_enumerator = 0x28,
+ DW_TAG_file_type = 0x29,
+ DW_TAG_friend = 0x2a,
+ DW_TAG_namelist = 0x2b,
+ DW_TAG_namelist_item = 0x2c,
+ DW_TAG_packed_type = 0x2d,
+ DW_TAG_subprogram = 0x2e,
+ DW_TAG_template_type_param = 0x2f,
+ DW_TAG_template_value_param = 0x30,
+ DW_TAG_thrown_type = 0x31,
+ DW_TAG_try_block = 0x32,
+ DW_TAG_variant_part = 0x33,
+ DW_TAG_variable = 0x34,
+ DW_TAG_volatile_type = 0x35,
+ DW_TAG_lo_user = 0x4080,
+ DW_TAG_MIPS_loop = 0x4081,
+ DW_TAG_format_label = 0x4101,
+ DW_TAG_function_template = 0x4102,
+ DW_TAG_class_template = 0x4103,
+ DW_TAG_hi_user = 0xffff
+ };
+
+
+/* Children determination encodings. */
+enum
+ {
+ DW_CHILDREN_no = 0,
+ DW_CHILDREN_yes = 1
+ };
+
+
+/* DWARF attributes encodings. */
+enum
+ {
+ DW_AT_sibling = 0x01,
+ DW_AT_location = 0x02,
+ DW_AT_name = 0x03,
+ DW_AT_ordering = 0x09,
+ DW_AT_subscr_data = 0x0a,
+ DW_AT_byte_size = 0x0b,
+ DW_AT_bit_offset = 0x0c,
+ DW_AT_bit_size = 0x0d,
+ DW_AT_element_list = 0x0f,
+ DW_AT_stmt_list = 0x10,
+ DW_AT_low_pc = 0x11,
+ DW_AT_high_pc = 0x12,
+ DW_AT_language = 0x13,
+ DW_AT_member = 0x14,
+ DW_AT_discr = 0x15,
+ DW_AT_discr_value = 0x16,
+ DW_AT_visibility = 0x17,
+ DW_AT_import = 0x18,
+ DW_AT_string_length = 0x19,
+ DW_AT_common_reference = 0x1a,
+ DW_AT_comp_dir = 0x1b,
+ DW_AT_const_value = 0x1c,
+ DW_AT_containing_type = 0x1d,
+ DW_AT_default_value = 0x1e,
+ DW_AT_inline = 0x20,
+ DW_AT_is_optional = 0x21,
+ DW_AT_lower_bound = 0x22,
+ DW_AT_producer = 0x25,
+ DW_AT_prototyped = 0x27,
+ DW_AT_return_addr = 0x2a,
+ DW_AT_start_scope = 0x2c,
+ DW_AT_stride_size = 0x2e,
+ DW_AT_upper_bound = 0x2f,
+ DW_AT_abstract_origin = 0x31,
+ DW_AT_accessibility = 0x32,
+ DW_AT_address_class = 0x33,
+ DW_AT_artificial = 0x34,
+ DW_AT_base_types = 0x35,
+ DW_AT_calling_convention = 0x36,
+ DW_AT_count = 0x37,
+ DW_AT_data_member_location = 0x38,
+ DW_AT_decl_column = 0x39,
+ DW_AT_decl_file = 0x3a,
+ DW_AT_decl_line = 0x3b,
+ DW_AT_declaration = 0x3c,
+ DW_AT_discr_list = 0x3d,
+ DW_AT_encoding = 0x3e,
+ DW_AT_external = 0x3f,
+ DW_AT_frame_base = 0x40,
+ DW_AT_friend = 0x41,
+ DW_AT_identifier_case = 0x42,
+ DW_AT_macro_info = 0x43,
+ DW_AT_namelist_items = 0x44,
+ DW_AT_priority = 0x45,
+ DW_AT_segment = 0x46,
+ DW_AT_specification = 0x47,
+ DW_AT_static_link = 0x48,
+ DW_AT_type = 0x49,
+ DW_AT_use_location = 0x4a,
+ DW_AT_variable_parameter = 0x4b,
+ DW_AT_virtuality = 0x4c,
+ DW_AT_vtable_elem_location = 0x4d,
+ DW_AT_lo_user = 0x2000,
+ DW_AT_MIPS_fde = 0x2001,
+ DW_AT_MIPS_loop_begin = 0x2002,
+ DW_AT_MIPS_tail_loop_begin = 0x2003,
+ DW_AT_MIPS_epilog_begin = 0x2004,
+ DW_AT_MIPS_loop_unroll_factor = 0x2005,
+ DW_AT_MIPS_software_pipeline_depth = 0x2006,
+ DW_AT_MIPS_linkage_name = 0x2007,
+ DW_AT_MIPS_stride = 0x2008,
+ DW_AT_MIPS_abstract_name = 0x2009,
+ DW_AT_MIPS_clone_origin = 0x200a,
+ DW_AT_MIPS_has_inlines = 0x200b,
+ DW_AT_MIPS_stride_byte = 0x200c,
+ DW_AT_MIPS_stride_elem = 0x200d,
+ DW_AT_MIPS_ptr_dopetype = 0x200e,
+ DW_AT_MIPS_allocatable_dopetype = 0x200f,
+ DW_AT_MIPS_assumed_shape_dopetype = 0x2010,
+ DW_AT_MIPS_assumed_size = 0x2011,
+ DW_AT_sf_names = 0x2101,
+ DW_AT_src_info = 0x2102,
+ DW_AT_mac_info = 0x2103,
+ DW_AT_src_coords = 0x2104,
+ DW_AT_body_begin = 0x2105,
+ DW_AT_body_end = 0x2106,
+ DW_AT_hi_user = 0x3fff
+ };
+
+
+/* DWARF form encodings. */
+enum
+ {
+ DW_FORM_addr = 0x01,
+ DW_FORM_block2 = 0x03,
+ DW_FORM_block4 = 0x04,
+ DW_FORM_data2 = 0x05,
+ DW_FORM_data4 = 0x06,
+ DW_FORM_data8 = 0x07,
+ DW_FORM_string = 0x08,
+ DW_FORM_block = 0x09,
+ DW_FORM_block1 = 0x0a,
+ DW_FORM_data1 = 0x0b,
+ DW_FORM_flag = 0x0c,
+ DW_FORM_sdata = 0x0d,
+ DW_FORM_strp = 0x0e,
+ DW_FORM_udata = 0x0f,
+ DW_FORM_ref_addr = 0x10,
+ DW_FORM_ref1 = 0x11,
+ DW_FORM_ref2 = 0x12,
+ DW_FORM_ref4 = 0x13,
+ DW_FORM_ref8 = 0x14,
+ DW_FORM_ref_udata = 0x15,
+ DW_FORM_indirect = 0x16
+ };
+
+
+/* DWARF location operation encodings. */
+enum
+ {
+ DW_OP_addr = 0x03, /* Constant address. */
+ DW_OP_deref = 0x06,
+ DW_OP_const1u = 0x08, /* Unsigned 1-byte constant. */
+ DW_OP_const1s = 0x09, /* Signed 1-byte constant. */
+ DW_OP_const2u = 0x0a, /* Unsigned 2-byte constant. */
+ DW_OP_const2s = 0x0b, /* Signed 2-byte constant. */
+ DW_OP_const4u = 0x0c, /* Unsigned 4-byte constant. */
+ DW_OP_const4s = 0x0d, /* Signed 4-byte constant. */
+ DW_OP_const8u = 0x0e, /* Unsigned 8-byte constant. */
+ DW_OP_const8s = 0x0f, /* Signed 8-byte constant. */
+ DW_OP_constu = 0x10, /* Unsigned LEB128 constant. */
+ DW_OP_consts = 0x11, /* Signed LEB128 constant. */
+ DW_OP_dup = 0x12,
+ DW_OP_drop = 0x13,
+ DW_OP_over = 0x14,
+ DW_OP_pick = 0x15, /* 1-byte stack index. */
+ DW_OP_swap = 0x16,
+ DW_OP_rot = 0x17,
+ DW_OP_xderef = 0x18,
+ DW_OP_abs = 0x19,
+ DW_OP_and = 0x1a,
+ DW_OP_div = 0x1b,
+ DW_OP_minus = 0x1c,
+ DW_OP_mod = 0x1d,
+ DW_OP_mul = 0x1e,
+ DW_OP_neg = 0x1f,
+ DW_OP_not = 0x20,
+ DW_OP_or = 0x21,
+ DW_OP_plus = 0x22,
+ DW_OP_plus_uconst = 0x23, /* Unsigned LEB128 addend. */
+ DW_OP_shl = 0x24,
+ DW_OP_shr = 0x25,
+ DW_OP_shra = 0x26,
+ DW_OP_xor = 0x27,
+ DW_OP_bra = 0x28, /* Signed 2-byte constant. */
+ DW_OP_eq = 0x29,
+ DW_OP_ge = 0x2a,
+ DW_OP_gt = 0x2b,
+ DW_OP_le = 0x2c,
+ DW_OP_lt = 0x2d,
+ DW_OP_ne = 0x2e,
+ DW_OP_skip = 0x2f, /* Signed 2-byte constant. */
+ DW_OP_lit0 = 0x30, /* Literal 0. */
+ DW_OP_lit1 = 0x31, /* Literal 1. */
+ DW_OP_lit2 = 0x32, /* Literal 2. */
+ DW_OP_lit3 = 0x33, /* Literal 3. */
+ DW_OP_lit4 = 0x34, /* Literal 4. */
+ DW_OP_lit5 = 0x35, /* Literal 5. */
+ DW_OP_lit6 = 0x36, /* Literal 6. */
+ DW_OP_lit7 = 0x37, /* Literal 7. */
+ DW_OP_lit8 = 0x38, /* Literal 8. */
+ DW_OP_lit9 = 0x39, /* Literal 9. */
+ DW_OP_lit10 = 0x3a, /* Literal 10. */
+ DW_OP_lit11 = 0x3b, /* Literal 11. */
+ DW_OP_lit12 = 0x3c, /* Literal 12. */
+ DW_OP_lit13 = 0x3d, /* Literal 13. */
+ DW_OP_lit14 = 0x3e, /* Literal 14. */
+ DW_OP_lit15 = 0x3f, /* Literal 15. */
+ DW_OP_lit16 = 0x40, /* Literal 16. */
+ DW_OP_lit17 = 0x41, /* Literal 17. */
+ DW_OP_lit18 = 0x42, /* Literal 18. */
+ DW_OP_lit19 = 0x43, /* Literal 19. */
+ DW_OP_lit20 = 0x44, /* Literal 20. */
+ DW_OP_lit21 = 0x45, /* Literal 21. */
+ DW_OP_lit22 = 0x46, /* Literal 22. */
+ DW_OP_lit23 = 0x47, /* Literal 23. */
+ DW_OP_lit24 = 0x48, /* Literal 24. */
+ DW_OP_lit25 = 0x49, /* Literal 25. */
+ DW_OP_lit26 = 0x4a, /* Literal 26. */
+ DW_OP_lit27 = 0x4b, /* Literal 27. */
+ DW_OP_lit28 = 0x4c, /* Literal 28. */
+ DW_OP_lit29 = 0x4d, /* Literal 29. */
+ DW_OP_lit30 = 0x4e, /* Literal 30. */
+ DW_OP_lit31 = 0x4f, /* Literal 31. */
+ DW_OP_reg0 = 0x50, /* Register 0. */
+ DW_OP_reg1 = 0x51, /* Register 1. */
+ DW_OP_reg2 = 0x52, /* Register 2. */
+ DW_OP_reg3 = 0x53, /* Register 3. */
+ DW_OP_reg4 = 0x54, /* Register 4. */
+ DW_OP_reg5 = 0x55, /* Register 5. */
+ DW_OP_reg6 = 0x56, /* Register 6. */
+ DW_OP_reg7 = 0x57, /* Register 7. */
+ DW_OP_reg8 = 0x58, /* Register 8. */
+ DW_OP_reg9 = 0x59, /* Register 9. */
+ DW_OP_reg10 = 0x5a, /* Register 10. */
+ DW_OP_reg11 = 0x5b, /* Register 11. */
+ DW_OP_reg12 = 0x5c, /* Register 12. */
+ DW_OP_reg13 = 0x5d, /* Register 13. */
+ DW_OP_reg14 = 0x5e, /* Register 14. */
+ DW_OP_reg15 = 0x5f, /* Register 15. */
+ DW_OP_reg16 = 0x60, /* Register 16. */
+ DW_OP_reg17 = 0x61, /* Register 17. */
+ DW_OP_reg18 = 0x62, /* Register 18. */
+ DW_OP_reg19 = 0x63, /* Register 19. */
+ DW_OP_reg20 = 0x64, /* Register 20. */
+ DW_OP_reg21 = 0x65, /* Register 21. */
+ DW_OP_reg22 = 0x66, /* Register 22. */
+ DW_OP_reg23 = 0x67, /* Register 24. */
+ DW_OP_reg24 = 0x68, /* Register 24. */
+ DW_OP_reg25 = 0x69, /* Register 25. */
+ DW_OP_reg26 = 0x6a, /* Register 26. */
+ DW_OP_reg27 = 0x6b, /* Register 27. */
+ DW_OP_reg28 = 0x6c, /* Register 28. */
+ DW_OP_reg29 = 0x6d, /* Register 29. */
+ DW_OP_reg30 = 0x6e, /* Register 30. */
+ DW_OP_reg31 = 0x6f, /* Register 31. */
+ DW_OP_breg0 = 0x70, /* Base register 0. */
+ DW_OP_breg1 = 0x71, /* Base register 1. */
+ DW_OP_breg2 = 0x72, /* Base register 2. */
+ DW_OP_breg3 = 0x73, /* Base register 3. */
+ DW_OP_breg4 = 0x74, /* Base register 4. */
+ DW_OP_breg5 = 0x75, /* Base register 5. */
+ DW_OP_breg6 = 0x76, /* Base register 6. */
+ DW_OP_breg7 = 0x77, /* Base register 7. */
+ DW_OP_breg8 = 0x78, /* Base register 8. */
+ DW_OP_breg9 = 0x79, /* Base register 9. */
+ DW_OP_breg10 = 0x7a, /* Base register 10. */
+ DW_OP_breg11 = 0x7b, /* Base register 11. */
+ DW_OP_breg12 = 0x7c, /* Base register 12. */
+ DW_OP_breg13 = 0x7d, /* Base register 13. */
+ DW_OP_breg14 = 0x7e, /* Base register 14. */
+ DW_OP_breg15 = 0x7f, /* Base register 15. */
+ DW_OP_breg16 = 0x80, /* Base register 16. */
+ DW_OP_breg17 = 0x81, /* Base register 17. */
+ DW_OP_breg18 = 0x82, /* Base register 18. */
+ DW_OP_breg19 = 0x83, /* Base register 19. */
+ DW_OP_breg20 = 0x84, /* Base register 20. */
+ DW_OP_breg21 = 0x85, /* Base register 21. */
+ DW_OP_breg22 = 0x86, /* Base register 22. */
+ DW_OP_breg23 = 0x87, /* Base register 23. */
+ DW_OP_breg24 = 0x88, /* Base register 24. */
+ DW_OP_breg25 = 0x89, /* Base register 25. */
+ DW_OP_breg26 = 0x8a, /* Base register 26. */
+ DW_OP_breg27 = 0x8b, /* Base register 27. */
+ DW_OP_breg28 = 0x8c, /* Base register 28. */
+ DW_OP_breg29 = 0x8d, /* Base register 29. */
+ DW_OP_breg30 = 0x8e, /* Base register 30. */
+ DW_OP_breg31 = 0x8f, /* Base register 31. */
+ DW_OP_regx = 0x90, /* Unsigned LEB128 register. */
+ DW_OP_fbreg = 0x91, /* Signed LEB128 register. */
+ DW_OP_bregx = 0x92, /* ULEB128 register followed by SLEB128 off. */
+ DW_OP_piece = 0x93, /* ULEB128 size of piece addressed. */
+ DW_OP_deref_size = 0x94, /* 1-byte size of data retrieved. */
+ DW_OP_xderef_size = 0x95, /* 1-byte size of data retrieved. */
+ DW_OP_nop = 0x96,
+ DW_OP_push_object_address = 0x97,
+ DW_OP_call2 = 0x98,
+ DW_OP_call4 = 0x99,
+ DW_OP_call_ref = 0x9a,
+
+ DW_OP_lo_user = 0xe0, /* Implementation-defined range start. */
+ DW_OP_hi_user = 0xff /* Implementation-defined range end. */
+ };
+
+
+/* DWARF base type encodings. */
+enum
+ {
+ DW_ATE_void = 0x0,
+ DW_ATE_address = 0x1,
+ DW_ATE_boolean = 0x2,
+ DW_ATE_complex_float = 0x3,
+ DW_ATE_float = 0x4,
+ DW_ATE_signed = 0x5,
+ DW_ATE_signed_char = 0x6,
+ DW_ATE_unsigned = 0x7,
+ DW_ATE_unsigned_char = 0x8,
+
+ DW_ATE_lo_user = 0x80,
+ DW_ATE_hi_user = 0xff
+ };
+
+
+/* DWARF accessibility encodings. */
+enum
+ {
+ DW_ACCESS_public = 1,
+ DW_ACCESS_protected = 2,
+ DW_ACCESS_private = 3
+ };
+
+
+/* DWARF visibility encodings. */
+enum
+ {
+ DW_VIS_local = 1,
+ DW_VIS_exported = 2,
+ DW_VIS_qualified = 3
+ };
+
+
+/* DWARF virtuality encodings. */
+enum
+ {
+ DW_VIRTUALITY_none = 0,
+ DW_VIRTUALITY_virtual = 1,
+ DW_VIRTUALITY_pure_virtual = 2
+ };
+
+
+/* DWARF language encodings. */
+enum
+ {
+ DW_LANG_C89 = 0x0001,
+ DW_LANG_C = 0x0002,
+ DW_LANG_Ada83 = 0x0003,
+ DW_LANG_C_plus_plus = 0x0004,
+ DW_LANG_Cobol74 = 0x0005,
+ DW_LANG_Cobol85 = 0x0006,
+ DW_LANG_Fortran77 = 0x0007,
+ DW_LANG_Fortran90 = 0x0008,
+ DW_LANG_Pascal83 = 0x0009,
+ DW_LANG_Modula2 = 0x000a,
+ DW_LANG_Java = 0x000b,
+ DW_LANG_C99 = 0x000c,
+ DW_LANG_Ada95 = 0x000d,
+ DW_LANG_Fortran95 = 0x000e,
+ DW_LANG_PL1 = 0x000f,
+ DW_LANG_lo_user = 0x8000,
+ DW_LANG_Mips_Assembler = 0x8001,
+ DW_LANG_hi_user = 0xffff
+ };
+
+
+/* DWARF identifier case encodings. */
+enum
+ {
+ DW_ID_case_sensitive = 0,
+ DW_ID_up_case = 1,
+ DW_ID_down_case = 2,
+ DW_ID_case_insensitive = 3
+ };
+
+
+/* DWARF calling conventions encodings. */
+enum
+ {
+ DW_CC_normal = 0x1,
+ DW_CC_program = 0x2,
+ DW_CC_nocall = 0x3,
+ DW_CC_lo_user = 0x40,
+ DW_CC_hi_user = 0xff
+ };
+
+
+/* DWARF inline encodings. */
+enum
+ {
+ DW_INL_not_inlined = 0,
+ DW_INL_inlined = 1,
+ DW_INL_declared_not_inlined = 2,
+ DW_INL_declared_inlined = 3
+ };
+
+
+/* DWARF ordering encodings. */
+enum
+ {
+ DW_ORD_row_major = 0,
+ DW_ORD_col_major = 1
+ };
+
+
+/* DWARF discriminant descriptor encodings. */
+enum
+ {
+ DW_DSC_label = 0,
+ DW_DSC_range = 1
+ };
+
+
+/* DWARF standard opcode encodings. */
+enum
+ {
+ DW_LNS_copy = 1,
+ DW_LNS_advance_pc = 2,
+ DW_LNS_advance_line = 3,
+ DW_LNS_set_file = 4,
+ DW_LNS_set_column = 5,
+ DW_LNS_negate_stmt = 6,
+ DW_LNS_set_basic_block = 7,
+ DW_LNS_const_add_pc = 8,
+ DW_LNS_fixed_advance_pc = 9,
+ DW_LNS_set_prologue_end = 10,
+ DW_LNS_set_epilog_begin = 11
+ };
+
+
+/* DWARF extended opcide encodings. */
+enum
+ {
+ DW_LNE_end_sequence = 1,
+ DW_LNE_set_address = 2,
+ DW_LNE_define_file = 3
+ };
+
+
+/* DWARF macinfo type encodings. */
+enum
+ {
+ DW_MACINFO_define = 1,
+ DW_MACINFO_undef = 2,
+ DW_MACINFO_start_file = 3,
+ DW_MACINFO_end_file = 4,
+ DW_MACINFO_vendor_ext = 255
+ };
+
+
+/* DWARF call frame instruction encodings. */
+enum
+ {
+ DW_CFA_advance_loc = 0x40,
+ DW_CFA_offset = 0x80,
+ DW_CFA_restore = 0xc0,
+ DW_CFA_extended = 0,
+
+ DW_CFA_nop = 0x00,
+ DW_CFA_set_loc = 0x01,
+ DW_CFA_advance_loc1 = 0x02,
+ DW_CFA_advance_loc2 = 0x03,
+ DW_CFA_advance_loc4 = 0x04,
+ DW_CFA_offset_extended = 0x05,
+ DW_CFA_restore_extended = 0x06,
+ DW_CFA_undefined = 0x07,
+ DW_CFA_same_value = 0x08,
+ DW_CFA_register = 0x09,
+ DW_CFA_remember_state = 0x0a,
+ DW_CFA_restore_state = 0x0b,
+ DW_CFA_def_cfa = 0x0c,
+ DW_CFA_def_cfa_register = 0x0d,
+ DW_CFA_def_cfa_offset = 0x0e,
+ DW_CFA_low_user = 0x1c,
+ DW_CFA_MIPS_advance_loc8 = 0x1d,
+ DW_CFA_GNU_window_save = 0x2d,
+ DW_CFA_GNU_args_size = 0x2e,
+ DW_CFA_high_user = 0x3f
+ };
+
+
+/* DWARF XXX. */
+#define DW_ADDR_none 0
+
+#endif /* dwarf.h */
diff --git a/libdwarf/dwarf_abbrev_hash.c b/libdwarf/dwarf_abbrev_hash.c
new file mode 100644
index 00000000..a1964498
--- /dev/null
+++ b/libdwarf/dwarf_abbrev_hash.c
@@ -0,0 +1,29 @@
+/* Implementation of hash table for DWARF .debug_abbrev section content.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#define NO_UNDEF
+#include "libdwarfP.h"
+
+#define next_prime __libdwarf_next_prime
+extern size_t next_prime (size_t) attribute_hidden;
+
+#include <dynamicsizehash.c>
+
+#undef next_prime
+#define next_prime attribute_hidden __libdwarf_next_prime
+#include "../lib/next_prime.c"
diff --git a/libdwarf/dwarf_abbrev_hash.h b/libdwarf/dwarf_abbrev_hash.h
new file mode 100644
index 00000000..45c23462
--- /dev/null
+++ b/libdwarf/dwarf_abbrev_hash.h
@@ -0,0 +1,24 @@
+/* Hash table for DWARF .debug_abbrev section content.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifndef _DWARF_ABBREV_HASH_H
+#define _DWARF_ABBREV_HASH_H 1
+
+#define NAME Dwarf_Abbrev_Hash
+#define TYPE Dwarf_Abbrev
+#define COMPARE(a, b) (0)
+
+#include <dynamicsizehash.h>
+
+#endif /* dwarf_abbrev_hash.h */
diff --git a/libdwarf/dwarf_arrayorder.c b/libdwarf/dwarf_arrayorder.c
new file mode 100644
index 00000000..88f30800
--- /dev/null
+++ b/libdwarf/dwarf_arrayorder.c
@@ -0,0 +1,31 @@
+/* Return array ordering information associated with die.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_arrayorder (die, return_order, error)
+ Dwarf_Die die;
+ Dwarf_Unsigned *return_order;
+ Dwarf_Error *error;
+{
+ return __libdwarf_getconstant (die, DW_AT_ordering, return_order, error);
+}
diff --git a/libdwarf/dwarf_attr.c b/libdwarf/dwarf_attr.c
new file mode 100644
index 00000000..f1b20f4d
--- /dev/null
+++ b/libdwarf/dwarf_attr.c
@@ -0,0 +1,113 @@
+/* Return die attribute with specified of given type.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_attr (die, attr, return_attr, error)
+ Dwarf_Die die;
+ Dwarf_Half attr;
+ Dwarf_Attribute *return_attr;
+ Dwarf_Error *error;
+{
+ Dwarf_Debug dbg = die->cu->dbg;
+ Dwarf_Small *die_addr;
+ Dwarf_Word u128;
+ Dwarf_Abbrev abbrev;
+ Dwarf_Small *attrp;
+
+ /* Address of the given die. */
+ die_addr = die->addr;
+
+ /* Get abbrev code. */
+ get_uleb128 (u128, die_addr);
+ /* And get the abbreviation itself. */
+ abbrev = __libdwarf_get_abbrev (dbg, die->cu, u128, error);
+ if (abbrev == NULL)
+ return DW_DLV_ERROR;
+
+ /* This is where the attributes start. */
+ attrp = abbrev->attrp;
+
+ /* Search the name attribute. */
+ while (1)
+ {
+ Dwarf_Word attr_name;
+ Dwarf_Word attr_form;
+
+ /* Are we still in bounds? */
+ if (unlikely (attrp
+ >= ((Dwarf_Small *) dbg->sections[IDX_debug_abbrev].addr
+ + dbg->sections[IDX_debug_abbrev].size)))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* Get attribute name and form.
+
+ XXX We don't check whether this reads beyond the end of the
+ section. */
+ get_uleb128 (attr_name, attrp);
+ get_uleb128 (attr_form, attrp);
+
+ /* We can stop if we found the attribute with value zero. */
+ if (attr_name == 0 && attr_form == 0)
+ break;
+
+ /* Is this the name attribute? */
+ if (attr_name == attr)
+ {
+ Dwarf_Attribute new_attr;
+
+ new_attr =
+ (Dwarf_Attribute) malloc (sizeof (struct Dwarf_Attribute_s));
+ if (new_attr == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ new_attr->code = attr_name;
+ new_attr->form = attr_form;
+ new_attr->valp = die_addr;
+ new_attr->cu = die->cu;
+
+ *return_attr = new_attr;
+ return DW_DLV_OK;
+ }
+
+ /* Skip over the rest of this attribute (if there is any). */
+ if (attr_form != 0)
+ {
+ size_t len;
+
+ if (__libdwarf_form_val_len (dbg, die->cu, attr_form, die_addr, &len,
+ error) != DW_DLV_OK)
+ return DW_DLV_ERROR;
+
+ die_addr += len;
+ }
+ }
+
+ /* No such attribute present. */
+ return DW_DLV_NO_ENTRY;
+}
diff --git a/libdwarf/dwarf_attrlist.c b/libdwarf/dwarf_attrlist.c
new file mode 100644
index 00000000..bef5a112
--- /dev/null
+++ b/libdwarf/dwarf_attrlist.c
@@ -0,0 +1,182 @@
+/* Return attribute list for die.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <libdwarfP.h>
+
+
+struct attrlist
+{
+ struct attrlist *next;
+ Dwarf_Attribute attr;
+};
+
+
+int
+dwarf_attrlist (die, attrbuf, attrcount, error)
+ Dwarf_Die die;
+ Dwarf_Attribute **attrbuf;
+ Dwarf_Signed *attrcount;
+ Dwarf_Error *error;
+{
+ Dwarf_Debug dbg = die->cu->dbg;
+ Dwarf_Small *die_addr;
+ Dwarf_Word u128;
+ Dwarf_Abbrev abbrev;
+ Dwarf_Small *attrp;
+ struct attrlist *alist;
+ int nattr;
+ Dwarf_Attribute *result;
+
+ /* Address of the given die. */
+ die_addr = die->addr;
+
+ /* Get abbrev code. */
+ get_uleb128 (u128, die_addr);
+ /* And get the abbreviation itself. */
+ abbrev = __libdwarf_get_abbrev (dbg, die->cu, u128, error);
+ if (abbrev == NULL)
+ return DW_DLV_ERROR;
+
+ /* This is where the attributes start. */
+ attrp = abbrev->attrp;
+
+ /* Initialize the list. We create one because we don't know yet how
+ many attributes there will be. */
+ alist = NULL;
+ nattr = 0;
+
+ /* Go over the list of attributes. */
+ while (1)
+ {
+ Dwarf_Word attr_name;
+ Dwarf_Word attr_form;
+ Dwarf_Attribute new_attr;
+ struct attrlist *new_alist;
+
+ /* Are we still in bounds? */
+ if (unlikely (attrp
+ >= ((Dwarf_Small *) dbg->sections[IDX_debug_abbrev].addr
+ + dbg->sections[IDX_debug_abbrev].size)))
+ {
+ while (alist != NULL)
+ {
+ free (alist->attr);
+ alist = alist->next;
+ }
+
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* Get attribute name and form.
+
+ XXX We don't check whether this reads beyond the end of the
+ section. */
+ get_uleb128 (attr_name, attrp);
+ get_uleb128 (attr_form, attrp);
+
+ /* We can stop if we found the attribute with value zero. */
+ if (attr_name == 0 && attr_form == 0)
+ break;
+
+ /* Allocate the attribute data structure. */
+ new_attr = (Dwarf_Attribute) malloc (sizeof (struct Dwarf_Attribute_s));
+ if (new_attr == NULL)
+ {
+ while (alist != NULL)
+ {
+ free (alist->attr);
+ alist = alist->next;
+ }
+
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ /* Fill in the values. */
+ new_attr->code = attr_name;
+ new_attr->form = attr_form;
+ new_attr->valp = die_addr;
+ new_attr->cu = die->cu;
+
+ /* Enqueue. */
+ new_alist = (struct attrlist *) alloca (sizeof (struct attrlist));
+ new_alist->attr = new_attr;
+ new_alist->next = alist;
+ alist = new_alist;
+ ++nattr;
+
+ /* Skip over the rest of this attribute (if there is any). */
+ if (attr_form != 0)
+ {
+ size_t len;
+
+ if (unlikely (__libdwarf_form_val_len (dbg, die->cu, attr_form,
+ die_addr, &len, error)
+ != DW_DLV_OK))
+ {
+ while (alist != NULL)
+ {
+ free (alist->attr);
+ alist = alist->next;
+ }
+
+ return DW_DLV_ERROR;
+ }
+
+ die_addr += len;
+ }
+ }
+
+ if (nattr == 0)
+ {
+ *attrcount = 0;
+ *attrbuf = NULL;
+ return DW_DLV_NO_ENTRY;
+ }
+
+ /* Allocate the array for the result. */
+ result = (Dwarf_Attribute *) malloc (nattr * sizeof (Dwarf_Attribute));
+ if (result == NULL)
+ {
+ while (alist != NULL)
+ {
+ free (alist->attr);
+ alist = alist->next;
+ }
+
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ /* Store the number of attributes and the result pointer. */
+ *attrcount = nattr;
+ *attrbuf = result;
+
+ /* Put the attribute entries in the array (in the right order). */
+ do
+ {
+ result[--nattr] = alist->attr;
+ alist = alist->next;
+ }
+ while (nattr > 0);
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_bitoffset.c b/libdwarf/dwarf_bitoffset.c
new file mode 100644
index 00000000..bfc91654
--- /dev/null
+++ b/libdwarf/dwarf_bitoffset.c
@@ -0,0 +1,31 @@
+/* Return bit offset value associated with die.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_bitoffset (die, return_size, error)
+ Dwarf_Die die;
+ Dwarf_Unsigned *return_size;
+ Dwarf_Error *error;
+{
+ return __libdwarf_getconstant (die, DW_AT_bit_offset, return_size, error);
+}
diff --git a/libdwarf/dwarf_bitsize.c b/libdwarf/dwarf_bitsize.c
new file mode 100644
index 00000000..007975c7
--- /dev/null
+++ b/libdwarf/dwarf_bitsize.c
@@ -0,0 +1,31 @@
+/* Return bit size value associated with die.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_bitsize (die, return_size, error)
+ Dwarf_Die die;
+ Dwarf_Unsigned *return_size;
+ Dwarf_Error *error;
+{
+ return __libdwarf_getconstant (die, DW_AT_bit_size, return_size, error);
+}
diff --git a/libdwarf/dwarf_bytesize.c b/libdwarf/dwarf_bytesize.c
new file mode 100644
index 00000000..68d728ad
--- /dev/null
+++ b/libdwarf/dwarf_bytesize.c
@@ -0,0 +1,31 @@
+/* Return byte size value associated with die.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_bytesize (die, return_size, error)
+ Dwarf_Die die;
+ Dwarf_Unsigned *return_size;
+ Dwarf_Error *error;
+{
+ return __libdwarf_getconstant (die, DW_AT_byte_size, return_size, error);
+}
diff --git a/libdwarf/dwarf_child.c b/libdwarf/dwarf_child.c
new file mode 100644
index 00000000..ee9c8336
--- /dev/null
+++ b/libdwarf/dwarf_child.c
@@ -0,0 +1,123 @@
+/* Return child of die.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_child (die, return_kid, error)
+ Dwarf_Die die;
+ Dwarf_Die *return_kid;
+ Dwarf_Error *error;
+{
+ Dwarf_Debug dbg = die->cu->dbg;
+ Dwarf_Abbrev abbrev;
+ Dwarf_Small *attrp;
+ Dwarf_Small *die_addr;
+ Dwarf_Word u128;
+ Dwarf_Die new_die;
+
+ if (! die->abbrev->has_children)
+ return DW_DLV_NO_ENTRY;
+
+ /* Address of the given die. */
+ die_addr = die->addr;
+
+ /* Get abbrev code. */
+ get_uleb128 (u128, die_addr);
+ /* And get the abbreviation itself. */
+ abbrev = __libdwarf_get_abbrev (dbg, die->cu, u128, error);
+ if (abbrev == NULL)
+ return DW_DLV_ERROR;
+
+ /* This is where the attributes start. */
+ attrp = abbrev->attrp;
+
+ /* Skip over the attributes of the given die. */
+ while (1)
+ {
+ Dwarf_Word attr_name;
+ Dwarf_Word attr_form;
+
+ /* Are we still in bounds? */
+ if (unlikely (attrp
+ >= ((Dwarf_Small *)dbg->sections[IDX_debug_abbrev].addr
+ + dbg->sections[IDX_debug_abbrev].size)))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* Get attribute name and form.
+
+ XXX We don't check whether this reads beyond the end of the
+ section. */
+ get_uleb128 (attr_name, attrp);
+ get_uleb128 (attr_form, attrp);
+
+ /* We can stop if we found the attribute with value zero. */
+ if (attr_name == 0 && attr_form == 0)
+ break;
+
+ /* Skip over the rest of this attribute (if there is any). */
+ if (attr_form != 0)
+ {
+ size_t len;
+
+ if (unlikely (__libdwarf_form_val_len (dbg, die->cu, attr_form,
+ die_addr, &len, error)
+ != DW_DLV_OK))
+ return DW_DLV_ERROR;
+
+ die_addr += len;
+ }
+ }
+
+ /* Allocate the die structure for the result. */
+ new_die = (Dwarf_Die) malloc (sizeof (struct Dwarf_Die_s));
+ if (new_die == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+#ifdef DWARF_DEBUG
+ new_die->memtag = DW_DLA_DIE;
+#endif
+
+ /* Remember the address. */
+ new_die->addr = die_addr;
+
+ /* And the compile unit. */
+ new_die->cu = die->cu;
+
+ /* 7.5.2 Debugging Information Entry
+
+ Each debugging information entry begins with an unsigned LEB128
+ number containing the abbreviation code for the entry. */
+ get_uleb128 (u128, die_addr);
+
+ /* Find the abbreviation. */
+ new_die->abbrev = __libdwarf_get_abbrev (dbg, die->cu, u128, error);
+ if (new_die->abbrev == NULL)
+ return DW_DLV_ERROR;
+
+ *return_kid = new_die;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_dealloc.c b/libdwarf/dwarf_dealloc.c
new file mode 100644
index 00000000..365303bd
--- /dev/null
+++ b/libdwarf/dwarf_dealloc.c
@@ -0,0 +1,32 @@
+/* Deallocate memory.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <libdwarfP.h>
+
+
+void
+dwarf_dealloc (dbg, space, alloc_type)
+ Dwarf_Debug dbg;
+ Dwarf_Ptr space;
+ Dwarf_Unsigned alloc_type;
+{
+ /* XXX For now we don't do anything fancy. */
+ free (space);
+}
diff --git a/libdwarf/dwarf_die_CU_offset.c b/libdwarf/dwarf_die_CU_offset.c
new file mode 100644
index 00000000..2d80fd5a
--- /dev/null
+++ b/libdwarf/dwarf_die_CU_offset.c
@@ -0,0 +1,33 @@
+/* Return offset of die in compile unit data.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_die_CU_offset (die, return_offset, error)
+ Dwarf_Die die;
+ Dwarf_Off *return_offset;
+ Dwarf_Error *error;
+{
+ *return_offset =
+ (die->addr
+ - (Dwarf_Small *) die->cu->dbg->sections[IDX_debug_info].addr
+ - die->cu->offset);
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_diename.c b/libdwarf/dwarf_diename.c
new file mode 100644
index 00000000..2dfcd57a
--- /dev/null
+++ b/libdwarf/dwarf_diename.c
@@ -0,0 +1,139 @@
+/* Return string in name attribute of die.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <string.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_diename (die, return_name, error)
+ Dwarf_Die die;
+ char **return_name;
+ Dwarf_Error *error;
+{
+ Dwarf_Debug dbg = die->cu->dbg;
+ Dwarf_Small *die_addr;
+ Dwarf_Word u128;
+ Dwarf_Abbrev abbrev;
+ Dwarf_Small *attrp;
+
+ /* Address of the given die. */
+ die_addr = die->addr;
+
+ /* Get abbrev code. */
+ get_uleb128 (u128, die_addr);
+ /* And get the abbreviation itself. */
+ abbrev = __libdwarf_get_abbrev (dbg, die->cu, u128, error);
+ if (abbrev == NULL)
+ return DW_DLV_ERROR;
+
+ /* This is where the attributes start. */
+ attrp = abbrev->attrp;
+
+ /* Search the name attribute. */
+ while (1)
+ {
+ Dwarf_Word attr_name;
+ Dwarf_Word attr_form;
+
+ /* Are we still in bounds? */
+ if (unlikely (attrp
+ >= ((Dwarf_Small *)dbg->sections[IDX_debug_abbrev].addr
+ + dbg->sections[IDX_debug_abbrev].size)))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* Get attribute name and form.
+
+ XXX We don't check whether this reads beyond the end of the
+ section. */
+ get_uleb128 (attr_name, attrp);
+ get_uleb128 (attr_form, attrp);
+
+ /* We can stop if we found the attribute with value zero. */
+ if (attr_name == 0 && attr_form == 0)
+ break;
+
+ /* Is this the name attribute? */
+ if (attr_name == DW_AT_name)
+ {
+ char *str;
+
+ /* We found it. Duplicate the string and return. There are
+ two possible forms: DW_FORM_string and DW_FORM_strp. */
+ if (attr_form == DW_FORM_string)
+ {
+ str = (char *) die_addr;
+ }
+ else if (likely (attr_form == DW_FORM_strp))
+ {
+ Dwarf_Unsigned off;
+ Dwarf_Signed len;
+
+ if (die->cu->offset_size == 4)
+ off = read_4ubyte_unaligned (dbg, die_addr);
+ else
+ off = read_8ubyte_unaligned (dbg, die_addr);
+
+ /* This is an offset in the .debug_str section. Make sure
+ it's within range. */
+ if (unlikely (dwarf_get_str (dbg, off, &str, &len, error)
+ != DW_DLV_OK))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ }
+ else
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ str = strdup (str);
+ if (str == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ *return_name = str;
+ return DW_DLV_OK;
+ }
+
+ /* Skip over the rest of this attribute (if there is any). */
+ if (attr_form != 0)
+ {
+ size_t len;
+
+ if (unlikely (__libdwarf_form_val_len (dbg, die->cu, attr_form,
+ die_addr, &len, error)
+ != DW_DLV_OK))
+ return DW_DLV_ERROR;
+
+ die_addr += len;
+ }
+ }
+
+ /* No name attribute present. */
+ return DW_DLV_NO_ENTRY;
+}
diff --git a/libdwarf/dwarf_dieoffset.c b/libdwarf/dwarf_dieoffset.c
new file mode 100644
index 00000000..2886f9f8
--- /dev/null
+++ b/libdwarf/dwarf_dieoffset.c
@@ -0,0 +1,31 @@
+/* Return offset of die in .debug_info section.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_dieoffset (die, return_offset, error)
+ Dwarf_Die die;
+ Dwarf_Off *return_offset;
+ Dwarf_Error *error;
+{
+ *return_offset =
+ (die->addr - (Dwarf_Small *) die->cu->dbg->sections[IDX_debug_info].addr);
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_elf_init.c b/libdwarf/dwarf_elf_init.c
new file mode 100644
index 00000000..d69d7474
--- /dev/null
+++ b/libdwarf/dwarf_elf_init.c
@@ -0,0 +1,197 @@
+/* Create descriptor from ELF handle for processing file.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <endian.h>
+#include <gelf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libdwarfP.h>
+
+
+/* Section names. */
+static const char dwarf_scnnames[IDX_last][17] =
+{
+ [IDX_debug_info] = ".debug_info",
+ [IDX_debug_abbrev] = ".debug_abbrev",
+ [IDX_debug_aranges] = ".debug_aranges",
+ [IDX_debug_line] = ".debug_line",
+ [IDX_debug_frame] = ".debug_frame",
+ [IDX_eh_frame] = ".eh_frame",
+ [IDX_debug_loc] = ".debug_loc",
+ [IDX_debug_pubnames] = ".debug_pubnames",
+ [IDX_debug_str] = ".debug_str",
+ [IDX_debug_funcnames] = ".debug_funcnames",
+ [IDX_debug_typenames] = ".debug_typenames",
+ [IDX_debug_varnames] = ".debug_varnames",
+ [IDX_debug_weaknames] = ".debug_weaknames",
+ [IDX_debug_macinfo] = ".debug_macinfo"
+};
+#define ndwarf_scnnames (sizeof (dwarf_scnnames) / sizeof (dwarf_scnnames[0]))
+
+
+int
+dwarf_elf_init (elf, access, errhand, errarg, dbg, error)
+ Elf *elf;
+ Dwarf_Unsigned access;
+ Dwarf_Handler errhand;
+ Dwarf_Ptr errarg;
+ Dwarf_Debug *dbg;
+ Dwarf_Error *error;
+{
+ int result = DW_DLV_ERROR;
+ Dwarf_Debug newdbg;
+ GElf_Ehdr ehdr_mem;
+ GElf_Ehdr *ehdr;
+ Elf_Scn *scn;
+
+ /* XXX For now nothing but read-only support is available. */
+ if (access != DW_DLC_READ)
+ abort ();
+
+ /* Get the ELF header of the file. We need various pieces of
+ information from it. */
+ ehdr = gelf_getehdr (elf, &ehdr_mem);
+ if (ehdr == NULL)
+ {
+ struct Dwarf_Debug_s tmpdbg;
+
+ tmpdbg.dbg_errhand = errhand;
+ tmpdbg.dbg_errarg = errarg;
+
+ if (elf_kind (elf) != ELF_K_ELF)
+ __libdwarf_error (&tmpdbg, error, DW_E_NOELF);
+ else
+ __libdwarf_error (&tmpdbg, error, DW_E_GETEHDR_ERROR);
+
+ return result;
+ }
+
+ /* Allocate and fill the result data structure. */
+ newdbg = (Dwarf_Debug) calloc (1, sizeof (struct Dwarf_Debug_s));
+ if (newdbg == NULL)
+ {
+ struct Dwarf_Debug_s tmpdbg;
+
+ tmpdbg.dbg_errhand = errhand;
+ tmpdbg.dbg_errarg = errarg;
+
+ __libdwarf_error (&tmpdbg, error, DW_E_NOMEM);
+ }
+ else
+ {
+ /* We have been able to allocate the memory for the debug handle. */
+ newdbg->dbg_errhand = errhand;
+ newdbg->dbg_errarg = errarg;
+ newdbg->elf = elf;
+ if ((BYTE_ORDER == LITTLE_ENDIAN
+ && ehdr->e_ident[EI_DATA] == ELFDATA2MSB)
+ || (BYTE_ORDER == BIG_ENDIAN
+ && ehdr->e_ident[EI_DATA] == ELFDATA2LSB))
+ newdbg->other_byte_order = 1;
+ newdbg->access = access;
+#ifdef DWARF_DEBUG
+ newdbg->memtag = DW_DLA_DEBUG;
+#endif
+
+ /* All done. */
+ *dbg = newdbg;
+ result = DW_DLV_OK;
+
+ /* Find out whether the file actually has the necessary DWARF
+ sections. */
+ scn = NULL;
+ while ((scn = elf_nextscn (elf, scn)) != NULL)
+ {
+ GElf_Shdr shdr_mem;
+ GElf_Shdr *shdr;
+ const char *scnname;
+ size_t cnt;
+ Elf_Data *data;
+
+ /* Get the section header data. */
+ shdr = gelf_getshdr (scn, &shdr_mem);
+ if (shdr == NULL)
+ /* This should never happen. If it does something is
+ wrong in the libelf library. */
+ abort ();
+
+ /* We recognize the DWARF section by their names. This is
+ not very safe and stable but the best we can do. */
+ scnname = elf_strptr (elf, ehdr->e_shstrndx, shdr->sh_name);
+ if (scnname == NULL)
+ {
+ /* The section name must be valid. Otherwise is the ELF file
+ invalid. */
+ __libdwarf_error (newdbg, error, DW_E_INVALID_ELF);
+ break;
+ }
+
+ /* Recognize the various sections. Most names start with
+ .debug_. */
+ for (cnt = 0; cnt < ndwarf_scnnames; ++cnt)
+ if (strcmp (scnname, dwarf_scnnames[cnt]) == 0)
+ break;
+
+ if (cnt < ndwarf_scnnames)
+ {
+ /* Found it. Remember where the data is. */
+ assert (cnt < IDX_last);
+ if (unlikely (newdbg->sections[cnt].addr != NULL))
+ {
+ /* A section appears twice. That's bad. */
+ __libdwarf_error (newdbg, error, DW_E_INVALID_DWARF);
+ break;
+ }
+
+ /* Get the section data. */
+ data = elf_getdata (scn, NULL);
+ if (data != NULL && data->d_size != 0)
+ {
+ /* Yep, there is actually data available. */
+ newdbg->sections[cnt].addr = data->d_buf;
+ newdbg->sections[cnt].size = data->d_size;
+ }
+ }
+ }
+
+ if (scn == NULL)
+ {
+ /* We looked at all the sections. Now determine whether all
+ the sections with debugging information we need are there.
+
+ XXX Which sections are absolutely necessary? Add tests
+ if necessary. For now we require only .debug_info. Hopefully
+ this is correct. */
+ if (newdbg->sections[IDX_debug_info].addr == NULL)
+ {
+ __libdwarf_error (newdbg, error, DW_E_NO_DWARF);
+ result = DW_DLV_NO_ENTRY;
+ }
+ else
+ result = DW_DLV_OK;
+ }
+
+ if (result != DW_DLV_OK)
+ /* Something went wrong. */
+ free (newdbg);
+ }
+
+ return result;
+}
diff --git a/libdwarf/dwarf_errmsg.c b/libdwarf/dwarf_errmsg.c
new file mode 100644
index 00000000..1d19f416
--- /dev/null
+++ b/libdwarf/dwarf_errmsg.c
@@ -0,0 +1,67 @@
+/* Return error message.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+/* Map error values to strings. */
+/* XXX This table should avoid string pointers. Fixing it can wait
+ until the code is stable. */
+static const char *msgs[] =
+{
+ [DW_E_NOERROR] = N_("no error"),
+ [DW_E_INVALID_ACCESS] = N_("invalid access mode"),
+ [DW_E_NO_REGFILE] = N_("no regular file"),
+ [DW_E_IO_ERROR] = N_("I/O error"),
+ [DW_E_NOMEM] = N_("out of memory"),
+ [DW_E_NOELF] = N_("file is not an ELF file"),
+ [DW_E_GETEHDR_ERROR] = N_("getehdr call failed"),
+ [DW_E_INVALID_ELF] = N_("invalid ELF file"),
+ [DW_E_INVALID_DWARF] = N_("invalid DWARF debugging information"),
+ [DW_E_NO_DWARF] = N_("no DWARF debugging information available"),
+ [DW_E_NO_CU] = N_("no compilation unit"),
+ [DW_E_1ST_NO_CU] = N_("first die is no compile unit die"),
+ [DW_E_INVALID_OFFSET] = N_("invalid offset"),
+ [DW_E_INVALID_REFERENCE] = N_("invalid reference form"),
+ [DW_E_NO_REFERENCE] = N_("no reference form"),
+ [DW_E_NO_ADDR] = N_("no address form"),
+ [DW_E_NO_FLAG] = N_("no flag form"),
+ [DW_E_NO_CONSTANT] = N_("no constant form"),
+ [DW_E_NO_BLOCK] = N_("no block form"),
+ [DW_E_NO_STRING] = N_("no string form"),
+ [DW_E_WRONG_ATTR] = N_("wrong attribute code"),
+ [DW_E_NO_DATA] = N_("no data form"),
+ [DW_E_NO_DEBUG_LINE] = N_(".debug_line section missing"),
+ [DW_E_VERSION_ERROR] = N_("version mismatch"),
+ [DW_E_INVALID_DIR_IDX] = N_("invalid directory index"),
+ [DW_E_INVALID_ADDR] = N_("invalid address"),
+ [DW_E_NO_ABBR] = N_("no valid abbreviation"),
+};
+#define nmsgs (sizeof (msgs) / sizeof (msgs[0]))
+
+
+const char *
+dwarf_errmsg (Dwarf_Error error)
+{
+ const char *retval = N_("unknown error");
+
+ if (error->de_error < nmsgs)
+ retval = msgs[error->de_error];
+
+ return _(retval);
+}
diff --git a/libdwarf/dwarf_errno.c b/libdwarf/dwarf_errno.c
new file mode 100644
index 00000000..4d659e09
--- /dev/null
+++ b/libdwarf/dwarf_errno.c
@@ -0,0 +1,26 @@
+/* Return error value.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+Dwarf_Unsigned
+dwarf_errno (Dwarf_Error error)
+{
+ return error->de_error;
+}
diff --git a/libdwarf/dwarf_error.c b/libdwarf/dwarf_error.c
new file mode 100644
index 00000000..16c0c45a
--- /dev/null
+++ b/libdwarf/dwarf_error.c
@@ -0,0 +1,52 @@
+/* Handle error.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include <libdwarfP.h>
+#include <system.h>
+
+
+void
+internal_function
+__libdwarf_error (Dwarf_Debug dbg, Dwarf_Error *error, int errval)
+{
+ /* Allocate memory for the error structure given to the user. */
+ Dwarf_Error errmem = (Dwarf_Error) malloc (sizeof (*error));
+ /* We cannot report an error if we cannot allocate memory. */
+ if (errmem == NULL)
+ return;
+
+ errmem->de_error = errval;
+
+ /* DBG must never be NULL. */
+ assert (dbg != NULL);
+
+ if (error != NULL)
+ /* If the user provides an ERROR parameter we have to use it. */
+ *error = errmem;
+ else if (likely (dbg->dbg_errhand != NULL))
+ /* Use the handler the user provided if possible. */
+ dbg->dbg_errhand (error, dbg->dbg_errarg);
+ else
+ {
+ assert (! "error and dbg->dbg_errhand == NULL");
+ abort ();
+ }
+}
diff --git a/libdwarf/dwarf_find_macro_value_start.c b/libdwarf/dwarf_find_macro_value_start.c
new file mode 100644
index 00000000..fdaaf72a
--- /dev/null
+++ b/libdwarf/dwarf_find_macro_value_start.c
@@ -0,0 +1,45 @@
+/* Find start of macro value.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarf.h>
+
+
+char *
+dwarf_find_macro_value_start (macro_string)
+ char *macro_string;
+{
+ int with_paren = 0;
+
+ while (*macro_string != '\0')
+ {
+ if (*macro_string == '(')
+ with_paren = 1;
+ else if (*macro_string == ')')
+ /* After the closing parenthesis there must be a space. */
+ return macro_string + 2;
+ else if (*macro_string == ' ' && ! with_paren)
+ /* Not a function like macro and we found the space terminating
+ the name. */
+ return macro_string + 1;
+
+ ++macro_string;
+ }
+
+ /* The macro has no value. Return a pointer to the NUL byte. */
+ return macro_string;
+}
diff --git a/libdwarf/dwarf_finish.c b/libdwarf/dwarf_finish.c
new file mode 100644
index 00000000..f689e79c
--- /dev/null
+++ b/libdwarf/dwarf_finish.c
@@ -0,0 +1,40 @@
+/* Free resources allocated for debug handle.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_finish (dbg, error)
+ Dwarf_Debug dbg;
+ Dwarf_Error *error;
+{
+ if (dbg == NULL)
+ return DW_DLV_ERROR;
+
+#ifdef DWARF_DEBUG
+ if (dbg->memtag != DW_DLA_DEBUG)
+ return DW_DLV_ERROR;
+#endif
+
+ free (dbg);
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_form.c b/libdwarf/dwarf_form.c
new file mode 100644
index 00000000..9adf3ede
--- /dev/null
+++ b/libdwarf/dwarf_form.c
@@ -0,0 +1,107 @@
+/* Helper functions for form handling.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <string.h>
+
+#include <libdwarfP.h>
+
+
+int
+internal_function
+__libdwarf_form_val_len (Dwarf_Debug dbg, Dwarf_CU_Info cu, Dwarf_Word form,
+ Dwarf_Small *valp, size_t *len, Dwarf_Error *error)
+{
+ Dwarf_Small *saved;
+ Dwarf_Word u128;
+
+ switch (form)
+ {
+ case DW_FORM_addr:
+ case DW_FORM_strp:
+ case DW_FORM_ref_addr:
+ *len = cu->address_size;
+ break;
+
+ case DW_FORM_block1:
+ *len = *valp + 1;
+ break;
+
+ case DW_FORM_block2:
+ *len = read_2ubyte_unaligned (dbg, valp) + 2;
+ break;
+
+ case DW_FORM_block4:
+ *len = read_4ubyte_unaligned (dbg, valp) + 4;
+ break;
+
+ case DW_FORM_block:
+ saved = valp;
+ get_uleb128 (u128, valp);
+ *len = u128 + (valp - saved);
+ break;
+
+ case DW_FORM_ref1:
+ case DW_FORM_data1:
+ case DW_FORM_flag:
+ *len = 1;
+ break;
+
+ case DW_FORM_data2:
+ case DW_FORM_ref2:
+ *len = 2;
+ break;
+
+ case DW_FORM_data4:
+ case DW_FORM_ref4:
+ *len = 4;
+ break;
+
+ case DW_FORM_data8:
+ case DW_FORM_ref8:
+ *len = 8;
+ break;
+
+ case DW_FORM_string:
+ *len = strlen ((char *) valp) + 1;
+ break;
+
+ case DW_FORM_sdata:
+ case DW_FORM_udata:
+ case DW_FORM_ref_udata:
+ saved = valp;
+ get_uleb128 (u128, valp);
+ *len = valp - saved;
+ break;
+
+ case DW_FORM_indirect:
+ saved = valp;
+ get_uleb128 (u128, valp);
+ if (__libdwarf_form_val_len (dbg, cu, u128, valp, len, error)
+ != DW_DLV_OK)
+ return DW_DLV_ERROR;
+ *len += valp - saved;
+ break;
+
+ default:
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_formaddr.c b/libdwarf/dwarf_formaddr.c
new file mode 100644
index 00000000..148508fe
--- /dev/null
+++ b/libdwarf/dwarf_formaddr.c
@@ -0,0 +1,42 @@
+/* Return address represented by attribute.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_formaddr (attr, return_addr, error)
+ Dwarf_Attribute attr;
+ Dwarf_Addr *return_addr;
+ Dwarf_Error *error;
+{
+ if (unlikely (attr->form != DW_FORM_addr))
+ {
+ __libdwarf_error (attr->cu->dbg, error, DW_E_NO_ADDR);
+ return DW_DLV_ERROR;
+ }
+
+ if (attr->cu->address_size == 4)
+ *return_addr = read_4ubyte_unaligned (attr->cu->dbg, attr->valp);
+ else
+ *return_addr = read_8ubyte_unaligned (attr->cu->dbg, attr->valp);
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_formblock.c b/libdwarf/dwarf_formblock.c
new file mode 100644
index 00000000..44606edd
--- /dev/null
+++ b/libdwarf/dwarf_formblock.c
@@ -0,0 +1,76 @@
+/* Return block of uninterpreted data represented by attribute.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <stdlib.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_formblock (attr, return_block, error)
+ Dwarf_Attribute attr;
+ Dwarf_Block **return_block;
+ Dwarf_Error *error;
+{
+ Dwarf_Small *attrp = attr->valp;
+ Dwarf_Unsigned len;
+ Dwarf_Ptr *data;
+ Dwarf_Block *result;
+
+ switch (attr->form)
+ {
+ case DW_FORM_block1:
+ len = *attrp;
+ data = (Dwarf_Ptr) (attrp + 1);
+ break;
+
+ case DW_FORM_block2:
+ len = read_2ubyte_unaligned (attr->cu->dbg, attrp);
+ data = (Dwarf_Ptr) (attrp + 2);
+ break;
+
+ case DW_FORM_block4:
+ len = read_4ubyte_unaligned (attr->cu->dbg, attrp);
+ data = (Dwarf_Ptr) (attrp + 2);
+ break;
+
+ case DW_FORM_block:
+ get_uleb128 (len, attrp);
+ data = (Dwarf_Ptr) attrp;
+ break;
+
+ default:
+ __libdwarf_error (attr->cu->dbg, error, DW_E_NO_BLOCK);
+ return DW_DLV_ERROR;
+ }
+
+ /* Allocate memory for the result. */
+ result = (Dwarf_Block *) malloc (sizeof (Dwarf_Block));
+ if (result == NULL)
+ {
+ __libdwarf_error (attr->cu->dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ result->bl_len = len;
+ result->bl_data = data;
+
+ *return_block = result;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_formflag.c b/libdwarf/dwarf_formflag.c
new file mode 100644
index 00000000..32a98fd8
--- /dev/null
+++ b/libdwarf/dwarf_formflag.c
@@ -0,0 +1,39 @@
+/* Return flag represented by attribute.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_formflag (attr, return_bool, error)
+ Dwarf_Attribute attr;
+ Dwarf_Bool *return_bool;
+ Dwarf_Error *error;
+{
+ if (unlikely (attr->form != DW_FORM_flag))
+ {
+ __libdwarf_error (attr->cu->dbg, error, DW_E_NO_FLAG);
+ return DW_DLV_ERROR;
+ }
+
+ *return_bool = attr->valp != 0;
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_formref.c b/libdwarf/dwarf_formref.c
new file mode 100644
index 00000000..4ae353a8
--- /dev/null
+++ b/libdwarf/dwarf_formref.c
@@ -0,0 +1,67 @@
+/* Return compile-unit relative offset of reference associated with form.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_formref (attr, return_offset, error)
+ Dwarf_Attribute attr;
+ Dwarf_Off *return_offset;
+ Dwarf_Error *error;
+{
+ switch (attr->form)
+ {
+ case DW_FORM_ref1:
+ *return_offset = *attr->valp;
+ break;
+
+ case DW_FORM_ref2:
+ *return_offset = read_2ubyte_unaligned (attr->cu->dbg, attr->valp);
+ break;
+
+ case DW_FORM_ref4:
+ *return_offset = read_4ubyte_unaligned (attr->cu->dbg, attr->valp);
+ break;
+
+ case DW_FORM_ref8:
+ *return_offset = read_8ubyte_unaligned (attr->cu->dbg, attr->valp);
+ break;
+
+ case DW_FORM_ref_udata:
+ {
+ Dwarf_Off off;
+ Dwarf_Small *attrp = attr->valp;
+ get_uleb128 (off, attrp);
+ *return_offset = off;
+ }
+ break;
+
+ case DW_FORM_ref_addr:
+ __libdwarf_error (attr->cu->dbg, error, DW_E_INVALID_REFERENCE);
+ return DW_DLV_ERROR;
+
+ default:
+ __libdwarf_error (attr->cu->dbg, error, DW_E_NO_REFERENCE);
+ return DW_DLV_ERROR;
+ }
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_formsdata.c b/libdwarf/dwarf_formsdata.c
new file mode 100644
index 00000000..8024e763
--- /dev/null
+++ b/libdwarf/dwarf_formsdata.c
@@ -0,0 +1,72 @@
+/* Return signed constant represented by attribute.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_formsdata (attr, return_sval, error)
+ Dwarf_Attribute attr;
+ Dwarf_Signed *return_sval;
+ Dwarf_Error *error;
+{
+ Dwarf_Signed u128;
+
+ switch (attr->form)
+ {
+ case DW_FORM_data1:
+ *return_sval = *attr->valp;
+ break;
+
+ case DW_FORM_data2:
+ *return_sval = read_2ubyte_unaligned (attr->cu->dbg, attr->valp);
+ break;
+
+ case DW_FORM_data4:
+ *return_sval = read_4ubyte_unaligned (attr->cu->dbg, attr->valp);
+ break;
+
+ case DW_FORM_data8:
+ *return_sval = read_8ubyte_unaligned (attr->cu->dbg, attr->valp);
+ break;
+
+ case DW_FORM_sdata:
+ {
+ Dwarf_Small *attrp = attr->valp;
+ get_sleb128 (u128, attrp);
+ *return_sval = u128;
+ }
+ break;
+
+ case DW_FORM_udata:
+ {
+ Dwarf_Small *attrp = attr->valp;
+ get_uleb128 (u128, attrp);
+ *return_sval = u128;
+ }
+ break;
+
+ default:
+ __libdwarf_error (attr->cu->dbg, error, DW_E_NO_CONSTANT);
+ return DW_DLV_ERROR;
+ }
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_formstring.c b/libdwarf/dwarf_formstring.c
new file mode 100644
index 00000000..205a9466
--- /dev/null
+++ b/libdwarf/dwarf_formstring.c
@@ -0,0 +1,51 @@
+/* Return string represented by attribute.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <string.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_formstring (attr, return_string, error)
+ Dwarf_Attribute attr;
+ char **return_string;
+ Dwarf_Error *error;
+{
+ char *result;
+
+ if (attr->form == DW_FORM_string)
+ result = (char *) attr->valp;
+ else if (likely (attr->form == DW_FORM_strp))
+ {
+ Dwarf_Unsigned offset;
+
+ offset = read_4ubyte_unaligned (attr->cu->dbg, attr->valp);
+
+ result = (char *) attr->cu->dbg->sections[IDX_debug_str].addr + offset;
+ }
+ else
+ {
+ __libdwarf_error (attr->cu->dbg, error, DW_E_NO_STRING);
+ return DW_DLV_ERROR;
+ }
+
+ *return_string = result;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_formudata.c b/libdwarf/dwarf_formudata.c
new file mode 100644
index 00000000..35e133cb
--- /dev/null
+++ b/libdwarf/dwarf_formudata.c
@@ -0,0 +1,72 @@
+/* Return unsigned constant represented by attribute.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_formudata (attr, return_uval, error)
+ Dwarf_Attribute attr;
+ Dwarf_Unsigned *return_uval;
+ Dwarf_Error *error;
+{
+ Dwarf_Unsigned u128;
+
+ switch (attr->form)
+ {
+ case DW_FORM_data1:
+ *return_uval = *attr->valp;
+ break;
+
+ case DW_FORM_data2:
+ *return_uval = read_2ubyte_unaligned (attr->cu->dbg, attr->valp);
+ break;
+
+ case DW_FORM_data4:
+ *return_uval = read_4ubyte_unaligned (attr->cu->dbg, attr->valp);
+ break;
+
+ case DW_FORM_data8:
+ *return_uval = read_8ubyte_unaligned (attr->cu->dbg, attr->valp);
+ break;
+
+ case DW_FORM_sdata:
+ {
+ Dwarf_Small *attrp = attr->valp;
+ get_sleb128 (u128, attrp);
+ *return_uval = u128;
+ }
+ break;
+
+ case DW_FORM_udata:
+ {
+ Dwarf_Small *attrp = attr->valp;
+ get_uleb128 (u128, attrp);
+ *return_uval = u128;
+ }
+ break;
+
+ default:
+ __libdwarf_error (attr->cu->dbg, error, DW_E_NO_CONSTANT);
+ return DW_DLV_ERROR;
+ }
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_abbrev.c b/libdwarf/dwarf_get_abbrev.c
new file mode 100644
index 00000000..0295f9bd
--- /dev/null
+++ b/libdwarf/dwarf_get_abbrev.c
@@ -0,0 +1,111 @@
+/* Get abbreviation record.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <stdlib.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_get_abbrev (dbg, offset, return_abbrev, length, attr_count, error)
+ Dwarf_Debug dbg;
+ Dwarf_Unsigned offset;
+ Dwarf_Abbrev *return_abbrev;
+ Dwarf_Unsigned *length;
+ Dwarf_Unsigned *attr_count;
+ Dwarf_Error *error;
+{
+ Dwarf_Abbrev ent;
+ Dwarf_Small *abbrevp;
+ Dwarf_Small *start_abbrevp;
+
+ /* Address in memory. */
+ abbrevp = (Dwarf_Small *) dbg->sections[IDX_debug_abbrev].addr + offset;
+
+ /* Remember where we started. */
+ start_abbrevp = abbrevp;
+
+ if (*abbrevp != '\0')
+ {
+ /* 7.5.3 Abbreviations Tables
+
+ [...] Each declaration begins with an unsigned LEB128 number
+ representing the abbreviation code itself. [...] The
+ abbreviation code is followed by another unsigned LEB128
+ number that encodes the entry's tag. [...]
+
+ [...] Following the tag encoding is a 1-byte value that
+ determines whether a debugging information entry using this
+ abbreviation has child entries or not. [...]
+
+ [...] Finally, the child encoding is followed by a series of
+ attribute specifications. Each attribute specification
+ consists of two parts. The first part is an unsigned LEB128
+ number representing the attribute's name. The second part is
+ an unsigned LEB128 number representing the attribute s form. */
+ Dwarf_Word abbrev_code;
+ Dwarf_Word abbrev_tag;
+ Dwarf_Word attr_name;
+ Dwarf_Word attr_form;
+ Dwarf_Unsigned attrcnt;
+
+ /* XXX We have no tests for crossing the section boundary here.
+ We should compare with dbg->sections[IDX_debug_abbrev].size. */
+ get_uleb128 (abbrev_code, abbrevp);
+ get_uleb128 (abbrev_tag, abbrevp);
+
+ /* Get memory for the result. */
+ ent = (Dwarf_Abbrev) malloc (sizeof (struct Dwarf_Abbrev_s));
+ if (ent == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ ent->code = abbrev_code;
+ ent->tag = abbrev_tag;
+ ent->has_children = *abbrevp++ == DW_CHILDREN_yes;
+ ent->attrp = abbrevp;
+ ent->offset = offset;
+
+ /* Skip over all the attributes. */
+ attrcnt = 0;
+ do
+ {
+ get_uleb128 (attr_name, abbrevp);
+ get_uleb128 (attr_form, abbrevp);
+ }
+ while (attr_name != 0 && attr_form != 0 && ++attrcnt);
+
+ /* Number of attributes. */
+ *attr_count = ent->attrcnt = attrcnt;
+
+ /* Store the actual abbreviation record. */
+ *return_abbrev = ent;
+ }
+ else
+ /* Read over the NUL byte. */
+ ++abbrevp;
+
+ /* Length of the entry. */
+ *length = abbrevp - start_abbrevp;
+
+ /* If we come here we haven't found anything. */
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_abbrev_children_flag.c b/libdwarf/dwarf_get_abbrev_children_flag.c
new file mode 100644
index 00000000..079c85a8
--- /dev/null
+++ b/libdwarf/dwarf_get_abbrev_children_flag.c
@@ -0,0 +1,29 @@
+/* Get children flag of abbreviation record.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwarfP.h"
+
+
+int dwarf_get_abbrev_children_flag (abbrev, return_flag, error)
+ Dwarf_Abbrev abbrev;
+ Dwarf_Signed *return_flag;
+ Dwarf_Error *error;
+{
+ *return_flag = abbrev->has_children;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_abbrev_code.c b/libdwarf/dwarf_get_abbrev_code.c
new file mode 100644
index 00000000..08ecb43b
--- /dev/null
+++ b/libdwarf/dwarf_get_abbrev_code.c
@@ -0,0 +1,29 @@
+/* Get code of abbreviation record.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwarfP.h"
+
+
+int dwarf_get_abbrev_code (abbrev, return_code, error)
+ Dwarf_Abbrev abbrev;
+ Dwarf_Unsigned *return_code;
+ Dwarf_Error *error;
+{
+ *return_code = abbrev->code;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_abbrev_entry.c b/libdwarf/dwarf_get_abbrev_entry.c
new file mode 100644
index 00000000..4deccd0d
--- /dev/null
+++ b/libdwarf/dwarf_get_abbrev_entry.c
@@ -0,0 +1,63 @@
+/* Get attribute from abbreviation record.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <stdlib.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_get_abbrev_entry (abbrev, idx, attr_num, form, offset, error)
+ Dwarf_Abbrev abbrev;
+ Dwarf_Signed idx;
+ Dwarf_Half *attr_num;
+ Dwarf_Signed *form;
+ Dwarf_Off *offset;
+ Dwarf_Error *error;
+{
+ Dwarf_Small *attrp;
+ Dwarf_Small *start_attrp;
+ Dwarf_Word attr_name;
+ Dwarf_Word attr_form;
+
+ if (idx < 0)
+ return DW_DLV_NO_ENTRY;
+
+ /* Address in memory. */
+ attrp = abbrev->attrp;
+
+ /* Read the attributes, skip over the ones we don't want. */
+ do
+ {
+ start_attrp = attrp;
+
+ get_uleb128 (attr_name, attrp);
+ get_uleb128 (attr_form, attrp);
+
+ if (attr_name == 0 || attr_form == 0)
+ return DW_DLV_NO_ENTRY;
+ }
+ while (idx-- > 0);
+
+ *attr_num = attr_name;
+ *form = attr_form;
+ *offset = (start_attrp - abbrev->attrp) + abbrev->offset;
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_abbrev_tag.c b/libdwarf/dwarf_get_abbrev_tag.c
new file mode 100644
index 00000000..b3f9fd1c
--- /dev/null
+++ b/libdwarf/dwarf_get_abbrev_tag.c
@@ -0,0 +1,29 @@
+/* Get tag of abbreviation record.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwarfP.h"
+
+
+int dwarf_get_abbrev_tag (abbrev, return_tag, error)
+ Dwarf_Abbrev abbrev;
+ Dwarf_Half *return_tag;
+ Dwarf_Error *error;
+{
+ *return_tag = abbrev->tag;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_address_size.c b/libdwarf/dwarf_get_address_size.c
new file mode 100644
index 00000000..fe5234c9
--- /dev/null
+++ b/libdwarf/dwarf_get_address_size.c
@@ -0,0 +1,30 @@
+/* Return address size.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_get_address_size (dbg, addr_size, error)
+ Dwarf_Debug dbg;
+ Dwarf_Half *addr_size;
+ Dwarf_Error *error;
+{
+ *addr_size = elf_getident (dbg->elf, NULL)[EI_CLASS] == ELFCLASS64 ? 8 : 4;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_arange.c b/libdwarf/dwarf_get_arange.c
new file mode 100644
index 00000000..02df19d2
--- /dev/null
+++ b/libdwarf/dwarf_get_arange.c
@@ -0,0 +1,41 @@
+/* Find matching range for address.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_get_arange (aranges, arange_count, address, return_arange, error)
+ Dwarf_Arange *aranges;
+ Dwarf_Unsigned arange_count;
+ Dwarf_Addr address;
+ Dwarf_Arange *return_arange;
+ Dwarf_Error *error;
+{
+ Dwarf_Unsigned cnt;
+
+ for (cnt = 0; cnt < arange_count; ++cnt)
+ if (aranges[cnt]->address <= address
+ && address < aranges[cnt]->address + aranges[cnt]->length)
+ {
+ *return_arange = aranges[cnt];
+ return DW_DLV_OK;
+ }
+
+ return DW_DLV_NO_ENTRY;
+}
diff --git a/libdwarf/dwarf_get_arange_info.c b/libdwarf/dwarf_get_arange_info.c
new file mode 100644
index 00000000..4d37e087
--- /dev/null
+++ b/libdwarf/dwarf_get_arange_info.c
@@ -0,0 +1,48 @@
+/* Return start, length, and CU DIE offset of range.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_get_arange_info (arange, start, length, cu_die_offset, error)
+ Dwarf_Arange arange;
+ Dwarf_Addr *start;
+ Dwarf_Unsigned *length;
+ Dwarf_Off *cu_die_offset;
+ Dwarf_Error *error;
+{
+ Dwarf_Small *cu_header;
+ unsigned int offset_size;
+
+ *start = arange->address;
+ *length = arange->length;
+
+ /* Determine the size of the CU header. */
+ cu_header =
+ ((Dwarf_Small *) arange->info->dbg->sections[IDX_debug_info].addr
+ + arange->info->offset);
+ if (read_4ubyte_unaligned_noncvt (cu_header) == 0xffffffff)
+ offset_size = 8;
+ else
+ offset_size = 4;
+
+ *cu_die_offset = arange->info->offset + 3 * offset_size - 4 + 3;
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_aranges.c b/libdwarf/dwarf_get_aranges.c
new file mode 100644
index 00000000..b8cabb03
--- /dev/null
+++ b/libdwarf/dwarf_get_aranges.c
@@ -0,0 +1,186 @@
+/* Return list address ranges.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+
+#include <libdwarfP.h>
+
+
+struct arangelist
+{
+ Dwarf_Arange arange;
+ struct arangelist *next;
+};
+
+
+int
+dwarf_get_aranges (dbg, aranges, return_count, error)
+ Dwarf_Debug dbg;
+ Dwarf_Arange **aranges;
+ Dwarf_Signed *return_count;
+ Dwarf_Error *error;
+{
+ Dwarf_Small *readp;
+ Dwarf_Small *readendp;
+ struct arangelist *arangelist = NULL;
+ unsigned int narangelist = 0;
+
+ if (dbg->sections[IDX_debug_aranges].addr == NULL)
+ return DW_DLV_NO_ENTRY;
+
+ readp = (Dwarf_Small *) dbg->sections[IDX_debug_aranges].addr;
+ readendp = readp + dbg->sections[IDX_debug_aranges].size;
+
+ while (readp < readendp)
+ {
+ Dwarf_Small *hdrstart = readp;
+ Dwarf_Unsigned length;
+ unsigned int length_bytes;
+ unsigned int version;
+ Dwarf_Unsigned offset;
+ unsigned int address_size;
+ unsigned int segment_size;
+ Dwarf_Arange_Info arange_info;
+
+ /* Each entry starts with a header:
+
+ 1. A 4-byte or 12-byte length containing the length of the
+ set of entries for this compilation unit, not including the
+ length field itself. [...]
+
+ 2. A 2-byte version identifier containing the value 2 for
+ DWARF Version 2.1.
+
+ 3. A 4-byte or 8-byte offset into the .debug_info section. [...]
+
+ 4. A 1-byte unsigned integer containing the size in bytes of
+ an address (or the offset portion of an address for segmented
+ addressing) on the target system.
+
+ 5. A 1-byte unsigned integer containing the size in bytes of
+ a segment descriptor on the target system. */
+ length = read_4ubyte_unaligned (dbg, readp);
+ readp += 4;
+ length_bytes = 4;
+ if (length == 0xffffffff)
+ {
+ length = read_8ubyte_unaligned (dbg, readp);
+ readp += 8;
+ length_bytes = 8;
+ }
+
+ version = read_2ubyte_unaligned (dbg, readp);
+ readp += 2;
+ if (version != 2)
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ if (length_bytes == 4)
+ offset = read_4ubyte_unaligned (dbg, readp);
+ else
+ offset = read_8ubyte_unaligned (dbg, readp);
+ readp += length_bytes;
+
+ address_size = *readp++;
+ segment_size = *readp++;
+
+ /* Round the address to the next multiple of 2*address_size. */
+ readp += ((2 * address_size - ((readp - hdrstart) % (2 * address_size)))
+ % (2 * address_size));
+
+ arange_info =
+ (Dwarf_Arange_Info) malloc (sizeof (struct Dwarf_Arange_s));
+ if (arange_info == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ arange_info->dbg = dbg;
+ arange_info->offset = offset;
+
+ while (1)
+ {
+ Dwarf_Unsigned range_address;
+ Dwarf_Unsigned range_length;
+ struct arangelist *new_arange;
+
+ if (address_size == 4)
+ {
+ range_address = read_4ubyte_unaligned (dbg, readp);
+ readp += 4;
+ range_length = read_4ubyte_unaligned (dbg, readp);
+ readp += 4;
+ }
+ else if (likely (address_size == 8))
+ {
+ range_address = read_8ubyte_unaligned (dbg, readp);
+ readp += 8;
+ range_length = read_8ubyte_unaligned (dbg, readp);
+ readp += 8;
+ }
+ else
+ abort ();
+
+ /* Two zero values mark the end. */
+ if (range_address == 0 && range_length == 0)
+ break;
+
+ new_arange =
+ (struct arangelist *) alloca (sizeof (struct arangelist));
+ new_arange->arange =
+ (Dwarf_Arange) malloc (sizeof (struct Dwarf_Arange_s));
+ if (new_arange->arange == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ new_arange->arange->address = range_address;
+ new_arange->arange->length = range_length;
+ new_arange->arange->info = arange_info;
+
+ new_arange->next = arangelist;
+ arangelist = new_arange;
+ ++narangelist;
+ }
+ }
+
+ if (narangelist == 0)
+ return DW_DLV_NO_ENTRY;
+
+ /* Allocate the array for the result. */
+ *return_count = narangelist;
+ *aranges = (Dwarf_Arange *) malloc (narangelist
+ * sizeof (struct Dwarf_Arange_s));
+ if (*aranges == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ while (narangelist-- > 0)
+ {
+ (*aranges)[narangelist] = arangelist->arange;
+ arangelist = arangelist->next;
+ }
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_cie_info.c b/libdwarf/dwarf_get_cie_info.c
new file mode 100644
index 00000000..029d9c93
--- /dev/null
+++ b/libdwarf/dwarf_get_cie_info.c
@@ -0,0 +1,53 @@
+/* Get information about CIE.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_get_cie_info (cie, bytes_in_cie, version, augmenter,
+ code_alignment_factor, data_alignment_factor,
+ return_address_register, initial_instructions,
+ initial_instructions_length, error)
+ Dwarf_Cie cie;
+ Dwarf_Unsigned *bytes_in_cie;
+ Dwarf_Small *version;
+ char **augmenter;
+ Dwarf_Unsigned *code_alignment_factor;
+ Dwarf_Signed *data_alignment_factor;
+ Dwarf_Half *return_address_register;
+ Dwarf_Ptr *initial_instructions;
+ Dwarf_Unsigned *initial_instructions_length;
+ Dwarf_Error *error;
+{
+ *bytes_in_cie = cie->length;
+
+ *version = CIE_VERSION;
+
+ *augmenter = cie->augmentation;
+
+ *code_alignment_factor = cie->code_alignment_factor;
+ *data_alignment_factor = cie->data_alignment_factor;
+
+ *return_address_register = cie->return_address_register;
+
+ *initial_instructions = cie->initial_instructions;
+ *initial_instructions_length = cie->initial_instructions_length;
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_cie_of_fde.c b/libdwarf/dwarf_get_cie_of_fde.c
new file mode 100644
index 00000000..49718e9e
--- /dev/null
+++ b/libdwarf/dwarf_get_cie_of_fde.c
@@ -0,0 +1,30 @@
+/* Get CIE of FDE.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_get_cie_of_fde (fde, return_cie, error)
+ Dwarf_Fde fde;
+ Dwarf_Cie *return_cie;
+ Dwarf_Error *error;
+{
+ *return_cie = fde->cie;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_cu_die_offset.c b/libdwarf/dwarf_get_cu_die_offset.c
new file mode 100644
index 00000000..a358d5cf
--- /dev/null
+++ b/libdwarf/dwarf_get_cu_die_offset.c
@@ -0,0 +1,43 @@
+/* Return offset of compile unit DIE containing the range.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_get_cu_die_offset (arange, return_offset, error)
+ Dwarf_Arange arange;
+ Dwarf_Off *return_offset;
+ Dwarf_Error *error;
+{
+ Dwarf_Small *cu_header;
+ unsigned int offset_size;
+
+ /* Determine the size of the CU header. */
+ cu_header =
+ ((Dwarf_Small *) arange->info->dbg->sections[IDX_debug_info].addr
+ + arange->info->offset);
+ if (read_4ubyte_unaligned_noncvt (cu_header) == 0xffffffff)
+ offset_size = 8;
+ else
+ offset_size = 4;
+
+ *return_offset = arange->info->offset + 3 * offset_size - 4 + 3;
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_elf.c b/libdwarf/dwarf_get_elf.c
new file mode 100644
index 00000000..9313e95a
--- /dev/null
+++ b/libdwarf/dwarf_get_elf.c
@@ -0,0 +1,33 @@
+/* Return ELF handle.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_get_elf_init (dbg, elf, error)
+ Dwarf_Debug dbg;
+ Elf **elf;
+ Dwarf_Error *error;
+{
+ if (dbg == NULL)
+ return DW_DLV_ERROR;
+
+ *elf = dbg->elf;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_fde_at_pc.c b/libdwarf/dwarf_get_fde_at_pc.c
new file mode 100644
index 00000000..fee2efdb
--- /dev/null
+++ b/libdwarf/dwarf_get_fde_at_pc.c
@@ -0,0 +1,57 @@
+/* Find FDE for given address.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwarfP.h"
+
+
+int
+dwarf_get_fde_at_pc (fde_data, pc_of_interest, returned_fde, lopc, hipc, error)
+ Dwarf_Fde *fde_data;
+ Dwarf_Addr pc_of_interest;
+ Dwarf_Fde *returned_fde;
+ Dwarf_Addr *lopc;
+ Dwarf_Addr *hipc;
+ Dwarf_Error *error;
+{
+ Dwarf_Debug dbg = fde_data[0]->cie->dbg;
+ int low = 0;
+ int high = dbg->fde_cnt - 1;
+
+ /* Since the FDEs are sorted by their addresses and since there can
+ potentially be many FDEs we better use binary search. */
+ while (low <= high)
+ {
+ int curidx = (low + high) / 2;
+ Dwarf_Fde cur = fde_data[curidx];
+
+ if (pc_of_interest < cur->initial_location)
+ high = curidx - 1;
+ else if (likely (cur->initial_location + cur->address_range
+ <= pc_of_interest))
+ low = curidx + 1;
+ else
+ {
+ *returned_fde = cur;
+ *lopc = cur->initial_location;
+ *hipc = cur->initial_location + cur->address_range - 1;
+ return DW_DLV_OK;
+ }
+ }
+
+ return DW_DLV_NO_ENTRY;
+}
diff --git a/libdwarf/dwarf_get_fde_instr_bytes.c b/libdwarf/dwarf_get_fde_instr_bytes.c
new file mode 100644
index 00000000..74a5388e
--- /dev/null
+++ b/libdwarf/dwarf_get_fde_instr_bytes.c
@@ -0,0 +1,33 @@
+/* Get frame construction instructions of FDE.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_get_fde_instr_bytes (fde, outinstrs, outlen, error)
+ Dwarf_Fde fde;
+ Dwarf_Ptr *outinstrs;
+ Dwarf_Unsigned *outlen;
+ Dwarf_Error *error;
+{
+ *outinstrs = fde->instructions;
+ *outlen = fde->instructions_length;
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_fde_list_eh.c b/libdwarf/dwarf_get_fde_list_eh.c
new file mode 100644
index 00000000..bcda71b0
--- /dev/null
+++ b/libdwarf/dwarf_get_fde_list_eh.c
@@ -0,0 +1,363 @@
+/* Get frame descriptions. GCC version using .eh_frame.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libdwarfP.h>
+
+
+struct cielist
+{
+ Dwarf_Cie cie;
+ struct cielist *next;
+};
+
+
+struct fdelist
+{
+ Dwarf_Fde fde;
+ Dwarf_Small *cie_id_ptr;
+ struct fdelist *next;
+};
+
+
+int
+dwarf_get_fde_list_eh (dbg, cie_data, cie_element_count, fde_data,
+ fde_element_count, error)
+ Dwarf_Debug dbg;
+ Dwarf_Cie **cie_data;
+ Dwarf_Signed *cie_element_count;
+ Dwarf_Fde **fde_data;
+ Dwarf_Signed *fde_element_count;
+ Dwarf_Error *error;
+{
+ Dwarf_Small *readp;
+ Dwarf_Small *readendp;
+ struct cielist *cielist = NULL;
+ struct cielist *copy_cielist;
+ unsigned int ncielist = 0;
+ struct fdelist *fdelist = NULL;
+ unsigned int nfdelist = 0;
+
+ if (dbg->sections[IDX_eh_frame].addr == NULL)
+ return DW_DLV_NO_ENTRY;
+
+ readp = (Dwarf_Small *) dbg->sections[IDX_eh_frame].addr;
+ readendp = readp + dbg->sections[IDX_eh_frame].size;
+
+ while (readp < readendp)
+ {
+ /* Each CIE contains the following:
+
+ 1. CIE_length (initial length)
+
+ A constant that gives the number of bytes of the CIE
+ structure, not including the length field, itself [...].
+
+ 2. CIE_id
+
+ A constant that is used to distinguish CIEs from FDEs.
+
+ 3. version (ubyte) [...]
+
+ 4. augmentation (array of ubyte)
+
+ A null-terminated string that identifies the augmentation to
+ this CIE or to the FDEs that use it.
+
+ 5. code_alignment_factor (unsigned LEB128)
+
+ A constant that is factored out of all advance location
+ instructions (see below).
+
+ 6. data_alignment_factor (signed LEB128)
+
+ A constant that is factored out of all offset instructions
+ [...].
+
+ 7. return_address_register (ubyte)
+
+ A constant that indicates which column in the rule table
+ represents the return address of the function.
+
+ 8. initial_instructions (array of ubyte) [...] */
+ Dwarf_Small *fde_cie_start;
+ Dwarf_Small *readstartp;
+ Dwarf_Small *cie_id_ptr;
+ Dwarf_Unsigned length;
+ unsigned int address_size;
+ Dwarf_Unsigned start_offset;
+ Dwarf_Unsigned cie_id;
+
+ /* Remember where this entry started. */
+ fde_cie_start = readp;
+ start_offset = (readp
+ - (Dwarf_Small *) dbg->sections[IDX_eh_frame].addr);
+
+ length = read_4ubyte_unaligned (dbg, readp);
+ address_size = 4;
+ readp += 4;
+ if (length == 0xffffffff)
+ {
+ length = read_8ubyte_unaligned (dbg, readp);
+ readp += 8;
+ address_size = 8;
+ }
+ readstartp = readp;
+
+ /* Requirement from the DWARF specification. */
+ if (unlikely (length % address_size != 0))
+ {
+ /* XXX Free resources. */
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* No more entries. */
+ if (length == 0)
+ break;
+
+ cie_id_ptr = readp;
+ if (address_size == 4)
+ {
+ cie_id = read_4sbyte_unaligned (dbg, readp);
+ readp += 4;
+ }
+ else
+ {
+ cie_id = read_8sbyte_unaligned (dbg, readp);
+ readp += 8;
+ }
+
+ /* Now we can distinguish between CIEs and FDEs. gcc uses 0 to
+ signal the record is a CIE. */
+ if (cie_id == 0)
+ {
+ char *augmentation;
+ Dwarf_Unsigned code_alignment_factor;
+ Dwarf_Signed data_alignment_factor;
+ Dwarf_Small *initial_instructions;
+ Dwarf_Small return_address_register;
+ struct cielist *new_cie;
+
+ if (unlikely (*readp++ != CIE_VERSION))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ augmentation = (char *) readp;
+ readp += strlen (augmentation) + 1;
+
+ if (strcmp (augmentation, "") == 0)
+ {
+ get_uleb128 (code_alignment_factor, readp);
+ get_sleb128 (data_alignment_factor, readp);
+ return_address_register = *readp++;
+ initial_instructions = readp;
+ }
+ else if (strcmp (augmentation, "eh") == 0)
+ {
+ /* GCC exception handling. It has an extra field next
+ which is the address of a exception table. We ignore
+ this value since it's only used at runtime by the
+ exception handling. */
+ readp += address_size;
+
+ /* Now the standard fields. */
+ get_uleb128 (code_alignment_factor, readp);
+ get_sleb128 (data_alignment_factor, readp);
+ return_address_register = *readp++;
+ initial_instructions = readp;
+ }
+ else
+ {
+ /* We don't know this augmentation. Skip the rest. The
+ specification says that nothing after the augmentation
+ string is usable. */
+ code_alignment_factor = 0;
+ data_alignment_factor = 0;
+ return_address_register = 0;
+ initial_instructions = NULL;
+ }
+
+ /* Go to the next record. */
+ readp = readstartp + length;
+
+ /* Create the new CIE record. */
+ new_cie = (struct cielist *) alloca (sizeof (struct cielist));
+ new_cie->cie = (Dwarf_Cie) malloc (sizeof (struct Dwarf_Cie_s));
+ if (new_cie->cie == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ new_cie->cie->dbg = dbg;
+ new_cie->cie->length = length;
+ new_cie->cie->augmentation = augmentation;
+ new_cie->cie->code_alignment_factor = code_alignment_factor;
+ new_cie->cie->data_alignment_factor = data_alignment_factor;
+ new_cie->cie->return_address_register = return_address_register;
+ new_cie->cie->initial_instructions = initial_instructions;
+ new_cie->cie->initial_instructions_length =
+ readp - initial_instructions;
+
+ new_cie->cie->offset = start_offset;
+ new_cie->cie->index = ncielist;
+ new_cie->next = cielist;
+ cielist = new_cie;
+ ++ncielist;
+ }
+ else
+ {
+ Dwarf_Addr initial_location;
+ Dwarf_Unsigned address_range;
+ Dwarf_Small *instructions;
+ struct fdelist *new_fde;
+ struct cielist *cie;
+
+ if (address_size == 4)
+ {
+ initial_location = read_4ubyte_unaligned (dbg, readp);
+ readp += 4;
+ address_range = read_4ubyte_unaligned (dbg, readp);
+ readp += 4;
+ }
+ else
+ {
+ initial_location = read_8ubyte_unaligned (dbg, readp);
+ readp += 8;
+ address_range = read_8ubyte_unaligned (dbg, readp);
+ readp += 8;
+ }
+
+ instructions = readp;
+
+ /* Go to the next record. */
+ readp = readstartp + length;
+
+ /* Create the new FDE record. */
+ new_fde = (struct fdelist *) alloca (sizeof (struct fdelist));
+ new_fde->fde = (Dwarf_Fde) malloc (sizeof (struct Dwarf_Fde_s));
+ if (new_fde->fde == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ new_fde->fde->initial_location = initial_location;
+ new_fde->fde->address_range = address_range;
+ new_fde->fde->instructions = instructions;
+ new_fde->fde->instructions_length = readp - instructions;
+ new_fde->fde->fde_bytes = fde_cie_start;
+ new_fde->fde->fde_byte_length = readstartp + length - fde_cie_start;
+ new_fde->fde->cie = NULL;
+ new_fde->cie_id_ptr = cie_id_ptr;
+
+ for (cie = cielist; cie != NULL; cie = cie->next)
+ /* This test takes the non-standard way of using the CIE ID
+ in the GNU .eh_frame sectio into account. Instead of being
+ a direct offset in the section it is a offset from the
+ location of the FDE'S CIE ID value itself to the CIE entry. */
+ if (cie->cie->offset
+ == (size_t) (cie_id_ptr - cie_id
+ - (Dwarf_Small *) dbg->sections[IDX_eh_frame].addr))
+ {
+ new_fde->fde->cie = cie->cie;
+ break;
+ }
+
+ new_fde->fde->offset = cie_id;
+ new_fde->next = fdelist;
+ fdelist = new_fde;
+ ++nfdelist;
+ }
+ }
+
+ /* There must always be at least one CIE. */
+ if (unlikely (ncielist == 0))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* Create the lists. */
+ *cie_data = (Dwarf_Cie *) malloc (ncielist * sizeof (struct Dwarf_Cie_s));
+ if (nfdelist > 0)
+ *fde_data = (Dwarf_Fde *) malloc (nfdelist * sizeof (struct Dwarf_Fde_s));
+ else
+ *fde_data = NULL;
+ if ((nfdelist > 0 && *fde_data == NULL) || *cie_data == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ /* Remember the counts. */
+ dbg->fde_cnt = nfdelist;
+ dbg->cie_cnt = ncielist;
+
+ /* Add all the CIEs. */
+ copy_cielist = cielist;
+ *cie_element_count = ncielist;
+ while (ncielist-- > 0)
+ {
+ (*cie_data)[ncielist] = cielist->cie;
+ cielist = cielist->next;
+ }
+
+ /* Add all the FDEs. */
+ *fde_element_count = nfdelist;
+ while (nfdelist-- > 0)
+ {
+ (*fde_data)[nfdelist] = fdelist->fde;
+
+ if (fdelist->fde->cie == NULL)
+ {
+ /* We have not yet found the CIE. Search now that we know
+ about all of them. */
+ cielist = copy_cielist;
+ do
+ {
+ if (cielist->cie->offset
+ == (size_t) (fdelist->cie_id_ptr - fdelist->fde->offset
+ - (Dwarf_Small *) dbg->sections[IDX_eh_frame].addr))
+ {
+ fdelist->fde->cie = cielist->cie;
+ break;
+ }
+ cielist = cielist->next;
+ }
+ while (cielist != NULL);
+
+ if (cielist == NULL)
+ {
+ /* There is no matching CIE. This is bad. */
+ /* XXX Free everything. */
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ }
+
+ fdelist = fdelist->next;
+ }
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_fde_n.c b/libdwarf/dwarf_get_fde_n.c
new file mode 100644
index 00000000..5531deaf
--- /dev/null
+++ b/libdwarf/dwarf_get_fde_n.c
@@ -0,0 +1,36 @@
+/* Get nth frame descriptions.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwarfP.h"
+
+
+int
+dwarf_get_fde_n (fde_data, fde_index, returned_fde, error)
+ Dwarf_Fde *fde_data;
+ Dwarf_Unsigned fde_index;
+ Dwarf_Fde *returned_fde;
+ Dwarf_Error *error;
+{
+ Dwarf_Debug dbg = fde_data[0]->cie->dbg;
+
+ if (fde_index >= dbg->fde_cnt)
+ return DW_DLV_NO_ENTRY;
+
+ *returned_fde = fde_data[fde_index];
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_fde_range.c b/libdwarf/dwarf_get_fde_range.c
new file mode 100644
index 00000000..f7049145
--- /dev/null
+++ b/libdwarf/dwarf_get_fde_range.c
@@ -0,0 +1,44 @@
+/* Get information about the function range.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwarfP.h"
+
+
+int
+dwarf_get_fde_range (fde, low_pc, func_length, fde_bytes, fde_byte_length,
+ cie_offset, cie_index, fde_offset, error)
+ Dwarf_Fde fde;
+ Dwarf_Addr *low_pc;
+ Dwarf_Unsigned *func_length;
+ Dwarf_Ptr *fde_bytes;
+ Dwarf_Unsigned *fde_byte_length;
+ Dwarf_Off *cie_offset;
+ Dwarf_Signed *cie_index;
+ Dwarf_Off *fde_offset;
+ Dwarf_Error *error;
+{
+ *low_pc = fde->initial_location;
+ *func_length = fde->address_range;
+ *fde_bytes = fde->fde_bytes;
+ *fde_byte_length = fde->fde_byte_length;
+ *cie_offset = fde->cie->offset;
+ *cie_index = fde->cie->index;
+ *fde_offset = fde->offset;
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_globals.c b/libdwarf/dwarf_get_globals.c
new file mode 100644
index 00000000..01b48ae7
--- /dev/null
+++ b/libdwarf/dwarf_get_globals.c
@@ -0,0 +1,176 @@
+/* Return list of global definitions.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stdlib.h>
+#include <string.h>
+
+#include <libdwarfP.h>
+
+
+struct globallist
+{
+ Dwarf_Global global;
+ struct globallist *next;
+};
+
+
+/* Read the whole given section. */
+int
+dwarf_get_globals (dbg, globals, return_count, error)
+ Dwarf_Debug dbg;
+ Dwarf_Global **globals;
+ Dwarf_Signed *return_count;
+ Dwarf_Error *error;
+{
+ Dwarf_Small *readp;
+ Dwarf_Small *readendp;
+ struct globallist *globallist = NULL;
+ unsigned int ngloballist = 0;
+
+ if (dbg->sections[IDX_debug_pubnames].addr == NULL)
+ return DW_DLV_NO_ENTRY;
+
+ readp = (Dwarf_Small *) dbg->sections[IDX_debug_pubnames].addr;
+ readendp = readp + dbg->sections[IDX_debug_pubnames].size;
+
+ while (readp < readendp)
+ {
+ Dwarf_Unsigned length;
+ Dwarf_Unsigned info_length;
+ unsigned int length_bytes;
+ unsigned int version;
+ Dwarf_Unsigned offset;
+ Dwarf_Global_Info global_info;
+
+ /* Each entry starts with a header:
+
+ 1. A 4-byte or 12-byte length of the set of entries for this
+ compilation unit, not including the length field itself. [...]
+
+ 2. A 2-byte version identifier containing the value 2 for
+ DWARF Version 2.1.
+
+ 3. A 4-byte or 8-byte offset into the .debug_info section. [...]
+
+ 4. A 4-byte or 8-byte length containing the size in bytes of
+ the contents of the .debug_info section generated to
+ represent this compilation unit. [...] */
+ length = read_4ubyte_unaligned (dbg, readp);
+ readp += 4;
+ length_bytes = 4;
+ if (length == 0xffffffff)
+ {
+ length = read_8ubyte_unaligned (dbg, readp);
+ readp += 8;
+ length_bytes = 8;
+ }
+
+ version = read_2ubyte_unaligned (dbg, readp);
+ readp += 2;
+ if (unlikely (version != 2))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ if (length_bytes == 4)
+ {
+ offset = read_4ubyte_unaligned (dbg, readp);
+ readp += 4;
+ info_length = read_4ubyte_unaligned (dbg, readp);
+ readp += 4;
+ }
+ else
+ {
+ offset = read_8ubyte_unaligned (dbg, readp);
+ readp += 8;
+ info_length = read_8ubyte_unaligned (dbg, readp);
+ readp += 8;
+ }
+
+ global_info =
+ (Dwarf_Global_Info) malloc (sizeof (struct Dwarf_Global_s));
+ if (global_info == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ global_info->dbg = dbg;
+ global_info->offset = offset;
+
+ /* Following the section contains tuples of offsets and
+ nul-terminated strings. */
+ while (1)
+ {
+ Dwarf_Unsigned die_offset;
+ struct globallist *new_global;
+
+ if (length_bytes == 4)
+ die_offset = read_4ubyte_unaligned (dbg, readp);
+ else
+ die_offset = read_8ubyte_unaligned (dbg, readp);
+ readp += length_bytes;
+
+ if (die_offset == 0)
+ /* This closes this entry. */
+ break;
+
+ new_global =
+ (struct globallist *) alloca (sizeof (struct globallist));
+ new_global->global =
+ (Dwarf_Global) malloc (sizeof (struct Dwarf_Global_s));
+ if (new_global->global == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ new_global->global->offset = die_offset;
+ new_global->global->name = (char *) readp;
+ new_global->global->info = global_info;
+
+ new_global->next = globallist;
+ globallist = new_global;
+ ++ngloballist;
+
+ readp = (Dwarf_Small *) rawmemchr (readp, '\0') + 1;
+ }
+ }
+
+ if (ngloballist == 0)
+ return DW_DLV_NO_ENTRY;
+
+ /* Allocate the array for the result. */
+ *return_count = ngloballist;
+ *globals = (Dwarf_Global *) malloc (ngloballist
+ * sizeof (struct Dwarf_Global_s));
+ if (*globals == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ while (ngloballist-- > 0)
+ {
+ (*globals)[ngloballist] = globallist->global;
+ globallist = globallist->next;
+ }
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_loclist_entry.c b/libdwarf/dwarf_get_loclist_entry.c
new file mode 100644
index 00000000..f6510c77
--- /dev/null
+++ b/libdwarf/dwarf_get_loclist_entry.c
@@ -0,0 +1,88 @@
+/* Return location list entry.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include "libdwarfP.h"
+
+
+int
+dwarf_get_loclist_entry (dbg, offset, hipc_offset, lopc_offset, data,
+ entry_len, next_entry, error)
+ Dwarf_Debug dbg;
+ Dwarf_Unsigned offset;
+ Dwarf_Addr *hipc_offset;
+ Dwarf_Addr *lopc_offset;
+ Dwarf_Ptr *data;
+ Dwarf_Unsigned *entry_len;
+ Dwarf_Unsigned *next_entry;
+ Dwarf_Error *error;
+{
+ Dwarf_Small *locp;
+
+ /* Make sure we have room for at least two addresses. */
+ if (unlikely (offset + 2 * dbg->cu_list->address_size
+ > dbg->sections[IDX_debug_loc].size))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ locp = (Dwarf_Small *) dbg->sections[IDX_debug_loc].addr + offset;
+
+ /* Get the two values. */
+ if (dbg->cu_list->address_size == 4)
+ {
+ *lopc_offset = read_4ubyte_unaligned (dbg, locp);
+ *hipc_offset = read_4ubyte_unaligned (dbg, locp + 4);
+ locp += 8;
+ offset += 8;
+ }
+ else
+ {
+ *lopc_offset = read_8ubyte_unaligned (dbg, locp);
+ *hipc_offset = read_8ubyte_unaligned (dbg, locp + 8);
+ locp += 16;
+ offset += 16;
+ }
+
+ /* Does this signal the end? */
+ if (*lopc_offset == 0 && *hipc_offset == 0)
+ return DW_DLV_OK;
+
+ /* Make sure another 2 bytes are available for the length. */
+ if (unlikely (offset + 2 > dbg->sections[IDX_debug_loc].size))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ *entry_len = read_2ubyte_unaligned (dbg, locp);
+ locp += 2;
+ offset += 2;
+ *data = locp;
+
+ /* Now we know how long the block is. Test whether that much
+ data is available. */
+ if (unlikely (offset + *entry_len > dbg->sections[IDX_debug_loc].size))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ *next_entry = offset + *entry_len;
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_get_str.c b/libdwarf/dwarf_get_str.c
new file mode 100644
index 00000000..3f289c3d
--- /dev/null
+++ b/libdwarf/dwarf_get_str.c
@@ -0,0 +1,43 @@
+/* Return string from debug string section.
+ Copyright (C) 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2001.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#include "libdwarfP.h"
+
+
+int
+dwarf_get_str (dbg, offset, string, returned_str_len, error)
+ Dwarf_Debug dbg;
+ Dwarf_Off offset;
+ char **string;
+ Dwarf_Signed *returned_str_len;
+ Dwarf_Error *error;
+{
+ *string = (char *) dbg->sections[IDX_debug_str].addr;
+ if (*string == NULL)
+ return DW_DLV_NO_ENTRY;
+
+ if (unlikely (offset >= dbg->sections[IDX_debug_str].size))
+ return DW_DLV_NO_ENTRY;
+
+ *string += offset;
+ *returned_str_len = strlen (*string);
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_getabbrev.c b/libdwarf/dwarf_getabbrev.c
new file mode 100644
index 00000000..2220fc34
--- /dev/null
+++ b/libdwarf/dwarf_getabbrev.c
@@ -0,0 +1,73 @@
+/* Internal abbrev list handling
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <stdlib.h>
+
+#include <libdwarfP.h>
+
+
+Dwarf_Abbrev
+__libdwarf_get_abbrev (dbg, cu, code, error)
+ Dwarf_Debug dbg;
+ Dwarf_CU_Info cu;
+ Dwarf_Word code;
+ Dwarf_Error *error;
+{
+ Dwarf_Abbrev ent;
+
+ /* See whether the entry is already in the hash table. */
+ ent = Dwarf_Abbrev_Hash_find (&cu->abbrev_hash, code, NULL);
+ if (ent != NULL)
+ return ent;
+
+ while (1)
+ {
+ Dwarf_Unsigned length;
+ Dwarf_Unsigned attr_count;
+
+ if (dwarf_get_abbrev (dbg, cu->last_abbrev_offset, &ent, &length,
+ &attr_count, error) != DW_DLV_OK)
+ return NULL;
+
+ if (length == 1)
+ /* This is the end of the list. */
+ break;
+
+ /* Update the offset to the next record. */
+ cu->last_abbrev_offset += length;
+
+ /* Insert the new entry into the hashing table. */
+ if (unlikely (Dwarf_Abbrev_Hash_insert (&cu->abbrev_hash, ent->code, ent)
+ != 0))
+ {
+ free (ent);
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return NULL;
+ }
+
+ /* Is this the code we are looking for? */
+ if (ent->code == code)
+ /* Yes! */
+ return ent;
+ }
+
+ /* If we come here we haven't found anything. */
+ __libdwarf_error (dbg, error, DW_E_NO_ABBR);
+ return NULL;
+}
diff --git a/libdwarf/dwarf_getconstant.c b/libdwarf/dwarf_getconstant.c
new file mode 100644
index 00000000..39727f8a
--- /dev/null
+++ b/libdwarf/dwarf_getconstant.c
@@ -0,0 +1,125 @@
+/* Return constant value of given attribute type associated with die.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#include <libdwarfP.h>
+
+
+int
+__libdwarf_getconstant (die, name, return_size, error)
+ Dwarf_Die die;
+ Dwarf_Half name;
+ Dwarf_Unsigned *return_size;
+ Dwarf_Error *error;
+{
+ Dwarf_Debug dbg = die->cu->dbg;
+ Dwarf_Small *die_addr;
+ Dwarf_Word u128;
+ Dwarf_Abbrev abbrev;
+ Dwarf_Small *attrp;
+
+ /* Address of the given die. */
+ die_addr = die->addr;
+
+ /* Get abbrev code. */
+ get_uleb128 (u128, die_addr);
+ /* And get the abbreviation itself. */
+ abbrev = __libdwarf_get_abbrev (dbg, die->cu, u128, error);
+ if (abbrev == NULL)
+ return DW_DLV_ERROR;
+
+ /* This is where the attributes start. */
+ attrp = abbrev->attrp;
+
+ /* Search the name attribute. */
+ while (1)
+ {
+ Dwarf_Word attr_name;
+ Dwarf_Word attr_form;
+
+ /* Are we still in bounds? */
+ if (unlikely (attrp
+ >= ((Dwarf_Small *) dbg->sections[IDX_debug_abbrev].addr
+ + dbg->sections[IDX_debug_abbrev].size)))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* Get attribute name and form.
+
+ XXX We don't check whether this reads beyond the end of the
+ section. */
+ get_uleb128 (attr_name, attrp);
+ get_uleb128 (attr_form, attrp);
+
+ /* We can stop if we found the attribute with value zero. */
+ if (attr_name == 0 && attr_form == 0)
+ break;
+
+ /* Is this the name attribute? */
+ if (unlikely (attr_name == name))
+ {
+ switch (attr_form)
+ {
+ case DW_FORM_data1:
+ *return_size = *die_addr;
+ break;
+ case DW_FORM_data2:
+ *return_size = read_2ubyte_unaligned (dbg, die_addr);
+ break;
+ case DW_FORM_data4:
+ *return_size = read_4ubyte_unaligned (dbg, die_addr);
+ break;
+ case DW_FORM_data8:
+ *return_size = read_8ubyte_unaligned (dbg, die_addr);
+ break;
+ case DW_FORM_sdata:
+ get_sleb128 (u128, die_addr);
+ *return_size = u128;
+ break;
+ case DW_FORM_udata:
+ get_uleb128 (u128, die_addr);
+ *return_size = u128;
+ break;
+ default:
+ __libdwarf_error (dbg, error, DW_E_NO_CONSTANT);
+ return DW_DLV_ERROR;
+ }
+
+ return DW_DLV_OK;
+ }
+
+ /* Skip over the rest of this attribute (if there is any). */
+ if (attr_form != 0)
+ {
+ size_t len;
+
+ if (unlikely (__libdwarf_form_val_len (dbg, die->cu, attr_form,
+ die_addr, &len, error)
+ != DW_DLV_OK))
+ return DW_DLV_ERROR;
+
+ die_addr += len;
+ }
+ }
+
+ /* No such attribute present. */
+ return DW_DLV_NO_ENTRY;
+}
diff --git a/libdwarf/dwarf_global_cu_offset.c b/libdwarf/dwarf_global_cu_offset.c
new file mode 100644
index 00000000..b5a30f42
--- /dev/null
+++ b/libdwarf/dwarf_global_cu_offset.c
@@ -0,0 +1,44 @@
+/* Return offset of header of compile unit containing the global definition.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_global_cu_offset (global, return_offset, error)
+ Dwarf_Global global;
+ Dwarf_Off *return_offset;
+ Dwarf_Error *error;
+{
+ Dwarf_Small *cu_header;
+ unsigned int offset_size;
+
+ cu_header =
+ ((Dwarf_Small *) global->info->dbg->sections[IDX_debug_info].addr
+ + global->info->offset);
+ if (read_4ubyte_unaligned_noncvt (cu_header) == 0xffffffff)
+ offset_size = 8;
+ else
+ offset_size = 4;
+
+ *return_offset = global->info->offset + 3 * offset_size - 4 + 3;
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_global_die_offset.c b/libdwarf/dwarf_global_die_offset.c
new file mode 100644
index 00000000..654340fc
--- /dev/null
+++ b/libdwarf/dwarf_global_die_offset.c
@@ -0,0 +1,33 @@
+/* Return DIE offset for global definition.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_global_die_offset (global, return_offset, error)
+ Dwarf_Global global;
+ Dwarf_Off *return_offset;
+ Dwarf_Error *error;
+{
+ *return_offset = global->info->offset + global->offset;
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_global_formref.c b/libdwarf/dwarf_global_formref.c
new file mode 100644
index 00000000..16ea7b7a
--- /dev/null
+++ b/libdwarf/dwarf_global_formref.c
@@ -0,0 +1,73 @@
+/* Return .debug_info section global offset of reference associated with form.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_global_formref (attr, return_offset, error)
+ Dwarf_Attribute attr;
+ Dwarf_Off *return_offset;
+ Dwarf_Error *error;
+{
+ switch (attr->form)
+ {
+ case DW_FORM_ref1:
+ *return_offset = *attr->valp + attr->cu->offset;
+ break;
+
+ case DW_FORM_ref2:
+ *return_offset = (read_2ubyte_unaligned (attr->cu->dbg, attr->valp)
+ + attr->cu->offset);
+ break;
+
+ case DW_FORM_ref4:
+ *return_offset = (read_4ubyte_unaligned (attr->cu->dbg, attr->valp)
+ + attr->cu->offset);
+ break;
+
+ case DW_FORM_ref8:
+ *return_offset = (read_8ubyte_unaligned (attr->cu->dbg, attr->valp)
+ + attr->cu->offset);
+ break;
+
+ case DW_FORM_ref_udata:
+ {
+ Dwarf_Off off;
+ Dwarf_Small *attrp = attr->valp;
+ get_uleb128 (off, attrp);
+ *return_offset = off + attr->cu->offset;
+ }
+ break;
+
+ case DW_FORM_ref_addr:
+ if (attr->cu->address_size == 4)
+ *return_offset = read_4ubyte_unaligned (attr->cu->dbg, attr->valp);
+ else
+ *return_offset = read_8ubyte_unaligned (attr->cu->dbg, attr->valp);
+ break;
+
+ default:
+ __libdwarf_error (attr->cu->dbg, error, DW_E_NO_REFERENCE);
+ return DW_DLV_ERROR;
+ }
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_global_name_offsets.c b/libdwarf/dwarf_global_name_offsets.c
new file mode 100644
index 00000000..a9b149c0
--- /dev/null
+++ b/libdwarf/dwarf_global_name_offsets.c
@@ -0,0 +1,64 @@
+/* Return name, DIE offset, and offset of the compile unit for global
+ definition.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_global_name_offsets (global, return_name, die_offset, cu_offset, error)
+ Dwarf_Global global;
+ char **return_name;
+ Dwarf_Off *die_offset;
+ Dwarf_Off *cu_offset;
+ Dwarf_Error *error;
+{
+ if (return_name != NULL)
+ {
+ *return_name = strdup (global->name);
+ if (*return_name == NULL)
+ {
+ __libdwarf_error (global->info->dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+ }
+
+ if (die_offset != NULL)
+ *die_offset = global->offset + global->info->offset;
+
+ /* Determine the size of the CU header. */
+ if (cu_offset != NULL)
+ {
+ Dwarf_Small *cu_header;
+ unsigned int offset_size;
+
+ cu_header =
+ ((Dwarf_Small *) global->info->dbg->sections[IDX_debug_info].addr
+ + global->info->offset);
+ if (read_4ubyte_unaligned_noncvt (cu_header) == 0xffffffff)
+ offset_size = 8;
+ else
+ offset_size = 4;
+
+ *cu_offset = global->info->offset + 3 * offset_size - 4 + 3;
+ }
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_globname.c b/libdwarf/dwarf_globname.c
new file mode 100644
index 00000000..1c565290
--- /dev/null
+++ b/libdwarf/dwarf_globname.c
@@ -0,0 +1,38 @@
+/* Return name for global definition.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_globname (global, return_name, error)
+ Dwarf_Global global;
+ char **return_name;
+ Dwarf_Error *error;
+{
+ *return_name = strdup (global->name);
+ if (*return_name == NULL)
+ {
+ __libdwarf_error (global->info->dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_hasattr.c b/libdwarf/dwarf_hasattr.c
new file mode 100644
index 00000000..337a3e10
--- /dev/null
+++ b/libdwarf/dwarf_hasattr.c
@@ -0,0 +1,98 @@
+/* Determine whether die has attribute specified of given type.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_hasattr (die, attr, return_bool, error)
+ Dwarf_Die die;
+ Dwarf_Half attr;
+ Dwarf_Bool *return_bool;
+ Dwarf_Error *error;
+{
+ Dwarf_Debug dbg = die->cu->dbg;
+ Dwarf_Small *die_addr;
+ Dwarf_Word u128;
+ Dwarf_Abbrev abbrev;
+ Dwarf_Small *attrp;
+
+ /* Address of the given die. */
+ die_addr = die->addr;
+
+ /* Get abbrev code. */
+ get_uleb128 (u128, die_addr);
+ /* And get the abbreviation itself. */
+ abbrev = __libdwarf_get_abbrev (dbg, die->cu, u128, error);
+ if (abbrev == NULL)
+ return DW_DLV_ERROR;
+
+ /* This is where the attributes start. */
+ attrp = abbrev->attrp;
+
+ /* Search the name attribute. */
+ while (1)
+ {
+ Dwarf_Word attr_name;
+ Dwarf_Word attr_form;
+
+ /* Are we still in bounds? */
+ if (unlikely (attrp
+ >= ((Dwarf_Small *) dbg->sections[IDX_debug_abbrev].addr
+ + dbg->sections[IDX_debug_abbrev].size)))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* Get attribute name and form.
+
+ XXX We don't check whether this reads beyond the end of the
+ section. */
+ get_uleb128 (attr_name, attrp);
+ get_uleb128 (attr_form, attrp);
+
+ /* We can stop if we found the attribute with value zero. */
+ if (attr_name == 0 && attr_form == 0)
+ break;
+
+ /* Is this the name attribute? */
+ if (attr_name == attr)
+ {
+ *return_bool = 1;
+ return DW_DLV_OK;
+ }
+
+ /* Skip over the rest of this attribute (if there is any). */
+ if (attr_form != 0)
+ {
+ size_t len;
+
+ if (unlikely (__libdwarf_form_val_len (dbg, die->cu, attr_form,
+ die_addr, &len, error)
+ != DW_DLV_OK))
+ return DW_DLV_ERROR;
+
+ die_addr += len;
+ }
+ }
+
+ /* No such attribute present. */
+ *return_bool = 0;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_hasform.c b/libdwarf/dwarf_hasform.c
new file mode 100644
index 00000000..cfb6cf99
--- /dev/null
+++ b/libdwarf/dwarf_hasform.c
@@ -0,0 +1,31 @@
+/* Determine whether attribute has given form.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_hasform (attr, form, return_hasform, error)
+ Dwarf_Attribute attr;
+ Dwarf_Half form;
+ Dwarf_Bool *return_hasform;
+ Dwarf_Error *error;
+{
+ *return_hasform = attr->form == form;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_highpc.c b/libdwarf/dwarf_highpc.c
new file mode 100644
index 00000000..5e56376d
--- /dev/null
+++ b/libdwarf/dwarf_highpc.c
@@ -0,0 +1,108 @@
+/* Return high program counter value associated with die.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_highpc (die, return_highpc, error)
+ Dwarf_Die die;
+ Dwarf_Addr *return_highpc;
+ Dwarf_Error *error;
+{
+ Dwarf_Debug dbg = die->cu->dbg;
+ Dwarf_Small *die_addr;
+ Dwarf_Word u128;
+ Dwarf_Abbrev abbrev;
+ Dwarf_Small *attrp;
+
+ /* Address of the given die. */
+ die_addr = die->addr;
+
+ /* Get abbrev code. */
+ get_uleb128 (u128, die_addr);
+ /* And get the abbreviation itself. */
+ abbrev = __libdwarf_get_abbrev (dbg, die->cu, u128, error);
+ if (abbrev == NULL)
+ return DW_DLV_ERROR;
+
+ /* This is where the attributes start. */
+ attrp = abbrev->attrp;
+
+ /* Search the name attribute. */
+ while (1)
+ {
+ Dwarf_Word attr_name;
+ Dwarf_Word attr_form;
+
+ /* Are we still in bounds? */
+ if (unlikely (attrp
+ >= ((Dwarf_Small *) dbg->sections[IDX_debug_abbrev].addr
+ + dbg->sections[IDX_debug_abbrev].size)))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* Get attribute name and form.
+
+ XXX We don't check whether this reads beyond the end of the
+ section. */
+ get_uleb128 (attr_name, attrp);
+ get_uleb128 (attr_form, attrp);
+
+ /* We can stop if we found the attribute with value zero. */
+ if (attr_name == 0 && attr_form == 0)
+ break;
+
+ /* Is this the name attribute? */
+ if (unlikely (attr_name == DW_AT_high_pc))
+ {
+ if (unlikely (attr_form != DW_FORM_addr))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ if (die->cu->address_size == 4)
+ *return_highpc = read_4ubyte_unaligned (dbg, die_addr);
+ else
+ *return_highpc = read_8ubyte_unaligned (dbg, die_addr);
+
+ return DW_DLV_OK;
+ }
+
+ /* Skip over the rest of this attribute (if there is any). */
+ if (attr_form != 0)
+ {
+ size_t len;
+
+ if (unlikely (__libdwarf_form_val_len (dbg, die->cu, attr_form,
+ die_addr, &len, error)
+ != DW_DLV_OK))
+ return DW_DLV_ERROR;
+
+ die_addr += len;
+ }
+ }
+
+ /* No such attribute present. */
+ return DW_DLV_NO_ENTRY;
+}
diff --git a/libdwarf/dwarf_init.c b/libdwarf/dwarf_init.c
new file mode 100644
index 00000000..bbb86602
--- /dev/null
+++ b/libdwarf/dwarf_init.c
@@ -0,0 +1,92 @@
+/* Create descriptor from file descriptor for processing file.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <stddef.h>
+#include <sys/stat.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_init (fd, access, errhand, errarg, dbg, error)
+ int fd;
+ Dwarf_Unsigned access;
+ Dwarf_Handler errhand;
+ Dwarf_Ptr errarg;
+ Dwarf_Debug *dbg;
+ Dwarf_Error *error;
+{
+ Elf *elf;
+ Elf_Cmd cmd;
+ struct Dwarf_Debug_s newdbg;
+ int result = DW_DLV_ERROR;
+
+ switch (access)
+ {
+ case DW_DLC_READ:
+ cmd = ELF_C_READ_MMAP;
+ break;
+ case DW_DLC_WRITE:
+ cmd = ELF_C_WRITE;
+ break;
+ case DW_DLC_RDWR:
+ cmd = ELF_C_RDWR;
+ break;
+ default:
+ /* These are the error values we want to use. */
+ newdbg.dbg_errhand = errhand;
+ newdbg.dbg_errarg = errarg;
+
+ __libdwarf_error (&newdbg, error, DW_E_INVALID_ACCESS);
+ return DW_DLV_ERROR;
+ }
+
+ /* We have to call `elf_version' here since the user might have not
+ done it or initialized libelf with a different version. This
+ would break libdwarf since we are using the ELF data structures
+ in a certain way. */
+ elf_version (EV_CURRENT);
+
+ /* Get an ELF descriptor. */
+ elf = elf_begin (fd, cmd, NULL);
+ if (elf == NULL)
+ {
+ /* Test why the `elf_begin" call failed. */
+ struct stat64 st;
+
+ /* These are the error values we want to use. */
+ newdbg.dbg_errhand = errhand;
+ newdbg.dbg_errarg = errarg;
+
+ if (fstat64 (fd, &st) == 0 && ! S_ISREG (st.st_mode))
+ __libdwarf_error (&newdbg, error, DW_E_NO_REGFILE);
+ else
+ __libdwarf_error (&newdbg, error, DW_E_IO_ERROR);
+ }
+ else
+ {
+ /* Do the real work now that we have an ELF descriptor. */
+ result = dwarf_elf_init (elf, access, errhand, errarg, dbg, error);
+
+ /* If this failed, free the resources. */
+ if (result != DW_DLV_OK)
+ elf_end (elf);
+ }
+
+ return result;
+}
diff --git a/libdwarf/dwarf_lineaddr.c b/libdwarf/dwarf_lineaddr.c
new file mode 100644
index 00000000..4bf49435
--- /dev/null
+++ b/libdwarf/dwarf_lineaddr.c
@@ -0,0 +1,30 @@
+/* Return address associate with line.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_lineaddr (line, return_lineaddr, error)
+ Dwarf_Line line;
+ Dwarf_Addr *return_lineaddr;
+ Dwarf_Error *error;
+{
+ *return_lineaddr = line->addr;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_linebeginstatement.c b/libdwarf/dwarf_linebeginstatement.c
new file mode 100644
index 00000000..d04c6ec9
--- /dev/null
+++ b/libdwarf/dwarf_linebeginstatement.c
@@ -0,0 +1,30 @@
+/* Determine whether line is the beginning of a statement.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_linebeginstatement (line, return_bool, error)
+ Dwarf_Line line;
+ Dwarf_Bool *return_bool;
+ Dwarf_Error *error;
+{
+ *return_bool = line->is_stmt;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_lineblock.c b/libdwarf/dwarf_lineblock.c
new file mode 100644
index 00000000..f15e54b9
--- /dev/null
+++ b/libdwarf/dwarf_lineblock.c
@@ -0,0 +1,30 @@
+/* Determine whether line is marked as beginning a basic block.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_lineblock (line, return_bool, error)
+ Dwarf_Line line;
+ Dwarf_Bool *return_bool;
+ Dwarf_Error *error;
+{
+ *return_bool = line->basic_block;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_lineendsequence.c b/libdwarf/dwarf_lineendsequence.c
new file mode 100644
index 00000000..93cbf8ec
--- /dev/null
+++ b/libdwarf/dwarf_lineendsequence.c
@@ -0,0 +1,30 @@
+/* Determine whether line is marked as ending a text sequence.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_lineendsequence (line, return_bool, error)
+ Dwarf_Line line;
+ Dwarf_Bool *return_bool;
+ Dwarf_Error *error;
+{
+ *return_bool = line->end_sequence;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_lineepiloguebegin.c b/libdwarf/dwarf_lineepiloguebegin.c
new file mode 100644
index 00000000..33df13f1
--- /dev/null
+++ b/libdwarf/dwarf_lineepiloguebegin.c
@@ -0,0 +1,30 @@
+/* Determine whether line is marked as beginning the epilogue.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_lineepiloguebegin (line, return_bool, error)
+ Dwarf_Line line;
+ Dwarf_Bool *return_bool;
+ Dwarf_Error *error;
+{
+ *return_bool = line->epilogue_begin;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_lineno.c b/libdwarf/dwarf_lineno.c
new file mode 100644
index 00000000..83f911d5
--- /dev/null
+++ b/libdwarf/dwarf_lineno.c
@@ -0,0 +1,30 @@
+/* Return source statement line number.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_lineno (line, return_lineno, error)
+ Dwarf_Line line;
+ Dwarf_Unsigned *return_lineno;
+ Dwarf_Error *error;
+{
+ *return_lineno = line->line;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_lineoff.c b/libdwarf/dwarf_lineoff.c
new file mode 100644
index 00000000..82f4bbcc
--- /dev/null
+++ b/libdwarf/dwarf_lineoff.c
@@ -0,0 +1,30 @@
+/* Return column at which the statement begins.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_lineoff (line, return_lineoff, error)
+ Dwarf_Line line;
+ Dwarf_Signed *return_lineoff;
+ Dwarf_Error *error;
+{
+ *return_lineoff = line->column ?: -1;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_lineprologueend.c b/libdwarf/dwarf_lineprologueend.c
new file mode 100644
index 00000000..f202f73d
--- /dev/null
+++ b/libdwarf/dwarf_lineprologueend.c
@@ -0,0 +1,30 @@
+/* Determine whether line is marked as ending the prologue.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_lineprologueend (line, return_bool, error)
+ Dwarf_Line line;
+ Dwarf_Bool *return_bool;
+ Dwarf_Error *error;
+{
+ *return_bool = line->prologue_end;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_linesrc.c b/libdwarf/dwarf_linesrc.c
new file mode 100644
index 00000000..5c990009
--- /dev/null
+++ b/libdwarf/dwarf_linesrc.c
@@ -0,0 +1,44 @@
+/* Return source file for line.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <string.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_linesrc (line, return_linesrc, error)
+ Dwarf_Line line;
+ char **return_linesrc;
+ Dwarf_Error *error;
+{
+ if (unlikely (line->file >= line->files->nfiles))
+ {
+ __libdwarf_error (line->files->dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ *return_linesrc = strdup (line->files->info[line->file].name);
+ if (*return_linesrc == NULL)
+ {
+ __libdwarf_error (line->files->dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_loclist.c b/libdwarf/dwarf_loclist.c
new file mode 100644
index 00000000..22a3944f
--- /dev/null
+++ b/libdwarf/dwarf_loclist.c
@@ -0,0 +1,470 @@
+/* Return location expression list.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <stdlib.h>
+
+#include <libdwarfP.h>
+
+
+struct loclist
+{
+ Dwarf_Small atom;
+ Dwarf_Unsigned number;
+ Dwarf_Unsigned number2;
+ Dwarf_Unsigned offset;
+ struct loclist *next;
+};
+
+struct locdesclist
+{
+ Dwarf_Addr lopc;
+ Dwarf_Addr hipc;
+ Dwarf_Half cents;
+ struct loclist *s;
+ struct locdesclist *next;
+};
+
+
+int
+dwarf_loclist (attr, llbuf, listlen, error)
+ Dwarf_Attribute attr;
+ Dwarf_Locdesc **llbuf;
+ Dwarf_Signed *listlen;
+ Dwarf_Error *error;
+{
+ Dwarf_CU_Info cu = attr->cu;
+ Dwarf_Debug dbg = cu->dbg;
+ Dwarf_Unsigned offset;
+ Dwarf_Unsigned offset_end;
+ Dwarf_Small *locp;
+ struct locdesclist *locdesclist;
+ Dwarf_Locdesc *result;
+ unsigned int n;
+
+ /* Must by one of the attribute listed below. */
+ if (attr->code != DW_AT_location
+ && attr->code != DW_AT_data_member_location
+ && attr->code != DW_AT_vtable_elem_location
+ && attr->code != DW_AT_string_length
+ && attr->code != DW_AT_use_location
+ && attr->code != DW_AT_return_addr)
+ {
+ __libdwarf_error (dbg, error, DW_E_WRONG_ATTR);
+ return DW_DLV_ERROR;
+ }
+
+ /* Must have the form data4 or data8 which act as an offset. */
+ if (attr->form == DW_FORM_data4)
+ offset = read_4ubyte_unaligned (dbg, attr->valp);
+ else if (likely (attr->form == DW_FORM_data8))
+ offset = read_8ubyte_unaligned (dbg, attr->valp);
+ else
+ {
+ __libdwarf_error (dbg, error, DW_E_NO_DATA);
+ return DW_DLV_ERROR;
+ }
+
+ /* Check whether the .debug_loc section is available. */
+ if (unlikely (dbg->sections[IDX_debug_loc].addr == NULL))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* This is the part of the .debug_loc section we can read. */
+ locp = (Dwarf_Small *) dbg->sections[IDX_debug_loc].addr + offset;
+ offset_end = offset + dbg->sections[IDX_debug_loc].size;
+
+ locdesclist = NULL;
+ n = 0;
+ while (1)
+ {
+ Dwarf_Addr lopc;
+ Dwarf_Addr hipc;
+ Dwarf_Ptr data;
+ Dwarf_Unsigned len2;
+ struct locdesclist *newdesc;
+ Dwarf_Small *locp;
+ Dwarf_Small *blkendp;
+ Dwarf_Small *blkstartp;
+
+ if (unlikely (dwarf_get_loclist_entry (dbg, offset, &hipc, &lopc, &data,
+ &len2, &offset, error)
+ != DW_DLV_OK))
+ return DW_DLV_ERROR;
+
+ /* Does this signal the end? */
+ if (lopc == 0 && hipc == 0)
+ break;
+
+ locp = data;
+ blkstartp = locp;
+ blkendp = locp + len2;
+
+ /* Create a new Locdesc entry. */
+ newdesc = (struct locdesclist *) alloca (sizeof (struct locdesclist));
+ newdesc->lopc = lopc;
+ newdesc->hipc = hipc;
+ newdesc->cents = 0;
+ newdesc->s = NULL;
+ newdesc->next = locdesclist;
+ locdesclist = newdesc;
+ ++n;
+
+ /* Decode the opcodes. It is possible in some situations to
+ have a block of size zero. */
+ while (locp < blkendp)
+ {
+ struct loclist *newloc;
+
+ newloc = (struct loclist *) alloca (sizeof (struct loclist));
+ newloc->number = 0;
+ newloc->number2 = 0;
+ newloc->offset = locp - blkstartp;
+ newloc->next = newdesc->s;
+ newdesc->s = newloc;
+ ++newdesc->cents;
+
+ newloc->atom = *locp;
+ switch (*locp++)
+ {
+ case DW_OP_addr:
+ /* Address, depends on address size of CU. */
+ if (cu->address_size == 4)
+ {
+ if (unlikely (locp + 4 > blkendp))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ newloc->number = read_4ubyte_unaligned (dbg, locp);
+ locp += 4;
+ }
+ else
+ {
+ if (unlikely (locp + 8 > blkendp))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ newloc->number = read_8ubyte_unaligned (dbg, locp);
+ locp += 8;
+ }
+ break;
+
+ case DW_OP_deref:
+ 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_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_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_nop:
+ case DW_OP_push_object_address:
+ case DW_OP_call_ref:
+ /* No operand. */
+ break;
+
+ case DW_OP_const1u:
+ case DW_OP_pick:
+ case DW_OP_deref_size:
+ case DW_OP_xderef_size:
+ if (unlikely (locp >= blkendp))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ newloc->number = *((uint8_t *) locp)++;
+ break;
+
+ case DW_OP_const1s:
+ if (unlikely (locp >= blkendp))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ newloc->number = *((int8_t *) locp)++;
+ break;
+
+ case DW_OP_const2u:
+ if (unlikely (locp + 2 > blkendp))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ newloc->number = read_2ubyte_unaligned (dbg, locp);
+ locp += 2;
+ break;
+
+ case DW_OP_const2s:
+ case DW_OP_skip:
+ case DW_OP_bra:
+ case DW_OP_call2:
+ if (unlikely (locp + 2 > blkendp))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ newloc->number = read_2sbyte_unaligned (dbg, locp);
+ locp += 2;
+ break;
+
+ case DW_OP_const4u:
+ if (unlikely (locp + 4 > blkendp))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ newloc->number = read_4ubyte_unaligned (dbg, locp);
+ locp += 4;
+ break;
+
+ case DW_OP_const4s:
+ case DW_OP_call4:
+ if (unlikely (locp + 4 > blkendp))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ newloc->number = read_4sbyte_unaligned (dbg, locp);
+ locp += 4;
+ break;
+
+ case DW_OP_const8u:
+ if (unlikely (locp + 8 > blkendp))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ newloc->number = read_8ubyte_unaligned (dbg, locp);
+ locp += 8;
+ break;
+
+ case DW_OP_const8s:
+ if (unlikely (locp + 8 > blkendp))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ newloc->number = read_8sbyte_unaligned (dbg, locp);
+ locp += 8;
+ break;
+
+ case DW_OP_constu:
+ case DW_OP_plus_uconst:
+ case DW_OP_regx:
+ case DW_OP_piece:
+ /* XXX Check size. */
+ get_uleb128 (newloc->number, locp);
+ break;
+
+ 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:
+ /* XXX Check size. */
+ get_sleb128 (newloc->number, locp);
+ break;
+
+ case DW_OP_bregx:
+ /* XXX Check size. */
+ get_uleb128 (newloc->number, locp);
+ get_sleb128 (newloc->number2, locp);
+ break;
+
+ default:
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ }
+ }
+
+ if (unlikely (n == 0))
+ {
+ /* This is not allowed.
+
+ XXX Is it? */
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* Allocate the array. */
+ result = (Dwarf_Locdesc *) malloc (n * sizeof (Dwarf_Locdesc));
+ if (result == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ /* Store the result. */
+ *llbuf = result;
+ *listlen = n;
+
+ do
+ {
+ unsigned int cents;
+ struct loclist *s;
+
+ /* We populate the array from the back since the list is
+ backwards. */
+ --n;
+
+ result[n].ld_lopc = locdesclist->lopc;
+ result[n].ld_hipc = locdesclist->hipc;
+ result[n].ld_cents = cents = locdesclist->cents;
+ result[n].ld_s = (Dwarf_Loc *) malloc (cents * sizeof (Dwarf_Loc));
+ if (result == NULL)
+ {
+ /* XXX Should be bother freeing memory? */
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ s = locdesclist->s;
+ while (cents-- > 0)
+ {
+ /* This list is also backwards. */
+ result[n].ld_s[cents].lr_atom = s->atom;
+ result[n].ld_s[cents].lr_number = s->number;
+ result[n].ld_s[cents].lr_number2 = s->number2;
+ result[n].ld_s[cents].lr_offset = s->offset;
+ s = s->next;
+ }
+
+ locdesclist = locdesclist->next;
+ }
+ while (n > 0);
+
+ /* We did it. */
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_lowpc.c b/libdwarf/dwarf_lowpc.c
new file mode 100644
index 00000000..c21edc92
--- /dev/null
+++ b/libdwarf/dwarf_lowpc.c
@@ -0,0 +1,108 @@
+/* Return low program counter value associated with die.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_lowpc (die, return_lowpc, error)
+ Dwarf_Die die;
+ Dwarf_Addr *return_lowpc;
+ Dwarf_Error *error;
+{
+ Dwarf_Debug dbg = die->cu->dbg;
+ Dwarf_Small *die_addr;
+ Dwarf_Word u128;
+ Dwarf_Abbrev abbrev;
+ Dwarf_Small *attrp;
+
+ /* Address of the given die. */
+ die_addr = die->addr;
+
+ /* Get abbrev code. */
+ get_uleb128 (u128, die_addr);
+ /* And get the abbreviation itself. */
+ abbrev = __libdwarf_get_abbrev (dbg, die->cu, u128, error);
+ if (abbrev == NULL)
+ return DW_DLV_ERROR;
+
+ /* This is where the attributes start. */
+ attrp = abbrev->attrp;
+
+ /* Search the name attribute. */
+ while (1)
+ {
+ Dwarf_Word attr_name;
+ Dwarf_Word attr_form;
+
+ /* Are we still in bounds? */
+ if (unlikely (attrp
+ >= ((Dwarf_Small *) dbg->sections[IDX_debug_abbrev].addr
+ + dbg->sections[IDX_debug_abbrev].size)))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* Get attribute name and form.
+
+ XXX We don't check whether this reads beyond the end of the
+ section. */
+ get_uleb128 (attr_name, attrp);
+ get_uleb128 (attr_form, attrp);
+
+ /* We can stop if we found the attribute with value zero. */
+ if (attr_name == 0 && attr_form == 0)
+ break;
+
+ /* Is this the name attribute? */
+ if (unlikely (attr_name == DW_AT_low_pc))
+ {
+ if (unlikely (attr_form != DW_FORM_addr))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ if (die->cu->address_size == 4)
+ *return_lowpc = read_4ubyte_unaligned (dbg, die_addr);
+ else
+ *return_lowpc = read_8ubyte_unaligned (dbg, die_addr);
+
+ return DW_DLV_OK;
+ }
+
+ /* Skip over the rest of this attribute (if there is any). */
+ if (attr_form != 0)
+ {
+ size_t len;
+
+ if (unlikely (__libdwarf_form_val_len (dbg, die->cu, attr_form,
+ die_addr, &len, error)
+ != DW_DLV_OK))
+ return DW_DLV_ERROR;
+
+ die_addr += len;
+ }
+ }
+
+ /* No such attribute present. */
+ return DW_DLV_NO_ENTRY;
+}
diff --git a/libdwarf/dwarf_next_cu_header.c b/libdwarf/dwarf_next_cu_header.c
new file mode 100644
index 00000000..54bb39e3
--- /dev/null
+++ b/libdwarf/dwarf_next_cu_header.c
@@ -0,0 +1,234 @@
+/* Get offset of next compilation unit.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <assert.h>
+#include <stdlib.h>
+
+#include <libdwarfP.h>
+
+
+/* A good initial size for the abbreviation hashing table. */
+#define DEFAULT_ABBREV_HASH_SIZE 257
+
+
+int
+internal_function
+__libdwarf_get_cu_at_offset (Dwarf_Debug dbg, Dwarf_Unsigned offset,
+ Dwarf_CU_Info *result_cu, Dwarf_Error *error)
+{
+ Dwarf_CU_Info cu;
+ Dwarf_Small *cu_bytes;
+ Dwarf_Unsigned length;
+ Dwarf_Half offset_size;
+
+ /* Make sure there is enough space in the .debug_info section for at
+ least the initial word. We cannot test the rest since we don't
+ know yet whether this is a 64-bit object or not. */
+ if (unlikely (offset + 4 >= dbg->sections[IDX_debug_info].size))
+ {
+ dbg->cu_list_current = NULL;
+ return DW_DLV_NO_ENTRY;
+ }
+
+ /* This points into the .debug_info section to the beginning of the
+ CU entry. */
+ cu_bytes = (Dwarf_Small *) dbg->sections[IDX_debug_info].addr + offset;
+
+ /* The format of the CU header is described in dwarf2p1 7.5.1:
+
+ 1. A 4-byte or 12-byte unsigned integer representing the length
+ of the .debug_info contribution for that compilation unit, not
+ including the length field itself. In the 32-bit DWARF format,
+ this is a 4-byte unsigned integer (which must be less than
+ 0xffffff00); in the 64-bit DWARF format, this consists of the
+ 4-byte value 0xffffffff followed by an 8-byte unsigned integer
+ that gives the actual length (see Section 7.4).
+
+ 2. A 2-byte unsigned integer representing the version of the
+ DWARF information for that compilation unit. For DWARF Version
+ 2.1, the value in this field is 2.
+
+ 3. A 4-byte or 8-byte unsigned offset into the .debug_abbrev
+ section. This offset associates the compilation unit with a
+ particular set of debugging information entry abbreviations. In
+ the 32-bit DWARF format, this is a 4-byte unsigned length; in
+ the 64-bit DWARF format, this is an 8-byte unsigned length (see
+ Section 7.4).
+
+ 4. A 1-byte unsigned integer representing the size in bytes of
+ an address on the target architecture. If the system uses
+ segmented addressing, this value represents the size of the
+ offset portion of an address. */
+ length = read_4ubyte_unaligned (dbg, cu_bytes);
+ cu_bytes += 4;
+ offset_size = 4;
+ if (length == 0xffffffff)
+ offset_size = 8;
+
+ /* Now we know how large the header is. Note the trick in the
+ computation. If the offset_size is 4 the '- 4' term undoes the
+ '2 *'. If offset_size is 8 this term computes the size of the
+ escape value plus the 8 byte offset. */
+ if (unlikely (offset + 2 * offset_size - 4 + sizeof (Dwarf_Half)
+ + offset_size + sizeof (Dwarf_Small)
+ >= dbg->sections[IDX_debug_info].size))
+ {
+ dbg->cu_list_current = NULL;
+ return DW_DLV_NO_ENTRY;
+ }
+
+ if (length == 0xffffffff)
+ {
+ /* This is a 64-bit DWARF format. */
+ length = read_8ubyte_unaligned (dbg, cu_bytes);
+ cu_bytes += 8;
+ }
+
+ /* We know we have enough room in the .debug_section. Allocate the
+ result data structure. */
+ cu = (Dwarf_CU_Info) malloc (sizeof (struct Dwarf_CU_Info_s));
+ if (cu == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ /* Store the values in the data structure. */
+ cu->offset = offset;
+ cu->offset_size = offset_size;
+ cu->length = length;
+
+ /* Store the version stamp. Always a 16-bit value. */
+ cu->version_stamp = read_2ubyte_unaligned (dbg, cu_bytes);
+ cu_bytes += 2;
+
+ /* Get offset in .debug_abbrev. Note that the size of the entry
+ depends on whether this is a 32-bit or 64-bit DWARF definition. */
+ if (offset_size == 4)
+ cu->abbrev_offset = read_4ubyte_unaligned (dbg, cu_bytes);
+ else
+ cu->abbrev_offset = read_8ubyte_unaligned (dbg, cu_bytes);
+ cu_bytes += offset_size;
+ cu->last_abbrev_offset = cu->abbrev_offset;
+
+ /* The address size. Always an 8-bit value. */
+ cu->address_size = *cu_bytes++;
+
+ /* Store the header length. */
+ cu->header_length = (cu_bytes
+ - ((Dwarf_Small *) dbg->sections[IDX_debug_info].addr
+ + offset));
+
+ /* Initilize a few more members. */
+ if (unlikely (Dwarf_Abbrev_Hash_init (&cu->abbrev_hash,
+ DEFAULT_ABBREV_HASH_SIZE) != 0))
+ {
+ free (cu);
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ /* Remember the debugging handle. */
+ cu->dbg = dbg;
+
+ /* There is no other entry yet. */
+ cu->next = NULL;
+
+ /* Enqueue the new entry. */
+ if (dbg->cu_list == NULL)
+ dbg->cu_list = dbg->cu_list_tail = cu;
+ else
+ {
+ dbg->cu_list_tail->next = cu;
+ dbg->cu_list_tail = cu;
+ }
+ *result_cu = cu;
+
+ return DW_DLV_OK;
+}
+
+
+int
+dwarf_next_cu_header (dbg, cu_header_length, version_stamp, abbrev_offset,
+ address_size, next_cu_header, error)
+ Dwarf_Debug dbg;
+ Dwarf_Unsigned *cu_header_length;
+ Dwarf_Half *version_stamp;
+ Dwarf_Unsigned *abbrev_offset;
+ Dwarf_Half *address_size;
+ Dwarf_Unsigned *next_cu_header;
+ Dwarf_Error *error;
+{
+ Dwarf_Unsigned offset_next_cu;
+ Dwarf_CU_Info cu;
+
+ if (dbg == NULL)
+ return DW_DLV_ERROR;
+
+ /* Determine offset of next CU header. If we don't have a current
+ CU this is the first call and we start right at the beginning. */
+ if (dbg->cu_list_current == NULL)
+ {
+ offset_next_cu = 0;
+ cu = dbg->cu_list;
+ }
+ else
+ {
+ /* We can compute the offset from the information we read from
+ the last CU header. */
+ cu = dbg->cu_list_current;
+
+ offset_next_cu = cu->offset + 2 * cu->offset_size - 4 + cu->length;
+
+ /* See whether the next entry entry is available. */
+ cu = cu->next;
+ }
+
+ /* If the entry is not yet available get it. */
+ if (cu == NULL)
+ {
+ int res = __libdwarf_get_cu_at_offset (dbg, offset_next_cu, &cu, error);
+
+ /* If it still does not exist, fail. Note that this can mean an
+ error or that we reached the end. */
+ if (res != DW_DLV_OK)
+ return res;
+
+ dbg->cu_list_current = cu;
+ assert (cu != NULL);
+ }
+
+ /* See get_cu_at_offset for an explanation of the trick in this
+ formula. */
+ *next_cu_header = offset_next_cu + 2 * cu->offset_size - 4 + cu->length;
+
+ /* Extract the information and put it where the user wants it. */
+ if (cu_header_length != NULL)
+ *cu_header_length = cu->header_length;
+
+ if (version_stamp != NULL)
+ *version_stamp = cu->version_stamp;
+
+ if (abbrev_offset != NULL)
+ *abbrev_offset = cu->abbrev_offset;
+
+ if (address_size != NULL)
+ *address_size = cu->address_size;
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_offdie.c b/libdwarf/dwarf_offdie.c
new file mode 100644
index 00000000..2e94d2ea
--- /dev/null
+++ b/libdwarf/dwarf_offdie.c
@@ -0,0 +1,123 @@
+/* Return die at given offset.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <stdlib.h>
+
+#include <libdwarfP.h>
+
+
+/* XXX This function will have to be optimized. The search is too linear
+ to be performed too often -> O(n²). */
+static Dwarf_CU_Info
+find_cu (Dwarf_Debug dbg, Dwarf_Off offset, Dwarf_Error *error)
+{
+ Dwarf_CU_Info cu;
+ Dwarf_Word cu_offset;
+
+ /* Search in the CUs already known. */
+ for (cu = dbg->cu_list; cu != NULL; cu = cu->next)
+ if (cu->offset <= offset
+ && cu->offset + 2 * cu->offset_size - 4 + cu->length > offset)
+ return cu;
+
+ /* The CU is not yet loaded. Do this now. */
+ if (dbg->cu_list_tail == NULL)
+ cu_offset = 0;
+ else
+ cu_offset = (dbg->cu_list_tail->offset
+ + 2 * dbg->cu_list_tail->offset_size - 4
+ + dbg->cu_list_tail->length);
+
+ while (1)
+ {
+ /* Get next CU and add it to the end of the list. */
+ if (__libdwarf_get_cu_at_offset (dbg, cu_offset, &cu, error)
+ != DW_DLV_OK)
+ return NULL;
+
+ /* Offset of next CU. */
+ cu_offset += 2 * cu->offset_size - 4 + cu->length;
+
+ /* If this the CU we are looking for? */
+ if (offset < cu_offset)
+ return cu;
+ }
+}
+
+
+int
+dwarf_offdie (dbg, offset, return_die, error)
+ Dwarf_Debug dbg;
+ Dwarf_Off offset;
+ Dwarf_Die *return_die;
+ Dwarf_Error *error;
+{
+ Dwarf_CU_Info cu;
+ Dwarf_Die new_die;
+ Dwarf_Small *die_addr;
+ Dwarf_Word u128;
+
+ if (offset >= dbg->sections[IDX_debug_info].size)
+ {
+ /* Completely out of bounds. */
+ __libdwarf_error (dbg, error, DW_E_INVALID_OFFSET);
+ return DW_DLV_ERROR;
+ }
+
+ /* Find the compile unit this address belongs to. */
+ cu = find_cu (dbg, offset, error);
+ if (cu == NULL)
+ return DW_DLV_ERROR;
+
+ /* Creata a new die. */
+ new_die = (Dwarf_Die) malloc (sizeof (struct Dwarf_Die_s));
+ if (new_die == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+#ifdef DWARF_DEBUG
+ new_die->memtag = DW_DLA_DIE;
+#endif
+
+ /* Remember the address. */
+ die_addr = (Dwarf_Small *) dbg->sections[IDX_debug_info].addr + offset;
+ new_die->addr = die_addr;
+
+ /* And the compile unit. */
+ new_die->cu = cu;
+
+ /* 7.5.2 Debugging Information Entry
+
+ Each debugging information entry begins with an unsigned LEB128
+ number containing the abbreviation code for the entry. */
+ get_uleb128 (u128, die_addr);
+
+ /* Find the abbreviation. */
+ new_die->abbrev = __libdwarf_get_abbrev (dbg, cu, u128, error);
+ if (new_die->abbrev == NULL)
+ {
+ free (new_die);
+ return DW_DLV_ERROR;
+ }
+
+ *return_die = new_die;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_seterrarg.c b/libdwarf/dwarf_seterrarg.c
new file mode 100644
index 00000000..8b52d24a
--- /dev/null
+++ b/libdwarf/dwarf_seterrarg.c
@@ -0,0 +1,30 @@
+/* Set new error handler argument.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+Dwarf_Ptr
+dwarf_seterrarg (dbg, errarg)
+ Dwarf_Debug dbg;
+ Dwarf_Ptr errarg;
+{
+ Dwarf_Ptr old = dbg->dbg_errarg;
+ dbg->dbg_errarg = errarg;
+ return old;
+}
diff --git a/libdwarf/dwarf_seterrhand.c b/libdwarf/dwarf_seterrhand.c
new file mode 100644
index 00000000..199a2504
--- /dev/null
+++ b/libdwarf/dwarf_seterrhand.c
@@ -0,0 +1,30 @@
+/* Set new error handler.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+Dwarf_Handler
+dwarf_seterrhand (dbg, errhand)
+ Dwarf_Debug dbg;
+ Dwarf_Handler errhand;
+{
+ Dwarf_Handler old = dbg->dbg_errhand;
+ dbg->dbg_errhand = errhand;
+ return old;
+}
diff --git a/libdwarf/dwarf_siblingof.c b/libdwarf/dwarf_siblingof.c
new file mode 100644
index 00000000..04a3ab6d
--- /dev/null
+++ b/libdwarf/dwarf_siblingof.c
@@ -0,0 +1,257 @@
+/* Return descriptor for sibling of die.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <stdlib.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_siblingof (dbg, die, return_sub, error)
+ Dwarf_Debug dbg;
+ Dwarf_Die die;
+ Dwarf_Die *return_sub;
+ Dwarf_Error *error;
+{
+ Dwarf_Small *die_addr;
+ Dwarf_CU_Info cu;
+ Dwarf_Unsigned u128;
+ Dwarf_Die new_die;
+
+ if (dbg == NULL)
+ return DW_DLV_ERROR;
+
+ if (die == NULL)
+ {
+ Dwarf_Unsigned die_offset;
+
+ /* We are supposed to return the DW_TAG_compile_unit die for the
+ current compile unit. For this to succeed the user must have
+ looked for the compile unit before. */
+ if (dbg->cu_list_current == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NO_CU);
+ return DW_DLV_ERROR;
+ }
+
+ cu = dbg->cu_list_current;
+
+ die_offset = (cu->offset + 2 * cu->offset_size - 4 + sizeof (Dwarf_Half)
+ + cu->offset_size + 1);
+
+ /* Check whether this is withing the debug section. */
+ if (die_offset >= dbg->sections[IDX_debug_info].size)
+ return DW_DLV_NO_ENTRY;
+
+ /* Compute the pointer. */
+ die_addr = ((Dwarf_Small *) dbg->sections[IDX_debug_info].addr
+ + die_offset);
+ }
+ else
+ {
+ unsigned int level = 0;
+
+ /* We start from the given die. */
+ cu = die->cu;
+
+ /* Address of the given die. */
+ die_addr = die->addr;
+
+ /* Search for the beginning of the next die on this level. We
+ must not return the dies for children of the given die. */
+ do
+ {
+ Dwarf_Abbrev abbrev;
+ Dwarf_Small *attrp;
+ Dwarf_Word attr_name;
+ Dwarf_Word attr_form;
+
+ /* Get abbrev code. */
+ get_uleb128 (u128, die_addr);
+ /* And get the abbreviation itself. */
+ abbrev = __libdwarf_get_abbrev (dbg, cu, u128, error);
+ if (abbrev == NULL)
+ return DW_DLV_ERROR;
+
+ /* This is where the attributes start. */
+ attrp = abbrev->attrp;
+
+ /* Does this abbreviation have children? */
+ if (abbrev->has_children)
+ ++level;
+
+ while (1)
+ {
+ /* Are we still in bounds? */
+ if (attrp >= ((Dwarf_Small *)dbg->sections[IDX_debug_abbrev].addr
+ + dbg->sections[IDX_debug_abbrev].size))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* Get attribute name and form.
+
+ XXX We don't check whether this reads beyond the end of
+ the section. */
+ get_uleb128 (attr_name, attrp);
+ get_uleb128 (attr_form, attrp);
+
+ /* We can stop if we found the attribute with value zero. */
+ if (attr_name == 0 && attr_form == 0)
+ break;
+
+ /* See whether this is an sibling attribute which would help
+ us to skip ahead. */
+ if (attr_name == DW_AT_sibling)
+ {
+ /* Cool. We just have to decode the parameter and we know
+ the offset. */
+ Dwarf_Unsigned offset;
+
+ switch (attr_form)
+ {
+ case DW_FORM_ref1:
+ offset = *die_addr;
+ break;
+
+ case DW_FORM_ref2:
+ offset = read_2ubyte_unaligned (dbg, die_addr);
+ break;
+
+ case DW_FORM_ref4:
+ offset = read_4ubyte_unaligned (dbg, die_addr);
+ break;
+
+ case DW_FORM_ref8:
+ offset = read_8ubyte_unaligned (dbg, die_addr);
+ break;
+
+ case DW_FORM_ref_udata:
+ get_uleb128 (offset, die_addr);
+ break;
+
+ default:
+ /* The above are all legal forms. Everything else is
+ an error. */
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* Compute the new address. Some sanity check first,
+ though. */
+ if (unlikely (offset > 2 * cu->offset_size - 4 + cu->length))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ die_addr =
+ ((Dwarf_Small *) dbg->sections[IDX_debug_info].addr
+ + cu->offset + offset);
+
+ /* Even if the abbreviation has children we have stepped
+ over them now. */
+ if (abbrev->has_children)
+ --level;
+ break;
+ }
+
+ /* Skip over the rest of this attribute (if there is any). */
+ if (attr_form != 0)
+ {
+ size_t len;
+
+ if (unlikely (__libdwarf_form_val_len (dbg, cu, attr_form,
+ die_addr, &len, error)
+ != DW_DLV_OK))
+ return DW_DLV_ERROR;
+
+ die_addr += len;
+ }
+ }
+
+ /* Check that we are not yet at the end. */
+ if (*die_addr == 0)
+ {
+ if (level == 0)
+ return DW_DLV_NO_ENTRY;
+
+ do
+ ++die_addr;
+ while (--level > 0 && *die_addr == 0);
+ }
+ }
+ while (level > 0);
+ }
+
+ /* Are we at the end. */
+ if (die != NULL
+ && die_addr >= ((Dwarf_Small *) dbg->sections[IDX_debug_info].addr
+ + cu->offset + cu->length + 2 * cu->offset_size - 4))
+ return DW_DLV_NO_ENTRY;
+
+ /* See whether there is another sibling available or whether this is
+ the end. */
+ if (*die_addr == 0)
+ return DW_DLV_NO_ENTRY;
+
+ /* There is more data. Create the data structure. */
+ new_die = (Dwarf_Die) malloc (sizeof (struct Dwarf_Die_s));
+ if (new_die == NULL)
+ {
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+#ifdef DWARF_DEBUG
+ new_die->memtag = DW_DLA_DIE;
+#endif
+
+ /* Remember the address. */
+ new_die->addr = die_addr;
+
+ /* And the compile unit. */
+ new_die->cu = cu;
+
+ /* 7.5.2 Debugging Information Entry
+
+ Each debugging information entry begins with an unsigned LEB128
+ number containing the abbreviation code for the entry. */
+ get_uleb128 (u128, die_addr);
+
+ /* Find the abbreviation. */
+ new_die->abbrev = __libdwarf_get_abbrev (dbg, cu, u128, error);
+ if (new_die->abbrev == NULL)
+ {
+ free (new_die);
+ return DW_DLV_ERROR;
+ }
+
+ /* If we are looking for the first entry this must be a compile unit. */
+ if (die == NULL && unlikely (new_die->abbrev->tag != DW_TAG_compile_unit))
+ {
+ free (new_die);
+ __libdwarf_error (dbg, error, DW_E_1ST_NO_CU);
+ return DW_DLV_ERROR;
+ }
+
+ *return_sub = new_die;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_srcfiles.c b/libdwarf/dwarf_srcfiles.c
new file mode 100644
index 00000000..1090d837
--- /dev/null
+++ b/libdwarf/dwarf_srcfiles.c
@@ -0,0 +1,344 @@
+/* Return source files of compilation unit.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libdwarfP.h>
+
+
+struct dirlist
+{
+ char *dir;
+ size_t len;
+ struct dirlist *next;
+};
+
+struct filelist
+{
+ char *name;
+ Dwarf_Unsigned mtime;
+ Dwarf_Unsigned length;
+ struct filelist *next;
+};
+
+
+static int
+read_file_names (Dwarf_Debug dbg, char *comp_dir, Dwarf_Small **linepp,
+ char ***result, Dwarf_Signed *nresult, Dwarf_Error *error)
+{
+ Dwarf_Small *linep = *linepp;
+ struct dirlist comp_dir_elem;
+ struct dirlist *dirlist;
+ unsigned int ndirlist;
+ struct dirlist **dirarray;
+ struct filelist *filelist = NULL;
+ unsigned int nfilelist = 0;
+
+ /* First comes the list of directories. Add the compilation directory
+ first since the index zero is used for it. */
+ comp_dir_elem.dir = comp_dir;
+ comp_dir_elem.len = comp_dir ? strlen (comp_dir) : 0;
+ comp_dir_elem.next = NULL;
+ dirlist = &comp_dir_elem;
+ ndirlist = 1;
+
+ while (*linep != 0)
+ {
+ struct dirlist *new_dir = (struct dirlist *) alloca (sizeof (*new_dir));
+
+ new_dir->dir = (char *) linep;
+ new_dir->len = strlen ((char *) linep);
+ new_dir->next = dirlist;
+ dirlist = new_dir;
+ ++ndirlist;
+ linep += new_dir->len + 1;
+ }
+ /* Skip the final NUL byte. */
+ ++linep;
+
+ /* Rearrange the list in array form. */
+ dirarray = (struct dirlist **) alloca (sizeof (*dirarray));
+ while (ndirlist-- > 0)
+ {
+ dirarray[ndirlist] = dirlist;
+ dirlist = dirlist->next;
+ }
+
+ /* Now read the files. */
+ while (*linep != 0)
+ {
+ struct filelist *new_file =
+ (struct filelist *) alloca (sizeof (*new_file));
+ char *fname;
+ size_t fnamelen;
+ Dwarf_Unsigned diridx;
+
+ /* First comes the file name. */
+ fname = (char *) linep;
+ fnamelen = strlen (fname);
+ linep += fnamelen + 1;
+
+ /* Then the index. */
+ get_uleb128 (diridx, linep);
+ if (unlikely (diridx >= ndirlist))
+ {
+ __libdwarf_error (dbg, error, DW_E_INVALID_DIR_IDX);
+ return DW_DLV_ERROR;
+ }
+
+ if (*fname == '/')
+ /* It's an absolute path. */
+ new_file->name = strdup (fname);
+ else
+ {
+ new_file->name = (char *) malloc (dirarray[diridx]->len + 1
+ + fnamelen + 1);
+ if (new_file->name != NULL)
+ {
+ char *cp = new_file->name;
+
+ if (dirarray[diridx]->dir != NULL)
+ /* This value could be NULL in case the DW_AT_comp_dir
+ was not present. We cannot do much in this case.
+ The easiest thing is to convert the path in an
+ absolute path. */
+ cp = stpcpy (cp, dirarray[diridx]->dir);
+ *cp++ = '/';
+ strcpy (cp, fname);
+ }
+ }
+ if (new_file->name == NULL)
+ {
+ /* XXX Should we bother to free all the memory? */
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ /* Next comes the modification time. */
+ get_uleb128 (new_file->mtime, linep);
+
+ /* Finally the length of the file. */
+ get_uleb128 (new_file->length, linep);
+
+ new_file->next = filelist;
+ filelist = new_file;
+ ++nfilelist;
+ }
+
+ /* Put all the files in an array. */
+ *result = (char **) malloc (nfilelist * sizeof (char *));
+ if (*result == NULL)
+ {
+ /* XXX Should we bother to free all the memory? */
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ *nresult = nfilelist;
+ while (nfilelist-- > 0)
+ {
+ (*result)[nfilelist] = filelist->name;
+ filelist = filelist->next;
+ }
+
+ /* Provide caller address of next byte. */
+ *linepp = linep + 1;
+
+ return DW_DLV_OK;
+}
+
+
+int
+dwarf_srcfiles (die, srcfiles, srcfilecount, error)
+ Dwarf_Die die;
+ char ***srcfiles;
+ Dwarf_Signed *srcfilecount;
+ Dwarf_Error *error;
+{
+ Dwarf_CU_Info cu = die->cu;
+ Dwarf_Debug dbg = cu->dbg;
+ Dwarf_Attribute stmt_list;
+ Dwarf_Attribute comp_dir_attr;
+ char *comp_dir;
+ Dwarf_Unsigned offset;
+ Dwarf_Small *linep;
+ Dwarf_Small *lineendp;
+ Dwarf_Small *header_start;
+ Dwarf_Unsigned header_length;
+ unsigned int unit_length;
+ unsigned int version;
+ unsigned int opcode_base;
+ int length;
+ int res;
+
+ /* For now we haven't found anything. */
+ *srcfilecount = 0;
+
+ /* The die must be for a compilation unit. */
+ if (die->abbrev->tag != DW_TAG_compile_unit)
+ {
+ __libdwarf_error (die->cu->dbg, error, DW_E_NO_CU);
+ return DW_DLV_ERROR;
+ }
+
+ /* The die must have a statement list associated. */
+ res = dwarf_attr (die, DW_AT_stmt_list, &stmt_list, error);
+ if (res != DW_DLV_OK)
+ return res;
+
+ /* Get the offset into the .debug_line section. */
+ res = dwarf_formudata (stmt_list, &offset, error);
+ if (res != DW_DLV_OK)
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ return res;
+ }
+
+ /* We need a .debug_line section. */
+ if (dbg->sections[IDX_debug_line].addr == NULL)
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_NO_DEBUG_LINE);
+ return DW_DLV_ERROR;
+ }
+
+ linep = (Dwarf_Small *) dbg->sections[IDX_debug_line].addr + offset;
+ lineendp = ((Dwarf_Small *) dbg->sections[IDX_debug_line].addr
+ + dbg->sections[IDX_debug_line].size);
+
+ /* Test whether at least the first 4 bytes are available. */
+ if (unlikely (linep + 4 > lineendp))
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* Get the compilation directory. */
+ res = dwarf_attr (die, DW_AT_comp_dir, &comp_dir_attr, error);
+ if (unlikely (res == DW_DLV_ERROR)
+ || (res == DW_DLV_OK
+ && unlikely (dwarf_formstring (comp_dir_attr, &comp_dir, error)
+ == DW_DLV_ERROR)))
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ else if (res == DW_DLV_OK)
+ dwarf_dealloc (dbg, comp_dir_attr, DW_DLA_ATTR);
+ else
+ comp_dir = NULL;
+
+ /* Read the unit_length. */
+ unit_length = read_4ubyte_unaligned (dbg, linep);
+ linep += 4;
+ length = 4;
+ if (unit_length == 0xffffffff)
+ {
+ if (unlikely (linep + 8 > lineendp))
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ unit_length = read_8ubyte_unaligned (dbg, linep);
+ linep += 8;
+ length = 8;
+ }
+
+ /* Check whether we have enough room in the section. */
+ if (unlikely (linep + unit_length > lineendp))
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ lineendp = linep + unit_length;
+
+ /* The next element of the header is the version identifier. */
+ version = read_2ubyte_unaligned (dbg, linep);
+ if (unlikely (version != DWARF_VERSION))
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_VERSION_ERROR);
+ return DW_DLV_ERROR;
+ }
+ linep += 2;
+
+ /* Next comes the header length. */
+ if (length == 4)
+ {
+ header_length = read_4ubyte_unaligned (dbg, linep);
+ linep += 4;
+ }
+ else
+ {
+ header_length = read_8ubyte_unaligned (dbg, linep);
+ linep += 8;
+ }
+ header_start = linep;
+
+ /* Next the minimum instruction length. Skip it. */
+ ++linep;
+
+ /* Then the flag determining the default value of the is_stmt
+ register. Skip it. */
+ ++linep;
+
+ /* Now the line base. Skip it. */
+ ++linep;
+
+ /* And the line range. Skip it. */
+ ++linep;
+
+ /* The opcode base. */
+ opcode_base = *linep++;
+
+ /* Skip the array with the standard opcode length. */
+ linep += opcode_base - 1;
+
+ /* Next the include directories and the file names. */
+ if (unlikely (read_file_names (dbg, comp_dir, &linep, srcfiles, srcfilecount,
+ error) != DW_DLV_OK))
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ return DW_DLV_ERROR;
+ }
+
+ /* Consistency check. */
+ if (unlikely (linep != header_start + header_length))
+ {
+ int i;
+
+ for (i = 0; i < *srcfilecount; ++i)
+ dwarf_dealloc (dbg, (*srcfiles)[i], DW_DLA_STRING);
+ dwarf_dealloc (dbg, *srcfiles, DW_DLA_LIST);
+
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_srclang.c b/libdwarf/dwarf_srclang.c
new file mode 100644
index 00000000..45140633
--- /dev/null
+++ b/libdwarf/dwarf_srclang.c
@@ -0,0 +1,31 @@
+/* Return source language associated with die.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_srclang (die, return_lang, error)
+ Dwarf_Die die;
+ Dwarf_Unsigned *return_lang;
+ Dwarf_Error *error;
+{
+ return __libdwarf_getconstant (die, DW_AT_language, return_lang, error);
+}
diff --git a/libdwarf/dwarf_srclines.c b/libdwarf/dwarf_srclines.c
new file mode 100644
index 00000000..796b7900
--- /dev/null
+++ b/libdwarf/dwarf_srclines.c
@@ -0,0 +1,745 @@
+/* Return source lines of compilation unit.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <dwarf.h>
+#include <stdlib.h>
+#include <string.h>
+
+#include <libdwarfP.h>
+
+
+struct dirlist
+{
+ char *dir;
+ size_t len;
+ struct dirlist *next;
+};
+
+struct filelist
+{
+ char *name;
+ Dwarf_Unsigned mtime;
+ Dwarf_Unsigned length;
+ struct filelist *next;
+};
+
+struct linelist
+{
+ Dwarf_Line line;
+ struct linelist *next;
+};
+
+
+/* Adds a new line to the matrix. We cannot definte a function because
+ we want to use alloca. */
+#define NEW_LINE(end_seq) \
+ do { \
+ /* Add the new line. */ \
+ new_line = (struct linelist *) alloca (sizeof (struct linelist)); \
+ new_line->line = (Dwarf_Line) malloc (sizeof (struct Dwarf_Line_s)); \
+ if (new_line == NULL) \
+ { \
+ /* XXX Should we bother to free the memory? */ \
+ __libdwarf_error (dbg, error, DW_E_NOMEM); \
+ return DW_DLV_ERROR; \
+ } \
+ \
+ /* Set the line information. */ \
+ new_line->line->addr = address; \
+ new_line->line->file = file; \
+ new_line->line->line = line; \
+ new_line->line->column = column; \
+ new_line->line->is_stmt = is_stmt; \
+ new_line->line->basic_block = basic_block; \
+ new_line->line->end_sequence = end_seq; \
+ new_line->line->prologue_end = prologue_end; \
+ new_line->line->epilogue_begin = epilogue_begin; \
+ \
+ new_line->next = linelist; \
+ linelist = new_line; \
+ ++nlinelist; \
+ } while (0)
+
+
+int
+dwarf_srclines (die, linebuf, linecount, error)
+ Dwarf_Die die;
+ Dwarf_Line **linebuf;
+ Dwarf_Signed *linecount;
+ Dwarf_Error *error;
+{
+ Dwarf_CU_Info cu = die->cu;
+ Dwarf_Debug dbg = cu->dbg;
+ Dwarf_Attribute stmt_list;
+ Dwarf_Attribute comp_dir_attr;
+ char *comp_dir;
+ Dwarf_Unsigned offset;
+ Dwarf_Small *linep;
+ Dwarf_Small *lineendp;
+ Dwarf_Small *header_start;
+ Dwarf_Unsigned header_length;
+ Dwarf_File files;
+ Dwarf_Line *lines;
+ unsigned int unit_length;
+ unsigned int version;
+ unsigned int opcode_base;
+ Dwarf_Small *standard_opcode_lengths;
+ unsigned int minimum_instruction_length;
+ unsigned int default_is_stmt;
+ int line_base;
+ unsigned int line_range;
+ int length;
+ struct dirlist comp_dir_elem;
+ struct dirlist *dirlist;
+ unsigned int ndirlist;
+ struct dirlist **dirarray;
+ struct filelist *filelist;
+ unsigned int nfilelist;
+ struct filelist null_file;
+ Dwarf_Unsigned address;
+ size_t file;
+ size_t line;
+ size_t column;
+ int is_stmt;
+ int basic_block;
+ int prologue_end;
+ int epilogue_begin;
+ struct linelist *linelist;
+ unsigned int nlinelist;
+ int res;
+
+ /* The die must be for a compilation unit. */
+ if (unlikely (die->abbrev->tag != DW_TAG_compile_unit))
+ {
+ __libdwarf_error (die->cu->dbg, error, DW_E_NO_CU);
+ return DW_DLV_ERROR;
+ }
+
+ /* The die must have a statement list associated. */
+ res = dwarf_attr (die, DW_AT_stmt_list, &stmt_list, error);
+ if (unlikely (res != DW_DLV_OK))
+ return res;
+
+ /* Get the offset into the .debug_line section. */
+ res = dwarf_formudata (stmt_list, &offset, error);
+ if (unlikely (res != DW_DLV_OK))
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ return res;
+ }
+
+ /* We need a .debug_line section. */
+ if (dbg->sections[IDX_debug_line].addr == NULL)
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_NO_DEBUG_LINE);
+ return DW_DLV_ERROR;
+ }
+
+ linep = (Dwarf_Small *) dbg->sections[IDX_debug_line].addr + offset;
+ lineendp = ((Dwarf_Small *) dbg->sections[IDX_debug_line].addr
+ + dbg->sections[IDX_debug_line].size);
+
+ /* Test whether at least the first 4 bytes are available. */
+ if (unlikely (linep + 4 > lineendp))
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* Get the compilation directory. */
+ res = dwarf_attr (die, DW_AT_comp_dir, &comp_dir_attr, error);
+ if (unlikely (res == DW_DLV_ERROR)
+ || (res == DW_DLV_OK
+ && unlikely (dwarf_formstring (comp_dir_attr, &comp_dir, error)
+ == DW_DLV_ERROR)))
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ else if (res == DW_DLV_OK)
+ dwarf_dealloc (dbg, comp_dir_attr, DW_DLA_ATTR);
+ else
+ comp_dir = NULL;
+
+ /* Read the unit_length. */
+ unit_length = read_4ubyte_unaligned (dbg, linep);
+ linep += 4;
+ length = 4;
+ if (unit_length == 0xffffffff)
+ {
+ if (unlikely (linep + 8 > lineendp))
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ unit_length = read_8ubyte_unaligned (dbg, linep);
+ linep += 8;
+ length = 8;
+ }
+
+ /* Check whether we have enough room in the section. */
+ if (unlikely (linep + unit_length > lineendp))
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+ lineendp = linep + unit_length;
+
+ /* The next element of the header is the version identifier. */
+ version = read_2ubyte_unaligned (dbg, linep);
+ if (unlikely (version != DWARF_VERSION))
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_VERSION_ERROR);
+ return DW_DLV_ERROR;
+ }
+ linep += 2;
+
+ /* Next comes the header length. */
+ if (length == 4)
+ {
+ header_length = read_4ubyte_unaligned (dbg, linep);
+ linep += 4;
+ }
+ else
+ {
+ header_length = read_8ubyte_unaligned (dbg, linep);
+ linep += 8;
+ }
+ header_start = linep;
+
+ /* Next the minimum instruction length. */
+ minimum_instruction_length = *linep++;
+
+ /* Then the flag determining the default value of the is_stmt
+ register. */
+ default_is_stmt = *linep++;
+
+ /* Now the line base. */
+ line_base = *((signed char *) linep)++;
+
+ /* And the line range. */
+ line_range = *linep++;
+
+ /* The opcode base. */
+ opcode_base = *linep++;
+
+ /* Remember array with the standard opcode length (-1 to account for
+ the opcode with value zero not being mentioned). */
+ standard_opcode_lengths = linep - 1;
+ linep += opcode_base - 1;
+
+ /* First comes the list of directories. Add the compilation directory
+ first since the index zero is used for it. */
+ comp_dir_elem.dir = comp_dir;
+ comp_dir_elem.len = comp_dir ? strlen (comp_dir) : 0;
+ comp_dir_elem.next = NULL;
+ dirlist = &comp_dir_elem;
+ ndirlist = 1;
+
+ while (*linep != 0)
+ {
+ struct dirlist *new_dir = (struct dirlist *) alloca (sizeof (*new_dir));
+
+ new_dir->dir = (char *) linep;
+ new_dir->len = strlen ((char *) linep);
+ new_dir->next = dirlist;
+ dirlist = new_dir;
+ ++ndirlist;
+ linep += new_dir->len + 1;
+ }
+ /* Skip the final NUL byte. */
+ ++linep;
+
+ /* Rearrange the list in array form. */
+ dirarray = (struct dirlist **) alloca (sizeof (*dirarray));
+ while (ndirlist-- > 0)
+ {
+ dirarray[ndirlist] = dirlist;
+ dirlist = dirlist->next;
+ }
+
+ comp_dir_elem.dir = comp_dir;
+ comp_dir_elem.len = comp_dir ? strlen (comp_dir) : 0;
+ comp_dir_elem.next = NULL;
+ dirlist = &comp_dir_elem;
+ ndirlist = 1;
+
+ /* Now read the files. */
+ null_file.name = "???";
+ null_file.mtime = 0;
+ null_file.length = 0;
+ null_file.next = NULL;
+ filelist = &null_file;
+ nfilelist = 1;
+
+ while (*linep != 0)
+ {
+ struct filelist *new_file =
+ (struct filelist *) alloca (sizeof (*new_file));
+ char *fname;
+ size_t fnamelen;
+ Dwarf_Unsigned diridx;
+
+ /* First comes the file name. */
+ fname = (char *) linep;
+ fnamelen = strlen (fname);
+ linep += fnamelen + 1;
+
+ /* Then the index. */
+ get_uleb128 (diridx, linep);
+ if (unlikely (diridx >= ndirlist))
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DIR_IDX);
+ return DW_DLV_ERROR;
+ }
+
+ if (*fname == '/')
+ /* It's an absolute path. */
+ new_file->name = strdup (fname);
+ else
+ {
+ new_file->name = (char *) malloc (dirarray[diridx]->len + 1
+ + fnamelen + 1);
+ if (new_file->name != NULL)
+ {
+ char *cp = new_file->name;
+
+ if (dirarray[diridx]->dir != NULL)
+ /* This value could be NULL in case the DW_AT_comp_dir
+ was not present. We cannot do much in this case.
+ The easiest thing is to convert the path in an
+ absolute path. */
+ cp = stpcpy (cp, dirarray[diridx]->dir);
+ *cp++ = '/';
+ strcpy (cp, fname);
+ }
+ }
+ if (new_file->name == NULL)
+ {
+ /* XXX Should we bother to free all the memory? */
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ /* Next comes the modification time. */
+ get_uleb128 (new_file->mtime, linep);
+
+ /* Finally the length of the file. */
+ get_uleb128 (new_file->length, linep);
+
+ new_file->next = filelist;
+ filelist = new_file;
+ ++nfilelist;
+ }
+ ++linep;
+
+ /* Consistency check. */
+ if (unlikely (linep != header_start + header_length))
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* We are about to process the statement program. Initialize the
+ state machine registers (see 6.2.2 in the v2.1 specification). */
+ address = 0;
+ file = 1;
+ line = 1;
+ column = 0;
+ is_stmt = default_is_stmt;
+ basic_block = 0;
+ prologue_end = 0;
+ epilogue_begin = 0;
+
+ /* Process the instructions. */
+ linelist = NULL;
+ nlinelist = 0;
+ while (linep < lineendp)
+ {
+ struct linelist *new_line;
+ unsigned int opcode;
+ unsigned int u128;
+ int s128;
+
+ /* Read the opcode. */
+ opcode = *linep++;
+
+ /* Is this a special opcode? */
+ if (likely (opcode >= opcode_base))
+ {
+ /* Yes. Handling this is quite easy since the opcode value
+ is computed with
+
+ opcode = (desired line increment - line_base)
+ + (line_range * address advance) + opcode_base
+ */
+ int line_increment = line_base + (opcode - opcode_base) % line_range;
+ unsigned int address_increment = (minimum_instruction_length
+ * ((opcode - opcode_base)
+ / line_range));
+
+ /* Perform the increments. */
+ line += line_increment;
+ address += address_increment;
+
+ /* Add a new line with the current state machine values. */
+ NEW_LINE (0);
+
+ /* Reset the flags. */
+ basic_block = 0;
+ prologue_end = 0;
+ epilogue_begin = 0;
+ }
+ else if (opcode == 0)
+ {
+ /* This an extended opcode. */
+ unsigned int len;
+
+ /* The length. */
+ len = *linep++;
+
+ /* The sub-opecode. */
+ opcode = *linep++;
+
+ switch (opcode)
+ {
+ case DW_LNE_end_sequence:
+ /* Add a new line with the current state machine values.
+ The is the end of the sequence. */
+ NEW_LINE (1);
+
+ /* Reset the registers. */
+ address = 0;
+ file = 1;
+ line = 1;
+ column = 0;
+ is_stmt = default_is_stmt;
+ basic_block = 0;
+ prologue_end = 0;
+ epilogue_begin = 0;
+ break;
+
+ case DW_LNE_set_address:
+ if (cu->address_size == 4)
+ address = read_4ubyte_unaligned (dbg, linep);
+ else
+ address = read_8ubyte_unaligned (dbg, linep);
+ linep += cu->address_size;
+ break;
+
+ case DW_LNE_define_file:
+ {
+ struct filelist *new_file;
+ char *fname;
+ size_t fnamelen;
+ unsigned int diridx;
+ Dwarf_Unsigned mtime;
+ Dwarf_Unsigned length;
+
+ fname = (char *) linep;
+ fnamelen = strlen (fname);
+ linep += fnamelen + 1;
+
+ get_uleb128 (diridx, linep);
+ get_uleb128 (mtime, linep);
+ get_uleb128 (length, linep);
+
+ new_file = (struct filelist *) alloca (sizeof (*new_file));
+ if (fname[0] == '/')
+ new_file->name = strdup (fname);
+ else
+ {
+
+ new_file->name = (char *) malloc (dirarray[diridx]->len + 1
+ + fnamelen + 1);
+ if (new_file->name != NULL)
+ {
+ char *cp = new_file->name;
+
+ if (dirarray[diridx]->dir != NULL)
+ /* This value could be NULL in case the
+ DW_AT_comp_dir was not present. We
+ cannot do much in this case. The easiest
+ thing is to convert the path in an
+ absolute path. */
+ cp = stpcpy (cp, dirarray[diridx]->dir);
+ *cp++ = '/';
+ strcpy (cp, fname);
+ }
+ }
+ if (new_file->name == NULL)
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ new_file->mtime = mtime;
+ new_file->length = length;
+ new_file->next = filelist;
+ filelist = new_file;
+ ++nfilelist;
+ }
+ break;
+
+ default:
+ /* Unknown, ignore it. */
+ linep += len - 1;
+ break;
+ }
+ }
+ else if (opcode <= DW_LNS_set_epilog_begin)
+ {
+ /* This is a known standard opcode. */
+ switch (opcode)
+ {
+ case DW_LNS_copy:
+ /* Takes no argument. */
+ if (unlikely (standard_opcode_lengths[opcode] != 0))
+ {
+ /* XXX Free memory. */
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ /* Add a new line with the current state machine values. */
+ NEW_LINE (0);
+
+ /* Reset the flags. */
+ basic_block = 0;
+ /* XXX Whether the following two lines are necessary is
+ unclear. I guess the current v2.1 specification has
+ a bug in that it says clearing these two registers is
+ not necessary. */
+ prologue_end = 0;
+ epilogue_begin = 0;
+ break;
+
+ case DW_LNS_advance_pc:
+ /* Takes one uleb128 parameter which is added to the address. */
+ if (unlikely (standard_opcode_lengths[opcode] != 1))
+ {
+ /* XXX Free memory. */
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ get_uleb128 (u128, linep);
+ address += minimum_instruction_length * u128;
+ break;
+
+ case DW_LNS_advance_line:
+ /* Takes one sleb128 parameter which is added to the line. */
+ if (unlikely (standard_opcode_lengths[opcode] != 1))
+ {
+ /* XXX Free memory. */
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ get_sleb128 (s128, linep);
+ line += s128;
+ break;
+
+ case DW_LNS_set_file:
+ /* Takes one uleb128 parameter which is stored in file. */
+ if (unlikely (standard_opcode_lengths[opcode] != 1))
+ {
+ /* XXX Free memory. */
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ get_uleb128 (u128, linep);
+ file = u128;
+ break;
+
+ case DW_LNS_set_column:
+ /* Takes one uleb128 parameter which is stored in column. */
+ if (unlikely (standard_opcode_lengths[opcode] != 1))
+ {
+ /* XXX Free memory. */
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ get_uleb128 (u128, linep);
+ column = u128;
+ break;
+
+ case DW_LNS_negate_stmt:
+ /* Takes no argument. */
+ if (unlikely (standard_opcode_lengths[opcode] != 0))
+ {
+ /* XXX Free memory. */
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ is_stmt = 1 - is_stmt;
+ break;
+
+ case DW_LNS_set_basic_block:
+ /* Takes no argument. */
+ if (unlikely (standard_opcode_lengths[opcode] != 0))
+ {
+ /* XXX Free memory. */
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ basic_block = 1;
+ break;
+
+ case DW_LNS_const_add_pc:
+ /* Takes no argument. */
+ if (unlikely (standard_opcode_lengths[opcode] != 0))
+ {
+ /* XXX Free memory. */
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ address += (minimum_instruction_length
+ * ((255 - opcode_base) / line_range));
+ break;
+
+ case DW_LNS_fixed_advance_pc:
+ /* Takes one 16 bit parameter which is added to the address. */
+ if (unlikely (standard_opcode_lengths[opcode] != 1))
+ {
+ /* XXX Free memory. */
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ address += read_2ubyte_unaligned (dbg, linep);
+ linep += 2;
+ break;
+
+ case DW_LNS_set_prologue_end:
+ /* Takes no argument. */
+ if (unlikely (standard_opcode_lengths[opcode] != 0))
+ {
+ /* XXX Free memory. */
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ prologue_end = 1;
+ break;
+
+ case DW_LNS_set_epilog_begin:
+ /* Takes no argument. */
+ if (unlikely (standard_opcode_lengths[opcode] != 0))
+ {
+ /* XXX Free memory. */
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_INVALID_DWARF);
+ return DW_DLV_ERROR;
+ }
+
+ epilogue_begin = 1;
+ break;
+ }
+ }
+ else
+ {
+ /* This is a new opcode the generator but not we know about.
+ Read the parameters associated with it but then discard
+ everything. */
+ int n;
+
+ /* Read all the parameters for this opcode. */
+ for (n = standard_opcode_lengths[opcode]; n > 0; --n)
+ {
+ Dwarf_Unsigned u128;
+ get_uleb128 (u128, linep);
+ }
+
+ /* Next round, ignore this opcode. */
+ continue;
+ }
+ }
+
+ /* Put all the files in an array. */
+ files = (Dwarf_File) malloc (sizeof (struct Dwarf_File_s)
+ + nfilelist * sizeof (Dwarf_Fileinfo));
+ if (files == NULL)
+ {
+ /* XXX Should we bother to free all the memory? */
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ files->nfiles = nfilelist;
+ while (nfilelist-- > 0)
+ {
+ files->info[nfilelist].name = filelist->name;
+ files->info[nfilelist].mtime = filelist->mtime;
+ files->info[nfilelist].length = filelist->length;
+ filelist = filelist->next;
+ }
+
+ /* Remember the debugging descriptor. */
+ files->dbg = dbg;
+
+ /* Now put the lines in an array. */
+ lines = (Dwarf_Line *) malloc (nlinelist * sizeof (Dwarf_Line));
+ if (lines == NULL)
+ {
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+ __libdwarf_error (dbg, error, DW_E_NOMEM);
+ return DW_DLV_ERROR;
+ }
+
+ *linebuf = lines;
+ *linecount = nlinelist;
+
+ while (nlinelist--)
+ {
+ lines[nlinelist] = linelist->line;
+ linelist->line->files = files;
+ linelist = linelist->next;
+ }
+
+ dwarf_dealloc (dbg, stmt_list, DW_DLA_ATTR);
+
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_tag.c b/libdwarf/dwarf_tag.c
new file mode 100644
index 00000000..3c4d36ec
--- /dev/null
+++ b/libdwarf/dwarf_tag.c
@@ -0,0 +1,30 @@
+/* Return tag of die.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_tag (die, tagval, error)
+ Dwarf_Die die;
+ Dwarf_Half *tagval;
+ Dwarf_Error *error;
+{
+ *tagval = die->abbrev->tag;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_whatattr.c b/libdwarf/dwarf_whatattr.c
new file mode 100644
index 00000000..9887f2e1
--- /dev/null
+++ b/libdwarf/dwarf_whatattr.c
@@ -0,0 +1,30 @@
+/* Return code of attribute.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_whatattr (attr, return_attr, error)
+ Dwarf_Attribute attr;
+ Dwarf_Half *return_attr;
+ Dwarf_Error *error;
+{
+ *return_attr = attr->code;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/dwarf_whatform.c b/libdwarf/dwarf_whatform.c
new file mode 100644
index 00000000..5cb67b3d
--- /dev/null
+++ b/libdwarf/dwarf_whatform.c
@@ -0,0 +1,30 @@
+/* Return form of attribute.
+ Copyright (C) 2000, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifdef HAVE_CONFIG_H
+# include <config.h>
+#endif
+
+#include <libdwarfP.h>
+
+
+int
+dwarf_whatform (attr, return_form, error)
+ Dwarf_Attribute attr;
+ Dwarf_Half *return_form;
+ Dwarf_Error *error;
+{
+ *return_form = attr->form;
+ return DW_DLV_OK;
+}
diff --git a/libdwarf/libdwarf.h b/libdwarf/libdwarf.h
new file mode 100644
index 00000000..37c958ca
--- /dev/null
+++ b/libdwarf/libdwarf.h
@@ -0,0 +1,514 @@
+/* Interface for libdwarf.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifndef _LIBDWARF_H
+#define _LIBDWARF_H 1
+
+#include <libelf.h>
+#include <stdint.h>
+
+/* Basic data types. */
+
+/* Used for boolean values. */
+typedef int Dwarf_Bool;
+
+/* Numeric values of different sizes. */
+typedef uint8_t Dwarf_Small;
+typedef uint16_t Dwarf_Half;
+typedef uint64_t Dwarf_Unsigned;
+typedef int64_t Dwarf_Signed;
+
+/* Offsets in the debugging sections. */
+typedef uint64_t Dwarf_Off;
+
+/* Program counter value in the target object file. */
+typedef uint64_t Dwarf_Addr;
+
+/* Address in the host process. */
+typedef void *Dwarf_Ptr;
+
+
+/* Location record. */
+typedef struct
+ {
+ Dwarf_Small lr_atom; /* Operation */
+ Dwarf_Unsigned lr_number; /* Operand */
+ Dwarf_Unsigned lr_number2; /* Possible second operand */
+ Dwarf_Unsigned lr_offset; /* Offset in location expression */
+ } Dwarf_Loc;
+
+
+/* Location description. */
+typedef struct
+ {
+ Dwarf_Addr ld_lopc; /* Beginning of range */
+ Dwarf_Addr ld_hipc; /* End of range */
+ Dwarf_Half ld_cents; /* Number of location records */
+ Dwarf_Loc *ld_s; /* Array of location records */
+ } Dwarf_Locdesc;
+
+
+/* Error handler function. */
+typedef struct Dwarf_Error_s *Dwarf_Error; /* Forward declaration. */
+typedef void (*Dwarf_Handler) (Dwarf_Error *, Dwarf_Ptr);
+
+/* Descriptor for block of uninterpreted data. */
+typedef struct
+ {
+ Dwarf_Unsigned bl_len;
+ Dwarf_Ptr bl_data;
+ } Dwarf_Block;
+
+
+/* Descriptor for libdwarf session. */
+typedef struct Dwarf_Debug_s *Dwarf_Debug;
+
+/* Descriptor for DWARF DIE. */
+typedef struct Dwarf_Die_s *Dwarf_Die;
+
+/* Descriptor for DWARF attribute list. */
+typedef struct Dwarf_Attribute_s *Dwarf_Attribute;
+
+/* Descriptor for source lines. */
+typedef struct Dwarf_Line_s *Dwarf_Line;
+
+/* Descriptor for global name. */
+typedef struct Dwarf_Global_s *Dwarf_Global;
+
+/* Descriptor for address range. */
+typedef struct Dwarf_Arange_s *Dwarf_Arange;
+
+/* Descriptor for common information entry. */
+typedef struct Dwarf_Cie_s *Dwarf_Cie;
+
+/* Descriptor for frame descriptor entry. */
+typedef struct Dwarf_Fde_s *Dwarf_Fde;
+
+/* Descriptor for abbreviations. */
+typedef struct Dwarf_Abbrev_s *Dwarf_Abbrev;
+
+
+/* Return values. */
+enum
+ {
+ DW_DLV_NO_ENTRY = -1, /* No error, but no entry. */
+ DW_DLV_OK = 0, /* Success. */
+ DW_DLV_ERROR = 1, /* Failure. */
+ };
+
+
+/* Values for ACCESS parameter of 'dwarf_init' and 'dwarf_elf_init'. */
+enum
+ {
+ DW_DLC_READ = 0, /* Read-only access. */
+ DW_DLC_WRITE = 1, /* Write-only access. */
+ DW_DLC_RDWR = 2 /* Read-write access. */
+ };
+
+
+/* Open file associates with FD for use with the other functions of
+ this library. Set the error handler and the parameter passed. */
+extern int dwarf_init (int fd, Dwarf_Unsigned access,
+ Dwarf_Handler errhand, Dwarf_Ptr errarg,
+ Dwarf_Debug *dbg, Dwarf_Error *errdesc);
+
+/* Similar to `dwarf_init' but instead of a file descriptor of ELF
+ descriptor is passed. */
+extern int dwarf_elf_init (Elf *elf, Dwarf_Unsigned access,
+ Dwarf_Handler errhand, Dwarf_Ptr errarg,
+ Dwarf_Debug *dbg, Dwarf_Error *errdesc);
+
+/* Return ELF handle. */
+extern int dwarf_get_elf_init (Dwarf_Debug dbg, Elf **elf,
+ Dwarf_Error *errdesc);
+
+/* Free resources allocated for debug handle. */
+extern int dwarf_finish (Dwarf_Debug dbg, Dwarf_Error *errdesc);
+
+
+/* Return information about current and find new compile unit header. */
+extern int dwarf_next_cu_header (Dwarf_Debug dbg,
+ Dwarf_Unsigned *cu_header_length,
+ Dwarf_Half *version_stamp,
+ Dwarf_Unsigned *abbrev_offset,
+ Dwarf_Half *address_size,
+ Dwarf_Unsigned *next_cu_header,
+ Dwarf_Error *errdesc);
+
+/* Return sibling of given DIE. */
+extern int dwarf_siblingof (Dwarf_Debug dbg, Dwarf_Die die,
+ Dwarf_Die *return_sub, Dwarf_Error *errdesc);
+
+/* Return child of DIE. */
+extern int dwarf_child (Dwarf_Die die, Dwarf_Die *return_kid,
+ Dwarf_Error *errdesc);
+
+/* Return DIE at given offset. */
+extern int dwarf_offdie (Dwarf_Debug dbg, Dwarf_Off offset,
+ Dwarf_Die *return_die, Dwarf_Error *errdesc);
+
+
+/* Return tag of DIE. */
+extern int dwarf_tag (Dwarf_Die die, Dwarf_Half *tagval, Dwarf_Error *errdesc);
+
+/* Return offset of DIE in .debug_info section. */
+extern int dwarf_dieoffset (Dwarf_Die die, Dwarf_Off *return_offset,
+ Dwarf_Error *errdesc);
+
+/* Return offset of DIE in compile unit data. */
+extern int dwarf_die_CU_offset (Dwarf_Die die, Dwarf_Off *return_offset,
+ Dwarf_Error *errdesc);
+
+/* Return name attribute of DIE. */
+extern int dwarf_diename (Dwarf_Die die, char **return_name,
+ Dwarf_Error *errdesc);
+
+/* Return list of attributes for DIE. */
+extern int dwarf_attrlist (Dwarf_Die die, Dwarf_Attribute **attrbuf,
+ Dwarf_Signed *attrcount, Dwarf_Error *errdesc);
+
+/* Determine whether DIE has attribute specified of given type. */
+extern int dwarf_hasattr (Dwarf_Die die, Dwarf_Half attr,
+ Dwarf_Bool *return_bool, Dwarf_Error *errdesc);
+
+/* Return DIE attribute with specified of given type. */
+extern int dwarf_attr (Dwarf_Die die, Dwarf_Half attr,
+ Dwarf_Attribute *return_attr, Dwarf_Error *errdesc);
+
+/* Return low program counter value associated with die. */
+extern int dwarf_lowpc (Dwarf_Die die, Dwarf_Addr *return_lowpc,
+ Dwarf_Error *errdesc);
+
+/* Return high program counter value associated with die. */
+extern int dwarf_highpc (Dwarf_Die die, Dwarf_Addr *return_lowpc,
+ Dwarf_Error *errdesc);
+
+/* Return byte size value associated with die. */
+extern int dwarf_bytesize (Dwarf_Die die, Dwarf_Unsigned *return_size,
+ Dwarf_Error *errdesc);
+
+/* Return bit size value associated with die. */
+extern int dwarf_bitsize (Dwarf_Die die, Dwarf_Unsigned *return_size,
+ Dwarf_Error *errdesc);
+
+/* Return bit offset value associated with die. */
+extern int dwarf_bitoffset (Dwarf_Die die, Dwarf_Unsigned *return_size,
+ Dwarf_Error *errdesc);
+
+/* Return source language associated with die. */
+extern int dwarf_srclang (Dwarf_Die die, Dwarf_Unsigned *return_lang,
+ Dwarf_Error *errdesc);
+
+/* Return source language associated with die. */
+extern int dwarf_arrayorder (Dwarf_Die die, Dwarf_Unsigned *return_order,
+ Dwarf_Error *errdesc);
+
+
+/* Determine whether attribute has given form. */
+extern int dwarf_hasform (Dwarf_Attribute attr, Dwarf_Half form,
+ Dwarf_Bool *return_hasform, Dwarf_Error *errdesc);
+
+/* Return form of attribute. */
+extern int dwarf_whatform (Dwarf_Attribute attr, Dwarf_Half *return_form,
+ Dwarf_Error *errdesc);
+
+/* Return code of attribute. */
+extern int dwarf_whatattr (Dwarf_Attribute attr, Dwarf_Half *return_attr,
+ Dwarf_Error *errdesc);
+
+/* Return compile-unit relative offset of reference associated with form. */
+extern int dwarf_formref (Dwarf_Attribute attr, Dwarf_Off *return_offset,
+ Dwarf_Error *errdesc);
+
+/* Return .debug_info section global offset of reference associated
+ with form. */
+extern int dwarf_global_formref (Dwarf_Attribute attr,
+ Dwarf_Off *return_offset,
+ Dwarf_Error *errdesc);
+
+/* Return address represented by attribute. */
+extern int dwarf_formaddr (Dwarf_Attribute attr, Dwarf_Addr *return_addr,
+ Dwarf_Error *errdesc);
+
+/* Return flag represented by attribute. */
+extern int dwarf_formflag (Dwarf_Attribute attr, Dwarf_Bool *return_bool,
+ Dwarf_Error *errdesc);
+
+/* Return unsigned constant represented by attribute. */
+extern int dwarf_formudata (Dwarf_Attribute attr, Dwarf_Unsigned *return_uval,
+ Dwarf_Error *errdesc);
+
+/* Return signed constant represented by attribute. */
+extern int dwarf_formsdata (Dwarf_Attribute attr, Dwarf_Signed *return_uval,
+ Dwarf_Error *errdesc);
+
+/* Return block of uninterpreted data represented by attribute. */
+extern int dwarf_formblock (Dwarf_Attribute attr, Dwarf_Block **return_block,
+ Dwarf_Error *errdesc);
+
+/* Return string represented by attribute. */
+extern int dwarf_formstring (Dwarf_Attribute attr, char **return_string,
+ Dwarf_Error *errdesc);
+
+/* Return location expression list. */
+extern int dwarf_loclist (Dwarf_Attribute attr, Dwarf_Locdesc **llbuf,
+ Dwarf_Signed *listlen, Dwarf_Error *errdesc);
+
+
+/* Return source lines of compilation unit. */
+extern int dwarf_srclines (Dwarf_Die die, Dwarf_Line **linebuf,
+ Dwarf_Signed *linecount, Dwarf_Error *errdesc);
+
+/* Return files used in compilation unit. */
+extern int dwarf_srcfiles (Dwarf_Die die, char ***srcfiles,
+ Dwarf_Signed *srcfilecount, Dwarf_Error *errdesc);
+
+/* Determine whether line is the beginning of a statement. */
+extern int dwarf_linebeginstatement (Dwarf_Line line, Dwarf_Bool *return_bool,
+ Dwarf_Error *errdesc);
+
+/* Determine whether line is marked as ending a text sequence. */
+extern int dwarf_lineendsequence (Dwarf_Line line, Dwarf_Bool *return_bool,
+ Dwarf_Error *errdesc);
+
+/* Return source statement line number. */
+extern int dwarf_lineno (Dwarf_Line line, Dwarf_Unsigned *return_lineno,
+ Dwarf_Error *errdesc);
+
+/* Return address associate with line. */
+extern int dwarf_lineaddr (Dwarf_Line line, Dwarf_Addr *return_lineaddr,
+ Dwarf_Error *errdesc);
+
+/* Return column at which the statement begins. */
+extern int dwarf_lineoff (Dwarf_Line line, Dwarf_Signed *return_lineoff,
+ Dwarf_Error *errdesc);
+
+/* Return source file for line. */
+extern int dwarf_linesrc (Dwarf_Line line, char **return_linesrc,
+ Dwarf_Error *errdesc);
+
+/* Determine whether line is marked as beginning a basic block. */
+extern int dwarf_lineblock (Dwarf_Line line, Dwarf_Bool *return_bool,
+ Dwarf_Error *errdesc);
+
+/* Determine whether line is marked as ending the prologue. */
+extern int dwarf_lineprologueend (Dwarf_Line line, Dwarf_Bool *return_bool,
+ Dwarf_Error *errdesc);
+
+/* Determine whether line is marked as beginning the epilogue. */
+extern int dwarf_lineepiloguebegin (Dwarf_Line line, Dwarf_Bool *return_bool,
+ Dwarf_Error *errdesc);
+
+
+/* Return list of global definitions. */
+extern int dwarf_get_globals (Dwarf_Debug dbg, Dwarf_Global **globals,
+ Dwarf_Signed *return_count,
+ Dwarf_Error *errdesc);
+
+/* Return name for global definition. */
+extern int dwarf_globname (Dwarf_Global global, char **return_name,
+ Dwarf_Error *errdesc);
+
+/* Return DIE offset for global definition. */
+extern int dwarf_global_die_offset (Dwarf_Global global,
+ Dwarf_Off *return_offset,
+ Dwarf_Error *errdesc);
+
+/* Return offset of header of compile unit containing the global definition. */
+extern int dwarf_global_cu_offset (Dwarf_Global global,
+ Dwarf_Off *return_offset,
+ Dwarf_Error *errdesc);
+
+/* Return name, DIE offset, and offset of the compile unit DIE for the
+ global definition. */
+extern int dwarf_global_name_offsets (Dwarf_Global global, char **return_name,
+ Dwarf_Off *die_offset,
+ Dwarf_Off *cu_offset,
+ Dwarf_Error *errdesc);
+
+
+/* Find start of macro value. */
+extern char *dwarf_find_macro_value_start (char *macro_string);
+
+
+/* Return string from debug string section. */
+extern int dwarf_get_str (Dwarf_Debug dbg, Dwarf_Off offset, char **string,
+ Dwarf_Signed *returned_str_len,
+ Dwarf_Error *errdesc);
+
+
+/* Return list address ranges. */
+extern int dwarf_get_aranges (Dwarf_Debug dbg, Dwarf_Arange **aranges,
+ Dwarf_Signed *return_count,
+ Dwarf_Error *errdesc);
+
+/* Find matching range for address. */
+extern int dwarf_get_arange (Dwarf_Arange *aranges,
+ Dwarf_Unsigned arange_count, Dwarf_Addr address,
+ Dwarf_Arange *return_arange,
+ Dwarf_Error *errdesc);
+
+/* Return offset of compile unit DIE containing the range. */
+extern int dwarf_get_cu_die_offset (Dwarf_Arange arange,
+ Dwarf_Off *return_offset,
+ Dwarf_Error *errdesc);
+
+/* Return start, length, and CU DIE offset of range. */
+extern int dwarf_get_arange_info (Dwarf_Arange arange, Dwarf_Addr *start,
+ Dwarf_Unsigned *length,
+ Dwarf_Off *cu_die_offset,
+ Dwarf_Error *errdesc);
+
+
+/* Frame descriptor handling. */
+
+/* Get frame descriptions. GCC version using .eh_frame. */
+extern int dwarf_get_fde_list_eh (Dwarf_Debug dbg, Dwarf_Cie **cie_data,
+ Dwarf_Signed *cie_element_count,
+ Dwarf_Fde **fde_data,
+ Dwarf_Signed *fde_element_count,
+ Dwarf_Error *errdesc);
+
+/* Get CIE of FDE. */
+extern int dwarf_get_cie_of_fde (Dwarf_Fde fde, Dwarf_Cie *return_cie,
+ Dwarf_Error *errdesc);
+
+/* Get information about the function range. */
+extern int dwarf_get_fde_range (Dwarf_Fde fde, Dwarf_Addr *low_pc,
+ Dwarf_Unsigned *func_length,
+ Dwarf_Ptr *fde_bytes,
+ Dwarf_Unsigned *fde_byte_length,
+ Dwarf_Off *cie_offset, Dwarf_Signed *cie_index,
+ Dwarf_Off *fde_offset, Dwarf_Error *errdesc);
+
+/* Get information about CIE. */
+extern int dwarf_get_cie_info (Dwarf_Cie cie, Dwarf_Unsigned *bytes_in_cie,
+ Dwarf_Small *version, char **augmenter,
+ Dwarf_Unsigned *code_alignment_factor,
+ Dwarf_Signed *data_alignment_factor,
+ Dwarf_Half *return_address_register,
+ Dwarf_Ptr *initial_instructions,
+ Dwarf_Unsigned *initial_instructions_length,
+ Dwarf_Error *errdesc);
+
+/* Get frame construction instructions of FDE. */
+extern int dwarf_get_fde_instr_bytes (Dwarf_Fde fde, Dwarf_Ptr *outinstrs,
+ Dwarf_Unsigned *outlen,
+ Dwarf_Error *errdesc);
+
+/* Get nth frame descriptions. */
+extern int dwarf_get_fde_n (Dwarf_Fde *fde_data, Dwarf_Unsigned fde_index,
+ Dwarf_Fde *returned_fde, Dwarf_Error *errdesc);
+
+/* Find FDE for given address. */
+extern int dwarf_get_fde_at_pc (Dwarf_Fde *fde_data, Dwarf_Addr pc_of_interest,
+ Dwarf_Fde *returned_fde, Dwarf_Addr *lopc,
+ Dwarf_Addr *hipc, Dwarf_Error *errdesc);
+
+
+/* Return location list entry. */
+extern int dwarf_get_loclist_entry (Dwarf_Debug dbg, Dwarf_Unsigned offset,
+ Dwarf_Addr *hipc_offset,
+ Dwarf_Addr *lopc_offset, Dwarf_Ptr *data,
+ Dwarf_Unsigned *entry_len,
+ Dwarf_Unsigned *next_entry,
+ Dwarf_Error *errdesc);
+
+
+/* Get abbreviation record. */
+extern int dwarf_get_abbrev (Dwarf_Debug dbg,
+ Dwarf_Unsigned offset,
+ Dwarf_Abbrev *returned_abbrev,
+ Dwarf_Unsigned *length,
+ Dwarf_Unsigned *attr_count, Dwarf_Error *errdesc);
+
+/* Get tag of abbreviation record. */
+extern int dwarf_get_abbrev_tag (Dwarf_Abbrev abbrev, Dwarf_Half *return_tag,
+ Dwarf_Error *errdesc);
+
+/* Get code of abbreviation record. */
+extern int dwarf_get_abbrev_code (Dwarf_Abbrev abbrev,
+ Dwarf_Unsigned *return_code,
+ Dwarf_Error *errdesc);
+
+/* Get children flag of abbreviation record. */
+extern int dwarf_get_abbrev_children_flag (Dwarf_Abbrev abbrev,
+ Dwarf_Signed *return_flag,
+ Dwarf_Error *errdesc);
+
+/* Get attribute from abbreviation record. */
+extern int dwarf_get_abbrev_entry (Dwarf_Abbrev abbrev, Dwarf_Signed idx,
+ Dwarf_Half *attr_num, Dwarf_Signed *form,
+ Dwarf_Off *offset, Dwarf_Error *errdesc);
+
+
+/* Memory handling. */
+
+/* Values for ALLOC_TYPE parameter of 'dwarf_dealloc'. */
+enum
+ {
+ DW_DLA_NONE = 0,
+ DW_DLA_STRING, /* char* */
+ DW_DLA_LOC, /* Dwarf_Loc */
+ DW_DLA_LOCDESC, /* Dwarf_Locdesc */
+ DW_DLA_ELLIST, /* Dwarf_Ellist */
+ DW_DLA_BOUNDS, /* Dwarf_Bounds */
+ DW_DLA_BLOCK, /* Dwarf_Block */
+ DW_DLA_DEBUG, /* Dwarf_Debug */
+ DW_DLA_DIE, /* Dwarf_Die */
+ DW_DLA_LINE, /* Dwarf_Line */
+ DW_DLA_ATTR, /* Dwarf_Attribute */
+ DW_DLA_TYPE, /* Dwarf_Type */
+ DW_DLA_SUBSCR, /* Dwarf_Subscr */
+ DW_DLA_GLOBAL, /* Dwarf_Global */
+ DW_DLA_ERROR, /* Dwarf_Error */
+ DW_DLA_LIST, /* a list */
+ DW_DLA_LINEBUF, /* Dwarf_Line* */
+ DW_DLA_ARANGE, /* Dwarf_Arange */
+ DW_DLA_ABBREV, /* Dwarf_Abbrev */
+ DW_DLA_FRAME_OP, /* Dwarf_Frame_Op */
+ DW_DLA_CIE, /* Dwarf_Cie */
+ DW_DLA_FDE, /* Dwarf_Fde */
+ DW_DLA_LOC_BLOCK, /* Dwarf_Loc Block */
+ DW_DLA_FRAME_BLOCK, /* Dwarf_Frame Block */
+ DW_DLA_FUNC, /* Dwarf_Func */
+ DW_DLA_TYPENAME, /* Dwarf_Type */
+ DW_DLA_VAR, /* Dwarf_Var */
+ DW_DLA_WEAK, /* Dwarf_Weak */
+ DW_DLA_ADDR, /* Dwarf_Addr sized entries */
+ };
+
+/* Deallocate memory. */
+extern void dwarf_dealloc (Dwarf_Debug dbg, Dwarf_Ptr space,
+ Dwarf_Unsigned alloc_type);
+
+
+/* Determine size of address of the binary. */
+extern int dwarf_get_address_size (Dwarf_Debug dbg, Dwarf_Half *addr_size,
+ Dwarf_Error *errdesc);
+
+
+/* Return error number. */
+extern Dwarf_Unsigned dwarf_errno (Dwarf_Error errdesc);
+
+/* Return string corresponding to error. */
+extern const char *dwarf_errmsg (Dwarf_Error errdesc);
+
+
+/* Set new error handler. */
+extern Dwarf_Handler dwarf_seterrhand (Dwarf_Debug dbg, Dwarf_Handler errhand);
+
+/* Set new error handler argument. */
+extern Dwarf_Ptr dwarf_seterrarg (Dwarf_Debug dbg, Dwarf_Ptr errarg);
+
+#endif /* libdwarf.h */
diff --git a/libdwarf/libdwarf.map b/libdwarf/libdwarf.map
new file mode 100644
index 00000000..ec0e805e
--- /dev/null
+++ b/libdwarf/libdwarf.map
@@ -0,0 +1,81 @@
+ELFUTILS_1.0 {
+ global:
+ dwarf_arrayorder;
+ dwarf_attr;
+ dwarf_attrlist;
+ dwarf_bitoffset;
+ dwarf_bitsize;
+ dwarf_bytesize;
+ dwarf_child;
+ dwarf_dealloc;
+ dwarf_die_CU_offset;
+ dwarf_diename;
+ dwarf_dieoffset;
+ dwarf_elf_init;
+ dwarf_errmsg;
+ dwarf_errno;
+ dwarf_find_macro_value_start;
+ dwarf_finish;
+ dwarf_formaddr;
+ dwarf_formblock;
+ dwarf_formflag;
+ dwarf_formref;
+ dwarf_formsdata;
+ dwarf_formstring;
+ dwarf_formudata;
+ dwarf_get_abbrev;
+ dwarf_get_abbrev_children_flag;
+ dwarf_get_abbrev_code;
+ dwarf_get_abbrev_entry;
+ dwarf_get_abbrev_tag;
+ dwarf_get_address_size;
+ dwarf_get_arange;
+ dwarf_get_arange_info;
+ dwarf_get_aranges;
+ dwarf_get_cie_info;
+ dwarf_get_cie_of_fde;
+ dwarf_get_cu_die_offset;
+ dwarf_get_elf_init;
+ dwarf_get_fde_at_pc;
+ dwarf_get_fde_instr_bytes;
+ dwarf_get_fde_list_eh;
+ dwarf_get_fde_n;
+ dwarf_get_fde_range;
+ dwarf_get_globals;
+ dwarf_get_loclist_entry;
+ dwarf_get_str;
+ dwarf_global_cu_offset;
+ dwarf_global_die_offset;
+ dwarf_global_formref;
+ dwarf_global_name_offsets;
+ dwarf_globname;
+ dwarf_hasattr;
+ dwarf_hasform;
+ dwarf_highpc;
+ dwarf_init;
+ dwarf_lineaddr;
+ dwarf_linebeginstatement;
+ dwarf_lineblock;
+ dwarf_lineendsequence;
+ dwarf_lineepiloguebegin;
+ dwarf_lineno;
+ dwarf_lineoff;
+ dwarf_lineprologueend;
+ dwarf_linesrc;
+ dwarf_loclist;
+ dwarf_lowpc;
+ dwarf_next_cu_header;
+ dwarf_offdie;
+ dwarf_seterrarg;
+ dwarf_seterrhand;
+ dwarf_siblingof;
+ dwarf_srcfiles;
+ dwarf_srclang;
+ dwarf_srclines;
+ dwarf_tag;
+ dwarf_whatattr;
+ dwarf_whatform;
+
+ local:
+ *;
+};
diff --git a/libdwarf/libdwarfP.h b/libdwarf/libdwarfP.h
new file mode 100644
index 00000000..c6162eee
--- /dev/null
+++ b/libdwarf/libdwarfP.h
@@ -0,0 +1,319 @@
+/* Internal definitions for libdwarf.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifndef _LIBDWARFP_H
+#define _LIBDWARFP_H 1
+
+#include <libdwarf.h>
+#include <libintl.h>
+#include <limits.h>
+
+#include <dwarf_abbrev_hash.h>
+
+
+/* Version of the DWARF specification we support. */
+#define DWARF_VERSION 2
+
+/* Version of the CIE format. */
+#define CIE_VERSION 1
+
+/* Some additional basic types. */
+typedef unsigned int Dwarf_Word;
+
+
+/* Valid indeces for the section data. */
+enum
+ {
+ IDX_debug_info = 0,
+ IDX_debug_abbrev,
+ IDX_debug_aranges,
+ IDX_debug_line,
+ IDX_debug_frame,
+ IDX_eh_frame,
+ IDX_debug_loc,
+ IDX_debug_pubnames,
+ IDX_debug_str,
+ IDX_debug_funcnames,
+ IDX_debug_typenames,
+ IDX_debug_varnames,
+ IDX_debug_weaknames,
+ IDX_debug_macinfo,
+ IDX_last
+ };
+
+
+/* This is the structure representing the debugging state. */
+struct Dwarf_Debug_s
+ {
+#ifdef DWARF_DEBUG
+ int memtag;
+#endif
+
+ Dwarf_Handler dbg_errhand;
+ Dwarf_Ptr dbg_errarg;
+
+ Elf *elf;
+ int other_byte_order;
+
+ Dwarf_Unsigned access;
+
+ /* The section data. */
+ struct
+ {
+ Dwarf_Small *addr;
+ Dwarf_Unsigned size;
+ } sections[IDX_last];
+
+ /* Compilation unit handling. To enable efficient searching we
+ keep track of the unit we already found. */
+ struct Dwarf_CU_Info_s
+ {
+ /* This is the information the 'dwarf_next_cu_header' function
+ is supposed to return. */
+ Dwarf_Unsigned header_length;
+ Dwarf_Unsigned length;
+ Dwarf_Unsigned abbrev_offset;
+ Dwarf_Half version_stamp;
+ Dwarf_Half address_size;
+
+ Dwarf_Unsigned offset; /* In .debug_info section. */
+
+ /* Used to distinguish between 32-bit and 64-bit DWARF. */
+ Dwarf_Half offset_size;
+
+ /* Hash table for the abbreviations. */
+ Dwarf_Abbrev_Hash abbrev_hash;
+ Dwarf_Unsigned last_abbrev_offset;
+
+ Dwarf_Debug dbg;
+
+ struct Dwarf_CU_Info_s *next;
+ } *cu_list;
+ struct Dwarf_CU_Info_s *cu_list_current;
+ struct Dwarf_CU_Info_s *cu_list_tail;
+
+ Dwarf_Unsigned cie_cnt;
+ Dwarf_Unsigned fde_cnt;
+ };
+typedef struct Dwarf_CU_Info_s *Dwarf_CU_Info;
+
+
+/* Memory access macros. We have to define it here since code in the
+ header needs to know the structure of Dwarf_Debug. */
+#include "memory-access.h"
+
+
+/* DWARF die representation. */
+struct Dwarf_Die_s
+ {
+#ifdef DWARF_DEBUG
+ int memtag;
+#endif
+
+ Dwarf_Small *addr;
+ Dwarf_Abbrev abbrev;
+ Dwarf_CU_Info cu;
+ };
+
+
+/* Abbreviation list. */
+struct Dwarf_Abbrev_s
+ {
+ Dwarf_Unsigned code; /* The code. */
+ Dwarf_Half tag; /* The tag. */
+ Dwarf_Small *attrp; /* Pointer to beginning of attributes. */
+ Dwarf_Unsigned attrcnt; /* Number of attributes. */
+ int has_children; /* Nonzero of abbreviation has children. */
+ Dwarf_Unsigned offset; /* Offset in the .debug_abbrev section. */
+ };
+
+
+/* Attribute list. */
+struct Dwarf_Attribute_s
+ {
+ Dwarf_Half code; /* DWARF attribute code. */
+ Dwarf_Half form; /* DWARF form. */
+ Dwarf_Small *valp;
+ Dwarf_CU_Info cu;
+ };
+
+
+/* Structure for error values. */
+struct Dwarf_Error_s
+ {
+ unsigned int de_error;
+ };
+
+
+/* Files in line information records. */
+typedef struct Dwarf_File_s
+ {
+ Dwarf_Debug dbg;
+ unsigned int nfiles;
+ struct Dwarf_Fileinfo_s
+ {
+ char *name;
+ Dwarf_Unsigned mtime;
+ Dwarf_Unsigned length;
+ } info[0];
+ } *Dwarf_File;
+typedef struct Dwarf_Fileinfo_s Dwarf_Fileinfo;
+
+
+/* Representation of a row in the line table. */
+struct Dwarf_Line_s
+ {
+ Dwarf_Addr addr;
+ unsigned int file;
+ int line;
+ unsigned short int column;
+ unsigned int is_stmt:1;
+ unsigned int basic_block:1;
+ unsigned int end_sequence:1;
+ unsigned int prologue_end:1;
+ unsigned int epilogue_begin:1;
+
+ Dwarf_File files;
+ };
+
+
+/* Additional, shared information required for Dwarf_Global handling. */
+typedef struct Dwarf_Global_Info_s
+ {
+ Dwarf_Debug dbg;
+ Dwarf_Unsigned offset;
+ } *Dwarf_Global_Info;
+
+/* Representation of a global name entry. */
+struct Dwarf_Global_s
+ {
+ Dwarf_Unsigned offset;
+ char *name;
+ Dwarf_Global_Info info;
+ };
+
+
+/* Additional, shared information required for Dwarf_Arange handling. */
+typedef struct Dwarf_Arange_Info_s
+ {
+ Dwarf_Debug dbg;
+ Dwarf_Unsigned offset;
+ } *Dwarf_Arange_Info;
+
+/* Representation of an address range entry. */
+struct Dwarf_Arange_s
+ {
+ Dwarf_Addr address;
+ Dwarf_Unsigned length;
+ Dwarf_Arange_Info info;
+ };
+
+
+/* Representation of a common information entry. */
+struct Dwarf_Cie_s
+ {
+ Dwarf_Debug dbg;
+ Dwarf_Unsigned length;
+ char *augmentation;
+ Dwarf_Unsigned code_alignment_factor;
+ Dwarf_Signed data_alignment_factor;
+ Dwarf_Small *initial_instructions;
+ Dwarf_Unsigned initial_instructions_length;
+ Dwarf_Small return_address_register;
+ Dwarf_Unsigned offset;
+ Dwarf_Signed index;
+ };
+
+
+/* Representation of a frame descriptor entry. */
+struct Dwarf_Fde_s
+ {
+ Dwarf_Cie cie;
+ Dwarf_Addr initial_location;
+ Dwarf_Unsigned address_range;
+ Dwarf_Small *instructions;
+ Dwarf_Unsigned instructions_length;
+ Dwarf_Unsigned offset;
+ Dwarf_Small *fde_bytes;
+ Dwarf_Unsigned fde_byte_length;
+ };
+
+
+/* Internal error values. */
+enum
+ {
+ DW_E_NOERROR = 0,
+ DW_E_INVALID_ACCESS,
+ DW_E_NO_REGFILE,
+ DW_E_IO_ERROR,
+ DW_E_NOMEM,
+ DW_E_NOELF,
+ DW_E_GETEHDR_ERROR,
+ DW_E_INVALID_ELF,
+ DW_E_INVALID_DWARF,
+ DW_E_NO_DWARF,
+ DW_E_NO_CU,
+ DW_E_1ST_NO_CU,
+ DW_E_INVALID_OFFSET,
+ DW_E_INVALID_REFERENCE,
+ DW_E_NO_REFERENCE,
+ DW_E_NO_ADDR,
+ DW_E_NO_FLAG,
+ DW_E_NO_CONSTANT,
+ DW_E_NO_BLOCK,
+ DW_E_NO_STRING,
+ DW_E_WRONG_ATTR,
+ DW_E_NO_DATA,
+ DW_E_NO_DEBUG_LINE,
+ DW_E_VERSION_ERROR,
+ DW_E_INVALID_DIR_IDX,
+ DW_E_INVALID_ADDR,
+ DW_E_NO_ABBR,
+ };
+
+
+/* Handle error according to user's wishes. */
+extern void __libdwarf_error (Dwarf_Debug dbg, Dwarf_Error *err, int errval)
+ internal_function;
+
+
+/* Find CU at given offset. */
+extern int __libdwarf_get_cu_at_offset (Dwarf_Debug dbg, Dwarf_Unsigned offset,
+ Dwarf_CU_Info *result_cu,
+ Dwarf_Error *err) internal_function;
+
+/* Find abbreviation. */
+extern Dwarf_Abbrev __libdwarf_get_abbrev (Dwarf_Debug dbg,
+ Dwarf_CU_Info cu,
+ Dwarf_Word code,
+ Dwarf_Error *err)
+ internal_function;
+
+/* Get constant type attribute value. */
+extern int __libdwarf_getconstant (Dwarf_Die die, Dwarf_Half name,
+ Dwarf_Unsigned *return_size,
+ Dwarf_Error *err) internal_function;
+
+/* Determine length of form parameters. */
+extern int __libdwarf_form_val_len (Dwarf_Debug dbg, Dwarf_CU_Info cu,
+ Dwarf_Word form, Dwarf_Small *valp,
+ size_t *len, Dwarf_Error *err)
+ internal_function;
+
+
+/* gettext helper macros. */
+#define _(Str) dgettext ("libdwarf", Str)
+#define N_(Str) Str
+
+#endif /* libdwarfP.h */
diff --git a/libdwarf/memory-access.h b/libdwarf/memory-access.h
new file mode 100644
index 00000000..dcd52b5b
--- /dev/null
+++ b/libdwarf/memory-access.h
@@ -0,0 +1,207 @@
+/* Unaligned memory access functionality.
+ Copyright (C) 2000, 2001, 2002 Red Hat, Inc.
+ Written by Ulrich Drepper <drepper@redhat.com>, 2000.
+
+ This program is Open Source software; you can redistribute it and/or
+ modify it under the terms of the Open Software License version 1.0 as
+ published by the Open Source Initiative.
+
+ You should have received a copy of the Open Software License along
+ with this program; if not, you may obtain a copy of the Open Software
+ License version 1.0 from http://www.opensource.org/licenses/osl.php or
+ by writing the Open Source Initiative c/o Lawrence Rosen, Esq.,
+ 3001 King Ranch Road, Ukiah, CA 95482. */
+
+#ifndef _MEMORY_ACCESS_H
+#define _MEMORY_ACCESS_H 1
+
+#include <byteswap.h>
+#include <stdint.h>
+
+
+/* Number decoding macros. See 7.6 Variable Length Data. */
+#define get_uleb128(var, addr) \
+ do { \
+ Dwarf_Small __b = *addr++; \
+ var = __b & 0x7f; \
+ if (__b & 0x80) \
+ { \
+ __b = *addr++; \
+ var |= (__b & 0x7f) << 7; \
+ if (__b & 0x80) \
+ { \
+ __b = *addr++; \
+ var |= (__b & 0x7f) << 14; \
+ if (__b & 0x80) \
+ { \
+ __b = *addr++; \
+ var |= (__b & 0x7f) << 21; \
+ if (__b & 0x80) \
+ /* Other implementation set VALUE to UINT_MAX in this \
+ case. So we better do this as well. */ \
+ var = UINT_MAX; \
+ } \
+ } \
+ } \
+ } while (0)
+
+/* The signed case is a big more complicated. */
+#define get_sleb128(var, addr) \
+ do { \
+ Dwarf_Small __b = *addr++; \
+ int32_t __res = __b & 0x7f; \
+ if ((__b & 0x80) == 0) \
+ { \
+ if (__b & 0x40) \
+ __res |= 0xffffff80; \
+ } \
+ else \
+ { \
+ __b = *addr++; \
+ __res |= (__b & 0x7f) << 7; \
+ if ((__b & 0x80) == 0) \
+ { \
+ if (__b & 0x40) \
+ __res |= 0xffffc000; \
+ } \
+ else \
+ { \
+ __b = *addr++; \
+ __res |= (__b & 0x7f) << 14; \
+ if ((__b & 0x80) == 0) \
+ { \
+ if (__b & 0x40) \
+ __res |= 0xffe00000; \
+ } \
+ else \
+ { \
+ __b = *addr++; \
+ __res |= (__b & 0x7f) << 21; \
+ if ((__b & 0x80) == 0) \
+ { \
+ if (__b & 0x40) \
+ __res |= 0xf0000000; \
+ } \
+ else \
+ /* Other implementation set VALUE to INT_MAX in this \
+ case. So we better do this as well. */ \
+ __res = INT_MAX; \
+ } \
+ } \
+ } \
+ var = __res; \
+ } while (0)
+
+
+/* We use simple memory access functions in case the hardware allows it.
+ The caller has to make sure we don't have alias problems. */
+#if ALLOW_UNALIGNED
+
+# define read_2ubyte_unaligned(Dbg, Addr) \
+ ((Dbg)->other_byte_order \
+ ? bswap_16 (*((uint16_t *) (Addr))) \
+ : *((uint16_t *) (Addr)))
+# define read_2sbyte_unaligned(Dbg, Addr) \
+ ((Dbg)->other_byte_order \
+ ? (int16_t) bswap_16 (*((int16_t *) (Addr))) \
+ : *((int16_t *) (Addr)))
+
+# define read_4ubyte_unaligned_noncvt(Addr) \
+ *((uint32_t *) (Addr))
+# define read_4ubyte_unaligned(Dbg, Addr) \
+ ((Dbg)->other_byte_order \
+ ? bswap_32 (*((uint32_t *) (Addr))) \
+ : *((uint32_t *) (Addr)))
+# define read_4sbyte_unaligned(Dbg, Addr) \
+ ((Dbg)->other_byte_order \
+ ? (int32_t) bswap_32 (*((int32_t *) (Addr))) \
+ : *((int32_t *) (Addr)))
+
+# define read_8ubyte_unaligned(Dbg, Addr) \
+ ((Dbg)->other_byte_order \
+ ? bswap_64 (*((uint64_t *) (Addr))) \
+ : *((uint64_t *) (Addr)))
+# define read_8sbyte_unaligned(Dbg, Addr) \
+ ((Dbg)->other_byte_order \
+ ? (int64_t) bswap_64 (*((int64_t *) (Addr))) \
+ : *((int64_t *) (Addr)))
+
+#else
+
+# if __GNUC__
+
+union unaligned
+ {
+ void *p;
+ uint16_t u2;
+ uint32_t u4;
+ uint64_t u8;
+ int16_t s2;
+ int32_t s4;
+ int64_t s8;
+ } __attribute__ ((packed));
+
+static inline uint16_t
+read_2ubyte_unaligned (Dwarf_Debug dbg, void *p)
+{
+ union unaligned *up = p;
+ if (dbg->other_byte_order)
+ return bswap_16 (up->u2);
+ return up->u2;
+}
+static inline int16_t
+read_2sbyte_unaligned (Dwarf_Debug dbg, void *p)
+{
+ union unaligned *up = p;
+ if (dbg->other_byte_order)
+ return (int16_t) bswap_16 (up->u2);
+ return up->s2;
+}
+
+static inline uint32_t
+read_4ubyte_unaligned_noncvt (void *p)
+{
+ union unaligned *up = p;
+ return up->u4;
+}
+static inline uint32_t
+read_4ubyte_unaligned (Dwarf_Debug dbg, void *p)
+{
+ union unaligned *up = p;
+ if (dbg->other_byte_order)
+ return bswap_32 (up->u4);
+ return up->u4;
+}
+static inline int32_t
+read_4sbyte_unaligned (Dwarf_Debug dbg, void *p)
+{
+ union unaligned *up = p;
+ if (dbg->other_byte_order)
+ return (int32_t) bswap_32 (up->u4);
+ return up->s4;
+}
+
+static inline uint64_t
+read_8ubyte_unaligned (Dwarf_Debug dbg, void *p)
+{
+ union unaligned *up = p;
+ if (dbg->other_byte_order)
+ return bswap_64 (up->u8);
+ return up->u8;
+}
+static inline int64_t
+read_8sbyte_unaligned (Dwarf_Debug dbg, void *p)
+{
+ union unaligned *up = p;
+ if (dbg->other_byte_order)
+ return (int64_t) bswap_64 (up->u8);
+ return up->s8;
+}
+
+# else
+# error "TODO"
+# endif
+
+#endif
+
+#endif /* memory-access.h */